Я начинаю с этой структуры данных, содержащей мои операции CharStrings (поэтому в основном эти 3 элемента в массиве JSON образуют 3 символа шрифта):
[
{
"name": "a",
"type": "CHARSTRING",
"value": [
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": 10
},
"dy": {
"type": "NUMBER",
"value": 160
},
"name": {
"type": "OP",
"value": 5
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": 0
},
"dy": {
"type": "NUMBER",
"value": -20
},
"name": {
"type": "OP",
"value": 21
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": 80
},
"dy": {
"type": "NUMBER",
"value": 20
},
"name": {
"type": "OP",
"value": 5
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": -80
},
"dy": {
"type": "NUMBER",
"value": 0
},
"name": {
"type": "OP",
"value": 5
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": 80
},
"dy": {
"type": "NUMBER",
"value": 0
},
"name": {
"type": "OP",
"value": 21
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": -80
},
"dy": {
"type": "NUMBER",
"value": -20
},
"name": {
"type": "OP",
"value": 5
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": 0
},
"dy": {
"type": "NUMBER",
"value": 60
},
"name": {
"type": "OP",
"value": 21
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": 80
},
"dy": {
"type": "NUMBER",
"value": -60
},
"name": {
"type": "OP",
"value": 5
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": 0
},
"dy": {
"type": "NUMBER",
"value": 60
},
"name": {
"type": "OP",
"value": 21
}
}
}
]
},
{
"name": "b",
"type": "CHARSTRING",
"value": [
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": 10
},
"dy": {
"type": "NUMBER",
"value": 20
},
"name": {
"type": "OP",
"value": 5
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": 0
},
"dy": {
"type": "NUMBER",
"value": 180
},
"name": {
"type": "OP",
"value": 21
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": 0
},
"dy": {
"type": "NUMBER",
"value": -100
},
"name": {
"type": "OP",
"value": 5
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": 30
},
"dy": {
"type": "NUMBER",
"value": 0
},
"name": {
"type": "OP",
"value": 21
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": -30
},
"dy": {
"type": "NUMBER",
"value": 100
},
"name": {
"type": "OP",
"value": 21
}
}
}
]
},
{
"name": "d",
"type": "CHARSTRING",
"value": [
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": 90
},
"dy": {
"type": "NUMBER",
"value": 20
},
"name": {
"type": "OP",
"value": 5
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": 0
},
"dy": {
"type": "NUMBER",
"value": 180
},
"name": {
"type": "OP",
"value": 21
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": 0
},
"dy": {
"type": "NUMBER",
"value": -100
},
"name": {
"type": "OP",
"value": 5
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": -30
},
"dy": {
"type": "NUMBER",
"value": 0
},
"name": {
"type": "OP",
"value": 21
}
}
},
{
"name": "CharString Op",
"fields": {
"dx": {
"type": "NUMBER",
"value": 30
},
"dy": {
"type": "NUMBER",
"value": 100
},
"name": {
"type": "OP",
"value": 21
}
}
}
]
}
]
и в конечном итоге это из ttx Regular.otf
:
<?xml version="1.0" encoding="UTF-8"?>
<ttFont sfntVersion="OTTO" ttLibVersion="3.36">
<GlyphOrder>
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
<GlyphID id="0" name=".notdef"/>
<GlyphID id="1" name="b"/>
<GlyphID id="2" name="d"/>
</GlyphOrder>
<head>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="1.0"/>
<fontRevision value="0.0"/>
<checkSumAdjustment value="0x0"/>
<magicNumber value="0x5f0f3cf5"/>
<flags value="00000000 00000011"/>
<unitsPerEm value="1000"/>
<created value="Tue Jan 22 09:38:57 2019"/>
<modified value="Tue Jan 22 09:38:57 2019"/>
<xMin value="0"/>
<yMin value="0"/>
<xMax value="90"/>
<yMax value="0"/>
<macStyle value="00000000 00000000"/>
<lowestRecPPEM value="3"/>
<fontDirectionHint value="2"/>
<indexToLocFormat value="0"/>
<glyphDataFormat value="0"/>
</head>
<hhea>
<tableVersion value="0x00010000"/>
<ascent value="200"/>
<descent value="100"/>
<lineGap value="0"/>
<advanceWidthMax value="90"/>
<minLeftSideBearing value="0"/>
<minRightSideBearing value="0"/>
<xMaxExtent value="0"/>
<caretSlopeRise value="1"/>
<caretSlopeRun value="0"/>
<caretOffset value="0"/>
<reserved0 value="0"/>
<reserved1 value="0"/>
<reserved2 value="0"/>
<reserved3 value="0"/>
<metricDataFormat value="0"/>
<numberOfHMetrics value="3"/>
</hhea>
<maxp>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="0x10000"/>
<numGlyphs value="3"/>
<maxPoints value="5"/>
<maxContours value="1"/>
<maxCompositePoints value="0"/>
<maxCompositeContours value="0"/>
<maxZones value="1"/>
<maxTwilightPoints value="0"/>
<maxStorage value="0"/>
<maxFunctionDefs value="0"/>
<maxInstructionDefs value="0"/>
<maxStackElements value="0"/>
<maxSizeOfInstructions value="0"/>
<maxComponentElements value="0"/>
<maxComponentDepth value="0"/>
</maxp>
<OS_2>
<!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
will be recalculated by the compiler -->
<version value="5"/>
<xAvgCharWidth value="90"/>
<usWeightClass value="500"/>
<usWidthClass value="5"/>
<fsType value="00000000 00000000"/>
<ySubscriptXSize value="650"/>
<ySubscriptYSize value="699"/>
<ySubscriptXOffset value="0"/>
<ySubscriptYOffset value="140"/>
<ySuperscriptXSize value="650"/>
<ySuperscriptYSize value="699"/>
<ySuperscriptXOffset value="0"/>
<ySuperscriptYOffset value="479"/>
<yStrikeoutSize value="49"/>
<yStrikeoutPosition value="258"/>
<sFamilyClass value="0"/>
<panose>
<bFamilyType value="0"/>
<bSerifStyle value="0"/>
<bWeight value="0"/>
<bProportion value="0"/>
<bContrast value="0"/>
<bStrokeVariation value="0"/>
<bArmStyle value="0"/>
<bLetterForm value="0"/>
<bMidline value="0"/>
<bXHeight value="0"/>
</panose>
<ulUnicodeRange1 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
<achVendID value="XXXX"/>
<fsSelection value="00000000 01000000"/>
<usFirstCharIndex value="97"/>
<usLastCharIndex value="100"/>
<sTypoAscender value="200"/>
<sTypoDescender value="100"/>
<sTypoLineGap value="0"/>
<usWinAscent value="0"/>
<usWinDescent value="0"/>
<ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
<ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
<sxHeight value="100"/>
<sCapHeight value="40"/>
<usDefaultChar value="0"/>
<usBreakChar value="0"/>
<usMaxContext value="0"/>
<usLowerOpticalPointSize value="0.0"/>
<usUpperOpticalPointSize value="0.15"/>
</OS_2>
<hmtx>
<mtx name=".notdef" width="90" lsb="0"/>
<mtx name="b" width="90" lsb="0"/>
<mtx name="d" width="90" lsb="0"/>
</hmtx>
<cmap>
<tableVersion version="0"/>
<cmap_format_4 platformID="3" platEncID="1" language="0">
<map code="0x62" name="b"/><!-- LATIN SMALL LETTER B -->
<map code="0x64" name="d"/><!-- LATIN SMALL LETTER D -->
</cmap_format_4>
</cmap>
<name>
<namerecord nameID="6" platformID="1" platEncID="0" langID="0x0" unicode="True">
Foo
</namerecord>
<namerecord nameID="1" platformID="1" platEncID="0" langID="0x0" unicode="True">
Foo
</namerecord>
<namerecord nameID="2" platformID="1" platEncID="0" langID="0x0" unicode="True">
Regular
</namerecord>
<namerecord nameID="3" platformID="1" platEncID="0" langID="0x0" unicode="True">
foo
</namerecord>
<namerecord nameID="4" platformID="1" platEncID="0" langID="0x0" unicode="True">
Foo Regular
</namerecord>
<namerecord nameID="13" platformID="1" platEncID="0" langID="0x0" unicode="True">
Licensed under the Apache License, Version 2.0
</namerecord>
<namerecord nameID="5" platformID="1" platEncID="0" langID="0x0" unicode="True">
Version 1.000
</namerecord>
</name>
<post>
<formatType value="3.0"/>
<italicAngle value="0.0"/>
<underlinePosition value="0"/>
<underlineThickness value="0"/>
<isFixedPitch value="0"/>
<minMemType42 value="0"/>
<maxMemType42 value="0"/>
<minMemType1 value="0"/>
<maxMemType1 value="0"/>
</post>
<CFF2>
<major value="2"/>
<minor value="0"/>
<CFFFont name="CFF2Font">
<FontMatrix value="0.001 0.0 0.0 0.001 0.0 0.0"/>
<FDArray>
<FontDict index="0">
<Private>
<BlueScale value="0.039625"/>
<BlueShift value="7"/>
<BlueFuzz value="1"/>
</Private>
</FontDict>
</FDArray>
<CharStrings>
<CharString name=".notdef">
10</CharString>
<CharString name="b">
10 20 rlineto
0</CharString>
<CharString name="d">
90 20 rlineto
0</CharString>
</CharStrings>
</CFFFont>
<GlobalSubrs>
<!-- The 'index' attribute is only for humans; it is ignored when parsed. -->
</GlobalSubrs>
</CFF2>
</ttFont>
Если я изменю все в CharStrings на 0 (все значения dx и dy и т. Д., А не операторы), это приведет к:
...
<CFF2>
<major value="2"/>
<minor value="0"/>
<CFFFont name="CFF2Font">
<FontMatrix value="0.001 0.0 0.0 0.001 0.0 0.0"/>
<FDArray>
<FontDict index="0">
<Private>
<BlueScale value="0.039625"/>
<BlueShift value="7"/>
<BlueFuzz value="1"/>
</Private>
</FontDict>
</FDArray>
<CharStrings>
<CharString name=".notdef">
0 0 rlineto
0 0 rmoveto
0 0 rlineto
0 0 rlineto
0 0 rmoveto
0 0 rlineto
0 0 rmoveto
0 0 rlineto
0 0 rmoveto
</CharString>
<CharString name="b">
0 0 rlineto
0 0 rmoveto
0 0 rlineto
0 0 rmoveto
0 0 rmoveto
</CharString>
<CharString name="d">
0 0 rlineto
0 0 rmoveto
0 0 rlineto
0 0 rmoveto
0 0 rmoveto
</CharString>
</CharStrings>
</CFFFont>
<GlobalSubrs>
<!-- The 'index' attribute is only for humans; it is ignored when parsed. -->
</GlobalSubrs>
</CFF2>
</ttFont>
Это коды операций для JSON в начале:
var charStringCodes = {
rlineto: 5,
rmoveto : 21
}
В основном мой вопрос, почему вывод такой странный. Я еще не заставил шрифт работать, только ttx / fonttools настолько близко подошли к отладке. Но я пока не понимаю, почему при использовании регулярных входных данных для точек кривой это практически не дает выходных данных, а замена их на 0 приводит к почти полному выходному сигналу.