Code

Merge from trunk
[inkscape.git] / src / style.h
1 #ifndef SEEN_SP_STYLE_H
2 #define SEEN_SP_STYLE_H
4 /** \file
5  * SPStyle - a style object for SPItem objects
6  */
7 /* Authors:
8  *   Lauris Kaplinski <lauris@kaplinski.com>
9  *   Jon A. Cruz <jon@joncruz.org>
10  *
11  * Copyright (C) 2010 Jon A. Cruz
12  * Copyright (C) 2001-2002 Lauris Kaplinski
13  * Copyright (C) 2001 Ximian, Inc.
14  *
15  * Released under GNU GPL, read the file 'COPYING' for more information
16  */
18 #include "color.h"
19 #include "forward.h"
20 #include "sp-marker-loc.h"
21 #include "sp-filter.h"
22 #include "sp-filter-reference.h"
23 #include "uri-references.h"
24 #include "uri.h"
25 #include "sp-paint-server.h"
27 #include <sigc++/connection.h>
29 namespace Inkscape {
30 namespace XML {
31 class Node;
32 }
33 }
35 class SPCSSAttr;
37 class SPIFloat;
38 class SPIScale24;
39 class SPIInt;
40 class SPIShort;
41 class SPIEnum;
42 class SPIString;
43 class SPILength;
44 class SPIPaint;
45 class SPIFontSize;
47 /// Float type internal to SPStyle.
48 struct SPIFloat {
49     unsigned set : 1;
50     unsigned inherit : 1;
51     unsigned data : 30;
52     float value;
53 };
55 /*
56  * One might think that the best value for SP_SCALE24_MAX would be ((1<<24)-1), which allows the
57  * greatest possible precision for fitting [0, 1] fractions into 24 bits.
58  *
59  * However, in practice, that gives a problem with 0.5, which falls half way between two fractions
60  * of ((1<<24)-1).  What's worse is that casting double(1<<23) / ((1<<24)-1) to float on x86
61  * produces wrong rounding behaviour, resulting in a fraction of ((1<<23)+2.0f) / (1<<24) rather
62  * than ((1<<23)+1.0f) / (1<<24) as one would expect, let alone ((1<<23)+0.0f) / (1<<24) as one
63  * would ideally like for this example.
64  *
65  * The value (1<<23) is thus best if one considers float conversions alone.
66  *
67  * The value 0xff0000 can exactly represent all 8-bit alpha channel values,
68  * and can exactly represent all multiples of 0.1.  I haven't yet tested whether
69  * rounding bugs still get in the way of conversions to & from float, but my instinct is that
70  * it's fairly safe because 0xff fits three times inside float's significand.
71  *
72  * We should probably use the value 0xffff00 once we support 16 bits per channel and/or LittleCMS,
73  * though that might need to be accompanied by greater use of double instead of float for
74  * colours and opacities, to be safe from rounding bugs.
75  */
76 #define SP_SCALE24_MAX (0xff0000)
77 #define SP_SCALE24_TO_FLOAT(v) ((double) (v) / SP_SCALE24_MAX)
78 #define SP_SCALE24_FROM_FLOAT(v) unsigned(((v) * SP_SCALE24_MAX) + .5)
80 /** Returns a scale24 for the product of two scale24 values. */
81 #define SP_SCALE24_MUL(_v1, _v2) unsigned((double)(_v1) * (_v2) / SP_SCALE24_MAX + .5)
83 /// 24 bit data type internal to SPStyle.
84 struct SPIScale24 {
85     unsigned set : 1;
86     unsigned inherit : 1;
87     unsigned value : 24;
88 };
90 /// Int type internal to SPStyle.
91 struct SPIInt {
92     unsigned set : 1;
93     unsigned inherit : 1;
94     unsigned data : 30;
95     int value;
96 };
98 /// Short type internal to SPStyle.
99 struct SPIShort {
100     unsigned set : 1;
101     unsigned inherit : 1;
102     unsigned data : 14;
103     int value : 16;
104 };
106 /// Enum type internal to SPStyle.
107 struct SPIEnum {
108     unsigned set : 1;
109     unsigned inherit : 1;
110     unsigned value : 8;
111     unsigned computed : 8;
112 };
114 /// String type internal to SPStyle.
115 struct SPIString {
116     unsigned set : 1;
117     unsigned inherit : 1;
118     unsigned data : 30;
119     gchar *value;
120 };
122 enum {
123     SP_CSS_UNIT_NONE,
124     SP_CSS_UNIT_PX,
125     SP_CSS_UNIT_PT,
126     SP_CSS_UNIT_PC,
127     SP_CSS_UNIT_MM,
128     SP_CSS_UNIT_CM,
129     SP_CSS_UNIT_IN,
130     SP_CSS_UNIT_EM,
131     SP_CSS_UNIT_EX,
132     SP_CSS_UNIT_PERCENT
133 };
135 /// Length type internal to SPStyle.
136 struct SPILength {
137     unsigned set : 1;
138     unsigned inherit : 1;
139     unsigned unit : 4;
140     float value;
141     float computed;
142 };
144 #define SP_STYLE_FILL_SERVER(s) (((SPStyle *) (s))->getFillPaintServer())
145 #define SP_STYLE_STROKE_SERVER(s) (((SPStyle *) (s))->getStrokePaintServer())
146 #define SP_OBJECT_STYLE_FILL_SERVER(o) (SP_OBJECT (o)->style->getFillPaintServer())
147 #define SP_OBJECT_STYLE_STROKE_SERVER(o) (SP_OBJECT (o)->style->getStrokePaintServer())
149 class SVGICCColor;
151 /// Paint type internal to SPStyle.
152 struct SPIPaint {
153     unsigned set : 1;
154     unsigned inherit : 1;
155     unsigned currentcolor : 1;
156     unsigned int colorSet : 1;
157     unsigned int noneSet : 1;
158     struct {
159          SPPaintServerReference *href;
160          SPColor color;
161     } value;
164     bool isSet() const { return true; /* set || colorSet*/}
165     bool isSameType( SPIPaint const & other ) const {return (isPaintserver() == other.isPaintserver()) && (colorSet == other.colorSet) && (currentcolor == other.currentcolor);}
167     bool isNoneSet() const {return noneSet;}
169     bool isNone() const {return !currentcolor && !colorSet && !isPaintserver();} // TODO refine
170     bool isColor() const {return colorSet && !isPaintserver();}
171     bool isPaintserver() const {return value.href && value.href->getObject();}
173     void clear();
175     void setColor( float r, float g, float b ) {value.color.set( r, g, b ); colorSet = true;}
176     void setColor( guint32 val ) {value.color.set( val ); colorSet = true;}
177     void setColor( SPColor const& color ) {value.color = color; colorSet = true;}
178 };
180 /// Filter type internal to SPStyle
181 struct SPIFilter {
182     unsigned set : 1;
183     unsigned inherit : 1;
184     SPFilterReference *href;
185 };
187 enum {
188     SP_FONT_SIZE_LITERAL,
189     SP_FONT_SIZE_LENGTH,
190     SP_FONT_SIZE_PERCENTAGE
191 };
193 #define SP_FONT_SIZE ((1 << 24) - 1)
195 #define SP_F8_16_TO_FLOAT(v) ((gdouble) (v) / (1 << 16))
196 #define SP_F8_16_FROM_FLOAT(v) ((int) ((v) * ((1 << 16) + 0.9999)))
198 #define SP_STYLE_FLAG_IFSET (1 << 0)
199 #define SP_STYLE_FLAG_IFDIFF (1 << 1)
200 #define SP_STYLE_FLAG_ALWAYS (1 << 2)
202 /// Fontsize type internal to SPStyle.
203 struct SPIFontSize {
204     unsigned set : 1;
205     unsigned inherit : 1;
206     unsigned type : 2;
207     unsigned value : 24;
208     float computed;
209 };
211 /// Text decoration type internal to SPStyle.
212 struct SPITextDecoration {
213     unsigned set : 1;
214     unsigned inherit : 1;
215     unsigned underline : 1;
216     unsigned overline : 1;
217     unsigned line_through : 1;
218     unsigned blink : 1;    // "Conforming user agents are not required to support this value." yay!
219 };
221 /// Extended length type internal to SPStyle.
222 struct SPILengthOrNormal {
223     unsigned set : 1;
224     unsigned inherit : 1;
225     unsigned normal : 1;
226     unsigned unit : 4;
227     float value;
228     float computed;
229 };
231 class SPTextStyle;
233 /// Stroke dash details.
234 class NRVpathDash {
235 public:
236     double offset;
237     int n_dash;
238     double *dash;
239 };
241 /// An SVG style object.
242 struct SPStyle {
243     int refcount;
245     /** Object we are attached to */
246     SPObject *object;
247     /** Document we are associated with */
248     SPDocument *document;
250     /** Our text style component */
251     SPTextStyle *text;
252     unsigned text_private : 1;
254     /* CSS2 */
255     /* Font */
256     /** Size of the font */
257     SPIFontSize font_size;
258     /** Style of the font */
259     SPIEnum font_style;
260     /** Which substyle of the font */
261     SPIEnum font_variant;
262     /** Weight of the font */
263     SPIEnum font_weight;
264     /** Stretch of the font */
265     SPIEnum font_stretch;
267     /** First line indent of paragraphs (css2 16.1) */
268     SPILength text_indent;
269     /** text alignment (css2 16.2) (not to be confused with text-anchor) */
270     SPIEnum text_align;
271     /** text decoration (css2 16.3.1) */
272     SPITextDecoration text_decoration;
273     // 16.3.2 is text-shadow. That's complicated.
274     /** Line spacing (css2 10.8.1) */
275     SPILengthOrNormal line_height;
276     /** letter spacing (css2 16.4) */
277     SPILengthOrNormal letter_spacing;
278     /** word spacing (also css2 16.4) */
279     SPILengthOrNormal word_spacing;
280     /** capitalization (css2 16.5) */
281     SPIEnum text_transform;
283     /* CSS3 Text */
284     /** text direction (css3 text 3.2) */
285     SPIEnum direction;
286     /** block progression (css3 text 3.2) */
287     SPIEnum block_progression;
288     /** Writing mode (css3 text 3.2 and svg1.1 10.7.2) */
289     SPIEnum writing_mode;
291     /* SVG */
292     /** Anchor of the text (svg1.1 10.9.1) */
293     SPIEnum text_anchor;
295     /* Misc attributes */
296     unsigned clip_set : 1;
297     unsigned color_set : 1;
298     unsigned cursor_set : 1;
299     unsigned overflow_set : 1;
300     unsigned clip_path_set : 1;
301     unsigned clip_rule_set : 1;
302     unsigned mask_set : 1;
304     /** display */
305     SPIEnum display;
307     /** overflow */
308     SPIEnum overflow;
310     /** visibility */
311     SPIEnum visibility;
313     /** opacity */
314     SPIScale24 opacity;
316     /** color */
317     SPIPaint color;
319     /** fill */
320     SPIPaint fill;
321     /** fill-opacity */
322     SPIScale24 fill_opacity;
323     /** fill-rule: 0 nonzero, 1 evenodd */
324     SPIEnum fill_rule;
326     /** stroke */
327     SPIPaint stroke;
328     /** stroke-width */
329     SPILength stroke_width;
330     /** stroke-linecap */
331     SPIEnum stroke_linecap;
332     /** stroke-linejoin */
333     SPIEnum stroke_linejoin;
334     /** stroke-miterlimit */
335     SPIFloat stroke_miterlimit;
336     /** stroke-dash* */
337     NRVpathDash stroke_dash;
338     unsigned stroke_dasharray_set : 1;
339     unsigned stroke_dasharray_inherit : 1;
340     unsigned stroke_dashoffset_set : 1;
341     unsigned stroke_dashoffset_inherit : 1;
342     /** stroke-opacity */
343     SPIScale24 stroke_opacity;
345     /** Marker list */
346     SPIString marker[SP_MARKER_LOC_QTY];
348     /** Filter effect */
349     SPIFilter filter;
351     SPIEnum filter_blend_mode;
353    /** normally not used, but duplicates the Gaussian blur deviation (if any) from the attached
354         filter when the style is used for querying */
355     SPILength filter_gaussianBlur_deviation;
357     /** enable-background, used for defining where filter effects get
358      * their background image */
359     SPIEnum enable_background;
361     /// style belongs to a cloned object
362     bool cloned;
364     sigc::connection release_connection;
366     sigc::connection filter_modified_connection;
367     sigc::connection fill_ps_modified_connection;
368     sigc::connection stroke_ps_modified_connection;
370     SPObject *getFilter() { return (filter.href) ? filter.href->getObject() : 0; }
371     SPObject const *getFilter() const { return (filter.href) ? filter.href->getObject() : 0; }
372     gchar const *getFilterURI() const { return (filter.href) ? filter.href->getURI()->toString() : 0; }
374     SPPaintServer *getFillPaintServer() { return (fill.value.href) ? fill.value.href->getObject() : 0; }
375     SPPaintServer const *getFillPaintServer() const { return (fill.value.href) ? fill.value.href->getObject() : 0; }
376     gchar const *getFillURI() const { return (fill.value.href) ? fill.value.href->getURI()->toString() : 0; }
378     SPPaintServer *getStrokePaintServer() { return (stroke.value.href) ? stroke.value.href->getObject() : 0; }
379     SPPaintServer const *getStrokePaintServer() const { return (stroke.value.href) ? stroke.value.href->getObject() : 0; }
380     gchar const  *getStrokeURI() const { return (stroke.value.href) ? stroke.value.href->getURI()->toString() : 0; }
381 };
383 SPStyle *sp_style_new(SPDocument *document);
385 SPStyle *sp_style_new_from_object(SPObject *object);
387 SPStyle *sp_style_ref(SPStyle *style);
389 SPStyle *sp_style_unref(SPStyle *style);
391 void sp_style_read_from_object(SPStyle *style, SPObject *object);
393 void sp_style_read_from_prefs(SPStyle *style, Glib::ustring const &path);
395 void sp_style_merge_from_style_string(SPStyle *style, gchar const *p);
397 void sp_style_merge_from_parent(SPStyle *style, SPStyle const *parent);
399 void sp_style_merge_from_dying_parent(SPStyle *style, SPStyle const *parent);
401 gchar *sp_style_write_string(SPStyle const *style, guint flags = SP_STYLE_FLAG_IFSET);
403 gchar *sp_style_write_difference(SPStyle const *from, SPStyle const *to);
405 void sp_style_set_to_uri_string (SPStyle *style, bool isfill, const gchar *uri);
407 /* SPTextStyle */
409 enum SPCSSFontSize {
410     SP_CSS_FONT_SIZE_XX_SMALL,
411     SP_CSS_FONT_SIZE_X_SMALL,
412     SP_CSS_FONT_SIZE_SMALL,
413     SP_CSS_FONT_SIZE_MEDIUM,
414     SP_CSS_FONT_SIZE_LARGE,
415     SP_CSS_FONT_SIZE_X_LARGE,
416     SP_CSS_FONT_SIZE_XX_LARGE,
417     SP_CSS_FONT_SIZE_SMALLER,
418     SP_CSS_FONT_SIZE_LARGER
419 };
421 enum SPCSSFontStyle {
422     SP_CSS_FONT_STYLE_NORMAL,
423     SP_CSS_FONT_STYLE_ITALIC,
424     SP_CSS_FONT_STYLE_OBLIQUE
425 };
427 enum SPCSSFontVariant {
428     SP_CSS_FONT_VARIANT_NORMAL,
429     SP_CSS_FONT_VARIANT_SMALL_CAPS
430 };
432 enum SPCSSFontWeight {
433     SP_CSS_FONT_WEIGHT_100,
434     SP_CSS_FONT_WEIGHT_200,
435     SP_CSS_FONT_WEIGHT_300,
436     SP_CSS_FONT_WEIGHT_400,
437     SP_CSS_FONT_WEIGHT_500,
438     SP_CSS_FONT_WEIGHT_600,
439     SP_CSS_FONT_WEIGHT_700,
440     SP_CSS_FONT_WEIGHT_800,
441     SP_CSS_FONT_WEIGHT_900,
442     SP_CSS_FONT_WEIGHT_NORMAL,
443     SP_CSS_FONT_WEIGHT_BOLD,
444     SP_CSS_FONT_WEIGHT_LIGHTER,
445     SP_CSS_FONT_WEIGHT_BOLDER
446 };
448 enum SPCSSFontStretch {
449     SP_CSS_FONT_STRETCH_ULTRA_CONDENSED,
450     SP_CSS_FONT_STRETCH_EXTRA_CONDENSED,
451     SP_CSS_FONT_STRETCH_CONDENSED,
452     SP_CSS_FONT_STRETCH_SEMI_CONDENSED,
453     SP_CSS_FONT_STRETCH_NORMAL,
454     SP_CSS_FONT_STRETCH_SEMI_EXPANDED,
455     SP_CSS_FONT_STRETCH_EXPANDED,
456     SP_CSS_FONT_STRETCH_EXTRA_EXPANDED,
457     SP_CSS_FONT_STRETCH_ULTRA_EXPANDED,
458     SP_CSS_FONT_STRETCH_NARROWER,
459     SP_CSS_FONT_STRETCH_WIDER
460 };
462 enum SPCSSTextAlign {
463     SP_CSS_TEXT_ALIGN_START,
464     SP_CSS_TEXT_ALIGN_END,
465     SP_CSS_TEXT_ALIGN_LEFT,
466     SP_CSS_TEXT_ALIGN_RIGHT,
467     SP_CSS_TEXT_ALIGN_CENTER,
468     SP_CSS_TEXT_ALIGN_JUSTIFY
469     // also <string> is allowed, but only within table calls
470 };
472 enum SPCSSTextTransform {
473     SP_CSS_TEXT_TRANSFORM_CAPITALIZE,
474     SP_CSS_TEXT_TRANSFORM_UPPERCASE,
475     SP_CSS_TEXT_TRANSFORM_LOWERCASE,
476     SP_CSS_TEXT_TRANSFORM_NONE
477 };
479 enum SPCSSDirection {
480     SP_CSS_DIRECTION_LTR,
481     SP_CSS_DIRECTION_RTL
482 };
484 enum SPCSSBlockProgression {
485     SP_CSS_BLOCK_PROGRESSION_TB,
486     SP_CSS_BLOCK_PROGRESSION_RL,
487     SP_CSS_BLOCK_PROGRESSION_LR
488 };
490 enum SPCSSWritingMode {
491     SP_CSS_WRITING_MODE_LR_TB,
492     SP_CSS_WRITING_MODE_RL_TB,
493     SP_CSS_WRITING_MODE_TB_RL,
494     SP_CSS_WRITING_MODE_TB_LR
495 };
497 enum SPTextAnchor {
498     SP_CSS_TEXT_ANCHOR_START,
499     SP_CSS_TEXT_ANCHOR_MIDDLE,
500     SP_CSS_TEXT_ANCHOR_END
501 };
503 enum SPVisibility {
504     SP_CSS_VISIBILITY_HIDDEN,
505     SP_CSS_VISIBILITY_COLLAPSE,
506     SP_CSS_VISIBILITY_VISIBLE
507 };
509 enum SPOverflow {
510     SP_CSS_OVERFLOW_VISIBLE,
511     SP_CSS_OVERFLOW_HIDDEN,
512     SP_CSS_OVERFLOW_SCROLL,
513     SP_CSS_OVERFLOW_AUTO
514 };
516 /// \todo more display types
517 enum SPCSSDisplay {
518     SP_CSS_DISPLAY_NONE,
519     SP_CSS_DISPLAY_INLINE,
520     SP_CSS_DISPLAY_BLOCK,
521     SP_CSS_DISPLAY_LIST_ITEM,
522     SP_CSS_DISPLAY_RUN_IN,
523     SP_CSS_DISPLAY_COMPACT,
524     SP_CSS_DISPLAY_MARKER,
525     SP_CSS_DISPLAY_TABLE,
526     SP_CSS_DISPLAY_INLINE_TABLE,
527     SP_CSS_DISPLAY_TABLE_ROW_GROUP,
528     SP_CSS_DISPLAY_TABLE_HEADER_GROUP,
529     SP_CSS_DISPLAY_TABLE_FOOTER_GROUP,
530     SP_CSS_DISPLAY_TABLE_ROW,
531     SP_CSS_DISPLAY_TABLE_COLUMN_GROUP,
532     SP_CSS_DISPLAY_TABLE_COLUMN,
533     SP_CSS_DISPLAY_TABLE_CELL,
534     SP_CSS_DISPLAY_TABLE_CAPTION
535 };
537 enum SPEnableBackground {
538     SP_CSS_BACKGROUND_ACCUMULATE,
539     SP_CSS_BACKGROUND_NEW
540 };
542 /// An SPTextStyle has a refcount, a font family, and a font name.
543 struct SPTextStyle {
544     int refcount;
546     /* CSS font properties */
547     SPIString font_family;
549     /* Full font name, as font_factory::ConstructFontSpecification would give */
550     SPIString font_specification;
552     /** \todo fixme: The 'font' property is ugly, and not working (lauris) */
553     SPIString font;
554 };
556 SPCSSAttr *sp_css_attr_from_style (SPStyle const *const style, guint flags);
557 SPCSSAttr *sp_css_attr_from_object(SPObject *object, guint flags = SP_STYLE_FLAG_IFSET);
558 SPCSSAttr *sp_css_attr_unset_text(SPCSSAttr *css);
559 SPCSSAttr *sp_css_attr_unset_uris(SPCSSAttr *css);
560 SPCSSAttr *sp_css_attr_scale(SPCSSAttr *css, double ex);
562 void sp_style_unset_property_attrs(SPObject *o);
564 void sp_style_set_property_url (SPObject *item, gchar const *property, SPObject *linked, bool recursive);
566 gchar *attribute_unquote(gchar const *val);
567 gchar *css2_escape_quote(gchar const *val);
569 #endif // SEEN_SP_STYLE_H
572 /*
573   Local Variables:
574   mode:c++
575   c-file-style:"stroustrup"
576   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
577   indent-tabs-mode:nil
578   fill-column:99
579   End:
580 */
581 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :