diff --git a/src/pixie/fontformats/opentype.nim b/src/pixie/fontformats/opentype.nim index 5725640..536b89b 100644 --- a/src/pixie/fontformats/opentype.nim +++ b/src/pixie/fontformats/opentype.nim @@ -1,4 +1,4 @@ -import bitops, flatty/binny, math, pixie/common, pixie/paths, tables, unicode, vmath +import bitops, flatty/binny, math, pixie/common, pixie/paths, sets, tables, unicode, vmath ## See https://docs.microsoft.com/en-us/typography/opentype/spec/ @@ -158,6 +158,7 @@ type version*: uint16 nTables*: uint16 subTables*: seq[KernSubTable] + kerningPairs: Table[(uint16, uint16), float32] TableRecord* = object tag*: string @@ -215,6 +216,7 @@ type glyphArray: seq[uint16] rangeCount: uint16 rangeRecords: seq[RangeRecord] + coveredGlyphs: HashSet[uint16] ValueRecord = object xPlacement: int16 @@ -271,6 +273,10 @@ type classDef1: ClassDef classDef2: ClassDef coverage: Coverage + glyphIdToClass1: Table[uint16, uint16] + glyphIdToClass2: Table[uint16, uint16] + classPairAdjustments: Table[(uint16, uint16), int16] + glyphPairAdjustments: Table[(uint16, uint16), int16] Lookup = object lookupType: uint16 @@ -283,7 +289,7 @@ type lookupCount: uint16 lookupOffsets: seq[uint16] lookups: seq[Lookup] - pairPos: PairPos + pairPosTables: seq[PairPos] GposTable = ref object majorVersion: uint16 @@ -316,7 +322,6 @@ type kern*: KernTable gpos*: GposTable glyphPaths: Table[Rune, Path] - kerningPairs: Table[(Rune, Rune), float32] when defined(release): {.push checks: off.} @@ -657,7 +662,7 @@ proc parseGlyfTable(buf: string, offset: int, loca: LocaTable): GlyfTable = for glyphId in 0 ..< loca.offsets.len: result.offsets[glyphId] = offset.uint32 + loca.offsets[glyphId] -proc parseKernTable(buf: string, offset: int): KernTable = +proc parseKernTable(buf: string, offset: int, cmap: CmapTable): KernTable = var i = offset buf.eofCheck(i + 2) @@ -701,6 +706,22 @@ proc parseKernTable(buf: string, offset: int): KernTable = i += 6 result.subTables.add(subTable) + + for table in result.subTables: + if (table.coverage and 1) != 0: # Horizontal data + for pair in table.kernPairs: + if pair.value != 0 and + pair.left in cmap.glyphIdToRune and + pair.right in cmap.glyphIdToRune: + let key = (pair.left, 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 + elif version == 1: discard # Mac format else: @@ -817,6 +838,10 @@ proc parseCoverage(buf: string, offset: int): Coverage = buf.eofCheck(i + result.glyphCount.int * 2) result.glyphArray = buf.readUint16Seq(i, result.glyphCount.int) + + for ci, glyphId in result.glyphArray: + result.coveredGlyphs.incl(glyphId) + of 2: result.rangeCount = buf.readUint16(i + 0).swap() i += 2 @@ -825,6 +850,13 @@ proc parseCoverage(buf: string, offset: int): Coverage = for j in 0 ..< result.rangeCount.int: result.rangeRecords[j] = parseRangeRecord(buf, i + j * sizeof(RangeRecord)) + + for rangeRecord in result.rangeRecords: + var ci = rangeRecord.startCoverageIndex.int + for glyphId in rangeRecord.startGlyphID .. rangeRecord.endGlyphID: + result.coveredGlyphs.incl(glyphId) + inc ci + else: failUnsupported() @@ -870,7 +902,7 @@ proc parsePairValueRecord( i += 2 result.valueRecord1 = parseValueRecord(buf, i, valueFormat1) - result.valueRecord1 = + result.valueRecord2 = parseValueRecord(buf, i + countSetBits(valueFormat1) * 2, valueFormat2) proc parsePairSet( @@ -889,14 +921,21 @@ proc parsePairSet( result.pairValueRecords.setLen(result.pairValueCount.int) for j in 0 ..< result.pairValueCount.int: result.pairValueRecords[j] = parsePairValueRecord( - buf, i + j * pairValueRecordSize, valueFormat1, valueFormat2 + buf, i, valueFormat1, valueFormat2 ) + i += pairValueRecordSize proc parseClass2Record( buf: string, offset: int, valueFormat1, valueFormat2: uint16 ): Class2Record = + let class2RecordSize = ( + countSetBits(valueFormat1) + countSetBits(valueFormat2) + ) * 2 + buf.eofCheck(offset + class2RecordSize) result.valueRecord1 = parseValueRecord(buf, offset, valueFormat1) - result.valueRecord2 = parseValueRecord(buf, offset, valueFormat2) + result.valueRecord2 = parseValueRecord( + buf, offset + countSetBits(valueFormat1) * 2, valueFormat2 + ) proc parseClass1Record( buf: string, offset: int, valueFormat1, valueFormat2, class2Count: uint16 @@ -957,14 +996,12 @@ proc parsePairPos(buf: string, offset: int): PairPos = buf.eofCheck(i + 4) - let posFormat = buf.readUint16(i + 0).swap() + result = PairPos() + result.posFormat = buf.readUint16(i + 0).swap() i += 2 - case posFormat: + case result.posFormat: of 1: - result = PairPos() - result.posFormat = posFormat - buf.eofCheck(i + 8) result.coverageOffset = buf.readUint16(i + 0).swap() @@ -988,10 +1025,35 @@ proc parsePairPos(buf: string, offset: int): PairPos = ) result.coverage = parseCoverage(buf, offset + result.coverageOffset.int) - of 2: - result = PairPos() - result.posFormat = posFormat + if (result.valueFormat1 and 0b100) != 0: + case result.coverage.coverageFormat: + of 1: + if result.coverage.glyphCount != result.pairSetCount: + failUnsupported() + for ci, glyphId in result.coverage.glyphArray: + if ci < 0 or ci >= result.pairSets.len: + failUnsupported() + for pairValueRecord in result.pairSets[ci].pairValueRecords: + if pairValueRecord.valueRecord1.xAdvance != 0: + let glyphPair = (glyphId, pairValueRecord.secondGlyph) + result.glyphPairAdjustments[glyphPair] = + pairValueRecord.valueRecord1.xAdvance + of 2: + for rangeRecord in result.coverage.rangeRecords: + var ci = rangeRecord.startCoverageIndex.int + for glyphId in rangeRecord.startGlyphID .. rangeRecord.endGlyphID: + if ci < 0 or ci >= result.pairSets.len: + failUnsupported() + for pairValueRecord in result.pairSets[ci].pairValueRecords: + if pairValueRecord.valueRecord1.xAdvance != 0: + let glyphPair = (glyphId, pairValueRecord.secondGlyph) + result.glyphPairAdjustments[glyphPair] = + pairValueRecord.valueRecord1.xAdvance + inc ci + else: + discard + of 2: buf.eofCheck(i + 14) result.coverageOffset = buf.readUint16(i + 0).swap() @@ -1013,12 +1075,52 @@ proc parsePairPos(buf: string, offset: int): PairPos = result.class1Records[j] = parseClass1Record( buf, i, result.valueFormat1, result.valueFormat2, result.class2Count ) - i += class2RecordSize + i += class2RecordSize * result.class2Count.int result.classDef1 = parseClassDef(buf, offset + result.classDef1Offset.int) result.classDef2 = parseClassDef(buf, offset + result.classDef2Offset.int) result.coverage = parseCoverage(buf, offset + result.coverageOffset.int) + + proc classDefFormat1( + classDef: ClassDef, table: var Table[uint16, uint16] + ) = + for i in 0.uint16 ..< classDef.glyphCount: + if classDef.classValueArray[i] != 0: + table[classDef.startGlyphID + i] = classDef.classValueArray[i] + + proc classDefFormat2( + classDef: ClassDef, table: var Table[uint16, uint16] + ) = + for record in classDef.classRangeRecords: + if record.startGlyphID > record.endGlyphID: + failUnsupported() + if record.class != 0: + for glyphId in record.startGlyphID .. record.endGlyphID: + table[glyphId] = record.class + + case result.classDef1.classFormat: + of 1: + classDefFormat1(result.classDef1, result.glyphIdToClass1) + of 2: + classDefFormat2(result.classDef1, result.glyphIdToClass1) + else: + discard + + case result.classDef2.classFormat: + of 1: + classDefFormat1(result.classDef2, result.glyphIdToClass2) + of 2: + classDefFormat2(result.classDef2, result.glyphIdToClass2) + else: + discard + + if (result.valueFormat1 and 0b100) != 0: + for class1, class1Record in result.class1Records: + for class2, class2Record in class1Record.class2Records: + if class2Record.valueRecord1.xAdvance != 0: + result.classPairAdjustments[(class1.uint16, class2.uint16)] = + class2Record.valueRecord1.xAdvance else: failUnsupported() @@ -1043,8 +1145,10 @@ proc parseLookup(buf: string, offset: int, gpos: GposTable): Lookup = for subTableOffset in result.subTableOffsets: if result.lookupType == 2: - gpos.lookupList.pairPos = - parsePairPos(buf, offset + subTableOffset.int) + let pairPos = parsePairPos(buf, offset + subTableOffset.int) + if pairPos.glyphPairAdjustments.len > 0 or + pairPos.classPairAdjustments.len > 0: + gpos.lookupList.pairPosTables.add(pairPos) proc parseLookupList(buf: string, offset: int, gpos: GposTable): LookupList = var i = offset @@ -1377,9 +1481,38 @@ proc getAdvance*(opentype: OpenType, rune: Rune): float32 = result = opentype.hmtx.hMetrics[^1].advanceWidth.float32 proc getKerningAdjustment*(opentype: OpenType, left, right: Rune): float32 = - let pair = (left, right) - if pair in opentype.kerningPairs: - result = opentype.kerningPairs[pair] + let + leftGlyphId = opentype.cmap.runeToGlyphId[left] + rightGlyphId = opentype.cmap.runeToGlyphId[right] + glyphPair = (leftGlyphId, rightGlyphId) + + if opentype.gpos != nil: + for pairPos in opentype.gpos.lookupList.pairPosTables: + if leftGlyphId notin pairPos.coverage.coveredGlyphs: + continue + + case pairPos.posFormat: + of 1: + if glyphPair in pairPos.glyphPairAdjustments: + result = pairPos.glyphPairAdjustments[glyphPair].float32 + break + of 2: + var leftClass, rightClass: uint16 + if leftGlyphId in pairPos.glyphIdToClass1: + leftClass = pairPos.glyphIdToClass1[leftGlyphId] + if rightGlyphId in pairPos.glyphIdToClass2: + rightClass = pairPos.glyphIdToClass2[rightGlyphId] + + let classPair = (leftClass, rightClass) + if classPair in pairPos.classPairAdjustments: + result = pairPos.classPairAdjustments[classPair].float32 + break + else: + discard + + elif opentype.kern != nil: + if glyphPair in opentype.kern.kerningPairs: + result = opentype.kern.kerningPairs[glyphPair] proc parseOpenType*(buf: string): OpenType = result = OpenType() @@ -1427,119 +1560,15 @@ proc parseOpenType*(buf: string): OpenType = result.loca = parseLocaTable( buf, result.tableRecords["loca"].offset.int, result.head, result.maxp ) - result.glyf = parseGlyfTable( - buf, result.tableRecords["glyf"].offset.int, result.loca - ) + result.glyf = + parseGlyfTable(buf, result.tableRecords["glyf"].offset.int, result.loca) if "kern" in result.tableRecords: - result.kern = parseKernTable(buf, result.tableRecords["kern"].offset.int) + result.kern = + parseKernTable(buf, result.tableRecords["kern"].offset.int, result.cmap) - if result.kern != nil: - for table in result.kern.subTables: - if (table.coverage and 1) != 0: # Horizontal data - for pair in table.kernPairs: - if pair.value != 0 and - pair.left in result.cmap.glyphIdToRune and - pair.right in result.cmap.glyphIdToRune: - let key = ( - result.cmap.glyphIdToRune[pair.left], - result.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 - - # if "GPOS" in result.tableRecords: - # result.gpos = parseGposTable(buf, result.tableRecords["GPOS"].offset.int) - - # if result.gpos != nil and result.gpos.lookupList.pairPos != nil: - # # case result.gpos.lookupList.pairPos.coverage.coverageFormat: - # # of 1: - # # echo "GLYPH COUNT:", result.gpos.lookupList.pairPos.coverage.glyphCount - # # of 2: - # # echo "RANGE COUNT:", result.gpos.lookupList.pairPos.coverage.rangeCount - # # else: - # # failUnsupported() - - # case result.gpos.lookupList.pairPos.posFormat: - # of 1: - # echo "posFormat 1 not implemented" - # of 2: - # proc classDefFormat1(classDef: ClassDef): Table[uint16, uint16] = - # for i in 0.uint16 ..< classDef.glyphCount: - # result[classDef.startGlyphID + i] = classDef.classValueArray[i] - - # proc classDefFormat2(classDef: ClassDef): Table[uint16, uint16] = - # for record in classDef.classRangeRecords: - # if record.startGlyphID > record.endGlyphID: - # failUnsupported() - # for glyphId in record.startGlyphID .. record.endGlyphID: - # result[glyphId] = record.class - - # var glyphIdToClass1: Table[uint16, uint16] - # case result.gpos.lookupList.pairPos.classDef1.classFormat: - # of 1: - # glyphIdToClass1 = - # classDefFormat1(result.gpos.lookupList.pairPos.classDef1) - # of 2: - # glyphIdToClass1 = - # classDefFormat2(result.gpos.lookupList.pairPos.classDef1) - # else: - # failUnsupported() - - # var glyphIdToClass2: Table[uint16, uint16] - # case result.gpos.lookupList.pairPos.classDef2.classFormat: - # of 1: - # glyphIdToClass2 = - # classDefFormat1(result.gpos.lookupList.pairPos.classDef2) - # of 2: - # glyphIdToClass2 = - # classDefFormat2(result.gpos.lookupList.pairPos.classDef2) - # else: - # failUnsupported() - - # var runeToClass1: Table[Rune, uint16] - # for glyphId, class in glyphIdToClass1: - # if glyphId in result.cmap.glyphIdToRune: - # let rune = result.cmap.glyphIdToRune[glyphId] - # runeToClass1[rune] = class - - # var runeToClass2: Table[Rune, uint16] - # for glyphId, class in glyphIdToClass2: - # if glyphId in result.cmap.glyphIdToRune: - # let rune = result.cmap.glyphIdToRune[glyphId] - # runeToClass2[rune] = class - - # var classPairs: Table[(uint16, uint16), Class2Record] - # for i, class1Record in result.gpos.lookupList.pairPos.class1Records: - # for j, class2Record in class1Record.class2Records: - # classPairs[(i.uint16, j.uint16)] = class2Record - - # for left in result.cmap.runeToGlyphId.keys: - # for right in result.cmap.runeToGlyphId.keys: - # var leftClass, rightClass: uint16 - # if left in runeToClass1: - # leftClass = runeToClass1[left] - # if right in runeToClass2: - # rightClass = runeToClass2[right] - - # let pair = (leftClass, rightClass) - # if pair in classPairs: - # let classPair = classPairs[pair] - # if classPair.valueRecord1.xAdvance != 0: - # result.kerningPairs[(left, right)] = - # classPair.valueRecord1.xAdvance.float32 - # else: - # failUnsupported() - - # echo Rune(32) in result.cmap.runeToGlyphId - # echo getAdvance(result, Rune(32)) - # echo result.head.unitsPerEm - # echo result.getGlyphId(Rune(32)) + if "GPOS" in result.tableRecords: + result.gpos = parseGposTable(buf, result.tableRecords["GPOS"].offset.int) when defined(release): {.pop.} diff --git a/src/pixie/fonts.nim b/src/pixie/fonts.nim index 3cb6455..206bd97 100644 --- a/src/pixie/fonts.nim +++ b/src/pixie/fonts.nim @@ -35,21 +35,21 @@ type # tcSmallCaps # tcSmallCapsForced -proc ascent(typeface: Typeface): float32 {.inline.} = +proc ascent*(typeface: Typeface): float32 {.inline.} = ## The font ascender value in font units. if typeface.opentype != nil: typeface.opentype.hhea.ascender.float32 else: typeface.svgFont.ascent -proc descent(typeface: Typeface): float32 {.inline.} = +proc descent*(typeface: Typeface): float32 {.inline.} = ## The font descender value in font units. if typeface.opentype != nil: typeface.opentype.hhea.descender.float32 else: typeface.svgFont.descent -proc lineGap(typeface: Typeface): float32 {.inline.} = +proc lineGap*(typeface: Typeface): float32 {.inline.} = ## The font line gap value in font units. if typeface.opentype != nil: result = typeface.opentype.hhea.lineGap.float32 @@ -61,14 +61,14 @@ proc getGlyphPath*(typeface: Typeface, rune: Rune): Path {.inline.} = else: typeface.svgFont.getGlyphPath(rune) -proc getAdvance(typeface: Typeface, rune: Rune): float32 {.inline.} = +proc getAdvance*(typeface: Typeface, rune: Rune): float32 {.inline.} = ## The advance for the rune in pixels. if typeface.opentype != nil: typeface.opentype.getAdvance(rune) else: typeface.svgFont.getAdvance(rune) -proc getKerningAdjustment( +proc getKerningAdjustment*( typeface: Typeface, left, right: Rune ): float32 {.inline.} = ## The kerning adjustment for the rune pair, in pixels. diff --git a/tests/fonts/Aclonica-Regular.ttf b/tests/fonts/Aclonica-Regular_1.ttf similarity index 100% rename from tests/fonts/Aclonica-Regular.ttf rename to tests/fonts/Aclonica-Regular_1.ttf diff --git a/tests/fonts/IBMPlexSans-Regular.ttf b/tests/fonts/IBMPlexSans-Regular_2.ttf similarity index 100% rename from tests/fonts/IBMPlexSans-Regular.ttf rename to tests/fonts/IBMPlexSans-Regular_2.ttf diff --git a/tests/fonts/NotoSans-Regular.ttf b/tests/fonts/NotoSans-Regular.ttf deleted file mode 100644 index 9dd1019..0000000 Binary files a/tests/fonts/NotoSans-Regular.ttf and /dev/null differ diff --git a/tests/fonts/NotoSans-Regular_4.ttf b/tests/fonts/NotoSans-Regular_4.ttf new file mode 100644 index 0000000..170c15c Binary files /dev/null and b/tests/fonts/NotoSans-Regular_4.ttf differ diff --git a/tests/fonts/Pacifico-Regular.ttf b/tests/fonts/Pacifico-Regular_4.ttf similarity index 100% rename from tests/fonts/Pacifico-Regular.ttf rename to tests/fonts/Pacifico-Regular_4.ttf diff --git a/tests/fonts/Roboto-Regular.ttf b/tests/fonts/Roboto-Regular.ttf deleted file mode 100644 index 2c32a98..0000000 Binary files a/tests/fonts/Roboto-Regular.ttf and /dev/null differ diff --git a/tests/fonts/Roboto-Regular_1.ttf b/tests/fonts/Roboto-Regular_1.ttf new file mode 100644 index 0000000..2c97eea Binary files /dev/null and b/tests/fonts/Roboto-Regular_1.ttf differ diff --git a/tests/fonts/Ubuntu-Regular.ttf b/tests/fonts/Ubuntu-Regular_1.ttf similarity index 100% rename from tests/fonts/Ubuntu-Regular.ttf rename to tests/fonts/Ubuntu-Regular_1.ttf diff --git a/tests/fonts/diffs/basic1.png b/tests/fonts/diffs/basic1.png index 73382a6..cb654e8 100644 Binary files a/tests/fonts/diffs/basic1.png and b/tests/fonts/diffs/basic1.png differ diff --git a/tests/fonts/diffs/basic2.png b/tests/fonts/diffs/basic2.png index 7b3854f..b933717 100644 Binary files a/tests/fonts/diffs/basic2.png and b/tests/fonts/diffs/basic2.png differ diff --git a/tests/fonts/diffs/basic3.png b/tests/fonts/diffs/basic3.png index bf42cf5..c179aaf 100644 Binary files a/tests/fonts/diffs/basic3.png and b/tests/fonts/diffs/basic3.png differ diff --git a/tests/fonts/diffs/basic4.png b/tests/fonts/diffs/basic4.png index c181e9c..8058ed1 100644 Binary files a/tests/fonts/diffs/basic4.png and b/tests/fonts/diffs/basic4.png differ diff --git a/tests/fonts/diffs/basic6.png b/tests/fonts/diffs/basic6.png index 14e5a91..8abcfb7 100644 Binary files a/tests/fonts/diffs/basic6.png and b/tests/fonts/diffs/basic6.png differ diff --git a/tests/fonts/diffs/basic7.png b/tests/fonts/diffs/basic7.png index 6f43f6f..7cae15b 100644 Binary files a/tests/fonts/diffs/basic7.png and b/tests/fonts/diffs/basic7.png differ diff --git a/tests/fonts/diffs/basic8.png b/tests/fonts/diffs/basic8.png index e8fef19..1bbbae0 100644 Binary files a/tests/fonts/diffs/basic8.png and b/tests/fonts/diffs/basic8.png differ diff --git a/tests/fonts/diffs/basic9.png b/tests/fonts/diffs/basic9.png index e0f2d0f..1cac49a 100644 Binary files a/tests/fonts/diffs/basic9.png and b/tests/fonts/diffs/basic9.png differ diff --git a/tests/fonts/diffs/huge1.png b/tests/fonts/diffs/huge1.png new file mode 100644 index 0000000..4a543a2 Binary files /dev/null and b/tests/fonts/diffs/huge1.png differ diff --git a/tests/fonts/diffs/huge1_nokern.png b/tests/fonts/diffs/huge1_nokern.png new file mode 100644 index 0000000..6bfeb09 Binary files /dev/null and b/tests/fonts/diffs/huge1_nokern.png differ diff --git a/tests/fonts/diffs/huge2.png b/tests/fonts/diffs/huge2.png new file mode 100644 index 0000000..8bcfbe9 Binary files /dev/null and b/tests/fonts/diffs/huge2.png differ diff --git a/tests/fonts/diffs/huge2_nokern.png b/tests/fonts/diffs/huge2_nokern.png new file mode 100644 index 0000000..a1d635e Binary files /dev/null and b/tests/fonts/diffs/huge2_nokern.png differ diff --git a/tests/fonts/diffs/huge3.png b/tests/fonts/diffs/huge3.png new file mode 100644 index 0000000..0b05db3 Binary files /dev/null and b/tests/fonts/diffs/huge3.png differ diff --git a/tests/fonts/diffs/huge3_nokern.png b/tests/fonts/diffs/huge3_nokern.png new file mode 100644 index 0000000..f22cb70 Binary files /dev/null and b/tests/fonts/diffs/huge3_nokern.png differ diff --git a/tests/fonts/diffs/pairs1.png b/tests/fonts/diffs/pairs1.png new file mode 100644 index 0000000..3040a43 Binary files /dev/null and b/tests/fonts/diffs/pairs1.png differ diff --git a/tests/fonts/diffs/pairs2.png b/tests/fonts/diffs/pairs2.png new file mode 100644 index 0000000..9c0df3e Binary files /dev/null and b/tests/fonts/diffs/pairs2.png differ diff --git a/tests/fonts/diffs/pairs3.png b/tests/fonts/diffs/pairs3.png new file mode 100644 index 0000000..8d1eed3 Binary files /dev/null and b/tests/fonts/diffs/pairs3.png differ diff --git a/tests/fonts/diffs/paragraph1.png b/tests/fonts/diffs/paragraph1.png index e5d793a..d774c46 100644 Binary files a/tests/fonts/diffs/paragraph1.png and b/tests/fonts/diffs/paragraph1.png differ diff --git a/tests/fonts/diffs/paragraph1_2.png b/tests/fonts/diffs/paragraph1_2.png index 5911ae0..323d9a5 100644 Binary files a/tests/fonts/diffs/paragraph1_2.png and b/tests/fonts/diffs/paragraph1_2.png differ diff --git a/tests/fonts/diffs/paragraph1_3.png b/tests/fonts/diffs/paragraph1_3.png index 3404078..30bdd17 100644 Binary files a/tests/fonts/diffs/paragraph1_3.png and b/tests/fonts/diffs/paragraph1_3.png differ diff --git a/tests/fonts/diffs/paragraph1_nokern.png b/tests/fonts/diffs/paragraph1_nokern.png index d220c25..e5e4952 100644 Binary files a/tests/fonts/diffs/paragraph1_nokern.png and b/tests/fonts/diffs/paragraph1_nokern.png differ diff --git a/tests/fonts/diffs/paragraph1_nokern_2.png b/tests/fonts/diffs/paragraph1_nokern_2.png index af5e251..dbc6e04 100644 Binary files a/tests/fonts/diffs/paragraph1_nokern_2.png and b/tests/fonts/diffs/paragraph1_nokern_2.png differ diff --git a/tests/fonts/diffs/paragraph1_nokern_3.png b/tests/fonts/diffs/paragraph1_nokern_3.png index a147a21..96a410d 100644 Binary files a/tests/fonts/diffs/paragraph1_nokern_3.png and b/tests/fonts/diffs/paragraph1_nokern_3.png differ diff --git a/tests/fonts/diffs/paragraph3.png b/tests/fonts/diffs/paragraph3.png index 5c46f4b..bc51484 100644 Binary files a/tests/fonts/diffs/paragraph3.png and b/tests/fonts/diffs/paragraph3.png differ diff --git a/tests/fonts/diffs/paragraph3_2.png b/tests/fonts/diffs/paragraph3_2.png index fb663f4..8100141 100644 Binary files a/tests/fonts/diffs/paragraph3_2.png and b/tests/fonts/diffs/paragraph3_2.png differ diff --git a/tests/fonts/diffs/paragraph3_3.png b/tests/fonts/diffs/paragraph3_3.png index 63efb57..c9c2e7b 100644 Binary files a/tests/fonts/diffs/paragraph3_3.png and b/tests/fonts/diffs/paragraph3_3.png differ diff --git a/tests/fonts/diffs/paragraph4.png b/tests/fonts/diffs/paragraph4.png index 4b210cd..8696251 100644 Binary files a/tests/fonts/diffs/paragraph4.png and b/tests/fonts/diffs/paragraph4.png differ diff --git a/tests/fonts/diffs/paragraph4_2.png b/tests/fonts/diffs/paragraph4_2.png index 8c3ebef..fde9201 100644 Binary files a/tests/fonts/diffs/paragraph4_2.png and b/tests/fonts/diffs/paragraph4_2.png differ diff --git a/tests/fonts/diffs/paragraph4_3.png b/tests/fonts/diffs/paragraph4_3.png index 605f8b1..2ecbcd1 100644 Binary files a/tests/fonts/diffs/paragraph4_3.png and b/tests/fonts/diffs/paragraph4_3.png differ diff --git a/tests/fonts/diffs/paragraph4_nokern.png b/tests/fonts/diffs/paragraph4_nokern.png index b7cc912..bfd42d2 100644 Binary files a/tests/fonts/diffs/paragraph4_nokern.png and b/tests/fonts/diffs/paragraph4_nokern.png differ diff --git a/tests/fonts/diffs/paragraph4_nokern_2.png b/tests/fonts/diffs/paragraph4_nokern_2.png index f91585c..51cf884 100644 Binary files a/tests/fonts/diffs/paragraph4_nokern_2.png and b/tests/fonts/diffs/paragraph4_nokern_2.png differ diff --git a/tests/fonts/diffs/paragraph4_nokern_3.png b/tests/fonts/diffs/paragraph4_nokern_3.png index d79030d..e2cd98e 100644 Binary files a/tests/fonts/diffs/paragraph4_nokern_3.png and b/tests/fonts/diffs/paragraph4_nokern_3.png differ diff --git a/tests/fonts/diffs/paragraph5.png b/tests/fonts/diffs/paragraph5.png index d78b571..6c54306 100644 Binary files a/tests/fonts/diffs/paragraph5.png and b/tests/fonts/diffs/paragraph5.png differ diff --git a/tests/fonts/diffs/paragraph5_2.png b/tests/fonts/diffs/paragraph5_2.png index cc29beb..f84f601 100644 Binary files a/tests/fonts/diffs/paragraph5_2.png and b/tests/fonts/diffs/paragraph5_2.png differ diff --git a/tests/fonts/diffs/paragraph5_3.png b/tests/fonts/diffs/paragraph5_3.png index c2e4530..af155ee 100644 Binary files a/tests/fonts/diffs/paragraph5_3.png and b/tests/fonts/diffs/paragraph5_3.png differ diff --git a/tests/fonts/image_fill.png b/tests/fonts/image_fill.png index ee45abd..74ca38d 100644 Binary files a/tests/fonts/image_fill.png and b/tests/fonts/image_fill.png differ diff --git a/tests/fonts/image_stroke.png b/tests/fonts/image_stroke.png index 96cdade..ee6ea66 100644 Binary files a/tests/fonts/image_stroke.png and b/tests/fonts/image_stroke.png differ diff --git a/tests/fonts/mask_fill.png b/tests/fonts/mask_fill.png index a6d39c9..73183c4 100644 Binary files a/tests/fonts/mask_fill.png and b/tests/fonts/mask_fill.png differ diff --git a/tests/fonts/mask_stroke.png b/tests/fonts/mask_stroke.png index 0a1eb36..f3d82d5 100644 Binary files a/tests/fonts/mask_stroke.png and b/tests/fonts/mask_stroke.png differ diff --git a/tests/fonts/masters/huge1.png b/tests/fonts/masters/huge1.png new file mode 100644 index 0000000..fb83009 Binary files /dev/null and b/tests/fonts/masters/huge1.png differ diff --git a/tests/fonts/masters/huge1_nokern.png b/tests/fonts/masters/huge1_nokern.png new file mode 100644 index 0000000..a6200f5 Binary files /dev/null and b/tests/fonts/masters/huge1_nokern.png differ diff --git a/tests/fonts/masters/huge2.png b/tests/fonts/masters/huge2.png new file mode 100644 index 0000000..5f5ae91 Binary files /dev/null and b/tests/fonts/masters/huge2.png differ diff --git a/tests/fonts/masters/huge2_nokern.png b/tests/fonts/masters/huge2_nokern.png new file mode 100644 index 0000000..aa15e3b Binary files /dev/null and b/tests/fonts/masters/huge2_nokern.png differ diff --git a/tests/fonts/masters/huge3.png b/tests/fonts/masters/huge3.png new file mode 100644 index 0000000..a646cae Binary files /dev/null and b/tests/fonts/masters/huge3.png differ diff --git a/tests/fonts/masters/huge3_nokern.png b/tests/fonts/masters/huge3_nokern.png new file mode 100644 index 0000000..3eb6d2a Binary files /dev/null and b/tests/fonts/masters/huge3_nokern.png differ diff --git a/tests/fonts/masters/pairs1.png b/tests/fonts/masters/pairs1.png new file mode 100644 index 0000000..c8bcde9 Binary files /dev/null and b/tests/fonts/masters/pairs1.png differ diff --git a/tests/fonts/masters/pairs2.png b/tests/fonts/masters/pairs2.png new file mode 100644 index 0000000..71bc2e5 Binary files /dev/null and b/tests/fonts/masters/pairs2.png differ diff --git a/tests/fonts/masters/pairs3.png b/tests/fonts/masters/pairs3.png new file mode 100644 index 0000000..680ba3f Binary files /dev/null and b/tests/fonts/masters/pairs3.png differ diff --git a/tests/fonts/rendered/basic1.png b/tests/fonts/rendered/basic1.png index 9154788..07ecae7 100644 Binary files a/tests/fonts/rendered/basic1.png and b/tests/fonts/rendered/basic1.png differ diff --git a/tests/fonts/rendered/basic2.png b/tests/fonts/rendered/basic2.png index 285c31a..8b2ed35 100644 Binary files a/tests/fonts/rendered/basic2.png and b/tests/fonts/rendered/basic2.png differ diff --git a/tests/fonts/rendered/basic3.png b/tests/fonts/rendered/basic3.png index 7c658eb..b6729aa 100644 Binary files a/tests/fonts/rendered/basic3.png and b/tests/fonts/rendered/basic3.png differ diff --git a/tests/fonts/rendered/basic4.png b/tests/fonts/rendered/basic4.png index 8873de8..7409f47 100644 Binary files a/tests/fonts/rendered/basic4.png and b/tests/fonts/rendered/basic4.png differ diff --git a/tests/fonts/rendered/basic6.png b/tests/fonts/rendered/basic6.png index 69fd40f..abb7064 100644 Binary files a/tests/fonts/rendered/basic6.png and b/tests/fonts/rendered/basic6.png differ diff --git a/tests/fonts/rendered/basic7.png b/tests/fonts/rendered/basic7.png index 64f3047..ddf03e2 100644 Binary files a/tests/fonts/rendered/basic7.png and b/tests/fonts/rendered/basic7.png differ diff --git a/tests/fonts/rendered/basic8.png b/tests/fonts/rendered/basic8.png index 4775747..5e66e06 100644 Binary files a/tests/fonts/rendered/basic8.png and b/tests/fonts/rendered/basic8.png differ diff --git a/tests/fonts/rendered/basic9.png b/tests/fonts/rendered/basic9.png index cc183fc..4b747ff 100644 Binary files a/tests/fonts/rendered/basic9.png and b/tests/fonts/rendered/basic9.png differ diff --git a/tests/fonts/rendered/huge1.png b/tests/fonts/rendered/huge1.png new file mode 100644 index 0000000..661ce69 Binary files /dev/null and b/tests/fonts/rendered/huge1.png differ diff --git a/tests/fonts/rendered/huge1_nokern.png b/tests/fonts/rendered/huge1_nokern.png new file mode 100644 index 0000000..3c9e80d Binary files /dev/null and b/tests/fonts/rendered/huge1_nokern.png differ diff --git a/tests/fonts/rendered/huge2.png b/tests/fonts/rendered/huge2.png new file mode 100644 index 0000000..cfa5ccd Binary files /dev/null and b/tests/fonts/rendered/huge2.png differ diff --git a/tests/fonts/rendered/huge2_nokern.png b/tests/fonts/rendered/huge2_nokern.png new file mode 100644 index 0000000..5753c16 Binary files /dev/null and b/tests/fonts/rendered/huge2_nokern.png differ diff --git a/tests/fonts/rendered/huge3.png b/tests/fonts/rendered/huge3.png new file mode 100644 index 0000000..2a7c8ca Binary files /dev/null and b/tests/fonts/rendered/huge3.png differ diff --git a/tests/fonts/rendered/huge3_nokern.png b/tests/fonts/rendered/huge3_nokern.png new file mode 100644 index 0000000..0df1b96 Binary files /dev/null and b/tests/fonts/rendered/huge3_nokern.png differ diff --git a/tests/fonts/rendered/pairs1.png b/tests/fonts/rendered/pairs1.png new file mode 100644 index 0000000..6367f97 Binary files /dev/null and b/tests/fonts/rendered/pairs1.png differ diff --git a/tests/fonts/rendered/pairs2.png b/tests/fonts/rendered/pairs2.png new file mode 100644 index 0000000..0dfca9a Binary files /dev/null and b/tests/fonts/rendered/pairs2.png differ diff --git a/tests/fonts/rendered/pairs3.png b/tests/fonts/rendered/pairs3.png new file mode 100644 index 0000000..cf0493c Binary files /dev/null and b/tests/fonts/rendered/pairs3.png differ diff --git a/tests/fonts/rendered/paragraph1.png b/tests/fonts/rendered/paragraph1.png index 8964af1..b51f2d5 100644 Binary files a/tests/fonts/rendered/paragraph1.png and b/tests/fonts/rendered/paragraph1.png differ diff --git a/tests/fonts/rendered/paragraph1_1.png b/tests/fonts/rendered/paragraph1_1.png deleted file mode 100644 index 19e500e..0000000 Binary files a/tests/fonts/rendered/paragraph1_1.png and /dev/null differ diff --git a/tests/fonts/rendered/paragraph1_2.png b/tests/fonts/rendered/paragraph1_2.png index 19e500e..359dd30 100644 Binary files a/tests/fonts/rendered/paragraph1_2.png and b/tests/fonts/rendered/paragraph1_2.png differ diff --git a/tests/fonts/rendered/paragraph1_3.png b/tests/fonts/rendered/paragraph1_3.png index 79a37c6..fabe147 100644 Binary files a/tests/fonts/rendered/paragraph1_3.png and b/tests/fonts/rendered/paragraph1_3.png differ diff --git a/tests/fonts/rendered/paragraph1_nokern.png b/tests/fonts/rendered/paragraph1_nokern.png index 8964af1..1d22360 100644 Binary files a/tests/fonts/rendered/paragraph1_nokern.png and b/tests/fonts/rendered/paragraph1_nokern.png differ diff --git a/tests/fonts/rendered/paragraph1_nokern_2.png b/tests/fonts/rendered/paragraph1_nokern_2.png index 19e500e..dc0e255 100644 Binary files a/tests/fonts/rendered/paragraph1_nokern_2.png and b/tests/fonts/rendered/paragraph1_nokern_2.png differ diff --git a/tests/fonts/rendered/paragraph1_nokern_3.png b/tests/fonts/rendered/paragraph1_nokern_3.png index 79a37c6..404c13d 100644 Binary files a/tests/fonts/rendered/paragraph1_nokern_3.png and b/tests/fonts/rendered/paragraph1_nokern_3.png differ diff --git a/tests/fonts/rendered/paragraph3.png b/tests/fonts/rendered/paragraph3.png index aab3e48..d4aa2a8 100644 Binary files a/tests/fonts/rendered/paragraph3.png and b/tests/fonts/rendered/paragraph3.png differ diff --git a/tests/fonts/rendered/paragraph3_2.png b/tests/fonts/rendered/paragraph3_2.png index 5d380cb..ff50720 100644 Binary files a/tests/fonts/rendered/paragraph3_2.png and b/tests/fonts/rendered/paragraph3_2.png differ diff --git a/tests/fonts/rendered/paragraph3_3.png b/tests/fonts/rendered/paragraph3_3.png index 62255e2..6a622e6 100644 Binary files a/tests/fonts/rendered/paragraph3_3.png and b/tests/fonts/rendered/paragraph3_3.png differ diff --git a/tests/fonts/rendered/paragraph4.png b/tests/fonts/rendered/paragraph4.png index 065b4b5..e8b47d2 100644 Binary files a/tests/fonts/rendered/paragraph4.png and b/tests/fonts/rendered/paragraph4.png differ diff --git a/tests/fonts/rendered/paragraph4_2.png b/tests/fonts/rendered/paragraph4_2.png index f6bcb94..e6ab9c0 100644 Binary files a/tests/fonts/rendered/paragraph4_2.png and b/tests/fonts/rendered/paragraph4_2.png differ diff --git a/tests/fonts/rendered/paragraph4_3.png b/tests/fonts/rendered/paragraph4_3.png index e98050e..c439944 100644 Binary files a/tests/fonts/rendered/paragraph4_3.png and b/tests/fonts/rendered/paragraph4_3.png differ diff --git a/tests/fonts/rendered/paragraph4_nokern.png b/tests/fonts/rendered/paragraph4_nokern.png index 065b4b5..2524bca 100644 Binary files a/tests/fonts/rendered/paragraph4_nokern.png and b/tests/fonts/rendered/paragraph4_nokern.png differ diff --git a/tests/fonts/rendered/paragraph4_nokern_2.png b/tests/fonts/rendered/paragraph4_nokern_2.png index f6bcb94..09ecd3f 100644 Binary files a/tests/fonts/rendered/paragraph4_nokern_2.png and b/tests/fonts/rendered/paragraph4_nokern_2.png differ diff --git a/tests/fonts/rendered/paragraph4_nokern_3.png b/tests/fonts/rendered/paragraph4_nokern_3.png index e98050e..cceca7f 100644 Binary files a/tests/fonts/rendered/paragraph4_nokern_3.png and b/tests/fonts/rendered/paragraph4_nokern_3.png differ diff --git a/tests/fonts/rendered/paragraph5.png b/tests/fonts/rendered/paragraph5.png index ec1d181..637a59d 100644 Binary files a/tests/fonts/rendered/paragraph5.png and b/tests/fonts/rendered/paragraph5.png differ diff --git a/tests/fonts/rendered/paragraph5_2.png b/tests/fonts/rendered/paragraph5_2.png index f9317e3..60cb8fa 100644 Binary files a/tests/fonts/rendered/paragraph5_2.png and b/tests/fonts/rendered/paragraph5_2.png differ diff --git a/tests/fonts/rendered/paragraph5_3.png b/tests/fonts/rendered/paragraph5_3.png index 5967957..f8a280c 100644 Binary files a/tests/fonts/rendered/paragraph5_3.png and b/tests/fonts/rendered/paragraph5_3.png differ diff --git a/tests/fonts/rendered/paragraph5_nokern_32.png b/tests/fonts/rendered/paragraph5_nokern_32.png deleted file mode 100644 index 5967957..0000000 Binary files a/tests/fonts/rendered/paragraph5_nokern_32.png and /dev/null differ diff --git a/tests/test_fonts.nim b/tests/test_fonts.nim index fa92eef..2830074 100644 --- a/tests/test_fonts.nim +++ b/tests/test_fonts.nim @@ -1,7 +1,7 @@ import pixie, pixie/fileformats/png, strformat block: - var font = readFont("tests/fonts/Roboto-Regular.ttf") + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 64 let image = newImage(200, 100) image.fill(rgba(255, 255, 255, 255)) @@ -9,7 +9,7 @@ block: image.writeFile("tests/fonts/image_fill.png") block: - var font = readFont("tests/fonts/Roboto-Regular.ttf") + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 64 let image = newImage(200, 100) image.fill(rgba(255, 255, 255, 255)) @@ -17,14 +17,14 @@ block: image.writeFile("tests/fonts/image_stroke.png") block: - var font = readFont("tests/fonts/Roboto-Regular.ttf") + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 64 let mask = newMask(200, 100) mask.fillText(font, "fill") writeFile("tests/fonts/mask_fill.png", mask.encodePng()) block: - var font = readFont("tests/fonts/Roboto-Regular.ttf") + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 64 let mask = newMask(200, 100) mask.strokeText(font, "stroke") @@ -74,7 +74,7 @@ proc doDiff(rendered: Image, name: string) = diffImage.writeFile(&"tests/fonts/diffs/{name}.png") block: - var font = readFont("tests/fonts/Roboto-Regular.ttf") + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 72 let image = newImage(200, 100) @@ -84,7 +84,7 @@ block: doDiff(image, "basic1") block: - var font = readFont("tests/fonts/Roboto-Regular.ttf") + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 72 let image = newImage(200, 100) @@ -94,7 +94,7 @@ block: doDiff(image, "basic2") block: - var font = readFont("tests/fonts/Roboto-Regular.ttf") + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 24 let image = newImage(200, 100) @@ -104,7 +104,7 @@ block: doDiff(image, "basic3") block: - var font = readFont("tests/fonts/Roboto-Regular.ttf") + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 24 font.lineHeight = 100 @@ -115,7 +115,7 @@ block: doDiff(image, "basic4") block: - var font = readFont("tests/fonts/Ubuntu-Regular.ttf") + var font = readFont("tests/fonts/Ubuntu-Regular_1.ttf") font.size = 24 let image = newImage(200, 100) @@ -125,7 +125,7 @@ block: doDiff(image, "basic5") block: - var font = readFont("tests/fonts/Aclonica-Regular.ttf") + var font = readFont("tests/fonts/Aclonica-Regular_1.ttf") font.size = 24 let image = newImage(200, 100) @@ -135,7 +135,7 @@ block: doDiff(image, "basic6") block: - var font = readFont("tests/fonts/Roboto-Regular.ttf") + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 24 let image = newImage(200, 100) @@ -155,7 +155,7 @@ block: doDiff(image, "basic7") block: - var font = readFont("tests/fonts/Roboto-Regular.ttf") + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 24 let image = newImage(200, 100) @@ -170,7 +170,7 @@ block: doDiff(image, "basic8") block: - var font = readFont("tests/fonts/Roboto-Regular.ttf") + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 24 let image = newImage(200, 100) @@ -191,7 +191,7 @@ const paragraphs = [paragraph, paragraph_2, paragraph_3] block: - var font = readFont("tests/fonts/Roboto-Regular.ttf") + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 16 let image = newImage(1000, 150) @@ -209,7 +209,7 @@ block: doDiff(image, name) block: - var font = readFont("tests/fonts/Roboto-Regular.ttf") + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") font.size = 16 let image = newImage(1000, 150) @@ -228,7 +228,7 @@ block: doDiff(image, name) block: - var font = readFont("tests/fonts/Ubuntu-Regular.ttf") + var font = readFont("tests/fonts/Ubuntu-Regular_1.ttf") font.size = 16 let image = newImage(1000, 150) @@ -246,7 +246,7 @@ block: doDiff(image, name) block: - var font = readFont("tests/fonts/Ubuntu-Regular.ttf") + var font = readFont("tests/fonts/Ubuntu-Regular_1.ttf") font.size = 16 let image = newImage(1000, 150) @@ -265,7 +265,7 @@ block: doDiff(image, name) block: - var font = readFont("tests/fonts/IBMPlexSans-Regular.ttf") + var font = readFont("tests/fonts/IBMPlexSans-Regular_2.ttf") font.size = 16 let image = newImage(1000, 150) @@ -283,7 +283,7 @@ block: doDiff(image, name) block: - var font = readFont("tests/fonts/IBMPlexSans-Regular.ttf") + var font = readFont("tests/fonts/IBMPlexSans-Regular_2.ttf") font.size = 16 let image = newImage(1000, 150) @@ -302,7 +302,7 @@ block: doDiff(image, name) block: - var font = readFont("tests/fonts/NotoSans-Regular.ttf") + var font = readFont("tests/fonts/NotoSans-Regular_4.ttf") font.size = 16 let image = newImage(1000, 150) @@ -320,7 +320,7 @@ block: doDiff(image, name) block: - var font = readFont("tests/fonts/NotoSans-Regular.ttf") + var font = readFont("tests/fonts/NotoSans-Regular_4.ttf") font.size = 16 let image = newImage(1000, 150) @@ -339,7 +339,7 @@ block: doDiff(image, name) block: - var font = readFont("tests/fonts/Pacifico-Regular.ttf") + var font = readFont("tests/fonts/Pacifico-Regular_4.ttf") font.size = 16 let image = newImage(1000, 150) @@ -357,7 +357,7 @@ block: doDiff(image, name) block: - var font = readFont("tests/fonts/Pacifico-Regular.ttf") + var font = readFont("tests/fonts/Pacifico-Regular_4.ttf") font.size = 16 let image = newImage(1000, 150) @@ -374,3 +374,141 @@ block: let name = if i > 0: &"paragraph5_nokern_{i + 1}" else: "paragraph5_nokern" doDiff(image, name) + +block: + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") + font.size = 200 + + let image = newImage(2800, 400) + image.fill(rgba(255, 255, 255, 255)) + image.fillText( + font, + "Shehadcometotheconclusion", + rgba(0, 0, 0, 255), + bounds = image.wh + ) + + doDiff(image, "huge1") + +block: + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") + font.size = 200 + + let image = newImage(2800, 400) + image.fill(rgba(255, 255, 255, 255)) + image.fillText( + font, + "Shehadcometotheconclusion", + rgba(0, 0, 0, 255), + bounds = image.wh, + kerning = false + ) + + doDiff(image, "huge1_nokern") + +block: + var font = readFont("tests/fonts/Ubuntu-Regular_1.ttf") + font.size = 200 + + let image = newImage(2800, 400) + image.fill(rgba(255, 255, 255, 255)) + image.fillText( + font, + "Shehadcometotheconclusion", + rgba(0, 0, 0, 255), + bounds = image.wh + ) + + doDiff(image, "huge2") + +block: + var font = readFont("tests/fonts/Ubuntu-Regular_1.ttf") + font.size = 200 + + let image = newImage(2800, 400) + image.fill(rgba(255, 255, 255, 255)) + image.fillText( + font, + "Shehadcometotheconclusion", + rgba(0, 0, 0, 255), + bounds = image.wh, + kerning = false + ) + + doDiff(image, "huge2_nokern") + +block: + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") + font.size = 200 + + let image = newImage(2800, 400) + image.fill(rgba(255, 255, 255, 255)) + image.fillText( + font, + "Wrapping text to the next line", + rgba(0, 0, 0, 255), + bounds = image.wh + ) + + doDiff(image, "huge3") + +block: + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") + font.size = 200 + + let image = newImage(2800, 400) + image.fill(rgba(255, 255, 255, 255)) + image.fillText( + font, + "Wrapping text to the next line", + rgba(0, 0, 0, 255), + bounds = image.wh, + kerning = false + ) + + doDiff(image, "huge3_nokern") + +block: + var font = readFont("tests/fonts/Roboto-Regular_1.ttf") + font.size = 100 + + let image = newImage(2800, 200) + image.fill(rgba(255, 255, 255, 255)) + image.fillText( + font, + "HA HT HX HY IA IT IX IY MA MT MX MY NA NT NX NY", + rgba(0, 0, 0, 255), + bounds = image.wh + ) + + doDiff(image, "pairs1") + +block: + var font = readFont("tests/fonts/Ubuntu-Regular_1.ttf") + font.size = 100 + + let image = newImage(2800, 200) + image.fill(rgba(255, 255, 255, 255)) + image.fillText( + font, + "V( V) V- V/ V: v; v? v@ VT VV VW VX VY V] Vu Vz V{", + rgba(0, 0, 0, 255), + bounds = image.wh + ) + + doDiff(image, "pairs2") + +block: + var font = readFont("tests/fonts/IBMPlexSans-Regular_2.ttf") + font.size = 100 + + let image = newImage(2800, 200) + image.fill(rgba(255, 255, 255, 255)) + image.fillText( + font, + "B, B. BA BJ BT BW BY Bf Bg Bt bw By", + rgba(0, 0, 0, 255), + bounds = image.wh + ) + + doDiff(image, "pairs3") diff --git a/tests/validate_fonts.nim b/tests/validate_fonts.nim new file mode 100644 index 0000000..131c3e1 --- /dev/null +++ b/tests/validate_fonts.nim @@ -0,0 +1,42 @@ +import pixie, stb_truetype, unicode + +let fontFiles = [ + # "tests/fonts/Roboto-Regular_1.ttf" + # "tests/fonts/Aclonica-Regular_1.ttf" + # "tests/fonts/Ubuntu-Regular_1.ttf" + # "tests/fonts/IBMPlexSans-Regular_2.ttf" + # "tests/fonts/NotoSans-Regular_4.ttf" + "tests/fonts/Pacifico-Regular_4.ttf" +] + +for fontFile in fontFiles: + let stbtt = initFont(readFile(fontFile)) + var font = readFont(fontFile) + + var ascent, descent, lineGap: cint + stbtt.getFontVMetrics(ascent, descent, lineGap) + + doAssert font.typeface.ascent == ascent.float32 + doAssert font.typeface.descent == descent.float32 + doAssert font.typeface.lineGap == lineGap.float32 + + for i in 32 .. 126: + var advanceWidth, leftSideBearing: cint + stbtt.getCodepointHMetrics(Rune(i), advanceWidth, leftSideBearing) + + doAssert font.typeface.getAdvance(Rune(i)) == advanceWidth.float32 + + for i in 32 .. 126: + for j in 32 .. 126: + # echo i, ": ", $Rune(i), " ", j, ": ", $Rune(j) + let + a = stbtt.getCodepointKernAdvance(Rune(i), Rune(j)).float32 + b = font.typeface.getKerningAdjustment(Rune(i), Rune(j)) + if a != b: + # echo fontFile + echo i, ": ", $Rune(i), " ", j, ": ", $Rune(j) + echo "DISAGREE: ", a, " != ", b, " <<<<<<<<<<<<<<<<<<<<<<<<<<<" + # quit() + + # echo stbtt.getCodepointKernAdvance(Rune('r'), Rune('s')).float32 + # echo font.typeface.getKerningAdjustment(Rune('r'), Rune('s'))