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