예제 #1
0
 def split_glyph_list(self, glyph):
     glyphs = []
     if len(glyph) > 1:
         # glyph names need to be converted to unicode
         # we need to take into account, that there can be more than one first/second letter in the very same hkern element
         # in this case they will be commas separated and each first letter needs to be combined with each next letter
         # e.g. <hkern g1="A,Agrave,Aacute,Acircumflex,Atilde,Adieresis,Amacron,Abreve,Aogonek" g2="T,Tcaron" k="5" />
         glyph_names = glyph.split(",")
         for glyph_name in glyph_names:
             # each glyph can have additional special markers, e.g. o.cmp
             # toUnicode will not respect those and convert them to a simple letter
             # this behaviour will generate a wrong spacing for this letter.
             # Let's make sure to also transfer the separators and extensions to our json file
             separators = [".", "_"]
             used_separator = False
             for separator in separators:
                 glyph_with_separator = glyph_name.split(separator)
                 if len(glyph_with_separator) == 2:
                     glyphs.append("%s%s%s" %
                                   (toUnicode(glyph_with_separator[0]),
                                    separator, glyph_with_separator[1]))
                     used_separator = True
                     continue
             # there is no extra separator
             if not used_separator:
                 glyphs.append(toUnicode(glyph_name))
     else:
         glyphs.append(glyph)
     return glyphs
예제 #2
0
 def test_spec_examples(self):
     # https://github.com/adobe-type-tools/agl-specification#3-examples
     self.assertEqual(agl.toUnicode("Lcommaaccent"), "Ļ")
     self.assertEqual(agl.toUnicode("uni20AC0308"), "\u20AC\u0308")
     self.assertEqual(agl.toUnicode("u1040C"), "\U0001040C")
     self.assertEqual(agl.toUnicode("uniD801DC0C"), "")
     self.assertEqual(agl.toUnicode("uni20ac"), "")
     self.assertEqual(
         agl.toUnicode("Lcommaaccent_uni20AC0308_u1040C.alternate"),
         "\u013B\u20AC\u0308\U0001040C")
     self.assertEqual(agl.toUnicode("Lcommaaccent_uni013B_u013B"), "ĻĻĻ")
     self.assertEqual(agl.toUnicode("foo"), "")
     self.assertEqual(agl.toUnicode(".notdef"), "")
예제 #3
0
def get_glyph(glyph_name, data=glyphdata_generated):
    """Return a named tuple (Glyph) containing information derived from a glyph
    name akin to GSGlyphInfo.

    The information is derived from an included copy of GlyphsData.xml,
    going purely by the glyph name.
    """

    # First, get the base name of the glyph. .notdef and .null are exceptions.
    # Periods denote glyph variants as per the AGLFN convention, which should
    # be in the same category as their base glyph.
    if glyph_name in (".notdef", ".null"):
        base_name = glyph_name
    else:
        base_name = glyph_name.split(".", 1)[0]

    # Next, look up the glyph name in Glyph's name database to get a Unicode
    # pseudoname, or "production name" as found in a font's post table
    # (e.g. "A-cy" -> "uni0410") so that e.g. PDF readers can map from names
    # to Unicode values. FontTool's agl module can turn this into the actual
    # character.
    production_name = _lookup_production_name(glyph_name)

    # Some Glyphs files use production names instead of Glyph's "nice names".
    # We catch this here, so that we can return the same properties as if
    # the Glyphs file had been following the Glyphs naming conventions.
    # https://github.com/googlei18n/glyphsLib/issues/232
    if production_name is None:
        rev_prodname = data.PRODUCTION_NAMES_REVERSED.get(base_name)
        if rev_prodname is not None:
            production_name = base_name
            base_name = rev_prodname

    # Finally, if we couldn't find a known production name one way or another,
    # conclude that the glyph name doesn't carry any Unicode semantics. Use the
    # bare name in that case.
    if production_name is None:
        production_name = glyph_name

    # Next, derive the actual characters from the production name, e.g.
    # "uni0414" -> "Д". Two caveats:
    # 1. For some glyphs, Glyphs does not have a mapped character even when one
    #    could be derived.
    # 2. For some others, Glyphs has a different idea than the agl module.
    unicode_characters = None
    if base_name not in data.MISSING_UNICODE_STRINGS:  # 1.
        unicode_characters = data.IRREGULAR_UNICODE_STRINGS.get(
            base_name)  # 2.
        if unicode_characters is None:
            unicode_characters = agl.toUnicode(production_name) or None

    # Lastly, generate the category in the sense of Glyph's
    # GSGlyphInfo.category and .subCategory.
    category, sub_category = _get_category(base_name, unicode_characters, data)

    return Glyph(glyph_name, production_name, unicode_characters, category,
                 sub_category)
예제 #4
0
 def test_dingbats(self):
     self.assertEqual(agl.toUnicode("a20", isZapfDingbats=True), "✔")
     self.assertEqual(agl.toUnicode("a20.alt", isZapfDingbats=True), "✔")
     self.assertEqual(agl.toUnicode("a206", isZapfDingbats=True), "❰")
     self.assertEqual(agl.toUnicode("a20", isZapfDingbats=False), "")
     self.assertEqual(agl.toUnicode("a0", isZapfDingbats=True), "")
     self.assertEqual(agl.toUnicode("a207", isZapfDingbats=True), "")
     self.assertEqual(agl.toUnicode("abcdef", isZapfDingbats=True), "")
예제 #5
0
 def test_uniABCD(self):
     self.assertEqual(agl.toUnicode("uni0041"), "A")
     self.assertEqual(agl.toUnicode("uni0041_uni0042_uni0043"), "ABC")
     self.assertEqual(agl.toUnicode("uni004100420043"), "ABC")
     self.assertEqual(agl.toUnicode("uni"), "")
     self.assertEqual(agl.toUnicode("uni41"), "")
     self.assertEqual(agl.toUnicode("uni004101"), "")
     self.assertEqual(agl.toUnicode("uniDC00"), "")
예제 #6
0
 def test_dingbats(self):
     self.assertEqual(agl.toUnicode("a20", isZapfDingbats=True), "✔")
     self.assertEqual(agl.toUnicode("a20.alt", isZapfDingbats=True), "✔")
     self.assertEqual(agl.toUnicode("a206", isZapfDingbats=True), "❰")
     self.assertEqual(agl.toUnicode("a20", isZapfDingbats=False), "")
     self.assertEqual(agl.toUnicode("a0", isZapfDingbats=True), "")
     self.assertEqual(agl.toUnicode("a207", isZapfDingbats=True), "")
     self.assertEqual(agl.toUnicode("abcdef", isZapfDingbats=True), "")
예제 #7
0
 def test_uniABCD(self):
     self.assertEqual(agl.toUnicode("uni0041"), "A")
     self.assertEqual(agl.toUnicode("uni0041_uni0042_uni0043"), "ABC")
     self.assertEqual(agl.toUnicode("uni004100420043"), "ABC")
     self.assertEqual(agl.toUnicode("uni"), "")
     self.assertEqual(agl.toUnicode("uni41"), "")
     self.assertEqual(agl.toUnicode("uni004101"), "")
     self.assertEqual(agl.toUnicode("uniDC00"), "")
예제 #8
0
def get_glyph(name, data=glyphdata_generated):
    prodname = data.PRODUCTION_NAMES.get(name, name)
    unistr = data.IRREGULAR_UNICODE_STRINGS.get(name)
    if unistr is None:
        unistr = agl.toUnicode(prodname)
    if unistr != "" and name not in data.MISSING_UNICODE_STRINGS:
        unistr_result = unistr
    else:
        unistr_result = None
    category, subCategory = _get_category(name, unistr, data)
    return Glyph(name, prodname, unistr_result, category, subCategory)
예제 #9
0
 def test_spec_examples(self):
     # https://github.com/adobe-type-tools/agl-specification#3-examples
     #
     # TODO: Currently, we only handle AGLFN instead of legacy AGL names.
     # Therefore, the test cases below use Iogonek instead of Lcommaaccent.
     # Change Iogonek to Lcommaaccent as soon as the implementation has
     # been fixed to also support legacy AGL names.
     # https://github.com/fonttools/fonttools/issues/775
     self.assertEqual(agl.toUnicode("Iogonek"), "Į")
     self.assertEqual(agl.toUnicode("uni20AC0308"), "\u20AC\u0308")
     self.assertEqual(agl.toUnicode("u1040C"), "\U0001040C")
     self.assertEqual(agl.toUnicode("uniD801DC0C"), "")
     self.assertEqual(agl.toUnicode("uni20ac"), "")
     self.assertEqual(agl.toUnicode("Iogonek_uni20AC0308_u1040C.alternate"),
                      "\u012E\u20AC\u0308\U0001040C")
     self.assertEqual(agl.toUnicode("Iogonek_uni012E_u012E"), "ĮĮĮ")
     self.assertEqual(agl.toUnicode("foo"), "")
     self.assertEqual(agl.toUnicode(".notdef"), "")
예제 #10
0
 def test_spec_examples(self):
     # https://github.com/adobe-type-tools/agl-specification#3-examples
     #
     # TODO: Currently, we only handle AGLFN instead of legacy AGL names.
     # Therefore, the test cases below use Iogonek instead of Lcommaaccent.
     # Change Iogonek to Lcommaaccent as soon as the implementation has
     # been fixed to also support legacy AGL names.
     # https://github.com/fonttools/fonttools/issues/775
     self.assertEqual(agl.toUnicode("Iogonek"), "Į")
     self.assertEqual(agl.toUnicode("uni20AC0308"), "\u20AC\u0308")
     self.assertEqual(agl.toUnicode("u1040C"), "\U0001040C")
     self.assertEqual(agl.toUnicode("uniD801DC0C"), "")
     self.assertEqual(agl.toUnicode("uni20ac"), "")
     self.assertEqual(
         agl.toUnicode("Iogonek_uni20AC0308_u1040C.alternate"),
         "\u012E\u20AC\u0308\U0001040C")
     self.assertEqual(agl.toUnicode("Iogonek_uni012E_u012E"), "ĮĮĮ")
     self.assertEqual(agl.toUnicode("foo"), "")
     self.assertEqual(agl.toUnicode(".notdef"), "")
예제 #11
0
def get_glyph(name, data=glyphdata_generated):
    prodname = data.PRODUCTION_NAMES.get(name)
    # Some Glyphs files use production names (instead of Glyphs names).
    # We catch this here, so that we can return the same properties as if
    # the Glyphs file had been following the Glyphs naming conventions.
    # https://github.com/googlei18n/glyphsLib/issues/232
    if prodname is None:
        rev_prodname = data.PRODUCTION_NAMES_REVERSED.get(name)
        if rev_prodname is not None:
            prodname = name
            name = rev_prodname
    if prodname is None:
        prodname = name
    unistr = data.IRREGULAR_UNICODE_STRINGS.get(name)
    if unistr is None:
        unistr = agl.toUnicode(prodname)
    if unistr != "" and name not in data.MISSING_UNICODE_STRINGS:
        unistr_result = unistr
    else:
        unistr_result = None
    category, subCategory = _get_category(name, unistr, data)
    return Glyph(name, prodname, unistr_result, category, subCategory)
예제 #12
0
    def _read_encoding_with_differences(self) -> None:

        # check whether we've been here before
        if len(self._unicode_lookup_to_character_identifier) > 0:
            return

        # figure out how many characters we'll need to calculate
        assert "FirstChar" in self
        assert isinstance(self["FirstChar"], pDecimal)
        assert "LastChar" in self
        assert isinstance(self["LastChar"], pDecimal)
        first_char: int = int(self["FirstChar"])
        last_char: int = int(self["LastChar"])
        self._character_identifier_to_unicode_lookup = {}

        # apply differences
        i: int = 0
        j: int = 0
        while i < len(self["Encoding"]["Differences"]):
            assert isinstance(self["Encoding"]["Differences"][i], pDecimal)
            character_code: int = self["Encoding"]["Differences"][i]
            j = i + 1
            while j < len(self["Encoding"]["Differences"]) and not isinstance(
                self["Encoding"]["Differences"][j], pDecimal
            ):
                glyph_name: str = str(self["Encoding"]["Differences"][j])
                self._character_identifier_to_unicode_lookup[
                    int(character_code)
                ] = toUnicode(glyph_name)
                character_code += 1
                j += 1
            i = j

        # build reverse map
        self._unicode_lookup_to_character_identifier = {
            v: k for k, v in self._character_identifier_to_unicode_lookup.items()
        }
예제 #13
0
 def test_aglfn(self):
     self.assertEqual(agl.toUnicode("longs_t"), "ſt")
     self.assertEqual(agl.toUnicode("f_f_i.alt123"), "ffi")
예제 #14
0
 def test_uABCD(self):
     self.assertEqual(agl.toUnicode("u0041"), "A")
     self.assertEqual(agl.toUnicode("u00041"), "A")
     self.assertEqual(agl.toUnicode("u000041"), "A")
     self.assertEqual(agl.toUnicode("u0000041"), "")
     self.assertEqual(agl.toUnicode("u0041_uni0041_A.alt"), "AAA")
예제 #15
0
 def test_union(self):
     # Interesting test case because "uni" is a prefix of "union".
     self.assertEqual(agl.toUnicode("union"), "∪")
     # U+222A U+FE00 is a Standardized Variant for UNION WITH SERIFS.
     self.assertEqual(agl.toUnicode("union_uniFE00"), "\u222A\uFE00")
예제 #16
0
 def test_uABCD(self):
     self.assertEqual(agl.toUnicode("u0041"), "A")
     self.assertEqual(agl.toUnicode("u00041"), "A")
     self.assertEqual(agl.toUnicode("u000041"), "A")
     self.assertEqual(agl.toUnicode("u0000041"), "")
     self.assertEqual(agl.toUnicode("u0041_uni0041_A.alt"), "AAA")
예제 #17
0
 def test_union(self):
     # Interesting test case because "uni" is a prefix of "union".
     self.assertEqual(agl.toUnicode("union"), "∪")
     # U+222A U+FE00 is a Standardized Variant for UNION WITH SERIFS.
     self.assertEqual(agl.toUnicode("union_uniFE00"), "\u222A\uFE00")
예제 #18
0
 def test_aglfn(self):
     self.assertEqual(agl.toUnicode("longs_t"), "ſt")
     self.assertEqual(agl.toUnicode("f_f_i.alt123"), "ffi")