mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-30 23:47:27 +03:00 
			
		
		
		
	Merge pull request #3907 from yawor/pcfenconding
Support for different charset encodings in PcfFontFile
This commit is contained in:
		
						commit
						596adb9e8a
					
				|  | @ -4,6 +4,7 @@ NotoSansJP-Thin.otf, from https://www.google.com/get/noto/help/cjk/ | |||
| AdobeVFPrototype.ttf, from https://github.com/adobe-fonts/adobe-variable-font-prototype | ||||
| TINY5x3GX.ttf, from http://velvetyne.fr/fonts/tiny | ||||
| ArefRuqaa-Regular.ttf, from https://github.com/google/fonts/tree/master/ofl/arefruqaa | ||||
| ter-x20b.pcf, from http://terminus-font.sourceforge.net/ | ||||
| 
 | ||||
| All of the above fonts are published under the SIL Open Font License (OFL) v1.1 (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL), which allows you to copy, modify, and redistribute them if you need to. | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										
											BIN
										
									
								
								Tests/fonts/ter-x20b-cp1250.pbm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/fonts/ter-x20b-cp1250.pbm
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 2.4 KiB | 
							
								
								
									
										
											BIN
										
									
								
								Tests/fonts/ter-x20b-cp1250.pil
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/fonts/ter-x20b-cp1250.pil
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Tests/fonts/ter-x20b-iso8859-1.pbm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/fonts/ter-x20b-iso8859-1.pbm
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 2.2 KiB | 
							
								
								
									
										
											BIN
										
									
								
								Tests/fonts/ter-x20b-iso8859-1.pil
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/fonts/ter-x20b-iso8859-1.pil
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Tests/fonts/ter-x20b-iso8859-2.pbm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/fonts/ter-x20b-iso8859-2.pbm
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 2.1 KiB | 
							
								
								
									
										
											BIN
										
									
								
								Tests/fonts/ter-x20b-iso8859-2.pil
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/fonts/ter-x20b-iso8859-2.pil
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Tests/fonts/ter-x20b.pcf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/fonts/ter-x20b.pcf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Tests/images/test_draw_pbm_ter_en_target.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/images/test_draw_pbm_ter_en_target.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 253 B | 
							
								
								
									
										
											BIN
										
									
								
								Tests/images/test_draw_pbm_ter_pl_target.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/images/test_draw_pbm_ter_pl_target.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 284 B | 
							
								
								
									
										120
									
								
								Tests/test_font_pcf_charsets.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								Tests/test_font_pcf_charsets.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,120 @@ | |||
| import os | ||||
| 
 | ||||
| from PIL import FontFile, Image, ImageDraw, ImageFont, PcfFontFile | ||||
| 
 | ||||
| from .helper import assert_image_equal, assert_image_similar, skip_unless_feature | ||||
| 
 | ||||
| fontname = "Tests/fonts/ter-x20b.pcf" | ||||
| 
 | ||||
| charsets = { | ||||
|     "iso8859-1": { | ||||
|         "glyph_count": 223, | ||||
|         "message": "hello, world", | ||||
|         "image1": "Tests/images/test_draw_pbm_ter_en_target.png", | ||||
|     }, | ||||
|     "iso8859-2": { | ||||
|         "glyph_count": 223, | ||||
|         "message": "witaj świecie", | ||||
|         "image1": "Tests/images/test_draw_pbm_ter_pl_target.png", | ||||
|     }, | ||||
|     "cp1250": { | ||||
|         "glyph_count": 250, | ||||
|         "message": "witaj świecie", | ||||
|         "image1": "Tests/images/test_draw_pbm_ter_pl_target.png", | ||||
|     }, | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| pytestmark = skip_unless_feature("zlib") | ||||
| 
 | ||||
| 
 | ||||
| def save_font(request, tmp_path, encoding): | ||||
|     with open(fontname, "rb") as test_file: | ||||
|         font = PcfFontFile.PcfFontFile(test_file, encoding) | ||||
|     assert isinstance(font, FontFile.FontFile) | ||||
|     # check the number of characters in the font | ||||
|     assert len([_f for _f in font.glyph if _f]) == charsets[encoding]["glyph_count"] | ||||
| 
 | ||||
|     tempname = str(tmp_path / "temp.pil") | ||||
| 
 | ||||
|     def delete_tempfile(): | ||||
|         try: | ||||
|             os.remove(tempname[:-4] + ".pbm") | ||||
|         except OSError: | ||||
|             pass  # report? | ||||
| 
 | ||||
|     request.addfinalizer(delete_tempfile) | ||||
|     font.save(tempname) | ||||
| 
 | ||||
|     with Image.open(tempname.replace(".pil", ".pbm")) as loaded: | ||||
|         with Image.open("Tests/fonts/ter-x20b-%s.pbm" % encoding) as target: | ||||
|             assert_image_equal(loaded, target) | ||||
| 
 | ||||
|     with open(tempname, "rb") as f_loaded: | ||||
|         with open("Tests/fonts/ter-x20b-%s.pil" % encoding, "rb") as f_target: | ||||
|             assert f_loaded.read() == f_target.read() | ||||
|     return tempname | ||||
| 
 | ||||
| 
 | ||||
| def _test_sanity(request, tmp_path, encoding): | ||||
|     save_font(request, tmp_path, encoding) | ||||
| 
 | ||||
| 
 | ||||
| def test_sanity_iso8859_1(request, tmp_path): | ||||
|     _test_sanity(request, tmp_path, "iso8859-1") | ||||
| 
 | ||||
| 
 | ||||
| def test_sanity_iso8859_2(request, tmp_path): | ||||
|     _test_sanity(request, tmp_path, "iso8859-2") | ||||
| 
 | ||||
| 
 | ||||
| def test_sanity_cp1250(request, tmp_path): | ||||
|     _test_sanity(request, tmp_path, "cp1250") | ||||
| 
 | ||||
| 
 | ||||
| def _test_draw(request, tmp_path, encoding): | ||||
|     tempname = save_font(request, tmp_path, encoding) | ||||
|     font = ImageFont.load(tempname) | ||||
|     im = Image.new("L", (150, 30), "white") | ||||
|     draw = ImageDraw.Draw(im) | ||||
|     message = charsets[encoding]["message"].encode(encoding) | ||||
|     draw.text((0, 0), message, "black", font=font) | ||||
|     with Image.open(charsets[encoding]["image1"]) as target: | ||||
|         assert_image_similar(im, target, 0) | ||||
| 
 | ||||
| 
 | ||||
| def test_draw_iso8859_1(request, tmp_path): | ||||
|     _test_draw(request, tmp_path, "iso8859-1") | ||||
| 
 | ||||
| 
 | ||||
| def test_draw_iso8859_2(request, tmp_path): | ||||
|     _test_draw(request, tmp_path, "iso8859-2") | ||||
| 
 | ||||
| 
 | ||||
| def test_draw_cp1250(request, tmp_path): | ||||
|     _test_draw(request, tmp_path, "cp1250") | ||||
| 
 | ||||
| 
 | ||||
| def _test_textsize(request, tmp_path, encoding): | ||||
|     tempname = save_font(request, tmp_path, encoding) | ||||
|     font = ImageFont.load(tempname) | ||||
|     for i in range(255): | ||||
|         (dx, dy) = font.getsize(bytearray([i])) | ||||
|         assert dy == 20 | ||||
|         assert dx in (0, 10) | ||||
|     message = charsets[encoding]["message"].encode(encoding) | ||||
|     for l in range(len(message)): | ||||
|         msg = message[: l + 1] | ||||
|         assert font.getsize(msg) == (len(msg) * 10, 20) | ||||
| 
 | ||||
| 
 | ||||
| def test_textsize_iso8859_1(request, tmp_path): | ||||
|     _test_textsize(request, tmp_path, "iso8859-1") | ||||
| 
 | ||||
| 
 | ||||
| def test_textsize_iso8859_2(request, tmp_path): | ||||
|     _test_textsize(request, tmp_path, "iso8859-2") | ||||
| 
 | ||||
| 
 | ||||
| def test_textsize_cp1250(request, tmp_path): | ||||
|     _test_textsize(request, tmp_path, "cp1250") | ||||
|  | @ -56,7 +56,9 @@ class PcfFontFile(FontFile.FontFile): | |||
| 
 | ||||
|     name = "name" | ||||
| 
 | ||||
|     def __init__(self, fp): | ||||
|     def __init__(self, fp, charset_encoding="iso8859-1"): | ||||
| 
 | ||||
|         self.charset_encoding = charset_encoding | ||||
| 
 | ||||
|         magic = l32(fp.read(4)) | ||||
|         if magic != PCF_MAGIC: | ||||
|  | @ -229,12 +231,17 @@ class PcfFontFile(FontFile.FontFile): | |||
| 
 | ||||
|         nencoding = (lastCol - firstCol + 1) * (lastRow - firstRow + 1) | ||||
| 
 | ||||
|         for i in range(nencoding): | ||||
|             encodingOffset = i16(fp.read(2)) | ||||
|             if encodingOffset != 0xFFFF: | ||||
|         encodingOffsets = [i16(fp.read(2)) for _ in range(nencoding)] | ||||
| 
 | ||||
|         for i in range(firstCol, len(encoding)): | ||||
|             try: | ||||
|                     encoding[i + firstCol] = encodingOffset | ||||
|                 except IndexError: | ||||
|                     break  # only load ISO-8859-1 glyphs | ||||
|                 encodingOffset = encodingOffsets[ | ||||
|                     ord(bytearray([i]).decode(self.charset_encoding)) | ||||
|                 ] | ||||
|                 if encodingOffset != 0xFFFF: | ||||
|                     encoding[i] = encodingOffset | ||||
|             except UnicodeDecodeError: | ||||
|                 # character is not supported in selected encoding | ||||
|                 pass | ||||
| 
 | ||||
|         return encoding | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user