Merge pull request #386 from guzba/master

4.0.1 fix for custom line-height on font
This commit is contained in:
treeform 2022-02-22 18:02:11 -08:00 committed by GitHub
commit 00d93e6921
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 84 additions and 21 deletions

View file

@ -1,4 +1,4 @@
version = "4.0.0"
version = "4.0.1"
author = "Andre von Houck and Ryan Oldenburg"
description = "Full-featured 2d graphics library for Nim."
license = "MIT"

View file

@ -82,6 +82,7 @@ proc lineGap*(typeface: Typeface): float32 {.raises: [].} =
proc lineHeight*(typeface: Typeface): float32 {.inline, raises: [].} =
## The default line height in font units.
# The descent is negative number, so this is really ascent + descent + lineGap.
typeface.ascent - typeface.descent + typeface.lineGap
proc underlinePosition(typeface: Typeface): float32 =
@ -186,6 +187,18 @@ proc defaultLineHeight*(font: Font): float32 {.inline, raises: [].} =
font.typeface.ascent - font.typeface.descent + font.typeface.lineGap
round(fontUnits * font.scale)
proc lineGap(font: Font): float32 =
## The line gap in font units for the current font size and line-height.
let lineHeight =
if font.lineHeight >= 0:
font.lineHeight
else:
font.defaultLineHeight
if lineHeight == font.defaultLineHeight:
font.typeface.lineGap
else:
(lineHeight / font.scale) - font.typeface.ascent + font.typeface.descent
proc paint*(font: Font): Paint {.inline, raises: [].} =
font.paints[0]
@ -356,20 +369,10 @@ proc typeset*(
for spanIndex, (start, stop) in result.spans:
let
font = result.fonts[spanIndex]
lineHeight =
if font.lineHeight >= 0:
font.lineHeight
else:
font.defaultLineHeight
var fontUnitInitialY = font.typeface.ascent + font.typeface.lineGap / 2
if lineHeight != font.defaultLineHeight:
fontUnitInitialY += (
(lineHeight / font.scale) - font.typeface.lineHeight
) / 2
fontUnitInitialY = font.typeface.ascent + font.lineGap / 2
maxInitialY = max(maxInitialY, round(fontUnitInitialY * font.scale))
for runeIndex in start .. stop:
if runeIndex == result.lines[0][1]:
break outer
if stop >= result.lines[0][1]:
break outer
maxInitialY
var lineHeights = newSeq[float32](result.lines.len)
@ -385,6 +388,8 @@ proc typeset*(
font.defaultLineHeight
lineHeights[line] = max(lineHeights[line], fontLineHeight)
for runeIndex in start .. stop:
# This span could be many lines. This check can be made faster by
# hopping based on line endings instead of checking each index.
if line + 1 < result.lines.len and
runeIndex == result.lines[line + 1][0]:
inc line
@ -401,8 +406,8 @@ proc typeset*(
let
font = result.fonts[spanIndex]
lineHeight =
if font.lineheight >= 0:
font.lineheight
if font.lineHeight >= 0:
font.lineHeight
else:
font.defaultLineHeight
for runeIndex in start .. stop:
@ -411,8 +416,8 @@ proc typeset*(
inc line
baseline += lineHeights[line]
result.positions[runeIndex].y = baseline
result.selectionRects[runeIndex].y =
baseline - round(font.typeface.ascent * font.scale)
result.selectionRects[runeIndex].y = baseline -
round((font.typeface.ascent + font.lineGap / 2) * font.scale)
result.selectionRects[runeIndex].h = lineHeight
if vAlign != TopAlign:

BIN
tests/fonts/Inter-Bold.ttf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -1101,3 +1101,61 @@ block:
image.fillText(font, "This[]Advance!")
doDiff(image, "tofu_advance")
block:
let image = newImage(200, 200)
image.fill(color(1, 1, 1, 1))
let paint = newPaint(SolidPaint)
paint.color = color(1, 0, 0, 1)
let ctx = newContext(image)
ctx.lineWidth = 1
ctx.strokeStyle = paint
ctx.strokeRect(0, 60, 200, 80)
let text = "AbCd\naBcD"
let font = pixie.read_font("tests/fonts/Inter-Bold.ttf")
font.size = 40
font.line_height = 27
let arrangement1 = font.typeset(
text,
vec2(200, 80),
CenterAlign,
TopAlign
)
# let p1 = newPath()
# p1.rect(arrangement1.selectionRects[0])
# image.fillpath(p1, rgba(196, 196, 196, 255), translate(vec2(0, 266)))
font.paint.color = color(1, 0, 0, 1)
image.fillText(arrangement1, translate(vec2(0, 60)))
let arrangement2 = font.typeset(
text,
vec2(200, 80),
CenterAlign,
MiddleAlign
)
# let p2 = newPath()
# p2.rect(arrangement2.selectionRects[0])
# image.fillpath(p2, rgba(196, 196, 196, 255), translate(vec2(0, 266)))
font.paint.color = color(0, 1, 0, 1)
image.fillText(arrangement2, translate(vec2(0, 60)))
font.paint.color = color(0, 0, 1, 1)
image.fillText(
font,
text,
bounds = vec2(200, 80),
hAlign = CenterAlign,
vAlign = BottomAlign,
transform = translate(vec2(0, 60))
)
doDiff(image, "customlineheight")

View file

@ -14,7 +14,7 @@ block:
heartShape,
rgba(255, 0, 0, 255)
)
image.writeFile("tests/paths/SolidPaint.png")
image.writeFile("tests/paths/paintSolid.png")
block:
let paint = newPaint(ImagePaint)
@ -23,7 +23,7 @@ block:
let image = newImage(100, 100)
image.fillPath(heartShape, paint)
image.writeFile("tests/paths/ImagePaint.png")
image.writeFile("tests/paths/paintImage.png")
block:
let paint = newPaint(ImagePaint)
@ -42,7 +42,7 @@ block:
let image = newImage(100, 100)
image.fillPath(heartShape, paint)
image.writeFile("tests/paths/TiledImagePaint.png")
image.writeFile("tests/paths/paintImageTiled.png")
block:
let paint = newPaint(TiledImagePaint)