The variables that control glyph sizing in TrueType fonts

511 Views Asked by At

I have the following data from ttx fonttools which describes a font binary I have built manually:

<?xml version="1.0" encoding="UTF-8"?>
<ttFont sfntVersion="true" 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="1.0681"/>
    <checkSumAdjustment value="0x0"/>
    <magicNumber value="0x5f0f3cf5"/>
    <flags value="00000000 00000011"/>
    <unitsPerEm value="1000"/>
    <created value="Tue Jan 22 12:25:10 2019"/>
    <modified value="Tue Jan 22 12:25:10 2019"/>
    <xMin value="10"/>
    <yMin value="10"/>
    <xMax value="90"/>
    <yMax value="90"/>
    <macStyle value="00000000 00000000"/>
    <lowestRecPPEM value="3"/>
    <fontDirectionHint value="2"/>
    <indexToLocFormat value="1"/>
    <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="90"/>
    <usWinDescent value="10"/>
    <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>

  <loca>
    <!-- The 'loca' table will be calculated by the compiler -->
  </loca>

  <glyf>

    <!-- The xMin, yMin, xMax and yMax values
         will be recalculated by the compiler. -->

    <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="100" yMax="300">
      <contour>
        <pt x="10" y="10" on="1"/>
        <pt x="90" y="10" on="1"/>
        <pt x="90" y="90" on="1"/>
        <pt x="10" y="90" on="1"/>
        <pt x="10" y="10" on="1"/>
      </contour>
      <instructions/>
    </TTGlyph>

    <TTGlyph name="b" xMin="0" yMin="0" xMax="100" yMax="300">
      <contour>
        <pt x="10" y="10" on="1"/>
        <pt x="90" y="10" on="1"/>
        <pt x="90" y="90" on="1"/>
        <pt x="10" y="90" on="1"/>
        <pt x="10" y="10" on="1"/>
      </contour>
      <instructions/>
    </TTGlyph>

    <TTGlyph name="d" xMin="0" yMin="0" xMax="100" yMax="300">
      <contour>
        <pt x="10" y="10" on="1"/>
        <pt x="90" y="10" on="1"/>
        <pt x="90" y="90" on="1"/>
        <pt x="10" y="90" on="1"/>
        <pt x="10" y="10" on="1"/>
      </contour>
      <instructions/>
    </TTGlyph>

  </glyf>

  <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>

</ttFont>

All 3 symbols are just a square:

<TTGlyph name="d" xMin="0" yMin="0" xMax="100" yMax="300">
  <contour>
    <pt x="10" y="10" on="1"/>
    <pt x="90" y="10" on="1"/>
    <pt x="90" y="90" on="1"/>
    <pt x="10" y="90" on="1"/>
    <pt x="10" y="10" on="1"/>
  </contour>
  <instructions/>
</TTGlyph>

What it shows up for me in the Font viewer is this:

enter image description here

Just some diagonal lines at the bottom corner.

In the browser when the letters b and d are styled with the font, it shows up with pretty much no width or probably height either. It looks like it's a tiny square though.

enter image description here

Wondering what I'm missing. Specifically, the following are the variables involved in the actual display/sizing/positioning of the glyphs.

  • glyf table:
    • numberOfContours
    • xMin
    • yMin
    • xMax
    • yMax
    • endPtsOfContours
    • instructionLength
    • flags
    • xCoordinates
    • yCoordinates
  • head table:
    • unitsPerEm
    • xMin
    • yMin
    • xMax
    • yMax
    • lowestRecPPEM
  • hhea table:
    • ascender
    • descender
    • advanceWidthMax
    • minLeftSideBearing
    • minRightSideBearing
    • xMaxExtent: maxLeftSideBearing + (xMax - xMin),
  • os2 table: I think this isn't necessary, not sure though, but there's a few variables related to size/positioning here that are duplicates of others in other tables.
  • post table:
    • isFixedPitch (monospaced fonts)

I think that's pretty much it. Please let me know if there is any required more than this.

These properties somehow control the size/position of the glyph. I think the glyph display problem above might have something to do with the size/scale of these variables. I'm not sure if they should be on the order-of-magnitude of 100, of 1000, or 10,000, etc. I'm not sure what is the "anchor" size that everything is based off. Maybe it's unitsPerEm, or maybe it's based on the xMin and xMax and yMin and yMax (so 100, 300).

What I currently have for these values are this:

  • glyf table:
    • numberOfContours: 1
    • xMin: 0
    • yMin: 0
    • xMax: 100
    • yMax: 300
    • endPtsOfContours: lastIndex
    • instructionLength: 0
    • flags: flags
    • xCoordinates: relativeCoordinates
    • yCoordinates: relativeCoordinates
  • head table:
    • unitsPerEm: 2000
    • xMin: 0
    • yMin: 0
    • xMax: 100
    • yMax: 300
    • lowestRecPPEM: 3
  • hhea table:
    • ascender: 200
    • descender: -100 (but it always becomes 100, so maybe - isn't necessary)
    • advanceWidthMax: glyphs[i].advanceWidth max
    • minLeftSideBearing: 0
    • minRightSideBearing: 100
    • xMaxExtent: maxLeftSideBearing + (xMax - xMin),
  • os2 table: I think this isn't necessary, not sure though, but there's a few variables related to size/positioning here that are duplicates of others in other tables.
  • post table:
    • isFixedPitch true (since it's simpler for now)

My questions are:

  1. What these values should be (in the list above).
  2. What the "anchor" value is, where everything is relative to that scale/size (if one exists).
  3. How I go about placing a glyph into a bounding box so that it appears flush with whatever other font there is on the screen (or at least it's relatively close to the same size). In my font I only have characters b and d, so if I write abcd I should see a□c□ if my character is just drawing a simple square for each (and the sizing should be about the same). Right now I just see a small diagonal line.
0

There are 0 best solutions below