Пример #1
0
 public RecordArray(IShapeData parent)
     : base(-1)
 {
     this.Parent = parent;
 }
Пример #2
0
		public FillPath(FillStyle fillStyle, IShapeData segment)
		{
			this.FillStyle = fillStyle;
			this.Segment = segment;
		}
Пример #3
0
        public void WritePaths(IShapeData[][] ips)
        {
            WriteStartArray();
            WriteBits((int)DVex.PathDefinition, 8);
            WriteBits(ips.Length, 11); // number of path defs
            for(int i = 0; i < ips.Length; i++)
            {
                WritePathBody(ips[i]);
            }

            FlushBits();
            WriteEndArray();
        }
Пример #4
0
 public StrokePath(StrokeStyle strokeStyle, IShapeData segment)
 {
     this.StrokeStyle = strokeStyle;
     this.Segment = segment;
 }
Пример #5
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);
            }
        }
Пример #6
0
        private static void ConsolidatePaths(Symbol symbol, DVexWriter writer)
        {
            List<FillStyle> fills = new List<FillStyle>();
            List<StrokeStyle> strokes = new List<StrokeStyle>();
            fills.Add( new SolidFill(Color.Transparent) );
            strokes.Add( new SolidStroke(0.0F, Color.Transparent) );
            ArrayList allPaths = new ArrayList();
            ArrayList allSrs = new ArrayList();

            // Find all used colors/strokes, and the F0,F1,S info for each seg
            foreach(Shape sh in symbol.Shapes)
            {
                foreach(IShapeData s in sh.ShapeData)
                {
                    int fill = 0;
                    int stroke = 0;
                    if (!fills.Contains(shape.Fills[s.FillIndex]))
                    {
                        fill = fills.Add(shape.Fills[s.FillIndex]);
                    }
                    else
                    {
                        fill = fills.IndexOf(shape.Fills[s.FillIndex]);
                    }
                    if( !strokes.Contains(shape.Strokes[s.StrokeIndex]) )
                    {
                        stroke = strokes.Add(shape.Strokes[s.StrokeIndex]);
                    }
                    else
                    {
                        stroke = strokes.IndexOf(shape.Strokes[s.StrokeIndex]);
                    }
                    // break path into shape records
                    foreach(IPathPrimitive ipp in s.Path)
                    {
                        if(ipp is IShapeData)
                        {
                            IShapeData ip = (IShapeData)ipp;
                            if(allPaths.Contains(ip))
                            {
                                // this must be a fill1 if it is a dup
                                int index = allPaths.IndexOf(ip);
                                Shrec sr = (Shrec)allSrs[index];
                                Shrec newShrec = new Shrec(0, 0);
                                newShrec.F0 = (sr.F0 == 0) ? fill : sr.F0 ;
                                newShrec.F1 = (sr.F1 == 0) ? fill : sr.F1 ;
                                newShrec.S = (sr.S == 0) ? stroke : sr.S ;
                                allSrs[index] = newShrec;
                            }
                            else
                            {
                                allSrs.Add(new Shrec(fill, stroke));
                                allPaths.Add(ip);
                            }
                        }
                    }
                } // end groups
            } // end shapes

            // ok, now write out colors
            // sort fills by rgb, argb, and gradients
            ArrayList orderedFills = new ArrayList();
            ArrayList rgbas = new ArrayList();
            ArrayList gfs = new ArrayList();
            foreach(Fill sf in fills)
            {
                if(sf is SolidFill)
                {
                    if( ((SolidFill)sf).Color.A == 255 ||
                        (SolidFill)sf == fills[0]) // 'no fill'
                    {
                        orderedFills.Add(sf);
                    }
                    else
                    {
                        rgbas.Add(sf);
                    }
                }
                else if(sf is GradientFill)
                {
                    gfs.Add(sf);
                }
                else
                {
                    // bitmap fills
                    orderedFills.Add(new SolidFill(Color.Gray));
                };
            }

            SolidFill[] wrgbs = new SolidFill[orderedFills.Count];
            wrgbs[0] = new SolidFill(Color.FromArgb(255,0,0,0));
            int fRgb = 1;
            foreach(Fill f in orderedFills)
            {
                if(f != fills[0])
                {
                    wrgbs[fRgb++] = (SolidFill)f;
                }
            }
            int fRgba = 0;
            SolidFill[] wrgbas = new SolidFill[rgbas.Count];
            foreach(Fill f in rgbas)
            {
                orderedFills.Add(f);
                wrgbas[fRgba++] = (SolidFill)f;
            }

            int fGr = 0;
            GradientFill[] wgfs = new GradientFill[gfs.Count];
            foreach(Fill f in gfs)
            {
                orderedFills.Add(f);
                wgfs[fGr++] = (GradientFill)(f);
            }

            writer.WriteNbitColorDefs(wrgbs);
            writer.WriteNbitColorDefs(wrgbas);
            writer.WriteNbitGradientDefs(wgfs);
            //writer.WriteRgbColorDefs(wrgbs);
            //writer.WriteRgbaColorDefs(wrgbas);
            //writer.WriteGradientColorDefs(wgfs);

            // ok, colors written, now strokes
            // write out all the stroke defs second
            // get counts
            int wrgbCount = 0;
            int wrgbaCount = 0;
            foreach(Stroke st in strokes)
            {
                if(st.Color.A == 255 || st == strokes[0])
                    {wrgbCount++;}
                    else{wrgbaCount++;}
            }
            // create stroke arrays
            Stroke[] wsrgbs = new Stroke[wrgbCount];
            Stroke[] wsrgbas = new Stroke[wrgbaCount];
            int sRgb = 0;
            int sRgba = 0;
            foreach(Stroke st in strokes)
            {
                if( st.Color.A == 255 || st == strokes[0])
                {
                    wsrgbs[sRgb++] = st;
                }
                else
                {
                    wsrgbas[sRgba++] = st;
                }
            }
            // now write the stroke data
            writer.WriteNbitStrokeDefs(wsrgbs);
            writer.WriteNbitStrokeDefs(wsrgbas);
            //writer.WriteRgbStrokeDefs(wsrgbs);
            //writer.WriteRgbaStrokeDefs(wsrgbas);

            // and now paths
            // valid pathsegs must have the same F0, F1, and S
            ArrayList tempPaths = new ArrayList();
            ArrayList tempSrsAl = new ArrayList();
            PathCollection pc = new PathCollection();
            Shrec curShrec = Shrec.Empty;
            for(int i = 0; i < allSrs.Count; i++) //Shrec sr in srsAl)
            {
                Shrec sr = (Shrec)allSrs[i];
                if(sr.Equals(curShrec) || curShrec.Equals(Shrec.Empty))
                {
                    //add to path
                    pc.Add((IShapeData)allPaths[i]);
                }
                else
                {
                    // write to hash
                    tempPaths.Add(pc);
                    tempSrsAl.Add(curShrec);

                    pc = new PathCollection();
                    pc.Add((IShapeData)allPaths[i]);
                }
                curShrec = sr;
            }
            if(!tempSrsAl.Contains(curShrec))
            {
                tempPaths.Add(pc);
                tempSrsAl.Add(curShrec);
            }
            // split non contig paths
            ArrayList paths = new ArrayList();
            ArrayList srsAl = new ArrayList();
            foreach(PathCollection pcoll in tempPaths)
            {
                //pcoll.ReorderPath();
                PathCollection[] pcolls = pcoll.SplitPath();
                foreach(PathCollection splitP in pcolls)
                {
                    paths.Add(splitP);
                    srsAl.Add(tempSrsAl[tempPaths.IndexOf(pcoll)] );
                    //writer.WritePath(splitP.PointSegments);
                }
            }
            IShapeData[][] ips = new IShapeData[paths.Count][];
            for(int i = 0; i < paths.Count; i++)
            {
                ips[i] = ((PathCollection)paths[i]).PointSegments;
            }
            writer.WritePaths(ips);

            // convert to array
            Shrec[] srs = new Shrec[srsAl.Count];
            for(int i = 0; i < srsAl.Count; i++)
            {
                srs[i] = (Shrec)srsAl[i];
            }

            // and finally, uses - must be sorted by fill color
            // use order Fill1 (no strokes), fill0[stroke], stroke only's
            // for each fill index{..}, then dangling strokes

            ArrayList shapeRecords = new ArrayList();

            // start at 1 to avoid empty fills
            foreach(Fill f in orderedFills)
            {
                int curFill = fills.IndexOf(f);
                if(curFill != 0)
                {
                    // all F1's of this color first
                    ArrayList Fs = new ArrayList();
                    for(int i = 0; i < srs.Length; i++)
                    {
                        if(srs[i].F0 == curFill)
                        {
                            // add use for F0
                            ShapeRecord curSr = new ShapeRecord();

                            curSr.Fill = orderedFills.IndexOf(f);
                            curSr.Stroke = srs[i].S;
                            curSr.Path = i;
                            Fs.Add(curSr);
                        }
                        if(srs[i].F1 == curFill )
                        {
                            // add use for F1
                            ShapeRecord curSr = new ShapeRecord();
                            curSr.Fill = orderedFills.IndexOf(f);
                            curSr.Stroke = 0;
                            curSr.Path = i;
                            Fs.Add(curSr);
                        }
                    }
                    //now sort the F1s from tip to tail
                    if(Fs.Count > 0)
                    {
                        ArrayList finalFs = new ArrayList();
                        finalFs.Add(Fs[0]);
                        PointF end =
                            ((PathCollection)paths[((ShapeRecord)Fs[0]).Path]).LastPoint;
                        Fs.RemoveAt(0);
                        while(Fs.Count > 0)
                        {
                            bool found = false;
                            foreach(ShapeRecord sr in Fs)
                            {
                                PathCollection srp = (PathCollection)paths[sr.Path];
                                if(srp.FirstPoint == end)
                                {
                                    end = srp.LastPoint;
                                    finalFs.Add(sr);
                                    Fs.Remove(sr);
                                    found = true;
                                    break;
                                }
                            }
                            if(found == false)
                            {
                                finalFs.Add(Fs[0]);
                                end = ( (PathCollection)paths[
                                    ((ShapeRecord)Fs[0]).Path] ).LastPoint;
                                Fs.RemoveAt(0);
                            }
                        }
                        // and write them
                        foreach(ShapeRecord sr in finalFs)
                        {
                            shapeRecords.Add(sr);
                        }
                    }

                }
            }
            for(int i = 0; i < srs.Length; i++)
            {
                if(srs[i].F0 == 0 && srs[i].F1 == 0)
                {
                    // must be stroke
                    ShapeRecord curSr = new ShapeRecord();
                    curSr.Fill = 0;
                    curSr.Stroke = srs[i].S;
                    curSr.Path = i;
                    shapeRecords.Add(curSr);
                }
            }
            // convert to array
            ShapeRecord[] srecs = new ShapeRecord[shapeRecords.Count];
            for(int i = 0; i < shapeRecords.Count; i++)
            {
                srecs[i] = (ShapeRecord)shapeRecords[i];
            }

            writer.WriteUses(srecs);
        }
Пример #7
0
 public FillStyleArray(IShapeData shape)
 {
     this.Parent = shape;
 }
Пример #8
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
            }
        }
Пример #9
0
 public StrokePath(StrokeStyle strokeStyle, IShapeData segment)
 {
     this.StrokeStyle = strokeStyle;
     this.Segment     = segment;
 }