Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Devanagari font not rendered correctly #3191

Closed
shubhampateliitm opened this issue Jun 18, 2018 · 18 comments
Closed

Devanagari font not rendered correctly #3191

shubhampateliitm opened this issue Jun 18, 2018 · 18 comments
Labels
Bug Any unexpected behavior, until confirmed feature. Font Rendering
Projects

Comments

@shubhampateliitm
Copy link

shubhampateliitm commented Jun 18, 2018

What did you do?

I am trying to print Devanagari text on the image. The text is printing on the image. But, it is not appearing the way it supposed to be. Devanagari is not like ordinary language script. In UTF-8 standard some particular characters when appear together show different character(The new character that formed is not define in UTF-8). Take a look at this doc for reference look this doc : https://www.unicode.org/versions/Unicode6.0.0/ch09.pdf#G12284 and variant shape section of this https://www.unicode.org/standard/where/.

Python Code :

from PIL import Image, ImageDraw, ImageFont

img = Image.new('RGB', (100, 30), color = (73, 109, 137))

fnt = ImageFont.truetype('NotoSans-Regular.ttf', 15)
d = ImageDraw.Draw(img)
d.text((10,10), "यात्रा", font=fnt, fill=(255, 255, 0))
img.save('pil_text_font.png')

Eventually Ubuntu also suffer from the same problem.

Please try to rectify this issue. Since otherwise it will changing whole spelling of words which is not fair to any Devanagari reader(Devanagari is the script for languages such Hindi, Marathi, Nepali).

Yatra shouldn't be like.
pil_text_font
It should be like
image

@radarhere radarhere changed the title Library does not interpreting Devanagari font the way it should. Library does not interpreting Devanagari font the way it should Jun 20, 2018
@radarhere radarhere changed the title Library does not interpreting Devanagari font the way it should Library is not interpreting Devanagari font the way it should Jun 29, 2018
@aclark4life aclark4life changed the title Library is not interpreting Devanagari font the way it should Devanagari font not rendered correctly Jun 30, 2018
@aclark4life aclark4life added the Bug Any unexpected behavior, until confirmed feature. label Jun 30, 2018
@radarhere
Copy link
Member

radarhere commented Aug 23, 2018

Just a link to NotoSans-Regular - https://fonts.google.com/specimen/Noto+Sans

@shubhampateliitm
Copy link
Author

@radarhere I don't get it. What do you mean by link of NotoSans Regular ??

@radarhere
Copy link
Member

Apologies, I wasn't trying to give you advice, I was trying to assist any future people looking at this issue by providing a link to the font that you were using, in order to help them to replicate your issue.

To try and be helpful now though, is raqm a possible solution to your problem? https://pillow.readthedocs.io/en/5.2.x/releasenotes/4.2.0.html#added-complex-text-rendering
https://pillow.readthedocs.io/en/5.2.x/reference/ImageFont.html?highlight=raqm#PIL.ImageFont.truetype

@shubhampateliitm
Copy link
Author

@radarhere This guy @ldo has some implementation of harfbuzz along with Cairo and Freetype, which worked for me. https://github.com/ldo/harfpy .
Maybe it can be helpful in resolving this issue.

@ldo
Copy link

ldo commented Aug 23, 2018

Just to clarify, the issue is that the writing system in question has mandatory contextual substitutions, so a simple character-to-glyph mapping is insufficient for correct text rendering. The way to deal with this is to support OpenType text shaping, which is what HarfBuzz does for you.

This may be sufficient for the Indic scripts, which I believe are all left-to-right. Then you may want to support bidirectional scripts as well (Hebrew, Arabic). This will require FriBidi. Then there are other complications, like Thai...

@HinTak
Copy link
Contributor

HinTak commented Oct 26, 2018

Give this a try - it has a devanagari example, https://github.com/HinTak/harfbuzz-python-demos .

@bipul21
Copy link

bipul21 commented Dec 21, 2018

Hi,

I am not sure if this is related.
I am trying some devanagari font text (hindi) with python 2.7.15, Pillow 3.5.0 and ubuntu 16 with harbuff, freebid and raqm setup.
The problem i am facing is that with "NotoSans-Bold" font type output is clipped but with Lohit Devnagari (https://www.fontsc.com/font/lohit-devanagari) it returns a correct output.

A sample script

# coding=utf-8
from PIL import Image, ImageDraw, ImageFont

string = u'से नये'
font = ImageFont.truetype('/<absolute_path>/NotoSans-Bold.ttf', 48)
im = Image.new("RGB", (200, 200), (255,0,0,0))
d = ImageDraw.Draw(im)
d.multiline_text((0, 0), string, fill="#000000", font=font)
im.save("hindi.jpeg")

With NotoSans-Bold (Incorrect)
hindi

With Lohit-Devanagari (Correct)
hindi_lohit

I would like to use "NotoSans-Bold" 💯

@ldo
Copy link

ldo commented Dec 21, 2018

@bipul21 When I try your example text with Noto Sans Bold on my system, it just shows up as empty blocks, while Lohit Devanagari renders fine.

Is there some kind of substitution going on with another font? And the clipping could be happening because the wrong font metrics are being used?

@bipul21
Copy link

bipul21 commented Dec 22, 2018

Thanks for checking it out.

I just tried the same, by downloading the fonts from here. https://www.google.com/get/noto/
I think the support for hindi is not there anymore.

https://www.google.com/get/noto/#sans-deva
But the same is happening by using Noto Devanagari font as well.

If it is a font issue, Can any anyone confirm ?

@ldo
Copy link

ldo commented Dec 22, 2018

Noto Sans Devanagari and Noto Serif Devanagari both work for me. On my Debian system if I ask for “Noto Devanagari”, it falls back to DejaVu Sans, which doesn’t work.

@bipul21
Copy link

bipul21 commented Dec 22, 2018

Are you not specifying path for your fonts?
Are you seeing tofu's with DevaVu Sans ? Can you share the output with both of them ?

What can i do to move forward?
Can you give your debian and dependency version details?
I seen somewhere, it was suggesting to patch a C file to fix a issue similar to fine but can't find it now :(

@ldo
Copy link

ldo commented Dec 22, 2018

@bipul21 Not paths, I use Fontconfig match patterns. My tests were done with Python scripts written with these libraries:

@bipul21
Copy link

bipul21 commented Dec 22, 2018

Alright so this answer posted just 2 days ago helps.

https://stackoverflow.com/a/53859718/577360

I am trying out pyvips for longevity but the quicker fix with trailing spaces works as well.

@ldo
Copy link

ldo commented Dec 23, 2018

The specific example raised by @bipul21 is slightly different. That particular text seems to render OK without contextual substitutions, but I think the clipping is occurring because of a confusion between advance width and glyph bounds.

The glyph bounds indicate where the glyph will appear relative to the current position. The advance width indicates how to update the current position for placing the next glyph. So the glyph bounds comprise a rectangle, while the advance width is a vector. Advance width might typically have a zero y-component for horizontal text, and a zero x-component for vertical text. (Right-to-left text is typically reordered during the rendering phase and drawn left-to-right, i.e. in the opposite of reading/storage order.)

Note that the glyph can appear just about anywhere in relation to the current position; it might hang a little to the left or below (e.g. kerning, descenders), or may be offset to the right or above, or some combination of these. For example, “combining forms” have a zero advance width and hang entirely to the left of the current position, so that they will appear on top of the previous glyph. By not updating the advance width, you can overprint any number of these combining forms at once. But they still have nonempty glyph bounds.

Conversely, a space character can have empty glyph bounds, since nothing needs to be drawn. But it still has an advance width, in order to take up space between words.

So any worthwhile text API needs to allow the caller to keep track of all these metrics.

@HinTak
Copy link
Contributor

HinTak commented Dec 23, 2018

Shameless plug - there is a devanagari example towards the bottom. Using harfbuzz's gobject binding (maintained within harfbuzz itself):
https://github.com/HinTak/harfbuzz-python-demos

@ldo
Copy link

ldo commented Dec 23, 2018

@HinTak Well, at least your example illustrates why PyCairo is such a pain to use, and why I created Qahirah.

@chintal
Copy link

chintal commented Aug 31, 2019

Vanilla pillow (PIL) (Image, ImageDraw, and ImageFont) seems to still have the same rendering problems. However, with libraqm also installed, pillow's renders are correct, or much closer to correct.

@radarhere
Copy link
Member

I agree with @chintal that the code from the original post works when using Pillow with libraqm.

pil_text_font

As for @bipul21, testing, I find that the clipping problem was fixed by #3787

hindi

Pillow automation moved this from Icebox to Closed Feb 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Any unexpected behavior, until confirmed feature. Font Rendering
Projects
Pillow
  
Closed
Development

No branches or pull requests

7 participants