@@ 0,0 1,101 @@
+# SPDX-FileCopyrightText: ☭ 2021 Emery Hemingway
+# SPDX-License-Identifier: Unlicense
+
+import std/sequtils
+import pixie, pixie/systemtypefaces
+import svui
+
+type Typesetting* = object
+ h1, h2, h3, p: Font
+
+proc newFont(typeface: Typeface, size: float32): Font =
+ result = newFont(typeface)
+ result.size = size
+
+proc initTypesetting*(): Typesetting =
+ let typeface = readTypeface findSystemTypeface(family = "Gentium Plus")
+ result.h1 = newFont(typeface, 24)
+ result.h2 = newFont(typeface, 20)
+ result.h3 = newFont(typeface, 16)
+ result.p = newFont(typeface, 12)
+
+proc body(xhtml: Xhtml): XmlElement =
+ for e in xhtml.elements:
+ if e.orKind == XmlNodeKind.`XmlElement` and e.xmlElement.name == "body":
+ return e.xmlElement
+ raise newException(ValueError, "no body in XHTML document")
+
+proc name(node: XmlNode): string = node.xmlElement.name
+
+proc text(node: XmlNode): string =
+ case node.orKind
+ of XmlNodeKind.XmlElement:
+ for e in node.xmlElement.elements:
+ result.add e.text
+ of XmlNodeKind.XmlText:
+ result.add node.xmlText.data
+
+func height(arr: Arrangement): float =
+ if arr.positions.len > 0: result = arr.positions[arr.positions.high].y
+
+proc add(result: var Arrangement; other: sink Arrangement) =
+ if result.lines.len == 0:
+ result = other
+ else:
+ let runeOff = result.runes.len
+ add(result.lines, map(other.lines,
+ proc (x: (int, int)): (int, int) = (x[0]+runeOff, x[1]+runeOff)))
+ add(result.spans, map(other.spans,
+ proc (x: (int, int)): (int, int) = (x[0]+runeOff, x[1]+runeOff)))
+ add(result.fonts, other.fonts)
+ add(result.runes, other.runes)
+ let yOff = result.positions[result.positions.high].y
+ add(result.positions,
+ map(other.positions,
+ proc(pos: Vec2): Vec2 = vec2(pos.x, pos.y + yOff)))
+ add(result.selectionRects,
+ map(other.selectionRects,
+ proc(rect: Rect): Rect = rect(rect.x, rect.y + yOff, rect.w, rect.h)))
+
+proc render*(ts: Typesetting; xhtml: Xhtml): Image =
+ # TODO: render by font size, not by wh
+ var wh = computeBounds(ts.p, "X")
+ wh.x = wh.x * 80
+ wh.y = wh.y * 50
+ let margin = wh / 9.0
+ var
+ printSpace = wh * (7.0 / 9.0)
+ pages = @[Arrangement()]
+
+ proc pageEnd(): float =
+ let
+ pi = pages.high
+ li = pages[pi].lines.high
+ ci = pages[pi].lines[li][1]
+ pages[pi].positions[ci].y
+
+ proc append(span: Span) =
+ var arr = typeset(@[span], printSpace)
+ if pages[pages.high].height + arr.height < printSpace.y:
+ pages[pages.high].add arr
+ else:
+ discard
+
+ for e in xhtml.body.elements:
+ let tag = e.name
+ case tag
+ of "h1":
+ append newSpan(e.text & "\n", ts.h1)
+ of "h2":
+ append newSpan("\n" & e.text & "\n", ts.h2)
+ of "h3":
+ append newSpan("\n" & e.text & "\n", ts.h3)
+ of "p":
+ append newSpan(" " & e.text & "\n\n", ts.p)
+ else:
+ discard
+ # raise newException(ValueError, "unhandled element in XHTML :" & tag)
+
+ result = newImage(int wh.x, int wh.y)
+ fill(result, rgba(255, 255, 255, 255))
+ fillText(result, pages[0], translate(margin))
@@ 11,8 11,8 @@ import nimsvg
import bumpy, pixie, pixie/fileformats/svg
import sdl2
-
-import svui, svui/render/xhtml
+import svui
+import ./private/render/xhtml
type
Svui = svui.Svui[Ref]