diff options
author | rumpf_a@web.de <> | 2010-02-14 13:02:39 +0100 |
---|---|---|
committer | rumpf_a@web.de <> | 2010-02-14 13:02:39 +0100 |
commit | 77c6e52cd4cab05a15fe3870a9b5b248234377d0 (patch) | |
tree | 24af10d6d357506f6e7ff3d1d7f192739d606355 /lib/devel | |
parent | 01fb99bc804ecc38bc2b7e36aefeba338d5604e4 (diff) | |
download | Nim-77c6e52cd4cab05a15fe3870a9b5b248234377d0.tar.gz |
further development of graphics module
Diffstat (limited to 'lib/devel')
-rw-r--r-- | lib/devel/graphics.nim | 74 |
1 files changed, 66 insertions, 8 deletions
diff --git a/lib/devel/graphics.nim b/lib/devel/graphics.nim index 6e4d83187..3495c5a30 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(><fn(ar, br), ><fn(ag, bg), ><fn(ab, bb)) const colRed* = TColor(0x00ff0000) # RGB - colGreen* = ... - colBlue* = ... - colOrange* = ... + colGreen* = TColor(0x0000ff00) + colBlue* = TColor(0x000000ff) + colOrange* = TColor() proc newSurface*(width, height: int): PSurface -proc color*(name: string): TColor +proc toColor*(name: string): TColor proc isColor*(name: string): bool -proc rgb*(r, g, b: range[0..255]): TColor - +proc rgb*(r, g, b: range[0..255]): TColor = + ## constructs a color from RGB values. + result = rawRGB(r, g, b) proc drawRect*(sur: PSurface, r: TRect, col: TColor) proc fillRect*(sur: PSurface, r: TRect, col: TColor) |