Registriert seit: 15. Mär 2007
4.094 Beiträge
Delphi 12 Athens
|
AW: Algorithmus für Text zu Polygon/TPath (Vector)
25. Jul 2016, 14:38
Hallo Milos,
hier ist noch ein "grober" Versuch Text in einen Pfad zu rendern unter FMX.
Jedenfalls hatte ich immer Probleme mit dem Scaling untern verschiedenen Plattformen,
und auch davon einen Screenshot zu machen hatte diverse Probleme.
Mit viel manuellen Korrekturen läuft es, aber ob es auf allen Geräten gleich aussieht kann ich nicht garantieren.
Ich will den Text erst im 0,0 Punkt mittig zentrieren,
dann drehen und verschieben, und
an die finale Position positioinieren.
Das alles mit den Matrizen.
Vielleicht hilft dir das ja auch it´rgendwie weiter.
Delphi-Quellcode:
procedure TS4Shape.PaintToLayout_Text(Canvas: TCanvas; const ARect: TRectF);
var
ptS, ptE, ptC: TPointF;
// sAng: Single;
// mtrx: TMatrix;
// mtrxOfs: TMatrix;
// sAngL: Single;
F_Arm : Single;
len : Single;
// mtrxTrn: TMatrix;
// mtrxRot: TMatrix;
// rcText: TRectF;
// szBmp: TSizeF;
// MState: TMatrix;
// ptVP: TPointF;
// sSclC: Single;
// sSclCP: Single;
// sSclP: Single;
// sSclB: Single;
// sSclSC: Single;
pd: TPathData;
ang: Single;
rcImg: TRectF;
lenOfs: Single;
sHeight: Single;
rcTxt: TRectF;
sScale: Single;
mat: TMatrix;
sSclScrn: Single;
sSclCan: Single;
sSclBmp: Single;
bOrientH: Boolean;
FScrn: IFMXScreenService;
sGetScrnScale: Single;
sTxtFak: Single;
// bIsTablet: Boolean;
begin
// New Approach 24.04.16
if FShapes.IsSuppressText then
begin
Exit; // Don'T want Text here
end;
sGetScrnScale := 1.0;
if TPlatformServices.Current.SupportsPlatformService( IFMXScreenService, FScrn) then
begin
sGetScrnScale := FScrn.GetScreenScale;
FScrn := nil;
end;
// New Approach 24.04.16
pd := TPathData.Create;
try
if (FText <> '') and
(FSelPtsTextIdx[0] >= 0) and
(FSelPtsTextIdx[1] >= 0) then
begin
pd.Clear;
rcImg := RectF(0, 0,
Min(Canvas.Width, Canvas.Height),
Max(Canvas.Width, Canvas.Height)
);
if Canvas.TextToPath(pd,
rcImg,
// RectF(0,
// 0,
// Min(Canvas.Width, Canvas.Height),
// Max(Canvas.Width, Canvas.Height)),
FText,
True,
TTextAlign.Center,
TTextAlign.Leading
) then
begin
ptS := FSelPtsList.Items[FSelPtsTextIdx[0]].Position.Point;
ptE := FSelPtsList.Items[FSelPtsTextIdx[1]].Position.Point;
len := ptS.Distance( ptE );
if len >= 10 then
begin
// Retrieve ScreenOrient
bOrientH := TS4View_Manager.Orientation_Current_IsPortrait;
ang := ptS.Angle( ptE ) + Pi; // As Radian
ptC := (ptS + ptE) / 2;
if FSelPtsList.Count >= 3 then
FSelPtsList.Items[2].Position.Point := ptC
else
ptC := ptC;
// FLine.Center.Offset ang + Pi/2; // Turn 90°
// if bOrientH then
F_Arm := ang - Pi * 0.5; // 90° direction angFac; // - for L-Arm + for R-Arm
// else
// F_Arm := ang + Pi * 0.5; // 90° direction angFac; // - for L-Arm + for R-Arm
// len := TextSize * sSclB * sSclP * FShapes.ScaleShapes * 1.0;
// mtrxOfs := TMatrix.CreateTranslation(Cos(FL) * len, Sin(FL) * len);
// rcImg := RectF(0, 0, Canvas.Width, Canvas.Height);
pd.FitToRect( rcImg );
lenOfs := pd.GetBounds.Height;
sSclScrn := sGetScrnScale;
sSclCan := Canvas.Scale;
sSclBmp := FShapes.GetImgViewCtrl.Bitmap.BitmapScale;
sHeight := rcImg.Width; // Min(Canvas.Width, Canvas.Height );
sHeight := sHeight / 6;
// sHeight := 40;
{$IFDEF MSWINDOWS}
// sHeight := 80;
{$ENDIF MSWINDOWS}
{$IFDEF MACOS}
// sHeight := 80;
{$ENDIF MACOS}
{$IF DEFINED(IOS) or DEFINED(ANDROID)}
{$IF DEFINED(IOS)}
sHeight := 40;
{$ENDIF DEFINED(IOS)}
{$IF DEFINED(ANDROID)}
sHeight := 20;
{$ENDIF DEFINED(ANDROID)}
if sSclScrn <= 2 then
begin
sHeight := sHeight * 1.5;
end
else
begin
sHeight := sHeight / 1.5;
end;
if not FShapes.IsInMakeScreenshot then
sHeight := sHeight * sSclScrn;
{$ENDIF DEFINED(IOS) or DEFINED(ANDROID)}
rcTxt := RectF(0,0,
len * sSclScrn,
sHeight * sSclScrn); // Height/Size of Text
sTxtFak := 1.5; //!!! Hier ist der Faktor der die Größe bestimmt ??
if FText.Length >= 3 then
begin
sTxtFak := sTxtFak * (Min(Max(FText.Length, 2), 10) / 6); // Get TextLen dependend Factor
lenOfs := lenOfs * 0.95;
end
else
begin
sTxtFak := sTxtFak * (Min(Max(FText.Length, 1), 10) / 7); // Get TextLen dependend Factor
lenOfs := lenOfs * 0.80;
end;
rcImg.FitInto(rcTxt, sScale);
if sScale > 0.0 then
sScale := Max(0.1, 1 / sScale) * sTxtFak
else
sScale := Max(0.1, 1 / 1.0) * sTxtFak;
lenOfs := 1.05 * lenOfs * sScale;
mat := TMatrix.Identity;
// Center at 0/0
mat := mat * TMatrix.CreateTranslation( -rcImg.Width /2, // -Canvas.Width /2,
-rcImg.Height/2); // -Canvas.Height/2 );
// Scale to TextRect
mat := mat * TMatrix.CreateScaling(sScale, sScale);
// Rotate to TextRect
mat := mat * TMatrix.CreateRotation( ang ); // ang );
// Translate OffCenter, to Upper Line
// if bOrientH then
mat := mat * TMatrix.CreateTranslation( Cos(F_Arm) * lenOfs,
Sin(F_Arm) * lenOfs);
// else
// mat := mat * TMatrix.CreateTranslation( Cos(F_Arm) * lenOfs * 4,
// Sin(F_Arm) * lenOfs * 4);
// Translate to TextRect Center
mat := mat * TMatrix.CreateTranslation( ptC.X, // + rcTxt.Width /2,
ptC.Y // + rcTxt.Height/2 );
);
pd.ApplyMatrix( mat );
Canvas.Stroke.Color := Canvas.Fill.Color;
Canvas.FillPath( pd, 1);
Canvas.DrawPath( pd, 1);
end;
end;
end;
finally
pd.Free;
end;
end;
Rollo
Geändert von Rollo62 (25. Jul 2016 um 14:42 Uhr)
|