Code

Another week coding offline...
authorJucaBlues <JucaBlues@users.sourceforge.net>
Mon, 5 Jan 2009 23:49:00 +0000 (23:49 +0000)
committerJucaBlues <JucaBlues@users.sourceforge.net>
Mon, 5 Jan 2009 23:49:00 +0000 (23:49 +0000)
* Adding Set Width (horiz-adv-x attribute) slider to the SVGFonts dialog.
* Fixed the order of some language options at the i18n preferences page.
* Fixed parsing and handling of u1 and u2 (CSS2 unicode range) attributes for kerning pair nodes
* Fixed a warning in helper-fns.h
* commented out unused variable in sp-font.cpp
* refactoring of nr-svgfonts.cpp
* using 1000 instead of horiz-adv-x when scaling the glyph coordinates. Probably should use a value based on units-per-em in the future. Or maybe accent-height,
cap-height, x-height... I don't know. I should study this subject a bit more first.

share/examples/svgfont.svg
src/display/nr-svgfonts.cpp
src/helper-fns.h
src/sp-font.cpp
src/ui/dialog/inkscape-preferences.cpp
src/ui/dialog/svg-fonts-dialog.cpp
src/unicoderange.cpp

index edf96f19a3122f4703178d0e215a3921a1a4fe1a..c5ff179fafbc48c265c157e23bff50205a88a1d0 100644 (file)
        <font-face font-family="Super Sans" font-style="oblique" font-stretch="ultra-expanded" />
 
        <!-- This font has 2 glyphs (one for "@" and one for "!"): -->
-       <glyph unicode="!" d="M0,0h500v500h-500z"> <!--  Currently we only render the path description declared in the d attribute  -->
+       <glyph unicode="!" glyph-name="Exclamation" d="M0,0h500v500h-500z"> <!--  Currently we only render the path description declared in the d attribute  -->
           <circle r='500' cx='500' cy='500' style="fill:none;stroke:green;"/> <!-- So... this part of the glyph wont render yet. -->
        </glyph>
 
-       <glyph unicode="@" d="M500,500h500v500h-500z">
+       <glyph unicode="@" glyph-name="At Sign" d="M500,500h500v500h-500z">
           <circle r='250' cx='500' cy='500' style="fill:blue;"/> <!-- This circle wont render yet -->
        </glyph>
 
        <!-- and also a missing-glyph, which is used for every other character on the string that do not have a specific glyph -->
-       <missing-glyph d="M0,0h1000v1000h-1000z"></missing-glyph>
+       <missing-glyph glyph-name="Missing..." d="M0,0h1000v1000h-1000z"></missing-glyph>
 
        <!-- And every pair of "!" followed by "@" has a kerning of 500 units -->
        <hkern u1="!" u2="@" k="500" />
 
     <font id="AnotherSVGFont" horiz-adv-x="1100">
        <font-face font-family="Super Sans2" font-style="oblique" font-stretch="ultra-expanded" />
-       <glyph unicode="!" d="M0,0h500v500h-500v-300h100v200h300v-300h-400z" />
-       <glyph unicode="@!" d="M0,0h200L1000,800v200h-200L0,200z" />
-       <glyph unicode="@" d="M500,500h250v250h-250z" />
-       <missing-glyph d="M0,0h1000v1000z"></missing-glyph>
+       <glyph unicode="!" glyph-name="exclamation" d="M0,0h500v500h-500v-300h100v200h300v-300h-400z" />
+       <glyph unicode="@!" glyph-name="A ligature glyph" d="M0,0h200L1000,800v200h-200L0,200z" />
+       <glyph unicode="@" glyph-name="At sign" d="M500,500h250v250h-250z" />
+       <missing-glyph glyph-name="The Missing Glyph" d="M0,0h1000v1000z"></missing-glyph>
        <hkern u1="!" u2="@" k="1000" />
     </font>
 
index 633f4cddd3ec197fe0c092291d15bc2fef4ebaa2..86da5b7a1daa2a5a0d0728cf737485fd0922bfef 100644 (file)
@@ -104,6 +104,17 @@ unsigned int size_of_substring(const char* substring, gchar* str){
                return 0;
 }
 
+//TODO: in these macros, verify what happens when using unicode strings.
+#define Match_VKerning_Rule (((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.c_str()))
+
+#define Match_HKerning_Rule (((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.c_str()))
+
 cairo_status_t
 SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
                                const char      *utf8,
@@ -126,22 +137,22 @@ SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
 
     bool missing;
     //First we findout whats the number of glyphs needed.
-    while(g_utf8_get_char(_utf8) != 0){
-       missing = true;
-       for (i=0; i < (unsigned long) this->glyphs.size(); i++){
-            if ( (len = size_of_substring(this->glyphs[i]->unicode.c_str(), _utf8)) ){
-               //TODO: store this cluster
-               _utf8+=len;
-               count++;
-               missing=false;
-               break;
-           }
-       }
-       if (missing){
-               //TODO: store this cluster
-               _utf8++;
-               count++;
-       }
+    while(g_utf8_get_char(_utf8)){
+               missing = true;
+               for (i=0; i < (unsigned long) this->glyphs.size(); i++){
+                       if ( (len = size_of_substring(this->glyphs[i]->unicode.c_str(), _utf8)) ){
+                               //TODO: store this cluster
+                               _utf8+=len;
+                               count++;
+                               missing=false;
+                               break;
+                       }
+               }
+               if (missing){
+                       //TODO: store this cluster
+                       _utf8++;
+                       count++;
+               }
     }
 
 
@@ -155,54 +166,48 @@ SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
     double x=0, y=0;//These vars store the position of the glyph within the rendered string
     bool is_horizontal_text = true; //TODO
     _utf8 = (char*) utf8;
-    while(g_utf8_get_char(_utf8) != 0){
-       len = 0;
+
+    while(g_utf8_get_char(_utf8)){
+               len = 0;
         for (i=0; i < (unsigned long) this->glyphs.size(); i++){
-            if ( (len = size_of_substring(this->glyphs[i]->unicode.c_str(), _utf8)) ){
-               //check whether is there a glyph declared on the SVG document
-               // that matches with the text string in its current position
-               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)->g1->contains(previous_glyph_name)) &&
-                               (((SPHkern*)node)->u2->contains(this->glyphs[i]->unicode[0])
-                                || ((SPHkern*)node)->g2->contains(this->glyphs[i]->glyph_name.c_str()))
-                       )//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)->g1->contains(previous_glyph_name)) &&
-                               (((SPVkern*)node)->u2->contains(this->glyphs[i]->unicode[0])
-                                || ((SPVkern*)node)->g2->contains(this->glyphs[i]->glyph_name.c_str()))
-                       )//TODO: idem
-                               y -= (((SPVkern*)node)->k / this->font->vert_adv_y);
-                   }
-               }
-               previous_unicode = (char*) this->glyphs[i]->unicode.c_str();//used for kerning checking
-               previous_glyph_name = (char*) this->glyphs[i]->glyph_name.c_str();//used for kerning checking
-                (*glyphs)[count].index = i;
-                (*glyphs)[count].x = x;
-                (*glyphs)[count++].y = y;
-               //advance glyph coordinates:
-               if (is_horizontal_text) x++;
-               else y++;
-                _utf8+=len; //advance 'len' bytes in our string pointer
-               //continue;
-               goto dirty;
+                       //check whether is there a glyph declared on the SVG document
+                       // that matches with the text string in its current position
+                       if ( (len = size_of_substring(this->glyphs[i]->unicode.c_str(), _utf8)) ){
+                               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 && Match_HKerning_Rule ){
+                                               x -= (((SPHkern*)node)->k / 1000.0);//TODO: use here the height of the font
+                                       }
+                                       if (SP_IS_VKERN(node) && !is_horizontal_text && Match_VKerning_Rule ){
+                                               y -= (((SPVkern*)node)->k / 1000.0);//TODO: use here the "height" of the font
+                                       }
+                               }
+                               previous_unicode = (char*) this->glyphs[i]->unicode.c_str();//used for kerning checking
+                               previous_glyph_name = (char*) this->glyphs[i]->glyph_name.c_str();//used for kerning checking
+                               (*glyphs)[count].index = i;
+                               (*glyphs)[count].x = x;
+                               (*glyphs)[count++].y = y;
+
+                               //advance glyph coordinates:
+                               if (is_horizontal_text) x+=(this->font->horiz_adv_x/1000.0);//TODO: use here the height of the font
+                               else y+=(this->font->vert_adv_y/1000.0);//TODO: use here the "height" of the font
+                               _utf8+=len; //advance 'len' bytes in our string pointer
+                               //continue;
+                               goto raptorz;
             }
         }
-dirty:
-       if (!len){
-               (*glyphs)[count].index = i;
-               (*glyphs)[count].x = x;
-               (*glyphs)[count++].y = y;
-               //advance glyph coordinates:
-               if (is_horizontal_text) x++;
-               else y++;
-               _utf8 = g_utf8_next_char(_utf8); //advance 1 char in our string pointer
-       }
+raptorz:
+               if (len==0){
+                       (*glyphs)[count].index = i;
+                       (*glyphs)[count].x = x;
+                       (*glyphs)[count++].y = y;
+
+                       //advance glyph coordinates:
+                       if (is_horizontal_text) x+=(this->font->horiz_adv_x/1000.0);//TODO: use here the height of the font
+                       else y+=(this->font->vert_adv_y/1000.0);//TODO: use here the "height" of the font
+
+                       _utf8 = g_utf8_next_char(_utf8); //advance 1 char in our string pointer
+               }
     }
     *num_glyphs = count;
     return CAIRO_STATUS_SUCCESS;
@@ -246,11 +251,13 @@ SvgFont::scaled_font_render_glyph (cairo_scaled_font_t  *scaled_font,
         //This glyph has a path description on its d attribute, so we render it:
         cairo_new_path(cr);
                //adjust scale of the glyph
-        Geom::Scale s(1.0/((SPFont*) node->parent)->horiz_adv_x);
+//        Geom::Scale s(1.0/((SPFont*) node->parent)->horiz_adv_x);
+        Geom::Scale s(1.0/1000);//TODO: use here the units-per-em attribute?
                //This matrix flips the glyph vertically
         Geom::Matrix m(Geom::Coord(1),Geom::Coord(0),Geom::Coord(0),Geom::Coord(-1),Geom::Coord(0),Geom::Coord(0));
                //then we offset it
-               pathv += Geom::Point(Geom::Coord(0),Geom::Coord(-((SPFont*) node->parent)->horiz_adv_x));
+//             pathv += Geom::Point(Geom::Coord(0),Geom::Coord(-((SPFont*) node->parent)->horiz_adv_x));
+               pathv += Geom::Point(Geom::Coord(0),Geom::Coord(-1000));//TODO: use here the units-per-em attribute?
 
         Geom::Rect area( Geom::Point(0,0), Geom::Point(1,1) ); //I need help here!    (reaction: note that the 'area' parameter is an *optional* rect, so you can pass an empty Geom::OptRect() )
 
index 39d919aa7b4c8472355516557b60ec4d80715a80..43c90063b28252cb2a6ca1eeca2c47e2a640fcc9 100644 (file)
@@ -57,7 +57,7 @@ inline bool helperfns_read_bool(gchar const *value, bool default_value){
 inline std::vector<gdouble> helperfns_read_vector(const gchar* value, int size){
         std::vector<gdouble> v(size, (gdouble) 0);
         std::istringstream is(value);
-        for(int i = 0; i < size && (is >> v[i]); i++);
+        for(int i = 0; i < size && (is >> v[i]); i++){};
         return v;
 }
 
index f2d37f3bfa111ddb687c5645e67e6d1310bdbd54..07aeaabf41ffb76a801763a3587992fe0aae729c 100644 (file)
@@ -144,7 +144,7 @@ sp_font_remove_child(SPObject *object, Inkscape::XML::Node *child)
 
 static void sp_font_release(SPObject *object)
 {
-    SPFont *font = SP_FONT(object);
+    //SPFont *font = SP_FONT(object);
     sp_document_remove_resource(SP_OBJECT_DOCUMENT(object), "font", object);
 
     if (((SPObjectClass *) parent_class)->release) {
index e8a1e539cca5ca8890ceb8a3bf6da093ac587a0f..0d97c0b778e80cdb8d92715f9cf296c5e03e3da3 100644 (file)
@@ -1044,14 +1044,14 @@ void InkscapePreferences::initPageUI()
         _("sv Swedish"), _("th Thai"), _("tr Turkish"), _("uk Ukrainian"), _("vi Vietnamese"), _("zh_CN Chinese, as spoken in China"), 
         _("zh_TW Chinese, as spoken in Taiwan")};
     Glib::ustring langValues[] = {"", "am", "ar", "az", "be", "bg", "bn", "br", "ca", "ca@valencia", "cs", "da", "de",
-        "dz", "el", "en", "en_AU", "en_CA", "en_GB", "en_US@piglatin", "eo", "es_MX", "es", "et", "eu", "fi", "fr", "ga",
+        "dz", "el", "en", "en_AU", "en_CA", "en_GB", "en_US@piglatin", "eo", "es", "es_MX", "et", "eu", "fi", "fr", "ga",
         "gl", "he", "hr", "hu", "hy", "id", "it", "ja", "km", "ko", "lt", "mk", "mn", "nb", "ne", "nl", "nn", "pa",
-        "pl", "pt_BR", "pt", "ro", "ru", "rw", "sk", "sl", "sq", "sr@latin", "sr", "sv", "th", "tr", "uk", "vi",
+        "pl", "pt", "pt_BR", "ro", "ru", "rw", "sk", "sl", "sq", "sr", "sr@latin", "sv", "th", "tr", "uk", "vi",
         "zh_CN", "zh_TW"};
 
-    _ui_languages.init( "/ui/language", languages, langValues, G_N_ELEMENTS(languages), languages[0]);   
+    _ui_languages.init( "/ui/language", languages, langValues, G_N_ELEMENTS(languages), languages[0]);
     _page_ui.add_line( false, _("Language (requires restart):"), _ui_languages, "",
-                              _("Set the language for menues and number-formats"), false);
+                              _("Set the language for menus and number-formats"), false);
 
      Glib::ustring sizeLabels[] = {_("Normal"), _("Medium"), _("Small")};
     int sizeValues[] = {0, 1, 2};
index a29a015106b516fced81b089c3a2d2de0ff8e9da..abdf4c3aeb64009648266891d93f1211f275130e 100644 (file)
@@ -321,6 +321,9 @@ void SvgFontsDialog::on_setwidth_changed(){
     if (spfont){
         spfont->horiz_adv_x = setwidth_spin.get_value();
         //TODO: tell cairo that the glyphs cache has to be invalidated
+               //              The current solution is to recreate the whole cairo svgfont.
+               //              This is not a good solution to the issue because big fonts will result in poor performance.
+        update_glyphs();
     }
 }
 
@@ -364,16 +367,17 @@ Gtk::VBox* SvgFontsDialog::global_settings_tab(){
     global_vbox->add(*AttrCombo((gchar*) _("Variant:"), SP_PROP_FONT_VARIANT));
     global_vbox->add(*AttrCombo((gchar*) _("Weight:"), SP_PROP_FONT_WEIGHT));
 */
+
 //Set Width (horiz_adv_x):
-/*    Gtk::HBox* setwidth_hbox = Gtk::manage(new Gtk::HBox());
+    Gtk::HBox* setwidth_hbox = Gtk::manage(new Gtk::HBox());
     setwidth_hbox->add(*Gtk::manage(new Gtk::Label(_("Set width:"))));
     setwidth_hbox->add(setwidth_spin);
 
     setwidth_spin.signal_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::on_setwidth_changed));
     setwidth_spin.set_range(0, 4096);
     setwidth_spin.set_increments(10, 100);
-    global_vbox->add(*setwidth_hbox);
-*/
+    global_vbox.pack_start(*setwidth_hbox, false, false);
+
     return &global_vbox;
 }
 
@@ -498,7 +502,8 @@ void SvgFontsDialog::missing_glyph_description_from_selected_path(){
     Geom::Matrix m(Geom::Coord(1),Geom::Coord(0),Geom::Coord(0),Geom::Coord(-1),Geom::Coord(0),Geom::Coord(0));
        pathv*=m;
        //then we offset it
-       pathv+=Geom::Point(Geom::Coord(0),Geom::Coord(get_selected_spfont()->horiz_adv_x));
+//     pathv+=Geom::Point(Geom::Coord(0),Geom::Coord(get_selected_spfont()->horiz_adv_x));
+       pathv+=Geom::Point(Geom::Coord(0),Geom::Coord(1000));//TODO: use here the units-per-em attribute?
 
        SPObject* obj;
        for (obj = get_selected_spfont()->children; obj; obj=obj->next){
index 72df25b5cf6aefa23fe3715f596c1518f9f03a0c..688969207e5f3cf421d4df47941346e719078e9e 100644 (file)
@@ -9,8 +9,9 @@ static unsigned int hex2int(char* s){
        while(s[i+1]!='\0') i++;
 
        while(i>=0){
-               if (s[i] > '9') res += mul * (s[i]-'A'+10);
-               else res += mul * (s[i]-'0');
+               if (s[i] >= 'A' && s[i] <= 'F') res += mul * (s[i]-'A'+10);
+               if (s[i] >= 'a' && s[i] <= 'f') res += mul * (s[i]-'a'+10);
+               if (s[i] >= '0' && s[i] <= '9') res += mul * (s[i]-'0');
                i--;
                mul*=16;
        }
@@ -22,9 +23,8 @@ UnicodeRange::UnicodeRange(const gchar* value){
        gchar* val = (gchar*) value;
        while(val[0] != '\0'){
                if (val[0]=='U' && val[1]=='+'){
-                       val += add_range(val);
+                       val += add_range(val+2);
                } else {
-//                     g_warning("adding unichar. unichar=%c", g_utf8_get_char(&val[0]));
                        this->unichars.push_back(g_utf8_get_char(&val[0]));
                        val++;
                }
@@ -36,9 +36,7 @@ UnicodeRange::UnicodeRange(const gchar* value){
 int
 UnicodeRange::add_range(gchar* val){
                Urange r;
-               //U+
-               val+=2;
-               int i=0, count=2;
+               int i=0, count=0;
                while(val[i]!='\0' && val[i]!='-' && val[i]!=' ' && val[i]!=',') i++;
                r.start = (gchar*) malloc((i+1)*sizeof(gchar*));
                strncpy(r.start, val, i);
@@ -57,7 +55,6 @@ UnicodeRange::add_range(gchar* val){
                } else {
                        r.end=NULL;
                }
-//             g_warning("adding range. from %s to %s", r.start, r.end);
                this->range.push_back(r);
                return count+1;
 }
@@ -69,7 +66,6 @@ bool UnicodeRange::contains(gchar unicode){
 
        unsigned int unival;
        unival = g_utf8_get_char (&unicode);
-//     g_warning("unival=%d", unival);
        char uni[9] = "00000000";
        uni[8]= '\0';
        unsigned char val;
@@ -79,19 +75,21 @@ bool UnicodeRange::contains(gchar unicode){
                if (val < 10) uni[i] = '0' + val;
                else uni[i] = 'A'+ val - 10;
        }
-//     g_warning("uni=%s", uni);
 
        bool found;
        for(unsigned int i=0;i<this->range.size();i++){
                Urange r = this->range[i];
                if (r.end){
-//                     g_warning("hex2int: start=%d", hex2int(r.start));
-//                     g_warning("hex2int: end=%d", hex2int(r.end));
                        if (unival >= hex2int(r.start) && unival <= hex2int(r.end)) return true;
                } else {
                        found = true;
-                       for (int pos=0;pos<8;pos++){
-                               if (uni[pos]!='?' && uni[pos]!=r.start[pos]) found = false;
+
+                       int p=0;
+                       while (r.start[p]!='\0') p++;
+                       p--;
+
+                       for (int pos=8;p>=0;pos--,p--){
+                               if (uni[pos]!='?' && uni[pos]!=r.start[p]) found = false;
                        }
                        if (found) return true;
                }
@@ -108,8 +106,9 @@ Glib::ustring UnicodeRange::attribute_string(){
        }
 
        for(i=0; i<this->range.size(); i++){
-               result += "U+" + Glib::ustring(this->range[i].start) + "-" + Glib::ustring(this->range[i].end);
-               if (i!=this->range.size()-1) result += ",";
+               result += "U+" + Glib::ustring(this->range[i].start);
+               if (this->range[i].end) result += "-" + Glib::ustring(this->range[i].end);
+               if (i!=this->range.size()-1) result += ", ";
        }
 
        return result;