Code

implement kerning by glyph-name, g1 and g2 attributes
authorJucaBlues <JucaBlues@users.sourceforge.net>
Mon, 23 Jun 2008 02:47:44 +0000 (02:47 +0000)
committerJucaBlues <JucaBlues@users.sourceforge.net>
Mon, 23 Jun 2008 02:47:44 +0000 (02:47 +0000)
src/display/nr-svgfonts.cpp
src/sp-glyph-kerning.cpp
src/sp-glyph-kerning.h
src/unicoderange.cpp

index e9d251820ffb23740530a13b2f4f25679e7d85d3..7b0b4938b7584acde2e529e6bac7eb488b3a2734 100644 (file)
@@ -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;
index 1c439be19aa365e9cb6088860f8a7c9377eece13..c8138731ebcced61ab60de7c60c051367b380e7f 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "document.h"
 #include "helper-fns.h"
+#include <string>
 
 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;
index 9e8395d3b96e6e90072a653e72907e547a361a06..1800306097445efd243e8f571398ca3737bd1b3a 100644 (file)
 #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;
 };
 
index e1cb1eee34ec82c6c48da4452704211515c7d608..a4dcc8a0b41518ae18813bdbd492f41de34e0970 100644 (file)
@@ -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]=='+'){