private List <GraphicsPath> GetPath(List <IShapeData> shapes, bool isFilled) { List <GraphicsPath> result = new List <GraphicsPath>(); if (shapes.Count == 0) { return(result); } DDW.Vex.Point endPoint = shapes[0].EndPoint; GraphicsPath gp = new GraphicsPath(); gp.FillMode = FillMode.Alternate; result.Add(gp); for (int i = 0; i < shapes.Count; i++) { IShapeData sd = shapes[i]; if (sd.StartPoint != endPoint) { if (isFilled) { gp.CloseFigure(); } else { gp = new GraphicsPath(); gp.FillMode = FillMode.Alternate; result.Add(gp); } } switch (sd.SegmentType) { case SegmentType.Line: Line l = (Line)sd; gp.AddLine(l.Anchor0.X, l.Anchor0.Y, l.Anchor1.X, l.Anchor1.Y); break; case SegmentType.CubicBezier: CubicBezier cb = (CubicBezier)sd; gp.AddBezier( cb.Anchor0.X, cb.Anchor0.Y, cb.Control0.X, cb.Control0.Y, cb.Control1.X, cb.Control1.Y, cb.Anchor1.X, cb.Anchor1.Y); break; case SegmentType.QuadraticBezier: QuadBezier qb = (QuadBezier)sd; CubicBezier qtc = qb.GetCubicBezier(); gp.AddBezier( qtc.Anchor0.X, qtc.Anchor0.Y, qtc.Control0.X, qtc.Control0.Y, qtc.Control1.X, qtc.Control1.Y, qtc.Anchor1.X, qtc.Anchor1.Y); break; } endPoint = sd.EndPoint; } if (isFilled) { gp.CloseFigure(); } return(result); }
protected override void RenderPath(FillStyle fs, StrokeStyle ss, List <IShapeData> sh, bool silverlight) { // <Path Fill="#FFFF0000" // StrokeThickness="0.00491913" StrokeLineJoin="Round" Stroke="#FF014393" // Data="M 196.667,4L 388.667,100L 388.667,292L 196.667,388L 4.66669,292L 4.66669,100L 196.667,4 Z "/> if (sh.Count == 0) { return; } xw.WriteStartElement("Path"); bool isGradient = false; bool isTiledBitmap = false; if (fs != null) { if (fs.FillType == FillType.Solid) { Color c = ((SolidFill)fs).Color; xw.WriteStartAttribute("Fill"); xw.WriteColor(c); xw.WriteEndAttribute(); // try to clean up faint edges if (ss == null && c != new Color(0xFF, 0xFF, 0xFF) && c.A != 0) { ss = new SolidStroke(0.3F, c); } } else if ( fs.FillType == FillType.Linear || fs.FillType == FillType.Radial || fs.FillType == FillType.Focal) { isGradient = true; } else if (fs.FillType == FillType.Image) { // Fill="{StaticResource vb_1}" ImageFill img = (ImageFill)fs; if (img.IsTiled || silverlight) { isTiledBitmap = true;// this causes bitmap to be written inline } else { string brushName = imageBrushes[img.ImagePath]; xw.WriteStartAttribute("Fill"); xw.WriteValue("{StaticResource " + brushName + "}"); xw.WriteEndAttribute(); } } } if (ss != null) { if (ss is SolidStroke) { // StrokeThickness="3" StrokeLineJoin="Round" Stroke="#FF014393" // StrokeStartLineCap="Round" // StrokeEndLineCap="Round" SolidStroke st = (SolidStroke)ss; xw.WriteStartAttribute("StrokeThickness"); xw.WriteFloat(st.LineWidth); xw.WriteEndAttribute(); xw.WriteStartAttribute("StrokeLineJoin"); xw.WriteString("Round"); xw.WriteEndAttribute(); xw.WriteStartAttribute("StrokeStartLineCap"); xw.WriteString("Round"); xw.WriteEndAttribute(); xw.WriteStartAttribute("StrokeEndLineCap"); xw.WriteString("Round"); xw.WriteEndAttribute(); xw.WriteStartAttribute("Stroke"); xw.WriteColor(st.Color); xw.WriteEndAttribute(); } } float minX = float.PositiveInfinity; float minY = float.PositiveInfinity; float maxX = float.NegativeInfinity; float maxY = float.NegativeInfinity; xw.WriteStartAttribute("Data"); xw.WriteMoveTo(sh[0].StartPoint); Point lastPoint = sh[0].StartPoint; for (int i = 0; i < sh.Count; i++) { IShapeData sd = sh[i]; if (lastPoint != sd.StartPoint) { xw.WriteMoveTo(sd.StartPoint); } switch (sd.SegmentType) { case SegmentType.Line: xw.WriteLineTo(sd.EndPoint); lastPoint = sd.EndPoint; break; case SegmentType.CubicBezier: CubicBezier cb = (CubicBezier)sd; xw.WriteCubicCurveTo(cb.Control0, cb.Control1, cb.Anchor1); lastPoint = cb.EndPoint; minX = Math.Min(minX, cb.Control0.X); maxX = Math.Max(maxX, cb.Control0.X); minY = Math.Min(minY, cb.Control0.Y); maxY = Math.Max(maxY, cb.Control0.Y); minX = Math.Min(minX, cb.Control1.X); maxX = Math.Max(maxX, cb.Control1.X); minY = Math.Min(minY, cb.Control1.Y); maxY = Math.Max(maxY, cb.Control1.Y); break; case SegmentType.QuadraticBezier: QuadBezier qb = (QuadBezier)sd; xw.WriteQuadraticCurveTo(qb.Control, qb.Anchor1); lastPoint = qb.EndPoint; minX = Math.Min(minX, qb.Control.X); maxX = Math.Max(maxX, qb.Control.X); minY = Math.Min(minY, qb.Control.Y); maxY = Math.Max(maxY, qb.Control.Y); break; } // need bounds for gradient :( if (isGradient) { minX = Math.Min(minX, sd.StartPoint.X); maxX = Math.Max(maxX, sd.StartPoint.X); minY = Math.Min(minY, sd.StartPoint.Y); maxY = Math.Max(maxY, sd.StartPoint.Y); minX = Math.Min(minX, sd.EndPoint.X); maxX = Math.Max(maxX, sd.EndPoint.X); minY = Math.Min(minY, sd.EndPoint.Y); maxY = Math.Max(maxY, sd.EndPoint.Y); } } xw.WriteEndAttribute(); if (isGradient) { GradientFill gf = (GradientFill)fs; // need a gradient def here if (fs.FillType == FillType.Linear) { //<Path.Fill> // <LinearGradientBrush StartPoint="0.14706,0.532137" EndPoint="1.14962,0.55353"> // <LinearGradientBrush.GradientStops> // <GradientStop Color="#FF4A4A4A" Offset="0"/> // <GradientStop Color="#FFB0B0B0" Offset="0.412067"/> // <GradientStop Color="#FFBBBBBB" Offset="0.638141"/> // <GradientStop Color="#FF545454" Offset="1"/> // </LinearGradientBrush.GradientStops> // </LinearGradientBrush> //</Path.Fill> xw.WriteStartElement("Path.Fill"); xw.WriteStartElement("LinearGradientBrush"); Matrix m = gf.Transform; Rectangle r = GradientFill.GradientVexRect; sysDraw2D.Matrix m2 = new sysDraw2D.Matrix(m.ScaleX, m.Rotate0, m.Rotate1, m.ScaleY, m.TranslateX, m.TranslateY); float midY = r.Point.Y + (r.Size.Height / 2); sysDraw.PointF pt0 = new sysDraw.PointF(r.Point.X, midY); sysDraw.PointF pt1 = new sysDraw.PointF(r.Point.X + r.Size.Width, midY); sysDraw.PointF[] pts = new sysDraw.PointF[] { pt0, pt1 }; m2.TransformPoints(pts); float ratX = 1 / (maxX - minX); float ratY = 1 / (maxY - minY); float d0x = (pts[0].X - minX) * ratX; float d0y = (pts[0].Y - minY) * ratY; float d1x = (pts[1].X - minX) * ratX; float d1y = (pts[1].Y - minY) * ratY; xw.WriteStartAttribute("StartPoint"); xw.WritePoint(new Point(d0x, d0y)); xw.WriteEndAttribute(); xw.WriteStartAttribute("EndPoint"); xw.WritePoint(new Point(d1x, d1y)); xw.WriteEndAttribute(); xw.WriteStartAttribute("SpreadMethod"); xw.WriteValue("Pad"); xw.WriteEndAttribute(); xw.WriteStartElement("LinearGradientBrush.GradientStops"); for (int i = 0; i < gf.Stops.Count; i++) { xw.WriteStartElement("GradientStop"); xw.WriteStartAttribute("Color"); xw.WriteColor(gf.Fills[i]); xw.WriteEndAttribute(); xw.WriteStartAttribute("Offset"); xw.WriteFloat(gf.Stops[i]); xw.WriteEndAttribute(); xw.WriteEndElement(); // GradientStop } xw.WriteEndElement(); // LinearGradientBrush.GradientStops xw.WriteEndElement(); // LinearGradientBrush xw.WriteEndElement(); // Path.Fill } else if (fs.FillType == FillType.Radial) { //<Ellipse.Fill> // <RadialGradientBrush RadiusX="0.622359" RadiusY="0.604589" Center="0.5,0.5" GradientOrigin="0.5,0.5"> // <RadialGradientBrush.RelativeTransform> // <TransformGroup/> // </RadialGradientBrush.RelativeTransform> // <GradientStop Color="#95000000" Offset="0.347222"/> // <GradientStop Color="#007877A7" Offset="0.773148"/> // </RadialGradientBrush> //</Ellipse.Fill> xw.WriteStartElement("Path.Fill"); xw.WriteStartElement("RadialGradientBrush"); Matrix m = gf.Transform; Rectangle r = GradientFill.GradientVexRect; sysDraw2D.Matrix m2 = new sysDraw2D.Matrix(m.ScaleX, m.Rotate0, m.Rotate1, m.ScaleY, m.TranslateX, m.TranslateY); float midX = r.Point.X + (r.Size.Width / 2); float midY = r.Point.Y + (r.Size.Height / 2); sysDraw.PointF pt0 = new sysDraw.PointF(midX, midY); // center sysDraw.PointF pt1 = new sysDraw.PointF(r.Point.X + r.Size.Width, midY); // radius vector sysDraw.PointF[] pts = new sysDraw.PointF[] { pt0, pt1 }; m2.TransformPoints(pts); float ratX = 1 / (maxX - minX); float ratY = 1 / (maxY - minY); float d0x = (pts[0].X - minX) * ratX; float d0y = (pts[0].Y - minY) * ratY; float d1x = (pts[1].X - pts[0].X); //float d1y = (pts[1].Y - pts[0].Y) * ratY; float rad = (float)Math.Sqrt(d1x * d1x); xw.WriteStartAttribute("RadiusX"); xw.WriteFloat(rad * ratX); xw.WriteEndAttribute(); xw.WriteStartAttribute("RadiusY"); xw.WriteFloat(rad * ratY); xw.WriteEndAttribute(); xw.WriteStartAttribute("Center"); xw.WritePoint(new Point(d0x, d0y)); xw.WriteEndAttribute(); xw.WriteStartAttribute("GradientOrigin"); xw.WritePoint(new Point(d0x, d0y)); xw.WriteEndAttribute(); xw.WriteStartAttribute("SpreadMethod"); xw.WriteValue("Pad"); xw.WriteEndAttribute(); //xw.WriteStartElement("RadialGradientBrush.GradientStops"); for (int i = 0; i < gf.Stops.Count; i++) { xw.WriteStartElement("GradientStop"); xw.WriteStartAttribute("Color"); xw.WriteColor(gf.Fills[i]); xw.WriteEndAttribute(); xw.WriteStartAttribute("Offset"); xw.WriteFloat(1 - gf.Stops[i]); // xaml fill is reversed from gdi xw.WriteEndAttribute(); xw.WriteEndElement(); // GradientStop } //xw.WriteEndElement(); // LinearGradientBrush.GradientStops xw.WriteEndElement(); // LinearGradientBrush xw.WriteEndElement(); // Path.Fill } } else if (isTiledBitmap) { //<Path.Fill> // <ImageBrush ImageSource="Resources\bmp_1.jpg" TileMode="Tile" RelativeTransform=".2,0,0,.2,0,0"/> //</Path.Fill> ImageFill img = (ImageFill)fs; xw.WriteStartElement("Path.Fill"); xw.WriteStartElement("ImageBrush"); xw.WriteStartAttribute("ImageSource"); xw.WriteValue(img.ImagePath); xw.WriteEndAttribute(); if (!silverlight) { xw.WriteStartAttribute("TileMode"); xw.WriteValue("Tile"); xw.WriteEndAttribute(); } //xw.WriteStartAttribute("ViewportUnits"); //xw.WriteValue("Absolute"); //xw.WriteEndAttribute(); Matrix pMatrix = ApplyMatrixToShape(sh, img.Matrix, images[img.ImagePath].StrokeBounds); //Matrix pMatrix = ApplyMatrixToImage(img.Matrix, images[img.ImagePath].Bounds); xw.WriteStartAttribute("RelativeTransform"); xw.WriteMatrix(pMatrix); //xw.WriteMatrix(img.Matrix); xw.WriteEndAttribute(); xw.WriteEndElement(); // Path.Fill xw.WriteEndElement(); // ImageBrush } xw.WriteEndElement(); // Path }
public void WritePathBody(IShapeData[] ips) { if (ips.Length < 1) { return; } // write header int count = 0; List <int> alVals = new List <int>(); List <string> alTypes = new List <string>(); Point prevPoint = Point.Empty; for (int i = 0; i < ips.Length; i++) { // figure out if it is a line, curve, or (needs a) move record // moveTo if (ips[i].StartPoint != prevPoint) { alTypes.Add("M"); alVals.Add((int)(ips[i].StartPoint.X * 20)); alVals.Add((int)(ips[i].StartPoint.Y * 20)); count += 2; } // lineTo if (ips[i] is Line) { alTypes.Add("L"); alVals.Add((int)(ips[i].StartPoint.X * 20)); alVals.Add((int)(ips[i].StartPoint.Y * 20)); count += 2; } // curveTo if (ips[i] is QuadBezier) { alTypes.Add("C"); QuadBezier qb = (QuadBezier)ips[i]; alVals.Add((int)(qb.Control.X * 20)); alVals.Add((int)(qb.Control.Y * 20)); alVals.Add((int)(qb.Anchor1.X * 20)); alVals.Add((int)(qb.Anchor1.Y * 20)); count += 4; } prevPoint = ips[i].EndPoint; } int[] vals = new int[alVals.Count]; for (int i = 0; i < alVals.Count; i++) { vals[i] = (int)alVals[i]; } int maxBits = MinBits(vals) + 1; // sign // nBits WriteBits(2 - 2, 5); // data count WriteBits(alTypes.Count, 11); // write out all type data first as it is even (line/curve/move) for (int i = 0; i < alTypes.Count; i++) { // L:0 C:1 M:2 string st = (string)alTypes[i]; int type = (st == "M") ? 2 : (st == "C") ? 0 : 1; WriteBits(type, 2); } // nBits WriteBits(maxBits - 2, 5); // data count WriteBits(alVals.Count, 11); // write out int data nBits * (L2, C4, M2) for data) for (int i = 0; i < vals.Length; i++) { WriteBits(vals[i], maxBits); } }
private void WritePath(DrawPath path) { int count = 0; List <SegmentType> types = new List <SegmentType>(); List <int> values = new List <int>(); Point prevPoint = Point.Empty; for (int i = 0; i < path.Segments.Count; i++) { IShapeData sd = path.Segments[i]; // moveTo if (sd.StartPoint != prevPoint) { types.Add(SegmentType.Move); values.Add((int)(sd.StartPoint.X * DrawObject.twips)); values.Add((int)(sd.StartPoint.Y * DrawObject.twips)); count += 2; } types.Add(sd.SegmentType); switch (sd.SegmentType) { case SegmentType.Line: values.Add((int)(sd.EndPoint.X * DrawObject.twips)); values.Add((int)(sd.EndPoint.Y * DrawObject.twips)); count += 2; break; case SegmentType.QuadraticBezier: QuadBezier qb = (QuadBezier)sd; values.Add((int)(qb.Control.X * DrawObject.twips)); values.Add((int)(qb.Control.Y * DrawObject.twips)); values.Add((int)(qb.EndPoint.X * DrawObject.twips)); values.Add((int)(qb.EndPoint.Y * DrawObject.twips)); count += 4; break; case SegmentType.CubicBezier: CubicBezier cb = (CubicBezier)sd; values.Add((int)(cb.Control0.X * DrawObject.twips)); values.Add((int)(cb.Control0.Y * DrawObject.twips)); values.Add((int)(cb.Control1.X * DrawObject.twips)); values.Add((int)(cb.Control1.Y * DrawObject.twips)); values.Add((int)(cb.EndPoint.X * DrawObject.twips)); values.Add((int)(cb.EndPoint.Y * DrawObject.twips)); count += 6; break; } prevPoint = sd.EndPoint; } uint dataBits = MinBits(values); WriteNBitsCount(dataBits); WriteBits(types.Count, 11); int[] lens = new int[] { 2, 2, 4, 6 }; int valIndex = 0; for (int i = 0; i < types.Count; i++) { // types M:0 L:1 Q:2 C:3 int type = (int)types[i]; WriteBits(type, 2); // data for (int j = 0; j < lens[type]; j++) { WriteBits(values[valIndex++], dataBits); } } }
protected override void RenderPath(FillStyle fs, StrokeStyle ss, List <IShapeData> sh, bool silverlight) { // <Path Fill="#FFFF0000" // StrokeThickness="0.00491913" StrokeLineJoin="Round" Stroke="#FF014393" // Data="M 196.667,4L 388.667,100L 388.667,292L 196.667,388L 4.66669,292L 4.66669,100L 196.667,4 Z "/> if (sh.Count == 0) { return; } xw.WriteStartElement("path"); if (fs != null) { switch (fs.FillType) { case FillType.Solid: Color c = ((SolidFill)fs).Color; xw.WriteStartAttribute("fill"); xw.WriteColor(c); xw.WriteEndAttribute(); // try to clean up faint edges if (ss == null && c != new Color(0xFF, 0xFF, 0xFF) && c.A != 0) { ss = new SolidStroke(0.3F, c); } break; case FillType.Linear: case FillType.Radial: case FillType.Focal: GradientFill gf = (GradientFill)fs; // fill="url(#lg)" xw.WriteStartAttribute("fill"); xw.WriteValue("url(#gf_" + gf.TagId + ")"); xw.WriteEndAttribute(); break; case FillType.Image: ImageFill img = (ImageFill)fs; if (img.IsTiled) { //isTiledBitmap = true; } break; } } else { xw.WriteStartAttribute("fill"); xw.WriteValue("none"); xw.WriteEndAttribute(); } if (ss != null) { if (ss is SolidStroke) { // StrokeThickness="3" StrokeLineJoin="Round" Stroke="#FF014393" // StrokeStartLineCap="Round" // StrokeEndLineCap="Round" SolidStroke st = (SolidStroke)ss; if (st.LineWidth != 0.3f) { xw.WriteStartAttribute("stroke-width"); xw.WriteFloat(st.LineWidth); xw.WriteEndAttribute(); } xw.WriteStartAttribute("stroke"); xw.WriteColor(st.Color); xw.WriteEndAttribute(); } } // todo: this is pre defined in svg //if (isTiledBitmap) //{ // //<Path.Fill> // // <ImageBrush ImageSource="Resources\bmp_1.jpg" TileMode="Tile" RelativeTransform=".2,0,0,.2,0,0"/> // //</Path.Fill> // ImageFill img = (ImageFill)fs; // xw.WriteStartElement("Path.Fill"); // xw.WriteStartElement("ImageBrush"); // xw.WriteStartAttribute("ImageSource"); // xw.WriteValue(img.ImagePath); // xw.WriteEndAttribute(); // if (!silverlight) // { // xw.WriteStartAttribute("TileMode"); // xw.WriteValue("Tile"); // xw.WriteEndAttribute(); // } // Matrix pMatrix = ApplyMatrixToShape(sh, img.Matrix, images[img.ImagePath].StrokeBounds); // //Matrix pMatrix = ApplyMatrixToImage(img.Matrix, images[img.ImagePath].Bounds); // xw.WriteStartAttribute("RelativeTransform"); // xw.WriteMatrix(pMatrix); // //xw.WriteMatrix(img.Matrix); // xw.WriteEndAttribute(); // xw.WriteEndElement(); // Path.Fill // xw.WriteEndElement(); // ImageBrush //} xw.WriteStartAttribute("d"); xw.WriteMoveTo(sh[0].StartPoint); Point lastPoint = sh[0].StartPoint; for (int i = 0; i < sh.Count; i++) { IShapeData sd = sh[i]; if (lastPoint != sd.StartPoint) { xw.WriteMoveTo(sd.StartPoint); } switch (sd.SegmentType) { case SegmentType.Line: xw.WriteLineTo(sd.EndPoint); lastPoint = sd.EndPoint; break; case SegmentType.CubicBezier: CubicBezier cb = (CubicBezier)sd; xw.WriteCubicCurveTo(cb.Control0, cb.Control1, cb.Anchor1); lastPoint = cb.EndPoint; break; case SegmentType.QuadraticBezier: QuadBezier qb = (QuadBezier)sd; xw.WriteQuadraticCurveTo(qb.Control, qb.Anchor1); lastPoint = qb.EndPoint; break; } } xw.WriteEndAttribute(); xw.WriteEndElement(); // Path }
public void WriteGradientDefinition(Shape shape) { GradientFill gf = (GradientFill)shape.Fill; gf.TagId = gradientCounter++; List <IShapeData> shapeData = shape.ShapeData; float minX = float.PositiveInfinity; float minY = float.PositiveInfinity; float maxX = float.NegativeInfinity; float maxY = float.NegativeInfinity; Point lastPoint = shapeData[0].StartPoint; for (int i = 0; i < shapeData.Count; i++) { IShapeData sd = shapeData[i]; switch (sd.SegmentType) { case SegmentType.Line: lastPoint = sd.EndPoint; break; case SegmentType.CubicBezier: CubicBezier cb = (CubicBezier)sd; lastPoint = cb.EndPoint; minX = Math.Min(minX, cb.Control0.X); maxX = Math.Max(maxX, cb.Control0.X); minY = Math.Min(minY, cb.Control0.Y); maxY = Math.Max(maxY, cb.Control0.Y); minX = Math.Min(minX, cb.Control1.X); maxX = Math.Max(maxX, cb.Control1.X); minY = Math.Min(minY, cb.Control1.Y); maxY = Math.Max(maxY, cb.Control1.Y); break; case SegmentType.QuadraticBezier: QuadBezier qb = (QuadBezier)sd; lastPoint = qb.EndPoint; minX = Math.Min(minX, qb.Control.X); maxX = Math.Max(maxX, qb.Control.X); minY = Math.Min(minY, qb.Control.Y); maxY = Math.Max(maxY, qb.Control.Y); break; } minX = Math.Min(minX, sd.StartPoint.X); maxX = Math.Max(maxX, sd.StartPoint.X); minY = Math.Min(minY, sd.StartPoint.Y); maxY = Math.Max(maxY, sd.StartPoint.Y); minX = Math.Min(minX, sd.EndPoint.X); maxX = Math.Max(maxX, sd.EndPoint.X); minY = Math.Min(minY, sd.EndPoint.Y); maxY = Math.Max(maxY, sd.EndPoint.Y); } if (gf.FillType == FillType.Linear) { //<linearGradient id = "g1" x1 = "50%" y1 = "50%" x2 = "60%" y2 = "60%"> // <stop stop-color = "green" offset = "0%"/> // <stop stop-color = "pink" offset = "100%"/> //</linearGradient> xw.WriteStartElement("linearGradient"); xw.WriteStartAttribute("id"); xw.WriteValue("gf_" + gf.TagId); xw.WriteEndAttribute(); Matrix m = gf.Transform; Rectangle r = GradientFill.GradientVexRect; sysDraw2D.Matrix m2 = new sysDraw2D.Matrix(m.ScaleX, m.Rotate0, m.Rotate1, m.ScaleY, m.TranslateX, m.TranslateY); float midY = r.Point.Y + (r.Size.Height / 2); sysDraw.PointF pt0 = new sysDraw.PointF(r.Point.X, midY); sysDraw.PointF pt1 = new sysDraw.PointF(r.Point.X + r.Size.Width, midY); sysDraw.PointF[] pts = new sysDraw.PointF[] { pt0, pt1 }; m2.TransformPoints(pts); float ratX = 1 / (maxX - minX); float ratY = 1 / (maxY - minY); float d0x = (pts[0].X - minX) * ratX; float d0y = (pts[0].Y - minY) * ratY; float d1x = (pts[1].X - minX) * ratX; float d1y = (pts[1].Y - minY) * ratY; xw.WriteStartAttribute("x1"); xw.WriteFloat(d0x); xw.WriteEndAttribute(); xw.WriteStartAttribute("y1"); xw.WriteFloat(d0y); xw.WriteEndAttribute(); xw.WriteStartAttribute("x2"); xw.WriteFloat(d1x); xw.WriteEndAttribute(); xw.WriteStartAttribute("y2"); xw.WriteFloat(d1y); xw.WriteEndAttribute(); xw.WriteStartAttribute("spreadMethod"); xw.WriteValue("pad"); xw.WriteEndAttribute(); for (int i = 0; i < gf.Stops.Count; i++) { xw.WriteStartElement("stop"); xw.WriteStartAttribute("stop-color"); xw.WriteValue("#" + gf.Fills[i].RGB.ToString("X6")); xw.WriteEndAttribute(); if (gf.Fills[i].A < 255) { xw.WriteStartAttribute("stop-opacity"); xw.WriteValue((gf.Fills[i].A / 255f).ToString("f3")); xw.WriteEndAttribute(); } xw.WriteStartAttribute("offset"); xw.WriteFloat(gf.Stops[i] * 100); xw.WriteValue("%"); xw.WriteEndAttribute(); xw.WriteEndElement(); // stop } xw.WriteEndElement(); // linearGradient } else if (gf.FillType == FillType.Radial) { //<radialGradient id = "g2" cx = "100" cy = "100" r = "50"> // <stop stop-color = "green" offset = "0%"/> // <stop stop-color = "pink" offset = "100%"/> //</radialGradient> xw.WriteStartElement("radialGradient"); xw.WriteStartAttribute("id"); xw.WriteValue("gf_" + gf.TagId); xw.WriteEndAttribute(); xw.WriteAttributeString("gradientUnits", "userSpaceOnUse"); xw.WriteAttributeString("cx", "0"); xw.WriteAttributeString("cy", "0"); xw.WriteAttributeString("r", GradientFill.GradientVexRect.Right.ToString()); Matrix m = gf.Transform; xw.WriteStartAttribute("gradientTransform"); xw.WriteValue("matrix(" + m.ScaleX + "," + m.Rotate0 + "," + m.Rotate1 + "," + m.ScaleY + "," + m.TranslateX + "," + m.TranslateY + ")"); xw.WriteEndAttribute(); xw.WriteStartAttribute("spreadMethod"); xw.WriteValue("pad"); xw.WriteEndAttribute(); for (int i = gf.Stops.Count - 1; i >= 0; i--) { xw.WriteStartElement("stop"); xw.WriteStartAttribute("stop-color"); xw.WriteValue("#" + gf.Fills[i].RGB.ToString("X6")); xw.WriteEndAttribute(); if (gf.Fills[i].A < 255) { xw.WriteStartAttribute("stop-opacity"); xw.WriteValue((gf.Fills[i].A / 255f).ToString("f3")); xw.WriteEndAttribute(); } xw.WriteStartAttribute("offset"); xw.WriteFloat((1 - gf.Stops[i]) * 100); // xaml fill is reversed from gdi xw.WriteValue("%"); xw.WriteEndAttribute(); xw.WriteEndElement(); // stop } xw.WriteEndElement(); // radialGradient } }