From 65593a3827dfef5f5c8e92bfbb1a8ff0c2c64af4 Mon Sep 17 00:00:00 2001 From: hugovk Date: Sat, 5 Jul 2014 00:04:19 +0300 Subject: [PATCH 1/6] More tests for ImageFont.py --- .coveragerc | 4 ++- Tests/test_imagefont.py | 74 +++++++++++++++++++++++++++++++++-------- 2 files changed, 63 insertions(+), 15 deletions(-) diff --git a/.coveragerc b/.coveragerc index 87e3e968f..39ae20ac6 100644 --- a/.coveragerc +++ b/.coveragerc @@ -11,4 +11,6 @@ exclude_lines = if __name__ == .__main__.: # Don't complain about debug code if Image.DEBUG: - if DEBUG: \ No newline at end of file + if DEBUG: + # Don't complain about Windows code as Travis is Linux + if sys.platform == "win32": diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index 927c80bee..ea1b13cc6 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -5,8 +5,8 @@ from PIL import ImageDraw from io import BytesIO import os -font_path = "Tests/fonts/FreeMono.ttf" -font_size = 20 +FONT_PATH = "Tests/fonts/FreeMono.ttf" +FONT_SIZE = 20 try: @@ -20,17 +20,17 @@ try: ImageFont.core.freetype2_version, "\d+\.\d+\.\d+$") def test_font_with_name(self): - ImageFont.truetype(font_path, font_size) - self._render(font_path) + ImageFont.truetype(FONT_PATH, FONT_SIZE) + self._render(FONT_PATH) self._clean() def _font_as_bytes(self): - with open(font_path, 'rb') as f: + with open(FONT_PATH, 'rb') as f: font_bytes = BytesIO(f.read()) return font_bytes def test_font_with_filelike(self): - ImageFont.truetype(self._font_as_bytes(), font_size) + ImageFont.truetype(self._font_as_bytes(), FONT_SIZE) self._render(self._font_as_bytes()) # Usage note: making two fonts from the same buffer fails. # shared_bytes = self._font_as_bytes() @@ -39,18 +39,18 @@ try: self._clean() def test_font_with_open_file(self): - with open(font_path, 'rb') as f: + with open(FONT_PATH, 'rb') as f: self._render(f) self._clean() def test_font_old_parameters(self): self.assert_warning( DeprecationWarning, - lambda: ImageFont.truetype(filename=font_path, size=font_size)) + lambda: ImageFont.truetype(filename=FONT_PATH, size=FONT_SIZE)) def _render(self, font): txt = "Hello World!" - ttf = ImageFont.truetype(font, font_size) + ttf = ImageFont.truetype(font, FONT_SIZE) w, h = ttf.getsize(txt) img = Image.new("RGB", (256, 64), "white") d = ImageDraw.Draw(img) @@ -63,8 +63,8 @@ try: os.unlink('font.png') def test_render_equal(self): - img_path = self._render(font_path) - with open(font_path, 'rb') as f: + img_path = self._render(FONT_PATH) + with open(FONT_PATH, 'rb') as f: font_filelike = BytesIO(f.read()) img_filelike = self._render(font_filelike) @@ -74,7 +74,7 @@ try: def test_render_multiline(self): im = Image.new(mode='RGB', size=(300, 100)) draw = ImageDraw.Draw(im) - ttf = ImageFont.truetype(font_path, font_size) + ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) line_spacing = draw.textsize('A', font=ttf)[1] + 8 lines = ['hey you', 'you are awesome', 'this looks awkward'] y = 0 @@ -94,7 +94,7 @@ try: img_grey = Image.new("L", (100, 100)) draw = ImageDraw.Draw(img_grey) word = "testing" - font = ImageFont.truetype(font_path, font_size) + font = ImageFont.truetype(FONT_PATH, FONT_SIZE) orientation = Image.ROTATE_90 transposed_font = ImageFont.TransposedFont( @@ -116,7 +116,7 @@ try: img_grey = Image.new("L", (100, 100)) draw = ImageDraw.Draw(img_grey) word = "testing" - font = ImageFont.truetype(font_path, font_size) + font = ImageFont.truetype(FONT_PATH, FONT_SIZE) orientation = None transposed_font = ImageFont.TransposedFont( @@ -133,6 +133,52 @@ try: # Check boxes a and b are same size self.assertEqual(box_size_a, box_size_b) + def test_free_type_font_get_name(self): + # Arrange + font = ImageFont.truetype(FONT_PATH, FONT_SIZE) + + # Act + name = font.getname() + + # Assert + self.assertEqual(('FreeMono', 'Regular'), name) + + def test_free_type_font_get_metrics(self): + # Arrange + font = ImageFont.truetype(FONT_PATH, FONT_SIZE) + + # Act + ascent, descent = font.getmetrics() + + # Assert + self.assertIsInstance(ascent, int) + self.assertIsInstance(descent, int) + self.assertEqual((ascent, descent), (16, 4)) # too exact check? + + def test_load_path_not_found(self): + # Arrange + filename = "somefilenamethatdoesntexist.ttf" + + # Act/Assert + self.assertRaises(IOError, lambda: ImageFont.load_path(filename)) + + def test_default_font(self): + # Arrange + txt = 'This is a "better than nothing" default font.' + im = Image.new(mode='RGB', size=(300, 100)) + draw = ImageDraw.Draw(im) + + target = 'Tests/images/default_font.png' + target_img = Image.open(target) + + # Act + default_font = ImageFont.load_default() + draw.text((10, 10), txt, font=default_font) + + # Assert + self.assert_image_equal(im, target_img) + + except ImportError: class TestImageFont(PillowTestCase): def test_skip(self): From ff6a0b9b8c9f97954814fdd0adf2a9c32171c7c6 Mon Sep 17 00:00:00 2001 From: hugovk Date: Sat, 5 Jul 2014 00:18:52 +0300 Subject: [PATCH 2/6] Add test image using ImageFont's default font --- Tests/images/default_font.png | Bin 0 -> 586 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Tests/images/default_font.png diff --git a/Tests/images/default_font.png b/Tests/images/default_font.png new file mode 100644 index 0000000000000000000000000000000000000000..bb4862b996fe733cc94fb396ecc9209e9fbbedcf GIT binary patch literal 586 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#hD_uc6 zKy~{6|I;r!U*_p%;Lb6>`?7j@8^fdy!_?bAEl}`7_uI;Q{l_0$=B#J0s}sF#EPSpn zieqA@(Bz$3dyD4P*oAw#?SH@h#1xy|I_v*Eosh!GZGUhr|Eu|jZ!C2b`n^wo$qutu z7oJb5JF8Baa%Y4T=)*Ln5Fn_pFPc!H-sEpCwEY5?WR?6$Fdh!_50cVukZ-d{@o=PUA6ewe&0FI4d(wi zzF^MHT}fZ=g`b@%UY2mva&ls^Dc@Hu+3zRU)TBK#Rx?YC`}yun{?s!oo_t$f7I^-R znOu*T+ndPhwR`RsU488J|MJy{veRmJ{?(@YygmGJMfQLB8~cxFgnrqy)Ld)vc9HwV zwSO)9zgF;`Uw`b%?f-9${pW~YWxTsbdt0*1UC#48vuxkZnr&nDEo#>Fmb=QJ0!x@1e#g8Q+<_y)dj`?{B`D@u%(7Qr}9jz~YAz b`oT-)*Xv};1n&#bP0l+XkKI4k`b literal 0 HcmV?d00001 From 770ef9312be9c6e10e9d3b31d27c12b4f8d7cf1a Mon Sep 17 00:00:00 2001 From: hugovk Date: Sat, 5 Jul 2014 01:02:46 +0300 Subject: [PATCH 3/6] flake8 and fix path in __main__ --- PIL/ImageFont.py | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/PIL/ImageFont.py b/PIL/ImageFont.py index 18d09b871..25993007d 100644 --- a/PIL/ImageFont.py +++ b/PIL/ImageFont.py @@ -29,13 +29,15 @@ from __future__ import print_function from PIL import Image from PIL._util import isDirectory, isPath -import os, sys +import os +import sys try: import warnings except ImportError: warnings = None + class _imagingft_not_installed: # module placeholder def __getattr__(self, id): @@ -90,8 +92,8 @@ class ImageFont: # read PILfont header if file.readline() != b"PILfont\n": raise SyntaxError("Not a PILfont file") - d = file.readline().split(b";") - self.info = [] # FIXME: should be a dictionary + file.readline().split(b";") + self.info = [] # FIXME: should be a dictionary while True: s = file.readline() if not s or s == b"DATA\n": @@ -113,6 +115,7 @@ class ImageFont: self.getsize = self.font.getsize self.getmask = self.font.getmask + ## # Wrapper for FreeType fonts. Application code should use the # truetype factory function to create font objects. @@ -124,14 +127,18 @@ class FreeTypeFont: # FIXME: use service provider instead if file: if warnings: - warnings.warn('file parameter deprecated, please use font parameter instead.', DeprecationWarning) + warnings.warn( + 'file parameter deprecated, ' + 'please use font parameter instead.', + DeprecationWarning) font = file if isPath(font): self.font = core.getfont(font, size, index, encoding) else: self.font_bytes = font.read() - self.font = core.getfont("", size, index, encoding, self.font_bytes) + self.font = core.getfont( + "", size, index, encoding, self.font_bytes) def getname(self): return self.font.family, self.font.style @@ -151,7 +158,7 @@ class FreeTypeFont: def getmask2(self, text, mode="", fill=Image.core.fill): size, offset = self.font.getsize(text) im = fill("L", size, 0) - self.font.render(text, im.id, mode=="1") + self.font.render(text, im.id, mode == "1") return im, offset ## @@ -163,12 +170,13 @@ class FreeTypeFont: # be one of Image.FLIP_LEFT_RIGHT, Image.FLIP_TOP_BOTTOM, # Image.ROTATE_90, Image.ROTATE_180, or Image.ROTATE_270. + class TransposedFont: "Wrapper for writing rotated or mirrored text" def __init__(self, font, orientation=None): self.font = font - self.orientation = orientation # any 'transpose' argument, or None + self.orientation = orientation # any 'transpose' argument, or None def getsize(self, text): w, h = self.font.getsize(text) @@ -221,7 +229,10 @@ def truetype(font=None, size=10, index=0, encoding="", filename=None): if filename: if warnings: - warnings.warn('filename parameter deprecated, please use font parameter instead.', DeprecationWarning) + warnings.warn( + 'filename parameter deprecated, ' + 'please use font parameter instead.', + DeprecationWarning) font = filename try: @@ -272,8 +283,8 @@ def load_default(): import base64 f = ImageFont() f._load_pilfont_data( - # courB08 - BytesIO(base64.decodestring(b''' + # courB08 + BytesIO(base64.decodestring(b''' UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA @@ -395,8 +406,8 @@ w7IkEbzhVQAAAABJRU5ErkJggg== if __name__ == "__main__": # create font data chunk for embedding - import base64, os, sys - font = "../Tests/images/courB08" + import base64 + font = "Tests/images/courB08" print(" f._load_pilfont_data(") print(" # %s" % os.path.basename(font)) print(" BytesIO(base64.decodestring(b'''") From 318b405889ae4911a69ff45b3fa07cc246c16607 Mon Sep 17 00:00:00 2001 From: hugovk Date: Sat, 5 Jul 2014 21:32:09 +0300 Subject: [PATCH 4/6] Don't exclude Windows code --- .coveragerc | 2 -- 1 file changed, 2 deletions(-) diff --git a/.coveragerc b/.coveragerc index 39ae20ac6..ea79190ae 100644 --- a/.coveragerc +++ b/.coveragerc @@ -12,5 +12,3 @@ exclude_lines = # Don't complain about debug code if Image.DEBUG: if DEBUG: - # Don't complain about Windows code as Travis is Linux - if sys.platform == "win32": From add45b494a6a99cdc9084f6b0ef8dafa66b20a8c Mon Sep 17 00:00:00 2001 From: hugovk Date: Mon, 7 Jul 2014 22:31:20 +0300 Subject: [PATCH 5/6] Extract __main__ section of PIL/ImageFont.py into Scripts/createfontdatachunk.py --- PIL/ImageFont.py | 13 +------------ Scripts/createfontdatachunk.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 Scripts/createfontdatachunk.py diff --git a/PIL/ImageFont.py b/PIL/ImageFont.py index 25993007d..036a42eb9 100644 --- a/PIL/ImageFont.py +++ b/PIL/ImageFont.py @@ -403,15 +403,4 @@ w7IkEbzhVQAAAABJRU5ErkJggg== ''')))) return f - -if __name__ == "__main__": - # create font data chunk for embedding - import base64 - font = "Tests/images/courB08" - print(" f._load_pilfont_data(") - print(" # %s" % os.path.basename(font)) - print(" BytesIO(base64.decodestring(b'''") - base64.encode(open(font + ".pil", "rb"), sys.stdout) - print("''')), Image.open(BytesIO(base64.decodestring(b'''") - base64.encode(open(font + ".pbm", "rb"), sys.stdout) - print("'''))))") +# End of file diff --git a/Scripts/createfontdatachunk.py b/Scripts/createfontdatachunk.py new file mode 100644 index 000000000..0c860701a --- /dev/null +++ b/Scripts/createfontdatachunk.py @@ -0,0 +1,16 @@ +import base64 +import os +import sys + +if __name__ == "__main__": + # create font data chunk for embedding + font = "Tests/images/courB08" + print(" f._load_pilfont_data(") + print(" # %s" % os.path.basename(font)) + print(" BytesIO(base64.decodestring(b'''") + base64.encode(open(font + ".pil", "rb"), sys.stdout) + print("''')), Image.open(BytesIO(base64.decodestring(b'''") + base64.encode(open(font + ".pbm", "rb"), sys.stdout) + print("'''))))") + +# End of file From b5c3eb58307f948932e214dc958de003da8aec8e Mon Sep 17 00:00:00 2001 From: wiredfool Date: Tue, 8 Jul 2014 10:37:27 -0700 Subject: [PATCH 6/6] ucase(font_path,font_size) --- Tests/test_imagefont.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index ed3715ed9..ed2439e7c 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -74,7 +74,7 @@ try: def test_textsize_equal(self): im = Image.new(mode='RGB', size=(300, 100)) draw = ImageDraw.Draw(im) - ttf = ImageFont.truetype(font_path, font_size) + ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) txt = "Hello World!" size = draw.textsize(txt, ttf)