private void OnPrintPage(object sender, PrintPageEventArgs e) { Rectangle r = e.PageBounds; // ist IMMER in 100 dpi // die Pixelauflösung des Druckers ist in e.Graphics.DpiX bzw. DpiY double fctpap = 100 / 25.4; //double fct = 100 / 25.4; double fct = e.Graphics.DpiX / 25.4; // das ist die echte Auflösung // fct /= 2; war nur ein Test e.Graphics.PageScale = (float)(1.0); for (int i = 0; i < layout.PatchCount; ++i) { LayoutPatch lp = layout.Patches[i]; e.Graphics.Transform = new System.Drawing.Drawing2D.Matrix((float)fctpap, 0.0f, 0.0f, (float)-fctpap, 0.0f, (float)(layout.PaperHeight * fctpap)); BoundingRect ext; if (lp.Area != null) { ext = lp.Area.Extent; } else { ext = new BoundingRect(0.0, 0.0, layout.PaperWidth, layout.PaperHeight); } // der Faktor fct ist willkürlich, macht man ihn zu groß, gibt es ein OutOfMemory in OpenGl // zu klein, wird die Auflösung beim Drucken zu grob. Abhilfe würde es schaffen, wenn man nicht ein // Bitmap erzeugt, sondern dieses kachelt. Ob man es aber nahtlos zusammensetzen kann? // eigentlich gefragt wäre hier die Pixelauflösung des Graphics, aber vielleicht gibt es die garnicht // und es ist ein Metafile, der zum Drucker weitergereicht wird. GeoPoint2D ll = ext.GetLowerLeft(); GeoPoint2D ur = ext.GetUpperRight(); Rectangle clipRectangle = Rectangle.FromLTRB((int)ll.x, (int)ll.y, (int)ur.x, (int)ur.y); System.Drawing.Bitmap PaintToBitmap; int bitmapwidth = (int)(clipRectangle.Width * fct); int bitmapheight = (int)(clipRectangle.Height * fct); PaintToBitmap = new System.Drawing.Bitmap(bitmapwidth, bitmapheight); IPaintTo3D ipaintTo3D = Frame.UIService.CreatePaintInterface(PaintToBitmap, lp.Model.Extent.Size / 1000); ipaintTo3D.MakeCurrent(); ipaintTo3D.Clear(Color.White); ipaintTo3D.AvoidColor(Color.White); Projection pr = lp.Projection.Clone(); pr.SetUnscaledProjection(new ModOp(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0) * pr.UnscaledProjection); double factor, dx, dy; pr.GetPlacement(out factor, out dx, out dy); //new System.Drawing.Drawing2D.Matrix((float)factor, 0.0f, 0.0f, (float)-factor, 0.0f, (float)(layout.PaperHeight * factor)); pr.SetPlacement(fct * factor, fct * (dx - ext.Left), fct * (dy - ext.Bottom)); ipaintTo3D.SetProjection(pr, lp.Model.Extent); ipaintTo3D.UseZBuffer(true); ipaintTo3D.PaintFaces(PaintTo3D.PaintMode.All); ipaintTo3D.UseLineWidth = true; // hier darf nicht mit Listen gearbeitet werden, sonst macht OpanGL die Krätsche foreach (IGeoObject go in lp.Model) { PaintFlatVisibleLayer(ipaintTo3D, go, lp.visibleLayers); } //CategorizedDislayLists displayLists = new CategorizedDislayLists(); //// beim Zeichnen auf Bitmaps müssen die Displaylisten lokal zu diesem rendercontext gehören //// obwohl sharelists angegeben wurde und das keinen Fehler bringt //// leider wird alles hierbei flach. Man könnte das höchstens damit übertricksen, //// dass man bei tringle die Farbe an jedem Eckpunkt mit dem Normalenvektor verrechnet //// aber ob das hilft? //foreach (IGeoObject go in lp.Model) //{ // go.PaintTo3DList(ipaintTo3D, displayLists); //} //displayLists.Finish(ipaintTo3D); //ipaintTo3D.PaintFaces(PaintTo3D.PaintMode.FacesOnly); //foreach (KeyValuePair<Layer, IPaintTo3DList> kv in displayLists.layerFaceDisplayList) //{ // if (lp.IsLayerVisible(kv.Key) || displayLists.NullLayer == kv.Key) // { // ipaintTo3D.List(kv.Value); // } //} //ipaintTo3D.PaintFaces(PaintTo3D.PaintMode.CurvesOnly); //foreach (KeyValuePair<Layer, IPaintTo3DList> kv in displayLists.layerCurveDisplayList) //{ // if (lp.IsLayerVisible(kv.Key) || displayLists.NullLayer == kv.Key) // { // ipaintTo3D.List(kv.Value); // } //} //// wozu war das folgende noch? ////foreach (IGeoObject go in lp.Model) ////{ //// go.PaintTo3D(ipaintTo3D); ////} //// ipaintTo3D.Dispose(); gibt OpenGL Fehler //ipaintTo3D.FinishPaint(); //gr.ReleaseHdc(dc); //displayLists = null; //System.GC.Collect(); //System.GC.WaitForPendingFinalizers(); //ipaintTo3D.Dispose(); PaintToBitmap.MakeTransparent(Color.White); //e.Graphics.DrawImageUnscaled(PaintToBitmap, clipRectangle); PointF[] dest = new PointF[3]; dest[0].X = (float)ll.x; dest[0].Y = (float)ur.y; dest[1].X = (float)ur.x; dest[1].Y = (float)ur.y; dest[2].X = (float)ll.x; dest[2].Y = (float)ll.y; RectangleF src = new RectangleF(new PointF(0.0f, 0.0f), PaintToBitmap.Size); e.Graphics.DrawImage(PaintToBitmap, dest, src, GraphicsUnit.Pixel); } }
void IView.OnPaint(PaintEventArgs e) { IPaintTo3D paintTo3D = canvas.PaintTo3D; Rectangle clr = e.ClipRectangle; if (!IsInitialized) { ZoomTotal(1.1); } //PaintToOpenGl paintTo3D = new PaintToOpenGl(1e-3); // woher nehmen? // IntPtr dc = e.Graphics.GetHdc(); //paintTo3D.Init(dc, condorCtrl.ClientRectangle.Width, condorCtrl.ClientRectangle.Height, false); IPaintTo3D ipaintTo3D = paintTo3D; // ipaintTo3D.Init(condorCtrl); // das erzeugt jedesmal einen neuen renderContext, das kann doch nicht richtig sein ipaintTo3D.MakeCurrent(); ipaintTo3D.Clear(Color.Black); // damit ist black die Backgroundcolor //e.Graphics.FillRectangle(Brushes.Black, e.Graphics.ClipBounds); GeoPoint2D ll = layoutToScreen * new GeoPoint2D(0.0, 0.0); GeoPoint2D ur = layoutToScreen * new GeoPoint2D(layout.PaperWidth, layout.PaperHeight); RectangleF paperrect = RectangleF.FromLTRB((float)ll.x, (float)ur.y, (float)ur.x, (float)ll.y); //e.Graphics.FillRectangle(Brushes.White, paperrect); //BoundingCube bc = new BoundingCube(ll.x, ur.x, ll.y, ur.y, -1.0, 1.0); //ipaintTo3D.SetProjection(new Projection(Projection.StandardProjection.FromTop), bc); ipaintTo3D.UseZBuffer(false); ipaintTo3D.SetColor(Color.White); ipaintTo3D.FillRect2D(ll.PointF, ur.PointF); //ipaintTo3D.FinishPaint();// DEBUG //return; // DEBUG ipaintTo3D.AvoidColor(Color.White); if (RepaintActionEvent != null) { RepaintActionEvent(this, ipaintTo3D); } for (int i = 0; i < layout.Patches.Length; ++i) { LayoutPatch lp = layout.Patches[i]; BoundingRect paperRect = new BoundingRect(0.0, 0.0, layout.PaperWidth, layout.PaperHeight); BoundingRect ext; if (lp.Area != null) { ext = lp.Area.Extent; } else { ext = paperRect; } GeoPoint2D clipll = layoutToScreen * ext.GetLowerLeft(); GeoPoint2D clipur = layoutToScreen * ext.GetUpperRight(); Rectangle clipRectangle = Rectangle.FromLTRB((int)clipll.x, (int)clipur.y, (int)clipur.x, (int)clipll.y); Projection pr = lp.Projection.Clone(); double factor, dx, dy; pr.GetPlacement(out factor, out dx, out dy); pr.SetPlacement(layoutToScreen.Factor * factor, ll.x + layoutToScreen.Factor * dx, ll.y - layoutToScreen.Factor * dy); pr.Precision = lp.Model.Extent.Size / 1000; ipaintTo3D.Precision = pr.Precision; ipaintTo3D.SetProjection(pr, lp.Model.Extent); ipaintTo3D.UseZBuffer(true); ipaintTo3D.SetClip(clipRectangle); ipaintTo3D.PaintFaces(PaintTo3D.PaintMode.All); // lp.Model.ClearDisplayLists(); lp.Model.RecalcDisplayLists(ipaintTo3D); if (lp.Projection.ShowFaces) { ipaintTo3D.PaintFaces(PaintTo3D.PaintMode.FacesOnly); foreach (KeyValuePair <Layer, IPaintTo3DList> kv in lp.Model.layerFaceDisplayList) { if (lp.IsLayerVisible(kv.Key) || lp.Model.nullLayer == kv.Key) { ipaintTo3D.List(kv.Value); } } } ipaintTo3D.PaintFaces(PaintTo3D.PaintMode.CurvesOnly); foreach (KeyValuePair <Layer, IPaintTo3DList> kv in lp.Model.layerCurveDisplayList) { if (lp.IsLayerVisible(kv.Key) || lp.Model.nullLayer == kv.Key) { ipaintTo3D.List(kv.Value); } } ipaintTo3D.SetClip(Rectangle.Empty); } ipaintTo3D.FinishPaint(); }