summaryrefslogtreecommitdiffstats
path: root/src/text-editing.cpp
diff options
context:
space:
mode:
authorMartin Owens <doctormo@gmail.com>2014-03-27 01:33:44 +0000
committerMartin Owens <doctormo@gmail.com>2014-03-27 01:33:44 +0000
commit5a4fb2325f60d292b47330f540b26a3279341c90 (patch)
treed2aa7967be25450b83e625025366c618101ae49f /src/text-editing.cpp
parentThe Polar Arrange Tab of the Arrange Dialog now hides the parametric (diff)
parentRemove Snap menu item and improve grid menu item text (diff)
downloadinkscape-5a4fb2325f60d292b47330f540b26a3279341c90.tar.gz
inkscape-5a4fb2325f60d292b47330f540b26a3279341c90.zip
Commit a merge to trunk, with probabal errors
(bzr r11073.1.36)
Diffstat (limited to 'src/text-editing.cpp')
-rw-r--r--src/text-editing.cpp88
1 files changed, 62 insertions, 26 deletions
diff --git a/src/text-editing.cpp b/src/text-editing.cpp
index 8f005d86a..cae123616 100644
--- a/src/text-editing.cpp
+++ b/src/text-editing.cpp
@@ -24,16 +24,18 @@
#include "inkscape.h"
#include "message-stack.h"
#include "style.h"
-#include "unit-constants.h"
+#include "util/units.h"
#include "document.h"
#include "xml/repr.h"
#include "xml/attribute-record.h"
+#include "xml/sp-css-attr.h"
#include "sp-textpath.h"
#include "sp-flowtext.h"
#include "sp-flowdiv.h"
#include "sp-flowregion.h"
+#include "sp-item-group.h"
#include "sp-tref.h"
#include "sp-tspan.h"
@@ -41,7 +43,7 @@
static const gchar *tref_edit_message = _("You cannot edit <b>cloned character data</b>.");
-static bool tidy_xml_tree_recursively(SPObject *root);
+static bool tidy_xml_tree_recursively(SPObject *root, bool has_text_decoration);
Inkscape::Text::Layout const * te_get_layout (SPItem const *item)
{
@@ -62,6 +64,22 @@ static void te_update_layout_now (SPItem *item)
item->updateRepr();
}
+void te_update_layout_now_recursive(SPItem *item)
+{
+ if (SP_IS_GROUP(item)) {
+ GSList *item_list = sp_item_group_item_list(SP_GROUP(item));
+ for(GSList* elem = item_list; elem; elem = elem->next) {
+ SPItem* list_item = static_cast<SPItem*>(elem->data);
+ te_update_layout_now_recursive(list_item);
+ }
+ g_slist_free(item_list);
+ } else if (SP_IS_TEXT(item))
+ SP_TEXT(item)->rebuildLayout();
+ else if (SP_IS_FLOWTEXT (item))
+ SP_FLOWTEXT(item)->rebuildLayout();
+ item->updateRepr();
+}
+
bool sp_te_output_is_empty(SPItem const *item)
{
Inkscape::Text::Layout const *layout = te_get_layout(item);
@@ -756,6 +774,10 @@ sp_te_delete (SPItem *item, Inkscape::Text::Layout::iterator const &start,
SPObject *common_ancestor = get_common_ancestor(item, start_item, end_item);
+ bool has_text_decoration = false;
+ gchar const *root_style = (item)->getRepr()->attribute("style");
+ if(strstr(root_style,"text-decoration"))has_text_decoration = true;
+
if (start_item == end_item) {
// the quick case where we're deleting stuff all from the same string
if (SP_IS_STRING(start_item)) { // always true (if it_start != it_end anyway)
@@ -817,7 +839,7 @@ sp_te_delete (SPItem *item, Inkscape::Text::Layout::iterator const &start,
}
}
- while (tidy_xml_tree_recursively(common_ancestor)){};
+ while (tidy_xml_tree_recursively(common_ancestor, has_text_decoration)){};
te_update_layout_now(item);
item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
layout->validateIterator(&iter_pair.first);
@@ -1260,23 +1282,23 @@ sp_te_adjust_linespacing_screen (SPItem *text, Inkscape::Text::Layout::iterator
style->line_height.value = style->line_height.computed;
break;
case SP_CSS_UNIT_PT:
- style->line_height.computed += zby * PT_PER_PX;
+ style->line_height.computed += Inkscape::Util::Quantity::convert(zby, "px", "pt");
style->line_height.value = style->line_height.computed;
break;
case SP_CSS_UNIT_PC:
- style->line_height.computed += zby * (PT_PER_PX / 12);
+ style->line_height.computed += (Inkscape::Util::Quantity::convert(zby, "px", "pt") / 12);
style->line_height.value = style->line_height.computed;
break;
case SP_CSS_UNIT_MM:
- style->line_height.computed += zby * MM_PER_PX;
+ style->line_height.computed += Inkscape::Util::Quantity::convert(zby, "px", "mm");
style->line_height.value = style->line_height.computed;
break;
case SP_CSS_UNIT_CM:
- style->line_height.computed += zby * CM_PER_PX;
+ style->line_height.computed += Inkscape::Util::Quantity::convert(zby, "px", "cm");
style->line_height.value = style->line_height.computed;
break;
case SP_CSS_UNIT_IN:
- style->line_height.computed += zby * IN_PER_PX;
+ style->line_height.computed += Inkscape::Util::Quantity::convert(zby, "px", "in");
style->line_height.value = style->line_height.computed;
break;
}
@@ -1536,7 +1558,7 @@ static SPObject* ascend_while_first(SPObject *item, Glib::ustring::iterator text
/** empty spans: abc<span></span>def
-> abcdef */
-static bool tidy_operator_empty_spans(SPObject **item)
+static bool tidy_operator_empty_spans(SPObject **item, bool /*has_text_decoration*/)
{
bool result = false;
if ( !(*item)->hasChildren()
@@ -1554,7 +1576,7 @@ static bool tidy_operator_empty_spans(SPObject **item)
/** inexplicable spans: abc<span style="">def</span>ghi
-> "abc""def""ghi"
the repeated strings will be merged by another operator. */
-static bool tidy_operator_inexplicable_spans(SPObject **item)
+static bool tidy_operator_inexplicable_spans(SPObject **item, bool /*has_text_decoration*/)
{
//XML Tree being directly used here while it shouldn't be.
if (*item && sp_repr_is_meta_element((*item)->getRepr())) {
@@ -1589,7 +1611,7 @@ static bool tidy_operator_inexplicable_spans(SPObject **item)
/** repeated spans: <font a>abc</font><font a>def</font>
-> <font a>abcdef</font> */
-static bool tidy_operator_repeated_spans(SPObject **item)
+static bool tidy_operator_repeated_spans(SPObject **item, bool /*has_text_decoration*/)
{
SPObject *first = *item;
SPObject *second = first->getNext();
@@ -1635,7 +1657,7 @@ static bool tidy_operator_repeated_spans(SPObject **item)
-> <font b>abc</font>
excessive nesting: <font a><size 1>abc</size></font>
-> <font a,size 1>abc</font> */
-static bool tidy_operator_excessive_nesting(SPObject **item)
+static bool tidy_operator_excessive_nesting(SPObject **item, bool /*has_text_decoration*/)
{
if (!(*item)->hasChildren()) {
return false;
@@ -1713,7 +1735,7 @@ example. You may note that this only does its work when the doubly-nested
child is the first or last. The other cases are called 'style inversion'
below, and I'm not yet convinced that the result of that operation will be
tidier in all cases. */
-static bool tidy_operator_redundant_double_nesting(SPObject **item)
+static bool tidy_operator_redundant_double_nesting(SPObject **item, bool /*has_text_decoration*/)
{
if (!(*item)->hasChildren()) return false;
if ((*item)->firstChild() == (*item)->lastChild()) return false; // this is excessive nesting, done above
@@ -1774,7 +1796,7 @@ static bool redundant_semi_nesting_processor(SPObject **item, SPObject *child, b
-> <font b>abc</font><font>def</font>
test this by applying a colour to a region, then a different colour to
a partially-overlapping region. */
-static bool tidy_operator_redundant_semi_nesting(SPObject **item)
+static bool tidy_operator_redundant_semi_nesting(SPObject **item, bool /*has_text_decoration*/)
{
if (!(*item)->hasChildren()) return false;
if ((*item)->firstChild() == (*item)->lastChild()) return false; // this is redundant nesting, done above
@@ -1801,13 +1823,21 @@ static SPString* find_last_string_child_not_equal_to(SPObject *root, SPObject *n
return NULL;
}
-/** whitespace-only spans: abc<font> </font>def
- -> abc<font></font> def
- abc<b><i>def</i> </b>ghi
- -> abc<b><i>def</i></b> ghi */
-static bool tidy_operator_styled_whitespace(SPObject **item)
+/** whitespace-only spans:
+ abc<font> </font>def
+ -> abc<font></font> def
+ abc<b><i>def</i> </b>ghi
+ -> abc<b><i>def</i></b> ghi
+
+ visible text-decoration changes on white spaces should not be subject
+ to this sort of processing. So
+ abc<text-decoration-color> </text-decoration-color>def
+ is unchanged.
+*/
+static bool tidy_operator_styled_whitespace(SPObject **item, bool has_text_decoration)
{
- if (!SP_IS_STRING(*item)) {
+ // any type of visible text decoration is OK as pure spaces, so do nothing here in that case.
+ if (!SP_IS_STRING(*item) || has_text_decoration ) {
return false;
}
Glib::ustring const &str = SP_STRING(*item)->string;
@@ -1817,6 +1847,7 @@ static bool tidy_operator_styled_whitespace(SPObject **item)
}
}
+
SPObject *test_item = *item;
SPString *next_string;
for ( ; ; ) { // find the next string
@@ -1844,7 +1875,7 @@ static bool tidy_operator_styled_whitespace(SPObject **item)
if (next_string == NULL) {
return false; // an empty paragraph
}
- next_string->string += str;
+ next_string->string = str + next_string->string;
break;
}
}
@@ -1878,9 +1909,11 @@ It may be that some of the later tidy operators that I wrote are actually
general cases of the earlier operators, and hence the special-case-only
versions can be removed. I haven't analysed my work in detail to figure
out if this is so. */
-static bool tidy_xml_tree_recursively(SPObject *root)
+static bool tidy_xml_tree_recursively(SPObject *root, bool has_text_decoration)
{
- static bool (* const tidy_operators[])(SPObject**) = {
+ gchar const *root_style = (root)->getRepr()->attribute("style");
+ if(root_style && strstr(root_style,"text-decoration"))has_text_decoration = true;
+ static bool (* const tidy_operators[])(SPObject**, bool) = {
tidy_operator_empty_spans,
tidy_operator_inexplicable_spans,
tidy_operator_repeated_spans,
@@ -1897,12 +1930,12 @@ static bool tidy_xml_tree_recursively(SPObject *root)
continue;
}
if (child->hasChildren()) {
- changes |= tidy_xml_tree_recursively(child);
+ changes |= tidy_xml_tree_recursively(child, has_text_decoration);
}
unsigned i;
for (i = 0 ; i < sizeof(tidy_operators) / sizeof(tidy_operators[0]) ; i++) {
- if (tidy_operators[i](&child)) {
+ if (tidy_operators[i](&child, has_text_decoration)) {
changes = true;
break;
}
@@ -2000,7 +2033,10 @@ void sp_te_apply_style(SPItem *text, Inkscape::Text::Layout::iterator const &sta
and neither option can be made to work, a fallback could be to reduce
everything to a single level of nesting and drop all pretence of
roundtrippability. */
- while (tidy_xml_tree_recursively(common_ancestor)){};
+ bool has_text_decoration = false;
+ gchar const *root_style = (text)->getRepr()->attribute("style");
+ if(strstr(root_style,"text-decoration"))has_text_decoration = true;
+ while (tidy_xml_tree_recursively(common_ancestor, has_text_decoration)){};
// if we only modified subobjects this won't have been automatically sent
text->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);