From e931bd03195afb749d0ea65fa5787ed2df082253 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg <guzba8@gmail.com> Date: Fri, 7 May 2021 19:28:49 -0500 Subject: [PATCH] computeBounds, no iterator --- src/pixie.nim | 36 ++++++++++++++++++++---------------- src/pixie/fonts.nim | 17 ++++++++++------- tests/test_fonts.nim | 7 +++++++ 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/pixie.nim b/src/pixie.nim index b8f86ac..d47afbb 100644 --- a/src/pixie.nim +++ b/src/pixie.nim @@ -341,13 +341,13 @@ proc fillText*( ) = ## Typesets and fills the text. Optional parameters: ## transform: translation or matrix to apply - ## bounds: width determines wrapping and halign, height for valign + ## bounds: width determines wrapping and hAlign, height for vAlign ## hAlign: horizontal alignment of the text ## vAlign: vertical alignment of the text ## textCase: text character case ## wrap: enable/disable text wrapping ## kerning: enable/disable kerning adjustments to letter spacing - for path in font.typeset( + let arrangement = font.typeset( text, bounds, hAlign, @@ -355,8 +355,9 @@ proc fillText*( textCase, wrap, kerning - ).paths: - image.fillPath(path, color, transform) + ) + for i in 0 ..< arrangement.runes.len: + image.fillPath(arrangement.getPath(i), color, transform) proc fillText*( mask: Mask, @@ -372,13 +373,13 @@ proc fillText*( ) = ## Typesets and fills the text. Optional parameters: ## transform: translation or matrix to apply - ## bounds: width determines wrapping and halign, height for valign + ## bounds: width determines wrapping and hAlign, height for vAlign ## hAlign: horizontal alignment of the text ## vAlign: vertical alignment of the text ## textCase: text character case ## wrap: enable/disable text wrapping ## kerning: enable/disable kerning adjustments to letter spacing - for path in font.typeset( + let arrangement = font.typeset( text, bounds, hAlign, @@ -386,8 +387,9 @@ proc fillText*( textCase, wrap, kerning - ).paths: - mask.fillPath(path, transform) + ) + for i in 0 ..< arrangement.runes.len: + mask.fillPath(arrangement.getPath(i), transform) proc strokeText*( image: Image, @@ -405,13 +407,13 @@ proc strokeText*( ) = ## Typesets and strokes the text. Optional parameters: ## transform: translation or matrix to apply - ## bounds: width determines wrapping and halign, height for valign + ## bounds: width determines wrapping and hAlign, height for vAlign ## hAlign: horizontal alignment of the text ## vAlign: vertical alignment of the text ## textCase: text character case ## wrap: enable/disable text wrapping ## kerning: enable/disable kerning adjustments to letter spacing - for path in font.typeset( + let arrangement = font.typeset( text, bounds, hAlign, @@ -419,8 +421,9 @@ proc strokeText*( textCase, wrap, kerning - ).paths: - image.strokePath(path, color, transform, strokeWidth) + ) + for i in 0 ..< arrangement.runes.len: + image.strokePath(arrangement.getPath(i), color, transform, strokeWidth) proc strokeText*( mask: Mask, @@ -437,13 +440,13 @@ proc strokeText*( ) = ## Typesets and strokes the text. Optional parameters: ## transform: translation or matrix to apply - ## bounds: width determines wrapping and halign, height for valign + ## bounds: width determines wrapping and hAlign, height for vAlign ## hAlign: horizontal alignment of the text ## vAlign: vertical alignment of the text ## textCase: text character case ## wrap: enable/disable text wrapping ## kerning: enable/disable kerning adjustments to letter spacing - for path in font.typeset( + let arrangement = font.typeset( text, bounds, hAlign, @@ -451,5 +454,6 @@ proc strokeText*( textCase, wrap, kerning - ).paths: - mask.strokePath(path, transform, strokeWidth) + ) + for i in 0 ..< arrangement.runes.len: + mask.strokePath(arrangement.getPath(i), transform, strokeWidth) diff --git a/src/pixie/fonts.nim b/src/pixie/fonts.nim index 423cbf8..cde4c3d 100644 --- a/src/pixie/fonts.nim +++ b/src/pixie/fonts.nim @@ -128,7 +128,7 @@ proc typeset*( ): Arrangement = ## Lays out the character glyphs and returns the arrangement. ## Optional parameters: - ## bounds: width determines wrapping and halign, height for valign + ## bounds: width determines wrapping and hAlign, height for vAlign ## hAlign: horizontal alignment of the text ## vAlign: vertical alignment of the text ## textCase: text character case @@ -209,7 +209,7 @@ proc typeset*( result.selectionRects[i] = rect(at.x, at.y - initialY, advance, lineHeight) at.x += advance - if bounds.x > 0 and hAlign != haLeft: + if hAlign != haLeft: # Since horizontal alignment adjustments are different for each line, # find the start and stop of each line of text. var @@ -244,7 +244,7 @@ proc typeset*( result.positions[i].x += xAdjustment result.selectionRects[i].x += xAdjustment - if bounds.y > 0: + if vAlign != vaTop: let finalSelectionRect = result.selectionRects[^1] furthestY = finalSelectionRect.y + finalSelectionRect.h @@ -271,10 +271,13 @@ proc getPath*(arrangement: Arrangement, index: int): Path = scale(vec2(arrangement.font.scale)) ) -iterator paths*(arrangement: Arrangement): Path = - ## Iterates over the paths for the arrangement. - for i in 0 ..< arrangement.runes.len: - yield arrangement.getPath(i) +proc computeBounds*(font: Font, text: string): Vec2 = + let arrangement = font.typeset(text) + if arrangement.runes.len > 0: + for rect in arrangement.selectionRects: + result.x = max(result.x, rect.x + rect.w) + let finalRect = arrangement.selectionRects[^1] + result.y = finalRect.y + finalRect.h proc parseOtf*(buf: string): Font = result.typeface = Typeface() diff --git a/tests/test_fonts.nim b/tests/test_fonts.nim index 0cf985e..9d551f8 100644 --- a/tests/test_fonts.nim +++ b/tests/test_fonts.nim @@ -8,6 +8,13 @@ proc doDiff(rendered: Image, name: string) = echo &"{name} score: {diffScore}" diffImage.writeFile(&"tests/fonts/diffs/{name}.png") +block: + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") + font.size = 24 + + let bounds = font.computeBounds("Word") + doAssert bounds == vec2(56.05078125, 28) + block: var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 64