/* * Copyright (C) 2007 Kevin Ollivier * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include #include #include "fontprops.h" #include "math.h" #include "MathExtras.h" #include #include "wx/msw/private.h" inline long my_round(double x) { return (long)(x < 0 ? x - 0.5 : x + 0.5); } wxFontProperties::wxFontProperties(wxFont* font): m_ascent(0), m_descent(0), m_lineGap(0), m_lineSpacing(0), m_xHeight(0) { HDC dc = GetDC(0); WXHFONT hFont = font->GetHFONT(); ::SelectObject(dc, hFont); if (font){ int height = font->GetPointSize(); TEXTMETRIC tm; GetTextMetrics(dc, &tm); m_ascent = lroundf(tm.tmAscent); m_descent = lroundf(tm.tmDescent); m_xHeight = m_ascent * 0.56f; // Best guess for xHeight for non-Truetype fonts. m_lineGap = lroundf(tm.tmExternalLeading); m_lineSpacing = m_lineGap + m_ascent + m_descent; } RestoreDC(dc, -1); ReleaseDC(0, dc); } 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 > 0 ) { 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); } }