public void WriteNbitColorDefs(SolidFill[] argbs) { if (argbs.Length == 0) { return; } int count = argbs.Length; int[] vals = new int[argbs.Length]; for (int i = 0; i < argbs.Length; i++) { FillDefs.Add(argbs[i]); vals[i] = argbs[i].Color.ARGB & 0x00FFFFFF; // alpha inverted so solid (common case) is zero vals[i] |= (~argbs[i].Color.A) << 24; } int nBits = MinBits(vals); // always positive // header WriteStartArray(); WriteBits((int)DVex.ArgbDefinitions, 8); // type 0x40 int wnBits = nBits > 1 ? nBits - 2 : 0; WriteBits(wnBits, 5); WriteBits(count, 11); // 2074 max for (int i = 0; i < vals.Length; i++) { WriteBits(vals[i], wnBits + 2); } FlushBits(); WriteEndArray(); }
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(); }