Right-to-left text


#1

Hey folks, long time no see. I’ve been away from processing for a while but now I’ve opened it again for a small project: I am trying to render some Persian text within processing. The text looks fine when the result is rendered using P2d and exported as a PNG. However when the renderer is switched to PDF the text looks all broken like the characters are being flipped. I believe this has to do with how PDF mode handles RTL text. Unfortunately a simple scale to flip the whole text does not fix the problem.

Is there a way to handle this issue?


#2

Can you provide a small code sample reproducing the problem?

Kf


#3

Hi @Miguel!
I run into this issue a lot in Arabic, and not just in processing, but also in illustrator, photoshop, etc. One quick fix I tend to use is to flip input text (you can do that on your own or use this online tool to flip it)

For example, اهلا وسهلا in Arabic (It means “Welcome”) appears correctly to you right now, but then it appears like this when rendered to pdf:
flippedincorrect

So then, I change اهلا وسهلا to its flipped version using the previous tool ﻼﻬﺳﻭ ﻼﻫﺍ, and then it appears correctly.
flippedcorrect

If anyone needs a simple example to test this out, here it is:

import processing.pdf.*;

void setup() {
  size(400, 400, PDF, "test.pdf");
  textAlign(CENTER, CENTER);
  fill(0);
  textSize(64);
}

void draw() {
  background(255);  
  text("ﻼﻬﺳﻭ ﻼﻫﺍ", width/2, height/2);
  exit(); 
}

#4

WakeMeAtThree:
I tried a similar approach to what this tool is doing, mainly reversing the string with StringBuilder:

import processing.pdf.*;

void setup() {
  size(400, 400, PDF, "test.pdf");
  textAlign(CENTER, CENTER);
  fill(0);
  textSize(64);
}

void draw() {
  background(255);
  String welcome = "اهلا وسهلا";
  String emoclew = new StringBuilder(welcome).reverse().toString();
  text(emoclew, width/2, height/2);
  exit(); 
}

I am not a Persian speaker, but I believe by looking at the results that even though the string was reversed, the end results were definitely not accurate, still did not look legible. Maybe I missed something.

I have also tried to use unicode characters to set the text direction (https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Bidirectional_General_Formatting) but it looks like they are being ignored by Processing.


#5

Hi @Miguel,
It is not exactly a reversed string (I wish if it was as easy as that). I would encourage you to use the online tool I suggested previously to flip your texts instead rather than implement it yourself. This should help make your text legible, and if it still isn’t, post your code + sample text here so we can see what’s the issue.


#6

The problem is I am pulling text from a database, so this tool wont help much ;(


#7

Does this work?

String oldString = "hello world";
String newString = "";

void setup(){
  size(400, 400);
  background(255);
  fill(0);
  for(int chr = oldString.length()-1; chr >= 0; chr--){
    newString += oldString.charAt(chr);    
  }
  text("original string: " + oldString, 50, 50);
  text("new string: " + newString, 50, 100);
}

#8

Unfortunately not. Tried that, it is just another form of doing StringBuilder().rever() or convert a string to a char array and looping it. I am not so knowledgeable about Arabic, but I believe it has to do with the fact that some characters take more memory allocation than other.


#9

Here’s a blog post that addresses the Arabic text shape issue. You will also find mentioned a Python port of Better Arabic Reshaper which is written in Java. So there are two approaches you can take:

  • Either incorporate Better Arabic Reshaper (or an similar set of tools) into your processing sketch so that you transform your data as you render it.
  • Or transform the dataset first (maybe in python with arabic_reshaper or a similar library) and then do your pdf generation as normal in processing.

Also, one more issue you might have is that the set of letters in your text-script may have 3 or 4 more distinct letters than Arabic, so if you don’t find any dedicated library to it, you may have to include it yourself in whatever library you end up using.

@TheWizardBear I wish that would work, but it’s not just reversed string. Take a look at this code to get an idea from the Arabic reshaper set of tools I linked to earlier.


#10

Thank you very much, WakeMeAtThree. This is the kind of information I needed to understand the issue and implement my own solution. I really appreciate you taking the time to dig this. As a side note, maybe something like that could be incorporated in Processing core, like a direction parameter on the text() or a TextDirection(), like we have TextMode().