Code

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