Code

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