X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fsp-font-face.cpp;h=1ec6f4601b90e3a389e7c09c215af002eea7aa6d;hb=b50ad86b7ef2cb76fcaa91c27a579837be8f0fd2;hp=31886b718522d0252ed0f9e6ef08e3c8d46ca567;hpb=43d06c7da14a174c6b2b41f9849b0cf098de4770;p=inkscape.git diff --git a/src/sp-font-face.cpp b/src/sp-font-face.cpp index 31886b718..1ec6f4601 100644 --- a/src/sp-font-face.cpp +++ b/src/sp-font-face.cpp @@ -1,4 +1,7 @@ -#include "config.h" +#ifdef HAVE_CONFIG_H +# include +#endif + #ifdef ENABLE_SVG_FONTS #define __SP_FONTFACE_C__ @@ -6,7 +9,7 @@ * SVG element implementation * * Section 20.8.3 of the W3C SVG 1.1 spec - * available at: + * available at: * http://www.w3.org/TR/SVG/fonts.html#FontFaceElement * * Author: @@ -23,6 +26,7 @@ #include "document.h" #include "helper-fns.h" +//TODO: apparently unused. Maybe should be removed. class ObjectContainer { @@ -54,6 +58,240 @@ private: bool isset; }; +static std::vector sp_read_fontFaceStyleType(gchar const *value){ + std::vector v; + + if (!value){ + v.push_back(SP_FONTFACE_STYLE_ALL); + return v; + } + + if (strncmp(value, "all", 3) == 0){ + value += 3; + while(value[0]==',' || value[0]==' ') + value++; + v.push_back(SP_FONTFACE_STYLE_ALL); + return v; + } + + while(value[0]!='\0'){ + switch(value[0]){ + case 'n': + if (strncmp(value, "normal", 6) == 0){ + v.push_back(SP_FONTFACE_STYLE_NORMAL); + value += 6; + } + break; + case 'i': + if (strncmp(value, "italic", 6) == 0){ + v.push_back(SP_FONTFACE_STYLE_ITALIC); + value += 6; + } + break; + case 'o': + if (strncmp(value, "oblique", 7) == 0){ + v.push_back(SP_FONTFACE_STYLE_OBLIQUE); + value += 7; + } + break; + } + while(value[0]==',' || value[0]==' ') + value++; + } + return v; +} + +static std::vector sp_read_fontFaceVariantType(gchar const *value){ + std::vector v; + + if (!value){ + v.push_back(SP_FONTFACE_VARIANT_NORMAL); + return v; + } + + while(value[0]!='\0'){ + switch(value[0]){ + case 'n': + if (strncmp(value, "normal", 6) == 0){ + v.push_back(SP_FONTFACE_VARIANT_NORMAL); + value += 6; + } + break; + case 's': + if (strncmp(value, "small-caps", 10) == 0){ + v.push_back(SP_FONTFACE_VARIANT_SMALL_CAPS); + value += 10; + } + break; + } + while(value[0]==',' || value[0]==' ') + value++; + } + return v; +} + +static std::vector sp_read_fontFaceWeightType(gchar const *value){ + std::vector v; + + if (!value){ + v.push_back(SP_FONTFACE_WEIGHT_ALL); + return v; + } + + if (strncmp(value, "all", 3) == 0){ + value += 3; + while(value[0]==',' || value[0]==' ') + value++; + v.push_back(SP_FONTFACE_WEIGHT_ALL); + return v; + } + + while(value[0]!='\0'){ + switch(value[0]){ + case 'n': + if (strncmp(value, "normal", 6) == 0){ + v.push_back(SP_FONTFACE_WEIGHT_NORMAL); + value += 6; + } + break; + case 'b': + if (strncmp(value, "bold", 4) == 0){ + v.push_back(SP_FONTFACE_WEIGHT_BOLD); + value += 4; + } + break; + case '1': + if (strncmp(value, "100", 3) == 0){ + v.push_back(SP_FONTFACE_WEIGHT_100); + value += 3; + } + break; + case '2': + if (strncmp(value, "200", 3) == 0){ + v.push_back(SP_FONTFACE_WEIGHT_200); + value += 3; + } + break; + case '3': + if (strncmp(value, "300", 3) == 0){ + v.push_back(SP_FONTFACE_WEIGHT_300); + value += 3; + } + break; + case '4': + if (strncmp(value, "400", 3) == 0){ + v.push_back(SP_FONTFACE_WEIGHT_400); + value += 3; + } + break; + case '5': + if (strncmp(value, "500", 3) == 0){ + v.push_back(SP_FONTFACE_WEIGHT_500); + value += 3; + } + break; + case '6': + if (strncmp(value, "600", 3) == 0){ + v.push_back(SP_FONTFACE_WEIGHT_600); + value += 3; + } + break; + case '7': + if (strncmp(value, "700", 3) == 0){ + v.push_back(SP_FONTFACE_WEIGHT_700); + value += 3; + } + break; + case '8': + if (strncmp(value, "800", 3) == 0){ + v.push_back(SP_FONTFACE_WEIGHT_800); + value += 3; + } + break; + case '9': + if (strncmp(value, "900", 3) == 0){ + v.push_back(SP_FONTFACE_WEIGHT_900); + value += 3; + } + break; + } + while(value[0]==',' || value[0]==' ') + value++; + } + return v; +} + +static std::vector sp_read_fontFaceStretchType(gchar const *value){ + std::vector v; + + if (!value){ + v.push_back(SP_FONTFACE_STRETCH_NORMAL); + return v; + } + + if (strncmp(value, "all", 3) == 0){ + value += 3; + while(value[0]==',' || value[0]==' ') + value++; + v.push_back(SP_FONTFACE_STRETCH_ALL); + return v; + } + + while(value[0]!='\0'){ + switch(value[0]){ + case 'n': + if (strncmp(value, "normal", 6) == 0){ + v.push_back(SP_FONTFACE_STRETCH_NORMAL); + value += 6; + } + break; + case 'u': + if (strncmp(value, "ultra-condensed", 15) == 0){ + v.push_back(SP_FONTFACE_STRETCH_ULTRA_CONDENSED); + value += 15; + } + if (strncmp(value, "ultra-expanded", 14) == 0){ + v.push_back(SP_FONTFACE_STRETCH_ULTRA_EXPANDED); + value += 14; + } + break; + case 'e': + if (strncmp(value, "expanded", 8) == 0){ + v.push_back(SP_FONTFACE_STRETCH_EXPANDED); + value += 8; + } + if (strncmp(value, "extra-condensed", 15) == 0){ + v.push_back(SP_FONTFACE_STRETCH_EXTRA_CONDENSED); + value += 15; + } + if (strncmp(value, "extra-expanded", 14) == 0){ + v.push_back(SP_FONTFACE_STRETCH_EXTRA_EXPANDED); + value += 14; + } + break; + case 'c': + if (strncmp(value, "condensed", 9) == 0){ + v.push_back(SP_FONTFACE_STRETCH_CONDENSED); + value += 9; + } + break; + case 's': + if (strncmp(value, "semi-condensed", 14) == 0){ + v.push_back(SP_FONTFACE_STRETCH_SEMI_CONDENSED); + value += 14; + } + if (strncmp(value, "semi-expanded", 13) == 0){ + v.push_back(SP_FONTFACE_STRETCH_SEMI_EXPANDED); + value += 13; + } + break; + } + while(value[0]==',' || value[0]==' ') + value++; + } + return v; +} + static void sp_fontface_class_init(SPFontFaceClass *fc); static void sp_fontface_init(SPFontFace *font); @@ -75,15 +313,15 @@ GType sp_fontface_get_type(void) if (!type) { GTypeInfo info = { sizeof(SPFontFaceClass), - NULL, /* base_init */ - NULL, /* base_finalize */ + NULL, /* base_init */ + NULL, /* base_finalize */ (GClassInitFunc) sp_fontface_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ + NULL, /* class_finalize */ + NULL, /* class_data */ sizeof(SPFontFace), - 16, /* n_preallocs */ + 16, /* n_preallocs */ (GInstanceInitFunc) sp_fontface_init, - NULL, /* value_table */ + NULL, /* value_table */ }; type = g_type_register_static(SP_TYPE_OBJECT, "SPFontFace", &info, (GTypeFlags) 0); } @@ -108,7 +346,28 @@ static void sp_fontface_class_init(SPFontFaceClass *fc) static void sp_fontface_init(SPFontFace *face) { -/* + std::vector style; + style.push_back(SP_FONTFACE_STYLE_ALL); + face->font_style = style; + + std::vector variant; + variant.push_back(SP_FONTFACE_VARIANT_NORMAL); + face->font_variant = variant; + + std::vector weight; + weight.push_back(SP_FONTFACE_WEIGHT_ALL); + face->font_weight = weight; + + std::vector stretch; + stretch.push_back(SP_FONTFACE_STRETCH_NORMAL); + face->font_stretch = stretch; + face->font_family = NULL; + /* + //face->font_style = ; + //face->font_variant = ; + //face->font_weight = ; + //face->font_stretch = ; + face->font_size = NULL; //face->unicode_range = ; face->units_per_em = 1000; //face->panose_1 = ; @@ -145,6 +404,12 @@ static void sp_fontface_build(SPObject *object, SPDocument *document, Inkscape:: ((SPObjectClass *) (parent_class))->build(object, document, repr); } + sp_object_read_attr(object, "font-family"); + sp_object_read_attr(object, "font-style"); + sp_object_read_attr(object, "font-variant"); + sp_object_read_attr(object, "font-weight"); + sp_object_read_attr(object, "font-stretch"); + sp_object_read_attr(object, "font-size"); sp_object_read_attr(object, "unicode-range"); sp_object_read_attr(object, "units-per-em"); sp_object_read_attr(object, "panose-1"); @@ -174,7 +439,7 @@ static void sp_fontface_build(SPObject *object, SPDocument *document, Inkscape:: sp_object_read_attr(object, "overline-thickness"); } -static void sp_fontface_children_modified(SPFontFace *sp_fontface) +static void sp_fontface_children_modified(SPFontFace */*sp_fontface*/) { } @@ -222,193 +487,239 @@ static void sp_fontface_set(SPObject *object, unsigned int key, const gchar *val { SPFontFace *face = SP_FONTFACE(object); double number; + std::vector style; + std::vector variant; + std::vector weight; + std::vector stretch; switch (key) { - case SP_ATTR_UNITS_PER_EM: + case SP_PROP_FONT_FAMILY: + if (face->font_family) g_free(face->font_family); + face->font_family = g_strdup(value); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_PROP_FONT_STYLE: + style = sp_read_fontFaceStyleType(value); + if (face->font_style.size() != style.size()){ + face->font_style = style; + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + } else { + for (unsigned int i=0;ifont_style[i]){ + face->font_style = style; + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + } + } + } + break; + case SP_PROP_FONT_VARIANT: + variant = sp_read_fontFaceVariantType(value); + if (face->font_variant.size() != variant.size()){ + face->font_variant = variant; + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + } else { + for (unsigned int i=0;ifont_variant[i]){ + face->font_variant = variant; + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + } + } + } + break; + case SP_PROP_FONT_WEIGHT: + weight = sp_read_fontFaceWeightType(value); + if (face->font_weight.size() != weight.size()){ + face->font_weight = weight; + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + } else { + for (unsigned int i=0;ifont_weight[i]){ + face->font_weight = weight; + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + } + } + } + break; + case SP_PROP_FONT_STRETCH: + stretch = sp_read_fontFaceStretchType(value); + if (face->font_stretch.size() != stretch.size()){ + face->font_stretch = stretch; + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + } else { + for (unsigned int i=0;ifont_stretch[i]){ + face->font_stretch = stretch; + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + } + } + } + break; + case SP_ATTR_UNITS_PER_EM: number = helperfns_read_number(value); if (number != face->units_per_em){ face->units_per_em = number; -g_warning(": SP_ATTR_UNITS_PER_EM: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_STEMV: + case SP_ATTR_STEMV: number = helperfns_read_number(value); if (number != face->stemv){ face->stemv = number; -g_warning(": SP_ATTR_STEMV: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_STEMH: + case SP_ATTR_STEMH: number = helperfns_read_number(value); if (number != face->stemh){ face->stemh = number; -g_warning(": SP_ATTR_STEMH: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_SLOPE: + case SP_ATTR_SLOPE: number = helperfns_read_number(value); if (number != face->slope){ face->slope = number; -g_warning(": SP_ATTR_SLOPE: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_CAP_HEIGHT: + case SP_ATTR_CAP_HEIGHT: number = helperfns_read_number(value); if (number != face->cap_height){ face->cap_height = number; -g_warning(": SP_ATTR_CAP_HEIGHT: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_X_HEIGHT: + case SP_ATTR_X_HEIGHT: number = helperfns_read_number(value); if (number != face->x_height){ face->x_height = number; -g_warning(": SP_ATTR_X_HEIGHT: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_ACCENT_HEIGHT: + case SP_ATTR_ACCENT_HEIGHT: number = helperfns_read_number(value); if (number != face->accent_height){ face->accent_height = number; -g_warning(": SP_ATTR_ACCENT_HEIGHT: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_ASCENT: + case SP_ATTR_ASCENT: number = helperfns_read_number(value); if (number != face->ascent){ face->ascent = number; -g_warning(": SP_ATTR_ASCENT: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_DESCENT: + case SP_ATTR_DESCENT: number = helperfns_read_number(value); if (number != face->descent){ face->descent = number; -g_warning(": SP_ATTR_DESCENT: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_IDEOGRAPHIC: + case SP_ATTR_IDEOGRAPHIC: number = helperfns_read_number(value); if (number != face->ideographic){ face->ideographic = number; -g_warning(": SP_ATTR_IDEOGRAPHIC: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_ALPHABETIC: + case SP_ATTR_ALPHABETIC: number = helperfns_read_number(value); if (number != face->alphabetic){ face->alphabetic = number; -g_warning(": SP_ATTR_ALPHABETIC: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_MATHEMATICAL: + case SP_ATTR_MATHEMATICAL: number = helperfns_read_number(value); if (number != face->mathematical){ face->mathematical = number; -g_warning(": SP_ATTR_MATHEMATICAL: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_HANGING: + case SP_ATTR_HANGING: number = helperfns_read_number(value); if (number != face->hanging){ face->hanging = number; -g_warning(": SP_ATTR_HANGING: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_V_IDEOGRAPHIC: + case SP_ATTR_V_IDEOGRAPHIC: number = helperfns_read_number(value); if (number != face->v_ideographic){ face->v_ideographic = number; -g_warning(": SP_ATTR_V_IDEOGRAPHIC: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_V_ALPHABETIC: + case SP_ATTR_V_ALPHABETIC: number = helperfns_read_number(value); if (number != face->v_alphabetic){ face->v_alphabetic = number; -g_warning(": SP_ATTR_V_ALPHABETIC: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_V_MATHEMATICAL: + case SP_ATTR_V_MATHEMATICAL: number = helperfns_read_number(value); if (number != face->v_mathematical){ face->v_mathematical = number; -g_warning(": SP_ATTR_V_MATHEMATICAL: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_V_HANGING: + case SP_ATTR_V_HANGING: number = helperfns_read_number(value); if (number != face->v_hanging){ face->v_hanging = number; -g_warning(": SP_ATTR_V_HANGING: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_UNDERLINE_POSITION: + case SP_ATTR_UNDERLINE_POSITION: number = helperfns_read_number(value); if (number != face->underline_position){ face->underline_position = number; -g_warning(": SP_ATTR_UNDERLINE_POSITION: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_UNDERLINE_THICKNESS: + case SP_ATTR_UNDERLINE_THICKNESS: number = helperfns_read_number(value); if (number != face->underline_thickness){ face->underline_thickness = number; -g_warning(": SP_ATTR_UNDERLINE_THICKNESS: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_STRIKETHROUGH_POSITION: + case SP_ATTR_STRIKETHROUGH_POSITION: number = helperfns_read_number(value); if (number != face->strikethrough_position){ face->strikethrough_position = number; -g_warning(": SP_ATTR_STRIKETHROUGH_POSITION: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_STRIKETHROUGH_THICKNESS: + case SP_ATTR_STRIKETHROUGH_THICKNESS: number = helperfns_read_number(value); if (number != face->strikethrough_thickness){ face->strikethrough_thickness = number; -g_warning(": SP_ATTR_STRIKETHROUGH_THICKNESS: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_OVERLINE_POSITION: + case SP_ATTR_OVERLINE_POSITION: number = helperfns_read_number(value); if (number != face->overline_position){ face->overline_position = number; -g_warning(": SP_ATTR_OVERLINE_POSITION: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_OVERLINE_THICKNESS: + case SP_ATTR_OVERLINE_THICKNESS: number = helperfns_read_number(value); if (number != face->overline_thickness){ face->overline_thickness = number; -g_warning(": SP_ATTR_OVERLINE_THICKNESS: %f", number); object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - default: + default: if (((SPObjectClass *) (parent_class))->set) { ((SPObjectClass *) (parent_class))->set(object, key, value); } @@ -423,6 +734,12 @@ static void sp_fontface_update(SPObject *object, SPCtx *ctx, guint flags) { if (flags & (SP_OBJECT_MODIFIED_FLAG)) { + sp_object_read_attr(object, "font-family"); + sp_object_read_attr(object, "font-style"); + sp_object_read_attr(object, "font-variant"); + sp_object_read_attr(object, "font-weight"); + sp_object_read_attr(object, "font-stretch"); + sp_object_read_attr(object, "font-size"); sp_object_read_attr(object, "unicode-range"); sp_object_read_attr(object, "units-per-em"); sp_object_read_attr(object, "panose-1"); @@ -468,6 +785,12 @@ static Inkscape::XML::Node *sp_fontface_write(SPObject *object, Inkscape::XML::D } //TODO: + //sp_repr_set_svg_double(repr, "font-family", face->font_family); + //sp_repr_set_svg_double(repr, "font-style", face->font_style); + //sp_repr_set_svg_double(repr, "font-variant", face->font_variant); + //sp_repr_set_svg_double(repr, "font-weight", face->font_weight); + //sp_repr_set_svg_double(repr, "font-stretch", face->font_stretch); + //sp_repr_set_svg_double(repr, "font-size", face->font_size); //sp_repr_set_svg_double(repr, "unicode-range", face->unicode_range); sp_repr_set_svg_double(repr, "units-per-em", face->units_per_em); //sp_repr_set_svg_double(repr, "panose-1", face->panose_1); @@ -497,6 +820,12 @@ static Inkscape::XML::Node *sp_fontface_write(SPObject *object, Inkscape::XML::D sp_repr_set_svg_double(repr, "overline-thickness", face->overline_thickness); if (repr != SP_OBJECT_REPR(object)) { + COPY_ATTR(repr, object->repr, "font-family"); + COPY_ATTR(repr, object->repr, "font-style"); + COPY_ATTR(repr, object->repr, "font-variant"); + COPY_ATTR(repr, object->repr, "font-weight"); + COPY_ATTR(repr, object->repr, "font-stretch"); + COPY_ATTR(repr, object->repr, "font-size"); COPY_ATTR(repr, object->repr, "unicode-range"); COPY_ATTR(repr, object->repr, "units-per-em"); COPY_ATTR(repr, object->repr, "panose-1");