// Constructor. public DrawingGraphics(IToolkit toolkit, Xsharp.Graphics graphics) : base(toolkit) { this.graphics = graphics; this.font = null; this.gaveHdc = false; }
// Select this brush into a graphics object. public override void Select(IToolkitGraphics _graphics) { DrawingGraphics graphics = (_graphics as DrawingGraphics); if (graphics != null) { Xsharp.Graphics g = graphics.graphics; Xsharp.Bitmap bitmap; lock (typeof(DrawingHatchBrush)) { bitmap = GetBitmap(style); } g.Function = GCFunction.GXcopy; g.SubwindowMode = SubwindowMode.ClipByChildren; if (bitmap != null) { // Use an opaque stipple to fill the region. g.Foreground = DrawingToolkit.DrawingToXColor(foreColor); g.Background = DrawingToolkit.DrawingToXColor(backColor); g.SetFillOpaqueStippled(bitmap, 0, 0); } else { // We don't recognize this hatch style, so use a // solid brush with the foreground color. g.Foreground = DrawingToolkit.DrawingToXColor(foreColor); g.SetFillSolid(); } graphics.Brush = this; } }
// Dispose of this object. protected override void Dispose(bool disposing) { if (graphics != null) { graphics.Dispose(); graphics = null; } }
// Dispose of this object. protected override void Dispose(bool disposing) { if(graphics != null) { graphics.Dispose(); graphics = null; } }
// Select this brush into a graphics object. public override void Select(IToolkitGraphics _graphics) { innerBrush.Select(_graphics); DrawingGraphics graphics = (_graphics as DrawingGraphics); if (graphics != null) { Xsharp.Graphics g = graphics.graphics; g.Function = GCFunction.GXxor; g.SubwindowMode = SubwindowMode.IncludeInferiors; } graphics.Brush = this; }
// Handle a paint event from Xsharp. protected override void OnPaint(Xsharp.Graphics graphics) { if (sink != null) { System.Drawing.Region clip = RegionToDrawingRegion(graphics.ExposeRegion); DrawingGraphics g = new DrawingGraphics(toolkit, graphics); using (System.Drawing.Graphics gr = ToolkitManager.CreateGraphics(g, clip)) { sink.ToolkitExpose(gr); } } }
// Select this brush into a graphics object. public override void Select(IToolkitGraphics _graphics) { DrawingGraphics graphics = (_graphics as DrawingGraphics); if (graphics != null) { Xsharp.Graphics g = graphics.graphics; g.Function = GCFunction.GXcopy; g.SubwindowMode = SubwindowMode.ClipByChildren; g.SetFillSolid(); g.Foreground = DrawingToolkit.DrawingToXColor(Color); graphics.Brush = this; } }
// Select this brush into a graphics object. public void Select(IToolkitGraphics _graphics) { DrawingGraphics graphics = (_graphics as DrawingGraphics); if (graphics != null && image != null) { Xsharp.Graphics g = graphics.graphics; Xsharp.Image nativeImage = image.GetNativeImage(); g.Function = GCFunction.GXcopy; g.SubwindowMode = SubwindowMode.ClipByChildren; g.SetFillTiled(nativeImage.Pixmap, (int)(dstRect.X), (int)(dstRect.Y)); } }
// Convert an XImage mask into a Bitmap object. public static Bitmap XImageMaskToBitmap(Screen screen, IntPtr ximage) { int width, height; Xlib.XSharpGetImageSize(ximage, out width, out height); Bitmap bitmap = new Bitmap(screen, width, height); Graphics graphics = new Graphics(bitmap); graphics.PutXImage(ximage, 0, 0, 0, 0, width, height); graphics.Dispose(); return bitmap; }
// Redraw this button. private void Draw() { using(Graphics graphics = new Graphics(this)) { OnPaint(graphics); } }
// Draw a caption button. Returns the width of the button. private static int DrawCaptionButton (Graphics graphics, Rectangle rect, int subtract, bool pressed, bool draw, XPixmap buttonPixmap) { int buttonSize = rect.height - 4; int x = rect.x + rect.width - subtract - buttonSize; int y = rect.y + 2; if(draw) { if(pressed) { graphics.DrawEffect(x, y, buttonSize, buttonSize, Effect.CaptionButtonIndented); ++x; ++y; } else { graphics.DrawEffect(x, y, buttonSize, buttonSize, Effect.CaptionButtonRaised); } x += (buttonSize - 9) / 2; y += (buttonSize - 9) / 2; graphics.DrawBitmap(x, y, 9, 9, buttonPixmap); } return buttonSize; }
/// <summary> /// <para>Method that is raised when the widget needs to be /// painted in reponse to an <c>Expose</c> event.</para> /// </summary> /// /// <param name="graphics"> /// <para>The graphics object to use to repaint the widget. This /// graphics object will have been initialised with the widgets foreground /// and background colors, and with the clipping region set to the area /// that needs to be repainted.</para> /// </param> protected virtual void OnPaint(Graphics graphics) { // Nothing to do in this class. }
/// <summary> /// <para>Get extent information for this font, when drawing /// onto a particular graphics context.</para> /// </summary> /// /// <param name="graphics"> /// <para>The graphics context to get the extent information for.</para> /// </param> /// /// <returns> /// <para>Returns the extent information.</para> /// </returns> /// /// <exception cref="T:System.ArgumentNullException"> /// <para>Raised if <paramref name="graphics"/> is <see langword="null"/>. /// </para> /// </exception> public virtual FontExtents GetFontExtents(Graphics graphics) { if(graphics == null) { throw new ArgumentNullException("graphics"); } FontExtents extents = null; GetFontSet(graphics.dpy, out extents); return extents; }
/// <summary> /// <para>Measure the width, ascent, and descent of a string, /// to calculate its extents when drawn on a graphics context /// using this font.</para> /// </summary> /// /// <param name="graphics"> /// <para>The graphics context to measure with.</para> /// </param> /// /// <param name="str"> /// <para>The string to be measured.</para> /// </param> /// /// <param name="index"> /// <para>The starting index in <paramref name="str"/> of the first /// character to be measured.</para> /// </param> /// /// <param name="count"> /// <para>The number of characters <paramref name="str"/> /// to be measured.</para> /// </param> /// /// <param name="width"> /// <para>The width of the string, in pixels.</para> /// </param> /// /// <param name="ascent"> /// <para>The ascent of the string, in pixels.</para> /// </param> /// /// <param name="descent"> /// <para>The descent of the string, in pixels.</para> /// </param> /// /// <exception cref="T:System.ArgumentNullException"> /// <para>Raised if <paramref name="graphics"/> is <see langword="null"/>. /// </para> /// </exception> public virtual void MeasureString (Graphics graphics, String str, int index, int count, out int width, out int ascent, out int descent) { // Validate the parameters. if(graphics == null) { throw new ArgumentNullException("graphics"); } if(str == null || count == 0) { width = 0; ascent = 0; descent = 0; return; } // Extract the substring to be measured. // TODO: make this more efficient by avoiding the data copy. str = str.Substring(index, count); // Get the font set to use to measure the string. IntPtr fontSet = GetFontSet(graphics.dpy); if(fontSet == IntPtr.Zero) { width = 0; ascent = 0; descent = 0; return; } // Get the text extents and decode them into useful values. XRectangle overall_ink; XRectangle overall_logical; try { IntPtr display = graphics.dpy.Lock(); Xlib.XSharpTextExtentsSet (display, fontSet, str, out overall_ink, out overall_logical); } finally { graphics.dpy.Unlock(); } width = overall_logical.width; ascent = -(overall_logical.y); descent = overall_logical.height + overall_logical.y; // Increase the descent to account for underlining. // We always draw the underline on pixel below // the font base line. if((style & FontStyle.Underlined) != 0) { if(descent < 2) { descent = 2; } } }
// Clear a double buffer at the start of a drawing operation. internal void ClearAtStart(Graphics graphics) { // Fill the pixmap with the background color if necessary. // We don't have to do this with Xdbe buffers because the // X server should have already taken care of it for us // during the last expose operation on the widget. // [Marc Haisenko] I'm experiencing a strange bug if double // buffering is enabled and certain widgets use a transparent // background color... this is fixed by clearing the buffer. // But I don't think this is the cause... if ((!usesXdbe) || (widget.Background.Index == StandardColor.Inherit)) { graphics.Clear(); } }
// End a double buffer drawing operation. internal void End(Graphics graphics) { try { IntPtr display = dpy.Lock(); if(handle != XDrawable.Zero) { if(usesXdbe) { Xlib.XdbeSwapInfo info = new Xlib.XdbeSwapInfo(); info.swap_window = widget.GetWidgetHandle(); info.swap_action = Xlib.XdbeSwapAction.Background; Xlib.XdbeSwapBuffers(display, ref info, 1); } else { using(Graphics g = new Graphics(widget)) { Xlib.XCopyArea (display, handle, widget.GetGCHandle(), g.gc, 0, 0, (uint)width, (uint)height, 0, 0); } } } } finally { dpy.Unlock(); } }
// Change the state of a caption button. Returns true if the // button was pressed before we changed its state. private bool ChangeButtonState(HitTest hitTest, bool pressed) { // Determine what change we need to apply. CaptionFlags buttonsToDraw = (CaptionFlags)0; CaptionFlags pressedState = (CaptionFlags)0; CaptionFlags origFlags = flags; switch(hitTest) { case HitTest.Close: { buttonsToDraw = CaptionFlags.HasClose; pressedState = CaptionFlags.ClosePressed; } break; case HitTest.Maximize: { buttonsToDraw = CaptionFlags.HasMaximize; pressedState = CaptionFlags.MaximizePressed; } break; case HitTest.Minimize: { buttonsToDraw = CaptionFlags.HasMinimize; pressedState = CaptionFlags.MinimizePressed; } break; case HitTest.Restore: { buttonsToDraw = CaptionFlags.HasRestore; pressedState = CaptionFlags.RestorePressed; } break; case HitTest.Help: { buttonsToDraw = CaptionFlags.HasHelp; pressedState = CaptionFlags.HelpPressed; } break; } if(pressed) { flags |= pressedState; } else { flags &= ~pressedState; } // Redraw the caption buttons to match the state change. if(flags != origFlags) { Rectangle rect = new Rectangle (FrameBorderSize, FrameBorderSize, width - FrameBorderSize * 2, captionHeight - FrameBorderSize); using(Graphics graphics = new Graphics(this)) { DrawCaptionButtons (graphics, rect, flags, buttonsToDraw); } } return ((origFlags & pressedState) != 0); }
// Paint this widget in response to an "Expose" event. protected override void OnPaint(Graphics graphics) { // Draw the thick 3D border around the outside first. graphics.DrawEffect(0, 0, width, height, Effect.Raised); // Get the rectangle containing the caption area. Rectangle rect = new Rectangle (FrameBorderSize, FrameBorderSize, width - FrameBorderSize * 2, captionHeight - FrameBorderSize); // If the rectangle does not overlap the expose region, // then there is no point drawing the main caption area. if(!graphics.ExposeRegion.Overlaps(rect)) { return; } // Get the colors to use for the foreground and background. Color foreground, background, endBackground; if((flags & CaptionFlags.Active) != 0) { foreground = new Color(StandardColor.HighlightForeground); background = new Color(StandardColor.HighlightBackground); endBackground = new Color(StandardColor.HighlightEndBackground); } else { foreground = new Color(StandardColor.Background); background = new Color(StandardColor.BottomShadow); endBackground = new Color(StandardColor.EndBackground); } // Create a gradient for the title bar, if necessary. if(gradient != null && (gradient.Width != rect.width || gradient.Height != rect.height)) { // The size has changed and we need a new gradient. gradient.Dispose(); gradient = null; } if(gradient == null && screen.DefaultDepth >= 15) { DotGNU.Images.Image image = CreateGradient (rect.width, rect.height, background, endBackground); gradient = new Xsharp.Image(screen, image.GetFrame(0)); image.Dispose(); } // Clear the caption background. if(gradient == null) { graphics.Foreground = background; graphics.SetFillSolid(); graphics.FillRectangle(rect); } else { graphics.SetFillTiled(gradient.Pixmap, rect.x, rect.y); graphics.FillRectangle(rect); graphics.SetFillSolid(); } // Draw the caption buttons and then subtract that // region off the caption rectangle so we don't get // bleed through when we draw the caption text. rect.width -= DrawCaptionButtons (graphics, rect, flags, (CaptionFlags)(~0)); // Bail out if the rectangle is too small for the text. if(rect.width <= 2) { return; } // Position the caption text. Font font = GetCaptionFont(); FontExtents extents = font.GetFontExtents(graphics); int textY = (rect.height - extents.Ascent) / 2; textY += rect.y + extents.Ascent; // Draw the caption text, clipped to the caption area // so that it won't overwrite the buttons on the right. using(Region region = new Region(graphics.ExposeRegion)) { region.Intersect(rect); graphics.SetClipRegion(region); graphics.Foreground = foreground; graphics.DrawString(rect.x + 2, textY, child.Name, font); } }
// Draw the caption buttons in their current state. Returns the // number of pixels on the right of the caption that are occupied // by the buttons. private static int DrawCaptionButtons (Graphics graphics, Rectangle rect, CaptionFlags flags, CaptionFlags buttonsToDraw) { int subtract = 2; if((flags & CaptionFlags.HasClose) != 0) { subtract += DrawCaptionButton (graphics, rect, subtract, ((flags & CaptionFlags.ClosePressed) != 0), ((buttonsToDraw & CaptionFlags.HasClose) != 0), graphics.dpy.bitmaps.Close); if((flags & (CaptionFlags.HasMaximize | CaptionFlags.HasRestore | CaptionFlags.HasMinimize)) != 0) { // Leave a gap between the close button and the others. subtract += 2; } } if((flags & CaptionFlags.HasMaximize) != 0) { subtract += DrawCaptionButton (graphics, rect, subtract, ((flags & CaptionFlags.MaximizePressed) != 0), ((buttonsToDraw & CaptionFlags.HasMaximize) != 0), graphics.dpy.bitmaps.Maximize); } if((flags & CaptionFlags.HasRestore) != 0) { subtract += DrawCaptionButton (graphics, rect, subtract, ((flags & CaptionFlags.RestorePressed) != 0), ((buttonsToDraw & CaptionFlags.HasRestore) != 0), graphics.dpy.bitmaps.Restore); } if((flags & CaptionFlags.HasMinimize) != 0) { subtract += DrawCaptionButton (graphics, rect, subtract, ((flags & CaptionFlags.MinimizePressed) != 0), ((buttonsToDraw & CaptionFlags.HasMinimize) != 0), graphics.dpy.bitmaps.Minimize); } if((flags & CaptionFlags.HasHelp) != 0) { // Leave a gap between the help button and the others. subtract += 2; subtract += DrawCaptionButton (graphics, rect, subtract, ((flags & CaptionFlags.HelpPressed) != 0), ((buttonsToDraw & CaptionFlags.HasHelp) != 0), graphics.dpy.bitmaps.Help); } if(subtract > 2) { // Leave a gap between the buttons and the text. return subtract + 2; } else { // There are no buttons, so no need for an extra gap. return 2; } }
// Convert an XImage into a Pixmap object. public static Pixmap XImageToPixmap(Screen screen, IntPtr ximage) { int width, height; Xlib.XSharpGetImageSize(ximage, out width, out height); Pixmap pixmap = new Pixmap(screen, width, height); Graphics graphics = new Graphics(pixmap); graphics.PutXImage(ximage, 0, 0, 0, 0, width, height); graphics.Dispose(); return pixmap; }
public override void DrawString (Graphics graphics, int x, int y, String str, int index, int count) { // Validate the parameters. if(x < -32768 || x > 32767 || y < -32768 || y > 32767) { throw new XException(S._("X_PointCoordRange")); } if(graphics == null) { throw new ArgumentNullException("graphics"); } if(str == null || count <= 0) { return; } if(index < 0 || index >= str.Length || count > (str.Length - index)) { return; } // Get the font set to use for the font. IntPtr fontSet = GetFontSet(graphics.dpy); if(fontSet == IntPtr.Zero) { return; } // Draw the string using the specified font set. try { IntPtr display = graphics.dpy.Lock(); Xlib.XSharpDrawStringPCF (display, graphics.drawableHandle, graphics.gc, fontSet, x, y, str, index, count, (int)style); } finally { graphics.dpy.Unlock(); } }
// Select this pen into a graphics object. public override void Select(IToolkitGraphics _graphics) { if (_graphics == null) { return; } if (_graphics is DrawingGraphics) { DrawingGraphics graphics = _graphics as DrawingGraphics; Xsharp.Graphics g = graphics.graphics; int width = (int)(properties.Width); LineStyle style = MapLineStyle(properties.DashStyle); if (style == LineStyle.LineOnOffDash) { if (width == 1) { width = 0; } switch (properties.DashStyle) { case DashStyle.Dash: { g.DashPattern = dash; } break; case DashStyle.Dot: { g.DashPattern = dot; } break; case DashStyle.DashDot: { g.DashPattern = dashdot; } break; case DashStyle.DashDotDot: { g.DashPattern = dashdotdot; } break; case DashStyle.Custom: { float [] src = properties.DashPattern; int iLen = src.Length; byte [] ayCopy = new byte[iLen]; float fWidth = properties.Width; float tmp; for (int i = 0; i < iLen; i++) { tmp = src[i] * fWidth; if (tmp < 0) { tmp = 0; } else if (tmp > 0xFF) { tmp = 0xFF; } ayCopy[i] = (byte)(tmp); if (ayCopy[i] == 0) { ayCopy[i] = 1; // must not be zero } } g.DashPattern = ayCopy; } break; } } g.Function = GCFunction.GXcopy; g.SubwindowMode = SubwindowMode.ClipByChildren; g.LineWidth = width; g.LineStyle = style; g.CapStyle = MapCapStyle(properties.EndCap); g.JoinStyle = MapJoinStyle(properties.LineJoin); g.Foreground = DrawingToolkit.DrawingToXColor (properties.Color); g.SetFillSolid(); graphics.Pen = this; } else if (_graphics is DrawingGraphicsImage) { DrawingGraphicsImage graphics = _graphics as DrawingGraphicsImage; graphics.Pen = this; } }
/// <summary> /// <para>Draw a string at a particular position on a /// specified graphics context.</para> /// </summary> /// /// <param name="graphics"> /// <para>The graphics context to draw on.</para> /// </param> /// /// <param name="x"> /// <para>The X co-ordinate of the position to start drawing text.</para> /// </param> /// /// <param name="y"> /// <para>The Y co-ordinate of the position to start drawing text.</para> /// </param> /// /// <param name="str"> /// <para>The string to be drawn.</para> /// </param> /// /// <param name="index"> /// <para>The starting index in <paramref name="str"/> of the first /// character to be measured.</para> /// </param> /// /// <param name="count"> /// <para>The number of characters <paramref name="str"/> /// to be measured.</para> /// </param> /// /// <exception cref="T:Xsharp.XException"> /// <para>One of the co-ordinate values is out of range.</para> /// </exception> /// /// <exception cref="T:System.ArgumentNullException"> /// <para>Raised if <paramref name="graphics"/> is <see langword="null"/>. /// </para> /// </exception> public virtual void DrawString (Graphics graphics, int x, int y, String str, int index, int count) { // Validate the parameters. if(x < -32768 || x > 32767 || y < -32768 || y > 32767) { throw new XException(S._("X_PointCoordRange")); } if(graphics == null) { throw new ArgumentNullException("graphics"); } if(str == null || count == 0) { return; } // Extract the substring to be measured. // TODO: make this more efficient by avoiding the data copy. str = str.Substring(index, count); // Get the font set to use for the font. IntPtr fontSet = GetFontSet(graphics.dpy); if(fontSet == IntPtr.Zero) { return; } // Draw the string using the specified font set. try { IntPtr display = graphics.dpy.Lock(); Xlib.XSharpDrawStringSet (display, graphics.drawableHandle, graphics.gc, fontSet, x, y, str, (int)style); } finally { graphics.dpy.Unlock(); } }
// Start a double buffer drawing operation. internal void Start(Graphics graphics) { // Re-create the pixmap object if the widget size has changed. if(!usesXdbe) { if(widget.width != width || widget.height != height) { try { IntPtr display = dpy.Lock(); if(handle != XDrawable.Zero) { Xlib.XFreePixmap(display, (XPixmap)handle); } handle = (XDrawable) Xlib.XCreatePixmap (display, (XDrawable) Xlib.XRootWindowOfScreen(screen.screen), (uint)(widget.Width), (uint)(widget.Height), (uint)Xlib.XDefaultDepthOfScreen (screen.screen)); } finally { dpy.Unlock(); } } } // Copy the width and height values from the widget. width = widget.Width; height = widget.Height; }
/// <summary> /// <para>Update this widget by immediately redrawing invalidated /// regions.</para> /// </summary> /// /// <param name="clear"> /// <para>Setting clear to true clears the region to the background. /// </para> /// </param> public void Update(bool clear) { Region region = invalidateRegion; invalidateRegion = null; if(region != null) { // Remove the region from the pending list. dpy.RemovePendingInvalidate(this); // No point redrawing if we are unmapped or the // region to be drawn is empty. if(mapped && AncestorsMapped && (!clear || ClearRegion(region, XBool.False))) { // Paint the region as if we got a regular expose. Graphics graphics = new Graphics(this); graphics.exposeRegion = region; graphics.SetClipRegion(region); try { OnPaint(graphics); } finally { graphics.Dispose(); } } // Dispose the region that we no longer require. region.Dispose(); } }
// Paint this widget in response to an "Expose" event. protected override void OnPaint(Graphics graphics) { XPixmap pixmap; if((flags & CaptionWidget.CaptionFlags.HasClose) != 0) { pixmap = graphics.dpy.bitmaps.Close; } else if((flags & CaptionWidget.CaptionFlags.HasRestore) != 0) { pixmap = graphics.dpy.bitmaps.Restore; } else { pixmap = graphics.dpy.bitmaps.Minimize; } int x = (width - 9) / 2; int y = (height - 9) / 2; if(pressed && entered) { graphics.DrawEffect(0, 0, width, height, Effect.CaptionButtonIndented); ++x; ++y; } else { graphics.DrawEffect(0, 0, width, height, Effect.CaptionButtonRaised); } graphics.DrawBitmap(x, y, 9, 9, pixmap); }
// Process pending exposures on this widget. internal void Expose() { Region region = exposeRegion; if(region != null) { exposeRegion = null; // sometimes it could be that Expose is called but the handle is destroyed. // so check here, if handle not null. if( handle != XDrawable.Zero ) { try { Graphics graphics = new Graphics(this); graphics.exposeRegion = region; graphics.SetClipRegion(region); OnPaint(graphics); graphics.Dispose(); region.Dispose(); } catch( XInvalidOperationException ) { // irgnore Widget disposed exception } } } }
// Get the size of the top-most border on a caption widget, // including the title bar display area. private static int GetCaptionHeight(Widget widget) { Font font = GetCaptionFont(); int height; using(Graphics graphics = new Graphics(widget)) { FontExtents extents = font.GetFontExtents(graphics); height = extents.Ascent + extents.Descent; } height += CaptionExtra; if(height < CaptionMinimum) { height = CaptionMinimum; } return height + FrameBorderSize; }