summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: de6a6af)
raw | patch | inline | side by side (parent: de6a6af)
author | tavmjong-free <tavmjong@free.fr> | |
Fri, 14 May 2010 20:13:53 +0000 (22:13 +0200) | ||
committer | tavmjong-free <tavmjong@free.fr> | |
Fri, 14 May 2010 20:13:53 +0000 (22:13 +0200) |
text toolbar along with routines needed by them.
diff --git a/src/sp-text.cpp b/src/sp-text.cpp
index 11665b89072002f98ea55365f763c1edab232021..0f21b59d19a237b0129942442e89db47661d1cbf 100644 (file)
--- a/src/sp-text.cpp
+++ b/src/sp-text.cpp
@@ -926,6 +926,50 @@ void TextTagAttributes::transform(Geom::Matrix const &matrix, double scale_x, do
*it = it->computed * scale_y;
}
+double TextTagAttributes::getDx(unsigned index)
+{
+ if( attributes.dx.size() == 0 ) {
+ return 0.0;
+ }
+ if( index < attributes.dx.size() ) {
+ return attributes.dx[index].computed;
+ } else {
+ return 0.0; // attributes.dx.back().computed;
+ }
+}
+
+
+double TextTagAttributes::getDy(unsigned index)
+{
+ if( attributes.dy.size() == 0 ) {
+ return 0.0;
+ }
+ if( index < attributes.dy.size() ) {
+ return attributes.dy[index].computed;
+ } else {
+ return 0.0; // attributes.dy.back().computed;
+ }
+}
+
+
+void TextTagAttributes::addToDx(unsigned index, double delta)
+{
+ SVGLength zero_length;
+ zero_length = 0.0;
+
+ if (attributes.dx.size() < index + 1) attributes.dx.resize(index + 1, zero_length);
+ attributes.dx[index] = attributes.dx[index].computed + delta;
+}
+
+void TextTagAttributes::addToDy(unsigned index, double delta)
+{
+ SVGLength zero_length;
+ zero_length = 0.0;
+
+ if (attributes.dy.size() < index + 1) attributes.dy.resize(index + 1, zero_length);
+ attributes.dy[index] = attributes.dy[index].computed + delta;
+}
+
void TextTagAttributes::addToDxDy(unsigned index, Geom::Point const &adjust)
{
SVGLength zero_length;
}
}
+double TextTagAttributes::getRotate(unsigned index)
+{
+ if( attributes.rotate.size() == 0 ) {
+ return 0.0;
+ }
+ if( index < attributes.rotate.size() ) {
+ return attributes.rotate[index].computed;
+ } else {
+ return attributes.rotate.back().computed;
+ }
+}
+
+
void TextTagAttributes::addToRotate(unsigned index, double delta)
{
SVGLength zero_length;
}
+void TextTagAttributes::setRotate(unsigned index, double angle)
+{
+ SVGLength zero_length;
+ zero_length = 0.0;
+
+ if (attributes.rotate.size() < index + 2) {
+ if (attributes.rotate.empty())
+ attributes.rotate.resize(index + 2, zero_length);
+ else
+ attributes.rotate.resize(index + 2, attributes.rotate.back());
+ }
+ attributes.rotate[index] = mod360(angle);
+}
+
+
/*
Local Variables:
mode:c++
diff --git a/src/text-editing.cpp b/src/text-editing.cpp
index e93ebdffada702e11ceb028c2c4a4f9c91b96bb9..372f5026d54acb5bd0421a776e4bf2edace5de87 100644 (file)
--- a/src/text-editing.cpp
+++ b/src/text-editing.cpp
/** Returns the attributes block and the character index within that block
which represents the iterator \a position. */
-static TextTagAttributes*
+TextTagAttributes*
text_tag_attributes_at_position(SPItem *item, Inkscape::Text::Layout::iterator const &position, unsigned *char_index)
{
if (item == NULL || char_index == NULL || !SP_IS_TEXT(item))
@@ -972,6 +972,36 @@ sp_te_adjust_kerning_screen (SPItem *item, Inkscape::Text::Layout::iterator cons
item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
+void
+sp_te_adjust_dx (SPItem *item, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPDesktop *desktop, double delta)
+{
+ unsigned char_index;
+ TextTagAttributes *attributes = text_tag_attributes_at_position(item, std::min(start, end), &char_index);
+ if (attributes) attributes->addToDx(char_index, delta);
+ if (start != end) {
+ attributes = text_tag_attributes_at_position(item, std::max(start, end), &char_index);
+ if (attributes) attributes->addToDx(char_index, -delta);
+ }
+
+ item->updateRepr();
+ item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+}
+
+void
+sp_te_adjust_dy (SPItem *item, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPDesktop *desktop, double delta)
+{
+ unsigned char_index;
+ TextTagAttributes *attributes = text_tag_attributes_at_position(item, std::min(start, end), &char_index);
+ if (attributes) attributes->addToDy(char_index, delta);
+ if (start != end) {
+ attributes = text_tag_attributes_at_position(item, std::max(start, end), &char_index);
+ if (attributes) attributes->addToDy(char_index, -delta);
+ }
+
+ item->updateRepr();
+ item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+}
+
void
sp_te_adjust_rotation_screen(SPItem *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPDesktop *desktop, gdouble pixels)
{
@@ -1011,6 +1041,25 @@ sp_te_adjust_rotation(SPItem *text, Inkscape::Text::Layout::iterator const &star
text->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
+void
+sp_te_set_rotation(SPItem *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPDesktop */*desktop*/, gdouble degrees)
+{
+ unsigned char_index;
+ TextTagAttributes *attributes = text_tag_attributes_at_position(text, std::min(start, end), &char_index);
+ if (attributes == NULL) return;
+
+ if (start != end) {
+ for (Inkscape::Text::Layout::iterator it = std::min(start, end) ; it != std::max(start, end) ; it.nextCharacter()) {
+ attributes = text_tag_attributes_at_position(text, it, &char_index);
+ if (attributes) attributes->setRotate(char_index, degrees);
+ }
+ } else
+ attributes->setRotate(char_index, degrees);
+
+ text->updateRepr();
+ text->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+}
+
void
sp_te_adjust_tspan_letterspacing_screen(SPItem *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPDesktop *desktop, gdouble by)
{
diff --git a/src/text-editing.h b/src/text-editing.h
index 7e845dbc905dff38e9d6d1b93ee341de6f727261..038458ff7af4eecaf12dda0ecb68b3b3f24cd78d 100644 (file)
--- a/src/text-editing.h
+++ b/src/text-editing.h
#include <utility> // std::pair
#include "libnrtype/Layout-TNG.h"
#include <libnr/nr-forward.h>
+#include "text-tag-attributes.h"
class SPCSSAttr;
struct SPItem;
Glib::ustring sp_te_get_string_multiline(SPItem const *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end);
void sp_te_set_repr_text_multiline(SPItem *text, gchar const *str);
+TextTagAttributes*
+text_tag_attributes_at_position(SPItem *item, Inkscape::Text::Layout::iterator const &position, unsigned *char_index);
+
void sp_te_adjust_kerning_screen(SPItem *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPDesktop *desktop, Geom::Point by);
+void sp_te_adjust_dx (SPItem *item, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPDesktop *desktop, double delta);
+void sp_te_adjust_dy (SPItem *item, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPDesktop *desktop, double delta);
void sp_te_adjust_rotation_screen(SPItem *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPDesktop *desktop, gdouble pixels);
void sp_te_adjust_rotation(SPItem *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPDesktop *desktop, gdouble degrees);
+void sp_te_set_rotation(SPItem *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPDesktop *desktop, gdouble degrees);
void sp_te_adjust_tspan_letterspacing_screen(SPItem *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPDesktop *desktop, gdouble by);
void sp_te_adjust_linespacing_screen(SPItem *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPDesktop *desktop, gdouble by);
index 7a7ba576359f59e1e0ba09560bda3e7d54717739..197bfb73fb44a6180e316d3ca9e6d6a1c29f83c9 100644 (file)
position. */
void transform(Geom::Matrix const &matrix, double scale_x, double scale_y, bool extend_zero_length = false);
+ /** Gets current value of dx vector at \a index. */
+ double getDx(unsigned index);
+
+ /** Gets current value of dy vector at \a index. */
+ double getDy(unsigned index);
+
+ /** Adds the given value to the dx vector at the given
+ \a index. The vector is extended if necessary. */
+ void addToDx(unsigned index, double delta);
+
+ /** Adds the given value to the dy vector at the given
+ \a index. The vector is extended if necessary. */
+ void addToDy(unsigned index, double delta);
+
/** Adds the given values to the dx and dy vectors at the given
\a index. The vectors are extended if necessary. */
void addToDxDy(unsigned index, Geom::Point const &adjust);
+ /** Gets current value of rotate vector at \a index. */
+ double getRotate(unsigned index);
+
/** Adds the given value to the rotate vector at the given \a index. The
vector is extended if necessary. Delta is measured in degrees, clockwise
positive. */
void addToRotate(unsigned index, double delta);
+ /** Sets rotate vector at the given \a index. The vector is extended if
+ necessary. Angle is measured in degrees, clockwise positive. */
+ void setRotate(unsigned index, double angle);
+
/** Returns the first coordinates in the x and y vectors. If either
is zero length, 0.0 is used for that coordinate. */
Geom::Point firstXY() const;
index 6a5ac6ebef4d8da85aa5ed95f25e3bd299c91034..4078fec06c36ba626673903537ab68429d60924a 100644 (file)
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
#include "../sp-text.h"
#include "../style.h"
#include "../svg/css-ostringstream.h"
+#include "../text-context.h"
+#include "../text-editing.h"
#include "../tools-switch.h"
#include "../tweak-context.h"
#include "../spray-context.h"
" <toolitem action='TextLineHeightAction' />"
" <toolitem action='TextLetterSpacingAction' />"
" <toolitem action='TextWordSpacingAction' />"
+ " <toolitem action='TextDxAction' />"
+ " <toolitem action='TextDyAction' />"
+ " <toolitem action='TextRotationAction' />"
" <separator />"
" <toolitem action='TextOrientationAction' />"
" </toolbar>"
@@ -6869,6 +6874,82 @@ static void sp_text_letterspacing_value_changed( GtkAdjustment *adj, GObject *tb
g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
}
+
+static void sp_text_dx_value_changed( GtkAdjustment *adj, GObject *tbl )
+{
+ // quit if run by the _changed callbacks
+ if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
+ return;
+ }
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
+
+ gdouble new_dx = adj->value;
+
+ SPTextContext *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context);
+ if( tc ) {
+ unsigned char_index = -1;
+ TextTagAttributes *attributes =
+ text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index );
+ if( attributes ) {
+ double old_dx = attributes->getDx( char_index );
+ double delta_dx = new_dx - old_dx;
+ sp_te_adjust_dx( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_dx );
+ }
+ }
+
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
+}
+
+static void sp_text_dy_value_changed( GtkAdjustment *adj, GObject *tbl )
+{
+ // quit if run by the _changed callbacks
+ if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
+ return;
+ }
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
+
+ gdouble new_dy = adj->value;
+
+ SPTextContext *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context);
+ if( tc ) {
+ unsigned char_index = -1;
+ TextTagAttributes *attributes =
+ text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index );
+ if( attributes ) {
+ double old_dy = attributes->getDy( char_index );
+ double delta_dy = new_dy - old_dy;
+ sp_te_adjust_dy( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_dy );
+ }
+ }
+
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
+}
+
+static void sp_text_rotation_value_changed( GtkAdjustment *adj, GObject *tbl )
+{
+ // quit if run by the _changed callbacks
+ if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
+ return;
+ }
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
+
+ gdouble new_degrees = adj->value;
+
+ SPTextContext *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context);
+ if( tc ) {
+ unsigned char_index = -1;
+ TextTagAttributes *attributes =
+ text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index );
+ if( attributes ) {
+ double old_degrees = attributes->getRotate( char_index );
+ double delta_deg = new_degrees - old_degrees;
+ sp_te_adjust_rotation( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_deg );
+ }
+ }
+
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
+}
+
static void sp_text_orientation_mode_changed( EgeSelectOneAction *act, GObject *tbl )
{
// quit if run by the _changed callbacks
@@ -6938,6 +7019,9 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/
const gchar* id = SP_OBJECT_ID((SPItem *) items->data);
std::cout << " " << id << std::endl;
}
+ Glib::ustring selected_text = sp_text_get_selected_text((SP_ACTIVE_DESKTOP)->event_context);
+ std::cout << " Selected text:" << std::endl;
+ std::cout << selected_text << std::endl;
#endif
// quit if run by the _changed callbacks
@@ -7116,7 +7200,6 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/
ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( letterSpacingAction ));
gtk_adjustment_set_value( letterSpacingAdjustment, letterSpacing );
-
// Orientation
int activeButton2 = (query->writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB ? 0 : 1);
@@ -7146,12 +7229,52 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/
<< " letter_spacing.value: " << query->letter_spacing.value
<< " letter_spacing.unit: " << query->letter_spacing.unit << std::endl;
std::cout << " GUI: writing_mode.computed: " << query->writing_mode.computed << std::endl;
- std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl;
- std::cout << std::endl;
#endif
sp_style_unref(query);
+ // Kerning (xshift), yshift, rotation. NB: These are not CSS attributes.
+ SPTextContext *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context);
+ if( tc ) {
+ unsigned char_index = -1;
+ TextTagAttributes *attributes =
+ text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index );
+ if( attributes ) {
+
+ // Dx
+ double dx = attributes->getDx( char_index );
+ GtkAction* dxAction = GTK_ACTION( g_object_get_data( tbl, "TextDxAction" ));
+ GtkAdjustment *dxAdjustment =
+ ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( dxAction ));
+ gtk_adjustment_set_value( dxAdjustment, dx );
+
+ // Dy
+ double dy = attributes->getDy( char_index );
+ GtkAction* dyAction = GTK_ACTION( g_object_get_data( tbl, "TextDyAction" ));
+ GtkAdjustment *dyAdjustment =
+ ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( dyAction ));
+ gtk_adjustment_set_value( dyAdjustment, dy );
+
+ // Rotation
+ double rotation = attributes->getRotate( char_index );
+ GtkAction* rotationAction = GTK_ACTION( g_object_get_data( tbl, "TextRotationAction" ));
+ GtkAdjustment *rotationAdjustment =
+ ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( rotationAction ));
+ gtk_adjustment_set_value( rotationAdjustment, rotation );
+
+#ifdef DEBUG_TEXT
+ std::cout << " GUI: Dx: " << dx << std::endl;
+ std::cout << " GUI: Dy: " << dy << std::endl;
+ std::cout << " GUI: Rotation: " << rotation << std::endl;
+#endif
+ }
+ }
+
+#ifdef DEBUG_TEXT
+ std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl;
+ std::cout << std::endl;
+#endif
+
g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
}
@@ -7452,6 +7575,96 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
g_object_set_data( holder, "TextLetterSpacingAction", eact );
}
+ /* Character kerning (horizontal shift) */
+ {
+ // Drop down menu
+ gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ gdouble values[] = { -2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5 };
+
+ EgeAdjustmentAction *eact = create_adjustment_action(
+ "TextDxAction", /* name */
+ _("Kerning"), /* label */
+ _("Kern:"), /* short label */
+ _("Kerning (horizontal shift of characters)."), /* tooltip */
+ "/tools/text/dx", /* path? */
+ 0.0, /* default */
+ GTK_WIDGET(desktop->canvas), /* focusTarget */
+ NULL, /* unit selector */
+ holder, /* dataKludge */
+ FALSE, /* set alt-x keyboard shortcut? */
+ NULL, /* altx_mark */
+ -100.0, 100.0, 0.01, 0.1, /* lower, upper, step (arrow up/down), page up/down */
+ labels, values, G_N_ELEMENTS(labels), /* drop down menu */
+ sp_text_dx_value_changed, /* callback */
+ 0.1, /* step (used?) */
+ 2, /* digits to show */
+ 1.0 /* factor (multiplies default) */
+ );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+ gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
+ g_object_set_data( holder, "TextDxAction", eact );
+ }
+
+ /* Character vertical shift */
+ {
+ // Drop down menu
+ gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ gdouble values[] = { -2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5 };
+
+ EgeAdjustmentAction *eact = create_adjustment_action(
+ "TextDyAction", /* name */
+ _("Vertical Shift"), /* label */
+ _("Vert:"), /* short label */
+ _("Vertical shift of characters."), /* tooltip */
+ "/tools/text/dy", /* path? */
+ 0.0, /* default */
+ GTK_WIDGET(desktop->canvas), /* focusTarget */
+ NULL, /* unit selector */
+ holder, /* dataKludge */
+ FALSE, /* set alt-x keyboard shortcut? */
+ NULL, /* altx_mark */
+ -100.0, 100.0, 0.01, 0.1, /* lower, upper, step (arrow up/down), page up/down */
+ labels, values, G_N_ELEMENTS(labels), /* drop down menu */
+ sp_text_dy_value_changed, /* callback */
+ 0.1, /* step (used?) */
+ 2, /* digits to show */
+ 1.0 /* factor (multiplies default) */
+ );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+ gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
+ g_object_set_data( holder, "TextDyAction", eact );
+ }
+
+ /* Character rotation */
+ {
+ // Drop down menu
+ gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ gdouble values[] = { -90, -45, -30, -15, 0, 15, 30, 45, 90, 180 };
+
+ EgeAdjustmentAction *eact = create_adjustment_action(
+ "TextRotationAction", /* name */
+ _("Letter rotation"), /* label */
+ _("Rot:"), /* short label */
+ _("Rotation of selected characters (degrees)."),/* tooltip */
+ "/tools/text/letterspacing", /* path? */
+ 0.0, /* default */
+ GTK_WIDGET(desktop->canvas), /* focusTarget */
+ NULL, /* unit selector */
+ holder, /* dataKludge */
+ FALSE, /* set alt-x keyboard shortcut? */
+ NULL, /* altx_mark */
+ -180.0, 180.0, 0.1, 1.0, /* lower, upper, step (arrow up/down), page up/down */
+ labels, values, G_N_ELEMENTS(labels), /* drop down menu */
+ sp_text_rotation_value_changed, /* callback */
+ 0.1, /* step (used?) */
+ 2, /* digits to show */
+ 1.0 /* factor (multiplies default) */
+ );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+ gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
+ g_object_set_data( holder, "TextRotationAction", eact );
+ }
+
// Is this necessary to call? Shouldn't hurt.
sp_text_toolbox_selection_changed(sp_desktop_selection(desktop), holder);