/// <summary> /// <para>Blit a drawable's entire contents to this graphics context.</para> /// </summary> /// /// <param name="x"> /// <para>The X co-ordinate of the top-left point of /// the destination bounding rectangle.</para> /// </param> /// /// <param name="y"> /// <para>The Y co-ordinate of the top-left point of /// the destination bounding rectangle.</para> /// </param> /// /// <param name="drawable"> /// <para>The drawable to copy from.</para> /// </param> /// /// <exception cref="T:System.ArgumentNullException"> /// <para>Raised if <paramref name="drawable"/> is <see langword="null"/>. /// </para> /// </exception> /// /// <exception cref="T:Xsharp.XException"> /// <para>One of the co-ordinate or size values is out of range.</para> /// </exception> public void BitBlt(int x, int y, Drawable drawable) { // Validate the drawable parameter. if(drawable == null) { throw new ArgumentNullException("drawable"); } // Perform the blit operation. BitBlt(x, y, drawable, 0, 0, drawable.Width, drawable.Height); }
/// <summary> /// <para>Constructs a new <see cref="T:Xsharp.Graphics"/> object and /// attaches it to a <see cref="T:Xsharp.Drawable"/> instance.</para> /// </summary> /// /// <param name="drawable"> /// <para>The drawable to attach this graphics context to. If the /// drawable is a widget, the foreground and background colors of the /// graphics object will be initially set to the widget's standard /// foreground and background colors.</para> /// </param> /// /// <exception cref="T:System.ArgumentNullException"> /// <para>Raised if <paramref name="drawable"/> is <see langword="null"/>. /// </para> /// </exception> /// /// <exception cref="T:Xsharp.XInvalidOperationException"> /// <para>Raised if <paramref name="drawable"/> does not support /// output, is disposed, or is the root window.</para> /// </exception> public Graphics(Drawable drawable) { if(drawable == null) { throw new ArgumentNullException("drawable"); } else if(drawable.Kind == DrawableKind.InputOnlyWidget) { throw new XInvalidOperationException (S._("X_GraphicsIsOutputOnly")); } else if(drawable is RootWindow) { throw new XInvalidOperationException (S._("X_NonRootOperation")); } dpy = drawable.dpy; this.drawable = drawable; XGCValues gcValues = new XGCValues(); InputOutputWidget widget = (drawable as InputOutputWidget); DoubleBuffer buffer = (drawable as DoubleBuffer); Bitmap bitmap = (drawable as Bitmap); if(widget != null) { foreground = widget.Foreground; background = widget.Background; } else if(buffer != null) { foreground = buffer.Widget.Foreground; background = buffer.Widget.Background; } else if(bitmap != null) { foreground = new Color(0x00, 0x00, 0x00); background = new Color(0xFF, 0xFF, 0xFF); } else { foreground = new Color (StandardColor.Foreground); background = new Color (StandardColor.Background); } gcValues.foreground = drawable.ToPixel(foreground); gcValues.background = drawable.ToPixel(background); if(drawable is DoubleBuffer) { ((DoubleBuffer)drawable).Start(this); } try { IntPtr display = dpy.Lock(); drawableHandle = drawable.GetGCHandle(); gc = drawable.screen.GetGC(bitmap != null); if(gc == IntPtr.Zero) { // Create a new GC because the cache is empty. gc = Xlib.XCreateGC(display, drawableHandle, (uint)(GCValueMask.GCForeground | GCValueMask.GCBackground), ref gcValues); if(gc == IntPtr.Zero) { Display.OutOfMemory(); } } else { // Reset the cached GC back to the default settings. // Xlib will take care of stripping the list down // to just the changes that need to be applied. gcValues.function = Xsharp.GCFunction.GXcopy; gcValues.plane_mask = ~((XPixel)0); gcValues.line_width = 0; gcValues.line_style = Xsharp.LineStyle.LineSolid; gcValues.cap_style = Xsharp.CapStyle.CapButt; gcValues.join_style = Xsharp.JoinStyle.JoinMiter; gcValues.fill_style = Xsharp.FillStyle.FillSolid; gcValues.fill_rule = Xsharp.FillRule.EvenOddRule; gcValues.arc_mode = Xsharp.ArcMode.ArcPieSlice; gcValues.ts_x_origin = 0; gcValues.ts_y_origin = 0; gcValues.subwindow_mode = Xsharp.SubwindowMode.ClipByChildren; gcValues.graphics_exposures = true; gcValues.clip_x_origin = 0; gcValues.clip_y_origin = 0; gcValues.clip_mask = XPixmap.Zero; gcValues.dash_offset = 0; gcValues.dashes = (sbyte)4; Xlib.XChangeGC(display, gc, (uint)(GCValueMask.GCFunction | GCValueMask.GCPlaneMask | GCValueMask.GCForeground | GCValueMask.GCBackground | GCValueMask.GCLineWidth | GCValueMask.GCLineStyle | GCValueMask.GCCapStyle | GCValueMask.GCJoinStyle | GCValueMask.GCFillStyle | GCValueMask.GCFillRule | GCValueMask.GCTileStipXOrigin | GCValueMask.GCTileStipYOrigin | GCValueMask.GCSubwindowMode | GCValueMask.GCGraphicsExposures | GCValueMask.GCClipXOrigin | GCValueMask.GCClipYOrigin | GCValueMask.GCClipMask | GCValueMask.GCDashOffset | GCValueMask.GCDashList | GCValueMask.GCArcMode), ref gcValues); } int sn = drawable.screen.ScreenNumber; double px, mm; px = (double)Xlib.XDisplayWidth(display, sn); mm = (double)Xlib.XDisplayWidthMM(display, sn); dpiX = (float)((px * 25.4) / mm); px = (double)Xlib.XDisplayHeight(display, sn); mm = (double)Xlib.XDisplayHeightMM(display, sn); dpiY = (float)((px * 25.4) / mm); } finally { dpy.Unlock(); } if(drawable is DoubleBuffer) { ((DoubleBuffer)drawable).ClearAtStart(this); } isDisposed = false; }
/// <summary> /// <para>Blit a drawable sub-part to this graphics context.</para> /// </summary> /// /// <param name="x"> /// <para>The X co-ordinate of the top-left point of /// the destination bounding rectangle.</para> /// </param> /// /// <param name="y"> /// <para>The Y co-ordinate of the top-left point of /// the destination bounding rectangle.</para> /// </param> /// /// <param name="drawable"> /// <para>The drawable to copy from.</para> /// </param> /// /// <param name="srcX"> /// <para>The X co-ordinate of the top-left point of /// the drawable sub-part to be drawn.</para> /// </param> /// /// <param name="srcY"> /// <para>The Y co-ordinate of the top-left point of /// the drawable sub-part to be drawn.</para> /// </param> /// /// <param name="srcWidth"> /// <para>The width of the drawable sub-part to be drawn.</para> /// </param> /// /// <param name="srcHeight"> /// <para>The height of the drawable sub-part to be drawn.</para> /// </param> /// /// <exception cref="T:System.ArgumentNullException"> /// <para>Raised if <paramref name="drawable"/> is <see langword="null"/>. /// </para> /// </exception> /// /// <exception cref="T:Xsharp.XException"> /// <para>One of the co-ordinate or size values is out of range.</para> /// </exception> public void BitBlt(int x, int y, Drawable drawable, int srcX, int srcY, int srcWidth, int srcHeight) { // Validate the drawable parameter. if(drawable == null) { throw new ArgumentNullException("drawable"); } // Bail out if the source co-ordinates are out of range. int width, height; width = drawable.Width; height = drawable.Height; if(srcX < 0 || srcX >= width || srcY < 0 || srcY >= height || srcWidth <= 0 || srcHeight <= 0 || srcWidth > width || srcHeight > height || srcX > (width - srcWidth) || srcY > (height - srcHeight)) { throw new XException(S._("X_RectCoordRange")); } // Blit the contents of the drawable. try { IntPtr display = Lock(); Xlib.XCopyArea(display, drawable.GetGCHandle(), drawableHandle, gc, srcX, srcY, (uint)srcWidth, (uint)srcHeight, x, y); } finally { dpy.Unlock(); } }