Re: [PATCH] Icon view RTL layout
- From: Christian Neumair <chris gnome-de org>
- To: Alexander Larsson <alexl redhat com>
- Cc: nautilus-list gnome org
- Subject: Re: [PATCH] Icon view RTL layout
- Date: Sat, 04 Mar 2006 11:04:31 +0100
Am Freitag, den 03.03.2006, 18:17 +0100 schrieb Alexander Larsson:
> On Fri, 2006-03-03 at 15:56 +0100, Christian Neumair wrote:
>
> > My first thought was: Well, let's calc. the width needed by the layout
> > and shift the final text position to the right by (max_width -
> > layout_width). This seemed to work totally fine, until I discovered what
> > happens when you mix RTL and LTR layouts. You may well up with something
> > like:
> >
> > [ alephbeth ]
> > [ somemorelatintext ]
> >
> > So a simple offset will break your layout. A PangoLayout with a width of
> > max_width will never be appropriate for arbitrary mixtures of LTR/RTL,
> > because sometimes you just can't get the offset right.
>
> I'm not sure what exactly the problem is here. Lets use some concrete
> examples. Say upper case is RTL and lower case is LTR, the main
> direction is RTL, and the max width is this:
> [ ]
>
> Lets start with some simple string that fits in max-width: "ABC abc",
> "ABC", and "abc". These should be layed out as:
> [ abc CBA]
>
> [ abc]
>
> [ CBA]
>
> This is not a problem. We set the max width, get the pixel width and we
> shift the layout by max-text-width - pixel_width.
>
> With longer strings, like "abcd efgh ijkl mnop", "ABCD EFGH IJKL MNOP",
> "ABCD efgh ijkl MNOP" we get:
>
> [ abcd efgh]
> [ ijkl mnop]
>
> [ HGFE DCBA]
> [ PONM LKJI]
>
> [ efgh DCBA]
> [ PONM ijkl]
>
> For all these we can also just take max-text-width - pixel-width and
> shift the layout by it.
>
> Can you give an example string in this "language" where this method
> would not work?
When you consider multiple paragraphs, they can independently be either
RTL or LTR, so a layout like
[ LTRLTRLTR ]
[ RTL ]
is possible, i.e. there is one base directions for each of the
paragraphs. This could only be relevant if there are paragraph
separation characters in the layout - I don't know the RTL semantics.
I'm attaching a new patch which addresses your performance concerns by
setting the layout to single-paragraph mode, adapting its alignment,
calculating the base direction and adding an offset based on this data.
I hope the switch statements don't look too clumsy, I don't think
separating them out into an own helper buys us much.
--
Christian Neumair <chris gnome-de org>
Index: libnautilus-private/nautilus-icon-canvas-item.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-icon-canvas-item.c,v
retrieving revision 1.197
diff -u -p -r1.197 nautilus-icon-canvas-item.c
--- libnautilus-private/nautilus-icon-canvas-item.c 3 Mar 2006 13:34:54 -0000 1.197
+++ libnautilus-private/nautilus-icon-canvas-item.c 4 Mar 2006 09:56:54 -0000
@@ -105,6 +105,8 @@ struct NautilusIconCanvasItemDetails {
PangoLayout *editable_text_layout;
PangoLayout *additional_text_layout;
+ PangoDirection editable_text_dir;
+ PangoDirection additional_text_dir;
GdkRectangle embedded_text_rect;
PangoLayout *embedded_text_layout;
@@ -198,6 +200,7 @@ static void draw_mask
int x,
int y);
static PangoLayout *get_label_layout (PangoLayout **layout,
+ PangoDirection *dir,
NautilusIconCanvasItem *item,
const char *text);
static void draw_label_layout (NautilusIconCanvasItem *item,
@@ -942,7 +945,7 @@ draw_or_measure_label_text (NautilusIcon
int icon_width;
gboolean have_editable, have_additional, needs_highlight, needs_frame;
int max_text_width;
- int x;
+ int x_additional, x_editable;
GdkGC *gc;
ArtIRect text_rect;
int text_back_padding_x, text_back_padding_y;
@@ -1002,7 +1005,9 @@ draw_or_measure_label_text (NautilusIcon
additional_layout = NULL;
if (have_editable) {
- editable_layout = get_label_layout (&details->editable_text_layout, item, details->editable_text);
+ editable_layout = get_label_layout (&details->editable_text_layout,
+ &details->editable_text_dir,
+ item, details->editable_text);
pango_layout_get_pixel_size (editable_layout,
&editable_width,
@@ -1010,7 +1015,9 @@ draw_or_measure_label_text (NautilusIcon
}
if (have_additional) {
- additional_layout = get_label_layout (&details->additional_text_layout, item, details->additional_text);
+ additional_layout = get_label_layout (&details->additional_text_layout,
+ &details->additional_text_dir,
+ item, details->additional_text);
pango_layout_get_pixel_size (additional_layout,
&additional_width,
@@ -1066,14 +1073,39 @@ draw_or_measure_label_text (NautilusIcon
text_rect.y1 - text_rect.y0);
}
-
- if (container->details->label_position == NAUTILUS_ICON_LABEL_POSITION_BESIDE) {
- x = text_rect.x0 + 2;
- } else {
- x = text_rect.x0 + ((text_rect.x1 - text_rect.x0) - max_text_width) / 2;
+ x_additional = x_editable = 0;
+
+ if (container->details->label_position != NAUTILUS_ICON_LABEL_POSITION_BESIDE) {
+ x_additional = x_editable = text_rect.x0 + ((text_rect.x1 - text_rect.x0) - max_text_width) / 2;
}
if (have_editable) {
+ if (container->details->label_position == NAUTILUS_ICON_LABEL_POSITION_BESIDE) {
+ switch (details->editable_text_dir) {
+ case PANGO_DIRECTION_LTR:
+ case PANGO_DIRECTION_TTB_LTR:
+ case PANGO_DIRECTION_WEAK_LTR:
+ x_editable = text_rect.x0 + text_back_padding_x;
+ break;
+
+ case PANGO_DIRECTION_RTL:
+ case PANGO_DIRECTION_TTB_RTL:
+ case PANGO_DIRECTION_WEAK_RTL:
+ x_editable = text_rect.x0 + MAX (editable_width, additional_width)
+ - max_text_width + text_back_padding_x;
+ break;
+ case PANGO_DIRECTION_NEUTRAL:
+ default:
+ if (gtk_widget_get_direction (GTK_WIDGET (container)) == GTK_TEXT_DIR_LTR) {
+ x_editable = text_rect.x0 + text_back_padding_x;
+ } else {
+ x_editable = text_rect.x0 + MAX (editable_width, additional_width)
+ - max_text_width + text_back_padding_x;
+ }
+ break;
+ }
+ }
+
gtk_widget_style_get (GTK_WIDGET (container),
"frame_text", &needs_frame,
NULL);
@@ -1095,11 +1127,37 @@ draw_or_measure_label_text (NautilusIcon
draw_label_layout (item, drawable,
editable_layout, needs_highlight,
label_color,
- x,
+ x_editable,
text_rect.y0 + text_back_padding_y, gc);
}
if (have_additional) {
+ if (container->details->label_position == NAUTILUS_ICON_LABEL_POSITION_BESIDE) {
+ switch (details->additional_text_dir) {
+ case PANGO_DIRECTION_LTR:
+ case PANGO_DIRECTION_TTB_LTR:
+ case PANGO_DIRECTION_WEAK_LTR:
+ x_additional = text_rect.x0 + text_back_padding_x;
+ break;
+
+ case PANGO_DIRECTION_RTL:
+ case PANGO_DIRECTION_TTB_RTL:
+ case PANGO_DIRECTION_WEAK_RTL:
+ x_additional = text_rect.x0 + MAX (additional_width, additional_width)
+ - max_text_width + text_back_padding_x;
+ break;
+ case PANGO_DIRECTION_NEUTRAL:
+ default:
+ if (gtk_widget_get_direction (GTK_WIDGET (container)) == GTK_TEXT_DIR_LTR) {
+ x_additional = text_rect.x0 + text_back_padding_x;
+ } else {
+ x_additional = text_rect.x0 + MAX (additional_width, additional_width)
+ - max_text_width + text_back_padding_x;
+ }
+ break;
+ }
+ }
+
gc = nautilus_icon_container_get_label_color_and_gc
(NAUTILUS_ICON_CONTAINER (canvas_item->canvas),
&label_color, FALSE, needs_highlight);
@@ -1107,7 +1165,7 @@ draw_or_measure_label_text (NautilusIcon
draw_label_layout (item, drawable,
additional_layout, needs_highlight,
label_color,
- x,
+ x_additional,
text_rect.y0 + editable_height + LABEL_LINE_SPACING + text_back_padding_y, gc);
}
@@ -1638,13 +1696,18 @@ create_label_layout (NautilusIconCanvasI
pango_layout_set_width (layout, floor (nautilus_icon_canvas_item_get_max_text_width (item)) * PANGO_SCALE);
if (container->details->label_position == NAUTILUS_ICON_LABEL_POSITION_BESIDE) {
- pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
+ if (gtk_widget_get_direction (GTK_WIDGET (container)) == GTK_TEXT_DIR_LTR) {
+ pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
+ } else {
+ pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
+ }
} else {
pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
}
pango_layout_set_spacing (layout, LABEL_LINE_SPACING);
pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
+ pango_layout_set_single_paragraph_mode (layout, TRUE);
/* Create a font description */
if (container->details->font) {
@@ -1664,11 +1727,13 @@ create_label_layout (NautilusIconCanvasI
static PangoLayout *
get_label_layout (PangoLayout **layout,
+ PangoDirection *dir,
NautilusIconCanvasItem *item,
const char *text)
{
if (*layout == NULL) {
*layout = create_label_layout (item, text);
+ *dir = pango_find_base_dir (text, -1);
}
g_object_ref (*layout);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]