summaryrefslogtreecommitdiffstats
path: root/src/object/sp-string.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/object/sp-string.cpp')
-rw-r--r--src/object/sp-string.cpp177
1 files changed, 177 insertions, 0 deletions
diff --git a/src/object/sp-string.cpp b/src/object/sp-string.cpp
new file mode 100644
index 0000000..ee38bfd
--- /dev/null
+++ b/src/object/sp-string.cpp
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * SVG <text> and <tspan> implementation
+ *
+ * Author:
+ * Lauris Kaplinski <lauris@kaplinski.com>
+ * Jon A. Cruz <jon@joncruz.org>
+ * Abhishek Sharma
+ *
+ * Copyright (C) 1999-2002 Lauris Kaplinski
+ * Copyright (C) 2000-2001 Ximian, Inc.
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+/*
+ * fixme:
+ *
+ * These subcomponents should not be items, or alternately
+ * we have to invent set of flags to mark, whether standard
+ * attributes are applicable to given item (I even like this
+ * idea somewhat - Lauris)
+ *
+ */
+
+#include "sp-string.h"
+#include "style.h"
+
+/*#####################################################
+# SPSTRING
+#####################################################*/
+
+SPString::SPString() : SPObject() {
+
+ // This is dangerous but strings shouldn't have style.
+ // delete (style);
+ // style = nullptr;
+}
+
+SPString::~SPString() = default;
+
+void SPString::build(SPDocument *doc, Inkscape::XML::Node *repr) {
+
+ read_content();
+
+ SPObject::build(doc, repr);
+}
+
+void SPString::release() {
+ SPObject::release();
+}
+
+
+void SPString::read_content() {
+
+ string.clear();
+
+ //XML Tree being used directly here while it shouldn't be.
+ gchar const *xml_string = getRepr()->content();
+
+ // std::cout << ">" << (xml_string?xml_string:"Null") << "<" << std::endl;
+
+ // SVG2/CSS Text Level 3 'white-space' has five values.
+ // See: http://dev.w3.org/csswg/css-text/#white-space
+ // | New Lines | Spaces/Tabs | Text Wrapping
+ // ---------|------------|--------------|--------------
+ // normal | Collapse | Collapse | Wrap
+ // pre | Preserve | Preserve | No Wrap
+ // nowrap | Collapse | Collapse | No Wrap
+ // pre-wrap | Preserve | Preserve | Wrap
+ // pre-line | Preserve | Collapse | Wrap
+
+ // 'xml:space' has two values:
+ // 'default' which corresponds to 'normal' (without wrapping).
+ // 'preserve' which corresponds to 'pre' except new lines are converted to spaces.
+ // See algorithms described in svg 1.1 section 10.15
+
+ bool collapse_space = true;
+ bool collapse_line = true;
+ bool is_css = false;
+
+ // Strings don't have style, check parent for style
+ if( parent && parent->style ) {
+ if( parent->style->white_space.computed == SP_CSS_WHITE_SPACE_PRE ||
+ parent->style->white_space.computed == SP_CSS_WHITE_SPACE_PREWRAP ||
+ parent->style->white_space.computed == SP_CSS_WHITE_SPACE_PRELINE ) {
+ collapse_line = false;
+ }
+ if( parent->style->white_space.computed == SP_CSS_WHITE_SPACE_PRE ||
+ parent->style->white_space.computed == SP_CSS_WHITE_SPACE_PREWRAP ) {
+ collapse_space = false;
+ }
+ if( parent->style->white_space.computed != SP_CSS_WHITE_SPACE_NORMAL ) {
+ is_css = true; // If white-space not normal, we assume white-space is set.
+ }
+ }
+ if( !is_css ) {
+ // SVG 2: Use 'xml:space' only if 'white-space' not 'normal'.
+ if (xml_space.value == SP_XML_SPACE_PRESERVE) {
+ collapse_space = false;
+ }
+ }
+
+ bool white_space = false;
+ for ( ; *xml_string ; xml_string = g_utf8_next_char(xml_string) ) {
+
+ gunichar c = g_utf8_get_char(xml_string);
+ switch (c) {
+ case 0xd: // Carriage return
+ // XML Parsers convert 0xa, 0xd, 0xD 0xA to 0xA. CSS also follows this rule so we
+ // should never see 0xd.
+ std::cerr << "SPString: Carriage Return found! Argh!" << std::endl;
+ continue;
+ break;
+ case 0xa: // Line feed
+ if( collapse_line ) {
+ if( !is_css && collapse_space ) continue; // xml:space == 'default' strips LFs.
+ white_space = true; // Convert to space and collapse
+ } else {
+ string += c; // Preserve line feed
+ continue;
+ }
+ break;
+ case '\t': // Tab
+ if( collapse_space ) {
+ white_space = true; // Convert to space and collapse
+ } else {
+ string += c; // Preserve tab
+ continue;
+ }
+ break;
+ case ' ': // Space
+ if( collapse_space ) {
+ white_space = true; // Collapse white space
+ } else {
+ string += c; // Preserve space
+ continue;
+ }
+ break;
+ default:
+ if( white_space && (!string.empty() || (getPrev() != nullptr))) {
+ string += ' ';
+ }
+ string += c;
+ white_space = false;
+
+ } // End switch
+ } // End loop
+
+ // Insert white space at end if more text follows
+ if (white_space && getRepr()->next() != nullptr) { // can't use SPObject::getNext() when the SPObject tree is still being built
+ string += ' ';
+ }
+
+ // std::cout << ">" << string << "<" << std::endl;
+ requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+}
+
+void SPString::update(SPCtx * /*ctx*/, unsigned /*flags*/) {
+
+ // if (flags & (SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_MODIFIED_FLAG)) {
+ // /* Parent style or we ourselves changed, so recalculate */
+ // flags &= ~SP_OBJECT_USER_MODIFIED_FLAG_B; // won't be "just a transformation" anymore, we're going to recompute "x" and "y" attributes
+ // }
+}
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :