Esempio n. 1
0
    def getGlyphInfos(self):
        result = []
#        glyphIndexToNameMap = {}
        glyphToCharacterMap = self.getGlyphIndexToCharacterMap()
        if self.ftFont.has_glyph_names:
            for glyphIndex in self.getGlyphIndices():
                glyphNameBuffer = ' '*256
                error = freetype.FT_Get_Glyph_Name(self.ftFont._FT_Face,
                                                   glyphIndex,
                                                   glyphNameBuffer,
                                                   len(glyphNameBuffer) - 1)
                if error:
                    raise freetype.FT_Exception(error)

                glyphInfo = TFSMap()
                glyphInfo.glyphIndex = glyphIndex
                glyphInfo.glyphName = glyphNameBuffer.strip()[:-1]
#                print 'glyphName', glyphIndex, glyphName, len(glyphName)
                glyphInfo.characterCode = None
                if glyphIndex in glyphToCharacterMap:
                    glyphInfo.characterCode = glyphToCharacterMap[glyphIndex]
                result.append(glyphInfo)

        else:
            for glyphIndex, characterCode in glyphToCharacterMap.items():
                glyphInfo = TFSMap()
                glyphInfo.glyphIndex = glyphIndex
                glyphInfo.glyphName = getUnicodeCharacterName(characterCode)
                glyphInfo.characterCode = characterCode
#                glyphInfoMap[glyphIndex] = glyphInfo
                result.append(glyphInfo)

        return result
Esempio n. 2
0
    def getCommandLineSettings(self, *replacementValues):

        parser = self.createParser()

        if replacementValues:
            args = parser.parse_args(replacementValues)
        else:
            args = parser.parse_args()

    #    print 'args', args

        if self.target is None:
            self.target = TFSMap()
        '''
        Copy attributes
        '''
        if self.dumpCommandLineSettings():
            print()
        for attr in sorted(dir(args)):
            if attr.startswith('_'):
                continue
            if self.dumpCommandLineSettings():
                print('arg', attr, getattr(args, attr))
            setattr(self.target, attr, getattr(args, attr))
        if self.dumpCommandLineSettings():
            print()
Esempio n. 3
0
def do_kern_for_pairs(dir_path, fontfilename, weights_str, kernlistdir):
    x = 0
    #
    _dir = dir_path + '/'
    #
    weights = weights_str.split(',')
    #
    get_kern_pair_file_to_tupple(fontfilename, weights, kernlistdir)
    #
    for w in weights:
        #
        print(_dir + fontfilename + "_" + w + ".ufo")
        #
        in_fnt = _dir + fontfilename + "_" + w + "_krn.ufo"
        out_fnt = _dir + fontfilename + "_" + w + "_krn_fix.ufo"
        #
        pseudo_argv = ('--ufo-src-path', in_fnt, '--ufo-dst-path', out_fnt,
                       '--min-distance-ems', '0.04', '--max-distance-ems',
                       '0.05', '--max-x-extrema-overlap-ems', '0.1',
                       '--intrusion-tolerance-ems', '0.02', '--precision-ems',
                       '0.005', '--glyph-pairs-to-kern')

        autokernArgs = TFSMap()
        AutokernSettings(autokernArgs).getCommandLineSettings(*(pseudo_argv +
                                                                pairlist[w]))
        autokern = Autokern(autokernArgs)
        autokern.process()
        #
        x = x + 1
        #
        print('Completed:' + w + ' ' + str(x) + '/' + str(len(weights)) +
              '\n' + ' Produced Kerned UFO:' + out_fnt)
        #
        print('Replace the kern.plist at your leasure')
def do_kern_for_pairs(dir_path, fontfilename, weights_str):
    x = 0
    #
    _dir = dir_path + '/'
    #
    weights = weights_str.split(',')
    #
    #
    for w in weights:
        #
        print(_dir + fontfilename + "_" + w + ".ufo")
        #
        in_fnt = _dir + fontfilename + "_" + w + ".ufo"
        out_fnt = _dir + fontfilename + "_" + w + "_krn.ufo"
        #
        pseudo_argv = (
            '--ufo-src-path',
            in_fnt,
            '--ufo-dst-path',
            out_fnt,
            '--min-distance-ems',
            '0.08',
            '--max-distance-ems',
            '0.10',
            '--max-x-extrema-overlap-ems',
            '0.10',
            '--intrusion-tolerance-ems',
            '0.02',
            '--precision-ems',
            '0.005',
            #'--log-path',
            #'/media/root/Malysh1/winshm/advent_repo/Advent/scripts/kerning_scripts/kern_log/log',
            #'--log-basic-pairs',
            #'--write-kerning-pair-logs'
        )

        print('pseudo_argv', ' '.join([str(arg) for arg in pseudo_argv]))

        autokernArgs = TFSMap()
        AutokernSettings(autokernArgs).getCommandLineSettings(*pseudo_argv)
        autokern = Autokern(autokernArgs)
        autokern.process()
        #
        x = x + 1
        #
        print('Completed:' + w + ' ' + str(x) + '/' + str(len(weights)) +
              '\n' + ' Produced Kerned UFO:' + out_fnt)
        #
        print('Replace the kern.plist at your leasure')
Esempio n. 5
0
#
pseudo_argv = ('--ufo-src-path',
				os.path.join(pardir,'advent_pro','advent_pro_thn.ufo'),
				'--ufo-dst-path',
				os.path.join(pardir,'advent_pro','advent_pro_thn_flat_kern.ufo'),
				'--min-distance-ems',
				'0.05',
				'--max-distance-ems',
				'0.1',
				'--max-x-extrema-overlap-ems',
				'0.1',
				'--intrusion-tolerance-ems',
				'0.4',
				'--precision-ems',
				'0.02',
				#'--log-path',
				#os.path.join(pardir,'logs','log'),
				#'--log-basic-pairs',
				#'--write-kerning-pair-logs',
				)

print ('pseudo_argv', ' '.join([str(arg) for arg in pseudo_argv]))

autokernArgs = TFSMap()

AutokernSettings(autokernArgs).getCommandLineSettings(*pseudo_argv)
autokern = Autokern(autokernArgs)
autokern.process()

print ('complete.')
    def dumpMetricsMap(self, kerningPairMap, htmlFilename):

        print
        print 'fonts scanned:', len(self.processedPostscriptNames)
        print 'fonts processed:', len(self.nonEmptyPostscriptNames)
        print 'glyph pairs observed:', len(kerningPairMap)
        maxGlyphPairCount = reduce(max, kerningPairMap.values())
        print 'Highest glyph pair frequency:', maxGlyphPairCount

        glyphs = []
        for (
                glyph0,
                glyph1,
        ), count in kerningPairMap.iteritems():
            glyph = TFSMap()
            glyph.glyph0 = glyph0
            glyph.glyph1 = glyph1
            glyph.count = count
            glyphs.append(glyph)

        def glyphCountSort(glyph0, glyph1):
            # Negate; we want reverse order for count.
            result = -cmp(glyph0.count, glyph1.count)
            if result != 0:
                return result

            result = cmp(glyph0.glyph0, glyph1.glyph0)
            if result != 0:
                return result

            result = cmp(glyph0.glyph1, glyph1.glyph1)
            if result != 0:
                return result

            return 0
#            return cmp(glyph0.codePoint, glyph1.codePoint)

        glyphs.sort(glyphCountSort)

        print 'Most common glyph:', glyphs[0]
        print 'Least common glyph:', glyphs[-1]

        locale.setlocale(locale.LC_ALL, 'en_US')

        pres = []
        for glyph in glyphs[:5000]:
            #        for glyph in glyphs[:1000]:
            #            pre = {}

            pre = {
                #                    'glyphHex': hex(glyph.codePoint),
                'glyphHex0':
                '%04X' % glyph.glyph0,
                'glyphHex1':
                '%04X' % glyph.glyph1,
                #                    'glyphName0': getUnicodeLongName(glyph.glyph0,
                #                                                    ignoreUnknown=True,
                #                                                    skipValidation=True),
                #                    'glyphName1': getUnicodeLongName(glyph.glyph1,
                #                                                    ignoreUnknown=True,
                #                                                    skipValidation=True),
                'glyphName0':
                getUnicodeCharacterName(glyph.glyph0, ignoreUnknown=True),
                'glyphName1':
                getUnicodeCharacterName(glyph.glyph1, ignoreUnknown=True),
                'glyphCount':
                locale.format("%d", glyph.count, grouping=True),
                'glyphPercent':
                '%0.2f%%' % (100.0 * glyph.count /
                             float(len(self.nonEmptyPostscriptNames))),
                #                   'glyphColor': '%06X' % glyphColor,
            }

            #            pre['value'] = '%s %s: %d (%0.2f%%)' % ( hex(glyph.codePoint),
            #                                            getUnicodeLongName(glyph.codePoint,
            #                                                                    ignoreUnknown=True,
            #                                                                    skipValidation=True),
            #                                            glyph.count,
            #                                            glyph.count / float(len(self.nonEmptyPostscriptNames)),
            #                                            )
            #            print 'pre', pre
            pres.append(pre)

        self.writeMustacheLog(
            'kia_pre_template.txt',
            htmlFilename,
            #                              'most_common_kerning_pairs.html',
            mustacheVars={
                'pres':
                pres,
                #                                              'headerPres': headerPres,
                'pageTitle':
                '1,000 Most Common Kerning Pairs',
                'headerTitle':
                '1,000 Most Common Kerning Pairs',
                #                                              'headerTitle': 'Kerning Pairs Implementation Statistics',
                'statsTitle':
                'Statistics',
                'stats': (
                    {
                        'key':
                        'Total Fonts',
                        'value':
                        locale.format("%d",
                                      len(self.processedPostscriptNames),
                                      grouping=True),
                    },
                    {
                        'key':
                        'Fonts With Valid Kerning Table',
                        'value':
                        locale.format("%d",
                                      len(self.nonEmptyPostscriptNames),
                                      grouping=True),
                    },
                    {
                        'key':
                        'Kerning Pairs Observed',
                        'value':
                        locale.format("%d", len(kerningPairMap),
                                      grouping=True),
                    },
                ),
            }
            #                              replaceMap = {'<!-- SVG Graph Placeholder -->': tableSvg,
            #                                            }
        )
    def dumpMetrics(self):

        print
        print 'fonts scanned:', len(self.processedPostscriptNames)
        print 'fonts processed:', len(self.nonEmptyPostscriptNames)
        print 'glyph pairs observed:', len(self.kerningPairCountMap)
        maxGlyphPairCount = reduce(max, self.kerningPairCountMap.values())
        print 'Highest glyph pair frequency:', maxGlyphPairCount

        #        self.dumpMetricsMap(self.kerningPairCountMap, 'most_common_kerning_pairs.html')
        #        self.dumpMetricsMap(self.kerningPairAbsEmsMap, 'most_common_kerning_pairs_ems.html')
        #        kerningPairAverageMap = {}
        #        for key in self.kerningPairCountMap:
        #            kerningPairAverageMap[key] = self.kerningPairAbsEmsMap[key] / self.kerningPairCountMap[key]
        #        self.dumpMetricsMap(kerningPairAverageMap, 'most_common_kerning_pairs_avg.html')

        countGlyphs = []
        avgGlyphs = []
        for key in self.kerningPairCountMap:
            glyph0, glyph1 = key
            glyph = TFSMap()
            glyph.glyph0 = glyph0
            glyph.glyph1 = glyph1
            glyph.absEmsTotal = self.kerningPairAbsEmsMap[key]
            glyph.count = self.kerningPairCountMap[key]
            glyph.frequencyPct = 100.0 * glyph.count / float(
                len(self.nonEmptyPostscriptNames))
            glyph.absEmsRawAverage = self.kerningPairAbsEmsMap[key] / float(
                len(self.nonEmptyPostscriptNames))
            glyph.absEmsWeightedAverage = self.kerningPairAbsEmsMap[
                key] / float(self.kerningPairCountMap[key])

            glyphHex0 = '%04X' % glyph.glyph0
            glyphHex1 = '%04X' % glyph.glyph1

            def getGlyphName(codePoint):
                result = getUnicodeCharacterName(codePoint,
                                                 ignoreUnknown=True,
                                                 skipValidation=True)
                if result is None:
                    return 'Unknown'
                result = result.replace('<', '').replace('>', '')
                return result

            glyph.label = '0x%s &#x%s %s vs. 0x%s &#x%s %s' % (
                glyphHex0,
                glyphHex0,
                getGlyphName(glyph.glyph0),
                glyphHex1,
                glyphHex1,
                getGlyphName(glyph.glyph1),
            )

            #                   'glyphCount': locale.format("%d", glyph.count, grouping=True),
            #                   'glyphPercent': '%0.2f%%' % (100.0 * glyph.count / float(len(self.nonEmptyPostscriptNames))),

            if glyph.frequencyPct >= 10.0:
                countGlyph = TFSMap(glyph)
                countGlyph.sortValue = glyph.count
                countGlyph.displayValue = glyph.count
                countGlyph.displayValue = '%0.0f%%' % (glyph.frequencyPct, )
                countGlyphs.append(countGlyph)

            if glyph.absEmsRawAverage > 0.03:
                avgGlyph = TFSMap(glyph)
                avgGlyph.sortValue = glyph.absEmsRawAverage
                avgGlyph.displayValue = '%0.2f em' % (glyph.absEmsRawAverage, )
                #            avgGlyph.displayValue = '%0.2f%%' % (100.0 * glyph.absEmsRawAverage, )
                avgGlyphs.append(avgGlyph)

        self.dumpMetricsGroup(countGlyphs, 'Most Common Kerning Pairs',
                              'The most frequent kerning pairs.',
                              'most_common_kerning_pairs_avg.html')
        self.dumpMetricsGroup(avgGlyphs, 'Most Heavily Kerning Pairs',
                              'The most heavily kerning pairs.',
                              'most_heavily_kerning_pairs_avg.html')
Esempio n. 8
0
def getCommandLineSettings(*replacementValues):

    def assertExists(value):
        if not os.path.exists(value):
            msg = "%s does not exist" % value
            raise argparse.ArgumentTypeError(msg)

    def assertParentExists(value):
        if not (os.path.exists(os.path.dirname(value)) and
                os.path.isdir(os.path.dirname(value))):
            msg = "%s is not a valid directory" % os.path.dirname(value)
            raise argparse.ArgumentTypeError(msg)

    def assertIsFolder(value):
        assertExists(value)
        if not os.path.isdir(value):
            msg = "%s is not a folder" % value
            raise argparse.ArgumentTypeError(msg)

    def folderType(value):
        assertIsFolder(value)
        return value
#        return os.path.abspath(value)

    def assertFileExtension(value, extension):
        basename = os.path.basename(value)
        if not basename.lower().endswith(extension.lower()):
            msg = "%s is not a %s file" % ( value, extension, )
            raise argparse.ArgumentTypeError(msg)

    def ufoSrcFolderType(value):
        assertIsFolder(value)
        assertFileExtension(value, '.ufo')
        return value
#        return os.path.abspath(value)

    def ufoDstFolderType(value):
        assertParentExists(value)
        assertFileExtension(value, '.ufo')
#        return os.path.abspath(value)
        return value

    def otfDstFileType(value):
        assertParentExists(value)
        assertFileExtension(value, '.otf')
        return value
#        return os.path.abspath(value)

    parser = argparse.ArgumentParser(description='')

    parser.add_argument('--ufo-src-path',
                        type=ufoSrcFolderType,
                        help='The .ufo source file to kern.',
#                        ) # TODO:
                        required=True)
    parser.add_argument('--ufo-dst-path',
                        type=ufoDstFolderType,
                        help='The .ufo destination file.',
#                        ) # TODO:
                        required=True)
    parser.add_argument('--otf-dst',
                        type=otfDstFileType,
                        help='Optional OpenType (.otf) destination file.',
                        ) # TODO:
#                        required=True)

    parser.add_argument('--log-path',
                        type=folderType,
                        help='Optional folder in which to write HTML logs.  CAUTION: This folder will be completely overwritten.')

    parser.add_argument('--default-diacritical-distance-ems',
                        type=float,
                        default=0.065,
                        help='The default distance between a glyph and its diacritical in ems. 0.0 <= x <= 1.0. Default: 0.065 em')

    parser.add_argument('--top-join-centers',
                        nargs='*',
                        help='A list of custom (unicode code point, horizontal center value) pairs used for top-aligned diacriticals.  To center the diacritical Grave (unicode: 0x60) 100 units right of its origin, use --top-join-centers 0x60 100.  Accepts an arbitrary number of pairs.')

    parser.add_argument('--tail-join-centers',
                        nargs='*',
                        help='A list of custom (unicode code point, horizontal center value) pairs used for tail-aligned diacriticals.  To center the diacritical Ogonek (unicode: 0x2DB) 100 units right of its origin, use --tail-join-centers 0x2DB 100.  Accepts an arbitrary number of pairs.')

    parser.add_argument('--middle-join-centers',
                        nargs='*',
                        help='A list of custom (unicode code point, horizontal center value) pairs used for middle-aligned diacriticals.  To center the diacritical Middle Dot (unicode: 0xB7) 100 units right of its origin, use --middle-join-centers 0xB7 100.  Accepts an arbitrary number of pairs.')

    if replacementValues:
        args = parser.parse_args(replacementValues)
    else:
        args = parser.parse_args()

#    print 'args', args

    result = TFSMap()
    result.ufo_src_path = args.ufo_src
    result.ufo_dst_path = args.ufo_dst
    result.otf_dst = args.otf_dst
    result.log_path = args.log_dst
    result.default_diacritical_distance_ems = args.default_diacritical_distance_ems

    result.top_join_centers = args.top_join_centers
    if result.top_join_centers is not None:
        if len(result.top_join_centers) % 2 != 0:
            raise Exception('--top-join-centers requires an even number of values.')

    result.tail_join_centers = args.tail_join_centers
    if result.tail_join_centers is not None:
        if len(result.tail_join_centers) % 2 != 0:
            raise Exception('--tail-join-centers requires an even number of values.')

    result.middle_join_centers = args.middle_join_centers
    if result.middle_join_centers is not None:
        if len(result.middle_join_centers) % 2 != 0:
            raise Exception('--middle-join-centers requires an even number of values.')

#    print 'args.top_join_centers', args.custom_glyph_centers
#    import sys
#    sys.exit(0)


    return result
Esempio n. 9
0
def _makeUnicodedataCategoryMap():
    '''

http://bugs.python.org/file19991/unicodedata-doc.diff

+   +--------------------------------------------------------------------------+
+   | **General Categories**                                                   |
+   +----+-------------+------------------+------------------------------------+
+   |Name|Major        |Minor             |Examples                            |
+   +====+=============+==================+====================================+
+   |Lu  | Letter      | uppercase        |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Ll  | Letter      | lowercase        |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Lt  | Letter      | titlecase        |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Lm  | Letter      | modifier         |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Lo  | Letter      | other            |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Mn  | Mark        | nonspacing       |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Mc  | Mark        | spacing combining|                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Me  | Mark        | enclosing        |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Nd  | Number      | decimal digit    |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Nl  | Number      | letter           |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |No  | Number      | other            |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Pc  | Punctuation | connector        |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Pd  | Punctuation | dash             |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Ps  | Punctuation | open             |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Pe  | Punctuation | close            |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Pi  | Punctuation | initial quote    |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Pf  | Punctuation | final quote      |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Po  | Punctuation | other            |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Sm  | Symbol      | math             |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Sc  | Symbol      | currency         |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Sk  | Symbol      | modifier         |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |So  | Symbol      | other            |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Zs  | Separator   | space            |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Zl  | Separator   | line             |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Zp  | Separator   | paragraph        |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Cc  | Other       | control          |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Cf  | Other       | format           |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Cs  | Other       | surrogate        |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Co  | Other       | private use      |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Cn  | Other       | not assigned     |                                    |
+   +----+-------------+------------------+------------------------------------+
'''
    result = {}
    for name, major, minor in (
                                ( 'Lu', 'Letter', 'uppercase',),
                                ( 'Ll', 'Letter', 'lowercase',),
                                ( 'Lt', 'Letter', 'titlecase',),
                                ( 'Lm', 'Letter', 'modifier',),
                                ( 'Lo', 'Letter', 'other',),
                                ( 'Mn', 'Mark', 'nonspacing',),
                                ( 'Mc', 'Mark', 'spacing combining',),
                                ( 'Me', 'Mark', 'enclosing',),
                                ( 'Nd', 'Number', 'decimal digit',),
                                ( 'Nl', 'Number', 'letter',),
                                ( 'No', 'Number', 'other',),
                                ( 'Pc', 'Punctuation', 'connector',),
                                ( 'Pd', 'Punctuation', 'dash',),
                                ( 'Ps', 'Punctuation', 'open',),
                                ( 'Pe', 'Punctuation', 'close',),
                                ( 'Pi', 'Punctuation', 'initial quote',),
                                ( 'Pf', 'Punctuation', 'final quote',),
                                ( 'Po', 'Punctuation', 'other',),
                                ( 'Sm', 'Symbol', 'math',),
                                ( 'Sc', 'Symbol', 'currency',),
                                ( 'Sk', 'Symbol', 'modifier',),
                                ( 'So', 'Symbol', 'other',),
                                ( 'Zs', 'Separator', 'space',),
                                ( 'Zl', 'Separator', 'line',),
                                ( 'Zp', 'Separator', 'paragraph',),
                                ( 'Cc', 'Other', 'control',),
                                ( 'Cf', 'Other', 'format',),
                                ( 'Cs', 'Other', 'surrogate',),
                                ( 'Co', 'Other', 'private use',),
                                ( 'Cn', 'Other', 'not assigned',),
                                ):
        category = TFSMap()
        category.name = name
        category.major = major
        category.minor = minor
        result[category.name] = category
    return result
Esempio n. 10
0
    def dumpMetrics(self):

        print
        print 'fonts scanned:', len(self.processedPostscriptNames)
        print 'fonts processed:', len(self.nonEmptyPostscriptNames)
        print 'glyphs observed:', len(self.glyphCountMap)
        maxGlyphCount = reduce(max, self.glyphCountMap.values())
        print 'Highest glyph frequency:', maxGlyphCount

        glyphs = []
        for codePoint, count in self.glyphCountMap.iteritems():
            glyph = TFSMap()
            glyph.codePoint = codePoint
            glyph.count = count
            glyphs.append(glyph)

        def glyphCountSort(glyph0, glyph1):
            # Negate; we want reverse order for count.
            result = -cmp(glyph0.count, glyph1.count)
            if result != 0:
                return result

            return cmp(glyph0.codePoint, glyph1.codePoint)

        glyphs.sort(glyphCountSort)

        print 'Most common glyph:', glyphs[0]
        print 'Least common glyph:', glyphs[-1]

        locale.setlocale(locale.LC_ALL, 'en_US')

        pres = []
        for glyph in glyphs[:1000]:
#            pre = {}

            pre = {
#                    'glyphHex': hex(glyph.codePoint),
                    'glyphHex': '%04X' % glyph.codePoint,
                    'glyphName': getUnicodeLongName(glyph.codePoint,
                                                    ignoreUnknown=True,
                                                    skipValidation=True),
                   'glyphCount': locale.format("%d", glyph.count, grouping=True),
                   'glyphPercent': '%0.2f%%' % (100.0 * glyph.count / float(len(self.nonEmptyPostscriptNames))),
#                   'glyphColor': '%06X' % glyphColor,
                   }

#            pre['value'] = '%s %s: %d (%0.2f%%)' % ( hex(glyph.codePoint),
#                                            getUnicodeLongName(glyph.codePoint,
#                                                                    ignoreUnknown=True,
#                                                                    skipValidation=True),
#                                            glyph.count,
#                                            glyph.count / float(len(self.nonEmptyPostscriptNames)),
#                                            )
#            print 'pre', pre
            pres.append(pre)


        glyphs.sort(lambda glyph0, glyph1:cmp(glyph0.codePoint, glyph1.codePoint))
        headerPres = []
        for glyph in glyphs[:10000]:

            minGlyphColor = 0xffafafff
            maxGlyphColor = 0xff0f0f5f
            phase = glyph.count / float(maxGlyphCount)
            from tfs.common.TFSSvg import blendArgbColors
            glyphColor = 0xffffff & blendArgbColors(minGlyphColor, maxGlyphColor, phase)

            pre = {
#                    'glyphHex': hex(glyph.codePoint),
                    'glyphHex': '%X' % glyph.codePoint,
                    'glyphName': getUnicodeLongName(glyph.codePoint,
                                                    ignoreUnknown=True,
                                                    skipValidation=True),
                   'glyphCount': locale.format("%d", glyph.count, grouping=True),
                   'glyphPercent': '%0.2f%%' % (100.0 * glyph.count / float(len(self.nonEmptyPostscriptNames))),
                   'glyphColor': '%06X' % glyphColor,
                   }
#            pre['value'] = '%s %s: %d (%0.2f%%)' % ( hex(glyph.codePoint),
#                                            getUnicodeCharacterName(glyph.codePoint,
#                                                                    ignoreUnknown=True,
#                                                                    skipValidation=True),
#                                            glyph.count,
#                                            glyph.count / float(len(self.nonEmptyPostscriptNames)),
#                                            )
#            print 'pre', pre
            headerPres.append(pre)

#        tableSvg = self.getTableSvg(glyphs, maxGlyphCount)


        self.writeMustacheLog('gia_pre_template.txt',
                              'most_common_glyphs.html',
                              mustacheVars = { 'pres': pres,
                                              'headerPres': headerPres,
                                              'pageTitle': '1,000 Most Commonly Implemented Font Glyphs',
                                              'headerTitle': 'Glyph Implementation Statistics',
                                              'statsTitle': 'Statistics',
                                              'stats': (
                                                        { 'key': 'Total Fonts Scanned', 'value': locale.format("%d", len(self.processedPostscriptNames), grouping=True), },
                                                        { 'key': 'Distinct Code Points Observed', 'value': locale.format("%d", len(self.glyphCountMap), grouping=True), },
                                                        ),
                                              }
#                              replaceMap = {'<!-- SVG Graph Placeholder -->': tableSvg,
#                                            }
                              )
Esempio n. 11
0
    def getGlyphInfos(self):
        result = []
        #        glyphIndexToNameMap = {}
        glyphToCharacterMap = self.getGlyphIndexToCharacterMap()
        if self.ftFont.has_glyph_names:
            for glyphIndex in self.getGlyphIndices():
                glyphNameBuffer = ' ' * 256
                error = freetype.FT_Get_Glyph_Name(self.ftFont._FT_Face,
                                                   glyphIndex, glyphNameBuffer,
                                                   len(glyphNameBuffer) - 1)
                if error:
                    raise freetype.FT_Exception(error)

                glyphInfo = TFSMap()
                glyphInfo.glyphIndex = glyphIndex
                glyphInfo.glyphName = glyphNameBuffer.strip()[:-1]
                #                print 'glyphName', glyphIndex, glyphName, len(glyphName)
                glyphInfo.characterCode = None
                if glyphIndex in glyphToCharacterMap:
                    glyphInfo.characterCode = glyphToCharacterMap[glyphIndex]
                result.append(glyphInfo)

        else:
            for glyphIndex, characterCode in glyphToCharacterMap.items():
                glyphInfo = TFSMap()
                glyphInfo.glyphIndex = glyphIndex
                glyphInfo.glyphName = getUnicodeCharacterName(characterCode)
                glyphInfo.characterCode = characterCode
                #                glyphInfoMap[glyphIndex] = glyphInfo
                result.append(glyphInfo)

        return result
    def dumpMetricsMap(self, kerningPairMap, htmlFilename):

        print
        print 'fonts scanned:', len(self.processedPostscriptNames)
        print 'fonts processed:', len(self.nonEmptyPostscriptNames)
        print 'glyph pairs observed:', len(kerningPairMap)
        maxGlyphPairCount = reduce(max, kerningPairMap.values())
        print 'Highest glyph pair frequency:', maxGlyphPairCount

        glyphs = []
        for (glyph0, glyph1,), count in kerningPairMap.iteritems():
            glyph = TFSMap()
            glyph.glyph0 = glyph0
            glyph.glyph1 = glyph1
            glyph.count = count
            glyphs.append(glyph)

        def glyphCountSort(glyph0, glyph1):
            # Negate; we want reverse order for count.
            result = -cmp(glyph0.count, glyph1.count)
            if result != 0:
                return result

            result = cmp(glyph0.glyph0, glyph1.glyph0)
            if result != 0:
                return result

            result = cmp(glyph0.glyph1, glyph1.glyph1)
            if result != 0:
                return result

            return 0
#            return cmp(glyph0.codePoint, glyph1.codePoint)

        glyphs.sort(glyphCountSort)

        print 'Most common glyph:', glyphs[0]
        print 'Least common glyph:', glyphs[-1]

        locale.setlocale(locale.LC_ALL, 'en_US')

        pres = []
        for glyph in glyphs[:5000]:
#        for glyph in glyphs[:1000]:
#            pre = {}

            pre = {
#                    'glyphHex': hex(glyph.codePoint),
                    'glyphHex0': '%04X' % glyph.glyph0,
                    'glyphHex1': '%04X' % glyph.glyph1,
#                    'glyphName0': getUnicodeLongName(glyph.glyph0,
#                                                    ignoreUnknown=True,
#                                                    skipValidation=True),
#                    'glyphName1': getUnicodeLongName(glyph.glyph1,
#                                                    ignoreUnknown=True,
#                                                    skipValidation=True),
                    'glyphName0': getUnicodeCharacterName(glyph.glyph0, ignoreUnknown=True),
                    'glyphName1': getUnicodeCharacterName(glyph.glyph1, ignoreUnknown=True),
                   'glyphCount': locale.format("%d", glyph.count, grouping=True),
                   'glyphPercent': '%0.2f%%' % (100.0 * glyph.count / float(len(self.nonEmptyPostscriptNames))),
#                   'glyphColor': '%06X' % glyphColor,
                   }

#            pre['value'] = '%s %s: %d (%0.2f%%)' % ( hex(glyph.codePoint),
#                                            getUnicodeLongName(glyph.codePoint,
#                                                                    ignoreUnknown=True,
#                                                                    skipValidation=True),
#                                            glyph.count,
#                                            glyph.count / float(len(self.nonEmptyPostscriptNames)),
#                                            )
#            print 'pre', pre
            pres.append(pre)


        self.writeMustacheLog('kia_pre_template.txt',
                              htmlFilename,
#                              'most_common_kerning_pairs.html',
                              mustacheVars={ 'pres': pres,
#                                              'headerPres': headerPres,
                                              'pageTitle': '1,000 Most Common Kerning Pairs',
                                              'headerTitle': '1,000 Most Common Kerning Pairs',
#                                              'headerTitle': 'Kerning Pairs Implementation Statistics',
                                              'statsTitle': 'Statistics',
                                              'stats': (
                                                        { 'key': 'Total Fonts', 'value': locale.format("%d", len(self.processedPostscriptNames), grouping=True), },
                                                        { 'key': 'Fonts With Valid Kerning Table', 'value': locale.format("%d", len(self.nonEmptyPostscriptNames), grouping=True), },
                                                        { 'key': 'Kerning Pairs Observed', 'value': locale.format("%d", len(kerningPairMap), grouping=True), },
                                                        ),
                                              }
#                              replaceMap = {'<!-- SVG Graph Placeholder -->': tableSvg,
#                                            }
                              )
    def dumpMetrics(self):

        print
        print 'fonts scanned:', len(self.processedPostscriptNames)
        print 'fonts processed:', len(self.nonEmptyPostscriptNames)
        print 'glyph pairs observed:', len(self.kerningPairCountMap)
        maxGlyphPairCount = reduce(max, self.kerningPairCountMap.values())
        print 'Highest glyph pair frequency:', maxGlyphPairCount

#        self.dumpMetricsMap(self.kerningPairCountMap, 'most_common_kerning_pairs.html')
#        self.dumpMetricsMap(self.kerningPairAbsEmsMap, 'most_common_kerning_pairs_ems.html')
#        kerningPairAverageMap = {}
#        for key in self.kerningPairCountMap:
#            kerningPairAverageMap[key] = self.kerningPairAbsEmsMap[key] / self.kerningPairCountMap[key]
#        self.dumpMetricsMap(kerningPairAverageMap, 'most_common_kerning_pairs_avg.html')

        countGlyphs = []
        avgGlyphs = []
        for key in self.kerningPairCountMap:
            glyph0, glyph1 = key
            glyph = TFSMap()
            glyph.glyph0 = glyph0
            glyph.glyph1 = glyph1
            glyph.absEmsTotal = self.kerningPairAbsEmsMap[key]
            glyph.count = self.kerningPairCountMap[key]
            glyph.frequencyPct = 100.0 * glyph.count / float(len(self.nonEmptyPostscriptNames))
            glyph.absEmsRawAverage = self.kerningPairAbsEmsMap[key] / float(len(self.nonEmptyPostscriptNames))
            glyph.absEmsWeightedAverage = self.kerningPairAbsEmsMap[key] / float(self.kerningPairCountMap[key])

            glyphHex0 = '%04X' % glyph.glyph0
            glyphHex1 = '%04X' % glyph.glyph1

            def getGlyphName(codePoint):
                result = getUnicodeCharacterName(codePoint, ignoreUnknown=True, skipValidation=True)
                if result is None:
                    return 'Unknown'
                result = result.replace('<', '').replace('>', '')
                return result
            glyph.label = '0x%s &#x%s %s vs. 0x%s &#x%s %s' % ( glyphHex0,
                                                                glyphHex0,
                                                                getGlyphName(glyph.glyph0),
                                                                glyphHex1,
                                                                glyphHex1,
                                                                getGlyphName(glyph.glyph1),
                                                                )

#                   'glyphCount': locale.format("%d", glyph.count, grouping=True),
#                   'glyphPercent': '%0.2f%%' % (100.0 * glyph.count / float(len(self.nonEmptyPostscriptNames))),

            if glyph.frequencyPct >= 10.0:
                countGlyph = TFSMap(glyph)
                countGlyph.sortValue = glyph.count
                countGlyph.displayValue = glyph.count
                countGlyph.displayValue = '%0.0f%%' % ( glyph.frequencyPct, )
                countGlyphs.append(countGlyph)

            if glyph.absEmsRawAverage > 0.03:
                avgGlyph = TFSMap(glyph)
                avgGlyph.sortValue = glyph.absEmsRawAverage
                avgGlyph.displayValue = '%0.2f em' % (glyph.absEmsRawAverage,)
    #            avgGlyph.displayValue = '%0.2f%%' % (100.0 * glyph.absEmsRawAverage, )
                avgGlyphs.append(avgGlyph)


        self.dumpMetricsGroup(countGlyphs,
                              'Most Common Kerning Pairs',
                              'The most frequent kerning pairs.',
                              'most_common_kerning_pairs_avg.html')
        self.dumpMetricsGroup(avgGlyphs,
                              'Most Heavily Kerning Pairs',
                              'The most heavily kerning pairs.',
                              'most_heavily_kerning_pairs_avg.html')
Esempio n. 14
0
def _makeUnicodedataCategoryMap():
    '''

http://bugs.python.org/file19991/unicodedata-doc.diff

+   +--------------------------------------------------------------------------+
+   | **General Categories**                                                   |
+   +----+-------------+------------------+------------------------------------+
+   |Name|Major        |Minor             |Examples                            |
+   +====+=============+==================+====================================+
+   |Lu  | Letter      | uppercase        |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Ll  | Letter      | lowercase        |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Lt  | Letter      | titlecase        |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Lm  | Letter      | modifier         |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Lo  | Letter      | other            |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Mn  | Mark        | nonspacing       |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Mc  | Mark        | spacing combining|                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Me  | Mark        | enclosing        |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Nd  | Number      | decimal digit    |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Nl  | Number      | letter           |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |No  | Number      | other            |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Pc  | Punctuation | connector        |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Pd  | Punctuation | dash             |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Ps  | Punctuation | open             |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Pe  | Punctuation | close            |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Pi  | Punctuation | initial quote    |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Pf  | Punctuation | final quote      |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Po  | Punctuation | other            |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Sm  | Symbol      | math             |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Sc  | Symbol      | currency         |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Sk  | Symbol      | modifier         |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |So  | Symbol      | other            |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Zs  | Separator   | space            |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Zl  | Separator   | line             |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Zp  | Separator   | paragraph        |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Cc  | Other       | control          |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Cf  | Other       | format           |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Cs  | Other       | surrogate        |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Co  | Other       | private use      |                                    |
+   +----+-------------+------------------+------------------------------------+
+   |Cn  | Other       | not assigned     |                                    |
+   +----+-------------+------------------+------------------------------------+
'''
    result = {}
    for name, major, minor in (
        (
            'Lu',
            'Letter',
            'uppercase',
        ),
        (
            'Ll',
            'Letter',
            'lowercase',
        ),
        (
            'Lt',
            'Letter',
            'titlecase',
        ),
        (
            'Lm',
            'Letter',
            'modifier',
        ),
        (
            'Lo',
            'Letter',
            'other',
        ),
        (
            'Mn',
            'Mark',
            'nonspacing',
        ),
        (
            'Mc',
            'Mark',
            'spacing combining',
        ),
        (
            'Me',
            'Mark',
            'enclosing',
        ),
        (
            'Nd',
            'Number',
            'decimal digit',
        ),
        (
            'Nl',
            'Number',
            'letter',
        ),
        (
            'No',
            'Number',
            'other',
        ),
        (
            'Pc',
            'Punctuation',
            'connector',
        ),
        (
            'Pd',
            'Punctuation',
            'dash',
        ),
        (
            'Ps',
            'Punctuation',
            'open',
        ),
        (
            'Pe',
            'Punctuation',
            'close',
        ),
        (
            'Pi',
            'Punctuation',
            'initial quote',
        ),
        (
            'Pf',
            'Punctuation',
            'final quote',
        ),
        (
            'Po',
            'Punctuation',
            'other',
        ),
        (
            'Sm',
            'Symbol',
            'math',
        ),
        (
            'Sc',
            'Symbol',
            'currency',
        ),
        (
            'Sk',
            'Symbol',
            'modifier',
        ),
        (
            'So',
            'Symbol',
            'other',
        ),
        (
            'Zs',
            'Separator',
            'space',
        ),
        (
            'Zl',
            'Separator',
            'line',
        ),
        (
            'Zp',
            'Separator',
            'paragraph',
        ),
        (
            'Cc',
            'Other',
            'control',
        ),
        (
            'Cf',
            'Other',
            'format',
        ),
        (
            'Cs',
            'Other',
            'surrogate',
        ),
        (
            'Co',
            'Other',
            'private use',
        ),
        (
            'Cn',
            'Other',
            'not assigned',
        ),
    ):
        category = TFSMap()
        category.name = name
        category.major = major
        category.minor = minor
        result[category.name] = category
    return result