diff --git a/lib/devel/graphics.nim b/lib/devel/graphics.nim index 6e4d831871..3495c5a300 100644 --- a/lib/devel/graphics.nim +++ b/lib/devel/graphics.nim @@ -10,9 +10,13 @@ ## This module implements graphical output for Nimrod; the current ## implementation uses Cairo under the surface. +import cairo + type PSurface* = ref TSurface TSurface {.pure, final.} = object + c: cairo.PSurface + ... # internal data @@ -21,23 +25,77 @@ type TColor* = distinct int ## a color stored as RGB -proc `==` (a, b: TColor): bool {.borrow.} -# XXX maybe other operations for colors? What about saturated artithmetic? +proc `==` *(a, b: TColor): bool {.borrow.} + ## compares two colors. + +template extract(a: TColor, r, g, b: expr) = + var r = a shr 16 and 0xff + var g = a shr 8 and 0xff + var b = a and 0xff + +template rawRGB(r, g, b: expr): expr = + TColor(r shl 16 or g shl 8 or b) + +template colorOp(op: expr) = + extract(a, ar, ag, ab) + extract(b, br, bg, bb) + result = rawRGB(op(ar, br), op(ag, bg), op(ab, bb)) + +template satPlus(a, b: expr): expr = + # saturated plus: + block: + var result = a +% b + if result > 255: result = 255 + result + +template satMinus(a, b: expr): expr = + block: + var result = a -% b + if result < 0: result = 0 + result + +proc `+`*(a, b: TColor): TColor = + ## adds two colors: This uses saturated artithmetic, so that each color + ## component cannot overflow (255 is used as a maximum). + colorOp(satPlus) + +proc `-`*(a, b: TColor): TColor = + ## substracts two colors: This uses saturated artithmetic, so that each color + ## component cannot overflow (255 is used as a maximum). + colorOp(satMinus) + +template mix*(a, b: TColor, fn: expr): expr = + ## uses `fn` to mix the colors `a` and `b`. `fn` is invoked for each component + ## R, G, and B. This is a template because `fn` should be inlined and the + ## compiler cannot inline proc pointers yet. If `fn`'s result is not in the + ## range[0..255], it will be saturated to be so. + template `><` (x: expr): expr = + # keep it in the range 0..255 + block: + var xx = x # eval only once + if xx >% 255: + xx = if xx < 0: 0 else: 255 + xx + + extract(a, ar, ag, ab) + extract(b, br, bg, bb) + rawRGB(>``, like ``
  • ``: errors.add(expected(x, result)) break - of tagTr, tagTd, tagTh: - if htmlTag(x.elementName) in {tagTr, tagTd, tagTh}: + of tagTr, tagTd, tagTh, tagTfoot, tagThead: + if htmlTag(x.elementName) in {tagTr, tagTd, tagTh, tagTfoot, tagThead}: errors.add(expected(x, result)) break of tagOptgroup: diff --git a/tests/wildhtml.html b/tests/wildhtml.html new file mode 100644 index 0000000000..06ff2eaf41 --- /dev/null +++ b/tests/wildhtml.html @@ -0,0 +1,2 @@ + +