コード例 #1
0
	/// <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;
			}