diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2014-10-14 11:49:43 +0000 |
|---|---|---|
| committer | tavmjong-free <tavmjong@free.fr> | 2014-10-14 11:49:43 +0000 |
| commit | f8d50684eddc79a56c79a679b6d0d608b739a0cc (patch) | |
| tree | 7ad5a65a230f5fb0b97cae3a04ccd3f5c2940b35 /src | |
| parent | Fix crash with GTK+ 3.14 on launch (diff) | |
| download | inkscape-f8d50684eddc79a56c79a679b6d0d608b739a0cc.tar.gz inkscape-f8d50684eddc79a56c79a679b6d0d608b739a0cc.zip | |
Add 'white-space' CSS property (replaces deprecated xml:space).
(bzr r13612)
Diffstat (limited to 'src')
| -rw-r--r-- | src/attributes.cpp | 10 | ||||
| -rw-r--r-- | src/attributes.h | 31 | ||||
| -rw-r--r-- | src/sp-string.cpp | 119 | ||||
| -rw-r--r-- | src/style-enums.h | 17 | ||||
| -rw-r--r-- | src/style.cpp | 10 | ||||
| -rw-r--r-- | src/style.h | 40 |
6 files changed, 177 insertions, 50 deletions
diff --git a/src/attributes.cpp b/src/attributes.cpp index fec5d3af4..2474e4abe 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -413,10 +413,6 @@ static SPStyleProp const props[] = { /* Text */ {SP_PROP_TEXT_INDENT, "text-indent"}, {SP_PROP_TEXT_ALIGN, "text-align"}, - {SP_PROP_TEXT_DECORATION, "text-decoration"}, - {SP_PROP_TEXT_DECORATION_LINE, "text-decoration-line"}, - {SP_PROP_TEXT_DECORATION_STYLE,"text-decoration-style"}, - {SP_PROP_TEXT_DECORATION_COLOR,"text-decoration-color"}, {SP_PROP_LINE_HEIGHT, "line-height"}, {SP_PROP_LETTER_SPACING, "letter-spacing"}, {SP_PROP_WORD_SPACING, "word-spacing"}, @@ -433,6 +429,12 @@ static SPStyleProp const props[] = { {SP_PROP_GLYPH_ORIENTATION_VERTICAL, "glyph-orientation-vertical"}, {SP_PROP_KERNING, "kerning"}, {SP_PROP_TEXT_ANCHOR, "text-anchor"}, + {SP_PROP_WHITE_SPACE, "white-space"}, + /* Text Decoration */ + {SP_PROP_TEXT_DECORATION, "text-decoration"}, + {SP_PROP_TEXT_DECORATION_LINE, "text-decoration-line"}, + {SP_PROP_TEXT_DECORATION_STYLE,"text-decoration-style"}, + {SP_PROP_TEXT_DECORATION_COLOR,"text-decoration-color"}, /* Misc */ {SP_PROP_CLIP, "clip"}, {SP_PROP_COLOR, "color"}, diff --git a/src/attributes.h b/src/attributes.h index 3397e4034..7f18cb5ea 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -399,9 +399,11 @@ enum SPAttributeEnum { SP_ATTR_TEXT_EXCLUDE, SP_ATTR_LAYOUT_OPTIONS, - /* CSS2 */ - /* Custom full font name because Font stuff below is inadequate */ + /* CSS & SVG Properties */ + + /* Custom full font name because Font stuff below is inadequate REMOVE ME */ SP_PROP_INKSCAPE_FONT_SPEC, + /* Font */ SP_PROP_FONT, SP_PROP_FONT_FAMILY, @@ -411,18 +413,16 @@ enum SPAttributeEnum { SP_PROP_FONT_STYLE, SP_PROP_FONT_VARIANT, SP_PROP_FONT_WEIGHT, - /* Text */ + + /* Text Layout */ SP_PROP_TEXT_INDENT, SP_PROP_TEXT_ALIGN, - SP_PROP_TEXT_DECORATION, /* SVG 1 underline etc.( no color or style) OR SVG2 with _LINE, _STYLE, _COLOR values */ - SP_PROP_TEXT_DECORATION_LINE, /* SVG 2 underline etc. */ - SP_PROP_TEXT_DECORATION_STYLE, /* SVG 2 proposed solid [SVG 1], dotted, etc.)*/ - SP_PROP_TEXT_DECORATION_COLOR, /* SVG 2 proposed same as text [SVG 1], specified*/ + SP_PROP_LINE_HEIGHT, SP_PROP_LETTER_SPACING, SP_PROP_WORD_SPACING, SP_PROP_TEXT_TRANSFORM, - /* text (css3) */ + SP_PROP_DIRECTION, SP_PROP_BLOCK_PROGRESSION, SP_PROP_WRITING_MODE, @@ -434,6 +434,14 @@ enum SPAttributeEnum { SP_PROP_GLYPH_ORIENTATION_VERTICAL, SP_PROP_KERNING, SP_PROP_TEXT_ANCHOR, + SP_PROP_WHITE_SPACE, + + /* Text Decoration */ + SP_PROP_TEXT_DECORATION, /* SVG 1 underline etc.( no color or style) OR SVG2 with _LINE, _STYLE, _COLOR values */ + SP_PROP_TEXT_DECORATION_LINE, /* SVG 2 underline etc. */ + SP_PROP_TEXT_DECORATION_STYLE, /* SVG 2 proposed solid [SVG 1], dotted, etc.)*/ + SP_PROP_TEXT_DECORATION_COLOR, /* SVG 2 proposed same as text [SVG 1], specified*/ + /* Misc */ SP_PROP_CLIP, SP_PROP_COLOR, @@ -443,24 +451,29 @@ enum SPAttributeEnum { SP_PROP_VISIBILITY, SP_PROP_MIX_BLEND_MODE, SP_PROP_ISOLATION, + /* SVG */ /* Clip/Mask */ SP_PROP_CLIP_PATH, SP_PROP_CLIP_RULE, SP_PROP_MASK, SP_PROP_OPACITY, + /* Filter */ SP_PROP_ENABLE_BACKGROUND, SP_PROP_FILTER, SP_PROP_FLOOD_COLOR, SP_PROP_FLOOD_OPACITY, SP_PROP_LIGHTING_COLOR, + /* Gradient */ SP_PROP_STOP_COLOR, SP_PROP_STOP_OPACITY, SP_PROP_STOP_PATH, + /* Interactivity */ SP_PROP_POINTER_EVENTS, + /* Paint */ SP_PROP_COLOR_INTERPOLATION, SP_PROP_COLOR_INTERPOLATION_FILTERS, @@ -487,10 +500,12 @@ enum SPAttributeEnum { SP_PROP_STROKE_OPACITY, SP_PROP_STROKE_WIDTH, SP_PROP_TEXT_RENDERING, + /* Conditional */ SP_PROP_SYSTEM_LANGUAGE, SP_PROP_REQUIRED_FEATURES, SP_PROP_REQUIRED_EXTENSIONS, + /* LivePathEffect */ SP_PROP_PATH_EFFECT, }; diff --git a/src/sp-string.cpp b/src/sp-string.cpp index e9dfc168b..b561187d0 100644 --- a/src/sp-string.cpp +++ b/src/sp-string.cpp @@ -30,10 +30,14 @@ #include "sp-string.h" +#include "style.h" + #include "xml/repr.h" #include "sp-factory.h" +#include <iostream> + namespace { SPObject* createString() { return new SPString(); @@ -65,45 +69,110 @@ void SPString::release() { void SPString::read_content() { - SPString* object = this; + SPString* object = this; SPString *string = SP_STRING(object); string->string.clear(); //XML Tree being used directly here while it shouldn't be. gchar const *xml_string = string->getRepr()->content(); - // see algorithms described in svg 1.1 section 10.15 - if (object->xml_space.value == SP_XML_SPACE_PRESERVE) { - for ( ; *xml_string ; xml_string = g_utf8_next_char(xml_string) ) { - gunichar c = g_utf8_get_char(xml_string); - if ((c == 0xa) || (c == 0xd) || (c == '\t')) { - c = ' '; - } - string->string += c; + + // 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 | Collapes | 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( object->parent && object->parent->style ) { + if( object->parent->style->white_space.computed == SP_CSS_WHITE_SPACE_PRE || + object->parent->style->white_space.computed == SP_CSS_WHITE_SPACE_PREWRAP || + object->parent->style->white_space.computed == SP_CSS_WHITE_SPACE_PRELINE ) { + collapse_line = false; + } + if( object->parent->style->white_space.computed == SP_CSS_WHITE_SPACE_PRE || + object->parent->style->white_space.computed == SP_CSS_WHITE_SPACE_PREWRAP ) { + collapse_space = false; + } + if( object->parent->style->white_space.computed != SP_CSS_WHITE_SPACE_NORMAL ) { + is_css = true; // If white-space not normal, we assume white-space is set. } } - else { - bool whitespace = false; - for ( ; *xml_string ; xml_string = g_utf8_next_char(xml_string) ) { - gunichar c = g_utf8_get_char(xml_string); - if ((c == 0xa) || (c == 0xd)) { + if( !is_css ) { + // SVG 2: Use 'xml:space' only if 'white-space' not 'normal'. + if (object->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; - } - if ((c == ' ') || (c == '\t')) { - whitespace = true; - } else { - if (whitespace && (!string->string.empty() || (object->getPrev() != NULL))) { + 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->string += c; // Preserve line feed + continue; + } + break; + case '\t': // Tab + if( collapse_space ) { + white_space = true; // Convert to space and collapse + } else { + string->string += c; // Preserve tab + continue; + } + break; + case ' ': // Space + if( collapse_space ) { + white_space = true; // Collapse white space + } else { + string->string += c; // Preserve space + continue; + } + break; + default: + if( white_space && (!string->string.empty() || (object->getPrev() != NULL))) { string->string += ' '; } string->string += c; - whitespace = false; - } - } - if (whitespace && object->getRepr()->next() != NULL) { // can't use SPObject::getNext() when the SPObject tree is still being built - string->string += ' '; - } + white_space = false; + + } // End switch + } // End loop + + // Insert white space at end if more text follows + if (white_space && object->getRepr()->next() != NULL) { // can't use SPObject::getNext() when the SPObject tree is still being built + string->string += ' '; } + + // std::cout << ">" << string->string << "<" << std::endl; object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } diff --git a/src/style-enums.h b/src/style-enums.h index 356029a40..024943458 100644 --- a/src/style-enums.h +++ b/src/style-enums.h @@ -113,6 +113,14 @@ enum SPTextAnchor { SP_CSS_TEXT_ANCHOR_END }; +enum SPWhiteSpace { + SP_CSS_WHITE_SPACE_NORMAL, + SP_CSS_WHITE_SPACE_PRE, + SP_CSS_WHITE_SPACE_NOWRAP, + SP_CSS_WHITE_SPACE_PREWRAP, + SP_CSS_WHITE_SPACE_PRELINE +}; + enum SPCSSBaselineShift { SP_CSS_BASELINE_SHIFT_BASELINE, SP_CSS_BASELINE_SHIFT_SUB, @@ -326,6 +334,15 @@ static SPStyleEnum const enum_text_anchor[] = { {NULL, -1} }; +static SPStyleEnum const enum_white_space[] = { + {"normal", SP_CSS_WHITE_SPACE_NORMAL }, + {"pre", SP_CSS_WHITE_SPACE_PRE }, + {"nowrap", SP_CSS_WHITE_SPACE_NOWRAP }, + {"pre-wrap", SP_CSS_WHITE_SPACE_PREWRAP}, + {"pre-line", SP_CSS_WHITE_SPACE_PRELINE}, + {NULL, -1} +}; + static SPStyleEnum const enum_direction[] = { {"ltr", SP_CSS_DIRECTION_LTR}, {"rtl", SP_CSS_DIRECTION_RTL}, diff --git a/src/style.cpp b/src/style.cpp index abc928d76..a91611d89 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -135,6 +135,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : writing_mode( "writing-mode", enum_writing_mode, SP_CSS_WRITING_MODE_LR_TB ), baseline_shift(), text_anchor( "text-anchor", enum_text_anchor, SP_CSS_TEXT_ANCHOR_START ), + white_space( "white-space", enum_white_space, SP_CSS_WHITE_SPACE_NORMAL ), // General visual properties clip_rule( "clip-rule", enum_clip_rule, SP_WIND_RULE_NONZERO ), @@ -297,6 +298,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : _properties.push_back( &writing_mode ); _properties.push_back( &baseline_shift ); _properties.push_back( &text_anchor ); + _properties.push_back( &white_space ); _properties.push_back( &clip_rule ); _properties.push_back( &display ); @@ -379,6 +381,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // _propmap.insert( std::make_pair( writing_mode.name, reinterpret_cast<SPIBasePtr>(&SPStyle::writing_mode ) ) ); // _propmap.insert( std::make_pair( baseline_shift.name, reinterpret_cast<SPIBasePtr>(&SPStyle::baseline_shift ) ) ); // _propmap.insert( std::make_pair( text_anchor.name, reinterpret_cast<SPIBasePtr>(&SPStyle::text_anchor ) ) ); + // _propmap.insert( std::make_pair( white_space.name, reinterpret_cast<SPIBasePtr>(&SPStyle::white_space ) ) ); // _propmap.insert( std::make_pair( clip_rule.name, reinterpret_cast<SPIBasePtr>(&SPStyle::clip_rule ) ) ); // _propmap.insert( std::make_pair( display.name, reinterpret_cast<SPIBasePtr>(&SPStyle::display ) ) ); @@ -670,6 +673,9 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { case SP_PROP_TEXT_ANCHOR: text_anchor.readIfUnset( val ); break; + case SP_PROP_WHITE_SPACE: + white_space.readIfUnset( val ); + break; case SP_PROP_BASELINE_SHIFT: baseline_shift.readIfUnset( val ); break; @@ -1623,6 +1629,9 @@ sp_style_unset_property_attrs(SPObject *o) if (style->text_anchor.set) { repr->setAttribute("text-anchor", NULL); } + if (style->white_space.set) { + repr->setAttribute("white_space", NULL); + } if (style->writing_mode.set) { repr->setAttribute("writing_mode", NULL); } @@ -1712,6 +1721,7 @@ sp_css_attr_unset_text(SPCSSAttr *css) sp_repr_css_set_property(css, "block-progression", NULL); sp_repr_css_set_property(css, "writing-mode", NULL); sp_repr_css_set_property(css, "text-anchor", NULL); + sp_repr_css_set_property(css, "white_space", NULL); sp_repr_css_set_property(css, "kerning", NULL); // not implemented yet sp_repr_css_set_property(css, "dominant-baseline", NULL); // not implemented yet sp_repr_css_set_property(css, "alignment-baseline", NULL); // not implemented yet diff --git a/src/style.h b/src/style.h index 3627b4ec2..01a9d4b84 100644 --- a/src/style.h +++ b/src/style.h @@ -92,8 +92,10 @@ private: public: /* ----------------------- THE PROPERTIES ------------------------- */ + /* Match order in style.cpp. */ + + /* Font ---------------------------- */ - /* Font */ /** Font style */ SPIEnum font_style; /** Which substyle of the font */ @@ -113,23 +115,13 @@ public: /** Full font name, as font_factory::ConstructFontSpecification would give, for internal use. */ SPIString font_specification; + /* Text ----------------------------- */ + /** First line indent of paragraphs (css2 16.1) */ SPILength text_indent; /** text alignment (css2 16.2) (not to be confused with text-anchor) */ SPIEnum text_align; - /** text decoration (css2 16.3.1) */ - SPITextDecoration text_decoration; - /** CSS 3 2.1, 2.2, 2.3 */ - /** Not done yet, test_decoration3 = css3 2.4*/ - SPITextDecorationLine text_decoration_line; - SPITextDecorationStyle text_decoration_style; // SPIEnum? Only one can be set at time. - SPIColor text_decoration_color; - // used to implement text_decoration, not saved to or read from SVG file - SPITextDecorationData text_decoration_data; - - // 16.3.2 is text-shadow. That's complicated. - /** letter spacing (css2 16.4) */ SPILengthOrNormal letter_spacing; /** word spacing (also css2 16.4) */ @@ -151,6 +143,25 @@ public: /** Anchor of the text (svg1.1 10.9.1) */ SPIEnum text_anchor; + /** white space (svg2) */ + SPIEnum white_space; + + /* Text Decoration ----------------------- */ + + /** text decoration (css2 16.3.1) */ + SPITextDecoration text_decoration; + /** CSS 3 2.1, 2.2, 2.3 */ + /** Not done yet, test_decoration3 = css3 2.4*/ + SPITextDecorationLine text_decoration_line; + SPITextDecorationStyle text_decoration_style; // SPIEnum? Only one can be set at time. + SPIColor text_decoration_color; + // used to implement text_decoration, not saved to or read from SVG file + SPITextDecorationData text_decoration_data; + + // 16.3.2 is text-shadow. That's complicated. + + /* General visual properties ------------- */ + /** clip-rule: 0 nonzero, 1 evenodd */ SPIEnum clip_rule; @@ -215,6 +226,8 @@ public: SPIString marker_end; SPIString* marker_ptrs[SP_MARKER_LOC_QTY]; + /* Filter effects ------------------------ */ + /** Filter effect */ SPIFilter filter; /** Filter blend mode */ @@ -225,6 +238,7 @@ public: /** enable-background, used for defining where filter effects get their background image */ SPIEnum enable_background; + /* Rendering hints ----------------------- */ /** hints on how to render: e.g. speed vs. accuracy. * As of April, 2013, only image_rendering used. */ |
