aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--widgets/table/e-table-header-utils.c136
1 files changed, 46 insertions, 90 deletions
diff --git a/widgets/table/e-table-header-utils.c b/widgets/table/e-table-header-utils.c
index 20c1529a23..dc407a80d4 100644
--- a/widgets/table/e-table-header-utils.c
+++ b/widgets/table/e-table-header-utils.c
@@ -77,7 +77,6 @@ e_table_header_compute_height (ETableCol *ecol, GtkWidget *widget)
int ythick;
int height;
PangoLayout *layout;
- PangoRectangle ink_rect;
g_return_val_if_fail (ecol != NULL, -1);
g_return_val_if_fail (E_IS_TABLE_COL (ecol), -1);
@@ -87,9 +86,7 @@ e_table_header_compute_height (ETableCol *ecol, GtkWidget *widget)
layout = build_header_layout (widget, ecol->text);
- pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
-
- height = PANGO_DESCENT (ink_rect) - PANGO_ASCENT (ink_rect);
+ pango_layout_get_pixel_size (layout, NULL, &height);
if (ecol->is_pixbuf) {
g_assert (ecol->pixbuf != NULL);
@@ -224,51 +221,6 @@ make_composite_pixmap (GdkDrawable *drawable, GdkGC *gc,
return pixmap;
}
-
-/* Computes the length of a string that needs to be trimmed for elision */
-static int
-compute_elision_length (GtkWidget *widget, const char *str, int max_width)
-{
- int len;
- int l = 0, left, right;
- PangoLayout *layout = build_header_layout (widget, str);
- PangoRectangle ink_rect;
-
- len = strlen (str);
-
- if (len <= 0)
- return 0;
-
- left = 0;
- right = len;
-
- while (left < right) {
- l = (left + right) / 2;
-
- pango_layout_set_text (layout, str, l);
-
- pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
-
- if (PANGO_RBEARING (ink_rect) < max_width)
- left = l + 1;
- else if (PANGO_RBEARING (ink_rect) > max_width)
- right = l;
- else {
- g_object_unref (layout);
- return l;
- }
- }
-
- g_object_unref (layout);
-
- if (PANGO_RBEARING (ink_rect) > max_width)
- return MAX (0, l - 1);
- else
- return l;
-
- return l;
-}
-
/* Default width of the elision arrow in pixels */
#define ARROW_WIDTH 4
@@ -279,7 +231,8 @@ compute_elision_length (GtkWidget *widget, const char *str, int max_width)
* @gc: GC to use for drawing.
* @x: X insertion point for the string.
* @y: Y insertion point for the string's baseline.
- * @str: String to draw.
+ * @layout: the PangoLayout to draw.
+ * @str: the string we're drawing, passed in so we can change the layout if it needs eliding.
* @max_width: Maximum width in which the string must fit.
* @center: Whether to center the string in the available area if it does fit.
*
@@ -289,25 +242,29 @@ compute_elision_length (GtkWidget *widget, const char *str, int max_width)
**/
static void
e_table_draw_elided_string (GdkDrawable *drawable, GdkGC *gc, GtkWidget *widget,
- int x, int y, const char *str, int max_width, gboolean center)
+ int x, int y, PangoLayout *layout, char *str,
+ int max_width, gboolean center)
{
- PangoLayout *layout;
- PangoRectangle ink_rect;
+ int width;
+ int height;
+ int index;
+ GSList *lines;
+ PangoLayoutLine *line;
g_return_if_fail (drawable != NULL);
g_return_if_fail (gc != NULL);
- g_return_if_fail (str != NULL);
+ g_return_if_fail (layout != NULL);
g_return_if_fail (max_width >= 0);
- layout = build_header_layout (widget, str);
+ pango_layout_get_pixel_size (layout, &width, &height);
- pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
+ gdk_gc_set_clip_rectangle (gc, NULL);
- if (PANGO_RBEARING (ink_rect) <= max_width) {
+ if (width <= max_width) {
int xpos;
if (center)
- xpos = x + (max_width - ink_rect.width) / 2;
+ xpos = x + (max_width - width) / 2;
else
xpos = x;
@@ -316,7 +273,6 @@ e_table_draw_elided_string (GdkDrawable *drawable, GdkGC *gc, GtkWidget *widget,
layout);
} else {
int arrow_width;
- int len;
int i;
if (max_width < ARROW_WIDTH + 1)
@@ -324,17 +280,21 @@ e_table_draw_elided_string (GdkDrawable *drawable, GdkGC *gc, GtkWidget *widget,
else
arrow_width = ARROW_WIDTH;
- len = compute_elision_length (widget, str, max_width - arrow_width - 1);
- pango_layout_set_text (layout, str, len);
+ lines = pango_layout_get_lines (layout);
+ line = lines->data;
- gdk_draw_layout (drawable, gc,
- x, y,
- layout);
+ if (!pango_layout_line_x_to_index (line,
+ (max_width - arrow_width) * PANGO_SCALE,
+ &index,
+ NULL)) {
+ g_warning ("pango_layout_line_x_to_index returned false");
+ return;
+ }
- pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
+ pango_layout_set_text (layout, str, index);
- y -= PANGO_ASCENT (ink_rect);
+ gdk_draw_layout (drawable, gc, x, y, layout);
for (i = 0; i < arrow_width; i++) {
int h;
@@ -342,10 +302,10 @@ e_table_draw_elided_string (GdkDrawable *drawable, GdkGC *gc, GtkWidget *widget,
h = 2 * i + 1;
gdk_draw_line (drawable, gc,
- x + PANGO_RBEARING(ink_rect) + arrow_width - i,
- y + (PANGO_ASCENT (ink_rect) + PANGO_DESCENT (ink_rect) - h) / 2,
- x + PANGO_RBEARING (ink_rect) + arrow_width - i,
- y + (PANGO_ASCENT (ink_rect) + PANGO_DESCENT (ink_rect) - h) / 2 + h - 1);
+ x + max_width - i,
+ y + height / 2 - i,
+ x + max_width - i,
+ y + height / 2 + i + 1);
}
}
@@ -361,7 +321,6 @@ static GtkWidget *g_label;
* @style: Style to use for drawing the button.
* @state: State of the table widget.
* @widget: The table widget.
- * @gc: GC to use for drawing.
* @x: Leftmost coordinate of the button.
* @y: Topmost coordinate of the button.
* @width: Width of the region to draw.
@@ -385,6 +344,7 @@ e_table_header_draw_button (GdkDrawable *drawable, ETableCol *ecol,
int inner_width, inner_height;
GdkGC *gc;
char *text;
+ PangoLayout *layout;
g_return_if_fail (drawable != NULL);
g_return_if_fail (ecol != NULL);
@@ -404,7 +364,9 @@ e_table_header_draw_button (GdkDrawable *drawable, ETableCol *ecol,
gtk_widget_ensure_style (g_label);
}
- gc = g_label->style->fg_gc[GTK_STATE_NORMAL];
+ gc = g_label->style->fg_gc[state];
+
+ gdk_gc_set_clip_rectangle (gc, NULL);
xthick = style->xthickness;
ythick = style->ythickness;
@@ -459,8 +421,9 @@ e_table_header_draw_button (GdkDrawable *drawable, ETableCol *ecol,
if (inner_width < 1)
return; /* nothing else fits */
- /* Pixbuf or label */
+ layout = build_header_layout (widget, ecol->text);
+ /* Pixbuf or label */
if (ecol->is_pixbuf) {
int pwidth, pheight;
int clip_width, clip_height;
@@ -478,26 +441,20 @@ e_table_header_draw_button (GdkDrawable *drawable, ETableCol *ecol,
xpos = inner_x;
if (inner_width - pwidth > 11) {
- PangoLayout *layout;
- PangoRectangle ink_rect;
+ int width;
int ypos;
- /* really sucks to generate another
- PangoLayout here when we turn around and
- make one in draw_elided_string */
-
- layout = build_header_layout (widget, ecol->text);
- pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
+ pango_layout_get_pixel_size (layout, &width, NULL);
- if (PANGO_RBEARING (ink_rect) < inner_width - (pwidth + 1)) {
- xpos = inner_x + (inner_width - ink_rect.width - (pwidth + 1)) / 2;
+ if (width < inner_width - (pwidth + 1)) {
+ xpos = inner_x + (inner_width - width - (pwidth + 1)) / 2;
}
ypos = inner_y;
e_table_draw_elided_string (drawable, gc, widget,
xpos + pwidth + 1, ypos,
- ecol->text, inner_width - (xpos - inner_x), FALSE);
+ layout, ecol->text, inner_width - (xpos - inner_x), FALSE);
g_object_unref (layout);
}
@@ -507,6 +464,9 @@ e_table_header_draw_button (GdkDrawable *drawable, ETableCol *ecol,
clip_width, clip_height,
xpos,
inner_y + (inner_height - clip_height) / 2);
+
+ gdk_gc_set_clip_rectangle (gc, NULL);
+
if (pixmap) {
gdk_draw_pixmap (drawable, gc, pixmap,
0, 0,
@@ -516,12 +476,8 @@ e_table_header_draw_button (GdkDrawable *drawable, ETableCol *ecol,
gdk_pixmap_unref (pixmap);
}
} else {
- int ypos;
-
- ypos = inner_y;
-
e_table_draw_elided_string (drawable, gc, widget,
- inner_x, ypos,
- ecol->text, inner_width, TRUE);
+ inner_x, inner_y,
+ layout, ecol->text, inner_width, TRUE);
}
}