make the Pen/Brush code backward compatible as discussed on wx-dev; marked the blocks...
[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 pango_x_render( wxGlobalDisplay(), drawable, gc, font, glyphs, x, y );
91 }
92 }
93
94 void
95 x11_draw_layout_line_with_colors( Drawable drawable,
96 GC gc,
97 int x,
98 int y,
99 PangoLayoutLine *line,
100 wxColour &colour )
101 {
102 PangoRectangle overall_rect;
103 PangoRectangle logical_rect;
104 PangoRectangle ink_rect;
105 PangoContext *context;
106 gint x_off = 0;
107 gint rise = 0;
108
109 context = pango_layout_get_context (line->layout);
110
111 pango_layout_line_get_extents (line,NULL, &overall_rect);
112
113 GSList *tmp_list = line->runs;
114 while (tmp_list)
115 {
116 PangoUnderline uline = PANGO_UNDERLINE_NONE;
117 PangoLayoutRun *run = (PangoLayoutRun *) tmp_list->data;
118 PangoColor fg_color, bg_color;
119 gboolean strike, fg_set, bg_set, shape_set;
120 gint risen_y;
121
122 tmp_list = tmp_list->next;
123
124 x11_pango_get_item_properties (run->item, &uline,
125 &strike, &rise, &fg_color, &fg_set, &bg_color, &bg_set,
126 &shape_set, &ink_rect, &logical_rect);
127
128 /* we subtract the rise because X coordinates are upside down */
129 risen_y = y - rise / PANGO_SCALE;
130
131 if (!shape_set)
132 {
133 if (uline == PANGO_UNDERLINE_NONE)
134 pango_glyph_string_extents (run->glyphs, run->item->analysis.font, NULL, &logical_rect);
135 else
136 pango_glyph_string_extents (run->glyphs, run->item->analysis.font, &ink_rect, &logical_rect);
137 }
138
139 #if 0
140 XDrawRectangle( drawable, gc, TRUE,
141 x + (x_off + logical_rect.x) / PANGO_SCALE,
142 risen_y + overall_rect.y / PANGO_SCALE,
143 logical_rect.width / PANGO_SCALE,
144 overall_rect.height / PANGO_SCALE);
145 #endif
146
147 if (!shape_set)
148 {
149 int gx = x + x_off / PANGO_SCALE;
150 int gy = risen_y;
151
152 x11_draw_glyphs( drawable, gc, run->item->analysis.font, gx, gy, run->glyphs, colour );
153 }
154
155 if (uline == PANGO_UNDERLINE_SINGLE)
156 {
157 XDrawLine( wxGlobalDisplay(), drawable, gc,
158 x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
159 risen_y + 1,
160 x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
161 risen_y + 1);
162 }
163
164 x_off += logical_rect.width;
165 }
166 }
167
168 void
169 x11_draw_layout_with_colors( Drawable drawable,
170 GC gc,
171 int x,
172 int y,
173 PangoLayout *layout,
174 wxColour &colour )
175 {
176 PangoLayoutIter *iter = pango_layout_get_iter (layout);
177
178 do
179 {
180 PangoLayoutLine *line = pango_layout_iter_get_line (iter);
181
182 PangoRectangle logical_rect;
183 pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
184
185 int baseline = pango_layout_iter_get_baseline (iter);
186
187 x11_draw_layout_line_with_colors( drawable, gc,
188 x + logical_rect.x / PANGO_SCALE,
189 y + baseline / PANGO_SCALE,
190 line,
191 colour );
192
193 } while (pango_layout_iter_next_line (iter));
194
195 pango_layout_iter_free (iter);
196 }
197
198 void
199 x11_draw_layout( Drawable drawable,
200 GC gc,
201 int x,
202 int y,
203 PangoLayout *layout,
204 wxColour &colour)
205 {
206 wxCHECK_RET( layout, wxT("No layout") );
207
208 x11_draw_layout_with_colors (drawable, gc, x, y, layout, colour );
209 }
210
211 void
212 x11_pango_get_item_properties( PangoItem *item,
213 PangoUnderline *uline,
214 gboolean *strikethrough,
215 gint *rise,
216 PangoColor *fg_color,
217 gboolean *fg_set,
218 PangoColor *bg_color,
219 gboolean *bg_set,
220 gboolean *shape_set,
221 PangoRectangle *ink_rect,
222 PangoRectangle *logical_rect)
223 {
224 GSList *tmp_list = item->analysis.extra_attrs;
225
226 if (strikethrough)
227 *strikethrough = FALSE;
228
229 if (fg_set)
230 *fg_set = FALSE;
231
232 if (bg_set)
233 *bg_set = FALSE;
234
235 if (shape_set)
236 *shape_set = FALSE;
237
238 if (rise)
239 *rise = 0;
240
241 while (tmp_list)
242 {
243 PangoAttribute *attr = (PangoAttribute *) tmp_list->data;
244
245 switch (attr->klass->type)
246 {
247 case PANGO_ATTR_UNDERLINE:
248 if (uline)
249 *uline = (PangoUnderline) ((PangoAttrInt *)attr)->value;
250 break;
251
252 case PANGO_ATTR_STRIKETHROUGH:
253 if (strikethrough)
254 *strikethrough = ((PangoAttrInt *)attr)->value;
255 break;
256
257 case PANGO_ATTR_FOREGROUND:
258 if (fg_color)
259 *fg_color = ((PangoAttrColor *)attr)->color;
260 if (fg_set)
261 *fg_set = TRUE;
262
263 break;
264
265 case PANGO_ATTR_BACKGROUND:
266 if (bg_color)
267 *bg_color = ((PangoAttrColor *)attr)->color;
268 if (bg_set)
269 *bg_set = TRUE;
270
271 break;
272
273 case PANGO_ATTR_SHAPE:
274 if (shape_set)
275 *shape_set = TRUE;
276 if (logical_rect)
277 *logical_rect = ((PangoAttrShape *)attr)->logical_rect;
278 if (ink_rect)
279 *ink_rect = ((PangoAttrShape *)attr)->ink_rect;
280 break;
281
282 case PANGO_ATTR_RISE:
283 if (rise)
284 *rise = ((PangoAttrInt *)attr)->value;
285 break;
286
287 default:
288 break;
289 }
290 tmp_list = tmp_list->next;
291 }
292 }
293