Arabic+text+on+the+mainwin+and+printer+(LBB)

//by Richard Russell, December 2014//

[|LB Booster] supports **Unicode**, so it is possible for a program to contain, and for the mainwin and printer to show, characters from foreign alphabets (Cyrillic, Greek, Arabic, Hebrew etc.) //without// needing to configure your PC for a specific 'code page'. This means that you can write a program which outputs text in one //or more// of these languages such that it will run on **any** (modern) Windows PC, so long as an appropriate font which contains the characters is selected.

However, whilst being able to output the necessary characters is sufficient for languages like Russian and Greek, some languages have additional requirements which you may need to take account of in your programs. For example Hebrew is written right-to-left so as well as changing the **character set** you also need to change the **direction** (you might get away with outputting the characters in the reverse order but it's not very satisfactory).

Another example is Arabic, which as well as being written right-to-left has a large number of **contextual** character forms which means that the appearance of a character may change according to which other character(s) precede and/or follow it (Arabic is written in a cursive script in which the characters 'run into' each other). In that case you certainly won't get away with simply outputting the characters in reverse order!

When outputting to a Windows **GUI control** (such as a textbox) the writing-direction and any special contextual forms are usually taken care of automatically by Windows. The article Displaying Unicode text in a control describes the steps you need to take to achieve this. When outputting to the **mainwin** or to the **printer** however there is no such automatic support, but fortunately LBB //does// provide the necessary features to achieve the required effects.

In order to switch the output direction to right-to-left (on both the mainwin and the printer) you can send this character sequence: code format="lb" print chr$(23);chr$(16);chr$(2);space$(7) code

This should be sufficient to output Hebrew to the printer, for example try this program (remember to enable **Unicode support** in the Options menu): code format="lb" PrinterFont$ = "Arial 16" print chr$(23);chr$(16);chr$(2);space$(7) ' right-to-left lprint "זוהי הדגמה של כתיבת טקסט בעברית מימין לשמאל" dump code

Outputting to the mainwin is basically the same, except that since the text will be written adjacent to the right 'margin' you will need to scroll across before you can see anything: code format="lb" print chr$(23);chr$(16);chr$(2);space$(7) ' right-to-left print "זוהי הדגמה של כתיבת טקסט בעברית מימין לשמאל" code

To circumvent that issue you can set the right margin at a smaller value (here at column 70): code format="lb" print chr$(28);chr$(0);chr$(66);chr$(70);chr$(0) ' set right margin print chr$(23);chr$(16);chr$(2);space$(7) ' right-to-left print "זוהי הדגמה של כתיבת טקסט בעברית מימין לשמאל" code

We have still not solved the problem of the Arabic contextual forms however. To do that requires a special function **Arabic$** which is included in the programs below. Firstly to output some Arabic text to the printer (again, remember to enable **Unicode support**): code format="lb" PrinterFont$ = "Arial 16" print chr$(23);chr$(16);chr$(2);space$(7) lprint Arabic$("هذا مثال يمكنك من الكتابة من اليمين") lprint Arabic$("الى اليسار باللغة العربية") dump end

function Arabic$(a$) a$ = a$ + chr$(0) for i = 1 to len(a$) c = asc(mid$(a$,i)) if c =192 then l = o : o = p : p = u       u = (c and 63) * 64 + (asc(mid$(a$,i+1)) and 63) if c<128 then u = 0 select case case u=1548 or u=1567: u = 0 case u<1570: u = u         case u<1574: u =  1+2*(u-1570) case u<1576: u = 9+4*(u-1574) case u<1578: u = 15+4*(u-1576) case u<1583: u = 21+4*(u-1578) case u<1587: u = 41+2*(u-1583) case u<1595: u = 49+4*(u-1587) case u<1601: u = u         case u<1608: u = 81+4*(u-1601) case u<1611: u =109+2*(u-1608) end select if p<>0 and p<128 then b = p         if o=93 and p<5  then b = b + 116 if o=93 and p=7 then b = b + 114 if o=93 and p=13 then b = b + 110 if b>p then b$=LEFT$(b$,len(b$)-3) : o = l         if u<>0 and p>7 and p<>13 and p<>19 and p<>41 and p<>43 and _ p<>45 and p<>47 and p<>109 and p<>111 then b = b + 2 if o<>0 and o>7 and o<>13 and o<>19 and o<>41 and o<>43 and _ o<>45 and o<>47 and o<>109 and o<>111 then b = b + 1 b$ = left$(b$,len(b$)-2)+chr$(239)+chr$(186+b/64)+chr$(128+(b and 63)) end if     end if      b$ = b$ + chr$(c) next Arabic$ = left$(b$,len(b$)-1) end function code

And finally some Arabic text sent to the mainwin: code format="lb" print chr$(28);chr$(0);chr$(66);chr$(70);chr$(0) print chr$(23);chr$(16);chr$(2);space$(7) print Arabic$("هذا مثال يمكنك من الكتابة من اليمين") print Arabic$("الى اليسار باللغة العربية") end

function Arabic$(a$) a$ = a$ + chr$(0) for i = 1 to len(a$) c = asc(mid$(a$,i)) if c =192 then l = o : o = p : p = u       u = (c and 63) * 64 + (asc(mid$(a$,i+1)) and 63) if c<128 then u = 0 select case case u=1548 or u=1567: u = 0 case u<1570: u = u         case u<1574: u =  1+2*(u-1570) case u<1576: u = 9+4*(u-1574) case u<1578: u = 15+4*(u-1576) case u<1583: u = 21+4*(u-1578) case u<1587: u = 41+2*(u-1583) case u<1595: u = 49+4*(u-1587) case u<1601: u = u         case u<1608: u = 81+4*(u-1601) case u<1611: u =109+2*(u-1608) end select if p<>0 and p<128 then b = p         if o=93 and p<5  then b = b + 116 if o=93 and p=7 then b = b + 114 if o=93 and p=13 then b = b + 110 if b>p then b$=LEFT$(b$,len(b$)-3) : o = l         if u<>0 and p>7 and p<>13 and p<>19 and p<>41 and p<>43 and _ p<>45 and p<>47 and p<>109 and p<>111 then b = b + 2 if o<>0 and o>7 and o<>13 and o<>19 and o<>41 and o<>43 and _ o<>45 and o<>47 and o<>109 and o<>111 then b = b + 1 b$ = left$(b$,len(b$)-2)+chr$(239)+chr$(186+b/64)+chr$(128+(b and 63)) end if     end if      b$ = b$ + chr$(c) next Arabic$ = left$(b$,len(b$)-1) end function code

This is what it looks like on-screen (in this case from Windows XP):