|
@@ -1,6 +1,7 @@
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Drawing;
|
|
|
+using System.Globalization;
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
using System.Text.RegularExpressions;
|
|
@@ -16,6 +17,21 @@ namespace SketchAssistant
|
|
|
/// </summary>
|
|
|
Form1 program;
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// scale factor for coordinates of svg file
|
|
|
+ /// </summary>
|
|
|
+ double scale;
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// line pointer for the current svg document
|
|
|
+ /// </summary>
|
|
|
+ int i;
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// array containing all characters interpreted as whitespaces which seperate words/tokens in the input file
|
|
|
+ /// </summary>
|
|
|
+ readonly char[] whitespaces = new char[] { ' ' , ',' };
|
|
|
+
|
|
|
public FileImporter(Form1 newProgram)
|
|
|
{
|
|
|
program = newProgram;
|
|
@@ -151,5 +167,491 @@ namespace SketchAssistant
|
|
|
return ParseISADInput(allLines);
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// parses a svg drawing, given as a .svg file
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="fileName">the path of the input file</param>
|
|
|
+ /// <returns>the width and height of the left canvas and the parsed picture as a list of lines</returns>
|
|
|
+ public (int, int, List<Line>) ParseSVGInputFile(String fileName, int windowWidth, int windowHeight)
|
|
|
+ {
|
|
|
+ return ParseSVGInput(System.IO.File.ReadAllLines(fileName), windowWidth, windowHeight);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// parses a svg drawing, given as the content of a .svg file, seperated into lines
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="allLines">an array holding all lines of the input file</param>
|
|
|
+ /// <returns>the width and height of the left canvas and the parsed picture as a list of lines</returns>
|
|
|
+ private (int, int, List<Line>) ParseSVGInput(String[] allLines, double windowWidth, double windowHeight)
|
|
|
+ {
|
|
|
+ i = 0; //reset line pointer
|
|
|
+ if (allLines.Length == 0) //check for empty file
|
|
|
+ {
|
|
|
+ throw new FileImporterException("file is empty", "", -1);
|
|
|
+ }
|
|
|
+ (int, int) sizedef = ParseSVGHeader(allLines); //parse svg file header and get internal coordinate range
|
|
|
+ i++;
|
|
|
+ int width; //width of the resulting picture in pixels
|
|
|
+ int height; //height of the resulting picture in pixels
|
|
|
+ if (windowWidth / windowHeight > sizedef.Item1 / sizedef.Item2) //height dominant, width has to be smaller than drawing window to preserve xy-scale
|
|
|
+ {
|
|
|
+ scale = windowHeight / sizedef.Item2;
|
|
|
+ Console.WriteLine("scale: (heights) " + windowHeight + "/" + sizedef.Item2);
|
|
|
+ Console.WriteLine("widths: " + windowWidth + "/" + sizedef.Item1);
|
|
|
+ height = (int)Math.Round(windowHeight);
|
|
|
+ width = (int) Math.Round(scale * sizedef.Item1);
|
|
|
+ Console.WriteLine(width + "x" + height + " (" + scale + ")");
|
|
|
+ }
|
|
|
+ else //width dominant, height has to be smaller than drawing window to preserve xy-scale
|
|
|
+ {
|
|
|
+ scale = windowWidth / sizedef.Item1;
|
|
|
+ Console.WriteLine("scale: (widths) " + windowWidth + "/" + sizedef.Item1);
|
|
|
+ Console.WriteLine("heights: " + windowHeight + "/" + sizedef.Item2);
|
|
|
+ width = (int)Math.Round(windowWidth);
|
|
|
+ height = (int)Math.Round(scale * sizedef.Item2);
|
|
|
+ Console.WriteLine(width + "x" + height + " (" + scale + ")");
|
|
|
+ }
|
|
|
+ for(int j=0; j < allLines.Length; j++)
|
|
|
+ {
|
|
|
+ allLines[j] = allLines[j].Trim(whitespaces);
|
|
|
+ }
|
|
|
+ List<Line> picture = ParseSVGBody(allLines); //parse whole svg drawing into list of lines
|
|
|
+ return (width, height, picture);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// parses the svg file header and returns the internal coordinate range of this drawing, and iterates i to point to the start of svg element definitions
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="allLines">an array holding all lines of the input file</param>
|
|
|
+ /// <returns>the internal coordinate range of this drawing</returns>
|
|
|
+ private (int, int) ParseSVGHeader(String[] allLines)
|
|
|
+ {
|
|
|
+ while (!allLines[i].StartsWith("<svg")) //skip non-relevant metadata at start of svg file
|
|
|
+ {
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ String[] currentLine = allLines[i].Split(' ');
|
|
|
+ int width= -1;
|
|
|
+ int height= -1;
|
|
|
+ for(int j= 0; j < currentLine.Length; j++)
|
|
|
+ {
|
|
|
+ if (currentLine[j].StartsWith("width"))
|
|
|
+ {
|
|
|
+ width = Convert.ToInt32(ParseSingleSVGAttribute(currentLine[j]));
|
|
|
+ }
|
|
|
+ else if (currentLine[j].StartsWith("height"))
|
|
|
+ {
|
|
|
+ height = Convert.ToInt32(ParseSingleSVGAttribute(currentLine[j]));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(width == -1)
|
|
|
+ {
|
|
|
+ throw new FileImporterException("missing width definition in SVG header", "the header should contain the \"width=...\" attribute", i+1);
|
|
|
+ }
|
|
|
+ if (height == -1)
|
|
|
+ {
|
|
|
+ throw new FileImporterException("missing height definition in SVG header", "the header should contain the \"height=...\" attribute", i + 1);
|
|
|
+ }
|
|
|
+ return (width, height);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// parses all relevant svg element definitions and skips the ones not representable by the sketch assistant
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="allLines">an array holding all lines of the input file</param>
|
|
|
+ /// <returns>the parsed picture as a list of lines</returns>
|
|
|
+ private List<Line> ParseSVGBody(String[] allLines)
|
|
|
+ {
|
|
|
+ List<Line> picture = new List<Line>();
|
|
|
+ while (!allLines[i].StartsWith("</svg"))
|
|
|
+ {
|
|
|
+ List<Line> element = ParseSingleSVGElement(allLines);
|
|
|
+ if (element != null)
|
|
|
+ {
|
|
|
+ picture.AddRange(element);
|
|
|
+ }
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ return picture;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// parses one toplevel svg element
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="allLines">an array holding all lines of the input file</param>
|
|
|
+ /// <returns>the parsed Element as a list of lines</returns>
|
|
|
+ private List<Line> ParseSingleSVGElement(string[] allLines)
|
|
|
+ {
|
|
|
+ String[] currentElement = GetCurrentElement(allLines);
|
|
|
+ if (currentElement[currentElement.Length - 1].EndsWith("/>")) //single line element
|
|
|
+ {
|
|
|
+ return ParseSingleLineSVGElement(currentElement);
|
|
|
+ }
|
|
|
+ else //element containing sub-elements
|
|
|
+ {
|
|
|
+ return ParseMultiLineSVGElement(currentElement, allLines);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// parses a single toplevel svg element only taking one line
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="allLines">an array holding all lines of the input file</param>
|
|
|
+ /// <returns>the parsed element as a Line object, or null if the element is not supported</returns>
|
|
|
+ private List<Line> ParseSingleLineSVGElement(string[] currentElement)
|
|
|
+ {
|
|
|
+ List<Point> points= null;
|
|
|
+ List<Line> element = null;
|
|
|
+ switch (currentElement[0])
|
|
|
+ {
|
|
|
+ case "<rect":
|
|
|
+ points = parseRect(currentElement);
|
|
|
+ break;
|
|
|
+ case "<circle":
|
|
|
+ points = parseCircle(currentElement);
|
|
|
+ break;
|
|
|
+ case "<ellipse":
|
|
|
+ points = parseEllipse(currentElement);
|
|
|
+ break;
|
|
|
+ case "<line":
|
|
|
+ points = parseLine(currentElement);
|
|
|
+ break;
|
|
|
+ case "<polyline":
|
|
|
+ points = parsePolyline(currentElement);
|
|
|
+ break;
|
|
|
+ case "<polygon":
|
|
|
+ points = parsePolygon(currentElement);
|
|
|
+ break;
|
|
|
+ case "<path":
|
|
|
+ element = parsePath(currentElement);
|
|
|
+ break;
|
|
|
+ default: //unsupported svg element
|
|
|
+ Console.WriteLine("unsupported element: " + currentElement[0] + currentElement[0].Length);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ if (element == null)
|
|
|
+ {
|
|
|
+ element = new List<Line>();
|
|
|
+ element.Add(new Line(points));
|
|
|
+ }
|
|
|
+ return element;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// parses a rectangle definition into a List of Points representing a single line around the rectangle (in clockwise direction)
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="currentElement">the definition of the element as whitespace seperated String[]</param>
|
|
|
+ /// <returns>the parsed element as a List of Points</returns>
|
|
|
+ private List<Point> parseRect(string[] currentElement)
|
|
|
+ {
|
|
|
+ double x = 0;
|
|
|
+ double y = 0;
|
|
|
+ double w = 0;
|
|
|
+ double h = 0;
|
|
|
+ double rx = 0;
|
|
|
+ double ry = 0;
|
|
|
+ for(int j= 0; j < currentElement.Length; j++)
|
|
|
+ {
|
|
|
+ if (currentElement[j].StartsWith("x="))
|
|
|
+ {
|
|
|
+ x = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ else if (currentElement[j].StartsWith("y="))
|
|
|
+ {
|
|
|
+ y = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ else if (currentElement[j].StartsWith("width="))
|
|
|
+ {
|
|
|
+ w = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ else if (currentElement[j].StartsWith("height="))
|
|
|
+ {
|
|
|
+ h = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ else if (currentElement[j].StartsWith("rx="))
|
|
|
+ {
|
|
|
+ rx = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ else if (currentElement[j].StartsWith("ry="))
|
|
|
+ {
|
|
|
+ ry = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<Point> rect = new List<Point>();
|
|
|
+ rect.Add(ScaleAndCreatePoint(x, y));
|
|
|
+ rect.Add(ScaleAndCreatePoint(x + w, y));
|
|
|
+ rect.Add(ScaleAndCreatePoint(x + w, y + h));
|
|
|
+ rect.Add(ScaleAndCreatePoint(x, y + h));
|
|
|
+ rect.Add(ScaleAndCreatePoint(x, y));
|
|
|
+ Console.WriteLine("parsed point: " + x + ";" + y);
|
|
|
+ return rect;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// parses a circle definition into a List of Points
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="currentElement">the definition of the element as whitespace seperated String[]</param>
|
|
|
+ /// <returns>the parsed element as a List of Points</returns>
|
|
|
+ private List<Point> parseCircle(string[] currentElement)
|
|
|
+ {
|
|
|
+ double x = 0;
|
|
|
+ double y = 0;
|
|
|
+ double r = 0;
|
|
|
+ for (int j = 0; j < currentElement.Length; j++)
|
|
|
+ {
|
|
|
+ if (currentElement[j].StartsWith("cx="))
|
|
|
+ {
|
|
|
+ x = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ else if (currentElement[j].StartsWith("cy="))
|
|
|
+ {
|
|
|
+ y = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ else if (currentElement[j].StartsWith("r="))
|
|
|
+ {
|
|
|
+ r = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return SampleEllipse(x, y, r, r);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// parses a ellipse definition into a List of Points
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="currentElement">the definition of the element as whitespace seperated String[]</param>
|
|
|
+ /// <returns>the parsed element as a List of Points</returns>
|
|
|
+ private List<Point> parseEllipse(string[] currentElement)
|
|
|
+ {
|
|
|
+ double x = 0;
|
|
|
+ double y = 0;
|
|
|
+ double rx = 0;
|
|
|
+ double ry = 0;
|
|
|
+ for (int j = 0; j < currentElement.Length; j++)
|
|
|
+ {
|
|
|
+ if (currentElement[j].StartsWith("cx="))
|
|
|
+ {
|
|
|
+ x = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ else if (currentElement[j].StartsWith("cy="))
|
|
|
+ {
|
|
|
+ y = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ else if (currentElement[j].StartsWith("rx="))
|
|
|
+ {
|
|
|
+ rx = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ else if (currentElement[j].StartsWith("ry="))
|
|
|
+ {
|
|
|
+ ry = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return SampleEllipse(x, y, rx, ry);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// parses a line definition into a List of two Points
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="currentElement">the definition of the element as whitespace seperated String[]</param>
|
|
|
+ /// <returns>the parsed element as a List of Points</returns>
|
|
|
+ private List<Point> parseLine(string[] currentElement)
|
|
|
+ {
|
|
|
+ double x1 = 0;
|
|
|
+ double y1 = 0;
|
|
|
+ double x2 = 0;
|
|
|
+ double y2 = 0;
|
|
|
+ for (int j = 0; j < currentElement.Length; j++)
|
|
|
+ {
|
|
|
+ if (currentElement[j].StartsWith("x1="))
|
|
|
+ {
|
|
|
+ x1 = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ else if (currentElement[j].StartsWith("y1="))
|
|
|
+ {
|
|
|
+ y1 = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ else if (currentElement[j].StartsWith("x2="))
|
|
|
+ {
|
|
|
+ x2 = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ else if (currentElement[j].StartsWith("y2="))
|
|
|
+ {
|
|
|
+ y2 = Convert.ToDouble(ParseSingleSVGAttribute(currentElement[j]), CultureInfo.InvariantCulture);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<Point> line = new List<Point>();
|
|
|
+ line.Add(ScaleAndCreatePoint(x1, y1));
|
|
|
+ line.Add(ScaleAndCreatePoint(x2, y2));
|
|
|
+ return line;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// parses a polyline definition into a List of Points
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="currentElement">the definition of the element as whitespace seperated String[]</param>
|
|
|
+ /// <returns>the parsed element as a List of Points</returns>
|
|
|
+ private List<Point> parsePolyline(string[] currentElement)
|
|
|
+ {
|
|
|
+ String[] points = null;
|
|
|
+ for (int j = 0; j < currentElement.Length; j++)
|
|
|
+ {
|
|
|
+ if (currentElement[j].StartsWith("points="))
|
|
|
+ {
|
|
|
+ List<String> pointDefs = new List<string>();
|
|
|
+ pointDefs.Add(currentElement[j].Substring(8)); //parse first point coordinates by removing 'points="'
|
|
|
+ j++;
|
|
|
+ while (!currentElement[j].EndsWith("\""))
|
|
|
+ {
|
|
|
+ pointDefs.Add(currentElement[j]); //parse intermediate point coordinates
|
|
|
+ j++;
|
|
|
+ }
|
|
|
+ pointDefs.Add(currentElement[j].Trim('"')); //parse last point coordinates by removing '"'
|
|
|
+ points = pointDefs.ToArray();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<Point> polyline = new List<Point>();
|
|
|
+ for (int k = 0; k < points.Length - 1; k += 2)
|
|
|
+ {
|
|
|
+ polyline.Add(ScaleAndCreatePoint(Convert.ToDouble(points[k], CultureInfo.InvariantCulture), Convert.ToDouble(points[k + 1], CultureInfo.InvariantCulture)));
|
|
|
+ }
|
|
|
+ return polyline;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// parses a polygon definition into a List of Points
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="currentElement">the definition of the element as whitespace seperated String[]</param>
|
|
|
+ /// <returns>the parsed element as a List of Points</returns>
|
|
|
+ private List<Point> parsePolygon(string[] currentElement)
|
|
|
+ {
|
|
|
+ String[] points = null;
|
|
|
+ for (int j = 0; j < currentElement.Length; j++)
|
|
|
+ {
|
|
|
+ if (currentElement[j].StartsWith("points="))
|
|
|
+ {
|
|
|
+ List<String> pointDefs = new List<string>();
|
|
|
+ pointDefs.Add(currentElement[j].Substring(8)); //parse first point coordinates by removing 'points="'
|
|
|
+ j++;
|
|
|
+ while (!currentElement[j].EndsWith("\""))
|
|
|
+ {
|
|
|
+ pointDefs.Add(currentElement[j]); //parse intermediate point coordinates
|
|
|
+ j++;
|
|
|
+ }
|
|
|
+ pointDefs.Add(currentElement[j].Trim('"')); //parse last point coordinates by removing '"'
|
|
|
+ points = pointDefs.ToArray();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<Point> polygon = new List<Point>();
|
|
|
+ for (int k = 0; k < points.Length - 1; k+=2)
|
|
|
+ {
|
|
|
+ polygon.Add(ScaleAndCreatePoint(Convert.ToDouble(points[k], CultureInfo.InvariantCulture), Convert.ToDouble(points[k+1], CultureInfo.InvariantCulture)));
|
|
|
+ Console.WriteLine("parsed point: " + points[k] + ";" + points[k + 1]);
|
|
|
+ }
|
|
|
+ polygon.Add(ScaleAndCreatePoint(Convert.ToDouble(points[0], CultureInfo.InvariantCulture), Convert.ToDouble(points[1], CultureInfo.InvariantCulture))); //close polygon
|
|
|
+ Console.WriteLine("parsed point: " + points[0] + ";" + points[1]);
|
|
|
+ return polygon;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// parses a path definition into a List of Points
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="currentElement">the definition of the element as whitespace seperated String[]</param>
|
|
|
+ /// <returns>the parsed element as a List of Points</returns>
|
|
|
+ private List<Line> parsePath(string[] currentElement)
|
|
|
+ {
|
|
|
+ List<String> pathElements = new List<string>();
|
|
|
+ for (int j = 0; j < currentElement.Length; j++)
|
|
|
+ {
|
|
|
+ if (currentElement[j].StartsWith("d="))
|
|
|
+ {
|
|
|
+ pathElements.Add(currentElement[j].Substring(3)); //parse first path element by removing 'd="'
|
|
|
+ j++;
|
|
|
+ while (!currentElement[j].EndsWith("\""))
|
|
|
+ {
|
|
|
+ pathElements.Add(currentElement[j]); //parse intermediate path element
|
|
|
+ j++;
|
|
|
+ }
|
|
|
+ pathElements.Add(currentElement[j].Trim('"')); //parse last path element by removing '"'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<Line> element = new List<Line>();
|
|
|
+ List<Point> currentLine = new List<Point>();
|
|
|
+ Point mirroredBezierPoint;
|
|
|
+ pathElements = PreparePathElements(pathElements); //split pathElement list objects until every object is atomar (single character or single number (coordinate))
|
|
|
+ //int k = 0; //index of active element in pathElements is always 0
|
|
|
+ currentLine = parse_M(pathElements);
|
|
|
+ while(!(pathElements.Count == 0){
|
|
|
+ if (pathElements.First().Equals("M"))
|
|
|
+ {
|
|
|
+ element.Add(new Line(currentLine));
|
|
|
+ currentLine = parse_M(pathElements);
|
|
|
+ }
|
|
|
+ else if (pathElements.First().Equals(""))
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return element;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// parses a hierarchical svg element and all its sub-elements
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="currentElement">the definition of the top level element as whitespace seperated String[]</param>
|
|
|
+ /// <param name="allLines">an array holding all lines of the input file</param>
|
|
|
+ /// <returns>the parsed element as a Line object, or null if the element is not supported</returns>
|
|
|
+ private List<Line> ParseMultiLineSVGElement(string[] currentElement, string[] allLines)
|
|
|
+ {
|
|
|
+ throw new NotImplementedException();
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// removes the name of the attribute aswell as the '="' at the beginning and the '"' or '">' at the end of an attribute definition
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="definition">the definition from the svg file</param>
|
|
|
+ /// <returns>the value of the attribute, as String (the part of definition contained between '"'s)</returns>
|
|
|
+ private String ParseSingleSVGAttribute(String definition)
|
|
|
+ {
|
|
|
+ return definition.Split('"')[1];
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// fetches a single svg element definition that may extend ovr several lines of the input file, iterates i to point to the last line of the element definition
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="allLines">an array holding all lines of the input file</param>
|
|
|
+ /// <returns>the definition of the current svg element, as String[] split by whitespaces</returns>
|
|
|
+ private String[] GetCurrentElement(String[] allLines)
|
|
|
+ {
|
|
|
+ List<String> currentElementTemp = allLines[i].Split(whitespaces).ToList();
|
|
|
+ while (!currentElementTemp.Last().EndsWith(">"))
|
|
|
+ {
|
|
|
+ i++;
|
|
|
+ currentElementTemp.AddRange(allLines[i].Split(whitespaces).ToList());
|
|
|
+ }
|
|
|
+ return currentElementTemp.ToArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// applies the scale factor to the coordinates and creates a new Point
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="x">unscaled x coordinate</param>
|
|
|
+ /// <param name="y">unscaled y coordinate</param>
|
|
|
+ /// <returns>new Point with scaled coordinates</returns>
|
|
|
+ private Point ScaleAndCreatePoint(double x, double y)
|
|
|
+ {
|
|
|
+ return new Point((int)Math.Round(x * scale), (int)Math.Round(y * scale));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// creates a representation of an ellipse as a List of Points by sampling the outline of the ellipse
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="x">x coordinate of the center of the ellipse</param>
|
|
|
+ /// <param name="y">y coordinate of the center of the ellipse</param>
|
|
|
+ /// <param name="rx">x radius of the ellipse</param>
|
|
|
+ /// <param name="ry">y radius of the ellipse</param>
|
|
|
+ /// <returns>the parsed element as a List of Points</returns>
|
|
|
+ private List<Point> SampleEllipse(double x, double y, double rx, double ry)
|
|
|
+ {
|
|
|
+ throw new NotImplementedException();
|
|
|
+ }
|
|
|
}
|
|
|
}
|