示例#1
0
    def build(self):
        # TODO: Consider emitting multiple subtables to save space.
        # Partition the marks and bases into disjoint subsets, so that
        # MarkBasePos rules would only access glyphs from a single
        # subset. This would likely lead to smaller mark/base
        # matrices, so we might be able to omit many of the empty
        # anchor tables that we currently produce. Of course, this
        # would only work if the MarkBasePos rules of real-world fonts
        # allow partitioning into multiple subsets. We should find out
        # whether this is the case; if so, implement the optimization.

        st = otTables.MarkBasePos()
        st.Format = 1
        st.MarkCoverage = \
            self.buildCoverage_(self.marks, otTables.MarkCoverage)
        markClasses = self.buildMarkClasses_(self.marks)
        st.ClassCount = len(markClasses)
        self.setMarkArray_(self.marks, markClasses, st)

        st.BaseCoverage = \
            self.buildCoverage_(self.bases, otTables.BaseCoverage)
        st.BaseArray = otTables.BaseArray()
        st.BaseArray.BaseCount = len(st.BaseCoverage.glyphs)
        st.BaseArray.BaseRecord = []
        for base in st.BaseCoverage.glyphs:
            baserec = otTables.BaseRecord()
            st.BaseArray.BaseRecord.append(baserec)
            baserec.BaseAnchor = []
            for markClass in sorted(markClasses.keys(), key=markClasses.get):
                baserec.BaseAnchor.append(self.bases[base].get(markClass))

        return self.buildLookup_([st])
示例#2
0
def buildMarkBasePosSubtable(marks, bases, glyphMap):
    """Build a single MarkBasePos subtable.

    a1, a2, a3, a4, a5 = buildAnchor(500, 100), ...
    marks = {"acute": (0, a1), "grave": (0, a1), "cedilla": (1, a2)}
    bases = {"a": {0: a3, 1: a5}, "b": {0: a4, 1: a5}}
    """
    self = ot.MarkBasePos()
    self.Format = 1
    self.MarkCoverage = buildCoverage(marks, glyphMap)
    self.MarkArray = buildMarkArray(marks, glyphMap)
    self.ClassCount = max([mc for mc, _ in marks.values()]) + 1
    self.BaseCoverage = buildCoverage(bases, glyphMap)
    self.BaseArray = buildBaseArray(bases, self.ClassCount, glyphMap)
    return self
示例#3
0
def test_splitMarkBasePos():
    from fontTools.otlLib.builder import buildAnchor, buildMarkBasePosSubtable

    marks = {
        "acutecomb": (0, buildAnchor(0, 600)),
        "gravecomb": (0, buildAnchor(0, 590)),
        "cedillacomb": (1, buildAnchor(0, 0)),
    }
    bases = {
        "a": {
            0: buildAnchor(350, 500),
            1: None,
        },
        "c": {
            0: buildAnchor(300, 700),
            1: buildAnchor(300, 0),
        },
    }
    glyphOrder = ["a", "c", "acutecomb", "gravecomb", "cedillacomb"]
    glyphMap = {g: i for i, g in enumerate(glyphOrder)}

    oldSubTable = buildMarkBasePosSubtable(marks, bases, glyphMap)
    oldSubTable.MarkCoverage.Format = oldSubTable.BaseCoverage.Format = 1
    newSubTable = otTables.MarkBasePos()

    ok = otTables.splitMarkBasePos(oldSubTable,
                                   newSubTable,
                                   overflowRecord=None)

    assert ok
    assert oldSubTable.Format == newSubTable.Format
    assert oldSubTable.MarkCoverage.glyphs == ["acutecomb", "gravecomb"]
    assert newSubTable.MarkCoverage.glyphs == ["cedillacomb"]
    assert newSubTable.MarkCoverage.Format == 1
    assert oldSubTable.BaseCoverage.glyphs == newSubTable.BaseCoverage.glyphs
    assert newSubTable.BaseCoverage.Format == 1
    assert oldSubTable.ClassCount == newSubTable.ClassCount == 1
    assert oldSubTable.MarkArray.MarkCount == 2
    assert newSubTable.MarkArray.MarkCount == 1
    assert oldSubTable.BaseArray.BaseCount == newSubTable.BaseArray.BaseCount
    assert newSubTable.BaseArray.BaseRecord[0].BaseAnchor[0] is None
    assert newSubTable.BaseArray.BaseRecord[1].BaseAnchor[0] == buildAnchor(
        300, 0)
示例#4
0
def test_splitMarkBasePos():
    from fontTools.otlLib.builder import buildAnchor, buildMarkBasePosSubtable

    marks = {
        "acutecomb": (0, buildAnchor(0, 600)),
        "gravecomb": (0, buildAnchor(0, 590)),
        "cedillacomb": (1, buildAnchor(0, 0)),
    }
    bases = {
        "a": {
            0: buildAnchor(350, 500),
            1: None,
        },
        "c": {
            0: buildAnchor(300, 700),
            1: buildAnchor(300, 0),
        },
    }
    glyphOrder = ["a", "c", "acutecomb", "gravecomb", "cedillacomb"]
    glyphMap = {g: i for i, g in enumerate(glyphOrder)}

    oldSubTable = buildMarkBasePosSubtable(marks, bases, glyphMap)
    newSubTable = otTables.MarkBasePos()

    ok = otTables.splitMarkBasePos(oldSubTable,
                                   newSubTable,
                                   overflowRecord=None)

    assert ok

    assert getXML(oldSubTable.toXML) == [
        '<MarkBasePos Format="1">',
        '  <MarkCoverage>',
        '    <Glyph value="acutecomb"/>',
        '    <Glyph value="gravecomb"/>',
        '  </MarkCoverage>',
        '  <BaseCoverage>',
        '    <Glyph value="a"/>',
        '    <Glyph value="c"/>',
        '  </BaseCoverage>',
        '  <!-- ClassCount=1 -->',
        '  <MarkArray>',
        '    <!-- MarkCount=2 -->',
        '    <MarkRecord index="0">',
        '      <Class value="0"/>',
        '      <MarkAnchor Format="1">',
        '        <XCoordinate value="0"/>',
        '        <YCoordinate value="600"/>',
        '      </MarkAnchor>',
        '    </MarkRecord>',
        '    <MarkRecord index="1">',
        '      <Class value="0"/>',
        '      <MarkAnchor Format="1">',
        '        <XCoordinate value="0"/>',
        '        <YCoordinate value="590"/>',
        '      </MarkAnchor>',
        '    </MarkRecord>',
        '  </MarkArray>',
        '  <BaseArray>',
        '    <!-- BaseCount=2 -->',
        '    <BaseRecord index="0">',
        '      <BaseAnchor index="0" Format="1">',
        '        <XCoordinate value="350"/>',
        '        <YCoordinate value="500"/>',
        '      </BaseAnchor>',
        '    </BaseRecord>',
        '    <BaseRecord index="1">',
        '      <BaseAnchor index="0" Format="1">',
        '        <XCoordinate value="300"/>',
        '        <YCoordinate value="700"/>',
        '      </BaseAnchor>',
        '    </BaseRecord>',
        '  </BaseArray>',
        '</MarkBasePos>',
    ]

    assert getXML(newSubTable.toXML) == [
        '<MarkBasePos Format="1">',
        '  <MarkCoverage>',
        '    <Glyph value="cedillacomb"/>',
        '  </MarkCoverage>',
        '  <BaseCoverage>',
        '    <Glyph value="a"/>',
        '    <Glyph value="c"/>',
        '  </BaseCoverage>',
        '  <!-- ClassCount=1 -->',
        '  <MarkArray>',
        '    <!-- MarkCount=1 -->',
        '    <MarkRecord index="0">',
        '      <Class value="0"/>',
        '      <MarkAnchor Format="1">',
        '        <XCoordinate value="0"/>',
        '        <YCoordinate value="0"/>',
        '      </MarkAnchor>',
        '    </MarkRecord>',
        '  </MarkArray>',
        '  <BaseArray>',
        '    <!-- BaseCount=2 -->',
        '    <BaseRecord index="0">',
        '      <BaseAnchor index="0" empty="1"/>',
        '    </BaseRecord>',
        '    <BaseRecord index="1">',
        '      <BaseAnchor index="0" Format="1">',
        '        <XCoordinate value="300"/>',
        '        <YCoordinate value="0"/>',
        '      </BaseAnchor>',
        '    </BaseRecord>',
        '  </BaseArray>',
        '</MarkBasePos>',
    ]