text alignments

This commit is contained in:
Ryan Oldenburg 2021-05-07 11:12:03 -05:00
parent 5130651f15
commit eb550c0671
6 changed files with 155 additions and 6 deletions

View file

@ -139,6 +139,10 @@ proc typeset*(
if rune.uint32 >= SP.uint32 or rune.uint32 == LF.uint32:
result.runes.add(rune)
if result.runes.len == 0:
# No runes to typeset, early return
return
result.runes.convertTextCase(textCase)
result.positions.setLen(result.runes.len)
result.selectionRects.setLen(result.runes.len)
@ -197,6 +201,60 @@ proc typeset*(
result.selectionRects[i] = rect(at.x, at.y - initialY, advance, lineHeight)
at.x += advance
if bounds.x > 0 and hAlign != haLeft:
# Since horizontal alignment adjustments are different for each line,
# find the start and stop of each line of text.
var
lines: seq[(int, int)] # (start, stop)
start: int
prevY = result.positions[0].y
for i, pos in result.positions:
if pos.y != prevY:
lines.add((start, i - 1))
start = i
prevY = pos.y
lines.add((start, result.positions.len - 1))
for (start, stop) in lines:
var furthestX: float32
for i in countdown(stop, start):
if result.runes[i] != SP and result.runes[i] != LF:
furthestX = result.selectionRects[i].x + result.selectionRects[i].w
break
var xAdjustment: float32
case hAlign:
of haLeft:
discard
of haCenter:
xAdjustment = round((bounds.x - furthestX) / 2)
of haRight:
xAdjustment = bounds.x - furthestX
if xAdjustment != 0:
for i in 0 ..< result.positions.len:
result.positions[i].x += xAdjustment
result.selectionRects[i].x += xAdjustment
if bounds.y > 0:
let
finalSelectionRect = result.selectionRects[^1]
furthestY = finalSelectionRect.y + finalSelectionRect.h
var yAdjustment: float32
case vAlign:
of vaTop:
discard
of vaMiddle:
yAdjustment = round((bounds.y - furthestY) / 2)
of vaBottom:
yAdjustment = bounds.y - furthestY
if yAdjustment != 0:
for i in 0 ..< result.positions.len:
result.positions[i].y += yAdjustment
result.selectionRects[i].y += yAdjustment
iterator paths*(arrangement: Arrangement): Path =
for i in 0 ..< arrangement.runes.len:
if arrangement.runes[i].uint32 > SP.uint32: # Don't draw control runes

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View file

@ -1,11 +1,12 @@
import common, pixie, flatty/memoryused
import common, pixie
# Clone https://github.com/google/fonts
# Check out commit ebaa6a7aab9b700da4e30a4682687acdf427eae7
# Clone https://github.com/treeform/fidgetfonts
let fontPaths = findAllFonts("../fonts")
let fontPaths = findAllFonts("../fidgetfonts")
for fontPath in fontPaths:
echo fontPath
let font = readFont(fontPath)
# echo memoryUsed(font)
try:
var font = readFont(fontPath)
except PixieError:
echo "ERROR: ", getCurrentExceptionMsg()

View file

@ -553,3 +553,93 @@ Fifth line""",
)
doDiff(image, "lines2")
block:
var font = readFont("tests/fonts/Roboto-Regular_1.ttf")
font.size = 36
let image = newImage(800, 800)
image.fill(rgba(255, 255, 255, 255))
image.fillText(
font,
"TopLeft",
rgba(0, 0, 0, 255),
bounds = image.wh,
hAlign = haLeft,
vAlign = vaTop
)
image.fillText(
font,
"TopCenter",
rgba(0, 0, 0, 255),
bounds = image.wh,
hAlign = haCenter,
vAlign = vaTop
)
image.fillText(
font,
"TopRight",
rgba(0, 0, 0, 255),
bounds = image.wh,
hAlign = haRight,
vAlign = vaTop
)
image.fillText(
font,
"MiddleLeft",
rgba(0, 0, 0, 255),
bounds = image.wh,
hAlign = haLeft,
vAlign = vaMiddle
)
image.fillText(
font,
"MiddleCenter",
rgba(0, 0, 0, 255),
bounds = image.wh,
hAlign = haCenter,
vAlign = vaMiddle
)
image.fillText(
font,
"MiddleRight",
rgba(0, 0, 0, 255),
bounds = image.wh,
hAlign = haRight,
vAlign = vaMiddle
)
image.fillText(
font,
"BottomLeft",
rgba(0, 0, 0, 255),
bounds = image.wh,
hAlign = haLeft,
vAlign = vaBottom
)
image.fillText(
font,
"BottomCenter",
rgba(0, 0, 0, 255),
bounds = image.wh,
hAlign = haCenter,
vAlign = vaBottom
)
image.fillText(
font,
"BottomRight",
rgba(0, 0, 0, 255),
bounds = image.wh,
hAlign = haRight,
vAlign = vaBottom
)
doDiff(image, "alignments")