summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: dfc8081)
raw | patch | inline | side by side (parent: dfc8081)
author | JucaBlues <JucaBlues@users.sourceforge.net> | |
Mon, 5 Jan 2009 23:49:00 +0000 (23:49 +0000) | ||
committer | JucaBlues <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.
* 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.
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)
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,
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++;
+ }
}
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;
//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() )
diff --git a/src/helper-fns.h b/src/helper-fns.h
index 39d919aa7b4c8472355516557b60ec4d80715a80..43c90063b28252cb2a6ca1eeca2c47e2a640fcc9 100644 (file)
--- a/src/helper-fns.h
+++ b/src/helper-fns.h
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;
}
diff --git a/src/sp-font.cpp b/src/sp-font.cpp
index f2d37f3bfa111ddb687c5645e67e6d1310bdbd54..07aeaabf41ffb76a801763a3587992fe0aae729c 100644 (file)
--- a/src/sp-font.cpp
+++ b/src/sp-font.cpp
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)
_("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)
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();
}
}
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;
}
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){
diff --git a/src/unicoderange.cpp b/src/unicoderange.cpp
index 72df25b5cf6aefa23fe3715f596c1518f9f03a0c..688969207e5f3cf421d4df47941346e719078e9e 100644 (file)
--- a/src/unicoderange.cpp
+++ b/src/unicoderange.cpp
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;
}
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++;
}
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);
} else {
r.end=NULL;
}
-// g_warning("adding range. from %s to %s", r.start, r.end);
this->range.push_back(r);
return count+1;
}
unsigned int unival;
unival = g_utf8_get_char (&unicode);
-// g_warning("unival=%d", unival);
char uni[9] = "00000000";
uni[8]= '\0';
unsigned char val;
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;
}
}
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;