From 41818acb40207cb4ef9e8d44d5219cb7c0c7e2db Mon Sep 17 00:00:00 2001 From: Mathias Hasselmann Date: Wed, 18 Jul 2007 12:57:17 +0000 Subject: [PATCH] Extend the test to support rotations. Support ellipsizing and wrapping on MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2007-07-16 Mathias Hasselmann * tests/testellipsise.c: Extend the test to support rotations. * gtk/gtklabel.c: Support ellipsizing and wrapping on labels rotated by multiples of 90°. svn path=/branches/extended-layout/; revision=18493 --- ChangeLog.gtk-extended-layout | 6 ++ gtk/gtklabel.c | 113 +++++++++++++++++++++------------- tests/testellipsise.c | 28 +++++++-- 3 files changed, 97 insertions(+), 50 deletions(-) diff --git a/ChangeLog.gtk-extended-layout b/ChangeLog.gtk-extended-layout index 4bc802cd4e..d87cd3c1cc 100644 --- a/ChangeLog.gtk-extended-layout +++ b/ChangeLog.gtk-extended-layout @@ -1,3 +1,9 @@ +2007-07-16 Mathias Hasselmann + + * tests/testellipsise.c: Extend the test to support rotations. + * gtk/gtklabel.c: Support ellipsizing and wrapping on labels + rotated by multiples of 90°. + 2007-07-16 Mathias Hasselmann * gtk/gtkvbox.c, tests/testextendedlayout.c: diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index 10c790a970..b7e512bbe2 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -25,6 +25,7 @@ #include #include +#include #include #include "gtklabel.h" #include "gtkaccellabel.h" @@ -2000,14 +2001,14 @@ gtk_label_ensure_layout (GtkLabel *label) PangoAlignment align = PANGO_ALIGN_LEFT; /* Quiet gcc */ gdouble angle = gtk_label_get_angle (label); - if (angle != 0.0 && !label->wrap && !label->ellipsize && !label->select_info) + if (angle != 0.0 && !label->select_info) { + PangoMatrix matrix = PANGO_MATRIX_INIT; + /* We rotate the standard singleton PangoContext for the widget, * depending on the fact that it's meant pretty much exclusively * for our use. */ - PangoMatrix matrix = PANGO_MATRIX_INIT; - pango_matrix_rotate (&matrix, angle); pango_context_set_matrix (gtk_widget_get_pango_context (widget), &matrix); @@ -2051,8 +2052,8 @@ gtk_label_ensure_layout (GtkLabel *label) pango_layout_set_single_paragraph_mode (label->layout, label->single_line_mode); if (label->ellipsize) - pango_layout_set_width (label->layout, - widget->allocation.width * PANGO_SCALE); + pango_layout_set_width (label->layout, + widget->allocation.width * PANGO_SCALE); else if (label->wrap) { GtkWidgetAuxInfo *aux_info; @@ -2133,8 +2134,8 @@ gtk_label_size_request (GtkWidget *widget, { GtkLabel *label; GtkLabelPrivate *priv; - gint width, height; PangoRectangle logical_rect; + PangoRectangle required_rect; GtkWidgetAuxInfo *aux_info; g_return_if_fail (GTK_IS_LABEL (widget)); @@ -2161,39 +2162,21 @@ gtk_label_size_request (GtkWidget *widget, gtk_label_ensure_layout (label); - width = label->misc.xpad * 2; - height = label->misc.ypad * 2; - aux_info = _gtk_widget_get_aux_info (widget, FALSE); - if (label->have_transform) - { - PangoRectangle rect; - PangoContext *context = pango_layout_get_context (label->layout); - const PangoMatrix *matrix = pango_context_get_matrix (context); - - pango_layout_get_extents (label->layout, NULL, &rect); - pango_matrix_transform_rectangle (matrix, &rect); - pango_extents_to_pixels (&rect, NULL); - - requisition->width = width + rect.width; - requisition->height = height + rect.height; - - return; - } - else - pango_layout_get_extents (label->layout, NULL, &logical_rect); + pango_layout_get_extents (label->layout, NULL, &logical_rect); + required_rect.x = required_rect.y = 0; if ((label->wrap || label->ellipsize || priv->width_chars > 0 || priv->max_width_chars > 0) && aux_info && aux_info->width > 0) - width += aux_info->width; + required_rect.width = aux_info->width; else if (label->ellipsize || priv->width_chars > 0 || priv->max_width_chars > 0) { - width += PANGO_PIXELS (get_label_char_width (label)); + required_rect.width = PANGO_PIXELS (get_label_char_width (label)); } else - width += PANGO_PIXELS (logical_rect.width); + required_rect.width = PANGO_PIXELS (logical_rect.width); if (label->single_line_mode) { @@ -2209,13 +2192,26 @@ gtk_label_size_request (GtkWidget *widget, descent = pango_font_metrics_get_descent (metrics); pango_font_metrics_unref (metrics); - height += PANGO_PIXELS (ascent + descent); + required_rect.height = PANGO_PIXELS (ascent + descent); } else - height += PANGO_PIXELS (logical_rect.height); + required_rect.height = PANGO_PIXELS (logical_rect.height); - requisition->width = width; - requisition->height = height; + if (label->have_transform) + { + PangoContext *context = pango_layout_get_context (label->layout); + const PangoMatrix *matrix = pango_context_get_matrix (context); + PangoRectangle rect; + + pango_layout_get_extents (label->layout, NULL, &rect); + pango_matrix_transform_rectangle (matrix, &rect); + pango_extents_to_pixels (&rect, NULL); + + pango_matrix_transform_pixel_rectangle (matrix, &required_rect); + } + + requisition->width = required_rect.width + label->misc.xpad * 2; + requisition->height = required_rect.height + label->misc.ypad * 2; } static void @@ -2232,16 +2228,25 @@ gtk_label_size_allocate (GtkWidget *widget, { if (label->layout) { - gint width; PangoRectangle logical; + PangoRectangle bounds; - width = (allocation->width - label->misc.xpad * 2) * PANGO_SCALE; + bounds.x = bounds.y = 0; + bounds.width = allocation->width - label->misc.xpad * 2; + bounds.height = allocation->height - label->misc.ypad * 2; pango_layout_set_width (label->layout, -1); pango_layout_get_extents (label->layout, NULL, &logical); - if (logical.width > width) - pango_layout_set_width (label->layout, width); + if (label->have_transform) + { + PangoContext *context = gtk_widget_get_pango_context (widget); + const PangoMatrix *matrix = pango_context_get_matrix (context); + pango_matrix_transform_pixel_rectangle (matrix, &bounds); + } + + if (logical.width > bounds.width) + pango_layout_set_width (label->layout, bounds.width * PANGO_SCALE); } } @@ -2322,8 +2327,9 @@ get_layout_location (GtkLabel *label, GtkWidget *widget; GtkLabelPrivate *priv; gfloat xalign; - gint req_width, x, y; - gfloat dy; + gint req_width; + gint req_height; + gint x, y; misc = GTK_MISC (label); widget = GTK_WIDGET (label); @@ -2340,26 +2346,43 @@ get_layout_location (GtkLabel *label, PangoRectangle logical; width = pango_layout_get_width (label->layout); - pango_layout_get_pixel_extents (label->layout, NULL, &logical); + pango_layout_get_extents (label->layout, NULL, &logical); + + if (label->have_transform) + { + PangoContext *context = gtk_widget_get_pango_context (widget); + const PangoMatrix *matrix = pango_context_get_matrix (context); + pango_matrix_transform_rectangle (matrix, &logical); + } + + pango_extents_to_pixels (&logical, NULL); req_width = logical.width; + req_height = logical.height; + if (width != -1) req_width = MIN(PANGO_PIXELS (width), req_width); + req_width += 2 * misc->xpad; + req_height += 2 * misc->ypad; } else - req_width = widget->requisition.width; + { + req_width = widget->requisition.width; + req_height = widget->requisition.height; + } x = floor (widget->allocation.x + (gint)misc->xpad + - xalign * (widget->allocation.width - req_width)); + xalign * (widget->allocation.width - req_width)); if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) x = MAX (x, widget->allocation.x + misc->xpad); else x = MIN (x, widget->allocation.x + widget->allocation.width - misc->xpad); - dy = (widget->allocation.height - widget->requisition.height) * misc->yalign; - y = floor (widget->allocation.y + (gint)misc->ypad + priv->baseline_offset + MAX (dy, 0)); + y = floor (widget->allocation.y + (gint)misc->ypad + + misc->yalign * (widget->allocation.height - req_height) + + priv->baseline_offset); if (xp) *xp = x; @@ -4279,6 +4302,8 @@ gtk_label_extended_layout_get_natural_size (GtkExtendedLayout *layout, PangoLayout *tmp; label = GTK_LABEL (layout); + gtk_label_ensure_layout (label); + ellipsize = label->ellipsize; label->ellipsize = PANGO_ELLIPSIZE_NONE; diff --git a/tests/testellipsise.c b/tests/testellipsise.c index 0783d619da..591cbdb432 100644 --- a/tests/testellipsise.c +++ b/tests/testellipsise.c @@ -37,30 +37,46 @@ combo_changed_cb (GtkWidget *combo, gtk_label_set_ellipsize (GTK_LABEL (label), (PangoEllipsizeMode)active); } +static void +scale_changed_cb (GtkRange *range, + gpointer data) +{ + GtkWidget *label = GTK_WIDGET (data); + double angle = gtk_range_get_value (range); + + gtk_label_set_angle (GTK_LABEL (label), angle); +} + int main (int argc, char *argv[]) { - GtkWidget *window, *vbox, *hbox, *label, *combo; + GtkWidget *window, *vbox, *label, *combo, *scale; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_container_set_border_width (GTK_CONTAINER (window), 12); g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); - vbox = gtk_vbox_new (0, FALSE); + + vbox = gtk_vbox_new (FALSE, 6); gtk_container_add (GTK_CONTAINER (window), vbox); - hbox = gtk_hbox_new (0, FALSE); - gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); + label = gtk_label_new ("This label may be ellipsized\nto make it fit."); - gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); + gtk_box_pack_end (GTK_BOX (vbox), label, TRUE, TRUE, 0); + combo = gtk_combo_box_new_text (); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "NONE"); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "START"); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "MIDDLE"); gtk_combo_box_append_text (GTK_COMBO_BOX (combo), "END"); gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); - gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, TRUE, 0); g_signal_connect (combo, "changed", G_CALLBACK (combo_changed_cb), label); + scale = gtk_hscale_new_with_range (0, 360, 1); + g_signal_connect (scale, "value-changed", G_CALLBACK (scale_changed_cb), label); + gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, TRUE, 0); + gtk_widget_show_all (window); gtk_main ();