further development of graphics module

This commit is contained in:
rumpf_a@web.de
2010-02-14 13:02:39 +01:00
parent 01fb99bc80
commit 77c6e52cd4
3 changed files with 70 additions and 10 deletions

View File

@@ -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)

View File

@@ -281,8 +281,8 @@ proc untilElementEnd(x: var TXmlParser, result: PXmlNode,
# some tags are common to have no ``</end>``, like ``<li>``:
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:

2
tests/wildhtml.html Normal file
View File

@@ -0,0 +1,2 @@
<!DOCTYPE some doctype >