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