]> git.saurik.com Git - wxWidgets.git/blob - src/common/textmeasurecmn.cpp
Allow using wxTextMeasure::GetLargestStringExtent() with wxArrayString.
[wxWidgets.git] / src / common / textmeasurecmn.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/textmeasurecmn.cpp
3 // Purpose: wxTextMeasureBase implementation
4 // Author: Manuel Martin
5 // Created: 2012-10-05
6 // RCS-ID: $Id:
7 // Copyright: (c) 1997-2012 wxWidgets team
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifndef WX_PRECOMP
23 #include "wx/dc.h"
24 #include "wx/window.h"
25 #endif //WX_PRECOMP
26
27 #include "wx/private/textmeasure.h"
28
29 // ============================================================================
30 // wxTextMeasureBase implementation
31 // ============================================================================
32
33 wxTextMeasureBase::wxTextMeasureBase(const wxDC *dc, const wxFont *theFont)
34 : m_dc(dc),
35 m_win(NULL),
36 m_font(theFont)
37 {
38 wxASSERT_MSG( dc, wxS("wxTextMeasure needs a valid wxDC") );
39
40 // By default, use wxDC version, we'll explicitly reset this to false in
41 // the derived classes if the DC is of native variety.
42 m_useDCImpl = true;
43 }
44
45 wxTextMeasureBase::wxTextMeasureBase(const wxWindow *win, const wxFont *theFont)
46 : m_dc(NULL),
47 m_win(win),
48 m_font(theFont)
49 {
50 wxASSERT_MSG( win, wxS("wxTextMeasure needs a valid wxWindow") );
51
52 // We don't have any wxDC so we can't forward to it.
53 m_useDCImpl = false;
54 }
55
56 void wxTextMeasureBase::CallGetTextExtent(const wxString& string,
57 wxCoord *width,
58 wxCoord *height,
59 wxCoord *descent,
60 wxCoord *externalLeading)
61 {
62 if ( m_useDCImpl )
63 m_dc->GetTextExtent(string, width, height, descent, externalLeading);
64 else
65 DoGetTextExtent(string, width, height, descent, externalLeading);
66 }
67
68 void wxTextMeasureBase::GetTextExtent(const wxString& string,
69 wxCoord *width,
70 wxCoord *height,
71 wxCoord *descent,
72 wxCoord *externalLeading)
73 {
74 // To make the code simpler, make sure that the width and height pointers
75 // are always valid, even if they point to dummy variables.
76 int unusedWidth, unusedHeight;
77 if ( !width )
78 width = &unusedWidth;
79 if ( !height )
80 height = &unusedHeight;
81
82 if ( string.empty() )
83 {
84 *width =
85 *height = 0;
86
87 return;
88 }
89
90 MeasuringGuard guard(*this);
91
92 CallGetTextExtent(string, width, height, descent, externalLeading);
93 }
94
95 void wxTextMeasureBase::GetMultiLineTextExtent(const wxString& text,
96 wxCoord *width,
97 wxCoord *height,
98 wxCoord *heightOneLine)
99 {
100 MeasuringGuard guard(*this);
101
102 wxCoord widthTextMax = 0, widthLine,
103 heightTextTotal = 0, heightLineDefault = 0, heightLine = 0;
104
105 wxString curLine;
106 for ( wxString::const_iterator pc = text.begin(); ; ++pc )
107 {
108 if ( pc == text.end() || *pc == wxS('\n') )
109 {
110 if ( curLine.empty() )
111 {
112 // we can't use GetTextExtent - it will return 0 for both width
113 // and height and an empty line should count in height
114 // calculation
115
116 // assume that this line has the same height as the previous
117 // one
118 if ( !heightLineDefault )
119 heightLineDefault = heightLine;
120
121 if ( !heightLineDefault )
122 {
123 // but we don't know it yet - choose something reasonable
124 int dummy;
125 CallGetTextExtent(wxS("W"), &dummy, &heightLineDefault);
126 }
127
128 heightTextTotal += heightLineDefault;
129 }
130 else
131 {
132 CallGetTextExtent(curLine, &widthLine, &heightLine);
133 if ( widthLine > widthTextMax )
134 widthTextMax = widthLine;
135 heightTextTotal += heightLine;
136 }
137
138 if ( pc == text.end() )
139 {
140 break;
141 }
142 else // '\n'
143 {
144 curLine.clear();
145 }
146 }
147 else
148 {
149 curLine += *pc;
150 }
151 }
152
153 if ( width )
154 *width = widthTextMax;
155 if ( height )
156 *height = heightTextTotal;
157 if ( heightOneLine )
158 *heightOneLine = heightLine;
159 }
160
161 wxSize wxTextMeasureBase::GetLargestStringExtent(size_t n,
162 const wxString* strings)
163 {
164 MeasuringGuard guard(*this);
165
166 wxCoord w, h, widthMax = 0, heightMax = 0;
167 for ( size_t i = 0; i < n; ++i )
168 {
169 CallGetTextExtent(strings[i], &w, &h);
170
171 if ( w > widthMax )
172 widthMax = w;
173 if ( h > heightMax )
174 heightMax = h;
175 }
176
177 return wxSize(widthMax, heightMax);
178 }
179
180 bool wxTextMeasureBase::GetPartialTextExtents(const wxString& text,
181 wxArrayInt& widths,
182 double scaleX)
183 {
184 widths.Empty();
185 if ( text.empty() )
186 return true;
187
188 MeasuringGuard guard(*this);
189
190 widths.Add(0, text.length());
191
192 return DoGetPartialTextExtents(text, widths, scaleX);
193 }