Неправильный рендеринг текста деванагари в PyGame

У нас есть небольшое веб-приложение, которое мы хотим преобразовать во что-то нативное. Прямо сейчас у него много движущихся частей (бэкенд, браузер и т. д.), и мы хотели бы преобразовать его в одно компактное приложение. Мы решили использовать PyGame для этого, и до сих пор все было в порядке, за исключением проблемы с рендерингом шрифта.

Строка, которую я хотел бы отобразить, это कोझिकोड. Это, правильно отображенное, выглядит как Отображено правильно.

Конкретные кодовые точки: क ो झ ि क ो и ड

Теперь это выглядит нормально в моем редакторе и браузере, но когда я пытаюсь отобразить это в PyGame, я получаю это Неправильно отображается. По сути, знак гласной (> ि) должен был быть слева от झ, но он появляется справа (и слева от क), тем самым полностью искажая его. Этого не происходит в браузере или текстовом редакторе (с той же входной строкой), поэтому я предполагаю, что это проблема с рендерером в PyGame.

Есть одно грубое исправление, которое работает только в этом конкретном случае: поставить ि (ि) перед झ (झ). В этом случае он отображается правильно следующим образом: Грубое исправление. Это зависит от того, что я что-то знаю о языке и включаю эту логику в код. Мне приходится иметь дело с несколькими языками здесь, так что это нереально.

У меня нет большого опыта работы с юникодом, поэтому я не знаю, как решить эту проблему. Есть ли что-то, что я могу сделать, чтобы исправить это?

Если это имеет значение, я использую шрифт freesans, который есть в Debian и который имеет необходимые глифы для отображения этого.

Обновление: код для рендеринга выглядит следующим образом.

# -*- 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

Вот как это выглядит Ошибка рендеринга

Первое слово отображается правильно, но мы сделали это, инвертировав положение гласных и букв, как я упоминал в грубом исправлении. Второй написан правильно, но не отображается правильно.

Обновление 2: в отсутствие чего-либо еще я решил попытаться преобразовать строку в изображение с помощью внешней программы, а затем перенести это изображение на поверхность PyGame. Я попробовал imagemagick, но он так же мешает нам, как и этот. Gimp работает нормально, поэтому я планирую использовать пакетный режим для выполнения своей работы.


person Noufal Ibrahim    schedule 30.05.2017    source источник
comment
Кстати, я заметил, что много лет назад похожая ошибка влияет на браузер Chrome.   -  person Ilario Pierbattista    schedule 02.06.2017
comment
Вы должны открыть отчет об ошибке в отношении SDL_ttf. Другие рендереры шрифтов понимают это правильно, и это еще раз доказывает, что рендеринг текста — нетривиальная задача. Если вы не заставите разработчиков SDL_ttf исправить это, я боюсь, что ваш единственный вариант — переключиться на другой движок рендеринга текста (например, freetype, возможно, через pango или что-то в этом роде).   -  person Jonas Schäfer    schedule 02.06.2017
comment
Вот где я сейчас. Тем не менее, я действительно ищу обходной путь прямо сейчас, чтобы узнать, есть ли какой-то документированный способ, которым я могу заставить это правильно отображать.   -  person Noufal Ibrahim    schedule 02.06.2017
comment
это чем-то похоже на это? github.com/python-pillow/Pillow/issues/2255   -  person Ubdus Samad    schedule 08.06.2017
comment
Я так не думаю.   -  person Noufal Ibrahim    schedule 08.06.2017


Ответы (2)


Я думаю, что это проблема SDL_ttf (базовый компонент, который фактически отображает текст).

Хотя моя IDE правильно отображает строку

Программа SDL_TTF не:

Вот код: https://gist.github.com/ilario-pierbattista/be6b967b05fa2f1eb322f35988a33ad0

Я все еще ищу решение

person Ilario Pierbattista    schedule 02.06.2017

В конце концов мне пришлось прибегнуть к действительно уродливому, но полезному обходному пути для моей собственной ситуации. Я написал плагин script-fu, который принимает в качестве аргументов имя файла и фрагмент текста. Затем он записывает текст и сохраняет его в файл png с помощью gimp. Затем моя программа загружает это и копирует png прямо на поверхность.

person Noufal Ibrahim    schedule 08.06.2017