bool wxFontContainsCharacters(const wxFont& font, const UChar* characters, int length) { // FIXME: Microsoft documentation seems to imply that characters can be output using a given font and DC // merely by testing code page intersection. This seems suspect though. Can't a font only partially // cover a given code page? static IMultiLanguage *multiLanguage; if (!multiLanguage) { if (CoCreateInstance(CLSID_CMultiLanguage, 0, CLSCTX_ALL, IID_IMultiLanguage, (void**)&multiLanguage) != S_OK) return true; } static IMLangFontLink2* langFontLink; if (!langFontLink) { if (multiLanguage->QueryInterface(&langFontLink) != S_OK) return true; } HDC dc = GetDC(0); DWORD acpCodePages; langFontLink->CodePageToCodePages(CP_ACP, &acpCodePages); DWORD fontCodePages; langFontLink->GetFontCodePages(dc, static_cast<HFONT>(font.GetHFONT()), &fontCodePages); DWORD actualCodePages; long numCharactersProcessed; long offset = 0; while (offset < length) { langFontLink->GetStrCodePages(characters, length, acpCodePages, &actualCodePages, &numCharactersProcessed); if ((actualCodePages & fontCodePages)) return false; offset += numCharactersProcessed; } ReleaseDC(0, dc); return true; }
void GetTextExtent( const wxFont& font, const wxString& str, wxCoord *width, wxCoord *height, wxCoord *descent, wxCoord *externalLeading ) { HDC dc = GetDC(0); WXHFONT hFont = font.GetHFONT(); ::SelectObject(dc, hFont); HFONT hfontOld; if ( font != wxNullFont ) { wxASSERT_MSG( font.Ok(), _T("invalid font in wxDC::GetTextExtent") ); hfontOld = (HFONT)::SelectObject(dc, hFont); } else // don't change the font { hfontOld = 0; } SIZE sizeRect; const size_t len = str.length(); if ( !::GetTextExtentPoint32(dc, str, len, &sizeRect) ) { wxLogLastError(_T("GetTextExtentPoint32()")); } #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) // the result computed by GetTextExtentPoint32() may be too small as it // accounts for under/overhang of the first/last character while we want // just the bounding rect for this string so adjust the width as needed // (using API not available in 2002 SDKs of WinCE) if ( len > 1 ) { ABC width; const wxChar chFirst = *str.begin(); if ( ::GetCharABCWidths(dc, chFirst, chFirst, &width) ) { if ( width.abcA < 0 ) sizeRect.cx -= width.abcA; if ( len > 1 ) { const wxChar chLast = *str.rbegin(); ::GetCharABCWidths(dc, chLast, chLast, &width); } //else: we already have the width of the last character if ( width.abcC < 0 ) sizeRect.cx -= width.abcC; } //else: GetCharABCWidths() failed, not a TrueType font? } #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) TEXTMETRIC tm; ::GetTextMetrics(dc, &tm); if (width) *width = sizeRect.cx; if (height) *height = sizeRect.cy; if (descent) *descent = tm.tmDescent; if (externalLeading) *externalLeading = tm.tmExternalLeading; if ( hfontOld ) { ::SelectObject(dc, hfontOld); } ReleaseDC(0, dc); }