improvements graphics module

This commit is contained in:
Andreas Rumpf 2010-03-10 21:16:05 +01:00
commit 3dafd6856b
3 changed files with 45 additions and 32 deletions

View file

@ -11,7 +11,7 @@
## implementation uses SDL but the interface is meant to support multiple ## implementation uses SDL but the interface is meant to support multiple
## backends some day. ## backends some day.
import colors, math import colors
from sdl import PSurface # Bug from sdl import PSurface # Bug
from sdl_ttf import OpenFont from sdl_ttf import OpenFont
@ -107,8 +107,7 @@ proc blitSurface*(destSurf: PSurface, destRect: TRect, srcSurf: PSurface, srcRec
if SDL.blitSurface(srcSurf.s, addr(srcTRect), destSurf.s, addr(destTRect)) != 0: if SDL.blitSurface(srcSurf.s, addr(srcTRect), destSurf.s, addr(destTRect)) != 0:
raise newException(ESDLError, $SDL.GetError()) raise newException(ESDLError, $SDL.GetError())
proc textBounds*(font: string, fontSize: int, proc textBounds*(font: string, fontSize: int, text: string): tuple[width, height: int] =
text: string): tuple[width, height: int] =
var fontFile = OpenFont(font, fontSize) # Open the font file var fontFile = OpenFont(font, fontSize) # Open the font file
if fontFile == nil: raise newException(ESDLError, "Could not open font file") if fontFile == nil: raise newException(ESDLError, "Could not open font file")
@ -131,7 +130,7 @@ proc drawText*(sur: PSurface, p: TPoint, font: string, text: string,
var RGBfg = fg.extractRGB var RGBfg = fg.extractRGB
# Convert the colors.TColor to SDL.TColor # Convert colors.TColor to SDL.TColor
var SDLfg: SDL.TColor var SDLfg: SDL.TColor
SDLfg.r = toU8(RGBfg.r) SDLfg.r = toU8(RGBfg.r)
SDLfg.g = toU8(RGBfg.g) SDLfg.g = toU8(RGBfg.g)
@ -158,7 +157,7 @@ proc drawText*(sur: PSurface, p: TPoint, font: string, text: string,
var RGBfg = fg.extractRGB var RGBfg = fg.extractRGB
var RGBbg = bg.extractRGB var RGBbg = bg.extractRGB
# Convert the colors.TColor to SDL.TColor # Convert colors.TColor to SDL.TColor
var SDLfg: SDL.TColor var SDLfg: SDL.TColor
SDLfg.r = toU8(RGBfg.r) SDLfg.r = toU8(RGBfg.r)
SDLfg.g = toU8(RGBfg.g) SDLfg.g = toU8(RGBfg.g)
@ -265,10 +264,15 @@ proc drawVerLine*(sur: PSurface, x, y, h: Natural, Color: TColor) =
for i in 0 .. min(sur.s.h-y, h-1)-1: for i in 0 .. min(sur.s.h-y, h-1)-1:
setPix(video, pitch, x, y + i, color) setPix(video, pitch, x, y + i, color)
proc drawLine2*(sur: PSurface, p0: TPoint, p1: TPoint, color: TColor) = proc drawLine2*(sur: PSurface, p0, p1: TPoint, color: TColor) =
## Draws a line from ``p0`` to ``p1``, using the Bresenham's line algorithm ## Draws a line from ``p0`` to ``p1``, using the Bresenham's line algorithm
var (x0, x1, y0, y1) = (p0.x, p1.x, p0.y, p1.y) var (x0, x1, y0, y1) = (p0.x, p1.x, p0.y, p1.y)
if x0 >= sur.s.w: x0 = sur.s.w-1
if x1 >= sur.s.w: x1 = sur.s.w-1
if y0 >= sur.s.h: y0 = sur.s.h-1
if y1 >= sur.s.h: y1 = sur.s.h-1
var video = cast[PPixels](sur.s.pixels) var video = cast[PPixels](sur.s.pixels)
var pitch = sur.s.pitch div ColSize var pitch = sur.s.pitch div ColSize
@ -358,19 +362,21 @@ proc Plot4EllipsePoints(sur: PSurface, CX, CY, X, Y: Natural, col: TColor) =
var video = cast[PPixels](sur.s.pixels) var video = cast[PPixels](sur.s.pixels)
var pitch = sur.s.pitch div ColSize var pitch = sur.s.pitch div ColSize
if CX+X < sur.s.w and CY+Y < sur.s.h: if CX+X <= sur.s.w-1 and CY+Y <= sur.s.h-1:
setPix(video, pitch, CX+X, CY+Y, col) setPix(video, pitch, CX+X, CY+Y, col)
if CX-X < sur.s.w and CY+Y < sur.s.h:
if CX-X <= sur.s.w-1 and CY+Y <= sur.s.h-1:
setPix(video, pitch, CX-X, CY+Y, col) setPix(video, pitch, CX-X, CY+Y, col)
if CX-X < sur.s.w and CY-Y < sur.s.h:
if CX-X <= sur.s.w-1 and CY-Y <= sur.s.h-1:
setPix(video, pitch, CX-X, CY-Y, col) setPix(video, pitch, CX-X, CY-Y, col)
if CX+X < sur.s.w and CY-Y < sur.s.h:
if CX+X <= sur.s.w-1 and CY-Y <= sur.s.h-1:
setPix(video, pitch, CX+X, CY-Y, col) setPix(video, pitch, CX+X, CY-Y, col)
proc drawEllipse*(sur: PSurface, CX, CY, XRadius, YRadius: Natural, col: TColor) = proc drawEllipse*(sur: PSurface, CX, CY, XRadius, YRadius: Natural, col: TColor) =
## Draws an ellipse, ``CX`` and ``CY`` specify the center X and Y of ## Draws an ellipse, ``CX`` and ``CY`` specify the center X and Y of the ellipse,
## the ellipse, ``XRadius`` and ``YRadius`` specify the width and height ## ``XRadius`` and ``YRadius`` specify half the width and height of the ellipse.
## of the ellipse.
var var
X, Y: Natural X, Y: Natural
XChange, YChange: Natural XChange, YChange: Natural
@ -432,13 +438,13 @@ proc plotAA(sur: PSurface, x, y, c: float, color: TColor) =
setPix(video, pitch, x.toInt(), y.toInt(), setPix(video, pitch, x.toInt(), y.toInt(),
pixColor.intensity(1.0 - c) + color.intensity(c)) pixColor.intensity(1.0 - c) + color.intensity(c))
import math
proc ipart(x: float): float = proc ipart(x: float): float =
return x.trunc() return x.trunc()
proc fpart(x: float): float = proc fpart(x: float): float =
return x - ipart(x) return x - ipart(x)
proc rfpart(x: float): float = proc rfpart(x: float): float =
return 1.0 - fpart(x) return 1.0 - fpart(x)
proc drawLineAA(sur: PSurface, p1: TPoint, p2: TPoint, color: TColor) = proc drawLineAA(sur: PSurface, p1: TPoint, p2: TPoint, color: TColor) =
## Draws a anti-aliased line from ``p1`` to ``p2``, using Xiaolin Wu's line algorithm ## Draws a anti-aliased line from ``p1`` to ``p2``, using Xiaolin Wu's line algorithm
var (x1, x2, y1, y2) = (p1.x.toFloat(), p2.x.toFloat(), var (x1, x2, y1, y2) = (p1.x.toFloat(), p2.x.toFloat(),
@ -492,7 +498,8 @@ when isMainModule:
# Draw the shapes # Draw the shapes
surf.fillRect(r, colWhite) surf.fillRect(r, colWhite)
surf.drawLineAA((400, 599), (100, 170), colTan) surf.drawLineAA((100, 170), (400, 471), colTan)
surf.drawLine2((100, 170), (400, 471), colRed)
surf.drawEllipse(200, 300, 200, 30, colSeaGreen) surf.drawEllipse(200, 300, 200, 30, colSeaGreen)
surf.drawHorLine(1, 300, 400, colViolet) # Check if the ellipse is the size it's suppose to be. surf.drawHorLine(1, 300, 400, colViolet) # Check if the ellipse is the size it's suppose to be.
@ -505,7 +512,7 @@ when isMainModule:
surf.drawVerLine(5, 60, 800, colRed) surf.drawVerLine(5, 60, 800, colRed)
surf.drawCircle((600, 500), 60, colRed) surf.drawCircle((600, 500), 60, colRed)
surf.drawText((300, 300), "VeraMono.ttf", "TEST", colTan, colMidnightBlue, 150) surf.drawText((300, 300), "VeraMono.ttf", "TEST", colMidnightBlue, 150)
var textSize = textBounds("VeraMono.ttf", 150, "TEST") var textSize = textBounds("VeraMono.ttf", 150, "TEST")
surf.drawText((300, 300 + textSize.height), "VeraMono.ttf", $textSize.width & ", " & $textSize.height, colDarkGreen, 50) surf.drawText((300, 300 + textSize.height), "VeraMono.ttf", $textSize.width & ", " & $textSize.height, colDarkGreen, 50)
@ -538,7 +545,7 @@ when isMainModule:
mouseStartY = 0 mouseStartY = 0
else: else:
echo(event.theType) #echo(event.theType)
SDL.UpdateRect(surf.s, int32(0), int32(0), int32(800), int32(600)) SDL.UpdateRect(surf.s, int32(0), int32(0), int32(800), int32(600))

View file

@ -98,28 +98,30 @@ proc colorBool(b: bool): string =
else: result = "<span style=\"color:red\">no</span>" else: result = "<span style=\"color:red\">no</span>"
const const
TableHeader = "<table border=\"1\"><tr><td>Test</td><td>Expected</td>" & TableHeader4 = "<table border=\"1\"><tr><td>Test</td><td>Expected</td>" &
"<td>Given</td><td>Success</td></tr>\n"
TableHeader3 = "<table border=\"1\"><tr><td>Test</td><td>Expected</td>" &
"<td>Given</td><td>Success</td></tr>\n" "<td>Given</td><td>Success</td></tr>\n"
TableFooter = "</table>\n" TableFooter = "</table>\n"
proc `$`(r: TResults): string =
result = TableHeader
result.add(r.data)
result.add(TableFooter)
proc addResult(r: var TResults, test, expected, given: string, proc addResult(r: var TResults, test, expected, given: string,
success: bool) = success: bool) =
r.data.addf("<tr><td>$#</td><td>$#</td><td>$#</td><td>$#</td></tr>\n", [ r.data.addf("<tr><td>$#</td><td>$#</td><td>$#</td><td>$#</td></tr>\n", [
test, expected, given, success.colorBool]) test, expected, given, success.colorBool])
proc addResult(r: var TResults, test, given: string,
success: bool) =
r.data.addf("<tr><td>$#</td><td>$#</td><td>$#</td></tr>\n", [
test, given, success.colorBool])
proc listResults(reject, compile, run: TResults) = proc listResults(reject, compile, run: TResults) =
var s = "<html>" var s = "<html>"
s.add("<h1>Tests to Reject</h1>\n") s.add("<h1>Tests to Reject</h1>\n")
s.add($reject) s.add(TableHeader4 & reject.data & TableFooter)
s.add("<br /><br /><br /><h1>Tests to Compile</h1>\n") s.add("<br /><br /><br /><h1>Tests to Compile</h1>\n")
s.add($compile) s.add(TableHeader3 & compile.data & TableFooter)
s.add("<br /><br /><br /><h1>Tests to Run</h1>\n") s.add("<br /><br /><br /><h1>Tests to Run</h1>\n")
s.add($run) s.add(TableHeader4 & run.data & TableFooter)
s.add("</html>") s.add("</html>")
var outp: TFile var outp: TFile
if open(outp, resultsFile, fmWrite): if open(outp, resultsFile, fmWrite):
@ -148,13 +150,16 @@ proc reject(r: var TResults, dir, options: string) =
var given = callCompiler(test, options) var given = callCompiler(test, options)
cmpMsgs(r, specs[expected], given, t) cmpMsgs(r, specs[expected], given, t)
if r.total > 3: break
proc compile(r: var TResults, pattern, options: string) = proc compile(r: var TResults, pattern, options: string) =
for test in os.walkFiles(pattern): for test in os.walkFiles(pattern):
var t = extractFilename(test) var t = extractFilename(test)
inc(r.total) inc(r.total)
var given = callCompiler(test, options) var given = callCompiler(test, options)
r.addResult(t, "", given.msg, not given.err) r.addResult(t, given.msg, not given.err)
if not given.err: inc(r.passed) if not given.err: inc(r.passed)
if r.total > 3: break
proc run(r: var TResults, dir, options: string) = proc run(r: var TResults, dir, options: string) =
var specs = parseRunData(dir) var specs = parseRunData(dir)
@ -174,6 +179,7 @@ proc run(r: var TResults, dir, options: string) =
r.addResult(t, expected.outp, buf, success) r.addResult(t, expected.outp, buf, success)
else: else:
r.addResult(t, expected.outp, "executable not found", false) r.addResult(t, expected.outp, "executable not found", false)
if r.total > 3: break
var options = "" var options = ""
var rejectRes = initResults() var rejectRes = initResults()
@ -185,9 +191,9 @@ for i in 1.. paramCount():
add(options, paramStr(i)) add(options, paramStr(i))
reject(rejectRes, "tests/reject", options) reject(rejectRes, "tests/reject", options)
#compile(compileRes, "tests/accept/compile/t*.nim", options) compile(compileRes, "tests/accept/compile/t*.nim", options)
compile(compileRes, "examples/*.nim", options) compile(compileRes, "examples/*.nim", options)
#compile(compileRes, "examples/gtk/*.nim", options) compile(compileRes, "examples/gtk/*.nim", options)
#run(runRes, "tests/accept/run", options) run(runRes, "tests/accept/run", options)
listResults(rejectRes, compileRes, runRes) listResults(rejectRes, compileRes, runRes)
openDefaultBrowser(resultsFile) openDefaultBrowser(resultsFile)

View file

@ -54,7 +54,7 @@ Additions
- Added ``colors`` module. - Added ``colors`` module.
- Many wrappers now do not contain redundant name prefixes (like ``GTK_``, - Many wrappers now do not contain redundant name prefixes (like ``GTK_``,
``lua``). The old wrappers are still available in ``lib/oldwrappers``. ``lua``). The old wrappers are still available in ``lib/oldwrappers``.
Change your configuration file to use these. You can change your configuration file to use these.
- Triple quoted strings allow for ``"`` in more contexts. - Triple quoted strings allow for ``"`` in more contexts.
- ``""`` within raw string literals stands for a single quotation mark. - ``""`` within raw string literals stands for a single quotation mark.
- More extensive subscript operator overloading. See - More extensive subscript operator overloading. See