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) });
            }
        }
Example #3
0
        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);
        }