镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Multiline ttb text is not supported #4945

Closed

Description

@nulano

Drawing multiline text currently draws a single vertical line of overlapping characters. I'm not sure how/if this can be fixed within the existing API since it is not clear whether ttb lines should advance to the left or the right.

What did you do?

from PIL import ImageFont, ImageDraw, Image

im = Image.new("RGB", (200, 200), "white")
draw = ImageDraw.Draw(im)
font = ImageFont.truetype("Tests/fonts/DejaVuSans.ttf", 24)
dram.text((100, 10), "abc\n123\nXYZ", "black", font, direction="ttb")
im.show()

What actually happened?

Before #4930 (master):

multiline

With #4930:

ValueError: ttb direction is unsupported for multiline text

Activity

  1. radarhere commented on Oct 24, 2020

    @radarhere
    Member

    https://www.w3.org/International/questions/qa-scripts#:~:text=Ideographic%20languages%20(e.g.%20Japanese%2C%20Korean,occasionally%20written%20right%20to%20left.

    Ideographic languages (e.g. Japanese, Korean, Chinese) are more flexible in their writing direction. They are generally written left-to-right, or vertically top-to-bottom (with the vertical lines proceeding from right to left).

    Should ttb lines then advance to the left?

  2. nulano commented on Dec 11, 2020

    @nulano
    ContributorAuthor

    Advancing lines to the left would be fine for languages that actually use ttb, but not for e.g. English text written in ttb mode. For example, the Bungee font is designed with English ttb in mind, and that would most likely advance to the right.

    How's this proposal: The spacing=4 parameter is currently used to add an additional offset to the line-height automatically chosen by Pillow (height of the letter A). In ttb mode, it could be reused to specify the exact distance between lines horizontally, so 20 would place lines at 20px intervals advancing to the right and -10 would place lines at 10px intervals advancing to the left. The default value doesn't make sense here, but ttb fonts might not have a glyph for the letter A anyway.

  3. kubinka0505 commented on Dec 17, 2020

    @kubinka0505

    If You mean Top To Bottom it could be easily done by setting spacing variable as @nulano said, and getting textwrap.wrap with it to work, but in your case I see it can be splitted by newlines.

    No offence, but I strongly advise You to write fonts on new transparent Image instances, since it's easier to manipulate them later.

    from PIL import Image, ImageDraw, ImageFont
    
    im = Image.new("RGB", (200, 200), "white")
    im_text = Image.new("RGBA", im.size, (0,) * 4)
    draw = ImageDraw.Draw(im_text)
    
    #---#
    text = "abc\n123\nXYZ"
    font = ImageFont.truetype(r"Roboto.otf", 24)
    co_ords = (100, 10)
    #---#
    
    spacing = 0
    for Line in text.split("\n"):
    	draw.text((0, spacing), Line, fill = "black", font)
    	spacing += font.getsize(Line)[1]
    
    # Crop transparent pixels
    im_text = im_text.crop(im_text.getbbox())
    
    im.paste(im_text, co_ords, im_text)
    im.show()
  4. andjc commented on Jun 29, 2022

    @andjc

    @radarhere asked:

    Should ttb lines then advance to the left?

    I am wondering how it is implemented in Raqm, what their values are in terms of layout. Two different things seem to be mixed up together, text direction and text progression.

    ttb tells you the direction of the text run, but doesn't tell you the progression of lines of text.

    For instance, Han ideographs when written vertically (Chinese, Japanese, Korean (in Hanja), Vietnamese in Chữ Nôm) is written in lines from top of text area to bottom, with lines of text progressing to the left.

    Mongolian script on the other hand is written top to bottom as well, but lines of text progress to the right instead of the left, so as Mongolian progression is the opposite to Han ideographs, any rendering system needs to be able to support vertical text progression in either direction.

  5. nulano commented on Jun 29, 2022

    @nulano
    ContributorAuthor

    I am wondering how it is implemented in Raqm

    Raqm does not yet support line-breaking, but instead treats the whole input as a single line of text: HOST-Oman/libraqm#50

  6. andjc commented on Jul 1, 2022

    @andjc

    Thanks @nulano,

    I suspected that was the case, although I guess it's a moot point at the moment, since I can't get a single vertical line to correctly render, let alone multiple lines. I suspect that the writing system (script) I am working with isn't supported in raqm yet.

  7. changed the title [-]Multiline ttb text doesn't work[/-] [+]Multiline ttb text is not supported[/+] on Dec 23, 2023
  8. radarhere commented on Jun 12, 2025

    @radarhere
    Member

    I've created #8730 to resolve this.

    from PIL import ImageFont, ImageDraw, Image
    
    im = Image.new("RGB", (200, 200), "white")
    draw = ImageDraw.Draw(im)
    font = ImageFont.truetype("Tests/fonts/DejaVuSans/DejaVuSans.ttf", 24)
    draw.text((100, 10), "abc\n123\nXYZ", "black", font, direction="ttb")
    im.show()

    would generate
    Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions