public DefineShape3Tag(SwfReader r) { this.ShapeId = r.GetUI16(); this.ShapeBounds = new Rect(r); this.Shapes = new ShapeWithStyle(r, ShapeType.DefineShape3); r.Align(); }
public DefineShape4Tag(SwfReader r) { this.ShapeId = r.GetUI16(); this.ShapeBounds = new Rect(r); this.EdgeBounds = new Rect(r); r.SkipBits(6); this.UsesNonScalingStrokes = r.GetBit(); this.UsesScalingStrokes = r.GetBit(); this.Shapes = new ShapeWithStyle(r, ShapeType.DefineShape4); r.Align(); }
private void ParseShapeWithStyle(ShapeWithStyle tag) { ParseFillStyleArray(tag.FillStyles); foreach (IShapeRecord o in tag.ShapeRecords) { if (o is StyleChangedRecord) { StyleChangedRecord scr = (StyleChangedRecord)o; if (scr.HasNewStyles) { ParseFillStyleArray(scr.FillStyles); } } } }
Bitmap DrawShape(ShapeWithStyle s, Edge[] edges, Rect r) { int top = r.YMin / TWIP; int left = r.XMin / TWIP; int w = (r.XMax - r.XMin) / TWIP; int h = (r.YMax - r.YMin) / TWIP; colors.Clear(); colors.Add(new PixelData(0xFF, 0xFF, 0xFF, 0x00)); foreach (IFillStyle fs in s.FillStyles.FillStyles) { if (fs.FillType == FillType.Solid) { RGBA c = ((SolidFill)fs).Color; colors.Add(new PixelData(c.R, c.G, c.B, c.A)); } else { colors.Add(new PixelData(0x80, 0x80, 0x80, 0xFF)); } } //UnsafeBitmapP b = new UnsafeBitmapP(w, h); UnsafeBitmap b = new UnsafeBitmap(w + left, h + top); b.LockBitmap(); List<Edge> activeEdges = new List<Edge>(); int edgeIndex = 0; byte[,] bytes = new byte[w, h]; bool orderChanged = true; int syTwip = 0; for (int sy = 0; sy < h + top; sy++) { syTwip += TWIP; //AdjustActiveTable //remove stale for(int i = activeEdges.Count - 1; i >= 0; i--) { if (activeEdges[i].endY < sy * TWIP) { activeEdges.RemoveAt(i); } } // add new elements while (edgeIndex < edges.Length && edges[edgeIndex].startY <= sy * TWIP) { activeEdges.Add(edges[edgeIndex]); edgeIndex++; orderChanged = true; } // sort if(orderChanged) { activeEdges.Sort(Edge.CurrentXComparer); orderChanged = false; } if (activeEdges.Count > 0) { int xIndex = 0; byte curFill = 0; Edge edge = activeEdges[xIndex]; PixelData col = colors[0]; PixelData nextCol = colors[0]; int sxTwip = 0; float pc = 0; for (int sx = 0; sx < w + left; sx++) { sxTwip += TWIP; if (sxTwip >= edge.currentX) { pc = (edge.currentX % TWIP) / TWIP; if ((int)edge.currentX != edge.startX) { nextCol = colors[edge.fill0]; col.Interpolate(pc, nextCol); } while (sxTwip >= edge.currentX) { xIndex++; if (xIndex < activeEdges.Count) { if (xIndex > 0 && activeEdges[xIndex - 1].currentX > activeEdges[xIndex].currentX) { } else { edge = activeEdges[xIndex]; curFill = edge.fill1; } } else { b.SetPixel(sx, sy, col); goto ENDXLOOP; } } } if (sy == 80) { //col.blue = 255; } if (col.alpha > 0) { b.SetPixel(sx, sy, col); } col = colors[curFill]; } } ENDXLOOP: for (int i = 0; i < activeEdges.Count; i++) { activeEdges[i].IncX(syTwip); } } b.UnlockBitmap(); Program.form.Bitmap = b.Bitmap; // b.Bitmap.Save("test.png"); return null; }
Edge[] ParseEdges(ShapeWithStyle s, Rect bounds) { List<Edge> edges = new List<Edge>(); uint f0 = 0; uint f1 = 0; uint ln = 0; int curX = -bounds.XMin; // always 0,0 int curY = -bounds.YMin; FillStyleArray curFills = s.FillStyles; LineStyleArray curLines = s.LineStyles; int fillOffset = 0; int lineOffset = 0; foreach (IShapeRecord rec in s.ShapeRecords) { if (rec is StyleChangedRecord) { StyleChangedRecord r = (StyleChangedRecord)rec; if (r.HasNewStyles) // todo: this also sets 'grouped' elements (and therefore layers) { fillOffset = curFills.FillStyles.Count; lineOffset = curLines.LineStyles.Count; curFills.FillStyles.AddRange(r.FillStyles.FillStyles); curLines.LineStyles.AddRange(r.LineStyles.LineStyles); } if (r.HasFillStyle0) { f0 = r.FillStyle0 == 0 ? 0 : (uint)(r.FillStyle0 + fillOffset); } if (r.HasFillStyle1) { f1 = r.FillStyle1 == 0 ? 0 : (uint)(r.FillStyle1 + fillOffset); } if (r.HasLineStyle) { ln = r.LineStyle == 0 ? 0 : (uint)(r.LineStyle + lineOffset); } if(r.HasMove) { curX = r.MoveDeltaX; // this is based on the initial location, which is now 0,0 curY = r.MoveDeltaY; } } else if (rec is StraightEdgeRecord) { StraightEdgeRecord r = (StraightEdgeRecord)rec; Edge e = new Edge(curX, curY, curX + r.DeltaX, curY + r.DeltaY, (byte)f0, (byte)f1, (byte)ln); curX += r.DeltaX; curY += r.DeltaY; edges.Add(e); } else if (rec is CurvedEdgeRecord) { CurvedEdgeRecord r = (CurvedEdgeRecord)rec; int curveX = curX + r.ControlX; int curveY = curY + r.ControlY; int destX = curveX + r.AnchorX; int destY = curveY + r.AnchorY; // split nodes if curve is outside start/end Y if(curveY >= curY && curveY <= destY) { Edge e = new CurvedEdge(curX, curY, curveX, curveY, destX, destY, (byte)f0, (byte)f1, (byte)ln); edges.Add(e); } else { Edge[] split = CurvedEdge.SplitAtPeak(curX, curY, curveX, curveY, destX, destY, (byte)f0, (byte)f1, (byte)ln); edges.Add(split[0]); edges.Add(split[1]); } curX = destX; curY = destY; } } edges.Sort(Edge.MaxYComparer); return edges.ToArray(); }
private void ParseShapeWithStyle(ShapeWithStyle tag) { List<FillStyle> curFillStyles = ParseFillStyleArray(tag.FillStyles); List<StrokeStyle> curStrokeStyles = ParseLineStyleArray(tag.LineStyles); int curX = 0; int curY = 0; int curFill0 = 0; int curFill1 = 0; int curStroke = 0; List<FillPath> fillPaths = new List<FillPath>(); List<StrokePath> strokePaths = new List<StrokePath>(); foreach (IShapeRecord o in tag.ShapeRecords) { if (o is StraightEdgeRecord) { StraightEdgeRecord r = (StraightEdgeRecord)o; Line line = new Line( new Point(curX / twips, curY / twips), new Point((curX + r.DeltaX) / twips, (curY + r.DeltaY) / twips)); if (curFill0 > 0) { if (curFill0 > curFillStyles.Count) { fillPaths.Add(new FillPath(new DDW.Vex.SolidFill(new Color(255, 0, 0)), line)); } else { fillPaths.Add(new FillPath(curFillStyles[curFill0 - 1], line)); } } if (curFill1 > 0) { if (curFill1 > curFillStyles.Count) { fillPaths.Add(new FillPath(new DDW.Vex.SolidFill(new Color(255, 0, 0)), line)); } else { fillPaths.Add(new FillPath(curFillStyles[curFill1 - 1], line)); } } if (curStroke > 0) { strokePaths.Add(new StrokePath(curStrokeStyles[curStroke - 1], line)); } curX += r.DeltaX; curY += r.DeltaY; } else if (o is CurvedEdgeRecord) { CurvedEdgeRecord r = (CurvedEdgeRecord)o; Point a0 = new Point(curX / twips, curY / twips); Point c0 = new Point((curX + r.ControlX) / twips, (curY + r.ControlY) / twips); curX += r.ControlX; curY += r.ControlY; Point a1 = new Point((curX + r.AnchorX) / twips, (curY + r.AnchorY) / twips); curX += r.AnchorX; curY += r.AnchorY; QuadBezier bez = new QuadBezier(a0, c0, a1); if (curFill0 > 0) { if (curFill1 > curFillStyles.Count) { fillPaths.Add(new FillPath(new DDW.Vex.SolidFill(new Color(255, 0, 0)), bez)); } else { fillPaths.Add(new FillPath(curFillStyles[curFill0 - 1], bez)); } } if (curFill1 > 0) { if (curFill1 > curFillStyles.Count) { fillPaths.Add( new FillPath( new DDW.Vex.SolidFill(new Color(255,0,0)), bez) ); } else { fillPaths.Add(new FillPath(curFillStyles[curFill1 - 1], bez)); } } if (curStroke > 0) { strokePaths.Add(new StrokePath(curStrokeStyles[curStroke - 1], bez)); } } else if (o is StyleChangedRecord) { StyleChangedRecord scr = (StyleChangedRecord)o; if (scr.HasMove) { curX = scr.MoveDeltaX; curY = scr.MoveDeltaY; } if (scr.HasFillStyle0) { curFill0 = (int)scr.FillStyle0; } if (scr.HasFillStyle1) { curFill1 = (int)scr.FillStyle1; } if (scr.HasLineStyle) { curStroke = (int)scr.LineStyle; } if (scr.HasNewStyles) { ProcessPaths(fillPaths, strokePaths); fillPaths.Clear(); strokePaths.Clear(); curFillStyles = ParseFillStyleArray(scr.FillStyles); curStrokeStyles = ParseLineStyleArray(scr.LineStyles); } } else if (o is EndShapeRecord) { // end } } ProcessPaths(fillPaths, strokePaths); }