Commit e2958714 authored by ONO Yoshio's avatar ONO Yoshio Committed by Jehan

MR !19: Add support for vertical text writing.

Squashed commit of the following:

commit ee1ff7d502658cfa1248a13a3f0348495db07eda
Author: ONO Yoshio <ohtsuka.yoshio@gmail.com>
Date:   Sun Jul 29 00:31:47 2018 +0900

    Fixed that gimp-text-dir-ttb-* icons are lacked in Symbolic.

commit d87d012d697628da28fe90199cc04b95b72ba8ef
Author: ONO Yoshio <ohtsuka.yoshio@gmail.com>
Date:   Sat Jul 28 16:23:10 2018 +0900

    Fix a typo.

commit cf0238bf7df56c384cdf3b7ec69557d14740f853
Author: ONO Yoshio <ohtsuka.yoshio@gmail.com>
Date:   Sat Jul 28 15:50:57 2018 +0900

    Fixed seg fault error.

commit b07f60d0
Author: ONO Yoshio <ohtsuka.yoshio@gmail.com>
Date:   Fri Jul 27 17:15:34 2018 +0900

    Add support for vertical text writing.

    #641

(cherry picked from commit 587d9bbb)
parent b43473d9
...@@ -65,7 +65,31 @@ static const GimpRadioActionEntry text_editor_direction_actions[] = ...@@ -65,7 +65,31 @@ static const GimpRadioActionEntry text_editor_direction_actions[] =
NC_("text-editor-action", "RTL"), NULL, NC_("text-editor-action", "RTL"), NULL,
NC_("text-editor-action", "From right to left"), NC_("text-editor-action", "From right to left"),
GIMP_TEXT_DIRECTION_RTL, GIMP_TEXT_DIRECTION_RTL,
NULL } NULL },
{ "text-editor-direction-ttb-rtl", GIMP_ICON_FORMAT_TEXT_DIRECTION_TTB_RTL,
NC_("text-editor-action", "TTB-RTL"), NULL,
NC_("text-editor-action", "Characters are from top to bottom, Lines are from right to left"),
GIMP_TEXT_DIRECTION_TTB_RTL,
NULL },
{ "text-editor-direction-ttb-rtl-upright", GIMP_ICON_FORMAT_TEXT_DIRECTION_TTB_RTL_UPRIGHT,
NC_("text-editor-action", "TTB-RTL-UPRIGHT"), NULL,
NC_("text-editor-action", "Upright characters are from top to bottom, Lines are from right to left"),
GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT,
NULL },
{ "text-editor-direction-ttb-ltr", GIMP_ICON_FORMAT_TEXT_DIRECTION_TTB_LTR,
NC_("text-editor-action", "TTB-LTR"), NULL,
NC_("text-editor-action", "Characters are from top to bottom, Lines are from left to right"),
GIMP_TEXT_DIRECTION_TTB_LTR,
NULL },
{ "text-editor-direction-ttb-ltr-upright", GIMP_ICON_FORMAT_TEXT_DIRECTION_TTB_LTR_UPRIGHT,
NC_("text-editor-action", "TTB-LTR-UPRIGHT"), NULL,
NC_("text-editor-action", "Upright characters are from top to bottom, Lines are from left to right"),
GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT,
NULL },
}; };
...@@ -102,6 +126,22 @@ text_editor_actions_update (GimpActionGroup *group, ...@@ -102,6 +126,22 @@ text_editor_actions_update (GimpActionGroup *group,
case GIMP_TEXT_DIRECTION_RTL: case GIMP_TEXT_DIRECTION_RTL:
SET_ACTIVE ("text-editor-direction-rtl", TRUE); SET_ACTIVE ("text-editor-direction-rtl", TRUE);
break; break;
case GIMP_TEXT_DIRECTION_TTB_RTL:
SET_ACTIVE ("text-editor-direction-ttb-rtl", TRUE);
break;
case GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT:
SET_ACTIVE ("text-editor-direction-ttb-rtl-upright", TRUE);
break;
case GIMP_TEXT_DIRECTION_TTB_LTR:
SET_ACTIVE ("text-editor-direction-ttb-ltr", TRUE);
break;
case GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT:
SET_ACTIVE ("text-editor-direction-ttb-ltr-upright", TRUE);
break;
} }
#undef SET_ACTIVE #undef SET_ACTIVE
......
...@@ -110,6 +110,26 @@ static const GimpRadioActionEntry text_tool_direction_actions[] = ...@@ -110,6 +110,26 @@ static const GimpRadioActionEntry text_tool_direction_actions[] =
{ "text-tool-direction-rtl", GIMP_ICON_FORMAT_TEXT_DIRECTION_RTL, { "text-tool-direction-rtl", GIMP_ICON_FORMAT_TEXT_DIRECTION_RTL,
NC_("text-tool-action", "From right to left"), NULL, NULL, NC_("text-tool-action", "From right to left"), NULL, NULL,
GIMP_TEXT_DIRECTION_RTL, GIMP_TEXT_DIRECTION_RTL,
NULL },
{ "text-tool-direction-ttb-rtl", GIMP_ICON_FORMAT_TEXT_DIRECTION_TTB_RTL,
NC_("text-tool-action", "Characters are from top to bottom, Lines are from right to left"), NULL, NULL,
GIMP_TEXT_DIRECTION_TTB_RTL,
NULL },
{ "text-tool-direction-ttb-rtl-upright", GIMP_ICON_FORMAT_TEXT_DIRECTION_TTB_RTL_UPRIGHT,
NC_("text-tool-action", "Upright characters are from top to bottom, Lines are from right to left"), NULL, NULL,
GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT,
NULL },
{ "text-tool-direction-ttb-ltr", GIMP_ICON_FORMAT_TEXT_DIRECTION_TTB_LTR,
NC_("text-tool-action", "Characters are from top to bottom, Lines are from left to right"), NULL, NULL,
GIMP_TEXT_DIRECTION_TTB_LTR,
NULL },
{ "text-tool-direction-ttb-ltr-upright", GIMP_ICON_FORMAT_TEXT_DIRECTION_TTB_LTR_UPRIGHT,
NC_("text-tool-action", "Upright characters are from top to bottom, Lines are from left to right"), NULL, NULL,
GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT,
NULL } NULL }
}; };
......
...@@ -39,7 +39,8 @@ enum ...@@ -39,7 +39,8 @@ enum
PROP_Y, PROP_Y,
PROP_WIDTH, PROP_WIDTH,
PROP_HEIGHT, PROP_HEIGHT,
PROP_OVERWRITE PROP_OVERWRITE,
PROP_DIRECTION
}; };
...@@ -47,11 +48,12 @@ typedef struct _GimpCanvasTextCursorPrivate GimpCanvasTextCursorPrivate; ...@@ -47,11 +48,12 @@ typedef struct _GimpCanvasTextCursorPrivate GimpCanvasTextCursorPrivate;
struct _GimpCanvasTextCursorPrivate struct _GimpCanvasTextCursorPrivate
{ {
gint x; gint x;
gint y; gint y;
gint width; gint width;
gint height; gint height;
gboolean overwrite; gboolean overwrite;
GimpTextDirection direction;
}; };
#define GET_PRIVATE(text_cursor) \ #define GET_PRIVATE(text_cursor) \
...@@ -122,6 +124,12 @@ gimp_canvas_text_cursor_class_init (GimpCanvasTextCursorClass *klass) ...@@ -122,6 +124,12 @@ gimp_canvas_text_cursor_class_init (GimpCanvasTextCursorClass *klass)
FALSE, FALSE,
GIMP_PARAM_READWRITE)); GIMP_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_DIRECTION,
g_param_spec_enum ("direction", NULL, NULL,
gimp_text_direction_get_type(),
GIMP_TEXT_DIRECTION_LTR,
GIMP_PARAM_READWRITE));
g_type_class_add_private (klass, sizeof (GimpCanvasTextCursorPrivate)); g_type_class_add_private (klass, sizeof (GimpCanvasTextCursorPrivate));
} }
...@@ -155,6 +163,9 @@ gimp_canvas_text_cursor_set_property (GObject *object, ...@@ -155,6 +163,9 @@ gimp_canvas_text_cursor_set_property (GObject *object,
case PROP_OVERWRITE: case PROP_OVERWRITE:
private->overwrite = g_value_get_boolean (value); private->overwrite = g_value_get_boolean (value);
break; break;
case PROP_DIRECTION:
private->direction = g_value_get_enum (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
...@@ -187,6 +198,9 @@ gimp_canvas_text_cursor_get_property (GObject *object, ...@@ -187,6 +198,9 @@ gimp_canvas_text_cursor_get_property (GObject *object,
case PROP_OVERWRITE: case PROP_OVERWRITE:
g_value_set_boolean (value, private->overwrite); g_value_set_boolean (value, private->overwrite);
break; break;
case PROP_DIRECTION:
g_value_set_enum (value, private->direction);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
...@@ -221,6 +235,20 @@ gimp_canvas_text_cursor_transform (GimpCanvasItem *item, ...@@ -221,6 +235,20 @@ gimp_canvas_text_cursor_transform (GimpCanvasItem *item,
*x = floor (*x) + 0.5; *x = floor (*x) + 0.5;
*y = floor (*y) + 0.5; *y = floor (*y) + 0.5;
switch (private->direction)
{
case GIMP_TEXT_DIRECTION_LTR:
case GIMP_TEXT_DIRECTION_RTL:
break;
case GIMP_TEXT_DIRECTION_TTB_RTL:
case GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT:
*x = *x - *w;
break;
case GIMP_TEXT_DIRECTION_TTB_LTR:
case GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT:
*y = *y + *h;
break;
}
if (private->overwrite) if (private->overwrite)
{ {
...@@ -229,8 +257,24 @@ gimp_canvas_text_cursor_transform (GimpCanvasItem *item, ...@@ -229,8 +257,24 @@ gimp_canvas_text_cursor_transform (GimpCanvasItem *item,
} }
else else
{ {
*w = 0; switch (private->direction)
*h = ceil (*h) - 1.0; {
case GIMP_TEXT_DIRECTION_LTR:
case GIMP_TEXT_DIRECTION_RTL:
*w = 0;
*h = ceil (*h) - 1.0;
break;
case GIMP_TEXT_DIRECTION_TTB_RTL:
case GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT:
*w = ceil (*w) - 1.0;
*h = 0;
break;
case GIMP_TEXT_DIRECTION_TTB_LTR:
case GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT:
*w = ceil (*w) - 1.0;
*h = 0;
break;
}
} }
} }
...@@ -250,14 +294,33 @@ gimp_canvas_text_cursor_draw (GimpCanvasItem *item, ...@@ -250,14 +294,33 @@ gimp_canvas_text_cursor_draw (GimpCanvasItem *item,
} }
else else
{ {
cairo_move_to (cr, x, y); switch (private->direction)
cairo_line_to (cr, x, y + h); {
case GIMP_TEXT_DIRECTION_LTR:
cairo_move_to (cr, x - 3.0, y); case GIMP_TEXT_DIRECTION_RTL:
cairo_line_to (cr, x + 3.0, y); cairo_move_to (cr, x, y);
cairo_line_to (cr, x, y + h);
cairo_move_to (cr, x - 3.0, y + h);
cairo_line_to (cr, x + 3.0, y + h); cairo_move_to (cr, x - 3.0, y);
cairo_line_to (cr, x + 3.0, y);
cairo_move_to (cr, x - 3.0, y + h);
cairo_line_to (cr, x + 3.0, y + h);
break;
case GIMP_TEXT_DIRECTION_TTB_RTL:
case GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT:
case GIMP_TEXT_DIRECTION_TTB_LTR:
case GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT:
cairo_move_to (cr, x, y);
cairo_line_to (cr, x + w, y);
cairo_move_to (cr, x, y - 3.0);
cairo_line_to (cr, x, y + 3.0);
cairo_move_to (cr, x + w, y - 3.0);
cairo_line_to (cr, x + w, y + 3.0);
break;
}
} }
_gimp_canvas_item_stroke (item, cr); _gimp_canvas_item_stroke (item, cr);
...@@ -282,10 +345,25 @@ gimp_canvas_text_cursor_get_extents (GimpCanvasItem *item) ...@@ -282,10 +345,25 @@ gimp_canvas_text_cursor_get_extents (GimpCanvasItem *item)
} }
else else
{ {
rectangle.x = floor (x - 4.5); switch (private->direction)
rectangle.y = floor (y - 1.5); {
rectangle.width = ceil (9.0); case GIMP_TEXT_DIRECTION_LTR:
rectangle.height = ceil (h + 3.0); case GIMP_TEXT_DIRECTION_RTL:
rectangle.x = floor (x - 4.5);
rectangle.y = floor (y - 1.5);
rectangle.width = ceil (9.0);
rectangle.height = ceil (h + 3.0);
break;
case GIMP_TEXT_DIRECTION_TTB_RTL:
case GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT:
case GIMP_TEXT_DIRECTION_TTB_LTR:
case GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT:
rectangle.x = floor (x - 1.5);
rectangle.y = floor (y - 4.5);
rectangle.width = ceil (w + 3.0);
rectangle.height = ceil (9.0);
break;
}
} }
return cairo_region_create_rectangle (&rectangle); return cairo_region_create_rectangle (&rectangle);
...@@ -294,7 +372,8 @@ gimp_canvas_text_cursor_get_extents (GimpCanvasItem *item) ...@@ -294,7 +372,8 @@ gimp_canvas_text_cursor_get_extents (GimpCanvasItem *item)
GimpCanvasItem * GimpCanvasItem *
gimp_canvas_text_cursor_new (GimpDisplayShell *shell, gimp_canvas_text_cursor_new (GimpDisplayShell *shell,
PangoRectangle *cursor, PangoRectangle *cursor,
gboolean overwrite) gboolean overwrite,
GimpTextDirection direction)
{ {
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL); g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL);
g_return_val_if_fail (cursor != NULL, NULL); g_return_val_if_fail (cursor != NULL, NULL);
...@@ -306,5 +385,6 @@ gimp_canvas_text_cursor_new (GimpDisplayShell *shell, ...@@ -306,5 +385,6 @@ gimp_canvas_text_cursor_new (GimpDisplayShell *shell,
"width", cursor->width, "width", cursor->width,
"height", cursor->height, "height", cursor->height,
"overwrite", overwrite, "overwrite", overwrite,
"direction", direction,
NULL); NULL);
} }
...@@ -51,7 +51,8 @@ GType gimp_canvas_text_cursor_get_type (void) G_GNUC_CONST; ...@@ -51,7 +51,8 @@ GType gimp_canvas_text_cursor_get_type (void) G_GNUC_CONST;
GimpCanvasItem * gimp_canvas_text_cursor_new (GimpDisplayShell *shell, GimpCanvasItem * gimp_canvas_text_cursor_new (GimpDisplayShell *shell,
PangoRectangle *cursor, PangoRectangle *cursor,
gboolean overwrite); gboolean overwrite,
GimpTextDirection direction);
#endif /* __GIMP_CANVAS_RECTANGLE_H__ */ #endif /* __GIMP_CANVAS_RECTANGLE_H__ */
...@@ -663,10 +663,26 @@ gimp_text_layer_render (GimpTextLayer *layer) ...@@ -663,10 +663,26 @@ gimp_text_layer_render (GimpTextLayer *layer)
gimp_drawable_get_format (drawable))) gimp_drawable_get_format (drawable)))
{ {
GeglBuffer *new_buffer; GeglBuffer *new_buffer;
GimpItem *item;
gint oldwidth;
gint newwidth;
item = GIMP_ITEM (drawable);
oldwidth = gimp_item_get_width (item);
new_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height), new_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height),
gimp_text_layer_get_format (layer)); gimp_text_layer_get_format (layer));
gimp_drawable_set_buffer (drawable, FALSE, NULL, new_buffer); gimp_drawable_set_buffer (drawable, FALSE, NULL, new_buffer);
newwidth = gimp_item_get_width(item);
if (layer->text->box_mode == GIMP_TEXT_BOX_DYNAMIC &&
oldwidth != newwidth &&
(layer->text->base_dir == GIMP_TEXT_DIRECTION_TTB_RTL ||
layer->text->base_dir == GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT))
{
gimp_item_translate (item, oldwidth - newwidth, 0, FALSE);
}
g_object_unref (new_buffer); g_object_unref (new_buffer);
if (gimp_layer_get_mask (GIMP_LAYER (layer))) if (gimp_layer_get_mask (GIMP_LAYER (layer)))
......
...@@ -37,6 +37,7 @@ gimp_text_layout_render (GimpTextLayout *layout, ...@@ -37,6 +37,7 @@ gimp_text_layout_render (GimpTextLayout *layout,
PangoLayout *pango_layout; PangoLayout *pango_layout;
cairo_matrix_t trafo; cairo_matrix_t trafo;
gint x, y; gint x, y;
gint width, height;
g_return_if_fail (GIMP_IS_TEXT_LAYOUT (layout)); g_return_if_fail (GIMP_IS_TEXT_LAYOUT (layout));
g_return_if_fail (cr != NULL); g_return_if_fail (cr != NULL);
...@@ -49,6 +50,22 @@ gimp_text_layout_render (GimpTextLayout *layout, ...@@ -49,6 +50,22 @@ gimp_text_layout_render (GimpTextLayout *layout,
gimp_text_layout_get_transform (layout, &trafo); gimp_text_layout_get_transform (layout, &trafo);
cairo_transform (cr, &trafo); cairo_transform (cr, &trafo);
if (base_dir == GIMP_TEXT_DIRECTION_TTB_RTL ||
base_dir == GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT)
{
gimp_text_layout_get_size (layout, &width, &height);
cairo_translate (cr, width, 0);
cairo_rotate (cr, G_PI_2);
}
if (base_dir == GIMP_TEXT_DIRECTION_TTB_LTR ||
base_dir == GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT)
{
gimp_text_layout_get_size (layout, &width, &height);
cairo_translate (cr, 0, height);
cairo_rotate (cr, -G_PI_2);
}
pango_layout = gimp_text_layout_get_pango_layout (layout); pango_layout = gimp_text_layout_get_pango_layout (layout);
if (path) if (path)
......
...@@ -136,8 +136,6 @@ gimp_text_layout_new (GimpText *text, ...@@ -136,8 +136,6 @@ gimp_text_layout_new (GimpText *text,
pango_layout_set_wrap (layout->layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_wrap (layout->layout, PANGO_WRAP_WORD_CHAR);
g_object_unref (context);
pango_layout_set_font_description (layout->layout, font_desc); pango_layout_set_font_description (layout->layout, font_desc);
pango_font_description_free (font_desc); pango_font_description_free (font_desc);
...@@ -167,12 +165,18 @@ gimp_text_layout_new (GimpText *text, ...@@ -167,12 +165,18 @@ gimp_text_layout_new (GimpText *text,
case GIMP_TEXT_BOX_DYNAMIC: case GIMP_TEXT_BOX_DYNAMIC:
break; break;
case GIMP_TEXT_BOX_FIXED: case GIMP_TEXT_BOX_FIXED:
pango_layout_set_width (layout->layout, if (! PANGO_GRAVITY_IS_VERTICAL (pango_context_get_base_gravity (context)))
pango_units_from_double pango_layout_set_width (layout->layout,
(gimp_units_to_pixels (text->box_width, pango_units_from_double
text->box_unit, (gimp_units_to_pixels (text->box_width,
xres) - text->box_unit,
2 * layout->text->border)); xres)));
else
pango_layout_set_width (layout->layout,
pango_units_from_double
(gimp_units_to_pixels (text->box_height,
text->box_unit,
yres)));
break; break;
} }
...@@ -210,6 +214,8 @@ gimp_text_layout_new (GimpText *text, ...@@ -210,6 +214,8 @@ gimp_text_layout_new (GimpText *text,
break; break;
} }
g_object_unref (context);
return layout; return layout;
} }
...@@ -591,6 +597,7 @@ gimp_text_layout_position (GimpTextLayout *layout) ...@@ -591,6 +597,7 @@ gimp_text_layout_position (GimpTextLayout *layout)
{ {
PangoRectangle ink; PangoRectangle ink;
PangoRectangle logical; PangoRectangle logical;
PangoContext *context;
gint x1, y1; gint x1, y1;
gint x2, y2; gint x2, y2;
...@@ -603,6 +610,7 @@ gimp_text_layout_position (GimpTextLayout *layout) ...@@ -603,6 +610,7 @@ gimp_text_layout_position (GimpTextLayout *layout)
ink.width = ceil ((gdouble) ink.width * layout->xres / layout->yres); ink.width = ceil ((gdouble) ink.width * layout->xres / layout->yres);
logical.width = ceil ((gdouble) logical.width * layout->xres / layout->yres); logical.width = ceil ((gdouble) logical.width * layout->xres / layout->yres);
context = pango_layout_get_context (layout->layout);
#ifdef VERBOSE #ifdef VERBOSE
g_printerr ("ink rect: %d x %d @ %d, %d\n", g_printerr ("ink rect: %d x %d @ %d, %d\n",
...@@ -641,7 +649,11 @@ gimp_text_layout_position (GimpTextLayout *layout) ...@@ -641,7 +649,11 @@ gimp_text_layout_position (GimpTextLayout *layout)
pango_layout_get_pixel_size (layout->layout, &width, NULL); pango_layout_get_pixel_size (layout->layout, &width, NULL);
if ((base_dir == GIMP_TEXT_DIRECTION_LTR && align == PANGO_ALIGN_RIGHT) || if ((base_dir == GIMP_TEXT_DIRECTION_LTR && align == PANGO_ALIGN_RIGHT) ||
(base_dir == GIMP_TEXT_DIRECTION_RTL && align == PANGO_ALIGN_LEFT)) (base_dir == GIMP_TEXT_DIRECTION_RTL && align == PANGO_ALIGN_LEFT) ||
(base_dir == GIMP_TEXT_DIRECTION_TTB_RTL && align == PANGO_ALIGN_RIGHT) ||
(base_dir == GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT && align == PANGO_ALIGN_RIGHT) ||
(base_dir == GIMP_TEXT_DIRECTION_TTB_LTR && align == PANGO_ALIGN_LEFT) ||
(base_dir == GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT && align == PANGO_ALIGN_LEFT))
{ {
layout->extents.x += layout->extents.x +=
PANGO_PIXELS (pango_layout_get_width (layout->layout)) - width; PANGO_PIXELS (pango_layout_get_width (layout->layout)) - width;
...@@ -663,6 +675,19 @@ gimp_text_layout_position (GimpTextLayout *layout) ...@@ -663,6 +675,19 @@ gimp_text_layout_position (GimpTextLayout *layout)
layout->extents.height += 2 * border; layout->extents.height += 2 * border;
} }
if (PANGO_GRAVITY_IS_VERTICAL (pango_context_get_base_gravity (context)))
{
gint temp;
temp = layout->extents.y;
layout->extents.y = layout->extents.x;
layout->extents.x = temp;
temp = layout->extents.height;
layout->extents.height = layout->extents.width;
layout->extents.width = temp;
}
#ifdef VERBOSE #ifdef VERBOSE
g_printerr ("layout extents: %d x %d @ %d, %d\n", g_printerr ("layout extents: %d x %d @ %d, %d\n",
layout->extents.width, layout->extents.height, layout->extents.width, layout->extents.height,
...@@ -732,10 +757,38 @@ gimp_text_get_pango_context (GimpText *text, ...@@ -732,10 +757,38 @@ gimp_text_get_pango_context (GimpText *text,
{ {
case GIMP_TEXT_DIRECTION_LTR: case GIMP_TEXT_DIRECTION_LTR:
pango_context_set_base_dir (context, PANGO_DIRECTION_LTR); pango_context_set_base_dir (context, PANGO_DIRECTION_LTR);
pango_context_set_gravity_hint (context, PANGO_GRAVITY_HINT_NATURAL);
pango_context_set_base_gravity (context, PANGO_GRAVITY_SOUTH);
break; break;
case GIMP_TEXT_DIRECTION_RTL: case GIMP_TEXT_DIRECTION_RTL:
pango_context_set_base_dir (context, PANGO_DIRECTION_RTL); pango_context_set_base_dir (context, PANGO_DIRECTION_RTL);
pango_context_set_gravity_hint (context, PANGO_GRAVITY_HINT_NATURAL);
pango_context_set_base_gravity (context, PANGO_GRAVITY_SOUTH);
break;
case GIMP_TEXT_DIRECTION_TTB_RTL:
pango_context_set_base_dir (context, PANGO_DIRECTION_LTR);
pango_context_set_gravity_hint (context, PANGO_GRAVITY_HINT_LINE);
pango_context_set_base_gravity (context, PANGO_GRAVITY_EAST);
break;
case GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT:
pango_context_set_base_dir (context, PANGO_DIRECTION_LTR);
pango_context_set_gravity_hint (context, PANGO_GRAVITY_HINT_STRONG);
pango_context_set_base_gravity (context, PANGO_GRAVITY_EAST);
break;
case GIMP_TEXT_DIRECTION_TTB_LTR:
pango_context_set_base_dir (context, PANGO_DIRECTION_LTR);
pango_context_set_gravity_hint (context, PANGO_GRAVITY_HINT_LINE);
pango_context_set_base_gravity (context, PANGO_GRAVITY_WEST);
break;
case GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT:
pango_context_set_base_dir (context, PANGO_DIRECTION_LTR);
pango_context_set_gravity_hint (context, PANGO_GRAVITY_HINT_STRONG);
pango_context_set_base_gravity (context, PANGO_GRAVITY_WEST);
break; break;
} }
......
...@@ -1147,16 +1147,17 @@ gimp_draw_tool_add_boundary (GimpDrawTool *draw_tool, ...@@ -1147,16 +1147,17 @@ gimp_draw_tool_add_boundary (GimpDrawTool *draw_tool,
} }
GimpCanvasItem * GimpCanvasItem *
gimp_draw_tool_add_text_cursor (GimpDrawTool *draw_tool, gimp_draw_tool_add_text_cursor (GimpDrawTool *draw_tool,
PangoRectangle *cursor, PangoRectangle *cursor,
gboolean overwrite) gboolean overwrite,
GimpTextDirection direction)
{ {
GimpCanvasItem *item; GimpCanvasItem *item;
g_return_val_if_fail (GIMP_IS_DRAW_TOOL (draw_tool), NULL); g_return_val_if_fail (GIMP_IS_DRAW_TOOL (draw_tool), NULL);
item = gimp_canvas_text_cursor_new (gimp_display_get_shell (draw_tool->display), item = gimp_canvas_text_cursor_new (gimp_display_get_shell (draw_tool->display),
cursor, overwrite); cursor, overwrite, direction);
gimp_draw_tool_add_item (draw_tool, item); gimp_draw_tool_add_item (draw_tool, item);
g_object_unref (item); g_object_unref (item);
......
...@@ -188,7 +188,8 @@ GimpCanvasItem * gimp_draw_tool_add_boundary (GimpDrawTool *draw_too ...@@ -188,7 +188,8 @@ GimpCanvasItem * gimp_draw_tool_add_boundary (GimpDrawTool *draw_too
GimpCanvasItem * gimp_draw_tool_add_text_cursor (GimpDrawTool *draw_tool, GimpCanvasItem * gimp_draw_tool_add_text_cursor (GimpDrawTool *draw_tool,
PangoRectangle *cursor, PangoRectangle *cursor,
gboolean overwrite); gboolean overwrite,
GimpTextDirection direction);
gboolean gimp_draw_tool_on_handle (GimpDrawTool *draw_tool, gboolean gimp_draw_tool_on_handle (GimpDrawTool *draw_tool,
GimpDisplay *display, GimpDisplay *display,
......
...@@ -119,6 +119,13 @@ static void gimp_text_tool_im_delete_preedit (GimpTextTool *text_tool); ...@@ -119,6 +119,13 @@ static void gimp_text_tool_im_delete_preedit (GimpTextTool *text_tool);
static void gimp_text_tool_editor_copy_selection_to_clipboard static void gimp_text_tool_editor_copy_selection_to_clipboard
(GimpTextTool *text_tool); (GimpTextTool *text_tool);
static void gimp_text_tool_fix_position (GimpTextTool *text_tool,
gdouble *x,
gdouble *y);
static void gimp_text_tool_convert_gdkkeyevent (GimpTextTool *text_tool,
GdkEventKey *kevent);
/* public functions */ /* public functions */
...@@ -466,6 +473,8 @@ gimp_text_tool_editor_key_press (GimpTextTool *text_tool, ...@@ -466,6 +473,8 @@ gimp_text_tool_editor_key_press (GimpTextTool *text_tool,
return TRUE; return TRUE;
} }
gimp_text_tool_convert_gdkkeyevent (text_tool, kevent);
gimp_text_tool_ensure_proxy (text_tool); gimp_text_tool_ensure_proxy (text_tool);
if (gtk_bindings_activate_event (GTK_OBJECT (text_tool->proxy_text_view), if (gtk_bindings_activate_event (GTK_OBJECT (text_tool->proxy_text_view),
...@@ -522,6 +531,8 @@ gimp_text_tool_editor_key_release (GimpTextTool *text_tool, ...@@ -522,6 +531,8 @@ gimp_text_tool_editor_key_release (GimpTextTool *text_tool,
return TRUE; return TRUE;
} }
gimp_text_tool_convert_gdkkeyevent (text_tool, kevent);
gimp_text_tool_ensure_proxy (text_tool); gimp_text_tool_ensure_proxy (text_tool);
if (gtk_bindings_activate_event (GTK_OBJECT (text_tool->proxy_text_view), if (gtk_bindings_activate_event (GTK_OBJECT (text_tool->proxy_text_view),
...@@ -597,6 +608,7 @@ gimp_text_tool_editor_get_cursor_rect (GimpTextTool *text_tool, ...@@ -597,6 +608,7 @@ gimp_text_tool_editor_get_cursor_rect (GimpTextTool *text_tool,
{ {
GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer); GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer);
PangoLayout *layout; PangoLayout *layout;
PangoContext *context;
gint offset_x; gint offset_x;
gint offset_y; gint offset_y;
GtkTextIter cursor; GtkTextIter cursor;
...@@ -614,19 +626,66 @@ gimp_text_tool_editor_get_cursor_rect (GimpTextTool *text_tool, ...@@ -614,19 +626,66 @@ gimp_text_tool_editor_get_cursor_rect (GimpTextTool *text_tool,
layout = gimp_text_layout_get_pango_layout (text_tool->layout); layout = gimp_text_layout_get_pango_layout (text_tool->layout);
context = pango_layout_get_context (layout);
gimp_text_layout_get_offsets (text_tool->layout, &offset_x, &offset_y); gimp_text_layout_get_offsets (text_tool->layout, &offset_x, &offset_y);
if (overwrite) if (overwrite)
pango_layout_index_to_pos (layout, cursor_index, cursor_rect); {
else pango_layout_index_to_pos (layout, cursor_index,