Skip to content

Commit 79ce4d3

Browse files
Merge pull request #96 from digao-dalpiaz/rtl-text
Rtl text
2 parents f850969 + 3708f1e commit 79ce4d3

File tree

5 files changed

+59
-8
lines changed

5 files changed

+59
-8
lines changed

CompInstall.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ IniVersion=2
33

44
[General]
55
Name=Digao Dalpiaz - DzHTMLText component
6-
Version=6.7
6+
Version=6.8
77
DelphiVersions=XE3;XE4;XE5;XE6;XE7;XE8;10;10.1;10.2;10.3;10.4;11;12
88
Packages=DzHTMLText_VCL;DzHTMLText_FMX;DzHTMLTextDesign_VCL;DzHTMLTextDesign_FMX
99
AddLibrary=1

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
![VCL and FMX](https://img.shields.io/badge/-VCL%20and%20FMX-lightgrey.svg)
1414
![Lazarus support](https://img.shields.io/badge/-Lazarus%20support-green.svg)
1515
![CJK line break](https://img.shields.io/badge/-Chinese+Japanese+Korean%20line%20break%20support-yellowgreen.svg)
16+
![RTL notation](https://img.shields.io/badge/-RTL%20notation-purple.svg)
1617

1718
[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/C0C53LVFN)
1819

@@ -38,13 +39,18 @@
3839

3940
## What's New
4041

41-
- 01/26/2025 (Version 6.7)
42+
- 03/15/2025 (Version 6.8)
4243

43-
- Fixed Lazarus compiling (GDI+ units)
44+
- Right-to-left (RTL) text supporting.
45+
- When using a Div without "keep properties" (default), now Horizontal Text Alignment get the same value as component pre-defined Horizontal Alignment.
4446

4547
<details>
4648
<summary>Click here to view the entire changelog</summary>
4749

50+
- 01/26/2025 (Version 6.7)
51+
52+
- Fixed Lazarus compiling (GDI+ units)
53+
4854
- 11/14/2024 (Version 6.6)
4955

5056
- Use GDI painting from Windows API when using VCL + Windows to draw rounded div
@@ -559,6 +565,8 @@ If you are using AutoWidth, the text never wraps to a new line unless a line bre
559565
560566
`ParagraphSpacing: TPixels` = Specify the default paragraph spacing in overall text. The paragraph spacing is added to original line spacing. You can use `<LS>` tag to determine paragraph spacing at specific lines.
561567
568+
`RightToLeftText: Boolean` = Enables Right-to-left text notation.
569+
562570
`StyleLinkNormal: TDHStyleLinkProp` = Properties to format a link when is not selected by mouse.
563571
564572
`StyleLinkHover: TDHStyleLinkProp` = Properties to format a link when is selected by mouse.

Source/Vcl.DHCommon.pas

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ TDHCharUtils = class
4040
private
4141
class function IsCJKChar(const C: Char): Boolean; inline;
4242
public
43+
class function IsPunctuationChar(const C: Char): Boolean;
4344
class function FindNextWordBreakChar(const A: string; From: Integer): Integer; inline;
4445
end;
4546

@@ -130,13 +131,29 @@ class function TDHCharUtils.FindNextWordBreakChar(const A: string; From: Integer
130131
begin
131132
C := A[I];
132133

133-
if CharInSet(C, [STR_SPACE,'<','>','/','\',#13,#10]) or IsCJKChar(C) then
134+
if CharInSet(C, [STR_SPACE,'<','>','/','\',#13,#10]) or IsPunctuationChar(C) or IsCJKChar(C) then
134135
Exit(I);
135136
end;
136137

137138
Result := 0;
138139
end;
139140

141+
class function TDHCharUtils.IsPunctuationChar(const C: Char): Boolean;
142+
143+
function IsArabic: Boolean;
144+
begin
145+
Result := False;
146+
case Integer(C) of
147+
$060C, //comma
148+
$061B //semicolon
149+
: Result := True;
150+
end;
151+
end;
152+
153+
begin
154+
Result := CharInSet(C, ['?','.',':',',',';','!']) or IsArabic;
155+
end;
156+
140157
class function TDHCharUtils.IsCJKChar(const C: Char): Boolean; //return if char is Chinese-Japanese-Korean
141158
begin
142159
//East Asian languages break lines in all chars, so each char must be considered as a full word.

Source/Vcl.DHTokenEngine.pas

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ TDHBuilder = class
480480
procedure ProcessSpecificObjects(List: TDHPreVisualItemList);
481481

482482
procedure CheckMissingClosingTags;
483+
function GetDefaultHorzTextAlign: TDHHorzAlign;
483484
public
484485
constructor Create(Lb: TDzHTMLText; Canvas: TCanvas;
485486
VisualItems: TDHVisualItemList; ProcBoundsAndLines: TDHProcBoundsAndLines);
@@ -1422,7 +1423,7 @@ procedure TDHToken_Div.Process;
14221423
Props.Offset.Top := 0;
14231424
Props.Offset.Bottom := 0;
14241425
Props.BackColor := clNone;
1425-
Props.HorzAlign := haLeft;
1426+
Props.HorzAlign := Builder.GetDefaultHorzTextAlign;
14261427
Props.VertAlign := vaTop;
14271428
Props.LineSpace := 0;
14281429
Props.ParagraphSpace := 0;
@@ -1677,7 +1678,7 @@ constructor TDHBuilder.Create(Lb: TDzHTMLText; Canvas: TCanvas;
16771678
Props.Offset.Bottom := Lb.CalcScale(Lb.Offset.Bottom);
16781679

16791680
Props.VertAlign := Lb.LineVertAlign;
1680-
Props.HorzAlign := Lb.LineHorzAlign;
1681+
Props.HorzAlign := GetDefaultHorzTextAlign;
16811682

16821683
Props.LineSpace := Lb.CalcScale(Lb.LineSpacing);
16831684
Props.ParagraphSpace := Lb.CalcScale(Lb.ParagraphSpacing);
@@ -1753,6 +1754,12 @@ procedure TDHBuilder.CheckMissingClosingTags;
17531754
end;
17541755
end;
17551756

1757+
function TDHBuilder.GetDefaultHorzTextAlign: TDHHorzAlign;
1758+
begin
1759+
Result := Lb.LineHorzAlign;
1760+
if Lb.RightToLeftText and (Result = haLeft) then Result := haRight;
1761+
end;
1762+
17561763
procedure TDHBuilder.AddInvalidToken(Position: Integer; const ErrorDescription: string);
17571764
var
17581765
Token: TDHToken_Word;
@@ -1829,7 +1836,7 @@ procedure TDHBuilder.ReadTokens;
18291836
with AddToken<TDHToken_Word> do
18301837
begin
18311838
Word := TDzHTMLText.UnescapeHTMLToText(Copy(Text, CurPos, I-CurPos));
1832-
Breakable := BreakableChar;
1839+
Breakable := BreakableChar and not TDHCharUtils.IsPunctuationChar(CharIni);
18331840
end;
18341841

18351842
CurPos := I;
@@ -2282,6 +2289,9 @@ TFuncAlignResult = record
22822289
end;
22832290

22842291
begin
2292+
if Lb.RightToLeftText then
2293+
Item.Position.X := Line.TextSize.Width - (Item.Position.X + Item.Size.Width);
2294+
22852295
Check(0, True, Item.HorzAlign);
22862296
Check(1, False, Item.VertAlign);
22872297

Source/Vcl.DzHTMLText.pas

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,8 @@ TDzHTMLText = class(
377377

378378
FCursor: TCursor;
379379

380+
FRightToLeftText: Boolean;
381+
380382
UpdatingSemaphore: Integer;
381383
InternalResizing: Boolean;
382384

@@ -435,6 +437,8 @@ TDzHTMLText = class(
435437
procedure SetParagraphIndent(const Value: TPixels);
436438
procedure SetCustomStyles(const Value: TDHCustomStyles);
437439

440+
procedure SetRightToLeftText(const Value: Boolean);
441+
438442
{$IFDEF USE_IMGLST}
439443
procedure SetImages(const Value: TCustomImageList);
440444
{$ENDIF}
@@ -644,6 +648,8 @@ TDzHTMLText = class(
644648
property ParagraphSpacing: TPixels read FParagraphSpacing write SetParagraphSpacing {$IFDEF VCL}default 0{$ENDIF};
645649
property ParagraphIndent: TPixels read FParagraphIndent write SetParagraphIndent {$IFDEF VCL}default 0{$ENDIF};
646650

651+
property RightToLeftText: Boolean read FRightToLeftText write SetRightToLeftText default False;
652+
647653
property About: string read FAbout;
648654
end;
649655

@@ -685,7 +691,7 @@ implementation
685691
, Winapi.GDIPOBJ, Winapi.GDIPAPI
686692
{$ENDIF};
687693

688-
const STR_VERSION = '6.7';
694+
const STR_VERSION = '6.8';
689695

690696
const DEFAULT_PPI = 96;
691697

@@ -1089,6 +1095,16 @@ procedure TDzHTMLText.SetParagraphIndent(const Value: TPixels);
10891095
end;
10901096
end;
10911097

1098+
procedure TDzHTMLText.SetRightToLeftText(const Value: Boolean);
1099+
begin
1100+
if Value<>FRightToLeftText then
1101+
begin
1102+
FRightToLeftText := Value;
1103+
1104+
BuildAndPaint;
1105+
end;
1106+
end;
1107+
10921108
procedure TDzHTMLText.SetListLevelPadding(const Value: TPixels);
10931109
begin
10941110
if Value<>FListLevelPadding then

0 commit comments

Comments
 (0)