Click here to Skip to main content
15,888,521 members
Please Sign up or sign in to vote.
4.50/5 (2 votes)
I am developing a very simple application which displays random shapes and text. I want the text to have different colors, and font types. Right now I am using Direct2D to create rectangles and the text. Unfortunately, the Direct2D libraries such as d2d1WriteFactory don't seem to be as fast as the GDI DrawText function.

For example, using Direct2D, you would do something like the following to create an array of characters. Note that there are 2 ways to do this, using something called a TextLayout, or a different function called DrawText.

C++
bool USE_TEXT_LAYOUT = true;
p_textColor->SetColor(font_color);
p_dWriteFactory->CreateTextFormat(
    font_name,
    NULL,
    DWRITE_FONT_WEIGHT_NORMAL,
    DWRITE_FONT_STYLE_NORMAL,
    DWRITE_FONT_STRETCH_NORMAL,
    font_size,
    L"", //locale
    &p_textFormat
    );

if (USE_TEXT_LAYOUT){
    int width  = text_position.right - text_position.left;
    int height = text_position.bottom - text_position.top;
    p_dWriteFactory->CreateTextLayout(
        char_array,      // The string to be laid out and formatted.
        char_array_size,  // The length of the string.
        p_textFormat,  // The text format to apply to the string (contains font information, etc).
        width,         // The width of the layout box.
        height,        // The height of the layout box.
        &p_textLayout  // The IDWriteTextLayout interface pointer.
        );
    p_renderTarget->DrawTextLayout(
        D2D1::Point2F(text_position.left, text_position.bottom),
        p_textLayout,
        p_textColor,
        D2D1_DRAW_TEXT_OPTIONS_NONE);
}
else {
    p_renderTarget->DrawText(
        char_array,
        char_array_size - 1,
        //ARRAYSIZE(char_array) - 1,
        p_textFormat,
        text_position),
        p_textColor);
}


On the other hand, if you want to stick to GDI libraries, you would do the following which seems to be faster:

C++
// Set the character.
int char_num   = int(255*rand()/RAND_MAX);
WCHAR text_char[2];
//text_char[0] = (WCHAR)G_RAMP[char_num];
text_char[0] = (WCHAR)char_num;
text_char[1] = 0;

// Get the font width and height.
G_LOG_FONT.lfHeight = font_height;
G_LOG_FONT.lfWidth  = font_width;
StringCchCopy(G_LOG_FONT.lfFaceName, 9, font_name);

// Set the color.
int font_red_byte   = int(255*rand()/RAND_MAX);
int font_green_byte = int(255*rand()/RAND_MAX);
int font_blue_byte  = int(255*rand()/RAND_MAX);
int font_size       = max(font_width, font_height);
DWORD font_color    = RGB(font_red_byte, font_green_byte, font_blue_byte);

COLORREF text_color       = font_color;
COLORREF background_color = RGB(font_green_byte, font_red_byte, font_blue_byte);
SetTextColor(h_dc, text_color);
SetBkColor(h_dc, background_color);
SetBkMode(h_dc, TRANSPARENT);

// Set the font.
G_H_FONT = CreateFontIndirect(&G_LOG_FONT);
SelectObject(h_dc, G_H_FONT);

DrawText(h_dc, (LPCWSTR)text_char, -1, &position, DT_NOCLIP |
    DT_NOPREFIX | DT_CALCRECT | DT_CENTER | DT_VCENTER);
DrawText(h_dc, (LPCWSTR)text_char, -1, &position, DT_NOPREFIX |
    DT_NOCLIP | DT_CENTER | DT_VCENTER);
DeleteObject(G_H_FONT);


Does anyone know any other approach that would be faster for displaying multicolor strings than these functions?
Posted
Comments
Sergey Alexandrovich Kryukov 5-May-11 14:32pm    
Interesting question (my 5). I always though DirectX is faster. Don't you abuse DirectX in some way. I only used WPF for things like that, always thought it's faster than GDI.
--SA

1 solution

Use WPF.
Set ForeColor Property.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900