drawbot icon indicating copy to clipboard operation
drawbot copied to clipboard

Problems when using language tag in FormattedString

Open frankrolf opened this issue 5 years ago • 6 comments

I am proofing Cyrillic, including Bulgarian alternates. This example makes two pages, one Russian, the other Bulgarian:

import os
import drawBot as db


def make_proof_page(language_tag):

    proof_text = 'вгджзийклнпттттфцчшщъьюѝ'

    font = 'SourceSerifPro-Light.otf'
    margin = 30
    pt_size = 40

    db.newPage(1200, 120)
    y_offset = db.height() - margin - pt_size
    fs = db.FormattedString(
        proof_text,
        font=font,
        language=language_tag,
        fontSize=pt_size,
    )

    db.text(fs, (margin, y_offset))
    print(fs.size().width)


db.newDrawing()
for language_tag in ['ru', 'bg']:
    make_proof_page(language_tag)

output_name = 'ru vs bgr.pdf'
db.saveImage(output_name)
os.system(f'open "{output_name}"')
db.endDrawing()

Issues I observe:

  • the result of size().width is the same no matter which language (they are not visually the same)

  • the Bulgarian string gets truncated after щ when using DrawBot from the command line: Screen Shot 2020-09-16 at 16 48 10

  • the rest of the Bulgarian string gets shoved somewhere below when using DrawBot desktop app – although there is no line break involved: Screen Shot 2020-09-16 at 16 48 34

Test case (with font) attached: Formatted String + language tag.zip

frankrolf avatar Sep 16 '20 14:09 frankrolf

I used DrawBot 3.126 (both module and packaged) on macOS 10.15.6.

frankrolf avatar Sep 16 '20 14:09 frankrolf

mm, Im unsure in CoreText when OT features are applied... I assume while doing the layout, so when a size of string is calculated there are no replacements done yet...

probably this is related @LettError variable arrows issue (cannot find it back directly)

if this is the case DrawBot needs to calculate the size based with laid out strings.

typemytype avatar Sep 18 '20 09:09 typemytype

Reference for clipping in variable font text issue: https://github.com/typemytype/drawbot/issues/332

LettError avatar Sep 18 '20 12:09 LettError

you can check the typesetted bounds of a formattestring with textBoxCharacterBounds

this should probably by used for textSize() and formattedString.size()

import os
import drawBot as db


def make_proof_page(language_tag):

    proof_text = 'вгджзийклнпттттфцчшщъьюѝ'

    font = 'SourceSerifPro-Light.otf'
    margin = 30
    pt_size = 40

    db.newPage(1200, 120)
    y_offset = db.height() - margin - pt_size
    fs = db.FormattedString(
        proof_text,
        font=font,
        language=language_tag,
        fontSize=pt_size,
    )

    db.text(fs, (margin, y_offset))
    
    dummyHeight = 5000
    boxes = db.textBoxCharacterBounds(fs, (margin, y_offset, 5000, dummyHeight))
    for box in boxes:
        db.fill(1, 0, 0, .5)
        x, y, w, h = box.bounds
        db.rect(x, y-dummyHeight + fs.fontLineHeight() + fs.fontDescender(), w, h)
    print(fs.size().width)


db.newDrawing()
for language_tag in ['ru', 'bg']:
    make_proof_page(language_tag)

output_name = 'ru vs bgr.pdf'
db.saveImage(output_name)
#os.system(f'open "{output_name}"')
db.endDrawing()

typemytype avatar Sep 21 '20 10:09 typemytype

Simplified test:

size(600, 120)

proof_text = 'вгджзийклнпттттфцчшщъьюѝ'

font('../fonts/SourceSerifPro-Regular.otf')
fontSize(39)
text(proof_text, (12, 74))
language("bg")
text(proof_text, (12, 33))

The second line wraps, so the box calculation is not using the correct language setting.

image

justvanrossum avatar Sep 26 '20 06:09 justvanrossum

FWIW, drawbot-skia now supports language()

  • https://github.com/justvanrossum/drawbot-skia/blob/master/tests/apitests/language.py
  • https://github.com/justvanrossum/drawbot-skia/blob/master/tests/apitests_expected_output/language.png

justvanrossum avatar Sep 26 '20 08:09 justvanrossum