Just fix header comments of wxTextMeasure-related files, no real changes.
[wxWidgets.git] / src / gtk / textmeasure.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/textmeasure.cpp
3 // Purpose: wxTextMeasure implementation for wxGTK
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/window.h"
24 #include "wx/log.h"
25 #endif //WX_PRECOMP
26
27 #include "wx/private/textmeasure.h"
28
29 #include "wx/fontutil.h"
30 #include "wx/gtk/private.h"
31
32 #ifndef __WXGTK3__
33 #include "wx/gtk/dcclient.h"
34 #endif
35
36 // ============================================================================
37 // wxTextMeasure implementation
38 // ============================================================================
39
40 void wxTextMeasure::Init()
41 {
42 wxASSERT_MSG( m_font, wxT("wxTextMeasure needs a valid wxFont") );
43
44 #ifndef __WXGTK3__
45 m_wdc = NULL;
46 #endif // GTK+ < 3
47 m_context = NULL;
48 m_layout = NULL;
49 }
50
51 // Get Gtk needed elements, if we have not them yet.
52 void wxTextMeasure::BeginMeasuring()
53 {
54 if ( m_dc )
55 {
56 #ifndef __WXGTK3__
57 m_wdc = wxDynamicCast(m_dc->GetImpl(), wxWindowDCImpl);
58 if ( m_wdc )
59 {
60 m_context = m_wdc->m_context;
61 m_layout = m_wdc->m_layout;
62 }
63 #endif // GTK+ < 3
64 }
65 else if ( m_win )
66 {
67 m_context = gtk_widget_get_pango_context( m_win->GetHandle() );
68 if ( m_context )
69 m_layout = pango_layout_new(m_context);
70 }
71
72 // set the font to use
73 if ( m_layout )
74 {
75 pango_layout_set_font_description(m_layout,
76 m_font->GetNativeFontInfo()->description);
77 }
78 }
79
80 void wxTextMeasure::EndMeasuring()
81 {
82 if ( !m_layout )
83 return;
84
85 #ifndef __WXGTK3__
86 if ( m_wdc )
87 {
88 // Reset dc own font description
89 pango_layout_set_font_description( m_wdc->m_layout, m_wdc->m_fontdesc );
90 }
91 else
92 #endif // GTK+ < 3
93 {
94 g_object_unref (m_layout);
95 }
96 }
97
98 // Notice we don't check here the font. It is supposed to be OK before the call.
99 void wxTextMeasure::DoGetTextExtent(const wxString& string,
100 wxCoord *width,
101 wxCoord *height,
102 wxCoord *descent,
103 wxCoord *externalLeading)
104 {
105 if ( !m_context )
106 {
107 *width =
108 *height = 0;
109 return;
110 }
111
112 // Set layout's text
113 const wxCharBuffer dataUTF8 = wxGTK_CONV_FONT(string, *m_font);
114 if ( !dataUTF8 )
115 {
116 // hardly ideal, but what else can we do if conversion failed?
117 wxLogLastError(wxT("GetTextExtent"));
118 return;
119 }
120 pango_layout_set_text(m_layout, dataUTF8, -1);
121
122 if ( m_dc )
123 {
124 // in device units
125 pango_layout_get_pixel_size(m_layout, width, height);
126 }
127 else // win
128 {
129 // the logical rect bounds the ink rect
130 PangoRectangle rect;
131 pango_layout_get_extents(m_layout, NULL, &rect);
132 *width = PANGO_PIXELS(rect.width);
133 *height = PANGO_PIXELS(rect.height);
134 }
135
136 if (descent)
137 {
138 PangoLayoutIter *iter = pango_layout_get_iter(m_layout);
139 int baseline = pango_layout_iter_get_baseline(iter);
140 pango_layout_iter_free(iter);
141 *descent = *height - PANGO_PIXELS(baseline);
142 }
143
144 if (externalLeading)
145 {
146 // No support for MSW-like "external leading" in Pango.
147 *externalLeading = 0;
148 }
149 }
150
151 bool wxTextMeasure::DoGetPartialTextExtents(const wxString& text,
152 wxArrayInt& widths,
153 double WXUNUSED(scaleX))
154 {
155 // Set layout's text
156 const wxCharBuffer dataUTF8 = wxGTK_CONV_FONT(text, *m_font);
157 if ( !dataUTF8 )
158 {
159 // hardly ideal, but what else can we do if conversion failed?
160 wxLogLastError(wxT("GetPartialTextExtents"));
161 return false;
162 }
163
164 pango_layout_set_text(m_layout, dataUTF8, -1);
165
166 // Calculate the position of each character based on the widths of
167 // the previous characters
168
169 // Code borrowed from Scintilla's PlatGTK
170 PangoLayoutIter *iter = pango_layout_get_iter(m_layout);
171 PangoRectangle pos;
172 pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
173 size_t i = 0;
174 while (pango_layout_iter_next_cluster(iter))
175 {
176 pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
177 int position = PANGO_PIXELS(pos.x);
178 widths[i++] = position;
179 }
180
181 const size_t len = text.length();
182 while (i < len)
183 widths[i++] = PANGO_PIXELS(pos.x + pos.width);
184 pango_layout_iter_free(iter);
185
186 return true;
187 }