3

I need to know the direction of my text before printing.

I'm using Unicode Characters.

How can I do that in C++?

j0k
  • 22,600
  • 28
  • 79
  • 90
kambi
  • 3,291
  • 10
  • 37
  • 58
  • I believe to the mark for RTL is U+200F ... Unicode is a bit broad. What UTF encoding are you using, what platform, what language and locale? – AJG85 Mar 24 '11 at 19:01

4 Answers4

6

If you don't want to use ICU, you can always manually parse the unicode database (.e.g., with a python script). It's a semicolon-separated text file, with each line representing a character code point. Look for the fifth record in each line - that's the character class. If it's R or AL, you have an RTL character, and 'L' is an LTR character. Other classes are weak or neutral types (like numerals), which I guess you'd want to ignore. Using that info, you can generate a lookup table of all RTL characters and then use it in your C++ code. If you really care about code size, you can minimize the size the lookup table takes in your code by using ranges (instead of an entry for each character), since most characters come in blocks of their BiDi class.

Now, define a function called GetCharDirection(wchar_t ch) which returns an enum value (say: Dir_LTR, Dir_RTL or Dir_Neutral) by checking the lookup table.

Now you can define a function GetStringDirection(const wchar_t*) which runs through all characters in the string until it encounters a character which is not Dir_Neutral. This first non-neutral character in the string should set the base direction for that string. Or at least that's how ICU seems to work.

Boaz Yaniv
  • 6,334
  • 21
  • 30
5

You could use the ICU library, which has a functions for that (ubidi_getDirection ubidi_getBaseDirection).

The size of ICU can be reduced, by recompiling the data library (which is normally about 15MB big), to include only the converters/locals which are needed for the project.

The section Reducing the Size of ICU's Data: Conversion Tables of the site http://userguide.icu-project.org/icudata, contains information how you can reduce the size of the data library.

If only need support for the most common encodings (US-ASCII, ISO-8859-1, UTF-7/8/16/32, SCSU, BOCU-1, CESU-8), the data library wont be needed anyway.

smerlin
  • 6,446
  • 3
  • 35
  • 58
  • OK, getBaseDirection is what he needs +1 :) – Yakov Galka Mar 24 '11 at 19:13
  • Thanks, but It has a size of about 16MB. I discovered that Microsoft started to offer a DLL for BIDI support like 10 years ago: "Uniscribe" and Apple has it's own parallel "ATSUI". Is there any C++ BIDI cross-platform adapter on top of them? Thanks. – kambi Mar 26 '11 at 18:00
  • i dont know, but regarding ICU, most of those 16MB are caused by the data-dll which by default contains encoding/decoding tables etc. pretty much all encodings. It can easily be stripped down in size. See http://userguide.icu-project.org/icudata, section `Reducing the Size of ICU's Data: Conversion Tables` – smerlin Mar 27 '11 at 19:01
2

From Boaz Yaniv said before, maybe something like this will easier and faster than parsing the whole file:

int aft_isrtl(int c){
  if (
    (c==0x05BE)||(c==0x05C0)||(c==0x05C3)||(c==0x05C6)||
    ((c>=0x05D0)&&(c<=0x05F4))||
    (c==0x0608)||(c==0x060B)||(c==0x060D)||
    ((c>=0x061B)&&(c<=0x064A))||
    ((c>=0x066D)&&(c<=0x066F))||
    ((c>=0x0671)&&(c<=0x06D5))||
    ((c>=0x06E5)&&(c<=0x06E6))||
    ((c>=0x06EE)&&(c<=0x06EF))||
    ((c>=0x06FA)&&(c<=0x0710))||
    ((c>=0x0712)&&(c<=0x072F))||
    ((c>=0x074D)&&(c<=0x07A5))||
    ((c>=0x07B1)&&(c<=0x07EA))||
    ((c>=0x07F4)&&(c<=0x07F5))||
    ((c>=0x07FA)&&(c<=0x0815))||
    (c==0x081A)||(c==0x0824)||(c==0x0828)||
    ((c>=0x0830)&&(c<=0x0858))||
    ((c>=0x085E)&&(c<=0x08AC))||
    (c==0x200F)||(c==0xFB1D)||
    ((c>=0xFB1F)&&(c<=0xFB28))||
    ((c>=0xFB2A)&&(c<=0xFD3D))||
    ((c>=0xFD50)&&(c<=0xFDFC))||
    ((c>=0xFE70)&&(c<=0xFEFC))||
    ((c>=0x10800)&&(c<=0x1091B))||
    ((c>=0x10920)&&(c<=0x10A00))||
    ((c>=0x10A10)&&(c<=0x10A33))||
    ((c>=0x10A40)&&(c<=0x10B35))||
    ((c>=0x10B40)&&(c<=0x10C48))||
    ((c>=0x1EE00)&&(c<=0x1EEBB))
  ) return 1;
  return 0;
}
amarullz
  • 346
  • 4
  • 4
-1

If you are using Windows GDI, it would seem that GetFontLanguageInfo(HDC) returns a DWORD; if GCP_REORDER is set, the language requires reordering for display, for example, Hebrew or Arabic.

Pierre
  • 4,114
  • 2
  • 34
  • 39
  • 1
    I don't mean to be sarcastic, but could I point out that a url to localhost is not generally all that useful on the internet. – Arafangion Oct 11 '12 at 07:01