1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 2000 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
23 #include "gdkprivate.h"
25 #define GDK_INFO_KEY "gdk-info"
27 typedef struct _GdkPangoContextInfo GdkPangoContextInfo;
29 struct _GdkPangoContextInfo
31 GdkColormap *colormap;
34 static void gdk_pango_get_item_properties (PangoItem *item,
35 PangoUnderline *uline,
37 PangoAttrColor *fg_color,
39 PangoAttrColor *bg_color,
42 PangoRectangle *ink_rect,
43 PangoRectangle *logical_rect);
46 gdk_pango_context_destroy (GdkPangoContextInfo *info)
48 gdk_colormap_unref (info->colormap);
52 static GdkPangoContextInfo *
53 gdk_pango_context_get_info (PangoContext *context, gboolean create)
55 GdkPangoContextInfo *info =
56 g_object_get_qdata (G_OBJECT (context),
57 g_quark_try_string (GDK_INFO_KEY));
60 info = g_new (GdkPangoContextInfo, 1);
61 info->colormap = NULL;
63 g_object_set_qdata_full (G_OBJECT (context),
64 g_quark_from_static_string (GDK_INFO_KEY),
65 info, (GDestroyNotify)gdk_pango_context_destroy);
72 gdk_pango_get_gc (PangoContext *context,
73 PangoAttrColor *fg_color,
76 GdkPangoContextInfo *info;
77 GdkColormap *colormap;
80 g_return_val_if_fail (context != NULL, NULL);
82 info = gdk_pango_context_get_info (context, FALSE);
84 if (info && info->colormap)
85 colormap = info->colormap;
87 colormap = gdk_colormap_get_system();
89 /* FIXME. FIXME. FIXME. Only works for true color */
91 color.red = fg_color->red;
92 color.green = fg_color->green;
93 color.blue = fg_color->blue;
95 if (gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE))
97 GdkGC *result = gdk_gc_new (gdk_parent_root);
98 gdk_gc_copy (result, base_gc);
99 gdk_gc_set_foreground (result, &color);
104 return gdk_gc_ref (base_gc);
108 gdk_pango_free_gc (PangoContext *context,
115 gdk_pango_context_set_colormap (PangoContext *context,
116 GdkColormap *colormap)
118 GdkPangoContextInfo *info;
120 g_return_if_fail (context != NULL);
122 info = gdk_pango_context_get_info (context, TRUE);
123 g_return_if_fail (info != NULL);
125 if (info->colormap != colormap)
128 gdk_colormap_unref (info->colormap);
130 info->colormap = colormap;
133 gdk_colormap_ref (info->colormap);
138 * gdk_draw_layout_line:
139 * @drawable: the drawable on which to draw the line
140 * @gc: base graphics to use
141 * @x: the x position of start of string (in pixels)
142 * @y: the y position of baseline (in pixels)
143 * @line: a #PangoLayoutLine
145 * Render a #PangoLayoutLine onto an GDK drawable
148 gdk_draw_layout_line (GdkDrawable *drawable,
152 PangoLayoutLine *line)
154 GSList *tmp_list = line->runs;
155 PangoRectangle overall_rect;
156 PangoRectangle logical_rect;
157 PangoRectangle ink_rect;
158 PangoContext *context;
162 g_return_if_fail (drawable != NULL);
163 g_return_if_fail (gc != NULL);
164 g_return_if_fail (line != NULL);
166 context = pango_layout_get_context (line->layout);
168 pango_layout_line_get_extents (line,NULL, &overall_rect);
172 PangoUnderline uline = PANGO_UNDERLINE_NONE;
173 PangoLayoutRun *run = tmp_list->data;
174 PangoAttrColor fg_color, bg_color;
175 gboolean fg_set, bg_set, shape_set;
179 tmp_list = tmp_list->next;
181 gdk_pango_get_item_properties (run->item, &uline,
189 /* we subtract the rise because X coordinates are upside down */
190 risen_y = y - rise / PANGO_SCALE;
194 if (uline == PANGO_UNDERLINE_NONE)
195 pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
196 NULL, &logical_rect);
198 pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
199 &ink_rect, &logical_rect);
204 GdkGC *bg_gc = gdk_pango_get_gc (context, &bg_color, gc);
206 gdk_draw_rectangle (drawable, bg_gc, TRUE,
207 x + (x_off + logical_rect.x) / PANGO_SCALE,
208 risen_y + overall_rect.y / PANGO_SCALE,
209 logical_rect.width / PANGO_SCALE,
210 overall_rect.height / PANGO_SCALE);
212 gdk_pango_free_gc (context, bg_gc);
216 fg_gc = gdk_pango_get_gc (context, &fg_color, gc);
221 gdk_draw_glyphs (drawable, fg_gc, run->item->analysis.font,
222 x + x_off / PANGO_SCALE,
228 case PANGO_UNDERLINE_NONE:
230 case PANGO_UNDERLINE_DOUBLE:
231 gdk_draw_line (drawable, fg_gc,
232 x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
234 x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
237 case PANGO_UNDERLINE_SINGLE:
238 gdk_draw_line (drawable, fg_gc,
239 x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
241 x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
244 case PANGO_UNDERLINE_LOW:
245 gdk_draw_line (drawable, fg_gc,
246 x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
247 risen_y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 1,
248 x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
249 risen_y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 1);
254 gdk_pango_free_gc (context, fg_gc);
256 x_off += logical_rect.width;
262 * @drawable: the drawable on which to draw string
263 * @gc: base graphics context to use
264 * @x: the X position of the left of the layout (in pixels)
265 * @y: the Y position of the top of the layout (in pixels)
266 * @layout: a #PangoLayout
268 * Render a #PangoLayout onto a GDK drawable
271 gdk_draw_layout (GdkDrawable *drawable,
277 PangoLayoutIter *iter;
279 g_return_if_fail (drawable != NULL);
280 g_return_if_fail (gc != NULL);
281 g_return_if_fail (layout != NULL);
283 iter = pango_layout_get_iter (layout);
287 PangoRectangle logical_rect;
288 PangoLayoutLine *line;
291 line = pango_layout_iter_get_line (iter);
293 pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
294 baseline = pango_layout_iter_get_baseline (iter);
296 gdk_draw_layout_line (drawable, gc,
297 x + logical_rect.x / PANGO_SCALE,
298 y + baseline / PANGO_SCALE,
301 while (pango_layout_iter_next_line (iter));
303 pango_layout_iter_free (iter);
307 gdk_pango_get_item_properties (PangoItem *item,
308 PangoUnderline *uline,
310 PangoAttrColor *fg_color,
312 PangoAttrColor *bg_color,
315 PangoRectangle *ink_rect,
316 PangoRectangle *logical_rect)
318 GSList *tmp_list = item->extra_attrs;
334 PangoAttribute *attr = tmp_list->data;
336 switch (attr->klass->type)
338 case PANGO_ATTR_UNDERLINE:
340 *uline = ((PangoAttrInt *)attr)->value;
343 case PANGO_ATTR_FOREGROUND:
345 *fg_color = *((PangoAttrColor *)attr);
351 case PANGO_ATTR_BACKGROUND:
353 *bg_color = *((PangoAttrColor *)attr);
359 case PANGO_ATTR_SHAPE:
363 *logical_rect = ((PangoAttrShape *)attr)->logical_rect;
365 *ink_rect = ((PangoAttrShape *)attr)->ink_rect;
368 case PANGO_ATTR_RISE:
370 *rise = ((PangoAttrInt *)attr)->value;
376 tmp_list = tmp_list->next;