Code

* add rule in configure.ac so that only who has cairo > 1.6.4 (currently cairo git...
[inkscape.git] / src / sp-font-face.cpp
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 void sp_fontface_class_init(SPFontFaceClass *fc);
58 static void sp_fontface_init(SPFontFace *font);
60 static void sp_fontface_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
61 static void sp_fontface_release(SPObject *object);
62 static void sp_fontface_set(SPObject *object, unsigned int key, const gchar *value);
63 static Inkscape::XML::Node *sp_fontface_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
65 static void sp_fontface_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref);
66 static void sp_fontface_remove_child(SPObject *object, Inkscape::XML::Node *child);
67 static void sp_fontface_update(SPObject *object, SPCtx *ctx, guint flags);
69 static SPObjectClass *parent_class;
71 GType sp_fontface_get_type(void)
72 {
73     static GType type = 0;
75     if (!type) {
76         GTypeInfo info = {
77             sizeof(SPFontFaceClass),
78             NULL,       /* base_init */
79             NULL,       /* base_finalize */
80             (GClassInitFunc) sp_fontface_class_init,
81             NULL,       /* class_finalize */
82             NULL,       /* class_data */
83             sizeof(SPFontFace),
84             16, /* n_preallocs */
85             (GInstanceInitFunc) sp_fontface_init,
86             NULL,       /* value_table */
87         };
88         type = g_type_register_static(SP_TYPE_OBJECT, "SPFontFace", &info, (GTypeFlags) 0);
89     }
91     return type;
92 }
94 static void sp_fontface_class_init(SPFontFaceClass *fc)
95 {
96     SPObjectClass *sp_object_class = (SPObjectClass *) fc;
98     parent_class = (SPObjectClass *) g_type_class_ref(SP_TYPE_OBJECT);
100     sp_object_class->build = sp_fontface_build;
101     sp_object_class->release = sp_fontface_release;
102     sp_object_class->set = sp_fontface_set;
103     sp_object_class->write = sp_fontface_write;
104     sp_object_class->child_added = sp_fontface_child_added;
105     sp_object_class->remove_child = sp_fontface_remove_child;
106     sp_object_class->update = sp_fontface_update;
109 static void sp_fontface_init(SPFontFace *face)
111 /*
112     //face->unicode_range = ;
113     face->units_per_em = 1000;
114     //face->panose_1 = ;
115     face->stem_v = ;
116     face->stem_h = ;
117     face->slope = 0;
118     face->cap_height = ;
119     face->x_height = ;
120     face->accent_height = ;
121     face->ascent = ;
122     face->descent = ;
123     face->widths = NULL;
124     face->bbox = NULL;
125     face->ideographic = ;
126     face->alphabetic = ;
127     face->mathematical = ;
128     face->hanging = ;
129     face->v_ideographic = ;
130     face->v_alphabetic = ;
131     face->v_mathematical = ;
132     face->v_hanging = ;
133     face->underline_position = ;
134     face->underline_thickness = ;
135     face->strikethrough_position = ;
136     face->strikethrough_thickness = ;
137     face->overline_position = ;
138     face->overline_thickness = ;
139 */
142 static void sp_fontface_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
144     if (((SPObjectClass *) (parent_class))->build) {
145         ((SPObjectClass *) (parent_class))->build(object, document, repr);
146     }
148     sp_object_read_attr(object, "unicode-range");
149     sp_object_read_attr(object, "units-per-em");
150     sp_object_read_attr(object, "panose-1");
151     sp_object_read_attr(object, "stem-v");
152     sp_object_read_attr(object, "stem-h");
153     sp_object_read_attr(object, "slope");
154     sp_object_read_attr(object, "cap-height");
155     sp_object_read_attr(object, "x-height");
156     sp_object_read_attr(object, "accent-height");
157     sp_object_read_attr(object, "ascent");
158     sp_object_read_attr(object, "descent");
159     sp_object_read_attr(object, "widths");
160     sp_object_read_attr(object, "bbox");
161     sp_object_read_attr(object, "ideographic");
162     sp_object_read_attr(object, "alphabetic");
163     sp_object_read_attr(object, "mathematical");
164     sp_object_read_attr(object, "ranging");
165     sp_object_read_attr(object, "v-ideogaphic");
166     sp_object_read_attr(object, "v-alphabetic");
167     sp_object_read_attr(object, "v-mathematical");
168     sp_object_read_attr(object, "v-hanging");
169     sp_object_read_attr(object, "underline-position");
170     sp_object_read_attr(object, "underline-thickness");
171     sp_object_read_attr(object, "strikethrough-position");
172     sp_object_read_attr(object, "strikethrough-thickness");
173     sp_object_read_attr(object, "overline-position");
174     sp_object_read_attr(object, "overline-thickness");
177 static void sp_fontface_children_modified(SPFontFace *sp_fontface)
181 /**
182  * Callback for child_added event.
183  */
184 static void
185 sp_fontface_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
187     SPFontFace *f = SP_FONTFACE(object);
189     if (((SPObjectClass *) parent_class)->child_added)
190         (* ((SPObjectClass *) parent_class)->child_added)(object, child, ref);
192     sp_fontface_children_modified(f);
193     object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
197 /**
198  * Callback for remove_child event.
199  */
200 static void
201 sp_fontface_remove_child(SPObject *object, Inkscape::XML::Node *child)
203     SPFontFace *f = SP_FONTFACE(object);
205     if (((SPObjectClass *) parent_class)->remove_child)
206         (* ((SPObjectClass *) parent_class)->remove_child)(object, child);
208     sp_fontface_children_modified(f);
209     object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
212 static void sp_fontface_release(SPObject *object)
214     //SPFontFace *font = SP_FONTFACE(object);
216     if (((SPObjectClass *) parent_class)->release) {
217         ((SPObjectClass *) parent_class)->release(object);
218     }
221 static void sp_fontface_set(SPObject *object, unsigned int key, const gchar *value)
223     SPFontFace *face = SP_FONTFACE(object);
224     double number;
226     switch (key) {
227         case SP_ATTR_UNITS_PER_EM:
228             number = helperfns_read_number(value);
229             if (number != face->units_per_em){
230                 face->units_per_em = number;
231 g_warning("<font-face>: SP_ATTR_UNITS_PER_EM: %f", number);
232                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
233             }
234             break;
235         case SP_ATTR_STEMV:
236             number = helperfns_read_number(value);
237             if (number != face->stemv){
238                 face->stemv = number;
239 g_warning("<font-face>: SP_ATTR_STEMV: %f", number);
240                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
241             }
242             break;
243         case SP_ATTR_STEMH:
244             number = helperfns_read_number(value);
245             if (number != face->stemh){
246                 face->stemh = number;
247 g_warning("<font-face>: SP_ATTR_STEMH: %f", number);
248                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
249             }
250             break;
251         case SP_ATTR_SLOPE:
252             number = helperfns_read_number(value);
253             if (number != face->slope){
254                 face->slope = number;
255 g_warning("<font-face>: SP_ATTR_SLOPE: %f", number);
256                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
257             }
258             break;
259         case SP_ATTR_CAP_HEIGHT:
260             number = helperfns_read_number(value);
261             if (number != face->cap_height){
262                 face->cap_height = number;
263 g_warning("<font-face>: SP_ATTR_CAP_HEIGHT: %f", number);
264                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
265             }
266             break;
267         case SP_ATTR_X_HEIGHT:
268             number = helperfns_read_number(value);
269             if (number != face->x_height){
270                 face->x_height = number;
271 g_warning("<font-face>: SP_ATTR_X_HEIGHT: %f", number);
272                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
273             }
274             break;
275         case SP_ATTR_ACCENT_HEIGHT:
276             number = helperfns_read_number(value);
277             if (number != face->accent_height){
278                 face->accent_height = number;
279 g_warning("<font-face>: SP_ATTR_ACCENT_HEIGHT: %f", number);
280                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
281             }
282             break;
283         case SP_ATTR_ASCENT:
284             number = helperfns_read_number(value);
285             if (number != face->ascent){
286                 face->ascent = number;
287 g_warning("<font-face>: SP_ATTR_ASCENT: %f", number);
288                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
289             }
290             break;
291         case SP_ATTR_DESCENT:
292             number = helperfns_read_number(value);
293             if (number != face->descent){
294                 face->descent = number;
295 g_warning("<font-face>: SP_ATTR_DESCENT: %f", number);
296                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
297             }
298             break;
299         case SP_ATTR_IDEOGRAPHIC:
300             number = helperfns_read_number(value);
301             if (number != face->ideographic){
302                 face->ideographic = number;
303 g_warning("<font-face>: SP_ATTR_IDEOGRAPHIC: %f", number);
304                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
305             }
306             break;
307         case SP_ATTR_ALPHABETIC:
308             number = helperfns_read_number(value);
309             if (number != face->alphabetic){
310                 face->alphabetic = number;
311 g_warning("<font-face>: SP_ATTR_ALPHABETIC: %f", number);
312                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
313             }
314             break;
315         case SP_ATTR_MATHEMATICAL:
316             number = helperfns_read_number(value);
317             if (number != face->mathematical){
318                 face->mathematical = number;
319 g_warning("<font-face>: SP_ATTR_MATHEMATICAL: %f", number);
320                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
321             }
322             break;
323         case SP_ATTR_HANGING:
324             number = helperfns_read_number(value);
325             if (number != face->hanging){
326                 face->hanging = number;
327 g_warning("<font-face>: SP_ATTR_HANGING: %f", number);
328                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
329             }
330             break;
331         case SP_ATTR_V_IDEOGRAPHIC:
332             number = helperfns_read_number(value);
333             if (number != face->v_ideographic){
334                 face->v_ideographic = number;
335 g_warning("<font-face>: SP_ATTR_V_IDEOGRAPHIC: %f", number);
336                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
337             }
338             break;
339         case SP_ATTR_V_ALPHABETIC:
340             number = helperfns_read_number(value);
341             if (number != face->v_alphabetic){
342                 face->v_alphabetic = number;
343 g_warning("<font-face>: SP_ATTR_V_ALPHABETIC: %f", number);
344                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
345             }
346             break;
347         case SP_ATTR_V_MATHEMATICAL:
348             number = helperfns_read_number(value);
349             if (number != face->v_mathematical){
350                 face->v_mathematical = number;
351 g_warning("<font-face>: SP_ATTR_V_MATHEMATICAL: %f", number);
352                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
353             }
354             break;
355         case SP_ATTR_V_HANGING:
356             number = helperfns_read_number(value);
357             if (number != face->v_hanging){
358                 face->v_hanging = number;
359 g_warning("<font-face>: SP_ATTR_V_HANGING: %f", number);
360                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
361             }
362             break;
363         case SP_ATTR_UNDERLINE_POSITION:
364             number = helperfns_read_number(value);
365             if (number != face->underline_position){
366                 face->underline_position = number;
367 g_warning("<font-face>: SP_ATTR_UNDERLINE_POSITION: %f", number);
368                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
369             }
370             break;
371         case SP_ATTR_UNDERLINE_THICKNESS:
372             number = helperfns_read_number(value);
373             if (number != face->underline_thickness){
374                 face->underline_thickness = number;
375 g_warning("<font-face>: SP_ATTR_UNDERLINE_THICKNESS: %f", number);
376                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
377             }
378             break;
379         case SP_ATTR_STRIKETHROUGH_POSITION:
380             number = helperfns_read_number(value);
381             if (number != face->strikethrough_position){
382                 face->strikethrough_position = number;
383 g_warning("<font-face>: SP_ATTR_STRIKETHROUGH_POSITION: %f", number);
384                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
385             }
386             break;
387         case SP_ATTR_STRIKETHROUGH_THICKNESS:
388             number = helperfns_read_number(value);
389             if (number != face->strikethrough_thickness){
390                 face->strikethrough_thickness = number;
391 g_warning("<font-face>: SP_ATTR_STRIKETHROUGH_THICKNESS: %f", number);
392                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
393             }
394             break;
395         case SP_ATTR_OVERLINE_POSITION:
396             number = helperfns_read_number(value);
397             if (number != face->overline_position){
398                 face->overline_position = number;
399 g_warning("<font-face>: SP_ATTR_OVERLINE_POSITION: %f", number);
400                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
401             }
402             break;
403         case SP_ATTR_OVERLINE_THICKNESS:
404             number = helperfns_read_number(value);
405             if (number != face->overline_thickness){
406                 face->overline_thickness = number;
407 g_warning("<font-face>: SP_ATTR_OVERLINE_THICKNESS: %f", number);
408                 object->requestModified(SP_OBJECT_MODIFIED_FLAG);
409             }
410             break;
411         default:
412             if (((SPObjectClass *) (parent_class))->set) {
413                 ((SPObjectClass *) (parent_class))->set(object, key, value);
414             }
415             break;
416     }
419 /**
420  * Receives update notifications.
421  */
422 static void
423 sp_fontface_update(SPObject *object, SPCtx *ctx, guint flags)
425     if (flags & (SP_OBJECT_MODIFIED_FLAG)) {
426         sp_object_read_attr(object, "unicode-range");
427         sp_object_read_attr(object, "units-per-em");
428         sp_object_read_attr(object, "panose-1");
429         sp_object_read_attr(object, "stemv");
430         sp_object_read_attr(object, "stemh");
431         sp_object_read_attr(object, "slope");
432         sp_object_read_attr(object, "cap-height");
433         sp_object_read_attr(object, "x-height");
434         sp_object_read_attr(object, "accent-height");
435         sp_object_read_attr(object, "ascent");
436         sp_object_read_attr(object, "descent");
437         sp_object_read_attr(object, "widths");
438         sp_object_read_attr(object, "bbox");
439         sp_object_read_attr(object, "ideographic");
440         sp_object_read_attr(object, "alphabetic");
441         sp_object_read_attr(object, "mathematical");
442         sp_object_read_attr(object, "hanging");
443         sp_object_read_attr(object, "v-ideographic");
444         sp_object_read_attr(object, "v-alphabetic");
445         sp_object_read_attr(object, "v-mathematical");
446         sp_object_read_attr(object, "v-hanging");
447         sp_object_read_attr(object, "underline-position");
448         sp_object_read_attr(object, "underline-thickness");
449         sp_object_read_attr(object, "strikethrough-position");
450         sp_object_read_attr(object, "strikethrough-thickness");
451         sp_object_read_attr(object, "overline-position");
452         sp_object_read_attr(object, "overline-thickness");
453     }
455     if (((SPObjectClass *) parent_class)->update) {
456         ((SPObjectClass *) parent_class)->update(object, ctx, flags);
457     }
460 #define COPY_ATTR(rd,rs,key) (rd)->setAttribute((key), rs->attribute(key));
462 static Inkscape::XML::Node *sp_fontface_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
464     SPFontFace *face = SP_FONTFACE(object);
466     if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
467         Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_OBJECT_DOCUMENT(object));
468         repr = xml_doc->createElement("svg:font-face");
469     }
471     //TODO:
472     //sp_repr_set_svg_double(repr, "unicode-range", face->unicode_range);
473     sp_repr_set_svg_double(repr, "units-per-em", face->units_per_em);
474     //sp_repr_set_svg_double(repr, "panose-1", face->panose_1);
475     sp_repr_set_svg_double(repr, "stemv", face->stemv);
476     sp_repr_set_svg_double(repr, "stemh", face->stemh);
477     sp_repr_set_svg_double(repr, "slope", face->slope);
478     sp_repr_set_svg_double(repr, "cap-height", face->cap_height);
479     sp_repr_set_svg_double(repr, "x-height", face->x_height);
480     sp_repr_set_svg_double(repr, "accent-height", face->accent_height);
481     sp_repr_set_svg_double(repr, "ascent", face->ascent);
482     sp_repr_set_svg_double(repr, "descent", face->descent);
483     //sp_repr_set_svg_double(repr, "widths", face->widths);
484     //sp_repr_set_svg_double(repr, "bbox", face->bbox);
485     sp_repr_set_svg_double(repr, "ideographic", face->ideographic);
486     sp_repr_set_svg_double(repr, "alphabetic", face->alphabetic);
487     sp_repr_set_svg_double(repr, "mathematical", face->mathematical);
488     sp_repr_set_svg_double(repr, "hanging", face->hanging);
489     sp_repr_set_svg_double(repr, "v-ideographic", face->v_ideographic);
490     sp_repr_set_svg_double(repr, "v-alphabetic", face->v_alphabetic);
491     sp_repr_set_svg_double(repr, "v-mathematical", face->v_mathematical);
492     sp_repr_set_svg_double(repr, "v-hanging", face->v_hanging);
493     sp_repr_set_svg_double(repr, "underline-position", face->underline_position);
494     sp_repr_set_svg_double(repr, "underline-thickness", face->underline_thickness);
495     sp_repr_set_svg_double(repr, "strikethrough-position", face->strikethrough_position);
496     sp_repr_set_svg_double(repr, "strikethrough-thickness", face->strikethrough_thickness);
497     sp_repr_set_svg_double(repr, "overline-position", face->overline_position);
498     sp_repr_set_svg_double(repr, "overline-thickness", face->overline_thickness);
500     if (repr != SP_OBJECT_REPR(object)) {
501         COPY_ATTR(repr, object->repr, "unicode-range");
502         COPY_ATTR(repr, object->repr, "units-per-em");
503         COPY_ATTR(repr, object->repr, "panose-1");
504         COPY_ATTR(repr, object->repr, "stemv");
505         COPY_ATTR(repr, object->repr, "stemh");
506         COPY_ATTR(repr, object->repr, "slope");
507         COPY_ATTR(repr, object->repr, "cap-height");
508         COPY_ATTR(repr, object->repr, "x-height");
509         COPY_ATTR(repr, object->repr, "accent-height");
510         COPY_ATTR(repr, object->repr, "ascent");
511         COPY_ATTR(repr, object->repr, "descent");
512         COPY_ATTR(repr, object->repr, "widths");
513         COPY_ATTR(repr, object->repr, "bbox");
514         COPY_ATTR(repr, object->repr, "ideographic");
515         COPY_ATTR(repr, object->repr, "alphabetic");
516         COPY_ATTR(repr, object->repr, "mathematical");
517         COPY_ATTR(repr, object->repr, "hanging");
518         COPY_ATTR(repr, object->repr, "v-ideographic");
519         COPY_ATTR(repr, object->repr, "v-alphabetic");
520         COPY_ATTR(repr, object->repr, "v-mathematical");
521         COPY_ATTR(repr, object->repr, "v-hanging");
522         COPY_ATTR(repr, object->repr, "underline-position");
523         COPY_ATTR(repr, object->repr, "underline-thickness");
524         COPY_ATTR(repr, object->repr, "strikethrough-position");
525         COPY_ATTR(repr, object->repr, "strikethrough-thickness");
526         COPY_ATTR(repr, object->repr, "overline-position");
527         COPY_ATTR(repr, object->repr, "overline-thickness");
528     }
530     if (((SPObjectClass *) (parent_class))->write) {
531         ((SPObjectClass *) (parent_class))->write(object, repr, flags);
532     }
534     return repr;
536 #endif //#ifdef ENABLE_SVG_FONTS
537 /*
538   Local Variables:
539   mode:c++
540   c-file-style:"stroustrup"
541   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
542   indent-tabs-mode:nil
543   fill-column:99
544   End:
545 */
546 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :