From f969a04a0325746bbd79869247a3b5e27b0ecf12 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Sat, 8 May 2021 16:18:22 -0500 Subject: [PATCH] move textCase, kerning flag --- src/pixie.nim | 52 +++++++------------------------------------- src/pixie/fonts.nim | 19 ++++++++-------- tests/test_fonts.nim | 32 +++++++++++++-------------- 3 files changed, 33 insertions(+), 70 deletions(-) diff --git a/src/pixie.nim b/src/pixie.nim index d47afbb..0468ff5 100644 --- a/src/pixie.nim +++ b/src/pixie.nim @@ -334,27 +334,18 @@ proc fillText*( transform: Vec2 | Mat3 = vec2(0, 0), bounds = vec2(0, 0), hAlign = haLeft, - vAlign = vaTop, - textCase = tcNormal, - wrap = true, - kerning = true + vAlign = vaTop ) = ## Typesets and fills the text. Optional parameters: ## transform: translation or matrix to apply ## 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 let arrangement = font.typeset( text, bounds, hAlign, - vAlign, - textCase, - wrap, - kerning + vAlign ) for i in 0 ..< arrangement.runes.len: image.fillPath(arrangement.getPath(i), color, transform) @@ -366,27 +357,18 @@ proc fillText*( transform: Vec2 | Mat3 = vec2(0, 0), bounds = vec2(0, 0), hAlign = haLeft, - vAlign = vaTop, - textCase = tcNormal, - wrap = true, - kerning = true + vAlign = vaTop ) = ## Typesets and fills the text. Optional parameters: ## transform: translation or matrix to apply ## 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 let arrangement = font.typeset( text, bounds, hAlign, - vAlign, - textCase, - wrap, - kerning + vAlign ) for i in 0 ..< arrangement.runes.len: mask.fillPath(arrangement.getPath(i), transform) @@ -400,27 +382,18 @@ proc strokeText*( strokeWidth = 1.0, bounds = vec2(0, 0), hAlign = haLeft, - vAlign = vaTop, - textCase = tcNormal, - wrap = true, - kerning = true + vAlign = vaTop ) = ## Typesets and strokes the text. Optional parameters: ## transform: translation or matrix to apply ## 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 let arrangement = font.typeset( text, bounds, hAlign, - vAlign, - textCase, - wrap, - kerning + vAlign ) for i in 0 ..< arrangement.runes.len: image.strokePath(arrangement.getPath(i), color, transform, strokeWidth) @@ -433,27 +406,18 @@ proc strokeText*( strokeWidth = 1.0, bounds = vec2(0, 0), hAlign = haLeft, - vAlign = vaTop, - textCase = tcNormal, - wrap = true, - kerning = true + vAlign = vaTop ) = ## Typesets and strokes the text. Optional parameters: ## transform: translation or matrix to apply ## 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 let arrangement = font.typeset( text, bounds, hAlign, - vAlign, - textCase, - wrap, - kerning + vAlign ) 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 cde4c3d..9192167 100644 --- a/src/pixie/fonts.nim +++ b/src/pixie/fonts.nim @@ -15,6 +15,8 @@ type typeface*: Typeface size*: float32 ## Font size in pixels. lineHeight*: float32 ## The line height in pixels or AutoLineHeight for the font's default line height. + textCase*: TextCase + noKerningAdjustments*: bool ## Optionally disable kerning pair adjustments Arrangement* = ref object font*: Font @@ -122,9 +124,7 @@ proc typeset*( bounds = vec2(0, 0), hAlign = haLeft, vAlign = vaTop, - textCase = tcNormal, - wrap = true, - kerning = true + wrap = true ): Arrangement = ## Lays out the character glyphs and returns the arrangement. ## Optional parameters: @@ -151,7 +151,7 @@ proc typeset*( # No runes to typeset, early return return - result.runes.convertTextCase(textCase) + result.runes.convertTextCase(font.textCase) result.positions.setLen(result.runes.len) result.selectionRects.setLen(result.runes.len) @@ -161,10 +161,8 @@ proc typeset*( else: font.defaultLineHeight - proc advance( - font: Font, runes: seq[Rune], i: int, kerning: bool - ): float32 {.inline.} = - if kerning and i + 1 < runes.len: + proc advance(font: Font, runes: seq[Rune], i: int): float32 {.inline.} = + if not font.noKerningAdjustments and i + 1 < runes.len: result += font.typeface.getKerningAdjustment(runes[i], runes[i + 1]) result += font.typeface.getAdvance(runes[i]) result *= font.scale @@ -193,7 +191,7 @@ proc typeset*( if rune.canWrap(): prevCanWrap = i - let advance = advance(font, result.runes, i, kerning) + let advance = advance(font, result.runes, i) if wrap and rune != SP and bounds.x > 0 and at.x + advance > bounds.x: # Wrap to new line at.x = 0 @@ -203,7 +201,7 @@ proc typeset*( if prevCanWrap > 0 and prevCanWrap != i: for j in prevCanWrap + 1 ..< i: result.positions[j] = at - at.x += advance(font, result.runes, j, kerning) + at.x += advance(font, result.runes, j) result.positions[i] = at result.selectionRects[i] = rect(at.x, at.y - initialY, advance, lineHeight) @@ -272,6 +270,7 @@ proc getPath*(arrangement: Arrangement, index: int): Path = ) proc computeBounds*(font: Font, text: string): Vec2 = + ## Computes the width and height of the text in pixels. let arrangement = font.typeset(text) if arrangement.runes.len > 0: for rect in arrangement.selectionRects: diff --git a/tests/test_fonts.nim b/tests/test_fonts.nim index 9d551f8..8d5681c 100644 --- a/tests/test_fonts.nim +++ b/tests/test_fonts.nim @@ -218,6 +218,7 @@ block: block: var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 16 + font.noKerningAdjustments = true let image = newImage(1000, 150) @@ -227,8 +228,7 @@ block: font, text, rgba(0, 0, 0, 255), - bounds = image.wh, - kerning = false + bounds = image.wh ) let name = if i > 0: &"paragraph1_nokern_{i + 1}" else: "paragraph1_nokern" @@ -255,6 +255,7 @@ block: block: var font = readFont("tests/fonts/Ubuntu-Regular_1.ttf") font.size = 16 + font.noKerningAdjustments = true let image = newImage(1000, 150) @@ -264,8 +265,7 @@ block: font, text, rgba(0, 0, 0, 255), - bounds = image.wh, - kerning = false + bounds = image.wh ) let name = if i > 0: &"paragraph2_nokern_{i + 1}" else: "paragraph2_nokern" @@ -292,6 +292,7 @@ block: block: var font = readFont("tests/fonts/IBMPlexSans-Regular_2.ttf") font.size = 16 + font.noKerningAdjustments = true let image = newImage(1000, 150) @@ -301,8 +302,7 @@ block: font, text, rgba(0, 0, 0, 255), - bounds = image.wh, - kerning = false + bounds = image.wh ) let name = if i > 0: &"paragraph3_nokern_{i + 1}" else: "paragraph3_nokern" @@ -329,6 +329,7 @@ block: block: var font = readFont("tests/fonts/NotoSans-Regular_4.ttf") font.size = 16 + font.noKerningAdjustments = true let image = newImage(1000, 150) @@ -338,8 +339,7 @@ block: font, text, rgba(0, 0, 0, 255), - bounds = image.wh, - kerning = false + bounds = image.wh ) let name = if i > 0: &"paragraph4_nokern_{i + 1}" else: "paragraph4_nokern" @@ -366,6 +366,7 @@ block: block: var font = readFont("tests/fonts/Pacifico-Regular_4.ttf") font.size = 16 + font.noKerningAdjustments = true let image = newImage(1000, 150) @@ -375,8 +376,7 @@ block: font, text, rgba(0, 0, 0, 255), - bounds = image.wh, - kerning = false + bounds = image.wh ) let name = if i > 0: &"paragraph5_nokern_{i + 1}" else: "paragraph5_nokern" @@ -400,6 +400,7 @@ block: block: var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 200 + font.noKerningAdjustments = true let image = newImage(2800, 400) image.fill(rgba(255, 255, 255, 255)) @@ -407,8 +408,7 @@ block: font, "Shehadcometotheconclusion", rgba(0, 0, 0, 255), - bounds = image.wh, - kerning = false + bounds = image.wh ) doDiff(image, "huge1_nokern") @@ -431,6 +431,7 @@ block: block: var font = readFont("tests/fonts/Ubuntu-Regular_1.ttf") font.size = 200 + font.noKerningAdjustments = true let image = newImage(2800, 400) image.fill(rgba(255, 255, 255, 255)) @@ -438,8 +439,7 @@ block: font, "Shehadcometotheconclusion", rgba(0, 0, 0, 255), - bounds = image.wh, - kerning = false + bounds = image.wh ) doDiff(image, "huge2_nokern") @@ -462,6 +462,7 @@ block: block: var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 200 + font.noKerningAdjustments = true let image = newImage(2800, 400) image.fill(rgba(255, 255, 255, 255)) @@ -469,8 +470,7 @@ block: font, "Wrapping text to the next line", rgba(0, 0, 0, 255), - bounds = image.wh, - kerning = false + bounds = image.wh ) doDiff(image, "huge3_nokern")