|
Antwort |
Registriert seit: 13. Jan 2004 Ort: Hamm(Westf) 1.944 Beiträge Delphi 12 Athens |
#1
TPath aus FMX.Objects kann
von folgenden SVG Path commands
Code:
Quelle: https://developer.mozilla.org/en-US/...#path_commands
MoveTo: M, m
LineTo: L, l, H, h, V, v Cubic Bézier Curve: C, c, S, s Quadratic Bézier Curve: Q, q, T, t Elliptical Arc Curve: A, a ClosePath: Z, z QqTt nicht. Ich denke die Ursache ist, dass FMX.Graphics.TPathData.SetPathString alle PathCommands rendert außer eben QqTt... 'C' wird wie folgt gerendert:
Delphi-Quellcode:
wäre es dann richtig 'Q' ebenso zu rendern nur eben eben mit Curvepoint2 := Curvepoint1 ?
'C':
begin CurvePoint1 := GetPointFromString(PathString, Pos); CurvePoint2 := GetPointFromString(PathString, Pos); CurveTo(CurvePoint1, CurvePoint2, GetPointFromString(PathString, Pos)); while HasRelativeOffset(PathString, Pos) do begin CurvePoint1 := GetPointFromString(PathString, Pos); CurvePoint2 := GetPointFromString(PathString, Pos); CurveTo(CurvePoint1, CurvePoint2, GetPointFromString(PathString, Pos)); end; end;
Delphi-Quellcode:
Muss noch eine andere Stelle gepatched werden?
'Q':
begin CurvePoint1 := GetPointFromString(PathString, Pos); CurvePoint2 := CurvePoint1; CurveTo(CurvePoint1, CurvePoint2, GetPointFromString(PathString, Pos)); while HasRelativeOffset(PathString, Pos) do begin CurvePoint1 := GetPointFromString(PathString, Pos); CurvePoint2 := CurvePoint1; CurveTo(CurvePoint1, CurvePoint2, GetPointFromString(PathString, Pos)); end; end;
Andreas
Monads? Wtf are Monads? |
Zitat |
Registriert seit: 19. Jan 2009 Ort: Kirchlinteln (LK Verden) 1.081 Beiträge Delphi 2009 Professional |
#2
Siehe hier.
Ansonsten siehe Quelltext verschiedener SVG-Renderer für Delphi, z.B. meinen (RedeemerSVG).
Janni
2005 PE, 2009 PA, XE2 PA Geändert von Redeemer (14. Mär 2023 um 09:12 Uhr) |
Zitat |
Registriert seit: 13. Jan 2004 Ort: Hamm(Westf) 1.944 Beiträge Delphi 12 Athens |
#3
Es gibt FMX.Graphics.TPathData.QuadCurveTo(const ControlPoint, EndPoint: TPointF);
Wird irgendwie nur nicht verwendet. Die sieht so aus für 'Q':
Delphi-Quellcode:
Ich habe dann mal darauf aufbauend folgende weitere methoden "abgeleitet":
procedure TPathData.QuadCurveTo(const ControlPoint, EndPoint: TPointF);
const OneThird = 1 / 3; TwoThirds = 2 / 3; var LP, CP1, CP2: TPointF; begin LP := LastPoint; CP1.X := OneThird * LP.X + TwoThirds * ControlPoint.X; CP1.Y := OneThird * LP.Y + TwoThirds * ControlPoint.Y; CP2.X := TwoThirds * ControlPoint.X + OneThird * EndPoint.X; CP2.Y := TwoThirds * ControlPoint.Y + OneThird * EndPoint.Y; CurveTo(CP1, CP2, EndPoint); end; Für 'q':
Delphi-Quellcode:
für 'T':
procedure TPathData.QuadCurveToRel(const ControlPoint, EndPoint: TPointF);
var LP: TPointF; begin LP := LastPoint; QuadCurveTo(LP+ControlPoint,LP+EndPoint); end;
Delphi-Quellcode:
für 't':
procedure TPathData.SmoothQuadCurveTo(const EndPoint: TPointF);
var ControlPoint1: TPointF; begin if Count > 2 then ControlPoint1 := LastPoint + (LastPoint - FPathData[FPathData.Count - 2].Point) else ControlPoint1 := LastPoint; QuadCurveTo(ControlPoint1, EndPoint); end;
Delphi-Quellcode:
procedure TPathData.SmoothQuadCurveToRel(const EndPoint: TPointF);
var ControlPoint1: TPointF; begin if Count > 2 then ControlPoint1 := LastPoint + (LastPoint - FPathData[FPathData.Count - 2].Point) else ControlPoint1 := LastPoint; QuadCurveToRel(ControlPoint1, EndPoint); end; Und dann entsprechend TPathData.SetPathString gepatcht
Delphi-Quellcode:
Dann geht das hier
procedure TPathData.SetPathString(const Value: string);
var Builder, TokenBuilder: TStringBuilder; PathString, Tokens: string; Radius, CurvePoint1, CurvePoint2, TempPoint: TPointF; Large, Sweet: Boolean; Pos, I, LastLength: Integer; Angle: Single; Token: Char; begin Builder := TStringBuilder.Create; TokenBuilder := TStringBuilder.Create; try for I := 0 to Value.Length - 1 do begin if Value.Chars[I].IsInArray([#9, #10, #13]) then Builder.Append(' ') else Builder.Append(Value.Chars[I]); end; PathString := Builder.ToString; FPathData.Clear; Pos := 0; LastLength := -1; while (Builder.Length > Pos) and (LastLength <> Pos) do begin LastLength := Pos; Tokens := GetTokensFromString(PathString, Pos); TokenBuilder.Clear; TokenBuilder.Append(Tokens); while TokenBuilder.Length > 0 do begin Token := TokenBuilder.Chars[0]; TokenBuilder.Remove(0, 1); case Token of 'z', 'Z': ClosePath; 'M': begin MoveTo(GetPointFromString(PathString, Pos)); while HasRelativeOffset(PathString, Pos) do LineTo(GetPointFromString(PathString, Pos)); end; 'm': begin MoveToRel(GetPointFromString(PathString, Pos)); while HasRelativeOffset(PathString, Pos) do LineToRel(GetPointFromString(PathString, Pos)); end; 'L': begin LineTo(GetPointFromString(PathString, Pos)); while HasRelativeOffset(PathString, Pos) do LineTo(GetPointFromString(PathString, Pos)); end; 'l': begin LineToRel(GetPointFromString(PathString, Pos)); while HasRelativeOffset(PathString, Pos) do LineToRel(GetPointFromString(PathString, Pos)); end; 'C': begin CurvePoint1 := GetPointFromString(PathString, Pos); CurvePoint2 := GetPointFromString(PathString, Pos); CurveTo(CurvePoint1, CurvePoint2, GetPointFromString(PathString, Pos)); while HasRelativeOffset(PathString, Pos) do begin CurvePoint1 := GetPointFromString(PathString, Pos); CurvePoint2 := GetPointFromString(PathString, Pos); CurveTo(CurvePoint1, CurvePoint2, GetPointFromString(PathString, Pos)); end; end; 'c': begin CurvePoint1 := GetPointFromString(PathString, Pos); CurvePoint2 := GetPointFromString(PathString, Pos); CurveToRel(CurvePoint1, CurvePoint2, GetPointFromString(PathString, Pos)); while HasRelativeOffset(PathString, Pos) do begin CurvePoint1 := GetPointFromString(PathString, Pos); CurvePoint2 := GetPointFromString(PathString, Pos); CurveToRel(CurvePoint1, CurvePoint2, GetPointFromString(PathString, Pos)); end; end; 'S': begin CurvePoint2 := GetPointFromString(PathString, Pos); SmoothCurveTo(CurvePoint2, GetPointFromString(PathString, Pos)); while HasRelativeOffset(PathString, Pos) do begin CurvePoint2 := GetPointFromString(PathString, Pos); SmoothCurveTo(CurvePoint2, GetPointFromString(PathString, Pos)); end; end; 's': begin CurvePoint2 := GetPointFromString(PathString, Pos); SmoothCurveToRel(CurvePoint2, GetPointFromString(PathString, Pos)); while HasRelativeOffset(PathString, Pos) do begin CurvePoint2 := GetPointFromString(PathString, Pos); SmoothCurveToRel(CurvePoint2, GetPointFromString(PathString, Pos)); end; end; 'H': HLineTo(StrToFloat(GetNumberFromString(PathString, Pos), USFormatSettings)); 'h': HLineToRel(StrToFloat(GetNumberFromString(PathString, Pos), USFormatSettings)); 'V': VLineTo(StrToFloat(GetNumberFromString(PathString, Pos), USFormatSettings)); 'v': VLineToRel(StrToFloat(GetNumberFromString(PathString, Pos), USFormatSettings)); 'Q': //A.R. //Quadratic Bezier Curve Begin CurvePoint1 := GetPointFromString(PathString, Pos); QuadCurveTo(CurvePoint1, GetPointFromString(PathString, Pos)); while HasRelativeOffset(PathString, Pos) do begin CurvePoint1 := GetPointFromString(PathString, Pos); QuadCurveTo(CurvePoint1, GetPointFromString(PathString, Pos)); end; End; 'q': //A.R. //Quadratic Bezier Curve begin CurvePoint1 := GetPointFromString(PathString, Pos); QuadCurveToRel(CurvePoint1, GetPointFromString(PathString, Pos)); while HasRelativeOffset(PathString, Pos) do begin CurvePoint1 := GetPointFromString(PathString, Pos); QuadCurveToRel(CurvePoint1, GetPointFromString(PathString, Pos)); end; end; 'T': //A.R. //Smooth Quadratic Bezier Curve begin SmoothQuadCurveTo(GetPointFromString(PathString, Pos)); while HasRelativeOffset(PathString, Pos) do SmoothQuadCurveTo(GetPointFromString(PathString, Pos)); end; 't': //A.R. //Smooth Quadratic Bezier Curve Begin CurvePoint2 := GetPointFromString(PathString, Pos); SmoothCurveToRel(CurvePoint2, CurvePoint2); while HasRelativeOffset(PathString, Pos) do begin CurvePoint2 := GetPointFromString(PathString, Pos); SmoothCurveToRel(CurvePoint2, CurvePoint2); end; End; 'A', 'a': begin if Count > 0 then CurvePoint1 := FPathData[FPathData.Count - 1].Point else CurvePoint1 := TPointF.Zero; Radius := GetPointFromString(PathString, Pos); Angle := StrToFloat(GetNumberFromString(PathString, Pos), USFormatSettings); TempPoint := GetPointFromString(PathString, Pos); Large := TempPoint.X = 1; Sweet := TempPoint.Y = 1; CurvePoint2 := GetPointFromString(PathString, Pos); if Token = 'a' then CurvePoint2 := CurvePoint1 + CurvePoint2; AddArcSvg(CurvePoint1, Radius, Angle, Large, Sweet, CurvePoint2); end; end; end; end; DoChanged; finally TokenBuilder.Free; Builder.Free; end; end;
Delphi-Quellcode:
Keine Ahnung wie man macht das es im Objekt Inspector oder zur designzeit schon funktioniert.
Path2.Data.Data := 'M24,40'+
'Q23,40 22.3,39.3'+ 'Q21.6,38.6 21.6,37.6'+ 'Q21.6,36.6 22.3,35.9'+ 'Q23,35.2 24,35.2'+ 'Q25,35.2 25.7,35.9'+ 'Q26.4,36.6 26.4,37.6'+ 'Q26.4,38.6 25.7,39.3'+ 'Q25,40 24,40'+ 'Z'+ 'M24,26.4'+ 'Q23,26.4 22.3,25.7'+ 'Q21.6,25 21.6,24'+ 'Q21.6,23 22.3,22.3'+ 'Q23,21.6 24,21.6'+ 'Q25,21.6 25.7,22.3'+ 'Q26.4,23 26.4,24'+ 'Q26.4,25 25.7,25.7'+ 'Q25,26.4 24,26.4'+ 'Z'+ 'M24,12.8'+ 'Q23,12.8 22.3,12.1'+ 'Q21.6,11.4 21.6,10.4'+ 'Q21.6,9.4 22.3,8.7'+ 'Q23,8 24,8'+ 'Q25,8 25.7,8.7'+ 'Q26.4,9.4 26.4,10.4'+ 'Q26.4,11.4 25.7,12.1'+ 'Q25,12.8 24,12.8'+ 'Z'; Probiert es aus , bitte. Und feedback oder direkt Verbesserungen!
Andreas
Monads? Wtf are Monads? Geändert von QuickAndDirty (14. Mär 2023 um 10:59 Uhr) |
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs 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
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |