From: JucaBlues Date: Mon, 23 Jun 2008 02:47:44 +0000 (+0000) Subject: implement kerning by glyph-name, g1 and g2 attributes X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=f45619747d788d05b19687aedde8620096f50048;p=inkscape.git implement kerning by glyph-name, g1 and g2 attributes --- diff --git a/src/display/nr-svgfonts.cpp b/src/display/nr-svgfonts.cpp index e9d251820..7b0b4938b 100644 --- a/src/display/nr-svgfonts.cpp +++ b/src/display/nr-svgfonts.cpp @@ -152,7 +152,9 @@ SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, //We use that info to allocate memory for the glyphs *glyphs = (cairo_glyph_t*) malloc(count*sizeof(cairo_glyph_t)); - char* previous_unicode = NULL; //This is used for kerning + char* previous_unicode = NULL; //This is used for kerning + gchar* previous_glyph_name = NULL; //This is used for kerning + count=0; double x=0, y=0;//These vars store the position of the glyph within the rendered string bool is_horizontal_text = true; //TODO @@ -166,15 +168,25 @@ SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, for(SPObject* node = this->font->children;previous_unicode && node;node=node->next){ //apply glyph kerning if appropriate if (SP_IS_HKERN(node) && is_horizontal_text){ - if ( (((SPHkern*)node)->u1->contains(previous_unicode[0])) && (((SPHkern*)node)->u2->contains(this->glyphs[i]->unicode[0]) ))//TODO: verify what happens when using unicode strings. + if ( (((SPHkern*)node)->u1->contains(previous_unicode[0]) + || ((SPHkern*)node)->g1->contains(previous_glyph_name)) && + (((SPHkern*)node)->u2->contains(this->glyphs[i]->unicode[0]) + || ((SPHkern*)node)->g2->contains(this->glyphs[i]->glyph_name)) + )//TODO: verify what happens when using unicode strings. x -= (((SPHkern*)node)->k / this->font->horiz_adv_x); } if (SP_IS_VKERN(node) && !is_horizontal_text){ - if ( (((SPVkern*)node)->u1->contains(previous_unicode[0])) && (((SPVkern*)node)->u2->contains(this->glyphs[i]->unicode[0]) ))//TODO: idem + if ( (((SPVkern*)node)->u1->contains(previous_unicode[0]) + || ((SPVkern*)node)->g1->contains(previous_glyph_name)) && + (((SPVkern*)node)->u2->contains(this->glyphs[i]->unicode[0]) + || ((SPVkern*)node)->g2->contains(this->glyphs[i]->glyph_name)) + )//TODO: idem y -= (((SPVkern*)node)->k / this->font->vert_adv_y); } } previous_unicode = this->glyphs[i]->unicode;//used for kerning checking + previous_glyph_name = this->glyphs[i]->glyph_name;//used for kerning checking + (*glyphs)[count].index = i; (*glyphs)[count].x = x; (*glyphs)[count++].y = y; diff --git a/src/sp-glyph-kerning.cpp b/src/sp-glyph-kerning.cpp index 1c439be19..c8138731e 100644 --- a/src/sp-glyph-kerning.cpp +++ b/src/sp-glyph-kerning.cpp @@ -20,6 +20,7 @@ #include "document.h" #include "helper-fns.h" +#include static void sp_glyph_kerning_class_init(SPGlyphKerningClass *gc); static void sp_glyph_kerning_init(SPGlyphKerning *glyph); @@ -123,6 +124,25 @@ static void sp_glyph_kerning_release(SPObject *object) } } +GlyphNames::GlyphNames(const gchar* value){ + if (value) this->names = strdup(value); +} + +GlyphNames::~GlyphNames(){ + if (this->names) g_free(this->names); +} + +bool GlyphNames::contains(gchar* name){ + if (!(this->names) || !name) return false; + std::istringstream is(this->names); + std::string str; + std::string s(name); + while (is >> str){ + if (str == s) return true; + } + return false; +} + 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. @@ -131,26 +151,26 @@ static void sp_glyph_kerning_set(SPObject *object, unsigned int key, const gchar switch (key) { case SP_ATTR_U1: - if (glyphkern->u1) g_free(glyphkern->u1); + if (glyphkern->u1) delete glyphkern->u1; glyphkern->u1 = new UnicodeRange(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); g_warning("<%s>: SP_ATTR_U1: %s", tag, value); break; case SP_ATTR_U2: - if (glyphkern->u2) g_free(glyphkern->u2); + if (glyphkern->u2) delete glyphkern->u2; glyphkern->u2 = new UnicodeRange(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); g_warning("<%s>: SP_ATTR_U2: %s", tag, value); break; case SP_ATTR_G1: - if (glyphkern->g1) g_free(glyphkern->g1); - glyphkern->g1 = g_strdup(value);//todo: + if (glyphkern->g1) delete glyphkern->g1; + glyphkern->g1 = new GlyphNames(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); g_warning("<%s>: SP_ATTR_G1: %s", tag, value); break; case SP_ATTR_G2: - if (glyphkern->g2) g_free(glyphkern->g2); - glyphkern->g2 = g_strdup(value);//todo: + if (glyphkern->g2) delete glyphkern->g2; + glyphkern->g2 = new GlyphNames(value); object->requestModified(SP_OBJECT_MODIFIED_FLAG); g_warning("<%s>: SP_ATTR_G2: %s", tag, value); break; diff --git a/src/sp-glyph-kerning.h b/src/sp-glyph-kerning.h index 9e8395d3b..180030609 100644 --- a/src/sp-glyph-kerning.h +++ b/src/sp-glyph-kerning.h @@ -29,11 +29,20 @@ #define SP_IS_VKERN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_VKERN)) #define SP_IS_VKERN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_VKERN)) +class GlyphNames{ +public: +GlyphNames(const gchar* value); +~GlyphNames(); +bool contains(gchar* name); +private: +gchar* names; +}; + struct SPGlyphKerning : public SPObject { UnicodeRange* u1; - char* g1; + GlyphNames* g1; UnicodeRange* u2; - char* g2; + GlyphNames* g2; double k; }; diff --git a/src/unicoderange.cpp b/src/unicoderange.cpp index e1cb1eee3..a4dcc8a0b 100644 --- a/src/unicoderange.cpp +++ b/src/unicoderange.cpp @@ -18,6 +18,7 @@ static unsigned int hex2int(char* s){ } UnicodeRange::UnicodeRange(const gchar* value){ + if (!value) return; gchar* val = (gchar*) value; while(val[0] != '\0'){ if (val[0]=='U' && val[1]=='+'){