locked
Measuring of Text with Multiple Fonts in One Single Line RRS feed

  • General discussion

  • I am following a request to write C++ code for a label that contains several text elements in one single line, varying by font, size, color.... Ok, that can be done easily in GDI+ by measuring each element's width and then execute a DrawString for each of the text elements starting at its calculated position.

    So far, I failed miserably.
    The horizontal text positions did not appear to be correct. I reverted now to very simple text width measuring tests where the results are still puzzling.

    Test 1 (GDI+): Use of MeasureString
    With the same font, the width of the string "MM" does not match the double with of the string "M". This cannot be explained with eventual rounding problems.

    Test 2 (GDI+): Use of MeasureCharacterRanges
    Used the same font as for the first test. The width of "MM" is now exactly double of the width of "M". But: The width of the "M" ist lightyears away from the measurement result in the first test.

    Test 3 (GDI): Use of GetCharABCWidthsFloat
    Attempted to create a GDI font as close as possible to the GDI+ font in the previous tests. Unfortunately, this third test shows results which do not match the previous results at all.

    I am appending the full example here; the results I found during the debug session have been added as comments:

    void ApplWindow_TextDrawTest(HDC hDC) { Gdiplus::Graphics *G = new Gdiplus::Graphics(hDC); G->SetTextRenderingHint(TextRenderingHint::TextRenderingHintClearTypeGridFit); Gdiplus::StringFormat MyFormat; MyFormat.SetAlignment(Gdiplus::StringAlignment::StringAlignmentNear); MyFormat.SetFormatFlags(Gdiplus::StringFormatFlags::StringFormatFlagsNoWrap); Gdiplus::Font TextFont(L"Calibri", 36, Gdiplus::FontStyle::FontStyleBold, Gdiplus::Unit::UnitPixel); const wchar_t *Text1M = L"M"; Gdiplus::PointF TextOrigin1M(0, 0); Gdiplus::RectF TextBounds1M; const wchar_t *Text2M = L"MM"; Gdiplus::PointF TextOrigin2M(0, 50); Gdiplus::RectF TextBounds2M; //--- Test #1: using MeasureString ---------- G->MeasureString(Text1M, (INT)wcslen(Text1M), &TextFont, TextOrigin1M, &MyFormat, &TextBounds1M); G->MeasureString(Text2M, (INT)wcslen(Text2M), &TextFont, TextOrigin2M, &MyFormat, &TextBounds2M); //--- Results: Text 1 Width= 44.414 ("M") //--- Text 2 Width= 76.828 ("MM") //--- Test #2: using MeasureCharacterRanges ---------- Gdiplus::Status RCode; Gdiplus::RectF LayoutRect(0, 0, 1000, 100); Gdiplus::Region RegionsList[3]; Gdiplus::CharacterRange CRanges[3]; CRanges[0].First = 0; CRanges[0].Length = 1; CRanges[1].First = 1; CRanges[1].Length = 1; CRanges[2].First = 0; CRanges[2].Length = 2; MyFormat.SetMeasurableCharacterRanges(3, CRanges); G->MeasureCharacterRanges(Text2M, (INT)wcslen(Text2M), &TextFont, LayoutRect, &MyFormat, 3, RegionsList); RCode = RegionsList[0].GetBounds(&TextBounds1M, G); // Result: Text 1 Width = 32.000 ("M") RCode = RegionsList[1].GetBounds(&TextBounds1M, G); // Result: Text 1 Width = 32.000 ("M"; the second char) RCode = RegionsList[2].GetBounds(&TextBounds2M, G); // Result: Text 2 Width = 64.000 ("MM") //--- Test #3: using the good old GDI ---------- int MapModeResult = SetMapMode(hDC, MM_TEXT); // MM_TEXT is equivalent to Unit::UnitPixel? HFONT TextFont3 = CreateFont(36, 0, 0, 0, FW_BOLD, false, false, false, ANSI_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH | FF_DONTCARE, L"Calibri"); HGDIOBJ PrevFont = SelectObject(hDC, TextFont3); ABCFLOAT ABCCharData; BOOL RFlg = GetCharABCWidthsFloat(hDC, (UINT)'M', (UINT)'M', &ABCCharData); // Results: abcfA = 2.000; abcfB = 22.000; abcfC = 2.000 //--- End of Test --- delete G; }


    Does anybody have an idea why I get so different results?
    Thanks in advance.

    • Changed type PHBecker Wednesday, April 8, 2015 10:43 AM Wrong forum
    Friday, October 31, 2014 2:15 PM

All replies

  • This is a development question and should be directed to a forum that assists in coding. The forum you posted to is for Windows 7 related questions.

    Sorry I cannot help you


    Don't forget to mark the post that solved your issue as "Answered." By marking the Answer you are enabling users with similar issues to find what helped you. Lewis Renwick - IT Professional

    Friday, October 31, 2014 4:03 PM
  • I have moved this question to a developer forum. Please consider this thread closed.
    Saturday, November 1, 2014 11:06 AM