diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2018-04-13 09:43:53 +0000 |
|---|---|---|
| committer | Tavmjong Bah <tavmjong@free.fr> | 2018-04-13 09:43:53 +0000 |
| commit | 1ddfdd2c6d5f915da6a7563c2d29021d53ff07ed (patch) | |
| tree | 21241bccd07beb89b054b746685f118021e4cf93 /src/libnrtype | |
| parent | Remove unused variables. (diff) | |
| download | inkscape-1ddfdd2c6d5f915da6a7563c2d29021d53ff07ed.tar.gz inkscape-1ddfdd2c6d5f915da6a7563c2d29021d53ff07ed.zip | |
Replace C FontSelector by C++ FontSelector.
Fix synchonization problems between users of FontLister (FontSelector/Text toolbar).
Hide unused size widget in Glyphs dialog.
Display style names in FontSelector using own style.
Diffstat (limited to 'src/libnrtype')
| -rw-r--r-- | src/libnrtype/font-lister.cpp | 157 | ||||
| -rw-r--r-- | src/libnrtype/font-lister.h | 43 |
2 files changed, 182 insertions, 18 deletions
diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 7c26f0b92..20ab3786d 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -2,8 +2,9 @@ #include <config.h> #endif -#include <gtkmm/liststore.h> -#include <gtkmm/treemodel.h> +#include <glibmm/regex.h> + +#include <gtkmm/cellrenderertext.h> #include <libnrtype/font-instance.h> @@ -15,12 +16,13 @@ #include "document.h" #include "inkscape.h" #include "preferences.h" + #include "object/sp-object.h" #include "object/sp-root.h" #include "object/sp-namedview.h" + #include "xml/repr.h" -#include <glibmm/regex.h> //#define DEBUG_FONT @@ -46,6 +48,10 @@ static const char* sp_font_family_get_name(PangoFontFamily* family) namespace Inkscape { FontLister::FontLister() + : current_family_row (0) + , current_family ("sans-serif") + , current_style ("Normal") + , block (false) { font_list_store = Gtk::ListStore::create(FontList); font_list_store->freeze_notify(); @@ -82,10 +88,6 @@ FontLister::FontLister() } } - current_family_row = 0; - current_family = "sans-serif"; - current_style = "Normal"; - font_list_store->thaw_notify(); style_list_store = Gtk::ListStore::create(FontStyleList); @@ -126,9 +128,10 @@ FontLister *FontLister::get_instance() return instance; } -void FontLister::ensureRowStyles(GtkTreeModel* model, GtkTreeIter const* iterator) +// To do: remove model (not needed for C++ version). +// Ensures the style list for a particular family has been created. +void FontLister::ensureRowStyles(Glib::RefPtr<Gtk::TreeModel> model, Gtk::TreeModel::iterator const iter) { - Gtk::TreeIter iter(model, iterator); Gtk::TreeModel::Row row = *iter; if (!row[FontList.styles]) { if (row[FontList.pango_family]) { @@ -178,6 +181,12 @@ void FontLister::insert_font_family(Glib::ustring new_family) (*treeModelIter)[FontList.styles] = styles; (*treeModelIter)[FontList.onSystem] = false; (*treeModelIter)[FontList.pango_family] = NULL; + + current_family = new_family; + current_family_row = 0; + current_style = "Normal"; + + emit_update(); } void FontLister::update_font_list(SPDocument *document) @@ -304,6 +313,7 @@ void FontLister::update_font_list(SPDocument *document) // std::cout << " Out: row: " << current_family_row << " " << current_family << std::endl; font_list_store->thaw_notify(); + emit_update(); } void FontLister::update_font_data_recursive(SPObject& r, std::map<Glib::ustring, std::set<Glib::ustring>> &font_data) @@ -335,6 +345,16 @@ void FontLister::update_font_data_recursive(SPObject& r, std::map<Glib::ustring, } } +void FontLister::emit_update() +{ + if (block) return; + + block = true; + update_signal.emit (get_fontspec()); + block = false; +} + + Glib::ustring FontLister::canonize_fontspec(Glib::ustring fontspec) { @@ -468,6 +488,9 @@ std::pair<Glib::ustring, Glib::ustring> FontLister::selection_update() std::cout << "FontLister::selection_update: exit" << std::endl; std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif + + emit_update(); + return std::make_pair(current_family, current_style); } @@ -486,10 +509,13 @@ void FontLister::set_fontspec(Glib::ustring new_fontspec, bool /*check*/) set_font_family(new_family, false); set_font_style(new_style); + + emit_update(); } // TODO: use to determine font-selector best style +// TODO: create new function new_font_family(Gtk::TreeModel::iterator iter) std::pair<Glib::ustring, Glib::ustring> FontLister::new_font_family(Glib::ustring new_family, bool /*check_style*/) { #ifdef DEBUG_FONT @@ -577,6 +603,9 @@ std::pair<Glib::ustring, Glib::ustring> FontLister::set_font_family(Glib::ustrin std::cout << "FontLister::set_font_family: end" << std::endl; std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif + + emit_update(); + return ui; } @@ -626,6 +655,8 @@ void FontLister::set_font_style(Glib::ustring new_style) std::cout << "FontLister::set_font_style: end" << std::endl; std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif + + emit_update(); } @@ -799,7 +830,6 @@ Glib::ustring FontLister::fontspec_from_style(SPStyle *style) Gtk::TreeModel::Row FontLister::get_row_for_font(Glib::ustring family) { - Gtk::TreePath path; Gtk::TreeModel::iterator iter = font_list_store->get_iter("0"); while (iter != font_list_store->children().end()) { @@ -823,7 +853,6 @@ Gtk::TreePath FontLister::get_path_for_font(Glib::ustring family) Gtk::TreeModel::Row FontLister::get_row_for_style(Glib::ustring style) { - Gtk::TreePath path; Gtk::TreeModel::iterator iter = style_list_store->get_iter("0"); while (iter != style_list_store->children().end()) { @@ -980,14 +1009,97 @@ const Glib::RefPtr<Gtk::ListStore> FontLister::get_style_list() const // Helper functions // Separator function (if true, a separator will be drawn) -gboolean font_lister_separator_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer /*data*/) +bool font_lister_separator_func(const Glib::RefPtr<Gtk::TreeModel>& model, + const Gtk::TreeModel::iterator& iter) { + + // Of what use is 'model', can we avoid using font_lister? + Inkscape::FontLister* font_lister = Inkscape::FontLister::get_instance(); + Gtk::TreeModel::Row row = *iter; + Glib::ustring entry = row[font_lister->FontList.family]; + return entry == "#"; +} + +// Needed until Text toolbar updated +gboolean font_lister_separator_func2(GtkTreeModel *model, GtkTreeIter *iter, gpointer /*data*/) { gchar *text = 0; gtk_tree_model_get(model, iter, 0, &text, -1); // Column 0: FontList.family return (text && strcmp(text, "#") == 0); } -void font_lister_cell_data_func(GtkCellLayout * /*cell_layout*/, +// Draw system fonts in dark blue, missing fonts with red strikeout. +// Used by both FontSelector and Text toolbar. +void font_lister_cell_data_func (Gtk::CellRenderer *renderer, Gtk::TreeIter const &iter) +{ + Inkscape::FontLister* font_lister = Inkscape::FontLister::get_instance(); + Gtk::TreeModel::Row row = *iter; + + Glib::ustring family = row[font_lister->FontList.family]; + bool onSystem = row[font_lister->FontList.onSystem]; + + Glib::ustring family_escaped = Glib::strescape( family ); + Glib::ustring markup; + + if (!onSystem) { + markup = "<span foreground='darkblue'>"; + + // See if font-family is on system (separately for each family in font stack). + std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("\\s*,\\s*", family); + + for (auto token: tokens) { + bool found = false; + Gtk::TreeModel::Children children = font_lister->get_font_list()->children(); + for (auto iter2: children) { + Gtk::TreeModel::Row row2 = *iter2; + Glib::ustring family2 = row2[font_lister->FontList.family]; + bool onSystem2 = row2[font_lister->FontList.onSystem]; + if (onSystem2 && familyNamesAreEqual(token, family)) { + found = true; + break; + } + } + + if (found) { + markup += Glib::strescape (token); + markup += ", "; + } else { + markup += "<span strikethrough=\"true\" strikethrough_color=\"red\">"; + markup += Glib::strescape (token); + markup += "</span>"; + markup += ", "; + } + } + + // Remove extra comma and space from end. + if (markup.size() >= 2) { + markup.resize(markup.size() - 2); + } + markup += "</span>"; + + } else { + markup = family_escaped; + } + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int show_sample = prefs->getInt("/tools/text/show_sample_in_list", 1); + if (show_sample) { + + Glib::ustring sample = prefs->getString("/tools/text/font_sample"); + + markup += " <span foreground='gray' font_family='"; + markup += family_escaped; + markup += "'>"; + markup += sample; + markup += "</span>"; + } + + // std::cout << "Markup: " << markup << std::endl; + + renderer->set_property("markup", markup); +} + +// Needed until Text toolbar updated +void font_lister_cell_data_func2(GtkCellLayout * /*cell_layout*/, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, @@ -1063,6 +1175,25 @@ void font_lister_cell_data_func(GtkCellLayout * /*cell_layout*/, g_free(family_escaped); } +// Draw Face name with face style. +void font_lister_style_cell_data_func (Gtk::CellRenderer *renderer, Gtk::TreeIter const &iter) +{ + Inkscape::FontLister* font_lister = Inkscape::FontLister::get_instance(); + Gtk::TreeModel::Row row = *iter; + + Glib::ustring family = font_lister->get_font_family(); + Glib::ustring style = row[font_lister->FontStyleList.cssStyle]; + + Glib::ustring style_escaped = Glib::strescape( style ); + Glib::ustring font_desc = family + ", " + style; + Glib::ustring markup; + + markup = "<span font='" + font_desc + "'>" + style_escaped + "</span>"; + std::cout << " markup: " << markup << std::endl; + + renderer->set_property("markup", markup); +} + /* Local Variables: mode:c++ diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index e5acdc107..7125cc0f4 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -19,16 +19,22 @@ #include <map> #include <set> +#include <glibmm/ustring.h> +#include <glibmm/stringutils.h> // For strescape() + #include <gtkmm/liststore.h> #include <gtkmm/treemodelcolumn.h> #include <gtkmm/treepath.h> -#include <glibmm/ustring.h> class SPObject; class SPDocument; class SPCSSAttr; class SPStyle; +namespace Gtk { +class CellRenderer; +} + namespace Inkscape { /** @@ -53,6 +59,10 @@ namespace Inkscape { * * This class is used by the UI interface (text-toolbar, font-select, etc.). * + * This class is a singleton (one instance per Inkscape session). Since fonts + * used in a document are added to the list, there really should be one + * instance per document. + * * "Font" includes family and style. It should not be used when one * means font-family. */ @@ -258,9 +268,21 @@ public: Glib::ustring get_best_style_match(Glib::ustring family, Glib::ustring style); /** - * Makes sure style ListStore is filled. + * Ensures the style list for a particular family has been created. + */ + void ensureRowStyles(Glib::RefPtr<Gtk::TreeModel> model, Gtk::TreeModel::iterator const iter); + + /** + * Let users of FontLister know to update GUI. + * This is to allow synchronization of changes across multiple widgets. + * Handlers should block signals. + * Input is fontspec to set. */ - void ensureRowStyles(GtkTreeModel* model, GtkTreeIter const* iter); + sigc::connection connectUpdate(sigc::slot<void, Glib::ustring> slot) { + return update_signal.connect(slot); + } + + bool blocked() { return block; } private: FontLister(); @@ -282,21 +304,32 @@ private: * If a font-family is not on system, this list of styles is used. */ GList *default_styles; + + bool block; + void emit_update(); + sigc::signal<void, Glib::ustring> update_signal; }; } // namespace Inkscape // Helper functions -gboolean font_lister_separator_func(GtkTreeModel *model, +bool font_lister_separator_func (const Glib::RefPtr<Gtk::TreeModel>& model, + const Gtk::TreeModel::iterator& iter); + +gboolean font_lister_separator_func2(GtkTreeModel *model, GtkTreeIter *iter, gpointer /*data*/); -void font_lister_cell_data_func(GtkCellLayout * /*cell_layout*/, +void font_lister_cell_data_func (Gtk::CellRenderer *renderer, Gtk::TreeIter const &iter); + +void font_lister_cell_data_func2(GtkCellLayout * /*cell_layout*/, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer /*data*/); +void font_lister_style_cell_data_func (Gtk::CellRenderer *renderer, Gtk::TreeIter const &iter); + #endif /* |
