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