简体   繁体   English

当我使用DirectWrite在GDI hdc上绘制文本时,如何设置透明的背景?

[英]When I use DirectWrite to draw text on a GDI hdc, how to set a transparent back ground?

Now I am working on a legacy product which use GDI to draw text in screen. 现在我正在研究一种使用GDI在屏幕上绘制文本的传统产品。 Now I try to use DirectWrite to draw text for better appearance and accurancy of font. 现在我尝试使用DirectWrite绘制文本,以获得更好的外观和字体的准确性。 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? 我遇到一个问题,当我使用DirectWrite在GDI hdc上绘制文本时,背景颜色总是白色,我需要透明背景,是否可能? it seems that the SetBkMode is useless 似乎SetBkMode是无用的

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);

Default (Stock) brush for freshly created GDI device context is white solid brush, which is why you have white rectangle in output. 新创建的GDI设备上下文的默认(库存)画笔是白色实心画笔,这就是输出中有白色矩形的原因。 See GetStockObject 请参阅GetStockObject

GDI doesn't work with transparent images, BitBlt will replace all pixels inside destination rectangle in target DC. GDI不适用于透明图像,BitBlt将替换目标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. 您必须在目标DC中复制目标DC目标矩形的内容,然后绘制文本并复制结果以达到所需效果。

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. 如果应用程序使用后台缓冲区来绘制窗口,则可以使用IDWriteBitmapRenderTarget内存DC而不是分配另一个 - 在这种情况下,您可以自动解决透明文本背景的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM