mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-18 13:30:33 +00:00
version 0.8.8
This commit is contained in:
@@ -11,9 +11,9 @@
|
||||
## implementation uses SDL but the interface is meant to support multiple
|
||||
## backends some day.
|
||||
|
||||
import colors
|
||||
import colors, math
|
||||
from sdl import PSurface # Bug
|
||||
from sdl_ttf import OpenFont
|
||||
from sdl_ttf import OpenFont, closeFont
|
||||
|
||||
type
|
||||
TRect* = tuple[x, y, width, height: int]
|
||||
@@ -24,7 +24,22 @@ type
|
||||
w, h: int
|
||||
s: sdl.PSurface
|
||||
|
||||
ESDLError = object of EBase
|
||||
EGraphics* = object of EBase
|
||||
|
||||
TFont {.pure, final.} = object
|
||||
f: sdl_ttf.PFont
|
||||
color: SDL.TColor
|
||||
PFont* = ref TFont ## represents a font
|
||||
|
||||
proc toSdlColor(c: TColor): Sdl.TColor =
|
||||
# Convert colors.TColor to SDL.TColor
|
||||
var x = c.extractRGB
|
||||
result.r = toU8(x.r)
|
||||
result.g = toU8(x.g)
|
||||
result.b = toU8(x.b)
|
||||
|
||||
proc raiseEGraphics =
|
||||
raise newException(EGraphics, $SDL.GetError())
|
||||
|
||||
proc surfaceFinalizer(s: PSurface) = sdl.freeSurface(s.s)
|
||||
|
||||
@@ -38,6 +53,24 @@ proc newSurface*(width, height: int): PSurface =
|
||||
|
||||
assert(not sdl.MustLock(result.s))
|
||||
|
||||
proc fontFinalizer(f: PFont) = closeFont(f.f)
|
||||
|
||||
proc newFont*(name = "VeraMono.ttf", size = 9, color = colBlack): PFont =
|
||||
## Creates a new font object. Raises ``EIO`` if the font cannot be loaded.
|
||||
new(result, fontFinalizer)
|
||||
result.f = OpenFont(name, size)
|
||||
if result.f == nil:
|
||||
raise newException(EIO, "Could not open font file: " & name)
|
||||
result.color = toSdlColor(color)
|
||||
|
||||
var
|
||||
defaultFont*: PFont ## default font that is used; this needs to initialized
|
||||
## by the client!
|
||||
|
||||
proc initDefaultFont*(name = "VeraMono.ttf", size = 9, color = colBlack) =
|
||||
## initializes the `defaultFont` var.
|
||||
defaultFont = newFont(name, size, color)
|
||||
|
||||
proc newScreenSurface(width, height: int): PSurface =
|
||||
## Creates a new screen surface
|
||||
new(result, surfaceFinalizer)
|
||||
@@ -45,12 +78,6 @@ proc newScreenSurface(width, height: int): PSurface =
|
||||
result.h = height
|
||||
result.s = SDL.SetVideoMode(width, height, 0, 0)
|
||||
|
||||
template withEvents(surf: PSurface, event: expr, actions: stmt): stmt =
|
||||
while True:
|
||||
var event: SDL.TEvent
|
||||
if SDL.PollEvent(addr(event)) == 1:
|
||||
actions
|
||||
|
||||
proc writeToBMP*(sur: PSurface, filename: string) =
|
||||
## Saves the contents of the surface `sur` to the file `filename` as a
|
||||
## BMP file.
|
||||
@@ -70,28 +97,37 @@ template getPix(video, pitch, x, y: expr): expr =
|
||||
const
|
||||
ColSize = 4
|
||||
|
||||
proc getPixel(sur: PSurface, x, y: Natural): colors.TColor =
|
||||
proc getPixel(sur: PSurface, x, y: Natural): colors.TColor {.inline.} =
|
||||
assert x <% sur.w
|
||||
assert y <% sur.h
|
||||
result = getPix(cast[PPixels](sur.s.pixels), sur.s.pitch div ColSize, x, y)
|
||||
|
||||
proc setPixel(sur: PSurface, x, y: Natural, col: colors.TColor) =
|
||||
proc setPixel(sur: PSurface, x, y: Natural, col: colors.TColor) {.inline.} =
|
||||
assert x <% sur.w
|
||||
assert y <% sur.h
|
||||
var pixs = cast[PPixels](sur.s.pixels)
|
||||
#pixs[y * (sur.s.pitch div colSize) + x] = int(col)
|
||||
setPix(pixs, sur.s.pitch div ColSize, x, y, col)
|
||||
|
||||
proc `[]`*(sur: PSurface, p: TPoint): TColor =
|
||||
## get pixel at position `p`. No range checking is done!
|
||||
result = getPixel(sur, p.x, p.y)
|
||||
|
||||
#proc `[,]`*(sur: PSurface, x, y: int): TColor =
|
||||
# result = setPixel(sur, x, y)
|
||||
proc `[,]`*(sur: PSurface, x, y: int): TColor =
|
||||
## get pixel at position ``(x, y)``. No range checking is done!
|
||||
result = getPixel(sur, x, y)
|
||||
|
||||
proc `[]=`*(sur: PSurface, p: TPoint, col: TColor) =
|
||||
## set the pixel at position `p`. No range checking is done!
|
||||
setPixel(sur, p.x, p.y, col)
|
||||
|
||||
#proc `[,]=`*(sur: PSurface, x, y: int, col: TColor) =
|
||||
# setPixel(sur, x, y, col)
|
||||
proc `[,]=`*(sur: PSurface, x, y: int, col: TColor) =
|
||||
## set the pixel at position ``(x, y)``. No range checking is done!
|
||||
setPixel(sur, x, y, col)
|
||||
|
||||
proc blitSurface*(destSurf: PSurface, destRect: TRect, srcSurf: PSurface, srcRect: TRect) =
|
||||
## Merges ``srcSurf`` into ``destSurf``
|
||||
proc blit*(destSurf: PSurface, destRect: TRect, srcSurf: PSurface,
|
||||
srcRect: TRect) =
|
||||
## Copies ``srcSurf`` into ``destSurf``
|
||||
var destTRect, srcTRect: SDL.TRect
|
||||
|
||||
destTRect.x = int16(destRect.x)
|
||||
@@ -105,75 +141,39 @@ proc blitSurface*(destSurf: PSurface, destRect: TRect, srcSurf: PSurface, srcRec
|
||||
srcTRect.h = int16(srcRect.height)
|
||||
|
||||
if SDL.blitSurface(srcSurf.s, addr(srcTRect), destSurf.s, addr(destTRect)) != 0:
|
||||
raise newException(ESDLError, $SDL.GetError())
|
||||
raiseEGraphics()
|
||||
|
||||
proc textBounds*(font: string, fontSize: int, text: string): tuple[width, height: int] =
|
||||
var fontFile = OpenFont(font, fontSize) # Open the font file
|
||||
if fontFile == nil: raise newException(ESDLError, "Could not open font file")
|
||||
|
||||
proc textBounds*(text: string, font = defaultFont): tuple[width, height: int] =
|
||||
var w, h: cint
|
||||
if sdl_ttf.SizeUTF8(fontFile, text, w, h) < 0:
|
||||
raise newException(ESDLError, $SDL.GetError())
|
||||
return (int(w), int(h))
|
||||
if sdl_ttf.SizeUTF8(font.f, text, w, h) < 0: raiseEGraphics()
|
||||
result.width = int(w)
|
||||
result.height = int(h)
|
||||
|
||||
proc drawText*(sur: PSurface, p: TPoint, font: string, text: string,
|
||||
fg: TColor = colBlack, fontSize: int = 9) =
|
||||
## Draws text with a transparent background, at location ``p``.
|
||||
## ``font`` specifies the path to the ttf file,
|
||||
## ``fontSize`` specifies the font size in pt, and ``fg``
|
||||
## specifies the foreground color.
|
||||
var fontFile = OpenFont(font, fontSize) # Open the font file
|
||||
if fontFile == nil: raise newException(ESDLError, "Could not open font file")
|
||||
|
||||
proc drawText*(sur: PSurface, p: TPoint, text: string, font = defaultFont) =
|
||||
## Draws text with a transparent background, at location ``p`` with the given
|
||||
## font.
|
||||
var textSur: PSurface # This surface will have the text drawn on it
|
||||
new(textSur, surfaceFinalizer)
|
||||
|
||||
var RGBfg = fg.extractRGB
|
||||
|
||||
# Convert colors.TColor to SDL.TColor
|
||||
var SDLfg: SDL.TColor
|
||||
SDLfg.r = toU8(RGBfg.r)
|
||||
SDLfg.g = toU8(RGBfg.g)
|
||||
SDLfg.b = toU8(RGBfg.b)
|
||||
|
||||
# Render the text
|
||||
textSur.s = sdl_ttf.RenderTextBlended(fontFile, text, SDLfg)
|
||||
textSur.s = sdl_ttf.RenderTextBlended(font.f, text, font.color)
|
||||
# Merge the text surface with sur
|
||||
sur.blitSurface((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h))
|
||||
sur.blit((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h))
|
||||
# Free the surface
|
||||
SDL.FreeSurface(sur.s)
|
||||
|
||||
proc drawText*(sur: PSurface, p: TPoint, font: string, text: string,
|
||||
bg: TColor, fg: TColor = colBlack, fontSize: int = 9) =
|
||||
## Draws text, at location ``p``, ``font`` specifies the path to
|
||||
## the ttf file, ``fontSize`` specifies the font size in pt, and ``fg``
|
||||
## and ``bg`` specify the foreground and background colors.
|
||||
var fontFile = OpenFont(font, fontSize) # Open the font file
|
||||
if fontFile == nil: raise newException(ESDLError, "Could not open font file")
|
||||
|
||||
proc drawText*(sur: PSurface, p: TPoint, text: string,
|
||||
bg: TColor, font = defaultFont) =
|
||||
## Draws text, at location ``p`` with font ``font``. ``bg``
|
||||
## is the background color.
|
||||
var textSur: PSurface # This surface will have the text drawn on it
|
||||
new(textSur, surfaceFinalizer)
|
||||
|
||||
var RGBfg = fg.extractRGB
|
||||
var RGBbg = bg.extractRGB
|
||||
|
||||
# Convert colors.TColor to SDL.TColor
|
||||
var SDLfg: SDL.TColor
|
||||
SDLfg.r = toU8(RGBfg.r)
|
||||
SDLfg.g = toU8(RGBfg.g)
|
||||
SDLfg.b = toU8(RGBfg.b)
|
||||
var SDLbg: SDL.TColor
|
||||
SDLbg.r = toU8(RGBbg.r)
|
||||
SDLbg.g = toU8(RGBbg.g)
|
||||
SDLbg.b = toU8(RGBbg.b)
|
||||
|
||||
# Render the text
|
||||
textSur.s = sdl_ttf.RenderTextShaded(fontFile, text, SDLfg, SDLbg)
|
||||
textSur.s = sdl_ttf.RenderTextShaded(font.f, text, font.color, toSdlColor(bg))
|
||||
# Merge the text surface with sur
|
||||
sur.blitSurface((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h))
|
||||
sur.blit((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h))
|
||||
# Free the surface
|
||||
SDL.FreeSurface(sur.s)
|
||||
|
||||
|
||||
proc drawCircle*(sur: PSurface, p: TPoint, r: Natural, color: TColor) =
|
||||
## draws a circle with center `p` and radius `r` with the given color
|
||||
## onto the surface `sur`.
|
||||
@@ -185,15 +185,21 @@ proc drawCircle*(sur: PSurface, p: TPoint, r: Natural, color: TColor) =
|
||||
var x = p.x
|
||||
var y = p.y
|
||||
while px <= py + 1:
|
||||
setPix(video, pitch, x + px, y + py, color)
|
||||
setPix(video, pitch, x + px, y - py, color)
|
||||
setPix(video, pitch, x - px, y + py, color)
|
||||
setPix(video, pitch, x - px, y - py, color)
|
||||
if x+px <% sur.w:
|
||||
if y+py <% sur.h: setPix(video, pitch, x+px, y+py, color)
|
||||
if y-py <% sur.h: setPix(video, pitch, x+px, y-py, color)
|
||||
|
||||
if x-px <% sur.w:
|
||||
if y+py <% sur.h: setPix(video, pitch, x-px, y+py, color)
|
||||
if y-py <% sur.h: setPix(video, pitch, x-px, y-py, color)
|
||||
|
||||
setPix(video, pitch, x + py, y + px, color)
|
||||
setPix(video, pitch, x + py, y - px, color)
|
||||
setPix(video, pitch, x - py, y + px, color)
|
||||
setPix(video, pitch, x - py, y - px, color)
|
||||
if x+py <% sur.w:
|
||||
if y+px <% sur.h: setPix(video, pitch, x+py, y+px, color)
|
||||
if y-px <% sur.h: setPix(video, pitch, x+py, y-px, color)
|
||||
|
||||
if x-py <% sur.w:
|
||||
if y+px <% sur.h: setPix(video, pitch, x-py, y+px, color)
|
||||
if y-px <% sur.h: setPix(video, pitch, x-py, y-px, color)
|
||||
|
||||
if a < 0:
|
||||
a = a + (2 * px + 3)
|
||||
@@ -202,16 +208,22 @@ proc drawCircle*(sur: PSurface, p: TPoint, r: Natural, color: TColor) =
|
||||
py = py - 1
|
||||
px = px + 1
|
||||
|
||||
proc `>-<`(val: int, s: PSurface): int {.inline.} =
|
||||
return if val < 0: 0 elif val >= s.w: s.w-1 else: val
|
||||
|
||||
proc `>|<`(val: int, s: PSurface): int {.inline.} =
|
||||
return if val < 0: 0 elif val >= s.h: s.h-1 else: val
|
||||
|
||||
proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) =
|
||||
## draws a line between the two points `p1` and `p2` with the given color
|
||||
## onto the surface `sur`.
|
||||
var stepx, stepy: int = 0
|
||||
var x0: int = p1.x
|
||||
var x1: int = p2.x
|
||||
var y0: int = p1.y
|
||||
var y1: int = p2.y
|
||||
var dy: int = y1 - y0
|
||||
var dx: int = x1 - x0
|
||||
var x0 = p1.x >-< sur
|
||||
var x1 = p2.x >-< sur
|
||||
var y0 = p1.y >|< sur
|
||||
var y1 = p2.y >|< sur
|
||||
var dy = y1 - y0
|
||||
var dx = x1 - x0
|
||||
if dy < 0:
|
||||
dy = -dy
|
||||
stepy = -1
|
||||
@@ -247,7 +259,7 @@ proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) =
|
||||
setPix(video, pitch, x0, y0, color)
|
||||
|
||||
proc drawHorLine*(sur: PSurface, x, y, w: Natural, Color: TColor) =
|
||||
## draws a horizontal line from (x,y) to (x+w-1, h).
|
||||
## draws a horizontal line from (x,y) to (x+w-1, y).
|
||||
var video = cast[PPixels](sur.s.pixels)
|
||||
var pitch = sur.s.pitch div ColSize
|
||||
|
||||
@@ -264,44 +276,6 @@ proc drawVerLine*(sur: PSurface, x, y, h: Natural, Color: TColor) =
|
||||
for i in 0 .. min(sur.s.h-y, h-1)-1:
|
||||
setPix(video, pitch, x, y + i, color)
|
||||
|
||||
proc drawLine2*(sur: PSurface, p0, p1: TPoint, color: TColor) =
|
||||
## 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)
|
||||
|
||||
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 pitch = sur.s.pitch div ColSize
|
||||
|
||||
var steep = abs(y1 - y0) > abs(x1 - x0)
|
||||
if steep:
|
||||
swap(x0, y0)
|
||||
swap(x1, y1)
|
||||
if x0 > x1:
|
||||
swap(x0, x1)
|
||||
swap(y0, y1)
|
||||
|
||||
var deltax = x1 - x0
|
||||
var deltay = abs(y1 - y0)
|
||||
var error = deltax div 2
|
||||
|
||||
var ystep: int
|
||||
var y = y0
|
||||
if y0 < y1: ystep = 1 else: ystep = -1
|
||||
|
||||
for x in x0..x1:
|
||||
if steep:
|
||||
setPix(video, pitch, y, x, color)
|
||||
else:
|
||||
setPix(video, pitch, x, y, color)
|
||||
error = error - deltay
|
||||
if error < 0:
|
||||
y = y + ystep
|
||||
error = error + deltax
|
||||
|
||||
proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: TColor) =
|
||||
## draws a circle with center `p` and radius `r` with the given color
|
||||
## onto the surface `sur` and fills it.
|
||||
@@ -361,22 +335,18 @@ proc fillRect*(sur: PSurface, r: TRect, col: TColor) =
|
||||
proc Plot4EllipsePoints(sur: PSurface, CX, CY, X, Y: Natural, col: TColor) =
|
||||
var video = cast[PPixels](sur.s.pixels)
|
||||
var pitch = sur.s.pitch div ColSize
|
||||
|
||||
if CX+X <= sur.s.w-1 and CY+Y <= sur.s.h-1:
|
||||
setPix(video, pitch, CX+X, CY+Y, col)
|
||||
|
||||
if CX-X <= sur.s.w-1 and CY+Y <= sur.s.h-1:
|
||||
setPix(video, pitch, CX-X, CY+Y, col)
|
||||
|
||||
if CX-X <= sur.s.w-1 and CY-Y <= sur.s.h-1:
|
||||
setPix(video, pitch, CX-X, CY-Y, col)
|
||||
|
||||
if CX+X <= sur.s.w-1 and CY-Y <= sur.s.h-1:
|
||||
setPix(video, pitch, CX+X, CY-Y, col)
|
||||
if CX+X <= sur.s.w-1:
|
||||
if CY+Y <= sur.s.h-1: setPix(video, pitch, CX+X, CY+Y, col)
|
||||
if CY-Y <= sur.s.h-1: setPix(video, pitch, CX+X, CY-Y, col)
|
||||
if CX-X <= sur.s.w-1:
|
||||
if CY+Y <= sur.s.h-1: setPix(video, pitch, CX-X, CY+Y, col)
|
||||
if CY-Y <= sur.s.h-1: setPix(video, pitch, CX-X, CY-Y, col)
|
||||
|
||||
proc drawEllipse*(sur: PSurface, CX, CY, XRadius, YRadius: Natural, col: TColor) =
|
||||
## Draws an ellipse, ``CX`` and ``CY`` specify the center X and Y of the ellipse,
|
||||
## ``XRadius`` and ``YRadius`` specify half the width and height of the ellipse.
|
||||
proc drawEllipse*(sur: PSurface, CX, CY, XRadius, YRadius: Natural,
|
||||
col: TColor) =
|
||||
## Draws an ellipse, ``CX`` and ``CY`` specify the center X and Y of the
|
||||
## ellipse, ``XRadius`` and ``YRadius`` specify half the width and height
|
||||
## of the ellipse.
|
||||
var
|
||||
X, Y: Natural
|
||||
XChange, YChange: Natural
|
||||
@@ -438,18 +408,15 @@ proc plotAA(sur: PSurface, x, y, c: float, color: TColor) =
|
||||
setPix(video, pitch, x.toInt(), y.toInt(),
|
||||
pixColor.intensity(1.0 - c) + color.intensity(c))
|
||||
|
||||
import math
|
||||
proc ipart(x: float): float =
|
||||
return x.trunc()
|
||||
proc fpart(x: float): float =
|
||||
return x - ipart(x)
|
||||
proc rfpart(x: float): float =
|
||||
return 1.0 - fpart(x)
|
||||
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
|
||||
proc ipart(x: float): float = return x.trunc()
|
||||
proc fpart(x: float): float = return x - ipart(x)
|
||||
proc rfpart(x: float): float = return 1.0 - fpart(x)
|
||||
|
||||
proc drawLineAA(sur: PSurface, p1, p2: TPoint, color: TColor) =
|
||||
## 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(),
|
||||
p1.y.toFloat(), p2.y.toFloat())
|
||||
|
||||
var dx = x2 - x1
|
||||
var dy = y2 - y1
|
||||
if abs(dx) < abs(dy):
|
||||
@@ -482,27 +449,28 @@ proc drawLineAA(sur: PSurface, p1: TPoint, p2: TPoint, color: TColor) =
|
||||
sur.plotAA(x.toFloat(), ipart(intery), rfpart(intery), color)
|
||||
sur.plotAA(x.toFloat(), ipart(intery) + 1.0, fpart(intery), color)
|
||||
intery = intery + gradient
|
||||
|
||||
|
||||
if sdl.Init(sdl.INIT_VIDEO) < 0:
|
||||
echo "sdl init failed: " & $SDL.GetError()
|
||||
|
||||
if sdl_ttf.Init() < 0:
|
||||
echo "sdl_ttf init failed: " & $SDL.GetError()
|
||||
template withEvents(surf: PSurface, event: expr, actions: stmt): stmt =
|
||||
while True:
|
||||
var event: SDL.TEvent
|
||||
if SDL.PollEvent(addr(event)) == 1:
|
||||
actions
|
||||
|
||||
if sdl.Init(sdl.INIT_VIDEO) < 0: raiseEGraphics()
|
||||
if sdl_ttf.Init() < 0: raiseEGraphics()
|
||||
|
||||
when isMainModule:
|
||||
#var txtSurf = drawText(
|
||||
|
||||
var surf = newScreenSurface(800, 600)
|
||||
var r: TRect = (0, 0, 900, 900)
|
||||
|
||||
# Draw the shapes
|
||||
surf.fillRect(r, colWhite)
|
||||
surf.drawLineAA((100, 170), (400, 471), colTan)
|
||||
surf.drawLine2((100, 170), (400, 471), colRed)
|
||||
surf.drawLine((100, 170), (400, 471), colRed)
|
||||
|
||||
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.
|
||||
surf.drawVerLine(200, 300 - 30 + 1, 60, colViolet) # ^^ | i suppose it is
|
||||
|
||||
surf.drawEllipse(400, 300, 300, 300, colOrange)
|
||||
@@ -512,35 +480,36 @@ when isMainModule:
|
||||
surf.drawVerLine(5, 60, 800, colRed)
|
||||
surf.drawCircle((600, 500), 60, colRed)
|
||||
|
||||
surf.drawText((300, 300), "VeraMono.ttf", "TEST", colMidnightBlue, 150)
|
||||
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), "TEST", colMidnightBlue)
|
||||
#var textSize = textBounds("TEST")
|
||||
#surf.drawText((300, 300 + textSize.height), $textSize.width & ", " &
|
||||
# $textSize.height, colDarkGreen)
|
||||
|
||||
var mouseStartX = 0
|
||||
var mouseStartY = 0
|
||||
withEvents(surf, event):
|
||||
case event.theType:
|
||||
case event.kind:
|
||||
of SDL.QUITEV:
|
||||
break
|
||||
of SDL.KEYDOWN:
|
||||
if event.key.keysym.sym == SDL.K_LEFT:
|
||||
echo(event.key.keysym.sym)
|
||||
if event.sym == SDL.K_LEFT:
|
||||
echo(event.sym)
|
||||
surf.drawHorLine(395, 300, 5, colPaleGoldenRod)
|
||||
echo("Drawing")
|
||||
else:
|
||||
echo(event.key.keysym.sym)
|
||||
echo(event.sym)
|
||||
of SDL.MOUSEBUTTONDOWN:
|
||||
# button.x/y is F* UP!
|
||||
echo("MOUSEDOWN", event.button.x)
|
||||
mouseStartX = event.button.x
|
||||
mouseStartY = event.button.y
|
||||
echo("MOUSEDOWN ", event.x)
|
||||
mouseStartX = event.x
|
||||
mouseStartY = event.y
|
||||
|
||||
of SDL.MOUSEBUTTONUP:
|
||||
echo("MOUSEUP ", mouseStartX)
|
||||
if mouseStartX != 0 and mouseStartY != 0:
|
||||
echo(mouseStartX, "->", int(event.button.x))
|
||||
echo(mouseStartX, "->", int(event.x))
|
||||
surf.drawLineAA((mouseStartX, MouseStartY),
|
||||
(int(event.button.x), int(event.button.y)), colPaleGoldenRod)
|
||||
(int(event.x), int(event.y)), colPaleGoldenRod)
|
||||
mouseStartX = 0
|
||||
mouseStartY = 0
|
||||
|
||||
|
||||
4189
lib/oldwrappers/zip/libzip_all.c
Executable file
4189
lib/oldwrappers/zip/libzip_all.c
Executable file
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@
|
||||
##
|
||||
## Every tag in the resulting tree is in lower case.
|
||||
##
|
||||
## **Note:** The resulting ``PXmlNode``s already use the ``clientData`` field,
|
||||
## **Note:** The resulting ``PXmlNode`` already use the ``clientData`` field,
|
||||
## so it cannot be used by clients of this library.
|
||||
|
||||
import strutils, streams, parsexml, xmltree, unicode, strtabs
|
||||
@@ -418,4 +418,4 @@ when isMainModule:
|
||||
f.close()
|
||||
else:
|
||||
quit("cannot write test.txt")
|
||||
|
||||
|
||||
|
||||
@@ -284,14 +284,14 @@ proc post*(url: string, extraHeaders = "", body = "",
|
||||
## | POST's ``body`` to the ``url`` and returns a ``TResponse`` object.
|
||||
## | This proc adds the necessary Content-Length header.
|
||||
## | This proc also handles redirection.
|
||||
extraHeaders.add("Content-Length: " & $len(body) & "\c\L")
|
||||
result = request(url, httpPOST, extraHeaders, body)
|
||||
var xh = extraHeaders & "Content-Length: " & $len(body) & "\c\L"
|
||||
result = request(url, httpPOST, xh, body)
|
||||
for i in 1..maxRedirects:
|
||||
if result.status.redirection():
|
||||
var locationHeader = result.headers["Location"]
|
||||
if locationHeader == "": httpError("location header expected")
|
||||
var meth = if result.status != "307": httpGet else: httpPost
|
||||
result = request(locationHeader, meth, extraHeaders, body)
|
||||
result = request(locationHeader, meth, xh, body)
|
||||
|
||||
proc postContent*(url: string, extraHeaders = "", body = ""): string =
|
||||
## | POST's ``body`` to ``url`` and returns the response's body as a string
|
||||
|
||||
@@ -108,7 +108,8 @@ type
|
||||
|
||||
# Nodes should be reference counted to make the `copy` operation very fast!
|
||||
# However, this is difficult to achieve: modify(n[0][1]) should propagate to
|
||||
# its father. How to do this without back references?
|
||||
# its father. How to do this without back references? Hm, BS, it works without
|
||||
# them.
|
||||
|
||||
proc `[]`* (n: PNimrodNode, i: int): PNimrodNode {.magic: "NChild".}
|
||||
## get `n`'s `i`'th child.
|
||||
|
||||
@@ -319,12 +319,12 @@ proc JoinPath*(head, tail: string): string {.noSideEffect.} =
|
||||
##
|
||||
## For example on Unix:
|
||||
##
|
||||
## ..code-block:: nimrod
|
||||
## .. code-block:: nimrod
|
||||
## JoinPath("usr", "lib")
|
||||
##
|
||||
## results in:
|
||||
##
|
||||
## ..code-block:: nimrod
|
||||
## .. code-block:: nimrod
|
||||
## "usr/lib"
|
||||
##
|
||||
## If head is the empty string, tail is returned.
|
||||
@@ -375,6 +375,7 @@ proc SplitPath*(path: string): tuple[head, tail: string] {.noSideEffect.} =
|
||||
## ``JoinPath(head, tail) == path``.
|
||||
##
|
||||
## Examples:
|
||||
##
|
||||
## .. code-block:: nimrod
|
||||
## SplitPath("usr/local/bin") -> ("usr/local", "bin")
|
||||
## SplitPath("usr/local/bin/") -> ("usr/local/bin", "")
|
||||
@@ -399,8 +400,8 @@ proc parentDir*(path: string): string {.noSideEffect.} =
|
||||
##
|
||||
## This is often the same as the ``head`` result of ``splitPath``.
|
||||
## If there is no parent, ``path`` is returned.
|
||||
## Example: ``parentDir("/usr/local/bin") == "/usr/local"``.
|
||||
## Example: ``parentDir("/usr/local/bin/") == "/usr/local"``.
|
||||
## | Example: ``parentDir("/usr/local/bin") == "/usr/local"``.
|
||||
## | Example: ``parentDir("/usr/local/bin/") == "/usr/local"``.
|
||||
var
|
||||
sepPos = -1
|
||||
q = 1
|
||||
@@ -834,7 +835,7 @@ iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] =
|
||||
## for kind, path in walkDir("dirA"):
|
||||
## echo(path)
|
||||
##
|
||||
## produces this output (though not necessarily in this order!)::
|
||||
## produces this output (but not necessarily in this order!)::
|
||||
## dirA/dirB
|
||||
## dirA/dirC
|
||||
## dirA/fileA1.txt
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2008 Andreas Rumpf
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -17,11 +17,11 @@
|
||||
##
|
||||
## .. include:: doc/mytest.cfg
|
||||
## :literal:
|
||||
## The file ``tests/tparscfg.nim`` demonstrates how to use the
|
||||
## The file ``examples/parsecfgex.nim`` demonstrates how to use the
|
||||
## configuration file parser:
|
||||
##
|
||||
## .. code-block:: nimrod
|
||||
## :file: tests/tparscfg.nim
|
||||
## :file: examples/parsecfgex.nim
|
||||
|
||||
|
||||
import
|
||||
|
||||
@@ -1190,7 +1190,7 @@ proc eat(p: var TPegParser, kind: TTokKind) =
|
||||
|
||||
proc parseExpr(p: var TPegParser): TPeg
|
||||
|
||||
proc getNonTerminal(p: TPegParser, name: string): PNonTerminal =
|
||||
proc getNonTerminal(p: var TPegParser, name: string): PNonTerminal =
|
||||
for i in 0..high(p.nonterms):
|
||||
result = p.nonterms[i]
|
||||
if cmpIgnoreStyle(result.name, name) == 0: return
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2008 Andreas Rumpf
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -36,7 +36,7 @@ proc newStringTable*(keyValuePairs: openarray[string],
|
||||
## var mytab = newStringTable("key1", "val1", "key2", "val2",
|
||||
## modeCaseInsensitive)
|
||||
|
||||
proc newStringTable*(mode: TStringTableMode = modeCaseSensitive): PStringTable
|
||||
proc newStringTable*(mode: TStringTableMode): PStringTable
|
||||
## creates a new string table that is empty.
|
||||
|
||||
proc `[]=`*(t: PStringTable, key, val: string)
|
||||
@@ -79,7 +79,7 @@ const
|
||||
growthFactor = 2
|
||||
startSize = 64
|
||||
|
||||
proc newStringTable(mode: TStringTableMode = modeCaseSensitive): PStringTable =
|
||||
proc newStringTable(mode: TStringTableMode): PStringTable =
|
||||
new(result)
|
||||
result.mode = mode
|
||||
result.counter = 0
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
## This module is based on Python's Unidecode module by Tomaz Solc,
|
||||
## which in turn is based on the ``Text::Unidecode`` Perl module by
|
||||
## Sean M. Burke
|
||||
## (http://search.cpan.org/~sburke/Text-Unidecode-0.04/lib/Text/Unidecode.pm).
|
||||
## (http://search.cpan.org/~sburke/Text-Unidecode-0.04/lib/Text/Unidecode.pm ).
|
||||
##
|
||||
## It provides a single proc that does Unicode to ASCII transliterations:
|
||||
## It finds the sequence of ASCII characters that is the closest approximation
|
||||
@@ -47,7 +47,7 @@ proc unidecode*(s: string): string =
|
||||
## Example:
|
||||
##
|
||||
## ..code-block:: nimrod
|
||||
## unidecode("\x53\x17\x4E\xB0")
|
||||
## unidecode("\\x53\\x17\\x4E\\xB0")
|
||||
##
|
||||
## Results in: "Bei Jing"
|
||||
##
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
import macros, strtabs
|
||||
|
||||
type
|
||||
PXmlNode* = ref TXmlNode ## an XML tree consists of ``PXmlNode``s.
|
||||
PXmlNode* = ref TXmlNode ## an XML tree consists of ``PXmlNode``'s.
|
||||
|
||||
TXmlNodeKind* = enum ## different kinds of ``PXmlNode``s
|
||||
TXmlNodeKind* = enum ## different kinds of ``PXmlNode``'s
|
||||
xnText, ## a text element
|
||||
xnElement, ## an element with 0 or more children
|
||||
xnCData, ## a CDATA node
|
||||
@@ -39,7 +39,7 @@ proc newXmlNode(kind: TXmlNodeKind): PXmlNode =
|
||||
result.k = kind
|
||||
|
||||
proc newElement*(tag: string): PXmlNode =
|
||||
## creates a new ``PXmlNode``. of kind ``xnText`` with the given `tag`.
|
||||
## creates a new ``PXmlNode`` of kind ``xnText`` with the given `tag`.
|
||||
result = newXmlNode(xnElement)
|
||||
result.fTag = tag
|
||||
result.s = @[]
|
||||
@@ -208,9 +208,14 @@ proc add*(result: var string, n: PXmlNode, indent = 0, indWidth = 2) =
|
||||
result.add(n.fText)
|
||||
result.add(';')
|
||||
|
||||
const
|
||||
xmlHeader* = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
|
||||
## header to use for complete XML output
|
||||
|
||||
proc `$`*(n: PXmlNode): string =
|
||||
## converts `n` into its string representation.
|
||||
result = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
|
||||
## converts `n` into its string representation. No ``<$xml ...$>`` declaration
|
||||
## is produced, so that the produced XML fragments are composable.
|
||||
result = ""
|
||||
result.add(n)
|
||||
|
||||
proc newXmlTree*(tag: string, children: openArray[PXmlNode],
|
||||
@@ -227,16 +232,21 @@ proc xmlConstructor(e: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||
var a = e[1]
|
||||
if a.kind == nnkCall:
|
||||
result = newCall("newXmlTree", toStrLit(a[0]))
|
||||
var attrs = newCall("newStringTable", [])
|
||||
var bracket = newNimNode(nnkBracket, a)
|
||||
var attrs = newNimNode(nnkBracket, a)
|
||||
var newStringTabCall = newCall("newStringTable", attrs,
|
||||
newIdentNode("modeCaseSensitive"))
|
||||
var elements = newNimNode(nnkBracket, a)
|
||||
for i in 1..a.len-1:
|
||||
if a[i].kind == nnkExprEqExpr:
|
||||
if a[i].kind == nnkExprEqExpr:
|
||||
attrs.add(toStrLit(a[i][0]))
|
||||
attrs.add(a[i][1])
|
||||
echo repr(attrs)
|
||||
else:
|
||||
bracket.add(a[i])
|
||||
result.add(bracket)
|
||||
if attrs.len > 1: result.add(attrs)
|
||||
elements.add(a[i])
|
||||
result.add(elements)
|
||||
if attrs.len > 1:
|
||||
echo repr(newStringTabCall)
|
||||
result.add(newStringTabCall)
|
||||
else:
|
||||
result = newCall("newXmlTree", toStrLit(a))
|
||||
|
||||
@@ -252,5 +262,3 @@ macro `<>`*(x: expr): expr =
|
||||
##
|
||||
result = xmlConstructor(x)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -85,9 +85,6 @@ proc gnome_init*() =
|
||||
proc bonobo_init*() =
|
||||
init()
|
||||
|
||||
proc xml_new*(fname: cstring, root: cstring, domain: cstring): PXML =
|
||||
result = xml_new(fname, root, domain)
|
||||
|
||||
proc xml_new_from_memory*(buffer: cstring, size: int32, root: cstring,
|
||||
domain: cstring): PXML =
|
||||
result = xml_new_from_buffer(buffer, size, root, domain)
|
||||
|
||||
@@ -799,9 +799,6 @@ type
|
||||
here*: ptr byte
|
||||
stop*: ptr byte
|
||||
|
||||
TUnknown*{.final.} = object # first declare the pointer type
|
||||
data1*: Pointer
|
||||
|
||||
PRWops* = ptr TRWops # now the pointer to function types
|
||||
TSeek* = proc (context: PRWops, offset: int, whence: int): int{.cdecl.}
|
||||
TRead* = proc (context: PRWops, thePtr: Pointer, size: int, maxnum: int): int{.
|
||||
@@ -809,23 +806,14 @@ type
|
||||
TWrite* = proc (context: PRWops, thePtr: Pointer, size: int, num: int): int{.
|
||||
cdecl.}
|
||||
TClose* = proc (context: PRWops): int{.cdecl.} # the variant record itself
|
||||
trange010 = range[0..2]
|
||||
TRWops*{.final.} = object
|
||||
seek*: TSeek
|
||||
read*: TRead
|
||||
write*: TWrite
|
||||
closeFile*: TClose # a keyword as name is not allowed
|
||||
# be warned! structure alignment may arise at this point
|
||||
case theType*: trange010
|
||||
of trange010(0):
|
||||
stdio*: TStdio
|
||||
|
||||
of trange010(1):
|
||||
mem*: TMem
|
||||
|
||||
of trange010(2):
|
||||
unknown*: TUnknown
|
||||
|
||||
theType*: cint
|
||||
mem*: TMem
|
||||
|
||||
RWops* = TRWops # SDL_timer.h types
|
||||
# Function prototype for the timer callback function
|
||||
@@ -1014,20 +1002,21 @@ type
|
||||
|
||||
TJoyButtonEvent*{.final.} = object # SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP
|
||||
# The "window resized" event
|
||||
# When you get this event, you are responsible for setting a new video
|
||||
# mode with the new width and height.
|
||||
# When you get this event, you are
|
||||
# responsible for setting a new video
|
||||
# mode with the new width and height.
|
||||
which*: byte # The joystick device index
|
||||
button*: byte # The joystick button index
|
||||
state*: byte # SDL_PRESSED or SDL_RELEASED
|
||||
|
||||
TResizeEvent*{.final.} = object # SDL_VIDEORESIZE
|
||||
# A user-defined event type
|
||||
w*: int # New width
|
||||
h*: int # New height
|
||||
w*: cint # New width
|
||||
h*: cint # New height
|
||||
|
||||
PUserEvent* = ptr TUserEvent
|
||||
TUserEvent*{.final.} = object # SDL_USEREVENT through SDL_NUMEVENTS-1
|
||||
code*: int # User defined event code
|
||||
code*: cint # User defined event code
|
||||
data1*: Pointer # User defined data pointer
|
||||
data2*: Pointer # User defined data pointer
|
||||
|
||||
@@ -1096,7 +1085,7 @@ elif defined(Unix):
|
||||
X11*: TX11
|
||||
|
||||
else:
|
||||
type # The generic custom window manager information structure
|
||||
type # The generic custom window manager information structure
|
||||
PSysWMinfo* = ptr TSysWMinfo
|
||||
TSysWMinfo*{.final.} = object
|
||||
version*: Tversion
|
||||
@@ -1108,46 +1097,59 @@ type
|
||||
msg*: PSysWMmsg
|
||||
|
||||
PEvent* = ptr TEvent
|
||||
TEvent*{.final.} = object # This function sets up a filter to process all events before they
|
||||
# change internal state and are posted to the internal event queue.
|
||||
#
|
||||
# The filter is protypted as:
|
||||
case theType*: TEventKind # SDL_NOEVENT, SDL_QUITEV: ();
|
||||
TEvent*{.final.} = object
|
||||
# This function sets up a filter to process all events before they
|
||||
# change internal state and are posted to the internal event queue.
|
||||
# The filter is protypted as:
|
||||
case kind*: TEventKind # SDL_NOEVENT, SDL_QUITEV: ();
|
||||
of ACTIVEEVENT:
|
||||
active*: TActiveEvent
|
||||
|
||||
gain*: byte # Whether given states were gained or lost (1/0)
|
||||
state*: byte # A mask of the focus states
|
||||
of KEYDOWN, KEYUP:
|
||||
key*: TKeyboardEvent
|
||||
|
||||
keystate*: byte # SDL_PRESSED or SDL_RELEASED
|
||||
scancode*: byte # hardware specific scancode
|
||||
sym*: TKey # SDL virtual keysym
|
||||
modifier*: TMod # current key modifiers
|
||||
unicode*: UInt16 # translated character
|
||||
of MOUSEMOTION:
|
||||
motion*: TMouseMotionEvent
|
||||
|
||||
motionState*: byte # The current button state
|
||||
motionX*, motionY*: UInt16 # The X/Y coordinates of the mouse
|
||||
xrel*: int16 # The relative motion in the X direction
|
||||
yrel*: int16 # The relative motion in the Y direction
|
||||
of MOUSEBUTTONDOWN, MOUSEBUTTONUP:
|
||||
button*: TMouseButtonEvent
|
||||
|
||||
button*: byte # The mouse button index
|
||||
buttonState*: byte # SDL_PRESSED or SDL_RELEASED
|
||||
align: byte
|
||||
x*: UInt16 # The X coordinates of the mouse at press time
|
||||
y*: UInt16 # The Y coordinates of the mouse at press time
|
||||
of JOYAXISMOTION:
|
||||
jaxis*: TJoyAxisEvent
|
||||
|
||||
axis*: byte # The joystick axis index
|
||||
value*: int16 # The axis value (range: -32768 to 32767)
|
||||
of JOYBALLMOTION:
|
||||
jball*: TJoyBallEvent
|
||||
|
||||
ball*: byte # The joystick trackball index
|
||||
joyXrel*: int16 # The relative motion in the X direction
|
||||
joyYrel*: int16 # The relative motion in the Y direction
|
||||
|
||||
of JOYHATMOTION:
|
||||
jhat*: TJoyHatEvent
|
||||
hat*: byte # The joystick hat index
|
||||
hatValue*: byte # The hat position value:
|
||||
# 8 1 2
|
||||
# 7 0 3
|
||||
# 6 5 4
|
||||
# Note that zero means the POV is centered.
|
||||
|
||||
of JOYBUTTONDOWN, JOYBUTTONUP:
|
||||
jbutton*: TJoyButtonEvent
|
||||
|
||||
joybutton*: byte # The joystick button index
|
||||
joyState*: byte # SDL_PRESSED or SDL_RELEASED
|
||||
|
||||
of VIDEORESIZE:
|
||||
resize*: TResizeEvent
|
||||
|
||||
w*: cint # New width
|
||||
h*: cint # New height
|
||||
of USEREVENT:
|
||||
user*: TUserEvent
|
||||
|
||||
of SYSWMEVENT:
|
||||
syswm*: TSysWMEvent
|
||||
|
||||
else:
|
||||
nil
|
||||
code*: cint # User defined event code
|
||||
data1*: Pointer # User defined data pointer
|
||||
data2*: Pointer # User defined data pointer
|
||||
else: nil
|
||||
|
||||
|
||||
TEventFilter* = proc (event: PEvent): int{.cdecl.} # SDL_video.h types
|
||||
@@ -1209,8 +1211,8 @@ type
|
||||
dst*: PPixelFormat
|
||||
|
||||
PSurface* = ptr TSurface
|
||||
TBlit* = proc (src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int{.
|
||||
cdecl.}
|
||||
TBlit* = proc (src: PSurface, srcrect: PRect,
|
||||
dst: PSurface, dstrect: PRect): int{.cdecl.}
|
||||
TSurface*{.final.} = object # Useful for determining the video hardware capabilities
|
||||
flags*: int32 # Read-only
|
||||
format*: PPixelFormat # Read-only
|
||||
@@ -1302,12 +1304,12 @@ type # This is the system-independent thread info struc
|
||||
PWordArray* = ptr TWordArray
|
||||
TWordArray* = array[0..16383, int16] # Generic procedure pointer
|
||||
TProcedure* = proc () #------------------------------------------------------------------------------
|
||||
# initialization
|
||||
#------------------------------------------------------------------------------
|
||||
# This function loads the SDL dynamically linked library and initializes
|
||||
# the subsystems specified by 'flags' (and those satisfying dependencies)
|
||||
# Unless the SDL_INIT_NOPARACHUTE flag is set, it will install cleanup
|
||||
# signal handlers for some commonly ignored fatal signals (like SIGSEGV)
|
||||
# initialization
|
||||
#------------------------------------------------------------------------------
|
||||
# This function loads the SDL dynamically linked library and initializes
|
||||
# the subsystems specified by 'flags' (and those satisfying dependencies)
|
||||
# Unless the SDL_INIT_NOPARACHUTE flag is set, it will install cleanup
|
||||
# signal handlers for some commonly ignored fatal signals (like SIGSEGV)
|
||||
|
||||
proc Init*(flags: int32): int{.cdecl, importc: "SDL_Init", dynlib: LibName.}
|
||||
# This function initializes specific SDL subsystems
|
||||
|
||||
@@ -178,9 +178,11 @@ const
|
||||
|
||||
type
|
||||
PFont* = ptr Tfont
|
||||
TFont*{.final.} = object # This macro can be used to fill a version structure with the compile-time
|
||||
# version of the SDL_ttf library.
|
||||
|
||||
TFont{.final.} = object
|
||||
|
||||
|
||||
# This macro can be used to fill a version structure with the compile-time
|
||||
# version of the SDL_ttf library.
|
||||
|
||||
proc Linked_Version*(): sdl.Pversion{.cdecl, importc: "TTF_Linked_Version",
|
||||
dynlib: ttfLibName.}
|
||||
|
||||
4189
lib/wrappers/zip/libzip_all.c
Executable file
4189
lib/wrappers/zip/libzip_all.c
Executable file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user