Is it a bug ? TextWidth('Hello') + TextWidth('World') TextWidth('HelloWorld');
Is it a bug ? TextWidth('Hello') + TextWidth('World') <> TextWidth('HelloWorld');
in a FMX application under Windows with an Italic font
procedure TForm1.FormPaint(Sender: TObject; Canvas: TCanvas;
const ARect: TRectF);
var
TextLayout: TTextLayout;
w1, w2, w3: Single;
begin
TextLayout := TTextLayoutManager.DefaultTextLayout.Create(Canvas);
TextLayout.Font.Family := 'Arial';
TextLayout.Font.Style := [TFontStyle.fsItalic];
TextLayout.Text := 'Hello';
w1 := TextLayout.TextWidth;
TextLayout.Text := 'World';
w2 := TextLayout.TextWidth;
TextLayout.Text := 'HelloWorld';
w3 := TextLayout.TextWidth;
TextLayout.Free;
Memo1.Lines.Add('TextWidth(Hello) = ' + FloatToStrF(w1, TFloatFormat.ffFixed, 15, 2));
Memo1.Lines.Add('TextWidth(World) = ' + FloatToStrF(w2, TFloatFormat.ffFixed, 15, 2));
Memo1.Lines.Add('TextWidth(HelloWord) = ' + FloatToStrF(w3, TFloatFormat.ffFixed, 15, 2));
Memo1.Lines.Add('TextWidth(Hello) + TextWidth(Word) = ' + FloatToStrF(w1 + w2, TFloatFormat.ffFixed, 15, 2));
{
TextWidth(Hello) = 29,06
TextWidth(World) = 33,17
TextWidth(HelloWord) = 60,52
TextWidth(Hello) + TextWidth(Word) = 62,23
}
end;
in a FMX application under Windows with an Italic font
procedure TForm1.FormPaint(Sender: TObject; Canvas: TCanvas;
const ARect: TRectF);
var
TextLayout: TTextLayout;
w1, w2, w3: Single;
begin
TextLayout := TTextLayoutManager.DefaultTextLayout.Create(Canvas);
TextLayout.Font.Family := 'Arial';
TextLayout.Font.Style := [TFontStyle.fsItalic];
TextLayout.Text := 'Hello';
w1 := TextLayout.TextWidth;
TextLayout.Text := 'World';
w2 := TextLayout.TextWidth;
TextLayout.Text := 'HelloWorld';
w3 := TextLayout.TextWidth;
TextLayout.Free;
Memo1.Lines.Add('TextWidth(Hello) = ' + FloatToStrF(w1, TFloatFormat.ffFixed, 15, 2));
Memo1.Lines.Add('TextWidth(World) = ' + FloatToStrF(w2, TFloatFormat.ffFixed, 15, 2));
Memo1.Lines.Add('TextWidth(HelloWord) = ' + FloatToStrF(w3, TFloatFormat.ffFixed, 15, 2));
Memo1.Lines.Add('TextWidth(Hello) + TextWidth(Word) = ' + FloatToStrF(w1 + w2, TFloatFormat.ffFixed, 15, 2));
{
TextWidth(Hello) = 29,06
TextWidth(World) = 33,17
TextWidth(HelloWord) = 60,52
TextWidth(Hello) + TextWidth(Word) = 62,23
}
end;
is the W overlapping the o? Than the calculation is correct. Give it a Try with LOL and OLO to see what happens
ReplyDeleteunder VCL I don't have this problem
ReplyDeleteprocedure TForm2.FormPaint(Sender: TObject);
var
w1, w2, w3: Integer;
begin
Canvas.Font.Name := 'Arial';
Canvas.Font.Style := [fsItalic];
w1 := Canvas.TextWidth('Hello');
w2 := Canvas.TextWidth('World');
w3 := Canvas.TextWidth('HelloWorld');
Memo1.Lines.Add('TextWidth(Hello) = ' + IntToStr(w1));
Memo1.Lines.Add('TextWidth(World) = ' + IntToStr(w2));
Memo1.Lines.Add('TextWidth(HelloWord) = ' + IntToStr(w3));
Memo1.Lines.Add('TextWidth(Hello) + TextWidth(Word) = ' + IntToStr(w1 + w2));
{
TextWidth(Hello) = 26
TextWidth(World) = 30
TextWidth(HelloWord) = 56
TextWidth(Hello) + TextWidth(Word) = 56
}
end;
Probably because VCL uses GDI and FMX uses DirectX?
ReplyDeleteOkay but how can I draw a selected text if I can't know the real selected portion width ?!
ReplyDeletegithub.com - Delphi
Text rendering can often change spacing between characters, because a font is often tweaked for specific pairs, font sizes, etc. If you want to see something really cool, look up ligatures, where pairs of characters are actually replaced with single symbols.
ReplyDeleteIn terms of drawing a selection, if you want to select "Wor" in "HelloWorld", finding the text width of "Hello" and "Wor" should do the trick well enough for a selection.
ok, I've found what is to be done
ReplyDelete1) use TextLayout.AddAttribute() to specify fonts change in the string
2) use TextLayout.RegionForRange returns the selected portion rectangle where I need to draw the selection background
3) TextLayout.RenderLayout display the text with the specified attributes