From 7a798f8724a3f519dfa7db3cf2245082d0c2f2e3 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Wed, 4 Mar 2015 00:00:18 +1100 Subject: [PATCH 01/15] Added copy method font_variant() and accessible properties to truetype() --- PIL/ImageFont.py | 11 +++++++++++ Tests/test_imagefont.py | 16 ++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/PIL/ImageFont.py b/PIL/ImageFont.py index cf1922c9e..5d08abfa5 100644 --- a/PIL/ImageFont.py +++ b/PIL/ImageFont.py @@ -133,6 +133,11 @@ class FreeTypeFont: DeprecationWarning) font = file + self.path = font + self.size = size + self.index = index + self.encoding = encoding + if isPath(font): self.font = core.getfont(font, size, index, encoding) else: @@ -162,6 +167,12 @@ class FreeTypeFont: self.font.render(text, im.id, mode == "1") return im, offset + def font_variant(self, font=None, size=None, index=None, encoding=None): + return FreeTypeFont(font = self.path if font == None else font, + size = self.size if size == None else size, + index = self.index if index == None else index, + encoding = self.encoding if encoding == None else encoding) + ## # Wrapper that creates a transposed font from any existing font # object. diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index 1f935088c..1b03ed13b 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -44,6 +44,22 @@ try: self.assertRegexpMatches( ImageFont.core.freetype2_version, "\d+\.\d+\.\d+$") + def test_font_properties(self): + ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE) + self.assertEqual(ttf.path, FONT_PATH) + self.assertEqual(ttf.size, FONT_SIZE) + + ttf_copy = ttf.font_variant() + self.assertEqual(ttf_copy.path, FONT_PATH) + self.assertEqual(ttf_copy.size, FONT_SIZE) + + ttf_copy = ttf.font_variant(size=FONT_SIZE+1) + self.assertEqual(ttf_copy.size, FONT_SIZE+1) + + second_font_path = "Tests/fonts/DejaVuSans.ttf" + ttf_copy = ttf.font_variant(font=second_font_path) + self.assertEqual(ttf_copy.path, second_font_path) + def test_font_with_name(self): ImageFont.truetype(FONT_PATH, FONT_SIZE) self._render(FONT_PATH) From 0b79c6e24a4cc293ef48bad0a4ae72407d84b74a Mon Sep 17 00:00:00 2001 From: hugovk Date: Thu, 5 Mar 2015 21:07:16 +0200 Subject: [PATCH 02/15] Remove unreachable code (if 0) --- PIL/PngImagePlugin.py | 14 +++++--------- libImaging/Dib.c | 13 ------------- libImaging/Geometry.c | 17 ----------------- libImaging/QuantHash.c | 19 ------------------- 4 files changed, 5 insertions(+), 58 deletions(-) diff --git a/PIL/PngImagePlugin.py b/PIL/PngImagePlugin.py index 7a9becd3b..d8593f90d 100644 --- a/PIL/PngImagePlugin.py +++ b/PIL/PngImagePlugin.py @@ -175,7 +175,7 @@ class iTXt(str): :param lang: language code :param tkey: UTF-8 version of the key name """ - + self = str.__new__(cls, text) self.lang = lang self.tkey = tkey @@ -198,7 +198,7 @@ class PngInfo: :param data: a byte string of the encoded data """ - + self.chunks.append((cid, data)) def add_itxt(self, key, value, lang="", tkey="", zip=False): @@ -211,7 +211,7 @@ class PngInfo: :param zip: compression flag """ - + if not isinstance(key, bytes): key = key.encode("latin-1", "strict") if not isinstance(value, bytes): @@ -235,7 +235,7 @@ class PngInfo: :param value: value for this key, text or an :py:class:`PIL.PngImagePlugin.iTXt` instance :param zip: compression flag - + """ if isinstance(value, iTXt): return self.add_itxt(key, value, value.lang, value.tkey, bool(zip)) @@ -462,7 +462,7 @@ class PngStream(ChunkStream): self.im_info[k] = self.im_text[k] = iTXt(v, lang, tk) self.check_text_memory(len(v)) - + return s @@ -729,10 +729,6 @@ def _save(im, fp, filename, chunk=putchunk, check=0): alpha_bytes = 2**bits chunk(fp, b"tRNS", alpha[:alpha_bytes]) - if 0: - # FIXME: to be supported some day - chunk(fp, b"gAMA", o32(int(gamma * 100000.0))) - dpi = im.encoderinfo.get("dpi") if dpi: chunk(fp, b"pHYs", diff --git a/libImaging/Dib.c b/libImaging/Dib.c index 8e138bd6b..55de7d9a5 100644 --- a/libImaging/Dib.c +++ b/libImaging/Dib.c @@ -204,19 +204,6 @@ ImagingNewDIB(const char *mode, int xsize, int ysize) #endif -#if 0 - { - /* DEBUG: dump palette to file */ - FILE *err = fopen("dib.pal", "w"); - for (i = 0; i < 256; i++) - fprintf(err, "%d: %d/%d/%d\n", i, - pal->palPalEntry[i].peRed, - pal->palPalEntry[i].peGreen, - pal->palPalEntry[i].peBlue); - fclose(err); - } -#endif - dib->palette = CreatePalette(pal); } diff --git a/libImaging/Geometry.c b/libImaging/Geometry.c index f586974c3..97cbcf2ed 100644 --- a/libImaging/Geometry.c +++ b/libImaging/Geometry.c @@ -304,23 +304,6 @@ perspective_transform(double* xin, double* yin, int x, int y, void* data) return 1; } -#if 0 -static int -quadratic_transform(double* xin, double* yin, int x, int y, void* data) -{ - double* a = (double*) data; - - double a0 = a[0]; double a1 = a[1]; double a2 = a[2]; double a3 = a[3]; - double a4 = a[4]; double a5 = a[5]; double a6 = a[6]; double a7 = a[7]; - double a8 = a[8]; double a9 = a[9]; double a10 = a[10]; double a11 = a[11]; - - xin[0] = a0 + a1*x + a2*y + a3*x*x + a4*x*y + a5*y*y; - yin[0] = a6 + a7*x + a8*y + a9*x*x + a10*x*y + a11*y*y; - - return 1; -} -#endif - static int quad_transform(double* xin, double* yin, int x, int y, void* data) { diff --git a/libImaging/QuantHash.c b/libImaging/QuantHash.c index a1f99ed3a..48b7a973e 100644 --- a/libImaging/QuantHash.c +++ b/libImaging/QuantHash.c @@ -44,9 +44,6 @@ struct _HashTable { #define RESIZE_FACTOR 3 static int _hashtable_insert_node(HashTable *,HashNode *,int,int,CollisionFunc); -#if 0 -static int _hashtable_test(HashTable *); -#endif HashTable *hashtable_new(HashFunc hf,HashCmpFunc cf) { HashTable *h; @@ -132,22 +129,6 @@ static void _hashtable_resize(HashTable *h) { } } -#if 0 -static int _hashtable_test(HashTable *h) { - uint32_t i; - int j; - HashNode *n; - for (i=0;ilength;i++) { - for (n=h->table[i];n&&n->next;n=n->next) { - j=h->cmpFunc(h,n->key,n->next->key); - printf ("%c",j?(j<0?'-':'+'):'='); - } - printf ("\n"); - } - return 0; -} -#endif - static int _hashtable_insert_node(HashTable *h,HashNode *node,int resize,int update,CollisionFunc cf) { uint32_t hash=h->hashFunc(h,node->key)%h->length; HashNode **n,*nv; From f1333617d5d5bd34fb5a3338a3e5d851e1ef6e2a Mon Sep 17 00:00:00 2001 From: hugovk Date: Thu, 5 Mar 2015 23:14:36 +0200 Subject: [PATCH 03/15] Replace harcoded assumption of RAND_MAX with constant. It caused an infinite loop if RAND_MAX > 32767 --- libImaging/Effects.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libImaging/Effects.c b/libImaging/Effects.c index eb598d968..a3f5e7cd9 100644 --- a/libImaging/Effects.c +++ b/libImaging/Effects.c @@ -98,8 +98,8 @@ ImagingEffectNoise(int xsize, int ysize, float sigma) /* after numerical recipes */ double v1, v2, radius, factor; do { - v1 = rand()*(2.0/32767.0) - 1.0; - v2 = rand()*(2.0/32767.0) - 1.0; + v1 = rand()*(2.0/RAND_MAX) - 1.0; + v2 = rand()*(2.0/RAND_MAX) - 1.0; radius= v1*v1 + v2*v2; } while (radius >= 1.0); factor = sqrt(-2.0*log(radius)/radius); From 9bd38bfa06fd14fce3c998877f9dfe35e0cf7fb5 Mon Sep 17 00:00:00 2001 From: hugovk Date: Thu, 5 Mar 2015 23:21:42 +0200 Subject: [PATCH 04/15] Run test_effect_noise() on non-Windows, don't be too strict --- Tests/test_image.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Tests/test_image.py b/Tests/test_image.py index 26e45b10a..de43b010e 100644 --- a/Tests/test_image.py +++ b/Tests/test_image.py @@ -168,8 +168,6 @@ class TestImage(PillowTestCase): ValueError, lambda: Image.effect_mandelbrot(size, extent, quality)) - @unittest.skipUnless(sys.platform.startswith('win32'), - "Stalls on Travis CI, passes on Windows") def test_effect_noise(self): # Arrange size = (100, 100) @@ -180,8 +178,8 @@ class TestImage(PillowTestCase): # Assert self.assertEqual(im.size, (100, 100)) - self.assertEqual(im.getpixel((0, 0)), 60) - self.assertEqual(im.getpixel((0, 1)), 28) + self.assertEqual(im.mode, "L") + self.assertNotEqual(im.getpixel((0, 0)), im.getpixel((0, 1))) def test_effect_spread(self): # Arrange From 44bb45d3b372fba84d0b029e9f59c5b73a1eee53 Mon Sep 17 00:00:00 2001 From: Hugo Date: Fri, 6 Mar 2015 10:52:10 +0200 Subject: [PATCH 05/15] Add OS X build badge [CI skip] We have OS X builds in another repo. Show the badge here too, to help spot OS X build breaks sooner (for example, if might pass on Linux). --- README.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index dfd3e2c31..c6cf3e419 100644 --- a/README.rst +++ b/README.rst @@ -7,8 +7,12 @@ Pillow is the "friendly" PIL fork by `Alex Clark and Contributors Date: Fri, 6 Mar 2015 13:07:28 -0800 Subject: [PATCH 06/15] Updated Changes.rst [ci skip] --- CHANGES.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 74d1b6b82..7afd47350 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,9 @@ Changelog (Pillow) 2.8.0 (unreleased) ------------------ +- Remove unreachable code + [hugovk] + - Let Python do the endian stuff + tests #1121 [amoibos, radarhere] From fb3fe4b8770941deb3e8da9f2f7ed85b0fef5d92 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 7 Mar 2015 18:38:17 +1100 Subject: [PATCH 07/15] Added documentation for font_variant() [ci skip] --- PIL/ImageFont.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/PIL/ImageFont.py b/PIL/ImageFont.py index 5d08abfa5..8f60ddb00 100644 --- a/PIL/ImageFont.py +++ b/PIL/ImageFont.py @@ -168,6 +168,15 @@ class FreeTypeFont: return im, offset def font_variant(self, font=None, size=None, index=None, encoding=None): + """ + Create a copy of this FreeTypeFont object, + using any specified arguments to override the settings. + + Parameters are identical to the parameters used to initialize this object, + minus the deprecated 'file' argument. + + :return: A FreeTypeFont object. + """ return FreeTypeFont(font = self.path if font == None else font, size = self.size if size == None else size, index = self.index if index == None else index, From 85977bc371c6b2fae775990059e90f0786d94571 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Sun, 8 Mar 2015 18:30:24 -0700 Subject: [PATCH 08/15] Update CHANGES.rst [ci skip] --- CHANGES.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 7afd47350..a995165c4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,9 @@ Changelog (Pillow) 2.8.0 (unreleased) ------------------ +- Fix ImagingEffectNoise #1128 + [hugovk] + - Remove unreachable code [hugovk] From 419ed13bb769b203084c9a68ae47275dcea50c02 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Tue, 10 Mar 2015 13:26:40 +1100 Subject: [PATCH 09/15] Fixed typos in CHANGES.rst [ci skip] --- CHANGES.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index a995165c4..451a6ba14 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -58,7 +58,7 @@ Changelog (Pillow) - Fix MSVC compiler error: Use Py_ssize_t instead of ssize_t #1051 [cgohlke] -- Fix compiler error: MSVC needs varaibles defined at the start of the block #1048 +- Fix compiler error: MSVC needs variables defined at the start of the block #1048 [cgohlke] - The GIF Palette optimization algorithm is only applicable to mode='P' or 'L' #993 @@ -1793,7 +1793,7 @@ Changelog (Pillow) (1.1.2c1 and 1.1.2 final released) + Adapted to Python 2.1. Among other things, all uses of the - "regex" module has been repleased with "re". + "regex" module have been replaced with "re". + Fixed attribute error when reading large PNG files (this bug was introduced in maintenance code released after the 1.1.1 @@ -2417,7 +2417,7 @@ Changelog (Pillow) the default value is 75. JPEG smooth smooth dithered images. value - is strengh (1-100). default is + is strength (1-100). default is off (0). PNG optimize minimize output file at the From ddf17df928bbb8aac044bfedad155c7947e1a64a Mon Sep 17 00:00:00 2001 From: Fahrzin Hemmati Date: Sat, 14 Mar 2015 02:41:14 -0700 Subject: [PATCH 10/15] Make gifmaker work with the current getheader GifImagePlugin.getheader was updated about 2 years ago and changed the API that gifmaker expects. --- Scripts/gifmaker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/gifmaker.py b/Scripts/gifmaker.py index 9fa5e71a4..bd4de99c1 100644 --- a/Scripts/gifmaker.py +++ b/Scripts/gifmaker.py @@ -78,7 +78,7 @@ def makedelta(fp, sequence): if not previous: # global header - for s in getheader(im) + getdata(im): + for s in getheader(im)[0] + getdata(im): fp.write(s) else: From b5475f2e1aee53075ed504a1f7193741fe44f7a5 Mon Sep 17 00:00:00 2001 From: Alex Clark Date: Wed, 18 Mar 2015 05:19:32 -0400 Subject: [PATCH 11/15] Nits [ci skip] - Mac OS X is now called just OS X - Capitalize headers --- docs/installation.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/installation.rst b/docs/installation.rst index cca94a135..3a9e8c50e 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -12,7 +12,7 @@ Installation .. note:: Pillow < 2.0.0 supports Python versions 2.4, 2.5, 2.6, 2.7. -Simple installation +Simple Installation ------------------- .. note:: @@ -121,7 +121,7 @@ Sample Usage:: $ MAX_CONCURRENCY=1 python setup.py build-ext --enable-[feature] install -Linux installation +Linux Installation ------------------ .. note:: @@ -160,8 +160,8 @@ Prerequisites are installed on **Fedora 20** with:: lcms2-devel libwebp-devel tcl-devel tk-devel -Mac OS X installation ---------------------- +OS X Installation +----------------- We provide binaries for OS X in the form of `Python Wheels `_. Alternatively you can compile Pillow with with XCode. @@ -173,7 +173,7 @@ Install Pillow with:: $ pip install Pillow -Windows installation +Windows Installation -------------------- We provide binaries for Windows in the form of Python Eggs and `Python Wheels @@ -208,8 +208,8 @@ to a specific version: $ pip install --use-wheel Pillow==2.6.1 -FreeBSD installation ---------------------- +FreeBSD Installation +-------------------- .. Note:: Only FreeBSD 10 tested From a37e022a0c50dcbff6b2f0d99f21444be8847207 Mon Sep 17 00:00:00 2001 From: Alex Clark Date: Wed, 18 Mar 2015 05:39:01 -0400 Subject: [PATCH 12/15] Wheels updates [ci skip] - No longer experimental - No longer need --use-wheels --- docs/installation.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/installation.rst b/docs/installation.rst index 3a9e8c50e..d68f78238 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -194,11 +194,11 @@ Python Eggs Python Wheels ^^^^^^^^^^^^^ -.. Note:: Experimental. Requires setuptools >=0.8 and pip >=1.4.1 +.. Note:: requires setuptools >=0.8 and pip >=1.4.1. Some older versions of pip required the ``--use-wheel`` flag. :: - $ pip install --use-wheel Pillow + $ pip install Pillow If the above does not work, it's likely because we haven't uploaded a wheel for the latest version of Pillow. In that case, try pinning it @@ -206,7 +206,7 @@ to a specific version: :: - $ pip install --use-wheel Pillow==2.6.1 + $ pip install Pillow==2.6.1 FreeBSD Installation -------------------- From d0e720929af4686976541f3bd5ec893e82652dac Mon Sep 17 00:00:00 2001 From: Alex Clark Date: Wed, 18 Mar 2015 05:46:54 -0400 Subject: [PATCH 13/15] Nits [ci skip] --- docs/installation.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/installation.rst b/docs/installation.rst index d68f78238..d9027bda6 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -163,7 +163,7 @@ Prerequisites are installed on **Fedora 20** with:: OS X Installation ----------------- -We provide binaries for OS X in the form of `Python Wheels `_. Alternatively you can compile Pillow with with XCode. +We provide binaries for OS X in the form of `Python Wheels `_. Alternatively you can compile Pillow from soure with XCode. The easiest way to install external libraries is via `Homebrew `_. After you install Homebrew, run:: @@ -194,7 +194,7 @@ Python Eggs Python Wheels ^^^^^^^^^^^^^ -.. Note:: requires setuptools >=0.8 and pip >=1.4.1. Some older versions of pip required the ``--use-wheel`` flag. +.. Note:: Requires setuptools >=0.8 and pip >=1.4.1. Some older versions of pip required the ``--use-wheel`` flag. :: From f820c5184d3ba7f9aa8bd0ddb8813ab4cddf3e40 Mon Sep 17 00:00:00 2001 From: Hugo Date: Sat, 21 Mar 2015 10:16:55 +0200 Subject: [PATCH 14/15] Update CHANGES.rst [CI skip] --- CHANGES.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 451a6ba14..f8ec2d685 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,9 @@ Changelog (Pillow) 2.8.0 (unreleased) ------------------ +- Added copy method font_variant() and accessible properties to truetype() #1123 + [radarhere] + - Fix ImagingEffectNoise #1128 [hugovk] From b17384cfca954ec3d979a837a572f77a26b407d3 Mon Sep 17 00:00:00 2001 From: hugovk Date: Sat, 21 Mar 2015 10:32:26 +0200 Subject: [PATCH 15/15] Tabs to spaces and other flake8 fixes --- PIL/ImageFont.py | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/PIL/ImageFont.py b/PIL/ImageFont.py index 8f60ddb00..a9c50e560 100644 --- a/PIL/ImageFont.py +++ b/PIL/ImageFont.py @@ -168,19 +168,20 @@ class FreeTypeFont: return im, offset def font_variant(self, font=None, size=None, index=None, encoding=None): - """ - Create a copy of this FreeTypeFont object, - using any specified arguments to override the settings. - - Parameters are identical to the parameters used to initialize this object, - minus the deprecated 'file' argument. - - :return: A FreeTypeFont object. - """ - return FreeTypeFont(font = self.path if font == None else font, - size = self.size if size == None else size, - index = self.index if index == None else index, - encoding = self.encoding if encoding == None else encoding) + """ + Create a copy of this FreeTypeFont object, + using any specified arguments to override the settings. + + Parameters are identical to the parameters used to initialize this + object, minus the deprecated 'file' argument. + + :return: A FreeTypeFont object. + """ + return FreeTypeFont(font=self.path if font is None else font, + size=self.size if size is None else size, + index=self.index if index is None else index, + encoding=self.encoding if encoding is None else + encoding) ## # Wrapper that creates a transposed font from any existing font @@ -275,8 +276,8 @@ def truetype(font=None, size=10, index=0, encoding="", filename=None): elif sys.platform in ('linux', 'linux2'): lindirs = os.environ.get("XDG_DATA_DIRS", "") if not lindirs: - #According to the freedesktop spec, XDG_DATA_DIRS should - #default to /usr/share + # According to the freedesktop spec, XDG_DATA_DIRS should + # default to /usr/share lindirs = '/usr/share' lindirs = lindirs.split(":") for lindir in lindirs: @@ -286,7 +287,8 @@ def truetype(font=None, size=10, index=0, encoding="", filename=None): filepath = os.path.join(walkroot, ttf_filename) return FreeTypeFont(filepath, size, index, encoding) elif sys.platform == 'darwin': - macdirs = ['/Library/Fonts/', '/System/Library/Fonts/', os.path.expanduser('~/Library/Fonts/')] + macdirs = ['/Library/Fonts/', '/System/Library/Fonts/', + os.path.expanduser('~/Library/Fonts/')] for macdir in macdirs: filepath = os.path.join(macdir, ttf_filename) if os.path.exists(filepath):