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