DPoint GetWmfSize() { if (WmfIsPlaceable) { bytesRead = 0; placeable = GetWmfPlaceable(); header = GetWmfHeader(); bool records = true; while (records) { int bytesReadPlusFuncHeaderSize = bytesRead; Wmf.FuncHeader fh = GetWmfFuncHeader(); bytesReadPlusFuncHeaderSize += (int)fh.Size * 2; switch (fh.Function) { case Wmf.SetWindowOrg: winY = GetInt16(); winX = GetInt16(); break; case Wmf.SetWindowExt: winHeight = GetInt16(); winWidth = GetInt16(); break; case Wmf.EOF: records = false; // this does not always work too well (there are some wacky values in wmf files) double width = Math.Abs(winWidth); if (winWidth != Math.Round((placeable.Right - placeable.Left) * ((double)PageTools.DpiX / placeable.Inch))) width *= (double)PageTools.DpiX / placeable.Inch; double height = Math.Abs(winHeight); if (winHeight != Math.Round((placeable.Bottom - placeable.Top) * ((double)PageTools.DpiY / placeable.Inch))) height *= (double)PageTools.DpiY / placeable.Inch; return new DPoint(width, height); } if (bytesRead != bytesReadPlusFuncHeaderSize) bytesRead = bytesReadPlusFuncHeaderSize; } } return new DPoint(0, 0); }
private void PaintWmf(DGraphics dg) { dg.Save(); dg.Clip(Rect); // store current matrix DMatrix m = dg.SaveTransform(); // clear gdi objects WmfGdiObjects.Clear(); // check for placeable key if (WmfIsPlaceable) { bytesRead = 0; // read placeable header placeable = GetWmfPlaceable(); // checksum int sum = 0; for (int i = 0; i < (Marshal.SizeOf(typeof(Wmf.Placeable)) - 2 /* WmfPlaceable.Checksum is UInt16 */) / 2; i++) sum = sum ^ BitConverter.ToUInt16(ImageData, i * 2); if (sum != placeable.Checksum) System.Diagnostics.Debug.Fail("checksum failed"); // init matrix WmfUpdateMaxtrix(dg, m); // read header header = GetWmfHeader(); // iterate draw commands bool records = true; while (records) { int bytesReadPlusFuncHeaderSize = bytesRead; Wmf.FuncHeader fh = GetWmfFuncHeader(); bytesReadPlusFuncHeaderSize += (int)fh.Size * 2; bool breakme = false; switch (fh.Function) { case Wmf.SaveDC: break; case Wmf.CreatePalette: break; case Wmf.SetBkMode: int bkMode = GetInt16(); break; case Wmf.SetMapMode: int mapMode = GetInt16(); break; case Wmf.SetROP2: break; case Wmf.SetRelabs: break; case Wmf.SetPolyFillMode: int polyfillMode = GetInt16(); if (polyfillMode == Wmf.PfmAlernate) fillRule = DFillRule.EvenOdd; else fillRule = DFillRule.Winding; break; case Wmf.SetStretchBltMode: break; case Wmf.DeleteObject: WmfDeleteGdiObject(GetInt16()); break; case Wmf.RestoreDC: break; case Wmf.SelectObject: WmfSelectGdiObject(GetInt16()); break; case Wmf.SetTextAlign: break; case Wmf.SetBkColor: break; case Wmf.SetTextColor: break; case Wmf.SetWindowOrg: winY = GetInt16(); winX = GetInt16(); WmfUpdateMaxtrix(dg, m); break; case Wmf.SetWindowExt: winHeight = GetInt16(); winWidth = GetInt16(); WmfUpdateMaxtrix(dg, m); break; case Wmf.SetViewportOrg: viewY = GetInt16(); viewX = GetInt16(); //wmfUpdateMaxtrix(dg, m); break; case Wmf.SetViewportExt: viewHeight = GetInt16(); viewWidth = GetInt16(); //wmfUpdateMaxtrix(dg, m); break; case Wmf.LineTo: DPoint pt = GetPoint(); if (StrokeValid) dg.DrawLine(curPoint, pt, stroke, 1, strokeStyle, strokeWidth, strokeCap); curPoint = pt; break; case Wmf.MoveTo: curPoint = GetPoint(); break; case Wmf.SelectPalette: break; case Wmf.CreatePenIndirect: int gdiPenStyle = GetInt16(); int widthX = GetInt16(); int widthY = GetInt16(); DColor penColor = GetColor(); double penWidth = widthX; WmfApplyTransforms(ref penWidth); DStrokeStyle penStyle = DStrokeStyle.Solid; DStrokeCap penCap = DStrokeCap.Round; DStrokeJoin penJoin = DStrokeJoin.Round; if ((gdiPenStyle & Wmf.PS_DASHDOTDOT) == Wmf.PS_DASHDOTDOT) penStyle = DStrokeStyle.DashDotDot; else if ((gdiPenStyle & Wmf.PS_DASHDOT) == Wmf.PS_DASHDOT) penStyle = DStrokeStyle.DashDot; else if ((gdiPenStyle & Wmf.PS_DOT) == Wmf.PS_DOT) penStyle = DStrokeStyle.Dot; else if ((gdiPenStyle & Wmf.PS_DASH) == Wmf.PS_DASH) penStyle = DStrokeStyle.Dash; else penStyle = DStrokeStyle.Solid; if ((gdiPenStyle & Wmf.PS_ENDCAP_FLAT) == Wmf.PS_ENDCAP_FLAT) penCap = DStrokeCap.Butt; else if ((gdiPenStyle & Wmf.PS_ENDCAP_SQUARE) == Wmf.PS_ENDCAP_SQUARE) penCap = DStrokeCap.Square; else penCap = DStrokeCap.Round; if ((gdiPenStyle & Wmf.PS_JOIN_MITER) == Wmf.PS_JOIN_MITER) penJoin = DStrokeJoin.Mitre; else if ((gdiPenStyle & Wmf.PS_JOIN_BEVEL) == Wmf.PS_JOIN_BEVEL) penJoin = DStrokeJoin.Bevel; else penJoin = DStrokeJoin.Round; if ((gdiPenStyle & Wmf.PS_NULL) == Wmf.PS_NULL) WmfAddGdiObject(new WmfGdiPen(DColor.Empty, penWidth, penStyle, penCap, penJoin)); else WmfAddGdiObject(new WmfGdiPen(penColor, penWidth, penStyle, penCap, penJoin)); break; case Wmf.CreateFontIndirect: WmfAddGdiObject("font"); break; case Wmf.CreateBrushIndirect: int brushStyle = GetInt16(); DColor brushColor = GetColor(); int brushHatch = GetInt16(); if ((brushStyle & Wmf.BS_NULL) == Wmf.BS_NULL) WmfAddGdiObject(new WmfGdiBrush(DColor.Empty)); else WmfAddGdiObject(new WmfGdiBrush(brushColor)); break; case Wmf.Polygon: DPoints polygonPts = GetPolyPoints(GetInt16(), true); if (FillValid) dg.FillPolygon(polygonPts, fill, 1, fillRule); if (StrokeValid) dg.DrawPolyline(polygonPts, stroke, 1, strokeWidth, strokeStyle, strokeJoin, strokeCap); break; case Wmf.Polyline: DPoints polylinePts = GetPolyPoints(GetInt16(), false); if (StrokeValid) dg.DrawPolyline(polylinePts, stroke, 1, strokeWidth, strokeStyle, strokeJoin, strokeCap); break; case Wmf.Ellipse: goto case Wmf.Rectangle; case Wmf.Rectangle: DPoint br = GetPoint(); DPoint tl = GetPoint(); if (FillValid) { if (fh.Function == Wmf.Rectangle) dg.FillRect(tl.X, tl.Y, br.X - tl.X, br.Y - tl.Y, fill, 1); else if (fh.Function == Wmf.Ellipse) dg.FillEllipse(tl.X, tl.Y, br.X - tl.X, br.Y - tl.Y, fill, 1); } if (StrokeValid) { if (fh.Function == Wmf.Rectangle) dg.DrawRect(tl.X, tl.Y, br.X - tl.X, br.Y - tl.Y, stroke, 1, strokeWidth, strokeStyle, strokeJoin); else if (fh.Function == Wmf.Ellipse) dg.DrawEllipse(tl.X, tl.Y, br.X - tl.X, br.Y - tl.Y, stroke, 1, strokeWidth, strokeStyle); } break; case Wmf.PolyPolygon: // find out how many points int numPolygons = GetInt16(); int[] numPoints = new int[numPolygons]; for (int i = 0; i < numPolygons; i++) numPoints[i] = GetInt16(); // join polygons together DPoints polyPolyPoints = new DPoints(); for (int i = 0; i < numPolygons; i++) foreach (DPoint polyPolyPt in GetPolyPoints(numPoints[i], true)) polyPolyPoints.Add(polyPolyPt); // draw if (FillValid) dg.FillPolygon(polyPolyPoints, fill, 1, fillRule); if (StrokeValid) dg.DrawPolyline(polyPolyPoints, stroke, 1, strokeWidth, strokeStyle, strokeJoin, strokeCap); break; case Wmf.Escape: break; default: breakme = true; break; } if (bytesRead != bytesReadPlusFuncHeaderSize) bytesRead = bytesReadPlusFuncHeaderSize; if (breakme) break; } } dg.Restore(); }
public WmfGraphics(double x1, double y1, double x2, double y2) { winX = 0; winY = 0; winWidth = x2 - x1; winHeight = y2 - y1; // create memory stream ms = new MemoryStream(); // write placeable Wmf.Placeable p = new Wmf.Placeable(); p.Key = Wmf.PlaceableKey; p.HWmf = 0; p.Left = (ushort)winX; p.Top = (ushort)winY; p.Right = (ushort)winWidth; p.Bottom = (ushort)winHeight; p.Inch = 96; p.Reserved = 0; // checksum int sum = 0; byte[] cd = RawSerialize(p); for (int i = 0; i < (Marshal.SizeOf(typeof(Wmf.Placeable)) - 2 /* WmfPlaceable.Checksum is UInt16 */) / 2; i++) sum = sum ^ BitConverter.ToUInt16(cd, i * 2); p.Checksum = (ushort)sum; byte[] buf = RawSerialize(p); ms.Write(buf, 0, buf.Length); // write header Wmf.Header h = new Wmf.Header(); h.Type = 0x0002; h.HeaderSize = (ushort)(Marshal.SizeOf(typeof(Wmf.Header)) / 2); h.Version = 0x0300; h.Filesize = 0; // see SaveToFile h.NumOfObjects = 0; // see SaveToFile h.MaxRecord = 0; // see SaveToFile h.NumOfMembers = 0; // not used buf = RawSerialize(h); ms.Write(buf, 0, buf.Length); // set window space WriteFuncHeader(5, Wmf.SetWindowOrg); WriteUShort((ushort)winX); WriteUShort((ushort)winY); WriteFuncHeader(5, Wmf.SetWindowExt); WriteUShort((ushort)winWidth); WriteUShort((ushort)winHeight); /* // draw stuff DrawEllipse(2, 2, 96, 96, DColor.Blue, 1, 2, DStrokeStyle.Dot); FillRect(10, 10, 80, 80, DColor.Red, 1); DrawRect(20, 20, 60, 60, DColor.LightGray, 1, 2, DStrokeStyle.Solid, DStrokeJoin.Bevel); DrawEllipse(20, 20, 60, 60, DColor.Blue, 1, 2, DStrokeStyle.DashDotDot); DrawLine(new DPoint(15, 50), new DPoint(85, 50), DColor.White, 1, DStrokeStyle.Solid, 1, DStrokeCap.Butt); DPoints pts = new DPoints(); for (int i = 0; i < 50; i += 5) for (int j = 0; j < 50; j += 5) pts.Add(new DPoint(i, j + i)); DrawPolyline(pts, DColor.Black); pts.Clear(); pts.Add(new DPoint(50, 50)); pts.Add(new DPoint(75, 75)); pts.Add(new DPoint(50, 75)); FillPolygon(pts, DColor.Blue, 1); */ }