diff options
| author | Shlomi Fish <shlomif@shlomifish.org> | 2016-09-15 17:03:32 +0000 |
|---|---|---|
| committer | Shlomi Fish <shlomif@shlomifish.org> | 2016-09-15 17:03:32 +0000 |
| commit | 3bb19d6df3b7d4e9c2518484e62997f9150d5f5d (patch) | |
| tree | 3ac3c8748744b75c468d8c55d8eec27b841cfbb0 /src/ui | |
| parent | Refactor == true (diff) | |
| parent | [Bug #459914] Non-ascii (ja) charactors aren't displayed properly in Handle t... (diff) | |
| download | inkscape-3bb19d6df3b7d4e9c2518484e62997f9150d5f5d.tar.gz inkscape-3bb19d6df3b7d4e9c2518484e62997f9150d5f5d.zip | |
Merged.
(bzr r15100.1.17)
Diffstat (limited to 'src/ui')
| -rw-r--r-- | src/ui/dialog/svg-fonts-dialog.cpp | 182 | ||||
| -rw-r--r-- | src/ui/dialog/svg-fonts-dialog.h | 36 | ||||
| -rw-r--r-- | src/ui/tools/freehand-base.cpp | 39 |
3 files changed, 199 insertions, 58 deletions
diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp index 0203d9778..e55a32bd5 100644 --- a/src/ui/dialog/svg-fonts-dialog.cpp +++ b/src/ui/dialog/svg-fonts-dialog.cpp @@ -29,6 +29,7 @@ #include "sp-font-face.h" #include "desktop.h" +#include <sstream> #include "display/nr-svgfonts.h" #include "verbs.h" #include "sp-glyph.h" @@ -74,6 +75,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; } @@ -110,6 +120,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; @@ -139,6 +150,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 (auto& node: dialog->get_selected_spfont()->children){ + 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)) ); @@ -279,7 +358,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()); } @@ -304,9 +382,18 @@ 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); + for (auto& obj: font->children) { 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); } } } @@ -321,11 +408,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); @@ -335,17 +419,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(); @@ -379,24 +452,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; } @@ -412,9 +498,10 @@ SvgFontsDialog::populate_glyphs_box() for (auto& node: spfont->children) { 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; } } } @@ -487,16 +574,14 @@ void SvgFontsDialog::add_glyph(){ Geom::PathVector SvgFontsDialog::flip_coordinate_system(Geom::PathVector pathv){ - double units_per_em = 1000; + double units_per_em = 1024; for (auto& obj: get_selected_spfont()->children) { if (SP_IS_FONTFACE(&obj)){ //XML Tree being directly used here while it shouldn't be. 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; @@ -631,6 +716,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; @@ -699,9 +804,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)); @@ -719,6 +824,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; @@ -798,7 +906,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 1588c0fc2..a0f1586d8 100644 --- a/src/ui/dialog/svg-fonts-dialog.h +++ b/src/ui/dialog/svg-fonts-dialog.h @@ -82,8 +82,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: @@ -96,6 +97,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(); @@ -107,7 +122,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(); @@ -129,7 +145,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(); @@ -165,11 +195,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; diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 7382c37ea..067035b97 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -212,19 +212,10 @@ static void spdc_paste_curve_as_freehand_shape(Geom::PathVector const &newpath, Effect::createAndApply(PATTERN_ALONG_PATH, dc->desktop->doc(), item); Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); static_cast<LPEPatternAlongPath*>(lpe)->pattern.set_new_value(newpath,true); - - // write pattern along path parameters: - lpe->getRepr()->setAttribute("copytype", "single_stretched"); - lpe->getRepr()->setAttribute("fuse_tolerance", "0"); - lpe->getRepr()->setAttribute("is_visible", "true"); - lpe->getRepr()->setAttribute("normal_offset", "0"); - lpe->getRepr()->setAttribute("prop_scale", "1"); - lpe->getRepr()->setAttribute("prop_units", "false"); - lpe->getRepr()->setAttribute("scale_y_rel", "false"); - lpe->getRepr()->setAttribute("spacing", "0"); - lpe->getRepr()->setAttribute("tang_offset", "0"); - lpe->getRepr()->setAttribute("vertical_pattern", "false"); - + double scale_doc = 1 / dc->desktop->doc()->getDocumentScale()[0]; + Inkscape::SVGOStringStream os; + os << scale_doc; + lpe->getRepr()->setAttribute("prop_scale", os.str().c_str()); } static void spdc_apply_powerstroke_shape(const std::vector<Geom::Point> & points, FreehandBase *dc, SPItem *item) @@ -341,7 +332,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, // "triangle in" std::vector<Geom::Point> points(1); points[0] = Geom::Point(0., swidth/2); - points[0] *= i2anc_affine(static_cast<SPItem *>(item->parent), NULL).inverse(); + //points[0] *= i2anc_affine(static_cast<SPItem *>(item->parent), NULL).inverse(); spdc_apply_powerstroke_shape(points, dc, item); shape_applied = true; @@ -353,7 +344,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, guint curve_length = curve->get_segment_count(); std::vector<Geom::Point> points(1); points[0] = Geom::Point(0, swidth/2); - points[0] *= i2anc_affine(static_cast<SPItem *>(item->parent), NULL).inverse(); + //points[0] *= i2anc_affine(static_cast<SPItem *>(item->parent), NULL).inverse(); points[0][Geom::X] = (double)curve_length; spdc_apply_powerstroke_shape(points, dc, item); @@ -791,16 +782,26 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) if (!dc->white_item) { // Attach repr + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + shapeType shape_selected = (shapeType)prefs->getInt(tool_name(dc) + "/shape", 0); SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr)); - - spdc_check_for_and_apply_waiting_LPE(dc, item, c); - if(previous_shape_type != BEND_CLIPBOARD){ - dc->selection->set(repr); + //Bend needs the transforms applied after, Other effects best before + if((previous_shape_type == BEND_CLIPBOARD && shape_selected == LAST_APPLIED) || + shape_selected == BEND_CLIPBOARD) + { + spdc_check_for_and_apply_waiting_LPE(dc, item, c); + previous_shape_type = BEND_CLIPBOARD; } Inkscape::GC::release(repr); item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); item->updateRepr(); item->doWriteTransform(item->getRepr(), item->transform, NULL, true); + if((previous_shape_type != BEND_CLIPBOARD || shape_selected != LAST_APPLIED) && + shape_selected != BEND_CLIPBOARD) + { + spdc_check_for_and_apply_waiting_LPE(dc, item, c); + dc->selection->set(repr); + } if(previous_shape_type == BEND_CLIPBOARD){ repr->parent()->removeChild(repr); } |
