[gtk+/wip/baseline: 3/7] GtkLabel: Support baseline
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/baseline: 3/7] GtkLabel: Support baseline
- Date: Thu, 7 Mar 2013 19:25:31 +0000 (UTC)
commit 2954b45f54afa02473009849c5b71be942b55d7e
Author: Alexander Larsson <alexl redhat com>
Date: Tue Mar 5 15:14:17 2013 +0100
GtkLabel: Support baseline
Report the baseline in get_preferred_height_and_baseline_for_width().
gtk/gtklabel.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 91 insertions(+), 17 deletions(-)
---
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index bc17554..6b7e73e 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -519,6 +519,12 @@ static void gtk_label_get_preferred_height_for_width (GtkWidget
gint width,
gint *minimum_height,
gint *natural_height);
+static void gtk_label_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height,
+ gint *minimum_baseline,
+ gint *natural_baseline);
static GtkBuildableIface *buildable_parent_iface = NULL;
@@ -585,6 +591,7 @@ gtk_label_class_init (GtkLabelClass *class)
widget_class->get_preferred_height = gtk_label_get_preferred_height;
widget_class->get_preferred_width_for_height = gtk_label_get_preferred_width_for_height;
widget_class->get_preferred_height_for_width = gtk_label_get_preferred_height_for_width;
+ widget_class->get_preferred_height_and_baseline_for_width =
gtk_label_get_preferred_height_and_baseline_for_width;
class->move_cursor = gtk_label_move_cursor;
class->copy_clipboard = gtk_label_copy_clipboard;
@@ -3434,15 +3441,18 @@ gtk_label_get_request_mode (GtkWidget *widget)
return GTK_SIZE_REQUEST_CONSTANT_SIZE;
}
+
static void
get_size_for_allocation (GtkLabel *label,
GtkOrientation orientation,
gint allocation,
gint *minimum_size,
- gint *natural_size)
+ gint *natural_size,
+ gint *minimum_baseline,
+ gint *natural_baseline)
{
PangoLayout *layout;
- gint text_height;
+ gint text_height, baseline;
layout = gtk_label_get_measuring_layout (label, NULL, allocation * PANGO_SCALE);
@@ -3454,6 +3464,16 @@ get_size_for_allocation (GtkLabel *label,
if (natural_size)
*natural_size = text_height;
+ if (minimum_baseline || natural_baseline)
+ {
+ baseline = pango_layout_get_baseline (layout) / PANGO_SCALE;
+ if (minimum_baseline)
+ *minimum_baseline = baseline;
+
+ if (natural_baseline)
+ *natural_baseline = baseline;
+ }
+
g_object_unref (layout);
}
@@ -3550,7 +3570,9 @@ static void
gtk_label_get_preferred_size (GtkWidget *widget,
GtkOrientation orientation,
gint *minimum_size,
- gint *natural_size)
+ gint *natural_size,
+ gint *minimum_baseline,
+ gint *natural_baseline)
{
GtkLabel *label = GTK_LABEL (widget);
GtkLabelPrivate *priv = label->priv;
@@ -3558,6 +3580,12 @@ gtk_label_get_preferred_size (GtkWidget *widget,
PangoRectangle smallest_rect;
GtkBorder border;
+ if (minimum_baseline)
+ *minimum_baseline = -1;
+
+ if (natural_baseline)
+ *natural_baseline = -1;
+
gtk_label_get_preferred_layout_size (label, &smallest_rect, &widest_rect);
/* Now that we have minimum and natural sizes in pango extents, apply a possible transform */
@@ -3612,7 +3640,8 @@ gtk_label_get_preferred_size (GtkWidget *widget,
get_size_for_allocation (label,
GTK_ORIENTATION_VERTICAL,
smallest_rect.height,
- minimum_size, natural_size);
+ minimum_size, natural_size,
+ NULL, NULL);
}
else
@@ -3639,7 +3668,16 @@ gtk_label_get_preferred_size (GtkWidget *widget,
get_size_for_allocation (label,
GTK_ORIENTATION_HORIZONTAL,
widest_rect.width,
- minimum_size, natural_size);
+ minimum_size, natural_size,
+ minimum_baseline, natural_baseline);
+
+ if (priv->angle == 180)
+ {
+ if (minimum_baseline)
+ *minimum_baseline = *minimum_size - *minimum_baseline;
+ if (natural_baseline)
+ *natural_baseline = *natural_size - *natural_baseline;
+ }
}
else
{
@@ -3652,6 +3690,12 @@ gtk_label_get_preferred_size (GtkWidget *widget,
*minimum_size += border.top + border.bottom;
*natural_size += border.top + border.bottom;
+
+ if (minimum_baseline && *minimum_baseline != -1)
+ *minimum_baseline += border.top;
+
+ if (natural_baseline && *natural_baseline != -1)
+ *natural_baseline += border.top;
}
}
@@ -3660,7 +3704,7 @@ gtk_label_get_preferred_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
- gtk_label_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size);
+ gtk_label_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size, NULL, NULL);
}
static void
@@ -3668,7 +3712,7 @@ gtk_label_get_preferred_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
- gtk_label_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size);
+ gtk_label_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size, NULL, NULL);
}
static void
@@ -3691,7 +3735,8 @@ gtk_label_get_preferred_width_for_height (GtkWidget *widget,
get_size_for_allocation (label, GTK_ORIENTATION_VERTICAL,
MAX (1, height - border.top - border.bottom),
- minimum_width, natural_width);
+ minimum_width, natural_width,
+ NULL, NULL);
if (minimum_width)
*minimum_width += border.right + border.left;
@@ -3704,15 +3749,17 @@ gtk_label_get_preferred_width_for_height (GtkWidget *widget,
}
static void
-gtk_label_get_preferred_height_for_width (GtkWidget *widget,
- gint width,
- gint *minimum_height,
- gint *natural_height)
+gtk_label_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height,
+ gint *minimum_baseline,
+ gint *natural_baseline)
{
GtkLabel *label = GTK_LABEL (widget);
GtkLabelPrivate *priv = label->priv;
- if (priv->wrap && (priv->angle == 0 || priv->angle == 180 || priv->angle == 360))
+ if (width != -1 && priv->wrap && (priv->angle == 0 || priv->angle == 180 || priv->angle == 360))
{
GtkBorder border;
@@ -3723,7 +3770,13 @@ gtk_label_get_preferred_height_for_width (GtkWidget *widget,
get_size_for_allocation (label, GTK_ORIENTATION_HORIZONTAL,
MAX (1, width - border.left - border.right),
- minimum_height, natural_height);
+ minimum_height, natural_height,
+ minimum_baseline, natural_baseline);
+
+ if (minimum_baseline && *minimum_baseline >= 0)
+ *minimum_baseline += border.top;
+ if (natural_baseline && *natural_baseline >= 0)
+ *natural_baseline += border.top;
if (minimum_height)
*minimum_height += border.top + border.bottom;
@@ -3732,7 +3785,18 @@ gtk_label_get_preferred_height_for_width (GtkWidget *widget,
*natural_height += border.top + border.bottom;
}
else
- GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, minimum_height, natural_height);
+ gtk_label_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimum_height, natural_height,
minimum_baseline, natural_baseline);
+}
+
+static void
+gtk_label_get_preferred_height_for_width (GtkWidget *widget,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ return gtk_label_get_preferred_height_and_baseline_for_width (widget, width,
+ minimum_height, natural_height,
+ NULL, NULL);
}
static void
@@ -3827,6 +3891,7 @@ get_layout_location (GtkLabel *label,
gint req_height;
gfloat xalign, yalign;
PangoRectangle logical;
+ gint baseline, layout_baseline, baseline_offset;
misc = GTK_MISC (label);
widget = GTK_WIDGET (label);
@@ -3859,6 +3924,15 @@ get_layout_location (GtkLabel *label,
x = floor (allocation.x + border.left + xalign * (allocation.width - req_width) - logical.x);
+ baseline_offset = 0;
+ baseline = gtk_widget_get_allocated_baseline (widget);
+ if (baseline >= 0 && !priv->have_transform)
+ {
+ layout_baseline = pango_layout_get_baseline (priv->layout) / PANGO_SCALE;
+ baseline_offset = baseline - layout_baseline;
+ yalign = 0.0; /* Can't support yalign while baseline aligning */
+ }
+
/* bgo#315462 - For single-line labels, *do* align the requisition with
* respect to the allocation, even if we are under-allocated. For multi-line
* labels, always show the top of the text when they are under-allocated. The
@@ -3873,9 +3947,9 @@ get_layout_location (GtkLabel *label,
* middle". You want to read the first line, at least, to get some context.
*/
if (pango_layout_get_line_count (priv->layout) == 1)
- y = floor (allocation.y + border.top + (allocation.height - req_height) * yalign) - logical.y;
+ y = floor (allocation.y + border.top + (allocation.height - req_height) * yalign) - logical.y +
baseline_offset;
else
- y = floor (allocation.y + border.top + MAX ((allocation.height - req_height) * yalign, 0)) - logical.y;
+ y = floor (allocation.y + border.top + MAX ((allocation.height - req_height) * yalign, 0)) - logical.y +
baseline_offset;
if (xp)
*xp = x;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]