public void DrawText( Graphics graphics, Bitmap backing, Point position, Color foreColor, Color backColor) { COLORREF foreColorRef = new COLORREF(foreColor); int width = backing.Width; int height = backing.Height; Rectangle bounds = new Rectangle(0, 0, width, height); Rectangle margin = new Rectangle(-height, 0, width + 2 * height, height); Debug.Assert(service.offscreenStrip != null); Debug.Assert(service.offscreenStrip.Width == width); Debug.Assert(service.offscreenStrip.Height == height); using (GDIBrush backBrush = new GDIBrush(backColor)) { GDI.FillRect(service.hdcOffscreenStrip, ref bounds, backBrush); } ProcessText( position, delegate ( int iItem, Point where, int endX, ref SCRIPT_ITEM item, ref ItemInfo itemExtra, Font font) { if (!graphics.IsVisible(new Rectangle(where.X - height, 0, endX - where.X + 2 * height, height))) { return true; } int fontCacheIndex = service.FontCacheIndex(font); GDI.SetTextColor(service.hdcOffscreenStrip, foreColorRef); GDI.SetBkMode(service.hdcOffscreenStrip, GDI.TRANSPARENT); GDI.SelectObject(service.hdcOffscreenStrip, service.fontToHFont[font]); int hr = ScriptTextOut( service.hdcOffscreenStrip, ref service.caches[fontCacheIndex].cache, where.X, where.Y, (ScriptTextOutOptions)0, IntPtr.Zero/*cliprect*/, ref item.a, IntPtr.Zero/*reserved*/, 0/*reserved*/, itemExtra.glyphs, itemExtra.cGlyphs, itemExtra.iAdvances, null/*piJustify*/, itemExtra.goffsets); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } return true; }); using (GDIRegion gdiRgnClip = new GDIRegion(graphics.Clip.GetHrgn(graphics))) { using (GraphicsHDC gdiHdcOffscreen = new GraphicsHDC(graphics)) { // Graphics/GDI+ doesn't pass clip region through so we have to reset it explicitly GDI.SelectClipRgn(gdiHdcOffscreen, gdiRgnClip); GDI.BitBlt( gdiHdcOffscreen, 0, 0, width, height, service.hdcOffscreenStrip, 0, 0, GDI.SRCCOPY); } } }
public ITextInfo AnalyzeText( Graphics graphics, Font font, int fontHeight, string line) { int index; if ((index = line.IndexOfAny(new char[] { '\r', '\n' })) >= 0) { Debug.Assert(false); throw new ArgumentException(); } if (offscreenStrip == null) { using (GraphicsHDC hdc = new GraphicsHDC(graphics)) { offscreenStrip = new GDIBitmap(visibleWidth, fontHeight, hdc); } Debug.Assert(hdcOffscreenStrip == null); hdcOffscreenStrip = GDIDC.Create(offscreenStrip); } using (Pin<string> pinLine = new Pin<string>(line)) { return TextItems.AnalyzeText( this, hdcOffscreenStrip, pinLine.AddrOfPinnedObject(), new FontRunInfo[] { new FontRunInfo(line.Length, font, fontHeight) }); } }
public GDIOffscreenBitmap(Graphics graphicsCompatibleWith, int width, int height) { if ((width <= 0) || (height <= 0)) { Debug.Assert(false); throw new ArgumentException(); } // Create GDI objects for offscreen. Must be created through GDI because Uniscribe/DirectWrite do not // like objects created by GDI+ and will draw with very poor quality on them. using (GraphicsHDC hDC = new GraphicsHDC(graphicsCompatibleWith)) { this.hDC = GDIDC.CreateCompatibleDC(hDC); hBitmap = new GDIBitmap(width, height, PixelFormat.Format32bppArgb); GDI.SelectObject(this.hDC, hBitmap); } graphics = Graphics.FromHdc(hDC); }