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:
print chr$(23);chr$(16);chr$(2);space$(7)
This should be sufficient to output Hebrew to the printer, for example try this program (remember to enable Unicode support in the Options menu):
PrinterFont$ = "Arial 16" print chr$(23);chr$(16);chr$(2);space$(7) ' right-to-left lprint "זוהי הדגמה של כתיבת טקסט בעברית מימין לשמאל" dump
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:
print chr$(23);chr$(16);chr$(2);space$(7) ' right-to-left print "זוהי הדגמה של כתיבת טקסט בעברית מימין לשמאל"
To circumvent that issue you can set the right margin at a smaller value (here at column 70):
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 "זוהי הדגמה של כתיבת טקסט בעברית מימין לשמאל"
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):
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<128 or 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
And finally some Arabic text sent to the mainwin:
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<128 or 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
This is what it looks like on-screen (in this case from Windows XP):