megatest start + improvements
This commit is contained in:
parent
4bdcc67baa
commit
7ae3d5c418
|
@ -543,6 +543,8 @@ proc parseKernTable(buf: string, offset: int): KernTable =
|
|||
failUnsupported()
|
||||
subTable.length = buf.readUint16(i + 2).swap()
|
||||
subTable.coverage = buf.readUint16(i + 4).swap()
|
||||
if subTable.coverage shr 8 != 0:
|
||||
failUnsupported()
|
||||
subTable.nPairs = buf.readUint16(i + 6).swap()
|
||||
subTable.searchRange = buf.readUint16(i + 8).swap()
|
||||
subTable.entrySelector = buf.readUint16(i + 10).swap()
|
||||
|
|
|
@ -40,24 +40,6 @@ proc lineGap*(font: Font): float32 {.inline.} =
|
|||
## The font line gap value in font units.
|
||||
font.opentype.hhea.lineGap.float32
|
||||
|
||||
proc getGlyphPath*(font: Font, rune: Rune): Path =
|
||||
if rune notin font.glyphPaths:
|
||||
font.glyphPaths[rune] = font.opentype.parseGlyph(rune)
|
||||
font.glyphPaths[rune].transform(scale(vec2(1, -1)))
|
||||
font.glyphPaths[rune]
|
||||
|
||||
proc getGlyphAdvance*(font: Font, rune: Rune): float32 =
|
||||
let glyphId = font.opentype.getGlyphId(rune).int
|
||||
if glyphId < font.opentype.hmtx.hMetrics.len:
|
||||
font.opentype.hmtx.hMetrics[glyphId].advanceWidth.float32
|
||||
else:
|
||||
font.opentype.hmtx.hMetrics[^1].advanceWidth.float32
|
||||
|
||||
proc getKerningAdjustment*(font: Font, left, right: Rune): float32 =
|
||||
let pair = (left, right)
|
||||
if pair in font.kerningPairs:
|
||||
result = font.kerningPairs[pair]
|
||||
|
||||
proc scale*(font: Font): float32 =
|
||||
## The scale factor to transform font units into pixels.
|
||||
font.size / font.opentype.head.unitsPerEm.float32
|
||||
|
@ -66,6 +48,29 @@ proc defaultLineHeight*(font: Font): float32 =
|
|||
## The default line height in pixels for the current font size.
|
||||
round((font.ascent + abs(font.descent) + font.lineGap) * font.scale)
|
||||
|
||||
proc getGlyphPath*(font: Font, rune: Rune): Path =
|
||||
## The glyph path for the parameter rune.
|
||||
if rune notin font.glyphPaths:
|
||||
font.glyphPaths[rune] = font.opentype.parseGlyph(rune)
|
||||
font.glyphPaths[rune].transform(scale(vec2(1, -1)))
|
||||
font.glyphPaths[rune]
|
||||
|
||||
proc getGlyphAdvance*(font: Font, rune: Rune): float32 =
|
||||
## The advance for the parameter rune in pixels.
|
||||
let glyphId = font.opentype.getGlyphId(rune).int
|
||||
if glyphId < font.opentype.hmtx.hMetrics.len:
|
||||
result = font.opentype.hmtx.hMetrics[glyphId].advanceWidth.float32
|
||||
else:
|
||||
result = font.opentype.hmtx.hMetrics[^1].advanceWidth.float32
|
||||
result *= font.scale
|
||||
|
||||
proc getKerningAdjustment*(font: Font, left, right: Rune): float32 =
|
||||
## The kerning adjustment for the parameter rune pair, in pixels.
|
||||
let pair = (left, right)
|
||||
if pair in font.kerningPairs:
|
||||
result = font.kerningPairs[pair]
|
||||
result *= font.scale
|
||||
|
||||
proc convertTextCase(runes: var seq[Rune], textCase: TextCase) =
|
||||
case textCase:
|
||||
of tcNormal:
|
||||
|
@ -111,9 +116,9 @@ proc typeset*(
|
|||
prevCanWrap = i
|
||||
|
||||
if i > 0:
|
||||
at.x += font.getKerningAdjustment(runes[i - 1], rune) * font.scale
|
||||
at.x += font.getKerningAdjustment(runes[i - 1], rune)
|
||||
|
||||
let advance = font.getGlyphAdvance(rune) * font.scale
|
||||
let advance = font.getGlyphAdvance(rune)
|
||||
if bounds.x > 0 and at.x + advance > bounds.x: # Wrap to new line
|
||||
at.x = 0
|
||||
at.y += lineHeight
|
||||
|
@ -122,9 +127,9 @@ proc typeset*(
|
|||
if prevCanWrap > 0 and prevCanWrap != i:
|
||||
for j in prevCanWrap + 1 ..< i:
|
||||
if j > 0:
|
||||
at.x += font.getKerningAdjustment(runes[j - 1], runes[j]) * font.scale
|
||||
at.x += font.getKerningAdjustment(runes[j - 1], runes[j])
|
||||
positions[j] = at
|
||||
at.x += font.getGlyphAdvance(runes[j]) * font.scale
|
||||
at.x += font.getGlyphAdvance(runes[j])
|
||||
|
||||
positions[i] = at
|
||||
at.x += advance
|
||||
|
@ -142,14 +147,22 @@ proc parseOtf*(buf: string): Font =
|
|||
|
||||
if result.opentype.kern != nil:
|
||||
for table in result.opentype.kern.subTables:
|
||||
for pair in table.kernPairs:
|
||||
if pair.value != 0 and
|
||||
pair.left in result.opentype.cmap.glyphIdToRune and
|
||||
pair.right in result.opentype.cmap.glyphIdToRune:
|
||||
result.kerningPairs[(
|
||||
result.opentype.cmap.glyphIdToRune[pair.left],
|
||||
result.opentype.cmap.glyphIdToRune[pair.right]
|
||||
)] = pair.value.float32
|
||||
if (table.coverage and 1) != 0: # Horizontal data
|
||||
for pair in table.kernPairs:
|
||||
if pair.value != 0 and
|
||||
pair.left in result.opentype.cmap.glyphIdToRune and
|
||||
pair.right in result.opentype.cmap.glyphIdToRune:
|
||||
let key = (
|
||||
result.opentype.cmap.glyphIdToRune[pair.left],
|
||||
result.opentype.cmap.glyphIdToRune[pair.right]
|
||||
)
|
||||
var value = pair.value.float32
|
||||
if key in result.kerningPairs:
|
||||
if (table.coverage and 0b1000) != 0: # Override
|
||||
discard
|
||||
else: # Accumulate
|
||||
value += result.kerningPairs[key]
|
||||
result.kerningPairs[key] = value
|
||||
|
||||
proc parseTtf*(buf: string): Font =
|
||||
parseOtf(buf)
|
||||
|
|
10
tests/fonts_megatest.nim
Normal file
10
tests/fonts_megatest.nim
Normal file
|
@ -0,0 +1,10 @@
|
|||
import common, pixie
|
||||
|
||||
# Clone https://github.com/google/fonts
|
||||
# Check out commit ebaa6a7aab9b700da4e30a4682687acdf427eae7
|
||||
|
||||
let fontPaths = findAllFonts("../fonts")
|
||||
|
||||
for fontPath in fontPaths:
|
||||
echo fontPath
|
||||
let font = readFont(fontPath)
|
Loading…
Reference in a new issue