summary refs log tree commit diff stats
path: root/lib/devel
diff options
context:
space:
mode:
authorrumpf_a@web.de <>2010-02-14 13:02:39 +0100
committerrumpf_a@web.de <>2010-02-14 13:02:39 +0100
commit77c6e52cd4cab05a15fe3870a9b5b248234377d0 (patch)
tree24af10d6d357506f6e7ff3d1d7f192739d606355 /lib/devel
parent01fb99bc804ecc38bc2b7e36aefeba338d5604e4 (diff)
downloadNim-77c6e52cd4cab05a15fe3870a9b5b248234377d0.tar.gz
further development of graphics module
Diffstat (limited to 'lib/devel')
-rw-r--r--lib/devel/graphics.nim74
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)