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