From 6c32bcd8f899ac2e8a7eafba446d4181c1b16d48 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Tue, 30 Mar 2010 01:07:19 -0700 Subject: [PATCH] Corrected string-to-number conversion to use locale-independent conversion and to handle missing/null values. Fixes bug #544833. --- src/sp-font-face.cpp | 106 ++++++++++++++++++++++++++++----------- src/sp-font.cpp | 43 +++++++++++----- src/sp-glyph-kerning.cpp | 36 +++++++++---- src/sp-glyph.cpp | 48 ++++++++++++------ src/sp-missing-glyph.cpp | 36 ++++++++----- 5 files changed, 190 insertions(+), 79 deletions(-) diff --git a/src/sp-font-face.cpp b/src/sp-font-face.cpp index 704985b8c..1912676d4 100644 --- a/src/sp-font-face.cpp +++ b/src/sp-font-face.cpp @@ -24,7 +24,6 @@ #include "attributes.h" #include "sp-font-face.h" #include "document.h" -#include "helper-fns.h" //TODO: apparently unused. Maybe should be removed. class ObjectContainer @@ -486,7 +485,6 @@ static void sp_fontface_release(SPObject *object) static void sp_fontface_set(SPObject *object, unsigned int key, const gchar *value) { SPFontFace *face = SP_FONTFACE(object); - double number; std::vector style; std::vector variant; std::vector weight; @@ -494,7 +492,9 @@ static void sp_fontface_set(SPObject *object, unsigned int key, const gchar *val switch (key) { case SP_PROP_FONT_FAMILY: - if (face->font_family) g_free(face->font_family); + if (face->font_family) { + g_free(face->font_family); + } face->font_family = g_strdup(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; @@ -505,7 +505,7 @@ static void sp_fontface_set(SPObject *object, unsigned int key, const gchar *val object->requestModified(SP_OBJECT_MODIFIED_FLAG); } else { for (unsigned int i=0;ifont_style[i]){ + if (style[i] != face->font_style[i]){ face->font_style = style; object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; @@ -520,7 +520,7 @@ static void sp_fontface_set(SPObject *object, unsigned int key, const gchar *val object->requestModified(SP_OBJECT_MODIFIED_FLAG); } else { for (unsigned int i=0;ifont_variant[i]){ + if (variant[i] != face->font_variant[i]){ face->font_variant = variant; object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; @@ -535,7 +535,7 @@ static void sp_fontface_set(SPObject *object, unsigned int key, const gchar *val object->requestModified(SP_OBJECT_MODIFIED_FLAG); } else { for (unsigned int i=0;ifont_weight[i]){ + if (weight[i] != face->font_weight[i]){ face->font_weight = weight; object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; @@ -550,7 +550,7 @@ static void sp_fontface_set(SPObject *object, unsigned int key, const gchar *val object->requestModified(SP_OBJECT_MODIFIED_FLAG); } else { for (unsigned int i=0;ifont_stretch[i]){ + if (stretch[i] != face->font_stretch[i]){ face->font_stretch = stretch; object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; @@ -559,166 +559,212 @@ static void sp_fontface_set(SPObject *object, unsigned int key, const gchar *val } break; case SP_ATTR_UNITS_PER_EM: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->units_per_em){ face->units_per_em = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_STEMV: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->stemv){ face->stemv = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_STEMH: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->stemh){ face->stemh = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_SLOPE: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->slope){ face->slope = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_CAP_HEIGHT: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->cap_height){ face->cap_height = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_X_HEIGHT: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->x_height){ face->x_height = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_ACCENT_HEIGHT: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->accent_height){ face->accent_height = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_ASCENT: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->ascent){ face->ascent = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_DESCENT: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->descent){ face->descent = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_IDEOGRAPHIC: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->ideographic){ face->ideographic = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_ALPHABETIC: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->alphabetic){ face->alphabetic = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_MATHEMATICAL: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->mathematical){ face->mathematical = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_HANGING: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->hanging){ face->hanging = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_V_IDEOGRAPHIC: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->v_ideographic){ face->v_ideographic = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_V_ALPHABETIC: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->v_alphabetic){ face->v_alphabetic = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_V_MATHEMATICAL: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->v_mathematical){ face->v_mathematical = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_V_HANGING: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->v_hanging){ face->v_hanging = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_UNDERLINE_POSITION: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->underline_position){ face->underline_position = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_UNDERLINE_THICKNESS: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->underline_thickness){ face->underline_thickness = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_STRIKETHROUGH_POSITION: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->strikethrough_position){ face->strikethrough_position = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_STRIKETHROUGH_THICKNESS: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->strikethrough_thickness){ face->strikethrough_thickness = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_OVERLINE_POSITION: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->overline_position){ face->overline_position = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_OVERLINE_THICKNESS: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != face->overline_thickness){ face->overline_thickness = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } default: if (((SPObjectClass *) (parent_class))->set) { ((SPObjectClass *) (parent_class))->set(object, key, value); diff --git a/src/sp-font.cpp b/src/sp-font.cpp index de272c72f..b2003cf08 100644 --- a/src/sp-font.cpp +++ b/src/sp-font.cpp @@ -21,7 +21,6 @@ #include "sp-glyph.h" #include "sp-missing-glyph.h" #include "document.h" -#include "helper-fns.h" #include "display/nr-svgfonts.h" @@ -79,15 +78,21 @@ static void sp_font_class_init(SPFontClass *fc) sp_object_class->update = sp_font_update; } +//I think we should have extra stuff here and in the set method in order to set default value as specified at http://www.w3.org/TR/SVG/fonts.html + +// TODO determine better values and/or make these dynamic: +double FNT_DEFAULT_ADV = 90; // TODO determine proper default +double FNT_DEFAULT_ASCENT = 90; // TODO determine proper default +double FNT_UNITS_PER_EM = 90; // TODO determine proper default + static void sp_font_init(SPFont *font) { font->horiz_origin_x = 0; font->horiz_origin_y = 0; - font->horiz_adv_x = 0; -//I think we should have extra stuff here and in the set method in order to set default value as specified at http://www.w3.org/TR/SVG/fonts.html - font->vert_origin_x = 0; - font->vert_origin_y = 0; - font->vert_adv_y = 0; + font->horiz_adv_x = FNT_DEFAULT_ADV; + font->vert_origin_x = FNT_DEFAULT_ADV / 2.0; + font->vert_origin_y = FNT_DEFAULT_ASCENT; + font->vert_adv_y = FNT_UNITS_PER_EM; } static void sp_font_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) @@ -155,51 +160,63 @@ static void sp_font_release(SPObject *object) static void sp_font_set(SPObject *object, unsigned int key, const gchar *value) { SPFont *font = SP_FONT(object); - double number; + // TODO these are floating point, so some epsilon comparison would be good switch (key) { case SP_ATTR_HORIZ_ORIGIN_X: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != font->horiz_origin_x){ font->horiz_origin_x = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_HORIZ_ORIGIN_Y: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != font->horiz_origin_y){ font->horiz_origin_y = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_HORIZ_ADV_X: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : FNT_DEFAULT_ADV; if (number != font->horiz_adv_x){ font->horiz_adv_x = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_VERT_ORIGIN_X: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : FNT_DEFAULT_ADV / 2.0; if (number != font->vert_origin_x){ font->vert_origin_x = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_VERT_ORIGIN_Y: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : FNT_DEFAULT_ASCENT; if (number != font->vert_origin_y){ font->vert_origin_y = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_VERT_ADV_Y: - number = helperfns_read_number(value); + { + double number = value ? g_ascii_strtod(value, 0) : FNT_UNITS_PER_EM; if (number != font->vert_adv_y){ font->vert_adv_y = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } default: if (((SPObjectClass *) (parent_class))->set) { ((SPObjectClass *) (parent_class))->set(object, key, value); diff --git a/src/sp-glyph-kerning.cpp b/src/sp-glyph-kerning.cpp index 872efc853..d62fbb2c2 100644 --- a/src/sp-glyph-kerning.cpp +++ b/src/sp-glyph-kerning.cpp @@ -22,7 +22,6 @@ #include "sp-glyph-kerning.h" #include "document.h" -#include "helper-fns.h" #include static void sp_glyph_kerning_class_init(SPGlyphKerningClass *gc); @@ -149,41 +148,60 @@ bool GlyphNames::contains(const char* name){ static void sp_glyph_kerning_set(SPObject *object, unsigned int key, const gchar *value) { SPGlyphKerning * glyphkern = (SPGlyphKerning*) object; //even if it is a VKern this will work. I did it this way just to avoind warnings. - double number; switch (key) { case SP_ATTR_U1: - if (glyphkern->u1) delete glyphkern->u1; + { + if (glyphkern->u1) { + delete glyphkern->u1; + } glyphkern->u1 = new UnicodeRange(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + } case SP_ATTR_U2: - if (glyphkern->u2) delete glyphkern->u2; + { + if (glyphkern->u2) { + delete glyphkern->u2; + } glyphkern->u2 = new UnicodeRange(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + } case SP_ATTR_G1: - if (glyphkern->g1) delete glyphkern->g1; + { + if (glyphkern->g1) { + delete glyphkern->g1; + } glyphkern->g1 = new GlyphNames(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + } case SP_ATTR_G2: - if (glyphkern->g2) delete glyphkern->g2; + { + if (glyphkern->g2) { + delete glyphkern->g2; + } glyphkern->g2 = new GlyphNames(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; - case SP_ATTR_K: - number = helperfns_read_number(value); + } + case SP_ATTR_K: + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != glyphkern->k){ glyphkern->k = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - default: + } + default: + { if (((SPObjectClass *) (parent_class))->set) { ((SPObjectClass *) (parent_class))->set(object, key, value); } break; + } } } diff --git a/src/sp-glyph.cpp b/src/sp-glyph.cpp index 37e266da0..0b3b85d3f 100644 --- a/src/sp-glyph.cpp +++ b/src/sp-glyph.cpp @@ -20,7 +20,6 @@ #include "attributes.h" #include "sp-glyph.h" #include "document.h" -#include "helper-fns.h" static void sp_glyph_class_init(SPGlyphClass *gc); static void sp_glyph_init(SPGlyph *glyph); @@ -146,78 +145,97 @@ static glyphOrientation sp_glyph_read_orientation(gchar const *value){ static void sp_glyph_set(SPObject *object, unsigned int key, const gchar *value) { SPGlyph *glyph = SP_GLYPH(object); - double number; - glyphOrientation orient; - glyphArabicForm form; switch (key) { case SP_ATTR_UNICODE: + { glyph->unicode.clear(); if (value) glyph->unicode.append(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + } case SP_ATTR_GLYPH_NAME: + { glyph->glyph_name.clear(); if (value) glyph->glyph_name.append(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + } case SP_ATTR_D: + { if (glyph->d) g_free(glyph->d); glyph->d = g_strdup(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + } case SP_ATTR_ORIENTATION: - orient = sp_glyph_read_orientation(value); + { + glyphOrientation orient = sp_glyph_read_orientation(value); if (glyph->orientation != orient){ glyph->orientation = orient; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_ARABIC_FORM: - form = sp_glyph_read_arabic_form(value); + { + glyphArabicForm form = sp_glyph_read_arabic_form(value); if (glyph->arabic_form != form){ glyph->arabic_form = form; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; + } case SP_ATTR_LANG: + { if (glyph->lang) g_free(glyph->lang); glyph->lang = g_strdup(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; - case SP_ATTR_HORIZ_ADV_X: - number = helperfns_read_number(value); + } + case SP_ATTR_HORIZ_ADV_X: + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != glyph->horiz_adv_x){ glyph->horiz_adv_x = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_VERT_ORIGIN_X: - number = helperfns_read_number(value); + } + case SP_ATTR_VERT_ORIGIN_X: + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != glyph->vert_origin_x){ glyph->vert_origin_x = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_VERT_ORIGIN_Y: - number = helperfns_read_number(value); + } + case SP_ATTR_VERT_ORIGIN_Y: + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != glyph->vert_origin_y){ glyph->vert_origin_y = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_VERT_ADV_Y: - number = helperfns_read_number(value); + } + case SP_ATTR_VERT_ADV_Y: + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != glyph->vert_adv_y){ glyph->vert_adv_y = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - default: + } + default: + { if (((SPObjectClass *) (parent_class))->set) { ((SPObjectClass *) (parent_class))->set(object, key, value); } break; + } } } diff --git a/src/sp-missing-glyph.cpp b/src/sp-missing-glyph.cpp index d25a5f812..7d5c42763 100644 --- a/src/sp-missing-glyph.cpp +++ b/src/sp-missing-glyph.cpp @@ -20,7 +20,6 @@ #include "attributes.h" #include "sp-missing-glyph.h" #include "document.h" -#include "helper-fns.h" static void sp_missing_glyph_class_init(SPMissingGlyphClass *gc); static void sp_missing_glyph_init(SPMissingGlyph *glyph); @@ -102,47 +101,60 @@ static void sp_missing_glyph_release(SPObject *object) static void sp_missing_glyph_set(SPObject *object, unsigned int key, const gchar *value) { SPMissingGlyph *glyph = SP_MISSING_GLYPH(object); - double number; switch (key) { case SP_ATTR_D: - if (glyph->d) g_free(glyph->d); + { + if (glyph->d) { + g_free(glyph->d); + } glyph->d = g_strdup(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; - case SP_ATTR_HORIZ_ADV_X: - number = helperfns_read_number(value); + } + case SP_ATTR_HORIZ_ADV_X: + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != glyph->horiz_adv_x){ glyph->horiz_adv_x = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_VERT_ORIGIN_X: - number = helperfns_read_number(value); + } + case SP_ATTR_VERT_ORIGIN_X: + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != glyph->vert_origin_x){ glyph->vert_origin_x = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_VERT_ORIGIN_Y: - number = helperfns_read_number(value); + } + case SP_ATTR_VERT_ORIGIN_Y: + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != glyph->vert_origin_y){ glyph->vert_origin_y = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - case SP_ATTR_VERT_ADV_Y: - number = helperfns_read_number(value); + } + case SP_ATTR_VERT_ADV_Y: + { + double number = value ? g_ascii_strtod(value, 0) : 0; if (number != glyph->vert_adv_y){ glyph->vert_adv_y = number; object->requestModified(SP_OBJECT_MODIFIED_FLAG); } break; - default: + } + default: + { if (((SPObjectClass *) (parent_class))->set) { ((SPObjectClass *) (parent_class))->set(object, key, value); } break; + } } } -- 2.30.2