On the train to Wien
This commit is contained in:
parent
f344b29e1e
commit
b28583c1ff
|
@ -1,4 +1,2 @@
|
|||
include_rules
|
||||
: well_of_text.nim |> !nim_bin |> {bin}
|
||||
: text_spans.nim |> !nim_bin |> {bin}
|
||||
: wells.nim |> !nim_bin |> {bin}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||
# SPDX-License-Identifier: Unlicense
|
||||
|
||||
import std/[asyncdispatch, options, os, tables]
|
||||
import std/[asyncdispatch, options, os, streams, tables]
|
||||
import preserves, syndicate, syndicate/[capabilities]
|
||||
import bumpy, pixie
|
||||
import sdl2
|
||||
|
@ -59,10 +59,9 @@ func rect(img: Image): bumpy.Rect =
|
|||
proc newApp(length: cint): App =
|
||||
## Create a new square plane of `length` pixels.
|
||||
result = App(
|
||||
topFrame: newFrame(length shl 1, length shl 1),
|
||||
well: newWell(length, length),
|
||||
zoomFactor: 1.0,
|
||||
)
|
||||
app.well = newWell(length, length)
|
||||
discard createWindowAndRenderer(
|
||||
length, length,
|
||||
SDL_WINDOW_RESIZABLE,
|
||||
|
@ -88,13 +87,14 @@ proc redraw(app: App) =
|
|||
app.renderer.setDrawColor(0x80, 0x80, 0x80)
|
||||
app.renderer.clear()
|
||||
|
||||
let wellRect = well.Rect
|
||||
let wellRect = app.well.rect
|
||||
if viewPort.overlaps wellRect:
|
||||
for (pane, rect) in well.intersectingPanes(viewPort)
|
||||
for (index, rect) in app.well.intersectingPanes(viewPort):
|
||||
let texture = app.well.texture(index, app.renderer, rect.wh * app.zoomFactor)
|
||||
if texture.isNil: break
|
||||
let
|
||||
texture = pane.texture(rect.wh *app.zoomFactor)
|
||||
overlap = viewPort and rect
|
||||
src = rect(overlap.xy - app.rect.xy, overlap.wh)
|
||||
src = rect(overlap.xy - rect.xy, overlap.wh)
|
||||
var dst: bumpy.Rect
|
||||
dst.x = (overlap.x - viewPort.x) * (sdlViewPort.w / viewPort.w)
|
||||
dst.y = (overlap.y - viewPort.y) * (sdlViewPort.h / viewPort.h)
|
||||
|
@ -107,6 +107,8 @@ proc redraw(app: App) =
|
|||
overlap.wh * app.zoomFactor
|
||||
var (sdlSrc, sdlDst) = (src.toSdl, dst.toSdl)
|
||||
app.renderer.copy(texture, addr sdlSrc, addr sdlDst)
|
||||
else:
|
||||
echo "no overlap of ", viewPort, " and ", wellRect
|
||||
app.renderer.present()
|
||||
|
||||
proc resize(app: App) =
|
||||
|
@ -126,18 +128,6 @@ proc recenter(app: App) =
|
|||
app.zoomFactor = 1.0
|
||||
app.redraw()
|
||||
|
||||
proc setImage(app: App; image: Image) =
|
||||
app.rect = image.rect
|
||||
echo "create surface of ", image.width, "x", cint image.height, " pixels"
|
||||
var
|
||||
dataPtr = image.data[0].addr
|
||||
surface = createRGBSurfaceFrom(
|
||||
dataPtr,
|
||||
cint image.width, cint image.height,
|
||||
cint 32, cint 4*image.width,
|
||||
rmask, gmask, bmask, amask)
|
||||
app.texture = createTextureFromSurface(app.renderer, surface)
|
||||
|
||||
proc main() =
|
||||
|
||||
discard sdl2.init(INIT_TIMER or INIT_VIDEO or INIT_EVENTS)
|
||||
|
@ -145,7 +135,8 @@ proc main() =
|
|||
|
||||
let
|
||||
typeface = readTypeface(typefacePath)
|
||||
fontTODO = newFont(typeface, 48)
|
||||
font = newFont(typeface)
|
||||
# TODO
|
||||
|
||||
app.redraw()
|
||||
|
||||
|
@ -164,15 +155,17 @@ proc main() =
|
|||
sdlTimeout = 500
|
||||
asyncPollTimeout = 500
|
||||
|
||||
let streamTODO = newFileStream(stdin)
|
||||
let stream = newFileStream(stdin)
|
||||
# TODO
|
||||
|
||||
var
|
||||
evt = sdl2.defaultEvent
|
||||
mousePanning: bool
|
||||
lineTODO: string
|
||||
line: string
|
||||
while true:
|
||||
if readLine(streamTODO, lineTODO):
|
||||
app.well.append(line, fontTODO)
|
||||
if readLine(stream, line):
|
||||
# TODO
|
||||
app.well.append(line, font)
|
||||
app.redraw()
|
||||
# asyncdispatch.poll(0)
|
||||
if waitEventTimeout(evt, sdlTimeout):
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||
# SPDX-License-Identifier: Unlicense
|
||||
|
||||
import std/[deques]
|
||||
import pixie
|
||||
import std/[deques, streams]
|
||||
import bumpy, pixie, sdl2
|
||||
|
||||
type
|
||||
Rect = bumpy.Rect
|
||||
|
||||
Pane* = ref object
|
||||
image: pixie.Image
|
||||
spans: seq[Span]
|
||||
|
@ -24,12 +26,12 @@ proc newWell*(width, height: int): Well =
|
|||
|
||||
proc margins*(well): Vec2 = well.dimensions / 9.0
|
||||
|
||||
proc bounds*(well): Vec2 = well.margin * 7.0
|
||||
proc bounds*(well): Vec2 = well.margins * 7.0
|
||||
|
||||
proc rect*(well): Rect =
|
||||
result.wh = well.dimensions
|
||||
|
||||
proc rectAt(well, offset:int):Rect =
|
||||
proc rectAt(well; offset: int): Rect =
|
||||
if offset < well.panes.len:
|
||||
let n = succ offset
|
||||
result.w = well.dimensions.x / float(2 * n)
|
||||
|
@ -52,14 +54,14 @@ proc append*(well; text: string; font: Font) =
|
|||
assert well.panes.len > 0
|
||||
let span = newSpan(text, font)
|
||||
while true:
|
||||
pane = well.panes[0]
|
||||
let pane = well.panes[0]
|
||||
pane.spans.add(span)
|
||||
var
|
||||
arrangement = typeset(spans, frame.bounds)
|
||||
arrangement = typeset(pane.spans, well.bounds)
|
||||
bounds = layoutBounds arrangement
|
||||
assert bounds.x <= well.boundx.x
|
||||
if bounds.bounds.y <= well.bounds.y:
|
||||
doAssert pane.spans.len > 1, "text does not find on a single pane"
|
||||
# assert bounds.x <= well.bounds.x
|
||||
if bounds.y <= well.bounds.y:
|
||||
doAssert pane.spans.len > 0, "text does not find on a single pane - " & $bounds & $well.bounds
|
||||
pane.arrangement = arrangement
|
||||
break
|
||||
else:
|
||||
|
@ -70,6 +72,7 @@ proc append*(well; stream: Stream; font: Font) =
|
|||
while readLine(stream, line):
|
||||
append(well, line, font)
|
||||
|
||||
#[
|
||||
proc render*(well; index: Natural; scale: float): Image =
|
||||
if index < well.panes.len:
|
||||
let dimensions = well.dimensions * scale
|
||||
|
@ -77,17 +80,41 @@ proc render*(well; index: Natural; scale: float): Image =
|
|||
result = newImage(int dimensions.x, int dimensions.y)
|
||||
fill(result, rgba(255, 255, 255, 255))
|
||||
fillText(well.panes[index].arrangment, translate(well.margin))
|
||||
]#
|
||||
|
||||
|
||||
iterator intersectingPanes(well; rect:Rect): (Pane, Rect) =
|
||||
iterator intersectingPanes*(well; rect: Rect): (int, Rect) =
|
||||
var i = 0
|
||||
while i <well.panes.len:
|
||||
let bounds = well.boundsAt(i)
|
||||
if i and 3:
|
||||
let quad = Rect(0, 0, bounds.x *2.0, bounds.y * 2.0)
|
||||
if not rect.overlaps quad:
|
||||
# all further panes are non-intersecting
|
||||
break
|
||||
if rect.overlaps bounds:
|
||||
yield (well.panes[i], bounds)
|
||||
inc(i)
|
||||
while i < well.panes.len:
|
||||
let bounds = well.rectAt(i)
|
||||
if (i and 3) == 3:
|
||||
let quad = rect(vec2(0,0), bounds.wh * 2.0)
|
||||
if not rect.overlaps quad:
|
||||
# all further panes are non-intersecting
|
||||
break
|
||||
if rect.overlaps bounds:
|
||||
yield (i, bounds)
|
||||
inc(i)
|
||||
|
||||
const
|
||||
amask = uint32 0xff000000
|
||||
rmask = uint32 0x000000ff
|
||||
gmask = uint32 0x0000ff00
|
||||
bmask = uint32 0x00ff0000
|
||||
|
||||
proc texture*(well; index: int; renderer: RendererPtr; wh: Vec2): TexturePtr =
|
||||
# TODO:caching
|
||||
if index >= well.panes.len or wh.x < 4 or wh.y < 4: return nil
|
||||
let pane = well.panes[index]
|
||||
let
|
||||
image = newImage(wh.x.int, wh.y.int)
|
||||
zoom = wh / well.dimensions
|
||||
margin = wh / 9.0
|
||||
if not pane.arrangement.isNil:
|
||||
image.fillText(pane.arrangement, scale(zoom) * translate(margin))
|
||||
var surface = createRGBSurfaceFrom(
|
||||
image.data[0].addr, wh.x.cint, wh.y.cint, cint 32, 4 * wh.x.cint,
|
||||
rmask, gmask, bmask, amask,
|
||||
)
|
||||
result = createTextureFromSurface(renderer, surface)
|
||||
destroy(surface)
|
||||
|
||||
|
|
|
@ -2,4 +2,4 @@ bin = @["well_of_text"]
|
|||
license = "Unlicense"
|
||||
requires: "nim", "syndicate", "sdl2"
|
||||
srcDir = "src"
|
||||
version = "20230906"
|
||||
version = "20230908"
|
||||
|
|
Loading…
Reference in New Issue