Ejemplo n.º 1
0
    def run(self, filename, pipedata):
        if 'optimize' in pipedata and not pipedata['optimize']:
            return
        self.bakery.logging_raw('### Optimize TTF {}'.format(filename))
        # copied from https://code.google.com/p/noto/source/browse/nototools/subset.py
        from fontTools.subset import Options, Subsetter, load_font, save_font

        options = Options()
        options.layout_features = "*"
        options.name_IDs = "*"
        options.hinting = True
        options.notdef_outline = True

        font = load_font(op.join(self.builddir, filename), options)
        subsetter = Subsetter(options=options)
        subsetter.populate(glyphs=font.getGlyphOrder())
        subsetter.subset(font)
        save_font(font, op.join(self.builddir, filename + '.opt'), options)

        newsize = op.getsize(op.join(self.builddir, filename + '.opt'))
        origsize = op.getsize(op.join(self.builddir, filename))

        # compare filesizes TODO print analysis of this :)
        comment = "# look at the size savings of that subset process"
        self.bakery.logging_cmd("ls -l '%s'* %s" % (filename, comment))

        statusmessage = "{0}.opt: {1} bytes\n{0}: {2} bytes\n"
        self.bakery.logging_raw(statusmessage.format(filename, newsize, origsize))

        # move ttx files to src
        shutil.move(op.join(self.builddir, filename + '.opt'),
                    op.join(self.builddir, filename),
                    log=self.bakery.logger)
Ejemplo n.º 2
0
    def run(self, pipedata):
        if 'optimize' in pipedata and not pipedata['optimize']:
            return

        from bakery_cli.utils import ProcessedFile
        filename = ProcessedFile()

        self.bakery.logging_raw('### Optimize TTF {}'.format(filename))
        # copied from https://code.google.com/p/noto/source/browse/nototools/subset.py
        from fontTools.subset import Options, Subsetter, load_font, save_font

        options = Options()
        options.layout_features = ["*"]
        options.name_IDs = ["*"]
        options.hinting = True
        options.legacy_kern = True
        options.notdef_outline = True
        options.no_subset_tables += ['DSIG']
        options.drop_tables = list(
            set(options._drop_tables_default) - set(['DSIG']))

        cmd_options = ('--glyphs=*'
                       ' --layout-features=*'
                       ' --name-IDs=*'
                       ' --hinting'
                       ' --legacy-kern --notdef-outline'
                       ' --no-subset-tables+=DSIG'
                       ' --drop-tables-=DSIG')

        font = load_font(op.join(self.builddir, filename), options)

        cmdline = 'pyftsubset {1} {0}'.format(cmd_options,
                                              op.join(self.builddir, filename))
        self.bakery.logging_cmd(cmdline)

        subsetter = Subsetter(options=options)
        subsetter.populate(glyphs=font.getGlyphOrder())
        subsetter.subset(font)
        save_font(font, op.join(self.builddir, filename + '.fix'), options)

        # compare filesizes TODO print analysis of this :)
        comment = "# look at the size savings of that subset process"
        self.bakery.logging_cmd(comment)
        run(u"ls -la {0} {0}.fix | awk '{{ print $5 \"\t\" $9 }}'".format(
            unicode(op.join(self.builddir, filename))))

        comment = "# copy back optimized ttf to original filename"
        self.bakery.logging_cmd(comment)
        shutil.move(op.join(self.builddir, filename + '.fix'),
                    op.join(self.builddir, filename))
Ejemplo n.º 3
0
def subset_font(basefile_path, buff, text):
    options = Options()
    options.name_IDs = []
    options.obfuscate_names = True
    options.flavor = 'woff'

    font = load_font(basefile_path, options)
    subsetter = Subsetter(options=options)
    subsetter.populate(text=text)
    subsetter.subset(font)
    save_font(font, buff, options)

    font.close()
    buff.seek(0)
    return
Ejemplo n.º 4
0
    def run(self, pipedata):
        if 'optimize' in pipedata and not pipedata['optimize']:
            return

        from bakery_cli.utils import ProcessedFile
        filename = ProcessedFile()

        self.bakery.logging_raw('### Optimize TTF {}'.format(filename))
        # copied from https://code.google.com/p/noto/source/browse/nototools/subset.py
        from fontTools.subset import Options, Subsetter, load_font, save_font

        options = Options()
        options.layout_features = ["*"]
        options.name_IDs = ["*"]
        options.hinting = True
        options.legacy_kern = True
        options.notdef_outline = True
        options.no_subset_tables += ['DSIG']
        options.drop_tables = list(set(options._drop_tables_default) - set(['DSIG']))

        cmd_options = ('--glyphs=*'
                       ' --layout-features=*'
                       ' --name-IDs=*'
                       ' --hinting'
                       ' --legacy-kern --notdef-outline'
                       ' --no-subset-tables+=DSIG'
                       ' --drop-tables-=DSIG')

        font = load_font(op.join(self.builddir, filename), options)

        cmdline = 'pyftsubset {1} {0}'.format(cmd_options, op.join(self.builddir, filename))
        self.bakery.logging_cmd(cmdline)

        subsetter = Subsetter(options=options)
        subsetter.populate(glyphs=font.getGlyphOrder())
        subsetter.subset(font)
        save_font(font, op.join(self.builddir, filename + '.fix'), options)

        # compare filesizes TODO print analysis of this :)
        comment = "# look at the size savings of that subset process"
        self.bakery.logging_cmd(comment)
        run(u"ls -la {0} {0}.fix | awk '{{ print $5 \"\t\" $9 }}'".format(unicode(op.join(self.builddir, filename))))

        comment = "# copy back optimized ttf to original filename"
        self.bakery.logging_cmd(comment)
        shutil.move(op.join(self.builddir, filename + '.fix'),
                    op.join(self.builddir, filename))
Ejemplo n.º 5
0
    def customSubsetting(self, font, text):
        options = Options()
        options.layout_features = "*"  # keep all GSUB/GPOS features
        options.glyph_names = False  # keep post glyph names
        options.legacy_cmap = True  # keep non-Unicode cmaps
        options.name_legacy = True  # keep non-Unicode names
        options.name_IDs = ["*"]  # keep all nameIDs
        options.name_languages = ["*"]  # keep all name languages
        options.notdef_outline = True
        options.ignore_missing_glyphs = False
        options.recommended_glyphs = True
        options.prune_unicode_ranges = True
        subsetter = Subsetter(options=options)
        subsetter.populate(text=text, unicodes=[0, 13, 32])
        subsetter.subset(font)

        return font
Ejemplo n.º 6
0
    def run(self, filename, pipedata):
        if 'optimize' in pipedata and not pipedata['optimize']:
            return

        self.bakery.logging_raw('### Optimize TTF {}'.format(filename))
        # copied from https://code.google.com/p/noto/source/browse/nototools/subset.py
        from fontTools.subset import Options, Subsetter, load_font, save_font

        options = Options()
        options.layout_features = ["*"]
        options.name_IDs = ["*"]
        options.hinting = True
        options.legacy_kern = True
        options.notdef_outline = True
        options.no_subset_tables += ['DSIG']
        options.drop_tables = list(
            set(options._drop_tables_default) - set(['DSIG']))

        font = load_font(op.join(self.builddir, filename), options)
        self.bakery.logging_raw('Before: {}'.format(font.keys()))

        self.bakery.logging_raw('{}'.format(options.__dict__))
        subsetter = Subsetter(options=options)
        subsetter.populate(glyphs=font.getGlyphOrder())
        subsetter.subset(font)
        save_font(font, op.join(self.builddir, filename + '.opt'), options)

        newsize = op.getsize(op.join(self.builddir, filename + '.opt'))
        origsize = op.getsize(op.join(self.builddir, filename))

        # compare filesizes TODO print analysis of this :)
        comment = "# look at the size savings of that subset process"
        self.bakery.logging_cmd("ls -l '%s'* %s" % (filename, comment))

        statusmessage = "{0}.opt: {1} bytes\n{0}: {2} bytes\n"
        self.bakery.logging_raw(
            statusmessage.format(filename, newsize, origsize))

        self.bakery.logging_raw('Now: {}'.format(font.keys()))
        # move ttx files to src
        shutil.move(op.join(self.builddir, filename + '.opt'),
                    op.join(self.builddir, filename),
                    log=self.bakery.logger)
Ejemplo n.º 7
0
    def _subset(self, otf, fmt):
        from fontTools.subset import Options, Subsetter

        for name, subset in self.subsets.items():
            logger.info(f"Creating {name}.{fmt.value} subset")
            new = deepcopy(otf)
            options = Options()
            options.name_IDs = ["*"]
            options.name_legacy = True
            options.name_languages = ["*"]
            options.recommended_glyphs = True
            options.layout_features = ["*"]
            options.notdef_outline = True
            options.notdef_glyph = True
            options.glyph_names = True
            options.hinting = True
            options.legacy_kern = True
            options.symbol_cmap = True
            options.layout_closure = False
            options.prune_unicode_ranges = False
            options.passthrough_tables = False
            options.recalc_average_width = True
            options.ignore_missing_glyphs = True
            options.layout_scripts = subset["langsys"]

            options.drop_tables.remove("DSIG")
            options.no_subset_tables += ["DSIG"]

            subsetter = Subsetter(options=options)
            subsetter.populate(subset["glyphlist"])

            with TemporaryLogLevel(logging.WARNING):
                subsetter.subset(new)

            new = self._optimize(new, name, fmt)
            names = subset.get("names")
            if names:
                logger.info(
                    f"Adding name entries to {name}.{fmt.value} susbet")
                self._setnames(new, names)
            self._buildwoff(new, name, fmt)
            self._save(new, name, fmt)
Ejemplo n.º 8
0
    def subsetter(self, font, subset):
        """ use the noto fonts glyphsnames
            to subset fonts with premade subsettings
        """
        options = Options()
        options.layout_features = "*"  # keep all GSUB/GPOS features
        # options.no_layout_closure = True # TESTING
        options.glyph_names = False  # keep post glyph names
        options.legacy_cmap = True  # keep non-Unicode cmaps
        options.name_legacy = True  # keep non-Unicode names
        options.name_IDs = ["*"]  # keep all nameIDs
        options.name_languages = ["*"]  # keep all name languages
        options.notdef_outline = False
        options.ignore_missing_glyphs = True
        options.prune_unicode_ranges = True
        options.recommended_glyphs = True
        subsetter = Subsetter(options=options)
        subsetter.populate(glyphs=subset)
        subsetter.subset(font)

        return font
def subsetFonts(family,
                writingSystem,
                flavor=["ttf"],
                familyNewName=" ",
                jsonpath=" ",
                keepFea=True):
    print(familyNewName)
    # if len(flavor) == 0:
    flavor = ["ttf"]
    latinProCodePageRange = [0, 1, 4, 7, 8]
    cyrProCodePageRange = [2]
    greekProCodePageRange = [3]
    ASCII = [0, 1]
    SecureSet = [0]
    coreArabicCodePageRange = [0, 6]
    unicodePageRangeDict = {
        "Cyrillic": latinProCodePageRange,
        "CyrillicPro": latinProCodePageRange,
        "Greek": greekProCodePageRange,
        "Latin": latinProCodePageRange,
        "ASCII": ASCII,
        "SecureSet": SecureSet,
        "Core_Arabic": coreArabicCodePageRange
    }
    pageRangeToApply = []
    subsetFolder = ""
    for i in writingSystem:
        subsetFolder += i
    formats = ["ttf", "woff", "woff2"]
    toKeep = list()
    folder = getFolder(family)
    folderFonts = os.path.join(folder, "fonts")
    options = Options()
    options.layout_features = '*'  # keep all GSUB/GPOS features
    # options.legacy_kern = True  # keep kern table
    options.glyph_names = False  # keep post glyph names
    options.legacy_cmap = True  # keep non-Unicode cmaps
    options.symbol_cmap = True  # keep Symbol cmaps
    options.name_legacy = True  # keep non-Unicode names
    options.name_IDs = ['*']  # keep all nameIDs
    options.name_languages = ['*']  # keep all name languages
    options.notdef_outline = True  # keep outline of .notdef
    options.ignore_missing_glyphs = True
    options.prune_unicode_ranges = True
    keep = []
    if family in pan_european_fonts:
        jsonpath = "subsets/lgc_glyphset.json"
    elif family in arabic_fonts:
        jsonpath = "subsets/arabic_glyphset.json"
    keep, pageRangeToApply = readJsonStoredSubset(jsonpath, writingSystem)
    for i in flavor:
        if not os.path.exists(os.path.join(folderFonts, i.upper())):
            print(">> Make {} fonts.".format(family))
            designSpace2Instances(family, i, secureSet=False)
    for i in flavor:
        fontspath = [os.path.join(folderFonts, i.upper(), font) \
                    for font in os.listdir(folder + "/fonts/" + i.upper())]
        for f in fontspath:
            if f.split(".")[-1] in formats:
                newfont = TTFont(f)
                for namerecord in newfont['name'].names:
                    namerecord.string = namerecord.toUnicode()
                    if namerecord.nameID == 2:
                        WeightName = namerecord.string
                    if namerecord.nameID == 17:
                        WeightName = "".join(namerecord.string.split(" "))
                        # print(family, WeightName)
                subsetter = Subsetter(options=options)
                subsetter.populate(glyphs=keep)
                subsetter.subset(newfont)
                destination = os.path.join(folder, "fonts",
                                           subsetFolder + "_subset", "fonts")
                if not os.path.exists(os.path.join(destination, i.upper())):
                    os.makedirs(os.path.join(destination, i.upper()))
                subsetName = family + subsetFolder + "-" + WeightName + "." + i
                newfont.save(os.path.join(destination, i.upper(), subsetName))
    folder = family + "/fonts/" + subsetFolder + "_subset"
    if familyNewName != " ":
        renameFonts(folder, familyNewName, codePageRange=pageRangeToApply)
    else:
        familyNewName = family + subsetFolder
        renameFonts(folder, familyNewName, codePageRange=pageRangeToApply)
    shutil.rmtree(destination)