13

We have a small web app that we want to convert into something native. Right now, it's got a lot of moving parts (the backend, the browser etc.) and we'd like to convert it into a single tight application. We decided to use PyGame to do this and it's been fine so far except for a font rendering issue.

The string I'd like to render is कोझिकोड. This, correctly rendered looks like Correctly rendered.

The specific code points are \u0915 \u094b \u091d \u093f \u0915 \u094b and \u0921

Now, this looks fine in my editor and my browser but when I try to render it in PyGame, I get this Wrongly rendered. Basically, the vowel sign (\u093f ि) should have been on the left of the झ but it appears to its right (and to the left of the क) thereby messing it up completely. This doesn't happen in a browser or a text editor (with the same input string) so I'm guessing it a renderer problem in PyGame.

There is one crude fix which works only in this specific case which i s to put the ि (\u093f) before the झ (\u091d). In that case, it renders properly like so Crude fix. This relies on me knowing something about the language and putting that logic into the code. I have to deal with multiple languages here so that's not really feasible.

I don't have much experience with unicode so I don't know how to approach this problem. Is there something I can do to fix this?

In case it matters, I'm using the freesans font which is there on Debian and which has the necessary glyphs to render this.

Update: The code to actually render this is as follows

# -*- coding: utf-8 -*-
import time

import pygame

# Pygame setup and create root window
pygame.font.init()
screen = pygame.display.set_mode((320, 200))
empty = pygame.Surface((320, 200))


font_file = pygame.font.match_font("freesans")  # Select and
font = pygame.font.Font(font_file, 30)          # open the font
writing = font.render(u"कोिझकोड  कोझिकोड", True, (0, 0, 0))  # Render text on a surface
screen.fill((255, 255, 255)) # Clear the background
screen.blit(writing, (10, 10)) # Blit the text surface on the background
pygame.display.flip()  # Refresh the display

input() # Wait for input before quitting

This is what it looks like Error in rendering

The first word is rendered correctly but we've done it by inverting the vowel and the letter positions as I mentioned in the crude fix. The second is written properly but not rendered correctly.

Update 2: In the absence of anything else, I've decided to try to render the string into an image using an external program and then blit this image onto the PyGame Surface. I tried imagemagick but it messes us in the same way as this. Gimp works fine and so I'm planning to use the batch mode to get my work done.

Noufal Ibrahim
  • 71,383
  • 13
  • 135
  • 169
  • By the way, I've noticed that, years ago, a [similar bug](https://bugs.chromium.org/p/chromium/issues/detail?id=43951) affected chromium browser. – Ilario Pierbattista Jun 02 '17 at 07:30
  • 1
    You should open a bug report against SDL_ttf. Other font renderers get it right and it proves once more that rendering text is a non-trivial task. Unless you get SDL_ttf developers to fix this, I’m afraid your only option is to switch to a different text rendering engine (such as freetype possibly via pango or something like that). – Jonas Schäfer Jun 02 '17 at 08:45
  • That's where I am right now. However, I'm really looking for a workaround right now to see whether there's some documented way I can get this to render correctly. – Noufal Ibrahim Jun 02 '17 at 09:51
  • is it somewhat similar to this ? https://github.com/python-pillow/Pillow/issues/2255 – Ubdus Samad Jun 07 '17 at 23:40
  • I don't think so. – Noufal Ibrahim Jun 08 '17 at 04:48

2 Answers2

5

I think is a SDL_ttf problem (the underlying component which actually renders the text).

While my IDE correctly renders the string

The SDL_TTF program does not:

There is the code: https://gist.github.com/ilario-pierbattista/be6b967b05fa2f1eb322f35988a33ad0

I'm still looking for a solution

Ilario Pierbattista
  • 3,175
  • 2
  • 31
  • 41
  • That's my situation too. – Noufal Ibrahim Jun 02 '17 at 08:41
  • This guy had the same problem and published a patch for SDL_ttf. [Here](http://forums.libsdl.org/viewtopic.php?p=48243) the main post, [here](https://bugzilla.libsdl.org/show_bug.cgi?id=3046) the bugzilla page, and [here](https://bugzilla-attachments.libsdl.org/attachment.cgi?id=2208) the patch. – Ilario Pierbattista Jun 02 '17 at 10:56
1

I had to finally resort to a really ugly but usable workaround for my own situation. I wrote a script-fu plugin which takes a filename and a piece of text as arguments. It then writes out the text and saves it a png file using gimp. My program then loads this up and blits the png directly onto the surface.

Noufal Ibrahim
  • 71,383
  • 13
  • 135
  • 169