diff --git a/bindings/bindings.nim b/bindings/bindings.nim index 82600b3..e4d5fc7 100644 --- a/bindings/bindings.nim +++ b/bindings/bindings.nim @@ -192,6 +192,7 @@ exportRefObject Typeface: descent lineGap lineHeight + hasGlyph getGlyphPath getAdvance getKerningAdjustment diff --git a/src/pixie/fontformats/opentype.nim b/src/pixie/fontformats/opentype.nim index 3f5e94b..6ecbc0a 100644 --- a/src/pixie/fontformats/opentype.nim +++ b/src/pixie/fontformats/opentype.nim @@ -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 diff --git a/src/pixie/fontformats/svgfont.nim b/src/pixie/fontformats/svgfont.nim index e6ab769..1370b05 100644 --- a/src/pixie/fontformats/svgfont.nim +++ b/src/pixie/fontformats/svgfont.nim @@ -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) diff --git a/src/pixie/fonts.nim b/src/pixie/fonts.nim index f80667d..538aa34 100644 --- a/src/pixie/fonts.nim +++ b/src/pixie/fonts.nim @@ -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: diff --git a/tests/fonts/diffs/cff_strikethrough.png b/tests/fonts/diffs/cff_strikethrough.png index ef7d4da..a037a16 100644 Binary files a/tests/fonts/diffs/cff_strikethrough.png and b/tests/fonts/diffs/cff_strikethrough.png differ diff --git a/tests/fonts/diffs/cff_underline.png b/tests/fonts/diffs/cff_underline.png index a2b521e..d77ca9e 100644 Binary files a/tests/fonts/diffs/cff_underline.png and b/tests/fonts/diffs/cff_underline.png differ diff --git a/tests/fonts/rendered/cff_strikethrough.png b/tests/fonts/rendered/cff_strikethrough.png index 85e655d..a7a380c 100644 Binary files a/tests/fonts/rendered/cff_strikethrough.png and b/tests/fonts/rendered/cff_strikethrough.png differ diff --git a/tests/fonts/rendered/cff_underline.png b/tests/fonts/rendered/cff_underline.png index 61acca4..a9271eb 100644 Binary files a/tests/fonts/rendered/cff_underline.png and b/tests/fonts/rendered/cff_underline.png differ