1

Now I am working on a legacy product which use GDI to draw text in screen. Now I try to use DirectWrite to draw text for better appearance and accurancy of font. I am very curious that has anyone done this before? I meet a problem that when I use DirectWrite to draw text on a GDI hdc, the background color is always white, I need a transparent background, is it possible? it seems that the SetBkMode is useless

The sample code is as below,

       SetBkMode(hdc, TRANSPARENT); //hDC is the target GDI dc
        SIZE size = {};
        HDC memoryHdc = NULL;
        memoryHdc = g_pBitmapRenderTarget->GetMemoryDC();
        SetBkMode(memoryHdc, TRANSPARENT);
        hr = g_pBitmapRenderTarget->GetSize(&size);          
        Rectangle(memoryHdc, 0, 0, size1.cx , size1.cy );

        if (SUCCEEDED(hr)) {
            hr = g_pTextLayout->Draw(NULL, g_pGdiTextRenderer, 0, 0);
        }
        BitBlt(hdc, x, y, width + 1, height + 1, memoryHdc, 0, 0, SRCCOPY | NOMIRRORBITMAP);
Emmanuel
  • 13,935
  • 12
  • 50
  • 72

1 Answers1

0

Default (Stock) brush for freshly created GDI device context is white solid brush, which is why you have white rectangle in output. See GetStockObject

GDI doesn't work with transparent images, BitBlt will replace all pixels inside destination rectangle in target DC. You have to copy contents of target DC destination rectangle in memory DC, then draw text and copy result back to achieve desired effect.

SetBkMode(hdc, TRANSPARENT); //hDC is the target GDI dc
SIZE size = {};
HDC memoryHdc = g_pBitmapRenderTarget->GetMemoryDC();
BitBlt(memoryHdc, 0, 0, width+1, height+1, hdc, x, y, SRCCOPY);

if (SUCCEEDED(hr)) {
    hr = g_pTextLayout->Draw(NULL, g_pGdiTextRenderer, 0, 0);
}
BitBlt(hdc, x, y, width + 1, height + 1, memoryHdc, 0, 0, SRCCOPY | NOMIRRORBITMAP);

Make sure you use smallest possible update region, since moving large chunks of bitmaps in memory will surely dwindle performance.

If application uses back buffer to draw windows, memory DC of IDWriteBitmapRenderTarget could be used instead of allocating another one - in that case you solve problem of transparent text background automatically.

weaknespase
  • 1,014
  • 8
  • 15
  • Hi nekavally, thanks for your help, I tried your idea but it does not work, I am not sure the reason. Now I switch to use the direct 2d api to draw the text to GDI dc, it works. – Southwind1984 Jan 28 '17 at 15:45