From cba533e737a48a86fca40126dbc7d4e8aec9511f Mon Sep 17 00:00:00 2001 From: treeform Date: Tue, 7 Sep 2021 12:42:22 -0700 Subject: [PATCH] Add hasGlyph --- src/pixie/fontformats/opentype.nim | 10 ++++++++-- src/pixie/fontformats/svgfont.nim | 3 +++ src/pixie/fonts.nim | 19 ++++++++++++++----- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/pixie/fontformats/opentype.nim b/src/pixie/fontformats/opentype.nim index 98b7d74..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,11 +2421,11 @@ proc getKerningAdjustment*( elif opentype.kern != nil: result = opentype.kern.kerningPairs.getOrDefault(glyphPair, 0) -proc getWindingOrder*(opentype: OpenType): bool = +proc isCCW*(opentype: OpenType): bool {.inline.} = ## Returns the expected winding order of a font. ## Gyph - false - clockwise ## CFF - true - counterclockwise - return opentype.cff == nil + opentype.cff == nil proc parseOpenType*(buf: string): OpenType {.raises: [PixieError].} = result = OpenType() 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 2482cb5..538aa34 100644 --- a/src/pixie/fonts.nim +++ b/src/pixie/fonts.nim @@ -92,11 +92,10 @@ proc strikeoutThickness(typeface: Typeface): float32 = if typeface.opentype != nil: result = typeface.opentype.os2.yStrikeoutSize.float32 -proc getWindingOrder(typeface: Typeface): bool = +proc isCCW(typeface: Typeface): bool {.inline.} = ## Returns the expected winding order of a font. if typeface.opentype != nil: - return typeface.opentype.getWindingOrder() - return true + return typeface.opentype.isCCW() proc getGlyphPath*( typeface: Typeface, rune: Rune @@ -109,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: @@ -485,7 +494,7 @@ proc textUber( position.y - underlinePosition + underlineThickness / 2, arrangement.selectionRects[runeIndex].w, underlineThickness, - font.typeface.getWindingOrder() + font.typeface.isCCW() ) if font.strikethrough: path.rect( @@ -493,7 +502,7 @@ proc textUber( position.y - strikeoutPosition, arrangement.selectionRects[runeIndex].w, strikeoutThickness, - font.typeface.getWindingOrder() + font.typeface.isCCW() ) when stroke: