Code

Fixed signed/unsigned problem with precision calc. Fixes bug #399604.
[inkscape.git] / src / sp-font-face.cpp
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
5 #ifdef ENABLE_SVG_FONTS
6 #define __SP_FONTFACE_C__
8 /*
9  * SVG <font-face> element implementation
10  *
11  * Section 20.8.3 of the W3C SVG 1.1 spec
12  * available at:
13  * http://www.w3.org/TR/SVG/fonts.html#FontFaceElement
14  *
15  * Author:
16  *   Felipe C. da S. Sanches <felipe.sanches@gmail.com>
17  *
18  * Copyright (C) 2008, Felipe C. da S. Sanches
19  *
20  * Released under GNU GPL, read the file 'COPYING' for more information
21  */
23 #include "xml/repr.h"
24 #include "attributes.h"
25 #include "sp-font-face.h"
26 #include "document.h"
27 #include "helper-fns.h"
29 //TODO: apparently unused. Maybe should be removed.
30 class ObjectContainer
31 {
33 public:
34     ObjectContainer(double def){
35         this->isset = false;
36         this->default_value = def;
37     }
39     double get(){
40         if (this->isset)
41             return this->obj;
42         else
43             return this->default_value;
44     }
46     void set(double val){
47         this->obj = val;
48         this->isset = true;
49     }
51     void unset(){
52         this->isset = false;
53     }
55 private:
56     double obj;
57     double default_value;
58     bool isset;
59 };
61 static std::vector<FontFaceStyleType> sp_read_fontFaceStyleType(gchar const *value){
62     std::vector<FontFaceStyleType> v;
64     if (!value){
65         v.push_back(SP_FONTFACE_STYLE_ALL);
66         return v;
67     }
69     if (strncmp(value, "all", 3) == 0){
70         value += 3;
71         while(value[0]==',' || value[0]==' ')
72             value++;
73         v.push_back(SP_FONTFACE_STYLE_ALL);
74         return v;
75     }
77     while(value[0]!='\0'){
78         switch(value[0]){
79             case 'n':
80                 if (strncmp(value, "normal", 6) == 0){
81                     v.push_back(SP_FONTFACE_STYLE_NORMAL);
82                     value += 6;
83                 }
84                 break;
85             case 'i':
86                 if (strncmp(value, "italic", 6) == 0){
87                     v.push_back(SP_FONTFACE_STYLE_ITALIC);
88                     value += 6;
89                 }
90                 break;
91             case 'o':
92                 if (strncmp(value, "oblique", 7) == 0){
93                     v.push_back(SP_FONTFACE_STYLE_OBLIQUE);
94                     value += 7;
95                 }
96                 break;
97         }
98         while(value[0]==',' || value[0]==' ')
99             value++;
100     }
101     return v;
104 static std::vector<FontFaceVariantType> sp_read_fontFaceVariantType(gchar const *value){
105     std::vector<FontFaceVariantType> v;
107     if (!value){
108         v.push_back(SP_FONTFACE_VARIANT_NORMAL);
109         return v;
110     }
112     while(value[0]!='\0'){
113         switch(value[0]){
114             case 'n':
115                 if (strncmp(value, "normal", 6) == 0){
116                     v.push_back(SP_FONTFACE_VARIANT_NORMAL);
117                     value += 6;
118                 }
119                 break;
120             case 's':
121                 if (strncmp(value, "small-caps", 10) == 0){
122                     v.push_back(SP_FONTFACE_VARIANT_SMALL_CAPS);
123                     value += 10;
124                 }
125                 break;
126         }
127         while(value[0]==',' || value[0]==' ')
128             value++;
129     }
130     return v;
133 static std::vector<FontFaceWeightType> sp_read_fontFaceWeightType(gchar const *value){
134     std::vector<FontFaceWeightType> v;
136     if (!value){
137         v.push_back(SP_FONTFACE_WEIGHT_ALL);
138         return v;
139     }
141     if (strncmp(value, "all", 3) == 0){
142         value += 3;
143         while(value[0]==',' || value[0]==' ')
144             value++;
145         v.push_back(SP_FONTFACE_WEIGHT_ALL);
146         return v;
147     }
149     while(value[0]!='\0'){
150         switch(value[0]){
151             case 'n':
152                 if (strncmp(value, "normal", 6) == 0){
153                     v.push_back(SP_FONTFACE_WEIGHT_NORMAL);
154                     value += 6;
155                 }
156                 break;
157             case 'b':
158                 if (strncmp(value, "bold", 4) == 0){
159                     v.push_back(SP_FONTFACE_WEIGHT_BOLD);
160                     value += 4;
161                 }
162                 break;
163             case '1':
164                 if (strncmp(value, "100", 3) == 0){
165                     v.push_back(SP_FONTFACE_WEIGHT_100);
166                     value += 3;
167                 }
168                 break;
169             case '2':
170                 if (strncmp(value, "200", 3) == 0){
171                     v.push_back(SP_FONTFACE_WEIGHT_200);
172                     value += 3;
173                 }
174                 break;
175             case '3':
176                 if (strncmp(value, "300", 3) == 0){
177                     v.push_back(SP_FONTFACE_WEIGHT_300);
178                     value += 3;
179                 }
180                 break;
181             case '4':
182                 if (strncmp(value, "400", 3) == 0){
183                     v.push_back(SP_FONTFACE_WEIGHT_400);
184                     value += 3;
185                 }
186                 break;
187             case '5':
188                 if (strncmp(value, "500", 3) == 0){
189                     v.push_back(SP_FONTFACE_WEIGHT_500);
190                     value += 3;
191                 }
192                 break;
193             case '6':
194                 if (strncmp(value, "600", 3) == 0){
195                     v.push_back(SP_FONTFACE_WEIGHT_600);
196                     value += 3;
197                 }
198                 break;
199             case '7':
200                 if (strncmp(value, "700", 3) == 0){
201                     v.push_back(SP_FONTFACE_WEIGHT_700);
202                     value += 3;
203                 }
204                 break;
205             case '8':
206                 if (strncmp(value, "800", 3) == 0){
207                     v.push_back(SP_FONTFACE_WEIGHT_800);
208                     value += 3;
209                 }
210                 break;
211             case '9':
212                 if (strncmp(value, "900", 3) == 0){
213                     v.push_back(SP_FONTFACE_WEIGHT_900);
214                     value += 3;
215                 }
216                 break;
217         }
218         while(value[0]==',' || value[0]==' ')
219             value++;
220     }
221     return v;
224 static std::vector<FontFaceStretchType> sp_read_fontFaceStretchType(gchar const *value){
225     std::vector<FontFaceStretchType> v;
227     if (!value){
228         v.push_back(SP_FONTFACE_STRETCH_NORMAL);
229         return v;
230     }
232     if (strncmp(value, "all", 3) == 0){
233         value += 3;
234         while(value[0]==',' || value[0]==' ')
235             value++;
236         v.push_back(SP_FONTFACE_STRETCH_ALL);
237         return v;
238     }
240     while(value[0]!='\0'){
241         switch(value[0]){
242             case 'n':
243                 if (strncmp(value, "normal", 6) == 0){
244                     v.push_back(SP_FONTFACE_STRETCH_NORMAL);
245                     value += 6;
246                 }
247                 break;
248             case 'u':
249                 if (strncmp(value, "ultra-condensed", 15) == 0){
250                     v.push_back(SP_FONTFACE_STRETCH_ULTRA_CONDENSED);
251                     value += 15;
252                 }
253                 if (strncmp(value, "ultra-expanded", 14) == 0){
254                     v.push_back(SP_FONTFACE_STRETCH_ULTRA_EXPANDED);
255                     value += 14;
256                 }
257                 break;
258             case 'e':
259                 if (strncmp(value, "expanded", 8) == 0){
260                     v.push_back(SP_FONTFACE_STRETCH_EXPANDED);
261                     value += 8;
262                 }
263                 if (strncmp(value, "extra-condensed", 15) == 0){
264                     v.push_back(SP_FONTFACE_STRETCH_EXTRA_CONDENSED);
265                     value += 15;
266                 }
267                 if (strncmp(value, "extra-expanded", 14) == 0){
268                     v.push_back(SP_FONTFACE_STRETCH_EXTRA_EXPANDED);
269                     value += 14;
270                 }
271                 break;
272             case 'c':
273                 if (strncmp(value, "condensed", 9) == 0){
274                     v.push_back(SP_FONTFACE_STRETCH_CONDENSED);
275                     value += 9;
276                 }
277                 break;
278             case 's':
279                 if (strncmp(value, "semi-condensed", 14) == 0){
280                     v.push_back(SP_FONTFACE_STRETCH_SEMI_CONDENSED);
281                     value += 14;
282                 }
283                 if (strncmp(value, "semi-expanded", 13) == 0){
284                     v.push_back(SP_FONTFACE_STRETCH_SEMI_EXPANDED);
285                     value += 13;
286                 }
287                 break;
288         }
289         while(value[0]==',' || value[0]==' ')
290             value++;
291     }
292     return v;
295 static void sp_fontface_class_init(SPFontFaceClass *fc);
296 static void sp_fontface_init(SPFontFace *font);
298 static void sp_fontface_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
299 static void sp_fontface_release(SPObject *object);
300 static void sp_fontface_set(SPObject *object, unsigned int key, const gchar *value);
301 static Inkscape::XML::Node *sp_fontface_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
303 static void sp_fontface_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref);
304 static void sp_fontface_remove_child(SPObject *object, Inkscape::XML::Node *child);
305 static void sp_fontface_update(SPObject *object, SPCtx *ctx, guint flags);
307 static SPObjectClass *parent_class;
309 GType sp_fontface_get_type(void)
311     static GType type = 0;
313     if (!type) {
314         GTypeInfo info = {
315             sizeof(SPFontFaceClass),
316             NULL,       /* base_init */
317             NULL,       /* base_finalize */
318             (GClassInitFunc) sp_fontface_class_init,
319             NULL,       /* class_finalize */
320             NULL,       /* class_data */
321             sizeof(SPFontFace),
322             16, /* n_preallocs */
323             (GInstanceInitFunc) sp_fontface_init,
324             NULL,       /* value_table */
325         };
326         type = g_type_register_static(SP_TYPE_OBJECT, "SPFontFace", &info, (GTypeFlags) 0);
327     }
329     return type;
332 static void sp_fontface_class_init(SPFontFaceClass *fc)
334     SPObjectClass *sp_object_class = (SPObjectClass *) fc;
336     parent_class = (SPObjectClass *) g_type_class_ref(SP_TYPE_OBJECT);
338     sp_object_class->build = sp_fontface_build;
339     sp_object_class->release = sp_fontface_release;
340     sp_object_class->set = sp_fontface_set;
341     sp_object_class->write = sp_fontface_write;
342     sp_object_class->child_added = sp_fontface_child_added;
343     sp_object_class->remove_child = sp_fontface_remove_child;
344     sp_object_class->update = sp_fontface_update;
347 static void sp_fontface_init(SPFontFace *face)
349     std::vector<FontFaceStyleType> style;
350     style.push_back(SP_FONTFACE_STYLE_ALL);
351     face->font_style = style;
353     std::vector<FontFaceVariantType> variant;
354     variant.push_back(SP_FONTFACE_VARIANT_NORMAL);
355     face->font_variant = variant;
357     std::vector<FontFaceWeightType> weight;
358     weight.push_back(SP_FONTFACE_WEIGHT_ALL);
359     face->font_weight = weight;
361     std::vector<FontFaceStretchType> stretch;
362     stretch.push_back(SP_FONTFACE_STRETCH_NORMAL);
363     face->font_stretch = stretch;
364     face->font_family = NULL;
365     /*
366     //face->font_style = ;
367     //face->font_variant = ;
368     //face->font_weight = ;
369     //face->font_stretch = ;
370     face->font_size = NULL;
371     //face->unicode_range = ;
372     face->units_per_em = 1000;
373     //face->panose_1 = ;
374     face->stem_v = ;
375     face->stem_h = ;
376     face->slope = 0;
377     face->cap_height = ;
378     face->x_height = ;
379     face->accent_height = ;
380     face->ascent = ;
381     face->descent = ;
382     face->widths = NULL;
383     face->bbox = NULL;
384     face->ideographic = ;
385     face->alphabetic = ;
386     face->mathematical = ;
387     face->hanging = ;
388     face->v_ideographic = ;
389     face->v_alphabetic = ;
390     face->v_mathematical = ;
391     face->v_hanging = ;
392     face->underline_position = ;
393     face->underline_thickness = ;
394     face->strikethrough_position = ;
395     face->strikethrough_thickness = ;
396     face->overline_position = ;
397     face->overline_thickness = ;
398 */
401 static void sp_fontface_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
403     if (((SPObjectClass *) (parent_class))->build) {
404         ((SPObjectClass *) (parent_class))->build(object, document, repr);
405     }
407     sp_object_read_attr(object, "font-family");
408     sp_object_read_attr(object, "font-style");
409     sp_object_read_attr(object, "font-variant");
410     sp_object_read_attr(object, "font-weight");
411     sp_object_read_attr(object, "font-stretch");
412     sp_object_read_attr(object, "font-size");
413     sp_object_read_attr(object, "unicode-range");
414     sp_object_read_attr(object, "units-per-em");
415     sp_object_read_attr(object, "panose-1");
416     sp_object_read_attr(object, "stem-v");
417     sp_object_read_attr(object, "stem-h");
418     sp_object_read_attr(object, "slope");
419     sp_object_read_attr(object, "cap-height");
420     sp_object_read_attr(object, "x-height");
421     sp_object_read_attr(object, "accent-height");
422     sp_object_read_attr(object, "ascent");
423     sp_object_read_attr(object, "descent");
424     sp_object_read_attr(object, "widths");
425     sp_object_read_attr(object, "bbox");
426     sp_object_read_attr(object, "ideographic");
427     sp_object_read_attr(object, "alphabetic");
428     sp_object_read_attr(object, "mathematical");
429     sp_object_read_attr(object, "ranging");
430     sp_object_read_attr(object, "v-ideogaphic");
431     sp_object_read_attr(object, "v-alphabetic");
432     sp_object_read_attr(object, "v-mathematical");
433     sp_object_read_attr(object, "v-hanging");
434     sp_object_read_attr(object, "underline-position");
435     sp_object_read_attr(object, "underline-thickness");
436     sp_object_read_attr(object, "strikethrough-position");
437     sp_object_read_attr(object, "strikethrough-thickness");
438     sp_object_read_attr(object, "overline-position");
439     sp_object_read_attr(object, "overline-thickness");
442 static void sp_fontface_children_modified(SPFontFace */*sp_fontface*/)
446 /**
447  * Callback for child_added event.
448  */
449 static void
450 sp_fontface_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
452     SPFontFace *f = SP_FONTFACE(object);
454     if (((SPObjectClass *) parent_class)->child_added)
455         (* ((SPObjectClass *) parent_class)->child_added)(object, child, ref);
457     sp_fontface_children_modified(f);
458     object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
462 /**
463  * Callback for remove_child event.
464  */
465 static void
466 sp_fontface_remove_child(SPObject *object, Inkscape::XML::Node *child)
468     SPFontFace *f = SP_FONTFACE(object);
470     if (((SPObjectClass *) parent_class)->remove_child)
471         (* ((SPObjectClass *) parent_class)->remove_child)(object, child);
473     sp_fontface_children_modified(f);
474     object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
477 static void sp_fontface_release(SPObject *object)
479     //SPFontFace *font = SP_FONTFACE(object);
481     if (((SPObjectClass *) parent_class)->release) {
482         ((SPObjectClass *) parent_class)->release(object);
483     }
486 static void sp_fontface_set(SPObject *object, unsigned int key, const gchar *value)
488     SPFontFace *face = SP_FONTFACE(object);
489     double number;
490     std::vector<FontFaceStyleType> style;
491     std::vector<FontFaceVariantType> variant;
492     std::vector<FontFaceWeightType> weight;
493     std::vector<FontFaceStretchType> stretch;
495     switch (key) {
496         case SP_PROP_FONT_FAMILY:
497             if (face->font_family) g_free(face->font_family);
498             face->font_family = g_strdup(value);
499             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
500             break;
501         case SP_PROP_FONT_STYLE:
502             style = sp_read_fontFaceStyleType(value);
503             if (face->font_style.size() != style.size()){
504                 face->font_style = style;
505                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
506             } else {
507                 for (unsigned int i=0;i<style.size();i++){
508                     if(style[i] != face->font_style[i]){
509                         face->font_style = style;
510                         object->requestModified(SP_OBJECT_MODIFIED_FLAG);
511                         break;
512                     }
513                 }
514             }
515             break;
516         case SP_PROP_FONT_VARIANT:
517             variant = sp_read_fontFaceVariantType(value);
518             if (face->font_variant.size() != variant.size()){
519                 face->font_variant = variant;
520                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
521             } else {
522                 for (unsigned int i=0;i<variant.size();i++){
523                     if(variant[i] != face->font_variant[i]){
524                         face->font_variant = variant;
525                         object->requestModified(SP_OBJECT_MODIFIED_FLAG);
526                         break;
527                     }
528                 }
529             }
530             break;
531         case SP_PROP_FONT_WEIGHT:
532             weight = sp_read_fontFaceWeightType(value);
533             if (face->font_weight.size() != weight.size()){
534                 face->font_weight = weight;
535                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
536             } else {
537                 for (unsigned int i=0;i<weight.size();i++){
538                     if(weight[i] != face->font_weight[i]){
539                         face->font_weight = weight;
540                         object->requestModified(SP_OBJECT_MODIFIED_FLAG);
541                         break;
542                     }
543                 }
544             }
545             break;
546         case SP_PROP_FONT_STRETCH:
547             stretch = sp_read_fontFaceStretchType(value);
548             if (face->font_stretch.size() != stretch.size()){
549                 face->font_stretch = stretch;
550                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
551             } else {
552                 for (unsigned int i=0;i<stretch.size();i++){
553                     if(stretch[i] != face->font_stretch[i]){
554                         face->font_stretch = stretch;
555                         object->requestModified(SP_OBJECT_MODIFIED_FLAG);
556                         break;
557                     }
558                 }
559             }
560             break;
561         case SP_ATTR_UNITS_PER_EM:
562             number = helperfns_read_number(value);
563             if (number != face->units_per_em){
564                 face->units_per_em = number;
565                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
566             }
567             break;
568         case SP_ATTR_STEMV:
569             number = helperfns_read_number(value);
570             if (number != face->stemv){
571                 face->stemv = number;
572                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
573             }
574             break;
575         case SP_ATTR_STEMH:
576             number = helperfns_read_number(value);
577             if (number != face->stemh){
578                 face->stemh = number;
579                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
580             }
581             break;
582         case SP_ATTR_SLOPE:
583             number = helperfns_read_number(value);
584             if (number != face->slope){
585                 face->slope = number;
586                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
587             }
588             break;
589         case SP_ATTR_CAP_HEIGHT:
590             number = helperfns_read_number(value);
591             if (number != face->cap_height){
592                 face->cap_height = number;
593                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
594             }
595             break;
596         case SP_ATTR_X_HEIGHT:
597             number = helperfns_read_number(value);
598             if (number != face->x_height){
599                 face->x_height = number;
600                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
601             }
602             break;
603         case SP_ATTR_ACCENT_HEIGHT:
604             number = helperfns_read_number(value);
605             if (number != face->accent_height){
606                 face->accent_height = number;
607                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
608             }
609             break;
610         case SP_ATTR_ASCENT:
611             number = helperfns_read_number(value);
612             if (number != face->ascent){
613                 face->ascent = number;
614                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
615             }
616             break;
617         case SP_ATTR_DESCENT:
618             number = helperfns_read_number(value);
619             if (number != face->descent){
620                 face->descent = number;
621                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
622             }
623             break;
624         case SP_ATTR_IDEOGRAPHIC:
625             number = helperfns_read_number(value);
626             if (number != face->ideographic){
627                 face->ideographic = number;
628                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
629             }
630             break;
631         case SP_ATTR_ALPHABETIC:
632             number = helperfns_read_number(value);
633             if (number != face->alphabetic){
634                 face->alphabetic = number;
635                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
636             }
637             break;
638         case SP_ATTR_MATHEMATICAL:
639             number = helperfns_read_number(value);
640             if (number != face->mathematical){
641                 face->mathematical = number;
642                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
643             }
644             break;
645         case SP_ATTR_HANGING:
646             number = helperfns_read_number(value);
647             if (number != face->hanging){
648                 face->hanging = number;
649                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
650             }
651             break;
652         case SP_ATTR_V_IDEOGRAPHIC:
653             number = helperfns_read_number(value);
654             if (number != face->v_ideographic){
655                 face->v_ideographic = number;
656                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
657             }
658             break;
659         case SP_ATTR_V_ALPHABETIC:
660             number = helperfns_read_number(value);
661             if (number != face->v_alphabetic){
662                 face->v_alphabetic = number;
663                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
664             }
665             break;
666         case SP_ATTR_V_MATHEMATICAL:
667             number = helperfns_read_number(value);
668             if (number != face->v_mathematical){
669                 face->v_mathematical = number;
670                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
671             }
672             break;
673         case SP_ATTR_V_HANGING:
674             number = helperfns_read_number(value);
675             if (number != face->v_hanging){
676                 face->v_hanging = number;
677                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
678             }
679             break;
680         case SP_ATTR_UNDERLINE_POSITION:
681             number = helperfns_read_number(value);
682             if (number != face->underline_position){
683                 face->underline_position = number;
684                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
685             }
686             break;
687         case SP_ATTR_UNDERLINE_THICKNESS:
688             number = helperfns_read_number(value);
689             if (number != face->underline_thickness){
690                 face->underline_thickness = number;
691                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
692             }
693             break;
694         case SP_ATTR_STRIKETHROUGH_POSITION:
695             number = helperfns_read_number(value);
696             if (number != face->strikethrough_position){
697                 face->strikethrough_position = number;
698                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
699             }
700             break;
701         case SP_ATTR_STRIKETHROUGH_THICKNESS:
702             number = helperfns_read_number(value);
703             if (number != face->strikethrough_thickness){
704                 face->strikethrough_thickness = number;
705                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
706             }
707             break;
708         case SP_ATTR_OVERLINE_POSITION:
709             number = helperfns_read_number(value);
710             if (number != face->overline_position){
711                 face->overline_position = number;
712                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
713             }
714             break;
715         case SP_ATTR_OVERLINE_THICKNESS:
716             number = helperfns_read_number(value);
717             if (number != face->overline_thickness){
718                 face->overline_thickness = number;
719                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
720             }
721             break;
722         default:
723             if (((SPObjectClass *) (parent_class))->set) {
724                 ((SPObjectClass *) (parent_class))->set(object, key, value);
725             }
726             break;
727     }
730 /**
731  * Receives update notifications.
732  */
733 static void
734 sp_fontface_update(SPObject *object, SPCtx *ctx, guint flags)
736     if (flags & (SP_OBJECT_MODIFIED_FLAG)) {
737         sp_object_read_attr(object, "font-family");
738         sp_object_read_attr(object, "font-style");
739         sp_object_read_attr(object, "font-variant");
740         sp_object_read_attr(object, "font-weight");
741         sp_object_read_attr(object, "font-stretch");
742         sp_object_read_attr(object, "font-size");
743         sp_object_read_attr(object, "unicode-range");
744         sp_object_read_attr(object, "units-per-em");
745         sp_object_read_attr(object, "panose-1");
746         sp_object_read_attr(object, "stemv");
747         sp_object_read_attr(object, "stemh");
748         sp_object_read_attr(object, "slope");
749         sp_object_read_attr(object, "cap-height");
750         sp_object_read_attr(object, "x-height");
751         sp_object_read_attr(object, "accent-height");
752         sp_object_read_attr(object, "ascent");
753         sp_object_read_attr(object, "descent");
754         sp_object_read_attr(object, "widths");
755         sp_object_read_attr(object, "bbox");
756         sp_object_read_attr(object, "ideographic");
757         sp_object_read_attr(object, "alphabetic");
758         sp_object_read_attr(object, "mathematical");
759         sp_object_read_attr(object, "hanging");
760         sp_object_read_attr(object, "v-ideographic");
761         sp_object_read_attr(object, "v-alphabetic");
762         sp_object_read_attr(object, "v-mathematical");
763         sp_object_read_attr(object, "v-hanging");
764         sp_object_read_attr(object, "underline-position");
765         sp_object_read_attr(object, "underline-thickness");
766         sp_object_read_attr(object, "strikethrough-position");
767         sp_object_read_attr(object, "strikethrough-thickness");
768         sp_object_read_attr(object, "overline-position");
769         sp_object_read_attr(object, "overline-thickness");
770     }
772     if (((SPObjectClass *) parent_class)->update) {
773         ((SPObjectClass *) parent_class)->update(object, ctx, flags);
774     }
777 #define COPY_ATTR(rd,rs,key) (rd)->setAttribute((key), rs->attribute(key));
779 static Inkscape::XML::Node *sp_fontface_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
781     SPFontFace *face = SP_FONTFACE(object);
783     if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
784         repr = xml_doc->createElement("svg:font-face");
785     }
787     //TODO:
788     //sp_repr_set_svg_double(repr, "font-family", face->font_family);
789     //sp_repr_set_svg_double(repr, "font-style", face->font_style);
790     //sp_repr_set_svg_double(repr, "font-variant", face->font_variant);
791     //sp_repr_set_svg_double(repr, "font-weight", face->font_weight);
792     //sp_repr_set_svg_double(repr, "font-stretch", face->font_stretch);
793     //sp_repr_set_svg_double(repr, "font-size", face->font_size);
794     //sp_repr_set_svg_double(repr, "unicode-range", face->unicode_range);
795     sp_repr_set_svg_double(repr, "units-per-em", face->units_per_em);
796     //sp_repr_set_svg_double(repr, "panose-1", face->panose_1);
797     sp_repr_set_svg_double(repr, "stemv", face->stemv);
798     sp_repr_set_svg_double(repr, "stemh", face->stemh);
799     sp_repr_set_svg_double(repr, "slope", face->slope);
800     sp_repr_set_svg_double(repr, "cap-height", face->cap_height);
801     sp_repr_set_svg_double(repr, "x-height", face->x_height);
802     sp_repr_set_svg_double(repr, "accent-height", face->accent_height);
803     sp_repr_set_svg_double(repr, "ascent", face->ascent);
804     sp_repr_set_svg_double(repr, "descent", face->descent);
805     //sp_repr_set_svg_double(repr, "widths", face->widths);
806     //sp_repr_set_svg_double(repr, "bbox", face->bbox);
807     sp_repr_set_svg_double(repr, "ideographic", face->ideographic);
808     sp_repr_set_svg_double(repr, "alphabetic", face->alphabetic);
809     sp_repr_set_svg_double(repr, "mathematical", face->mathematical);
810     sp_repr_set_svg_double(repr, "hanging", face->hanging);
811     sp_repr_set_svg_double(repr, "v-ideographic", face->v_ideographic);
812     sp_repr_set_svg_double(repr, "v-alphabetic", face->v_alphabetic);
813     sp_repr_set_svg_double(repr, "v-mathematical", face->v_mathematical);
814     sp_repr_set_svg_double(repr, "v-hanging", face->v_hanging);
815     sp_repr_set_svg_double(repr, "underline-position", face->underline_position);
816     sp_repr_set_svg_double(repr, "underline-thickness", face->underline_thickness);
817     sp_repr_set_svg_double(repr, "strikethrough-position", face->strikethrough_position);
818     sp_repr_set_svg_double(repr, "strikethrough-thickness", face->strikethrough_thickness);
819     sp_repr_set_svg_double(repr, "overline-position", face->overline_position);
820     sp_repr_set_svg_double(repr, "overline-thickness", face->overline_thickness);
822     if (repr != SP_OBJECT_REPR(object)) {
823         COPY_ATTR(repr, object->repr, "font-family");
824         COPY_ATTR(repr, object->repr, "font-style");
825         COPY_ATTR(repr, object->repr, "font-variant");
826         COPY_ATTR(repr, object->repr, "font-weight");
827         COPY_ATTR(repr, object->repr, "font-stretch");
828         COPY_ATTR(repr, object->repr, "font-size");
829         COPY_ATTR(repr, object->repr, "unicode-range");
830         COPY_ATTR(repr, object->repr, "units-per-em");
831         COPY_ATTR(repr, object->repr, "panose-1");
832         COPY_ATTR(repr, object->repr, "stemv");
833         COPY_ATTR(repr, object->repr, "stemh");
834         COPY_ATTR(repr, object->repr, "slope");
835         COPY_ATTR(repr, object->repr, "cap-height");
836         COPY_ATTR(repr, object->repr, "x-height");
837         COPY_ATTR(repr, object->repr, "accent-height");
838         COPY_ATTR(repr, object->repr, "ascent");
839         COPY_ATTR(repr, object->repr, "descent");
840         COPY_ATTR(repr, object->repr, "widths");
841         COPY_ATTR(repr, object->repr, "bbox");
842         COPY_ATTR(repr, object->repr, "ideographic");
843         COPY_ATTR(repr, object->repr, "alphabetic");
844         COPY_ATTR(repr, object->repr, "mathematical");
845         COPY_ATTR(repr, object->repr, "hanging");
846         COPY_ATTR(repr, object->repr, "v-ideographic");
847         COPY_ATTR(repr, object->repr, "v-alphabetic");
848         COPY_ATTR(repr, object->repr, "v-mathematical");
849         COPY_ATTR(repr, object->repr, "v-hanging");
850         COPY_ATTR(repr, object->repr, "underline-position");
851         COPY_ATTR(repr, object->repr, "underline-thickness");
852         COPY_ATTR(repr, object->repr, "strikethrough-position");
853         COPY_ATTR(repr, object->repr, "strikethrough-thickness");
854         COPY_ATTR(repr, object->repr, "overline-position");
855         COPY_ATTR(repr, object->repr, "overline-thickness");
856     }
858     if (((SPObjectClass *) (parent_class))->write) {
859         ((SPObjectClass *) (parent_class))->write(object, xml_doc, repr, flags);
860     }
862     return repr;
864 #endif //#ifdef ENABLE_SVG_FONTS
865 /*
866   Local Variables:
867   mode:c++
868   c-file-style:"stroustrup"
869   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
870   indent-tabs-mode:nil
871   fill-column:99
872   End:
873 */
874 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :