Convert one designspace file or one or more UFOs to a Glyphs.app source file.
519991
def ufo2glyphs(options):
    """"""
    import fontTools.designspaceLib
    import defcon

    sources = options.designspace_file_or_UFOs
    designspace_file = None
    if (
        len(sources) == 1
        and sources[0].endswith(".designspace")
        and os.path.isfile(sources[0])
    ):
        designspace_file = sources[0]
        designspace = fontTools.designspaceLib.DesignSpaceDocument()
        designspace.read(designspace_file)
        object_to_read = designspace
    elif all(source.endswith(".ufo") and os.path.isdir(source) for source in sources):
        ufos = [defcon.Font(source) for source in sources]
        ufos.sort(
            key=lambda ufo: [  # Order the masters by weight and width
                ufo.info.openTypeOS2WeightClass or 400,
                ufo.info.openTypeOS2WidthClass or 5,
            ]
        )
        object_to_read = ufos
    else:
        print(
            "Please specify just one designspace file *or* one or more "
            "UFOs. They must end in '.designspace' or '.ufo', respectively.",
            file=sys.stderr,
        )
        return 1

    font = glyphsLib.to_glyphs(
        object_to_read, minimize_ufo_diffs=options.no_preserve_glyphsapp_metadata
    )

    # Make the Glyphs file more suitable for roundtrip:
    font.customParameters["Disable Last Change"] = options.enable_last_change
    font.disablesAutomaticAlignment = options.enable_automatic_alignment

    if options.output_path:
        font.save(options.output_path)
    else:
        if designspace_file:
            filename_to_write = os.path.splitext(designspace_file)[0] + ".glyphs"
        else:
            filename_to_write = os.path.join(
                os.path.dirname(sources[0]),
                font.familyName.replace(" ", "") + ".glyphs",
            )
        font.save(filename_to_write)
1157123
def gen_properties(output, ascii_props=False, append=False):
    """"""

    files = {
        'gc': os.path.join(output, 'generalcategory.py'),
        'blk': os.path.join(output, 'block.py'),
        'sc': os.path.join(output, 'script.py'),
        'bc': os.path.join(output, 'bidiclass.py'),
        'binary': os.path.join(output, 'binary.py'),
        'posix': os.path.join(output, 'posix.py'),
        'age': os.path.join(output, 'age.py'),
        'ea': os.path.join(output, 'eastasianwidth.py'),
        'gcb': os.path.join(output, 'graphemeclusterbreak.py'),
        'lb': os.path.join(output, 'linebreak.py'),
        'sb': os.path.join(output, 'sentencebreak.py'),
        'wb': os.path.join(output, 'wordbreak.py'),
        'hst': os.path.join(output, 'hangulsyllabletype.py'),
        'dt': os.path.join(output, 'decompositiontype.py'),
        'jt': os.path.join(output, 'joiningtype.py'),
        'jg': os.path.join(output, 'joininggroup.py'),
        'nt': os.path.join(output, 'numerictype.py'),
        'nv': os.path.join(output, 'numericvalue.py'),
        'ccc': os.path.join(output, 'canonicalcombiningclass.py'),
        'qc': os.path.join(output, 'quickcheck.py'),
        'alias': os.path.join(output, 'alias.py')
    }

    files['scx'] = os.path.join(output, 'scriptextensions.py')
    files['insc'] = os.path.join(output, 'indicsyllabiccategory.py')
    if PY34:
        files['bpt'] = os.path.join(output, 'bidipairedbrackettype.py')
    if PY35:
        files['inpc'] = os.path.join(output, 'indicpositionalcategory.py')
    else:
        files['inmc'] = os.path.join(output, 'indicmatracategory.py')
    if PY37:
        files['vo'] = os.path.join(output, 'verticalorientation.py')

    prefix = "ascii" if ascii_props else 'unicode'

    # `L&` or `Lc` won't be found in the table,
    # so initialize 'c' at the start. `&` will have to be converted to 'c'
    # before sending it through.
    categories = [
        'generalcategory', 'script', 'block',
        'bidiclass', 'eastasianwidth', 'linebreak',
        'hangulsyllabletype', 'wordbreak', 'sentencebreak',
        'graphemeclusterbreak', 'decompositiontype', 'joiningtype',
        'joininggroup', 'numerictype', 'numericvalue',
        'canonicalcombiningclass', 'age'
    ]
    categories.append('scriptextensions')
    categories.append('indicsyllabiccategory')
    if PY34:
        categories.append('bidipairedbrackettype')
    if PY35:
        categories.append('indicpositionalcategory')
    else:
        categories.append('indicmatracategory')
    if PY37:
        categories.append('verticalorientation')
    if ascii_props:
        print('=========Ascii Tables=========')
    else:
        print('========Unicode Tables========')
    print('Building: General Category')
    max_range = ASCII_RANGE if ascii_props else UNICODE_RANGE
    all_chars = ALL_ASCII if ascii_props else ALL_CHARS
    table = {'l': {'c': []}}
    itable = {'l': {}}
    with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'UnicodeData.txt'), 'r', 'utf-8') as uf:
        for line in uf:
            data = line.strip().split(';')
            if data:
                i = int(data[0], 16)
                if i > max_range[1]:
                    continue
                p = data[2].lower()
                if p[0] not in table:
                    table[p[0]] = {}
                    itable[p[0]] = {}
                if p[1] not in table[p[0]]:
                    table[p[0]][p[1]] = []
                table[p[0]][p[1]].append(i)
                # Add LC which is a combo of Ll, Lu, and Lt
                if p[0] == 'l' and p[1] in ('l', 'u', 't'):
                    table['l']['c'].append(i)

    # Create inverse of each category
    for k1, v1 in table.items():
        inverse_category = set()
        for k2, v2 in v1.items():
            s = set(v2)
            inverse_category |= s
        itable[k1]['^'] = list(all_chars - inverse_category)

    # Generate Unicode blocks
    print('Building: Blocks')
    gen_blocks(files['blk'], ascii_props, append, prefix)

    # Generate Unicode scripts
    print('Building: Scripts & Script Extensions')
    gen_scripts(
        'Scripts.txt', 'ScriptExtensions.txt', 'scripts', 'script_extensions', files['sc'], files['scx'],
        notexplicit='zzzz', ascii_props=ascii_props, append=append, prefix=prefix
    )

    # Generate Unicode bidi classes
    print('Building: Bidi Classes')
    gen_bidi(files['bc'], ascii_props, append, prefix)

    if PY34:
        print('Building: Bidi Paired Bracket Type')
        gen_enum(
            'BidiBrackets.txt', 'bidi_paired_bracket_type', files['bpt'], notexplicit='n',
            field=2, ascii_props=ascii_props, append=append, prefix=prefix
        )

    # Generate Unicode binary
    print('Building: Binary')
    binary = gen_binary(table, files['binary'], ascii_props, append, prefix)

    # Generate posix table and write out to file.
    print('Building: Posix')
    gen_posix(files['posix'], is_bytes=ascii_props, append=append, prefix=prefix)

    print('Building: Age')
    gen_age(files['age'], ascii_props, append, prefix)

    print('Building: East Asian Width')
    gen_enum(
        'EastAsianWidth.txt', 'east_asian_width', files['ea'],
        notexplicit='n', ascii_props=ascii_props, append=append, prefix=prefix
    )

    print('Building: Grapheme Cluster Break')
    gen_enum(
        'GraphemeBreakProperty.txt', 'grapheme_cluster_break', files['gcb'], notexplicit='other',
        ascii_props=ascii_props, append=append, prefix=prefix
    )

    print('Building: Line Break')
    gen_enum(
        'LineBreak.txt', 'line_break', files['lb'], notexplicit='unknown',
        ascii_props=ascii_props, append=append, prefix=prefix
    )

    print('Building: Sentence Break')
    gen_enum(
        'SentenceBreakProperty.txt', 'sentence_break', files['sb'], notexplicit='other',
        ascii_props=ascii_props, append=append, prefix=prefix
    )

    print('Building: Word Break')
    gen_enum(
        'WordBreakProperty.txt', 'word_break', files['wb'], notexplicit='other',
        ascii_props=ascii_props, append=append, prefix=prefix
    )

    if PY35:
        print('Building: Indic Positional Category')
        gen_enum(
            'IndicPositionalCategory.txt', 'indic_positional_category', files['inpc'], notexplicit='na',
            ascii_props=ascii_props, append=append, prefix=prefix
        )
    else:
        print('Building: Indic Matra Category')
        gen_enum(
            'IndicMatraCategory.txt', 'indic_matra_category', files['inmc'], notexplicit='na',
            ascii_props=ascii_props, append=append, prefix=prefix
        )
    print('Building: Indic Syllabic Category')
    gen_enum(
        'IndicSyllabicCategory.txt', 'indic_syllabic_category', files['insc'], notexplicit='other',
        ascii_props=ascii_props, append=append, prefix=prefix
    )

    print('Building: Hangul Syllable Type')
    gen_enum(
        'HangulSyllableType.txt', 'hangul_syllable_type', files['hst'], notexplicit='na',
        ascii_props=ascii_props, append=append, prefix=prefix
    )

    print('Building: Decomposition Type')
    gen_enum(
        'DerivedDecompositionType.txt', 'decomposition_type', files['dt'], notexplicit='none',
        ascii_props=ascii_props, append=append, prefix=prefix
    )

    print('Building: Joining Type')
    gen_enum(
        'DerivedJoiningType.txt', 'joining_type', files['jt'], notexplicit='u',
        ascii_props=ascii_props, append=append, prefix=prefix
    )

    print('Building: Joining Group')
    gen_enum(
        'DerivedJoiningGroup.txt', 'joining_group', files['jg'], notexplicit='nonjoining',
        ascii_props=ascii_props, append=append, prefix=prefix
    )

    print('Building: Numeric Type')
    gen_enum(
        'DerivedNumericType.txt', 'numeric_type', files['nt'], notexplicit='none',
        ascii_props=ascii_props, append=append, prefix=prefix
    )

    print('Building: Numeric Value')
    gen_enum(
        'DerivedNumericValues.txt', 'numeric_values', files['nv'], field=3, notexplicit='nan',
        ascii_props=ascii_props, append=append, prefix=prefix
    )

    print('Building: Canonical Combining Class')
    gen_ccc(files['ccc'], ascii_props, append, prefix)

    print('Building: NF* Quick Check')
    categories.extend(gen_nf_quick_check(files['qc'], ascii_props, append, prefix))

    if PY37:
        print('Building: Vertical Orientation')
        gen_enum(
            'VerticalOrientation.txt', 'vertical_orientation', files['vo'], notexplicit='R',
            ascii_props=ascii_props, append=append, prefix=prefix
        )

    if not ascii_props:
        print('Building: Aliases')
        gen_alias(categories, binary, files['alias'], ascii_props, append, prefix)

    # Convert char values to string ranges.
    char2range(table, is_bytes=ascii_props)
    char2range(itable, is_bytes=ascii_props, invert=False)
    for k1, v1 in itable.items():
        table[k1]['^'] = v1['^']

    with codecs.open(files['gc'], 'a' if append else 'w', 'utf-8') as f:
        if not append:
            f.write(HEADER)
        # Write out the Unicode properties
        f.write('%s_properties = {\n' % prefix)
        count = len(table) - 1
        i = 0
        for k1, v1 in sorted(table.items()):
            f.write('    "%s": {\n' % k1)
            count2 = len(v1) - 1
            j = 0
            for k2, v2 in sorted(v1.items()):
                f.write('        "%s": "%s"' % (k2, v2))
                if j == count2:
                    f.write('\n    }')
                else:
                    f.write(',\n')
                j += 1
            if i == count:
                f.write('\n}\n')
            else:
                f.write(',\n')
            i += 1

    if not append:
        with codecs.open(os.path.join(output, '__init__.py'), 'w') as f:
            f.write(HEADER)
            for x in sorted(files):
                f.write('from .%s import *  # noqa\n' % os.path.basename(files[x])[:-3])
231994
function createAPIJS(symbols, filename) {

	var output = [];

	var rkeywords = /^(?:abstract|as|boolean|break|byte|case|catch|char|class|continue|const|debugger|default|delete|do|double|else|enum|export|extends|false|final|finally|float|for|function|goto|if|implements|import|in|instanceof|int|interface|is|long|namespace|native|new|null|package|private|protected|public|return|short|static|super|switch|synchronized|this|throw|throws|transient|true|try|typeof|use|var|void|volatile|while|with)$/;

	function isNoKeyword($) { return !rkeywords.test($.name); }

	function isAPI($) { return $.access === 'public' || $.access === 'protected' || !$.access; }

	function writeln(args) {
		if ( arguments.length ) {
			for (var i = 0; i < arguments.length; i++) {
				output.push(arguments[i]);
			}
		}
		output.push("\n");
	}

	function unwrap(docletSrc) {
		if (!docletSrc) { return ''; }

		// note: keep trailing whitespace for @examples
		// extra opening/closing stars are ignored
		// left margin is considered a star and a space
		// use the /m flag on regex to avoid having to guess what this platform's newline is
		docletSrc =
			docletSrc.replace(/^\/\*\*+/, '') // remove opening slash+stars
			.replace(/\**\*\/$/, "\\Z")       // replace closing star slash with end-marker
			.replace(/^\s*(\* ?|\\Z)/gm, '')  // remove left margin like: spaces+star or spaces+end-marker
			.replace(/\s*\\Z$/g, '');         // remove end-marker

		return docletSrc;
	}

	function comment($, sMetaType) {

		var s = unwrap($.comment.toString());

		// remove the @desc tag
		s = s.replace(/(\r\n|\r|\n)/gm, "\n");
		s = s.replace(/^\s*@desc\s*/gm, "");
		s = s.replace(/^\s*@alias[^\r\n]*(\r\n|\r|\n)?/gm, "");
		s = s.replace(/^\s*@name[^\r\n]*(\r\n|\r|\n)?/gm, "");
		s = s.replace(/^\s*@function[^\r\n]*(\r\n|\r|\n)?/gm, "");
		s = s.replace(/^\s*@author[^\r\n]*(\r\n|\r|\n)?/gm, "");
		s = s.replace(/^\s*@synthetic[^\r\n]*(\r\n|\r|\n)?/gm, "");
		s = s.replace(/^\s*<\/p><p>\s*(\r\n|\r|\n)?/gm, "\n");
		// skip empty documentation
		if ( !s ) {
			return;
		}

		// for namespaces, enforce the @.memberof tag
		if ( sMetaType === "namespace" && $.memberof && s.indexOf("@memberof") < 0 ) {
			s = s + "\n@memberof " + $.memberof;
		}

		writeln("/**\n * " + s.replace(/\n/g, "\n * ") + "\n */");

		/*
		writeln("/**");
		writeln(s.split(/\r\n|\r|\n/g).map(function($) { return " * " + $;}).join("\r\n"));
		writeln(" * /");
		*/

	}

	function signature($) {
		var p = $.params,
			r = [],
			i;
		if ( p ) {
			for (i = 0; i < p.length; i++) {
				// ignore @param tags for 'virtual' params that are used to document members of config-like params
				// (e.g. like "@param param1.key ...")
				if (p[i].name && p[i].name.indexOf('.') < 0) {
					r.push(p[i].name);
				}
			}
		}
		return r.join(',');
	}

	function qname(member,parent) {
		var r = member.memberof;
		if ( member.scope !== 'static' ) {
			r += ".prototype";
		}
		return (r ? r + "." : "") + member.name;
	}

	var mValues = {
		"boolean"  : "false",
		"int"      : "0",
		"float"    : "0.0",
		"number"   : "0.0",
		"string"   : "\"\"",
		"object"   : "new Object()",
		"function" : "function() {}"
	};

	function valueForType(type) {
		if ( type && type.names && type.names[0] ) {
			type = type.names[0];
			if ( REGEXP_ARRAY_TYPE.test(type) || type.indexOf("[]") > 0 ) {
				return "new Array()";
			} else if ( mValues[type] ) {
				return mValues[type];
			} else if ( type.indexOf(".") > 0 ) {
				return "new " + type + "()";
			} else {
				// return "/* unsupported type: " +  member.type + " */ null";
				return "null";
			}
		}
	}

	function value(member) {
		return valueForType(member.type);
	}

	function retvalue(member) {
		//debug(member);
		var r = valueForType(member.type || (member.returns && member.returns.length && member.returns[0] && member.returns[0].type && member.returns[0].type));
		if ( r ) {
			return "return " + r + ";";
		}
		return "";
	}

	var sortedSymbols = symbols.slice(0).filter(function($) { return isaClass($) && isAPI($) && !$.synthetic; }).sort(sortByAlias); // sort only a copy(!) of the symbols, otherwise the SymbolSet lookup is broken
	sortedSymbols.forEach(function(symbol) {

		var sMetaType = (symbol.kind === 'member' && symbol.isEnum) ? 'enum' : symbol.kind;
		if ( sMetaType ) {

			writeln("");
			writeln("// ---- " + symbol.longname + " --------------------------------------------------------------------------");
			writeln("");

			var memberId, member;

			var ownProperties = childrenOfKind(symbol, 'property').own.filter(isNoKeyword).sort(sortByAlias);
				if ( sMetaType === "class" ) {
					comment(symbol, sMetaType);
					writeln(symbol.longname + " = function(" + signature(symbol) + ") {};");
				for ( memberId in ownProperties ) {
					member = ownProperties[memberId];
					comment(member, sMetaType);
					writeln(qname(member, symbol) + " = " + value(member));
					writeln("");
				}
				} else if ( sMetaType === 'namespace' || sMetaType === 'enum' ) {
				//debug("found namespace " + symbol.longname);
				//debug(ownProperties);
					if ( ownProperties.length ) {
						writeln("// dummy function to make Eclipse aware of namespace");
						writeln(symbol.longname + ".toString = function() { return \"\"; };");
					}
				}

			var ownEvents = childrenOfKind(symbol, 'event').own.filter(isNoKeyword).sort(sortByAlias);
			if ( ownEvents.length ) {
				for ( memberId in ownEvents ) {
					member = ownEvents[memberId];
					comment(member, sMetaType);
					writeln(qname(member, symbol) + " = function(" + signature(member) + ") { " + retvalue(member) + " };");
					writeln("");
				}
			}

			var ownMethods = childrenOfKind(symbol, 'method').own.filter(isNoKeyword).sort(sortByAlias);
			if ( ownMethods.length ) {
				for ( memberId in ownMethods ) {
					member = ownMethods[memberId];
					comment(member, sMetaType);
					writeln(qname(member, symbol) + " = function(" + signature(member) + ") { " + retvalue(member) + " };");
					writeln("");
				}
			}

		}
	});

	writeln("// ---- static fields of namespaces ---------------------------------------------------------------------");

	sortedSymbols.forEach(function(symbol) {

		var sMetaType = (symbol.kind === 'member' && symbol.isEnum) ? 'enum' : symbol.kind;

		if ( sMetaType === 'namespace' || sMetaType === 'enum' ) {

			var ownProperties = childrenOfKind(symbol, 'property').own.filter(isNoKeyword).sort(sortByAlias);
			if ( ownProperties.length ) {
				writeln("");
				writeln("// ---- " + symbol.longname + " --------------------------------------------------------------------------");
				writeln("");

				for (var memberId in ownProperties ) {
					var member = ownProperties[memberId];
					comment(member, sMetaType);
					writeln(qname(member, symbol) + " = " + value(member) + ";");
					writeln("");
				}
			}
		}

	});

	fs.mkPath(path.dirname(filename));
	fs.writeFileSync(filename, output.join(""), 'utf8');
	info("  saved as " + filename);
}
208748
def _build_production_name(self, glyph):
        """"""

        # use PostScript names from UFO lib if available
        if self._postscriptNames:
            production_name = self._postscriptNames.get(glyph.name)
            return production_name if production_name else glyph.name

        # use name derived from unicode value
        unicode_val = glyph.unicode
        if glyph.unicode is not None:
            return '%s%04X' % (
                'u' if unicode_val > 0xffff else 'uni', unicode_val)

        # use production name + last (non-script) suffix if possible
        parts = glyph.name.rsplit('.', 1)
        if len(parts) == 2 and parts[0] in self.glyphSet:
            return '%s.%s' % (
                self._build_production_name(self.glyphSet[parts[0]]), parts[1])

        # use ligature name, making sure to look up components with suffixes
        parts = glyph.name.split('.', 1)
        if len(parts) == 2:
            liga_parts = ['%s.%s' % (n, parts[1]) for n in parts[0].split('_')]
        else:
            liga_parts = glyph.name.split('_')
        if len(liga_parts) > 1 and all(n in self.glyphSet for n in liga_parts):
            unicode_vals = [self.glyphSet[n].unicode for n in liga_parts]
            if all(v and v <= 0xffff for v in unicode_vals):
                return 'uni' + ''.join('%04X' % v for v in unicode_vals)
            return '_'.join(
                self._build_production_name(self.glyphSet[n]) for n in liga_parts)

        return glyph.name
479657
def _output_path(
        self,
        ufo_or_font_name,
        ext,
        is_instance=False,
        interpolatable=False,
        autohinted=False,
        is_variable=False,
        output_dir=None,
        suffix=None,
    ):
        """"""

        if isinstance(ufo_or_font_name, basestring):
            font_name = ufo_or_font_name
        elif ufo_or_font_name.path:
            font_name = os.path.splitext(
                os.path.basename(os.path.normpath(ufo_or_font_name.path))
            )[0]
        else:
            font_name = self._font_name(ufo_or_font_name)

        if output_dir is None:
            output_dir = self._output_dir(
                ext, is_instance, interpolatable, autohinted, is_variable
            )
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        if suffix:
            return os.path.join(output_dir, "{}-{}.{}".format(font_name, suffix, ext))
        else:
            return os.path.join(output_dir, "{}.{}".format(font_name, ext))
603207
def to_designspace_instances(self):
    """"""
    for instance in self.font.instances:
        if self.minimize_glyphs_diffs or (
            is_instance_active(instance)
            and _is_instance_included_in_family(self, instance)
        ):
            _to_designspace_instance(self, instance)
1199146
def font(self):
        """"""
        if self._font is not None:
            return self._font

        # Sort UFOS in the original order from the Glyphs file
        sorted_sources = self.to_glyphs_ordered_masters()

        # Convert all full source UFOs to Glyphs masters. Sources with layer names
        # are assumed to be sparse or "brace" layers and are ignored because Glyphs
        # considers them to be special layers and will handle them itself.
        self._font = self.glyphs_module.GSFont()
        self._sources = OrderedDict()  # Same as in UFOBuilder
        for index, source in enumerate(s for s in sorted_sources if not s.layerName):
            master = self.glyphs_module.GSFontMaster()

            # Filter bracket glyphs out of public.glyphOrder.
            if GLYPH_ORDER_KEY in source.font.lib:
                source.font.lib[GLYPH_ORDER_KEY] = [
                    glyph_name
                    for glyph_name in source.font.lib[GLYPH_ORDER_KEY]
                    if ".BRACKET." not in glyph_name
                ]

            self.to_glyphs_font_attributes(source, master, is_initial=(index == 0))
            self.to_glyphs_master_attributes(source, master)
            self._font.masters.insert(len(self._font.masters), master)
            self._sources[master.id] = source

            # First, move free-standing bracket glyphs back to layers to avoid dealing
            # with GSLayer transplantation.
            for bracket_glyph in [g for g in source.font if ".BRACKET." in g.name]:
                base_glyph, threshold = bracket_glyph.name.split(".BRACKET.")
                try:
                    int(threshold)
                except ValueError:
                    raise ValueError(
                        "Glyph '{}' has malformed bracket layer name. Must be '<glyph "
                        "name>.BRACKET.<crossover value>'.".format(bracket_glyph)
                    )
                layer_name = bracket_glyph.lib.get(
                    GLYPHLIB_PREFIX + "_originalLayerName", "[{}]".format(threshold)
                )
                if layer_name not in source.font.layers:
                    ufo_layer = source.font.newLayer(layer_name)
                else:
                    ufo_layer = source.font.layers[layer_name]
                bracket_glyph_new = ufo_layer.newGlyph(base_glyph)
                bracket_glyph_new.copyDataFromGlyph(bracket_glyph)

                # Remove all freestanding bracket layer glyphs from all layers.
                for layer in source.font.layers:
                    if bracket_glyph.name in layer:
                        del layer[bracket_glyph.name]

            for layer in _sorted_backgrounds_last(source.font.layers):
                self.to_glyphs_layer_lib(layer)
                for glyph in layer:
                    self.to_glyphs_glyph(glyph, layer, master)

        self.to_glyphs_features()
        self.to_glyphs_groups()
        self.to_glyphs_kerning()

        # Now that all GSGlyph are built, restore the glyph order
        if self.designspace.sources:
            first_ufo = self.designspace.sources[0].font
            if GLYPH_ORDER_KEY in first_ufo.lib:
                glyph_order = first_ufo.lib[GLYPH_ORDER_KEY]
                lookup = {name: i for i, name in enumerate(glyph_order)}
                self.font.glyphs = sorted(
                    self.font.glyphs, key=lambda glyph: lookup.get(glyph.name, 1 << 63)
                )
            # FIXME: (jany) We only do that on the first one. Maybe we should
            # merge the various `public.glyphorder` values?

            # Restore the layer ordering in each glyph
            for glyph in self._font.glyphs:
                self.to_glyphs_layer_order(glyph)

        self.to_glyphs_family_user_data_from_designspace()
        self.to_glyphs_axes()
        self.to_glyphs_sources()
        self.to_glyphs_instances()

        return self._font
715613
def process(name, path, data, module=True):
    
    # create dir if not exists
    try:
        os.makedirs(path)
    except OSError:
        pass

    global font, glyph_data
    if font is None:
        font = ImageFont.truetype(FONT, FONT_SIZE * SCALE)
    if glyph_data is None:
        glyph_data = TTFont(font.path)

    # make sure that the data is in list form
    if not isinstance(data, list):
        data = [data]

    if contains_bad_glyph(glyph_data, data):
        print("** %s has characters not in %s **" % (name, font.getname()[0]))
    else:
        create_screenshot(name, data, path, font=font, is_module=module)
213560
def loads(s):
    
    p = Parser(current_type=glyphsLib.classes.GSFont)
    logger.info("Parsing .glyphs file")
    data = p.parse(s)
    return data
212936
def _to_ufo_features(self, master, ufo):
    """"""

    # Recover the original feature code if it was stored in the user data
    original = master.userData[ORIGINAL_FEATURE_CODE_KEY]
    if original is not None:
        ufo.features.text = original
        return

    prefixes = []
    for prefix in self.font.featurePrefixes:
        strings = []
        if prefix.name != ANONYMOUS_FEATURE_PREFIX_NAME:
            strings.append("# Prefix: %s\n" % prefix.name)
        strings.append(autostr(prefix.automatic))
        strings.append(prefix.code)
        prefixes.append("".join(strings))

    prefix_str = "\n\n".join(prefixes)

    class_defs = []
    for class_ in self.font.classes:
        prefix = "@" if not class_.name.startswith("@") else ""
        name = prefix + class_.name
        class_defs.append(
            "{}{} = [ {} ];".format(autostr(class_.automatic), name, class_.code)
        )
    class_str = "\n\n".join(class_defs)

    feature_defs = []
    for feature in self.font.features:
        code = feature.code
        lines = ["feature %s {" % feature.name]
        if feature.notes:
            lines.append("# notes:")
            lines.extend("# " + line for line in feature.notes.splitlines())
        if feature.automatic:
            lines.append("# automatic")
        if feature.disabled:
            lines.append("# disabled")
            lines.extend("#" + line for line in code.splitlines())
        else:
            lines.append(code)
        lines.append("} %s;" % feature.name)
        feature_defs.append("\n".join(lines))
    fea_str = "\n\n".join(feature_defs)

    # Don't add a GDEF table when planning to round-trip. To get Glyphs.app-like
    # results, we would need anchor propagation or user intervention. Glyphs.app
    # only generates it on generating binaries.
    gdef_str = None
    if self.generate_GDEF:
        if re.search(r"^\s*table\s+GDEF\s+{", prefix_str, flags=re.MULTILINE):
            raise ValueError(
                "The features already contain a `table GDEF {...}` statement. "
                "Either delete it or set generate_GDEF to False."
            )
        gdef_str = _build_gdef(
            ufo, self._designspace.lib.get("public.skipExportGlyphs")
        )

    # make sure feature text is a unicode string, for defcon
    full_text = (
        "\n\n".join(filter(None, [class_str, prefix_str, fea_str, gdef_str])) + "\n"
    )
    ufo.features.text = full_text if full_text.strip() else ""
665854
function maybeCopyIcons(options, appPath, callback) {
  if (!options.icon) {
    callback();
    return;
  }

  if (options.platform === 'darwin' || options.platform === 'mas') {
    callback();
    return;
  }

  // windows & linux
  // put the icon file into the app
  const destIconPath = path.join(appPath, 'resources/app');
  const destFileName = `icon${path.extname(options.icon)}`;
  copy(options.icon, path.join(destIconPath, destFileName), (error) => {
    callback(error);
  });
}
501026
def _rename_glyphs_from_ufo(self):
        """"""
        rename_map = self._build_production_names()

        otf = self.otf
        otf.setGlyphOrder([rename_map.get(n, n) for n in otf.getGlyphOrder()])

        # we need to compile format 2 'post' table so that the 'extraNames'
        # attribute is updated with the list of the names outside the
        # standard Macintosh glyph order; otherwise, if one dumps the font
        # to TTX directly before compiling first, the post table will not
        # contain the extraNames.
        if 'post' in otf and otf['post'].formatType == 2.0:
            otf['post'].compile(self.otf)

        if 'CFF ' in otf:
            cff = otf['CFF '].cff.topDictIndex[0]
            char_strings = cff.CharStrings.charStrings
            cff.CharStrings.charStrings = {
                rename_map.get(n, n): v for n, v in char_strings.items()}
            cff.charset = [rename_map.get(n, n) for n in cff.charset]
132294
def synthesize(self, modules, use_string, x64, native):
        """"""
        # code_opts = CodeOpts(
        #     str.lower, None if use_string else hash_func,
        #     'reloc_delta', '->',
        #     True)
        # gen_opts = GenOpts('defs', transformed)
        print(hash_func)
        groups = group_by(modules, ends_with_punctuation)
        sources = self.make_source(groups, self.database)
        if sources:
            return stylify_files(
                {'defs.h': sources[0], 'init.c': sources[1]}
            )
        else:
            return ''
587609
def generate(env):
    """"""
    static_obj, shared_obj = SCons.Tool.createObjBuilders(env)

    for suffix in ASSuffixes:
        static_obj.add_action(suffix, SCons.Defaults.ASAction)
        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)

    for suffix in ASPPSuffixes:
        static_obj.add_action(suffix, SCons.Defaults.ASPPAction)
        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)

    env['AS']        = 'nasm'
    env['ASFLAGS']   = SCons.Util.CLVar('')
    env['ASPPFLAGS'] = '$ASFLAGS'
    env['ASCOM']     = '$AS $ASFLAGS -o $TARGET $SOURCES'
    env['ASPPCOM']   = '$CC $ASPPFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
773701
def get_glyph(glyph_name, data=None):
    

    # Read data on first use.
    if data is None:
        global GLYPHDATA
        if GLYPHDATA is None:
            GLYPHDATA = GlyphData.from_files(
                os.path.join(
                    os.path.dirname(glyphsLib.__file__), "data", "GlyphData.xml"
                ),
                os.path.join(
                    os.path.dirname(glyphsLib.__file__),
                    "data",
                    "GlyphData_Ideographs.xml",
                ),
            )
        data = GLYPHDATA

    # Look up data by full glyph name first.
    attributes = _lookup_attributes(glyph_name, data)

    production_name = attributes.get("production")
    if production_name is None:
        production_name = _construct_production_name(glyph_name, data=data)

    unicode_value = attributes.get("unicode")

    category = attributes.get("category")
    sub_category = attributes.get("subCategory")
    if category is None:
        category, sub_category = _construct_category(glyph_name, data)

    # TODO: Determine script in ligatures.
    script = attributes.get("script")
    description = attributes.get("description")

    return Glyph(
        glyph_name,
        production_name,
        unicode_value,
        category,
        sub_category,
        script,
        description,
    )
149490
def convertToMapPic(byteString, mapWidth):
    """"""
    data = []
    line = ""
    for idx,char in enumerate(byteString):
        line += str(ord(char))
        if ((idx+1)%mapWidth)==0:
            data.append(line)
            line = ""
    return data
433087
def ufo_create_background_layer_for_all_glyphs(ufo_font):
    # type: (defcon.Font) -> None
    """"""

    if "public.background" in ufo_font.layers:
        background = ufo_font.layers["public.background"]
    else:
        background = ufo_font.newLayer("public.background")

    for glyph in ufo_font:
        if glyph.name not in background:
            background.newGlyph(glyph.name)