Return NULL from wxWindow::GetCapture() when the capture is being lost.
[wxWidgets.git] / src / x11 / pango_x.cpp
1 /**
2 * This file gets included from dcclient.cpp and implements
3 * the X11 interface to Pango.
4 * Copyright (C) Owen Taylor and Robert Roebling.
5 * Licence: The wxWindows licence
6 */
7
8 /* Declaration */
9
10 void
11 x11_draw_glyphs( Drawable drawable,
12 GC gc,
13 PangoFont *font,
14 int x,
15 int y,
16 PangoGlyphString *glyphs,
17 wxColour &colour );
18
19 void
20 x11_draw_layout_line_with_colors( Drawable drawable,
21 GC gc,
22 int x,
23 int y,
24 PangoLayoutLine *line,
25 wxColour &colour );
26
27 void
28 x11_draw_layout_with_colors( Drawable drawable,
29 GC gc,
30 int x,
31 int y,
32 PangoLayout *layout,
33 wxColour &colour );
34
35 void
36 x11_draw_layout( Drawable drawable,
37 GC gc,
38 int x,
39 int y,
40 PangoLayout *layout,
41 wxColour &colour);
42
43 void
44 x11_pango_get_item_properties( PangoItem *item,
45 PangoUnderline *uline,
46 gboolean *strikethrough,
47 gint *rise,
48 PangoColor *fg_color,
49 gboolean *fg_set,
50 PangoColor *bg_color,
51 gboolean *bg_set,
52 gboolean *shape_set,
53 PangoRectangle *ink_rect,
54 PangoRectangle *logical_rect);
55
56 /* Implementation */
57
58 void
59 x11_draw_glyphs( Drawable drawable,
60 GC gc,
61 PangoFont *font,
62 int x,
63 int y,
64 PangoGlyphString *glyphs,
65 wxColour &colour )
66 {
67 #ifdef HAVE_PANGO_XFT
68 if (PANGO_XFT_IS_FONT (font))
69 {
70 Display* xdisplay = wxGlobalDisplay();
71 int xscreen = DefaultScreen( xdisplay );
72 Visual* xvisual = DefaultVisual( xdisplay, xscreen );
73
74 Colormap xcolormap = DefaultColormapOfScreen( XScreenOfDisplay( xdisplay, xscreen ) );
75
76 XftDraw *draw = XftDrawCreate( xdisplay, drawable, xvisual, xcolormap );
77 XftColor color;
78 color.pixel = 0;
79 color.color.red = colour.Red() << 8;
80 color.color.green = colour.Green() << 8;
81 color.color.blue = colour.Blue() << 8;
82 color.color.alpha = 65000;
83 pango_xft_render( draw, &color, font, glyphs, x, y );
84
85 XftDrawDestroy( draw );
86 }
87 else
88 #endif
89 {
90 wxUnusedVar(colour);
91 pango_x_render( wxGlobalDisplay(), drawable, gc, font, glyphs, x, y );
92 }
93 }
94
95 void
96 x11_draw_layout_line_with_colors( Drawable drawable,
97 GC gc,
98 int x,
99 int y,
100 PangoLayoutLine *line,
101 wxColour &colour )
102 {
103 PangoRectangle overall_rect;
104 PangoRectangle logical_rect;
105 PangoRectangle ink_rect;
106 PangoContext *context;
107 gint x_off = 0;
108 gint rise = 0;
109
110 context = pango_layout_get_context (line->layout);
111
112 pango_layout_line_get_extents (line,NULL, &overall_rect);
113
114 GSList *tmp_list = line->runs;
115 while (tmp_list)
116 {
117 PangoUnderline uline = PANGO_UNDERLINE_NONE;
118 PangoLayoutRun *run = (PangoLayoutRun *) tmp_list->data;
119 PangoColor fg_color, bg_color;
120 gboolean strike, fg_set, bg_set, shape_set;
121 gint risen_y;
122
123 tmp_list = tmp_list->next;
124
125 x11_pango_get_item_properties (run->item, &uline,
126 &strike, &rise, &fg_color, &fg_set, &bg_color, &bg_set,
127 &shape_set, &ink_rect, &logical_rect);
128
129 /* we subtract the rise because X coordinates are upside down */
130 risen_y = y - rise / PANGO_SCALE;
131
132 if (!shape_set)
133 {
134 if (uline == PANGO_UNDERLINE_NONE)
135 pango_glyph_string_extents (run->glyphs, run->item->analysis.font, NULL, &logical_rect);
136 else
137 pango_glyph_string_extents (run->glyphs, run->item->analysis.font, &ink_rect, &logical_rect);
138 }
139
140 #if 0
141 XDrawRectangle( drawable, gc, TRUE,
142 x + (x_off + logical_rect.x) / PANGO_SCALE,
143 risen_y + overall_rect.y / PANGO_SCALE,
144 logical_rect.width / PANGO_SCALE,
145 overall_rect.height / PANGO_SCALE);
146 #endif
147
148 if (!shape_set)
149 {
150 int gx = x + x_off / PANGO_SCALE;
151 int gy = risen_y;
152
153 x11_draw_glyphs( drawable, gc, run->item->analysis.font, gx, gy, run->glyphs, colour );
154 }
155
156 if (uline == PANGO_UNDERLINE_SINGLE)
157 {
158 XDrawLine( wxGlobalDisplay(), drawable, gc,
159 x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
160 risen_y + 1,
161 x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
162 risen_y + 1);
163 }
164
165 x_off += logical_rect.width;
166 }
167 }
168
169 void
170 x11_draw_layout_with_colors( Drawable drawable,
171 GC gc,
172 int x,
173 int y,
174 PangoLayout *layout,
175 wxColour &colour )
176 {
177 PangoLayoutIter *iter = pango_layout_get_iter (layout);
178
179 do
180 {
181 PangoLayoutLine *line = pango_layout_iter_get_line (iter);
182
183 PangoRectangle logical_rect;
184 pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
185
186 int baseline = pango_layout_iter_get_baseline (iter);
187
188 x11_draw_layout_line_with_colors( drawable, gc,
189 x + logical_rect.x / PANGO_SCALE,
190 y + baseline / PANGO_SCALE,
191 line,
192 colour );
193
194 } while (pango_layout_iter_next_line (iter));
195
196 pango_layout_iter_free (iter);
197 }
198
199 void
200 x11_draw_layout( Drawable drawable,
201 GC gc,
202 int x,
203 int y,
204 PangoLayout *layout,
205 wxColour &colour)
206 {
207 wxCHECK_RET( layout, wxT("No layout") );
208
209 x11_draw_layout_with_colors (drawable, gc, x, y, layout, colour );
210 }
211
212 void
213 x11_pango_get_item_properties( PangoItem *item,
214 PangoUnderline *uline,
215 gboolean *strikethrough,
216 gint *rise,
217 PangoColor *fg_color,
218 gboolean *fg_set,
219 PangoColor *bg_color,
220 gboolean *bg_set,
221 gboolean *shape_set,
222 PangoRectangle *ink_rect,
223 PangoRectangle *logical_rect)
224 {
225 GSList *tmp_list = item->analysis.extra_attrs;
226
227 if (strikethrough)
228 *strikethrough = FALSE;
229
230 if (fg_set)
231 *fg_set = FALSE;
232
233 if (bg_set)
234 *bg_set = FALSE;
235
236 if (shape_set)
237 *shape_set = FALSE;
238
239 if (rise)
240 *rise = 0;
241
242 while (tmp_list)
243 {
244 PangoAttribute *attr = (PangoAttribute *) tmp_list->data;
245
246 switch (attr->klass->type)
247 {
248 case PANGO_ATTR_UNDERLINE:
249 if (uline)
250 *uline = (PangoUnderline) ((PangoAttrInt *)attr)->value;
251 break;
252
253 case PANGO_ATTR_STRIKETHROUGH:
254 if (strikethrough)
255 *strikethrough = ((PangoAttrInt *)attr)->value;
256 break;
257
258 case PANGO_ATTR_FOREGROUND:
259 if (fg_color)
260 *fg_color = ((PangoAttrColor *)attr)->color;
261 if (fg_set)
262 *fg_set = TRUE;
263
264 break;
265
266 case PANGO_ATTR_BACKGROUND:
267 if (bg_color)
268 *bg_color = ((PangoAttrColor *)attr)->color;
269 if (bg_set)
270 *bg_set = TRUE;
271
272 break;
273
274 case PANGO_ATTR_SHAPE:
275 if (shape_set)
276 *shape_set = TRUE;
277 if (logical_rect)
278 *logical_rect = ((PangoAttrShape *)attr)->logical_rect;
279 if (ink_rect)
280 *ink_rect = ((PangoAttrShape *)attr)->ink_rect;
281 break;
282
283 case PANGO_ATTR_RISE:
284 if (rise)
285 *rise = ((PangoAttrInt *)attr)->value;
286 break;
287
288 default:
289 break;
290 }
291 tmp_list = tmp_list->next;
292 }
293 }
294