public static float[] GetGradientLine(GradientFill gf) { float[] result = new float[4]; System.Drawing.PointF[] pts = GradientFill.GradientVexRect.SysPointFs(); using (Draw2D.Matrix m = gf.Transform.SysMatrix()) { m.TransformPoints(pts); } if (gf.GradientType == GradientType.Linear) { result[0] = pts[0].X; result[1] = pts[0].Y; result[2] = pts[1].X; result[3] = pts[1].Y; } else // radial is center to rightCenter edge { result[0] = pts[0].X + (pts[1].X - pts[0].X) / 2; result[1] = pts[0].Y + (pts[2].Y - pts[0].Y) / 2; result[2] = pts[1].X; result[3] = pts[1].Y + (pts[2].Y - pts[0].Y) / 2; } return result; }
private ColorBlend GetColorBlend(Vex.GradientFill fill) { List <float> positions = new List <float>(); List <Color> colors = new List <Color>(); int numGradients = fill.Fills.Count; for (int i = 0; i < numGradients; i++) { positions.Add(fill.Stops[i]); colors.Add(fill.Fills[i].SysColor()); } // GDI color blends must start at 0.0 and end at 1.0 or they will crash if ((float)positions[0] != 0.0F) { positions.Insert(0, 0.0F); colors.Insert(0, colors[0]); } if ((float)positions[positions.Count - 1] != 1.0F) { positions.Add(1.0F); colors.Add(colors[colors.Count - 1]); } ColorBlend cb = new ColorBlend(positions.Count); cb.Colors = colors.ToArray(); cb.Positions = positions.ToArray(); return(cb); }
private ColorBlend GetColorBlend(GradientFill fill) { List<float> positions = new List<float>(); List<Ms.Color> colors = new List<Ms.Color>(); int numGradients = fill.Fills.Count; for (int i = 0; i < numGradients; i++) { positions.Add(fill.Stops[i]); colors.Add(GetColor(fill.Fills[i])); } // GDI color blends must start at 0.0 and end at 1.0 or they will crash if ((float)positions[0] != 0.0F) { positions.Insert(0, 0.0F); colors.Insert(0, colors[0]); } if ((float)positions[positions.Count - 1] != 1.0F) { positions.Add(1.0F); colors.Add(colors[colors.Count - 1]); } ColorBlend cb = new ColorBlend(positions.Count); cb.Colors = colors.ToArray(); cb.Positions = positions.ToArray(); return cb; }
public bool Equals(GradientFill o) { return (this.CompareTo(o) == 0); }
public void WriteGradientColorDefs(GradientFill[] gfs) { if(gfs.Length == 0) return; int count = gfs.Length; int totalBytes = 4; for(int i = 0; i < gfs.Length; i++) { int samples = gfs[i].Fills.Count; totalBytes += (samples * 4) + (samples * 1); // rgba ratio totalBytes += 1 + 6*2; // header and matrix } byte[] bytes = new byte[totalBytes]; // id8, count16 bytes[0] = (byte)DVex.GradientDefs; bytes[1] = 0; bytes[2] = (byte)((count & 0xFF00) >> 8); bytes[3] = (byte)(count & 0xFF); int index = 4; for(int i = 0; i < gfs.Length; i++) { int fillType = 0x00; // linearFill if(gfs[i].FillType == FillType.Radial) { fillType = 0x10; } int colorCount = gfs[i].Fills.Count; if(colorCount > 8) { colorCount = 8; Console.WriteLine("*Flash only supports 8 colors max in gradients"); } bytes[index++] = (byte)(fillType | colorCount); // add rgba+ratio array List<Color> colors = gfs[i].Fills; List<float> positions = gfs[i].Stops; // flash and gdi store colors & pos in opposite order for radials if(gfs[i].FillType == FillType.Radial) { int len = colors.Count; List<Color> tempc = new List<Color>(len); List<float> tempp = new List<float>(len); for(int col = 0; col < len; col++) { tempc[col] = colors[len-col-1]; tempp[col] = 255-positions[len-col-1]; } colors = tempc; positions = tempp; } for(int j = 0; j < colorCount; j++) { bytes[index++] = colors[j].R; bytes[index++] = colors[j].G; bytes[index++] = colors[j].B; int a = (int)(Math.Floor(colors[j].A / 2.55)); if (a >= 98) a = 100; if (a <= 2) a = 0; bytes[index++] = (byte)a; bytes[index++] = (byte) ( ((int)(positions[j] * 255)) & 0xFF); } // add matrix System.Drawing.Drawing2D.Matrix clone = gfs[i].Transform.GetDrawing2DMatrix(); clone.Scale(GradientFill.GradientVexRect.Size.Width, GradientFill.GradientVexRect.Size.Height); float[] mx = clone.Elements; clone.Dispose(); // add elements bytes[index++] = (byte) ((((int)mx[0])& 0xFF00) >> 8); bytes[index++] = (byte) ( ((int)mx[0])& 0xFF); bytes[index++] = (byte) ((((int)mx[1])& 0xFF00) >> 8); bytes[index++] = (byte) ( ((int)mx[1])& 0xFF); bytes[index++] = (byte) ((((int)mx[2])& 0xFF00) >> 8); bytes[index++] = (byte) ( ((int)mx[2])& 0xFF); bytes[index++] = (byte) ((((int)mx[3])& 0xFF00) >> 8); bytes[index++] = (byte) ( ((int)mx[3])& 0xFF); bytes[index++] = (byte) ((((int)mx[4])& 0xFF00) >> 8); bytes[index++] = (byte) ( ((int)mx[4])& 0xFF); bytes[index++] = (byte) ((((int)mx[5])& 0xFF00) >> 8); bytes[index++] = (byte) ( ((int)mx[5])& 0xFF); FillDefs.Add(gfs[i]); } WriteByteArray(bytes); }
public void WriteNbitGradientDefs(GradientFill[] gfs) { if(gfs.Length == 0) return; int count = gfs.Length; WriteStartArray(); WriteBits((int)DVex.GradientDefs, 8); WriteBits(gfs.Length, 11); // note: no nBits here!! for(int index = 0; index < gfs.Length; index++) { FillDefs.Add(gfs[index]); // first type - all non radial will be solid (as as doesn do bmp fills) int type = (gfs[index].FillType == FillType.Radial) ? 1 : 0; WriteBits(type, 1); // now argb colors List<Color> cols = gfs[index].Fills; List<float> positions = gfs[index].Stops; // flash and gdi store colors & pos in opposite order for radials if(gfs[index].FillType == FillType.Radial) { int len = cols.Count; List<Color> tempc = new List<Color>(len); List<float> tempp = new List<float>(len); for(int col = 0; col < len; col++) { tempc[col] = cols[len-col-1]; tempp[col] = 1-positions[len-col-1]; } cols = tempc; positions = tempp; } int sampCount = cols.Count; if(sampCount > 8) { sampCount = 8; Console.WriteLine("*Flash only supports 8 colors max in gradients"); } int[] wCols = new int[sampCount]; for(int i = 0; i < sampCount; i++) { wCols[i] = cols[i].ARGB & 0x00FFFFFF; wCols[i] |= (~cols[i].A) << 24; } int colBits = MinBits(wCols); int wcolBits = colBits > 1 ? colBits - 2 : 0; WriteBits(wcolBits, 5); WriteBits(sampCount, 11); for(int i = 0; i < sampCount; i++) { WriteBits(wCols[i], wcolBits+2); } // now ratios int[] rats = new int[positions.Count]; for(int i = 0; i < sampCount; i++) { rats[i] = (int)(positions[i]*255); } int ratBits = MinBits(rats); int wratBits = ratBits > 1 ? ratBits - 2 : 0; WriteBits(wratBits, 5); WriteBits(sampCount, 11); for(int i = 0; i < sampCount; i++) { WriteBits(rats[i], wratBits+2); } // now matrix System.Drawing.Drawing2D.Matrix clone = gfs[index].Transform.GetDrawing2DMatrix(); clone.Scale(GradientFill.GradientVexRect.Size.Width, GradientFill.GradientVexRect.Size.Height); float[] mx = clone.Elements; clone.Dispose(); int[] mxs = new int[6]{ (int)mx[0]*20, (int)mx[1]*20, (int)mx[2]*20, (int)mx[3]*20, (int)mx[4]*20, (int)mx[5]*20}; int mxBits = MinBits(mxs)+1; // neg int wmxBits = mxBits > 1 ? mxBits - 2 : 0; WriteBits(wmxBits, 5); WriteBits(6, 11); for(int i = 0; i < 6; i++) { WriteBits(mxs[i], wmxBits+2); } } FlushBits(); WriteEndArray(); }
private void FillPaths(Vex.FillStyle fill, List <GraphicsPath> paths) { Brush b = null; foreach (GraphicsPath path in paths) { if (fillOverride != null) { g.FillPath(fillOverride, path); } else { switch (fill.FillType) { case Vex.FillType.Solid: Vex.SolidFill sf = (Vex.SolidFill)fill; b = new SolidBrush(sf.Color.SysColor()); break; case Vex.FillType.Linear: Vex.GradientFill lf = (Vex.GradientFill)fill; RectangleF rect = Vex.GradientFill.GradientVexRect.SysRectangleF(); LinearGradientBrush lgb = new LinearGradientBrush( rect, Color.White, Color.White, 1.0F ); lgb.InterpolationColors = GetColorBlend(lf); lgb.Transform = lf.Transform.SysMatrix(); lgb.WrapMode = WrapMode.TileFlipX; ExtendGradientBrush(lgb, path); b = lgb; break; case Vex.FillType.Radial: Vex.GradientFill rf = (Vex.GradientFill)fill; ColorBlend cb = GetColorBlend(rf); SolidBrush bkgCol = new SolidBrush(cb.Colors[0]); g.FillPath(bkgCol, path); bkgCol.Dispose(); // radial fill part GraphicsPath gp = new GraphicsPath(); gp.AddEllipse(Vex.GradientFill.GradientVexRect.SysRectangleF()); PathGradientBrush pgb = new PathGradientBrush(gp); pgb.InterpolationColors = GetColorBlend(rf); pgb.Transform = rf.Transform.SysMatrix(); b = pgb; break; case Vex.FillType.Image: Vex.ImageFill imgFill = (Vex.ImageFill)fill; Bitmap bmp = new Bitmap(imgFill.ImagePath); b = new TextureBrush(bmp); break; default: b = new SolidBrush(Color.Red); break; } g.FillPath(b, path); } } if (b != null) { b.Dispose(); } }
public override int CompareTo(Object o) { int result = 0; if (o is FillStyle && this.FillType != ((FillStyle)o).FillType) { result = (this.FillType > ((FillStyle)o).FillType) ? 1 : -1; } else if (o is GradientFill) { GradientFill co = (GradientFill)o; if ((int)this.GradientType != (int)co.GradientType) { result = ((int)this.GradientType > (int)co.GradientType) ? 1 : -1; } else if (this.Fills.Count != co.Fills.Count) { result = (this.Fills.Count > co.Fills.Count) ? 1 : -1; } else if (this.Stops.Count != co.Stops.Count) { result = (this.Stops.Count > co.Stops.Count) ? 1 : -1; } else if (this.Stops.Count != this.Fills.Count) { result = -1; } else if (co.Stops.Count != co.Fills.Count) { result = 1; } else { for (int i = 0; i < this.Fills.Count; i++) { if (this.Fills[i] != co.Fills[i]) { result = this.Fills[i].CompareTo(co.Fills[i]); break; } if (this.Stops[i] != co.Stops[i]) { result = this.Fills[i].CompareTo(co.Fills[i]); break; } } if (result == 0) { if (this.Transform != co.Transform) { result = this.Transform.CompareTo(co.Transform); } } } } else { throw new ArgumentException("Objects being compared are not of the same type"); } return(result); }
public bool Equals(GradientFill o) { return(this.CompareTo(o) == 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); }
private GradientFill ParseGradient(Gradient tag) { GradientFill result = new DDW.Vex.GradientFill(); switch(tag.FillType) { case FillType.Linear: result.GradientType = GradientType.Linear; break; case FillType.Radial: result.GradientType = GradientType.Radial; break; } result.Transform = ParseMatrix(tag.GradientMatrix); // bug in flash, can add two stops at 1.0 bool hasStart = false; bool hasEnd = false; int tagCount = tag.Records.Count; for (int i = 0; i < tagCount; i++) { //int index = tagCount - 1 - i; GradientRecord r = tag.Records[i]; float stop = r.Ratio / 255F; bool safeToAdd = true; if (stop == 0F) { if (hasStart) { safeToAdd = false; } hasStart = true; } if (stop == 1F) { if (hasEnd) { safeToAdd = false; } hasEnd = true; } if (safeToAdd) { result.Fills.Add(ParseRGBA(r.Color)); result.Stops.Add(stop); } } // colors are opposite of swf in Vex (and like gdi) for radial fills if (result.GradientType == GradientType.Radial) { result.Fills.Reverse(); result.Stops.Reverse(); for (int i = 0; i < result.Stops.Count; i++) { result.Stops[i] = 1.0F - result.Stops[i]; } } return result; }
public void WriteGradientColor(GradientFill gf) { //this.WriteString("#" + gf.Color.ARGB.ToString("X8")); }
private string GetGradientLineString(GradientFill gf) { string result = ""; float[] pts = GetGradientLine(gf); string comma = ""; for (int i = 0; i < pts.Length; i++) { result += comma + pts[i].ToString("0.##"); comma = ","; } return result; }