mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 09:57:43 +03:00 
			
		
		
		
	Merge pull request #8701 from radarhere/stroke_outside
This commit is contained in:
		
						commit
						b03f143df1
					
				| 
						 | 
					@ -1396,6 +1396,28 @@ def test_stroke_descender() -> None:
 | 
				
			||||||
    assert_image_similar_tofile(im, "Tests/images/imagedraw_stroke_descender.png", 6.76)
 | 
					    assert_image_similar_tofile(im, "Tests/images/imagedraw_stroke_descender.png", 6.76)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@skip_unless_feature("freetype2")
 | 
				
			||||||
 | 
					def test_stroke_inside_gap() -> None:
 | 
				
			||||||
 | 
					    # Arrange
 | 
				
			||||||
 | 
					    im = Image.new("RGB", (120, 130))
 | 
				
			||||||
 | 
					    draw = ImageDraw.Draw(im)
 | 
				
			||||||
 | 
					    font = ImageFont.truetype("Tests/fonts/FreeMono.ttf", 120)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Act
 | 
				
			||||||
 | 
					    draw.text((12, 12), "i", "#f00", font, stroke_width=20)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Assert
 | 
				
			||||||
 | 
					    for y in range(im.height):
 | 
				
			||||||
 | 
					        glyph = ""
 | 
				
			||||||
 | 
					        for x in range(im.width):
 | 
				
			||||||
 | 
					            if im.getpixel((x, y)) == (0, 0, 0):
 | 
				
			||||||
 | 
					                if glyph == "started":
 | 
				
			||||||
 | 
					                    glyph = "ended"
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                assert glyph != "ended", "Gap inside stroked glyph"
 | 
				
			||||||
 | 
					                glyph = "started"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@skip_unless_feature("freetype2")
 | 
					@skip_unless_feature("freetype2")
 | 
				
			||||||
def test_split_word() -> None:
 | 
					def test_split_word() -> None:
 | 
				
			||||||
    # Arrange
 | 
					    # Arrange
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -461,6 +461,20 @@ def test_free_type_font_get_mask(font: ImageFont.FreeTypeFont) -> None:
 | 
				
			||||||
    assert mask.size == (108, 13)
 | 
					    assert mask.size == (108, 13)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_stroke_mask() -> None:
 | 
				
			||||||
 | 
					    # Arrange
 | 
				
			||||||
 | 
					    text = "i"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Act
 | 
				
			||||||
 | 
					    font = ImageFont.truetype(FONT_PATH, 128)
 | 
				
			||||||
 | 
					    mask = font.getmask(text, stroke_width=2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Assert
 | 
				
			||||||
 | 
					    assert mask.getpixel((34, 5)) == 255
 | 
				
			||||||
 | 
					    assert mask.getpixel((38, 5)) == 0
 | 
				
			||||||
 | 
					    assert mask.getpixel((42, 5)) == 255
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_load_when_image_not_found() -> None:
 | 
					def test_load_when_image_not_found() -> None:
 | 
				
			||||||
    with tempfile.NamedTemporaryFile(delete=False) as tmp:
 | 
					    with tempfile.NamedTemporaryFile(delete=False) as tmp:
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -643,6 +643,7 @@ class ImageDraw:
 | 
				
			||||||
                    features=features,
 | 
					                    features=features,
 | 
				
			||||||
                    language=language,
 | 
					                    language=language,
 | 
				
			||||||
                    stroke_width=stroke_width,
 | 
					                    stroke_width=stroke_width,
 | 
				
			||||||
 | 
					                    stroke_filled=True,
 | 
				
			||||||
                    anchor=anchor,
 | 
					                    anchor=anchor,
 | 
				
			||||||
                    ink=ink,
 | 
					                    ink=ink,
 | 
				
			||||||
                    start=start,
 | 
					                    start=start,
 | 
				
			||||||
| 
						 | 
					@ -692,7 +693,8 @@ class ImageDraw:
 | 
				
			||||||
                draw_text(stroke_ink, stroke_width)
 | 
					                draw_text(stroke_ink, stroke_width)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # Draw normal text
 | 
					                # Draw normal text
 | 
				
			||||||
                draw_text(ink, 0)
 | 
					                if ink != stroke_ink:
 | 
				
			||||||
 | 
					                    draw_text(ink)
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                # Only draw normal text
 | 
					                # Only draw normal text
 | 
				
			||||||
                draw_text(ink)
 | 
					                draw_text(ink)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -644,6 +644,7 @@ class FreeTypeFont:
 | 
				
			||||||
            features,
 | 
					            features,
 | 
				
			||||||
            language,
 | 
					            language,
 | 
				
			||||||
            stroke_width,
 | 
					            stroke_width,
 | 
				
			||||||
 | 
					            kwargs.get("stroke_filled", False),
 | 
				
			||||||
            anchor,
 | 
					            anchor,
 | 
				
			||||||
            ink,
 | 
					            ink,
 | 
				
			||||||
            start[0],
 | 
					            start[0],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,6 +28,7 @@ class Font:
 | 
				
			||||||
        features: list[str] | None,
 | 
					        features: list[str] | None,
 | 
				
			||||||
        lang: str | None,
 | 
					        lang: str | None,
 | 
				
			||||||
        stroke_width: float,
 | 
					        stroke_width: float,
 | 
				
			||||||
 | 
					        stroke_filled: bool,
 | 
				
			||||||
        anchor: str | None,
 | 
					        anchor: str | None,
 | 
				
			||||||
        foreground_ink_long: int,
 | 
					        foreground_ink_long: int,
 | 
				
			||||||
        x_start: float,
 | 
					        x_start: float,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -834,6 +834,7 @@ font_render(FontObject *self, PyObject *args) {
 | 
				
			||||||
    int mask = 0;  /* is FT_LOAD_TARGET_MONO enabled? */
 | 
					    int mask = 0;  /* is FT_LOAD_TARGET_MONO enabled? */
 | 
				
			||||||
    int color = 0; /* is FT_LOAD_COLOR enabled? */
 | 
					    int color = 0; /* is FT_LOAD_COLOR enabled? */
 | 
				
			||||||
    float stroke_width = 0;
 | 
					    float stroke_width = 0;
 | 
				
			||||||
 | 
					    int stroke_filled = 0;
 | 
				
			||||||
    PY_LONG_LONG foreground_ink_long = 0;
 | 
					    PY_LONG_LONG foreground_ink_long = 0;
 | 
				
			||||||
    unsigned int foreground_ink;
 | 
					    unsigned int foreground_ink;
 | 
				
			||||||
    const char *mode = NULL;
 | 
					    const char *mode = NULL;
 | 
				
			||||||
| 
						 | 
					@ -853,7 +854,7 @@ font_render(FontObject *self, PyObject *args) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!PyArg_ParseTuple(
 | 
					    if (!PyArg_ParseTuple(
 | 
				
			||||||
            args,
 | 
					            args,
 | 
				
			||||||
            "OO|zzOzfzLffO:render",
 | 
					            "OO|zzOzfpzLffO:render",
 | 
				
			||||||
            &string,
 | 
					            &string,
 | 
				
			||||||
            &fill,
 | 
					            &fill,
 | 
				
			||||||
            &mode,
 | 
					            &mode,
 | 
				
			||||||
| 
						 | 
					@ -861,6 +862,7 @@ font_render(FontObject *self, PyObject *args) {
 | 
				
			||||||
            &features,
 | 
					            &features,
 | 
				
			||||||
            &lang,
 | 
					            &lang,
 | 
				
			||||||
            &stroke_width,
 | 
					            &stroke_width,
 | 
				
			||||||
 | 
					            &stroke_filled,
 | 
				
			||||||
            &anchor,
 | 
					            &anchor,
 | 
				
			||||||
            &foreground_ink_long,
 | 
					            &foreground_ink_long,
 | 
				
			||||||
            &x_start,
 | 
					            &x_start,
 | 
				
			||||||
| 
						 | 
					@ -1005,7 +1007,8 @@ font_render(FontObject *self, PyObject *args) {
 | 
				
			||||||
        if (stroker != NULL) {
 | 
					        if (stroker != NULL) {
 | 
				
			||||||
            error = FT_Get_Glyph(glyph_slot, &glyph);
 | 
					            error = FT_Get_Glyph(glyph_slot, &glyph);
 | 
				
			||||||
            if (!error) {
 | 
					            if (!error) {
 | 
				
			||||||
                error = FT_Glyph_Stroke(&glyph, stroker, 1);
 | 
					                error = stroke_filled ? FT_Glyph_StrokeBorder(&glyph, stroker, 0, 1)
 | 
				
			||||||
 | 
					                                      : FT_Glyph_Stroke(&glyph, stroker, 1);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (!error) {
 | 
					            if (!error) {
 | 
				
			||||||
                FT_Vector origin = {0, 0};
 | 
					                FT_Vector origin = {0, 0};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user