diff --git a/app/actions/text-editor-actions.c b/app/actions/text-editor-actions.c
index 270bbc2d80..52bf963aa6 100644
--- a/app/actions/text-editor-actions.c
+++ b/app/actions/text-editor-actions.c
@@ -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
diff --git a/app/actions/text-tool-actions.c b/app/actions/text-tool-actions.c
index 9abf263523..66f9746cfb 100644
--- a/app/actions/text-tool-actions.c
+++ b/app/actions/text-tool-actions.c
@@ -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 }
};
diff --git a/app/display/gimpcanvastextcursor.c b/app/display/gimpcanvastextcursor.c
index 09cac03e9f..0e2780d723 100644
--- a/app/display/gimpcanvastextcursor.c
+++ b/app/display/gimpcanvastextcursor.c
@@ -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);
+ 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);
+ 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);
+ 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);
}
diff --git a/app/display/gimpcanvastextcursor.h b/app/display/gimpcanvastextcursor.h
index 6d930dcacf..210b2a25fb 100644
--- a/app/display/gimpcanvastextcursor.h
+++ b/app/display/gimpcanvastextcursor.h
@@ -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__ */
diff --git a/app/text/gimptextlayer.c b/app/text/gimptextlayer.c
index bfd5c8c544..525afb8dea 100644
--- a/app/text/gimptextlayer.c
+++ b/app/text/gimptextlayer.c
@@ -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)))
diff --git a/app/text/gimptextlayout-render.c b/app/text/gimptextlayout-render.c
index 7e401bd837..f3605e3361 100644
--- a/app/text/gimptextlayout-render.c
+++ b/app/text/gimptextlayout-render.c
@@ -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)
diff --git a/app/text/gimptextlayout.c b/app/text/gimptextlayout.c
index 069cac9b46..47beed7705 100644
--- a/app/text/gimptextlayout.c
+++ b/app/text/gimptextlayout.c
@@ -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;
}
diff --git a/app/tools/gimpdrawtool.c b/app/tools/gimpdrawtool.c
index e77aadf0b6..7b69f9b765 100644
--- a/app/tools/gimpdrawtool.c
+++ b/app/tools/gimpdrawtool.c
@@ -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);
diff --git a/app/tools/gimpdrawtool.h b/app/tools/gimpdrawtool.h
index 7552a097f1..de13001c26 100644
--- a/app/tools/gimpdrawtool.h
+++ b/app/tools/gimpdrawtool.h
@@ -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,
diff --git a/app/tools/gimptexttool-editor.c b/app/tools/gimptexttool-editor.c
index fa61e1520a..4921cb2f9c 100644
--- a/app/tools/gimptexttool-editor.c
+++ b/app/tools/gimptexttool-editor.c
@@ -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;
+ case GIMP_TEXT_DIRECTION_TTB_LTR:
+ case GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT:
+#ifdef _WIN32
+ switch (kevent->keyval)
+ {
+ case GDK_KEY_Up:
+ kevent->hardware_keycode = 0x26;/* VK_UP */
+ kevent->keyval = GDK_KEY_Up;
+ break;
+ case GDK_KEY_Down:
+ kevent->hardware_keycode = 0x28;/* VK_DOWN */
+ kevent->keyval = GDK_KEY_Down;
+ break;
+ case GDK_KEY_Left:
+ kevent->hardware_keycode = 0x25;/* VK_LEFT */
+ kevent->keyval = GDK_KEY_Left;
+ break;
+ case GDK_KEY_Right:
+ kevent->hardware_keycode = 0x27;/* VK_RIGHT */
+ kevent->keyval = GDK_KEY_Right;
+ break;
+ }
+#else
+ switch (kevent->keyval)
+ {
+ case GDK_KEY_Up:
+ kevent->hardware_keycode = 114;
+ kevent->keyval = GDK_KEY_Right;
+ break;
+ case GDK_KEY_Down:
+ kevent->hardware_keycode = 113;
+ kevent->keyval = GDK_KEY_Left;
+ break;
+ case GDK_KEY_Left:
+ kevent->hardware_keycode = 111;
+ kevent->keyval = GDK_KEY_Up;
+ break;
+ case GDK_KEY_Right:
+ kevent->hardware_keycode = 116;
+ kevent->keyval = GDK_KEY_Down;
+ break;
+ }
+#endif
+ break;
+ }
+}
diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c
index 6f4e6742dc..3e9f2eb24a 100644
--- a/app/tools/gimptexttool.c
+++ b/app/tools/gimptexttool.c
@@ -891,10 +891,11 @@ gimp_text_tool_draw (GimpDrawTool *draw_tool)
{
/* If the text buffer has no selection, draw the text cursor */
- GimpCanvasItem *item;
- PangoRectangle cursor_rect;
- gint off_x, off_y;
- gboolean overwrite;
+ GimpCanvasItem *item;
+ PangoRectangle cursor_rect;
+ gint off_x, off_y;
+ gboolean overwrite;
+ GimpTextDirection direction;
gimp_text_tool_editor_get_cursor_rect (text_tool,
text_tool->overwrite_mode,
@@ -906,8 +907,10 @@ gimp_text_tool_draw (GimpDrawTool *draw_tool)
overwrite = text_tool->overwrite_mode && cursor_rect.width != 0;
+ direction = gimp_text_tool_get_direction (text_tool);
+
item = gimp_draw_tool_add_text_cursor (draw_tool, &cursor_rect,
- overwrite);
+ overwrite, direction);
gimp_canvas_item_set_highlight (item, TRUE);
}
@@ -917,17 +920,20 @@ gimp_text_tool_draw (GimpDrawTool *draw_tool)
static void
gimp_text_tool_draw_selection (GimpDrawTool *draw_tool)
{
- GimpTextTool *text_tool = GIMP_TEXT_TOOL (draw_tool);
- GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer);
- GimpCanvasGroup *group;
- PangoLayout *layout;
- gint offset_x;
- gint offset_y;
- gint off_x, off_y;
- PangoLayoutIter *iter;
- GtkTextIter sel_start, sel_end;
- gint min, max;
- gint i;
+ GimpTextTool *text_tool = GIMP_TEXT_TOOL (draw_tool);
+ GtkTextBuffer *buffer = GTK_TEXT_BUFFER (text_tool->buffer);
+ GimpCanvasGroup *group;
+ PangoLayout *layout;
+ gint offset_x;
+ gint offset_y;
+ gint width;
+ gint height;
+ gint off_x, off_y;
+ PangoLayoutIter *iter;
+ GtkTextIter sel_start, sel_end;
+ gint min, max;
+ gint i;
+ GimpTextDirection direction;
group = gimp_draw_tool_add_stroke_group (draw_tool);
gimp_canvas_item_set_highlight (GIMP_CANVAS_ITEM (group), TRUE);
@@ -941,10 +947,14 @@ gimp_text_tool_draw_selection (GimpDrawTool *draw_tool)
gimp_text_layout_get_offsets (text_tool->layout, &offset_x, &offset_y);
+ gimp_text_layout_get_size (text_tool->layout, &width, &height);
+
gimp_item_get_offset (GIMP_ITEM (text_tool->layer), &off_x, &off_y);
offset_x += off_x;
offset_y += off_y;
+ direction = gimp_text_tool_get_direction (text_tool);
+
iter = pango_layout_get_iter (layout);
gimp_draw_tool_push_group (draw_tool, group);
@@ -971,12 +981,33 @@ gimp_text_tool_draw_selection (GimpDrawTool *draw_tool)
gimp_text_layout_transform_rect (text_tool->layout, &rect);
- rect.x += offset_x;
- rect.y += offset_y;
-
- gimp_draw_tool_add_rectangle (draw_tool, FALSE,
- rect.x, rect.y,
- rect.width, rect.height);
+ switch (direction)
+ {
+ case GIMP_TEXT_DIRECTION_LTR:
+ case GIMP_TEXT_DIRECTION_RTL:
+ rect.x += offset_x;
+ rect.y += offset_y;
+ gimp_draw_tool_add_rectangle (draw_tool, FALSE,
+ rect.x, rect.y,
+ rect.width, rect.height);
+ break;
+ case GIMP_TEXT_DIRECTION_TTB_RTL:
+ case GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT:
+ rect.y = offset_x - rect.y + width;
+ rect.x = offset_y + rect.x;
+ gimp_draw_tool_add_rectangle (draw_tool, FALSE,
+ rect.y, rect.x,
+ -rect.height, rect.width);
+ break;
+ case GIMP_TEXT_DIRECTION_TTB_LTR:
+ case GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT:
+ rect.y = offset_x + rect.y;
+ rect.x = offset_y - rect.x + height;
+ gimp_draw_tool_add_rectangle (draw_tool, FALSE,
+ rect.y, rect.x,
+ rect.height, -rect.width);
+ break;
+ }
}
}
while (pango_layout_iter_next_char (iter));
@@ -2264,3 +2295,10 @@ gimp_text_tool_create_vectors_warped (GimpTextTool *text_tool)
gimp_image_flush (text_tool->image);
}
+
+GimpTextDirection
+gimp_text_tool_get_direction (GimpTextTool *text_tool)
+{
+ GimpTextOptions *options = GIMP_TEXT_TOOL_GET_OPTIONS (text_tool);
+ return options->base_dir;
+}
diff --git a/app/tools/gimptexttool.h b/app/tools/gimptexttool.h
index d382ab9b6a..b463524440 100644
--- a/app/tools/gimptexttool.h
+++ b/app/tools/gimptexttool.h
@@ -119,6 +119,9 @@ void gimp_text_tool_paste_clipboard (GimpTextTool *text_tool);
void gimp_text_tool_create_vectors (GimpTextTool *text_tool);
void gimp_text_tool_create_vectors_warped (GimpTextTool *text_tool);
+GimpTextDirection
+ gimp_text_tool_get_direction (GimpTextTool *text_tool);
+
/* only for the text editor */
void gimp_text_tool_clear_layout (GimpTextTool *text_tool);
gboolean gimp_text_tool_ensure_layout (GimpTextTool *text_tool);
diff --git a/app/widgets/gimptexteditor.c b/app/widgets/gimptexteditor.c
index 953c7e3e80..dc25255cba 100644
--- a/app/widgets/gimptexteditor.c
+++ b/app/widgets/gimptexteditor.c
@@ -214,6 +214,10 @@ gimp_text_editor_new (const gchar *title,
switch (editor->base_dir)
{
case GIMP_TEXT_DIRECTION_LTR:
+ 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:
gtk_widget_set_direction (editor->view, GTK_TEXT_DIR_LTR);
break;
case GIMP_TEXT_DIRECTION_RTL:
@@ -286,6 +290,10 @@ gimp_text_editor_set_direction (GimpTextEditor *editor,
switch (editor->base_dir)
{
case GIMP_TEXT_DIRECTION_LTR:
+ 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:
gtk_widget_set_direction (editor->view, GTK_TEXT_DIR_LTR);
break;
case GIMP_TEXT_DIRECTION_RTL:
diff --git a/icons/Color/24/gimp-text-dir-ttb-ltr-upright.png b/icons/Color/24/gimp-text-dir-ttb-ltr-upright.png
new file mode 100644
index 0000000000..f955debd15
Binary files /dev/null and b/icons/Color/24/gimp-text-dir-ttb-ltr-upright.png differ
diff --git a/icons/Color/24/gimp-text-dir-ttb-ltr.png b/icons/Color/24/gimp-text-dir-ttb-ltr.png
new file mode 100644
index 0000000000..6bc4d84577
Binary files /dev/null and b/icons/Color/24/gimp-text-dir-ttb-ltr.png differ
diff --git a/icons/Color/24/gimp-text-dir-ttb-rtl-upright.png b/icons/Color/24/gimp-text-dir-ttb-rtl-upright.png
new file mode 100644
index 0000000000..66febba0a8
Binary files /dev/null and b/icons/Color/24/gimp-text-dir-ttb-rtl-upright.png differ
diff --git a/icons/Color/24/gimp-text-dir-ttb-rtl.png b/icons/Color/24/gimp-text-dir-ttb-rtl.png
new file mode 100644
index 0000000000..cf97823500
Binary files /dev/null and b/icons/Color/24/gimp-text-dir-ttb-rtl.png differ
diff --git a/icons/Color/scalable/gimp-text-dir-ttb-ltr-upright.svg b/icons/Color/scalable/gimp-text-dir-ttb-ltr-upright.svg
new file mode 100644
index 0000000000..c66ea41f2e
--- /dev/null
+++ b/icons/Color/scalable/gimp-text-dir-ttb-ltr-upright.svg
@@ -0,0 +1,290 @@
+
+
+
+
diff --git a/icons/Color/scalable/gimp-text-dir-ttb-ltr.svg b/icons/Color/scalable/gimp-text-dir-ttb-ltr.svg
new file mode 100644
index 0000000000..05b0deb01d
--- /dev/null
+++ b/icons/Color/scalable/gimp-text-dir-ttb-ltr.svg
@@ -0,0 +1,290 @@
+
+
+
+
diff --git a/icons/Color/scalable/gimp-text-dir-ttb-rtl-upright.svg b/icons/Color/scalable/gimp-text-dir-ttb-rtl-upright.svg
new file mode 100644
index 0000000000..714306ec0f
--- /dev/null
+++ b/icons/Color/scalable/gimp-text-dir-ttb-rtl-upright.svg
@@ -0,0 +1,190 @@
+
+
+
+
diff --git a/icons/Color/scalable/gimp-text-dir-ttb-rtl.svg b/icons/Color/scalable/gimp-text-dir-ttb-rtl.svg
new file mode 100644
index 0000000000..7606d33038
--- /dev/null
+++ b/icons/Color/scalable/gimp-text-dir-ttb-rtl.svg
@@ -0,0 +1,208 @@
+
+
+
+
diff --git a/icons/Legacy/24/gimp-text-dir-ttb-ltr-upright.png b/icons/Legacy/24/gimp-text-dir-ttb-ltr-upright.png
new file mode 100644
index 0000000000..08556b3b2a
Binary files /dev/null and b/icons/Legacy/24/gimp-text-dir-ttb-ltr-upright.png differ
diff --git a/icons/Legacy/24/gimp-text-dir-ttb-ltr-upright.xcf b/icons/Legacy/24/gimp-text-dir-ttb-ltr-upright.xcf
new file mode 100644
index 0000000000..f4ef93ff42
Binary files /dev/null and b/icons/Legacy/24/gimp-text-dir-ttb-ltr-upright.xcf differ
diff --git a/icons/Legacy/24/gimp-text-dir-ttb-ltr.png b/icons/Legacy/24/gimp-text-dir-ttb-ltr.png
new file mode 100644
index 0000000000..5445cb8509
Binary files /dev/null and b/icons/Legacy/24/gimp-text-dir-ttb-ltr.png differ
diff --git a/icons/Legacy/24/gimp-text-dir-ttb-ltr.xcf b/icons/Legacy/24/gimp-text-dir-ttb-ltr.xcf
new file mode 100644
index 0000000000..7eab269f9a
Binary files /dev/null and b/icons/Legacy/24/gimp-text-dir-ttb-ltr.xcf differ
diff --git a/icons/Legacy/24/gimp-text-dir-ttb-rtl-upright.png b/icons/Legacy/24/gimp-text-dir-ttb-rtl-upright.png
new file mode 100644
index 0000000000..7361e95bf5
Binary files /dev/null and b/icons/Legacy/24/gimp-text-dir-ttb-rtl-upright.png differ
diff --git a/icons/Legacy/24/gimp-text-dir-ttb-rtl-upright.xcf b/icons/Legacy/24/gimp-text-dir-ttb-rtl-upright.xcf
new file mode 100644
index 0000000000..711c0c6563
Binary files /dev/null and b/icons/Legacy/24/gimp-text-dir-ttb-rtl-upright.xcf differ
diff --git a/icons/Legacy/24/gimp-text-dir-ttb-rtl.png b/icons/Legacy/24/gimp-text-dir-ttb-rtl.png
new file mode 100644
index 0000000000..3d622f4df3
Binary files /dev/null and b/icons/Legacy/24/gimp-text-dir-ttb-rtl.png differ
diff --git a/icons/Legacy/24/gimp-text-dir-ttb-rtl.xcf b/icons/Legacy/24/gimp-text-dir-ttb-rtl.xcf
new file mode 100644
index 0000000000..d4746f028b
Binary files /dev/null and b/icons/Legacy/24/gimp-text-dir-ttb-rtl.xcf differ
diff --git a/icons/Legacy/Makefile.am b/icons/Legacy/Makefile.am
index a5f8d57cbf..a16c12634a 100644
--- a/icons/Legacy/Makefile.am
+++ b/icons/Legacy/Makefile.am
@@ -389,6 +389,10 @@ icons24_DATA = \
24/gimp-print-resolution.png \
24/gimp-sample-point.png \
24/gimp-template.png \
+ 24/gimp-text-dir-ttb-rtl.png \
+ 24/gimp-text-dir-ttb-rtl-upright.png \
+ 24/gimp-text-dir-ttb-ltr.png \
+ 24/gimp-text-dir-ttb-ltr-upright.png \
24/gimp-text-layer.png \
24/gimp-toilet-paper.png \
24/gimp-tool-options.png \
diff --git a/icons/Symbolic/24/gimp-text-dir-ttb-ltr-upright.png b/icons/Symbolic/24/gimp-text-dir-ttb-ltr-upright.png
new file mode 100644
index 0000000000..87461c4937
Binary files /dev/null and b/icons/Symbolic/24/gimp-text-dir-ttb-ltr-upright.png differ
diff --git a/icons/Symbolic/24/gimp-text-dir-ttb-ltr.png b/icons/Symbolic/24/gimp-text-dir-ttb-ltr.png
new file mode 100644
index 0000000000..03412a184f
Binary files /dev/null and b/icons/Symbolic/24/gimp-text-dir-ttb-ltr.png differ
diff --git a/icons/Symbolic/24/gimp-text-dir-ttb-rtl-upright.png b/icons/Symbolic/24/gimp-text-dir-ttb-rtl-upright.png
new file mode 100644
index 0000000000..90fdf0156c
Binary files /dev/null and b/icons/Symbolic/24/gimp-text-dir-ttb-rtl-upright.png differ
diff --git a/icons/Symbolic/24/gimp-text-dir-ttb-rtl.png b/icons/Symbolic/24/gimp-text-dir-ttb-rtl.png
new file mode 100644
index 0000000000..830a9c7a60
Binary files /dev/null and b/icons/Symbolic/24/gimp-text-dir-ttb-rtl.png differ
diff --git a/icons/Symbolic/scalable/gimp-text-dir-ttb-ltr-symbolic.svg b/icons/Symbolic/scalable/gimp-text-dir-ttb-ltr-symbolic.svg
new file mode 100644
index 0000000000..4c5db3a24c
--- /dev/null
+++ b/icons/Symbolic/scalable/gimp-text-dir-ttb-ltr-symbolic.svg
@@ -0,0 +1,174 @@
+
+
diff --git a/icons/Symbolic/scalable/gimp-text-dir-ttb-ltr-upright-symbolic.svg b/icons/Symbolic/scalable/gimp-text-dir-ttb-ltr-upright-symbolic.svg
new file mode 100644
index 0000000000..c7512b02f4
--- /dev/null
+++ b/icons/Symbolic/scalable/gimp-text-dir-ttb-ltr-upright-symbolic.svg
@@ -0,0 +1,174 @@
+
+
diff --git a/icons/Symbolic/scalable/gimp-text-dir-ttb-rtl-symbolic.svg b/icons/Symbolic/scalable/gimp-text-dir-ttb-rtl-symbolic.svg
new file mode 100644
index 0000000000..9fa67ff9f4
--- /dev/null
+++ b/icons/Symbolic/scalable/gimp-text-dir-ttb-rtl-symbolic.svg
@@ -0,0 +1,173 @@
+
+
diff --git a/icons/Symbolic/scalable/gimp-text-dir-ttb-rtl-upright-symbolic.svg b/icons/Symbolic/scalable/gimp-text-dir-ttb-rtl-upright-symbolic.svg
new file mode 100644
index 0000000000..8f9b3550fb
--- /dev/null
+++ b/icons/Symbolic/scalable/gimp-text-dir-ttb-rtl-upright-symbolic.svg
@@ -0,0 +1,173 @@
+
+
diff --git a/icons/icon-list.mk b/icons/icon-list.mk
index 49dabe0b47..e50f1fc4d5 100644
--- a/icons/icon-list.mk
+++ b/icons/icon-list.mk
@@ -255,6 +255,10 @@ color_scalable_images = \
scalable/gimp-swap-colors.svg \
scalable/gimp-symmetry.svg \
scalable/gimp-template.svg \
+ scalable/gimp-text-dir-ttb-rtl.svg \
+ scalable/gimp-text-dir-ttb-rtl-upright.svg \
+ scalable/gimp-text-dir-ttb-ltr.svg \
+ scalable/gimp-text-dir-ttb-ltr-upright.svg \
scalable/gimp-text-layer.svg \
scalable/gimp-toilet-paper.svg \
scalable/gimp-tool-airbrush.svg \
@@ -751,6 +755,10 @@ symbolic_scalable_images = \
scalable/gimp-swap-colors-symbolic.svg \
scalable/gimp-symmetry-symbolic.svg \
scalable/gimp-template-symbolic.svg \
+ scalable/gimp-text-dir-ttb-rtl-symbolic.svg \
+ scalable/gimp-text-dir-ttb-rtl-upright-symbolic.svg \
+ scalable/gimp-text-dir-ttb-ltr-symbolic.svg \
+ scalable/gimp-text-dir-ttb-ltr-upright-symbolic.svg \
scalable/gimp-text-layer-symbolic.svg \
scalable/gimp-toilet-paper-symbolic.svg \
scalable/gimp-tool-airbrush-symbolic.svg \
@@ -1419,6 +1427,10 @@ icons24_images = \
24/gimp-smartphone.png \
24/gimp-symmetry.png \
24/gimp-template.png \
+ 24/gimp-text-dir-ttb-rtl.png \
+ 24/gimp-text-dir-ttb-rtl-upright.png \
+ 24/gimp-text-dir-ttb-ltr.png \
+ 24/gimp-text-dir-ttb-ltr-upright.png \
24/gimp-text-layer.png \
24/gimp-toilet-paper.png \
24/gimp-tool-airbrush.png \
diff --git a/libgimpbase/gimpbaseenums.c b/libgimpbase/gimpbaseenums.c
index 003eda0273..83dfe2ef2a 100644
--- a/libgimpbase/gimpbaseenums.c
+++ b/libgimpbase/gimpbaseenums.c
@@ -1795,6 +1795,10 @@ gimp_text_direction_get_type (void)
{
{ GIMP_TEXT_DIRECTION_LTR, "GIMP_TEXT_DIRECTION_LTR", "ltr" },
{ GIMP_TEXT_DIRECTION_RTL, "GIMP_TEXT_DIRECTION_RTL", "rtl" },
+ { GIMP_TEXT_DIRECTION_TTB_RTL, "GIMP_TEXT_DIRECTION_TTB_RTL", "ttb-rtl" },
+ { GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT, "GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT", "ttb-rtl-upright" },
+ { GIMP_TEXT_DIRECTION_TTB_LTR, "GIMP_TEXT_DIRECTION_TTB_LTR", "ttb-ltr" },
+ { GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT, "GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT", "ttb-ltr-upright" },
{ 0, NULL, NULL }
};
@@ -1802,6 +1806,10 @@ gimp_text_direction_get_type (void)
{
{ GIMP_TEXT_DIRECTION_LTR, NC_("text-direction", "From left to right"), NULL },
{ GIMP_TEXT_DIRECTION_RTL, NC_("text-direction", "From right to left"), NULL },
+ { GIMP_TEXT_DIRECTION_TTB_RTL, NC_("text-direction", "Characters are from top to bottom, Lines are from right to left"), NULL },
+ { GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT, NC_("text-direction", "Upright characters are from top to bottom, Lines are from right to left"), NULL },
+ { GIMP_TEXT_DIRECTION_TTB_LTR, NC_("text-direction", "Characters are from top to bottom, Lines are from left to right"), NULL },
+ { GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT, NC_("text-direction", "Upright characters are from top to bottom, Lines are from left to right"), NULL },
{ 0, NULL, NULL }
};
diff --git a/libgimpbase/gimpbaseenums.h b/libgimpbase/gimpbaseenums.h
index edc507a8d9..6a4d9e3ec8 100644
--- a/libgimpbase/gimpbaseenums.h
+++ b/libgimpbase/gimpbaseenums.h
@@ -1226,6 +1226,10 @@ typedef enum
* GimpTextDirection:
* @GIMP_TEXT_DIRECTION_LTR: From left to right
* @GIMP_TEXT_DIRECTION_RTL: From right to left
+ * @GIMP_TEXT_DIRECTION_TTB_RTL: Characters are from top to bottom, Lines are from right to left
+ * @GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT: Upright characters are from top to bottom, Lines are from right to left
+ * @GIMP_TEXT_DIRECTION_TTB_LTR: Characters are from top to bottom, Lines are from left to right
+ * @GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT: Upright characters are from top to bottom, Lines are from left to right
*
* Text directions.
**/
@@ -1235,8 +1239,12 @@ GType gimp_text_direction_get_type (void) G_GNUC_CONST;
typedef enum
{
- GIMP_TEXT_DIRECTION_LTR, /*< desc="From left to right" >*/
- GIMP_TEXT_DIRECTION_RTL /*< desc="From right to left" >*/
+ GIMP_TEXT_DIRECTION_LTR, /*< desc="From left to right" >*/
+ GIMP_TEXT_DIRECTION_RTL, /*< desc="From right to left" >*/
+ GIMP_TEXT_DIRECTION_TTB_RTL, /*< desc="Characters are from top to bottom, Lines are from right to left" >*/
+ GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT, /*< desc="Upright characters are from top to bottom, Lines are from right to left" >*/
+ GIMP_TEXT_DIRECTION_TTB_LTR, /*< desc="Characters are from top to bottom, Lines are from left to right" >*/
+ GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT /*< desc="Upright characters are from top to bottom, Lines are from left to right" >*/
} GimpTextDirection;
diff --git a/libgimpwidgets/gimpicons.h b/libgimpwidgets/gimpicons.h
index 11a88b490d..2be4d0be22 100644
--- a/libgimpwidgets/gimpicons.h
+++ b/libgimpwidgets/gimpicons.h
@@ -218,6 +218,10 @@ G_BEGIN_DECLS
#define GIMP_ICON_FORMAT_TEXT_UNDERLINE "format-text-underline"
#define GIMP_ICON_FORMAT_TEXT_DIRECTION_LTR "format-text-direction-ltr"
#define GIMP_ICON_FORMAT_TEXT_DIRECTION_RTL "format-text-direction-rtl"
+#define GIMP_ICON_FORMAT_TEXT_DIRECTION_TTB_RTL "gimp-text-dir-ttb-rtl" /* use FDO */
+#define GIMP_ICON_FORMAT_TEXT_DIRECTION_TTB_RTL_UPRIGHT "gimp-text-dir-ttb-rtl-upright" /* use FDO */
+#define GIMP_ICON_FORMAT_TEXT_DIRECTION_TTB_LTR "gimp-text-dir-ttb-ltr" /* use FDO */
+#define GIMP_ICON_FORMAT_TEXT_DIRECTION_TTB_LTR_UPRIGHT "gimp-text-dir-ttb-ltr-upright" /* use FDO */
#define GIMP_ICON_FORMAT_TEXT_SPACING_LETTER "gimp-letter-spacing"
#define GIMP_ICON_FORMAT_TEXT_SPACING_LINE "gimp-line-spacing"
diff --git a/menus/text-editor-toolbar.xml b/menus/text-editor-toolbar.xml
index 9d23692c03..d1e096fee5 100644
--- a/menus/text-editor-toolbar.xml
+++ b/menus/text-editor-toolbar.xml
@@ -8,5 +8,9 @@