public SVGRadialGradientBrush(SVGRadialGradientElement radialGradElement, Rect bounds, SVGMatrix matrix) { _transform = matrix; _radialGradElement = radialGradElement; Initialize(); // SetGradientVector(bounds, matrix); CreateFill(); }
public SVGLinearGradientBrush(SVGLinearGradientElement linearGradElement, Rect bounds, SVGMatrix matrix) { _transform = matrix; _linearGradElement = linearGradElement; Initialize(); /* SetGradientVector(bounds, matrix); PreLocationProcess(); */ CreateFill(); }
public static List<Vector2> GetPath(SVGMatrix matrix, SVGPolylineElement svgElement) { List<Vector2> output = new List<Vector2>(svgElement.listPoints.Count + 1); List<Vector2> listPoints = svgElement.listPoints; for (int i = 0; i < listPoints.Count; i++) { output.Add(matrix.Transform(listPoints[i])); } // Douglas Peucker Reduction return SVGBezier.Optimise(output, SVGGraphics.vpm); }
//--------------------------------------- public SVGMatrix Multiply(SVGMatrix secondMatrix) { float sa, sb, sc, sd, se, sf; sa = secondMatrix.a; sb = secondMatrix.b; sc = secondMatrix.c; sd = secondMatrix.d; se = secondMatrix.e; sf = secondMatrix.f; return new SVGMatrix(a * sa + c * sb, b * sa + d * sb, a * sc + c * sd, b * sc + d * sd, a * se + c * sf + e, b * se + d * sf + f); }
public void SetRotate(float angle, float cx, float cy) { this._type = SVGTransformMode.Rotate; this._angle = angle; this._matrix = new SVGMatrix().Translate(cx, cy).Rotate(angle).Translate(-cx, -cy); }
public void SetScale(float sx, float sy) { this._type = SVGTransformMode.Scale; this._matrix = new SVGMatrix().ScaleNonUniform(sx, sy); }
public void SetMatrix(SVGMatrix matrix) { this._type = SVGTransformMode.Matrix; this._matrix = matrix; }
public void AppendItems(SVGTransformList newListItem) { _listTransform.AddRange(newListItem._listTransform); _totalMatrix = null; }
public void AppendItem(SVGTransform newItem) { _listTransform.Add(newItem); _totalMatrix = null; }
//const float defaultViewportScale = 800f; private static SVGMatrix GetFillTransform(SVGPaintable svgPaintable, Rect bounds) { SVGFill svgFill = svgPaintable.svgFill; SVGMatrix transform = new SVGMatrix(); SVGMatrix gradientMatrix = svgFill.gradientTransform; Rect viewport = svgPaintable.viewport; if (svgFill.fillType == FILL_TYPE.GRADIENT) { switch (svgFill.gradientType) { case GRADIENT_TYPE.LINEAR: { Vector2 startPoint = GetGradientVector(svgFill.gradientStartX, svgFill.gradientStartY, bounds); Vector2 endPoint = GetGradientVector(svgFill.gradientEndX, svgFill.gradientEndY, bounds); Vector2 gradientVector = endPoint - startPoint; Vector2 normalizedVector = Vector2.zero; float angle = Mathf.Atan2(gradientVector.y, gradientVector.x) * Mathf.Rad2Deg; Vector2 posDiff = Vector2.Lerp(startPoint, endPoint, 0.5f); float magnitude = gradientVector.magnitude; if(magnitude != 0f) { normalizedVector.x = viewport.width / magnitude; normalizedVector.y = viewport.height / magnitude; } transform = transform.Translate(viewport.center); transform = transform.ScaleNonUniform(normalizedVector.x, normalizedVector.y); transform = transform.Rotate(-angle); transform = transform.Translate(-posDiff); transform = transform.Multiply(gradientMatrix.Inverse()); transform = transform.Multiply(svgFill.transform.Inverse()); break; } case GRADIENT_TYPE.RADIAL: { Vector2 point = GetGradientVector(svgFill.gradientStartX, svgFill.gradientStartY, bounds); float radius = GetGradientVector(svgFill.gradientEndX, svgFill.gradientEndY, bounds).x; if(svgFill.gradientEndX.unitType == SVGLengthType.Percentage) radius *= 0.5f; float radiusTimesTwo = radius * 2f; Vector2 normalizedVector = Vector2.zero; if(radiusTimesTwo != 0f) { normalizedVector.x = viewport.width / radiusTimesTwo; normalizedVector.y = viewport.height / radiusTimesTwo; } transform = transform.Translate(viewport.center); transform = transform.ScaleNonUniform(normalizedVector.x, normalizedVector.y); transform = transform.Translate(-point); transform = transform.Multiply(gradientMatrix.Inverse()); transform = transform.Multiply(svgFill.transform.Inverse()); break; } case GRADIENT_TYPE.CONICAL: { Vector2 point = GetGradientVector(svgFill.gradientStartX, svgFill.gradientStartY, bounds); float radius = GetGradientVector(svgFill.gradientEndX, svgFill.gradientEndY, bounds).x; if(svgFill.gradientEndX.unitType == SVGLengthType.Percentage) radius *= 0.5f; float radiusTimesTwo = radius * 2f; Vector2 normalizedVector = Vector2.zero; if(radiusTimesTwo != 0f) { normalizedVector.x = viewport.width / radiusTimesTwo; normalizedVector.y = viewport.height / radiusTimesTwo; } transform = transform.Translate(viewport.center); transform = transform.ScaleNonUniform(normalizedVector.x, normalizedVector.y); transform = transform.Translate(-point); transform = transform.Multiply(gradientMatrix.Inverse()); transform = transform.Multiply(svgFill.transform.Inverse()); break; } } } return transform; }
public static Mesh CreatePolygon(List<Vector2> inputShapes, SVGPaintable paintable, SVGMatrix matrix, out Mesh antialiasingMesh) { if(inputShapes == null || inputShapes.Count == 0) { antialiasingMesh = null; return null; } return CreatePolygon(new List<List<Vector2>>(){inputShapes}, paintable, matrix, out antialiasingMesh); }
private void ReadClipPath(string clipPathValue) { if (clipPathValue.IndexOf("url") >= 0) { string clipPathURL = SVGStringExtractor.ExtractUrl(clipPathValue); if(!string.IsNullOrEmpty(clipPathURL) && SVGParser._defs.ContainsKey(clipPathURL)) { Node clipPathNode = SVGParser._defs[clipPathURL]; if(clipPathNode != null) { SVGMatrix svgMatrix = new SVGMatrix(); string clipPathUnitsString = clipPathNode.attributes.GetValue("clipPathUnits"); switch(clipPathUnitsString.ToLower()) { case "userSpaceOnUse": _clipPathUnits = SVGClipPathUnits.UserSpaceOnUse; break; case "objectBoundingBox": _clipPathUnits = SVGClipPathUnits.ObjectBoundingBox; break; } List<Node> clipPathNodes = clipPathNode.GetNodes(); List<List<Vector2>> currentClipPathList = new List<List<Vector2>>(); if(clipPathNodes != null && clipPathNodes.Count > 0) { for(int i = 0; i < clipPathNodes.Count; i++) { List<List<Vector2>> clipPath = GetClipPath(clipPathNodes[i], svgMatrix); if(clipPath != null) { currentClipPathList.AddRange(clipPath); } } } if(currentClipPathList.Count > 0) { currentClipPathList = SVGGeom.MergePolygon(currentClipPathList); } if(_clipPathList.Count > 0) { _clipPathList = SVGGeom.ClipPolygon(_clipPathList, currentClipPathList); } else { _clipPathList = currentClipPathList; } } } } }
private List<List<Vector2>> GetClipPath(Node node, SVGMatrix svgMatrix) { SVGTransformList transformList = new SVGTransformList(); switch (node.name) { case SVGNodeName.Rect: { return SVGRectElement.GetClipPath(svgMatrix, new SVGRectElement(node, transformList)); } case SVGNodeName.Line: { return SVGLineElement.GetClipPath(svgMatrix, new SVGLineElement(node, transformList)); } case SVGNodeName.Circle: { return SVGCircleElement.GetClipPath(svgMatrix, new SVGCircleElement(node, transformList)); } case SVGNodeName.Ellipse: { return SVGEllipseElement.GetClipPath(svgMatrix, new SVGEllipseElement(node, transformList)); } case SVGNodeName.PolyLine: { return SVGPolylineElement.GetClipPath(svgMatrix, new SVGPolylineElement(node, transformList)); } case SVGNodeName.Polygon: { return SVGPolygonElement.GetClipPath(svgMatrix, new SVGPolygonElement(node, transformList)); } case SVGNodeName.Path: { return SVGPathElement.GetClipPath(svgMatrix, new SVGPathElement(node, transformList)); } case SVGNodeName.Use: { string xlink = node.attributes.GetValue("xlink:href"); if (!string.IsNullOrEmpty(xlink)) { if (xlink [0] == '#') xlink = xlink.Remove(0, 1); if (SVGParser._defs.ContainsKey(xlink)) { Node definitionNode = SVGParser._defs [xlink]; if (definitionNode != null && definitionNode != node) { return GetClipPath(definitionNode, svgMatrix); } } } break; } } return null; }
public static List <Vector2> GetPath(SVGLineElement svgElement) { return(GetPath(SVGMatrix.Identity(), svgElement)); }
public SVGLinearGradientBrush(SVGLinearGradientElement linearGradElement, Rect bounds, SVGMatrix matrix) { _transform = matrix; _linearGradElement = linearGradElement; Initialize(); /* * SetGradientVector(bounds, matrix); * PreLocationProcess(); */ CreateFill(); }
public SVGTransform() { this._matrix = new SVGMatrix(); this._type = SVGTransformMode.Matrix; }
public SVGRadialGradientBrush(SVGRadialGradientElement radialGradElement, Rect bounds, SVGMatrix matrix, Rect viewport) { _viewport = viewport; _transform = matrix; _radialGradElement = radialGradElement; Initialize(); CreateFill(bounds); }
public static List<List<Vector2>> GetClipPath(SVGMatrix matrix, SVGEllipseElement svgElement) { List<Vector2> path = GetPath(matrix, svgElement); if(path == null || path.Count == 0) return null; List<List<Vector2>> clipPath = new List<List<Vector2>>(); if(svgElement.paintable.IsFill()) { clipPath.Add(path); } if(svgElement.paintable.IsStroke()) { List<StrokeSegment[]> segments = new List<StrokeSegment[]>(){SVGSimplePath.GetSegments(path)}; List<List<Vector2>> strokePath = SVGLineUtils.StrokeShape(segments, svgElement.paintable.strokeWidth, Color.black, SVGSimplePath.GetStrokeLineJoin(svgElement.paintable.strokeLineJoin), SVGSimplePath.GetStrokeLineCap(svgElement.paintable.strokeLineCap), svgElement.paintable.miterLimit, svgElement.paintable.dashArray, svgElement.paintable.dashOffset, ClosePathRule.ALWAYS, SVGGraphics.roundQuality); if(strokePath != null && strokePath.Count > 0) clipPath.AddRange(strokePath); } return clipPath; }
public static Mesh CreatePolygon(List<List<Vector2>> inputShapes, SVGPaintable paintable, SVGMatrix matrix, out Mesh antialiasingMesh) { antialiasingMesh = null; if(inputShapes == null || inputShapes.Count == 0) { return null; } List<List<Vector2>> simplifiedShapes = new List<List<Vector2>>(); PolyFillType fillType = PolyFillType.pftNonZero; if(paintable.fillRule == SVGFillRule.EvenOdd) { fillType = PolyFillType.pftEvenOdd; } simplifiedShapes = SVGGeom.SimplifyPolygons(inputShapes, fillType); if(simplifiedShapes == null || simplifiedShapes.Count == 0) return null; AddInputShape(simplifiedShapes); Rect bounds = GetRect(simplifiedShapes); switch (paintable.GetPaintType()) { case SVGPaintMethod.SolidGradientFill: { Color color = Color.black; SVGColorType colorType = paintable.fillColor.Value.colorType; if(colorType == SVGColorType.Unknown || colorType == SVGColorType.None) { color.a *= paintable.fillOpacity; paintable.svgFill = new SVGFill(color); } else { color = paintable.fillColor.Value.color; color.a *= paintable.fillOpacity; paintable.svgFill = new SVGFill(color); } paintable.svgFill.fillType = FILL_TYPE.SOLID; if(color.a == 1) { paintable.svgFill.blend = FILL_BLEND.OPAQUE; } else { paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED; } } break; case SVGPaintMethod.LinearGradientFill: { SVGLinearGradientBrush linearGradBrush = paintable.GetLinearGradientBrush(bounds, matrix); paintable.svgFill = linearGradBrush.fill; } break; case SVGPaintMethod.RadialGradientFill: { SVGRadialGradientBrush radialGradBrush = paintable.GetRadialGradientBrush(bounds, matrix); paintable.svgFill = radialGradBrush.fill; } break; case SVGPaintMethod.ConicalGradientFill: { SVGConicalGradientBrush conicalGradBrush = paintable.GetConicalGradientBrush(bounds, matrix); paintable.svgFill = conicalGradBrush.fill; } break; case SVGPaintMethod.PathDraw: { Color color = Color.black; SVGColorType colorType = paintable.fillColor.Value.colorType; if(colorType == SVGColorType.Unknown || colorType == SVGColorType.None) { color.a *= paintable.strokeOpacity; paintable.svgFill = new SVGFill(color); } else { color = paintable.fillColor.Value.color; color.a *= paintable.strokeOpacity; paintable.svgFill = new SVGFill(color); } paintable.svgFill.fillType = FILL_TYPE.SOLID; if(color.a == 1) { paintable.svgFill.blend = FILL_BLEND.OPAQUE; } else { paintable.svgFill.blend = FILL_BLEND.ALPHA_BLENDED; } } break; default: break; } LibTessDotNet.Tess tesselation = new LibTessDotNet.Tess(); LibTessDotNet.ContourVertex[] path; int pathLength; for(int i = 0; i < simplifiedShapes.Count; i++) { if(simplifiedShapes[i] == null) continue; pathLength = simplifiedShapes[i].Count; path = new LibTessDotNet.ContourVertex[pathLength]; Vector2 position; for(int j = 0; j < pathLength; j++) { position = simplifiedShapes[i][j]; path[j].Position = new LibTessDotNet.Vec3{X = position.x, Y = position.y, Z = 0f}; } tesselation.AddContour(path); } tesselation.Tessellate(LibTessDotNet.WindingRule.EvenOdd, LibTessDotNet.ElementType.Polygons, 3); Mesh mesh = new Mesh(); int meshVertexCount = tesselation.Vertices.Length; Vector3[] vertices = new Vector3[meshVertexCount]; Vector2[] uv = null; Vector2[] uv2 = null; for(int i = 0; i < meshVertexCount; i++) { vertices[i] = new Vector3(tesselation.Vertices[i].Position.X, tesselation.Vertices[i].Position.Y, 0f); } int numTriangles = tesselation.ElementCount; int[] triangles = new int[numTriangles * 3]; for (int i = 0; i < numTriangles; i++) { triangles[i * 3] = tesselation.Elements[i * 3]; triangles[i * 3 + 1] = tesselation.Elements[i * 3 + 1]; triangles[i * 3 + 2] = tesselation.Elements[i * 3 + 2]; } SVGFill svgFill = paintable.svgFill; Color32 fillColor = Color.white; if (svgFill.fillType != FILL_TYPE.GRADIENT && svgFill.gradientColors == null) fillColor = svgFill.color; antialiasingMesh = CreateAntialiasing(simplifiedShapes, fillColor, -SVGAssetImport.antialiasingWidth, false, SVGImporter.Utils.ClosePathRule.ALWAYS); Color32[] colors32 = new Color32[meshVertexCount]; for (int i = 0; i < meshVertexCount; i++) { colors32 [i].r = fillColor.r; colors32 [i].g = fillColor.g; colors32 [i].b = fillColor.b; colors32 [i].a = fillColor.a; } if(antialiasingMesh != null) { Vector3[] antialiasingVertices = antialiasingMesh.vertices; Vector2[] antialiasingUV = antialiasingMesh.uv; Vector2[] antialiasingUV2 = antialiasingMesh.uv2; WriteUVGradientCoordinates(ref antialiasingUV, antialiasingVertices, paintable, bounds); WriteUVGradientIndexType(ref antialiasingUV2, antialiasingVertices.Length, paintable); antialiasingMesh.uv = antialiasingUV; antialiasingMesh.uv2 = antialiasingUV2; } WriteUVGradientCoordinates(ref uv, vertices, paintable, bounds); WriteUVGradientIndexType(ref uv2, meshVertexCount, paintable); mesh.vertices = vertices; mesh.triangles = triangles; if(colors32 != null) mesh.colors32 = colors32; if(uv != null) mesh.uv = uv; if(uv2 != null) mesh.uv2 = uv2; return mesh; }
public static List<Vector2> Ellipse(float cx, float cy, float rx, float ry, SVGMatrix matrix) { List<Vector2> output = new List<Vector2>(); cx -= rx; cy -= ry; float handleDistanceX = circleConstant * rx; float handleDistanceY = circleConstant * ry; Vector2 handleRight = new Vector2(handleDistanceX, 0f); Vector2 handleLeft = new Vector2(-handleDistanceX, 0f); Vector2 handleUp = new Vector2(0f, -handleDistanceY); Vector2 handleDown = new Vector2(0f, handleDistanceY); Vector2 topCenter = new Vector2(cx + rx, cy); Vector2 left = new Vector2(cx, cy + ry); // Vector2 center = new Vector2(cx + rx, cy + ry); Vector2 right = new Vector2(cx + rx * 2f, cy + ry ); Vector2 bottomCenter = new Vector2(cx + rx, cy + ry * 2f); output.AddRange(SVGGeomUtils.CubicCurve(matrix.Transform(topCenter), matrix.Transform(topCenter + handleRight), matrix.Transform(right + handleUp), matrix.Transform(right))); output.AddRange(SVGGeomUtils.CubicCurve(matrix.Transform(right), matrix.Transform(right + handleDown), matrix.Transform(bottomCenter + handleRight), matrix.Transform(bottomCenter))); output.AddRange(SVGGeomUtils.CubicCurve(matrix.Transform(bottomCenter), matrix.Transform(bottomCenter + handleLeft), matrix.Transform(left + handleDown), matrix.Transform(left))); output.AddRange(SVGGeomUtils.CubicCurve(matrix.Transform(left), matrix.Transform(left + handleUp), matrix.Transform(topCenter + handleLeft), matrix.Transform(topCenter))); return output; }
public void Clear() { _listTransform.Clear(); _totalMatrix = null; }
public static List<Vector2> GetPath(SVGMatrix matrix, SVGEllipseElement svgElement) { List<Vector2> output = Ellipse(svgElement.cx.value, svgElement.cy.value, svgElement.rx.value, svgElement.ry.value, matrix); output.Add(output[0]); return output; }
public void AppendItemAt(SVGTransform newItem, int index) { _listTransform.Insert(index, newItem); _totalMatrix = null; }
public static SVGMatrix GetViewBoxTransform(AttributeList attributeList, ref Rect viewport, bool negotiate = false) { SVGMatrix matrix = new SVGMatrix(); float x = 0.0f; float y = 0.0f; float w = 0.0f; float h = 0.0f; string preserveAspectRatio = attributeList.GetValue("preserveAspectRatio"); string viewBox = attributeList.GetValue("viewBox"); if (!string.IsNullOrEmpty(viewBox)) { string[] viewBoxValues = SVGStringExtractor.ExtractTransformValue(viewBox); if(viewBoxValues.Length == 4) { Rect contentRect = new Rect( new SVGLength(viewBoxValues[0]).value, new SVGLength(viewBoxValues[1]).value, new SVGLength(viewBoxValues[2]).value, new SVGLength(viewBoxValues[3]).value ); SVGViewport.Align align = SVGViewport.Align.xMidYMid; SVGViewport.MeetOrSlice meetOrSlice = SVGViewport.MeetOrSlice.Meet; if(!string.IsNullOrEmpty(preserveAspectRatio)) { string[] aspectRatioValues = SVGStringExtractor.ExtractStringArray(preserveAspectRatio); align = SVGViewport.GetAlignFromStrings(aspectRatioValues); meetOrSlice = SVGViewport.GetMeetOrSliceFromStrings(aspectRatioValues); } Rect oldViewport = viewport; viewport = SVGViewport.GetViewport(viewport, contentRect, align, meetOrSlice); float sizeX = 0f, sizeY = 0f; if(oldViewport.size.x != 0f) sizeX = viewport.size.x / oldViewport.size.x; if(oldViewport.size.y != 0f) sizeY = viewport.size.y / oldViewport.size.y; matrix.ScaleNonUniform(sizeX, sizeY); matrix = matrix.Translate(viewport.x - oldViewport.x, viewport.y - oldViewport.y); } } else { if(negotiate) { string attrXString = attributeList.GetValue("x"); string attrYString = attributeList.GetValue("y"); string attrWidthString = attributeList.GetValue("width"); string attrHeightString = attributeList.GetValue("height"); SVGLength attrX = new SVGLength(SVGLengthType.PX, 0f), attrY = new SVGLength(SVGLengthType.PX, 0f), attrWidth = new SVGLength(SVGLengthType.PX, 1f), attrHeight = new SVGLength(SVGLengthType.PX, 1f); if(!string.IsNullOrEmpty(attrXString)) { attrX = new SVGLength(attrXString); } if(!string.IsNullOrEmpty(attrYString)) { attrY = new SVGLength(attrYString); } if(!string.IsNullOrEmpty(attrWidthString)) { attrWidth = new SVGLength(attrWidthString); } if(!string.IsNullOrEmpty(attrHeightString)) { attrHeight = new SVGLength(attrHeightString); } x = attrX.value; y = attrY.value; w = attrWidth.value; h = attrHeight.value; float x_ratio = 1f; if(w != 0f) x_ratio = attrWidth.value / w; float y_ratio = 1f; if(h != 0f) y_ratio = attrHeight.value / h; matrix = matrix.ScaleNonUniform(x_ratio, y_ratio); matrix = matrix.Translate(x, y); viewport = new Rect(x, y, w, h); // Debug.Log(string.Format("x: {0}, y: {1}, width: {2}, height: {3}, attrWidth: {4}, attrHeight: {5}", x, y, w, h, attrWidth, attrHeight)); } // Debug.Log(string.Format("x: {0}, y: {1}, width: {2}, height: {3}, attrWidth: {4}, attrHeight: {5}", x, y, w, h, attrWidth, attrHeight)); } return matrix; }
public void AppendItemsAt(SVGTransformList newListItem, int index) { _listTransform.InsertRange(index, newListItem._listTransform); _totalMatrix = null; }
public static SVGMatrix GetRootViewBoxTransform(AttributeList attributeList, ref Rect viewport) { SVGMatrix matrix = new SVGMatrix(); float x = 0.0f; float y = 0.0f; float w = 0.0f; float h = 0.0f; string attrXString = attributeList.GetValue("x"); string attrYString = attributeList.GetValue("y"); string attrWidthString = attributeList.GetValue("width"); string attrHeightString = attributeList.GetValue("height"); SVGLength attrX = new SVGLength(SVGLengthType.PX, 0f), attrY = new SVGLength(SVGLengthType.PX, 0f), attrWidth = new SVGLength(SVGLengthType.PX, 1f), attrHeight = new SVGLength(SVGLengthType.PX, 1f); if(!string.IsNullOrEmpty(attrXString)) { attrX = new SVGLength(attrXString); } if(!string.IsNullOrEmpty(attrYString)) { attrY = new SVGLength(attrYString); } if(!string.IsNullOrEmpty(attrWidthString)) { attrWidth = new SVGLength(attrWidthString); } if(!string.IsNullOrEmpty(attrHeightString)) { attrHeight = new SVGLength(attrHeightString); } string viewBox = attributeList.GetValue("viewBox"); if (!string.IsNullOrEmpty(viewBox)) { string[] _temp = SVGStringExtractor.ExtractTransformValue(viewBox); if (_temp.Length > 0) { if(string.IsNullOrEmpty(attrXString)) { attrX = new SVGLength(_temp [0]); } } if (_temp.Length > 1) { if(string.IsNullOrEmpty(attrYString)) { attrY = new SVGLength(_temp [1]); } } if (_temp.Length > 2) { if(string.IsNullOrEmpty(attrWidthString)) { attrWidth = new SVGLength(_temp [2]); } } if (_temp.Length > 3) { if(string.IsNullOrEmpty(attrHeightString)) { attrHeight = new SVGLength(_temp [3]); } } viewport = new Rect(attrX.value, attrY.value, attrWidth.value, attrHeight.value); if(string.IsNullOrEmpty(attrXString)) { viewport.x = attrX.value; } if(string.IsNullOrEmpty(attrYString)) { viewport.y = attrY.value; } if(string.IsNullOrEmpty(attrWidthString)) { viewport.width = attrWidth.value; } if(string.IsNullOrEmpty(attrHeightString)) { viewport.height = attrHeight.value; } } else { viewport = new Rect(attrX.value, attrY.value, attrWidth.value, attrHeight.value); } return matrix; }
public void SetTranslate(float tx, float ty) { this._type = SVGTransformMode.Translate; this._matrix = new SVGMatrix().Translate(tx, ty); }
public static List<List<Vector2>> GetPaths(SVGMatrix matrix, SVGPathElement svgElement) { lastCommand = SVGPathSegTypes.Unknown; List<Vector2> positionBuffer = new List<Vector2>(); List<List<Vector2>> output = new List<List<Vector2>>(); SVGPathSegList segList = svgElement.segList; for (int i = 0; i < segList.Count; i++) { GetSegment(svgElement, segList.GetItem(i), output, positionBuffer, matrix); } if(lastCommand != SVGPathSegTypes.Close && positionBuffer.Count > 0) { output.Add(new List<Vector2>(positionBuffer.ToArray())); } //Vector2 startPoint, endPoint; for(int i = 0; i < output.Count; i++) { // Ramer Douglas Peucker Reduction if(output[i] == null || output[i].Count < 3) continue; output[i] = SVGBezier.Optimise(output[i], SVGGraphics.vpm); } return output; }
public void SetRotate(float angle) { this._type = SVGTransformMode.Rotate; this._angle = angle; this._matrix = new SVGMatrix().Rotate(angle); }
public static List<List<Vector2>> GetClipPath(SVGMatrix matrix, SVGPathElement svgElement) { List<List<Vector2>> path = GetPaths(matrix, svgElement); if(path == null || path.Count == 0) return null; List<List<Vector2>> clipPath = new List<List<Vector2>>(); if(svgElement.paintable.IsFill()) { clipPath.AddRange(path); } if(svgElement.paintable.IsStroke()) { List<StrokeSegment[]> segments = new List<StrokeSegment[]>(); for(int i = 0; i < path.Count; i++) { if(path[i] == null || path[i].Count < 2) continue; segments.Add(SVGSimplePath.GetSegments(path[i])); } List<List<Vector2>> strokePath = SVGLineUtils.StrokeShape(segments, svgElement.paintable.strokeWidth, Color.black, SVGSimplePath.GetStrokeLineJoin(svgElement.paintable.strokeLineJoin), SVGSimplePath.GetStrokeLineCap(svgElement.paintable.strokeLineCap), svgElement.paintable.miterLimit, svgElement.paintable.dashArray, svgElement.paintable.dashOffset, ClosePathRule.AUTO, SVGGraphics.roundQuality); if(strokePath != null && strokePath.Count > 0) clipPath.AddRange(strokePath); } return clipPath; }
public void SetSkewY(float angle) { this._type = SVGTransformMode.SkewY; this._angle = angle; this._matrix = new SVGMatrix().SkewY(angle); }
static bool GetSegment(SVGPathElement svgElement, SVGPathSeg segment, List<List<Vector2>> output, List<Vector2> positionBuffer, SVGMatrix matrix) { if (segment == null) return false; // Debug.Log("command: "+segment.type+", lastCommand: "+lastCommand); switch (segment.type) { case SVGPathSegTypes.Arc_Abs: SVGPathSegArcAbs arcAbs = segment as SVGPathSegArcAbs; #if PATH_COMMAND_DEBUG Debug.Log("arcAbs"); #endif positionBuffer.AddRange(SVGGeomUtils.Arc(SVGGeomUtils.TransformPoint(arcAbs.previousPoint, matrix), arcAbs.r1, arcAbs.r2, arcAbs.angle, arcAbs.largeArcFlag, arcAbs.sweepFlag, SVGGeomUtils.TransformPoint(arcAbs.currentPoint, matrix))); break; case SVGPathSegTypes.Arc_Rel: SVGPathSegArcRel arcRel = segment as SVGPathSegArcRel; #if PATH_COMMAND_DEBUG Debug.Log("arcRel"); #endif positionBuffer.AddRange(SVGGeomUtils.Arc(SVGGeomUtils.TransformPoint(arcRel.previousPoint, matrix), arcRel.r1, arcRel.r2, arcRel.angle, arcRel.largeArcFlag, arcRel.sweepFlag, SVGGeomUtils.TransformPoint(arcRel.currentPoint, matrix))); break; case SVGPathSegTypes.Close: #if PATH_COMMAND_DEBUG Debug.Log("Close"); #endif //Debug.Log("Close"); if(positionBuffer.Count > 0) { output.Add(new List<Vector2>(positionBuffer.ToArray())); } positionBuffer.Clear(); break; case SVGPathSegTypes.CurveTo_Cubic_Abs: SVGPathSegCurvetoCubicAbs curvetoCubicAbs = segment as SVGPathSegCurvetoCubicAbs; #if PATH_COMMAND_DEBUG Debug.Log("curvetoCubicAbs"); #endif positionBuffer.AddRange(SVGGeomUtils.CubicCurve(SVGGeomUtils.TransformPoint(curvetoCubicAbs.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoCubicAbs.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoCubicAbs.controlPoint2, matrix), SVGGeomUtils.TransformPoint(curvetoCubicAbs.currentPoint, matrix))); break; case SVGPathSegTypes.CurveTo_Cubic_Rel: SVGPathSegCurvetoCubicRel curvetoCubicRel = segment as SVGPathSegCurvetoCubicRel; #if PATH_COMMAND_DEBUG Debug.Log("curvetoCubicRel"); #endif positionBuffer.AddRange(SVGGeomUtils.CubicCurve(SVGGeomUtils.TransformPoint(curvetoCubicRel.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoCubicRel.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoCubicRel.controlPoint2, matrix), SVGGeomUtils.TransformPoint(curvetoCubicRel.currentPoint, matrix))); break; case SVGPathSegTypes.CurveTo_Cubic_Smooth_Abs: SVGPathSegCurvetoCubicSmoothAbs curvetoCubicSmoothAbs = segment as SVGPathSegCurvetoCubicSmoothAbs; #if PATH_COMMAND_DEBUG Debug.Log("curvetoCubicSmoothAbs"); #endif positionBuffer.AddRange(SVGGeomUtils.CubicCurve(SVGGeomUtils.TransformPoint(curvetoCubicSmoothAbs.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoCubicSmoothAbs.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoCubicSmoothAbs.controlPoint2, matrix), SVGGeomUtils.TransformPoint(curvetoCubicSmoothAbs.currentPoint, matrix))); break; case SVGPathSegTypes.CurveTo_Cubic_Smooth_Rel: SVGPathSegCurvetoCubicSmoothRel curvetoCubicSmoothRel = segment as SVGPathSegCurvetoCubicSmoothRel; #if PATH_COMMAND_DEBUG Debug.Log("curvetoCubicSmoothRel"); #endif positionBuffer.AddRange(SVGGeomUtils.CubicCurve(SVGGeomUtils.TransformPoint(curvetoCubicSmoothRel.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoCubicSmoothRel.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoCubicSmoothRel.controlPoint2, matrix), SVGGeomUtils.TransformPoint(curvetoCubicSmoothRel.currentPoint, matrix))); break; case SVGPathSegTypes.CurveTo_Quadratic_Abs: SVGPathSegCurvetoQuadraticAbs curvetoQuadraticAbs = segment as SVGPathSegCurvetoQuadraticAbs; #if PATH_COMMAND_DEBUG Debug.Log("curvetoQuadraticAbs"); #endif positionBuffer.AddRange(SVGGeomUtils.QuadraticCurve(SVGGeomUtils.TransformPoint(curvetoQuadraticAbs.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticAbs.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticAbs.currentPoint, matrix))); break; case SVGPathSegTypes.CurveTo_Quadratic_Rel: SVGPathSegCurvetoQuadraticRel curvetoQuadraticRel = segment as SVGPathSegCurvetoQuadraticRel; #if PATH_COMMAND_DEBUG Debug.Log("curvetoQuadraticRel"); #endif positionBuffer.AddRange(SVGGeomUtils.QuadraticCurve(SVGGeomUtils.TransformPoint(curvetoQuadraticRel.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticRel.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticRel.currentPoint, matrix))); break; case SVGPathSegTypes.CurveTo_Quadratic_Smooth_Abs: SVGPathSegCurvetoQuadraticSmoothAbs curvetoQuadraticSmoothAbs = segment as SVGPathSegCurvetoQuadraticSmoothAbs; #if PATH_COMMAND_DEBUG Debug.Log("curvetoQuadraticSmoothAbs"); #endif positionBuffer.AddRange(SVGGeomUtils.QuadraticCurve(SVGGeomUtils.TransformPoint(curvetoQuadraticSmoothAbs.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticSmoothAbs.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticSmoothAbs.currentPoint, matrix))); break; case SVGPathSegTypes.CurveTo_Quadratic_Smooth_Rel: SVGPathSegCurvetoQuadraticSmoothRel curvetoQuadraticSmoothRel = segment as SVGPathSegCurvetoQuadraticSmoothRel; #if PATH_COMMAND_DEBUG Debug.Log("curvetoQuadraticSmoothRel"); #endif positionBuffer.AddRange(SVGGeomUtils.QuadraticCurve(SVGGeomUtils.TransformPoint(curvetoQuadraticSmoothRel.previousPoint, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticSmoothRel.controlPoint1, matrix), SVGGeomUtils.TransformPoint(curvetoQuadraticSmoothRel.currentPoint, matrix))); break; case SVGPathSegTypes.LineTo_Abs: SVGPathSegLinetoAbs linetoAbs = segment as SVGPathSegLinetoAbs; #if PATH_COMMAND_DEBUG Debug.Log("linetoAbs"); #endif positionBuffer.Add(SVGGeomUtils.TransformPoint(linetoAbs.currentPoint, matrix)); break; case SVGPathSegTypes.LineTo_Horizontal_Abs: #if PATH_COMMAND_DEBUG Debug.Log("linetoHorizontalAbs"); #endif SVGPathSegLinetoHorizontalAbs linetoHorizontalAbs = segment as SVGPathSegLinetoHorizontalAbs; positionBuffer.Add(SVGGeomUtils.TransformPoint(linetoHorizontalAbs.currentPoint, matrix)); break; case SVGPathSegTypes.LineTo_Horizontal_Rel: #if PATH_COMMAND_DEBUG Debug.Log("linetoHorizontalRel"); #endif SVGPathSegLinetoHorizontalRel linetoHorizontalRel = segment as SVGPathSegLinetoHorizontalRel; positionBuffer.Add(SVGGeomUtils.TransformPoint(linetoHorizontalRel.currentPoint, matrix)); break; case SVGPathSegTypes.LineTo_Rel: SVGPathSegLinetoRel linetoRel = segment as SVGPathSegLinetoRel; #if PATH_COMMAND_DEBUG Debug.Log("linetoRel"); #endif positionBuffer.Add(SVGGeomUtils.TransformPoint(linetoRel.currentPoint, matrix)); break; case SVGPathSegTypes.LineTo_Vertical_Abs: SVGPathSegLinetoVerticalAbs linetoVerticalAbs = segment as SVGPathSegLinetoVerticalAbs; #if PATH_COMMAND_DEBUG Debug.Log("linetoVerticalAbs"); #endif positionBuffer.Add(SVGGeomUtils.TransformPoint(linetoVerticalAbs.currentPoint, matrix)); break; case SVGPathSegTypes.LineTo_Vertical_Rel: SVGPathSegLinetoVerticalRel linetoVerticalRel = segment as SVGPathSegLinetoVerticalRel; #if PATH_COMMAND_DEBUG Debug.Log("linetoVerticalRel"); #endif positionBuffer.Add(SVGGeomUtils.TransformPoint(linetoVerticalRel.currentPoint, matrix)); break; case SVGPathSegTypes.MoveTo_Abs: if(lastCommand != SVGPathSegTypes.Close && lastCommand != SVGPathSegTypes.MoveTo_Abs && lastCommand != SVGPathSegTypes.MoveTo_Rel) { if(positionBuffer.Count > 0) { output.Add(new List<Vector2>(positionBuffer.ToArray())); positionBuffer.Clear(); } } SVGPathSegMovetoAbs movetoAbs = segment as SVGPathSegMovetoAbs; #if PATH_COMMAND_DEBUG Debug.Log("movetoAbs"); #endif positionBuffer.Add(SVGGeomUtils.TransformPoint(movetoAbs.currentPoint, matrix)); break; case SVGPathSegTypes.MoveTo_Rel: if(lastCommand != SVGPathSegTypes.Close && lastCommand != SVGPathSegTypes.MoveTo_Abs && lastCommand != SVGPathSegTypes.MoveTo_Rel) { if(positionBuffer.Count > 0) { output.Add(new List<Vector2>(positionBuffer.ToArray())); positionBuffer.Clear(); } } SVGPathSegMovetoRel movetoRel = segment as SVGPathSegMovetoRel; #if PATH_COMMAND_DEBUG Debug.Log("movetoRel"); #endif positionBuffer.Add(SVGGeomUtils.TransformPoint(movetoRel.currentPoint, matrix)); break; } lastCommand = segment.type; return true; }
public SVGTransform(SVGMatrix matrix) { this._type = SVGTransformMode.Matrix; this._matrix = matrix; }
public SVGConicalGradientBrush(SVGConicalGradientElement conicalGradElement, Rect bounds, SVGMatrix matrix) { _transform = matrix; _conicalGradElement = conicalGradElement; Initialize(); // SetGradientVector(bounds, matrix); CreateFill(); }