Make it work both with Python2 and Python3

pull/267/head
Mike FABIAN 2019-07-17 10:33:21 +02:00 committed by Mike FABIAN
parent f09acc559b
commit a9ca546689
4 changed files with 74 additions and 45 deletions

View File

@ -66,7 +66,7 @@ def collect_seq_to_file(image_dirs, prefix, suffix):
def remap_values(seq_to_file, map_fn): 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): def get_png_file_to_advance_mapper(lineheight):
@ -228,7 +228,7 @@ def get_rtl_seq(seq):
rev_seq = list(seq) rev_seq = list(seq)
rev_seq.reverse() 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]): if is_fitzpatrick(rev_seq[i-1]):
tmp = rev_seq[i] tmp = rev_seq[i]
rev_seq[i] = rev_seq[i-1] rev_seq[i] = rev_seq[i-1]
@ -282,7 +282,7 @@ def add_ligature_sequences(font, seqs, aliases):
return return
rtl_seq_to_target_name = { 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) seq_to_target_name.update(rtl_seq_to_target_name)
# sequences that don't have rtl variants get mapped to the empty sequence, # sequences that don't have rtl variants get mapped to the empty sequence,
# delete it. # delete it.
@ -291,7 +291,7 @@ def add_ligature_sequences(font, seqs, aliases):
# organize by first codepoint in sequence # organize by first codepoint in sequence
keyed_ligatures = collections.defaultdict(list) 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] first_cp = t[0][0]
keyed_ligatures[first_cp].append(t) 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 source is a key in the dictionary, we can delete it. This updates the
dictionary and returns the usable aliases.""" dictionary and returns the usable aliases."""
usable_aliases = {} usable_aliases = {}
for k, v in aliases.iteritems(): for k, v in aliases.items():
if v in seq_dict: if v in seq_dict:
usable_aliases[k] = v usable_aliases[k] = v
if k in seq_dict: if k in seq_dict:

View File

@ -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.""" """Add PUA characters to the cmap of the first font and save as second."""
font = ttLib.TTFont(source_file) font = ttLib.TTFont(source_file)
cmap = font_data.get_cmap(font) cmap = font_data.get_cmap(font)
for pua, (ch1, ch2) in (add_emoji_gsub.EMOJI_KEYCAPS.items() for pua, (ch1, ch2) in (list(add_emoji_gsub.EMOJI_KEYCAPS.items())
+ add_emoji_gsub.EMOJI_FLAGS.items()): + list(add_emoji_gsub.EMOJI_FLAGS.items())):
if pua not in cmap: if pua not in cmap:
glyph_name = get_glyph_name_from_gsub([ch1, ch2], font) glyph_name = get_glyph_name_from_gsub([ch1, ch2], font)
if glyph_name is not None: if glyph_name is not None:

View File

@ -19,7 +19,7 @@
from __future__ import print_function from __future__ import print_function
import sys, struct, StringIO import sys, struct
from png import PNG from png import PNG
import os import os
from os import path from os import path
@ -112,9 +112,9 @@ class CBDT:
line_height = (ascent + descent) * y_ppem / float (upem) line_height = (ascent + descent) * y_ppem / float (upem)
line_ascent = ascent * y_ppem / float (upem) line_ascent = ascent * y_ppem / float (upem)
y_bearing = int (round (line_ascent - .5 * (line_height - height))) y_bearing = int (round (line_ascent - .5 * (line_height - height)))
# fudge y_bearing if calculations are a bit off # fudge y_bearing if calculations are a bit off
if y_bearing == 128: if y_bearing == 128:
y_bearing = 127 y_bearing = 127
advance = width advance = width
vert_x_bearing = - width / 2 vert_x_bearing = - width / 2
@ -133,22 +133,22 @@ class CBDT:
# CHAR vertBearingX # CHAR vertBearingX
# CHAR vertBearingY # CHAR vertBearingY
# BYTE vertAdvance # BYTE vertAdvance
try: try:
if big_metrics: if big_metrics:
self.write (struct.pack ("BBbbBbbB", self.write (struct.pack ("BBbbBbbB",
height, width, height, width,
x_bearing, y_bearing, x_bearing, y_bearing,
advance, advance,
vert_x_bearing, vert_y_bearing, vert_x_bearing, vert_y_bearing,
vert_advance)) vert_advance))
else: else:
self.write (struct.pack ("BBbbB", self.write (struct.pack ("BBbbB",
height, width, height, width,
x_bearing, y_bearing, x_bearing, y_bearing,
advance)) advance))
except Exception as e: except Exception as e:
raise ValueError("%s, h: %d w: %d x: %d y: %d %d a:" % ( raise ValueError("%s, h: %d w: %d x: %d y: %d %d a:" % (
e, height, width, x_bearing, y_bearing, advance)) e, height, width, x_bearing, y_bearing, advance))
def write_format1 (self, png): def write_format1 (self, png):
@ -179,12 +179,15 @@ class CBDT:
self.write (pixel) self.write (pixel)
offset += stride 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): def write_format17 (self, png):
self.write_format17or18(png, False) self.write_format17or18(png, False)
def write_format18 (self, png): def write_format18 (self, png):
self.write_format17or18(png, True) self.write_format17or18(png, True)
def write_format17or18 (self, png, big_metrics): def write_format17or18 (self, png, big_metrics):
@ -202,7 +205,7 @@ class CBDT:
def image_write_func (self, image_format): def image_write_func (self, image_format):
if image_format == 1: return self.write_format1 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 if image_format == 18: return self.write_format18
return None return None
@ -441,7 +444,10 @@ By default they are dropped.
def add_font_table (font, tag, data): def add_font_table (font, tag, data):
tab = ttLib.tables.DefaultTable.DefaultTable (tag) 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 font[tag] = tab
def drop_outline_tables (font): def drop_outline_tables (font):
@ -478,7 +484,7 @@ By default they are dropped.
eblc.write_header () eblc.write_header ()
eblc.start_strikes (len (img_prefixes)) eblc.start_strikes (len (img_prefixes))
def is_vs(cp): def is_vs(cp):
return cp >= 0xfe00 and cp <= 0xfe0f return cp >= 0xfe00 and cp <= 0xfe0f
for img_prefix in img_prefixes: for img_prefix in img_prefixes:
@ -491,14 +497,20 @@ By default they are dropped.
codes = img_file[len (img_prefix):-4] codes = img_file[len (img_prefix):-4]
if "_" in codes: if "_" in codes:
pieces = codes.split ("_") pieces = codes.split ("_")
cps = [int(code, 16) for code in pieces] cps = [int(code, 16) for code in pieces]
uchars = "".join ([unichr(cp) for cp in cps if not is_vs(cp)]) 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: else:
cp = int(codes, 16) cp = int(codes, 16)
if is_vs(cp): if is_vs(cp):
print("ignoring unexpected vs input %04x" % cp) print("ignoring unexpected vs input %04x" % cp)
continue continue
uchars = unichr(cp) if sys.version_info >= (3, 0, 0):
uchars = chr(cp)
else:
uchars = unichr(cp)
img_files[uchars] = img_file img_files[uchars] = img_file
if not img_files: if not img_files:
raise Exception ("No image files found in '%s'." % glb) 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 # 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 # remove it earlier, getGlyphID dies. Need to restructure all of this
# code. # code.
font_data.delete_from_cmap(font, [0xfe82b]) font_data.delete_from_cmap(font, [0xfe82b])
font.save (out_file) font.save (out_file)
print("Output font '%s' generated." % out_file) print("Output font '%s' generated." % out_file)

View File

@ -17,7 +17,12 @@
# Google Author(s): Behdad Esfahbod # 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: class PNG:
@ -26,7 +31,7 @@ class PNG:
def __init__ (self, f): def __init__ (self, f):
if isinstance(f, basestring): if (isinstance(f, str) or isinstance(f, type(u''))):
f = open (f, 'rb') f = open (f, 'rb')
self.f = f self.f = f
@ -43,7 +48,10 @@ class PNG:
def data (self): def data (self):
self.seek (0) 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 BadSignature (Exception): pass
class BadChunk (Exception): pass class BadChunk (Exception): pass
@ -55,7 +63,8 @@ class PNG:
return PNG.signature return PNG.signature
def read_chunk (self): 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_type = self.f.read (4)
chunk_data = self.f.read (length) chunk_data = self.f.read (length)
if len (chunk_data) != length: if len (chunk_data) != length:
@ -67,7 +76,7 @@ class PNG:
def read_IHDR (self): def read_IHDR (self):
(chunk_type, chunk_data, crc) = self.read_chunk () (chunk_type, chunk_data, crc) = self.read_chunk ()
if chunk_type != "IHDR": if chunk_type not in ("IHDR", b"IHDR"):
raise PNG.BadChunk raise PNG.BadChunk
# Width: 4 bytes # Width: 4 bytes
# Height: 4 bytes # Height: 4 bytes
@ -93,15 +102,24 @@ class PNG:
def filter_chunks (self, chunks): def filter_chunks (self, chunks):
self.seek (0); self.seek (0);
out = StringIO.StringIO () out = StringIO ()
out.write (self.read_signature ()) 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: while True:
chunk_type, chunk_data, crc = self.read_chunk () chunk_type, chunk_data, crc = self.read_chunk ()
if chunk_type in chunks: if chunk_type in chunks:
out.write (struct.pack (">I", len (chunk_data))) if sys.version_info >= (3,0,0): # Python3
out.write (chunk_type) out.write (struct.pack (">I", len (chunk_data)).decode('iso-8859-1'))
out.write (chunk_data) out.write (chunk_type.decode('iso-8859-1'))
out.write (crc) out.write (chunk_data.decode('iso-8859-1'))
if chunk_type == "IEND": 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 break
return PNG (out) return PNG (out)