move textCase, kerning flag
This commit is contained in:
parent
e931bd0319
commit
f969a04a03
3 changed files with 33 additions and 70 deletions
|
@ -334,27 +334,18 @@ proc fillText*(
|
||||||
transform: Vec2 | Mat3 = vec2(0, 0),
|
transform: Vec2 | Mat3 = vec2(0, 0),
|
||||||
bounds = vec2(0, 0),
|
bounds = vec2(0, 0),
|
||||||
hAlign = haLeft,
|
hAlign = haLeft,
|
||||||
vAlign = vaTop,
|
vAlign = vaTop
|
||||||
textCase = tcNormal,
|
|
||||||
wrap = true,
|
|
||||||
kerning = true
|
|
||||||
) =
|
) =
|
||||||
## Typesets and fills the text. Optional parameters:
|
## Typesets and fills the text. Optional parameters:
|
||||||
## transform: translation or matrix to apply
|
## 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
|
## hAlign: horizontal alignment of the text
|
||||||
## vAlign: vertical 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(
|
let arrangement = font.typeset(
|
||||||
text,
|
text,
|
||||||
bounds,
|
bounds,
|
||||||
hAlign,
|
hAlign,
|
||||||
vAlign,
|
vAlign
|
||||||
textCase,
|
|
||||||
wrap,
|
|
||||||
kerning
|
|
||||||
)
|
)
|
||||||
for i in 0 ..< arrangement.runes.len:
|
for i in 0 ..< arrangement.runes.len:
|
||||||
image.fillPath(arrangement.getPath(i), color, transform)
|
image.fillPath(arrangement.getPath(i), color, transform)
|
||||||
|
@ -366,27 +357,18 @@ proc fillText*(
|
||||||
transform: Vec2 | Mat3 = vec2(0, 0),
|
transform: Vec2 | Mat3 = vec2(0, 0),
|
||||||
bounds = vec2(0, 0),
|
bounds = vec2(0, 0),
|
||||||
hAlign = haLeft,
|
hAlign = haLeft,
|
||||||
vAlign = vaTop,
|
vAlign = vaTop
|
||||||
textCase = tcNormal,
|
|
||||||
wrap = true,
|
|
||||||
kerning = true
|
|
||||||
) =
|
) =
|
||||||
## Typesets and fills the text. Optional parameters:
|
## Typesets and fills the text. Optional parameters:
|
||||||
## transform: translation or matrix to apply
|
## 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
|
## hAlign: horizontal alignment of the text
|
||||||
## vAlign: vertical 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(
|
let arrangement = font.typeset(
|
||||||
text,
|
text,
|
||||||
bounds,
|
bounds,
|
||||||
hAlign,
|
hAlign,
|
||||||
vAlign,
|
vAlign
|
||||||
textCase,
|
|
||||||
wrap,
|
|
||||||
kerning
|
|
||||||
)
|
)
|
||||||
for i in 0 ..< arrangement.runes.len:
|
for i in 0 ..< arrangement.runes.len:
|
||||||
mask.fillPath(arrangement.getPath(i), transform)
|
mask.fillPath(arrangement.getPath(i), transform)
|
||||||
|
@ -400,27 +382,18 @@ proc strokeText*(
|
||||||
strokeWidth = 1.0,
|
strokeWidth = 1.0,
|
||||||
bounds = vec2(0, 0),
|
bounds = vec2(0, 0),
|
||||||
hAlign = haLeft,
|
hAlign = haLeft,
|
||||||
vAlign = vaTop,
|
vAlign = vaTop
|
||||||
textCase = tcNormal,
|
|
||||||
wrap = true,
|
|
||||||
kerning = true
|
|
||||||
) =
|
) =
|
||||||
## Typesets and strokes the text. Optional parameters:
|
## Typesets and strokes the text. Optional parameters:
|
||||||
## transform: translation or matrix to apply
|
## 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
|
## hAlign: horizontal alignment of the text
|
||||||
## vAlign: vertical 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(
|
let arrangement = font.typeset(
|
||||||
text,
|
text,
|
||||||
bounds,
|
bounds,
|
||||||
hAlign,
|
hAlign,
|
||||||
vAlign,
|
vAlign
|
||||||
textCase,
|
|
||||||
wrap,
|
|
||||||
kerning
|
|
||||||
)
|
)
|
||||||
for i in 0 ..< arrangement.runes.len:
|
for i in 0 ..< arrangement.runes.len:
|
||||||
image.strokePath(arrangement.getPath(i), color, transform, strokeWidth)
|
image.strokePath(arrangement.getPath(i), color, transform, strokeWidth)
|
||||||
|
@ -433,27 +406,18 @@ proc strokeText*(
|
||||||
strokeWidth = 1.0,
|
strokeWidth = 1.0,
|
||||||
bounds = vec2(0, 0),
|
bounds = vec2(0, 0),
|
||||||
hAlign = haLeft,
|
hAlign = haLeft,
|
||||||
vAlign = vaTop,
|
vAlign = vaTop
|
||||||
textCase = tcNormal,
|
|
||||||
wrap = true,
|
|
||||||
kerning = true
|
|
||||||
) =
|
) =
|
||||||
## Typesets and strokes the text. Optional parameters:
|
## Typesets and strokes the text. Optional parameters:
|
||||||
## transform: translation or matrix to apply
|
## 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
|
## hAlign: horizontal alignment of the text
|
||||||
## vAlign: vertical 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(
|
let arrangement = font.typeset(
|
||||||
text,
|
text,
|
||||||
bounds,
|
bounds,
|
||||||
hAlign,
|
hAlign,
|
||||||
vAlign,
|
vAlign
|
||||||
textCase,
|
|
||||||
wrap,
|
|
||||||
kerning
|
|
||||||
)
|
)
|
||||||
for i in 0 ..< arrangement.runes.len:
|
for i in 0 ..< arrangement.runes.len:
|
||||||
mask.strokePath(arrangement.getPath(i), transform, strokeWidth)
|
mask.strokePath(arrangement.getPath(i), transform, strokeWidth)
|
||||||
|
|
|
@ -15,6 +15,8 @@ type
|
||||||
typeface*: Typeface
|
typeface*: Typeface
|
||||||
size*: float32 ## Font size in pixels.
|
size*: float32 ## Font size in pixels.
|
||||||
lineHeight*: float32 ## The line height in pixels or AutoLineHeight for the font's default line height.
|
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
|
Arrangement* = ref object
|
||||||
font*: Font
|
font*: Font
|
||||||
|
@ -122,9 +124,7 @@ proc typeset*(
|
||||||
bounds = vec2(0, 0),
|
bounds = vec2(0, 0),
|
||||||
hAlign = haLeft,
|
hAlign = haLeft,
|
||||||
vAlign = vaTop,
|
vAlign = vaTop,
|
||||||
textCase = tcNormal,
|
wrap = true
|
||||||
wrap = true,
|
|
||||||
kerning = true
|
|
||||||
): Arrangement =
|
): Arrangement =
|
||||||
## Lays out the character glyphs and returns the arrangement.
|
## Lays out the character glyphs and returns the arrangement.
|
||||||
## Optional parameters:
|
## Optional parameters:
|
||||||
|
@ -151,7 +151,7 @@ proc typeset*(
|
||||||
# No runes to typeset, early return
|
# No runes to typeset, early return
|
||||||
return
|
return
|
||||||
|
|
||||||
result.runes.convertTextCase(textCase)
|
result.runes.convertTextCase(font.textCase)
|
||||||
result.positions.setLen(result.runes.len)
|
result.positions.setLen(result.runes.len)
|
||||||
result.selectionRects.setLen(result.runes.len)
|
result.selectionRects.setLen(result.runes.len)
|
||||||
|
|
||||||
|
@ -161,10 +161,8 @@ proc typeset*(
|
||||||
else:
|
else:
|
||||||
font.defaultLineHeight
|
font.defaultLineHeight
|
||||||
|
|
||||||
proc advance(
|
proc advance(font: Font, runes: seq[Rune], i: int): float32 {.inline.} =
|
||||||
font: Font, runes: seq[Rune], i: int, kerning: bool
|
if not font.noKerningAdjustments and i + 1 < runes.len:
|
||||||
): float32 {.inline.} =
|
|
||||||
if kerning and i + 1 < runes.len:
|
|
||||||
result += font.typeface.getKerningAdjustment(runes[i], runes[i + 1])
|
result += font.typeface.getKerningAdjustment(runes[i], runes[i + 1])
|
||||||
result += font.typeface.getAdvance(runes[i])
|
result += font.typeface.getAdvance(runes[i])
|
||||||
result *= font.scale
|
result *= font.scale
|
||||||
|
@ -193,7 +191,7 @@ proc typeset*(
|
||||||
if rune.canWrap():
|
if rune.canWrap():
|
||||||
prevCanWrap = i
|
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:
|
if wrap and rune != SP and bounds.x > 0 and at.x + advance > bounds.x:
|
||||||
# Wrap to new line
|
# Wrap to new line
|
||||||
at.x = 0
|
at.x = 0
|
||||||
|
@ -203,7 +201,7 @@ proc typeset*(
|
||||||
if prevCanWrap > 0 and prevCanWrap != i:
|
if prevCanWrap > 0 and prevCanWrap != i:
|
||||||
for j in prevCanWrap + 1 ..< i:
|
for j in prevCanWrap + 1 ..< i:
|
||||||
result.positions[j] = at
|
result.positions[j] = at
|
||||||
at.x += advance(font, result.runes, j, kerning)
|
at.x += advance(font, result.runes, j)
|
||||||
|
|
||||||
result.positions[i] = at
|
result.positions[i] = at
|
||||||
result.selectionRects[i] = rect(at.x, at.y - initialY, advance, lineHeight)
|
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 =
|
proc computeBounds*(font: Font, text: string): Vec2 =
|
||||||
|
## Computes the width and height of the text in pixels.
|
||||||
let arrangement = font.typeset(text)
|
let arrangement = font.typeset(text)
|
||||||
if arrangement.runes.len > 0:
|
if arrangement.runes.len > 0:
|
||||||
for rect in arrangement.selectionRects:
|
for rect in arrangement.selectionRects:
|
||||||
|
|
|
@ -218,6 +218,7 @@ block:
|
||||||
block:
|
block:
|
||||||
var font = readFont("tests/fonts/Roboto-Regular_1.ttf")
|
var font = readFont("tests/fonts/Roboto-Regular_1.ttf")
|
||||||
font.size = 16
|
font.size = 16
|
||||||
|
font.noKerningAdjustments = true
|
||||||
|
|
||||||
let image = newImage(1000, 150)
|
let image = newImage(1000, 150)
|
||||||
|
|
||||||
|
@ -227,8 +228,7 @@ block:
|
||||||
font,
|
font,
|
||||||
text,
|
text,
|
||||||
rgba(0, 0, 0, 255),
|
rgba(0, 0, 0, 255),
|
||||||
bounds = image.wh,
|
bounds = image.wh
|
||||||
kerning = false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
let name = if i > 0: &"paragraph1_nokern_{i + 1}" else: "paragraph1_nokern"
|
let name = if i > 0: &"paragraph1_nokern_{i + 1}" else: "paragraph1_nokern"
|
||||||
|
@ -255,6 +255,7 @@ block:
|
||||||
block:
|
block:
|
||||||
var font = readFont("tests/fonts/Ubuntu-Regular_1.ttf")
|
var font = readFont("tests/fonts/Ubuntu-Regular_1.ttf")
|
||||||
font.size = 16
|
font.size = 16
|
||||||
|
font.noKerningAdjustments = true
|
||||||
|
|
||||||
let image = newImage(1000, 150)
|
let image = newImage(1000, 150)
|
||||||
|
|
||||||
|
@ -264,8 +265,7 @@ block:
|
||||||
font,
|
font,
|
||||||
text,
|
text,
|
||||||
rgba(0, 0, 0, 255),
|
rgba(0, 0, 0, 255),
|
||||||
bounds = image.wh,
|
bounds = image.wh
|
||||||
kerning = false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
let name = if i > 0: &"paragraph2_nokern_{i + 1}" else: "paragraph2_nokern"
|
let name = if i > 0: &"paragraph2_nokern_{i + 1}" else: "paragraph2_nokern"
|
||||||
|
@ -292,6 +292,7 @@ block:
|
||||||
block:
|
block:
|
||||||
var font = readFont("tests/fonts/IBMPlexSans-Regular_2.ttf")
|
var font = readFont("tests/fonts/IBMPlexSans-Regular_2.ttf")
|
||||||
font.size = 16
|
font.size = 16
|
||||||
|
font.noKerningAdjustments = true
|
||||||
|
|
||||||
let image = newImage(1000, 150)
|
let image = newImage(1000, 150)
|
||||||
|
|
||||||
|
@ -301,8 +302,7 @@ block:
|
||||||
font,
|
font,
|
||||||
text,
|
text,
|
||||||
rgba(0, 0, 0, 255),
|
rgba(0, 0, 0, 255),
|
||||||
bounds = image.wh,
|
bounds = image.wh
|
||||||
kerning = false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
let name = if i > 0: &"paragraph3_nokern_{i + 1}" else: "paragraph3_nokern"
|
let name = if i > 0: &"paragraph3_nokern_{i + 1}" else: "paragraph3_nokern"
|
||||||
|
@ -329,6 +329,7 @@ block:
|
||||||
block:
|
block:
|
||||||
var font = readFont("tests/fonts/NotoSans-Regular_4.ttf")
|
var font = readFont("tests/fonts/NotoSans-Regular_4.ttf")
|
||||||
font.size = 16
|
font.size = 16
|
||||||
|
font.noKerningAdjustments = true
|
||||||
|
|
||||||
let image = newImage(1000, 150)
|
let image = newImage(1000, 150)
|
||||||
|
|
||||||
|
@ -338,8 +339,7 @@ block:
|
||||||
font,
|
font,
|
||||||
text,
|
text,
|
||||||
rgba(0, 0, 0, 255),
|
rgba(0, 0, 0, 255),
|
||||||
bounds = image.wh,
|
bounds = image.wh
|
||||||
kerning = false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
let name = if i > 0: &"paragraph4_nokern_{i + 1}" else: "paragraph4_nokern"
|
let name = if i > 0: &"paragraph4_nokern_{i + 1}" else: "paragraph4_nokern"
|
||||||
|
@ -366,6 +366,7 @@ block:
|
||||||
block:
|
block:
|
||||||
var font = readFont("tests/fonts/Pacifico-Regular_4.ttf")
|
var font = readFont("tests/fonts/Pacifico-Regular_4.ttf")
|
||||||
font.size = 16
|
font.size = 16
|
||||||
|
font.noKerningAdjustments = true
|
||||||
|
|
||||||
let image = newImage(1000, 150)
|
let image = newImage(1000, 150)
|
||||||
|
|
||||||
|
@ -375,8 +376,7 @@ block:
|
||||||
font,
|
font,
|
||||||
text,
|
text,
|
||||||
rgba(0, 0, 0, 255),
|
rgba(0, 0, 0, 255),
|
||||||
bounds = image.wh,
|
bounds = image.wh
|
||||||
kerning = false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
let name = if i > 0: &"paragraph5_nokern_{i + 1}" else: "paragraph5_nokern"
|
let name = if i > 0: &"paragraph5_nokern_{i + 1}" else: "paragraph5_nokern"
|
||||||
|
@ -400,6 +400,7 @@ block:
|
||||||
block:
|
block:
|
||||||
var font = readFont("tests/fonts/Roboto-Regular_1.ttf")
|
var font = readFont("tests/fonts/Roboto-Regular_1.ttf")
|
||||||
font.size = 200
|
font.size = 200
|
||||||
|
font.noKerningAdjustments = true
|
||||||
|
|
||||||
let image = newImage(2800, 400)
|
let image = newImage(2800, 400)
|
||||||
image.fill(rgba(255, 255, 255, 255))
|
image.fill(rgba(255, 255, 255, 255))
|
||||||
|
@ -407,8 +408,7 @@ block:
|
||||||
font,
|
font,
|
||||||
"Shehadcometotheconclusion",
|
"Shehadcometotheconclusion",
|
||||||
rgba(0, 0, 0, 255),
|
rgba(0, 0, 0, 255),
|
||||||
bounds = image.wh,
|
bounds = image.wh
|
||||||
kerning = false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
doDiff(image, "huge1_nokern")
|
doDiff(image, "huge1_nokern")
|
||||||
|
@ -431,6 +431,7 @@ block:
|
||||||
block:
|
block:
|
||||||
var font = readFont("tests/fonts/Ubuntu-Regular_1.ttf")
|
var font = readFont("tests/fonts/Ubuntu-Regular_1.ttf")
|
||||||
font.size = 200
|
font.size = 200
|
||||||
|
font.noKerningAdjustments = true
|
||||||
|
|
||||||
let image = newImage(2800, 400)
|
let image = newImage(2800, 400)
|
||||||
image.fill(rgba(255, 255, 255, 255))
|
image.fill(rgba(255, 255, 255, 255))
|
||||||
|
@ -438,8 +439,7 @@ block:
|
||||||
font,
|
font,
|
||||||
"Shehadcometotheconclusion",
|
"Shehadcometotheconclusion",
|
||||||
rgba(0, 0, 0, 255),
|
rgba(0, 0, 0, 255),
|
||||||
bounds = image.wh,
|
bounds = image.wh
|
||||||
kerning = false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
doDiff(image, "huge2_nokern")
|
doDiff(image, "huge2_nokern")
|
||||||
|
@ -462,6 +462,7 @@ block:
|
||||||
block:
|
block:
|
||||||
var font = readFont("tests/fonts/Roboto-Regular_1.ttf")
|
var font = readFont("tests/fonts/Roboto-Regular_1.ttf")
|
||||||
font.size = 200
|
font.size = 200
|
||||||
|
font.noKerningAdjustments = true
|
||||||
|
|
||||||
let image = newImage(2800, 400)
|
let image = newImage(2800, 400)
|
||||||
image.fill(rgba(255, 255, 255, 255))
|
image.fill(rgba(255, 255, 255, 255))
|
||||||
|
@ -469,8 +470,7 @@ block:
|
||||||
font,
|
font,
|
||||||
"Wrapping text to the next line",
|
"Wrapping text to the next line",
|
||||||
rgba(0, 0, 0, 255),
|
rgba(0, 0, 0, 255),
|
||||||
bounds = image.wh,
|
bounds = image.wh
|
||||||
kerning = false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
doDiff(image, "huge3_nokern")
|
doDiff(image, "huge3_nokern")
|
||||||
|
|
Loading…
Reference in a new issue