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,
36 PangoAttrColor *fg_color,
38 PangoAttrColor *bg_color,
43 gdk_pango_context_destroy (GdkPangoContextInfo *info)
45 gdk_colormap_unref (info->colormap);
49 static GdkPangoContextInfo *
50 gdk_pango_context_get_info (PangoContext *context, gboolean create)
52 GdkPangoContextInfo *info =
53 g_object_get_qdata (G_OBJECT (context),
54 g_quark_try_string (GDK_INFO_KEY));
57 info = g_new (GdkPangoContextInfo, 1);
58 info->colormap = NULL;
60 g_object_set_qdata_full (G_OBJECT (context),
61 g_quark_from_static_string (GDK_INFO_KEY),
62 info, (GDestroyNotify)gdk_pango_context_destroy);
69 gdk_pango_get_gc (PangoContext *context,
70 PangoAttrColor *fg_color,
73 GdkPangoContextInfo *info;
74 GdkColormap *colormap;
77 g_return_val_if_fail (context != NULL, NULL);
79 info = gdk_pango_context_get_info (context, FALSE);
81 if (info && info->colormap)
82 colormap = info->colormap;
84 colormap = gdk_colormap_get_system();
86 /* FIXME. FIXME. FIXME. Only works for true color */
88 color.red = fg_color->red;
89 color.green = fg_color->green;
90 color.blue = fg_color->blue;
92 if (gdk_colormap_alloc_color (colormap, &color, FALSE, TRUE))
94 GdkGC *result = gdk_gc_new (gdk_parent_root);
95 gdk_gc_copy (result, base_gc);
96 gdk_gc_set_foreground (result, &color);
101 return gdk_gc_ref (base_gc);
105 gdk_pango_free_gc (PangoContext *context,
112 gdk_pango_context_set_colormap (PangoContext *context,
113 GdkColormap *colormap)
115 GdkPangoContextInfo *info;
117 g_return_if_fail (context != NULL);
119 info = gdk_pango_context_get_info (context, TRUE);
120 g_return_if_fail (info != NULL);
122 if (info->colormap != colormap)
125 gdk_colormap_unref (info->colormap);
127 info->colormap = colormap;
130 gdk_colormap_ref (info->colormap);
136 * gdk_draw_layout_line:
137 * @drawable: the drawable on which to draw the line
138 * @gc: base graphics to use
139 * @x: the x position of start of string (in pixels)
140 * @y: the y position of baseline (in pixels)
141 * @line: a #PangoLayoutLine
143 * Render a #PangoLayoutLine onto an GDK drawable
146 gdk_draw_layout_line (GdkDrawable *drawable,
150 PangoLayoutLine *line)
152 GSList *tmp_list = line->runs;
153 PangoRectangle overall_rect;
154 PangoRectangle logical_rect;
155 PangoRectangle ink_rect;
156 PangoContext *context;
159 g_return_if_fail (drawable != NULL);
160 g_return_if_fail (gc != NULL);
161 g_return_if_fail (line != NULL);
163 context = pango_layout_get_context (line->layout);
165 pango_layout_line_get_extents (line,NULL, &overall_rect);
169 PangoUnderline uline = PANGO_UNDERLINE_NONE;
170 PangoLayoutRun *run = tmp_list->data;
171 PangoAttrColor fg_color, bg_color;
172 gboolean fg_set, bg_set, shape_set;
175 tmp_list = tmp_list->next;
177 gdk_pango_get_item_properties (run->item, &uline, &fg_color, &fg_set, &bg_color, &bg_set, &shape_set);
179 if (uline == PANGO_UNDERLINE_NONE)
180 pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
181 NULL, &logical_rect);
183 pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
184 &ink_rect, &logical_rect);
188 GdkGC *bg_gc = gdk_pango_get_gc (context, &bg_color, gc);
190 gdk_draw_rectangle (drawable, bg_gc, TRUE,
191 x + (x_off + logical_rect.x) / PANGO_SCALE,
192 y + overall_rect.y / PANGO_SCALE,
193 logical_rect.width / PANGO_SCALE,
194 overall_rect.height / PANGO_SCALE);
196 gdk_pango_free_gc (context, bg_gc);
203 fg_gc = gdk_pango_get_gc (context, &fg_color, gc);
207 gdk_draw_glyphs (drawable, fg_gc, run->item->analysis.font,
208 x + x_off / PANGO_SCALE, y, run->glyphs);
212 case PANGO_UNDERLINE_NONE:
214 case PANGO_UNDERLINE_DOUBLE:
215 gdk_draw_line (drawable, fg_gc,
216 x + (x_off + ink_rect.x) / PANGO_SCALE - 1, y + 4,
217 x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, y + 4);
219 case PANGO_UNDERLINE_SINGLE:
220 gdk_draw_line (drawable, fg_gc,
221 x + (x_off + ink_rect.x) / PANGO_SCALE - 1, y + 2,
222 x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, y + 2);
224 case PANGO_UNDERLINE_LOW:
225 gdk_draw_line (drawable, fg_gc,
226 x + (x_off + ink_rect.x) / PANGO_SCALE - 1, y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 2,
227 x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 2);
232 gdk_pango_free_gc (context, fg_gc);
234 x_off += logical_rect.width;
240 * @drawable: the drawable on which to draw string
241 * @gc: base graphics context to use
242 * @x: the X position of the left of the layout (in pixels)
243 * @y: the Y position of the top of the layout (in pixels)
244 * @layout: a #PangoLayout
246 * Render a #PangoLayout onto a GDK drawable
249 gdk_draw_layout (GdkDrawable *drawable,
255 PangoRectangle logical_rect;
257 PangoAlignment align;
261 gboolean first = FALSE;
263 g_return_if_fail (drawable != NULL);
264 g_return_if_fail (gc != NULL);
265 g_return_if_fail (layout != NULL);
267 indent = pango_layout_get_indent (layout);
268 width = pango_layout_get_width (layout);
269 align = pango_layout_get_alignment (layout);
271 if (width == -1 && align != PANGO_ALIGN_LEFT)
273 pango_layout_get_extents (layout, NULL, &logical_rect);
274 width = logical_rect.width;
277 tmp_list = pango_layout_get_lines (layout);
280 PangoLayoutLine *line = tmp_list->data;
283 pango_layout_line_get_extents (line, NULL, &logical_rect);
285 if (width != -1 && align == PANGO_ALIGN_RIGHT)
286 x_offset = width - logical_rect.width;
287 else if (width != -1 && align == PANGO_ALIGN_CENTER)
288 x_offset = (width - logical_rect.width) / 2;
296 if (align == PANGO_ALIGN_LEFT)
308 if (align == PANGO_ALIGN_LEFT)
315 gdk_draw_layout_line (drawable, gc,
316 x + x_offset / PANGO_SCALE, y + (y_offset - logical_rect.y) / PANGO_SCALE,
319 y_offset += logical_rect.height;
320 tmp_list = tmp_list->next;
325 gdk_pango_get_item_properties (PangoItem *item,
326 PangoUnderline *uline,
327 PangoAttrColor *fg_color,
329 PangoAttrColor *bg_color,
333 GSList *tmp_list = item->extra_attrs;
346 PangoAttribute *attr = tmp_list->data;
348 switch (attr->klass->type)
350 case PANGO_ATTR_UNDERLINE:
352 *uline = ((PangoAttrInt *)attr)->value;
355 case PANGO_ATTR_FOREGROUND:
357 *fg_color = *((PangoAttrColor *)attr);
363 case PANGO_ATTR_BACKGROUND:
365 *bg_color = *((PangoAttrColor *)attr);
371 case PANGO_ATTR_SHAPE:
379 tmp_list = tmp_list->next;