public void DrawImage(INativeImage image, int x, int y) { x -= origin.X; y -= origin.Y; // todo: allow null? X11Image x11Image = (X11Image)image; XRenderPictureAttributes attr = new XRenderPictureAttributes(); var tempPictureId = LibXRender.XRenderCreatePicture(display, x11Image.PixmapId, pictFormatPtr, 0, ref attr); try { LibXRender.XRenderComposite ( display, PictOp.PictOpOver, tempPictureId, 0, pictureId, 0, 0, 0, 0, x, y, (uint)x11Image.Width, (uint)x11Image.Height ); } finally { LibXRender.XRenderFreePicture(display, tempPictureId); } }
public static X11Graphics Create(IntPtr display) { int defaultScreen = LibX11.XDefaultScreen(display); ulong defaultRootWindow = LibX11.XDefaultRootWindow(display); //todo: is is safe to keep pictFormatPtr after reading it into XRenderPictFormat IntPtr pictFormatPtr = LibXRender.XRenderFindStandardFormat(display, StandardPictFormat.PictStandardARGB32); if (pictFormatPtr == IntPtr.Zero) { throw new InvalidOperationException("Display does not support 32-bit ARGB."); } XRenderPictFormat pictFormat = Marshal.PtrToStructure <XRenderPictFormat>(pictFormatPtr); int status = LibX11.XMatchVisualInfo ( display, defaultScreen, pictFormat.depth, VisualClass.TrueColor, out XVisualInfo visualInfo ); if (status == 0) { throw new InvalidOperationException($"TrueColor visual with depth {pictFormat.depth} does not exist."); } ulong colorMap = LibX11.XCreateColormap(display, defaultRootWindow, visualInfo.visual, CreateColormapOption.AllocNone); return(new X11Graphics(display, defaultScreen, defaultRootWindow, visualInfo.visual, colorMap, pictFormat, pictFormatPtr)); }
public void DrawString(Color color, FontConfig font, int x, int y, string text) { x -= origin.X; y -= origin.Y; var xftColorPtr = Marshal.AllocHGlobal(Marshal.SizeOf <XftColor>()); try { XRenderColor xColor = new XRenderColor(color); LibXft.XftColorAllocValue( display, visual, colormap, ref xColor, xftColorPtr ); try { XftFontExt fontExt = objectCache.GetXftFont(font); var fontInfo = Marshal.PtrToStructure <XftFont>(fontExt.MainFont); int xOffset = DrawString(xftDraw, xftColorPtr, fontExt, x, y + fontInfo.ascent, text); if (font.IsUnderline) { int lineHeight = Convert.ToInt32(Math.Max(font.Size / 10, 1)); LibXRender.XRenderFillRectangle( display, PictOp.PictOpOver, pictureId, ref xColor, x, y + fontInfo.ascent + (fontInfo.descent - lineHeight) / 2, (uint)xOffset, (uint)lineHeight ); } if (font.IsStrikeout) { int lineHeight = Convert.ToInt32(Math.Max(font.Size / 20, 1)); LibXRender.XRenderFillRectangle ( display, PictOp.PictOpOver, pictureId, ref xColor, x, y + fontInfo.ascent - (2 * fontInfo.ascent + 3 * lineHeight) / 6, (uint)xOffset, (uint)lineHeight ); } } finally { LibXft.XftColorFree(display, visual, colormap, xftColorPtr); } } finally { Marshal.FreeHGlobal(xftColorPtr); } }
public void SetClipRectangle(int x, int y, int width, int height) { x -= origin.X; y -= origin.Y; clipRectangles = new[] { new XRectangle(x, y, width, height) }; LibXRender.XRenderSetPictureClipRectangles(display, pictureId, 0, 0, clipRectangles, 1); LibXft.XftDrawSetClipRectangles(xftDraw, 0, 0, clipRectangles, 1); }
private void DrawPathWithXRenderCompositeTriStrip(Color color, int width, Point[] points) { if (width == 0) { width = 1; } XRenderColor xColor = new XRenderColor(color); // todo: cache brush ulong brush = LibXRender.XRenderCreateSolidFill(display, ref xColor); try { XPointFixed[] stripPoints = new XPointFixed[(points.Length - 1) * 3 + 1]; for (int i = 1, t = 0, m = 1; i < points.Length; i++, m = -m) { Point p1 = points[i - 1]; Point p2 = points[i]; p1.Offset(-origin.X, -origin.Y); p2.Offset(-origin.X, -origin.Y); int dx = p2.X - p1.X; int dy = p2.Y - p1.Y; double len = Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)); // todo: handle 0 points and zero-length segments int ox = Convert.ToInt32(-dy / len * 32768 * width) * m; int oy = Convert.ToInt32(dx / len * 32768 * width) * m; if (i == 1) { // todo: handle separately without if stripPoints[t++] = new XPointFixed { x = (p1.X << 16) + ox, y = (p1.Y << 16) + oy }; } stripPoints[t++] = new XPointFixed { x = (p1.X << 16) - ox, y = (p1.Y << 16) - oy }; stripPoints[t++] = new XPointFixed { x = (p2.X << 16) + ox, y = (p2.Y << 16) + oy }; stripPoints[t++] = new XPointFixed { x = (p2.X << 16) - ox, y = (p2.Y << 16) - oy }; } LibXRender.XRenderCompositeTriStrip(display, PictOp.PictOpOver, brush, pictureId, pictFormatPtr, 0, 0, stripPoints, stripPoints.Length); } finally { LibXRender.XRenderFreePicture(display, brush); } }
private void DrawPathWithXRenderCompositeDoublePoly(Color color, int width, Point[] points) { if (width == 0) { width = 1; } XRenderColor xColor = new XRenderColor(color); // todo: cache brush ulong brush = LibXRender.XRenderCreateSolidFill(display, ref xColor); try { XPointDouble[] polyPoints = new XPointDouble[points.Length * 2]; for (int i = 1, t = polyPoints.Length - 2; i < points.Length; i++, t--) { Point p1 = points[i - 1]; Point p2 = points[i]; p1.Offset(-origin.X, -origin.Y); p2.Offset(-origin.X, -origin.Y); int dx = p2.X - p1.X; int dy = p2.Y - p1.Y; double len = Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)); double ox = -dy / len * width / 2; double oy = dx / len * width / 2; polyPoints[i] = new XPointDouble { x = points[i].X + ox, y = points[i].Y + oy }; polyPoints[t] = new XPointDouble { x = points[i].X - ox, y = points[i].Y - oy }; if (i == 1) { // todo: handle separately without if polyPoints[0] = new XPointDouble { x = points[0].X + ox, y = points[0].Y + oy }; polyPoints[polyPoints.Length - 1] = new XPointDouble { x = points[0].X - ox, y = points[0].Y - oy }; } } LibXRender.XRenderCompositeDoublePoly(display, PictOp.PictOpOver, brush, pictureId, pictFormatPtr, 0, 0, 0, 0, polyPoints, polyPoints.Length, 1); } finally { LibXRender.XRenderFreePicture(display, brush); } }
public static X11Canvas CreateForDrawable( IntPtr display, int screenNum, X11ObjectCache objectCache, IntPtr visual, ulong colormap, IntPtr pictFormatPtr, ulong drawableId ) { const XRenderPictureAttributeMask attrMask = XRenderPictureAttributeMask.CPPolyEdge | XRenderPictureAttributeMask.CPPolyMode; XRenderPictureAttributes attr = new XRenderPictureAttributes { poly_edge = XRenderPolyEdge.Smooth, poly_mode = XRenderPolyMode.Imprecise }; ulong pictureId = LibXRender.XRenderCreatePicture ( display, drawableId, pictFormatPtr, attrMask, ref attr ); IntPtr xftDraw = IntPtr.Zero; X11Canvas canvas = null; try { xftDraw = LibXft.XftDrawCreate(display, drawableId, visual, colormap); canvas = new X11Canvas(display, screenNum, objectCache, visual, colormap, pictFormatPtr, drawableId, pictureId, xftDraw); xftDraw = IntPtr.Zero; } finally { if (canvas == null) { if (xftDraw != IntPtr.Zero) { LibXft.XftDrawDestroy(xftDraw); } LibXRender.XRenderFreePicture(display, pictureId); } } return(canvas); }
public void FillRectangle(Color color, int x, int y, int width, int height) { // todo: <= 0 instead? if (width < 0 || height < 0) { return; } x -= origin.X; y -= origin.Y; XRenderColor xColor = new XRenderColor(color); LibXRender.XRenderFillRectangle(display, PictOp.PictOpOver, pictureId, ref xColor, x, y, (uint)width, (uint)height); }
public void Dispose() { LibXft.XftDrawDestroy(xftDraw); LibXRender.XRenderFreePicture(display, pictureId); }