/** Creates new MetaState */ public MetaState() { savedStates = new Stack(); MetaObjects = new ArrayList(); currentPoint = new System.Drawing.Point(0, 0); currentPen = new MetaPen(); currentBrush = new MetaBrush(); currentFont = new MetaFont(); }
public void StrokeAndFill() { MetaPen pen = state.CurrentPen; MetaBrush brush = state.CurrentBrush; int penStyle = pen.Style; int brushStyle = brush.Style; if (penStyle == MetaPen.PS_NULL) { cb.ClosePath(); if (state.PolyFillMode == MetaState.ALTERNATE) { cb.EoFill(); } else { cb.Fill(); } } else { bool isBrush = (brushStyle == MetaBrush.BS_SOLID || (brushStyle == MetaBrush.BS_HATCHED && state.BackgroundMode == MetaState.OPAQUE)); if (isBrush) { if (state.PolyFillMode == MetaState.ALTERNATE) { cb.ClosePathEoFillStroke(); } else { cb.ClosePathFillStroke(); } } else { cb.ClosePathStroke(); } } }
public bool IsNullStrokeFill(bool isRectangle) { MetaPen pen = state.CurrentPen; MetaBrush brush = state.CurrentBrush; bool noPen = (pen.Style == MetaPen.PS_NULL); int style = brush.Style; bool isBrush = (style == MetaBrush.BS_SOLID || (style == MetaBrush.BS_HATCHED && state.BackgroundMode == MetaState.OPAQUE)); bool result = noPen && !isBrush; if (!noPen) { if (isRectangle) { state.LineJoinRectangle = cb; } else { state.LineJoinPolygon = cb; } } return(result); }
public void ReadAll() { if (meta.ReadInt() != unchecked ((int)0x9AC6CDD7)) { throw new DocumentException("Not a placeable windows metafile"); } meta.ReadWord(); left = meta.ReadShort(); top = meta.ReadShort(); right = meta.ReadShort(); bottom = meta.ReadShort(); inch = meta.ReadWord(); state.ScalingX = (float)(right - left) / (float)inch * 72f; state.ScalingY = (float)(bottom - top) / (float)inch * 72f; state.OffsetWx = left; state.OffsetWy = top; state.ExtentWx = right - left; state.ExtentWy = bottom - top; meta.ReadInt(); meta.ReadWord(); meta.Skip(18); int tsize; int function; cb.SetLineCap(1); cb.SetLineJoin(1); for (;;) { int lenMarker = meta.Length; tsize = meta.ReadInt(); if (tsize < 3) { break; } function = meta.ReadWord(); switch (function) { case 0: break; case META_CREATEPALETTE: case META_CREATEREGION: case META_DIBCREATEPATTERNBRUSH: state.AddMetaObject(new MetaObject()); break; case META_CREATEPENINDIRECT: { MetaPen pen = new MetaPen(); pen.Init(meta); state.AddMetaObject(pen); break; } case META_CREATEBRUSHINDIRECT: { MetaBrush brush = new MetaBrush(); brush.Init(meta); state.AddMetaObject(brush); break; } case META_CREATEFONTINDIRECT: { MetaFont font = new MetaFont(); font.Init(meta); state.AddMetaObject(font); break; } case META_SELECTOBJECT: { int idx = meta.ReadWord(); state.SelectMetaObject(idx, cb); break; } case META_DELETEOBJECT: { int idx = meta.ReadWord(); state.DeleteMetaObject(idx); break; } case META_SAVEDC: state.SaveState(cb); break; case META_RESTOREDC: { int idx = meta.ReadShort(); state.RestoreState(idx, cb); break; } case META_SETWINDOWORG: state.OffsetWy = meta.ReadShort(); state.OffsetWx = meta.ReadShort(); break; case META_SETWINDOWEXT: state.ExtentWy = meta.ReadShort(); state.ExtentWx = meta.ReadShort(); break; case META_MOVETO: { int y = meta.ReadShort(); System.Drawing.Point p = new System.Drawing.Point(meta.ReadShort(), y); state.CurrentPoint = p; break; } case META_LINETO: { int y = meta.ReadShort(); int x = meta.ReadShort(); System.Drawing.Point p = state.CurrentPoint; cb.MoveTo(state.TransformX(p.X), state.TransformY(p.Y)); cb.LineTo(state.TransformX(x), state.TransformY(y)); cb.Stroke(); state.CurrentPoint = new System.Drawing.Point(x, y); break; } case META_POLYLINE: { state.LineJoinPolygon = cb; int len = meta.ReadWord(); int x = meta.ReadShort(); int y = meta.ReadShort(); cb.MoveTo(state.TransformX(x), state.TransformY(y)); for (int k = 1; k < len; ++k) { x = meta.ReadShort(); y = meta.ReadShort(); cb.LineTo(state.TransformX(x), state.TransformY(y)); } cb.Stroke(); break; } case META_POLYGON: { if (IsNullStrokeFill(false)) { break; } int len = meta.ReadWord(); int sx = meta.ReadShort(); int sy = meta.ReadShort(); cb.MoveTo(state.TransformX(sx), state.TransformY(sy)); for (int k = 1; k < len; ++k) { int x = meta.ReadShort(); int y = meta.ReadShort(); cb.LineTo(state.TransformX(x), state.TransformY(y)); } cb.LineTo(state.TransformX(sx), state.TransformY(sy)); StrokeAndFill(); break; } case META_POLYPOLYGON: { if (IsNullStrokeFill(false)) { break; } int numPoly = meta.ReadWord(); int[] lens = new int[numPoly]; for (int k = 0; k < lens.Length; ++k) { lens[k] = meta.ReadWord(); } for (int j = 0; j < lens.Length; ++j) { int len = lens[j]; int sx = meta.ReadShort(); int sy = meta.ReadShort(); cb.MoveTo(state.TransformX(sx), state.TransformY(sy)); for (int k = 1; k < len; ++k) { int x = meta.ReadShort(); int y = meta.ReadShort(); cb.LineTo(state.TransformX(x), state.TransformY(y)); } cb.LineTo(state.TransformX(sx), state.TransformY(sy)); } StrokeAndFill(); break; } case META_ELLIPSE: { if (IsNullStrokeFill(state.LineNeutral)) { break; } int b = meta.ReadShort(); int r = meta.ReadShort(); int t = meta.ReadShort(); int l = meta.ReadShort(); cb.Arc(state.TransformX(l), state.TransformY(b), state.TransformX(r), state.TransformY(t), 0, 360); StrokeAndFill(); break; } case META_ARC: { if (IsNullStrokeFill(state.LineNeutral)) { break; } float yend = state.TransformY(meta.ReadShort()); float xend = state.TransformX(meta.ReadShort()); float ystart = state.TransformY(meta.ReadShort()); float xstart = state.TransformX(meta.ReadShort()); float b = state.TransformY(meta.ReadShort()); float r = state.TransformX(meta.ReadShort()); float t = state.TransformY(meta.ReadShort()); float l = state.TransformX(meta.ReadShort()); float cx = (r + l) / 2; float cy = (t + b) / 2; float arc1 = GetArc(cx, cy, xstart, ystart); float arc2 = GetArc(cx, cy, xend, yend); arc2 -= arc1; if (arc2 <= 0) { arc2 += 360; } cb.Arc(l, b, r, t, arc1, arc2); cb.Stroke(); break; } case META_PIE: { if (IsNullStrokeFill(state.LineNeutral)) { break; } float yend = state.TransformY(meta.ReadShort()); float xend = state.TransformX(meta.ReadShort()); float ystart = state.TransformY(meta.ReadShort()); float xstart = state.TransformX(meta.ReadShort()); float b = state.TransformY(meta.ReadShort()); float r = state.TransformX(meta.ReadShort()); float t = state.TransformY(meta.ReadShort()); float l = state.TransformX(meta.ReadShort()); float cx = (r + l) / 2; float cy = (t + b) / 2; float arc1 = GetArc(cx, cy, xstart, ystart); float arc2 = GetArc(cx, cy, xend, yend); arc2 -= arc1; if (arc2 <= 0) { arc2 += 360; } ArrayList ar = PdfContentByte.BezierArc(l, b, r, t, arc1, arc2); if (ar.Count == 0) { break; } float[] pt = (float [])ar[0]; cb.MoveTo(cx, cy); cb.LineTo(pt[0], pt[1]); for (int k = 0; k < ar.Count; ++k) { pt = (float [])ar[k]; cb.CurveTo(pt[2], pt[3], pt[4], pt[5], pt[6], pt[7]); } cb.LineTo(cx, cy); StrokeAndFill(); break; } case META_CHORD: { if (IsNullStrokeFill(state.LineNeutral)) { break; } float yend = state.TransformY(meta.ReadShort()); float xend = state.TransformX(meta.ReadShort()); float ystart = state.TransformY(meta.ReadShort()); float xstart = state.TransformX(meta.ReadShort()); float b = state.TransformY(meta.ReadShort()); float r = state.TransformX(meta.ReadShort()); float t = state.TransformY(meta.ReadShort()); float l = state.TransformX(meta.ReadShort()); float cx = (r + l) / 2; float cy = (t + b) / 2; float arc1 = GetArc(cx, cy, xstart, ystart); float arc2 = GetArc(cx, cy, xend, yend); arc2 -= arc1; if (arc2 <= 0) { arc2 += 360; } ArrayList ar = PdfContentByte.BezierArc(l, b, r, t, arc1, arc2); if (ar.Count == 0) { break; } float[] pt = (float [])ar[0]; cx = pt[0]; cy = pt[1]; cb.MoveTo(cx, cy); for (int k = 0; k < ar.Count; ++k) { pt = (float [])ar[k]; cb.CurveTo(pt[2], pt[3], pt[4], pt[5], pt[6], pt[7]); } cb.LineTo(cx, cy); StrokeAndFill(); break; } case META_RECTANGLE: { if (IsNullStrokeFill(true)) { break; } float b = state.TransformY(meta.ReadShort()); float r = state.TransformX(meta.ReadShort()); float t = state.TransformY(meta.ReadShort()); float l = state.TransformX(meta.ReadShort()); cb.Rectangle(l, b, r - l, t - b); StrokeAndFill(); break; } case META_ROUNDRECT: { if (IsNullStrokeFill(true)) { break; } float h = state.TransformY(0) - state.TransformY(meta.ReadShort()); float w = state.TransformX(meta.ReadShort()) - state.TransformX(0); float b = state.TransformY(meta.ReadShort()); float r = state.TransformX(meta.ReadShort()); float t = state.TransformY(meta.ReadShort()); float l = state.TransformX(meta.ReadShort()); cb.RoundRectangle(l, b, r - l, t - b, (h + w) / 4); StrokeAndFill(); break; } case META_INTERSECTCLIPRECT: { float b = state.TransformY(meta.ReadShort()); float r = state.TransformX(meta.ReadShort()); float t = state.TransformY(meta.ReadShort()); float l = state.TransformX(meta.ReadShort()); cb.Rectangle(l, b, r - l, t - b); cb.EoClip(); cb.NewPath(); break; } case META_EXTTEXTOUT: { int y = meta.ReadShort(); int x = meta.ReadShort(); int count = meta.ReadWord(); int flag = meta.ReadWord(); int x1 = 0; int y1 = 0; int x2 = 0; int y2 = 0; if ((flag & (MetaFont.ETO_CLIPPED | MetaFont.ETO_OPAQUE)) != 0) { x1 = meta.ReadShort(); y1 = meta.ReadShort(); x2 = meta.ReadShort(); y2 = meta.ReadShort(); } byte[] text = new byte[count]; int k; for (k = 0; k < count; ++k) { byte c = (byte)meta.ReadByte(); if (c == 0) { break; } text[k] = c; } string s; try { s = System.Text.Encoding.GetEncoding(1252).GetString(text, 0, k); } catch { s = System.Text.ASCIIEncoding.ASCII.GetString(text, 0, k); } OutputText(x, y, flag, x1, y1, x2, y2, s); break; } case META_TEXTOUT: { int count = meta.ReadWord(); byte[] text = new byte[count]; int k; for (k = 0; k < count; ++k) { byte c = (byte)meta.ReadByte(); if (c == 0) { break; } text[k] = c; } string s; try { s = System.Text.Encoding.GetEncoding(1252).GetString(text, 0, k); } catch { s = System.Text.ASCIIEncoding.ASCII.GetString(text, 0, k); } count = (count + 1) & 0xfffe; meta.Skip(count - k); int y = meta.ReadShort(); int x = meta.ReadShort(); OutputText(x, y, 0, 0, 0, 0, 0, s); break; } case META_SETBKCOLOR: state.CurrentBackgroundColor = meta.ReadColor(); break; case META_SETTEXTCOLOR: state.CurrentTextColor = meta.ReadColor(); break; case META_SETTEXTALIGN: state.TextAlign = meta.ReadWord(); break; case META_SETBKMODE: state.BackgroundMode = meta.ReadWord(); break; case META_SETPOLYFILLMODE: state.PolyFillMode = meta.ReadWord(); break; case META_SETPIXEL: { Color color = meta.ReadColor(); int y = meta.ReadShort(); int x = meta.ReadShort(); cb.SaveState(); cb.SetColorFill(color); cb.Rectangle(state.TransformX(x), state.TransformY(y), .2f, .2f); cb.Fill(); cb.RestoreState(); break; } case META_DIBSTRETCHBLT: case META_STRETCHDIB: { int rop = meta.ReadInt(); if (function == META_STRETCHDIB) { /*int usage = */ meta.ReadWord(); } int srcHeight = meta.ReadShort(); int srcWidth = meta.ReadShort(); int ySrc = meta.ReadShort(); int xSrc = meta.ReadShort(); float destHeight = state.TransformY(meta.ReadShort()) - state.TransformY(0); float destWidth = state.TransformX(meta.ReadShort()) - state.TransformX(0); float yDest = state.TransformY(meta.ReadShort()); float xDest = state.TransformX(meta.ReadShort()); byte[] b = new byte[(tsize * 2) - (meta.Length - lenMarker)]; for (int k = 0; k < b.Length; ++k) { b[k] = (byte)meta.ReadByte(); } try { MemoryStream inb = new MemoryStream(b); Image bmp = BmpImage.GetImage(inb, true, b.Length); cb.SaveState(); cb.Rectangle(xDest, yDest, destWidth, destHeight); cb.Clip(); cb.NewPath(); bmp.ScaleAbsolute(destWidth * bmp.Width / srcWidth, -destHeight * bmp.Height / srcHeight); bmp.SetAbsolutePosition(xDest - destWidth * xSrc / srcWidth, yDest + destHeight * ySrc / srcHeight - bmp.ScaledHeight); cb.AddImage(bmp); cb.RestoreState(); } catch { // empty on purpose } break; } } meta.Skip((tsize * 2) - (meta.Length - lenMarker)); } state.Cleanup(cb); }
public void SelectMetaObject(int index, PdfContentByte cb) { MetaObject obj = (MetaObject)MetaObjects[index]; if (obj == null) { return; } int style; switch (obj.Type) { case MetaObject.META_BRUSH: currentBrush = (MetaBrush)obj; style = currentBrush.Style; if (style == MetaBrush.BS_SOLID) { Color color = currentBrush.Color; cb.SetColorFill(color); } else if (style == MetaBrush.BS_HATCHED) { Color color = currentBackgroundColor; cb.SetColorFill(color); } break; case MetaObject.META_PEN: { currentPen = (MetaPen)obj; style = currentPen.Style; if (style != MetaPen.PS_NULL) { Color color = currentPen.Color; cb.SetColorStroke(color); cb.SetLineWidth(Math.Abs((float)currentPen.PenWidth * scalingX / extentWx)); switch (style) { case MetaPen.PS_DASH: cb.SetLineDash(18, 6, 0); break; case MetaPen.PS_DASHDOT: cb.SetLiteral("[9 6 3 6]0 d\n"); break; case MetaPen.PS_DASHDOTDOT: cb.SetLiteral("[9 3 3 3 3 3]0 d\n"); break; case MetaPen.PS_DOT: cb.SetLineDash(3, 0); break; default: cb.SetLineDash(0); break; } } break; } case MetaObject.META_FONT: { currentFont = (MetaFont)obj; break; } } }