summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2016-07-10 14:51:02 +0000
committertavmjong-free <tavmjong@free.fr>2016-07-10 14:51:02 +0000
commitdca182031f3a9c95ae6a1f06c139a89c298846a1 (patch)
tree2c356950ae2658ca10d01234c5774a5abe2dba01 /src/ui
parentDutch translation update (diff)
downloadinkscape-dca182031f3a9c95ae6a1f06c139a89c298846a1.tar.gz
inkscape-dca182031f3a9c95ae6a1f06c139a89c298846a1.zip
Improve font editing dialog:
1. Allow for fonts with other than 1000 units per em. 2. Allow setting 'ascent', 'descent', etc. 3. Allow setting individual glyph horizontal advances. 4. Fix bug where 'units-per-em' was not read correctly. (bzr r15014.1.1)
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/dialog/svg-fonts-dialog.cpp182
-rw-r--r--src/ui/dialog/svg-fonts-dialog.h37
2 files changed, 179 insertions, 40 deletions
diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp
index 08ebbcf14..3672fbe9e 100644
--- a/src/ui/dialog/svg-fonts-dialog.cpp
+++ b/src/ui/dialog/svg-fonts-dialog.cpp
@@ -31,6 +31,7 @@
#include "sp-font-face.h"
#include "desktop.h"
+#include <sstream>
#include "display/nr-svgfonts.h"
#include "verbs.h"
#include "sp-glyph.h"
@@ -76,6 +77,15 @@ bool SvgFontDrawingArea::on_expose_event (GdkEventExpose */*event*/){
cr->set_font_size (_y-20);
cr->move_to (10, 10);
cr->show_text (_text.c_str());
+
+ // Draw some lines to show line area.
+ cr->set_source_rgb( 0.5, 0.5, 0.5 );
+ cr->move_to ( 0, 10);
+ cr->line_to (_x, 10);
+ cr->stroke();
+ cr->move_to ( 0, _y-10);
+ cr->line_to (_x, _y-10);
+ cr->stroke();
}
return TRUE;
}
@@ -112,6 +122,7 @@ void SvgFontsDialog::AttrEntry::set_text(char* t){
entry.set_text(t);
}
+// 'font-family' has a problem as it is also a presentation attribute for <text>
void SvgFontsDialog::AttrEntry::on_attr_changed(){
SPObject* o = NULL;
@@ -141,6 +152,74 @@ void SvgFontsDialog::AttrEntry::on_attr_changed(){
}
+SvgFontsDialog::AttrSpin::AttrSpin(SvgFontsDialog* d, gchar* lbl, const SPAttributeEnum attr) {
+
+ this->dialog = d;
+ this->attr = attr;
+ this->add(* Gtk::manage(new Gtk::Label(lbl)) );
+ this->add(spin);
+ this->show_all();
+ spin.set_range(0, 4096);
+ spin.set_increments(16, 0);
+ spin.signal_value_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::AttrSpin::on_attr_changed));
+}
+
+void SvgFontsDialog::AttrSpin::set_range(double low, double high){
+ spin.set_range(low, high);
+}
+
+void SvgFontsDialog::AttrSpin::set_value(double v){
+ spin.set_value(v);
+}
+
+void SvgFontsDialog::AttrSpin::on_attr_changed(){
+
+ SPObject* o = NULL;
+ switch (this->attr) {
+
+ // <font> attributes
+ case SP_ATTR_HORIZ_ORIGIN_X:
+ case SP_ATTR_HORIZ_ORIGIN_Y:
+ case SP_ATTR_HORIZ_ADV_X:
+ case SP_ATTR_VERT_ORIGIN_X:
+ case SP_ATTR_VERT_ORIGIN_Y:
+ case SP_ATTR_VERT_ADV_Y:
+ o = this->dialog->get_selected_spfont();
+ break;
+
+ // <font-face> attributes
+ case SP_ATTR_UNITS_PER_EM:
+ case SP_ATTR_ASCENT:
+ case SP_ATTR_DESCENT:
+ case SP_ATTR_CAP_HEIGHT:
+ case SP_ATTR_X_HEIGHT:
+ for(SPObject* node = this->dialog->get_selected_spfont()->children; node; node=node->next){
+ if (SP_IS_FONTFACE(node)){
+ o = node;
+ continue;
+ }
+ }
+ break;
+
+ default:
+ o = NULL;
+ }
+
+ const gchar* name = (const gchar*)sp_attribute_name(this->attr);
+ if(name && o) {
+ std::ostringstream temp;
+ temp << this->spin.get_value();
+ o->getRepr()->setAttribute((const gchar*) name, temp.str().c_str() );
+ o->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+
+ Glib::ustring undokey = "svgfonts:";
+ undokey += name;
+ DocumentUndo::maybeDone(o->document, undokey.c_str(), SP_VERB_DIALOG_SVG_FONTS,
+ _("Set SVG Font attribute"));
+ }
+
+}
+
Gtk::HBox* SvgFontsDialog::AttrCombo(gchar* lbl, const SPAttributeEnum /*attr*/){
Gtk::HBox* hbox = Gtk::manage(new Gtk::HBox());
hbox->add(* Gtk::manage(new Gtk::Label(lbl)) );
@@ -283,7 +362,6 @@ void SvgFontsDialog::update_fonts()
}
void SvgFontsDialog::on_preview_text_changed(){
- _font_da.set_text((gchar*) _preview_entry.get_text().c_str());
_font_da.set_text(_preview_entry.get_text());
}
@@ -308,10 +386,19 @@ void SvgFontsDialog::update_global_settings_tab(){
SPFont* font = get_selected_spfont();
if (!font) return;
+ _horiz_adv_x_spin->set_value(font->horiz_adv_x);
+ _horiz_origin_x_spin->set_value(font->horiz_origin_x);
+ _horiz_origin_y_spin->set_value(font->horiz_origin_y);
+
SPObject* obj;
for (obj=font->children; obj; obj=obj->next){
if (SP_IS_FONTFACE(obj)){
_familyname_entry->set_text((SP_FONTFACE(obj))->font_family);
+ _units_per_em_spin->set_value((SP_FONTFACE(obj))->units_per_em);
+ _ascent_spin->set_value((SP_FONTFACE(obj))->ascent);
+ _descent_spin->set_value((SP_FONTFACE(obj))->descent);
+ _x_height_spin->set_value((SP_FONTFACE(obj))->x_height);
+ _cap_height_spin->set_value((SP_FONTFACE(obj))->cap_height);
}
}
}
@@ -326,11 +413,8 @@ void SvgFontsDialog::on_font_selection_changed(){
kerning_preview.set_svgfont(svgfont);
_font_da.set_svgfont(svgfont);
_font_da.redraw();
-
- double set_width = spfont->horiz_adv_x;
- setwidth_spin.set_value(set_width);
-
- kerning_slider->set_range(0, set_width);
+
+ kerning_slider->set_range(0, spfont->horiz_adv_x);
kerning_slider->set_draw_value(false);
kerning_slider->set_value(0);
@@ -340,17 +424,6 @@ void SvgFontsDialog::on_font_selection_changed(){
update_sensitiveness();
}
-void SvgFontsDialog::on_setfontdata_changed(){
- SPFont* spfont = this->get_selected_spfont();
- 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();
- }
-}
-
SPGlyphKerning* SvgFontsDialog::get_selected_kerning_pair()
{
Gtk::TreeModel::iterator i = _KerningPairsList.get_selection()->get_selected();
@@ -384,24 +457,37 @@ SPGlyph* SvgFontsDialog::get_selected_glyph()
}
Gtk::VBox* SvgFontsDialog::global_settings_tab(){
- _familyname_entry = new AttrEntry(this, (gchar*) _("Family Name:"), SP_PROP_FONT_FAMILY);
+ _font_label = new Gtk::Label( _("Font Attributes") );
+ _horiz_adv_x_spin = new AttrSpin( this, (gchar*) _("Horiz. Advance X"), SP_ATTR_HORIZ_ADV_X);
+ _horiz_origin_x_spin = new AttrSpin( this, (gchar*) _("Horiz. Origin X "), SP_ATTR_HORIZ_ORIGIN_X);
+ _horiz_origin_y_spin = new AttrSpin( this, (gchar*) _("Horiz. Origin Y "), SP_ATTR_HORIZ_ORIGIN_Y);
+ _font_face_label = new Gtk::Label( _("Font Face Attributes") );
+ _familyname_entry = new AttrEntry(this, (gchar*) _("Family Name:"), SP_PROP_FONT_FAMILY);
+ _units_per_em_spin = new AttrSpin( this, (gchar*) _("Units per em"), SP_ATTR_UNITS_PER_EM);
+ _ascent_spin = new AttrSpin( this, (gchar*) _("Ascent:"), SP_ATTR_ASCENT);
+ _descent_spin = new AttrSpin( this, (gchar*) _("Descent:"), SP_ATTR_DESCENT);
+ _cap_height_spin = new AttrSpin( this, (gchar*) _("Cap Height:"), SP_ATTR_CAP_HEIGHT);
+ _x_height_spin = new AttrSpin( this, (gchar*) _("x Height:"), SP_ATTR_X_HEIGHT);
+
+ _descent_spin->set_range(-4096,0);
+
+ global_vbox.pack_start(*_font_label, false, false);
+ global_vbox.pack_start(*_horiz_adv_x_spin, false, false);
+ global_vbox.pack_start(*_horiz_origin_x_spin, false, false);
+ global_vbox.pack_start(*_horiz_origin_y_spin, false, false);
+ global_vbox.pack_start(*_font_face_label, false, false);
+ global_vbox.pack_start(*_familyname_entry, false, false);
+ global_vbox.pack_start(*_units_per_em_spin, false, false);
+ global_vbox.pack_start(*_ascent_spin, false, false);
+ global_vbox.pack_start(*_descent_spin, false, false);
+ global_vbox.pack_start(*_cap_height_spin, false, false);
+ global_vbox.pack_start(*_x_height_spin, false, false);
- global_vbox.pack_start(*_familyname_entry, false, false);
/* global_vbox->add(*AttrCombo((gchar*) _("Style:"), SP_PROP_FONT_STYLE));
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());
- 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_setfontdata_changed));
- setwidth_spin.set_range(0, 4096);
- setwidth_spin.set_increments(10, 0);
- global_vbox.pack_start(*setwidth_hbox, false, false);
-
return &global_vbox;
}
@@ -417,9 +503,10 @@ SvgFontsDialog::populate_glyphs_box()
for(SPObject* node = spfont->children; node; node=node->next){
if (SP_IS_GLYPH(node)){
Gtk::TreeModel::Row row = *(_GlyphsListStore->append());
- row[_GlyphsListColumns.glyph_node] = static_cast<SPGlyph*>(node);
+ row[_GlyphsListColumns.glyph_node] = static_cast<SPGlyph*>(node);
row[_GlyphsListColumns.glyph_name] = (static_cast<SPGlyph*>(node))->glyph_name;
- row[_GlyphsListColumns.unicode] = (static_cast<SPGlyph*>(node))->unicode;
+ row[_GlyphsListColumns.unicode] = (static_cast<SPGlyph*>(node))->unicode;
+ row[_GlyphsListColumns.advance] = (static_cast<SPGlyph*>(node))->horiz_adv_x;
}
}
}
@@ -492,7 +579,7 @@ void SvgFontsDialog::add_glyph(){
Geom::PathVector
SvgFontsDialog::flip_coordinate_system(Geom::PathVector pathv){
- double units_per_em = 1000;
+ double units_per_em = 1024;
SPObject* obj;
for (obj = get_selected_spfont()->children; obj; obj=obj->next){
if (SP_IS_FONTFACE(obj)){
@@ -500,9 +587,7 @@ SvgFontsDialog::flip_coordinate_system(Geom::PathVector pathv){
sp_repr_get_double(obj->getRepr(), "units-per-em", &units_per_em);
}
}
-
double baseline_offset = units_per_em - get_selected_spfont()->horiz_origin_y;
-
//This matrix flips y-axis and places the origin at baseline
Geom::Affine m(Geom::Coord(1),Geom::Coord(0),Geom::Coord(0),Geom::Coord(-1),Geom::Coord(0),Geom::Coord(baseline_offset));
return pathv*m;
@@ -639,6 +724,26 @@ void SvgFontsDialog::glyph_unicode_edit(const Glib::ustring&, const Glib::ustrin
update_glyphs();
}
+void SvgFontsDialog::glyph_advance_edit(const Glib::ustring&, const Glib::ustring& str){
+ Gtk::TreeModel::iterator i = _GlyphsList.get_selection()->get_selected();
+ if (!i) return;
+
+ SPGlyph* glyph = (*i)[_GlyphsListColumns.glyph_node];
+ //XML Tree being directly used here while it shouldn't be.
+ std::istringstream is(str);
+ double value;
+ // Check if input valid
+ if ((is >> value)) {
+ glyph->getRepr()->setAttribute("horiz-adv-x", str.c_str());
+ SPDocument* doc = this->getDesktop()->getDocument();
+ DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Set glyph advance"));
+
+ update_glyphs();
+ } else {
+ std::cerr << "SvgFontDialog::glyph_advance_edit: Error in input: " << str << std::endl;
+ }
+}
+
void SvgFontsDialog::remove_selected_font(){
SPFont* font = get_selected_spfont();
if (!font) return;
@@ -707,9 +812,9 @@ Gtk::VBox* SvgFontsDialog::glyphs_tab(){
_GlyphsListScroller.add(_GlyphsList);
_GlyphsListStore = Gtk::ListStore::create(_GlyphsListColumns);
_GlyphsList.set_model(_GlyphsListStore);
- _GlyphsList.append_column_editable(_("Glyph name"), _GlyphsListColumns.glyph_name);
+ _GlyphsList.append_column_editable(_("Glyph name"), _GlyphsListColumns.glyph_name);
_GlyphsList.append_column_editable(_("Matching string"), _GlyphsListColumns.unicode);
-
+ _GlyphsList.append_column_numeric_editable(_("Advance"), _GlyphsListColumns.advance, "%.2f");
Gtk::HBox* hb = Gtk::manage(new Gtk::HBox());
add_glyph_button.set_label(_("Add Glyph"));
add_glyph_button.signal_clicked().connect(sigc::mem_fun(*this, &SvgFontsDialog::add_glyph));
@@ -727,6 +832,9 @@ Gtk::VBox* SvgFontsDialog::glyphs_tab(){
dynamic_cast<Gtk::CellRendererText*>( _GlyphsList.get_column_cell_renderer(1))->signal_edited().connect(
sigc::mem_fun(*this, &SvgFontsDialog::glyph_unicode_edit));
+ dynamic_cast<Gtk::CellRendererText*>( _GlyphsList.get_column_cell_renderer(2))->signal_edited().connect(
+ sigc::mem_fun(*this, &SvgFontsDialog::glyph_advance_edit));
+
_glyphs_observer.signal_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::update_glyphs));
return &glyphs_vbox;
@@ -806,7 +914,7 @@ Gtk::VBox* SvgFontsDialog::kerning_tab(){
kerning_amount_hbox->add(*kerning_slider);
kerning_preview.set_size(300 + 20, 150 + 20);
- _font_da.set_size(150 + 20, 50 + 20);
+ _font_da.set_size(300 + 50 + 20, 60 + 20);
return &kerning_vbox;
}
diff --git a/src/ui/dialog/svg-fonts-dialog.h b/src/ui/dialog/svg-fonts-dialog.h
index e80bbfd39..11bf52187 100644
--- a/src/ui/dialog/svg-fonts-dialog.h
+++ b/src/ui/dialog/svg-fonts-dialog.h
@@ -86,8 +86,9 @@ public:
void on_setfontdata_changed();
void add_font();
Geom::PathVector flip_coordinate_system(Geom::PathVector pathv);
+ bool updating;
- //TODO: AttrEntry is currently unused. Should we remove it?
+ // Used for font-family
class AttrEntry : public Gtk::HBox
{
public:
@@ -100,6 +101,20 @@ public:
SPAttributeEnum attr;
};
+ class AttrSpin : public Gtk::HBox
+ {
+ public:
+ AttrSpin(SvgFontsDialog* d, gchar* lbl, const SPAttributeEnum attr);
+ void set_value(double v);
+ void set_range(double low, double high);
+ Inkscape::UI::Widget::SpinButton* getSpin() { return &spin; }
+ private:
+ SvgFontsDialog* dialog;
+ void on_attr_changed();
+ Inkscape::UI::Widget::SpinButton spin;
+ SPAttributeEnum attr;
+ };
+
private:
void update_glyphs();
void update_sensitiveness();
@@ -111,7 +126,8 @@ private:
void reset_missing_glyph_description();
void add_glyph();
void glyph_unicode_edit(const Glib::ustring&, const Glib::ustring&);
- void glyph_name_edit(const Glib::ustring&, const Glib::ustring&);
+ void glyph_name_edit( const Glib::ustring&, const Glib::ustring&);
+ void glyph_advance_edit(const Glib::ustring&, const Glib::ustring&);
void remove_selected_glyph();
void remove_selected_font();
void remove_selected_kerning_pair();
@@ -133,7 +149,21 @@ private:
Gtk::HBox* AttrCombo(gchar* lbl, const SPAttributeEnum attr);
// Gtk::HBox* AttrSpin(gchar* lbl, const SPAttributeEnum attr);
Gtk::VBox* global_settings_tab();
+
+ // <font>
+ Gtk::Label* _font_label;
+ AttrSpin* _horiz_adv_x_spin;
+ AttrSpin* _horiz_origin_x_spin;
+ AttrSpin* _horiz_origin_y_spin;
+
+ // <font-face>
+ Gtk::Label* _font_face_label;
AttrEntry* _familyname_entry;
+ AttrSpin* _units_per_em_spin;
+ AttrSpin* _ascent_spin;
+ AttrSpin* _descent_spin;
+ AttrSpin* _cap_height_spin;
+ AttrSpin* _x_height_spin;
Gtk::VBox* kerning_tab();
Gtk::VBox* glyphs_tab();
@@ -169,11 +199,13 @@ private:
add(glyph_node);
add(glyph_name);
add(unicode);
+ add(advance);
}
Gtk::TreeModelColumn<SPGlyph*> glyph_node;
Gtk::TreeModelColumn<Glib::ustring> glyph_name;
Gtk::TreeModelColumn<Glib::ustring> unicode;
+ Gtk::TreeModelColumn<double> advance;
};
GlyphsColumns _GlyphsListColumns;
Glib::RefPtr<Gtk::ListStore> _GlyphsListStore;
@@ -215,7 +247,6 @@ private:
SvgFontDrawingArea _font_da, kerning_preview;
GlyphComboBox first_glyph, second_glyph;
SPGlyphKerning* kerning_pair;
- Inkscape::UI::Widget::SpinButton setwidth_spin;
#if WITH_GTKMM_3_0
Gtk::Scale* kerning_slider;