AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

FMX.Graphics.TCanvas.FillText drehen

Ein Thema von himitsu · begonnen am 3. Sep 2025 · letzter Beitrag vom 5. Sep 2025
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.719 Beiträge
 
Delphi 12 Athens
 
#1

FMX.Graphics.TCanvas.FillText drehen

  Alt 3. Sep 2025, 13:36
Tachchen,

gibt es wirklich keine Möglichkeit für TCanvas.FillText (FMX) einen Winkel anzugeben?

* ja, beim Skia geht es, aber Skia für OnCustomDraw einer Nicht-Skia-Komponente?
* und ansonsten fand ich nur Varianten auf ein Bitmap zu schreiben, das dann zu drehen und anschließend auf den eigentlichen Canvas zu kopieren

* und auf ein TImage zu malen und das in der Anzeige zu drehen (RotationAngle), ist hier auch keine Lösung (z.B. den Text einer Caption/Zelle in Grid)


90°, 180°, 270° wären für den Anfang ausreichend, aber natürlich gibt es bestimmt irgendwelche, die einen freien Winkel nuzen würden wollen.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
UliBru

Registriert seit: 10. Mai 2010
160 Beiträge
 
Delphi 12 Athens
 
#2

AW: FMX.Graphics.TCanvas.FillText drehen

  Alt 3. Sep 2025, 13:43
Die KI der Google-Suche spuckt dazu aus

Delphi-Quellcode:
// Example for FireMonkey
var
  Angle: Single;
  R: TRectF;
  Matrix: TMatrix;
begin
  Canvas.Fill.Color := TAlphaColors.Black;
  Angle := -ArcTan2(ClientHeight, ClientWidth); // Calculate angle
  R := ClientRect;
  Matrix := CreateRotationMatrix(Angle);
  Canvas.SetMatrix(Matrix); // Apply the rotation matrix
  Canvas.FillText(R, 'Rotated FMX Text', False, 1, [], TTextAlign.taLeading, TTextAlign.taTrailing);
end;
Ich hab's nicht getestet, da ich derzeit kein FMX verwende.

Grüsse
Uli
Er wollte so richtig in Delphi einsteigen. Nun steckt er ganz tief drin ...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.719 Beiträge
 
Delphi 12 Athens
 
#3

AW: FMX.Graphics.TCanvas.FillText drehen

  Alt 3. Sep 2025, 13:54
paar kleine Änderungen ....
Delphi-Quellcode:
uses
  System.Math, System.Math.Vectors; // FMX.Filter.Custom: AffineCreateRotationMatrix

procedure TForm28.FormPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
var
  Angle: Single;
  R: TRectF;
  Matrix: TMatrix;
begin
  Canvas.Fill.Color := TAlphaColors.Black;
  Angle := -ArcTan2(ClientHeight, ClientWidth); // Calculate angle
  R := ClientRect;
  Matrix := CreateRotationMatrix(Angle);
  Canvas.SetMatrix(Matrix); // Apply the rotation matrix
  Canvas.FillText(R, 'Rotated FMX Text', False, 1, [], TTextAlign.Leading, TTextAlign.Trailing);
end;
aber CreateRotationMatrix gibt es nicht, oder nicht mehr (und AffineCreateRotationMatrix ist wohl was Anderes)

und die Hilfe
https://docwiki.embarcadero.com/Libr...nvas.SetMatrix
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von joachimd
joachimd

Registriert seit: 17. Feb 2005
Ort: Weitingen
687 Beiträge
 
Delphi 12 Athens
 
#4

AW: FMX.Graphics.TCanvas.FillText drehen

  Alt 3. Sep 2025, 14:00
darüber finde ich aber wiederum System.Math.Vectors.TMatrix und da gibt es https://docwiki.embarcadero.com/Libr...CreateRotation

vllt hilft dir das?
Joachim Dürr
Joachim Dürr Softwareengineering
http://www.jd-engineering.de

Geändert von joachimd ( 3. Sep 2025 um 14:03 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.719 Beiträge
 
Delphi 12 Athens
 
#5

AW: FMX.Graphics.TCanvas.FillText drehen

  Alt 3. Sep 2025, 14:43
Dann schau ich heute abend daheim nochmal in Ruhe danach.

Hatte vor mehreren Tagen nach sowas gesucht und es dann erstmal aufgegeben/gelassen.
Aber, als ich gestern Abend nochmal an jenem Projekt was geändert hab, war mir das wieder in den Sinn gekommen (hatte angefangen eine DemoForm zu basteln, wo auch Labels drauf sind)
und ich dachte ich frag mal ... vielleicht findet sich ja was für heut Abend (oder Wochenende).
https://www.delphipraxis.net/217731-...ml#post1551367
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von joachimd
joachimd

Registriert seit: 17. Feb 2005
Ort: Weitingen
687 Beiträge
 
Delphi 12 Athens
 
#6

AW: FMX.Graphics.TCanvas.FillText drehen

  Alt 3. Sep 2025, 14:47
müsste vermutlich über

  Canvas.SetMatrix(Canvas.Matrix.CreateRotation(Angle)); zu lösen sein.
Joachim Dürr
Joachim Dürr Softwareengineering
http://www.jd-engineering.de
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.719 Beiträge
 
Delphi 12 Athens
 
#7

AW: FMX.Graphics.TCanvas.FillText drehen

  Alt 3. Sep 2025, 14:53
Ich sag schonmal Danke (falls es dann geht )



es könnte alles so einfach sein

Eine DEMO in der Hilfe, die aus mehr als einer Funktion / paar Codezeilen beseteht
https://docwiki.embarcadero.com/Code...anvas_(Delphi)
und dann kommt niemand auf die Idee sie in den Demos abzulegen
C:\Users\Public\Documents\Embarcadero\Studio\23.0\Samples\
https://github.com/Embarcadero/RADStudio12Demos

oder die sinnloseste "DEMO" der Welt (siehe Screenshot) :
C:\Program Files (x86)\Embarcadero\Studio\23.0\bin\FMXControlStyleViewer.exe
https://embt.atlassian.net/servicede...tal/1/RSS-4015
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
philipp.hofmann

Registriert seit: 21. Mär 2012
Ort: Hannover
950 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: FMX.Graphics.TCanvas.FillText drehen

  Alt 3. Sep 2025, 17:54
Ich nutze bei mir die folgende Funktion, dürfte dem oben kommunizierten entsprechen:

Delphi-Quellcode:
class procedure TDrawUtils.drawRotatedText(Canvas: TCanvas; x,y,xw,angle: Single; color: TAlphaColor; HTextAlign, VTextAlign: TTextAlign; const S: String);
var
  W: Single;
  H: Single;
  R: TRectF;
  SaveMatrix: TMatrix;
  Matrix: TMatrix;
begin
  W := Canvas.TextWidth(S);
  H := Canvas.TextHeight(S);
  r:=RectF(x,y,x+w,y+h);
  if (angle=270) then
    x:=x+((xw-(h*0.25))*0.5);
  case HTextAlign of
    TTextAlign.Center: R.Left := -W / 2;
    TTextAlign.Leading: R.Left := 0;
    TTextAlign.Trailing: R.Left := -W;
  end;
  R.Width := W;
  case VTextAlign of
    TTextAlign.Center: R.Top := -H / 2;
    TTextAlign.Leading: R.Top := 0;
    TTextAlign.Trailing: R.Top := -H;
  end;
  R.Height := H;
  SaveMatrix:=Canvas.matrix;
  matrix:=TMatrix.CreateRotation(DegToRad(angle));
  matrix.m31:=x;
  matrix.m32:=y;
  Canvas.MultiplyMatrix(matrix);
  Canvas.Stroke.Color := color;
  Canvas.Fill.Color := color;
  Canvas.Stroke.Kind := TBrushKind.Solid;
  Canvas.Stroke.Thickness := 1;
  Canvas.FillText(R, S, False, 1, [], HTextAlign, VTextAlign);
  Canvas.SetMatrix(SaveMatrix);
end;
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.719 Beiträge
 
Delphi 12 Athens
 
#9

AW: FMX.Graphics.TCanvas.FillText drehen

  Alt 3. Sep 2025, 22:21
Delphi-Quellcode:
procedure TForm3.FormPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
var
  Angle: Single;
  Matrix: TMatrix;
begin
  Canvas.Fill.Color := TAlphaColors.Black;
  Angle := -ArcTan2(ClientHeight, ClientWidth);
  Matrix := Canvas.Matrix.CreateRotation(Angle);
  Canvas.SetMatrix(Matrix);
  Canvas.FillText(ClientRect, 'Rotated FMX Text', False, 1, [], TTextAlign.Leading, TTextAlign.Trailing);
Hatte hier als Winkel zuerst 0.3 probiert, aber war nix zu sehn.
Delphi-Quellcode:
  Canvas.Fill.Color := TAlphaColors.Black;
  Canvas.SetMatrix(Canvas.Matrix.CreateRotation(-0.64));
  Canvas.FillText(ClientRect, 'Rotated FMX Text', False, 1, [], TTextAlign.Leading, TTextAlign.Trailing);
Ja, das Erste berechnet auch einen negativen Winkel und der liegt innerhalb des Canvas-Rechtecks.

Wie bei drawRotatedText muß man also noch das X:Y dazurechnen,
bzw. das RectF für FillText ordentlich befüllen.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.719 Beiträge
 
Delphi 12 Athens
 
#10

AW: FMX.Graphics.TCanvas.FillText drehen

  Alt 5. Sep 2025, 01:45
Danke nochmal an Phillip

und der Endkampf mit den Matrizen.


Also die CreateRotation gibt erstmal nur die Richtung vor, von Position 0:0 aus,
dann noch den Nullpunkt der Matrix festlegen
und "von" diesem Nullpunkt aus dann den Text zeichnen.

In diesem Fall die Nullpunkte jeweils in der Mitte (Text mittig im Ziel rotieren)
Delphi-Quellcode:
uses
  System.Math, System.Math.Vectors;

procedure TForm3.FormPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
begin
  var DrawRect := RectF(100, 200, 200, 250);
  var TextRect := RectF(-DrawRect.Width / 2, -DrawRect.Height / 2,
                        +DrawRect.Width / 2, +DrawRect.Height / 2);
  var DMatrix := TMatrix.CreateRotation(DegToRad(Tag));
  DMatrix.m31 := DrawRect.CenterPoint.X;
  DMatrix.m32 := DrawRect.CenterPoint.Y;
  Tag := Tag + 1;

  Canvas.Stroke.Kind := TBrushKind.Solid;
  Canvas.Stroke.Color := TAlphaColors.Red;
  Canvas.Fill.Color := TAlphaColors.Ghostwhite;
  Canvas.FillRect(DrawRect, 1);

  Canvas.SetMatrix(DMatrix);
  Canvas.Fill.Color := TAlphaColors.Black;
  Canvas.FillText(TextRect, 'Rotated FMX Text', False,
    1, [], TTextAlign.Center, TTextAlign.Center);
end;

procedure TForm3.Timer1Timer(Sender: TObject);
begin
  Self.Invalidate;
end;
Da ich aber eh nur 90°-Winkel brauch, kann ich's vereinfachen und an einer Ecke rotieren
(-90° = links-unten, +90° = rechts-oben und 180° = unten-rechts)
Delphi-Quellcode:
uses
  System.Math, System.Math.Vectors;

procedure TForm3.FormPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
begin
  var DrawRect := RectF(100, 200, 200, 250);
  var TextRect := RectF(0, 0, DrawRect.Height, DrawRect.Width)
  var DMatrix := TMatrix.CreateRotation(DegToRad(Tag));
  DMatrix.m31 := DrawRect.Left;
  DMatrix.m32 := DrawRect.Bottom;
  Tag := Tag + 1;

  Canvas.Stroke.Kind := TBrushKind.Solid;
  Canvas.Stroke.Color := TAlphaColors.Red;
  Canvas.Fill.Color := TAlphaColors.Ghostwhite;
  Canvas.FillRect(DrawRect, 1);

  Canvas.SetMatrix(DMatrix);
  Canvas.Fill.Color := TAlphaColors.Black;
  Canvas.FillText(TextRect, 'Rotated FMX Text', False,
    1, [], TTextAlign.Leading, TTextAlign.Leading);
end;

procedure TForm3.Timer1Timer(Sender: TObject);
begin
  Self.Invalidate;
end;
Und da ich hier ja eh nur mit 90°-Winkeln arbeite, lassen viele Berechnungen (Sinus und Cosinus) durch Konstanten ersetzen.
Delphi-Quellcode:
uses
  System.Math, System.Math.Vectors;

type
  TMatrixHelper = record helper {(TMatrixConstants)} for TMatrix
    const Identity: TMatrix = (m11: +1; m12: 0; m13: 0; m21: 0; m22: +1; m23: 0; m31: 0; m32: 0; m33: 1);
    const Degree180: TMatrix = (m11: -1; m12: 0; m13: 0; m21: 0; m22: -1; m23: 0; m31: 0; m32: 0; m33: 1);
    const Degree90: TMatrix = (m11: 0; m12: +1; m13: 0; m21: -1; m22: 0; m23: 0; m31: 0; m32: 0; m33: 1);
    const Degree270: TMatrix = (m11: 0; m12: -1; m13: 0; m21: +1; m22: 0; m23: 0; m31: 0; m32: 0; m33: 1);
    constructor Create(m11, m12, m13, m21, m22, m23, m31, m32, m33: Single); overload; // 3D-Matrix
    constructor Create(m11, m12, m21, m22, m31, m32: Single); overload; // 2D-Matrix
    constructor Create90 (m31, m32: Single);
    constructor Create180(m31, m32: Single);
    constructor Create270(m31, m32: Single);
  end;

procedure TForm3.FormPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
begin
  // unten-links / hochzu von rechts
  var DrawRect := RectF(100, 100, 120, 200);
  var TextRect := RectF(0, 0, DrawRect.Height, DrawRect.Width);
  var DMatrix := TMatrix.CreateRotation(DegToRad(-90));
  DMatrix.m31 := DrawRect.Left;
  DMatrix.m32 := DrawRect.Bottom;
  // besser als Konstante, da die Berechnung nicht genau 0 ergibt (-4.37113882867379e-08)
  //DMatrix := TMatrix.Create(0, -1, +1, 0, DrawRect.Left, DrawRect.Bottom);

  Canvas.Stroke.Kind := TBrushKind.Solid;
  Canvas.Stroke.Color := TAlphaColors.Red;
  Canvas.Fill.Color := TAlphaColors.Ghostwhite;
  Canvas.FillRect(DrawRect, 1);

  Canvas.SetMatrix(DMatrix);
  Canvas.Fill.Color := TAlphaColors.Black;
  Canvas.FillText(TextRect, ' Rotated FMX Text', False, 1, [], TTextAlign.Leading, TTextAlign.Center);
  Canvas.SetMatrix(TMatrix.Identity);

  // oben-rechts / runterzu von links
  DrawRect := RectF(200, 100, 220, 200);
  TextRect := RectF(0, 0, DrawRect.Height, DrawRect.Width); // ergibt natürlich das Gleiche, wie oben
  DMatrix := TMatrix.CreateRotation(DegToRad(+90));
  DMatrix.m31 := DrawRect.Right;
  DMatrix.m32 := DrawRect.Top;
  // besser als Konstante, da die Berechnung nicht genau 0 ergibt (-4.37113882867379e-08)
  //DMatrix := TMatrix.Create(0, +1, -1, 0, DrawRect.Right, DrawRect.Top);

  Canvas.Stroke.Kind := TBrushKind.Solid;
  Canvas.Stroke.Color := TAlphaColors.Red;
  Canvas.Fill.Color := TAlphaColors.Ghostwhite;
  Canvas.FillRect(DrawRect, 1);

  Canvas.SetMatrix(DMatrix);
  Canvas.Fill.Color := TAlphaColors.Black;
  Canvas.FillText(TextRect, ' Rotated FMX Text', False, 1, [], TTextAlign.Leading, TTextAlign.Center);
  Canvas.SetMatrix(TMatrix.Identity);

  // rechts-unten / kopfüber
  DrawRect := RectF(300, 100, 400, 120);
  TextRect := RectF(0, 0, DrawRect.Width, DrawRect.Height);
  DMatrix := TMatrix.CreateRotation(DegToRad(180));
  DMatrix.m31 := DrawRect.Right;
  DMatrix.m32 := DrawRect.Bottom;
  // besser als Konstante, da die Berechnung nicht genau 0 ergibt (-4.37113882867379e-08)
  //DMatrix := TMatrix.Create(-1, 0, 0, +1, DrawRect.Right, DrawRect.Bottom);

  Canvas.Stroke.Kind := TBrushKind.Solid;
  Canvas.Stroke.Color := TAlphaColors.Red;
  Canvas.Fill.Color := TAlphaColors.Ghostwhite;
  Canvas.FillRect(DrawRect, 1);

  Canvas.SetMatrix(DMatrix);
  Canvas.Fill.Color := TAlphaColors.Black;
  Canvas.FillText(TextRect, ' Rotated FMX Text', False, 1, [], TTextAlign.Leading, TTextAlign.Center);
  Canvas.SetMatrix(TMatrix.Identity);
end;

procedure TForm3.Timer1Timer(Sender: TObject);
begin
  Self.Invalidate;
end;
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:42 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz