X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/28dc9371d1d713a1e4df5aa1f414628b4917b5c3..8cd79b7af0760eb91d42ff9ac7c0ccead8d50c6b:/src/msw/textmeasure.cpp diff --git a/src/msw/textmeasure.cpp b/src/msw/textmeasure.cpp new file mode 100644 index 0000000000..c2b364a978 --- /dev/null +++ b/src/msw/textmeasure.cpp @@ -0,0 +1,172 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/msw/textmeasure.cpp +// Purpose: wxTextMeasure implementation for wxMSW +// Author: Manuel Martin +// Created: 2012-19-05 +// RCS-ID: +// Copyright: +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/msw/private.h" +#include "wx/msw/dc.h" + +#ifndef WX_PRECOMP + #include "wx/window.h" + #include "wx/font.h" +#endif //WX_PRECOMP + +#include "wx/private/textmeasure.h" + +// ============================================================================ +// wxTextMeasure implementation +// ============================================================================ + +void wxTextMeasure::Init() +{ + m_hdc = NULL; + m_hfontOld = NULL; +} + +void wxTextMeasure::BeginMeasuring() +{ + if ( m_dc ) + { + m_hdc = m_dc->GetHDC(); + + // Non-native wxDC subclasses should override their DoGetTextExtent() + // and other methods. + wxASSERT_MSG( m_hdc, wxS("Must not be used with non-native wxDCs") ); + } + else if ( m_win ) + { + m_hdc = ::GetDC(GetHwndOf(m_win)); + } + + if ( m_font ) + m_hfontOld = (HFONT)::SelectObject(m_hdc, GetHfontOf(*m_font)); +} + +void wxTextMeasure::EndMeasuring() +{ + if ( m_hfontOld ) + { + ::SelectObject(m_hdc, m_hfontOld); + m_hfontOld = NULL; + } + + if ( m_win ) + ::ReleaseDC(GetHwndOf(m_win), m_hdc); + //else: our HDC belongs to m_dc, don't touch it + + m_hdc = NULL; +} + +// Notice we don't check here the font. It is supposed to be OK before the call. +void wxTextMeasure::DoGetTextExtent(const wxString& string, + wxCoord *width, + wxCoord *height, + wxCoord *descent, + wxCoord *externalLeading) +{ + SIZE sizeRect; + const size_t len = string.length(); + if ( !::GetTextExtentPoint32(m_hdc, string.t_str(), len, &sizeRect) ) + { + wxLogLastError(wxT("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 widthABC; + const wxChar chFirst = *string.begin(); + if ( ::GetCharABCWidths(m_hdc, chFirst, chFirst, &widthABC) ) + { + if ( widthABC.abcA < 0 ) + sizeRect.cx -= widthABC.abcA; + + if ( len > 1 ) + { + const wxChar chLast = *string.rbegin(); + ::GetCharABCWidths(m_hdc, chLast, chLast, &widthABC); + } + //else: we already have the width of the last character + + if ( widthABC.abcC < 0 ) + sizeRect.cx -= widthABC.abcC; + } + //else: GetCharABCWidths() failed, not a TrueType font? + } +#endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400) + + *width = sizeRect.cx; + *height = sizeRect.cy; + + if ( descent || externalLeading ) + { + TEXTMETRIC tm; + ::GetTextMetrics(m_hdc, &tm); + if ( descent ) + *descent = tm.tmDescent; + if ( externalLeading ) + *externalLeading = tm.tmExternalLeading; + } +} + +bool wxTextMeasure::DoGetPartialTextExtents(const wxString& text, + wxArrayInt& widths, + double WXUNUSED(scaleX)) +{ + static int maxLenText = -1; + static int maxWidth = -1; + + if (maxLenText == -1) + { + // Win9x and WinNT+ have different limits + int version = wxGetOsVersion(); + maxLenText = version == wxOS_WINDOWS_NT ? 65535 : 8192; + maxWidth = version == wxOS_WINDOWS_NT ? INT_MAX : 32767; + } + + int len = text.length(); + if ( len > maxLenText ) + len = maxLenText; + + int fit = 0; + SIZE sz = {0,0}; + if ( !::GetTextExtentExPoint(m_hdc, + text.t_str(), // string to check + len, + maxWidth, + &fit, // [out] count of chars + // that will fit + &widths[0], // array to fill + &sz) ) + { + wxLogLastError(wxT("GetTextExtentExPoint")); + + return false; + } + + return true; +}