We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › activating non-latin font
Page Index Toggle Pages: 1
activating non-latin font (Read 4416 times)
activating non-latin font
Jul 27th, 2009, 8:22am
 
Hi all,
I am trying to create a wordmap in arabic, and I am having trouble creating an arabic font. Both using the Tools/Create Font and the createFont() function failed. I tried this with several fonts, and with "all characters" checked. With the first option i get an out of memory error (see below) and with both the standard font keeps on appearing.

here is the error:
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
     at processing.core.PImage.init(PImage.java:144)
     at processing.core.PImage.<init>(PImage.java:130)
     at processing.core.PFont.<init>(PFont.java:651)
     at processing.app.tools.CreateFont.build(CreateFont.java:329)
     at processing.app.tools.CreateFont$7.actionPerformed(CreateFont.java:223)
     at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1882)
     at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2202)
     at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)
     at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)
     at ch.randelshofer.quaqua.QuaquaButtonListener.mouseReleased(QuaquaButtonListener.j
ava:86)
     at java.awt.Component.processMouseEvent(Component.java:5602)
     at javax.swing.JComponent.processMouseEvent(JComponent.java:3135)
     at java.awt.Component.processEvent(Component.java:5367)
     at java.awt.Container.processEvent(Container.java:2010)
     at java.awt.Component.dispatchEventImpl(Component.java:4068)
     at java.awt.Container.dispatchEventImpl(Container.java:2068)
     at java.awt.Component.dispatchEvent(Component.java:3903)
     at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4256)
     at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3936)
     at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3866)
     at java.awt.Container.dispatchEventImpl(Container.java:2054)
     at java.awt.Window.dispatchEventImpl(Window.java:1801)
     at java.awt.Component.dispatchEvent(Component.java:3903)
     at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
     at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:2
69)
     at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190
)
     at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:184)
     at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:176)
     at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)

i cant attach the fonts im using because im new to this forum. Does anyone know how to get around this?

thanks
ayah
Re: activating non-latin font
Reply #1 - Jul 27th, 2009, 11:22am
 
See if the thread problem - unicode string in P2D and P3D mode can help you.
Re: activating non-latin font
Reply #2 - Jul 27th, 2009, 4:57pm
 
Thanks!
I tried to adapt the code in the previous post, it worked sort of well. I was able to create the font, and display arabic characters in the font i created. However I cannot access the characters I want, in a logical way.
If i type in an arabic string, i get the generic font again. if I type in a latin string, I get the arabic characters in the correct font. But there is no direct match between the code associated with the characters. Code below
Re: activating non-latin font
Reply #3 - Jul 27th, 2009, 4:57pm
 
post 3
Re: activating non-latin font
Reply #4 - Jul 27th, 2009, 4:58pm
 
post 4
Re: activating non-latin font
Reply #5 - Jul 27th, 2009, 4:58pm
 
post 5
Re: activating non-latin font
Reply #6 - Jul 27th, 2009, 4:58pm
 
NOW code below:


/*
Arabic Text Test
Code of Jaeho chang adapted to Arabic

-------------------------------

 Hangul

   version 0.1
   written by Jaeho Chang (trebari@gmail.com)
   special thanks to Philippe Lhoste
   
 IMPORTANT
 
   You must call "size()" before creating any instance of this class.
   
   If you encounter a memory error,
   adjust the memory setting in the Preferences.
   (http://processing.org/reference/troubleshooting/index.html#memory)

 EXAMPLE   */

   Hangul alhajar;

   void setup() {
 
     size(1000, 1000, P2D);
     alhajar = new Hangul("AXtAlHajarFont", 44);

   }

   void draw() {
     background(0);
     fill(255);

     alhajar.use();
     text("`~qwertyuiopasdfghjklzxcvbnm,./';[]", 10, 150);   // some arabic characters are displayed, but in a weird mapping
     text("مرحباً كيف حالك؟", 10, 150);     // the correct arabic characters are displayed, but it is not in the right direction ie right to left, and in a generic font (note arabic is right to left, so when i paste here, the order of this function is off)


   }

class Hangul {
 char[]   mCharset;
 PFont    mFont;

 Hangul(String fontName, int fontSize) {
   int index = 0, count = 0;

   // calculate the number of characters
   count += (0x007F - 0x0000 + 1);    // basic Latin
   count += (0x06F9 - 0x0621 + 1);    // Hangul jamo

   // allocate memory
   mCharset = new char[count];

   // loading basic Latin characters
   for (int code = 0x0000; code <= 0x007F; code++) {
     mCharset[index] = Character.toChars(code)[0];
     index++;
   }

   // loading arabic characters
   for (int code = 0x0621; code <= 0x06F9; code++) {
     mCharset[index] = Character.toChars(code)[0];
     index++;
   }

   // creating font
   print("Creating font " + fontName + "... please wait... ");
   mFont = createFont(fontName, fontSize, true, mCharset);
   println("done!");
 }

 void use() {
   textFont(mFont);
 }
}

Re: activating non-latin font
Reply #7 - Jul 28th, 2009, 1:57am
 
Unfortunately, I have no knowledge nor experience of Arabic, Hebrew or other RTL (right to left) language.
Note: Hangul is the name of the Korean alphabet, so you should rename the class (and comments!).
I was surprised by the "some arabic characters" displayed for Ascii content, but when I copy/pasted your code, I understood: you display the two lines of text at the same place, so Arabic is overlayed with plain Ascii. If you change the y position of the second text() call, it is sorted out.

Ah, I notice a funny thing: Firefox displays your second call as:
text("150 ,10 ,"<arabic chars>);
while when pasted in the PDE, I see it as
text("<squares>", 150, 10);
I get Arabic chars on output, but they don't look like the ones I see in Firefox.

Anyway, I am sure Java is able to correctly handle RTL display, although I don't know if Processing supports it (it might be transparent for it or it might need some additional settings, I don't know alas). Perhaps the limitation is on the PDE. You should try and use a UTF-8 able text editor (ie. saving its content in UTF-8 encoding) and type the text there.
Re: activating non-latin font
Reply #8 - Jul 29th, 2009, 8:23am
 
Thanks Phil. Will rename now Smiley

Do you know why when i do this:

     text("`~qwertyuiopasdfghjklzxcvbnm,./';[]", 10, 150);
     text("مرحباً كيفك", 10, 250);

the top line displays arabic characters but in the correct font, and the bottom line displays the generic font?
Why does this:      text("`~qwertyuiopasdfghjklzxcvbnm,./';[]", 10, 150);
result in arabic characters and how can i access the ones i want?

Re: activating non-latin font
Reply #9 - Jul 29th, 2009, 11:52am
 
Well, as I wrote, the first line displays Ascii chars for me. Perhaps that's a question of locales (I use French Windows).

I would be surprised you get two different fonts, if you do only one textFont() call. Not sure what you call "generic font".
Re: activating non-latin font
Reply #10 - Jan 20th, 2010, 8:00am
 
Well I had a different problem, the "create font" menu actually works well when you check the "all characters", and of course, choose a font where arabic letters are implemented. But if you get to type something in Arabic in PED, it's saved in the isolated form (not connected), moreover, it's displayed in the default left-to-right order, so I developed a generic static method to fix these 2 issues and thought I'd share it here:
Code:

// in some .java file
class someClass
{
public static String fixArabicUnicode(String s)
{
final int[] keys = {
0x627 // aa
,0x628 // b
,0x629 // t>
,0x62a // t
,0x62b // th
,0x62c // g
,0x62d // H
,0x62e // kh
,0x62f // d
,0x630 // dh
,0x631 // r
,0x632 // z
,0x633 // s
,0x634 // sh
,0x635 // S
,0x636 // D
,0x637 // T
,0x638 // Z
,0x639 // 3
,0x63a // G
,0x641 // f
,0x642 // q
,0x643 // k
,0x644 // l
,0x645 // m
,0x646 // n
,0x647 // h
,0x648 // w
,0x649 // E
,0x64a // ee
};

final int[] values = { // quadraples := <isolated, final, initial, medial>
0xFE8D, 0XFE8E, -1, -1 // aa
,0xFE8F, 0xFE90, 0xFE91, 0xFE92 // b
,0xFE93, 0xFE94, -1, -1 // t>
,0xFE95, 0xFE96, 0xFE97, 0xFE98 // t
,0xFE99, 0xFE9A, 0xFE9B, 0xFE9C // th
,0xFE9D, 0xFE9E, 0xFE9F, 0xFEA0 // g
,0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4 // H
,0xFEA5, 0xFEA6, 0xFEA7, 0xFEA8 // kh
,0xFEA9, 0XFEAA, -1, -1 // d
,0XFEAB, 0XFEAC, -1, -1 // dh
,0XFEAD, 0XFEAE, -1, -1 // r
,0XFEAF, 0XFEB0, -1, -1 // z
,0XFEB1, 0XFEB2, 0XFEB3, 0XFEB4 // s
,0XFEB5, 0XFEB6, 0XFEB7, 0XFEB8 // sh
,0XFEB9, 0XFEBA, 0XFEBB, 0XFEBC // S
,0XFEBD, 0XFEBE, 0XFEBF, 0XFEC0 // D
,0XFEC1, 0XFEC2, 0XFEC3, 0XFEC4 // T
,0XFEC5, 0XFEC6, 0XFEC7, 0XFEC8 // Z
,0XFEC9, 0XFECA, 0XFECB, 0XFECC // 3
,0XFECD, 0XFECE, 0XFECF, 0XFED0 // G
,0XFED1, 0XFED2, 0XFED3, 0XFED4 // f
,0XFED5, 0XFED6, 0XFED7, 0XFED8 // q
,0XFED9, 0XFEDA, 0XFEDB, 0XFEDC // k
,0XFEDD, 0XFEDE, 0XFEDF, 0XFEE0 // l
,0XFEE1, 0XFEE2, 0XFEE3, 0XFEE4 // m
,0XFEE5, 0XFEE6, 0XFEE7, 0XFEE8 // n
,0XFEE9, 0XFEEA, 0XFEEB, 0XFEEC // h
,0XFEED, 0XFEEE, -1, -1 // w
,0XFEEF, 0XFEF0, -1, -1 // E
,0XFEF1, 0XFEF2, 0XFEF3, 0XFEF4 // ee
};

final String spaces = " \t\r\n\f";

try
{
int[] ret = new int[s.length()] ;
int i, idx, I;
boolean sow, eow, efsel=false; // start of word, end of word, last char char separated the line
for(i=0; i<s.length(); i++)
{
//System.out.println ("char " + Integer.toString(s.codePointAt(i), 16) );
sow = ( i==0 || spaces.indexOf(s.charAt(i-1)) >=0 );
eow = ( i== s.length()-1 || spaces.indexOf(s.charAt(i+1)) >=0 ) ;
I = ret.length - i - 1;
idx = Arrays.binarySearch(keys, s.codePointAt(i));
//if (efsel) System.out.println("efsel is active with letter " + s.codePointAt(i));
if ( idx < 0 )
{
ret[I] = s.codePointAt(i);
efsel = true;
//ret[I] = 'n';
} else
{
if (sow && eow) // isolated
{
idx = idx*4;
ret[I] = values[idx];
efsel = false;
//ret[I] = 'i';
}
else if (eow) // final
{
idx = efsel? idx*4: idx*4+1;
ret[I] = (values[idx]);
efsel = false;
}
else if (sow || efsel) // initial
{
//if (efsel) System.out.println("efsel is active with letter " + Integer.toString(s.codePointAt(i), 16));
boolean oldefsel = efsel;
idx = idx*4+2;
if (values[idx] < 0)
{
// identical to isolated
ret[I] = (values[idx-2]);
efsel = true;
}
else
{
ret[I] = (values[idx]);
efsel = false;
}
//if (oldefsel) ret[I] = '>';

}
else // medial
{
idx = idx*4+3;
if (values[idx] < 0)
{
// identical to final
ret[I] = (values[idx-2]);
efsel = true;
}
else
{
ret[I] = (values[idx]);
efsel = false;
}
//if (efsel) ret[I] = '<';
}
}
}
return new String(ret, 0, ret.length);
} catch (Exception e)
{
return s;
}
}
}
// somewhere in your sketch
text(someClass.fixArabicUnicode("<arabic text>"), 0, 0 );



have fun!
Re: activating non-latin font
Reply #11 - Feb 9th, 2010, 6:01pm
 
I've been trying to render RTL text as well (Arabic). The hack for Arabic above works well, but I noticed it broke when I switched to using createFont() rather than loadFont().

Looking deeper, it seems that createFont() actually works better than loadFont() -- using createFont() there is no need to fix the characters.

I submitted a bug report describing this http://dev.processing.org/bugs/show_bug.cgi?id=1458. Here's code testing it:

Code:
PFont preload = loadFont("Arial-16.vlw");
PFont dynamic = createFont("Arial", 16);
String bismallah = "بسم الله الرحمن الرحيم";

size(180, 60);
background(0);
fill(255);

textFont(preload);
text(bismallah, 10, 20);

textFont(dynamic);
text(bismallah, 10, 46);
Re: activating non-latin font
Reply #12 - Jun 3rd, 2010, 11:59pm
 
I suppose he's right about implementation of this being a major thing. And it's not only the problem of RTL, but also - in case of Arabic script -, it's the joining characteristics and different letter forms for one single letter.
Page Index Toggle Pages: 1