Printing arabic - Lines are in reverse order when a paragraph is rendered in a block with multiple lines after using bid

Viewed 597

Okay first, My data's source is google sheets, a simple table with rows (ID, Confession and Age) I use google sheets api to connect the data to my python script using gspread and google oauth2client in order to fetch the Confession column ( which is mostly paragraphs, around 100 to 200 arabic words)

Once the data / confession is stored into the confessions Variable in my code, I run it by the arabic reshape functions and get display(bidi algorithm). then the output is processed by ''Pillow-Img'' in order to add the the paragraphs into an image. the output is fine, arabic is showing perfectly but the lines are starting from the bottom instead of the top right side.

the text must be written from right to left

example:test

however, the actual paragraph is

كيما يكون التقريران متسقين تماما، فإن هناك تغييرا طفيفا في الفقرة 2 من تقرير الفريق العامل الثاني، التي يرد فيها ذكر الرئيس والموظفين المعنيين الآخرين.

as you can notice "كيما يكون التقريران" is at the end of the end of the sentence in the image, yet it's at the beginning (right top side) in the original paragraph (quote) so basically lines are reversed and I cant find a workaround without splitting the paragraphs into small lines and then print them line by line which is literally impossible due to the avg paragraph is going to be around 200 words.

get_arabic_text() and arabicfix() are both functions are built for reshaping arabic, except get_arabic_text splits the input and reshapes word by word. but arabicfix() just pushes the all data into the arabic reshaper. in the code im only triggering arabicfix()

I tend to believe that the issue is within the bidi algorithm but I can't figure out a solution.

# -*- coding: utf-8 -*-
from PIL import Image, ImageDraw, ImageFont
from bidi.algorithm import get_display
import textwrap, os, re, arabic_reshaper
from rtl import reshaper

def f(p): return os.path.join(directory, p)
directory = os.path.normcase(os.path.dirname(__file__))

def get_arabic_text(text):
    if reshaper.has_arabic_letters(text):
        words = text.split()
        reshaped_words = []
        for word in words:
            if reshaper.has_arabic_letters(word):
                # for reshaping and concating words
                reshaped_text = reshaper.reshape(word)
                # for right to left
                bidi_text = get_display(reshaped_text)
                reshaped_words.append(bidi_text)
            else:
                reshaped_words.append(word)
        reshaped_words.reverse()
    return ' '.join(reshaped_words)
    return text



def draw_multiple_line_text(image, text, font, text_color, text_start_height):
    draw = ImageDraw.Draw(image)
    print(text)
    image_width, image_height = image.size
    y_text = text_start_height
    lines = textwrap.wrap(text, width=65)
    print(lines)
    for line in lines:
        line_width, line_height = font.getsize(line)
        draw.text(((image_width - line_width)/2, y_text),line, font=font, fill=text_color)
        y_text += line_height

def arabicfix(text):
    config_from_font = arabic_reshaper.config_for_true_type_font(
        f('arial.ttf'))
    reshaper = arabic_reshaper.ArabicReshaper(config_from_font)
    text_to_be_reshaped = text
    reshaped_text=reshaper.reshape(text_to_be_reshaped)
    bidi_text = get_display(reshaped_text,base_dir='R')
    return bidi_text



def main():
    image = Image.open('twitter2.jpg')
    arabictext=u"كيما يكون التقريران متسقين تماما، فإن هناك تغييرا طفيفا في الفقرة 2 من تقرير الفريق العامل الثاني، التي يرد فيها ذكر الرئيس والموظفين المعنيين الآخرين."
    text=arabicfix(arabictext)
    print("text:", text)
    fontsize = 25
    textcolor= (0,0,0)
    text_height =50
    font = ImageFont.truetype('/Users/Hady/PycharmProjects/untitled/arial.ttf', fontsize)
    draw_multiple_line_text(image, text, font,textcolor,text_height)


    image.save(f('tofff.jpg'))


main()
1 Answers

I solved a similar issue by not fixing the whole arabic text at once, instead I fixed each line before printing like this:

def draw_multiple_line_text(image, text, font, text_color, text_start_height):
    draw = ImageDraw.Draw(image)
    print(text)
    image_width, image_height = image.size
    y_text = text_start_height
    lines = textwrap.wrap(text, width=65)
    print(lines)
    for line in lines:
        line_width, line_height = font.getsize(line)
        draw.text(((image_width - line_width)/2, y_text),text=arabicfix(line), font=font, fill=text_color)
        y_text += line_height

def main():
    image = Image.open('twitter2.jpg')
    arabictext=u"كيما يكون التقريران متسقين تماما، فإن هناك تغييرا طفيفا في الفقرة 2 من تقرير الفريق العامل الثاني، التي يرد فيها ذكر الرئيس والموظفين المعنيين الآخرين."
    print("text:", text)
    fontsize = 25
    textcolor= (0,0,0)
    text_height =50
    font = ImageFont.truetype('/Users/Hady/PycharmProjects/untitled/arial.ttf', fontsize)
    draw_multiple_line_text(image, text, font,textcolor,text_height)


    image.save(f('tofff.jpg'))
Related