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;
102 }
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;
131 }
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;
222 }
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;
293 }
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)
310 {
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;
330 }
332 static void sp_fontface_class_init(SPFontFaceClass *fc)
333 {
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;
345 }
347 static void sp_fontface_init(SPFontFace *face)
348 {
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 */
399 }
401 static void sp_fontface_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
402 {
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");
440 }
442 static void sp_fontface_children_modified(SPFontFace */*sp_fontface*/)
443 {
444 }
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)
451 {
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);
459 }
462 /**
463 * Callback for remove_child event.
464 */
465 static void
466 sp_fontface_remove_child(SPObject *object, Inkscape::XML::Node *child)
467 {
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);
475 }
477 static void sp_fontface_release(SPObject *object)
478 {
479 //SPFontFace *font = SP_FONTFACE(object);
481 if (((SPObjectClass *) parent_class)->release) {
482 ((SPObjectClass *) parent_class)->release(object);
483 }
484 }
486 static void sp_fontface_set(SPObject *object, unsigned int key, const gchar *value)
487 {
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 }
728 }
730 /**
731 * Receives update notifications.
732 */
733 static void
734 sp_fontface_update(SPObject *object, SPCtx *ctx, guint flags)
735 {
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 }
775 }
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)
780 {
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;
863 }
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 :