Browse Source

Rewrites the bezier rendering of the svg output of fpvectorial

git-svn-id: trunk@15930 -
sekelsenmat 15 years ago
parent
commit
3f26a9795b
1 changed files with 43 additions and 85 deletions
  1. 43 85
      packages/fpvectorial/src/svgvectorialwriter.pas

+ 43 - 85
packages/fpvectorial/src/svgvectorialwriter.pas

@@ -25,7 +25,6 @@ type
     procedure WriteDocumentName(AStrings: TStrings; AData: TvVectorialDocument);
     procedure WriteDocumentName(AStrings: TStrings; AData: TvVectorialDocument);
     procedure WritePaths(AStrings: TStrings; AData: TvVectorialDocument);
     procedure WritePaths(AStrings: TStrings; AData: TvVectorialDocument);
     procedure WriteTexts(AStrings: TStrings; AData: TvVectorialDocument);
     procedure WriteTexts(AStrings: TStrings; AData: TvVectorialDocument);
-    procedure WriteBeziers(AStrings: TStrings; AData: TvVectorialDocument);
     procedure ConvertFPVCoordinatesToSVGCoordinates(
     procedure ConvertFPVCoordinatesToSVGCoordinates(
       const AData: TvVectorialDocument;
       const AData: TvVectorialDocument;
       const ASrcX, ASrcY: Double; var ADestX, ADestY: double);
       const ASrcX, ASrcY: Double; var ADestX, ADestY: double);
@@ -44,7 +43,9 @@ const
   // 1 Inch = 25.4 milimiters
   // 1 Inch = 25.4 milimiters
   // 90 inches per pixel = (1 / 90) * 25.4 = 0.2822
   // 90 inches per pixel = (1 / 90) * 25.4 = 0.2822
   // FLOAT_MILIMETERS_PER_PIXEL = 0.3528; // DPI 72 = 1 / 72 inches per pixel
   // FLOAT_MILIMETERS_PER_PIXEL = 0.3528; // DPI 72 = 1 / 72 inches per pixel
+
   FLOAT_MILIMETERS_PER_PIXEL = 0.2822; // DPI 90 = 1 / 90 inches per pixel
   FLOAT_MILIMETERS_PER_PIXEL = 0.2822; // DPI 90 = 1 / 90 inches per pixel
+  FLOAT_PIXELS_PER_MILIMETER = 3.5433; // DPI 90 = 1 / 90 inches per pixel
 
 
 { TvSVGVectorialWriter }
 { TvSVGVectorialWriter }
 
 
@@ -79,18 +80,20 @@ var
   PathStr: string;
   PathStr: string;
   lPath: TPath;
   lPath: TPath;
   PtX, PtY, OldPtX, OldPtY: double;
   PtX, PtY, OldPtX, OldPtY: double;
+  BezierCP1X, BezierCP1Y, BezierCP2X, BezierCP2Y: double;
 begin
 begin
   for i := 0 to AData.GetPathCount() - 1 do
   for i := 0 to AData.GetPathCount() - 1 do
   begin
   begin
     OldPtX := 0;
     OldPtX := 0;
     OldPtY := 0;
     OldPtY := 0;
 
 
-    PathStr := 'm ';
+    PathStr := '';
     lPath := AData.GetPath(i);
     lPath := AData.GetPath(i);
     for j := 0 to lPath.Len - 1 do
     for j := 0 to lPath.Len - 1 do
     begin
     begin
       if (lPath.Points[j].SegmentType <> st2DLine)
       if (lPath.Points[j].SegmentType <> st2DLine)
         and (lPath.Points[j].SegmentType <> stMoveTo)
         and (lPath.Points[j].SegmentType <> stMoveTo)
+        and (lPath.Points[j].SegmentType <> st2DBezier)
         then Break; // unsupported line type
         then Break; // unsupported line type
 
 
       // Coordinate conversion from fpvectorial to SVG
       // Coordinate conversion from fpvectorial to SVG
@@ -99,8 +102,44 @@ begin
       PtX := PtX - OldPtX;
       PtX := PtX - OldPtX;
       PtY := PtY - OldPtY;
       PtY := PtY - OldPtY;
 
 
-      PathStr := PathStr + FloatToStr(PtX, FPointSeparator) + ','
-        + FloatToStr(PtY, FPointSeparator) + ' ';
+      if (lPath.Points[j].SegmentType = stMoveTo) then
+      begin
+        PathStr := PathStr + 'm '
+          + FloatToStr(PtX, FPointSeparator) + ','
+          + FloatToStr(PtY, FPointSeparator) + ' ';
+      end
+      else if (lPath.Points[j].SegmentType = st2DLine) then
+      begin
+        PathStr := PathStr + 'l '
+          + FloatToStr(PtX, FPointSeparator) + ','
+          + FloatToStr(PtY, FPointSeparator) + ' ';
+      end
+      else if (lPath.Points[j].SegmentType = st2DBezier) then
+      begin
+        // Converts all coordinates to absolute values
+        ConvertFPVCoordinatesToSVGCoordinates(
+          AData, lPath.Points[j].X2, lPath.Points[j].Y2, BezierCP1X, BezierCP1X);
+        ConvertFPVCoordinatesToSVGCoordinates(
+          AData, lPath.Points[j].X3, lPath.Points[j].Y3, BezierCP2X, BezierCP2Y);
+
+        // Transforms them into values relative to the initial point
+        BezierCP1X := BezierCP1X - OldPtX;
+        BezierCP1Y := BezierCP1Y - OldPtY;
+        BezierCP2X := BezierCP2X - OldPtX;
+        BezierCP2Y := BezierCP2Y - OldPtY;
+
+        // PtX and PtY already contains the destination point
+
+        // Now render our 2D cubic bezier
+        PathStr := PathStr + 'c '
+          + FloatToStr(BezierCP1X, FPointSeparator) + ','
+          + FloatToStr(BezierCP1Y, FPointSeparator) + ' '
+          + FloatToStr(BezierCP2X, FPointSeparator) + ','
+          + FloatToStr(BezierCP2Y, FPointSeparator) + ' '
+          + FloatToStr(PtX, FPointSeparator) + ','
+          + FloatToStr(PtY, FPointSeparator) + ' '
+          ;
+      end;
 
 
       // Store the current position for future points
       // Store the current position for future points
       OldPtX := OldPtX + PtX;
       OldPtX := OldPtX + PtX;
@@ -153,7 +192,6 @@ begin
   AStrings.Add('  <g id="layer1">');
   AStrings.Add('  <g id="layer1">');
   WritePaths(AStrings, AData);
   WritePaths(AStrings, AData);
   WriteTexts(AStrings, AData);
   WriteTexts(AStrings, AData);
-  WriteBeziers(AStrings, AData);
   AStrings.Add('  </g>');
   AStrings.Add('  </g>');
 
 
   // finalization
   // finalization
@@ -192,86 +230,6 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure TvSVGVectorialWriter.WriteBeziers(AStrings: TStrings; AData: TvVectorialDocument);
-var
-  i, j: Integer;
-  PathStr: string;
-  lPath: TPath;
-  PtX, PtY, OldPtX, OldPtY, PtX2, PtY2, OldPtX2, OldPtY2,
-    PtX3, PtY3, OldPtX3, OldPtY3: double;
-  BezierType: TSegmentType;
-begin
-  for i := 0 to AData.GetPathCount() - 1 do
-  begin
-    OldPtX  := 0;
-    OldPtY  := 0;
-    OldPtX2 := 0;
-    OldPtY2 := 0;
-    OldPtX3 := 0;
-    OldPtY3 := 0;
-
-    PathStr := 'm ';
-    lPath   := AData.GetPath(i);
-    for j := 0 to lPath.Len - 1 do
-    begin
-      BezierType := lPath.Points[j].SegmentType;
-      if j>0 then
-      if (BezierType <> st2DBezier) and (BezierType <> stMoveTo)
-        and (BezierType <> st2DLine)
-      then Break; // unsupported Bezier type
-
-      if (BezierType = st2DBezier) or (BezierType = stMoveTo) then
-      begin
-        ConvertFPVCoordinatesToSVGCoordinates(
-         AData, lPath.Points[j].X, lPath.Points[j].Y, PtX, PtY);
-        ConvertFPVCoordinatesToSVGCoordinates(
-         AData, lPath.Points[j].X2, lPath.Points[j].Y2, PtX2, PtY2);
-        ConvertFPVCoordinatesToSVGCoordinates(
-         AData, lPath.Points[j].X3, lPath.Points[j].Y3, PtX3, PtY3);
-
-        PtX  := PtX - OldPtX;
-        PtY  := PtY - OldPtY;
-        PtX2 := PtX2 - OldPtX2;
-        PtY2 := PtY2 - OldPtY2;
-        PtX3 := PtX3 - OldPtX3;
-        PtY3 := PtY3 - OldPtY3;
-
-        if j = 0 then
-          PathStr := PathStr + FloatToStr(PtX, FPointSeparator) + ','
-            + FloatToStr(PtY, FPointSeparator) + ' ';
-
-        if j = 0 then
-        begin
-          PathStr := PathStr + 'q';
-//          if BezierType = st3DBezier then
-//            PathStr := PathStr + 'c';
-        end;
-
-        if j > 0 then
-          PathStr := PathStr + FloatToStr(PtX, FPointSeparator) + ','
-            + FloatToStr(PtY, FPointSeparator) + ' '
-            + FloatToStr(PtX2, FPointSeparator) + ','
-            + FloatToStr(PtY2, FPointSeparator) + ' '
-            + FloatToStr(PtX3, FPointSeparator) + ','
-            + FloatToStr(PtY3, FPointSeparator) + ' ';
-
-        // Store the current position for future points
-        OldPtX  := OldPtX + PtX;
-        OldPtY  := OldPtY + PtY;
-        OldPtX2 := OldPtX2 + PtX2;
-        OldPtY2 := OldPtY2 + PtY2;
-        OldPtX3 := OldPtX3 + PtX3;
-        OldPtY3 := OldPtY3 + PtY3;
-      end;
-    end;
-
-    AStrings.Add('  <path');
-    AStrings.Add('    style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"');
-    AStrings.Add('    d="' + PathStr + '"');
-    AStrings.Add('  id="Bezier' + IntToStr(i) + '" />');
-  end;
-end;
-
 initialization
 initialization
 
 
   RegisterVectorialWriter(TvSVGVectorialWriter, vfSVG);
   RegisterVectorialWriter(TvSVGVectorialWriter, vfSVG);