// SPDX-License-Identifier: GPL-2.0-or-later #ifndef SEEN_SP_STYLE_H #define SEEN_SP_STYLE_H /** \file * SPStyle - a style object for SPItem objects */ /* Authors: * Lauris Kaplinski * Jon A. Cruz * Tavmjong Bah * * Copyright (C) 2014 Tavmjong Bah * Copyright (C) 2010 Jon A. Cruz * Copyright (C) 2001-2002 Lauris Kaplinski * Copyright (C) 2001 Ximian, Inc. * * Released under GNU GPL v2+, read the file 'COPYING' for more information. */ #include "style-enums.h" #include "style-internal.h" #include #include #include #include #include "3rdparty/libcroco/cr-declaration.h" #include "3rdparty/libcroco/cr-prop-list.h" enum class SPAttr; // Define SPIBasePtr, a Pointer to a data member of SPStyle of type SPIBase; typedef SPIBase SPStyle::*SPIBasePtr; namespace Inkscape { namespace XML { class Node; } } /// An SVG style object. class SPStyle { public: SPStyle(SPDocument *document = nullptr, SPObject *object = nullptr);// document is ignored if valid object given ~SPStyle(); const std::vector properties(); void clear(); void clear(SPAttr id); void read(SPObject *object, Inkscape::XML::Node *repr); void readFromObject(SPObject *object); void readFromPrefs(Glib::ustring const &path); bool isSet(SPAttr id); void readIfUnset(SPAttr id, char const *val, SPStyleSrc const &source = SPStyleSrc::STYLE_PROP ); private: Glib::ustring write(unsigned int flags, SPStyleSrc style_src_req, SPStyle const *base = nullptr) const; public: Glib::ustring write(unsigned int flags = SP_STYLE_FLAG_IFSET) const; Glib::ustring write(SPStyleSrc style_src_req) const; Glib::ustring writeIfDiff(SPStyle const *base) const; void cascade( SPStyle const *const parent ); void merge( SPStyle const *const parent ); void mergeString( char const *const p ); void mergeStatement( CRStatement *statement ); bool operator==(const SPStyle& rhs); int style_ref() { ++_refcount; return _refcount; } int style_unref() { --_refcount; return _refcount; } int refCount() { return _refcount; } private: void _mergeString( char const *const p ); void _mergeDeclList( CRDeclaration const *const decl_list, SPStyleSrc const &source ); void _mergeDecl( CRDeclaration const *const decl, SPStyleSrc const &source ); void _mergeProps( CRPropList *const props ); void _mergeObjectStylesheet( SPObject const *const object ); void _mergeObjectStylesheet( SPObject const *const object, SPDocument *const document ); private: int _refcount; static int _count; // Poor man's leak detector // FIXME: Make private public: /** Object we are attached to */ SPObject *object; /** Document we are associated with */ SPDocument *document; private: /// Pointers to all the properties (for looping through them) std::vector _properties; // Shorthand for better readability template using T = TypedSPI; public: /* ----------------------- THE PROPERTIES ------------------------- */ /* Match order in style.cpp. */ /* SVG 2 attributes promoted to properties. */ /** Path data */ T d; /* Font ---------------------------- */ /** Font style */ T> font_style; /** Which substyle of the font (CSS 2. CSS 3 redefines as shorthand) */ T> font_variant; /** Weight of the font */ T> font_weight; /** Stretch of the font */ T> font_stretch; /** Size of the font */ T font_size; /** Line height (css2 10.8.1) */ T line_height; /** Font family */ T font_family; /** Font shorthand */ T font; /** Full font name, as font_factory::ConstructFontSpecification would give, for internal use. */ T font_specification; /* Font variants -------------------- */ /** Font variant ligatures */ T font_variant_ligatures; /** Font variant position (subscript/superscript) */ T> font_variant_position; /** Font variant caps (small caps) */ T> font_variant_caps; /** Font variant numeric (numerical formatting) */ T font_variant_numeric; /** Font variant alternates (alternates/swatches) */ T> font_variant_alternates; /** Font variant East Asian */ T font_variant_east_asian; /** Font feature settings (Low level access to TrueType tables) */ T font_feature_settings; /** Font variation settings (Low level access to OpenType variable font design-coordinate values) */ T font_variation_settings; /* Text ----------------------------- */ /** First line indent of paragraphs (css2 16.1) */ T text_indent; /** text alignment (css2 16.2) (not to be confused with text-anchor) */ T> text_align; /** letter spacing (css2 16.4) */ T letter_spacing; /** word spacing (also css2 16.4) */ T word_spacing; /** capitalization (css2 16.5) */ T> text_transform; /* CSS3 Text */ /** text direction (svg1.1) */ T> direction; /** Writing mode (svg1.1 10.7.2, CSS Writing Modes 3) */ T> writing_mode; /** Text orientation (CSS Writing Modes 3) */ T> text_orientation; /** Dominant baseline (svg1.1) */ T> dominant_baseline; /** Baseline shift (svg1.1 10.9.2) */ T baseline_shift; /* SVG */ /** Anchor of the text (svg1.1 10.9.1) */ T> text_anchor; /** white space (svg2) */ T> white_space; /** SVG2 Text Wrapping */ T shape_inside; T shape_subtract; T shape_padding; T shape_margin; T inline_size; /* Text Decoration ----------------------- */ /** text decoration (css2 16.3.1) */ T text_decoration; /** CSS 3 2.1, 2.2, 2.3 */ /** Not done yet, test_decoration3 = css3 2.4*/ T text_decoration_line; T text_decoration_style; // SPIEnum? Only one can be set at time. T text_decoration_color; T text_decoration_fill; T text_decoration_stroke; // 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 */ T> clip_rule; /** display */ T> display; /** overflow */ T> overflow; /** visibility */ T> visibility; /** opacity */ T opacity; /** mix-blend-mode: CSS Compositing and Blending Level 1 */ T> isolation; T> mix_blend_mode; T paint_order; /** color */ T color; /** color-interpolation */ T> color_interpolation; /** color-interpolation-filters */ T> color_interpolation_filters; /** solid-color */ T solid_color; /** solid-opacity */ T solid_opacity; /** vector effect */ T vector_effect; /** fill */ T fill; /** fill-opacity */ T fill_opacity; /** fill-rule: 0 nonzero, 1 evenodd */ T> fill_rule; /** stroke */ T stroke; /** stroke-width */ T stroke_width; /** stroke-linecap */ T> stroke_linecap; /** stroke-linejoin */ T> stroke_linejoin; /** stroke-miterlimit */ T stroke_miterlimit; /** stroke-dasharray */ T stroke_dasharray; /** stroke-dashoffset */ T stroke_dashoffset; /** stroke-opacity */ T stroke_opacity; /** -inkscape-stroke */ T stroke_extensions; /** Marker list */ T marker; T marker_start; T marker_mid; T marker_end; SPIString* marker_ptrs[SP_MARKER_LOC_QTY]; /* Filter effects ------------------------ */ /** Filter effect */ T filter; /** normally not used, but duplicates the Gaussian blur deviation (if any) from the attached filter when the style is used for querying */ // TODO remove, find other logic for querying T filter_gaussianBlur_deviation; /** enable-background, used for defining where filter effects get their background image */ T> enable_background; /** gradient-stop */ T stop_color; T stop_opacity; /* Rendering hints ----------------------- */ /** hints on how to render: e.g. speed vs. accuracy. * As of April, 2013, only image_rendering used. */ T> color_rendering; T> image_rendering; T> shape_rendering; T> text_rendering; /* ----------------------- END PROPERTIES ------------------------- */ /// style belongs to a cloned object bool cloned; sigc::connection release_connection; sigc::connection filter_modified_connection; sigc::connection fill_ps_modified_connection; sigc::connection stroke_ps_modified_connection; sigc::connection filter_changed_connection; sigc::connection fill_ps_changed_connection; sigc::connection stroke_ps_changed_connection; /** * Emitted when paint server object, fill paint refers to, is changed. That is * when the reference starts pointing to a different address in memory. * * NB It is different from fill_ps_modified signal. When paint server is modified * it means some of it's attributes or children change. */ sigc::signal signal_fill_ps_changed; /** * Emitted when paint server object, fill paint refers to, is changed. That is * when the reference starts pointing to a different address in memory. */ sigc::signal signal_stroke_ps_changed; SPFilter *getFilter() { return (filter.href) ? filter.href->getObject() : nullptr; } SPFilter const *getFilter() const { return (filter.href) ? filter.href->getObject() : nullptr; } Inkscape::URI const *getFilterURI() const { return (filter.href) ? filter.href->getURI() : nullptr; } SPPaintServer *getFillPaintServer() { return (fill.value.href) ? fill.value.href->getObject() : nullptr; } SPPaintServer const *getFillPaintServer() const { return (fill.value.href) ? fill.value.href->getObject() : nullptr; } Inkscape::URI const *getFillURI() const { return (fill.value.href) ? fill.value.href->getURI() : nullptr; } SPPaintServer *getStrokePaintServer() { return (stroke.value.href) ? stroke.value.href->getObject() : nullptr; } SPPaintServer const *getStrokePaintServer() const { return (stroke.value.href) ? stroke.value.href->getObject() : nullptr; } Inkscape::URI const *getStrokeURI() const { return (stroke.value.href) ? stroke.value.href->getURI() : nullptr; } /** * Return a font feature string useful for Pango. */ std::string getFontFeatureString(); /** * Get either the fill or the stroke property */ SPIPaint *getFillOrStroke(bool fill_) { return fill_ ? fill.upcast() : stroke.upcast(); } SPIPaint const *getFillOrStroke(bool fill_) const { return fill_ ? fill.upcast() : stroke.upcast(); } /* ----------------------- EXTENDED PROPERTIES ------------------------- */ std::map extended_properties; }; SPStyle *sp_style_ref(SPStyle *style); // SPStyle::ref(); SPStyle *sp_style_unref(SPStyle *style); // SPStyle::unref(); void sp_style_set_to_uri(SPStyle *style, bool isfill, Inkscape::URI const *uri); // ? char const *sp_style_get_css_unit_string(int unit); // No change? #define SP_CSS_FONT_SIZE_DEFAULT 12.0 double sp_style_css_size_px_to_units(double size, int unit, double font_size = SP_CSS_FONT_SIZE_DEFAULT); // No change? double sp_style_css_size_units_to_px(double size, int unit, double font_size = SP_CSS_FONT_SIZE_DEFAULT); // No change? SPCSSAttr *sp_css_attr_from_style (SPStyle const *const style, unsigned int flags); SPCSSAttr *sp_css_attr_from_object(SPObject *object, unsigned int flags = SP_STYLE_FLAG_IFSET); SPCSSAttr *sp_css_attr_unset_text(SPCSSAttr *css); SPCSSAttr *sp_css_attr_unset_blacklist(SPCSSAttr *css); SPCSSAttr *sp_css_attr_unset_uris(SPCSSAttr *css); SPCSSAttr *sp_css_attr_scale(SPCSSAttr *css, double ex); void sp_style_unset_property_attrs(SPObject *o); void sp_style_set_property_url (SPObject *item, char const *property, SPObject *linked, bool recursive); void css_quote( Glib::ustring &val ); // Add quotes around CSS values void css_unquote( Glib::ustring &val ); // Remove quotes from CSS values (style-internal.cpp, xml/repr-css.cpp) void css_font_family_quote( Glib::ustring &val ); // style-internal.cpp, text-toolbar.cpp void css_font_family_unquote( Glib::ustring &val ); // style-internal.cpp, text-toolbar.cpp Glib::ustring css2_escape_quote(char const *val); #endif // SEEN_SP_STYLE_H /* 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 :