drawbot
drawbot copied to clipboard
Problems when using language tag in FormattedString
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().widthis 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:

-
the rest of the Bulgarian string gets shoved somewhere below when using DrawBot desktop app – although there is no line break involved:

Test case (with font) attached: Formatted String + language tag.zip
I used DrawBot 3.126 (both module and packaged) on macOS 10.15.6.
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.
Reference for clipping in variable font text issue: https://github.com/typemytype/drawbot/issues/332
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()
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.

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