Lazarus

Programming => Widgetset => Win32/64 => Topic started by: Ocye on December 31, 2013, 01:05:17 pm

Title: [solved] Right-to-left reading direction under Windows XP
Post by: Ocye on December 31, 2013, 01:05:17 pm
I struggle with RTL under Windows XP. My problem is similar to http://forum.lazarus.freepascal.org/index.php?topic=20722.0 and the related bug report http://bugs.freepascal.org/view.php?id=24340. So I updated via svn and run the submitted program (actually, I'm not able to read Arab letter).
Linux shows in both flavors Qt and Gtk2 the expected RTL output but Windows XP doesn't. Surprisingly the Windows app started from Linux via wine works as expected. And when I compile and run under W7 it works too. What can I do?

Lazarus 1.3 r43599M FPC 2.6.2 x86_64-linux-qt (@Windows fpc 2.6.2 and LCL from todays svn)
Title: Re: Right-to-left reading direction under Windows XP
Post by: Ocye on January 02, 2014, 01:56:03 pm
Can somebody confirm this issue?

Sample project is attached.
Title: Re: Right-to-left reading direction under Windows XP
Post by: Martin_fr on January 02, 2014, 02:01:32 pm
Best is, if you attach a small (minimum) sample project to demonstrate the problem.

Then you have a better chance, that someone will test it.

Right now, I do not even know what component, or function you used for output.
Title: Re: Right-to-left reading direction under Windows XP
Post by: Ocye on January 02, 2014, 02:25:50 pm
I use the same code as in the linked posts/bugreport but not only with Qt as originally reported but with Windows XP. It's a simple DrawText() on a TCanvas; in my program it's wrong for MessageDlg() too.
Title: Re: Right-to-left reading direction under Windows XP
Post by: Martin_fr on January 02, 2014, 03:01:10 pm
It is still a lot of work, and a lot of extra to read...
copy and paste it together, find the correct units to use (assuming you use the same (drawtext from LclIntf?)

Most none RTL users will not bother, even though they could test.

--- anyway I did test, on win vista 32 bit. (with and without manifest)
Someone still needs to test xp

Code: [Select]
procedure TForm1.Button1Click(Sender: TObject);
var  s: String;
  R: TRect;
begin
  MessageDlg('% ,خطأ نسبي', '% ,خطأ نسبي', mtInformation, mbYesNo, 0);

s:='% ,خطأ نسبي';
r.Top := 40;
r.Left := 30;
r.Bottom := 88;
r.Right := 222;

  DrawText(Form1.Canvas.Handle, PChar(s), Length(s), R, DT_WORDBREAK);
end;

Note, the editor will display the messagedialog line in an unexpected way. The ', ' is between 2 RTL sections. The chars are have a weak leading, and will be taken an RTL too, meaning they read in the wrong direction.
However the first '% bound to the LTR text before so the % stays at the beginning.

Test results:
The words are displayed correct, but the % is at the left side not the end. I guess this is because my system is LTR.

For drawtext I can do:
Code: [Select]
  DrawText(Form1.Canvas.Handle, PChar(s), Length(s), R, DT_WORDBREAK + DT_RTLREADING);
And I get the correct words, and the % is on the right side
Title: Re: Right-to-left reading direction under Windows XP
Post by: Ocye on January 02, 2014, 03:11:18 pm
So the char خ is the left-most painted character on Vista? Actually I don't know what I want to achieve right now. If Vista is okay my users still have problems with their XP. And if someone confirms the issue I still don't know what to do. Perhaps a disclaimer that states a minimum requirement of Linux or W7... ;-)

It is still a lot of work, and a lot of extra to read...
Sorry and thank you. I'll add my code this evening (GMT+1).
Title: Re: Right-to-left reading direction under Windows XP
Post by: Martin_fr on January 02, 2014, 03:22:49 pm
Try
    LCLIntf.ExtUTF8Out(Form1.Canvas.Handle, X, Y, fuOptions, @ARect, Text, Length, NIL)

(last param MUST be nil)

And if that works, then the rest needs to be reported as bug.

For more see unit SynTextDrawer

Title: Re: Right-to-left reading direction under Windows XP
Post by: Ocye on January 03, 2014, 07:26:02 am
Whatever I do all output is LTR. Even a simple label whose bidiMode I set to RTL sticks to the original orientation.

(Sample project is attached now to the second posting)
Title: Re: Right-to-left reading direction under Windows XP
Post by: engkin on January 03, 2014, 08:20:07 am
Whatever I do all output is LTR.
Most likely you tried that, just want to make sure. Pass ETO_RTLREADING = 128 in the options parameter of ExtTextOut.

If that does not work, try to call ExtTextOut directly from Windows unit, again using ETO_RTLREADING.

This is just a guess.  :-[
Title: Re: Right-to-left reading direction under Windows XP
Post by: Martin_fr on January 03, 2014, 01:50:53 pm
I have to dig out my old XP netbook for testing. this will be a while.

But for what I can see there a 2 problems.

1)
The "%" being on the right or left. The "%" is a weak char, so it sticks to the leading of it's neighbouring chars, or the global leading (would have to check the exact unicode doc for the correct expected behaviour....)

When you use DrawText or ExtTextOut or similar, then I would *guess* that this depends on the locale of the windows system. And I would guess, that it is your responsibility to specify  ETO_RTLREADING.

As for labels, and other controls: If there bidi is RTL, then maybe they need to specify ETO_RTLREADING. That may or may not be a bug. I am not an expert on this.


2) The arabic words/sentence (including the space in the middle, that is surrounded by RTL on both sides, and must therefore be RTL itself too)

I do not actually know/read/speak Arab, so I can only judge from the overall appearance. The actual glyphs do not mean anything to me.

It does look as if the text is spelled out letter by letter. Arab is a script language, the letters should be connected. I do not know what breaks them up.

------

- I guess you have tested this text in Microsoft notepad! Does it work there?
- Does it display ok in the IDE (SynEdit) if you run the IDE on XP ?

If it does fail in notepad, then there may be a windows update that is needed for this to work.

If it works in notepad, then this looks like a bug that needs to be reported (with sample app, and all)


If it works in SynEdit, then ExtTextOut should work.

Title: Re: Right-to-left reading direction under Windows XP
Post by: Ocye on January 03, 2014, 02:14:48 pm
I have no idea about Arab or Hebrew as well (still in hope for a native speaker; Edit: just PM'd Yurii). Currently I'm on W7, and when I copy خطأ نسبي into notepad or wordpad the left-most u-like letter with two dots below is still on the left side. Its the same as in the browser and in the first three pictures. Furthermore, the cursor goes from right to left within the word when I press cursor right key.
In my examples only the fourth picture which was made with XP is inverted, e.g. the dotted u is on the right. Now I'm completely confused. Could it be that XP flips the correct RTL back to LTR?
Title: Re: Right-to-left reading direction under Windows XP
Post by: zariq on January 03, 2014, 02:39:43 pm
Arab is a script language, the letters should be connected.

Depends on the letter and the letters on iether side if any. Some connect some dont. Sorry if you meant something different.
Title: Re: Right-to-left reading direction under Windows XP
Post by: Martin_fr on January 03, 2014, 02:50:48 pm
I just tested, on my XP, in a notepad the "%" is on the left side. I do have an UK locale, so my locale is LTR. Not sure if that makes a difference.

That may be altered by inserting an RTL marker (a special invisible char).

The unicode specs for this are very long and I do not plan to read them. But this is what is implemented in windows anyhow. Not in FPC/Lazarus.

As I said for controls with bidi-mode=rtl, it may be a bug. Maybe they should specify ETO_RTLLeading.

-------------
As for the individual letters versus full words (which may also affect the RTL/LTR of the word): SynEdit on XP does display the words correct.

In the one (win.png) picture that you posted, something is breaking up the words into chars. (or codepoints). That is wrong.

But I can not reproduce. I jusst tested on my XP (home edition)/ latest lazarus trunk 1.3, fpc 2.6.0
- The code I posted works correct ("%" on the left, but I do not know if that is correct or not)
 That is both captions in the dialog, and drawtext work.

I also pasted the text in a labels caption. Works correct too.
And if I set the labels bidi to RTL, then the "%" goes to the right as it should.

------------------
So the point is, I do not know what is different in your code. You never posted an example.

It works fine with my code.


Or maybe you use some other font?
Those thinks can go wrong, if the font does not support them...
Title: Re: Right-to-left reading direction under Windows XP
Post by: Martin_fr on January 03, 2014, 02:55:10 pm
Arab is a script language, the letters should be connected.

Depends on the letter and the letters on iether side if any. Some connect some dont. Sorry if you meant something different.
Well yes, I was not very exact. As I pointed out my knowledge is from observation, rather than from knowledge.

And well, I did not know, though I could have guessed. But thanks for pointing it out.

What I tried to point out was the difference in his last picture. The effect that happens if you print each letter on its own, rather than printing whole words or sentences.


Title: Re: Right-to-left reading direction under Windows XP
Post by: Ocye on January 03, 2014, 03:02:51 pm
So the point is, I do not know what is different in your code. You never posted an example.

It works fine with my code.

Or maybe you use some other font?
Those thinks can go wrong, if the font does not support them...

Code is attached to the second posting. Font was default (Sans?) and is now Tahoma. I don't care too much if the % is on the left or right, but if one system flips the text and the others not somethings apparently goes wrong. I'm running XP in a virtualbox but double-checked it once with an old notebook.
FPC is 2.6.2 with LCL from svn.
Title: Re: Right-to-left reading direction under Windows XP
Post by: Martin_fr on January 03, 2014, 03:27:48 pm
Sorry, I missed that. I tested that now.

It works fine on my XP.

Except: If I switch the label's font to "times new roman" then lazarus on xp hangs. while it works on vista.

So it seems there is some code going wrong.

I'd say it is worth a bug report. Though with no guaranteed method to  reproduce, it will be hard to track.
Title: Re: Right-to-left reading direction under Windows XP
Post by: Martin_fr on January 03, 2014, 03:34:52 pm
OK single stepping, shows that the string is converted to utf16, and handed to the windows API...

try this.

uses windows;

var
  w: WideString;

    W := UTF8ToUTF16(yourtext);
    Result := Windows.ExtTextOutW(form.canvas.handle, X, Y, Options, LPRECT(Rect), PWideChar(W), Length(W), Dx);


Or the same with DrawText.

If that screws up, then it points to an issue in XP. Though something must be triggering it, because my XP does better.


----------
Maybe I did install the support at some time (I do not remember)
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/int_pr_install_complex_languages.mspx?mfr=true

-- EDIT: I just checked: I have them installed
Title: Re: Right-to-left reading direction under Windows XP
Post by: engkin on January 03, 2014, 04:14:31 pm
Control Panel
   - Regional and Language Options
      - Languages tab
         - Install files for complex script and right-to-left languages

Make sure to put a check mark next to that option.
Title: Re: Right-to-left reading direction under Windows XP
Post by: Ocye on January 03, 2014, 07:50:49 pm
Quote
Pass ETO_RTLREADING = 128 in the options parameter of ExtTextOut.
Nothing changes with 128.
Plus I completely removed Lazarus and built it new. Same result.

Quote
try...ExtTextOutW
ExtTextOutW does not paint successfully (-1), either with i:=0 or nil as parameter 7, with or without ETO_RTLREADING. How should I use DrawText() with widestring?

Code: [Select]
uses ...lclintf, lcltype, lclproc, windows;
var
  s: string;
  w: WideString;
  R: TRect;
  ts:TTextStyle;
  i:integer;
begin
  s := '% ,خطأ نسبي';
  W := UTF8ToUTF16(s);
  R := Bounds(10, 10, 200, 40);
  i:=0;
  Caption:=BoolToStr(Windows.ExtTextOutW(form1.canvas.handle, 1, 1,  ETO_RTLREADING, @r, PWideChar(W), Length(W), @i));

Quote
...files for complex script and right-to-left languages
This feature requires the original CD which I don't find anymore.
Title: Re: Right-to-left reading direction under Windows XP
Post by: engkin on January 03, 2014, 08:28:54 pm
Quote
...files for complex script and right-to-left languages
This feature requires the original CD which I don't find anymore.
I am sure that is the real problem.
Title: Re: Right-to-left reading direction under Windows XP
Post by: Martin_fr on January 03, 2014, 08:43:05 pm
Well without that feature it will not work. (that is to the best of my knowledge)
Title: Re: Right-to-left reading direction under Windows XP
Post by: engkin on January 03, 2014, 09:07:00 pm
I agree with Martin.

Quote
ExtTextOutW does not paint successfully (-1), either with i:=0 or nil as parameter 7, with or without ETO_RTLREADING.
If you are not using clipping ETO_CLIPPED you don't need the fifth parameter, pass nil for it. If you leave the spacing between letters to default values then also pass nil for the last parameter. Provide the address of the first letter in your WideString variable @w[1],
Code: [Select]
procedure TForm1.Button1Click(Sender: TObject);
var
  s: String;
  w: WideString;
begin
  s := 'ABCDEF % ,خطأ نسبي';
  w := UTF8ToUTF16(s);
  Windows.ExtTextOutW(Canvas.Handle {dc}, 1 {x}, 1 {y}, 0{ETO_RTLREADING} {options}, nil {pRect}, @w[1] {pWideChar}, Length(w) {count}, nil {lpDx});
end;

Edit:
Are you aware of/familiar with Uniscribe (http://en.wikipedia.org/wiki/Uniscribe)?
Title: Re: Right-to-left reading direction under Windows XP
Post by: Ocye on January 04, 2014, 11:31:34 am
I am sure that is the real problem.
And you are right. With this feature all letters are nicely connected.

Are you aware of/familiar with Uniscribe (http://en.wikipedia.org/wiki/Uniscribe)?
Now I am. I love my Linux :-)

Many thanks to you both. Not only my problem is solved but as well I read Arab a little bit better.