2019-10-19 16:07:16 +00:00
|
|
|
From e158cbe50e17dad1bd41c641d01f3c3989c083c6 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Mike FABIAN <maiku.fabian@gmail.com>
|
|
|
|
Date: Wed, 17 Jul 2019 10:33:21 +0200
|
|
|
|
Subject: [PATCH 1/2] Make it work both with Python2 and Python3
|
|
|
|
|
|
|
|
---
|
|
|
|
add_glyphs.py | 8 +--
|
|
|
|
map_pua_emoji.py | 4 +-
|
|
|
|
third_party/color_emoji/emoji_builder.py | 63 ++++++++++++++----------
|
|
|
|
third_party/color_emoji/png.py | 42 +++++++++++-----
|
|
|
|
4 files changed, 73 insertions(+), 44 deletions(-)
|
|
|
|
|
2019-07-15 14:13:12 +00:00
|
|
|
diff --git a/add_glyphs.py b/add_glyphs.py
|
2019-10-19 16:07:16 +00:00
|
|
|
index a12b4401..b5918d42 100644
|
2019-07-15 14:13:12 +00:00
|
|
|
--- 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):
|
2019-10-19 16:07:16 +00:00
|
|
|
@@ -280,7 +280,7 @@ def add_ligature_sequences(font, seqs, aliases):
|
2019-07-15 14:13:12 +00:00
|
|
|
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.
|
2019-10-19 16:07:16 +00:00
|
|
|
@@ -289,7 +289,7 @@ def add_ligature_sequences(font, seqs, aliases):
|
2019-07-15 14:13:12 +00:00
|
|
|
|
|
|
|
# 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)
|
|
|
|
|
2019-10-19 16:07:16 +00:00
|
|
|
@@ -339,7 +339,7 @@ def apply_aliases(seq_dict, aliases):
|
2019-07-15 14:13:12 +00:00
|
|
|
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
|
2019-10-19 16:07:16 +00:00
|
|
|
index aac031c5..ff8d6a9b 100644
|
2019-07-15 14:13:12 +00:00
|
|
|
--- 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
|
2019-10-19 16:07:16 +00:00
|
|
|
index 4157807e..7f17c62f 100644
|
2019-07-15 14:13:12 +00:00
|
|
|
--- 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
|
2019-10-19 16:07:16 +00:00
|
|
|
index 20f849ae..f5d4c2d5 100644
|
2019-07-15 14:13:12 +00:00
|
|
|
--- 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)
|
|
|
|
--
|
|
|
|
2.21.0
|
|
|
|
|