Gdi Can I use the new color Windows 10 Segoe UI Emoji font with DrawText?

I am creating a C ++ project using Embarcadero RAD Studio (10.2 Tokyo starter) and Windows GDI to draw text using the DrawText () function.

I recently saw that Windows 10 provides a new font called “Segoe UI Emoji,” which potentially allows text functions to draw colored emojis. I found some examples using Direct2D, but none of them have pure GDI features.

I also tried simple code, for example:

HDC hDC = ::GetDC(Handle); std::auto_ptr<TCanvas> pCanvas(new TCanvas()); pCanvas->Handle = hDC; pCanvas->Brush->Color = clWhite; pCanvas->Brush->Style = bsSolid; pCanvas->FillRect(TRect(0, 0, ClientWidth, ClientHeight)); const std::wstring text = L"Test 😀 😬 😁 😂 😃 😄 😅 😆"; TRect textRect(10, 10, ClientWidth - 10, ClientHeight - 10); hFont = ::CreateFont(-40, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, L"Segoe UI Emoji"); ::SelectObject(hDC, hFont); ::DrawTextW(hDC, text.c_str(), text.length(), &textRect, DT_LEFT | DT_TOP | DT_SINGLELINE); ::DeleteObject(hFont); 

The output sounds good in terms of symbols, but they are painted in black and white, without colors, as you can see in the screenshot below: enter image description here

I could not find any additional parameters that could allow me to draw text using colored characters instead of black and white. Is there a way to activate color support in the GDI DrawText () function, and if so, how to do it? Or can only Direct2D draw color emotions?

EDITED until 10/30/2017

Since GDI cannot do this work (unfortunately, and as I thought), I am posting here a version of Direct2D of the above code that worked for me.

 const std::wstring text = L"Test 😀 😬 😁 😂 😃 😄 😅 😆"; HDC hDC = ::GetDC(Handle); std::auto_ptr<TCanvas> pGDICanvas(new TCanvas()); pGDICanvas->Handle = hDC; pGDICanvas->Brush->Color = clWhite; pGDICanvas->Brush->Style = bsSolid; pGDICanvas->FillRect(TRect(0, 0, ClientWidth, ClientHeight)); ::D2D1_RECT_F textRect; textRect.left = 10; textRect.top = 10; textRect.right = ClientWidth - 10; textRect.bottom = ClientHeight - 10; std::auto_ptr<TDirect2DCanvas> pCanvas(new TDirect2DCanvas(hDC, TRect(0, 0, ClientWidth, ClientHeight))); // configure Direct2D font pCanvas->Font->Size = 40; pCanvas->Font->Name = L"Segoe UI Emoji"; pCanvas->Font->Orientation = 0; pCanvas->Font->Pitch = System::Uitypes::TFontPitch::fpVariable; pCanvas->Font->Style = TFontStyles(); // get DirectWrite text format object _di_IDWriteTextFormat pFormat = pCanvas->Font->Handle; if (!pFormat) return; pCanvas->RenderTarget->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE); ::D2D1_COLOR_F color; color.r = 0.0f; color.g = 0.0f; color.b = 0.0f; color.a = 1.0f; ::ID2D1SolidColorBrush* pBrush = NULL; // create solid color brush, use pen color if rect is completely filled with outline pCanvas->RenderTarget->CreateSolidColorBrush(color, &pBrush); if (!pBrush) return; // set horiz alignment pFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING); // set vert alignment pFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR); // set reading direction pFormat->SetReadingDirection(DWRITE_READING_DIRECTION_LEFT_TO_RIGHT); // set word wrapping mode pFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP); IDWriteInlineObject* pInlineObject = NULL; ::DWRITE_TRIMMING trimming; trimming.delimiter = 0; trimming.delimiterCount = 0; trimming.granularity = DWRITE_TRIMMING_GRANULARITY_NONE; // set text trimming pFormat->SetTrimming(&trimming, pInlineObject); pCanvas->BeginDraw(); pCanvas->RenderTarget->DrawText(text.c_str(), text.length(), pFormat, textRect, pBrush, D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT); pCanvas->EndDraw(); 

Of course, this code will draw colored emotions only in the latest versions of Windows 10 and above. In previous versions, the text will be drawn as described above (and the code cannot be compiled).

+5
source share
2 answers

GDI does not support color fonts (even if you switch to the full Uniscribe route), you need to use Direct2D if you want to support color fonts. It makes sense that the simpler GDI APIs do not support color fonts, since color fonts require the use of OpenType tags, and none of DrawText / TextOut provides this level of control, Uniscribe allows such tags, but simply has not been expanded to support color fonts .

+2
source

You can use DirectWrite to draw a color emulator onto a bitmap in DC memory, and then on BitBlt () to your permanent destination. Basically you need to implement your own IDWriteTextRenderer class and call IDWriteTextLayout :: Draw () with your renderer, and then copy the result. In your class, you extract IDWriteGdiInterop from IDWriteFactory and call IDWriteGdiInterop :: CreateBitmapRenderTarget () to get the target for rendering the bitmap; call IDWriteFactory :: CreateMonitorRenderingParams () to get the rendering options, and call IDWriteFactory :: CreateTextFormat () to customize the text format. The only significant method is DrawGlyphRun (), where you get IDWriteColorGlyphRunEnumerator with IDWriteFactory2 :: TranslateColorGlyphRun (), and with each color run IDWriteBitmapRenderTarget :: DrawGlyphRun () is called to do the job for you. Remember to update the target / rendering options when the size / position of the window changes. You can refer to this MSDN documentation:

Relate to the GDI surface https://msdn.microsoft.com/en-us/library/windows/desktop/ff485856(v=vs.85).aspx

+1
source

Source: https://habr.com/ru/post/1272827/


All Articles