Merge pull request #280 from treeform/fonts1

Fix strikethough and underline for CFF fonts with winding flag.
This commit is contained in:
treeform 2021-09-07 13:18:31 -07:00 committed by GitHub
commit 163a087366
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 35 additions and 2 deletions

View file

@ -192,6 +192,7 @@ exportRefObject Typeface:
descent
lineGap
lineHeight
hasGlyph
getGlyphPath
getAdvance
getKerningAdjustment

View file

@ -1070,6 +1070,9 @@ proc parseCFFCharstring(cff: CffTable, code: string, glyphIndex: int): Path =
x += stack.pop()
p.moveTo(x, y)
of 23: # vstemhm
parseStems()
of 24: # rcurveline
while stack.len > 2:
let
@ -2084,6 +2087,9 @@ proc parsePostTable(buf: string, offset: int): PostTable =
proc getGlyphId(opentype: OpenType, rune: Rune): uint16 =
result = opentype.cmap.runeToGlyphId.getOrDefault(rune, 0)
proc hasGlyph*(opentype: OpenType, rune: Rune): bool =
rune in opentype.cmap.runeToGlyphId
proc parseGlyfGlyph(opentype: OpenType, glyphId: uint16): Path {.raises: [PixieError].}
proc parseGlyphPath(
@ -2415,6 +2421,12 @@ proc getKerningAdjustment*(
elif opentype.kern != nil:
result = opentype.kern.kerningPairs.getOrDefault(glyphPair, 0)
proc isCCW*(opentype: OpenType): bool {.inline.} =
## Returns the expected winding order of a font.
## Gyph - false - clockwise
## CFF - true - counterclockwise
opentype.cff == nil
proc parseOpenType*(buf: string): OpenType {.raises: [PixieError].} =
result = OpenType()
result.buf = buf

View file

@ -11,6 +11,9 @@ type SvgFont* = ref object
proc getGlyphPath*(svgFont: SvgFont, rune: Rune): Path {.raises: [].} =
svgFont.glyphPaths.getOrDefault(rune, svgFont.missingGlyphPath)
proc hasGlyph*(svgFont: SvgFont, rune: Rune): bool =
rune in svgFont.glyphPaths
proc getAdvance*(svgFont: SvgFont, rune: Rune): float32 {.raises: [].} =
svgFont.advances.getOrDefault(rune, svgFont.missingGlyphAdvance)

View file

@ -92,6 +92,11 @@ proc strikeoutThickness(typeface: Typeface): float32 =
if typeface.opentype != nil:
result = typeface.opentype.os2.yStrikeoutSize.float32
proc isCCW(typeface: Typeface): bool {.inline.} =
## Returns the expected winding order of a font.
if typeface.opentype != nil:
return typeface.opentype.isCCW()
proc getGlyphPath*(
typeface: Typeface, rune: Rune
): Path {.inline, raises: [PixieError].} =
@ -103,6 +108,16 @@ proc getGlyphPath*(
else:
result.addPath(typeface.svgFont.getGlyphPath(rune))
proc hasGlyph*(typeface: Typeface, rune: Rune): bool {.inline.} =
## Returns if there is a glyph for this rune.
if rune.uint32 > SP.uint32: # Empty paths for control runes (not tofu)
if typeface.opentype != nil:
typeface.opentype.hasGlyph(rune)
else:
typeface.svgFont.hasGlyph(rune)
else:
false
proc getAdvance*(typeface: Typeface, rune: Rune): float32 {.inline, raises: [].} =
## The advance for the rune in pixels.
if typeface.opentype != nil:
@ -478,14 +493,16 @@ proc textUber(
arrangement.selectionRects[runeIndex].x,
position.y - underlinePosition + underlineThickness / 2,
arrangement.selectionRects[runeIndex].w,
underlineThickness
underlineThickness,
font.typeface.isCCW()
)
if font.strikethrough:
path.rect(
arrangement.selectionRects[runeIndex].x,
position.y - strikeoutPosition,
arrangement.selectionRects[runeIndex].w,
strikeoutThickness
strikeoutThickness,
font.typeface.isCCW()
)
when stroke:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB