def test__ne__(self):
     glyph1 = self._setupTestGlyph()
     glyph2 = MathGlyph(None)
     glyph2.width = 1
     glyph2.name = 'a'
     self.assertNotEqual(glyph1, glyph2)
     self.assertNotEqual(glyph1, 'foo')
Beispiel #2
0
 def test__ne__(self):
     glyph1 = self._setupTestGlyph()
     glyph2 = MathGlyph(None)
     glyph2.width = 1
     glyph2.name = 'a'
     self.assertNotEqual(glyph1, glyph2)
     self.assertNotEqual(glyph1, 'foo')
    def test__eq__(self):
        glyph1 = self._setupTestGlyph()
        glyph2 = self._setupTestGlyph()
        self.assertEqual(glyph1, glyph2)

        glyph2.width = 1
        self.assertFalse(glyph1 == glyph2)

        nonglyph = object()
        self.assertFalse(glyph1 == nonglyph)

        glyph1 = MathGlyph(None)
        glyph1.name = 'space'
        glyph1.width = 100

        class MyGlyph(object):
            pass

        other = MyGlyph()
        other.name = 'space'
        other.width = 100
        other.height = None
        other.contours = []
        other.components = []
        other.anchors = []
        other.guidelines = []
        other.image = {
            'fileName': None,
            'transformation': (1, 0, 0, 1, 0, 0),
            'color': None
        }
        other.lib = {}
        other.unicodes = None
        other.note = None
        self.assertEqual(glyph1, other)
Beispiel #4
0
    def test__eq__(self):
        glyph1 = self._setupTestGlyph()
        glyph2 = self._setupTestGlyph()
        self.assertEqual(glyph1, glyph2)

        glyph2.width = 1
        self.assertFalse(glyph1 == glyph2)

        nonglyph = object()
        self.assertFalse(glyph1 == nonglyph)

        glyph1 = MathGlyph(None)
        glyph1.name = 'space'
        glyph1.width = 100

        class MyGlyph(object):
            pass
        other = MyGlyph()
        other.name = 'space'
        other.width = 100
        other.height = None
        other.contours = []
        other.components = []
        other.anchors = []
        other.guidelines = []
        other.image = {'fileName': None,
                       'transformation': (1, 0, 0, 1, 0, 0),
                       'color': None}
        other.lib = {}
        other.unicodes = None
        other.note = None
        self.assertEqual(glyph1, other)
Beispiel #5
0
    def _calculateGlyph(self, targetGlyphObject, instanceLocationObject,
                        glyphMasters):
        """
        Build a Mutator object for this glyph.

        *   name:   glyphName
        *   location:   Location object
        *   glyphMasters:    dict with font objects.
        """
        sources = None
        items = []

        for item in glyphMasters:
            locationObject = item['location']
            fontObject = item['font']
            glyphName = item['glyphName']
            if not glyphName in fontObject:
                continue
            glyphObject = MathGlyph(fontObject[glyphName])
            items.append((locationObject, glyphObject))
        bias, m = buildMutator(items)
        instanceObject = m.makeInstance(instanceLocationObject)
        if self.roundGeometry:
            try:
                instanceObject = instanceObject.round()
            except AttributeError:
                self.logger.info("MathGlyph object missing round() method.")
        try:
            instanceObject.extractGlyph(targetGlyphObject, onlyGeometry=True)
        except TypeError:
            self.logger.info(
                "MathGlyph object extractGlyph() does not support onlyGeometry attribute."
            )
            instanceObject.extractGlyph(targetGlyphObject)
Beispiel #6
0
    def _calculateGlyph(self, targetGlyphObject, instanceLocationObject,
                        glyphMasters):
        """
        Build a Mutator object for this glyph.

        *   name:   glyphName
        *   location:   Location object
        *   glyphMasters:    dict with font objects.
        """
        sources = None
        items = []

        for item in glyphMasters:
            locationObject = item['location']
            fontObject = item['font']
            glyphName = item['glyphName']
            if not glyphName in fontObject:
                continue
            glyphObject = MathGlyph(fontObject[glyphName])
            items.append((locationObject, glyphObject))
        bias, m = buildMutator(items)
        instanceObject = m.makeInstance(instanceLocationObject)
        if self.roundGeometry:
            instanceObject = instanceObject.round()
        instanceObject.extractGlyph(targetGlyphObject, onlyGeometry=True)
Beispiel #7
0
        def _calculateGlyph(self, targetGlyphObject, instanceLocationObject, glyphMasters):
            # Search for a glyphMaster with the same location as instanceLocationObject
            found = False
            if not calc_glyphs: # i.e. if copying glyphs
                for item in glyphMasters:
                    locationObject = item['location'] # mutatorMath Location
                    if locationObject.sameAs(instanceLocationObject) == 0:
                        found = True
                        fontObject = item['font'] # defcon Font
                        glyphName = item['glyphName'] # string
                        glyphObject = MathGlyph(fontObject[glyphName])
                        glyphObject.extractGlyph(targetGlyphObject, onlyGeometry=True)
                        break

            if not found: # includes case of calc_glyphs == True
                super(LocalInstanceWriter, self)._calculateGlyph(targetGlyphObject,
                                                                 instanceLocationObject,
                                                                 glyphMasters)
Beispiel #8
0
    def _calculateGlyph(self, targetGlyphObject, instanceLocationObject,
                        glyphMasters):
        """
        Build a Mutator object for this glyph.

        *   name:   glyphName
        *   location:   Location object
        *   glyphMasters:    dict with font objects.
        """
        sources = None
        items = []

        for item in glyphMasters:
            locationObject = item['location']
            fontObject = item['font']
            glyphName = item['glyphName']
            if not glyphName in fontObject:
                continue
            glyphObject = MathGlyph(fontObject[glyphName])
            items.append((locationObject, glyphObject))
        bias, m = buildMutator(items, axes=self.axes)
        instanceObject = m.makeInstance(instanceLocationObject,
                                        bend=self.bendLocations)
        if self.roundGeometry:
            try:
                instanceObject = instanceObject.round()
            except AttributeError:
                if self.verbose and self.logger:
                    self.logger.info(
                        "MathGlyph object missing round() method.")

        try:
            instanceObject.extractGlyph(targetGlyphObject, onlyGeometry=True)
        except TypeError:
            # this causes ruled glyphs to end up in the wrong glyphname
            # but defcon2 objects don't support it
            pPen = targetGlyphObject.getPointPen()
            targetGlyphObject.clear()
            instanceObject.drawPoints(pPen)
            targetGlyphObject.width = instanceObject.width
 def _setupTestGlyph(self):
     glyph = MathGlyph(None)
     glyph.width = 0
     glyph.height = 0
     return glyph
    def makeInstance(self, instanceDescriptor, doRules=False, glyphNames=None):
        """ Generate a font object for this instance """
        font = self._instantiateFont(None)
        self._preppedAxes = self._prepAxesForBender()
        # make fonty things here
        loc = Location(instanceDescriptor.location)
        # groups,
        if hasattr(self.fonts[self.default.name],
                   "kerningGroupConversionRenameMaps"):
            renameMap = self.fonts[
                self.default.name].kerningGroupConversionRenameMaps
            self.problems.append("renameMap %s" % renameMap)
        else:
            renameMap = {}
        font.kerningGroupConversionRenameMaps = renameMap
        # make the kerning
        if instanceDescriptor.kerning:
            try:
                self.getKerningMutator().makeInstance(loc).extractKerning(font)
            except:
                self.problems.append("Could not make kerning for %s" % loc)
        # make the info
        if instanceDescriptor.info:
            try:
                self.getInfoMutator().makeInstance(loc).extractInfo(font.info)
                info = self._infoMutator.makeInstance(loc)
                info.extractInfo(font.info)
                font.info.familyName = instanceDescriptor.familyName
                font.info.styleName = instanceDescriptor.styleName
                font.info.postScriptFontName = instanceDescriptor.postScriptFontName
                font.info.styleMapFamilyName = instanceDescriptor.styleMapFamilyName
                font.info.styleMapStyleName = instanceDescriptor.styleMapStyleName
                # localised names need to go to the right openTypeNameRecords
                # records = []
                # nameID = 1
                # platformID =
                # for languageCode, name in instanceDescriptor.localisedStyleMapFamilyName.items():
                #    # Name ID 1 (font family name) is found at the generic styleMapFamily attribute.
                #    records.append((nameID, ))

            except:
                self.problems.append("Could not make fontinfo for %s" % loc)
        # copied info
        for sourceDescriptor in self.sources:
            if sourceDescriptor.copyInfo:
                # this is the source
                self._copyFontInfo(self.fonts[sourceDescriptor.name].info,
                                   font.info)
            if sourceDescriptor.copyLib:
                # excplicitly copy the font.lib items
                for key, value in self.fonts[
                        sourceDescriptor.name].lib.items():
                    font.lib[key] = value
            if sourceDescriptor.copyFeatures:
                featuresText = self.fonts[sourceDescriptor.name].features.text
                if isinstance(featuresText, str):
                    font.features.text = u"" + featuresText
                elif isinstance(featuresText, unicode):
                    font.features.text = featuresText
        # glyphs
        if glyphNames:
            selectedGlyphNames = glyphNames
        else:
            selectedGlyphNames = self.glyphNames
        # add the glyphnames to the font.lib['public.glyphOrder']
        if not 'public.glyphOrder' in font.lib.keys():
            font.lib['public.glyphOrder'] = selectedGlyphNames
        for glyphName in selectedGlyphNames:
            try:
                glyphMutator = self.getGlyphMutator(glyphName)
            except:
                self.problems.append("Could not make mutator for glyph %s" %
                                     glyphName)
                continue
            if glyphName in instanceDescriptor.glyphs.keys():
                # reminder: this is what the glyphData can look like
                # {'instanceLocation': {'custom': 0.0, 'weight': 824.0},
                #  'masters': [{'font': 'master.Adobe VF Prototype.Master_0.0',
                #               'glyphName': 'dollar.nostroke',
                #               'location': {'custom': 0.0, 'weight': 0.0}},
                #              {'font': 'master.Adobe VF Prototype.Master_1.1',
                #               'glyphName': 'dollar.nostroke',
                #               'location': {'custom': 0.0, 'weight': 368.0}},
                #              {'font': 'master.Adobe VF Prototype.Master_2.2',
                #               'glyphName': 'dollar.nostroke',
                #               'location': {'custom': 0.0, 'weight': 1000.0}},
                #              {'font': 'master.Adobe VF Prototype.Master_3.3',
                #               'glyphName': 'dollar.nostroke',
                #               'location': {'custom': 100.0, 'weight': 1000.0}},
                #              {'font': 'master.Adobe VF Prototype.Master_0.4',
                #               'glyphName': 'dollar.nostroke',
                #               'location': {'custom': 100.0, 'weight': 0.0}},
                #              {'font': 'master.Adobe VF Prototype.Master_4.5',
                #               'glyphName': 'dollar.nostroke',
                #               'location': {'custom': 100.0, 'weight': 368.0}}],
                #  'unicodes': [36]}
                glyphData = instanceDescriptor.glyphs[glyphName]
            else:
                glyphData = {}
            font.newGlyph(glyphName)
            font[glyphName].clear()
            if glyphData.get('mute', False):
                # mute this glyph, skip
                continue
            glyphInstanceLocation = Location(
                glyphData.get("instanceLocation", instanceDescriptor.location))
            try:
                uniValues = glyphMutator[()][0].unicodes
            except IndexError:
                uniValues = []
            glyphInstanceUnicodes = glyphData.get("unicodes", uniValues)
            note = glyphData.get("note")
            if note:
                font[glyphName] = note
            masters = glyphData.get("masters", None)
            if masters:
                items = []
                for glyphMaster in masters:
                    sourceGlyphFont = glyphMaster.get("font")
                    sourceGlyphName = glyphMaster.get("glyphName", glyphName)
                    m = self.fonts.get(sourceGlyphFont)
                    if not sourceGlyphName in m:
                        continue
                    sourceGlyph = MathGlyph(m[sourceGlyphName])
                    sourceGlyphLocation = Location(glyphMaster.get("location"))
                    items.append((sourceGlyphLocation, sourceGlyph))
                bias, glyphMutator = buildMutator(items,
                                                  axes=self._preppedAxes,
                                                  bias=self.defaultLoc)
            try:
                glyphInstanceObject = glyphMutator.makeInstance(
                    glyphInstanceLocation)
            except IndexError:
                # alignment problem with the data?
                print("Error making instance %s" % glyphName)
                continue
            font.newGlyph(glyphName)
            font[glyphName].clear()
            if self.roundGeometry:
                try:
                    glyphInstanceObject = glyphInstanceObject.round()
                except AttributeError:
                    pass
            try:
                glyphInstanceObject.extractGlyph(font[glyphName],
                                                 onlyGeometry=True)
            except TypeError:
                # this causes ruled glyphs to end up in the wrong glyphname
                # but defcon2 objects don't support it
                pPen = font[glyphName].getPointPen()
                font[glyphName].clear()
                glyphInstanceObject.drawPoints(pPen)
            font[glyphName].width = glyphInstanceObject.width
            font[glyphName].unicodes = glyphInstanceUnicodes
        if doRules:
            resultNames = processRules(self.rules, loc, self.glyphNames)
            for oldName, newName in zip(self.glyphNames, resultNames):
                if oldName != newName:
                    swapGlyphNames(font, oldName, newName)
        # copy the glyph lib?
        #for sourceDescriptor in self.sources:
        #    if sourceDescriptor.copyLib:
        #        pass
        #    pass
        # store designspace location in the font.lib
        font.lib['designspace'] = list(instanceDescriptor.location.items())
        return font
Beispiel #11
0
 def makeInstance(self, instanceDescriptor, doRules=False, glyphNames=None):
     """ Generate a font object for this instance """
     font = self._instantiateFont(None)
     # make fonty things here
     loc = instanceDescriptor.location
     anisotropic = False
     locHorizontal = locVertical = loc
     if self.isAnisotropic(loc):
         anisotropic = True
         locHorizontal, locVertical = self.splitAnisotropic(loc)
     # groups
     if hasattr(self.fonts[self.default.name],
                "kerningGroupConversionRenameMaps"):
         renameMap = self.fonts[
             self.default.name].kerningGroupConversionRenameMaps
     else:
         renameMap = {}
     font.kerningGroupConversionRenameMaps = renameMap
     # make the kerning
     # this kerning is always horizontal. We can take the horizontal location
     if instanceDescriptor.kerning:
         try:
             kerningMutator = self.getKerningMutator()
             kerningObject = kerningMutator.makeInstance(locHorizontal)
             kerningObject.extractKerning(font)
         except:
             self.problems.append("Could not make kerning for %s. %s" %
                                  (loc, traceback.format_exc()))
     # make the info
     try:
         infoMutator = self.getInfoMutator()
         if not anisotropic:
             infoInstanceObject = infoMutator.makeInstance(loc)
         else:
             horizontalInfoInstanceObject = infoMutator.makeInstance(
                 locHorizontal)
             verticalInfoInstanceObject = infoMutator.makeInstance(
                 locVertical)
             # merge them again
             infoInstanceObject = (1, 0) * horizontalInfoInstanceObject + (
                 0, 1) * verticalInfoInstanceObject
         infoInstanceObject.extractInfo(font.info)
         font.info.familyName = instanceDescriptor.familyName
         font.info.styleName = instanceDescriptor.styleName
         font.info.postScriptFontName = instanceDescriptor.postScriptFontName
         font.info.styleMapFamilyName = instanceDescriptor.styleMapFamilyName
         font.info.styleMapStyleName = instanceDescriptor.styleMapStyleName
         # NEED SOME HELP WITH THIS
         # localised names need to go to the right openTypeNameRecords
         # records = []
         # nameID = 1
         # platformID =
         # for languageCode, name in instanceDescriptor.localisedStyleMapFamilyName.items():
         #    # Name ID 1 (font family name) is found at the generic styleMapFamily attribute.
         #    records.append((nameID, ))
     except:
         self.problems.append("Could not make fontinfo for %s. %s" %
                              (loc, traceback.format_exc()))
     for sourceDescriptor in self.sources:
         if sourceDescriptor.copyInfo:
             # this is the source
             self._copyFontInfo(self.fonts[sourceDescriptor.name].info,
                                font.info)
         if sourceDescriptor.copyLib:
             # excplicitly copy the font.lib items
             for key, value in self.fonts[
                     sourceDescriptor.name].lib.items():
                 font.lib[key] = value
         if sourceDescriptor.copyFeatures:
             featuresText = self.fonts[sourceDescriptor.name].features.text
             if isinstance(featuresText, str):
                 font.features.text = u"" + featuresText
             elif isinstance(featuresText, unicode):
                 font.features.text = featuresText
     # glyphs
     if glyphNames:
         selectedGlyphNames = glyphNames
     else:
         selectedGlyphNames = self.glyphNames
     # add the glyphnames to the font.lib['public.glyphOrder']
     if not 'public.glyphOrder' in font.lib.keys():
         font.lib['public.glyphOrder'] = selectedGlyphNames
     for glyphName in selectedGlyphNames:
         try:
             glyphMutator = self.getGlyphMutator(glyphName)
             if glyphMutator is None:
                 continue
         except:
             self.problems.append("Could not make mutator for glyph %s %s" %
                                  (glyphName, traceback.format_exc()))
             continue
         if glyphName in instanceDescriptor.glyphs.keys():
             # XXX this should be able to go now that we have full rule support.
             # reminder: this is what the glyphData can look like
             # {'instanceLocation': {'custom': 0.0, 'weight': 824.0},
             #  'masters': [{'font': 'master.Adobe VF Prototype.Master_0.0',
             #               'glyphName': 'dollar.nostroke',
             #               'location': {'custom': 0.0, 'weight': 0.0}},
             #              {'font': 'master.Adobe VF Prototype.Master_1.1',
             #               'glyphName': 'dollar.nostroke',
             #               'location': {'custom': 0.0, 'weight': 368.0}},
             #              {'font': 'master.Adobe VF Prototype.Master_2.2',
             #               'glyphName': 'dollar.nostroke',
             #               'location': {'custom': 0.0, 'weight': 1000.0}},
             #              {'font': 'master.Adobe VF Prototype.Master_3.3',
             #               'glyphName': 'dollar.nostroke',
             #               'location': {'custom': 100.0, 'weight': 1000.0}},
             #              {'font': 'master.Adobe VF Prototype.Master_0.4',
             #               'glyphName': 'dollar.nostroke',
             #               'location': {'custom': 100.0, 'weight': 0.0}},
             #              {'font': 'master.Adobe VF Prototype.Master_4.5',
             #               'glyphName': 'dollar.nostroke',
             #               'location': {'custom': 100.0, 'weight': 368.0}}],
             #  'unicodes': [36]}
             glyphData = instanceDescriptor.glyphs[glyphName]
         else:
             glyphData = {}
         font.newGlyph(glyphName)
         font[glyphName].clear()
         if glyphData.get('mute', False):
             # mute this glyph, skip
             continue
         glyphInstanceLocation = glyphData.get("instanceLocation",
                                               instanceDescriptor.location)
         uniValues = []
         neutral = glyphMutator.get(())
         if neutral is not None:
             uniValues = neutral[0].unicodes
         glyphInstanceUnicodes = glyphData.get("unicodes", uniValues)
         note = glyphData.get("note")
         if note:
             font[glyphName] = note
         masters = glyphData.get("masters", None)
         if masters:
             items = []
             for glyphMaster in masters:
                 sourceGlyphFont = glyphMaster.get("font")
                 sourceGlyphName = glyphMaster.get("glyphName", glyphName)
                 m = self.fonts.get(sourceGlyphFont)
                 if not sourceGlyphName in m:
                     continue
                 if hasattr(m[sourceGlyphName], "toMathGlyph"):
                     sourceGlyph = m[sourceGlyphName].toMathGlyph()
                 else:
                     sourceGlyph = MathGlyph(m[sourceGlyphName])
                 sourceGlyphLocation = glyphMaster.get("location")
                 items.append((sourceGlyphLocation, sourceGlyph))
             bias, glyphMutator = self.getVariationModel(
                 items, axes=self.serializedAxes, bias=self.defaultLoc)
         try:
             if not self.isAnisotropic(glyphInstanceLocation):
                 glyphInstanceObject = glyphMutator.makeInstance(
                     glyphInstanceLocation)
             else:
                 # split anisotropic location into horizontal and vertical components
                 horizontal, vertical = self.splitAnisotropic(
                     glyphInstanceLocation)
                 horizontalGlyphInstanceObject = glyphMutator.makeInstance(
                     horizontal)
                 verticalGlyphInstanceObject = glyphMutator.makeInstance(
                     vertical)
                 # merge them again
                 glyphInstanceObject = (
                     0, 1) * horizontalGlyphInstanceObject + (
                         1, 0) * verticalGlyphInstanceObject
         except IndexError:
             # alignment problem with the data?
             print("Error making instance %s" % glyphName)
             continue
         font.newGlyph(glyphName)
         font[glyphName].clear()
         if self.roundGeometry:
             try:
                 glyphInstanceObject = glyphInstanceObject.round()
             except AttributeError:
                 pass
         try:
             glyphInstanceObject.extractGlyph(font[glyphName],
                                              onlyGeometry=True)
         except TypeError:
             # this causes ruled glyphs to end up in the wrong glyphname
             # but defcon2 objects don't support it
             pPen = font[glyphName].getPointPen()
             font[glyphName].clear()
             glyphInstanceObject.drawPoints(pPen)
         font[glyphName].width = glyphInstanceObject.width
         font[glyphName].unicodes = glyphInstanceUnicodes
     if doRules:
         resultNames = processRules(self.rules, loc, self.glyphNames)
         for oldName, newName in zip(self.glyphNames, resultNames):
             if oldName != newName:
                 swapGlyphNames(font, oldName, newName)
     # copy the glyph lib?
     #for sourceDescriptor in self.sources:
     #    if sourceDescriptor.copyLib:
     #        pass
     #    pass
     # store designspace location in the font.lib
     font.lib['designspace'] = list(instanceDescriptor.location.items())
     return font
Beispiel #12
0
 def makeInstance(self, instanceDescriptor,
         doRules=False,
         glyphNames=None,
         pairs=None,
         bend=False):
     """ Generate a font object for this instance """
     font = self._instantiateFont(None)
     # make fonty things here
     loc = Location(instanceDescriptor.location)
     anisotropic = False
     locHorizontal = locVertical = loc
     if self.isAnisotropic(loc):
         anisotropic = True
         locHorizontal, locVertical = self.splitAnisotropic(loc)
     # groups
     renameMap = getattr(self.fonts[self.default.name], "kerningGroupConversionRenameMaps", None)
     font.kerningGroupConversionRenameMaps = renameMap if renameMap is not None else {'side1': {}, 'side2': {}}
     # make the kerning
     # this kerning is always horizontal. We can take the horizontal location
     # filter the available pairs?
     if instanceDescriptor.kerning:
         if pairs:
             try:
                 kerningMutator = self.getKerningMutator(pairs=pairs)
                 kerningObject = kerningMutator.makeInstance(locHorizontal, bend=bend)
                 kerningObject.extractKerning(font)
             except:
                 self.problems.append("Could not make kerning for %s. %s" % (loc, traceback.format_exc()))
         else:
             kerningMutator = self.getKerningMutator()
             if kerningMutator is not None:
                 kerningObject = kerningMutator.makeInstance(locHorizontal, bend=bend)
                 kerningObject.extractKerning(font)
     # make the info
     try:
         infoMutator = self.getInfoMutator()
         if infoMutator is not None:
             if not anisotropic:
                 infoInstanceObject = infoMutator.makeInstance(loc, bend=bend)
             else:
                 horizontalInfoInstanceObject = infoMutator.makeInstance(locHorizontal, bend=bend)
                 verticalInfoInstanceObject = infoMutator.makeInstance(locVertical, bend=bend)
                 # merge them again
                 infoInstanceObject = (1,0)*horizontalInfoInstanceObject + (0,1)*verticalInfoInstanceObject
             if self.roundGeometry:
                 try:
                     infoInstanceObject = infoInstanceObject.round()
                 except AttributeError:
                     pass
             infoInstanceObject.extractInfo(font.info)
         font.info.familyName = instanceDescriptor.familyName
         font.info.styleName = instanceDescriptor.styleName
         font.info.postscriptFontName = instanceDescriptor.postScriptFontName # yikes, note the differences in capitalisation..
         font.info.styleMapFamilyName = instanceDescriptor.styleMapFamilyName
         font.info.styleMapStyleName = instanceDescriptor.styleMapStyleName
         # NEED SOME HELP WITH THIS
         # localised names need to go to the right openTypeNameRecords
         # records = []
         # nameID = 1
         # platformID =
         # for languageCode, name in instanceDescriptor.localisedStyleMapFamilyName.items():
         #    # Name ID 1 (font family name) is found at the generic styleMapFamily attribute.
         #    records.append((nameID, ))
     except:
         self.problems.append("Could not make fontinfo for %s. %s" % (loc, traceback.format_exc()))
     for sourceDescriptor in self.sources:
         if sourceDescriptor.copyInfo:
             # this is the source
             if self.fonts[sourceDescriptor.name] is not None:
                 self._copyFontInfo(self.fonts[sourceDescriptor.name].info, font.info)
         if sourceDescriptor.copyLib:
             # excplicitly copy the font.lib items
             if self.fonts[sourceDescriptor.name] is not None:
                 for key, value in self.fonts[sourceDescriptor.name].lib.items():
                     font.lib[key] = value
         if sourceDescriptor.copyGroups:
             if self.fonts[sourceDescriptor.name] is not None:
                 sides = font.kerningGroupConversionRenameMaps.get('side1', {})
                 sides.update(font.kerningGroupConversionRenameMaps.get('side2', {}))
                 for key, value in self.fonts[sourceDescriptor.name].groups.items():
                     if key not in sides:
                         font.groups[key] = value
         if sourceDescriptor.copyFeatures:
             if self.fonts[sourceDescriptor.name] is not None:
                 featuresText = self.fonts[sourceDescriptor.name].features.text
                 font.features.text = featuresText
     # glyphs
     if glyphNames:
         selectedGlyphNames = glyphNames
     else:
         selectedGlyphNames = self.glyphNames
     # add the glyphnames to the font.lib['public.glyphOrder']
     if not 'public.glyphOrder' in font.lib.keys():
         font.lib['public.glyphOrder'] = selectedGlyphNames
     for glyphName in selectedGlyphNames:
         try:
             glyphMutator = self.getGlyphMutator(glyphName)
             if glyphMutator is None:
                 self.problems.append("Could not make mutator for glyph %s" % (glyphName))
                 continue
         except:
             self.problems.append("Could not make mutator for glyph %s %s" % (glyphName, traceback.format_exc()))
             continue
         if glyphName in instanceDescriptor.glyphs.keys():
             # XXX this should be able to go now that we have full rule support.
             # reminder: this is what the glyphData can look like
             # {'instanceLocation': {'custom': 0.0, 'weight': 824.0},
             #  'masters': [{'font': 'master.Adobe VF Prototype.Master_0.0',
             #               'glyphName': 'dollar.nostroke',
             #               'location': {'custom': 0.0, 'weight': 0.0}},
             #              {'font': 'master.Adobe VF Prototype.Master_1.1',
             #               'glyphName': 'dollar.nostroke',
             #               'location': {'custom': 0.0, 'weight': 368.0}},
             #              {'font': 'master.Adobe VF Prototype.Master_2.2',
             #               'glyphName': 'dollar.nostroke',
             #               'location': {'custom': 0.0, 'weight': 1000.0}},
             #              {'font': 'master.Adobe VF Prototype.Master_3.3',
             #               'glyphName': 'dollar.nostroke',
             #               'location': {'custom': 100.0, 'weight': 1000.0}},
             #              {'font': 'master.Adobe VF Prototype.Master_0.4',
             #               'glyphName': 'dollar.nostroke',
             #               'location': {'custom': 100.0, 'weight': 0.0}},
             #              {'font': 'master.Adobe VF Prototype.Master_4.5',
             #               'glyphName': 'dollar.nostroke',
             #               'location': {'custom': 100.0, 'weight': 368.0}}],
             #  'unicodes': [36]}
             glyphData = instanceDescriptor.glyphs[glyphName]
         else:
             glyphData = {}
         font.newGlyph(glyphName)
         font[glyphName].clear()
         if glyphData.get('mute', False):
             # mute this glyph, skip
             continue
         glyphInstanceLocation = glyphData.get("instanceLocation", instanceDescriptor.location)
         glyphInstanceLocation = Location(glyphInstanceLocation)
         uniValues = []
         neutral = glyphMutator.get(())
         if neutral is not None:
             uniValues = neutral[0].unicodes
         else:
             neutralFont = self.getNeutralFont()
             if glyphName in neutralFont:
                 uniValues = neutralFont[glyphName].unicodes
         glyphInstanceUnicodes = glyphData.get("unicodes", uniValues)
         note = glyphData.get("note")
         if note:
             font[glyphName] = note
         # XXXX phase out support for instance-specific masters
         # this should be handled by the rules system.
         masters = glyphData.get("masters", None)
         if masters is not None:
             items = []
             for glyphMaster in masters:
                 sourceGlyphFont = glyphMaster.get("font")
                 sourceGlyphName = glyphMaster.get("glyphName", glyphName)
                 m = self.fonts.get(sourceGlyphFont)
                 if not sourceGlyphName in m:
                     continue
                 if hasattr(m[sourceGlyphName], "toMathGlyph"):
                     sourceGlyph = m[sourceGlyphName].toMathGlyph()
                 else:
                     sourceGlyph = MathGlyph(m[sourceGlyphName])
                 sourceGlyphLocation = glyphMaster.get("location")
                 items.append((Location(sourceGlyphLocation), sourceGlyph))
             bias, glyphMutator = self.getVariationModel(items, axes=self.serializedAxes, bias=self.newDefaultLocation(bend=True))
         try:
             if not self.isAnisotropic(glyphInstanceLocation):
                 glyphInstanceObject = glyphMutator.makeInstance(glyphInstanceLocation, bend=bend)
             else:
                 # split anisotropic location into horizontal and vertical components
                 horizontal, vertical = self.splitAnisotropic(glyphInstanceLocation)
                 horizontalGlyphInstanceObject = glyphMutator.makeInstance(horizontal, bend=bend)
                 verticalGlyphInstanceObject = glyphMutator.makeInstance(vertical, bend=bend)
                 # merge them again
                 glyphInstanceObject = (1,0)*horizontalGlyphInstanceObject + (0,1)*verticalGlyphInstanceObject
         except IndexError:
             # alignment problem with the data?
             self.problems.append("Quite possibly some sort of data alignment error in %s" % glyphName)
             continue
         font.newGlyph(glyphName)
         font[glyphName].clear()
         if self.roundGeometry:
             try:
                 glyphInstanceObject = glyphInstanceObject.round()
             except AttributeError:
                 pass
         try:
             # File "/Users/erik/code/ufoProcessor/Lib/ufoProcessor/__init__.py", line 649, in makeInstance
             #   glyphInstanceObject.extractGlyph(font[glyphName], onlyGeometry=True)
             # File "/Applications/RoboFont.app/Contents/Resources/lib/python3.6/fontMath/mathGlyph.py", line 315, in extractGlyph
             #   glyph.anchors = [dict(anchor) for anchor in self.anchors]
             # File "/Applications/RoboFont.app/Contents/Resources/lib/python3.6/fontParts/base/base.py", line 103, in __set__
             #   raise FontPartsError("no setter for %r" % self.name)
             #   fontParts.base.errors.FontPartsError: no setter for 'anchors'
             if hasattr(font[glyphName], "fromMathGlyph"):
                 font[glyphName].fromMathGlyph(glyphInstanceObject)
             else:
                 glyphInstanceObject.extractGlyph(font[glyphName], onlyGeometry=True)
         except TypeError:
             # this causes ruled glyphs to end up in the wrong glyphname
             # but defcon2 objects don't support it
             pPen = font[glyphName].getPointPen()
             font[glyphName].clear()
             glyphInstanceObject.drawPoints(pPen)
         font[glyphName].width = glyphInstanceObject.width
         font[glyphName].unicodes = glyphInstanceUnicodes
     if doRules:
         resultNames = processRules(self.rules, loc, self.glyphNames)
         for oldName, newName in zip(self.glyphNames, resultNames):
             if oldName != newName:
                 swapGlyphNames(font, oldName, newName)
     # copy the glyph lib?
     #for sourceDescriptor in self.sources:
     #    if sourceDescriptor.copyLib:
     #        pass
     #    pass
     # store designspace location in the font.lib
     font.lib['designspace.location'] = list(instanceDescriptor.location.items())
     return font
Beispiel #13
0
 def _setupTestGlyph(self):
     glyph = MathGlyph(None)
     glyph.width = 0
     glyph.height = 0
     return glyph
    def generateInstanceFont(self, spot, generationInfos):

        # self.w.spotSheet.close()
        # delattr(self.w, 'spotSheet')

        if generationInfos['sourceFont']:
            baseFont = generationInfos['sourceFont'][0]
            doKerning = generationInfos['interpolateKerning']
            doFontInfos = generationInfos['interpolateFontInfos']
            doReport = generationInfos['printReport']

            progress = ProgressWindow('Generating instance', parentWindow=self.w)

            fonts = [font for _, font in self.masters]

            i, j = spot
            ch = getKeyForValue(i)
            instanceLocation = Location(horizontal=i, vertical=j)
            masterLocations = [(Location(horizontal=getValueForKey(_ch), vertical=_j), masterFont) for (_ch, _j), masterFont in self.masters]

            # Build font
            newFont = RFont(showUI=False)
            newFont.info.familyName = baseFont.info.familyName
            newFont.info.styleName = '%s%s'%(ch.upper(), j+1)
            interpolatedGlyphs = []
            interpolatedInfo = None
            interpolatedKerning = None
            interpolationReports = []

            # interpolate font infos

            if doFontInfos:
                infoMasters = [(location, MathInfo(font.info)) for location, font in masterLocations]
                try:
                    bias, iM = buildMutator(infoMasters)
                    instanceInfo = iM.makeInstance(instanceLocation)
                    instanceInfo.extractInfo(newFont.info)
                except:
                    pass

            # interpolate kerning

            if doKerning:
                kerningMasters = [(location, MathKerning(font.kerning)) for location, font in masterLocations]
                try:
                    bias, kM = buildMutator(kerningMasters)
                    instanceKerning = kM.makeInstance(instanceLocation)
                    instanceKerning.extractKerning(newFont)
                    for key, value in baseFont.groups.items():
                        newFont.groups[key] = value
                except:
                    pass

            # filter compatible glyphs

            fontKeys = [set(font.keys()) for font in fonts]
            glyphList = set()
            for i, item in enumerate(fontKeys):
                if i == 0:
                    glyphList = item
                elif i > 0:
                    glyphList = glyphList & item

            compatibleBaseGlyphList = []
            compatibleCompositeGlyphList = []

            for glyphName in glyphList:
                glyphs = [font[glyphName] for font in fonts]
                compatible = True
                for glyph in glyphs[1:]:
                    comp, report = glyphs[0].isCompatible(glyph)
                    if comp == False:
                        name = '%s <X> %s'%(fontName(glyphs[0].getParent()), fontName(glyph.getParent()))
                        reportLine = (name, report)
                        if reportLine not in interpolationReports:
                            interpolationReports.append(reportLine)
                        compatible = False
                if compatible:
                    compatibleBaseGlyphList.append(glyphName)

            # initiate glyph interpolation

            for glyphName in compatibleBaseGlyphList:
                glyphMasters = [(location, MathGlyph(font[glyphName])) for location, font in masterLocations]
                try:
                    bias, gM = buildMutator(glyphMasters)
                    newGlyph = RGlyph()
                    instanceGlyph = gM.makeInstance(instanceLocation)
                    interpolatedGlyphs.append((glyphName, instanceGlyph.extractGlyph(newGlyph)))
                except:
                    continue

            for name, iGlyph in interpolatedGlyphs:
                newFont.insertGlyph(iGlyph, name)

            progress.close()
            digest = []

            if doReport:
                for fontNames, report in interpolationReports:
                    digest.append(fontNames)
                    digest += [u'– %s'%(reportLine) for reportLine in report]
                    digest.append('\n')
                print '\n'.join(digest)

            newFont.showUI()