Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2023-02

Canvas.TextRec aligns to canvas and not rectangle for tlTop and taLeftJustify.

4 messages · 4 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Russ

Hi,

When writing text to the canvas using Canvas.TextRec(), using layout tlTop and/or alignment? taLeftJustify, the text is aligned to the canvas left and top edges instead of those edges of the text rectangle. The other layout and alignment cases work correctly.

The sample code below illustrates this for all 9 possible combinations of layout and alignment.

Changing lines 1302 and 1304 of canvas.inc fixes this problem:
 ?? 1302:?? fRect.Left := X; --> fRect.Left := fRect.Left + X;
 ?? 1304:?? fRect.Top := Y;? --> fRect.Top := fRect.Top + Y;

canvas.inc in Lazarus 2.2.4 and trunk are the same.

Regards
Russ

<code>
 ?? unit Unit1;

?? {$mode objfpc}{$H+}

?? interface

 ?? uses
 ???? Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
 ?? type
 ???? TForm1 = class(TForm)
 ?????? procedure FormCreate(Sender: TObject);
 ?????? procedure FormPaint(Sender: TObject);
 ???? end;
 ?? var
 ???? Form1: TForm1;

?? implementation

?? {$R *.lfm}

 ?? procedure TForm1.FormCreate(Sender: TObject);
 ?? begin
 ???? Width := 300;
 ???? Height := 300;
 ???? Position := poDesktopCenter;
 ?? end;
 ?? procedure TForm1.FormPaint(Sender: TObject);
 ?? const
 ???? Txt ='%s'+LineEnding+'%s';
 ???? Spacing = 75;
 ???? LeftMargin = 50;
 ???? TopMargin = 50;
 ???? VAlign: array[0..2] of TTextLayout = (tlTop, tlCenter, tlBottom);
 ???? HAlign: array[0..2] of TAlignment = (taLeftJustify, taCenter,
taRightJustify);
 ?? var
 ???? TxtRect: TRect;??? // Rectangle used for text.
 ???? Outline: TRect;??? // Enclosing outline rectangle.
 ???? TxtStyle: TTextStyle;
 ???? Col, Row: integer;
 ???? X, Y: Integer;
 ???? VStr, HStr: string;
 ?? begin
 ???? TxtStyle := Default(TTextStyle);
 ???? TxtStyle.Wordbreak := true;
 ???? TxtStyle.SystemFont := true;
 ???? TxtRect := TRect.Create(0, 0, 55, 50);
 ???? Outline := TRect.Create(0, 0, 59, 52);
 ???? for Row := 0 to 2 do begin
 ?????? TxtStyle.Layout := VAlign[Row];
 ?????? WriteStr(VStr, VAlign[Row]);
 ?????? VStr := VStr.Replace('tl', '');
 ?????? Y := TopMargin + Row * Spacing;
 ?????? for Col := 0 to 2 do begin
 ???????? WriteStr(HStr, HAlign[Col]);
 ???????? HStr := HStr.Replace('Justify','').Replace('ta','');
 ???????? X := LeftMargin + Col * Spacing;
 ???????? Outline.SetLocation(X, Y);
 ???????? TxtRect.SetLocation(X, Y);
 ???????? TxtStyle.Alignment := HAlign[Col];
 ???????? Canvas.Rectangle(Outline);
 ???????? Canvas.TextRect(TxtRect, 2, 2, Txt.Format(Txt, [VStr, HStr]),
TxtStyle);
 ?????? end;
 ???? end;
 ?? end;

?? end.
</code>
<form>
?? object Form1: TForm1
???? Left = 728
???? Height = 529
???? Top = 176
???? Width = 545
???? Caption = 'Form1'
???? OnCreate = FormCreate
???? OnPaint = FormPaint
???? LCLVersion = '2.2.4.0'
?? end
</form>

Reply by email

John Landmesser
to Russ

Hi,

add information about lazarus and fpc Version plus OS you are running.

Thats a bugreport? and should be written to
https://gitlab.com/freepascal.org/

I confirm this bug for

Lazarus 2.3.0 (rev main-2_3-2854-g0278edaea3) FPC 3.2.2 x86_64-linux-gtk2

see:

https://i.imgur.com/oJw7tzf.png

regards

John Landmesser

Russ wrote 107 lines
Hi, When writing text to the canvas using Canvas.TextRec(), using layout tlTop and/or alignment? taLeftJustify, the text is aligned to the canvas left and top edges instead of those edges of the text rectangle. The other layout and alignment cases work correctly. The sample code below illustrates this for all 9 possible combinations of layout and alignment. Changing lines 1302 and 1304 of canvas.inc fixes this problem: ?? 1302:?? fRect.Left := X; --> fRect.Left := fRect.Left + X; ?? 1304:?? fRect.Top := Y;? --> fRect.Top := fRect.Top + Y; canvas.inc in Lazarus 2.2.4 and trunk are the same. Regards Russ <code> ?? unit Unit1; ?? {$mode objfpc}{$H+} ?? interface ?? uses ???? Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls; ?? type ???? TForm1 = class(TForm) ?????? procedure FormCreate(Sender: TObject); ?????? procedure FormPaint(Sender: TObject); ???? end; ?? var ???? Form1: TForm1; ?? implementation ?? {$R *.lfm} ?? procedure TForm1.FormCreate(Sender: TObject); ?? begin ???? Width := 300; ???? Height := 300; ???? Position := poDesktopCenter; ?? end; ?? procedure TForm1.FormPaint(Sender: TObject); ?? const ???? Txt ='%s'+LineEnding+'%s'; ???? Spacing = 75; ???? LeftMargin = 50; ???? TopMargin = 50; ???? VAlign: array[0..2] of TTextLayout = (tlTop, tlCenter, tlBottom); ???? HAlign: array[0..2] of TAlignment = (taLeftJustify, taCenter, taRightJustify); ?? var ???? TxtRect: TRect;??? // Rectangle used for text. ???? Outline: TRect;??? // Enclosing outline rectangle. ???? TxtStyle: TTextStyle; ???? Col, Row: integer; ???? X, Y: Integer; ???? VStr, HStr: string; ?? begin ???? TxtStyle := Default(TTextStyle); ???? TxtStyle.Wordbreak := true; ???? TxtStyle.SystemFont := true; ???? TxtRect := TRect.Create(0, 0, 55, 50); ???? Outline := TRect.Create(0, 0, 59, 52); ???? for Row := 0 to 2 do begin ?????? TxtStyle.Layout := VAlign[Row]; ?????? WriteStr(VStr, VAlign[Row]); ?????? VStr := VStr.Replace('tl', ''); ?????? Y := TopMargin + Row * Spacing; ?????? for Col := 0 to 2 do begin ???????? WriteStr(HStr, HAlign[Col]); ???????? HStr := HStr.Replace('Justify','').Replace('ta',''); ???????? X := LeftMargin + Col * Spacing; ???????? Outline.SetLocation(X, Y); ???????? TxtRect.SetLocation(X, Y); ???????? TxtStyle.Alignment := HAlign[Col]; ???????? Canvas.Rectangle(Outline); ???????? Canvas.TextRect(TxtRect, 2, 2, Txt.Format(Txt, [VStr, HStr]), TxtStyle); ?????? end; ???? end; ?? end; ?? end. </code> <form> ?? object Form1: TForm1 ???? Left = 728 ???? Height = 529 ???? Top = 176 ???? Width = 545 ???? Caption = 'Form1' ???? OnCreate = FormCreate ???? OnPaint = FormPaint ???? LCLVersion = '2.2.4.0' ?? end </form>

Reply by email

Werner Pamler
to Russ: When writing text to the canvas using Canvas.TextRec(), using layout tlTop and/or…
Russ wrote 13 lines
When writing text to the canvas using Canvas.TextRec(), using layout tlTop and/or alignment? taLeftJustify, the text is aligned to the canvas left and top edges instead of those edges of the text rectangle. The other layout and alignment cases work correctly. The sample code below illustrates this for all 9 possible combinations of layout and alignment. Changing lines 1302 and 1304 of canvas.inc fixes this problem: ?? 1302:?? fRect.Left := X; --> fRect.Left := fRect.Left + X; ?? 1304:?? fRect.Top := Y;? --> fRect.Top := fRect.Top + Y; canvas.inc in Lazarus 2.2.4 and trunk are the same.

Please don't change this - it will break numerous code.

The reported behaviour is compatible with Delphi. What do you think are the additional x,y parameters good for? Delphi (and Lazarus) interprets them as the starting point of the text in the case where Layout is tlTop and Alignment is taLeftJustify, no matter what the Rect parameter is (which is used a clipping rectangle, though). God knows why x,y are not interpreted as an offset to the positions defined by Layout/Alignment directly.

Reply by email

R.Smith
to Werner Pamler
Werner Pamler wrote
Please don't change this - it will break numerous code.

I agree with Werner, God knows why it's done that way, but it is, and changing it will surely break almost every application project I have. Please don't.

Reply by email