kosovali 0 Posted November 26, 2020 I want set "123 SAMPLE 456" to a label But displayed as : " SAMPLE 456 123" My Configuration: Language for Unicode programs : Arabic (Syria) Form BidiMode : bdRightToLeft Can you help me? Share this post Link to post
Guest Posted November 26, 2020 (edited) http://docwiki.embarcadero.com/RADStudio/Sydney/en/Including_Bi-directional_Functionality_in_Applications How should BiDi work? This table shows all the different combinations of BiDiMode with Horizontal Alignment. The table reflects the behavior of Delphi's VCL controls, and uses Delphi's terminology for BiDiMode settings. The example is given with Hebrew words and punctuation marks, in order to give a realistic demonstration of BiDi behavior. For those interested, the first phrase means "Not good...", the second means "Excellent!", and the third means "Alright;". BiDiMode H.Alignment Action Comments Example bdLeftToRight (No BiDi support) None, Left Align text to left Note that the ellipsis (...) is on the wrong side of the text. לא טוב... Center Center text לא טוב... Right Align text to right לא טוב... bdRightToLeft (Full BiDi support) None, Left Align text to right The exclamation mark (!) is on the correct side of the word. The alignment is opposite to the direction that is actually specified in H.Alignment. מצויין! Center Center text מצויין! Right Align text to left מצויין! bdRightToLeftNoAlign, bdRightToLeftReadingOnly (Partial BiDi support) None, Left Align text to left The semicolon (;) is on the correct side of the word. The alignment is as specified in H.Alignment. בסדר; Center Center text בסדר; Right Align text to right בסדר; source: https://reportman.sourceforge.io/doc/bidi_behavior.html Edited November 26, 2020 by Guest Share this post Link to post
kosovali 0 Posted November 26, 2020 H.Alignment changes does not affected. Sample output with DrawTextEx WinApi call : procedure TForm1.Button1Click(Sender: TObject); var Text:String; lpRect:TRect; uFormat:Cardinal; Options: Longint; begin Text:= '123 SAMPLE 456'; lpRect:=Rect(10,10,300,150); uFormat:= {DT_LEFT or }DT_EXPANDTABS or DT_NOPREFIX or DT_RTLREADING; DrawTextEx(Canvas.Handle, @Text[1], Length(Text), lpRect, uFormat, nil); end; Share this post Link to post
Guest Posted November 26, 2020 (edited) NOTE: my MSWindows is in Portuguese-Brazil and I dont have any other language installed Some languages do not follow the left to right reading order commonly found in Western languages, but rather use the right to left reading order for words and the left to right reading order for numbers. These languages are termed bi-directional (BiDi) because of this separation. The most common bi-directional languages are Arabic and Hebrew, although other Middle East languages are also bi-directional. The VCL supports bi-directional localization through the BiDiMode and ParentBiDiMode properties. TApplication has two properties, BiDiKeyboard and NonBiDiKeyboard, that allow you to specify the keyboard layout. implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var lX_Position: integer; begin { Specifies the bidirectional mode for the control. Use BiDiMode to enable the control to adjust its appearance and behavior automatically when the application runs in a locale that reads ... from right to left instead of left to right. The bidirectional mode controls the reading order for the text, the placement ... of the vertical scroll bar, and whether the alignment is changed. Alignment does not change for controls that are known to contain number, date, time, or currency values. For example, with data-aware controls, ... the alignment does not change for the following field types: ftSmallint, ftInteger, ftWord, ftFloat, ftCurrency, ftBCD, ftDate, ftTime, ... ftDateTime, ftAutoInc. } // ListBox1.BiDiMode := TBiDiMode.bdLeftToRight; ListBox1.BiDiMode := TBiDiMode.bdRightToLeft; // ListBox1.BiDiMode := TBiDiMode.bdRightToLeftNoAlign; // ListBox1.BiDiMode := TBiDiMode.bdRightToLeftReadingOnly; // ListBox1.Items.Add('مرحبا العالم القاسي'); ListBox1.Items.Add('هل هم بشر من أي وقت مضى؟'); // Edit1.BiDiMode := TBiDiMode.bdRightToLeft; Edit1.Text := 'مرحبا العالم القاسي'; // Edit1.Text := '123 SAMPLE 456'; // Label1.BiDiMode := Edit1.BiDiMode; Label1.Caption := Edit1.Text; // lX_Position := (Edit1.Left + Edit1.Width) - Self.Canvas.TextWidth(Edit1.Text); // Self.Canvas.Font.Orientation := -180 * 10; Self.Canvas.Font.Color := clBlue; // Self.Canvas.TextOut(lX_Position { x } , 270 { y } , Edit1.Text); // Rotation works in tenths of the angle reported, then: (Angle * 10) = your rotation // Horizontal to Right = (0 * 10) // Vertical to Down = (-90 * 10) // Horizontal to Left = (-180 * 10) // Vertical to Up = (90 * 10) end; hug Edited November 26, 2020 by Guest Share this post Link to post
Guest Posted November 26, 2020 My 2 cents on this, It is difficult to solve as it VCL is not much of help and OS is not helping too. To explain this, lets use this code to understand the problem first procedure TForm10.Button1Click(Sender: TObject); var st: string; begin st := '123 '; st := st + ' Sample '; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '123 '; st := st + 'عينة'; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '123 '; st := st + 'عينة'; st := st + ' Sample '; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '123 '; st := st + ' Sample '; st := st + 'عينة'; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); end; Here the result Now we can have a glimpse what is going wrong and where i separated building st to make sure the editors involved in copying and moving the sentences are irrelevant, this is essential. From the result, you see clearly parsing and switching between words within a string can and does change the string printing output, even within Windows components the drawing behaviour does change, i remember also GDI/+ was doing things differently, but not sure for current versions and Windows 10, and which is which, that is a thing you should test for your self, things gets more ugly and less predictable with symbols. One thing though, i love how Alexander In his HTML Delphi Components include the full parser algorithms to handle switching from RTL words and LTR in the same string, but also the it does fail in few corner cases when some char that steer the the parser in other direction like '.' or a bracket, but my DHTML is expired and old, and i don't expect any perfect algorithm to exist at all, the thing of me having the code for parsing i can change things to fir my need, as these symbols can be chars LTR ranges encapsulating RTL words, i think you are familiar with most popular case with brackets. Another thing, in the above example you used Arabic numbers "123.." they called Arabic, while the Arabic languages most likely will use Hindu numbers "٠١٢٣٤٥٦٧٨٩", and using those will greatly change the behaviour in different places lets see the different behaviour procedure TForm10.Button1Click(Sender: TObject); var st: string; begin st := '١٢٣ '; st := st + ' Sample '; st := st + ' ٤٥٦'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '١٢٣ '; st := st + 'عينة'; st := st + ' ٤٥٦'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '١٢٣ '; st := st + 'عينة'; st := st + ' Sample '; st := st + ' ٤٥٦'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '١٢٣ '; st := st + ' Sample '; st := st + 'عينة'; st := st + ' ٤٥٦'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); end; the result had changed Another thing there is special char to control such sentences called Right-to-Left Mark https://en.wikipedia.org/wiki/Right-to-left_mark You might want play and try to insert it between strings and see the effect in that page there is an example on how to add "!" at right place. That was my 2 cents, and really it depends on you understanding when the problem occur and how to find workaround, as i doubt the existence of a complete fix. Share this post Link to post
Guest Posted November 26, 2020 I found that adding RLM or ALM after words help building it right, it is not needed everywhere, but i wanted to find a simple rule to follow, procedure TForm10.Button2Click(Sender: TObject); const ALM=#$061c; RLM=#$200F; var st: string; begin st := '123 '; st := st + ' Sample '; st := st + RLM; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '123 '; st := st + 'عينة'; st := st + RLM; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '123 '; st := st + 'عينة'; st := st + RLM; st := st + ' Sample '; st := st + RLM; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); st := '123 '; st := st + ' Sample '; st := st + RLM; st := st + 'عينة'; st := st + RLM; st := st + ' 456'; Memo1.Lines.Add(st); Memo2.Lines.Add(st); end; Start there and see if you can build on that, but as i said i am trying things and don't know for sure if this is the right way to do it, if there is a way. And good luck. Share this post Link to post