further development of graphics module
This commit is contained in:
parent
01fb99bc80
commit
77c6e52cd4
3 changed files with 70 additions and 10 deletions
|
|
@ -10,9 +10,13 @@
|
||||||
## This module implements graphical output for Nimrod; the current
|
## This module implements graphical output for Nimrod; the current
|
||||||
## implementation uses Cairo under the surface.
|
## implementation uses Cairo under the surface.
|
||||||
|
|
||||||
|
import cairo
|
||||||
|
|
||||||
type
|
type
|
||||||
PSurface* = ref TSurface
|
PSurface* = ref TSurface
|
||||||
TSurface {.pure, final.} = object
|
TSurface {.pure, final.} = object
|
||||||
|
c: cairo.PSurface
|
||||||
|
|
||||||
... # internal data
|
... # internal data
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -21,23 +25,77 @@ type
|
||||||
|
|
||||||
TColor* = distinct int ## a color stored as RGB
|
TColor* = distinct int ## a color stored as RGB
|
||||||
|
|
||||||
proc `==` (a, b: TColor): bool {.borrow.}
|
proc `==` *(a, b: TColor): bool {.borrow.}
|
||||||
# XXX maybe other operations for colors? What about saturated artithmetic?
|
## 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
|
const
|
||||||
colRed* = TColor(0x00ff0000) # RGB
|
colRed* = TColor(0x00ff0000) # RGB
|
||||||
colGreen* = ...
|
colGreen* = TColor(0x0000ff00)
|
||||||
colBlue* = ...
|
colBlue* = TColor(0x000000ff)
|
||||||
colOrange* = ...
|
colOrange* = TColor()
|
||||||
|
|
||||||
proc newSurface*(width, height: int): PSurface
|
proc newSurface*(width, height: int): PSurface
|
||||||
|
|
||||||
proc color*(name: string): TColor
|
proc toColor*(name: string): TColor
|
||||||
proc isColor*(name: string): bool
|
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 drawRect*(sur: PSurface, r: TRect, col: TColor)
|
||||||
proc fillRect*(sur: PSurface, r: TRect, col: TColor)
|
proc fillRect*(sur: PSurface, r: TRect, col: TColor)
|
||||||
|
|
|
||||||
|
|
@ -281,8 +281,8 @@ proc untilElementEnd(x: var TXmlParser, result: PXmlNode,
|
||||||
# some tags are common to have no ``</end>``, like ``<li>``:
|
# some tags are common to have no ``</end>``, like ``<li>``:
|
||||||
errors.add(expected(x, result))
|
errors.add(expected(x, result))
|
||||||
break
|
break
|
||||||
of tagTr, tagTd, tagTh:
|
of tagTr, tagTd, tagTh, tagTfoot, tagThead:
|
||||||
if htmlTag(x.elementName) in {tagTr, tagTd, tagTh}:
|
if htmlTag(x.elementName) in {tagTr, tagTd, tagTh, tagTfoot, tagThead}:
|
||||||
errors.add(expected(x, result))
|
errors.add(expected(x, result))
|
||||||
break
|
break
|
||||||
of tagOptgroup:
|
of tagOptgroup:
|
||||||
|
|
|
||||||
2
tests/wildhtml.html
Normal file
2
tests/wildhtml.html
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
<!DOCTYPE some doctype >
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue