From a9ca546689d384b0ca73ad2a476891c3caaedc20 Mon Sep 17 00:00:00 2001 From: Mike FABIAN Date: Wed, 17 Jul 2019 10:33:21 +0200 Subject: [PATCH] Make it work both with Python2 and Python3 --- add_glyphs.py | 10 ++-- map_pua_emoji.py | 4 +- third_party/color_emoji/emoji_builder.py | 63 ++++++++++++++---------- third_party/color_emoji/png.py | 42 +++++++++++----- 4 files changed, 74 insertions(+), 45 deletions(-) diff --git a/add_glyphs.py b/add_glyphs.py index 5c71b61b4..36d40e676 100644 --- a/add_glyphs.py +++ b/add_glyphs.py @@ -66,7 +66,7 @@ def collect_seq_to_file(image_dirs, prefix, suffix): def remap_values(seq_to_file, map_fn): - return {k: map_fn(v) for k, v in seq_to_file.iteritems()} + return {k: map_fn(v) for k, v in seq_to_file.items()} def get_png_file_to_advance_mapper(lineheight): @@ -228,7 +228,7 @@ def get_rtl_seq(seq): rev_seq = list(seq) rev_seq.reverse() - for i in xrange(1, len(rev_seq)): + for i in range(1, len(rev_seq)): if is_fitzpatrick(rev_seq[i-1]): tmp = rev_seq[i] rev_seq[i] = rev_seq[i-1] @@ -282,7 +282,7 @@ def add_ligature_sequences(font, seqs, aliases): return rtl_seq_to_target_name = { - get_rtl_seq(seq): name for seq, name in seq_to_target_name.iteritems()} + get_rtl_seq(seq): name for seq, name in seq_to_target_name.items()} seq_to_target_name.update(rtl_seq_to_target_name) # sequences that don't have rtl variants get mapped to the empty sequence, # delete it. @@ -291,7 +291,7 @@ def add_ligature_sequences(font, seqs, aliases): # organize by first codepoint in sequence keyed_ligatures = collections.defaultdict(list) - for t in seq_to_target_name.iteritems(): + for t in seq_to_target_name.items(): first_cp = t[0][0] keyed_ligatures[first_cp].append(t) @@ -341,7 +341,7 @@ def apply_aliases(seq_dict, aliases): source is a key in the dictionary, we can delete it. This updates the dictionary and returns the usable aliases.""" usable_aliases = {} - for k, v in aliases.iteritems(): + for k, v in aliases.items(): if v in seq_dict: usable_aliases[k] = v if k in seq_dict: diff --git a/map_pua_emoji.py b/map_pua_emoji.py index aac031c56..ff8d6a9b0 100644 --- a/map_pua_emoji.py +++ b/map_pua_emoji.py @@ -53,8 +53,8 @@ def add_pua_cmap(source_file, target_file): """Add PUA characters to the cmap of the first font and save as second.""" font = ttLib.TTFont(source_file) cmap = font_data.get_cmap(font) - for pua, (ch1, ch2) in (add_emoji_gsub.EMOJI_KEYCAPS.items() - + add_emoji_gsub.EMOJI_FLAGS.items()): + for pua, (ch1, ch2) in (list(add_emoji_gsub.EMOJI_KEYCAPS.items()) + + list(add_emoji_gsub.EMOJI_FLAGS.items())): if pua not in cmap: glyph_name = get_glyph_name_from_gsub([ch1, ch2], font) if glyph_name is not None: diff --git a/third_party/color_emoji/emoji_builder.py b/third_party/color_emoji/emoji_builder.py index 4157807e8..7f17c62fd 100644 --- a/third_party/color_emoji/emoji_builder.py +++ b/third_party/color_emoji/emoji_builder.py @@ -19,7 +19,7 @@ from __future__ import print_function -import sys, struct, StringIO +import sys, struct from png import PNG import os from os import path @@ -112,9 +112,9 @@ class CBDT: line_height = (ascent + descent) * y_ppem / float (upem) line_ascent = ascent * y_ppem / float (upem) y_bearing = int (round (line_ascent - .5 * (line_height - height))) - # fudge y_bearing if calculations are a bit off - if y_bearing == 128: - y_bearing = 127 + # fudge y_bearing if calculations are a bit off + if y_bearing == 128: + y_bearing = 127 advance = width vert_x_bearing = - width / 2 @@ -133,22 +133,22 @@ class CBDT: # CHAR vertBearingX # CHAR vertBearingY # BYTE vertAdvance - try: - if big_metrics: - self.write (struct.pack ("BBbbBbbB", + try: + if big_metrics: + self.write (struct.pack ("BBbbBbbB", height, width, x_bearing, y_bearing, advance, vert_x_bearing, vert_y_bearing, vert_advance)) - else: - self.write (struct.pack ("BBbbB", + else: + self.write (struct.pack ("BBbbB", height, width, x_bearing, y_bearing, advance)) - except Exception as e: - raise ValueError("%s, h: %d w: %d x: %d y: %d %d a:" % ( - e, height, width, x_bearing, y_bearing, advance)) + except Exception as e: + raise ValueError("%s, h: %d w: %d x: %d y: %d %d a:" % ( + e, height, width, x_bearing, y_bearing, advance)) def write_format1 (self, png): @@ -179,12 +179,15 @@ class CBDT: self.write (pixel) offset += stride - png_allowed_chunks = ["IHDR", "PLTE", "tRNS", "sRGB", "IDAT", "IEND"] + png_allowed_chunks = [ + "IHDR", "PLTE", "tRNS", "sRGB", "IDAT", "IEND", # Python2 + b"IHDR", b"PLTE", b"tRNS", b"sRGB", b"IDAT", b"IEND", # Python3 + ] def write_format17 (self, png): self.write_format17or18(png, False) - def write_format18 (self, png): + def write_format18 (self, png): self.write_format17or18(png, True) def write_format17or18 (self, png, big_metrics): @@ -202,7 +205,7 @@ class CBDT: def image_write_func (self, image_format): if image_format == 1: return self.write_format1 - if image_format == 17: return self.write_format17 + if image_format == 17: return self.write_format17 if image_format == 18: return self.write_format18 return None @@ -441,7 +444,10 @@ By default they are dropped. def add_font_table (font, tag, data): tab = ttLib.tables.DefaultTable.DefaultTable (tag) - tab.data = str(data) + if sys.version_info >= (3, 0, 0): + tab.data = data + else: + tab.data = str(data) font[tag] = tab def drop_outline_tables (font): @@ -478,7 +484,7 @@ By default they are dropped. eblc.write_header () eblc.start_strikes (len (img_prefixes)) - def is_vs(cp): + def is_vs(cp): return cp >= 0xfe00 and cp <= 0xfe0f for img_prefix in img_prefixes: @@ -491,14 +497,20 @@ By default they are dropped. codes = img_file[len (img_prefix):-4] if "_" in codes: pieces = codes.split ("_") - cps = [int(code, 16) for code in pieces] - uchars = "".join ([unichr(cp) for cp in cps if not is_vs(cp)]) + cps = [int(code, 16) for code in pieces] + if sys.version_info >= (3, 0, 0): + uchars = "".join ([chr(cp) for cp in cps if not is_vs(cp)]) + else: + uchars = "".join ([unichr(cp) for cp in cps if not is_vs(cp)]) else: - cp = int(codes, 16) - if is_vs(cp): - print("ignoring unexpected vs input %04x" % cp) - continue - uchars = unichr(cp) + cp = int(codes, 16) + if is_vs(cp): + print("ignoring unexpected vs input %04x" % cp) + continue + if sys.version_info >= (3, 0, 0): + uchars = chr(cp) + else: + uchars = unichr(cp) img_files[uchars] = img_file if not img_files: raise Exception ("No image files found in '%s'." % glb) @@ -561,8 +573,7 @@ By default they are dropped. # hack removal of cmap pua entry for unknown flag glyph. If we try to # remove it earlier, getGlyphID dies. Need to restructure all of this # code. - font_data.delete_from_cmap(font, [0xfe82b]) - + font_data.delete_from_cmap(font, [0xfe82b]) font.save (out_file) print("Output font '%s' generated." % out_file) diff --git a/third_party/color_emoji/png.py b/third_party/color_emoji/png.py index 20f849aef..f5d4c2d5c 100644 --- a/third_party/color_emoji/png.py +++ b/third_party/color_emoji/png.py @@ -17,7 +17,12 @@ # Google Author(s): Behdad Esfahbod # -import struct, StringIO +import struct +import sys +if sys.version_info >= (3,0,0): # Python3 + from io import StringIO +else: + from StringIO import StringIO class PNG: @@ -26,7 +31,7 @@ class PNG: def __init__ (self, f): - if isinstance(f, basestring): + if (isinstance(f, str) or isinstance(f, type(u''))): f = open (f, 'rb') self.f = f @@ -43,7 +48,10 @@ class PNG: def data (self): self.seek (0) - return bytearray (self.f.read ()) + if sys.version_info >= (3,0,0): # Python3 + return bytearray (self.f.read (), 'iso-8859-1') + else: + return bytearray (self.f.read ()) class BadSignature (Exception): pass class BadChunk (Exception): pass @@ -55,7 +63,8 @@ class PNG: return PNG.signature def read_chunk (self): - length = struct.unpack (">I", self.f.read (4))[0] + buf = self.f.read (4) + length = struct.unpack (">I", buf)[0] chunk_type = self.f.read (4) chunk_data = self.f.read (length) if len (chunk_data) != length: @@ -67,7 +76,7 @@ class PNG: def read_IHDR (self): (chunk_type, chunk_data, crc) = self.read_chunk () - if chunk_type != "IHDR": + if chunk_type not in ("IHDR", b"IHDR"): raise PNG.BadChunk # Width: 4 bytes # Height: 4 bytes @@ -93,15 +102,24 @@ class PNG: def filter_chunks (self, chunks): self.seek (0); - out = StringIO.StringIO () - out.write (self.read_signature ()) + out = StringIO () + if sys.version_info >= (3,0,0): # Python3 + out.write (self.read_signature ().decode('iso-8859-1')) + else: + out.write (self.read_signature ()) while True: chunk_type, chunk_data, crc = self.read_chunk () if chunk_type in chunks: - out.write (struct.pack (">I", len (chunk_data))) - out.write (chunk_type) - out.write (chunk_data) - out.write (crc) - if chunk_type == "IEND": + if sys.version_info >= (3,0,0): # Python3 + out.write (struct.pack (">I", len (chunk_data)).decode('iso-8859-1')) + out.write (chunk_type.decode('iso-8859-1')) + out.write (chunk_data.decode('iso-8859-1')) + out.write (crc.decode('iso-8859-1')) + else: + out.write (struct.pack (">I", len (chunk_data))) + out.write (chunk_type) + out.write (chunk_data) + out.write (crc) + if chunk_type in ("IEND", b"IEND"): break return PNG (out)