Beispiel #1
0
        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);
        }
Beispiel #2
0
        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
        }
Beispiel #3
0
        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);
            }
        }
Beispiel #4
0
        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);
                }
            }
        }
Beispiel #5
0
        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
        }
Beispiel #6
0
        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
            }
        }