fix for custom line-heights
|
@ -1,4 +1,4 @@
|
||||||
version = "4.0.0"
|
version = "4.0.1"
|
||||||
author = "Andre von Houck and Ryan Oldenburg"
|
author = "Andre von Houck and Ryan Oldenburg"
|
||||||
description = "Full-featured 2d graphics library for Nim."
|
description = "Full-featured 2d graphics library for Nim."
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
@ -187,6 +187,18 @@ proc defaultLineHeight*(font: Font): float32 {.inline, raises: [].} =
|
||||||
font.typeface.ascent - font.typeface.descent + font.typeface.lineGap
|
font.typeface.ascent - font.typeface.descent + font.typeface.lineGap
|
||||||
round(fontUnits * font.scale)
|
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: [].} =
|
proc paint*(font: Font): Paint {.inline, raises: [].} =
|
||||||
font.paints[0]
|
font.paints[0]
|
||||||
|
|
||||||
|
@ -357,16 +369,7 @@ proc typeset*(
|
||||||
for spanIndex, (start, stop) in result.spans:
|
for spanIndex, (start, stop) in result.spans:
|
||||||
let
|
let
|
||||||
font = result.fonts[spanIndex]
|
font = result.fonts[spanIndex]
|
||||||
lineHeight =
|
fontUnitInitialY = font.typeface.ascent + font.lineGap / 2
|
||||||
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
|
|
||||||
maxInitialY = max(maxInitialY, round(fontUnitInitialY * font.scale))
|
maxInitialY = max(maxInitialY, round(fontUnitInitialY * font.scale))
|
||||||
if stop >= result.lines[0][1]:
|
if stop >= result.lines[0][1]:
|
||||||
break outer
|
break outer
|
||||||
|
@ -413,8 +416,8 @@ proc typeset*(
|
||||||
inc line
|
inc line
|
||||||
baseline += lineHeights[line]
|
baseline += lineHeights[line]
|
||||||
result.positions[runeIndex].y = baseline
|
result.positions[runeIndex].y = baseline
|
||||||
result.selectionRects[runeIndex].y =
|
result.selectionRects[runeIndex].y = baseline -
|
||||||
baseline - round(font.typeface.ascent * font.scale)
|
round((font.typeface.ascent + font.lineGap / 2) * font.scale)
|
||||||
result.selectionRects[runeIndex].h = lineHeight
|
result.selectionRects[runeIndex].h = lineHeight
|
||||||
|
|
||||||
if vAlign != TopAlign:
|
if vAlign != TopAlign:
|
||||||
|
|
BIN
tests/fonts/Inter-Bold.ttf
Normal file
BIN
tests/fonts/diffs/customlineheight.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
BIN
tests/fonts/masters/customlineheight.png
Normal file
After Width: | Height: | Size: 6 KiB |
BIN
tests/fonts/rendered/customlineheight.png
Normal file
After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
@ -1101,3 +1101,61 @@ block:
|
||||||
image.fillText(font, "This[]Advance!")
|
image.fillText(font, "This[]Advance!")
|
||||||
|
|
||||||
doDiff(image, "tofu_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")
|
||||||
|
|
|
@ -14,7 +14,7 @@ block:
|
||||||
heartShape,
|
heartShape,
|
||||||
rgba(255, 0, 0, 255)
|
rgba(255, 0, 0, 255)
|
||||||
)
|
)
|
||||||
image.writeFile("tests/paths/SolidPaint.png")
|
image.writeFile("tests/paths/paintSolid.png")
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let paint = newPaint(ImagePaint)
|
let paint = newPaint(ImagePaint)
|
||||||
|
@ -23,7 +23,7 @@ block:
|
||||||
|
|
||||||
let image = newImage(100, 100)
|
let image = newImage(100, 100)
|
||||||
image.fillPath(heartShape, paint)
|
image.fillPath(heartShape, paint)
|
||||||
image.writeFile("tests/paths/ImagePaint.png")
|
image.writeFile("tests/paths/paintImage.png")
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let paint = newPaint(ImagePaint)
|
let paint = newPaint(ImagePaint)
|
||||||
|
@ -42,7 +42,7 @@ block:
|
||||||
|
|
||||||
let image = newImage(100, 100)
|
let image = newImage(100, 100)
|
||||||
image.fillPath(heartShape, paint)
|
image.fillPath(heartShape, paint)
|
||||||
image.writeFile("tests/paths/TiledImagePaint.png")
|
image.writeFile("tests/paths/paintImageTiled.png")
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let paint = newPaint(TiledImagePaint)
|
let paint = newPaint(TiledImagePaint)
|
||||||
|
|