mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 07:57:27 +03:00 
			
		
		
		
	Merge pull request #333 from wiredfool/paddywwoof-truetype
Vertical Alignment of ttf rendering
This commit is contained in:
		
						commit
						dea45dafcb
					
				|  | @ -102,6 +102,8 @@ def getcolor(color, mode): | |||
|     if mode == "RGB": | ||||
|         return color | ||||
|     if mode == "RGBA": | ||||
|         if len(color) == 3: | ||||
|           color = (color + (255,)) | ||||
|         r, g, b, a = color | ||||
|         return r, g, b, a | ||||
|     if Image.getmodebase(mode) == "L": | ||||
|  |  | |||
|  | @ -157,6 +157,9 @@ class FreeTypeFont: | |||
|     def getsize(self, text): | ||||
|         return self.font.getsize(text)[0] | ||||
| 
 | ||||
|     def getoffset(self, text): | ||||
|         return self.font.getsize(text)[1] | ||||
| 
 | ||||
|     def getmask(self, text, mode=""): | ||||
|         return self.getmask2(text, mode)[0] | ||||
| 
 | ||||
|  | @ -183,7 +186,7 @@ class TransposedFont: | |||
|         self.orientation = orientation # any 'transpose' argument, or None | ||||
| 
 | ||||
|     def getsize(self, text): | ||||
|         w, h = self.font.getsize(text) | ||||
|         w, h = self.font.getsize(text)[0] | ||||
|         if self.orientation in (Image.ROTATE_90, Image.ROTATE_270): | ||||
|             return h, w | ||||
|         return w, h | ||||
|  |  | |||
							
								
								
									
										
											BIN
										
									
								
								Tests/images/multiline_text.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/images/multiline_text.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 2.8 KiB | 
|  | @ -35,7 +35,7 @@ def test_font_with_filelike(): | |||
|     #shared_bytes = _font_as_bytes() | ||||
|     #assert_no_exception(lambda: _render(shared_bytes)) | ||||
|     #assert_exception(Exception, lambda: _render(shared_bytes)) | ||||
|     _clean | ||||
|     _clean() | ||||
| 
 | ||||
| def test_font_with_open_file(): | ||||
|     with open(font_path, 'rb') as f: | ||||
|  | @ -67,3 +67,21 @@ def test_render_equal(): | |||
| 
 | ||||
|     assert_image_equal(img_path, img_filelike) | ||||
|     _clean() | ||||
| 
 | ||||
| 
 | ||||
| def test_render_multiline(): | ||||
|     im = Image.new(mode='RGB', size=(300,100)) | ||||
|     ttf = ImageFont.truetype(font_path, font_size) | ||||
|     draw = ImageDraw.Draw(im) | ||||
|     line_spacing = draw.textsize('A', font=ttf)[1] + 8 | ||||
|     lines = ['hey you', 'you are awesome', 'this looks awkward'] | ||||
|     y = 0 | ||||
|     for line in lines: | ||||
|         draw.text((0, y), line, font=ttf) | ||||
|         y += line_spacing | ||||
| 
 | ||||
|     target = 'Tests/images/multiline_text.png' | ||||
|     target_img = Image.open(target) | ||||
| 
 | ||||
|     assert_image_equal(im, target_img) | ||||
|      | ||||
|  |  | |||
							
								
								
									
										15
									
								
								_imagingft.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								_imagingft.c
									
									
									
									
									
								
							|  | @ -183,7 +183,7 @@ font_getsize(FontObject* self, PyObject* args) | |||
|     int i, x, y_max, y_min; | ||||
|     FT_ULong ch; | ||||
|     FT_Face face; | ||||
|     int xoffset; | ||||
|     int xoffset, yoffset; | ||||
|     FT_Bool kerning = FT_HAS_KERNING(self->face); | ||||
|     FT_UInt last_index = 0; | ||||
| 
 | ||||
|  | @ -203,7 +203,7 @@ font_getsize(FontObject* self, PyObject* args) | |||
|     } | ||||
| 
 | ||||
|     face = NULL; | ||||
|     xoffset = 0; | ||||
|     xoffset = yoffset = 0; | ||||
|     y_max = y_min = 0; | ||||
| 
 | ||||
|     for (x = i = 0; font_getchar(string, i, &ch); i++) { | ||||
|  | @ -231,7 +231,11 @@ font_getsize(FontObject* self, PyObject* args) | |||
|             y_max = bbox.yMax; | ||||
|         if (bbox.yMin < y_min) | ||||
|             y_min = bbox.yMin; | ||||
| 
 | ||||
|              | ||||
|         /* find max distance of baseline from top */ | ||||
|         if (face->glyph->metrics.horiBearingY > yoffset) | ||||
|             yoffset = face->glyph->metrics.horiBearingY; | ||||
|              | ||||
|         last_index = index; | ||||
|     } | ||||
| 
 | ||||
|  | @ -248,12 +252,15 @@ font_getsize(FontObject* self, PyObject* args) | |||
|             face->glyph->metrics.horiBearingX; | ||||
|         if (offset < 0) | ||||
|             x -= offset; | ||||
|         /* difference between the font ascender and the distance of
 | ||||
|          * the baseline from the top */ | ||||
|         yoffset = PIXEL(self->face->size->metrics.ascender - yoffset); | ||||
|     } | ||||
| 
 | ||||
|     return Py_BuildValue( | ||||
|         "(ii)(ii)", | ||||
|         PIXEL(x), PIXEL(y_max - y_min), | ||||
|         PIXEL(xoffset), 0 | ||||
|         PIXEL(xoffset), yoffset | ||||
|         ); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user