I'm trying to learn how to use TTextLayout object to add some special characters to my graphic drawings. Unfortunately this object seems having some special behaviours that seem not documented in Delphi help docs and on Embarcadero online docs. I have derived the following code from the Delphi code examples adding some features that I need to use. Teese features are the usage of TextWidth and TextHeight to obtain the width and height of the characters to be drawn. For convenience I have replaced the font I'm using with the Arial font. I have added some buttons to enlarge/reduce the size of the character, and some other buttons to choose different characters. Well, when the character changes, and when the size changes, nothing seems to change in width and height of the TTextLayout object. The values of width and height of the object seem remain the same. I have tried whatever came to my mind, putting before or after each single statement, but nothing. The Width and Height of the TTextLayout seem remain the same. What I'm doing wrong? What is it that I'm not understanding correctly? Thankyou for your kind help, as usual.
unit MainGraphicText;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.StdCtrls, FMX.Controls.Presentation, FMX.Objects,FMX.TextLayout, FMX.Edit;
type
TMainFormGraphicText = class(TForm)
Image1: TImage;
Width: TEdit;
Height: TEdit;
DimLess: TButton;
Label1: TLabel;
DimMore: TButton;
Label2: TLabel;
ShowDim: TEdit;
ShowChar: TEdit;
CharLess: TButton;
CharMore: TButton;
procedure FormCreate(Sender: TObject);
procedure Image1Paint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
procedure DimLessClick(Sender: TObject);
procedure DimMoreClick(Sender: TObject);
procedure CharLessClick(Sender: TObject);
procedure CharMoreClick(Sender: TObject);
private
{ Private declarations }
public
WhichChar : Integer;
Dimension : Single;
MyRect : TRectF;
end;
var
MainFormGraphicText: TMainFormGraphicText;
implementation
{$R *.fmx}
procedure TMainFormGraphicText.CharMoreClick(Sender: TObject);
begin
WhichChar := WhichChar + 1;
if WhichChar > 80 then
WhichChar := 80;
ShowChar.Text := WhichChar.ToString;
Image1.Repaint;
end;
procedure TMainFormGraphicText.CharLessClick(Sender: TObject);
begin
WhichChar := WhichChar - 1;
if WhichChar < 1 then
WhichChar := 1;
ShowChar.Text := WhichChar.ToString;
Image1.Repaint;
end;
procedure TMainFormGraphicText.DimLessClick(Sender: TObject);
begin
Dimension := Dimension - 1;
if Dimension < 9 then
Dimension := 9;
ShowDim.Text := Dimension.ToString;
Image1.Repaint;
end;
procedure TMainFormGraphicText.DimMoreClick(Sender: TObject);
begin
Dimension := Dimension + 1;
if Dimension > 72 then
Dimension := 72;
ShowDim.Text := Dimension.ToString;
Image1.Repaint;
end;
procedure TMainFormGraphicText.FormCreate(Sender: TObject);
begin
WhichChar := 40;
Dimension := 48;
MyRect := TRect.Create(TPoint.Create(0, 0),Trunc(Image1.Width),Trunc(Image1.Height));
Canvas.BeginScene;
Canvas.Stroke.Kind := TBrushKind.Solid;
Canvas.Stroke.Color := TAlphaColorRec.Black;
Canvas.Stroke.Thickness := 1.0;
Canvas.DrawRect(MyRect,1);
Canvas.EndScene;
end;
procedure TMainFormGraphicText.Image1Paint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
Const Acapo = '#13#10';
var
WPosition: Integer;
W,H : Single;
MyLayout: TTextLayout;
begin
Canvas.BeginScene;
Canvas.Stroke.Kind := TBrushKind.Solid;
Canvas.Stroke.Color := TAlphaColorRec.Black;
Canvas.Stroke.Thickness := 1.0;
Canvas.DrawRect(MyRect,1);
Canvas.EndScene;
MyLayout := TTextLayoutManager.DefaultTextLayout.Create;
MyLayout.BeginUpdate;
MyLayout.TopLeft := TPointF.Create(0, 0);
MyLayout.Font.Family := 'Arial'; // 'Delfos2';
MyLayout.Font.Size := Dimension;
MyLayout.Font.Style := [];
MyLayout.Trimming := TTextTrimming.Character;
MyLayout.Text := chr(63 + WhichChar); // Copy(Aspetti_Delfos2,WhichChar,1);
MyLayout.Color := TAlphaColorRec.Brown;
ShowDim.Text := MyLayout.Font.Size.ToString;
ShowChar.Text := WhichChar.ToString;
WPosition := MyLayout.PositionAtPoint(TPointF.Create(0, 0));
Width.Text := MyLayout.TextWidth.ToString;
Height.Text := MyLayout.TextHeight.ToString;
MyLayout.EndUpdate;
MyLayout.RenderLayout(Canvas);
MyLayout.Free;
end;
end.
@SilverWarrior: I have tried the modifications you have proposed, but it seems they're not working at all. Particularly, I tried what follows:
MyLayout.EndUpdate;
MyLayout.RenderLayout(Canvas);
Width.Text := MyLayout.TextWidth.ToString;
Height.Text := MyLayout.TextHeight.ToString;
Logics say that only after the rendition of MyLayout the object knows the data of the changed text, but it is not. The data inside the two TEdit shows the same value than before.
The fact of seeing updates only in case of INVALIDATION made me think. What if the problem was limited only to updating the video fields but the true dimension values were updated correctly? I added saving the dimensional values in memory and highlighted them when exiting the program to see if that was true and it is. The various text dimension values are updated. Only the value in TEdit fields is not. To update these values you need to call INVALIDATE, but not to know the true value of the TTextLayout dimensions, which are updated correctly.