private void StrokePaths(Vex.StrokeStyle stroke, List <GraphicsPath> paths) { Pen p = null; foreach (GraphicsPath path in paths) { if (penOverride != null) { g.DrawPath(penOverride, path); } else { if (stroke is Vex.SolidStroke) { Vex.SolidStroke ss = (Vex.SolidStroke)stroke; p = new Pen(ss.Color.SysColor(), ss.LineWidth); } else { p = new Pen(Color.Black, 1); } p.StartCap = LineCap.Round; p.EndCap = LineCap.Round; p.LineJoin = LineJoin.Round; g.DrawPath(p, path); p.Dispose(); } } }
private void DrawShape(Vex.Shape sh) { List <GraphicsPath> paths; if (sh.Fill != null && fillOverride != Brushes.Transparent) { paths = GetPath(sh.ShapeData, true); FillPaths(sh.Fill, paths); } if (sh.Stroke != null) { if (penOverride != Pens.Transparent) { paths = GetPath(sh.ShapeData, false); StrokePaths(sh.Stroke, paths); } } else { // this gets rid of slight aliasing spaces between touching vectors // todo: do average colors for gradients or something. if (sh.Fill.FillType == Vex.FillType.Solid) { Vex.StrokeStyle ss = new Vex.SolidStroke(.1F, ((Vex.SolidFill)sh.Fill).Color); paths = GetPath(sh.ShapeData, false); StrokePaths(ss, paths); } } }
public bool IsV2DShape() { bool result = false; if (Fill == null && Stroke is SolidStroke && ShapeData.Count > 2) { SolidStroke sf = (SolidStroke)Stroke; if ((sf.Color == outlineColor) && (sf.LineWidth <= outlineWidth)) { result = true; } } return(result); }
public override int CompareTo(Object o) { int result = 0; if (o is SolidStroke) { SolidStroke co = (SolidStroke)o; if (this.Color != co.Color) { result = this.Color.CompareTo(co.Color); } else if (this.LineWidth != co.LineWidth) { result = (this.LineWidth > co.LineWidth) ? 1 : -1; } } else { throw new ArgumentException("Objects being compared are not of the same type"); } return(result); }
protected 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 = gf.Rectangle; ms2.Matrix m2 = new ms2.Matrix(m.ScaleX, m.Rotate0, m.Rotate1, m.ScaleY, m.TranslateX, m.TranslateY); float midY = r.Point.Y + (r.Size.Height / 2); ms.PointF pt0 = new ms.PointF(r.Point.X, midY); ms.PointF pt1 = new ms.PointF(r.Point.X + r.Size.Width, midY); ms.PointF[] pts = new ms.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 = gf.Rectangle; ms2.Matrix m2 = new ms2.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); ms.PointF pt0 = new ms.PointF(midX, midY); // center ms.PointF pt1 = new ms.PointF(r.Point.X + r.Size.Width, midY); // radius vector ms.PointF[] pts = new ms.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 }
private void DrawShape(Shape sh) { List<GraphicsPath> paths; if (sh.Fill != null) { paths = GetPath(sh.ShapeData, true); FillPaths(sh.Fill, paths); } if (sh.Stroke != null) { paths = GetPath(sh.ShapeData, false); StrokePaths(sh.Stroke, paths); } else { // this gets rid of slight aliasing spaces between touching vectors // todo: do average colors for gradients or something. if (sh.Fill.FillType == FillType.Solid) { StrokeStyle ss = new SolidStroke(.1F, ((SolidFill)sh.Fill).Color); paths = GetPath(sh.ShapeData, false); StrokePaths(ss, paths); } } }
public void WriteNbitStrokeDefs(SolidStroke[] strokes) { if(strokes.Length == 0) return; WriteStartArray(); WriteBits((int)DVex.StrokeDefinitions, 8); // type 0x40 int count = strokes.Length; // Stroke Colors // first adjust argb color vals int[] cols = new int[count]; for(int i = 0; i < count; i++) { // TODO: I think the stroke/fill defs aren't refed in this class StrokeDefs.Add(strokes[i]); cols[i] = strokes[i].Color.ARGB & 0x00FFFFFF; // alpha inverted so solid (common case) is zero cols[i] |= (~strokes[i].Color.A) << 24; } int nBits = MinBits(cols); // always positive int wnBits = nBits > 1 ? nBits - 2 : 0; WriteBits(wnBits, 5); WriteBits(count, 11); // 2074 max for(int i = 0; i < count; i++) { WriteBits(cols[i], wnBits+2); } // Stroke Widths in next sequence int[] widths = new int[count]; for(int i = 0; i < count; i++) { StrokeDefs.Add(strokes[i]); widths[i] = (int)(strokes[i].LineWidth * 20); } nBits = MinBits(widths); // always positive wnBits = nBits > 1 ? nBits - 2 : 0; WriteBits(wnBits, 5); WriteBits(count, 11); // 2074 max for(int i = 0; i < count; i++) { WriteBits(widths[i], wnBits+2); } FlushBits(); WriteEndArray(); }
public bool Equals(SolidStroke o) { return ((this.LineWidth == o.LineWidth) && (this.Color == o.Color)); }
public bool Equals(SolidStroke o) { return((this.LineWidth == o.LineWidth) && (this.Color == o.Color)); }