Code

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