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 }
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;
125 }
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 }
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;
216 }
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 }
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;
287 }
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)
304 {
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;
324 }
326 static void sp_fontface_class_init(SPFontFaceClass *fc)
327 {
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;
339 }
341 static void sp_fontface_init(SPFontFace *face)
342 {
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 */
393 }
395 static void sp_fontface_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
396 {
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");
434 }
436 static void sp_fontface_children_modified(SPFontFace *sp_fontface)
437 {
438 }
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)
445 {
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);
453 }
456 /**
457 * Callback for remove_child event.
458 */
459 static void
460 sp_fontface_remove_child(SPObject *object, Inkscape::XML::Node *child)
461 {
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);
469 }
471 static void sp_fontface_release(SPObject *object)
472 {
473 //SPFontFace *font = SP_FONTFACE(object);
475 if (((SPObjectClass *) parent_class)->release) {
476 ((SPObjectClass *) parent_class)->release(object);
477 }
478 }
480 static void sp_fontface_set(SPObject *object, unsigned int key, const gchar *value)
481 {
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 }
772 }
774 /**
775 * Receives update notifications.
776 */
777 static void
778 sp_fontface_update(SPObject *object, SPCtx *ctx, guint flags)
779 {
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 }
819 }
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)
824 {
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;
908 }
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 :