1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/textmeasure.cpp
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2012 Vadim Zeitlin <vadim@wxwidgets.org>
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/private/textmeasure.h"
28 #if wxUSE_GENERIC_TEXTMEASURE
30 // ============================================================================
31 // wxTextMeasure generic implementation
32 // ============================================================================
34 // We assume that the ports not providing platform-specific wxTextMeasure
35 // implementation implement the corresponding functions in their wxDC and
36 // wxWindow classes, so forward back to them instead of using wxTextMeasure
37 // from there, as usual.
38 void wxTextMeasure::DoGetTextExtent(const wxString
& string
,
42 wxCoord
*externalLeading
)
46 m_dc
->GetTextExtent(string
, width
, height
,
47 descent
, externalLeading
, m_font
);
51 m_win
->GetTextExtent(string
, width
, height
,
52 descent
, externalLeading
, m_font
);
54 //else: we already asserted in the ctor, don't do it any more
57 // Each element of the widths array will be the width of the string up to and
58 // including the corresponding character in text. This is the generic
59 // implementation, the port-specific classes should do this with native APIs
60 // if available and if faster. Note: pango_layout_index_to_pos is much slower
61 // than calling GetTextExtent!!
68 FontWidthCache() : m_scaleX(1), m_widths(NULL
) { }
69 ~FontWidthCache() { delete []m_widths
; }
74 m_widths
= new int[FWC_SIZE
];
76 memset(m_widths
, 0, sizeof(int)*FWC_SIZE
);
84 static FontWidthCache s_fontWidthCache
;
86 bool wxTextMeasure::DoGetPartialTextExtents(const wxString
& text
,
92 // reset the cache if font or horizontal scale have changed
93 if ( !s_fontWidthCache
.m_widths
||
94 !wxIsSameDouble(s_fontWidthCache
.m_scaleX
, scaleX
) ||
95 (s_fontWidthCache
.m_font
!= *m_font
) )
97 s_fontWidthCache
.Reset();
98 s_fontWidthCache
.m_font
= *m_font
;
99 s_fontWidthCache
.m_scaleX
= scaleX
;
102 // Calculate the position of each character based on the widths of
103 // the previous characters. This is inexact for not fixed fonts.
105 for ( wxString::const_iterator it
= text
.begin();
109 const wxChar c
= *it
;
110 unsigned int c_int
= (unsigned int)c
;
113 if ((c_int
< FWC_SIZE
) && (s_fontWidthCache
.m_widths
[c_int
] != 0))
115 w
= s_fontWidthCache
.m_widths
[c_int
];
119 DoGetTextExtent(c
, &w
, NULL
);
120 if (c_int
< FWC_SIZE
)
121 s_fontWidthCache
.m_widths
[c_int
] = w
;
125 widths
[n
++] = totalWidth
;
131 #endif // wxUSE_GENERIC_TEXTMEASURE