Code

fixed broken page unit changing in Document Properties
[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"
20 namespace Inkscape {
21 namespace XML {
22 class Node;
23 }
24 }
26 class SPCSSAttr;
28 namespace Inkscape {
29 gchar *parse_css_url(gchar const *string);
30 }
32 class SPIFloat;
33 class SPIScale24;
34 class SPIInt;
35 class SPIShort;
36 class SPIEnum;
37 class SPIString;
38 class SPILength;
39 class SPIPaint;
40 class SPIFontSize;
42 /// Float type internal to SPStyle.
43 struct SPIFloat {
44     unsigned set : 1;
45     unsigned inherit : 1;
46     unsigned data : 30;
47     float value;
48 };
50 /*
51  * One might think that the best value for SP_SCALE24_MAX would be ((1<<24)-1), which allows the
52  * greatest possible precision for fitting [0, 1] fractions into 24 bits.
53  *
54  * However, in practice, that gives a problem with 0.5, which falls half way between two fractions
55  * of ((1<<24)-1).  What's worse is that casting double(1<<23) / ((1<<24)-1) to float on x86
56  * produces wrong rounding behaviour, resulting in a fraction of ((1<<23)+2.0f) / (1<<24) rather
57  * than ((1<<23)+1.0f) / (1<<24) as one would expect, let alone ((1<<23)+0.0f) / (1<<24) as one
58  * would ideally like for this example.
59  *
60  * The value (1<<23) is thus best if one considers float conversions alone.
61  *
62  * The value 0xff0000 can exactly represent all 8-bit alpha channel values,
63  * and can exactly represent all multiples of 0.1.  I haven't yet tested whether
64  * rounding bugs still get in the way of conversions to & from float, but my instinct is that
65  * it's fairly safe because 0xff fits three times inside float's significand.
66  *
67  * We should probably use the value 0xffff00 once we support 16 bits per channel and/or LittleCMS,
68  * though that might need to be accompanied by greater use of double instead of float for
69  * colours and opacities, to be safe from rounding bugs.
70  */
71 #define SP_SCALE24_MAX (0xff0000)
72 #define SP_SCALE24_TO_FLOAT(v) ((double) (v) / SP_SCALE24_MAX)
73 #define SP_SCALE24_FROM_FLOAT(v) unsigned(((v) * SP_SCALE24_MAX) + .5)
75 /** Returns a scale24 for the product of two scale24 values. */
76 #define SP_SCALE24_MUL(_v1, _v2) unsigned((double)(_v1) * (_v2) / SP_SCALE24_MAX + .5)
78 /// 24 bit data type internal to SPStyle.
79 struct SPIScale24 {
80     unsigned set : 1;
81     unsigned inherit : 1;
82     unsigned value : 24;
83 };
85 /// Int type internal to SPStyle.
86 struct SPIInt {
87     unsigned set : 1;
88     unsigned inherit : 1;
89     unsigned data : 30;
90     int value;
91 };
93 /// Short type internal to SPStyle.
94 struct SPIShort {
95     unsigned set : 1;
96     unsigned inherit : 1;
97     unsigned data : 14;
98     int value : 16;
99 };
101 /// Enum type internal to SPStyle.
102 struct SPIEnum {
103     unsigned set : 1;
104     unsigned inherit : 1;
105     unsigned value : 8;
106     unsigned computed : 8;
107 };
109 /// String type internal to SPStyle.
110 struct SPIString {
111     unsigned set : 1;
112     unsigned inherit : 1;
113     unsigned data : 30;
114     gchar *value;
115 };
117 enum {
118     SP_CSS_UNIT_NONE,
119     SP_CSS_UNIT_PX,
120     SP_CSS_UNIT_PT,
121     SP_CSS_UNIT_PC,
122     SP_CSS_UNIT_MM,
123     SP_CSS_UNIT_CM,
124     SP_CSS_UNIT_IN,
125     SP_CSS_UNIT_EM,
126     SP_CSS_UNIT_EX,
127     SP_CSS_UNIT_PERCENT
128 };
130 /// Length type internal to SPStyle.
131 struct SPILength {
132     unsigned set : 1;
133     unsigned inherit : 1;
134     unsigned unit : 4;
135     float value;
136     float computed;
137 };
139 #define SP_STYLE_FILL_SERVER(s) (((SPStyle *) (s))->fill.value.paint.server)
140 #define SP_STYLE_STROKE_SERVER(s) (((SPStyle *) (s))->stroke.value.paint.server)
141 #define SP_OBJECT_STYLE_FILL_SERVER(o) (SP_OBJECT (o)->style->fill.value.paint.server)
142 #define SP_OBJECT_STYLE_STROKE_SERVER(o) (SP_OBJECT (o)->style->stroke.value.paint.server)
144 enum {
145     SP_PAINT_TYPE_NONE,
146     SP_PAINT_TYPE_COLOR,
147     SP_PAINT_TYPE_PAINTSERVER,
148     SP_PAINT_TYPE_IMPOSSIBLE
149 };
151 class SVGICCColor;
153 /// Paint type internal to SPStyle.
154 struct SPIPaint {
155     unsigned set : 1;
156     unsigned inherit : 1;
157     unsigned currentcolor : 1;
158     unsigned type : 2;
159     union {
160         SPColor color;
161         struct {
162             SPPaintServer *server;
163             gchar *uri;
164         } paint;
165     } value;
166     SVGICCColor *iccColor;
167 };
169 enum {
170     SP_FONT_SIZE_LITERAL,
171     SP_FONT_SIZE_LENGTH,
172     SP_FONT_SIZE_PERCENTAGE
173 };
175 #define SP_FONT_SIZE ((1 << 24) - 1)
177 #define SP_F8_16_TO_FLOAT(v) ((gdouble) (v) / (1 << 16))
178 #define SP_F8_16_FROM_FLOAT(v) ((int) ((v) * ((1 << 16) + 0.9999)))
180 #define SP_STYLE_FLAG_IFSET (1 << 0)
181 #define SP_STYLE_FLAG_IFDIFF (1 << 1)
182 #define SP_STYLE_FLAG_ALWAYS (1 << 2)
184 /// Fontsize type internal to SPStyle.
185 struct SPIFontSize {
186     unsigned set : 1;
187     unsigned inherit : 1;
188     unsigned type : 2;
189     unsigned value : 24;
190     float computed;
191 };
193 /// Text decoration type internal to SPStyle.
194 struct SPITextDecoration {
195     unsigned set : 1;
196     unsigned inherit : 1;
197     unsigned underline : 1;
198     unsigned overline : 1;
199     unsigned line_through : 1;
200     unsigned blink : 1;    // "Conforming user agents are not required to support this value." yay!
201 };
203 /// Extended length type internal to SPStyle.
204 struct SPILengthOrNormal {
205     unsigned set : 1;
206     unsigned inherit : 1;
207     unsigned normal : 1;
208     unsigned unit : 4;
209     float value;
210     float computed;
211 };
213 class SPTextStyle;
215 /// Stroke dash details.
216 class NRVpathDash {
217 public:
218     double offset;
219     int n_dash;
220     double *dash;
221 };
223 /// An SVG style object.
224 struct SPStyle {
225     int refcount;
226     /** Object we are attached to */
227     SPObject *object;
228     /** Our text style component */
229     SPTextStyle *text;
230     unsigned text_private : 1;
232     /* CSS2 */
233     /* Font */
234     /** Size of the font */
235     SPIFontSize font_size;
236     /** Style of the font */
237     SPIEnum font_style;
238     /** Which substyle of the font */
239     SPIEnum font_variant;
240     /** Weight of the font */
241     SPIEnum font_weight;
242     /** Stretch of the font */
243     SPIEnum font_stretch;
245     /** First line indent of paragraphs (css2 16.1) */
246     SPILength text_indent;
247     /** text alignment (css2 16.2) (not to be confused with text-anchor) */
248     SPIEnum text_align;
249     /** text decoration (css2 16.3.1) */
250     SPITextDecoration text_decoration;
251     // 16.3.2 is text-shadow. That's complicated.
252     /** Line spacing (css2 10.8.1) */
253     SPILengthOrNormal line_height;
254     /** letter spacing (css2 16.4) */
255     SPILengthOrNormal letter_spacing;
256     /** word spacing (also css2 16.4) */
257     SPILengthOrNormal word_spacing;
258     /** capitalization (css2 16.5) */
259     SPIEnum text_transform;
261     /* CSS3 Text */
262     /** text direction (css3 text 3.2) */
263     SPIEnum direction;
264     /** block progression (css3 text 3.2) */
265     SPIEnum block_progression;
266     /** Writing mode (css3 text 3.2 and svg1.1 10.7.2) */
267     SPIEnum writing_mode;
269     /* SVG */
270     /** Anchor of the text (svg1.1 10.9.1) */
271     SPIEnum text_anchor;
273     /* Misc attributes */
274     unsigned clip_set : 1;
275     unsigned color_set : 1;
276     unsigned cursor_set : 1;
277     unsigned overflow_set : 1;
278     unsigned clip_path_set : 1;
279     unsigned clip_rule_set : 1;
280     unsigned mask_set : 1;
282     /** display */
283     SPIEnum display;
285     /** overflow */
286     SPIEnum overflow;
288     /** visibility */
289     SPIEnum visibility;
291     /** opacity */
292     SPIScale24 opacity;
294     /** color */
295     SPIPaint color;
297     /** fill */
298     SPIPaint fill;
299     /** fill-opacity */
300     SPIScale24 fill_opacity;
301     /** fill-rule: 0 nonzero, 1 evenodd */
302     SPIEnum fill_rule;
304     /** stroke */
305     SPIPaint stroke;
306     /** stroke-width */
307     SPILength stroke_width;
308     /** stroke-linecap */
309     SPIEnum stroke_linecap;
310     /** stroke-linejoin */
311     SPIEnum stroke_linejoin;
312     /** stroke-miterlimit */
313     SPIFloat stroke_miterlimit;
314     /** stroke-dash* */
315     NRVpathDash stroke_dash;
316     unsigned stroke_dasharray_set : 1;
317     unsigned stroke_dasharray_inherit : 1;
318     unsigned stroke_dashoffset_set : 1;
319     /** stroke-opacity */
320     SPIScale24 stroke_opacity;
322     /** Marker list */
323     SPIString marker[SP_MARKER_LOC_QTY];
325     /// style belongs to a cloned object, must not href anything
326     bool cloned; 
327     /// style has hreffed its fill/stroke paintservers, needs to release.
328     bool fill_hreffed; 
329     bool stroke_hreffed; 
330     /// style is listening to changes in fill/stroke paintservers, needs to disconnect.
331     bool fill_listening; 
332     bool stroke_listening; 
333 };
335 SPStyle *sp_style_new();
337 SPStyle *sp_style_new_from_object(SPObject *object);
339 SPStyle *sp_style_ref(SPStyle *style);
341 SPStyle *sp_style_unref(SPStyle *style);
343 void sp_style_read_from_object(SPStyle *style, SPObject *object);
345 void sp_style_read_from_repr(SPStyle *style, Inkscape::XML::Node *repr);
347 void sp_style_merge_from_style_string(SPStyle *style, gchar const *p);
349 void sp_style_merge_from_parent(SPStyle *style, SPStyle const *parent);
351 void sp_style_merge_from_dying_parent(SPStyle *style, SPStyle const *parent);
353 gchar *sp_style_write_string(SPStyle const *style, guint flags = SP_STYLE_FLAG_IFSET);
355 gchar *sp_style_write_difference(SPStyle const *from, SPStyle const *to);
357 /* SPTextStyle */
359 enum SPCSSFontSize {
360     SP_CSS_FONT_SIZE_XX_SMALL,
361     SP_CSS_FONT_SIZE_X_SMALL,
362     SP_CSS_FONT_SIZE_SMALL,
363     SP_CSS_FONT_SIZE_MEDIUM,
364     SP_CSS_FONT_SIZE_LARGE,
365     SP_CSS_FONT_SIZE_X_LARGE,
366     SP_CSS_FONT_SIZE_XX_LARGE,
367     SP_CSS_FONT_SIZE_SMALLER,
368     SP_CSS_FONT_SIZE_LARGER
369 };
371 enum SPCSSFontStyle {
372     SP_CSS_FONT_STYLE_NORMAL,
373     SP_CSS_FONT_STYLE_ITALIC,
374     SP_CSS_FONT_STYLE_OBLIQUE
375 };
377 enum SPCSSFontVariant {
378     SP_CSS_FONT_VARIANT_NORMAL,
379     SP_CSS_FONT_VARIANT_SMALL_CAPS
380 };
382 enum SPCSSFontWeight {
383     SP_CSS_FONT_WEIGHT_100,
384     SP_CSS_FONT_WEIGHT_200,
385     SP_CSS_FONT_WEIGHT_300,
386     SP_CSS_FONT_WEIGHT_400,
387     SP_CSS_FONT_WEIGHT_500,
388     SP_CSS_FONT_WEIGHT_600,
389     SP_CSS_FONT_WEIGHT_700,
390     SP_CSS_FONT_WEIGHT_800,
391     SP_CSS_FONT_WEIGHT_900,
392     SP_CSS_FONT_WEIGHT_NORMAL,
393     SP_CSS_FONT_WEIGHT_BOLD,
394     SP_CSS_FONT_WEIGHT_LIGHTER,
395     SP_CSS_FONT_WEIGHT_BOLDER
396 };
398 enum SPCSSFontStretch {
399     SP_CSS_FONT_STRETCH_ULTRA_CONDENSED,
400     SP_CSS_FONT_STRETCH_EXTRA_CONDENSED,
401     SP_CSS_FONT_STRETCH_CONDENSED,
402     SP_CSS_FONT_STRETCH_SEMI_CONDENSED,
403     SP_CSS_FONT_STRETCH_NORMAL,
404     SP_CSS_FONT_STRETCH_SEMI_EXPANDED,
405     SP_CSS_FONT_STRETCH_EXPANDED,
406     SP_CSS_FONT_STRETCH_EXTRA_EXPANDED,
407     SP_CSS_FONT_STRETCH_ULTRA_EXPANDED,
408     SP_CSS_FONT_STRETCH_NARROWER,
409     SP_CSS_FONT_STRETCH_WIDER
410 };
412 enum SPCSSTextAlign {
413     SP_CSS_TEXT_ALIGN_START,
414     SP_CSS_TEXT_ALIGN_END,
415     SP_CSS_TEXT_ALIGN_LEFT,
416     SP_CSS_TEXT_ALIGN_RIGHT,
417     SP_CSS_TEXT_ALIGN_CENTER,
418     SP_CSS_TEXT_ALIGN_JUSTIFY
419     // also <string> is allowed, but only within table calls
420 };
422 enum SPCSSTextTransform {
423     SP_CSS_TEXT_TRANSFORM_CAPITALIZE,
424     SP_CSS_TEXT_TRANSFORM_UPPERCASE,
425     SP_CSS_TEXT_TRANSFORM_LOWERCASE,
426     SP_CSS_TEXT_TRANSFORM_NONE
427 };
429 enum SPCSSDirection {
430     SP_CSS_DIRECTION_LTR,
431     SP_CSS_DIRECTION_RTL
432 };
434 enum SPCSSBlockProgression {
435     SP_CSS_BLOCK_PROGRESSION_TB,
436     SP_CSS_BLOCK_PROGRESSION_RL,
437     SP_CSS_BLOCK_PROGRESSION_LR
438 };
440 enum SPCSSWritingMode {
441     SP_CSS_WRITING_MODE_LR_TB,
442     SP_CSS_WRITING_MODE_RL_TB,
443     SP_CSS_WRITING_MODE_TB_RL,
444     SP_CSS_WRITING_MODE_TB_LR
445 };
447 enum SPTextAnchor {
448     SP_CSS_TEXT_ANCHOR_START,
449     SP_CSS_TEXT_ANCHOR_MIDDLE,
450     SP_CSS_TEXT_ANCHOR_END
451 };
453 enum SPVisibility {
454     SP_CSS_VISIBILITY_HIDDEN,
455     SP_CSS_VISIBILITY_COLLAPSE,
456     SP_CSS_VISIBILITY_VISIBLE
457 };
459 enum SPOverflow {
460     SP_CSS_OVERFLOW_VISIBLE,
461     SP_CSS_OVERFLOW_HIDDEN,
462     SP_CSS_OVERFLOW_SCROLL,
463     SP_CSS_OVERFLOW_AUTO
464 };
466 /// \todo more display types
467 enum SPCSSDisplay {
468     SP_CSS_DISPLAY_NONE,
469     SP_CSS_DISPLAY_INLINE,
470     SP_CSS_DISPLAY_BLOCK,
471     SP_CSS_DISPLAY_LIST_ITEM,
472     SP_CSS_DISPLAY_RUN_IN,
473     SP_CSS_DISPLAY_COMPACT,
474     SP_CSS_DISPLAY_MARKER,
475     SP_CSS_DISPLAY_TABLE,
476     SP_CSS_DISPLAY_INLINE_TABLE,
477     SP_CSS_DISPLAY_TABLE_ROW_GROUP,
478     SP_CSS_DISPLAY_TABLE_HEADER_GROUP,
479     SP_CSS_DISPLAY_TABLE_FOOTER_GROUP,
480     SP_CSS_DISPLAY_TABLE_ROW,
481     SP_CSS_DISPLAY_TABLE_COLUMN_GROUP,
482     SP_CSS_DISPLAY_TABLE_COLUMN,
483     SP_CSS_DISPLAY_TABLE_CELL,
484     SP_CSS_DISPLAY_TABLE_CAPTION
485 };
487 /// An SPTextStyle has a refcount, a font family, and a font name.
488 struct SPTextStyle {
489     int refcount;
491     /* CSS font properties */
492     SPIString font_family;
494     /** \todo fixme: The 'font' property is ugly, and not working (lauris) */
495     SPIString font;
496 };
498 SPCSSAttr *sp_css_attr_from_style (SPStyle const *const style, guint flags);
499 SPCSSAttr *sp_css_attr_from_object(SPObject *object, guint flags = SP_STYLE_FLAG_IFSET);
500 SPCSSAttr *sp_css_attr_unset_text(SPCSSAttr *css);
501 SPCSSAttr *sp_css_attr_unset_uris(SPCSSAttr *css);
502 SPCSSAttr *sp_css_attr_scale(SPCSSAttr *css, double ex);
504 void sp_style_unset_property_attrs(SPObject *o);
506 #endif
509 /*
510   Local Variables:
511   mode:c++
512   c-file-style:"stroustrup"
513   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
514   indent-tabs-mode:nil
515   fill-column:99
516   End:
517 */
518 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :