Einzelnen Beitrag anzeigen

Rollo62

Registriert seit: 15. Mär 2007
3.926 Beiträge
 
Delphi 12 Athens
 
#6

AW: Algorithmus für Text zu Polygon/TPath (Vector)

  Alt 25. Jul 2016, 13: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 13:42 Uhr)
  Mit Zitat antworten Zitat