1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/textmeasure.cpp
3 // Purpose: wxTextMeasure implementation for wxMSW
4 // Author: Manuel Martin
7 // Copyright: (c) 1997-2012 wxWidgets team
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
26 #include "wx/msw/private.h"
29 #include "wx/window.h"
33 #include "wx/private/textmeasure.h"
35 #include "wx/msw/dc.h"
37 // ============================================================================
38 // wxTextMeasure implementation
39 // ============================================================================
41 void wxTextMeasure
::Init()
48 wxClassInfo
* const ci
= m_dc
->GetImpl()->GetClassInfo();
50 if ( ci
->IsKindOf(wxCLASSINFO(wxMSWDCImpl
)))
57 void wxTextMeasure
::BeginMeasuring()
61 m_hdc
= m_dc
->GetHDC();
63 // Non-native wxDC subclasses should override their DoGetTextExtent()
65 wxASSERT_MSG( m_hdc
, wxS("Must not be used with non-native wxDCs") );
69 m_hdc
= ::GetDC(GetHwndOf(m_win
));
73 m_hfontOld
= (HFONT
)::SelectObject(m_hdc
, GetHfontOf(*m_font
));
76 void wxTextMeasure
::EndMeasuring()
80 ::SelectObject(m_hdc
, m_hfontOld
);
85 ::ReleaseDC(GetHwndOf(m_win
), m_hdc
);
86 //else: our HDC belongs to m_dc, don't touch it
91 // Notice we don't check here the font. It is supposed to be OK before the call.
92 void wxTextMeasure
::DoGetTextExtent(const wxString
& string
,
96 wxCoord
*externalLeading
)
99 const size_t len
= string
.length();
100 if ( !::GetTextExtentPoint32(m_hdc
, string
.t_str(), len
, &sizeRect
) )
102 wxLogLastError(wxT("GetTextExtentPoint32()"));
105 #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
106 // the result computed by GetTextExtentPoint32() may be too small as it
107 // accounts for under/overhang of the first/last character while we want
108 // just the bounding rect for this string so adjust the width as needed
109 // (using API not available in 2002 SDKs of WinCE)
113 const wxChar chFirst
= *string
.begin();
114 if ( ::GetCharABCWidths(m_hdc
, chFirst
, chFirst
, &widthABC
) )
116 if ( widthABC
.abcA
< 0 )
117 sizeRect
.cx
-= widthABC
.abcA
;
121 const wxChar chLast
= *string
.rbegin();
122 ::GetCharABCWidths(m_hdc
, chLast
, chLast
, &widthABC
);
124 //else: we already have the width of the last character
126 if ( widthABC
.abcC
< 0 )
127 sizeRect
.cx
-= widthABC
.abcC
;
129 //else: GetCharABCWidths() failed, not a TrueType font?
131 #endif // !defined(_WIN32_WCE) || (_WIN32_WCE >= 400)
133 *width
= sizeRect
.cx
;
134 *height
= sizeRect
.cy
;
136 if ( descent
|| externalLeading
)
139 ::GetTextMetrics(m_hdc
, &tm
);
141 *descent
= tm
.tmDescent
;
142 if ( externalLeading
)
143 *externalLeading
= tm
.tmExternalLeading
;
147 bool wxTextMeasure
::DoGetPartialTextExtents(const wxString
& text
,
149 double WXUNUSED(scaleX
))
151 static int maxLenText
= -1;
152 static int maxWidth
= -1;
154 if (maxLenText
== -1)
156 // Win9x and WinNT+ have different limits
157 int version
= wxGetOsVersion();
158 maxLenText
= version
== wxOS_WINDOWS_NT ?
65535 : 8192;
159 maxWidth
= version
== wxOS_WINDOWS_NT ? INT_MAX
: 32767;
162 int len
= text
.length();
163 if ( len
> maxLenText
)
168 if ( !::GetTextExtentExPoint(m_hdc
,
169 text
.t_str(), // string to check
172 &fit
, // [out] count of chars
174 &widths
[0], // array to fill
177 wxLogLastError(wxT("GetTextExtentExPoint"));