// -------------------------------------------------------------- void GFontWin32GDIPlus::GetExtent( const char * str, int inCharCount, float * outWidth, float * outHeight, VGDevice * context ) const { if (!inCharCount) { *outWidth = *outHeight = 0; return; } // convert input string DWORD count = (DWORD)mbstowcs(NULL, str, inCharCount); WCHAR * wstr = (WCHAR*) malloc ((count + 1) * sizeof(WCHAR)); mbstowcs(wstr, str, inCharCount); //std::string s(str); //std::wstring wstr(s.length(),L' '); //std::copy(s.begin(), s.end(), wstr.begin()); Graphics* gdiContext = (Graphics*) GetContext( context ); /* -- known Gdi+ issue: We must use the following way to determine correct font extent because typical Graphics::MeasureString() method doesn't work properly (return values are incorrect due to antialiasing) */ Font* dgiFont = GetNativeFont(); // Layout rectangles used for drawing strings RectF layoutRect_A(0.0f, 0.0f, 1300.0f, 1300.0f); // 1 range of character positions within the string CharacterRange charRange(0, inCharCount); // String format used to apply to string when drawing StringFormat strFormat; // Set three ranges of character positions. strFormat.SetMeasurableCharacterRanges(1, &charRange); Region *pCharRangeRegions = new Region(); // Get the regions that correspond to the ranges within the string when // layout rectangle A is used. gdiContext->MeasureCharacterRanges( wstr, inCharCount, dgiFont, layoutRect_A, &strFormat, 1, pCharRangeRegions); RectF boundRect; pCharRangeRegions->GetBounds( &boundRect, gdiContext); *outWidth = boundRect.Width; *outHeight = boundRect.Height; free (wstr); }
// -------------------------------------------------------------- void GFontWin32GDIPlus::GetExtent( unsigned char c, float * outWidth, float * outHeight, VGDevice * context ) const { WCHAR wstr [] = L"0"; mbstowcs(wstr, (const char*)&c, 1); Graphics* gdiContext = (Graphics*) GetContext( context ); /* -- known Gdi+ issue: We must use the following way to determine correct font extent because typical Graphics::MeasureString() method doesn't work properly (return values are incorrect due to antialiasing) */ Font* dgiFont = GetNativeFont(); // Layout rectangles used for drawing strings RectF layoutRect_A(0.0f, 0.0f, 1300.0f, 1300.0f); // 1 range of character positions within the string CharacterRange charRange(0, 1); // String format used to apply to string when drawing StringFormat strFormat; // Set three ranges of character positions. strFormat.SetMeasurableCharacterRanges(1, &charRange); Region *pCharRangeRegions = new Region(); // Get the regions that correspond to the ranges within the string when // layout rectangle A is used. gdiContext->MeasureCharacterRanges( wstr, 1, dgiFont, layoutRect_A, &strFormat, 1, pCharRangeRegions); RectF boundRect; pCharRangeRegions->GetBounds( &boundRect, gdiContext); *outHeight = boundRect.Height; *outWidth = boundRect.Width; // in some cases (when some symbols must be forced into char map), extent needs to be fixed if (c == 139) *outWidth = 6.0; }
/* ** Draws the string or calculates it's size ** */ bool CMeterString::DrawString(Graphics& graphics, RectF* rect) { if (m_Font == NULL) return false; LPCWSTR string = m_String.c_str(); int stringLen = (int)m_String.length(); StringFormat stringFormat; if (m_AntiAlias) { graphics.SetTextRenderingHint(TextRenderingHintAntiAlias); } else { graphics.SetTextRenderingHint(TextRenderingHintSingleBitPerPixelGridFit); } switch (m_Align) { case ALIGN_CENTERCENTER: stringFormat.SetAlignment(StringAlignmentCenter); stringFormat.SetLineAlignment(StringAlignmentCenter); break; case ALIGN_RIGHTCENTER: stringFormat.SetAlignment(StringAlignmentFar); stringFormat.SetLineAlignment(StringAlignmentCenter); break; case ALIGN_LEFTCENTER: stringFormat.SetAlignment(StringAlignmentNear); stringFormat.SetLineAlignment(StringAlignmentCenter); break; case ALIGN_CENTERBOTTOM: stringFormat.SetAlignment(StringAlignmentCenter); stringFormat.SetLineAlignment(StringAlignmentFar); break; case ALIGN_RIGHTBOTTOM: stringFormat.SetAlignment(StringAlignmentFar); stringFormat.SetLineAlignment(StringAlignmentFar); break; case ALIGN_LEFTBOTTOM: stringFormat.SetAlignment(StringAlignmentNear); stringFormat.SetLineAlignment(StringAlignmentFar); break; case ALIGN_CENTER: // Same as CenterTop stringFormat.SetAlignment(StringAlignmentCenter); stringFormat.SetLineAlignment(StringAlignmentNear); break; case ALIGN_RIGHT: // Same as RightTop stringFormat.SetAlignment(StringAlignmentFar); stringFormat.SetLineAlignment(StringAlignmentNear); break; case ALIGN_LEFT: // Same as LeftTop stringFormat.SetAlignment(StringAlignmentNear); stringFormat.SetLineAlignment(StringAlignmentNear); break; } if (m_ClipString) { stringFormat.SetTrimming(StringTrimmingEllipsisCharacter); } else { stringFormat.SetTrimming(StringTrimmingNone); stringFormat.SetFormatFlags(StringFormatFlagsNoClip | StringFormatFlagsNoWrap); } CharacterRange range(0, stringLen); stringFormat.SetMeasurableCharacterRanges(1, &range); REAL x = (REAL)GetX(); REAL y = (REAL)GetY(); if (rect) { PointF pos(x, y); graphics.MeasureString(string, stringLen, m_Font, pos, &stringFormat, rect); } else { RectF rcDest(x, y, (REAL)m_W, (REAL)m_H); m_Rect = rcDest; if (m_Angle != 0.0f) { graphics.TranslateTransform((Gdiplus::REAL)CMeter::GetX(), y); graphics.RotateTransform(CONVERT_TO_DEGREES(m_Angle)); graphics.TranslateTransform(-(Gdiplus::REAL)CMeter::GetX(), -y); } if (m_Effect != EFFECT_NONE) { SolidBrush solidBrush(m_EffectColor); RectF rcEffect(rcDest); if (m_Effect == EFFECT_SHADOW) { rcEffect.Offset(1, 1); graphics.DrawString(string, stringLen, m_Font, rcEffect, &stringFormat, &solidBrush); } else //if (m_Effect == EFFECT_BORDER) { rcEffect.Offset(0, 1); graphics.DrawString(string, stringLen, m_Font, rcEffect, &stringFormat, &solidBrush); rcEffect.Offset(1, -1); graphics.DrawString(string, stringLen, m_Font, rcEffect, &stringFormat, &solidBrush); rcEffect.Offset(-1, -1); graphics.DrawString(string, stringLen, m_Font, rcEffect, &stringFormat, &solidBrush); rcEffect.Offset(-1, 1); graphics.DrawString(string, stringLen, m_Font, rcEffect, &stringFormat, &solidBrush); } } SolidBrush solidBrush(m_Color); graphics.DrawString(string, stringLen, m_Font, rcDest, &stringFormat, &solidBrush); if (m_Angle != 0.0f) { graphics.ResetTransform(); } } return true; }