Esempio n. 1
0
 def test_round(self):
     m = _TestInfoObject()
     m.ascender = 699.99
     m.descender = -199.99
     m.xHeight = 399.66
     m.postscriptSlantAngle = None
     m.postscriptStemSnapH = [80.1, 90.2]
     m.guidelines = [{'y': 100.99, 'x': None, 'angle': None, 'name': 'bar'}]
     m.italicAngle = -9.4
     m.postscriptBlueScale = 0.137
     info = MathInfo(m)
     info = info.round()
     self.assertEqual(info.ascender, 700)
     self.assertEqual(info.descender, -200)
     self.assertEqual(info.xHeight, 400)
     self.assertEqual(m.italicAngle, -9.4)
     self.assertEqual(m.postscriptBlueScale, 0.137)
     self.assertIsNone(info.postscriptSlantAngle)
     self.assertEqual(info.postscriptStemSnapH, [80, 90])
     self.assertEqual(
         [sorted(gl.items()) for gl in info.guidelines],
         [[('angle', 0), ('name', 'bar'), ('x', 0), ('y', 101)]]
     )
     written = {}
     expected = {}
     for attr, value in _testData.items():
         if value is None:
             continue
         written[attr] = getattr(info, attr)
         if isinstance(value, list):
             expectedValue = [_roundNumber(v) for v in value]
         else:
             expectedValue = _roundNumber(value)
         expected[attr] = expectedValue
     self.assertEqual(sorted(expected), sorted(written))
 def test_round(self):
     m = _TestInfoObject()
     m.ascender = 699.99
     m.descender = -199.99
     m.xHeight = 399.66
     m.postscriptSlantAngle = None
     m.postscriptStemSnapH = [80.1, 90.2]
     m.guidelines = [{'y': 100.99, 'x': None, 'angle': None, 'name': 'bar'}]
     m.italicAngle = -9.4
     m.postscriptBlueScale = 0.137
     info = MathInfo(m)
     info = info.round()
     self.assertEqual(info.ascender, 700)
     self.assertEqual(info.descender, -200)
     self.assertEqual(info.xHeight, 400)
     self.assertEqual(m.italicAngle, -9.4)
     self.assertEqual(m.postscriptBlueScale, 0.137)
     self.assertIsNone(info.postscriptSlantAngle)
     self.assertEqual(info.postscriptStemSnapH, [80, 90])
     self.assertEqual([sorted(gl.items()) for gl in info.guidelines],
                      [[('angle', 0), ('name', 'bar'), ('x', 0),
                        ('y', 101)]])
     written = {}
     expected = {}
     for attr, value in _testData.items():
         if value is None:
             continue
         written[attr] = getattr(info, attr)
         if isinstance(value, list):
             expectedValue = [_roundNumber(v) for v in value]
         else:
             expectedValue = _roundNumber(value)
         expected[attr] = expectedValue
     self.assertEqual(sorted(expected), sorted(written))
 def test_compare_different(self):
     info1 = MathInfo(_TestInfoObject())
     info2 = MathInfo(_TestInfoObject())
     info2.ascender = info2.ascender - 1
     self.assertFalse(info1 < info2)
     self.assertTrue(info1 > info2)
     self.assertNotEqual(info1, info2)
Esempio n. 4
0
 def test_compare_different(self):
     info1 = MathInfo(_TestInfoObject())
     info2 = MathInfo(_TestInfoObject())
     info2.ascender = info2.ascender - 1
     self.assertFalse(info1 < info2)
     self.assertTrue(info1 > info2)
     self.assertNotEqual(info1, info2)
Esempio n. 5
0
 def test_weight_name(self):
     info1 = MathInfo(_TestInfoObject())
     info2 = MathInfo(_TestInfoObject())
     info2.openTypeOS2WeightClass = 0
     info3 = info1 + info2
     self.assertEqual(info3.openTypeOS2WeightClass, 500)
     self.assertEqual(info3.postscriptWeightName, "Medium")
     info2.openTypeOS2WeightClass = 49
     info3 = info1 + info2
     self.assertEqual(info3.openTypeOS2WeightClass, 549)
     self.assertEqual(info3.postscriptWeightName, "Medium")
     info2.openTypeOS2WeightClass = 50
     info3 = info1 + info2
     self.assertEqual(info3.openTypeOS2WeightClass, 550)
     self.assertEqual(info3.postscriptWeightName, "Semi-bold")
     info2.openTypeOS2WeightClass = 50
     info3 = info1 - info2
     self.assertEqual(info3.openTypeOS2WeightClass, 450)
     self.assertEqual(info3.postscriptWeightName, "Medium")
     info2.openTypeOS2WeightClass = 51
     info3 = info1 - info2
     self.assertEqual(info3.openTypeOS2WeightClass, 449)
     self.assertEqual(info3.postscriptWeightName, "Normal")
     info2.openTypeOS2WeightClass = 500
     info3 = info1 - info2
     self.assertEqual(info3.openTypeOS2WeightClass, 0)
     self.assertEqual(info3.postscriptWeightName, "Thin")
     info2.openTypeOS2WeightClass = 1500
     info3 = info1 - info2
     self.assertEqual(info3.openTypeOS2WeightClass, -1000)
     self.assertEqual(info3.postscriptWeightName, "Thin")
     info2.openTypeOS2WeightClass = 500
     info3 = info1 + info2
     self.assertEqual(info3.openTypeOS2WeightClass, 1000)
     self.assertEqual(info3.postscriptWeightName, "Black")
 def test_sub(self):
     info1 = MathInfo(_TestInfoObject())
     info2 = MathInfo(_TestInfoObject())
     info3 = info1 - info2
     written = {}
     expected = {}
     for attr, value in _testData.items():
         if value is None:
             continue
         written[attr] = getattr(info3, attr)
         if isinstance(value, list):
             expectedValue = [v - v for v in value]
         else:
             expectedValue = value - value
         expected[attr] = expectedValue
     self.assertEqual(sorted(expected.items()), sorted(written.items()))
 def test_add_data_subset_2nd_operand(self):
     info1 = MathInfo(_TestInfoObject())
     info2 = MathInfo(_TestInfoObject(_testDataSubset))
     info3 = info1 + info2
     written = {}
     expected = {}
     for attr, value in _testData.items():
         if value is None:
             continue
         written[attr] = getattr(info3, attr)
         if isinstance(value, list):
             expectedValue = [v + v for v in value]
         else:
             expectedValue = value + value
         expected[attr] = expectedValue
     self.assertEqual(sorted(expected), sorted(written))
Esempio n. 8
0
    def addInfo(self,
                instanceLocation=None,
                sources=None,
                copySourceName=None):
        """ Add font info data. """
        if instanceLocation is None:
            instanceLocation = self.locationObject
        infoObject = self.font.info
        infoMasters = []
        if sources is None:
            sources = self.sources
        items = []
        for sourceName, (source, sourceLocation) in sources.items():
            if sourceName in self.muted['info']:
                # info in this master was muted, so do not add.
                continue
            items.append((sourceLocation, MathInfo(source.info)))
        bias, m = buildMutator(items)
        instanceObject = m.makeInstance(instanceLocation)
        if self.roundGeometry:
            instanceObject = instanceObject.round()
        instanceObject.extractInfo(self.font.info)

        # handle the copyable info fields
        if copySourceName is not None:
            if not copySourceName in sources:
                if self.verbose and self.logger:
                    self.logger.info(
                        "Copy info source %s not found, skipping.",
                        copySourceName)
                    return
            copySourceObject, loc = sources[copySourceName]
            self._copyFontInfo(self.font.info, copySourceObject.info)
    def test_sub_undefined_number_list_sets_None(self):
        self.assertIn("postscriptBlueValues", _numberListAttrs)

        info1 = _TestInfoObject()
        info1.postscriptBlueValues = None
        m1 = MathInfo(info1)

        info2 = _TestInfoObject()
        info2.postscriptBlueValues = [1, 2, 3]
        m2 = MathInfo(info2)

        m3 = m2 - m1

        self.assertIsNone(m3.postscriptBlueValues)

        m4 = m1 - m2

        self.assertIsNone(m4.postscriptBlueValues)
    def test_number_lists_with_different_lengths(self):
        self.assertIn("postscriptBlueValues", _numberListAttrs)

        info1 = _TestInfoObject()
        info1.postscriptBlueValues = [1, 2]
        m1 = MathInfo(info1)

        info2 = _TestInfoObject()
        info2.postscriptBlueValues = [1, 2, 3]
        m2 = MathInfo(info2)

        m3 = m2 - m1

        self.assertIsNone(m3.postscriptBlueValues)

        m4 = m1 - m2

        self.assertIsNone(m4.postscriptBlueValues)

        m5 = m1 + m2

        self.assertIsNone(m5.postscriptBlueValues)
 def test_div(self):
     info1 = MathInfo(_TestInfoObject())
     info2 = info1 / 2
     written = {}
     expected = {}
     for attr, value in _testData.items():
         if value is None:
             continue
         written[attr] = getattr(info2, attr)
         if isinstance(value, list):
             expectedValue = [v / 2 for v in value]
         else:
             expectedValue = value / 2
         expected[attr] = expectedValue
     self.assertEqual(sorted(expected), sorted(written))
Esempio n. 12
0
    def addInfo(self,
                instanceLocation=None,
                sources=None,
                copySourceName=None):
        """ Add font info data. """
        if instanceLocation is None:
            instanceLocation = self.locationObject
        infoObject = self.font.info
        infoMasters = []
        if sources is None:
            sources = self.sources
        items = []
        for sourceName, (source, sourceLocation) in sources.items():
            if sourceName in self.muted['info']:
                # info in this master was muted, so do not add.
                continue
            items.append((sourceLocation, MathInfo(source.info)))
        try:
            bias, m = buildMutator(items, axes=self.axes)
        except:
            if self.logger:
                self.logger.exception("Error processing font info. %s", items)
            return
        instanceObject = m.makeInstance(instanceLocation,
                                        bend=self.bendLocations)
        if self.roundGeometry:
            try:
                instanceObject = instanceObject.round()
            except AttributeError:
                warnings.warn("MathInfo object missing round() method.")
        instanceObject.extractInfo(self.font.info)

        # handle the copyable info fields
        if copySourceName is not None:
            if not copySourceName in sources:
                if self.verbose and self.logger:
                    self.logger.info(
                        "Copy info source %s not found, skipping.",
                        copySourceName)
                    return
            copySourceObject, loc = sources[copySourceName]
            self._copyFontInfo(self.font.info, copySourceObject.info)
 def test_mul_data_subset(self):
     info1 = MathInfo(_TestInfoObject(_testDataSubset))
     info2 = info1 * 2.5
     written = {}
     expected = {}
     for attr, value in _testDataSubset.items():
         if value is None:
             continue
         written[attr] = getattr(info2, attr)
     expected = {
         "descender":
         -500.0,
         "guidelines": [{
             "y": 250.0,
             "x": 0.0,
             "identifier": "2",
             "angle": 0.0,
             "name": "bar"
         }],
         "postscriptBlueValues": [-25.0, 0.0, 1000.0, 1025.0, 1625.0],
         "unitsPerEm":
         2500.0
     }
     self.assertEqual(sorted(expected.items()), sorted(written.items()))
 def test_weight_name(self):
     info1 = MathInfo(_TestInfoObject())
     info2 = MathInfo(_TestInfoObject())
     info2.openTypeOS2WeightClass = 0
     info3 = info1 + info2
     self.assertEqual(info3.openTypeOS2WeightClass, 500)
     self.assertEqual(info3.postscriptWeightName, "Medium")
     info2.openTypeOS2WeightClass = 49
     info3 = info1 + info2
     self.assertEqual(info3.openTypeOS2WeightClass, 549)
     self.assertEqual(info3.postscriptWeightName, "Medium")
     info2.openTypeOS2WeightClass = 50
     info3 = info1 + info2
     self.assertEqual(info3.openTypeOS2WeightClass, 550)
     self.assertEqual(info3.postscriptWeightName, "Semi-bold")
     info2.openTypeOS2WeightClass = 50
     info3 = info1 - info2
     self.assertEqual(info3.openTypeOS2WeightClass, 450)
     self.assertEqual(info3.postscriptWeightName, "Medium")
     info2.openTypeOS2WeightClass = 51
     info3 = info1 - info2
     self.assertEqual(info3.openTypeOS2WeightClass, 449)
     self.assertEqual(info3.postscriptWeightName, "Normal")
     info2.openTypeOS2WeightClass = 500
     info3 = info1 - info2
     self.assertEqual(info3.openTypeOS2WeightClass, 0)
     self.assertEqual(info3.postscriptWeightName, "Thin")
     info2.openTypeOS2WeightClass = 1500
     info3 = info1 - info2
     self.assertEqual(info3.openTypeOS2WeightClass, -1000)
     self.assertEqual(info3.postscriptWeightName, "Thin")
     info2.openTypeOS2WeightClass = 500
     info3 = info1 + info2
     self.assertEqual(info3.openTypeOS2WeightClass, 1000)
     self.assertEqual(info3.postscriptWeightName, "Black")
 def test_compare_same(self):
     info1 = MathInfo(_TestInfoObject())
     info2 = MathInfo(_TestInfoObject())
     self.assertFalse(info1 < info2)
     self.assertFalse(info1 > info2)
     self.assertEqual(info1, info2)
    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()