cad454efd1ea1e639de7d9ed5ad16ebb614c8d8c
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 /// Paint type internal to SPStyle.
152 struct SPIPaint {
153 unsigned set : 1;
154 unsigned inherit : 1;
155 unsigned currentcolor : 1;
156 unsigned type : 2;
157 union {
158 SPColor color;
159 struct {
160 SPPaintServer *server;
161 gchar *uri;
162 } paint;
163 } value;
164 };
166 enum {
167 SP_FONT_SIZE_LITERAL,
168 SP_FONT_SIZE_LENGTH,
169 SP_FONT_SIZE_PERCENTAGE
170 };
172 #define SP_FONT_SIZE ((1 << 24) - 1)
174 #define SP_F8_16_TO_FLOAT(v) ((gdouble) (v) / (1 << 16))
175 #define SP_F8_16_FROM_FLOAT(v) ((int) ((v) * ((1 << 16) + 0.9999)))
177 #define SP_STYLE_FLAG_IFSET (1 << 0)
178 #define SP_STYLE_FLAG_IFDIFF (1 << 1)
179 #define SP_STYLE_FLAG_ALWAYS (1 << 2)
181 /// Fontsize type internal to SPStyle.
182 struct SPIFontSize {
183 unsigned set : 1;
184 unsigned inherit : 1;
185 unsigned type : 2;
186 unsigned value : 24;
187 float computed;
188 };
190 /// Text decoration type internal to SPStyle.
191 struct SPITextDecoration {
192 unsigned set : 1;
193 unsigned inherit : 1;
194 unsigned underline : 1;
195 unsigned overline : 1;
196 unsigned line_through : 1;
197 unsigned blink : 1; // "Conforming user agents are not required to support this value." yay!
198 };
200 /// Extended length type internal to SPStyle.
201 struct SPILengthOrNormal {
202 unsigned set : 1;
203 unsigned inherit : 1;
204 unsigned normal : 1;
205 unsigned unit : 4;
206 float value;
207 float computed;
208 };
210 class SPTextStyle;
212 /// Stroke dash details.
213 class NRVpathDash {
214 public:
215 double offset;
216 int n_dash;
217 double *dash;
218 };
220 /// An SVG style object.
221 struct SPStyle {
222 int refcount;
223 /** Object we are attached to */
224 SPObject *object;
225 /** Our text style component */
226 SPTextStyle *text;
227 unsigned text_private : 1;
229 /* CSS2 */
230 /* Font */
231 /** Size of the font */
232 SPIFontSize font_size;
233 /** Style of the font */
234 SPIEnum font_style;
235 /** Which substyle of the font */
236 SPIEnum font_variant;
237 /** Weight of the font */
238 SPIEnum font_weight;
239 /** Stretch of the font */
240 SPIEnum font_stretch;
242 /** First line indent of paragraphs (css2 16.1) */
243 SPILength text_indent;
244 /** text alignment (css2 16.2) (not to be confused with text-anchor) */
245 SPIEnum text_align;
246 /** text decoration (css2 16.3.1) */
247 SPITextDecoration text_decoration;
248 // 16.3.2 is text-shadow. That's complicated.
249 /** Line spacing (css2 10.8.1) */
250 SPILengthOrNormal line_height;
251 /** letter spacing (css2 16.4) */
252 SPILengthOrNormal letter_spacing;
253 /** word spacing (also css2 16.4) */
254 SPILengthOrNormal word_spacing;
255 /** capitalization (css2 16.5) */
256 SPIEnum text_transform;
258 /* CSS3 Text */
259 /** text direction (css3 text 3.2) */
260 SPIEnum direction;
261 /** block progression (css3 text 3.2) */
262 SPIEnum block_progression;
263 /** Writing mode (css3 text 3.2 and svg1.1 10.7.2) */
264 SPIEnum writing_mode;
266 /* SVG */
267 /** Anchor of the text (svg1.1 10.9.1) */
268 SPIEnum text_anchor;
270 /* Misc attributes */
271 unsigned clip_set : 1;
272 unsigned color_set : 1;
273 unsigned cursor_set : 1;
274 unsigned overflow_set : 1;
275 unsigned clip_path_set : 1;
276 unsigned clip_rule_set : 1;
277 unsigned mask_set : 1;
279 /** display */
280 SPIEnum display;
282 /** overflow */
283 SPIEnum overflow;
285 /** visibility */
286 SPIEnum visibility;
288 /** opacity */
289 SPIScale24 opacity;
291 /** color */
292 SPIPaint color;
294 /** fill */
295 SPIPaint fill;
296 /** fill-opacity */
297 SPIScale24 fill_opacity;
298 /** fill-rule: 0 nonzero, 1 evenodd */
299 SPIEnum fill_rule;
301 /** stroke */
302 SPIPaint stroke;
303 /** stroke-width */
304 SPILength stroke_width;
305 /** stroke-linecap */
306 SPIEnum stroke_linecap;
307 /** stroke-linejoin */
308 SPIEnum stroke_linejoin;
309 /** stroke-miterlimit */
310 SPIFloat stroke_miterlimit;
311 /** stroke-dash* */
312 NRVpathDash stroke_dash;
313 unsigned stroke_dasharray_set : 1;
314 unsigned stroke_dasharray_inherit : 1;
315 unsigned stroke_dashoffset_set : 1;
316 /** stroke-opacity */
317 SPIScale24 stroke_opacity;
319 /** Marker list */
320 SPIString marker[SP_MARKER_LOC_QTY];
322 /// style belongs to a cloned object, must not href anything
323 bool cloned;
324 /// style has hreffed its color/fill/stroke paintservers, needs to release
325 bool color_hreffed;
326 bool fill_hreffed;
327 bool stroke_hreffed;
328 /// style is listening to changes in color/fill/stroke paintservers, needs to disconnect
329 bool color_listening;
330 bool fill_listening;
331 bool stroke_listening;
332 };
334 SPStyle *sp_style_new();
336 SPStyle *sp_style_new_from_object(SPObject *object);
338 SPStyle *sp_style_ref(SPStyle *style);
340 SPStyle *sp_style_unref(SPStyle *style);
342 void sp_style_read_from_object(SPStyle *style, SPObject *object);
344 void sp_style_read_from_repr(SPStyle *style, Inkscape::XML::Node *repr);
346 void sp_style_merge_from_style_string(SPStyle *style, gchar const *p);
348 void sp_style_merge_from_parent(SPStyle *style, SPStyle const *parent);
350 void sp_style_merge_from_dying_parent(SPStyle *style, SPStyle const *parent);
352 gchar *sp_style_write_string(SPStyle const *style, guint flags = SP_STYLE_FLAG_IFSET);
354 gchar *sp_style_write_difference(SPStyle const *from, SPStyle const *to);
356 /* SPTextStyle */
358 enum SPCSSFontSize {
359 SP_CSS_FONT_SIZE_XX_SMALL,
360 SP_CSS_FONT_SIZE_X_SMALL,
361 SP_CSS_FONT_SIZE_SMALL,
362 SP_CSS_FONT_SIZE_MEDIUM,
363 SP_CSS_FONT_SIZE_LARGE,
364 SP_CSS_FONT_SIZE_X_LARGE,
365 SP_CSS_FONT_SIZE_XX_LARGE,
366 SP_CSS_FONT_SIZE_SMALLER,
367 SP_CSS_FONT_SIZE_LARGER
368 };
370 enum SPCSSFontStyle {
371 SP_CSS_FONT_STYLE_NORMAL,
372 SP_CSS_FONT_STYLE_ITALIC,
373 SP_CSS_FONT_STYLE_OBLIQUE
374 };
376 enum SPCSSFontVariant {
377 SP_CSS_FONT_VARIANT_NORMAL,
378 SP_CSS_FONT_VARIANT_SMALL_CAPS
379 };
381 enum SPCSSFontWeight {
382 SP_CSS_FONT_WEIGHT_100,
383 SP_CSS_FONT_WEIGHT_200,
384 SP_CSS_FONT_WEIGHT_300,
385 SP_CSS_FONT_WEIGHT_400,
386 SP_CSS_FONT_WEIGHT_500,
387 SP_CSS_FONT_WEIGHT_600,
388 SP_CSS_FONT_WEIGHT_700,
389 SP_CSS_FONT_WEIGHT_800,
390 SP_CSS_FONT_WEIGHT_900,
391 SP_CSS_FONT_WEIGHT_NORMAL,
392 SP_CSS_FONT_WEIGHT_BOLD,
393 SP_CSS_FONT_WEIGHT_LIGHTER,
394 SP_CSS_FONT_WEIGHT_BOLDER
395 };
397 enum SPCSSFontStretch {
398 SP_CSS_FONT_STRETCH_ULTRA_CONDENSED,
399 SP_CSS_FONT_STRETCH_EXTRA_CONDENSED,
400 SP_CSS_FONT_STRETCH_CONDENSED,
401 SP_CSS_FONT_STRETCH_SEMI_CONDENSED,
402 SP_CSS_FONT_STRETCH_NORMAL,
403 SP_CSS_FONT_STRETCH_SEMI_EXPANDED,
404 SP_CSS_FONT_STRETCH_EXPANDED,
405 SP_CSS_FONT_STRETCH_EXTRA_EXPANDED,
406 SP_CSS_FONT_STRETCH_ULTRA_EXPANDED,
407 SP_CSS_FONT_STRETCH_NARROWER,
408 SP_CSS_FONT_STRETCH_WIDER
409 };
411 enum SPCSSTextAlign {
412 SP_CSS_TEXT_ALIGN_START,
413 SP_CSS_TEXT_ALIGN_END,
414 SP_CSS_TEXT_ALIGN_LEFT,
415 SP_CSS_TEXT_ALIGN_RIGHT,
416 SP_CSS_TEXT_ALIGN_CENTER,
417 SP_CSS_TEXT_ALIGN_JUSTIFY
418 // also <string> is allowed, but only within table calls
419 };
421 enum SPCSSTextTransform {
422 SP_CSS_TEXT_TRANSFORM_CAPITALIZE,
423 SP_CSS_TEXT_TRANSFORM_UPPERCASE,
424 SP_CSS_TEXT_TRANSFORM_LOWERCASE,
425 SP_CSS_TEXT_TRANSFORM_NONE
426 };
428 enum SPCSSDirection {
429 SP_CSS_DIRECTION_LTR,
430 SP_CSS_DIRECTION_RTL
431 };
433 enum SPCSSBlockProgression {
434 SP_CSS_BLOCK_PROGRESSION_TB,
435 SP_CSS_BLOCK_PROGRESSION_RL,
436 SP_CSS_BLOCK_PROGRESSION_LR
437 };
439 enum SPCSSWritingMode {
440 SP_CSS_WRITING_MODE_LR_TB,
441 SP_CSS_WRITING_MODE_RL_TB,
442 SP_CSS_WRITING_MODE_TB_RL,
443 SP_CSS_WRITING_MODE_TB_LR
444 };
446 enum SPTextAnchor {
447 SP_CSS_TEXT_ANCHOR_START,
448 SP_CSS_TEXT_ANCHOR_MIDDLE,
449 SP_CSS_TEXT_ANCHOR_END
450 };
452 enum SPVisibility {
453 SP_CSS_VISIBILITY_HIDDEN,
454 SP_CSS_VISIBILITY_COLLAPSE,
455 SP_CSS_VISIBILITY_VISIBLE
456 };
458 enum SPOverflow {
459 SP_CSS_OVERFLOW_VISIBLE,
460 SP_CSS_OVERFLOW_HIDDEN,
461 SP_CSS_OVERFLOW_SCROLL,
462 SP_CSS_OVERFLOW_AUTO
463 };
465 /// \todo more display types
466 enum SPCSSDisplay {
467 SP_CSS_DISPLAY_NONE,
468 SP_CSS_DISPLAY_INLINE,
469 SP_CSS_DISPLAY_BLOCK,
470 SP_CSS_DISPLAY_LIST_ITEM,
471 SP_CSS_DISPLAY_RUN_IN,
472 SP_CSS_DISPLAY_COMPACT,
473 SP_CSS_DISPLAY_MARKER,
474 SP_CSS_DISPLAY_TABLE,
475 SP_CSS_DISPLAY_INLINE_TABLE,
476 SP_CSS_DISPLAY_TABLE_ROW_GROUP,
477 SP_CSS_DISPLAY_TABLE_HEADER_GROUP,
478 SP_CSS_DISPLAY_TABLE_FOOTER_GROUP,
479 SP_CSS_DISPLAY_TABLE_ROW,
480 SP_CSS_DISPLAY_TABLE_COLUMN_GROUP,
481 SP_CSS_DISPLAY_TABLE_COLUMN,
482 SP_CSS_DISPLAY_TABLE_CELL,
483 SP_CSS_DISPLAY_TABLE_CAPTION
484 };
486 /// An SPTextStyle has a refcount, a font family, and a font name.
487 struct SPTextStyle {
488 int refcount;
490 /* CSS font properties */
491 SPIString font_family;
493 /** \todo fixme: The 'font' property is ugly, and not working (lauris) */
494 SPIString font;
495 };
497 SPCSSAttr *sp_css_attr_from_style (SPStyle const *const style, guint flags);
498 SPCSSAttr *sp_css_attr_from_object(SPObject *object, guint flags = SP_STYLE_FLAG_IFSET);
499 SPCSSAttr *sp_css_attr_unset_text(SPCSSAttr *css);
500 SPCSSAttr *sp_css_attr_unset_uris(SPCSSAttr *css);
501 SPCSSAttr *sp_css_attr_scale(SPCSSAttr *css, double ex);
503 void sp_style_unset_property_attrs(SPObject *o);
505 #endif
508 /*
509 Local Variables:
510 mode:c++
511 c-file-style:"stroustrup"
512 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
513 indent-tabs-mode:nil
514 fill-column:99
515 End:
516 */
517 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :