public void Dispose() { if (graphics != IntPtr.Zero) { GdiPlusAPI.CheckStatus(GdiPlusAPI.GdipDeleteGraphics(graphics)); graphics = IntPtr.Zero; } if (defaultStringFormat != IntPtr.Zero) { GdiPlusAPI.CheckStatus(GdiPlusAPI.GdipDeleteStringFormat(defaultStringFormat)); graphics = IntPtr.Zero; } if (originalPen != IntPtr.Zero) { Gdi32API.SelectObjectChecked(hdc, originalPen); } if (originalBrush != IntPtr.Zero) { Gdi32API.SelectObjectChecked(hdc, originalBrush); } if (originalFont != IntPtr.Zero) { Gdi32API.SelectObjectChecked(hdc, originalFont); } }
private void DrawStringGDI(Color color, FontConfig font, int x, int y, string text) { if (color.IsFullyOpaque()) { DrawOpaqueStringGDI(color, font, x, y, text); return; } SelectGDIFont(font); Gdi32API.GetTextExtentPoint32W(hdc, text, text.Length, out var size); int leftPadding, rightPadding; if (font.IsItalic) { int infFontSize = Convert.ToInt32(font.Size); leftPadding = 1 + (4 * infFontSize + 199) / 200; rightPadding = 1 + (11 * infFontSize + 199) / 200; } else { leftPadding = 0; rightPadding = 0; } WithTransparentCanvas( new Rectangle(x - leftPadding, y, size.cx + leftPadding + rightPadding, size.cy), color.A, true, canvas => canvas.DrawOpaqueStringGDI(color, font, leftPadding, 0, text) ); }
private void DrawOpaqueStringGDI(Color color, FontConfig font, int x, int y, string text) { SelectGDIFont(font); Gdi32API.SetBkModeChecked(hdc, Gdi32BackgroundMode.TRANSPARENT); Gdi32API.SetTextColorChecked(hdc, Gdi32API.ToCOLORREF(color)); Gdi32API.TextOutW(hdc, x, y, text, text.Length); }
public void DrawImage(INativeImage image, int x, int y) { x += offset.X; y += offset.Y; // todo: allow null? Win32Image win32Image = (Win32Image)image; var bitmap = Gdi32API.CreateDIBSectionChecked(hdc, new BITMAPINFO(win32Image.Width, win32Image.Height), out IntPtr buffer); IntPtr hdcMem = IntPtr.Zero; try { Marshal.Copy(win32Image.Pixels, 0, buffer, win32Image.Pixels.Length); hdcMem = Gdi32API.CreateCompatibleDCChecked(hdc); var oldBitmap = Gdi32API.SelectObjectChecked(hdcMem, bitmap); Gdi32API.GdiAlphaBlend ( hdc, x, y, win32Image.Width, win32Image.Height, hdcMem, 0, 0, win32Image.Width, win32Image.Height, BLENDFUNCTION.SourceAlpha() ); Gdi32API.SelectObjectChecked(hdcMem, oldBitmap); } finally { Gdi32API.SafeDeleteObject(hdcMem); Gdi32API.DeleteObject(bitmap); } }
public static Win32Bitmap Create(IntPtr hdc, int width, int height) { IntPtr bitmapPtr = IntPtr.Zero; IntPtr bitmapHdc = IntPtr.Zero; try { bitmapPtr = Gdi32API.CreateCompatibleBitmapChecked(hdc, width, height); bitmapHdc = Gdi32API.CreateCompatibleDCChecked(hdc); Gdi32API.SelectObjectChecked(bitmapHdc, bitmapPtr); var bitmap = new Win32Bitmap(bitmapPtr, bitmapHdc, width, height); bitmapPtr = IntPtr.Zero; bitmapHdc = IntPtr.Zero; return(bitmap); } finally { if (bitmapHdc != IntPtr.Zero) { Gdi32API.DeleteDC(bitmapHdc); } if (bitmapPtr != IntPtr.Zero) { Gdi32API.DeleteObject(bitmapPtr); } } }
public Size MeasureString(FontConfig font, string text) { IntPtr hdc = Win32API.GetDCChecked(IntPtr.Zero); try { IntPtr fontPtr = objectCache.GetFont(font); IntPtr oldFont = Gdi32API.SelectObjectChecked(hdc, fontPtr); try { Gdi32API.GetTextExtentPoint32W(hdc, text, text.Length, out var size); return(new Size(size.cx, size.cy)); } finally { if (oldFont != IntPtr.Zero) { Gdi32API.SelectObjectChecked(hdc, fontPtr); } } } finally { Win32API.ReleaseDCChecked(IntPtr.Zero, hdc); } }
private void SelectGDIFont(FontConfig fontConfig) { IntPtr font = objectCache.GetFont(fontConfig); IntPtr oldFont = Gdi32API.SelectObjectChecked(hdc, font); if (originalFont == IntPtr.Zero) { originalFont = oldFont; } }
private void SelectSolidBrush(Color color) { IntPtr brush = objectCache.GetSolidBrush(color); IntPtr oldBrush = Gdi32API.SelectObjectChecked(hdc, brush); if (originalBrush == IntPtr.Zero) { originalBrush = oldBrush; } }
private void SelectSolidPen(Color color, int width) { IntPtr pen = objectCache.GetSolidPen(color, width); IntPtr oldPen = Gdi32API.SelectObjectChecked(hdc, pen); if (originalPen == IntPtr.Zero) { originalPen = oldPen; } }
private void WithTransparentCanvas(Rectangle rect, byte alpha, bool copySource, Action <Win32Canvas> action) { if (rect.Width <= 0 || rect.Height <= 0 || alpha == 0) { return; } IntPtr memoryHdc = Gdi32API.CreateCompatibleDCChecked(hdc); try { IntPtr memoryBitmap = Gdi32API.CreateCompatibleBitmapChecked(hdc, rect.Width, rect.Height); try { var originalBitmap = Gdi32API.SelectObjectChecked(memoryHdc, memoryBitmap); try { if (copySource) { Gdi32API.BitBlt(memoryHdc, 0, 0, rect.Width, rect.Height, hdc, rect.X, rect.Y, GDI32RasterOperation.SRCCOPY); } using (Win32Canvas memoryCanvas = new Win32Canvas(memoryHdc, offset, objectCache)) { action(memoryCanvas); } Gdi32API.GdiAlphaBlend ( hdc, rect.X, rect.Y, rect.Width, rect.Height, memoryHdc, 0, 0, rect.Width, rect.Height, BLENDFUNCTION.ConstantAlpha(alpha) ); } finally { Gdi32API.SelectObjectChecked(memoryHdc, originalBitmap); } } finally { Gdi32API.DeleteObject(memoryBitmap); } } finally { Gdi32API.DeleteDC(memoryHdc); } }
public void SetClipRectangle(int x, int y, int width, int height) { x += offset.X; y += offset.Y; var region = Gdi32API.CreateRectRgnChecked(x, y, x + width, y + height); try { Gdi32API.SelectClipRgn(hdc, region); } finally { Gdi32API.DeleteObject(region); } }
private void FillOpaqueRectangleGDI(Color color, int x, int y, int width, int height) { // todo: check that width and height are exact var region = Gdi32API.CreateRectRgnChecked(x, y, x + width, y + height); try { // todo: pick FillRgn or PaintRgn Gdi32API.FillRgn(hdc, region, objectCache.GetSolidBrush(color)); // SelectSolidBrush(color); // Gdi32API.PaintRgn(hdc, region); } finally { Gdi32API.DeleteObject(region); } }
public void FillOpaqueEllipseGDI(Color color, int x, int y, int width, int height) { SelectSolidPen(color, 0); SelectSolidBrush(color); Gdi32API.Ellipse(hdc, x, y, x + width, y + height); }
private void DrawOpaquePathGDI(Color color, int width, Point[] points) { SelectSolidPen(color, width); // todo: unlike X11, GDI does not paint last pixel Gdi32API.Polyline(hdc, points.Select(p => new POINT(p.X, p.Y)).ToArray(), points.Length); }
public void CopyTo(IntPtr hdc, int x, int y) { Gdi32API.BitBlt(hdc, x, y, width, height, bitmapHdc, 0, 0, GDI32RasterOperation.SRCCOPY); }
public void Dispose() { Gdi32API.DeleteDC(bitmapHdc); Gdi32API.DeleteObject(bitmapPtr); }