3

I have a significant pre-existing body of GDI+ code, written in native C++, which includes transparent layers upon which text and bitmaps are drawn. The layers (implemented using memory DCs with their own GDI+ Graphics) are subsequently combined before being presented to the screen.

I'm not that happy with the text elements, as GDI+ doesn't allow single runs of text to have multiple brush colors and hence I have to draw different colors as separate runs of text, next to each other. Concatenating separate text runs is mucky, because the kerning etc between adjacent runs isn't the same as if it were a continuous single run in different colors.

Cutting to the chase, it seemed like a good idea to explore what DirectWrite has to offer, so I'm trying to replicate some of the existing functionality in DirectWrite. Most specifically, rendering text to transparent bitmaps.

This is where it got tough: I can't get the DirectWrite text to render on an alpha-including background without the antialiasing going wrong (as foreground text pixels should fade to transparent, they instead fade to black). My text looks like the example in this post.

The MS documentation and examples on this are a bit thin, and no amount of googling/stackoverflow searching has shone any significant light thus far.

My code includes the following bits of DirectWrite stuff:

// create a Text Layout object
IDWriteTextLayout *textLayout = NULL;
DWFactory->CreateTextLayout(wcstring,length,textFormat,width,height,&textLayout);
// create the render target using the label DC
HDC hdc = NULL;
D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
                                                                    D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,D2D1_ALPHA_MODE_PREMULTIPLIED),
                                                                    0,0,D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE,D2D1_FEATURE_LEVEL_DEFAULT);
D2DFactory->CreateDCRenderTarget(&props, &D2DRT);
hdc = myGraphics->GetHDC();
RECT dwrect = {0,0,size.w,size.h};
D2DRT->BindDC(hdc,&dwrect);
D2DRT->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
// set rendering parameters
IDWriteRenderingParams *oldparams = NULL;
IDWriteRenderingParams *params = NULL;
DWFactory->CreateRenderingParams(&oldparams);
DWFactory->CreateCustomRenderingParams(oldparams->GetGamma(),oldparams->GetEnhancedContrast(),0.0f,oldparams->GetPixelGeometry(),DWRITE_RENDERING_MODE_DEFAULT,&params);
D2DRT->SetTextRenderingParams(params);
// create the brush colors
ID2D1SolidColorBrush *color = NULL;
D2DRT->CreateSolidColorBrush(<some ColorF>,&color);
// render the text
D2DRT->BeginDraw();
D2DRT->DrawTextLayout(origin,textLayout,color);
D2DRT->EndDraw();
myGraphics->ReleaseHDC(hdc);
hdc = NULL;

It looks like I need to fall back to grayscale antialiasing, but I'm struggling. Please would someone:

  • Explain what grayscale anti-aliasing is supposed to do, and whether it works with transparent bitmap render targets; and
  • Give me some pointers on how to get grayscale anti-alias to work?
Community
  • 1
  • 1
StuartW
  • 181
  • 1
  • 7

0 Answers0