Writing simple text on an image using PIL is easy.
draw = ImageDraw.Draw(img)
draw.text((10, y), text2, font=font, fill=forecolor )
However, when I try to write Hebrew punctuation marks (called "nikud" or ניקוד), the characters do not overlap as they should. (I would guess this question is relevant also to Arabic and other similar languages.)
On supporting environment, these two words take up the same space/width (the below example depends on your system, hence the image):
סֶפֶר ספר
However when drawing the text with PIL I get:
ס ֶ פ ֶ ר
since the library probably doesn't obey kerning(?) rules.
Is it possible to have the character and Hebrew punctuation mark take up the same space/width without manually writing character positioning?
image - nikud and letter spacing http://tinypic.com/r/jglhc5/5
image url: http://tinypic.com/r/jglhc5/5
funny, after 5 years, and with great help fron @Nasser Al-Wohaibi, I realized how to do it:
Reversing the text with a BIDI algorithm was needed.
# -*- coding: utf-8 -*-
from bidi.algorithm import get_display
import PIL.Image, PIL.ImageFont, PIL.ImageDraw
img= PIL.Image.new("L", (400, 200))
draw = PIL.ImageDraw.Draw(img)
font = PIL.ImageFont.truetype( r"c:\windows\fonts\arial.ttf", 30)
t1 = u'סֶפֶר ספר!'
draw.text( (10,10), 'before BiDi :' + t1, fill=255, font=font)
t2 = get_display(t1) # <--- here's the magic <---
draw.text( (10,50), 'after BiDi: ' + t2, fill=220, font=font)
img.save( 'bidi-test.png')
@Nasser's answer has extra value that's probably relevant only to arabic texts (the letters in arabic change shape and connected-ness based on their neiboring letters, in hebrew all letters are separate), so only the bidi part was relevant for this question.
in the sample result, the 2nd line is the correct form, and correct vocalization marks positioning.
thank you @tzot for help + code snippets
a-propos:
samples of different font behavior with Hebrew "nikud". Not all fonts behave the same: