Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
style.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
6/* Authors:
7 * Lauris Kaplinski <lauris@kaplinski.com>
8 * Peter Moulder <pmoulder@mail.csse.monash.edu.au>
9 * bulia byak <buliabyak@users.sf.net>
10 * Abhishek Sharma
11 * Tavmjong Bah <tavmjong@free.fr>
12 * Kris De Gussem <Kris.DeGussem@gmail.com>
13 *
14 * Copyright (C) 2001-2002 Lauris Kaplinski
15 * Copyright (C) 2001 Ximian, Inc.
16 * Copyright (C) 2005 Monash University
17 * Copyright (C) 2012 Kris De Gussem
18 * Copyright (C) 2014-2015 Tavmjong Bah
19 *
20 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
21 */
22
23#include "style.h"
24
25#include <cstring>
26#include <string>
27#include <unordered_map>
28#include <vector>
29
30#include <glibmm/regex.h>
31
32#include "attributes.h"
33#include "bad-uri-exception.h"
34#include "colors/manager.h"
35#include "document.h"
36#include "preferences.h"
37
40#include "object/uri.h"
41
43
44#include "util/units.h"
45
47#include "xml/simple-document.h"
48
49#if !GLIB_CHECK_VERSION(2, 64, 0)
50#define g_warning_once g_warning
51#endif
52
54
55static constexpr int BMAX = 8192;
56
57// static int _count = 0;
58
59/*#########################
60## FORWARD DECLARATIONS
61#########################*/
65
66static void sp_style_object_release(SPObject *object, SPStyle *style);
68
73class SPStylePropHelper {
74 SPStylePropHelper() {
75#define REGISTER_PROPERTY(id, member, name) \
76 g_assert(decltype(SPStyle::member)::static_id() == id); \
77 _register(reinterpret_cast<SPIBasePtr>(&SPStyle::member), id) /* name unused */
78
79 // SVG 2: Attributes promoted to properties
80 REGISTER_PROPERTY(SPAttr::D, d, "d");
81
82 // 'color' must be before 'fill', 'stroke', 'text-decoration-color', ...
83 REGISTER_PROPERTY(SPAttr::COLOR, color, "color");
84
85 // 'font-size'/'font' must be before properties that need to know em, ex size (SPILength,
86 // SPILengthOrNormal)
87 REGISTER_PROPERTY(SPAttr::FONT_STYLE, font_style, "font-style");
88 REGISTER_PROPERTY(SPAttr::FONT_VARIANT, font_variant, "font-variant");
89 REGISTER_PROPERTY(SPAttr::FONT_WEIGHT, font_weight, "font-weight");
90 REGISTER_PROPERTY(SPAttr::FONT_STRETCH, font_stretch, "font-stretch");
91 REGISTER_PROPERTY(SPAttr::FONT_SIZE, font_size, "font-size");
92 REGISTER_PROPERTY(SPAttr::LINE_HEIGHT, line_height, "line-height");
93 REGISTER_PROPERTY(SPAttr::FONT_FAMILY, font_family, "font-family");
94 REGISTER_PROPERTY(SPAttr::FONT, font, "font");
95 REGISTER_PROPERTY(SPAttr::INKSCAPE_FONT_SPEC, font_specification, "-inkscape-font-specification");
96
97 // Font variants
98 REGISTER_PROPERTY(SPAttr::FONT_VARIANT_LIGATURES, font_variant_ligatures, "font-variant-ligatures");
99 REGISTER_PROPERTY(SPAttr::FONT_VARIANT_POSITION, font_variant_position, "font-variant-position");
100 REGISTER_PROPERTY(SPAttr::FONT_VARIANT_CAPS, font_variant_caps, "font-variant-caps");
101 REGISTER_PROPERTY(SPAttr::FONT_VARIANT_NUMERIC, font_variant_numeric, "font-variant-numeric");
102 REGISTER_PROPERTY(SPAttr::FONT_VARIANT_ALTERNATES, font_variant_alternates, "font-variant-alternates");
103 REGISTER_PROPERTY(SPAttr::FONT_VARIANT_EAST_ASIAN, font_variant_east_asian, "font-variant-east-asian");
104 REGISTER_PROPERTY(SPAttr::FONT_FEATURE_SETTINGS, font_feature_settings, "font-feature-settings");
105
106 // Variable Fonts
107 REGISTER_PROPERTY(SPAttr::FONT_VARIATION_SETTINGS, font_variation_settings, "font-variation-settings");
108
109 REGISTER_PROPERTY(SPAttr::TEXT_INDENT, text_indent, "text-indent");
110 REGISTER_PROPERTY(SPAttr::TEXT_ALIGN, text_align, "text-align");
111
112 REGISTER_PROPERTY(SPAttr::TEXT_DECORATION, text_decoration, "text-decoration");
113 REGISTER_PROPERTY(SPAttr::TEXT_DECORATION_LINE, text_decoration_line, "text-decoration-line");
114 REGISTER_PROPERTY(SPAttr::TEXT_DECORATION_STYLE, text_decoration_style, "text-decoration-style");
115 REGISTER_PROPERTY(SPAttr::TEXT_DECORATION_COLOR, text_decoration_color, "text-decoration-color");
116 REGISTER_PROPERTY(SPAttr::TEXT_DECORATION_FILL, text_decoration_fill, "text-decoration-fill");
117 REGISTER_PROPERTY(SPAttr::TEXT_DECORATION_STROKE, text_decoration_stroke, "text-decoration-stroke");
118
119 REGISTER_PROPERTY(SPAttr::LETTER_SPACING, letter_spacing, "letter-spacing");
120 REGISTER_PROPERTY(SPAttr::WORD_SPACING, word_spacing, "word-spacing");
121 REGISTER_PROPERTY(SPAttr::TEXT_TRANSFORM, text_transform, "text-transform");
122
123 REGISTER_PROPERTY(SPAttr::WRITING_MODE, writing_mode, "writing-mode");
124 REGISTER_PROPERTY(SPAttr::DIRECTION, direction, "direction");
125 REGISTER_PROPERTY(SPAttr::TEXT_ORIENTATION, text_orientation, "text-orientation");
126 REGISTER_PROPERTY(SPAttr::DOMINANT_BASELINE, dominant_baseline, "dominant-baseline");
127 REGISTER_PROPERTY(SPAttr::BASELINE_SHIFT, baseline_shift, "baseline-shift");
128 REGISTER_PROPERTY(SPAttr::TEXT_ANCHOR, text_anchor, "text-anchor");
129 REGISTER_PROPERTY(SPAttr::WHITE_SPACE, white_space, "white-space");
130
131 REGISTER_PROPERTY(SPAttr::SHAPE_INSIDE, shape_inside, "shape-inside");
132 REGISTER_PROPERTY(SPAttr::SHAPE_SUBTRACT, shape_subtract, "shape-subtract");
133 REGISTER_PROPERTY(SPAttr::SHAPE_PADDING, shape_padding, "shape-padding");
134 REGISTER_PROPERTY(SPAttr::SHAPE_MARGIN, shape_margin, "shape-margin");
135 REGISTER_PROPERTY(SPAttr::INLINE_SIZE, inline_size, "inline-size");
136
137 REGISTER_PROPERTY(SPAttr::CLIP_RULE, clip_rule, "clip-rule");
138 REGISTER_PROPERTY(SPAttr::DISPLAY, display, "display");
139 REGISTER_PROPERTY(SPAttr::OVERFLOW_, overflow, "overflow");
140 REGISTER_PROPERTY(SPAttr::VISIBILITY, visibility, "visibility");
141 REGISTER_PROPERTY(SPAttr::OPACITY, opacity, "opacity");
142
143 REGISTER_PROPERTY(SPAttr::ISOLATION, isolation, "isolation");
144 REGISTER_PROPERTY(SPAttr::MIX_BLEND_MODE, mix_blend_mode, "mix-blend-mode");
145
146 REGISTER_PROPERTY(SPAttr::COLOR_INTERPOLATION, color_interpolation, "color-interpolation");
147 REGISTER_PROPERTY(SPAttr::COLOR_INTERPOLATION_FILTERS, color_interpolation_filters, "color-interpolation-filters");
148
149 REGISTER_PROPERTY(SPAttr::SOLID_COLOR, solid_color, "solid-color");
150 REGISTER_PROPERTY(SPAttr::SOLID_OPACITY, solid_opacity, "solid-opacity");
151
152 REGISTER_PROPERTY(SPAttr::VECTOR_EFFECT, vector_effect, "vector-effect");
153
154 REGISTER_PROPERTY(SPAttr::FILL, fill, "fill");
155 REGISTER_PROPERTY(SPAttr::FILL_OPACITY, fill_opacity, "fill-opacity");
156 REGISTER_PROPERTY(SPAttr::FILL_RULE, fill_rule, "fill-rule");
157
158 REGISTER_PROPERTY(SPAttr::STROKE, stroke, "stroke");
159 REGISTER_PROPERTY(SPAttr::STROKE_WIDTH, stroke_width, "stroke-width");
160 REGISTER_PROPERTY(SPAttr::STROKE_LINECAP, stroke_linecap, "stroke-linecap");
161 REGISTER_PROPERTY(SPAttr::STROKE_LINEJOIN, stroke_linejoin, "stroke-linejoin");
162 REGISTER_PROPERTY(SPAttr::STROKE_MITERLIMIT, stroke_miterlimit, "stroke-miterlimit");
163 REGISTER_PROPERTY(SPAttr::STROKE_DASHARRAY, stroke_dasharray, "stroke-dasharray");
164 REGISTER_PROPERTY(SPAttr::STROKE_DASHOFFSET, stroke_dashoffset, "stroke-dashoffset");
165 REGISTER_PROPERTY(SPAttr::STROKE_OPACITY, stroke_opacity, "stroke-opacity");
166 REGISTER_PROPERTY(SPAttr::STROKE_EXTENSIONS, stroke_extensions, "-inkscape-stroke");
167
168 REGISTER_PROPERTY(SPAttr::MARKER, marker, "marker");
169 REGISTER_PROPERTY(SPAttr::MARKER_START, marker_start, "marker-start");
170 REGISTER_PROPERTY(SPAttr::MARKER_MID, marker_mid, "marker-mid");
171 REGISTER_PROPERTY(SPAttr::MARKER_END, marker_end, "marker-end");
172
173 REGISTER_PROPERTY(SPAttr::PAINT_ORDER, paint_order, "paint-order");
174
175 REGISTER_PROPERTY(SPAttr::FILTER, filter, "filter");
176
177 REGISTER_PROPERTY(SPAttr::COLOR_RENDERING, color_rendering, "color-rendering");
178 REGISTER_PROPERTY(SPAttr::IMAGE_RENDERING, image_rendering, "image-rendering");
179 REGISTER_PROPERTY(SPAttr::SHAPE_RENDERING, shape_rendering, "shape-rendering");
180 REGISTER_PROPERTY(SPAttr::TEXT_RENDERING, text_rendering, "text-rendering");
181
182 REGISTER_PROPERTY(SPAttr::ENABLE_BACKGROUND, enable_background, "enable-background");
183
184 REGISTER_PROPERTY(SPAttr::STOP_COLOR, stop_color, "stop-color");
185 REGISTER_PROPERTY(SPAttr::STOP_OPACITY, stop_opacity, "stop-opacity");
186 }
187
188 // this is a singleton, copy not allowed
189 SPStylePropHelper(SPStylePropHelper const&) = delete;
190public:
191
195 static SPStylePropHelper &instance() {
196 static SPStylePropHelper _instance;
197 return _instance;
198 }
199
203 SPIBase *get(SPStyle *style, SPAttr id) {
204 auto it = m_id_map.find(id);
205 if (it != m_id_map.end()) {
206 return _get(style, it->second);
207 }
208 return nullptr;
209 }
210
214 SPIBase *get(SPStyle *style, const std::string &name) {
215 return get(style, sp_attribute_lookup(name.c_str()));
216 }
217
222 std::vector<SPIBase *> get_vector(SPStyle *style) {
223 std::vector<SPIBase *> v;
224 v.reserve(m_vector.size());
225 for (auto ptr : m_vector) {
226 v.push_back(_get(style, ptr));
227 }
228 return v;
229 }
230
231private:
232 SPIBase *_get(SPStyle *style, SPIBasePtr ptr) { return &(style->*ptr); }
233
234 void _register(SPIBasePtr ptr, SPAttr id) {
235 m_vector.push_back(ptr);
236
237 if (id != SPAttr::INVALID) {
238 m_id_map[id] = ptr;
239 }
240 }
241
242 std::unordered_map<SPAttr, SPIBasePtr> m_id_map;
243 std::vector<SPIBasePtr> m_vector;
244};
245
246auto &_prop_helper = SPStylePropHelper::instance();
247
248// C++11 allows one constructor to call another... might be useful. The original C code
249// had separate calls to create SPStyle, one with only SPDocument and the other with only
250// SPObject as parameters.
251SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) :
252
253 // Unimplemented SVG 1.1: alignment-baseline, clip, clip-path, color-profile, cursor,
254 // dominant-baseline, flood-color, flood-opacity, font-size-adjust,
255 // glyph-orientation-horizontal, glyph-orientation-vertical, kerning, lighting-color,
256 // pointer-events, unicode-bidi
257
258 // 'font', 'font-size', and 'font-family' must come first as other properties depend on them
259 // for calculated values (through 'em' and 'ex'). ('ex' is currently not read.)
260 // The following properties can depend on 'em' and 'ex':
261 // baseline-shift, kerning, letter-spacing, stroke-dash-offset, stroke-width, word-spacing,
262 // Non-SVG 1.1: text-indent, line-spacing
263
264 // Hidden in SPIFontStyle: (to be refactored)
265 // font-family
266 // font-specification
267
268
269 // SVG 2 attributes promoted to properties. (When geometry properties are added, move after font.)
270 d( false), // SPIString Not inherited!
271
272 // Font related properties and 'font' shorthand
273 font_style( SP_CSS_FONT_STYLE_NORMAL),
274 font_variant( SP_CSS_FONT_VARIANT_NORMAL),
275 font_weight( SP_CSS_FONT_WEIGHT_NORMAL),
276 font_stretch( SP_CSS_FONT_STRETCH_NORMAL),
277 font_size(),
278 line_height( 1.25 ), // SPILengthOrNormal
279 font_family( ), // SPIString w/default
280 font(), // SPIFont
281 font_specification( ), // SPIString
282
283 // Font variants (Features)
284 font_variant_ligatures( ),
285 font_variant_position( SP_CSS_FONT_VARIANT_POSITION_NORMAL),
286 font_variant_caps( SP_CSS_FONT_VARIANT_CAPS_NORMAL),
287 font_variant_numeric( ),
288 font_variant_alternates(SP_CSS_FONT_VARIANT_ALTERNATES_NORMAL),
289 font_variant_east_asian(),
290 font_feature_settings( ),
291
292 // Variable Fonts
293 font_variation_settings(), // SPIFontVariationSettings
294
295 // Text related properties
296 text_indent( ), // SPILength
297 text_align( SP_CSS_TEXT_ALIGN_START),
298
299 letter_spacing( ), // SPILengthOrNormal
300 word_spacing( ), // SPILengthOrNormal
301 text_transform( SP_CSS_TEXT_TRANSFORM_NONE),
302
303 direction( SP_CSS_DIRECTION_LTR),
304 writing_mode( SP_CSS_WRITING_MODE_LR_TB),
305 text_orientation( SP_CSS_TEXT_ORIENTATION_MIXED),
306 dominant_baseline( SP_CSS_BASELINE_AUTO),
307 baseline_shift(),
308 text_anchor( SP_CSS_TEXT_ANCHOR_START),
309 white_space( SP_CSS_WHITE_SPACE_NORMAL),
310
311 // SVG 2 Text Wrapping
312 shape_inside( ), // SPIString
313 shape_subtract( ), // SPIString
314 shape_padding( ), // SPILength for now
315 shape_margin( ), // SPILength for now
316 inline_size( ), // SPILength for now
317
318 text_decoration(),
319 text_decoration_line(),
320 text_decoration_style(),
321 text_decoration_color( ), // SPIColor
322 text_decoration_fill( ), // SPIPaint
323 text_decoration_stroke( ), // SPIPaint
324
325 // General visual properties
326 clip_rule( SP_WIND_RULE_NONZERO),
327 display( SP_CSS_DISPLAY_INLINE, false),
328 overflow( SP_CSS_OVERFLOW_VISIBLE, false),
329 visibility( SP_CSS_VISIBILITY_VISIBLE),
330 opacity( false),
331
332 isolation( SP_CSS_ISOLATION_AUTO),
333 mix_blend_mode( SP_CSS_BLEND_NORMAL),
334
335 paint_order(), // SPIPaintOrder
336
337 // Color properties
338 color( ), // SPIColor
339 color_interpolation( SP_CSS_COLOR_INTERPOLATION_SRGB),
340 color_interpolation_filters(SP_CSS_COLOR_INTERPOLATION_LINEARRGB),
341
342 // Solid color properties
343 solid_color( ), // SPIColor
344 solid_opacity( ),
345
346 // Vector effects
347 vector_effect(),
348
349 // Fill properties
350 fill( ), // SPIPaint
351 fill_opacity( ),
352 fill_rule( SP_WIND_RULE_NONZERO),
353
354 // Stroke properties
355 stroke( ), // SPIPaint
356 stroke_width( 1.0), // SPILength
357 stroke_linecap( SP_STROKE_LINECAP_BUTT),
358 stroke_linejoin( SP_STROKE_LINEJOIN_MITER),
359 stroke_miterlimit( 4), // SPIFloat (only use of float!)
360 stroke_dasharray(), // SPIDashArray
361 stroke_dashoffset( ), // SPILength for now
362
363 stroke_opacity( ),
364
365 stroke_extensions( ),
366
367 marker( ), // SPIString
368 marker_start( ), // SPIString
369 marker_mid( ), // SPIString
370 marker_end( ), // SPIString
371
372 // Filter properties
373 filter(),
374 enable_background( SP_CSS_BACKGROUND_ACCUMULATE, false),
375
376 // Rendering hint properties
377 color_rendering( SP_CSS_COLOR_RENDERING_AUTO),
378 image_rendering( SP_CSS_IMAGE_RENDERING_AUTO),
379 shape_rendering( SP_CSS_SHAPE_RENDERING_AUTO),
380 text_rendering( SP_CSS_TEXT_RENDERING_AUTO),
381
382 // Stop color and opacity
383 stop_color( false), // SPIColor, does not inherit
384 stop_opacity( false) // Does not inherit
385{
386 // std::cout << "SPStyle::SPStyle( SPDocument ): Entrance" << std::endl;
387 // std::cout << " Document: " << (document_in?"present":"null") << std::endl;
388 // std::cout << " Object: "
389 // << (object_in?(object_in->getId()?object_in->getId():"id null"):"object null") << std::endl;
390
391 // static bool first = true;
392 // if( first ) {
393 // std::cout << "Size of SPStyle: " << sizeof(SPStyle) << std::endl;
394 // std::cout << " SPIBase: " << sizeof(SPIBase) << std::endl;
395 // std::cout << " SPIFloat: " << sizeof(SPIFloat) << std::endl;
396 // std::cout << " SPIScale24: " << sizeof(SPIScale24) << std::endl;
397 // std::cout << " SPILength: " << sizeof(SPILength) << std::endl;
398 // std::cout << " SPILengthOrNormal: " << sizeof(SPILengthOrNormal) << std::endl;
399 // std::cout << " SPIColor: " << sizeof(SPIColor) << std::endl;
400 // std::cout << " SPIPaint: " << sizeof(SPIPaint) << std::endl;
401 // std::cout << " SPITextDecorationLine" << sizeof(SPITextDecorationLine) << std::endl;
402 // std::cout << " Glib::ustring:" << sizeof(Glib::ustring) << std::endl;
403 // std::cout << " Color: " << sizeof(Color) << std::endl;
404 // first = false;
405 // }
406
407 // ++_count; // Poor man's memory leak detector
408 // std::cout << "Style count: " << _count << std::endl;
409
410 cloned = false;
411
412 object = object_in;
413 if( object ) {
414 document = object->document;
416 object->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_style_object_release), this));
417
418 cloned = object->cloned;
419
420 } else {
421 document = document_in;
422 }
423
424 // 'font' shorthand requires access to included properties.
425 font.setStylePointer( this );
426
427 // Properties that depend on 'font-size' for calculating lengths.
428 baseline_shift.setStylePointer( this );
429 text_indent.setStylePointer( this );
430 line_height.setStylePointer( this );
431 letter_spacing.setStylePointer( this );
432 word_spacing.setStylePointer( this );
433 stroke_width.setStylePointer( this );
434 stroke_dashoffset.setStylePointer( this );
435 shape_padding.setStylePointer( this );
436 shape_margin.setStylePointer( this );
437 inline_size.setStylePointer( this );
438
439 // Properties that depend on 'color'
440 text_decoration_color.setStylePointer(this);
441 fill.setStylePointer(this);
442 stroke.setStylePointer(this);
443 color.setStylePointer(this);
444 stop_color.setStylePointer(this);
445 solid_color.setStylePointer(this);
446
447 // 'text_decoration' shorthand requires access to included properties.
448 text_decoration.setStylePointer( this );
449
450 // SPIPaint, SPIFilter needs access to 'this' (SPStyle)
451 // for setting up signals... 'fill', 'stroke' already done
452 filter.setStylePointer( this );
453 shape_inside.setStylePointer( this );
454 shape_subtract.setStylePointer( this );
455
456 // Used to iterate over markers
461
462
463 // This might be too resource hungary... but for now it possible to loop over properties
464 _properties = _prop_helper.get_vector(this);
465}
466
468
469 // std::cout << "SPStyle::~SPStyle" << std::endl;
470 // --_count; // Poor man's memory leak detector.
471
472 // Remove connections
473 release_connection.disconnect();
474 fill_ps_changed_connection.disconnect();
475 stroke_ps_changed_connection.disconnect();
476 filter_changed_connection.disconnect();
477
478 // The following should be moved into SPIPaint and SPIFilter
479 if (fill.href) {
480 fill_ps_modified_connection.disconnect();
481 }
482
483 if (stroke.href) {
485 }
486
487 if (filter.href) {
488 filter_modified_connection.disconnect();
489 }
490
491 // std::cout << "SPStyle::~SPStyle(): Exit\n" << std::endl;
492}
493
494void
496 SPIBase *p = _prop_helper.get(this, id);
497 if (p) {
498 p->clear();
499 } else {
500 g_warning("Unimplemented style property %d", (int)id);
501 }
502}
503
504void
506 for (auto * p : _properties) {
507 p->clear();
508 }
509
510 // Release connection to object, created in constructor.
511 release_connection.disconnect();
512
513 fill_ps_modified_connection.disconnect();
515
516 filter_modified_connection.disconnect();
517 if (filter.href) {
518 delete filter.href;
519 filter.href = nullptr;
520 }
521
522 if (document) {
524 filter_changed_connection = filter.href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_filter_ref_changed), this));
525
526 fill.href = std::make_shared<SPPaintServerReference>(document);
527 fill_ps_changed_connection = fill.href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_fill_paint_server_ref_changed), this));
528
529 stroke.href = std::make_shared<SPPaintServerReference>(document);
530 stroke_ps_changed_connection = stroke.href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_stroke_paint_server_ref_changed), this));
531 }
532
533 cloned = false;
534
535}
536
537// Matches void sp_style_read(SPStyle *style, SPObject *object, Inkscape::XML::Node *repr)
538void
540
541 // std::cout << "SPStyle::read( SPObject, Inkscape::XML::Node ): Entrance: "
542 // << (object?(object->getId()?object->getId():"id null"):"object null") << " "
543 // << (repr?(repr->name()?repr->name():"no name"):"repr null")
544 // << std::endl;
545 g_assert(repr != nullptr);
546 g_assert(!object || (object->getRepr() == repr));
547
548 // // Uncomment to verify that we don't need to call clear.
549 // std::cout << " Creating temp style for testing" << std::endl;
550 // SPStyle *temp = new SPStyle();
551 // if( !(*temp == *this ) ) std::cout << "SPStyle::read: Need to clear" << std::endl;
552 // delete temp;
553
554 clear(); // FIXME, If this isn't here, EVERYTHING stops working! Why?
555
556 if (!document && object) {
557 document = object->document;
558 }
559
560 if (object && object->cloned) {
561 cloned = true;
562 }
563
564 /* 1. Style attribute */
565 // std::cout << " MERGING STYLE ATTRIBUTE" << std::endl;
566 gchar const *val = repr->attribute("style");
567 if( val != nullptr && *val ) {
568 _mergeString( val );
569 }
570
571 /* 2 Style sheet */
572 if (object) {
573 _mergeObjectStylesheet( object );
574 }
575
576 /* 3 Presentation attributes */
577 for (auto * p : _properties) {
578 // Shorthands are not allowed as presentation properties. Note: text-decoration and
579 // font-variant are converted to shorthands in CSS 3 but can still be read as a
580 // non-shorthand for compatibility with older renders, so they should not be in this list.
581 if (p->id() != SPAttr::FONT && p->id() != SPAttr::MARKER) {
582 p->readAttribute( repr );
583 }
584 }
585
586 /* 4 Cascade from parent */
587 if( object ) {
588 if( object->parent ) {
590 }
591 } else if( repr->parent() ) { // When does this happen?
592 // std::cout << "SPStyle::read(): reading via repr->parent()" << std::endl;
594 parent->read( nullptr, repr->parent() );
595 cascade( parent );
596 delete parent;
597 }
598}
599
607void
609
610 // std::cout << "SPStyle::readFromObject: "<< (object->getId()?object->getId():"null") << std::endl;
611
612 g_return_if_fail(object != nullptr);
613
614 Inkscape::XML::Node *repr = object->getRepr();
615 g_return_if_fail(repr != nullptr);
616
617 read( object, repr );
618}
619
624void
625SPStyle::readFromPrefs(Glib::ustring const &path) {
626
627 g_return_if_fail(!path.empty());
628
630
631 // not optimal: we reconstruct the node based on the prefs, then pass it to
632 // sp_style_read for actual processing.
634 Inkscape::XML::Node *tempnode = tempdoc->createElement("prefs");
635
636 std::vector<Inkscape::Preferences::Entry> attrs = prefs->getAllEntries(path);
637 for (auto & attr : attrs) {
638 tempnode->setAttribute(attr.getEntryName(), attr.getString());
639 }
640
641 read( nullptr, tempnode );
642
643 Inkscape::GC::release(tempnode);
644 Inkscape::GC::release(tempdoc);
645 delete tempdoc;
646}
647
648// Matches sp_style_merge_property(SPStyle *style, gint id, gchar const *val)
649void
650SPStyle::readIfUnset(SPAttr id, gchar const *val, SPStyleSrc const &source ) {
651
652 // std::cout << "SPStyle::readIfUnset: Entrance: " << sp_attribute_name(id) << ": " << (val?val:"null") << std::endl;
653 // To Do: If it is not too slow, use std::map instead of std::vector inorder to remove switch()
654 // (looking up SPAttr::xxxx already uses a hash).
655 g_return_if_fail(val != nullptr);
656
657 switch (id) {
658 /* SVG */
659 /* Clip/Mask */
667 g_warning_once("attribute 'clip-path' given as CSS");
668
669 //XML Tree being directly used here.
670 if (object) {
671 object->setAttribute("clip-path", val);
672 }
673 return;
674 case SPAttr::MASK:
678 g_warning_once("attribute 'mask' given as CSS");
679
680 //XML Tree being directly used here.
681 if (object) {
682 object->setAttribute("mask", val);
683 }
684 return;
685 case SPAttr::FILTER:
686 if( !filter.inherit ) filter.readIfUnset( val, source );
687 return;
689 // We read it but issue warning
690 color_interpolation.readIfUnset( val, source );
692 g_warning("Inkscape currently only supports color-interpolation = sRGB");
693 }
694 return;
695 }
696
697 auto p = _prop_helper.get(this, id);
698 if (p) {
699 p->readIfUnset(val, source);
700 } else {
701 g_warning("Unimplemented style property %d", (int)id);
702 }
703}
704
705// return if is seted property
707{
708 bool set = false;
709 switch (id) {
711 return set;
712 case SPAttr::MASK:
713 return set;
714 case SPAttr::FILTER:
715 if (!filter.inherit)
716 set = filter.set;
717 return set;
719 // We read it but issue warning
720 return color_interpolation.set;
721 }
722
723 auto p = _prop_helper.get(this, id);
724 if (p) {
725 return p->set;
726 } else {
727 g_warning("Unimplemented style property %d", (int)id);
728 return set;
729 }
730}
731
745Glib::ustring
746SPStyle::write( guint const flags, SPStyleSrc const style_src_req, SPStyle const *const base ) const {
747
748 // std::cout << "SPStyle::write: flags: " << flags << std::endl;
749
750 // If not excluding this case, we'd end up writing all non-inheritable properties.
751 // Can happen when adding fallback <tspan>s to text like this:
752 // <text style="shape-inside:url(#x)">Hello</text>
753 if (base == this) {
754 assert((flags & SP_STYLE_FLAG_IFDIFF) && !(flags & SP_STYLE_FLAG_ALWAYS));
755 return {};
756 }
757
758 Glib::ustring style_string;
759 for(std::vector<SPIBase*>::size_type i = 0; i != _properties.size(); ++i) {
760 if( base != nullptr ) {
761 style_string += _properties[i]->write( flags, style_src_req, base->_properties[i] );
762 } else {
763 style_string += _properties[i]->write( flags, style_src_req, nullptr );
764 }
765 }
766
767 // Extended properties. Cascading not supported.
768 for (auto const &pair : extended_properties) {
769 // std::cout << "extended property: " << pair.first << " = " << pair.second << std::endl;
770 style_string += pair.first + ":" + pair.second + ";";
771 }
772
773 // Remove trailing ';'
774 if( style_string.size() > 0 ) {
775 style_string.erase( style_string.size() - 1 );
776 }
777 return style_string;
778}
782Glib::ustring SPStyle::write(unsigned int flags) const
783{
784 assert(flags & (SP_STYLE_FLAG_IFSET | SP_STYLE_FLAG_ALWAYS));
785 return write(flags, SPStyleSrc::UNSET);
786}
790Glib::ustring SPStyle::write(SPStyleSrc style_src_req) const
791{
792 assert(style_src_req != SPStyleSrc::UNSET);
793 return write(SP_STYLE_FLAG_IFSRC | SP_STYLE_FLAG_IFSET, style_src_req);
794}
799Glib::ustring SPStyle::writeIfDiff(SPStyle const *base) const
800{
802}
803
804// Corresponds to sp_style_merge_from_parent()
816void
818 // std::cout << "SPStyle::cascade: " << (object->getId()?object->getId():"null") << std::endl;
819 for(std::vector<SPIBase*>::size_type i = 0; i != _properties.size(); ++i) {
820 _properties[i]->cascade( parent->_properties[i] );
821 }
822}
823
824// Corresponds to sp_style_merge_from_dying_parent()
842void
844 // std::cout << "SPStyle::merge" << std::endl;
845 for(std::vector<SPIBase*>::size_type i = 0; i != _properties.size(); ++i) {
846 _properties[i]->merge( parent->_properties[i] );
847 }
848}
849
853void
854SPStyle::mergeString( gchar const *const p ) {
855 _mergeString( p );
856}
857
858void
860 Glib::ustring css_str;
862 _mergeString(css_str.c_str());
863}
864
869void
871 if (statement->type != RULESET_STMT) {
872 return;
873 }
874 CRDeclaration *decl_list = nullptr;
875 cr_statement_ruleset_get_declarations (statement, &decl_list);
876 if (decl_list) {
878 }
879}
880
881// Mostly for unit testing
882bool
883SPStyle::operator==(const SPStyle& rhs) const {
884
885 // Uncomment for testing
886 // for(std::vector<SPIBase*>::size_type i = 0; i != _properties.size(); ++i) {
887 // if( *_properties[i] != *rhs._properties[i])
888 // std::cout << _properties[i]->name << ": "
889 // << _properties[i]->write(SP_STYLE_FLAG_ALWAYS,NULL) << " "
890 // << rhs._properties[i]->write(SP_STYLE_FLAG_ALWAYS,NULL)
891 // << (*_properties[i] == *rhs._properties[i]) << std::endl;
892 // }
893
894 for(std::vector<SPIBase*>::size_type i = 0; i != _properties.size(); ++i) {
895 if( *_properties[i] != *rhs._properties[i]) return false;
896 }
897 return true;
898}
899
900void
901SPStyle::_mergeString( gchar const *const p ) {
902
903 // std::cout << "SPStyle::_mergeString: " << (p?p:"null") << std::endl;
904 CRDeclaration *const decl_list
905 = cr_declaration_parse_list_from_buf(reinterpret_cast<guchar const *>(p), CR_UTF_8);
906 if (decl_list) {
908 cr_declaration_destroy(decl_list);
909 }
910}
911
912void
913SPStyle::_mergeDeclList( CRDeclaration const *const decl_list, SPStyleSrc const &source ) {
914
915 // std::cout << "SPStyle::_mergeDeclList" << std::endl;
916
917 // In reverse order, as later declarations to take precedence over earlier ones.
918 // (Properties are only set if not previously set. See:
919 // Ref: http://www.w3.org/TR/REC-CSS2/cascade.html#cascading-order point 4.)
920 if (decl_list->next) {
921 _mergeDeclList( decl_list->next, source );
922 }
923 _mergeDecl( decl_list, source );
924}
925
926void
927SPStyle::_mergeDecl( CRDeclaration const *const decl, SPStyleSrc const &source ) {
928
929 // std::cout << "SPStyle::_mergeDecl" << std::endl;
930
931 auto prop_idx = sp_attribute_lookup(decl->property->stryng->str);
932 if (prop_idx != SPAttr::INVALID) {
938 if (!isSet(prop_idx) || decl->important) {
939 guchar *const str_value_unsigned = cr_term_to_string(decl->value);
940 gchar *const str_value = reinterpret_cast<gchar *>(str_value_unsigned);
941
942 // Add "!important" rule if necessary as this is not handled by cr_term_to_string().
943 gchar const *important = decl->important ? " !important" : "";
945 os << str_value << important;
946
947 readIfUnset(prop_idx, os.str().c_str(), source);
948 g_free(str_value);
949 }
950 } else {
951 gchar const *key = decl->property->stryng->str;
952 auto value = reinterpret_cast<gchar *>(cr_term_to_string(decl->value));
953
954 if (g_str_has_prefix(key, "--")) {
955 g_warning("Ignoring CSS variable: %s", key);
956 } else if (g_str_has_prefix(key, "-")) {
957 extended_properties[key] = value;
958 } else {
959 g_warning("Ignoring unrecognized CSS property: %s", key);
960 }
961
962 g_free(value);
963 }
964}
965
966void
968
969 // std::cout << "SPStyle::_mergeProps" << std::endl;
970
971 // In reverse order, as later declarations to take precedence over earlier ones.
972 if (props) {
974 CRDeclaration *decl = nullptr;
977 }
978}
979
980void
982
983 // std::cout << "SPStyle::_mergeObjectStylesheet: " << (object->getId()?object->getId():"null") << std::endl;
984
986}
987
988void
989SPStyle::_mergeObjectStylesheet( SPObject const *const object, SPDocument *const document ) {
990
991 static CRSelEng *sel_eng = sp_repr_sel_eng();
992
993 if (auto *const parent = document->getParent()) {
995 } else if (auto *const parent = document->get_reference_document()) {
997 }
998
999 CRPropList *props = nullptr;
1000
1001 //XML Tree being directly used here while it shouldn't be.
1002 CRStatus status =
1005 object->getRepr(),
1006 &props);
1007 g_return_if_fail(status == CR_OK);
1009 if (props) {
1012 }
1013}
1014
1015// Used for input into Pango. Must be computed value!
1016std::string
1018
1019 std::string feature_string;
1021 feature_string += "liga 0, clig 0, ";
1023 feature_string += "dlig, ";
1025 feature_string += "hlig, ";
1027 feature_string += "calt 0, ";
1028
1029 switch (font_variant_position.computed) {
1031 feature_string += "subs, ";
1032 break;
1034 feature_string += "sups, ";
1035 }
1036
1037 switch (font_variant_caps.computed) {
1039 feature_string += "smcp, ";
1040 break;
1042 feature_string += "smcp, c2sc, ";
1043 break;
1045 feature_string += "pcap, ";
1046 break;
1048 feature_string += "pcap, c2pc, ";
1049 break;
1051 feature_string += "unic, ";
1052 break;
1054 feature_string += "titl, ";
1055 }
1056
1058 feature_string += "lnum, ";
1060 feature_string += "onum, ";
1062 feature_string += "pnum, ";
1064 feature_string += "tnum, ";
1066 feature_string += "frac, ";
1068 feature_string += "afrc, ";
1070 feature_string += "ordn, ";
1072 feature_string += "zero, ";
1073
1075 feature_string += "jp78, ";
1077 feature_string += "jp83, ";
1079 feature_string += "jp90, ";
1081 feature_string += "jp04, ";
1083 feature_string += "smpl, ";
1085 feature_string += "trad, ";
1087 feature_string += "fwid, ";
1089 feature_string += "pwid, ";
1091 feature_string += "ruby, ";
1092
1093 char const *val = font_feature_settings.value();
1094 if (val[0] && strcmp(val, "normal")) {
1095 // We do no sanity checking...
1096 feature_string += val;
1097 feature_string += ", ";
1098 }
1099
1100 if (feature_string.empty()) {
1101 feature_string = "normal";
1102 } else {
1103 // Remove last ", "
1104 feature_string.resize(feature_string.size() - 2);
1105 }
1106
1107 return feature_string;
1108}
1109
1110
1111// Internal
1115static void
1117{
1118 (void)object; // TODO
1119 style->object = nullptr;
1120}
1121
1122// Internal
1126static void sp_style_filter_ref_modified(SPObject *obj, unsigned flags, SPStyle *style)
1127{
1128 auto filter = static_cast<SPFilter*>(obj);
1129
1130 g_assert(style->getFilter() == filter);
1131
1132 if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG)) {
1133 if (style->object) {
1134 // FIXME: This line results in now-unnecessary filter recreation.
1135 style->object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
1136 if (!style->block_filter_bbox_updates) {
1137 style->object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); // To update bbox.
1138 }
1139 }
1140 }
1141}
1142
1143// Internal
1148{
1149 if (old_ref) {
1150 static_cast<SPFilter*>(old_ref)->_refcount--;
1151 style->filter_modified_connection.disconnect();
1152 }
1153
1154 if (is<SPFilter>(ref)) {
1155 static_cast<SPFilter*>(ref)->_refcount++;
1156 style->filter_modified_connection = ref->connectModified(sigc::bind(sigc::ptr_fun(&sp_style_filter_ref_modified), style));
1157 }
1158
1159 style->signal_filter_changed.emit(old_ref, ref);
1160 sp_style_filter_ref_modified(ref, SP_OBJECT_FLAGS_ALL, style);
1161}
1162
1167static void sp_style_paint_server_ref_modified(SPObject *obj, unsigned /*flags*/, SPStyle *style)
1168{
1169 // todo: use flags
1170 auto server = static_cast<SPPaintServer*>(obj);
1171
1172 g_assert((style->fill .isPaintserver() && style->getFillPaintServer() == server) ||
1173 (style->stroke.isPaintserver() && style->getStrokePaintServer() == server) ||
1174 !server);
1175
1176 if (style->object) {
1185 // FIXME: For patterns and hatches, this line results in now-unnecessary pattern recreation.
1186 style->object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
1187 }
1188}
1189
1194{
1195 if (old_ref) {
1196 style->fill_ps_modified_connection.disconnect();
1197 }
1198
1199 if (is<SPPaintServer>(ref)) {
1200 style->fill_ps_modified_connection = ref->connectModified(sigc::bind(sigc::ptr_fun(&sp_style_paint_server_ref_modified), style));
1201 }
1202
1203 style->signal_fill_ps_changed.emit(old_ref, ref);
1205}
1206
1211{
1212 if (old_ref) {
1213 style->stroke_ps_modified_connection.disconnect();
1214 }
1215
1216 if (is<SPPaintServer>(ref)) {
1217 style->stroke_ps_modified_connection = ref->connectModified(sigc::bind(sigc::ptr_fun(&sp_style_paint_server_ref_modified), style));
1218 }
1219
1220 style->signal_stroke_ps_changed.emit(old_ref, ref);
1222}
1223
1224static CRSelEng *
1226{
1228
1242 g_assert(ret);
1243 return ret;
1244}
1245
1246// The following functions should be incorporated into SPIPaint. FIXME
1247// Called in: style.cpp, style-internal.cpp
1248void
1250{
1251 if (!paint->href) {
1252
1253 if (style->object) {
1254 // Should not happen as href should have been created in SPIPaint. (TODO: Removed code duplication.)
1255 paint->href = std::make_shared<SPPaintServerReference>(style->object);
1256 } else if (document || style->document) {
1257 // Used by desktop style (no object to attach to!).
1258 paint->href = std::make_shared<SPPaintServerReference>(document ? document : style->document);
1259 } else {
1260 std::cerr << "sp_style_set_ipaint_to_uri: No valid object or document!" << std::endl;
1261 return;
1262 }
1263
1264 if (paint == &style->fill) {
1265 style->fill_ps_changed_connection = paint->href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_fill_paint_server_ref_changed), style));
1266 } else {
1267 style->stroke_ps_changed_connection = paint->href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_stroke_paint_server_ref_changed), style));
1268 }
1269 }
1270
1271 if (paint->href){
1272 if (paint->href->getObject()){
1273 paint->href->detach();
1274 }
1275
1276 try {
1277 paint->href->attach(*uri);
1278 } catch (Inkscape::BadURIException &e) {
1279 g_warning("%s", e.what());
1280 paint->href->detach();
1281 }
1282 }
1283}
1284
1285// Called in: style.cpp, style-internal.cpp
1286void
1287sp_style_set_ipaint_to_uri_string (SPStyle *style, SPIPaint *paint, const gchar *uri)
1288{
1289 try {
1290 const Inkscape::URI IURI(uri);
1291 sp_style_set_ipaint_to_uri(style, paint, &IURI, style->document);
1292 } catch (...) {
1293 g_warning("URI failed to parse: %s", uri);
1294 }
1295}
1296
1297// Called in: desktop-style.cpp
1298void sp_style_set_to_uri(SPStyle *style, bool isfill, Inkscape::URI const *uri)
1299{
1300 sp_style_set_ipaint_to_uri(style, style->getFillOrStroke(isfill), uri, style->document);
1301}
1302
1303// Called in: widgets/font-selector.cpp, widgets/text-toolbar.cpp, ui/dialog/text-edit.cpp
1304gchar const *
1306{
1307 // specify px by default, see inkscape bug 1221626, mozilla bug 234789
1308 // This is a problematic fix as some properties (e.g. 'line-height') have
1309 // different behaviour if there is no unit.
1310 switch (unit) {
1311
1312 case SP_CSS_UNIT_NONE: return "px";
1313 case SP_CSS_UNIT_PX: return "px";
1314 case SP_CSS_UNIT_PT: return "pt";
1315 case SP_CSS_UNIT_PC: return "pc";
1316 case SP_CSS_UNIT_MM: return "mm";
1317 case SP_CSS_UNIT_CM: return "cm";
1318 case SP_CSS_UNIT_IN: return "in";
1319 case SP_CSS_UNIT_EM: return "em";
1320 case SP_CSS_UNIT_EX: return "ex";
1321 case SP_CSS_UNIT_PERCENT: return "%";
1322 default: return "px";
1323 }
1324 return "px";
1325}
1326
1327// Called in: style-internal.cpp, widgets/text-toolbar.cpp, ui/dialog/text-edit.cpp
1328/*
1329 * Convert a size in pixels into another CSS unit size
1330 */
1331double
1332sp_style_css_size_px_to_units(double size, int unit, double font_size)
1333{
1334 double unit_size = size;
1335
1336 if (font_size == 0) {
1337 g_warning("sp_style_get_css_font_size_units: passed in zero font_size");
1338 font_size = SP_CSS_FONT_SIZE_DEFAULT;
1339 }
1340
1341 switch (unit) {
1342
1343 case SP_CSS_UNIT_NONE: unit_size = size; break;
1344 case SP_CSS_UNIT_PX: unit_size = size; break;
1345 case SP_CSS_UNIT_PT: unit_size = Inkscape::Util::Quantity::convert(size, "px", "pt"); break;
1346 case SP_CSS_UNIT_PC: unit_size = Inkscape::Util::Quantity::convert(size, "px", "pc"); break;
1347 case SP_CSS_UNIT_MM: unit_size = Inkscape::Util::Quantity::convert(size, "px", "mm"); break;
1348 case SP_CSS_UNIT_CM: unit_size = Inkscape::Util::Quantity::convert(size, "px", "cm"); break;
1349 case SP_CSS_UNIT_IN: unit_size = Inkscape::Util::Quantity::convert(size, "px", "in"); break;
1350 case SP_CSS_UNIT_EM: unit_size = size / font_size; break;
1351 case SP_CSS_UNIT_EX: unit_size = size * 2.0 / font_size ; break;
1352 case SP_CSS_UNIT_PERCENT: unit_size = size * 100.0 / font_size; break;
1353
1354 default:
1355 g_warning("sp_style_get_css_font_size_units conversion to %d not implemented.", unit);
1356 break;
1357 }
1358
1359 return unit_size;
1360}
1361
1362// Called in: widgets/text-toolbar.cpp, ui/dialog/text-edit.cpp
1363/*
1364 * Convert a size in a CSS unit size to pixels
1365 */
1366double
1367sp_style_css_size_units_to_px(double size, int unit, double font_size)
1368{
1369 if (unit == SP_CSS_UNIT_PX) {
1370 return size;
1371 }
1372 //g_message("sp_style_css_size_units_to_px %f %d = %f px", size, unit, out);
1373 return size * (size / sp_style_css_size_px_to_units(size, unit, font_size));;
1374}
1375
1376
1377// FIXME: Everything below this line belongs in a different file - css-chemistry?
1378
1379void
1380sp_style_set_property_url (SPObject *item, gchar const *property, SPObject *linked, bool recursive)
1381{
1382 Inkscape::XML::Node *repr = item->getRepr();
1383
1384 if (repr == nullptr) return;
1385
1387 if (linked) {
1388 gchar *val = g_strdup_printf("url(#%s)", linked->getId());
1389 sp_repr_css_set_property(css, property, val);
1390 g_free(val);
1391 } else {
1393 }
1394
1395 if (recursive) {
1396 sp_repr_css_change_recursive(repr, css, "style");
1397 } else {
1398 sp_repr_css_change(repr, css, "style");
1399 }
1401}
1402
1408SPCSSAttr *
1409sp_css_attr_from_style(SPStyle const *const style, guint const flags)
1410{
1411 g_return_val_if_fail(style != nullptr, NULL);
1412 g_return_val_if_fail(((flags & SP_STYLE_FLAG_IFSET) ||
1413 (flags & SP_STYLE_FLAG_ALWAYS)),
1414 NULL);
1415 Glib::ustring style_str = style->write(flags);
1417 sp_repr_css_attr_add_from_string(css, style_str.c_str());
1418 return css;
1419}
1420
1421// Called in: selection-chemistry.cpp, widgets/stroke-marker-selector.cpp, widgets/stroke-style.cpp,
1422// ui/tools/freehand-base.cpp, pattern-manipulation.cpp
1427SPCSSAttr *sp_css_attr_from_object(SPObject *object, guint const flags)
1428{
1429 g_return_val_if_fail(((flags == SP_STYLE_FLAG_IFSET) ||
1430 (flags == SP_STYLE_FLAG_ALWAYS) ),
1431 NULL);
1432 SPCSSAttr * result = nullptr;
1433 if (object->style) {
1434 result = sp_css_attr_from_style(object->style, flags);
1435 }
1436 return result;
1437}
1438
1439// Called in: selection-chemistry.cpp, ui/dialog/inkscape-preferences.cpp
1443SPCSSAttr *
1445{
1446 sp_repr_css_set_property(css, "font", nullptr);
1447 sp_repr_css_set_property(css, "-inkscape-font-specification", nullptr);
1448 sp_repr_css_set_property(css, "font-size", nullptr);
1449 sp_repr_css_set_property(css, "font-size-adjust", nullptr); // not implemented yet
1450 sp_repr_css_set_property(css, "font-style", nullptr);
1451 sp_repr_css_set_property(css, "font-variant", nullptr);
1452 sp_repr_css_set_property(css, "font-weight", nullptr);
1453 sp_repr_css_set_property(css, "font-stretch", nullptr);
1454 sp_repr_css_set_property(css, "font-family", nullptr);
1455 sp_repr_css_set_property(css, "text-indent", nullptr);
1456 sp_repr_css_set_property(css, "text-align", nullptr);
1457 sp_repr_css_set_property(css, "line-height", nullptr);
1458 sp_repr_css_set_property(css, "letter-spacing", nullptr);
1459 sp_repr_css_set_property(css, "word-spacing", nullptr);
1460 sp_repr_css_set_property(css, "text-transform", nullptr);
1461 sp_repr_css_set_property(css, "direction", nullptr);
1462 sp_repr_css_set_property(css, "writing-mode", nullptr);
1463 sp_repr_css_set_property(css, "text-orientation", nullptr);
1464 sp_repr_css_set_property(css, "text-anchor", nullptr);
1465 sp_repr_css_set_property(css, "white-space", nullptr);
1466 sp_repr_css_set_property(css, "shape-inside", nullptr);
1467 sp_repr_css_set_property(css, "shape-subtract", nullptr);
1468 sp_repr_css_set_property(css, "shape-padding", nullptr);
1469 sp_repr_css_set_property(css, "shape-margin", nullptr);
1470 sp_repr_css_set_property(css, "inline-size", nullptr);
1471 sp_repr_css_set_property(css, "kerning", nullptr); // not implemented yet
1472 sp_repr_css_set_property(css, "dominant-baseline", nullptr); // not implemented yet
1473 sp_repr_css_set_property(css, "alignment-baseline", nullptr); // not implemented yet
1474 sp_repr_css_set_property(css, "baseline-shift", nullptr);
1475
1476 sp_repr_css_set_property(css, "text-decoration", nullptr);
1477 sp_repr_css_set_property(css, "text-decoration-line", nullptr);
1478 sp_repr_css_set_property(css, "text-decoration-color", nullptr);
1479 sp_repr_css_set_property(css, "text-decoration-style", nullptr);
1480
1481 sp_repr_css_set_property(css, "font-variant-ligatures", nullptr);
1482 sp_repr_css_set_property(css, "font-variant-position", nullptr);
1483 sp_repr_css_set_property(css, "font-variant-caps", nullptr);
1484 sp_repr_css_set_property(css, "font-variant-numeric", nullptr);
1485 sp_repr_css_set_property(css, "font-variant-alternates", nullptr);
1486 sp_repr_css_set_property(css, "font-variant-east-asian", nullptr);
1487 sp_repr_css_set_property(css, "font-feature-settings", nullptr);
1488
1489 return css;
1490}
1491
1492// ui/dialog/inkscape-preferences.cpp
1497SPCSSAttr *
1499{
1500 sp_repr_css_set_property(css, "color", nullptr);
1501 sp_repr_css_set_property(css, "clip-rule", nullptr);
1502 sp_repr_css_set_property(css, "d", nullptr);
1503 sp_repr_css_set_property(css, "display", nullptr);
1504 sp_repr_css_set_property(css, "overflow", nullptr);
1505 sp_repr_css_set_property(css, "visibility", nullptr);
1506 sp_repr_css_set_property(css, "isolation", nullptr);
1507 sp_repr_css_set_property(css, "mix-blend-mode", nullptr);
1508 sp_repr_css_set_property(css, "color-interpolation", nullptr);
1509 sp_repr_css_set_property(css, "color-interpolation-filters", nullptr);
1510 sp_repr_css_set_property(css, "solid-color", nullptr);
1511 sp_repr_css_set_property(css, "solid-opacity", nullptr);
1512 sp_repr_css_set_property(css, "fill-rule", nullptr);
1513 sp_repr_css_set_property(css, "color-rendering", nullptr);
1514 sp_repr_css_set_property(css, "image-rendering", nullptr);
1515 sp_repr_css_set_property(css, "shape-rendering", nullptr);
1516 sp_repr_css_set_property(css, "text-rendering", nullptr);
1517 sp_repr_css_set_property(css, "enable-background", nullptr);
1518
1519 return css;
1520}
1521
1522// Called in style.cpp
1523static bool
1524is_url(char const *p)
1525{
1526 if (p == nullptr)
1527 return false;
1532 return (g_ascii_strncasecmp(p, "url(", 4) == 0);
1533}
1534
1535// Called in: ui/dialog/inkscape-preferences.cpp, ui/tools/tweek-tool.cpp
1542SPCSSAttr *
1544{
1545// All properties that may hold <uri> or <paint> according to SVG 1.1
1546 if (is_url(sp_repr_css_property(css, "clip-path", nullptr))) sp_repr_css_set_property(css, "clip-path", nullptr);
1547 if (is_url(sp_repr_css_property(css, "color-profile", nullptr))) sp_repr_css_set_property(css, "color-profile", nullptr);
1548 if (is_url(sp_repr_css_property(css, "cursor", nullptr))) sp_repr_css_set_property(css, "cursor", nullptr);
1549 if (is_url(sp_repr_css_property(css, "filter", nullptr))) sp_repr_css_set_property(css, "filter", nullptr);
1550 if (is_url(sp_repr_css_property(css, "marker", nullptr))) sp_repr_css_set_property(css, "marker", nullptr);
1551 if (is_url(sp_repr_css_property(css, "marker-start", nullptr))) sp_repr_css_set_property(css, "marker-start", nullptr);
1552 if (is_url(sp_repr_css_property(css, "marker-mid", nullptr))) sp_repr_css_set_property(css, "marker-mid", nullptr);
1553 if (is_url(sp_repr_css_property(css, "marker-end", nullptr))) sp_repr_css_set_property(css, "marker-end", nullptr);
1554 if (is_url(sp_repr_css_property(css, "mask", nullptr))) sp_repr_css_set_property(css, "mask", nullptr);
1555 if (is_url(sp_repr_css_property(css, "fill", nullptr))) sp_repr_css_set_property(css, "fill", nullptr);
1556 if (is_url(sp_repr_css_property(css, "shape-inside", nullptr))) sp_repr_css_set_property(css, "shape-inside", nullptr);
1557 if (is_url(sp_repr_css_property(css, "shape-subtract", nullptr))) sp_repr_css_set_property(css, "shape-subtract", nullptr);
1558 if (is_url(sp_repr_css_property(css, "stroke", nullptr))) sp_repr_css_set_property(css, "stroke", nullptr);
1559
1560 return css;
1561}
1562
1563// Called in style.cpp
1567static void
1569 double ex, bool only_with_units = false)
1570{
1571 gchar const *w = sp_repr_css_property(css, property, nullptr);
1572 if (w) {
1573 gchar *units = nullptr;
1574 double wd = g_ascii_strtod(w, &units) * ex;
1575 if (w == units) {// nothing converted, non-numeric value
1576 return;
1577 }
1578 if (only_with_units && (units == nullptr || *units == '\0' || *units == '%' || *units == 'e')) {
1579 // only_with_units, but no units found, so do nothing.
1580 // 'e' matches 'em' or 'ex'
1581 return;
1582 }
1584 os << wd << units; // reattach units
1585 sp_repr_css_set_property(css, property, os.str().c_str());
1586 }
1587}
1588
1589// Called in style.cpp for stroke-dasharray
1593static void
1594sp_css_attr_scale_property_list(SPCSSAttr *css, gchar const *property, double ex)
1595{
1596 gchar const *string = sp_repr_css_property(css, property, nullptr);
1597 if (string) {
1599 gchar **a = g_strsplit(string, ",", 10000);
1600 bool first = true;
1601 for (gchar **i = a; i != nullptr; i++) {
1602 gchar *w = *i;
1603 if (w == nullptr)
1604 break;
1605 gchar *units = nullptr;
1606 double wd = g_ascii_strtod(w, &units) * ex;
1607 if (w == units) {// nothing converted, non-numeric value ("none" or "inherit"); do nothing
1608 g_strfreev(a);
1609 return;
1610 }
1611 if (!first) {
1612 os << ",";
1613 }
1614 os << wd << units; // reattach units
1615 first = false;
1616 }
1617 sp_repr_css_set_property(css, property, os.str().c_str());
1618 g_strfreev(a);
1619 }
1620}
1621
1622// Called in: text-editing.cpp,
1626SPCSSAttr *
1628{
1629 sp_css_attr_scale_property_single(css, "baseline-shift", ex);
1630 sp_css_attr_scale_property_single(css, "stroke-width", ex);
1631 sp_css_attr_scale_property_list (css, "stroke-dasharray", ex);
1632 sp_css_attr_scale_property_single(css, "stroke-dashoffset", ex);
1633 sp_css_attr_scale_property_single(css, "font-size", ex, true);
1634 sp_css_attr_scale_property_single(css, "kerning", ex);
1635 sp_css_attr_scale_property_single(css, "letter-spacing", ex);
1636 sp_css_attr_scale_property_single(css, "word-spacing", ex);
1637 sp_css_attr_scale_property_single(css, "line-height", ex, true);
1638
1639 return css;
1640}
1641
1642
1647void
1648css_quote(Glib::ustring &val)
1649{
1650 Glib::ustring out;
1651 bool quote = false;
1652
1653 // Can't wait for C++11!
1654 for( Glib::ustring::iterator it = val.begin(); it != val.end(); ++it) {
1655 if(g_ascii_isalnum(*it) || *it=='-' || *it=='_' || *it > 0xA0) {
1656 out += *it;
1657 } else if (*it == '\'') {
1658 // Single quotes require escaping and quotes.
1659 out += '\\';
1660 out += *it;
1661 quote = true;
1662 } else {
1663 // Quote everything else including spaces.
1664 // (CSS Fonts Level 3 recommends quoting with spaces.)
1665 out += *it;
1666 quote = true;
1667 }
1668 if( it == val.begin() && !g_ascii_isalpha(*it) ) {
1669 // A non-ASCII/non-alpha initial value on any identifier needs quotes.
1670 // (Actually it's a bit more complicated but as it never hurts to quote...)
1671 quote = true;
1672 }
1673 }
1674 if( quote ) {
1675 out.insert( out.begin(), '\'' );
1676 out += '\'';
1677 }
1678 val = out;
1679}
1680
1681
1686void
1687css_font_family_quote(Glib::ustring &val)
1688{
1689 std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("\\s*,\\s*", val );
1690
1691 val.erase();
1692 for(auto & token : tokens) {
1693 css_quote( token );
1694 val += token + ", ";
1695 }
1696 if( val.size() > 1 )
1697 val.erase( val.size() - 2 ); // Remove trailing ", "
1698}
1699
1700
1701// Called in style-internal.cpp, xml/repr-css.cpp
1705void
1706css_unquote(Glib::ustring &val)
1707{
1708 if( val.size() > 1 &&
1709 ( (val[0] == '"' && val[val.size()-1] == '"' ) ||
1710 (val[0] == '\'' && val[val.size()-1] == '\'' ) ) ) {
1711
1712 val.erase( 0, 1 );
1713 val.erase( val.size()-1 );
1714 }
1715}
1716
1717// Called in style-internal.cpp, text-toolbar.cpp
1723void
1724css_font_family_unquote(Glib::ustring &val)
1725{
1726 std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("\\s*,\\s*", val );
1727
1728 val.erase();
1729 for(auto & token : tokens) {
1730 css_unquote( token );
1731 val += token + ", ";
1732 }
1733 if( val.size() > 1 )
1734 val.erase( val.size() - 2 ); // Remove trailing ", "
1735}
1736
1737/*
1738 Local Variables:
1739 mode:c++
1740 c-file-style:"stroustrup"
1741 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1742 indent-tabs-mode:nil
1743 fill-column:99
1744 End:
1745*/
1746// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
SPAttr sp_attribute_lookup(gchar const *key)
Get attribute id by name.
static SPStyleProp const props[]
Lookup dictionary for attributes/properties.
Lookup dictionary for attributes/properties.
SPAttr
Definition attributes.h:27
@ TEXT_DECORATION_LINE
@ WHITE_SPACE
@ FONT_VARIANT_NUMERIC
@ INKSCAPE_FONT_SPEC
@ TEXT_ALIGN
@ TEXT_ORIENTATION
@ TEXT_ANCHOR
@ FILL_OPACITY
@ STROKE_OPACITY
@ FONT_VARIANT
@ LINE_HEIGHT
@ TEXT_DECORATION_FILL
@ MIX_BLEND_MODE
@ FONT_VARIANT_EAST_ASIAN
@ COLOR_RENDERING
@ LETTER_SPACING
@ SHAPE_MARGIN
@ STROKE_LINECAP
@ PAINT_ORDER
@ SHAPE_RENDERING
@ SOLID_OPACITY
@ FONT_STRETCH
@ TEXT_INDENT
@ MARKER_START
@ STROKE_WIDTH
@ STROKE_LINEJOIN
@ STOP_COLOR
@ MARKER_MID
@ WRITING_MODE
@ TEXT_DECORATION_COLOR
@ STOP_OPACITY
@ SHAPE_PADDING
@ VECTOR_EFFECT
@ FONT_FAMILY
@ MARKER_END
@ TEXT_DECORATION_STROKE
@ FONT_VARIANT_ALTERNATES
@ ENABLE_BACKGROUND
@ COLOR_INTERPOLATION
@ FONT_STYLE
@ FONT_VARIANT_POSITION
@ STROKE_DASHOFFSET
@ STROKE_EXTENSIONS
@ FONT_WEIGHT
@ VISIBILITY
@ TEXT_DECORATION_STYLE
@ INVALID
Must have value 0.
@ TEXT_RENDERING
@ STROKE_MITERLIMIT
@ INLINE_SIZE
@ SHAPE_INSIDE
@ WORD_SPACING
@ TEXT_TRANSFORM
@ COLOR_INTERPOLATION_FILTERS
@ BASELINE_SHIFT
@ FONT_FEATURE_SETTINGS
@ IMAGE_RENDERING
@ DOMINANT_BASELINE
@ FONT_VARIANT_LIGATURES
@ SHAPE_SUBTRACT
@ FONT_VARIATION_SETTINGS
@ STROKE_DASHARRAY
@ FONT_VARIANT_CAPS
@ TEXT_DECORATION
@ SOLID_COLOR
TODO: insert short description here.
A thin wrapper around std::ostringstream, but writing floating point numbers in the format required b...
Preference storage class.
Definition preferences.h:61
std::vector< Entry > getAllEntries(Glib::ustring const &path)
Get all entries from the specified directory.
static Preferences * get()
Access the singleton Preferences object.
Represents an URI as per RFC 2396.
Definition uri.h:36
static double convert(double from_dist, Unit const *from, Unit const *to)
Convert distances.
Definition units.cpp:588
Interface for refcounted XML nodes.
Definition node.h:80
virtual Node * parent()=0
Get the parent of this node.
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
Definition node.cpp:25
virtual char const * attribute(char const *key) const =0
Get the string representation of a node's attribute.
Node * createElement(char const *name) override
Typed SVG document implementation.
Definition document.h:101
SPDocument * get_reference_document()
CRCascade * getStyleCascade()
Definition document.h:223
SPDocument * getParent()
Definition document.h:217
Virtual base class for all SPStyle internal classes.
virtual void clear()
Paint type internal to SPStyle.
std::shared_ptr< SPPaintServerReference > href
SPObject is an abstract base class of all of the document nodes at the SVG document level.
Definition sp-object.h:160
void requestModified(unsigned int flags)
Requests that a modification notification signal be emitted later (e.g.
SPDocument * document
Definition sp-object.h:188
char const * getId() const
Returns the objects current ID string.
SPStyle * style
Represents the style properties, whether from presentation attributes, the style attribute,...
Definition sp-object.h:248
SPObject * parent
Definition sp-object.h:189
Inkscape::XML::Node * getRepr()
Returns the XML representation of tree.
unsigned int cloned
Definition sp-object.h:180
void requestDisplayUpdate(unsigned int flags)
Queues an deferred update of this object's display.
An SVG style object.
Definition style.h:45
bool isSet(SPAttr id)
Definition style.cpp:706
T< SPAttr::FONT_VARIANT_EAST_ASIAN, SPIEastAsian > font_variant_east_asian
Font variant East Asian.
Definition style.h:138
void clear()
Definition style.cpp:505
void merge(SPStyle const *parent)
Combine style and parent style specifications into a single style specification that preserves (as mu...
Definition style.cpp:843
T< SPAttr::COLOR_INTERPOLATION, SPIEnum< SPColorInterpolation > > color_interpolation
color-interpolation
Definition style.h:227
T< SPAttr::COLOR, SPIColor > color
color
Definition style.h:225
T< SPAttr::SHAPE_PADDING, SPILength > shape_padding
Definition style.h:181
void mergeCSS(SPCSSAttr *css)
Definition style.cpp:859
sigc::signal< void(SPObject *, SPObject *)> signal_fill_ps_changed
Emitted when the fill paint server changes, meaning it starts pointing to a different object.
Definition style.h:322
Glib::ustring writeIfDiff(SPStyle const *base) const
Get CSS string for set properties which are different from the given base style.
Definition style.cpp:799
sigc::connection fill_ps_changed_connection
Definition style.h:312
SPPaintServer * getFillPaintServer()
Definition style.h:339
T< SPAttr::FILL, SPIPaint > fill
fill
Definition style.h:240
bool block_filter_bbox_updates
(hack) Temporarily set to true to block filter changes from updating the object's bbox in situations ...
Definition style.h:303
T< SPAttr::STROKE, SPIPaint > stroke
stroke
Definition style.h:247
SPFilter * getFilter()
Definition style.h:335
T< SPAttr::STOP_COLOR, SPIColor > stop_color
gradient-stop
Definition style.h:284
T< SPAttr::LINE_HEIGHT, SPILengthOrNormal > line_height
Line height (css2 10.8.1)
Definition style.h:118
SPPaintServer * getStrokePaintServer()
Definition style.h:343
void _mergeDeclList(CRDeclaration const *decl_list, SPStyleSrc const &source)
Definition style.cpp:913
SPObject * object
Object we are attached to.
Definition style.h:84
T< SPAttr::FONT_FEATURE_SETTINGS, SPIString > font_feature_settings
Font feature settings (Low level access to TrueType tables)
Definition style.h:140
T< SPAttr::LETTER_SPACING, SPILengthOrNormal > letter_spacing
letter spacing (css2 16.4)
Definition style.h:153
void mergeStatement(CRStatement *statement)
Append an existing css statement into this style, used in css editing always appends declarations as ...
Definition style.cpp:870
void _mergeProps(CRPropList *props)
Definition style.cpp:967
void readFromObject(SPObject *object)
Read style properties from object's repr.
Definition style.cpp:608
T< SPAttr::MARKER_END, SPIString > marker_end
Definition style.h:269
T< SPAttr::STROKE_WIDTH, SPILength > stroke_width
stroke-width
Definition style.h:249
bool cloned
style belongs to a cloned object
Definition style.h:299
std::string getFontFeatureString()
Return a font feature string useful for Pango.
Definition style.cpp:1017
T< SPAttr::TEXT_DECORATION_COLOR, SPIColor > text_decoration_color
Definition style.h:193
T< SPAttr::TEXT_DECORATION, SPITextDecoration > text_decoration
text decoration (css2 16.3.1)
Definition style.h:188
Glib::ustring write(unsigned flags, SPStyleSrc style_src_req, SPStyle const *base=nullptr) const
std::map< std::string, std::string > extended_properties
Definition style.h:359
T< SPAttr::MARKER_START, SPIString > marker_start
Definition style.h:267
SPIPaint * getFillOrStroke(bool fill_)
Get either the fill or the stroke property.
Definition style.h:355
T< SPAttr::WORD_SPACING, SPILengthOrNormal > word_spacing
word spacing (also css2 16.4)
Definition style.h:155
std::vector< SPIBase * > _properties
Pointers to all the properties (for looping through them)
Definition style.h:90
sigc::signal< void(SPObject *, SPObject *)> signal_stroke_ps_changed
Emitted when the stroke paint server changes, meaning it starts pointing to a different object.
Definition style.h:328
sigc::connection filter_modified_connection
Definition style.h:307
void mergeString(char const *p)
Parses a style="..." string and merges it with an existing SPStyle.
Definition style.cpp:854
T< SPAttr::MARKER_MID, SPIString > marker_mid
Definition style.h:268
void readIfUnset(SPAttr id, char const *val, SPStyleSrc const &source=SPStyleSrc::STYLE_PROP)
Definition style.cpp:650
T< SPAttr::INLINE_SIZE, SPILength > inline_size
Definition style.h:183
void read(SPObject *object, Inkscape::XML::Node *repr)
Definition style.cpp:539
T< SPAttr::FONT_VARIANT_NUMERIC, SPINumeric > font_variant_numeric
Font variant numeric (numerical formatting)
Definition style.h:134
T< SPAttr::MARKER, SPIString > marker
Marker list.
Definition style.h:266
SPStyle(SPDocument *document=nullptr, SPObject *object=nullptr)
Definition style.cpp:251
T< SPAttr::SHAPE_INSIDE, SPIShapes > shape_inside
SVG2 Text Wrapping.
Definition style.h:179
sigc::connection filter_changed_connection
Definition style.h:311
sigc::connection fill_ps_modified_connection
Definition style.h:308
T< SPAttr::FONT_VARIANT_CAPS, SPIEnum< SPCSSFontVariantCaps > > font_variant_caps
Font variant caps (small caps)
Definition style.h:132
void _mergeObjectStylesheet(SPObject const *object)
Definition style.cpp:981
sigc::connection stroke_ps_changed_connection
Definition style.h:313
T< SPAttr::FILTER, SPIFilter > filter
Filter effect.
Definition style.h:275
T< SPAttr::FONT_VARIANT_POSITION, SPIEnum< SPCSSFontVariantPosition > > font_variant_position
Font variant position (subscript/superscript)
Definition style.h:130
T< SPAttr::FONT, SPIFont > font
Font shorthand.
Definition style.h:122
SPIString * marker_ptrs[SP_MARKER_LOC_QTY]
Definition style.h:270
T< SPAttr::STROKE_DASHOFFSET, SPILength > stroke_dashoffset
stroke-dashoffset
Definition style.h:259
T< SPAttr::SHAPE_MARGIN, SPILength > shape_margin
Definition style.h:182
T< SPAttr::SOLID_COLOR, SPIColor > solid_color
solid-color
Definition style.h:232
T< SPAttr::SHAPE_SUBTRACT, SPIShapes > shape_subtract
Definition style.h:180
bool operator==(SPStyle const &rhs) const
Definition style.cpp:883
sigc::signal< void(SPObject *, SPObject *)> signal_filter_changed
Emitted when the filter changes, meaning it starts pointing to a different object.
Definition style.h:333
T< SPAttr::TEXT_INDENT, SPILength > text_indent
First line indent of paragraphs (css2 16.1)
Definition style.h:148
void readFromPrefs(Glib::ustring const &path)
Read style properties from preferences.
Definition style.cpp:625
~SPStyle()
Definition style.cpp:467
void _mergeString(char const *p)
Definition style.cpp:901
sigc::connection stroke_ps_modified_connection
Definition style.h:309
void cascade(SPStyle const *parent)
Sets computed values in style, which may involve inheriting from (or in some other way calculating fr...
Definition style.cpp:817
T< SPAttr::FONT_VARIANT_LIGATURES, SPILigatures > font_variant_ligatures
Font variant ligatures.
Definition style.h:128
sigc::connection release_connection
Definition style.h:305
SPDocument * document
Document we are associated with.
Definition style.h:86
void _mergeDecl(CRDeclaration const *decl, SPStyleSrc const &source)
Definition style.cpp:927
T< SPAttr::BASELINE_SHIFT, SPIBaselineShift > baseline_shift
Baseline shift (svg1.1 10.9.2)
Definition style.h:169
const double w
Definition conic-4.cpp:19
CRDeclaration * cr_declaration_parse_list_from_buf(const guchar *a_str, enum CREncoding a_enc)
void cr_declaration_destroy(CRDeclaration *a_this)
void cr_prop_list_destroy(CRPropList *a_this)
typedefG_BEGIN_DECLS struct _CRPropList CRPropList
CRPropList * cr_prop_list_get_next(CRPropList *a_this)
enum CRStatus cr_prop_list_get_decl(CRPropList const *a_this, CRDeclaration **a_decl)
The declaration of the CRSelEng class.
typedefG_BEGIN_DECLS struct _CRSelEng CRSelEng
Definition cr-sel-eng.h:43
CRSelEng * cr_sel_eng_new(CRNodeIface const *)
enum CRStatus cr_sel_eng_get_matched_properties_from_cascade(CRSelEng *a_this, CRCascade *a_cascade, CRXMLNodePtr a_node, CRPropList **a_props)
@ RULESET_STMT
enum CRStatus cr_statement_ruleset_get_declarations(CRStatement *a_this, CRDeclaration **a_decl_list)
guchar * cr_term_to_string(CRTerm const *a_this)
CRStatus
The status type returned by the methods of the croco library.
Definition cr-utils.h:42
@ CR_OK
Definition cr-utils.h:43
@ CR_UTF_8
Definition cr-utils.h:89
TODO: insert short description here.
TODO: insert short description here.
std::shared_ptr< Css const > css
Css & result
Geom::IntPoint size
Colors::Color fill
Colors::Color stroke
static char const *const parent
Definition dir-util.cpp:70
SPItem * item
static InkscapeApplication * _instance
size_t v
static R & release(R &r)
Decrements the reference count of a anchored object.
T * get(GValue *value)
Returns a borrowed pointer to the T held by a value if it holds one, else nullptr.
Definition value-utils.h:64
CRNodeIface const croco_node_iface
Interface for XML nodes used by libcroco.
static cairo_user_data_key_t key
Singleton class to access the preferences file in a convenient way.
Ocnode ** ref
Definition quantize.cpp:32
SPCSSAttr * sp_repr_css_attr_new()
Creates an empty SPCSSAttr (a class for manipulating CSS style properties).
Definition repr-css.cpp:67
void sp_repr_css_write_string(SPCSSAttr *css, Glib::ustring &str)
Write a style attribute string from a list of properties stored in an SPCSAttr object.
Definition repr-css.cpp:242
void sp_repr_css_change(Node *repr, SPCSSAttr *css, gchar const *attr)
Creates a new SPCSAttr with the values filled from a repr, merges in properties from the given SPCSAt...
Definition repr-css.cpp:357
void sp_repr_css_attr_unref(SPCSSAttr *css)
Unreferences an SPCSSAttr (will be garbage collected if no references remain).
Definition repr-css.cpp:76
void sp_repr_css_change_recursive(Node *repr, SPCSSAttr *css, gchar const *attr)
Definition repr-css.cpp:370
char const * sp_repr_css_property(SPCSSAttr *css, gchar const *name, gchar const *defval)
Returns a character string of the value of a given style property or a default value if the attribute...
Definition repr-css.cpp:147
void sp_repr_css_unset_property(SPCSSAttr *css, gchar const *name)
Set a style property to "inkscape:unset".
Definition repr-css.cpp:201
void sp_repr_css_set_property(SPCSSAttr *css, gchar const *name, gchar const *value)
Set a style property to a new value (e.g.
Definition repr-css.cpp:190
void sp_repr_css_attr_add_from_string(SPCSSAttr *css, gchar const *p)
Use libcroco to parse a string for CSS properties and then merge them into an existing SPCSSAttr.
Definition repr-css.cpp:340
Inkscape::XML::SimpleDocument - generic XML document implementation.
@ SP_MARKER_LOC_START
@ SP_MARKER_LOC_END
@ SP_MARKER_LOC_MID
@ SP_MARKER_LOC
CRString *CRTerm * value
The property.
CRDeclaration * next
The abstraction of css statement as defined in the chapter 4 and appendix D.1 of the css2 spec.
enum CRStatementType type
The type of the statement.
@ SP_CSS_SHAPE_RENDERING_AUTO
@ SP_CSS_TEXT_ANCHOR_START
@ SP_WIND_RULE_NONZERO
Definition style-enums.h:24
@ SP_CSS_OVERFLOW_VISIBLE
@ SP_CSS_FONT_VARIANT_LIGATURES_CONTEXTUAL
@ SP_CSS_FONT_VARIANT_LIGATURES_DISCRETIONARY
@ SP_CSS_FONT_VARIANT_LIGATURES_HISTORICAL
@ SP_CSS_FONT_VARIANT_LIGATURES_COMMON
@ SP_CSS_TEXT_RENDERING_AUTO
@ SP_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS
@ SP_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS
@ SP_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS
@ SP_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO
@ SP_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS
@ SP_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS
@ SP_CSS_FONT_VARIANT_NUMERIC_ORDINAL
@ SP_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS
@ SP_CSS_BACKGROUND_ACCUMULATE
@ SP_CSS_BLEND_NORMAL
@ SP_STROKE_LINEJOIN_MITER
Definition style-enums.h:34
@ SP_CSS_COLOR_RENDERING_AUTO
@ SP_CSS_TEXT_ALIGN_START
@ SP_CSS_FONT_VARIANT_NORMAL
Definition style-enums.h:67
@ SP_CSS_ISOLATION_AUTO
@ SP_CSS_FONT_STYLE_NORMAL
Definition style-enums.h:61
@ SP_CSS_IMAGE_RENDERING_AUTO
@ SP_CSS_BASELINE_AUTO
@ SP_CSS_FONT_STRETCH_NORMAL
Definition style-enums.h:92
@ SP_CSS_FONT_VARIANT_CAPS_ALL_SMALL
@ SP_CSS_FONT_VARIANT_CAPS_SMALL
@ SP_CSS_FONT_VARIANT_CAPS_ALL_PETITE
@ SP_CSS_FONT_VARIANT_CAPS_NORMAL
@ SP_CSS_FONT_VARIANT_CAPS_UNICASE
@ SP_CSS_FONT_VARIANT_CAPS_TITLING
@ SP_CSS_FONT_VARIANT_CAPS_PETITE
@ SP_CSS_COLOR_INTERPOLATION_SRGB
@ SP_CSS_COLOR_INTERPOLATION_LINEARRGB
@ SP_CSS_TEXT_TRANSFORM_NONE
@ SP_CSS_FONT_VARIANT_EAST_ASIAN_RUBY
@ SP_CSS_FONT_VARIANT_EAST_ASIAN_JIS04
@ SP_CSS_FONT_VARIANT_EAST_ASIAN_PROPORTIONAL_WIDTH
@ SP_CSS_FONT_VARIANT_EAST_ASIAN_JIS78
@ SP_CSS_FONT_VARIANT_EAST_ASIAN_JIS90
@ SP_CSS_FONT_VARIANT_EAST_ASIAN_TRADITIONAL
@ SP_CSS_FONT_VARIANT_EAST_ASIAN_FULL_WIDTH
@ SP_CSS_FONT_VARIANT_EAST_ASIAN_JIS83
@ SP_CSS_FONT_VARIANT_EAST_ASIAN_SIMPLIFIED
@ SP_CSS_DISPLAY_INLINE
@ SP_CSS_FONT_VARIANT_ALTERNATES_NORMAL
@ SP_CSS_WRITING_MODE_LR_TB
@ SP_CSS_DIRECTION_LTR
@ SP_STROKE_LINECAP_BUTT
Definition style-enums.h:41
@ SP_CSS_FONT_VARIANT_POSITION_SUB
@ SP_CSS_FONT_VARIANT_POSITION_SUPER
@ SP_CSS_FONT_VARIANT_POSITION_NORMAL
@ SP_CSS_WHITE_SPACE_NORMAL
@ SP_CSS_TEXT_ORIENTATION_MIXED
@ SP_CSS_FONT_WEIGHT_NORMAL
Definition style-enums.h:81
@ SP_CSS_VISIBILITY_VISIBLE
void sp_style_filter_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style)
Gets called when the filter is (re)attached to the style.
Definition style.cpp:1147
void sp_style_fill_paint_server_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style)
Gets called when the paintserver is (re)attached to the style.
Definition style.cpp:1193
void sp_style_stroke_paint_server_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style)
Gets called when the paintserver is (re)attached to the style.
Definition style.cpp:1210
SPStyleSrc
static const unsigned SP_STYLE_FLAG_IFSET(1<< 0)
static const unsigned SP_STYLE_FLAG_ALWAYS(1<< 2)
static const unsigned SP_STYLE_FLAG_IFSRC(1<< 3)
static const unsigned SP_STYLE_FLAG_IFDIFF(1<< 1)
@ SP_CSS_UNIT_IN
@ SP_CSS_UNIT_PT
@ SP_CSS_UNIT_PX
@ SP_CSS_UNIT_PC
@ SP_CSS_UNIT_MM
@ SP_CSS_UNIT_PERCENT
@ SP_CSS_UNIT_NONE
@ SP_CSS_UNIT_EM
@ SP_CSS_UNIT_CM
@ SP_CSS_UNIT_EX
static CRSelEng * sp_repr_sel_eng()
Definition style.cpp:1225
SPCSSAttr * sp_css_attr_unset_blacklist(SPCSSAttr *css)
Unset properties that should not be set for default tool style.
Definition style.cpp:1498
void sp_style_filter_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style)
Gets called when the filter is (re)attached to the style.
Definition style.cpp:1147
void sp_style_set_ipaint_to_uri_string(SPStyle *style, SPIPaint *paint, const gchar *uri)
Definition style.cpp:1287
auto & _prop_helper
Definition style.cpp:246
void css_font_family_unquote(Glib::ustring &val)
Remove paired single and double quotes from font names in font-family lists, changing string in place...
Definition style.cpp:1724
static void sp_style_filter_ref_modified(SPObject *obj, unsigned flags, SPStyle *style)
Emit style modified signal on style's object if the filter changed.
Definition style.cpp:1126
void sp_style_set_property_url(SPObject *item, gchar const *property, SPObject *linked, bool recursive)
Definition style.cpp:1380
SPCSSAttr * sp_css_attr_from_object(SPObject *object, guint const flags)
Definition style.cpp:1427
SPCSSAttr * sp_css_attr_unset_text(SPCSSAttr *css)
Unset any text-related properties.
Definition style.cpp:1444
static constexpr int BMAX
Definition style.cpp:55
SPCSSAttr * sp_css_attr_scale(SPCSSAttr *css, double ex)
Scale any properties that may hold <length> by ex.
Definition style.cpp:1627
void css_quote(Glib::ustring &val)
Quote and/or escape string for writing to CSS, changing strings in place.
Definition style.cpp:1648
void sp_style_fill_paint_server_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style)
Gets called when the paintserver is (re)attached to the style.
Definition style.cpp:1193
void sp_style_set_to_uri(SPStyle *style, bool isfill, Inkscape::URI const *uri)
Definition style.cpp:1298
double sp_style_css_size_px_to_units(double size, int unit, double font_size)
Definition style.cpp:1332
SPCSSAttr * sp_css_attr_unset_uris(SPCSSAttr *css)
Unset any properties that contain URI values.
Definition style.cpp:1543
void sp_style_stroke_paint_server_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style)
Gets called when the paintserver is (re)attached to the style.
Definition style.cpp:1210
static void sp_style_object_release(SPObject *object, SPStyle *style)
Release callback.
Definition style.cpp:1116
static void sp_style_paint_server_ref_modified(SPObject *obj, unsigned, SPStyle *style)
Emit style modified signal on style's object if server is style's fill or stroke paint server.
Definition style.cpp:1167
double sp_style_css_size_units_to_px(double size, int unit, double font_size)
Definition style.cpp:1367
static bool is_url(char const *p)
Definition style.cpp:1524
static void sp_css_attr_scale_property_single(SPCSSAttr *css, gchar const *property, double ex, bool only_with_units=false)
Scale a single-value property.
Definition style.cpp:1568
void css_unquote(Glib::ustring &val)
Remove paired single and double quotes from a string, changing string in place.
Definition style.cpp:1706
void sp_style_set_ipaint_to_uri(SPStyle *style, SPIPaint *paint, const Inkscape::URI *uri, SPDocument *document)
Definition style.cpp:1249
SPCSSAttr * sp_css_attr_from_style(SPStyle const *const style, guint const flags)
Definition style.cpp:1409
static void sp_css_attr_scale_property_list(SPCSSAttr *css, gchar const *property, double ex)
Scale a list-of-values property.
Definition style.cpp:1594
void css_font_family_quote(Glib::ustring &val)
Quote font names in font-family lists, changing string in place.
Definition style.cpp:1687
gchar const * sp_style_get_css_unit_string(int unit)
Definition style.cpp:1305
SPStyle - a style object for SPItem objects.
SPIBase SPStyle::* SPIBasePtr
Definition style.h:35
Glib::ustring name
Definition toolbars.cpp:55