From: Havoc Pennington Date: Wed, 1 Nov 2000 07:07:46 +0000 (+0000) Subject: New function to create a pixbuf pointing to a subregion of another pixbuf. X-Git-Url: http://pileus.org/git/?a=commitdiff_plain;h=fe9f9d03f41936fc9ace154db4904e32f2ec3304;p=~andy%2Fgtk New function to create a pixbuf pointing to a subregion of another pixbuf. 2000-11-01 Havoc Pennington * gdk-pixbuf.c (gdk_pixbuf_new_subpixbuf): New function to create a pixbuf pointing to a subregion of another pixbuf. 2000-11-01 Havoc Pennington * gtk/gtklabel.c (gtk_label_set_attributes): Set a PangoAttrList on a label (gtk_label_finalize): unref the attr list if any. * gtk/testgtk.c (create_get_image): close test on second click (make_message_dialog): close dialog if it exists * gdk/gdkpango.c (gdk_draw_layout): Handle rise attribute * gdk-2.0.pc.in (Requires): Make it require gdk-pixbuf-2.0 not gdk-pixbuf * gtk/gtklabel.c (gtk_label_set_markup): new function to set label from Pango markup format (gtk_label_set_markup_with_accel): ditto but with accelerator parsing * gtk/gtkimage.c (gtk_image_expose): reformatting. * gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable): Hack to reflect current state of GDK - use gdk_drawable_get_colormap, etc. Check GDK_IS_WINDOW() not !GDK_IS_PIXMAP() to decide whether to call gdk_window_get_origin(). * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_to_drawable_alpha): implement GDK_PIXBUF_ALPHA_FULL --- diff --git a/ChangeLog b/ChangeLog index 88b586bf5..dffcbe857 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2000-11-01 Havoc Pennington + + * gtk/gtklabel.c (gtk_label_set_attributes): Set a PangoAttrList + on a label + (gtk_label_finalize): unref the attr list if any. + + * gtk/testgtk.c (create_get_image): close test on second click + (make_message_dialog): close dialog if it exists + + * gdk/gdkpango.c (gdk_draw_layout): Handle rise attribute + + * gdk-2.0.pc.in (Requires): Make it require gdk-pixbuf-2.0 not + gdk-pixbuf + + * gtk/gtklabel.c (gtk_label_set_markup): new function to set label + from Pango markup format + (gtk_label_set_markup_with_accel): ditto but with accelerator + parsing + + * gtk/gtkimage.c (gtk_image_expose): reformatting. + + * gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable): Hack to + reflect current state of GDK - use gdk_drawable_get_colormap, etc. + Check GDK_IS_WINDOW() not !GDK_IS_PIXMAP() to decide whether to + call gdk_window_get_origin(). + + * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_to_drawable_alpha): + implement GDK_PIXBUF_ALPHA_FULL + Wed Nov 1 03:43:42 2000 Tim Janik * gtk/gtksignal.c (gtk_signal_compat_matched): make use of diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 88b586bf5..dffcbe857 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,32 @@ +2000-11-01 Havoc Pennington + + * gtk/gtklabel.c (gtk_label_set_attributes): Set a PangoAttrList + on a label + (gtk_label_finalize): unref the attr list if any. + + * gtk/testgtk.c (create_get_image): close test on second click + (make_message_dialog): close dialog if it exists + + * gdk/gdkpango.c (gdk_draw_layout): Handle rise attribute + + * gdk-2.0.pc.in (Requires): Make it require gdk-pixbuf-2.0 not + gdk-pixbuf + + * gtk/gtklabel.c (gtk_label_set_markup): new function to set label + from Pango markup format + (gtk_label_set_markup_with_accel): ditto but with accelerator + parsing + + * gtk/gtkimage.c (gtk_image_expose): reformatting. + + * gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable): Hack to + reflect current state of GDK - use gdk_drawable_get_colormap, etc. + Check GDK_IS_WINDOW() not !GDK_IS_PIXMAP() to decide whether to + call gdk_window_get_origin(). + + * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_to_drawable_alpha): + implement GDK_PIXBUF_ALPHA_FULL + Wed Nov 1 03:43:42 2000 Tim Janik * gtk/gtksignal.c (gtk_signal_compat_matched): make use of diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 88b586bf5..dffcbe857 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,32 @@ +2000-11-01 Havoc Pennington + + * gtk/gtklabel.c (gtk_label_set_attributes): Set a PangoAttrList + on a label + (gtk_label_finalize): unref the attr list if any. + + * gtk/testgtk.c (create_get_image): close test on second click + (make_message_dialog): close dialog if it exists + + * gdk/gdkpango.c (gdk_draw_layout): Handle rise attribute + + * gdk-2.0.pc.in (Requires): Make it require gdk-pixbuf-2.0 not + gdk-pixbuf + + * gtk/gtklabel.c (gtk_label_set_markup): new function to set label + from Pango markup format + (gtk_label_set_markup_with_accel): ditto but with accelerator + parsing + + * gtk/gtkimage.c (gtk_image_expose): reformatting. + + * gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable): Hack to + reflect current state of GDK - use gdk_drawable_get_colormap, etc. + Check GDK_IS_WINDOW() not !GDK_IS_PIXMAP() to decide whether to + call gdk_window_get_origin(). + + * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_to_drawable_alpha): + implement GDK_PIXBUF_ALPHA_FULL + Wed Nov 1 03:43:42 2000 Tim Janik * gtk/gtksignal.c (gtk_signal_compat_matched): make use of diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 88b586bf5..dffcbe857 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,32 @@ +2000-11-01 Havoc Pennington + + * gtk/gtklabel.c (gtk_label_set_attributes): Set a PangoAttrList + on a label + (gtk_label_finalize): unref the attr list if any. + + * gtk/testgtk.c (create_get_image): close test on second click + (make_message_dialog): close dialog if it exists + + * gdk/gdkpango.c (gdk_draw_layout): Handle rise attribute + + * gdk-2.0.pc.in (Requires): Make it require gdk-pixbuf-2.0 not + gdk-pixbuf + + * gtk/gtklabel.c (gtk_label_set_markup): new function to set label + from Pango markup format + (gtk_label_set_markup_with_accel): ditto but with accelerator + parsing + + * gtk/gtkimage.c (gtk_image_expose): reformatting. + + * gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable): Hack to + reflect current state of GDK - use gdk_drawable_get_colormap, etc. + Check GDK_IS_WINDOW() not !GDK_IS_PIXMAP() to decide whether to + call gdk_window_get_origin(). + + * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_to_drawable_alpha): + implement GDK_PIXBUF_ALPHA_FULL + Wed Nov 1 03:43:42 2000 Tim Janik * gtk/gtksignal.c (gtk_signal_compat_matched): make use of diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 88b586bf5..dffcbe857 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,32 @@ +2000-11-01 Havoc Pennington + + * gtk/gtklabel.c (gtk_label_set_attributes): Set a PangoAttrList + on a label + (gtk_label_finalize): unref the attr list if any. + + * gtk/testgtk.c (create_get_image): close test on second click + (make_message_dialog): close dialog if it exists + + * gdk/gdkpango.c (gdk_draw_layout): Handle rise attribute + + * gdk-2.0.pc.in (Requires): Make it require gdk-pixbuf-2.0 not + gdk-pixbuf + + * gtk/gtklabel.c (gtk_label_set_markup): new function to set label + from Pango markup format + (gtk_label_set_markup_with_accel): ditto but with accelerator + parsing + + * gtk/gtkimage.c (gtk_image_expose): reformatting. + + * gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable): Hack to + reflect current state of GDK - use gdk_drawable_get_colormap, etc. + Check GDK_IS_WINDOW() not !GDK_IS_PIXMAP() to decide whether to + call gdk_window_get_origin(). + + * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_to_drawable_alpha): + implement GDK_PIXBUF_ALPHA_FULL + Wed Nov 1 03:43:42 2000 Tim Janik * gtk/gtksignal.c (gtk_signal_compat_matched): make use of diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 88b586bf5..dffcbe857 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,32 @@ +2000-11-01 Havoc Pennington + + * gtk/gtklabel.c (gtk_label_set_attributes): Set a PangoAttrList + on a label + (gtk_label_finalize): unref the attr list if any. + + * gtk/testgtk.c (create_get_image): close test on second click + (make_message_dialog): close dialog if it exists + + * gdk/gdkpango.c (gdk_draw_layout): Handle rise attribute + + * gdk-2.0.pc.in (Requires): Make it require gdk-pixbuf-2.0 not + gdk-pixbuf + + * gtk/gtklabel.c (gtk_label_set_markup): new function to set label + from Pango markup format + (gtk_label_set_markup_with_accel): ditto but with accelerator + parsing + + * gtk/gtkimage.c (gtk_image_expose): reformatting. + + * gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable): Hack to + reflect current state of GDK - use gdk_drawable_get_colormap, etc. + Check GDK_IS_WINDOW() not !GDK_IS_PIXMAP() to decide whether to + call gdk_window_get_origin(). + + * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_to_drawable_alpha): + implement GDK_PIXBUF_ALPHA_FULL + Wed Nov 1 03:43:42 2000 Tim Janik * gtk/gtksignal.c (gtk_signal_compat_matched): make use of diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 88b586bf5..dffcbe857 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,32 @@ +2000-11-01 Havoc Pennington + + * gtk/gtklabel.c (gtk_label_set_attributes): Set a PangoAttrList + on a label + (gtk_label_finalize): unref the attr list if any. + + * gtk/testgtk.c (create_get_image): close test on second click + (make_message_dialog): close dialog if it exists + + * gdk/gdkpango.c (gdk_draw_layout): Handle rise attribute + + * gdk-2.0.pc.in (Requires): Make it require gdk-pixbuf-2.0 not + gdk-pixbuf + + * gtk/gtklabel.c (gtk_label_set_markup): new function to set label + from Pango markup format + (gtk_label_set_markup_with_accel): ditto but with accelerator + parsing + + * gtk/gtkimage.c (gtk_image_expose): reformatting. + + * gdk/gdkpixbuf-drawable.c (gdk_pixbuf_get_from_drawable): Hack to + reflect current state of GDK - use gdk_drawable_get_colormap, etc. + Check GDK_IS_WINDOW() not !GDK_IS_PIXMAP() to decide whether to + call gdk_window_get_origin(). + + * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_to_drawable_alpha): + implement GDK_PIXBUF_ALPHA_FULL + Wed Nov 1 03:43:42 2000 Tim Janik * gtk/gtksignal.c (gtk_signal_compat_matched): make use of diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index 867ce4c75..160d5e9c9 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,7 @@ +2000-11-01 Havoc Pennington + + * gtk/gtk-sections.txt: Add new label functions + Sun Oct 29 02:59:50 2000 Owen Taylor * **: Updates to new gtk-doc, gsignal, causing quite diff --git a/docs/reference/gtk/gtk-sections.txt b/docs/reference/gtk/gtk-sections.txt index f1bfa9cdf..64296e3fe 100644 --- a/docs/reference/gtk/gtk-sections.txt +++ b/docs/reference/gtk/gtk-sections.txt @@ -1102,13 +1102,16 @@ GTK_ITEM_FACTORY_GET_CLASS GtkLabel GtkLabelWord gtk_label_new -gtk_label_set +gtk_label_set_text +gtk_label_set_attributes +gtk_label_set_markup +gtk_label_set_markup_with_accel gtk_label_set_pattern gtk_label_set_justify gtk_label_get gtk_label_parse_uline gtk_label_set_line_wrap -gtk_label_set_text +gtk_label_set GTK_LABEL GTK_IS_LABEL diff --git a/gdk-2.0.pc.in b/gdk-2.0.pc.in index 0dc03329c..38a24948e 100644 --- a/gdk-2.0.pc.in +++ b/gdk-2.0.pc.in @@ -7,6 +7,6 @@ target=@gdktarget@ Name: GDK Description: GIMP Drawing Kit Version: @VERSION@ -Requires: gdk-pixbuf,pangox +Requires: gdk-pixbuf-2.0,pangox Libs: -L${libdir} @more_ldflags@ -lgdk-${target}-1.3 @more_libs@ @GDK_WLIBS@ Cflags: -I${includedir}/gtk-2.0 -I${libdir}/gtk-2.0/include @more_cflags@ diff --git a/gdk-pixbuf/ChangeLog b/gdk-pixbuf/ChangeLog index d6165192f..3ce42c569 100644 --- a/gdk-pixbuf/ChangeLog +++ b/gdk-pixbuf/ChangeLog @@ -1,3 +1,8 @@ +2000-11-01 Havoc Pennington + + * gdk-pixbuf.c (gdk_pixbuf_new_subpixbuf): New function to create + a pixbuf pointing to a subregion of another pixbuf. + 2000-10-16 Tor Lillqvist * gdk-pixbuf-io.c: Define also m_save (for the non-gmodule case). diff --git a/gdk-pixbuf/gdk-pixbuf.c b/gdk-pixbuf/gdk-pixbuf.c index 84e086e72..b2e3f5396 100644 --- a/gdk-pixbuf/gdk-pixbuf.c +++ b/gdk-pixbuf/gdk-pixbuf.c @@ -203,6 +203,60 @@ gdk_pixbuf_copy (const GdkPixbuf *pixbuf) NULL); } +/** + * gdk_pixbuf_new_subpixbuf: + * @src_pixbuf: a #GdkPixbuf + * @src_x: X coord in @src_pixbuf + * @src_y: Y coord in @src_pixbuf + * @width: width of region in @src_pixbuf + * @height: height of region in @src_pixbuf + * + * Creates a new pixbuf which represents a sub-region of + * @src_pixbuf. The new pixbuf shares its pixels with the + * original pixbuf, so writing to one affects both. + * The new pixbuf holds a reference to @src_pixbuf, so + * @src_pixbuf will not be finalized until the new pixbuf + * is finalized. + * + * Return value: a new pixbuf + **/ +GdkPixbuf* +gdk_pixbuf_new_subpixbuf (GdkPixbuf *src_pixbuf, + int src_x, + int src_y, + int width, + int height) +{ + guchar *pixels; + GdkPixbuf *sub; + + g_return_val_if_fail (GDK_IS_PIXBUF (src_pixbuf), NULL); + g_return_val_if_fail (src_x >= 0 && src_x + width <= src_pixbuf->width, NULL); + g_return_val_if_fail (src_y >= 0 && src_y + height <= src_pixbuf->height, NULL); + + pixels = (gdk_pixbuf_get_pixels (src_pixbuf) + + src_y * src_pixbuf->rowstride + + src_x * src_pixbuf->n_channels); + + sub = gdk_pixbuf_new_from_data (pixels, + src_pixbuf->colorspace, + src_pixbuf->has_alpha, + src_pixbuf->bits_per_sample, + width, height, + src_pixbuf->rowstride, + NULL, NULL); + + /* Keep a reference to src_pixbuf */ + g_object_ref (G_OBJECT (src_pixbuf)); + + g_object_set_qdata_full (G_OBJECT (sub), + g_quark_from_static_string ("gdk-pixbuf-subpixbuf-src"), + src_pixbuf, + (GDestroyNotify) g_object_unref); + + return sub; +} + /* Accessors */ diff --git a/gdk-pixbuf/gdk-pixbuf.h b/gdk-pixbuf/gdk-pixbuf.h index e87737277..ee87b82bb 100644 --- a/gdk-pixbuf/gdk-pixbuf.h +++ b/gdk-pixbuf/gdk-pixbuf.h @@ -116,6 +116,13 @@ GdkPixbuf *gdk_pixbuf_new (GdkColorspace colorspace, gboolean has_alpha, int bit GdkPixbuf *gdk_pixbuf_copy (const GdkPixbuf *pixbuf); +/* Create a pixbuf which points to the pixels of another pixbuf */ +GdkPixbuf *gdk_pixbuf_new_subpixbuf (GdkPixbuf *src_pixbuf, + int src_x, + int src_y, + int width, + int height); + /* Simple loading */ GdkPixbuf *gdk_pixbuf_new_from_file (const char *filename, diff --git a/gdk/gdkpango.c b/gdk/gdkpango.c index 53af8371d..2a10fcc8e 100644 --- a/gdk/gdkpango.c +++ b/gdk/gdkpango.c @@ -33,6 +33,7 @@ struct _GdkPangoContextInfo static void gdk_pango_get_item_properties (PangoItem *item, PangoUnderline *uline, + gint *rise, PangoAttrColor *fg_color, gboolean *fg_set, PangoAttrColor *bg_color, @@ -133,7 +134,6 @@ gdk_pango_context_set_colormap (PangoContext *context, } } - /** * gdk_draw_layout_line: * @drawable: the drawable on which to draw the line @@ -157,7 +157,8 @@ gdk_draw_layout_line (GdkDrawable *drawable, PangoRectangle ink_rect; PangoContext *context; gint x_off = 0; - + gint rise = 0; + g_return_if_fail (drawable != NULL); g_return_if_fail (gc != NULL); g_return_if_fail (line != NULL); @@ -173,12 +174,21 @@ gdk_draw_layout_line (GdkDrawable *drawable, PangoAttrColor fg_color, bg_color; gboolean fg_set, bg_set, shape_set; GdkGC *fg_gc; + gint risen_y; tmp_list = tmp_list->next; - - gdk_pango_get_item_properties (run->item, &uline, &fg_color, &fg_set, &bg_color, &bg_set, &shape_set, &ink_rect, + + gdk_pango_get_item_properties (run->item, &uline, + &rise, + &fg_color, &fg_set, + &bg_color, &bg_set, + &shape_set, + &ink_rect, &logical_rect); + /* we subtract the rise because X coordinates are upside down */ + risen_y = y - rise / PANGO_SCALE; + if (!shape_set) { if (uline == PANGO_UNDERLINE_NONE) @@ -195,7 +205,7 @@ gdk_draw_layout_line (GdkDrawable *drawable, gdk_draw_rectangle (drawable, bg_gc, TRUE, x + (x_off + logical_rect.x) / PANGO_SCALE, - y + overall_rect.y / PANGO_SCALE, + risen_y + overall_rect.y / PANGO_SCALE, logical_rect.width / PANGO_SCALE, overall_rect.height / PANGO_SCALE); @@ -209,7 +219,9 @@ gdk_draw_layout_line (GdkDrawable *drawable, if (!shape_set) gdk_draw_glyphs (drawable, fg_gc, run->item->analysis.font, - x + x_off / PANGO_SCALE, y, run->glyphs); + x + x_off / PANGO_SCALE, + risen_y, + run->glyphs); switch (uline) { @@ -217,18 +229,22 @@ gdk_draw_layout_line (GdkDrawable *drawable, break; case PANGO_UNDERLINE_DOUBLE: gdk_draw_line (drawable, fg_gc, - x + (x_off + ink_rect.x) / PANGO_SCALE - 1, y + 4, + x + (x_off + ink_rect.x) / PANGO_SCALE - 1, + risen_y + 4, x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, y + 4); /* Fall through */ case PANGO_UNDERLINE_SINGLE: gdk_draw_line (drawable, fg_gc, - x + (x_off + ink_rect.x) / PANGO_SCALE - 1, y + 2, + x + (x_off + ink_rect.x) / PANGO_SCALE - 1, + risen_y + 2, x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, y + 2); break; case PANGO_UNDERLINE_LOW: gdk_draw_line (drawable, fg_gc, - x + (x_off + ink_rect.x) / PANGO_SCALE - 1, y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 2, - x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 2); + x + (x_off + ink_rect.x) / PANGO_SCALE - 1, + risen_y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 2, + x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, + risen_y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 2); break; } @@ -328,6 +344,7 @@ gdk_draw_layout (GdkDrawable *drawable, static void gdk_pango_get_item_properties (PangoItem *item, PangoUnderline *uline, + gint *rise, PangoAttrColor *fg_color, gboolean *fg_set, PangoAttrColor *bg_color, @@ -346,6 +363,9 @@ gdk_pango_get_item_properties (PangoItem *item, if (shape_set) *shape_set = FALSE; + + if (rise) + *rise = 0; while (tmp_list) { @@ -382,7 +402,12 @@ gdk_pango_get_item_properties (PangoItem *item, if (ink_rect) *ink_rect = ((PangoAttrShape *)attr)->ink_rect; break; - + + case PANGO_ATTR_RISE: + if (rise) + *rise = ((PangoAttrInt *)attr)->value; + break; + default: break; } diff --git a/gdk/gdkpixbuf-drawable.c b/gdk/gdkpixbuf-drawable.c index 07175a638..776ebe606 100644 --- a/gdk/gdkpixbuf-drawable.c +++ b/gdk/gdkpixbuf-drawable.c @@ -1195,14 +1195,12 @@ gdk_pixbuf_get_from_drawable (GdkPixbuf *dest, int src_width, src_height; GdkImage *image; int rowstride, bpp, alpha; - + /* General sanity checks */ g_return_val_if_fail (src != NULL, NULL); - if (GDK_IS_PIXMAP (src)) - g_return_val_if_fail (cmap != NULL, NULL); - else + if (GDK_IS_WINDOW (src)) /* FIXME: this is not perfect, since is_viewable() only tests * recursively up the Gdk parent window tree, but stops at * foreign windows or Gdk toplevels. I.e. if a window manager @@ -1219,6 +1217,17 @@ gdk_pixbuf_get_from_drawable (GdkPixbuf *dest, g_return_val_if_fail (dest->bits_per_sample == 8, NULL); } + if (cmap == NULL) + cmap = gdk_drawable_get_colormap (src); + + if (cmap == NULL) + { + g_warning ("%s: Source drawable has no colormap; either pass " + "in a colormap, or set the colormap on the drawable " + "with gdk_drawable_set_colormap()", G_STRLOC); + return NULL; + } + /* Coordinate sanity checks */ gdk_drawable_get_size (src, &src_width, &src_height); @@ -1233,7 +1242,7 @@ gdk_pixbuf_get_from_drawable (GdkPixbuf *dest, g_return_val_if_fail (dest_y + height <= dest->height, NULL); } - if (!GDK_IS_PIXMAP (src)) + if (GDK_IS_WINDOW (src)) { int ret; int src_xorigin, src_yorigin; @@ -1269,10 +1278,6 @@ gdk_pixbuf_get_from_drawable (GdkPixbuf *dest, } } - /* Get the colormap if needed */ - if (!GDK_IS_PIXMAP (src)) - cmap = gdk_window_get_colormap (src); - alpha = dest->has_alpha; rowstride = dest->rowstride; bpp = alpha ? 4 : 3; diff --git a/gdk/gdkpixbuf-render.c b/gdk/gdkpixbuf-render.c index 5ad39f760..9ef7bb6f6 100644 --- a/gdk/gdkpixbuf-render.c +++ b/gdk/gdkpixbuf-render.c @@ -246,6 +246,11 @@ gdk_pixbuf_render_to_drawable (GdkPixbuf *pixbuf, * the alpha channel of the image. If performance is crucial, consider handling * the alpha channel yourself (possibly by caching it in your application) and * using gdk_pixbuf_render_to_drawable() or GdkRGB directly instead. + * + * The #GDK_PIXBUF_ALPHA_FULL mode involves round trips to the X + * server, and may also be somewhat slow in its current implementation + * (though in the future it could be made significantly faster, in + * principle). **/ void gdk_pixbuf_render_to_drawable_alpha (GdkPixbuf *pixbuf, @@ -260,7 +265,8 @@ gdk_pixbuf_render_to_drawable_alpha (GdkPixbuf *pixbuf, { GdkBitmap *bitmap = NULL; GdkGC *gc; - + GdkPixbuf *composited = NULL; + g_return_if_fail (pixbuf != NULL); g_return_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB); g_return_if_fail (pixbuf->n_channels == 3 || pixbuf->n_channels == 4); @@ -278,31 +284,76 @@ gdk_pixbuf_render_to_drawable_alpha (GdkPixbuf *pixbuf, if (pixbuf->has_alpha) { - /* Right now we only support GDK_PIXBUF_ALPHA_BILEVEL, so we - * unconditionally create the clipping mask. - */ - - bitmap = gdk_pixmap_new (NULL, width, height, 1); - gdk_pixbuf_render_threshold_alpha (pixbuf, bitmap, - src_x, src_y, - 0, 0, - width, height, - alpha_threshold); - - gdk_gc_set_clip_mask (gc, bitmap); - gdk_gc_set_clip_origin (gc, dest_x, dest_y); + if (alpha_mode == GDK_PIXBUF_ALPHA_BILEVEL) + { + bitmap = gdk_pixmap_new (NULL, width, height, 1); + gdk_pixbuf_render_threshold_alpha (pixbuf, bitmap, + src_x, src_y, + 0, 0, + width, height, + alpha_threshold); + + gdk_gc_set_clip_mask (gc, bitmap); + gdk_gc_set_clip_origin (gc, dest_x, dest_y); + } + else if (alpha_mode == GDK_PIXBUF_ALPHA_FULL) + { + GdkPixbuf *sub = NULL; + + composited = gdk_pixbuf_get_from_drawable (NULL, + drawable, + NULL, + dest_x, dest_y, + 0, 0, + width, height); + + if (src_x != 0 || src_y != 0) + { + sub = gdk_pixbuf_new_subpixbuf (pixbuf, src_x, src_y, + width, height); + } + + gdk_pixbuf_composite (sub ? sub : pixbuf, + composited, + 0, 0, + width, height, + 0, 0, + 1.0, 1.0, + GDK_INTERP_BILINEAR, + 255); + + if (sub) + g_object_unref (G_OBJECT (sub)); + } } - gdk_pixbuf_render_to_drawable (pixbuf, drawable, gc, - src_x, src_y, - dest_x, dest_y, - width, height, - dither, - x_dither, y_dither); + if (composited) + { + gdk_pixbuf_render_to_drawable (composited, + drawable, gc, + 0, 0, + dest_x, dest_y, + width, height, + dither, + x_dither, y_dither); + } + else + { + gdk_pixbuf_render_to_drawable (pixbuf, + drawable, gc, + src_x, src_y, + dest_x, dest_y, + width, height, + dither, + x_dither, y_dither); + } if (bitmap) gdk_bitmap_unref (bitmap); + if (composited) + g_object_unref (G_OBJECT (composited)); + gdk_gc_unref (gc); } diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c index a4de696dd..8ac1d34ef 100644 --- a/gtk/gtkimage.c +++ b/gtk/gtkimage.c @@ -520,9 +520,8 @@ gtk_image_expose (GtkWidget *widget, image->data.stock.stock_id, image->data.stock.size, NULL); - if (stock_pixbuf) - { + { image_bound.width = gdk_pixbuf_get_width (stock_pixbuf); image_bound.height = gdk_pixbuf_get_height (stock_pixbuf); } @@ -583,8 +582,10 @@ gtk_image_expose (GtkWidget *widget, case GTK_IMAGE_PIXBUF: gdk_pixbuf_render_to_drawable_alpha (image->data.pixbuf.pixbuf, widget->window, - image_bound.x - x, image_bound.y - y, - image_bound.x, image_bound.y, + image_bound.x - x, + image_bound.y - y, + image_bound.x, + image_bound.y, image_bound.width, image_bound.height, GDK_PIXBUF_ALPHA_FULL, 128, @@ -598,8 +599,10 @@ gtk_image_expose (GtkWidget *widget, { gdk_pixbuf_render_to_drawable_alpha (stock_pixbuf, widget->window, - image_bound.x - x, image_bound.y - y, - image_bound.x, image_bound.y, + image_bound.x - x, + image_bound.y - y, + image_bound.x - 4, + image_bound.y - 4, image_bound.width, image_bound.height, GDK_PIXBUF_ALPHA_FULL, 128, diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index e7fcde574..9030d9a60 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -180,8 +180,9 @@ gtk_label_init (GtkLabel *label) label->jtype = GTK_JUSTIFY_CENTER; label->wrap = FALSE; - + label->layout = NULL; + label->attrs = NULL; gtk_label_set_text (label, ""); } @@ -204,10 +205,13 @@ gtk_label_set_text_internal (GtkLabel *label, gchar *str) { g_free (label->label); - + label->label = str; if (label->layout) - pango_layout_set_text (label->layout, str, -1); + { + g_object_unref (G_OBJECT (label->layout)); + label->layout = NULL; + } gtk_widget_queue_resize (GTK_WIDGET (label)); } @@ -217,10 +221,113 @@ gtk_label_set_text (GtkLabel *label, const gchar *str) { g_return_if_fail (GTK_IS_LABEL (label)); - + gtk_label_set_text_internal (label, g_strdup (str ? str : "")); } +/** + * gtk_label_set_attributes: + * @label: a #GtkLabel + * @attrs: a #PangoAttrList + * + * Sets a #PangoAttrList; the attributes in the list are applied to the + * label text. + **/ +void +gtk_label_set_attributes (GtkLabel *label, + PangoAttrList *attrs) +{ + g_return_if_fail (GTK_IS_LABEL (label)); + + if (attrs) + pango_attr_list_ref (attrs); + + if (label->attrs) + pango_attr_list_unref (label->attrs); + + label->attrs = attrs; +} + +static guint +set_markup (GtkLabel *label, + const gchar *str, + gboolean with_uline) +{ + gchar *text = NULL; + GError *error = NULL; + PangoAttrList *attrs = NULL; + gunichar accel_char = 0; + + if (str == NULL) + str = ""; + + if (!pango_parse_markup (str, + -1, + with_uline ? '_' : 0, + &attrs, + &text, + with_uline ? &accel_char : NULL, + &error)) + { + g_warning ("Failed to set label from markup due to error parsing markup: %s", + error->message); + g_error_free (error); + return 0; + } + + if (text) + gtk_label_set_text (label, text); + + if (attrs) + { + gtk_label_set_attributes (label, attrs); + pango_attr_list_unref (attrs); + } + + if (accel_char != 0) + return gdk_keyval_to_lower (accel_char); + else + return GDK_VoidSymbol; +} + +/** + * gtk_label_set_markup: + * @label: a #GtkLabel + * @str: a markup string (see Pango markup format) + * + * Parses @str which is marked up with the Pango text markup language, + * setting the label's text and attribute list based on the parse results. + **/ +void +gtk_label_set_markup (GtkLabel *label, + const gchar *str) +{ + g_return_if_fail (GTK_IS_LABEL (label)); + + set_markup (label, str, FALSE); +} + +/** + * gtk_label_set_markup: + * @label: a #GtkLabel + * @str: a markup string (see Pango markup format) + * + * Parses @str which is marked up with the Pango text markup language, + * setting the label's text and attribute list based on the parse results. + * If characters in @str are preceded by an underscore, they are underlined + * indicating that they represent a keyboard accelerator, and the GDK + * keyval for the first underlined accelerator is returned. If there are + * no underlines in the text, GDK_VoidSymbol will be returned. + **/ +guint +gtk_label_set_markup_with_accel (GtkLabel *label, + const gchar *str) +{ + g_return_if_fail (GTK_IS_LABEL (label)); + + return set_markup (label, str, TRUE); +} + /** * gtk_label_get_text: * @label: a #GtkLabel @@ -315,14 +422,16 @@ gtk_label_finalize (GObject *object) if (label->layout) g_object_unref (G_OBJECT (label->layout)); + if (label->attrs) + pango_attr_list_unref (label->attrs); + G_OBJECT_CLASS (parent_class)->finalize (object); } -static PangoAttrList * -gtk_label_pattern_to_attrs (GtkLabel *label) +static void +gtk_label_pattern_to_attrs (GtkLabel *label, + PangoAttrList *attrs) { - PangoAttrList *attrs = pango_attr_list_new (); - if (label->pattern) { const char *start; @@ -355,8 +464,6 @@ gtk_label_pattern_to_attrs (GtkLabel *label) break; } } - - return attrs; } static void @@ -398,13 +505,24 @@ gtk_label_size_request (GtkWidget *widget, if (!label->layout) { PangoAlignment align = PANGO_ALIGN_LEFT; /* Quiet gcc */ - PangoAttrList *attrs = gtk_label_pattern_to_attrs (label); + PangoAttrList *attrs = NULL; label->layout = gtk_widget_create_pango_layout (widget, label->label); - pango_layout_set_attributes (label->layout, attrs); + /* FIXME move to a model where the pattern isn't stored + * permanently, and just modifes or creates the AttrList + */ + if (label->attrs) + { + attrs = pango_attr_list_copy (label->attrs); + pango_layout_set_attributes (label->layout, attrs); + } + else + attrs = pango_attr_list_new (); + + gtk_label_pattern_to_attrs (label, attrs); pango_attr_list_unref (attrs); - + switch (label->jtype) { case GTK_JUSTIFY_LEFT: diff --git a/gtk/gtklabel.h b/gtk/gtklabel.h index b71ccae41..b0524af66 100644 --- a/gtk/gtklabel.h +++ b/gtk/gtklabel.h @@ -57,10 +57,11 @@ struct _GtkLabel gchar *pattern; guint jtype : 2; - gboolean wrap : 1; - + guint wrap : 1; + /*< private >*/ PangoLayout *layout; + PangoAttrList *attrs; }; struct _GtkLabelClass @@ -68,10 +69,19 @@ struct _GtkLabelClass GtkMiscClass parent_class; }; -GtkType gtk_label_get_type (void) G_GNUC_CONST; -GtkWidget *gtk_label_new (const char *str); -void gtk_label_set_text (GtkLabel *label, - const char *str); +GtkType gtk_label_get_type (void) G_GNUC_CONST; +GtkWidget *gtk_label_new (const char *str); +void gtk_label_set_text (GtkLabel *label, + const char *str); +void gtk_label_set_attributes (GtkLabel *label, + PangoAttrList *attrs); + +void gtk_label_set_markup (GtkLabel *label, + const gchar *str); +guint gtk_label_set_markup_with_accel (GtkLabel *label, + const gchar *str); + + /* Temporarily commented out until memory management behavior is figured out *//* gchar * gtk_label_get_text (GtkLabel *label); */ void gtk_label_set_justify (GtkLabel *label, GtkJustification jtype); diff --git a/gtk/gtktextbuffer.c b/gtk/gtktextbuffer.c index 54414acc1..085335be5 100644 --- a/gtk/gtktextbuffer.c +++ b/gtk/gtktextbuffer.c @@ -388,6 +388,7 @@ gtk_text_buffer_set_text (GtkTextBuffer *buffer, */ static void + gtk_text_buffer_real_insert_text (GtkTextBuffer *buffer, GtkTextIter *iter, const gchar *text, @@ -556,11 +557,11 @@ gtk_text_buffer_insert_interactive_at_cursor (GtkTextBuffer *buffer, * Copies text, tags, and pixbufs between @start and @end (the order * of @start and @end doesn't matter) and inserts the copy at @iter. * Used instead of simply getting/inserting text because it preserves - * images and tags. If @start and @end are in a different buffer - * from @buffer, the two buffers must share the same tag table. + * images and tags. If @start and @end are in a different buffer from + * @buffer, the two buffers must share the same tag table. * - * Implemented via multiple emissions of the insert_text and - * apply_tag signals, so expect those. + * Implemented via emissions of the insert_text and apply_tag signals, + * so expect those. **/ void gtk_text_buffer_insert_range (GtkTextBuffer *buffer, diff --git a/gtk/testgtk.c b/gtk/testgtk.c index 9a256b570..6f8542535 100644 --- a/gtk/testgtk.c +++ b/gtk/testgtk.c @@ -1902,7 +1902,9 @@ create_get_image (void) { static GtkWidget *window = NULL; - if (!window) + if (window) + gtk_widget_destroy (window); + else { GtkWidget *sw; GtkWidget *src; @@ -2085,6 +2087,28 @@ void create_labels (void) gtk_label_set_pattern (GTK_LABEL (label), "_________________________ _ _________ _ _____ _ __ __ ___ ____ _____"); gtk_container_add (GTK_CONTAINER (frame), label); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + + frame = gtk_frame_new ("Markup label"); + label = gtk_label_new (NULL); + + gtk_label_set_markup (GTK_LABEL (label), + "This label has " + "markup such as " + "Big Italics\n" + "Monospace font\n" + "Underline!\n" + "foo\n" + "Ugly colors\n" + "and nothing on this line,\n" + "or this.\n" + "or this either\n" + "or even on this one\n" + "la la la la la\n" + "but this word is purple\n" + "We like superscript and subscript too"); + gtk_container_add (GTK_CONTAINER (frame), label); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + } if (!GTK_WIDGET_VISIBLE (window)) gtk_widget_show_all (window); @@ -3031,8 +3055,7 @@ make_message_dialog (GtkWidget **dialog, { if (*dialog) { - if (GTK_WIDGET_REALIZED (*dialog)) - gdk_window_show ((*dialog)->window); + gtk_widget_destroy (*dialog); return; } diff --git a/tests/testgtk.c b/tests/testgtk.c index 9a256b570..6f8542535 100644 --- a/tests/testgtk.c +++ b/tests/testgtk.c @@ -1902,7 +1902,9 @@ create_get_image (void) { static GtkWidget *window = NULL; - if (!window) + if (window) + gtk_widget_destroy (window); + else { GtkWidget *sw; GtkWidget *src; @@ -2085,6 +2087,28 @@ void create_labels (void) gtk_label_set_pattern (GTK_LABEL (label), "_________________________ _ _________ _ _____ _ __ __ ___ ____ _____"); gtk_container_add (GTK_CONTAINER (frame), label); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + + frame = gtk_frame_new ("Markup label"); + label = gtk_label_new (NULL); + + gtk_label_set_markup (GTK_LABEL (label), + "This label has " + "markup such as " + "Big Italics\n" + "Monospace font\n" + "Underline!\n" + "foo\n" + "Ugly colors\n" + "and nothing on this line,\n" + "or this.\n" + "or this either\n" + "or even on this one\n" + "la la la la la\n" + "but this word is purple\n" + "We like superscript and subscript too"); + gtk_container_add (GTK_CONTAINER (frame), label); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + } if (!GTK_WIDGET_VISIBLE (window)) gtk_widget_show_all (window); @@ -3031,8 +3055,7 @@ make_message_dialog (GtkWidget **dialog, { if (*dialog) { - if (GTK_WIDGET_REALIZED (*dialog)) - gdk_window_show ((*dialog)->window); + gtk_widget_destroy (*dialog); return; }