/// <summary> /// Constructs a new PPaintContext. /// </summary> /// <param name="graphics"> /// The graphics context to associate with this paint context. /// </param> /// <param name="canvas">The canvas that the paint context will render on.</param> public PPaintContext(Graphics2D graphics, PCanvas canvas) { this.graphics = graphics; this.canvas = canvas; clipStack = new Stack(); localClipStack = new Stack(); cameraStack = new Stack(); transformStack = new Stack(); RenderQuality = RenderQuality.HighQuality; Region clip = graphics.Clip; if (clip.IsInfinite(graphics.Graphics)) { clip = new Region( new Rectangle(-int.MaxValue / 2, -int.MaxValue / 2, int.MinValue, int.MaxValue)); graphics.Clip = clip; } localClipStack.Push(graphics.ClipBounds); CURRENT_PAINT_CONTEXT = this; }
protected override void Paint(UMD.HCIL.PocketPiccolo.Util.PPaintContext paintContext) { Graphics2D g = paintContext.Graphics; if (points.Count > 0) { if (Brush != null && closed) { g.FillPolygon(Brush, (PointF[])points.ToArray(typeof(PointF))); } if (pen != null) { if (closed) { g.DrawPolygon(pen, (PointF[])points.ToArray(typeof(PointF))); } else { for (int i = 0; i < points.Count - 1; i++) { g.DrawLine(pen, (PointF)points[i], (PointF)points[i + 1]); } } } } }
protected override void Paint(PPaintContext paintContext) { Graphics2D g = paintContext.Graphics; if (Brush != null) { g.FillEllipse(Brush, Bounds); } if (pen != null) { g.DrawEllipse(pen, Bounds); } }
//**************************************************************** // Painting - Methods for painting a PText. //**************************************************************** /// <summary> /// Overridden. See <see cref="PNode.Paint">PNode.Paint</see>. /// </summary> protected override void Paint(UMD.HCIL.PocketPiccolo.Util.PPaintContext paintContext) { base.Paint(paintContext); if (text != null && textBrush != null && font != null) { Graphics2D g = paintContext.Graphics; float renderedFontSize = font.Size * paintContext.Scale; //font.SizeInPoints * paintContext.Scale; if (renderedFontSize < PUtil.GreekThreshold) { // .NET bug: DrawString throws a generic gdi+ exception when // the scaled font size is very small. So, we will render // the text as a simple rectangle for small fonts g.FillRectangle(textBrush, Bounds); } else if (renderedFontSize < PUtil.MaxFontSize) { g.DrawString(text, font, textBrush, Bounds); //, stringFormat); } } }
//**************************************************************** // Painting Layers - Methods for painting the layers viewed by // the camera. //**************************************************************** /// <summary> /// Overridden. Paint this camera (default background color is white) and then paint /// the camera's view through the view transform. /// </summary> /// <param name="paintContext">The paint context to use for painting this camera.</param> protected override void Paint(PPaintContext paintContext) { base.Paint(paintContext); RectangleF b = this.Bounds; Rectangle iBounds = new Rectangle((int)b.X, (int)b.Y, (int)b.Width, (int)b.Height); paintContext.PushClip(new Region(iBounds)); paintContext.PushTransform(viewMatrix); PaintCameraView(paintContext); PaintDebugInfo(paintContext); paintContext.PopTransform(viewMatrix); paintContext.PopClip(new Region(iBounds)); }
/// <summary> /// Overridden. Push the camera onto the paintContext, so that it can later be accessed /// by <see cref="PPaintContext.Camera">PPaintContext.Camera</see>, and then paint this /// node and all of it's descendents. /// </summary> /// <param name="paintContext">The paint context to use for painting this camera.</param> public override void FullPaint(PPaintContext paintContext) { paintContext.PushCamera(this); base.FullPaint(paintContext); paintContext.PopCamera(this); }
/// <summary> /// Overridden. See <see cref="Control.OnPaint">Control.OnPaint</see>. /// </summary> protected override void OnPaint(PaintEventArgs pe) { PDebug.StartProcessingOutput(); Graphics2D g = new Graphics2D(offscreenGraphics); g.Clip = new Region(pe.ClipRectangle); //Graphics2D g = new Graphics2D(pe.Graphics); // create new paint context and set render quality to lowest common // denominator render quality. //Rectangle clipRect = pe.ClipRectangle; //RectangleF fClipRect = new RectangleF(clipRect.X, clipRect.Y, clipRect.Width, clipRect.Height); PPaintContext paintContext = new PPaintContext(g, this); if (Interacting || Animating) { if (interactingRenderQuality < animatingRenderQuality) { paintContext.RenderQuality = interactingRenderQuality; } else { paintContext.RenderQuality = animatingRenderQuality; } } else { paintContext.RenderQuality = defaultRenderQuality; } // paint camera.FullPaint(paintContext); // if switched state from animating to not animating invalidate the entire // screen so that it will be drawn with the default instead of animating // render quality. if (!Animating && animatingOnLastPaint) { Invalidate(); } animatingOnLastPaint = Animating; // Calling the base class OnPaint base.OnPaint(pe); realGraphics.DrawImage(this.offscreenBitmap, 0, 0); PDebug.EndProcessingOutput(g); }
/* /// <summary> /// Constructs a new PrintDocument, allows the user to select which printer /// to print to, and then prints the node. /// </summary> public virtual void Print() { PrintDocument printDocument = new PrintDocument(); PrintDialog printDialog = new PrintDialog(); printDialog.Document = printDocument; if (printDialog.ShowDialog() == DialogResult.OK) { printDocument.PrintPage += new PrintPageEventHandler(printDocument_PrintPage); printDocument.Print(); } } /// <summary> /// Prints the node into the given Graphics context. /// </summary> /// <param name="sender">The source of the PrintPage event.</param> /// <param name="e">The PrintPageEventArgs.</param> protected virtual void printDocument_PrintPage(object sender, PrintPageEventArgs e) { Graphics g = (Graphics)e.Graphics; RectangleF bounds = FullBounds; // Approximate the printable area of the page. This approximation assumes // the unprintable margins are distributed equally between the left and right, // and top and bottom sides. To exactly determine the printable area, you // must resort to the Win32 API. RectangleF displayRect = new RectangleF( e.MarginBounds.Left - (e.PageBounds.Width - g.VisibleClipBounds.Width) / 2, e.MarginBounds.Top - (e.PageBounds.Height - g.VisibleClipBounds.Height) / 2, e.MarginBounds.Width, e.MarginBounds.Height); ScaleAndDraw(g, bounds, displayRect); } */ /// <summary> /// Scale the Graphics so that this node's full bounds fit in displayRect and then /// render into the given Graphics context. /// </summary> /// <param name="g">The Graphics context to use when rendering the node.</param> /// <param name="bounds">The full bounds of the node to be rendered.</param> /// <param name="displayRect">The imageable area.</param> protected virtual void ScaleAndDraw(Graphics2D g, RectangleF bounds, RectangleF displayRect) { g.TranslateTransform(displayRect.X, displayRect.Y); // scale the graphics so node's full bounds fit in the imageable bounds. float scale = displayRect.Width / bounds.Width; if (displayRect.Height / bounds.Height < scale) { scale = displayRect.Height / bounds.Height; } //g.ScaleTransform(scale, scale); g.ScaleTransform(scale); g.TranslateTransform(-bounds.X, -bounds.Y); PPaintContext pc = new PPaintContext(g, null); pc.RenderQuality = RenderQuality.HighQuality; FullPaint(pc); }
/// <summary> /// Subclasses that wish to do additional painting after their children /// are painted should override this method and do that painting here. /// </summary> /// <param name="paintContext"> /// The paint context to use for painting after the children are painted. /// </param> protected virtual void PaintAfterChildren(PPaintContext paintContext) { }
/// <summary> /// Paint this node and all of its descendents. /// </summary> /// <param name="paintContext">The paint context to use for painting this node.</param> /// <remarks> /// <b>Notes to Inheritors:</b> Most subclasses do not need to override this method, /// they should override <c>paint</c> or <c>paintAfterChildren</c> instead. /// </remarks> public virtual void FullPaint(PPaintContext paintContext) { if (Visible && FullIntersects(paintContext.LocalClip)) { paintContext.PushTransform(matrix); //paintContext.PushTransparency(transparency); if (!Occluded) { Paint(paintContext); } int count = ChildrenCount; for (int i = 0; i < count; i++) { children[i].FullPaint(paintContext); } PaintAfterChildren(paintContext); //paintContext.popTransparency(transparency); paintContext.PopTransform(matrix); } }
//**************************************************************** // Painting - Methods for painting a PImage. //**************************************************************** /// <summary> /// Overridden. See <see cref="PNode.Paint">PNode.Paint</see>. /// </summary> protected override void Paint(PPaintContext paintContext) { if (Image != null) { RectangleF b = Bounds; Graphics2D g = paintContext.Graphics; g.DrawImage(image, b.X, b.Y); } }
/// <summary> /// Overridden. Pops the clip from the paint context and then renders the outline /// of this node. /// </summary> /// <param name="paintContext"> /// The paint context to use for painting this node. /// </param> protected override void PaintAfterChildren(PPaintContext paintContext) { TEMP_REGION.MakeInfinite(); TEMP_REGION.Intersect(new Rectangle((int)Bounds.X, (int)Bounds.Y, (int)Bounds.Width, (int)Bounds.Height)); paintContext.PopClip(TEMP_REGION); base.PaintAfterChildren(paintContext); //if (Pen != null) { // Graphics g = paintContext.Graphics; // g.DrawPath(Pen, PathReference); //} }
/// <summary> /// Overridden. Renders the fill for this node and then pushes the clip onto the /// paint context, so that when this node's children are rendered they will be /// clipped accordingly. /// </summary> /// <param name="paintContext"> /// The paint context to use for painting this node. /// </param> protected override void Paint(PPaintContext paintContext) { //Brush b = Brush; //if (b != null) { // Graphics g = paintContext.Graphics; // g.FillPath(b, this.PathReference); //} base.Paint(paintContext); TEMP_REGION.MakeInfinite(); TEMP_REGION.Intersect(new Region(new Rectangle((int)Bounds.X, (int)Bounds.Y, (int)Bounds.Width, (int)Bounds.Height))); paintContext.PushClip(TEMP_REGION); }
/// <summary> /// Paint all the layers that the camera is looking at. /// </summary> /// <param name="paintContext"> /// The paint context to use for painting this camera's view. /// </param> /// <remarks> /// This method is only called when the cameras view matrix and clip are applied to /// the paintContext. /// </remarks> protected virtual void PaintCameraView(PPaintContext paintContext) { foreach (PLayer each in layers) { each.FullPaint(paintContext); } }
/* Not Implemented Yet * C# does not support setting an alpha composite value for all rendering public virtual float Transparency { get { return transparency; } set { if (Transparency != value) { transparency = value; InvalidatePaint(); } } } */ /// <summary> /// Paint this node behind any of its children nodes. /// </summary> /// <param name="paintContext">The paint context to use for painting this node.</param> /// <remarks> /// <b>Notes to Inheritors:</b> Subclasses that define a different appearance should /// override this method and paint themselves there. /// </remarks> protected virtual void Paint(PPaintContext paintContext) { if (Brush != null) { Graphics2D g = paintContext.Graphics; g.FillRectangle(Brush, Bounds); } }
/// <summary> /// This method paints the bounds and full bounds of nodes when the appropriate debug /// flags are set. /// </summary> /// <param name="paintContext"> /// The paint context to use for painting debug information. /// </param> /// <remarks> /// Setting debugBounds and/or debugFullBounds flags is useful for visual debugging. /// </remarks> protected virtual void PaintDebugInfo(PPaintContext paintContext) { if (PDebug.DebugBounds || PDebug.DebugFullBounds) { Graphics2D g = paintContext.Graphics; PNodeList nodes = new PNodeList(); RectangleF nodeBounds = RectangleF.Empty; for (int i = 0; i < LayerCount; i++) { GetLayer(i).GetAllNodes(null, nodes); } GetAllNodes(null, nodes); foreach (PNode each in nodes) { if (PDebug.DebugBounds) { nodeBounds = each.Bounds; if (!nodeBounds.IsEmpty) { nodeBounds = each.LocalToGlobal(nodeBounds); nodeBounds = GlobalToLocal(nodeBounds); if (each == this || each.IsDescendentOf(this)) { nodeBounds = LocalToView(nodeBounds); } g.DrawRectangle(boundsPen, nodeBounds.X, nodeBounds.Y, nodeBounds.Width, nodeBounds.Height); } } if (PDebug.DebugFullBounds) { nodeBounds = each.FullBounds; if (!nodeBounds.IsEmpty) { if (each.Parent != null) { nodeBounds = each.Parent.LocalToGlobal(nodeBounds); } nodeBounds = GlobalToLocal(nodeBounds); if (each == this || each.IsDescendentOf(this)) { nodeBounds = LocalToView(nodeBounds); } //g.FillRectangle(fullBoundsBrush, nodeBounds); g.DrawRectangle(fullBoundsPen, nodeBounds); } } } } }