Exemplo n.º 1
0
 def loadFromFontTools(self, subtable, lookup):
     super(GPOSLookupType5, self).loadFromFontTools(subtable, lookup)
     self.MarkCoverage = Coverage().loadFromFontTools(subtable.MarkCoverage)
     self.LigatureCoverage = Coverage().loadFromFontTools(subtable.LigatureCoverage)
     self.MarkArray = MarkArray().loadFromFontTools(subtable.MarkArray)
     self.LigatureArray = LigatureArray().loadFromFontTools(subtable.LigatureArray)
     return self
Exemplo n.º 2
0
 def loadFromFontTools(self, subtable, lookup):
     super(GPOSLookupType2Format1, self).loadFromFontTools(subtable, lookup)
     self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
     self.ValueFormat1 = subtable.ValueFormat1
     self.ValueFormat2 = subtable.ValueFormat2
     self.PairSet = [PairSet().loadFromFontTools(pairSet) for pairSet in subtable.PairSet]
     return self
Exemplo n.º 3
0
 def loadFromFontTools(self, subtable, lookup):
     super(GPOSLookupType6, self).loadFromFontTools(subtable, lookup)
     self.Mark1Coverage = Coverage().loadFromFontTools(subtable.Mark1Coverage)
     self.Mark2Coverage = Coverage().loadFromFontTools(subtable.Mark2Coverage)
     self.Mark1Array = MarkArray().loadFromFontTools(subtable.Mark1Array)
     self.Mark2Array = Mark2Array().loadFromFontTools(subtable.Mark2Array)
     return self
Exemplo n.º 4
0
 def loadFromFontTools(self, subtable, lookup):
     super(GSUBLookupType1Format2, self).loadFromFontTools(subtable, lookup)
     # fontTools has a custom implementation of this
     # subtable type, so it needs to be converted
     coverage = []
     self.Substitute = []
     for glyphName, alternate in sorted(subtable.mapping.items()):
         coverage.append(glyphName)
         self.Substitute.append(alternate)
     self.Coverage = Coverage().loadFromFontTools(coverage)
     return self
Exemplo n.º 5
0
 def loadFromFontTools(self, subtable, lookup):
     super(GSUBLookupType4, self).loadFromFontTools(subtable, lookup)
     # fontTools has a custom implementation of this
     # subtable type, so it needs to be converted
     coverage = []
     self.LigatureSet = []
     for glyphName, ligature in subtable.ligatures.items():
         ligatureSet = LigatureSet().loadFromFontTools(ligature)
         self.LigatureSet.append(ligatureSet)
         coverage.append(glyphName)
     self.Coverage = Coverage().loadFromFontTools(coverage)
     return self
Exemplo n.º 6
0
 def loadFromFontTools(self, subtable, lookup):
     super(GSUBLookupType3, self).loadFromFontTools(subtable, lookup)
     # fontTools has a custom implementation of this
     # subtable type, so it needs to be converted
     coverage = []
     self.AlternateSet = []
     for glyphName, alternates in subtable.alternates.items():
         coverage.append(glyphName)
         alternateSet = AlternateSet().loadFromFontTools(alternates)
         self.AlternateSet.append(alternateSet)
     self.Coverage = Coverage().loadFromFontTools(coverage)
     self.AlternateSetCount = len(self.AlternateSet)
     return self
Exemplo n.º 7
0
 def loadFromFontTools(self, subtable, lookup):
     super(GSUBLookupType2, self).loadFromFontTools(subtable, lookup)
     try:
         self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
         self.Sequence = [
             Sequence().loadFromFontTools(sequence)
             for sequence in subtable.Sequence
         ]
     except AttributeError:
         # the API for MultipleSubst lookups changed with fonttools 3.1:
         # https://github.com/fonttools/fonttools/pull/364
         mapping = getattr(subtable, "mapping", {})
         coverage = sorted(mapping.keys())
         self.Coverage = Coverage(coverage)
         self.Sequence = [Sequence(mapping[glyph]) for glyph in coverage]
     return self
Exemplo n.º 8
0
 def loadFromFontTools(self, subtable, lookup):
     super(GPOSLookupType7Format3, self).loadFromFontTools(subtable, lookup)
     self.Coverage = [Coverage().loadFromFontTools(coverage) for coverage in subtable.Coverage]
     self.GlyphCount = subtable.GlyphCount
     self.PosCount = subtable.PosCount
     self.PosLookupRecord = [PosLookupRecord().loadFromFontTools(record) for record in subtable.PosLookupRecord]
     return self
Exemplo n.º 9
0
 def loadFromFontTools(self, subtable, lookup):
     super(GSUBLookupType6Format1, self).loadFromFontTools(subtable, lookup)
     self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
     self.ChainSubRuleSet = [
         ChainSubRuleSet().loadFromFontTools(chainSubRuleSet)
         for chainSubRuleSet in subtable.ChainSubRuleSet
     ]
     return self
Exemplo n.º 10
0
 def loadFromFontTools(self, subtable, lookup):
     super(GPOSLookupType2Format2, self).loadFromFontTools(subtable, lookup)
     self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
     self.ValueFormat1 = subtable.ValueFormat1
     self.ValueFormat2 = subtable.ValueFormat2
     self.ClassDef1 = ClassDef().loadFromFontTools(subtable.ClassDef1)
     self.ClassDef2 = ClassDef().loadFromFontTools(subtable.ClassDef2)
     self.Class1Record = [Class1Record().loadFromFontTools(record) for record in subtable.Class1Record]
     return self
Exemplo n.º 11
0
class GPOSLookupType3(BaseSubTable):

    """
    Deviation from spec:
    - EntryExitRecordCount attribute is not implemented.
    """

    __slots__ = ["Coverage", "EntryExitRecord"] + globalPositionSubTableSlots

    def __init__(self):
        super(GPOSLookupType3, self).__init__()
        self.PosFormat = 1
        self.Coverage = None
        self.EntryExitRecord = []

    def loadFromFontTools(self, subtable, lookup):
        super(GPOSLookupType3, self).loadFromFontTools(subtable, lookup)
        self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
        self.EntryExitRecord = [EntryExitRecord().loadFromFontTools(entryExitRecord) for entryExitRecord in subtable.EntryExitRecord]
        return self

    def process(self, processed, glyphRecords, featureTag):
        performedPos = False
        currentRecord = glyphRecords[0]
        currentGlyph = currentRecord.glyphName
        if currentGlyph in self.Coverage:
            if not self._lookupFlagCoversGlyph(currentGlyph):
                nextRecord, nextRecordIndex = self._nextRecord(glyphRecords[1:])
                if nextRecord is not None:
                    nextGlyph = nextRecord.glyphName
                    if nextGlyph in self.Coverage:
                        performedPos = True
                        exitIndex = self.Coverage.index(currentGlyph)
                        exitAnchor = self.EntryExitRecord[exitIndex].ExitAnchor
                        entryIndex = self.Coverage.index(nextGlyph)
                        entryAnchor = self.EntryExitRecord[entryIndex].EntryAnchor
                        if exitAnchor is not None and entryAnchor is not None:
                            currentRecord.xAdvance += exitAnchor.XCoordinate - currentRecord.advanceWidth - entryAnchor.XCoordinate
                            currentRecord.yAdvance += exitAnchor.YCoordinate - currentRecord.advanceHeight - entryAnchor.YCoordinate
                        processed.append(currentRecord)
                        glyphRecords = glyphRecords[1:]
        return processed, glyphRecords, performedPos
Exemplo n.º 12
0
 def loadFromFontTools(self, subtable, lookup):
     super(GSUBLookupType1Format2, self).loadFromFontTools(subtable, lookup)
     # fontTools has a custom implementation of this
     # subtable type, so it needs to be converted
     coverage = []
     self.Substitute = []
     for glyphName, alternate in sorted(subtable.mapping.items()):
         coverage.append(glyphName)
         self.Substitute.append(alternate)
     self.Coverage = Coverage().loadFromFontTools(coverage)
     return self
Exemplo n.º 13
0
 def loadFromFontTools(self, subtable, lookup):
     super(GSUBLookupType5Format2, self).loadFromFontTools(subtable, lookup)
     self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
     self.ClassDef = ClassDef().loadFromFontTools(subtable.ClassDef)
     self.SubClassSet = []
     for subClassSet in subtable.SubClassSet:
         if subClassSet is None:
             self.SubClassSet.append(None)
         else:
             self.SubClassSet.append(
                 SubClassSet().loadFromFontTools(subClassSet))
     return self
Exemplo n.º 14
0
class GSUBLookupType3(BaseSubTable):
    """
    Deviation from spec:
    - AlternateSetCount attribute is not implemented.
    """

    __slots__ = ["Coverage", "AlternateSet", "AlternateSetCount"
                 ] + globalSubstitutionSubTableSlots

    def __init__(self):
        super(GSUBLookupType3, self).__init__()
        self.SubstFormat = 1
        self.AlternateSet = []
        self.Coverage = None
        self.AlternateSetCount = 0

    def loadFromFontTools(self, subtable, lookup):
        super(GSUBLookupType3, self).loadFromFontTools(subtable, lookup)
        # fontTools has a custom implementation of this
        # subtable type, so it needs to be converted
        coverage = []
        self.AlternateSet = []
        for glyphName, alternates in subtable.alternates.items():
            coverage.append(glyphName)
            alternateSet = AlternateSet().loadFromFontTools(alternates)
            self.AlternateSet.append(alternateSet)
        self.Coverage = Coverage().loadFromFontTools(coverage)
        self.AlternateSetCount = len(self.AlternateSet)
        return self

    def process(self, processed, glyphRecords, featureTag):
        performedSub = False
        currentRecord = glyphRecords[0]
        currentGlyph = currentRecord.glyphName
        if currentGlyph in self.Coverage:
            if not self._lookupFlagCoversGlyph(currentGlyph):
                performedSub = True
                index = self.Coverage.index(currentGlyph)
                alternateSet = self.AlternateSet[index]
                alternates = alternateSet.Alternate
                # special behavior for rand
                if featureTag == "rand":
                    currentRecord.saveState(currentRecord.glyphName)
                    currentRecord.glyphName = choice(alternates)
                # standard behavior
                else:
                    if currentRecord._alternatesReference != currentGlyph:
                        currentRecord._alternatesReference = currentGlyph
                        currentRecord.alternates = []
                    currentRecord.alternates.extend(alternates)
                processed.append(currentRecord)
                glyphRecords = glyphRecords[1:]
        return processed, glyphRecords, performedSub
Exemplo n.º 15
0
 def loadFromFontTools(self, subtable, lookup):
     super(GSUBLookupType4, self).loadFromFontTools(subtable, lookup)
     # fontTools has a custom implementation of this
     # subtable type, so it needs to be converted
     coverage = []
     self.LigatureSet = []
     for glyphName, ligature in subtable.ligatures.items():
         ligatureSet = LigatureSet().loadFromFontTools(ligature)
         self.LigatureSet.append(ligatureSet)
         coverage.append(glyphName)
     self.Coverage = Coverage().loadFromFontTools(coverage)
     return self
Exemplo n.º 16
0
class GSUBLookupType3(BaseSubTable):

    """
    Deviation from spec:
    - AlternateSetCount attribute is not implemented.
    """

    __slots__ = ["Coverage", "AlternateSet", "AlternateSetCount"] + globalSubstitutionSubTableSlots

    def __init__(self):
        super(GSUBLookupType3, self).__init__()
        self.SubstFormat = 1
        self.AlternateSet = []
        self.Coverage = None
        self.AlternateSetCount = 0

    def loadFromFontTools(self, subtable, lookup):
        super(GSUBLookupType3, self).loadFromFontTools(subtable, lookup)
        # fontTools has a custom implementation of this
        # subtable type, so it needs to be converted
        coverage = []
        self.AlternateSet = []
        for glyphName, alternates in subtable.alternates.items():
            coverage.append(glyphName)
            alternateSet = AlternateSet().loadFromFontTools(alternates)
            self.AlternateSet.append(alternateSet)
        self.Coverage = Coverage().loadFromFontTools(coverage)
        self.AlternateSetCount = len(self.AlternateSet)
        return self

    def process(self, processed, glyphRecords, featureTag):
        performedSub = False
        currentRecord = glyphRecords[0]
        currentGlyph = currentRecord.glyphName
        if currentGlyph in self.Coverage:
            if not self._lookupFlagCoversGlyph(currentGlyph):
                performedSub = True
                index = self.Coverage.index(currentGlyph)
                alternateSet = self.AlternateSet[index]
                alternates = alternateSet.Alternate
                # special behavior for rand
                if featureTag == "rand":
                    currentRecord.saveState(currentRecord.glyphName)
                    currentRecord.glyphName = choice(alternates)
                # standard behavior
                else:
                    if currentRecord._alternatesReference != currentGlyph:
                        currentRecord._alternatesReference = currentGlyph
                        currentRecord.alternates = []
                    currentRecord.alternates.extend(alternates)
                processed.append(currentRecord)
                glyphRecords = glyphRecords[1:]
        return processed, glyphRecords, performedSub
Exemplo n.º 17
0
 def loadFromFontTools(self, subtable, lookup):
     super(GPOSLookupType7Format2, self).loadFromFontTools(subtable, lookup)
     self.PosFormat = 2
     self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
     self.ClassDef = ClassDef().loadFromFontTools(subtable.ClassDef)
     self.PosClassSet = []
     for posClassSet in subtable.PosClassSet:
         if posClassSet is None:
             self.PosClassSet.append(None)
         else:
             self.PosClassSet.append(PosClassSet().loadFromFontTools(posClassSet))
     return self
Exemplo n.º 18
0
class GPOSLookupType2Format1(BaseSubTable):

    """
    Deviation from spec:
    - PairSetCount attribute is not implemented.
    """

    __slots__ = ["Coverage", "ValueFormat1", "ValueFormat2", "PairSet"] + globalPositionSubTableSlots

    def __init__(self):
        super(GPOSLookupType2Format1, self).__init__()
        self.PosFormat = 1
        self.Coverage = None
        self.ValueFormat1 = None
        self.ValueFormat2 = None
        self.PairSet = []

    def loadFromFontTools(self, subtable, lookup):
        super(GPOSLookupType2Format1, self).loadFromFontTools(subtable, lookup)
        self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
        self.ValueFormat1 = subtable.ValueFormat1
        self.ValueFormat2 = subtable.ValueFormat2
        self.PairSet = [PairSet().loadFromFontTools(pairSet) for pairSet in subtable.PairSet]
        return self

    def process(self, processed, glyphRecords, featureTag):
        performedPos = False
        currentRecord = glyphRecords[0]
        currentGlyph = currentRecord.glyphName
        if currentGlyph in self.Coverage:
            if not self._lookupFlagCoversGlyph(currentGlyph):
                nextRecord, nextRecordIndex = self._nextRecord(glyphRecords[1:])
                nextRecordIndex += 1
                if nextRecord is not None:
                    nextGlyph = nextRecord.glyphName
                    pairSetIndex = self.Coverage.index(currentGlyph)
                    pairSet = self.PairSet[pairSetIndex]
                    for pairValueRecord in pairSet.PairValueRecord:
                        if nextGlyph == pairValueRecord.SecondGlyph:
                            performedPos = True
                            if self.ValueFormat1:
                                currentRecord += pairValueRecord.Value1
                            if self.ValueFormat2:
                                nextRecord += pairValueRecord.Value2
                            if self.ValueFormat2:
                                processed.extend(glyphRecords[:nextRecordIndex+1])
                                glyphRecords = glyphRecords[nextRecordIndex+1:]
                            else:
                                processed.append(currentRecord)
                                glyphRecords = glyphRecords[1:]
                            break
        return processed, glyphRecords, performedPos
Exemplo n.º 19
0
class GSUBLookupType1Format2(BaseSubTable):

    """
    Deviation from spec:
    - fontTools interprets Lookup Type 1 formats 1 and 2
      into the same object structure. As such, only format 2
      is needed.
    - GlyphCount attribute is not implemented.
    """

    __slots__ = ["Coverage", "Substitute"] + globalSubstitutionSubTableSlots

    def __init__(self):
        super(GSUBLookupType1Format2, self).__init__()
        self.SubstFormat = 2
        self.Substitute = []
        self.Coverage = None

    def loadFromFontTools(self, subtable, lookup):
        super(GSUBLookupType1Format2, self).loadFromFontTools(subtable, lookup)
        # fontTools has a custom implementation of this
        # subtable type, so it needs to be converted
        coverage = []
        self.Substitute = []
        for glyphName, alternate in sorted(subtable.mapping.items()):
            coverage.append(glyphName)
            self.Substitute.append(alternate)
        self.Coverage = Coverage().loadFromFontTools(coverage)
        return self

    def process(self, processed, glyphRecords, featureTag):
        performedSub = False
        currentRecord = glyphRecords[0]
        currentGlyph = currentRecord.glyphName
        if currentGlyph in self.Coverage:
            if not self._lookupFlagCoversGlyph(currentGlyph):
                performedSub = True
                index = self.Coverage.index(currentGlyph)
                substitute = self.Substitute[index]
                # special behavior for aalt
                if featureTag == "aalt":
                    if currentRecord._alternatesReference != currentGlyph:
                        currentRecord._alternatesReference = currentGlyph
                        currentRecord.alternates = []
                    currentRecord.alternates.append(substitute)
                # standard behavior
                else:
                    currentRecord.saveState(currentRecord.glyphName)
                    currentRecord.glyphName = substitute
                processed.append(currentRecord)
                glyphRecords = glyphRecords[1:]
        return processed, glyphRecords, performedSub
Exemplo n.º 20
0
 def loadFromFontTools(self, subtable, lookup):
     super(GSUBLookupType3, self).loadFromFontTools(subtable, lookup)
     # fontTools has a custom implementation of this
     # subtable type, so it needs to be converted
     coverage = []
     self.AlternateSet = []
     for glyphName, alternates in subtable.alternates.items():
         coverage.append(glyphName)
         alternateSet = AlternateSet().loadFromFontTools(alternates)
         self.AlternateSet.append(alternateSet)
     self.Coverage = Coverage().loadFromFontTools(coverage)
     self.AlternateSetCount = len(self.AlternateSet)
     return self
Exemplo n.º 21
0
 def loadFromFontTools(self, subtable, lookup):
     super(GPOSLookupType8Format2, self).loadFromFontTools(subtable, lookup)
     self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
     self.BacktrackClassDef = ClassDef().loadFromFontTools(subtable.BacktrackClassDef)
     self.InputClassDef = ClassDef().loadFromFontTools(subtable.InputClassDef)
     self.LookAheadClassDef = ClassDef().loadFromFontTools(subtable.LookAheadClassDef)
     self.ChainPosClassSet = []
     for chainPosClassSet in subtable.ChainPosClassSet:
         if chainPosClassSet is None:
             self.ChainPosClassSet.append(None)
         else:
             self.ChainPosClassSet.append(ChainPosClassSet().loadFromFontTools(chainPosClassSet))
     return self
Exemplo n.º 22
0
 def loadFromFontTools(self, subtable, lookup):
     super(GSUBLookupType5Format3, self).loadFromFontTools(subtable, lookup)
     self.Coverage = [
         Coverage().loadFromFontTools(coverage)
         for coverage in subtable.Coverage
     ]
     self.GlyphCount = subtable.GlyphCount
     self.SubstCount = subtable.SubstCount
     self.SubstLookupRecord = [
         SubstLookupRecord().loadFromFontTools(record)
         for record in subtable.SubstLookupRecord
     ]
     return self
Exemplo n.º 23
0
class GSUBLookupType1Format2(BaseSubTable):
    """
    Deviation from spec:
    - fontTools interprets Lookup Type 1 formats 1 and 2
      into the same object structure. As such, only format 2
      is needed.
    - GlyphCount attribute is not implemented.
    """

    __slots__ = ["Coverage", "Substitute"] + globalSubstitutionSubTableSlots

    def __init__(self):
        super(GSUBLookupType1Format2, self).__init__()
        self.SubstFormat = 2
        self.Substitute = []
        self.Coverage = None

    def loadFromFontTools(self, subtable, lookup):
        super(GSUBLookupType1Format2, self).loadFromFontTools(subtable, lookup)
        # fontTools has a custom implementation of this
        # subtable type, so it needs to be converted
        coverage = []
        self.Substitute = []
        for glyphName, alternate in sorted(subtable.mapping.items()):
            coverage.append(glyphName)
            self.Substitute.append(alternate)
        self.Coverage = Coverage().loadFromFontTools(coverage)
        return self

    def process(self, processed, glyphRecords, featureTag):
        performedSub = False
        currentRecord = glyphRecords[0]
        currentGlyph = currentRecord.glyphName
        if currentGlyph in self.Coverage:
            if not self._lookupFlagCoversGlyph(currentGlyph):
                performedSub = True
                index = self.Coverage.index(currentGlyph)
                substitute = self.Substitute[index]
                # special behavior for aalt
                if featureTag == "aalt":
                    if currentRecord._alternatesReference != currentGlyph:
                        currentRecord._alternatesReference = currentGlyph
                        currentRecord.alternates = []
                    currentRecord.alternates.append(substitute)
                # standard behavior
                else:
                    currentRecord.saveState(currentRecord.glyphName)
                    currentRecord.glyphName = substitute
                processed.append(currentRecord)
                glyphRecords = glyphRecords[1:]
        return processed, glyphRecords, performedSub
Exemplo n.º 24
0
class GSUBLookupType2(BaseSubTable):
    """
    Deviation from spec:
    - SequenceCount attribute is not implemented.
    """

    __slots__ = ["Coverage", "Sequence"] + globalSubstitutionSubTableSlots

    def __init__(self):
        super(GSUBLookupType2, self).__init__()
        self.SubstFormat = 1
        self.Coverage = None
        self.Sequence = []

    def loadFromFontTools(self, subtable, lookup):
        super(GSUBLookupType2, self).loadFromFontTools(subtable, lookup)
        try:
            self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
            self.Sequence = [
                Sequence().loadFromFontTools(sequence)
                for sequence in subtable.Sequence
            ]
        except AttributeError:
            # the API for MultipleSubst lookups changed with fonttools 3.1:
            # https://github.com/fonttools/fonttools/pull/364
            mapping = getattr(subtable, "mapping", {})
            coverage = sorted(mapping.keys())
            self.Coverage = Coverage(coverage)
            self.Sequence = [Sequence(mapping[glyph]) for glyph in coverage]
        return self

    def process(self, processed, glyphRecords, featureTag):
        performedSub = False
        currentRecord = glyphRecords[0]
        currentGlyph = currentRecord.glyphName
        if currentGlyph in self.Coverage:
            if not self._lookupFlagCoversGlyph(currentGlyph):
                # XXX all glyph subsitituion states are destroyed here
                performedSub = True
                index = self.Coverage.index(currentGlyph)
                sequence = self.Sequence[index]
                substitute = sequence.Substitute
                substitute = glyphNamesToGlyphRecords(substitute)
                processed.extend(substitute)
                glyphRecords = glyphRecords[1:]
        return processed, glyphRecords, performedSub
Exemplo n.º 25
0
class GPOSLookupType1Format2(BaseSubTable):

    """
    Deviation from spec:
    - ValueCount attribute is not implemented.

    XXX need to handle ValueFormat?
    """

    __slots__ = ["Coverage", "ValueFormat", "Value"] + globalPositionSubTableSlots

    def __init__(self):
        super(GPOSLookupType1Format2, self).__init__()
        self.PosFormat = 2
        self.Coverage = None
        self.ValueFormat = None
        self.Value = []

    def loadFromFontTools(self, subtable, lookup):
        super(GPOSLookupType1Format2, self).loadFromFontTools(subtable, lookup)
        self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
        self.ValueFormat = subtable.ValueFormat
        self.Value = [ValueRecord().loadFromFontTools(value) for value in subtable.Value]
        return self

    def process(self, processed, glyphRecords, featureTag):
        performedPos = False
        currentRecord = glyphRecords[0]
        currentGlyph = currentRecord.glyphName
        if currentGlyph in self.Coverage:
            if not self._lookupFlagCoversGlyph(currentGlyph):
                performedPos = True
                valueIndex = self.Coverage.index(currentGlyph)
                value = self.Value[valueIndex]
                currentRecord += value
                processed.append(currentRecord)
                glyphRecords = glyphRecords[1:]
        return processed, glyphRecords, performedPos
Exemplo n.º 26
0
class GSUBLookupType2(BaseSubTable):

    """
    Deviation from spec:
    - SequenceCount attribute is not implemented.
    """

    __slots__ = ["Coverage", "Sequence"] + globalSubstitutionSubTableSlots

    def __init__(self):
        super(GSUBLookupType2, self).__init__()
        self.SubstFormat = 1
        self.Coverage = None
        self.Sequence = []

    def loadFromFontTools(self, subtable, lookup):
        super(GSUBLookupType2, self).loadFromFontTools(subtable, lookup)
        self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
        self.Sequence = [Sequence().loadFromFontTools(sequence) for sequence in subtable.Sequence]
        return self

    def process(self, processed, glyphRecords, featureTag):
        performedSub = False
        currentRecord = glyphRecords[0]
        currentGlyph  = currentRecord.glyphName
        if currentGlyph in self.Coverage:
            if not self._lookupFlagCoversGlyph(currentGlyph):
                # XXX all glyph subsitituion states are destroyed here
                performedSub = True
                index = self.Coverage.index(currentGlyph)
                sequence = self.Sequence[index]
                substitute = sequence.Substitute
                substitute = glyphNamesToGlyphRecords(substitute)
                processed.extend(substitute)
                glyphRecords = glyphRecords[1:]
        return processed, glyphRecords, performedSub
Exemplo n.º 27
0
 def loadFromFontTools(self, subtable, lookup):
     super(GPOSLookupType3, self).loadFromFontTools(subtable, lookup)
     self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
     self.EntryExitRecord = [EntryExitRecord().loadFromFontTools(entryExitRecord) for entryExitRecord in subtable.EntryExitRecord]
     return self
Exemplo n.º 28
0
 def loadFromFontTools(self, subtable, lookup):
     super(GPOSLookupType7Format1, self).loadFromFontTools(subtable, lookup)
     self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
     self.PosRuleSet = [PosRuleSet().loadFromFontTools(posRuleSet) for posRuleSet in subtable.PosRuleSet]
     return self
Exemplo n.º 29
0
class GSUBLookupType4(BaseSubTable):

    """
    Deviation from spec:
    - LigSetCount attribute is not implemented.
    """

    __slots__ = ["Coverage", "LigatureSet"] + globalSubstitutionSubTableSlots

    def __init__(self):
        super(GSUBLookupType4, self).__init__()
        self.SubstFormat = 1
        self.LigatureSet = []
        self.Coverage = None

    def loadFromFontTools(self, subtable, lookup):
        super(GSUBLookupType4, self).loadFromFontTools(subtable, lookup)
        # fontTools has a custom implementation of this
        # subtable type, so it needs to be converted
        coverage = []
        self.LigatureSet = []
        for glyphName, ligature in subtable.ligatures.items():
            ligatureSet = LigatureSet().loadFromFontTools(ligature)
            self.LigatureSet.append(ligatureSet)
            coverage.append(glyphName)
        self.Coverage = Coverage().loadFromFontTools(coverage)
        return self

    def process(self, processed, glyphRecords, featureTag):
        performedSub = False
        currentRecord = glyphRecords[0]
        currentGlyph = currentRecord.glyphName
        lookupFlag = self._lookup().LookupFlag
        if currentGlyph in self.Coverage:
            if not lookupFlag.coversGlyph(currentGlyph):
                while not performedSub:
                    coverageIndex = self.Coverage.index(currentGlyph)
                    ligatureSet = self.LigatureSet[coverageIndex]
                    for ligature in ligatureSet.Ligature:
                        component = ligature.Component
                        componentCount = ligature.CompCount
                        currentComponentIndex = 0
                        matchedRecordIndexes = set()
                        lastWasMatch = False
                        for index, glyphRecord in enumerate(glyphRecords[1:]):
                            glyphName = glyphRecord.glyphName
                            if not lookupFlag.coversGlyph(glyphName):
                                if not glyphName == component[currentComponentIndex]:
                                    lastWasMatch = False
                                    break
                                else:
                                    lastWasMatch = True
                                    matchedRecordIndexes.add(index)
                                    currentComponentIndex += 1
                                    if currentComponentIndex == componentCount - 1:
                                        break
                        if lastWasMatch and currentComponentIndex == componentCount - 1:
                            performedSub = True
                            currentRecord.saveState([currentGlyph] + ligature.Component)
                            currentRecord.glyphName = ligature.LigGlyph
                            currentRecord.ligatureComponents = [currentGlyph] + ligature.Component
                            processed.append(currentRecord)
                            glyphRecords = [record for index, record in enumerate(glyphRecords[1:]) if index not in matchedRecordIndexes]
                            break
                    break
        return processed, glyphRecords, performedSub
Exemplo n.º 30
0
 def loadFromFontTools(self, subtable, lookup):
     super(GPOSLookupType1Format1, self).loadFromFontTools(subtable, lookup)
     self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
     self.ValueFormat = subtable.ValueFormat
     self.Value = ValueRecord().loadFromFontTools(subtable.Value)
     return self
Exemplo n.º 31
0
class GPOSLookupType6(BaseSubTable):

    """
    Deviation from spec:
    - ClassCount attribute is not implemented.

    Note: This could process things in a buggy way.
    Not enough test cases are available to know for sure.
    """

    __slots__ = ["Mark1Coverage", "Mark1Array", "Mark2Coverage", "Mark2Array"] + globalPositionSubTableSlots

    def __init__(self):
        super(GPOSLookupType6, self).__init__()
        self.Mark1Coverage = None
        self.Mark2Coverage = None
        self.Mark1Array = None
        self.Mark2Array = None

    def loadFromFontTools(self, subtable, lookup):
        super(GPOSLookupType6, self).loadFromFontTools(subtable, lookup)
        self.Mark1Coverage = Coverage().loadFromFontTools(subtable.Mark1Coverage)
        self.Mark2Coverage = Coverage().loadFromFontTools(subtable.Mark2Coverage)
        self.Mark1Array = MarkArray().loadFromFontTools(subtable.Mark1Array)
        self.Mark2Array = Mark2Array().loadFromFontTools(subtable.Mark2Array)
        return self

    def process(self, processed, glyphRecords, featureTag):
        performedPos = False
        currentRecord = glyphRecords[0]
        currentGlyph = currentRecord.glyphName
        if currentGlyph in self.Mark1Coverage:
            if not self._lookupFlagCoversGlyph(currentGlyph):
                previousRecord = None
                previousRecordIndex = 0
                gdef = self._lookup()._gdef
                while previousRecord is None:
                    for _previousRecord in reversed(processed):
                        previousRecordIndex -= 1
                        _previousGlyph = _previousRecord.glyphName
                        if not self._lookupFlagCoversGlyph(_previousGlyph):
                            previousRecord = _previousRecord
                            break
                    break
                if previousRecord is not None:
                    previousGlyph = previousRecord.glyphName
                    if previousGlyph in self.Mark2Coverage:
                        performedPos = True

                        mark1CoverageIndex = self.Mark1Coverage.index(currentGlyph)
                        mark1Record = self.Mark1Array.MarkRecord[mark1CoverageIndex]
                        mark1Anchor = mark1Record.MarkAnchor

                        mark2CoverageIndex = self.Mark2Coverage.index(previousGlyph)
                        mark2Record = self.Mark2Array.Mark2Record[mark2CoverageIndex]
                        mark2Anchor = mark2Record.Mark2Anchor[mark1Record.Class]
                        xOffset, yOffset = _calculateAnchorDifference(mark2Anchor, mark1Anchor)
                        currentRecord.xPlacement += xOffset - previousRecord.advanceWidth
                        currentRecord.yPlacement += yOffset - previousRecord.advanceHeight
                        processed.append(currentRecord)
                        glyphRecords = glyphRecords[1:]
        return processed, glyphRecords, performedPos
Exemplo n.º 32
0
class GSUBLookupType4(BaseSubTable):
    """
    Deviation from spec:
    - LigSetCount attribute is not implemented.
    """

    __slots__ = ["Coverage", "LigatureSet"] + globalSubstitutionSubTableSlots

    def __init__(self):
        super(GSUBLookupType4, self).__init__()
        self.SubstFormat = 1
        self.LigatureSet = []
        self.Coverage = None

    def loadFromFontTools(self, subtable, lookup):
        super(GSUBLookupType4, self).loadFromFontTools(subtable, lookup)
        # fontTools has a custom implementation of this
        # subtable type, so it needs to be converted
        coverage = []
        self.LigatureSet = []
        for glyphName, ligature in subtable.ligatures.items():
            ligatureSet = LigatureSet().loadFromFontTools(ligature)
            self.LigatureSet.append(ligatureSet)
            coverage.append(glyphName)
        self.Coverage = Coverage().loadFromFontTools(coverage)
        return self

    def process(self, processed, glyphRecords, featureTag):
        performedSub = False
        currentRecord = glyphRecords[0]
        currentGlyph = currentRecord.glyphName
        lookupFlag = self._lookup().LookupFlag
        if currentGlyph in self.Coverage:
            if not lookupFlag.coversGlyph(currentGlyph):
                while not performedSub:
                    coverageIndex = self.Coverage.index(currentGlyph)
                    ligatureSet = self.LigatureSet[coverageIndex]
                    for ligature in ligatureSet.Ligature:
                        component = ligature.Component
                        componentCount = ligature.CompCount
                        currentComponentIndex = 0
                        matchedRecordIndexes = set()
                        lastWasMatch = False
                        for index, glyphRecord in enumerate(glyphRecords[1:]):
                            glyphName = glyphRecord.glyphName
                            if not lookupFlag.coversGlyph(glyphName):
                                if not glyphName == component[
                                        currentComponentIndex]:
                                    lastWasMatch = False
                                    break
                                else:
                                    lastWasMatch = True
                                    matchedRecordIndexes.add(index)
                                    currentComponentIndex += 1
                                    if currentComponentIndex == componentCount - 1:
                                        break
                        if lastWasMatch and currentComponentIndex == componentCount - 1:
                            performedSub = True
                            currentRecord.saveState([currentGlyph] +
                                                    ligature.Component)
                            currentRecord.glyphName = ligature.LigGlyph
                            currentRecord.ligatureComponents = [
                                currentGlyph
                            ] + ligature.Component
                            processed.append(currentRecord)
                            glyphRecords = [
                                record for index, record in enumerate(
                                    glyphRecords[1:])
                                if index not in matchedRecordIndexes
                            ]
                            break
                    break
        return processed, glyphRecords, performedSub
Exemplo n.º 33
0
class GPOSLookupType5(BaseSubTable):

    """
    Deviation from spec:
    - ClassCount attribute is not implemented.

    Note: This could process things in a buggy way.
    Not enough test cases are available to know for sure.
    """

    __slots__ = ["MarkCoverage", "LigatureCoverage", "MarkArray", "LigatureArray"] + globalPositionSubTableSlots

    def __init__(self):
        super(GPOSLookupType5, self).__init__()
        self.MarkCoverage = None
        self.LigatureCoverage = None
        self.MarkArray = None
        self.LigatureArray = None

    def loadFromFontTools(self, subtable, lookup):
        super(GPOSLookupType5, self).loadFromFontTools(subtable, lookup)
        self.MarkCoverage = Coverage().loadFromFontTools(subtable.MarkCoverage)
        self.LigatureCoverage = Coverage().loadFromFontTools(subtable.LigatureCoverage)
        self.MarkArray = MarkArray().loadFromFontTools(subtable.MarkArray)
        self.LigatureArray = LigatureArray().loadFromFontTools(subtable.LigatureArray)
        return self

    def process(self, processed, glyphRecords, featureTag):
        performedPos = False
        currentRecord = glyphRecords[0]
        currentGlyph = currentRecord.glyphName
        if currentGlyph in self.MarkCoverage:
            if not self._lookupFlagCoversGlyph(currentGlyph):
                previousRecord = None
                previousRecordIndex = 0
                gdef = self._lookup()._gdef
                # look back to find the most recent glyph that:
                # 1. is not covered by the lookup flag
                # 2. is not a mark glyph (as defined in the GDEF)
                while previousRecord is None:
                    for _previousRecord in reversed(processed):
                        previousRecordIndex -= 1
                        _previousGlyph = _previousRecord.glyphName
                        if not self._lookupFlagCoversGlyph(_previousGlyph):
                            if gdef is not None and gdef.GlyphClassDef[_previousGlyph] != 3:
                                previousRecord = _previousRecord
                                break
                    break
                if previousRecord is not None:
                    previousGlyph = previousRecord.glyphName
                    if previousGlyph in self.LigatureCoverage:
                        performedPos = True
                        markCoverageIndex = self.MarkCoverage.index(currentGlyph)
                        markRecord = self.MarkArray.MarkRecord[markCoverageIndex]
                        markAnchor = markRecord.MarkAnchor
                        ligatureCoverageIndex = self.LigatureCoverage.index(previousGlyph)
                        ligatureAttach = self.LigatureArray.LigatureAttach[ligatureCoverageIndex]
                        componentIndex = abs(previousRecordIndex) - 1
                        componentRecord = ligatureAttach.ComponentRecord[componentIndex]
                        ligatureAnchor = componentRecord.LigatureAnchor[markRecord.Class]
                        if ligatureAnchor is not None:
                            xOffset, yOffset = _calculateAnchorDifference(ligatureAnchor, markAnchor)
                            currentRecord.xPlacement += xOffset - previousRecord.advanceWidth
                            currentRecord.yPlacement += yOffset - previousRecord.advanceHeight
                        processed.append(currentRecord)
                        glyphRecords = glyphRecords[1:]
        return processed, glyphRecords, performedPos
Exemplo n.º 34
0
 def loadFromFontTools(self, attachList):
     self.Coverage = Coverage().loadFromFontTools(attachList.Coverage)
     for attachPoint in attachList.AttachPoint:
         attachPoint = AttachPoint().loadFromFontTools(attachPoint)
         self.AttachPoint.append(attachPoint)
     return self
Exemplo n.º 35
0
 def loadFromFontTools(self, subtable, lookup):
     super(GSUBLookupType2, self).loadFromFontTools(subtable, lookup)
     self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
     self.Sequence = [Sequence().loadFromFontTools(sequence) for sequence in subtable.Sequence]
     return self
Exemplo n.º 36
0
 def loadFromFontTools(self, subtable, lookup):
     super(GPOSLookupType1Format2, self).loadFromFontTools(subtable, lookup)
     self.Coverage = Coverage().loadFromFontTools(subtable.Coverage)
     self.ValueFormat = subtable.ValueFormat
     self.Value = [ValueRecord().loadFromFontTools(value) for value in subtable.Value]
     return self
Exemplo n.º 37
0
 def loadFromFontTools(self, ligCaretList):
     self.Coverage = Coverage().loadFromFontTools(ligCaretList.Coverage)
     for ligGlyph in ligCaretList.LigGlyph:
         ligGlyph = LigGlyph().loadFromFontTools(ligGlyph)
         self.LigGlyph.append(ligGlyph)
     return self
Exemplo n.º 38
0
class GPOSLookupType4(BaseSubTable):

    """
    Deviation from spec:
    - ClassCount attribute is not implemented.
    """

    __slots__ = ["MarkCoverage", "BaseCoverage", "MarkArray", "BaseArray"] + globalPositionSubTableSlots

    def __init__(self):
        super(GPOSLookupType4, self).__init__()
        self.MarkCoverage = None
        self.BaseCoverage = None
        self.MarkArray = None
        self.BaseArray = None

    def loadFromFontTools(self, subtable, lookup):
        super(GPOSLookupType4, self).loadFromFontTools(subtable, lookup)
        self.MarkCoverage = Coverage().loadFromFontTools(subtable.MarkCoverage)
        self.BaseCoverage = Coverage().loadFromFontTools(subtable.BaseCoverage)
        self.MarkArray = MarkArray().loadFromFontTools(subtable.MarkArray)
        self.BaseArray = BaseArray().loadFromFontTools(subtable.BaseArray)
        return self

    def process(self, processed, glyphRecords, featureTag):
        performedPos = False
        currentRecord = glyphRecords[0]
        currentGlyph = currentRecord.glyphName
        if currentGlyph in self.MarkCoverage:
            if not self._lookupFlagCoversGlyph(currentGlyph):
                previousRecord = None
                previousRecordIndex = 0
                gdef = self._lookup()._gdef
                # look back to find the most recent glyph that:
                # 1. is not covered by the lookup flag
                # 2. is not a mark glyph (as defined in the GDEF)
                while previousRecord is None:
                    for _previousRecord in reversed(processed):
                        previousRecordIndex -= 1
                        _previousGlyph = _previousRecord.glyphName
                        if not self._lookupFlagCoversGlyph(_previousGlyph):
                            if gdef is not None and gdef.GlyphClassDef[_previousGlyph] != 3:
                                previousRecord = _previousRecord
                                break
                    break
                if previousRecord is not None:
                    previousGlyph = previousRecord.glyphName
                    if previousGlyph in self.BaseCoverage:
                        performedPos = True
                        markCoverageIndex = self.MarkCoverage.index(currentGlyph)
                        markRecord = self.MarkArray.MarkRecord[markCoverageIndex]
                        markAnchor = markRecord.MarkAnchor
                        baseCoverageIndex = self.BaseCoverage.index(previousGlyph)
                        baseRecord = self.BaseArray.BaseRecord[baseCoverageIndex]
                        baseAnchor = baseRecord.BaseAnchor[markRecord.Class]
                        xOffset, yOffset = _calculateAnchorDifference(baseAnchor, markAnchor)
                        currentRecord.xPlacement += xOffset - previousRecord.advanceWidth
                        currentRecord.yPlacement += yOffset - previousRecord.advanceHeight
                        processed.append(currentRecord)
                        glyphRecords = glyphRecords[1:]
        return processed, glyphRecords, performedPos