Commit 587d9bbb 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
parent 712557e7
......@@ -65,7 +65,31 @@ static const GimpRadioActionEntry text_editor_direction_actions[] =
NC_("text-editor-action", "RTL"), NULL,
NC_("text-editor-action", "From right to left"),
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,
case GIMP_TEXT_DIRECTION_RTL:
SET_ACTIVE ("text-editor-direction-rtl", TRUE);
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
......
......@@ -110,6 +110,26 @@ static const GimpRadioActionEntry text_tool_direction_actions[] =
{ "text-tool-direction-rtl", GIMP_ICON_FORMAT_TEXT_DIRECTION_RTL,
NC_("text-tool-action", "From right to left"), NULL, NULL,
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 }
};
......
......@@ -39,7 +39,8 @@ enum
PROP_Y,
PROP_WIDTH,
PROP_HEIGHT,
PROP_OVERWRITE
PROP_OVERWRITE,
PROP_DIRECTION
};
......@@ -47,11 +48,12 @@ typedef struct _GimpCanvasTextCursorPrivate GimpCanvasTextCursorPrivate;
struct _GimpCanvasTextCursorPrivate
{
gint x;
gint y;
gint width;
gint height;
gboolean overwrite;
gint x;
gint y;
gint width;
gint height;
gboolean overwrite;
GimpTextDirection direction;
};
#define GET_PRIVATE(text_cursor) \
......@@ -122,6 +124,12 @@ gimp_canvas_text_cursor_class_init (GimpCanvasTextCursorClass *klass)
FALSE,
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));
}
......@@ -155,6 +163,9 @@ gimp_canvas_text_cursor_set_property (GObject *object,
case PROP_OVERWRITE:
private->overwrite = g_value_get_boolean (value);
break;
case PROP_DIRECTION:
private->direction = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
......@@ -187,6 +198,9 @@ gimp_canvas_text_cursor_get_property (GObject *object,
case PROP_OVERWRITE:
g_value_set_boolean (value, private->overwrite);
break;
case PROP_DIRECTION:
g_value_set_enum (value, private->direction);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
......@@ -221,6 +235,20 @@ gimp_canvas_text_cursor_transform (GimpCanvasItem *item,
*x = floor (*x) + 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)
{
......@@ -229,8 +257,24 @@ gimp_canvas_text_cursor_transform (GimpCanvasItem *item,
}
else
{
*w = 0;
*h = ceil (*h) - 1.0;
switch (private->direction)
{
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,
}
else
{
cairo_move_to (cr, x, y);
cairo_line_to (cr, x, 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);
switch (private->direction)
{
case GIMP_TEXT_DIRECTION_LTR:
case GIMP_TEXT_DIRECTION_RTL:
cairo_move_to (cr, x, y);
cairo_line_to (cr, x, 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);
......@@ -282,10 +345,25 @@ gimp_canvas_text_cursor_get_extents (GimpCanvasItem *item)
}
else
{
rectangle.x = floor (x - 4.5);
rectangle.y = floor (y - 1.5);
rectangle.width = ceil (9.0);
rectangle.height = ceil (h + 3.0);
switch (private->direction)
{
case GIMP_TEXT_DIRECTION_LTR:
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);
......@@ -294,7 +372,8 @@ gimp_canvas_text_cursor_get_extents (GimpCanvasItem *item)
GimpCanvasItem *
gimp_canvas_text_cursor_new (GimpDisplayShell *shell,
PangoRectangle *cursor,
gboolean overwrite)
gboolean overwrite,
GimpTextDirection direction)
{
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL);
g_return_val_if_fail (cursor != NULL, NULL);
......@@ -306,5 +385,6 @@ gimp_canvas_text_cursor_new (GimpDisplayShell *shell,
"width", cursor->width,
"height", cursor->height,
"overwrite", overwrite,
"direction", direction,
NULL);
}
......@@ -51,7 +51,8 @@ GType gimp_canvas_text_cursor_get_type (void) G_GNUC_CONST;
GimpCanvasItem * gimp_canvas_text_cursor_new (GimpDisplayShell *shell,
PangoRectangle *cursor,
gboolean overwrite);
gboolean overwrite,
GimpTextDirection direction);
#endif /* __GIMP_CANVAS_RECTANGLE_H__ */
......@@ -663,10 +663,26 @@ gimp_text_layer_render (GimpTextLayer *layer)
gimp_drawable_get_format (drawable)))
{
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),
gimp_text_layer_get_format (layer));
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);
if (gimp_layer_get_mask (GIMP_LAYER (layer)))
......
......@@ -37,6 +37,7 @@ gimp_text_layout_render (GimpTextLayout *layout,
PangoLayout *pango_layout;
cairo_matrix_t trafo;
gint x, y;
gint width, height;
g_return_if_fail (GIMP_IS_TEXT_LAYOUT (layout));
g_return_if_fail (cr != NULL);
......@@ -49,6 +50,22 @@ gimp_text_layout_render (GimpTextLayout *layout,
gimp_text_layout_get_transform (layout, &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);
if (path)
......
......@@ -136,8 +136,6 @@ gimp_text_layout_new (GimpText *text,
pango_layout_set_wrap (layout->layout, PANGO_WRAP_WORD_CHAR);
g_object_unref (context);
pango_layout_set_font_description (layout->layout, font_desc);
pango_font_description_free (font_desc);
......@@ -167,12 +165,18 @@ gimp_text_layout_new (GimpText *text,
case GIMP_TEXT_BOX_DYNAMIC:
break;
case GIMP_TEXT_BOX_FIXED:
pango_layout_set_width (layout->layout,
pango_units_from_double
(gimp_units_to_pixels (text->box_width,
text->box_unit,
xres) -
2 * layout->text->border));
if (! PANGO_GRAVITY_IS_VERTICAL (pango_context_get_base_gravity (context)))
pango_layout_set_width (layout->layout,
pango_units_from_double
(gimp_units_to_pixels (text->box_width,
text->box_unit,
xres)));
else
pango_layout_set_width (layout->layout,
pango_units_from_double
(gimp_units_to_pixels (text->box_height,
text->box_unit,
yres)));
break;
}
......@@ -210,6 +214,8 @@ gimp_text_layout_new (GimpText *text,
break;
}
g_object_unref (context);
return layout;
}
......@@ -591,6 +597,7 @@ gimp_text_layout_position (GimpTextLayout *layout)
{
PangoRectangle ink;
PangoRectangle logical;
PangoContext *context;
gint x1, y1;
gint x2, y2;
......@@ -603,6 +610,7 @@ gimp_text_layout_position (GimpTextLayout *layout)
ink.width = ceil ((gdouble) ink.width * layout->xres / layout->yres);
logical.width = ceil ((gdouble) logical.width * layout->xres / layout->yres);
context = pango_layout_get_context (layout->layout);
#ifdef VERBOSE
g_printerr ("ink rect: %d x %d @ %d, %d\n",
......@@ -641,7 +649,11 @@ gimp_text_layout_position (GimpTextLayout *layout)
pango_layout_get_pixel_size (layout->layout, &width, NULL);
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 +=
PANGO_PIXELS (pango_layout_get_width (layout->layout)) - width;
......@@ -663,6 +675,19 @@ gimp_text_layout_position (GimpTextLayout *layout)
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
g_printerr ("layout extents: %d x %d @ %d, %d\n",
layout->extents.width, layout->extents.height,
......@@ -732,10 +757,38 @@ gimp_text_get_pango_context (GimpText *text,
{
case GIMP_TEXT_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;
case GIMP_TEXT_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;
}
......
......@@ -1143,16 +1143,17 @@ gimp_draw_tool_add_boundary (GimpDrawTool *draw_tool,
}
GimpCanvasItem *
gimp_draw_tool_add_text_cursor (GimpDrawTool *draw_tool,
PangoRectangle *cursor,
gboolean overwrite)
gimp_draw_tool_add_text_cursor (GimpDrawTool *draw_tool,
PangoRectangle *cursor,
gboolean overwrite,
GimpTextDirection direction)
{
GimpCanvasItem *item;
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),
cursor, overwrite);
cursor, overwrite, direction);
gimp_draw_tool_add_item (draw_tool, item);
g_object_unref (item);
......
......@@ -188,7 +188,8 @@ GimpCanvasItem * gimp_draw_tool_add_boundary (GimpDrawTool *draw_too
GimpCanvasItem * gimp_draw_tool_add_text_cursor (GimpDrawTool *draw_tool,
PangoRectangle *cursor,
gboolean overwrite);
gboolean overwrite,
GimpTextDirection direction);
gboolean gimp_draw_tool_on_handle (GimpDrawTool *draw_tool,
GimpDisplay *display,
......
......@@ -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
(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 */
......@@ -467,6 +474,8 @@ gimp_text_tool_editor_key_press (GimpTextTool *text_tool,
return TRUE;
}
gimp_text_tool_convert_gdkkeyevent (text_tool, kevent);
gimp_text_tool_ensure_proxy (text_tool);
if (gtk_bindings_activate_event (G_OBJECT (text_tool->proxy_text_view),
......@@ -523,6 +532,8 @@ gimp_text_tool_editor_key_release (GimpTextTool *text_tool,
return TRUE;
}
gimp_text_tool_convert_gdkkeyevent (text_tool, kevent);
gimp_text_tool_ensure_proxy (text_tool);
if (gtk_bindings_activate_event (G_OBJECT (text_tool->proxy_text_view),
......@@ -598,6 +609,7 @@ gimp_text_tool_editor_get_cursor_rect (GimpTextTool *text_tool,
{
GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer);
PangoLayout *layout;
PangoContext *context;
gint offset_x;
gint offset_y;
GtkTextIter cursor;
......@@ -615,19 +627,66 @@ gimp_text_tool_editor_get_cursor_rect (GimpTextTool *text_tool,
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);
if (overwrite)
pango_layout_index_to_pos (layout, cursor_index, cursor_rect);
else
{
pango_layout_index_to_pos (layout, cursor_index, cursor_rect);
/* Avoid pango bug ? */
if (pango_context_get_base_gravity (context) == PANGO_GRAVITY_WEST &&
cursor_rect->width == 0)
pango_layout_get_cursor_pos (layout, cursor_index, cursor_rect, NULL);
}
else
pango_layout_get_cursor_pos (layout, cursor_index, cursor_rect, NULL);
gimp_text_layout_transform_rect (text_tool->layout, cursor_rect);
cursor_rect->x = PANGO_PIXELS (cursor_rect->x) + offset_x;
cursor_rect->y = PANGO_PIXELS (cursor_rect->y) + offset_y;
cursor_rect->width = PANGO_PIXELS (cursor_rect->width);
cursor_rect->height = PANGO_PIXELS (cursor_rect->height);
switch (gimp_text_tool_get_direction (text_tool))
{
case GIMP_TEXT_DIRECTION_LTR:
case GIMP_TEXT_DIRECTION_RTL:
cursor_rect->x = PANGO_PIXELS (cursor_rect->x) + offset_x;
cursor_rect->y = PANGO_PIXELS (cursor_rect->y) + offset_y;
cursor_rect->width = PANGO_PIXELS (cursor_rect->width);
cursor_rect->height = PANGO_PIXELS (cursor_rect->height);
break;
case GIMP_TEXT_DIRECTION_TTB_RTL:
case GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT:
{
gint temp, width, height;
gimp_text_layout_get_size (text_tool->layout, &width, &height);
temp = cursor_rect->x;
cursor_rect->x = width - PANGO_PIXELS (cursor_rect->y) + offset_x;
cursor_rect->y = PANGO_PIXELS (temp) + offset_y;
temp = cursor_rect->width;
cursor_rect->width = PANGO_PIXELS (cursor_rect->height);
cursor_rect->height = PANGO_PIXELS (temp);
}
break;
case GIMP_TEXT_DIRECTION_TTB_LTR:
case GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT:
{
gint temp, width, height;
gimp_text_layout_get_size (text_tool->layout, &width, &height);
temp = cursor_rect->x;
cursor_rect->x = PANGO_PIXELS (cursor_rect->y) + offset_x;
cursor_rect->y = height - PANGO_PIXELS (temp) + offset_y;
temp = cursor_rect->width;
cursor_rect->width = PANGO_PIXELS (cursor_rect->height);
cursor_rect->height = PANGO_PIXELS (temp);
}
break;
}
}
void
......@@ -1375,6 +1434,8 @@ gimp_text_tool_xy_to_iter (GimpTextTool *text_tool,
layout = gimp_text_layout_get_pango_layout (text_tool->layout);
gimp_text_tool_fix_position (text_tool, &x, &y);
pango_layout_xy_to_index (layout,
x * PANGO_SCALE,
y * PANGO_SCALE,
......@@ -1661,3 +1722,132 @@ gimp_text_tool_editor_copy_selection_to_clipboard (GimpTextTool *text_tool)
gtk_text_buffer_copy_clipboard (buffer, clipboard);
}
}
static void
gimp_text_tool_fix_position (GimpTextTool *text_tool,
gdouble *x,
gdouble *y)
{
gint temp, width, height;
gimp_text_layout_get_size (text_tool->layout, &width, &height);
switch (gimp_text_tool_get_direction(text_tool))
{
case GIMP_TEXT_DIRECTION_RTL:
case GIMP_TEXT_DIRECTION_LTR:
break;
case GIMP_TEXT_DIRECTION_TTB_RTL:
case GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT:
temp = width - *x;
*x = *y;
*y = temp;
break;
case GIMP_TEXT_DIRECTION_TTB_LTR:
case GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT:
temp = *x;
*x = height - *y;
*y = temp;
break;
}
}
static void
gimp_text_tool_convert_gdkkeyevent (GimpTextTool *text_tool,
GdkEventKey *kevent)
{
switch (gimp_text_tool_get_direction (text_tool))
{
case GIMP_TEXT_DIRECTION_LTR:
case GIMP_TEXT_DIRECTION_RTL:
break;
case GIMP_TEXT_DIRECTION_TTB_RTL:
case GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT:
#ifdef _WIN32
switch (kevent->keyval)
{
case GDK_KEY_Up:
kevent->hardware_keycode = 0x25;/* VK_LEFT */
kevent->keyval = GDK_KEY_Left;
break;
case GDK_KEY_Down:
kevent->hardware_keycode = 0x27;/* VK_RIGHT */
kevent->keyval = GDK_KEY_Right;
break;
case GDK_KEY_Left:
kevent->hardware_keycode = 0x28;/* VK_DOWN */
kevent->keyval = GDK_KEY_Down;
break;
case GDK_KEY_Right:
kevent->hardware_keycode = 0x26;/* VK_UP */
kevent->keyval = GDK_KEY_Up;
break;
}
#else
switch (kevent->keyval)
{
case GDK_KEY_Up:
kevent->hardware_keycode = 113;
kevent->keyval = GDK_KEY_Left;
break;
case GDK_KEY_Down:
kevent->hardware_keycode = 114;
kevent->keyval = GDK_KEY_Right;
break;
case GDK_KEY_Left:
kevent->hardware_keycode = 116;
kevent->keyval = GDK_KEY_Down;
break;
case GDK_KEY_Right:
kevent->hardware_keycode = 111;
kevent->keyval = GDK_KEY_Up;
break;
}
#endif
break;