View Issue Details

IDProjectCategoryView StatusLast Update
0038531LazarusPackagespublic2021-02-23 17:02
Reporterserbod Assigned To 
PrioritynormalSeverityminorReproducibilityhave not tried
Status newResolutionopen 
Product Version2.1 (SVN) 
Summary0038531: RTL (right-to-left) support for IpHtml
DescriptionSupplied path provide RTL (right-to-left) reading support for IpHtml component
TagsNo tags attached.
Fixed in Revision
LazTarget
Widgetset
Attached Files

Activities

serbod

2021-02-22 14:54

reporter  

ipro.patch (4,004 bytes)   
--- iphtml.pas	Mon Feb 22 17:25:05 2021
+++ iphtml.pas	Mon Feb 22 17:42:53 2021
@@ -355,6 +355,7 @@
     property Props : TIpHtmlProps read FProps;
   end;
 
+  TIpHtmlDirection = (hdLTR, hdRTL);
   { TIpHtmlNodeCore }
 
   TIpHtmlNodeCore = class(TIpHtmlNodeMulti)
@@ -369,6 +370,7 @@
     FTitle: string;
     FId: string;
     FAreaList: TFPList;
+    FDir: TIpHtmlDirection;
   protected
     procedure AddArea(const R: TRect);
     procedure BuildAreaList; virtual;
@@ -392,6 +394,7 @@
     property Id : string read FId write SetId;
     property Style : string read FStyle write FStyle;
     property Title : string read FTitle write FTitle;
+    property Dir : TIpHtmlDirection read FDir write FDir;
   end;
 
   TIpHtmlNodeInline = class(TIpHtmlNodeCore)
@@ -502,17 +505,14 @@
     property TextColor : TColor read FTextColor write SetTextColor;
   end;
 
-  TIpHtmlDirection = (hdLTR, hdRTL);
   TIpHtmlNodeHEAD = class(TIpHtmlNodeMulti)
   private
     FProfile: string;
     FLang: string;
-    FDir: TIpHtmlDirection;
   public
   {$IFDEF HTML_RTTI}
   published
   {$ENDIF}
-    property Dir : TIpHtmlDirection read FDir write FDir;
     property Lang : string read FLang write FLang;
     property Profile : string read FProfile write FProfile;
   end;
@@ -2031,7 +2031,7 @@
     function NewElement(EType : TElementType; Own: TIpHtmlNode) : PIpHtmlElement;
     function BuildStandardEntry(EType: TElementType): PIpHtmlElement;
     function BuildLinefeedEntry(EType: TElementType; AHeight: Integer): PIpHtmlElement;
-    function ParseDir: TIpHtmlDirection;
+    function ParseDir(ADefault: TIpHtmlDirection = hdLTR): TIpHtmlDirection;
     procedure ParseSPAN(Parent: TIpHtmlNode; const EndTokens: TIpHtmlTokenSet);
     procedure ParseQ(Parent: TIpHtmlNode; const EndTokens: TIpHtmlTokenSet);
     procedure ParseINS(Parent: TIpHtmlNode; const EndTokens: TIpHtmlTokenSet);
@@ -7365,13 +7365,16 @@
   end;
 end;
 
-function TIpHtml.ParseDir : TIpHtmlDirection;
+function TIpHtml.ParseDir(ADefault: TIpHtmlDirection): TIpHtmlDirection;
 var
   S : string;
 begin
-  Result := hdLTR;
+  Result := ADefault;
   S := UpperCase(FindAttribute(htmlAttrDIR));
-  if (length(S) = 0) or (S = 'LTR') then
+  if (length(S) = 0) then
+  else
+  if (S = 'LTR') then
+    Result := hdLTR
   else
   if (S = 'RTL') then
     Result := hdRTL
@@ -12388,6 +12391,10 @@
     ClassId := FindAttribute(htmlAttrCLASS);
     Title := FindAttribute(htmlAttrTITLE);
     Style := FindAttribute(htmlAttrSTYLE);
+    if ParentNode is TIpHtmlNodeCore then
+      Dir := ParseDir((ParentNode as TIpHtmlNodeCore).Dir)
+    else
+      Dir := ParseDir();
   end;
   if Style <> '' then
   begin
--- iphtmlblocklayout.pas	Tue Jan 26 16:07:05 2021
+++ iphtmlblocklayout.pas	Mon Feb 22 17:37:28 2021
@@ -445,6 +445,11 @@
         Dec(WMod);
       end else
         OffsetRect(R, dx + WDelta, 0);
+      { mirroring for RTL reading }
+      if FOwner.Dir = hdRTL then
+      begin
+        R.SetLocation(FPageRect.Right - R.Right + FPageRect.Left, R.Top);
+      end;
       SetWordRect(CurElem, R);
     end else
       SetWordRect(CurElem, NullRect);
--- iphtmltablelayout.pas	Tue Dec  8 09:58:22 2020
+++ iphtmltablelayout.pas	Mon Feb 22 17:37:45 2021
@@ -588,6 +588,17 @@
                     FRowSp[CurCol] := CellNode.RowSpan - 1;
                     Inc(CurCol);
                   end;
+
+                  { mirroring for RTL reading }
+                  if FOwner.Dir = hdRTL then
+                  begin
+                    CellNode.Dir := hdRTL;
+                    CellRect1 := CellNode.PadRect;
+                    CellRect1.SetLocation(FTableWidth - CellRect1.Right, CellRect1.Top);
+                    CellNode.PadRect := CellRect1;
+                    CellNode.Layouter.Layout(RenderProps, CellRect1);
+                  end;
+
                 end;
 
               maxYY := 0;
ipro.patch (4,004 bytes)   

serbod

2021-02-22 14:56

reporter   ~0129103

Example of LHelp for Hebrew pages

Juha Manninen

2021-02-23 07:37

developer   ~0129115

Do you have a link to a CHM file with RTL text?
I want to test the patch.

serbod

2021-02-23 08:09

reporter   ~0129116

Sample .chm file on Hebrew
he-IL.chm (349,689 bytes)

wp

2021-02-23 08:53

developer   ~0129117

Last edited: 2021-02-23 08:57

View 2 revisions

I think it is misleading and a latent issue when the property controlling RTL is named "Dir". Why not use the BiDiMode inherited from TControl? Or override the inherited UseRightToLeftReading? I guess ignoring these inherited properties causes issues in integration of the IpHTMLPanel into the TControl BiDiMode handling

serbod

2021-02-23 09:28

reporter   ~0129118

Global 'dir' attribute can be used with any HTML element. It allows reverse read direction for arbitrary elements. But it's not part of style.

TIpHtmlNode (abstract base node) derived from TPersistent, and does not contain any BiDiMode property.

BiDiMode property of TIpHtmlPanel can be used as default value for 'dir' attribute. But it will be overriden in HTML, if there will be any 'dir' attribute specified.

wp

2021-02-23 15:28

developer   ~0129124

Last edited: 2021-02-23 17:02

View 2 revisions

I did not know that "dir" is the name of the official html attribute for RTL in the content (https://www.w3.org/International/questions/qa-html-dir).

I do not live in an RTL country, so I only know that when BiDiMode of a form is set to right-to-left everything is flipped, even the Left value of a rectangle. So, when I set BiDiMode of the IpHtmlPanel to RTL will it flip the contents? I don't think so because neither before nor after your modification BiDi is mentioned. I do understand now that the TIpHtmlDirection is coming from the document/style, but I am lacking the connection to the BiDi architecture inherited from TControl. If we touch BiDi in this report we would should make it correctly, and you seem to be originated in an RTL country and have the knowledge to bring it all together.

Issue History

Date Modified Username Field Change
2021-02-22 14:54 serbod New Issue
2021-02-22 14:54 serbod File Added: ipro.patch
2021-02-22 14:56 serbod Note Added: 0129103
2021-02-22 14:56 serbod File Added: изображение_2021-02-22_175535.png
2021-02-23 07:37 Juha Manninen Note Added: 0129115
2021-02-23 08:09 serbod Note Added: 0129116
2021-02-23 08:09 serbod File Added: he-IL.chm
2021-02-23 08:53 wp Note Added: 0129117
2021-02-23 08:57 wp Note Edited: 0129117 View Revisions
2021-02-23 09:28 serbod Note Added: 0129118
2021-02-23 15:28 wp Note Added: 0129124
2021-02-23 17:02 wp Note Edited: 0129124 View Revisions