summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiam P. White <inkscapebrony@gmail.com>2014-08-17 02:47:53 +0000
committerLiam P. White <inkscapebrony@gmail.com>2014-08-17 02:47:53 +0000
commit2a2db8af11c2e518bd7bfe520e2f88a7e439d939 (patch)
treebdbf9071af198a9b54d698eef9d6a1b77f857d73
parentAdd 'Show handles' LPE (diff)
downloadinkscape-2a2db8af11c2e518bd7bfe520e2f88a7e439d939.tar.gz
inkscape-2a2db8af11c2e518bd7bfe520e2f88a7e439d939.zip
Merge in font-speedup branch to improve launch times
(bzr r13341.1.140)
-rw-r--r--src/ink-comboboxentry-action.cpp18
-rw-r--r--src/libnrtype/FontFactory.cpp76
-rw-r--r--src/libnrtype/FontFactory.h10
-rw-r--r--src/libnrtype/font-lister.cpp1697
-rw-r--r--src/libnrtype/font-lister.h556
-rw-r--r--src/ui/dialog/text-edit.cpp6
-rw-r--r--src/widgets/font-selector.cpp4
-rw-r--r--src/widgets/text-toolbar.cpp10
8 files changed, 1239 insertions, 1138 deletions
diff --git a/src/ink-comboboxentry-action.cpp b/src/ink-comboboxentry-action.cpp
index ebd238edc..6ae2a8485 100644
--- a/src/ink-comboboxentry-action.cpp
+++ b/src/ink-comboboxentry-action.cpp
@@ -383,6 +383,17 @@ GtkWidget* create_tool_item( GtkAction* action )
g_signal_connect( G_OBJECT(comboBoxEntry), "changed", G_CALLBACK(combo_box_changed_cb), action );
+ // Optionally add separator function...
+ if( ink_comboboxentry_action->separator_func != NULL ) {
+ gtk_combo_box_set_row_separator_func( ink_comboboxentry_action->combobox,
+ GtkTreeViewRowSeparatorFunc (ink_comboboxentry_action->separator_func),
+ NULL, NULL );
+ }
+
+ // FIXME: once gtk3 migration is done this can be removed
+ // https://bugzilla.gnome.org/show_bug.cgi?id=734915
+ gtk_widget_show_all (comboBoxEntry);
+
// Optionally add formatting...
if( ink_comboboxentry_action->cell_data_func != NULL ) {
GtkCellRenderer *cell = gtk_cell_renderer_text_new();
@@ -393,13 +404,6 @@ GtkWidget* create_tool_item( GtkAction* action )
NULL, NULL );
}
- // Optionally add separator function...
- if( ink_comboboxentry_action->separator_func != NULL ) {
- gtk_combo_box_set_row_separator_func( ink_comboboxentry_action->combobox,
- GtkTreeViewRowSeparatorFunc (ink_comboboxentry_action->separator_func),
- NULL, NULL );
- }
-
// Optionally widen the combobox width... which widens the drop-down list in list mode.
if( ink_comboboxentry_action->extra_width > 0 ) {
GtkRequisition req;
diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp
index 6859a4a5c..c5e68e264 100644
--- a/src/libnrtype/FontFactory.cpp
+++ b/src/libnrtype/FontFactory.cpp
@@ -513,6 +513,82 @@ static bool StyleNameCompareInternal(const StyleNames &style1, const StyleNames
return( StyleNameValue( style1.CssName ) < StyleNameValue( style2.CssName ) );
}
+static bool ustringPairSort(std::pair<PangoFontFamily*, Glib::ustring> const& first, std::pair<PangoFontFamily*, Glib::ustring> const& second)
+{
+ // well, this looks weird.
+ return first.second < second.second;
+}
+
+void font_factory::GetUIFamilies(std::vector<PangoFontFamily *>& out)
+{
+ // Gather the family names as listed by Pango
+ PangoFontFamily** families = NULL;
+ int numFamilies = 0;
+ pango_font_map_list_families(fontServer, &families, &numFamilies);
+
+ std::vector<std::pair<PangoFontFamily *, Glib::ustring> > sorted;
+
+ // not size_t
+ for (int currentFamily = 0; currentFamily < numFamilies; ++currentFamily) {
+ const char* displayName = pango_font_family_get_name(families[currentFamily]);
+
+ if (displayName == 0 || *displayName == '\0') {
+ continue;
+ }
+ sorted.push_back(std::make_pair(families[currentFamily], displayName));
+ }
+
+ std::sort(sorted.begin(), sorted.end(), ustringPairSort);
+
+ for (size_t i = 0; i < sorted.size(); ++i) {
+ out.push_back(sorted[i].first);
+ }
+}
+
+GList* font_factory::GetUIStyles(PangoFontFamily * in)
+{
+ GList* ret = NULL;
+ // Gather the styles for this family
+ PangoFontFace** faces = NULL;
+ int numFaces = 0;
+ pango_font_family_list_faces(in, &faces, &numFaces);
+
+ for (int currentFace = 0; currentFace < numFaces; currentFace++) {
+
+ // If the face has a name, describe it, and then use the
+ // description to get the UI family and face strings
+ const gchar* displayName = pango_font_face_get_face_name(faces[currentFace]);
+ if (displayName == NULL || *displayName == '\0') {
+ continue;
+ }
+
+ PangoFontDescription *faceDescr = pango_font_face_describe(faces[currentFace]);
+ if (faceDescr) {
+ Glib::ustring familyUIName = GetUIFamilyString(faceDescr);
+ Glib::ustring styleUIName = GetUIStyleString(faceDescr);
+
+ // Disable synthesized (faux) font faces except for CSS generic faces
+ if (pango_font_face_is_synthesized(faces[currentFace]) ) {
+ if (familyUIName.compare( "sans-serif" ) != 0 &&
+ familyUIName.compare( "serif" ) != 0 &&
+ familyUIName.compare( "monospace" ) != 0 &&
+ familyUIName.compare( "fantasy" ) != 0 &&
+ familyUIName.compare( "cursive" ) != 0 ) {
+ continue;
+ }
+ }
+
+ if (!familyUIName.empty() && !styleUIName.empty()) {
+ // Add the style information
+ ret = g_list_append(ret, new StyleNames(styleUIName, displayName));
+ }
+ }
+ pango_font_description_free(faceDescr);
+ }
+ g_free(faces);
+ return ret;
+}
+
void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map)
{
g_assert(map);
diff --git a/src/libnrtype/FontFactory.h b/src/libnrtype/FontFactory.h
index 513ee4bf7..c48ae831a 100644
--- a/src/libnrtype/FontFactory.h
+++ b/src/libnrtype/FontFactory.h
@@ -23,7 +23,7 @@
#include "nr-type-primitives.h"
#include "nr-type-pos-def.h"
#include "font-style-to-pos.h"
-#include "../style.h"
+#include "style.h"
/* Freetype */
#ifdef USE_PANGO_WIN32
@@ -123,7 +123,13 @@ public:
// Gathers all strings needed for UI while storing pango information in
// fontInstanceMap and fontStringMap
+ // don't use this function, it's too slow
void GetUIFamiliesAndStyles(FamilyToStylesMap *map);
+
+ // Helpfully inserts all font families into the provided vector
+ void GetUIFamilies(std::vector<PangoFontFamily *>& out);
+ // Retrieves style information about a family in a newly allocated GList.
+ GList* GetUIStyles(PangoFontFamily * in);
/// Retrieve a font_instance from a style object, first trying to use the font-specification, the CSS information
font_instance* FaceFromStyle(SPStyle const *style);
@@ -177,4 +183,4 @@ private:
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp
index 43c3045b1..07c80054d 100644
--- a/src/libnrtype/font-lister.cpp
+++ b/src/libnrtype/font-lister.cpp
@@ -1,5 +1,5 @@
#ifdef HAVE_CONFIG_H
-# include <config.h>
+#include <config.h>
#endif
#include <gtkmm/treemodel.h>
@@ -27,410 +27,432 @@
// CSS dictates that font family names are case insensitive.
// This should really implement full Unicode case unfolding.
-bool familyNamesAreEqual( const Glib::ustring &a, const Glib::ustring &b ) {
+bool familyNamesAreEqual(const Glib::ustring &a, const Glib::ustring &b)
+{
+ return (a.casefold().compare(b.casefold()) == 0);
+}
- return( a.casefold().compare( b.casefold() ) == 0 );
+static const char* sp_font_family_get_name(PangoFontFamily* family)
+{
+ const char* name = pango_font_family_get_name(family);
+ if (strncmp(name, "Sans", 4) == 0 && strlen(name) == 4)
+ return "sans-serif";
+ if (strncmp(name, "Serif", 5) == 0 && strlen(name) == 5)
+ return "serif";
+ if (strncmp(name, "Monospace", 9) == 0 && strlen(name) == 9)
+ return "monospace";
+ return name;
}
-namespace Inkscape
+namespace Inkscape {
+
+FontLister::FontLister()
{
- FontLister::FontLister ()
- {
- font_list_store = Gtk::ListStore::create (FontList);
- font_list_store->freeze_notify();
-
- FamilyToStylesMap familyStyleMap;
- font_factory::Default()->GetUIFamiliesAndStyles(&familyStyleMap);
-
- // Grab the family names into a list and then sort them
- std::list<Glib::ustring> familyList;
- for (FamilyToStylesMap::iterator iter = familyStyleMap.begin();
- iter != familyStyleMap.end();
- ++iter) {
- familyList.push_back((*iter).first);
+ font_list_store = Gtk::ListStore::create(FontList);
+ font_list_store->freeze_notify();
+
+ /* Create default styles for use when font-family is unknown on system. */
+ default_styles = g_list_append(NULL, new StyleNames("Normal"));
+ default_styles = g_list_append(default_styles, new StyleNames("Italic"));
+ default_styles = g_list_append(default_styles, new StyleNames("Bold"));
+ default_styles = g_list_append(default_styles, new StyleNames("Bold Italic"));
+
+ // Get sorted font families from Pango
+ std::vector<PangoFontFamily *> familyVector;
+ font_factory::Default()->GetUIFamilies(familyVector);
+
+ // Traverse through the family names and set up the list store
+ for (size_t i = 0; i < familyVector.size(); ++i) {
+ const char* displayName = sp_font_family_get_name(familyVector[i]);
+
+ if (displayName == 0 || *displayName == '\0') {
+ continue;
}
- familyList.sort();
- // Traverse through the family names and set up the list store (note that
- // the styles list that are the map's values are already sorted)
- while (!familyList.empty()) {
- Glib::ustring familyName = familyList.front();
- familyList.pop_front();
-
- if (!familyName.empty()) {
- Gtk::TreeModel::iterator treeModelIter = font_list_store->append();
- //(*treeModelIter)[FontList.family] = reinterpret_cast<const char*>(g_strdup(familyName.c_str()));
- (*treeModelIter)[FontList.family] = familyName;
-
- // Now go through the styles
- GList *styles = NULL;
- std::list<StyleNames> &styleStrings = familyStyleMap[familyName];
- for (std::list<StyleNames>::iterator it=styleStrings.begin();
- it != styleStrings.end();
- ++it) {
- // Our own copy
- StyleNames *copy = new StyleNames( *it );
- styles = g_list_append(styles, copy);
- }
-
- (*treeModelIter)[FontList.styles] = styles;
- (*treeModelIter)[FontList.onSystem] = true;
- }
+ Glib::ustring familyName = displayName;
+ if (!familyName.empty()) {
+ Gtk::TreeModel::iterator treeModelIter = font_list_store->append();
+ (*treeModelIter)[FontList.family] = familyName;
+
+ // we don't set this now (too slow) but the style will be cached if the user
+ // ever decides to use this font
+ (*treeModelIter)[FontList.styles] = NULL;
+ // store the pango representation for generating the style
+ (*treeModelIter)[FontList.pango_family] = familyVector[i];
+ (*treeModelIter)[FontList.onSystem] = true;
}
- current_family_row = 0;
- current_family = "sans-serif";
- current_style = "Normal";
- current_fontspec = "sans-serif"; // Empty style -> Normal
- current_fontspec_system = "Sans";
-
- /* Create default styles for use when font-family is unknown on system. */
- default_styles = g_list_append( NULL, new StyleNames( "Normal" ) );
- default_styles = g_list_append( default_styles, new StyleNames( "Italic" ) );
- default_styles = g_list_append( default_styles, new StyleNames( "Bold" ) );
- default_styles = g_list_append( default_styles, new StyleNames( "Bold Italic" ) );
-
- font_list_store->thaw_notify();
-
- style_list_store = Gtk::ListStore::create (FontStyleList);
-
- // Initialize style store with defaults
- style_list_store->freeze_notify();
- style_list_store->clear();
- for (GList *l=default_styles; l; l = l->next) {
- Gtk::TreeModel::iterator treeModelIter = style_list_store->append();
- (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames*)l->data)->CssName;
- (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames*)l->data)->DisplayName;
+ }
+
+ current_family_row = 0;
+ current_family = "sans-serif";
+ current_style = "Normal";
+ current_fontspec = "sans-serif"; // Empty style -> Normal
+ current_fontspec_system = "Sans";
+
+ font_list_store->thaw_notify();
+
+ style_list_store = Gtk::ListStore::create(FontStyleList);
+
+ // Initialize style store with defaults
+ style_list_store->freeze_notify();
+ style_list_store->clear();
+ for (GList *l = default_styles; l; l = l->next) {
+ Gtk::TreeModel::iterator treeModelIter = style_list_store->append();
+ (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames *)l->data)->CssName;
+ (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames *)l->data)->DisplayName;
+ }
+ style_list_store->thaw_notify();
+}
+
+FontLister::~FontLister()
+{
+ // Delete default_styles
+ for (GList *l = default_styles; l; l = l->next) {
+ delete ((StyleNames *)l->data);
+ }
+
+ // Delete other styles
+ Gtk::TreeModel::iterator iter = font_list_store->get_iter("0");
+ while (iter != font_list_store->children().end()) {
+ Gtk::TreeModel::Row row = *iter;
+ GList *styles = row[FontList.styles];
+ for (GList *l = styles; l; l = l->next) {
+ delete ((StyleNames *)l->data);
}
- style_list_store->thaw_notify();
+ ++iter;
}
+}
- FontLister::~FontLister() {
+FontLister *FontLister::get_instance()
+{
+ static Inkscape::FontLister *instance = new Inkscape::FontLister();
+ return instance;
+}
- // Delete default_styles
- for (GList *l=default_styles; l; l = l->next) {
- delete ((StyleNames*)l->data);
+void FontLister::ensureRowStyles(GtkTreeModel* model, GtkTreeIter const* iterator)
+{
+ Gtk::TreeIter iter(model, iterator);
+ Gtk::TreeModel::Row row = *iter;
+ if (!row[FontList.styles]) {
+ if (row[FontList.pango_family]) {
+ row[FontList.styles] = font_factory::Default()->GetUIStyles(row[FontList.pango_family]);
}
+ }
+}
- // Delete other styles
- Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" );
- while( iter != font_list_store->children().end() ) {
- Gtk::TreeModel::Row row = *iter;
- GList *styles = row[FontList.styles];
- for (GList *l=styles; l; l = l->next) {
- delete ((StyleNames*)l->data);
+// Example of how to use "foreach_iter"
+// bool
+// FontLister::print_document_font( const Gtk::TreeModel::iterator &iter ) {
+// Gtk::TreeModel::Row row = *iter;
+// if( !row[FontList.onSystem] ) {
+// std::cout << " Not on system: " << row[FontList.family] << std::endl;
+// return false;
+// }
+// return true;
+// }
+// font_list_store->foreach_iter( sigc::mem_fun(*this, &FontLister::print_document_font ));
+
+/* Used to insert a font that was not in the document and not on the system into the font list. */
+void FontLister::insert_font_family(Glib::ustring new_family)
+{
+ GList *styles = default_styles;
+
+ /* In case this is a fallback list, check if first font-family on system. */
+ std::vector<Glib::ustring> tokens = Glib::Regex::split_simple(",", new_family);
+ if (!tokens.empty() && !tokens[0].empty()) {
+ Gtk::TreeModel::iterator iter2 = font_list_store->get_iter("0");
+ while (iter2 != font_list_store->children().end()) {
+ Gtk::TreeModel::Row row = *iter2;
+ if (row[FontList.onSystem] && familyNamesAreEqual(tokens[0], row[FontList.family])) {
+ if (!row[FontList.styles]) {
+ row[FontList.styles] = font_factory::Default()->GetUIStyles(row[FontList.pango_family]);
+ }
+ styles = row[FontList.styles];
+ break;
}
- ++iter;
+ ++iter2;
}
}
- // Example of how to use "foreach_iter"
- // bool
- // FontLister::print_document_font( const Gtk::TreeModel::iterator &iter ) {
- // Gtk::TreeModel::Row row = *iter;
- // if( !row[FontList.onSystem] ) {
- // std::cout << " Not on system: " << row[FontList.family] << std::endl;
- // return false;
- // }
- // return true;
- // }
- // font_list_store->foreach_iter( sigc::mem_fun(*this, &FontLister::print_document_font ));
-
- /* Used to insert a font that was not in the document and not on the system into the font list. */
- void
- FontLister::insert_font_family( Glib::ustring new_family ) {
-
- GList *styles = default_styles;
-
- /* In case this is a fallback list, check if first font-family on system. */
- std::vector<Glib::ustring> tokens = Glib::Regex::split_simple(",", new_family );
- if( !tokens.empty() && !tokens[0].empty() ) {
-
- Gtk::TreeModel::iterator iter2 = font_list_store->get_iter( "0" );
- while( iter2 != font_list_store->children().end() ) {
- Gtk::TreeModel::Row row = *iter2;
- if( row[FontList.onSystem] && familyNamesAreEqual( tokens[0], row[FontList.family] ) ) {
- styles = row[FontList.styles];
+ Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend();
+ (*treeModelIter)[FontList.family] = new_family;
+ (*treeModelIter)[FontList.styles] = styles;
+ (*treeModelIter)[FontList.onSystem] = false;
+}
+
+void FontLister::update_font_list(SPDocument *document)
+{
+ SPObject *r = document->getRoot();
+ if (!r) {
+ return;
+ }
+
+ font_list_store->freeze_notify();
+
+ /* Find if current row is in document or system part of list */
+ gboolean row_is_system = false;
+ if (current_family_row > -1) {
+ Gtk::TreePath path;
+ path.push_back(current_family_row);
+ Gtk::TreeModel::iterator iter = font_list_store->get_iter(path);
+ if (iter) {
+ row_is_system = (*iter)[FontList.onSystem];
+ // std::cout << " In: row: " << current_family_row << " " << (*iter)[FontList.family] << std::endl;
+ }
+ }
+
+ /* Clear all old document font-family entries */
+ Gtk::TreeModel::iterator iter = font_list_store->get_iter("0");
+ while (iter != font_list_store->children().end()) {
+ Gtk::TreeModel::Row row = *iter;
+ if (!row[FontList.onSystem]) {
+ // std::cout << " Not on system: " << row[FontList.family] << std::endl;
+ iter = font_list_store->erase(iter);
+ } else {
+ // std::cout << " First on system: " << row[FontList.family] << std::endl;
break;
- }
- ++iter2;
}
- }
+ }
+
+ /* Get "font-family"s used in document. */
+ std::list<Glib::ustring> fontfamilies;
+ update_font_list_recursive(r, &fontfamilies);
+
+ fontfamilies.sort();
+ fontfamilies.unique();
+ fontfamilies.reverse();
+
- Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend();
- (*treeModelIter)[FontList.family] = reinterpret_cast<const char*>(g_strdup(new_family.c_str()));
- (*treeModelIter)[FontList.styles] = styles;
- (*treeModelIter)[FontList.onSystem] = false;
+ /* Insert separator */
+ if (!fontfamilies.empty()) {
+ Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend();
+ (*treeModelIter)[FontList.family] = "#";
+ (*treeModelIter)[FontList.onSystem] = false;
}
- void
- FontLister::update_font_list( SPDocument* document ) {
-
- SPObject *r = document->getRoot();
- if( !r ) {
- return;
- }
-
- font_list_store->freeze_notify();
-
- /* Find if current row is in document or system part of list */
- gboolean row_is_system = false;
- if( current_family_row > -1 ) {
- Gtk::TreePath path;
- path.push_back( current_family_row );
- Gtk::TreeModel::iterator iter = font_list_store->get_iter( path );
- if( iter ) {
- row_is_system = (*iter)[FontList.onSystem];
- // std::cout << " In: row: " << current_family_row << " " << (*iter)[FontList.family] << std::endl;
- }
- }
-
- /* Clear all old document font-family entries */
- Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" );
- while( iter != font_list_store->children().end() ) {
- Gtk::TreeModel::Row row = *iter;
- if( !row[FontList.onSystem] ) {
- // std::cout << " Not on system: " << row[FontList.family] << std::endl;
- iter = font_list_store->erase( iter );
- } else {
- // std::cout << " First on system: " << row[FontList.family] << std::endl;
- break;
- }
- }
-
- /* Get "font-family"s used in document. */
- std::list<Glib::ustring> fontfamilies;
- update_font_list_recursive( r, &fontfamilies );
-
- fontfamilies.sort();
- fontfamilies.unique();
- fontfamilies.reverse();
-
- /* Insert separator */
- if( !fontfamilies.empty() ) {
- Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend();
- (*treeModelIter)[FontList.family] = "#";
- (*treeModelIter)[FontList.onSystem] = false;
- }
-
- /* Insert font-family's in document. */
- std::list<Glib::ustring>::iterator i;
- for( i = fontfamilies.begin(); i != fontfamilies.end(); ++i) {
-
- GList *styles = default_styles;
+ /* Insert font-family's in document. */
+ std::list<Glib::ustring>::iterator i;
+ for (i = fontfamilies.begin(); i != fontfamilies.end(); ++i) {
+
+ GList *styles = default_styles;
/* See if font-family (or first in fallback list) is on system. If so, get styles. */
- std::vector<Glib::ustring> tokens = Glib::Regex::split_simple(",", *i );
- if( !tokens.empty() && !tokens[0].empty() ) {
-
- Gtk::TreeModel::iterator iter2 = font_list_store->get_iter( "0" );
- while( iter2 != font_list_store->children().end() ) {
- Gtk::TreeModel::Row row = *iter2;
- if( row[FontList.onSystem] && familyNamesAreEqual( tokens[0], row[FontList.family] ) ) {
- styles = row[FontList.styles];
- break;
- }
- ++iter2;
- }
- }
-
- Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend();
- (*treeModelIter)[FontList.family] = reinterpret_cast<const char*>(g_strdup((*i).c_str()));
- (*treeModelIter)[FontList.styles] = styles;
- (*treeModelIter)[FontList.onSystem] = false;
- }
-
- /* Now we do a song and dance to find the correct row as the row corresponding
- * to the current_family may have changed. We can't simply search for the
- * family name in the list since it can occur twice, once in the document
- * font family part and once in the system font family part. Above we determined
- * which part it is in.
- */
- if( current_family_row > -1 ) {
- int start = 0;
- if( row_is_system ) start = fontfamilies.size();
- int length = font_list_store->children().size();
- for( int i = 0; i < length; ++i ) {
- int row = i + start;
- if( row >= length ) row -= length;
- Gtk::TreePath path;
- path.push_back( row );
- Gtk::TreeModel::iterator iter = font_list_store->get_iter( path );
- if( iter ) {
- if( familyNamesAreEqual( current_family, (*iter)[FontList.family] ) ) {
- current_family_row = row;
- break;
- }
- }
- }
- }
- // std::cout << " Out: row: " << current_family_row << " " << current_family << std::endl;
-
- font_list_store->thaw_notify();
+ std::vector<Glib::ustring> tokens = Glib::Regex::split_simple(",", *i);
+ if (!tokens.empty() && !tokens[0].empty()) {
+
+ Gtk::TreeModel::iterator iter2 = font_list_store->get_iter("0");
+ while (iter2 != font_list_store->children().end()) {
+ Gtk::TreeModel::Row row = *iter2;
+ if (row[FontList.onSystem] && familyNamesAreEqual(tokens[0], row[FontList.family])) {
+ if (!row[FontList.styles]) {
+ row[FontList.styles] = font_factory::Default()->GetUIStyles(row[FontList.pango_family]);
+ }
+ styles = row[FontList.styles];
+ break;
+ }
+ ++iter2;
+ }
+ }
+
+ Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend();
+ (*treeModelIter)[FontList.family] = reinterpret_cast<const char *>(g_strdup((*i).c_str()));
+ (*treeModelIter)[FontList.styles] = styles;
+ (*treeModelIter)[FontList.onSystem] = false;
+
}
- void
- FontLister::update_font_list_recursive( SPObject *r, std::list<Glib::ustring> *l ) {
+ /* Now we do a song and dance to find the correct row as the row corresponding
+ * to the current_family may have changed. We can't simply search for the
+ * family name in the list since it can occur twice, once in the document
+ * font family part and once in the system font family part. Above we determined
+ * which part it is in.
+ */
+ if (current_family_row > -1) {
+ int start = 0;
+ if (row_is_system)
+ start = fontfamilies.size();
+ int length = font_list_store->children().size();
+ for (int i = 0; i < length; ++i) {
+ int row = i + start;
+ if (row >= length)
+ row -= length;
+ Gtk::TreePath path;
+ path.push_back(row);
+ Gtk::TreeModel::iterator iter = font_list_store->get_iter(path);
+ if (iter) {
+ if (familyNamesAreEqual(current_family, (*iter)[FontList.family])) {
+ current_family_row = row;
+ break;
+ }
+ }
+ }
+ }
+ // std::cout << " Out: row: " << current_family_row << " " << current_family << std::endl;
- const gchar *font_family = r->style->font_family.value;
- if( font_family ) {
- l->push_back( Glib::ustring( font_family ) );
- }
+ font_list_store->thaw_notify();
+}
- for (SPObject *child = r->firstChild(); child; child = child->getNext()) {
- update_font_list_recursive( child, l );
- }
+void FontLister::update_font_list_recursive(SPObject *r, std::list<Glib::ustring> *l)
+{
+ const gchar *font_family = r->style->font_family.value;
+ if (font_family) {
+ l->push_back(Glib::ustring(font_family));
}
- Glib::ustring
- FontLister::canonize_fontspec( Glib::ustring fontspec ) {
-
- // Pass fontspec to and back from Pango to get a the fontspec in
- // canonical form. -inkscape-font-specification relies on the
- // Pango constructed fontspec not changing form. If it does,
- // this is the place to fix it.
- PangoFontDescription *descr = pango_font_description_from_string( fontspec.c_str() );
- gchar* canonized = pango_font_description_to_string ( descr );
- Glib::ustring Canonized = canonized;
- g_free( canonized );
- pango_font_description_free( descr );
-
- // Pango canonized strings remove space after comma between family names. Put it back.
- size_t i = 0;
- while( (i = Canonized.find(",", i)) != std::string::npos) {
- Canonized.replace(i, 1, ", ");
- i += 2;
- }
-
- return Canonized;
+ for (SPObject *child = r->firstChild(); child; child = child->getNext()) {
+ update_font_list_recursive(child, l);
}
+}
+
+Glib::ustring FontLister::canonize_fontspec(Glib::ustring fontspec)
+{
- Glib::ustring
- FontLister::system_fontspec( Glib::ustring fontspec ) {
+ // Pass fontspec to and back from Pango to get a the fontspec in
+ // canonical form. -inkscape-font-specification relies on the
+ // Pango constructed fontspec not changing form. If it does,
+ // this is the place to fix it.
+ PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str());
+ gchar *canonized = pango_font_description_to_string(descr);
+ Glib::ustring Canonized = canonized;
+ g_free(canonized);
+ pango_font_description_free(descr);
+
+ // Pango canonized strings remove space after comma between family names. Put it back.
+ size_t i = 0;
+ while ((i = Canonized.find(",", i)) != std::string::npos) {
+ Canonized.replace(i, 1, ", ");
+ i += 2;
+ }
- // Find what Pango thinks is the closest match.
- Glib::ustring out = fontspec;
+ return Canonized;
+}
- PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str());
- font_instance *res = (font_factory::Default())->Face(descr);
- if (res->pFont) {
+Glib::ustring FontLister::system_fontspec(Glib::ustring fontspec)
+{
+
+ // Find what Pango thinks is the closest match.
+ Glib::ustring out = fontspec;
+
+ PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str());
+ font_instance *res = (font_factory::Default())->Face(descr);
+ if (res->pFont) {
PangoFontDescription *nFaceDesc = pango_font_describe(res->pFont);
out = sp_font_description_get_family(nFaceDesc);
- }
- pango_font_description_free(descr);
-
- return out;
}
+ pango_font_description_free(descr);
+
+ return out;
+}
- std::pair<Glib::ustring, Glib::ustring>
- FontLister::ui_from_fontspec( Glib::ustring fontspec ) {
-
- PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str());
- const gchar* family = pango_font_description_get_family(descr);
- if(!family)
- family = "sans-serif";
- Glib::ustring Family = family;
-
- // PANGO BUG...
- // A font spec of Delicious, 500 Italic should result in a family of 'Delicious'
- // and a style of 'Medium Italic'. It results instead with: a family of
- // 'Delicious, 500' with a style of 'Medium Italic'. We chop of any weight numbers
- // at the end of the family: match ",[1-9]00^".
- Glib::RefPtr<Glib::Regex> weight = Glib::Regex::create(",[1-9]00$");
- Family = weight->replace( Family, 0, "", Glib::REGEX_MATCH_PARTIAL );
-
- // Pango canonized strings remove space after comma between family names. Put it back.
- size_t i = 0;
- while( (i = Family.find(",", i)) != std::string::npos) {
- Family.replace(i, 1, ", ");
- i += 2;
- }
-
- pango_font_description_unset_fields(descr, PANGO_FONT_MASK_FAMILY);
- gchar* style = pango_font_description_to_string( descr );
- Glib::ustring Style = style;
- pango_font_description_free(descr);
- g_free( style );
-
- return std::make_pair( Family, Style );
+std::pair<Glib::ustring, Glib::ustring> FontLister::ui_from_fontspec(Glib::ustring fontspec)
+{
+ PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str());
+ const gchar *family = pango_font_description_get_family(descr);
+ if (!family)
+ family = "sans-serif";
+ Glib::ustring Family = family;
+
+ // PANGO BUG...
+ // A font spec of Delicious, 500 Italic should result in a family of 'Delicious'
+ // and a style of 'Medium Italic'. It results instead with: a family of
+ // 'Delicious, 500' with a style of 'Medium Italic'. We chop of any weight numbers
+ // at the end of the family: match ",[1-9]00^".
+ Glib::RefPtr<Glib::Regex> weight = Glib::Regex::create(",[1-9]00$");
+ Family = weight->replace(Family, 0, "", Glib::REGEX_MATCH_PARTIAL);
+
+ // Pango canonized strings remove space after comma between family names. Put it back.
+ size_t i = 0;
+ while ((i = Family.find(",", i)) != std::string::npos) {
+ Family.replace(i, 1, ", ");
+ i += 2;
}
- std::pair<Glib::ustring, Glib::ustring>
- FontLister::selection_update () {
+ pango_font_description_unset_fields(descr, PANGO_FONT_MASK_FAMILY);
+ gchar *style = pango_font_description_to_string(descr);
+ Glib::ustring Style = style;
+ pango_font_description_free(descr);
+ g_free(style);
+
+ return std::make_pair(Family, Style);
+}
+
+std::pair<Glib::ustring, Glib::ustring> FontLister::selection_update()
+{
#ifdef DEBUG_FONT
- std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
- std::cout << "FontLister::selection_update: entrance" << std::endl;
+ std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
+ std::cout << "FontLister::selection_update: entrance" << std::endl;
#endif
- // Get fontspec from a selection, preferences, or thin air.
- Glib::ustring fontspec;
- SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
-
- // Directly from stored font specification.
- int result =
- sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
-
- //std::cout << " Attempting selected style" << std::endl;
- if( result != QUERY_STYLE_NOTHING && query->font_specification.set ) {
- fontspec = query->font_specification.value;
- //std::cout << " fontspec from query :" << fontspec << ":" << std::endl;
- }
-
- // From style
- if( fontspec.empty() ) {
+ // Get fontspec from a selection, preferences, or thin air.
+ Glib::ustring fontspec;
+ SPStyle *query = sp_style_new(SP_ACTIVE_DOCUMENT);
+
+ // Directly from stored font specification.
+ int result =
+ sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
+
+ //std::cout << " Attempting selected style" << std::endl;
+ if (result != QUERY_STYLE_NOTHING && query->font_specification.set) {
+ fontspec = query->font_specification.value;
+ //std::cout << " fontspec from query :" << fontspec << ":" << std::endl;
+ }
+
+ // From style
+ if (fontspec.empty()) {
//std::cout << " Attempting desktop style" << std::endl;
- int rfamily = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY);
- int rstyle = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE);
-
- // Must have text in selection
- if( rfamily != QUERY_STYLE_NOTHING && rstyle != QUERY_STYLE_NOTHING ) {
- fontspec = fontspec_from_style( query );
- }
- //std::cout << " fontspec from style :" << fontspec << ":" << std::endl;
- }
-
- // From preferences
- if( fontspec.empty() ) {
+ int rfamily = sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY);
+ int rstyle = sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE);
+
+ // Must have text in selection
+ if (rfamily != QUERY_STYLE_NOTHING && rstyle != QUERY_STYLE_NOTHING) {
+ fontspec = fontspec_from_style(query);
+ }
+ //std::cout << " fontspec from style :" << fontspec << ":" << std::endl;
+ }
+
+ // From preferences
+ if (fontspec.empty()) {
//std::cout << " Attempting preferences" << std::endl;
sp_style_read_from_prefs(query, "/tools/text");
- fontspec = fontspec_from_style( query );
- //std::cout << " fontspec from prefs :" << fontspec << ":" << std::endl;
- }
- sp_style_unref(query);
+ fontspec = fontspec_from_style(query);
+ //std::cout << " fontspec from prefs :" << fontspec << ":" << std::endl;
+ }
+ sp_style_unref(query);
- // From thin air
- if( fontspec.empty() ) {
+ // From thin air
+ if (fontspec.empty()) {
//std::cout << " Attempting thin air" << std::endl;
- fontspec = current_family + ", " + current_style;
- //std::cout << " fontspec from thin air :" << fontspec << ":" << std::endl;
- }
-
- // Do we really need? Removes spaces between font-families.
- //current_fontspec = canonize_fontspec( fontspec );
- current_fontspec = fontspec; // Ignore for now
+ fontspec = current_family + ", " + current_style;
+ //std::cout << " fontspec from thin air :" << fontspec << ":" << std::endl;
+ }
+
+ // Do we really need? Removes spaces between font-families.
+ //current_fontspec = canonize_fontspec( fontspec );
+ current_fontspec = fontspec; // Ignore for now
- current_fontspec_system = system_fontspec( current_fontspec );
+ current_fontspec_system = system_fontspec(current_fontspec);
- std::pair<Glib::ustring, Glib::ustring> ui = ui_from_fontspec( current_fontspec );
- set_font_family( ui.first );
- set_font_style( ui.second );
+ std::pair<Glib::ustring, Glib::ustring> ui = ui_from_fontspec(current_fontspec);
+ set_font_family(ui.first);
+ set_font_style(ui.second);
#ifdef DEBUG_FONT
- std::cout << " family_row: :" << current_family_row << ":" << std::endl;
- std::cout << " canonized: :" << current_fontspec << ":" << std::endl;
- std::cout << " system: :" << current_fontspec_system << ":" << std::endl;
- std::cout << " family: :" << current_family << ":" << std::endl;
- std::cout << " style: :" << current_style << ":" << std::endl;
- std::cout << "FontLister::selection_update: exit" << std::endl;
- std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl;
+ std::cout << " family_row: :" << current_family_row << ":" << std::endl;
+ std::cout << " canonized: :" << current_fontspec << ":" << std::endl;
+ std::cout << " system: :" << current_fontspec_system << ":" << std::endl;
+ std::cout << " family: :" << current_family << ":" << std::endl;
+ std::cout << " style: :" << current_style << ":" << std::endl;
+ std::cout << "FontLister::selection_update: exit" << std::endl;
+ std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl;
#endif
- return std::make_pair( current_family, current_style );
- }
-
+ return std::make_pair(current_family, current_style);
+}
+
// Set fontspec. If check is false, best style match will not be done.
-void FontLister::set_fontspec(Glib::ustring new_fontspec, gboolean /*check*/)
+void FontLister::set_fontspec(Glib::ustring new_fontspec, bool /*check*/)
{
- std::pair<Glib::ustring,Glib::ustring> ui = ui_from_fontspec( new_fontspec );
+ std::pair<Glib::ustring, Glib::ustring> ui = ui_from_fontspec(new_fontspec);
Glib::ustring new_family = ui.first;
Glib::ustring new_style = ui.second;
@@ -439,13 +461,13 @@ void FontLister::set_fontspec(Glib::ustring new_fontspec, gboolean /*check*/)
<< " style:" << new_style << std::endl;
#endif
- set_font_family( new_family, false );
- set_font_style( new_style );
+ set_font_family(new_family, false);
+ set_font_style(new_style);
}
// TODO: use to determine font-selector best style
-std::pair<Glib::ustring, Glib::ustring> FontLister::new_font_family (Glib::ustring new_family, gboolean /*check_style*/ )
+std::pair<Glib::ustring, Glib::ustring> FontLister::new_font_family(Glib::ustring new_family, bool /*check_style*/)
{
#ifdef DEBUG_FONT
std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
@@ -453,12 +475,12 @@ std::pair<Glib::ustring, Glib::ustring> FontLister::new_font_family (Glib::ustri
#endif
// No need to do anything if new family is same as old family.
- if ( familyNamesAreEqual( new_family, current_family ) ) {
+ if (familyNamesAreEqual(new_family, current_family)) {
#ifdef DEBUG_FONT
- std::cout << "FontLister::new_font_family: exit: no change in family." << std::endl;
- std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl;
+ std::cout << "FontLister::new_font_family: exit: no change in family." << std::endl;
+ std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl;
#endif
- return std::make_pair( current_family, current_style );
+ return std::make_pair(current_family, current_style);
}
// We need to do two things:
@@ -466,596 +488,597 @@ std::pair<Glib::ustring, Glib::ustring> FontLister::new_font_family (Glib::ustri
// 2. Select best valid style match to old style.
// For finding style list, use list of first family in font-family list.
- GList* styles = NULL;
- Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" );
- while( iter != font_list_store->children().end() ) {
+ GList *styles = NULL;
+ Gtk::TreeModel::iterator iter = font_list_store->get_iter("0");
+ while (iter != font_list_store->children().end()) {
- Gtk::TreeModel::Row row = *iter;
+ Gtk::TreeModel::Row row = *iter;
- if( familyNamesAreEqual( new_family, row[FontList.family] ) ) {
+ if (familyNamesAreEqual(new_family, row[FontList.family])) {
+ if (!row[FontList.styles]) {
+ row[FontList.styles] = font_factory::Default()->GetUIStyles(row[FontList.pango_family]);
+ }
styles = row[FontList.styles];
break;
- }
- ++iter;
+ }
+ ++iter;
}
// Newly typed in font-family may not yet be in list... use default list.
// TODO: if font-family is list, check if first family in list is on system
// and set style accordingly.
- if( styles == NULL ) {
- styles = default_styles;
+ if (styles == NULL) {
+ styles = default_styles;
}
-
+
// Update style list.
style_list_store->freeze_notify();
style_list_store->clear();
- for (GList *l=styles; l; l = l->next) {
- Gtk::TreeModel::iterator treeModelIter = style_list_store->append();
- (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames*)l->data)->CssName;
- (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames*)l->data)->DisplayName;
+ for (GList *l = styles; l; l = l->next) {
+ Gtk::TreeModel::iterator treeModelIter = style_list_store->append();
+ (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames *)l->data)->CssName;
+ (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames *)l->data)->DisplayName;
}
style_list_store->thaw_notify();
-
+
// Find best match to the style from the old font-family to the
// styles available with the new font.
// TODO: Maybe check if an exact match exists before using Pango.
- Glib::ustring best_style = get_best_style_match( new_family, current_style );
+ Glib::ustring best_style = get_best_style_match(new_family, current_style);
#ifdef DEBUG_FONT
std::cout << "FontLister::new_font_family: exit: " << new_family << " " << best_style << std::endl;
std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl;
#endif
- return std::make_pair( new_family, best_style );
+ return std::make_pair(new_family, best_style);
}
-
- std::pair<Glib::ustring, Glib::ustring>
- FontLister::set_font_family (Glib::ustring new_family, gboolean check_style) {
+
+std::pair<Glib::ustring, Glib::ustring> FontLister::set_font_family(Glib::ustring new_family, bool check_style)
+{
#ifdef DEBUG_FONT
- std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
- std::cout << "FontLister::set_font_family: " << new_family << std::endl;
+ std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
+ std::cout << "FontLister::set_font_family: " << new_family << std::endl;
#endif
- std::pair<Glib::ustring, Glib::ustring> ui = new_font_family( new_family, check_style );
- current_family = ui.first;
- current_style = ui.second;
- current_fontspec = canonize_fontspec( current_family + ", " + current_style );
- current_fontspec_system = system_fontspec( current_fontspec );
+ std::pair<Glib::ustring, Glib::ustring> ui = new_font_family(new_family, check_style);
+ current_family = ui.first;
+ current_style = ui.second;
+ current_fontspec = canonize_fontspec(current_family + ", " + current_style);
+ current_fontspec_system = system_fontspec(current_fontspec);
#ifdef DEBUG_FONT
- std::cout << " family_row: :" << current_family_row << ":" << std::endl;
- std::cout << " canonized: :" << current_fontspec << ":" << std::endl;
- std::cout << " system: :" << current_fontspec_system << ":" << std::endl;
- std::cout << " family: :" << current_family << ":" << std::endl;
- std::cout << " style: :" << current_style << ":" << std::endl;
- std::cout << "FontLister::set_font_family: end" << std::endl;
- std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl;
+ std::cout << " family_row: :" << current_family_row << ":" << std::endl;
+ std::cout << " canonized: :" << current_fontspec << ":" << std::endl;
+ std::cout << " system: :" << current_fontspec_system << ":" << std::endl;
+ std::cout << " family: :" << current_family << ":" << std::endl;
+ std::cout << " style: :" << current_style << ":" << std::endl;
+ std::cout << "FontLister::set_font_family: end" << std::endl;
+ std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl;
#endif
- return ui;
- }
-
+ return ui;
+}
- std::pair<Glib::ustring, Glib::ustring>
- FontLister::set_font_family (int row, gboolean check_style) {
+
+std::pair<Glib::ustring, Glib::ustring> FontLister::set_font_family(int row, bool check_style)
+{
#ifdef DEBUG_FONT
- std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
- std::cout << "FontLister::set_font_family( row ): " << row << std::endl;
+ std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
+ std::cout << "FontLister::set_font_family( row ): " << row << std::endl;
#endif
- current_family_row = row;
- Gtk::TreePath path;
- path.push_back( row );
- Glib::ustring new_family = current_family;
- Gtk::TreeModel::iterator iter = font_list_store->get_iter( path );
- if( iter ) {
- new_family = (*iter)[FontList.family];
- }
+ current_family_row = row;
+ Gtk::TreePath path;
+ path.push_back(row);
+ Glib::ustring new_family = current_family;
+ Gtk::TreeModel::iterator iter = font_list_store->get_iter(path);
+ if (iter) {
+ new_family = (*iter)[FontList.family];
+ }
- std::pair<Glib::ustring, Glib::ustring> ui = set_font_family( new_family, check_style );
+ std::pair<Glib::ustring, Glib::ustring> ui = set_font_family(new_family, check_style);
#ifdef DEBUG_FONT
- std::cout << "FontLister::set_font_family( row ): end" << std::endl;
- std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl;
+ std::cout << "FontLister::set_font_family( row ): end" << std::endl;
+ std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl;
#endif
- return ui;
- }
+ return ui;
+}
- void
- FontLister::set_font_style (Glib::ustring new_style) {
+void FontLister::set_font_style(Glib::ustring new_style)
+{
- // TODO: Validate input using Pango. If Pango doesn't recognize a style it will
- // attach the "invalid" style to the font-family.
+// TODO: Validate input using Pango. If Pango doesn't recognize a style it will
+// attach the "invalid" style to the font-family.
#ifdef DEBUG_FONT
- std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
- std::cout << "FontLister:set_font_style: " << new_style << std::endl;
+ std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
+ std::cout << "FontLister:set_font_style: " << new_style << std::endl;
#endif
- current_style = new_style;
- current_fontspec = canonize_fontspec( current_family + ", " + current_style );
- current_fontspec_system = system_fontspec( current_fontspec );
+ current_style = new_style;
+ current_fontspec = canonize_fontspec(current_family + ", " + current_style);
+ current_fontspec_system = system_fontspec(current_fontspec);
#ifdef DEBUG_FONT
- std::cout << " canonized: :" << current_fontspec << ":" << std::endl;
- std::cout << " system: :" << current_fontspec_system << ":" << std::endl;
- std::cout << " family: " << current_family << std::endl;
- std::cout << " style: " << current_style << std::endl;
- std::cout << "FontLister::set_font_style: end" << std::endl;
- std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl;
+ std::cout << " canonized: :" << current_fontspec << ":" << std::endl;
+ std::cout << " system: :" << current_fontspec_system << ":" << std::endl;
+ std::cout << " family: " << current_family << std::endl;
+ std::cout << " style: " << current_style << std::endl;
+ std::cout << "FontLister::set_font_style: end" << std::endl;
+ std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl;
#endif
+}
+
+
+// We do this ourselves as we can't rely on FontFactory.
+void FontLister::fill_css(SPCSSAttr *css, Glib::ustring fontspec)
+{
+
+ if (fontspec.empty()) {
+ fontspec = current_fontspec;
+ }
+ std::pair<Glib::ustring, Glib::ustring> ui = ui_from_fontspec(fontspec);
+
+ Glib::ustring family = ui.first;
+
+
+ // Font spec is single quoted... for the moment
+ Glib::ustring fontspec_quoted(fontspec);
+ css_quote(fontspec_quoted);
+ sp_repr_css_set_property(css, "-inkscape-font-specification", fontspec_quoted.c_str());
+
+ // Font families needs to be properly quoted in CSS (used unquoted in font-lister)
+ css_font_family_quote(family);
+ sp_repr_css_set_property(css, "font-family", family.c_str());
+
+ PangoFontDescription *desc = pango_font_description_from_string(fontspec.c_str());
+ PangoWeight weight = pango_font_description_get_weight(desc);
+ switch (weight) {
+ case PANGO_WEIGHT_THIN:
+ sp_repr_css_set_property(css, "font-weight", "100");
+ break;
+ case PANGO_WEIGHT_ULTRALIGHT:
+ sp_repr_css_set_property(css, "font-weight", "200");
+ break;
+ case PANGO_WEIGHT_LIGHT:
+ sp_repr_css_set_property(css, "font-weight", "300");
+ break;
+ case PANGO_WEIGHT_BOOK:
+ sp_repr_css_set_property(css, "font-weight", "380");
+ break;
+ case PANGO_WEIGHT_NORMAL:
+ sp_repr_css_set_property(css, "font-weight", "normal");
+ break;
+ case PANGO_WEIGHT_MEDIUM:
+ sp_repr_css_set_property(css, "font-weight", "500");
+ break;
+ case PANGO_WEIGHT_SEMIBOLD:
+ sp_repr_css_set_property(css, "font-weight", "600");
+ break;
+ case PANGO_WEIGHT_BOLD:
+ sp_repr_css_set_property(css, "font-weight", "bold");
+ break;
+ case PANGO_WEIGHT_ULTRABOLD:
+ sp_repr_css_set_property(css, "font-weight", "800");
+ break;
+ case PANGO_WEIGHT_HEAVY:
+ sp_repr_css_set_property(css, "font-weight", "900");
+ break;
+ case PANGO_WEIGHT_ULTRAHEAVY:
+ sp_repr_css_set_property(css, "font-weight", "1000");
+ break;
+ }
+
+ PangoStyle style = pango_font_description_get_style(desc);
+ switch (style) {
+ case PANGO_STYLE_NORMAL:
+ sp_repr_css_set_property(css, "font-style", "normal");
+ break;
+ case PANGO_STYLE_OBLIQUE:
+ sp_repr_css_set_property(css, "font-style", "oblique");
+ break;
+ case PANGO_STYLE_ITALIC:
+ sp_repr_css_set_property(css, "font-style", "italic");
+ break;
}
+ PangoStretch stretch = pango_font_description_get_stretch(desc);
+ switch (stretch) {
+ case PANGO_STRETCH_ULTRA_CONDENSED:
+ sp_repr_css_set_property(css, "font-stretch", "ultra-condensed");
+ break;
+ case PANGO_STRETCH_EXTRA_CONDENSED:
+ sp_repr_css_set_property(css, "font-stretch", "extra-condensed");
+ break;
+ case PANGO_STRETCH_CONDENSED:
+ sp_repr_css_set_property(css, "font-stretch", "condensed");
+ break;
+ case PANGO_STRETCH_SEMI_CONDENSED:
+ sp_repr_css_set_property(css, "font-stretch", "semi-condensed");
+ break;
+ case PANGO_STRETCH_NORMAL:
+ sp_repr_css_set_property(css, "font-stretch", "normal");
+ break;
+ case PANGO_STRETCH_SEMI_EXPANDED:
+ sp_repr_css_set_property(css, "font-stretch", "semi-expanded");
+ break;
+ case PANGO_STRETCH_EXPANDED:
+ sp_repr_css_set_property(css, "font-stretch", "expanded");
+ break;
+ case PANGO_STRETCH_EXTRA_EXPANDED:
+ sp_repr_css_set_property(css, "font-stretch", "extra-expanded");
+ break;
+ case PANGO_STRETCH_ULTRA_EXPANDED:
+ sp_repr_css_set_property(css, "font-stretch", "ultra-expanded");
+ break;
+ }
- // We do this ourselves as we can't rely on FontFactory.
- void
- FontLister::fill_css( SPCSSAttr *css, Glib::ustring fontspec ) {
-
- if( fontspec.empty() ) {
- fontspec = current_fontspec;
- }
- std::pair<Glib::ustring,Glib::ustring> ui = ui_from_fontspec( fontspec );
-
- Glib::ustring family = ui.first;
-
-
- // Font spec is single quoted... for the moment
- Glib::ustring fontspec_quoted( fontspec );
- css_quote( fontspec_quoted );
- sp_repr_css_set_property (css, "-inkscape-font-specification", fontspec_quoted.c_str() );
-
- // Font families needs to be properly quoted in CSS (used unquoted in font-lister)
- css_font_family_quote( family );
- sp_repr_css_set_property (css, "font-family", family.c_str() );
-
- PangoFontDescription *desc = pango_font_description_from_string( fontspec.c_str() );
- PangoWeight weight = pango_font_description_get_weight( desc );
- switch ( weight ) {
- case PANGO_WEIGHT_THIN:
- sp_repr_css_set_property (css, "font-weight", "100" );
- break;
- case PANGO_WEIGHT_ULTRALIGHT:
- sp_repr_css_set_property (css, "font-weight", "200" );
- break;
- case PANGO_WEIGHT_LIGHT:
- sp_repr_css_set_property (css, "font-weight", "300" );
- break;
- case PANGO_WEIGHT_BOOK:
- sp_repr_css_set_property (css, "font-weight", "380" );
- break;
- case PANGO_WEIGHT_NORMAL:
- sp_repr_css_set_property (css, "font-weight", "normal" );
- break;
- case PANGO_WEIGHT_MEDIUM:
- sp_repr_css_set_property (css, "font-weight", "500" );
- break;
- case PANGO_WEIGHT_SEMIBOLD:
- sp_repr_css_set_property (css, "font-weight", "600" );
- break;
- case PANGO_WEIGHT_BOLD:
- sp_repr_css_set_property (css, "font-weight", "bold" );
- break;
- case PANGO_WEIGHT_ULTRABOLD:
- sp_repr_css_set_property (css, "font-weight", "800" );
- break;
- case PANGO_WEIGHT_HEAVY:
- sp_repr_css_set_property (css, "font-weight", "900" );
- break;
- case PANGO_WEIGHT_ULTRAHEAVY:
- sp_repr_css_set_property (css, "font-weight", "1000" );
- break;
- }
-
- PangoStyle style = pango_font_description_get_style( desc );
- switch ( style ) {
- case PANGO_STYLE_NORMAL:
- sp_repr_css_set_property (css, "font-style", "normal" );
- break;
- case PANGO_STYLE_OBLIQUE:
- sp_repr_css_set_property (css, "font-style", "oblique" );
- break;
- case PANGO_STYLE_ITALIC:
- sp_repr_css_set_property (css, "font-style", "italic" );
- break;
- }
-
- PangoStretch stretch = pango_font_description_get_stretch( desc );
- switch ( stretch ) {
- case PANGO_STRETCH_ULTRA_CONDENSED:
- sp_repr_css_set_property (css, "font-stretch", "ultra-condensed" );
- break;
- case PANGO_STRETCH_EXTRA_CONDENSED:
- sp_repr_css_set_property (css, "font-stretch", "extra-condensed" );
- break;
- case PANGO_STRETCH_CONDENSED:
- sp_repr_css_set_property (css, "font-stretch", "condensed" );
- break;
- case PANGO_STRETCH_SEMI_CONDENSED:
- sp_repr_css_set_property (css, "font-stretch", "semi-condensed" );
- break;
- case PANGO_STRETCH_NORMAL:
- sp_repr_css_set_property (css, "font-stretch", "normal" );
- break;
- case PANGO_STRETCH_SEMI_EXPANDED:
- sp_repr_css_set_property (css, "font-stretch", "semi-expanded" );
- break;
- case PANGO_STRETCH_EXPANDED:
- sp_repr_css_set_property (css, "font-stretch", "expanded" );
- break;
- case PANGO_STRETCH_EXTRA_EXPANDED:
- sp_repr_css_set_property (css, "font-stretch", "extra-expanded" );
- break;
- case PANGO_STRETCH_ULTRA_EXPANDED:
- sp_repr_css_set_property (css, "font-stretch", "ultra-expanded" );
- break;
- }
-
- PangoVariant variant = pango_font_description_get_variant( desc );
- switch ( variant ) {
- case PANGO_VARIANT_NORMAL:
- sp_repr_css_set_property (css, "font-variant", "normal" );
- break;
- case PANGO_VARIANT_SMALL_CAPS:
- sp_repr_css_set_property (css, "font-variant", "small-caps" );
- break;
- }
+ PangoVariant variant = pango_font_description_get_variant(desc);
+ switch (variant) {
+ case PANGO_VARIANT_NORMAL:
+ sp_repr_css_set_property(css, "font-variant", "normal");
+ break;
+ case PANGO_VARIANT_SMALL_CAPS:
+ sp_repr_css_set_property(css, "font-variant", "small-caps");
+ break;
}
+}
- // We do this ourselves as we can't rely on FontFactory.
- Glib::ustring
- FontLister::fontspec_from_style (SPStyle* style) {
+// We do this ourselves as we can't rely on FontFactory.
+Glib::ustring FontLister::fontspec_from_style(SPStyle *style)
+{
- //std::cout << "FontLister:fontspec_from_style: " << std::endl;
+ //std::cout << "FontLister:fontspec_from_style: " << std::endl;
- Glib::ustring fontspec;
- if (style) {
+ Glib::ustring fontspec;
+ if (style) {
- // First try to use the font specification if it is set
- if (style->font_specification.set
- && style->font_specification.value
- && *style->font_specification.value) {
+ // First try to use the font specification if it is set
+ if (style->font_specification.set && style->font_specification.value && *style->font_specification.value) {
- fontspec = style->font_specification.value;
+ fontspec = style->font_specification.value;
} else {
- fontspec = style->font_family.value;
- fontspec += ",";
-
- // Use weight names as defined by Pango
- switch (style->font_weight.computed) {
+ fontspec = style->font_family.value;
+ fontspec += ",";
- case SP_CSS_FONT_WEIGHT_100:
- fontspec += " Thin";
- break;
-
- case SP_CSS_FONT_WEIGHT_200:
- fontspec += " Ultra-Light";
- break;
+ // Use weight names as defined by Pango
+ switch (style->font_weight.computed) {
- case SP_CSS_FONT_WEIGHT_300:
- fontspec += " Light";
- break;
+ case SP_CSS_FONT_WEIGHT_100:
+ fontspec += " Thin";
+ break;
- case SP_CSS_FONT_WEIGHT_400:
- case SP_CSS_FONT_WEIGHT_NORMAL:
- //fontspec += " normal";
- break;
-
- case SP_CSS_FONT_WEIGHT_500:
- fontspec += " Medium";
- break;
-
- case SP_CSS_FONT_WEIGHT_600:
- fontspec += " Semi-Bold";
- break;
-
- case SP_CSS_FONT_WEIGHT_700:
- case SP_CSS_FONT_WEIGHT_BOLD:
- fontspec += " Bold";
- break;
-
- case SP_CSS_FONT_WEIGHT_800:
- fontspec += " Ultra-Bold";
- break;
-
- case SP_CSS_FONT_WEIGHT_900:
- fontspec += " Heavy";
- break;
-
- case SP_CSS_FONT_WEIGHT_LIGHTER:
- case SP_CSS_FONT_WEIGHT_BOLDER:
- default:
- g_warning("Unrecognized font_weight.computed value");
- break;
- }
-
- switch (style->font_style.computed) {
- case SP_CSS_FONT_STYLE_ITALIC:
- fontspec += " italic";
- break;
-
- case SP_CSS_FONT_STYLE_OBLIQUE:
- fontspec += " oblique";
- break;
-
- case SP_CSS_FONT_STYLE_NORMAL:
- default:
- //fontspec += " normal";
- break;
- }
-
- switch (style->font_stretch.computed) {
-
- case SP_CSS_FONT_STRETCH_ULTRA_CONDENSED:
- fontspec += " extra-condensed";
- break;
-
- case SP_CSS_FONT_STRETCH_EXTRA_CONDENSED:
- fontspec += " extra-condensed";
- break;
-
- case SP_CSS_FONT_STRETCH_CONDENSED:
- case SP_CSS_FONT_STRETCH_NARROWER:
- fontspec += " condensed";
- break;
-
- case SP_CSS_FONT_STRETCH_SEMI_CONDENSED:
- fontspec += " semi-condensed";
- break;
-
- case SP_CSS_FONT_STRETCH_NORMAL:
- //fontspec += " normal";
- break;
-
- case SP_CSS_FONT_STRETCH_SEMI_EXPANDED:
- fontspec += " semi-expanded";
- break;
-
- case SP_CSS_FONT_STRETCH_EXPANDED:
- case SP_CSS_FONT_STRETCH_WIDER:
- fontspec += " expanded";
- break;
-
- case SP_CSS_FONT_STRETCH_EXTRA_EXPANDED:
- fontspec += " extra-expanded";
- break;
-
- case SP_CSS_FONT_STRETCH_ULTRA_EXPANDED:
- fontspec += " ultra-expanded";
- break;
-
- default:
- //fontspec += " normal";
- break;
- }
-
- switch (style->font_variant.computed) {
-
- case SP_CSS_FONT_VARIANT_SMALL_CAPS:
- fontspec += "small-caps";
- break;
-
- default:
- //fontspec += "normal";
- break;
- }
- }
- }
- return canonize_fontspec( fontspec );
- }
+ case SP_CSS_FONT_WEIGHT_200:
+ fontspec += " Ultra-Light";
+ break;
+ case SP_CSS_FONT_WEIGHT_300:
+ fontspec += " Light";
+ break;
- Gtk::TreeModel::Row
- FontLister::get_row_for_font (Glib::ustring family)
- {
- Gtk::TreePath path;
+ case SP_CSS_FONT_WEIGHT_400:
+ case SP_CSS_FONT_WEIGHT_NORMAL:
+ //fontspec += " normal";
+ break;
+
+ case SP_CSS_FONT_WEIGHT_500:
+ fontspec += " Medium";
+ break;
+
+ case SP_CSS_FONT_WEIGHT_600:
+ fontspec += " Semi-Bold";
+ break;
- Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" );
- while( iter != font_list_store->children().end() ) {
+ case SP_CSS_FONT_WEIGHT_700:
+ case SP_CSS_FONT_WEIGHT_BOLD:
+ fontspec += " Bold";
+ break;
- Gtk::TreeModel::Row row = *iter;
+ case SP_CSS_FONT_WEIGHT_800:
+ fontspec += " Ultra-Bold";
+ break;
- if( familyNamesAreEqual( family, row[FontList.family] ) ) {
- return row;
- }
+ case SP_CSS_FONT_WEIGHT_900:
+ fontspec += " Heavy";
+ break;
- ++iter;
- }
+ case SP_CSS_FONT_WEIGHT_LIGHTER:
+ case SP_CSS_FONT_WEIGHT_BOLDER:
+ default:
+ g_warning("Unrecognized font_weight.computed value");
+ break;
+ }
- throw FAMILY_NOT_FOUND;
- }
+ switch (style->font_style.computed) {
+ case SP_CSS_FONT_STYLE_ITALIC:
+ fontspec += " italic";
+ break;
- Gtk::TreePath
- FontLister::get_path_for_font (Glib::ustring family)
- {
- return font_list_store->get_path( get_row_for_font ( family ) );
+ case SP_CSS_FONT_STYLE_OBLIQUE:
+ fontspec += " oblique";
+ break;
+
+ case SP_CSS_FONT_STYLE_NORMAL:
+ default:
+ //fontspec += " normal";
+ break;
+ }
+
+ switch (style->font_stretch.computed) {
+
+ case SP_CSS_FONT_STRETCH_ULTRA_CONDENSED:
+ fontspec += " extra-condensed";
+ break;
+
+ case SP_CSS_FONT_STRETCH_EXTRA_CONDENSED:
+ fontspec += " extra-condensed";
+ break;
+
+ case SP_CSS_FONT_STRETCH_CONDENSED:
+ case SP_CSS_FONT_STRETCH_NARROWER:
+ fontspec += " condensed";
+ break;
+
+ case SP_CSS_FONT_STRETCH_SEMI_CONDENSED:
+ fontspec += " semi-condensed";
+ break;
+
+ case SP_CSS_FONT_STRETCH_NORMAL:
+ //fontspec += " normal";
+ break;
+
+ case SP_CSS_FONT_STRETCH_SEMI_EXPANDED:
+ fontspec += " semi-expanded";
+ break;
+
+ case SP_CSS_FONT_STRETCH_EXPANDED:
+ case SP_CSS_FONT_STRETCH_WIDER:
+ fontspec += " expanded";
+ break;
+
+ case SP_CSS_FONT_STRETCH_EXTRA_EXPANDED:
+ fontspec += " extra-expanded";
+ break;
+
+ case SP_CSS_FONT_STRETCH_ULTRA_EXPANDED:
+ fontspec += " ultra-expanded";
+ break;
+
+ default:
+ //fontspec += " normal";
+ break;
+ }
+
+ switch (style->font_variant.computed) {
+
+ case SP_CSS_FONT_VARIANT_SMALL_CAPS:
+ fontspec += "small-caps";
+ break;
+
+ default:
+ //fontspec += "normal";
+ break;
+ }
+ }
}
+ return canonize_fontspec(fontspec);
+}
- 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() ) {
+Gtk::TreeModel::Row FontLister::get_row_for_font(Glib::ustring family)
+{
+ Gtk::TreePath path;
- Gtk::TreeModel::Row row = *iter;
+ Gtk::TreeModel::iterator iter = font_list_store->get_iter("0");
+ while (iter != font_list_store->children().end()) {
- if( familyNamesAreEqual( style, row[FontStyleList.cssStyle] ) ) {
- return row;
- }
+ Gtk::TreeModel::Row row = *iter;
- ++iter;
- }
+ if (familyNamesAreEqual(family, row[FontList.family])) {
+ return row;
+ }
- throw STYLE_NOT_FOUND;
+ ++iter;
}
- static gint
- compute_distance (const PangoFontDescription *a,
- const PangoFontDescription *b ) {
-
- // Weight: multiples of 100
- gint distance = abs( pango_font_description_get_weight( a ) -
- pango_font_description_get_weight( b ) );
-
- distance += 10000 * abs( pango_font_description_get_stretch( a ) -
- pango_font_description_get_stretch( b ) );
-
- PangoStyle style_a = pango_font_description_get_style( a );
- PangoStyle style_b = pango_font_description_get_style( b );
- if( style_a != style_b ) {
- if( (style_a == PANGO_STYLE_OBLIQUE && style_b == PANGO_STYLE_ITALIC) ||
- (style_b == PANGO_STYLE_OBLIQUE && style_a == PANGO_STYLE_ITALIC) ) {
- distance += 1000; // Oblique and italic are almost the same
- } else {
- distance += 100000; // Normal vs oblique/italic, not so similar
- }
- }
-
- // Normal vs small-caps
- distance += 1000000 * abs( pango_font_description_get_variant( a ) -
- pango_font_description_get_variant( b ) );
- return distance;
+ throw FAMILY_NOT_FOUND;
+}
+
+Gtk::TreePath FontLister::get_path_for_font(Glib::ustring family)
+{
+ return font_list_store->get_path(get_row_for_font(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()) {
+
+ Gtk::TreeModel::Row row = *iter;
+
+ if (familyNamesAreEqual(style, row[FontStyleList.cssStyle])) {
+ return row;
+ }
+
+ ++iter;
}
- // This is inspired by pango_font_description_better_match, but that routine
- // always returns false if variant or stretch are different. This means, for
- // example, that PT Sans Narrow with style Bold Condensed is never matched
- // to another font-family with Bold style.
- gboolean
- font_description_better_match( PangoFontDescription* target,
- PangoFontDescription* old_desc,
- PangoFontDescription* new_desc ) {
+ throw STYLE_NOT_FOUND;
+}
+
+static gint compute_distance(const PangoFontDescription *a, const PangoFontDescription *b)
+{
- if( old_desc == NULL ) return true;
- if( new_desc == NULL ) return false;
+ // Weight: multiples of 100
+ gint distance = abs(pango_font_description_get_weight(a) -
+ pango_font_description_get_weight(b));
- int old_distance = compute_distance( target, old_desc );
- int new_distance = compute_distance( target, new_desc );
- //std::cout << "font_description_better_match: old: " << old_distance << std::endl;
- //std::cout << " new: " << new_distance << std::endl;
+ distance += 10000 * abs(pango_font_description_get_stretch(a) -
+ pango_font_description_get_stretch(b));
- return (new_distance < old_distance );
+ PangoStyle style_a = pango_font_description_get_style(a);
+ PangoStyle style_b = pango_font_description_get_style(b);
+ if (style_a != style_b) {
+ if ((style_a == PANGO_STYLE_OBLIQUE && style_b == PANGO_STYLE_ITALIC) ||
+ (style_b == PANGO_STYLE_OBLIQUE && style_a == PANGO_STYLE_ITALIC)) {
+ distance += 1000; // Oblique and italic are almost the same
+ } else {
+ distance += 100000; // Normal vs oblique/italic, not so similar
+ }
}
- // void
- // font_description_dump( PangoFontDescription* target ) {
- // std::cout << " Font: " << pango_font_description_to_string( target ) << std::endl;
- // std::cout << " style: " << pango_font_description_get_style( target ) << std::endl;
- // std::cout << " weight: " << pango_font_description_get_weight( target ) << std::endl;
- // std::cout << " variant: " << pango_font_description_get_variant( target ) << std::endl;
- // std::cout << " stretch: " << pango_font_description_get_stretch( target ) << std::endl;
- // std::cout << " gravity: " << pango_font_description_get_gravity( target ) << std::endl;
- // }
-
- /* Returns style string */
- // TODO: Remove or turn into function to be used by new_font_family.
- Glib::ustring
- FontLister::get_best_style_match (Glib::ustring family, Glib::ustring target_style) {
+ // Normal vs small-caps
+ distance += 1000000 * abs(pango_font_description_get_variant(a) -
+ pango_font_description_get_variant(b));
+ return distance;
+}
-#ifdef DEBUG_FONT
- std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
- std::cout << "FontLister::get_best_style_match: " << family << " : " << target_style << std::endl;
-#endif
+// This is inspired by pango_font_description_better_match, but that routine
+// always returns false if variant or stretch are different. This means, for
+// example, that PT Sans Narrow with style Bold Condensed is never matched
+// to another font-family with Bold style.
+gboolean font_description_better_match(PangoFontDescription *target, PangoFontDescription *old_desc, PangoFontDescription *new_desc)
+{
+ if (old_desc == NULL)
+ return true;
+ if (new_desc == NULL)
+ return false;
+
+ int old_distance = compute_distance(target, old_desc);
+ int new_distance = compute_distance(target, new_desc);
+ //std::cout << "font_description_better_match: old: " << old_distance << std::endl;
+ //std::cout << " new: " << new_distance << std::endl;
- Glib::ustring fontspec = family + ", " + target_style;
-
- Gtk::TreeModel::Row row;
- try {
- row = get_row_for_font( family );
- } catch (...) {
- //std::cout << " ERROR: can't find family: " << family << std::endl;
- return (target_style);
- }
-
- PangoFontDescription* target = pango_font_description_from_string( fontspec.c_str() );
- PangoFontDescription* best = NULL;
-
- //font_description_dump( target );
-
- GList* styles = row[FontList.styles];
- for (GList *l=styles; l; l = l->next) {
- Glib::ustring fontspec = family + ", " + (char*)l->data;
- PangoFontDescription* candidate = pango_font_description_from_string( fontspec.c_str() );
- //font_description_dump( candidate );
- //std::cout << " " << font_description_better_match( target, best, candidate ) << std::endl;
- if( font_description_better_match( target, best, candidate ) ) {
- pango_font_description_free( best );
- best = candidate;
- //std::cout << " ... better: " << std::endl;
- } else {
- pango_font_description_free( candidate );
- //std::cout << " ... not better: " << std::endl;
- }
- }
-
- Glib::ustring best_style = target_style;
- if( best ) {
- pango_font_description_unset_fields( best, PANGO_FONT_MASK_FAMILY );
- best_style = pango_font_description_to_string( best );
- }
-
- if( target ) pango_font_description_free( target );
- if( best ) pango_font_description_free( best );
+ return (new_distance < old_distance);
+}
+// void
+// font_description_dump( PangoFontDescription* target ) {
+// std::cout << " Font: " << pango_font_description_to_string( target ) << std::endl;
+// std::cout << " style: " << pango_font_description_get_style( target ) << std::endl;
+// std::cout << " weight: " << pango_font_description_get_weight( target ) << std::endl;
+// std::cout << " variant: " << pango_font_description_get_variant( target ) << std::endl;
+// std::cout << " stretch: " << pango_font_description_get_stretch( target ) << std::endl;
+// std::cout << " gravity: " << pango_font_description_get_gravity( target ) << std::endl;
+// }
+
+/* Returns style string */
+// TODO: Remove or turn into function to be used by new_font_family.
+Glib::ustring FontLister::get_best_style_match(Glib::ustring family, Glib::ustring target_style)
+{
#ifdef DEBUG_FONT
- std::cout << " Returning: " << best_style << std::endl;
- std::cout << "FontLister::get_best_style_match: exit" << std::endl;
- std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl;
+ std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
+ std::cout << "FontLister::get_best_style_match: " << family << " : " << target_style << std::endl;
#endif
- return best_style;
- }
- const Glib::RefPtr<Gtk::ListStore>
- FontLister::get_font_list () const
+ Glib::ustring fontspec = family + ", " + target_style;
+
+ Gtk::TreeModel::Row row;
+ try
{
- return font_list_store;
+ row = get_row_for_font(family);
}
-
- const Glib::RefPtr<Gtk::ListStore>
- FontLister::get_style_list () const
+ catch (...)
{
- return style_list_store;
+ //std::cout << " ERROR: can't find family: " << family << std::endl;
+ return (target_style);
}
+
+ PangoFontDescription *target = pango_font_description_from_string(fontspec.c_str());
+ PangoFontDescription *best = NULL;
+
+ //font_description_dump( target );
+
+ if (!row[FontList.styles]) {
+ row[FontList.styles] = font_factory::Default()->GetUIStyles(row[FontList.pango_family]);
+ }
+ GList *styles = row[FontList.styles];
+ for (GList *l = styles; l; l = l->next) {
+ Glib::ustring fontspec = family + ", " + (char *)l->data;
+ PangoFontDescription *candidate = pango_font_description_from_string(fontspec.c_str());
+ //font_description_dump( candidate );
+ //std::cout << " " << font_description_better_match( target, best, candidate ) << std::endl;
+ if (font_description_better_match(target, best, candidate)) {
+ pango_font_description_free(best);
+ best = candidate;
+ //std::cout << " ... better: " << std::endl;
+ } else {
+ pango_font_description_free(candidate);
+ //std::cout << " ... not better: " << std::endl;
+ }
+ }
+
+ Glib::ustring best_style = target_style;
+ if (best) {
+ pango_font_description_unset_fields(best, PANGO_FONT_MASK_FAMILY);
+ best_style = pango_font_description_to_string(best);
+ }
+
+ if (target)
+ pango_font_description_free(target);
+ if (best)
+ pango_font_description_free(best);
+
+
+#ifdef DEBUG_FONT
+ std::cout << " Returning: " << best_style << std::endl;
+ std::cout << "FontLister::get_best_style_match: exit" << std::endl;
+ std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl;
+#endif
+ return best_style;
}
+const Glib::RefPtr<Gtk::ListStore> FontLister::get_font_list() const
+{
+ return font_list_store;
+}
+
+const Glib::RefPtr<Gtk::ListStore> FontLister::get_style_list() const
+{
+ return style_list_store;
+}
+
+} // namespace Inkscape
+
// Helper functions
// Separator function (if true, a separator will be drawn)
-gboolean font_lister_separator_func(GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer /*data*/)
+gboolean font_lister_separator_func(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);
+ 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*/,
- GtkCellRenderer *cell,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer /*data*/)
+void font_lister_cell_data_func(GtkCellLayout * /*cell_layout*/,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer /*data*/)
{
gchar *family;
gboolean onSystem = false;
gtk_tree_model_get(model, iter, 0, &family, 2, &onSystem, -1);
- Glib::ustring family_escaped = g_markup_escape_text(family, -1);
+ gchar* family_escaped = g_markup_escape_text(family, -1);
//g_free(family);
Glib::ustring markup;
- if( !onSystem ) {
+ if (!onSystem) {
markup = "<span foreground='darkblue'>";
/* See if font-family on system */
- std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("\\s*,\\s*", family_escaped );
- for( size_t i=0; i < tokens.size(); ++i ) {
+ std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("\\s*,\\s*", family_escaped);
+ for (size_t i = 0; i < tokens.size(); ++i) {
Glib::ustring token = tokens[i];
@@ -1064,17 +1087,17 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/,
gchar *family = 0;
gboolean onSystem = true;
gboolean found = false;
- for( valid = gtk_tree_model_get_iter_first( GTK_TREE_MODEL(model), &iter );
+ for (valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
valid;
- valid = gtk_tree_model_iter_next( GTK_TREE_MODEL(model), &iter ) ) {
+ valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter)) {
gtk_tree_model_get(model, &iter, 0, &family, 2, &onSystem, -1);
- if( onSystem && familyNamesAreEqual( token, family ) ) {
+ if (onSystem && familyNamesAreEqual(token, family)) {
found = true;
break;
}
}
- if( found ) {
+ if (found) {
markup += g_markup_escape_text(token.c_str(), -1);
markup += ", ";
} else {
@@ -1085,13 +1108,13 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/,
}
}
// Remove extra comma and space from end.
- if( markup.size() >= 2 ) {
- markup.resize( markup.size()-2 );
+ if (markup.size() >= 2) {
+ markup.resize(markup.size() - 2);
}
markup += "</span>";
// std::cout << markup << std::endl;
} else {
- markup = family_escaped;
+ markup = family_escaped;
}
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -1099,7 +1122,7 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/,
if (show_sample) {
Glib::ustring sample = prefs->getString("/tools/text/font_sample");
- Glib::ustring sample_escaped = g_markup_escape_text(sample.data(), -1);
+ Glib::ustring sample_escaped = Glib::Markup::escape_text(sample);
markup += " <span foreground='gray' font_family='";
markup += family_escaped;
@@ -1108,8 +1131,10 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/,
markup += "</span>";
}
- g_object_set (G_OBJECT (cell), "markup", markup.c_str(), NULL);
+ g_object_set(G_OBJECT(cell), "markup", markup.c_str(), NULL);
+ g_free(family_escaped);
}
+
/*
Local Variables:
mode:c++
@@ -1119,4 +1144,4 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/,
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h
index c89dab550..18e0d4b6e 100644
--- a/src/libnrtype/font-lister.h
+++ b/src/libnrtype/font-lister.h
@@ -28,294 +28,280 @@ class SPDocument;
class SPCSSAttr;
class SPStyle;
-namespace Inkscape
-{
- /**
- * This class enumerates fonts using libnrtype into reusable data stores and
- * allows for random access to the font-family list and the font-style list.
- * Setting the font-family updates the font-style list. "Style" in this case
- * refers to everything but family and size (e.g. italic/oblique, weight).
- *
- * This class handles font-family lists and fonts that are not on the system,
- * where there is not an entry in the fontInstanceMap.
- *
- * This class uses the idea of "font_spec". This is a plain text string as used by
- * Pango. It is similar to the CSS font shorthand except that font-family comes
- * first and in this class the font-size is not used.
- *
- * This class uses the FontFactory class to get a list of system fonts
- * and to find best matches via Pango. The Pango interface is only setup
- * to deal with fonts that are on the system so care must be taken. For
- * example, best matches should only be done with the first font-family
- * in a font-family list. If the first font-family is not on the system
- * then a generic font-family should be used (sans-serif -> Sans).
- *
- * This class is used by the UI interface (text-toolbar, font-select, etc.).
- *
- * "Font" includes family and style. It should not be used when one
- * means font-family.
- */
- class FontLister
- {
- public:
-
- enum Exceptions
- {
- FAMILY_NOT_FOUND,
- STYLE_NOT_FOUND
- };
-
-
- virtual ~FontLister ();
-
- /** GtkTreeModelColumnRecord for the font-family list Gtk::ListStore
- */
- class FontListClass
- : public Gtk::TreeModelColumnRecord
- {
- public:
- /** Column containing the family name
- */
- Gtk::TreeModelColumn<Glib::ustring> family;
-
- /** Column containing the styles for each family name.
- */
- Gtk::TreeModelColumn<GList*> styles;
-
- /** Column containing flag if font is on system
- */
- Gtk::TreeModelColumn<gboolean> onSystem;
-
- FontListClass ()
- {
- add (family);
- add (styles);
- add (onSystem);
- }
- };
-
- FontListClass FontList;
-
- class FontStyleListClass
- : public Gtk::TreeModelColumnRecord
- {
- public:
- /** Column containing the styles as Font designer used.
- */
- Gtk::TreeModelColumn<Glib::ustring> displayStyle;
-
- /** Column containing the styles in CSS/Pango format.
- */
- Gtk::TreeModelColumn<Glib::ustring> cssStyle;
-
- FontStyleListClass ()
- {
- add (cssStyle);
- add (displayStyle);
- }
- };
-
- FontStyleListClass FontStyleList;
-
- /** Returns the ListStore with the family names
- *
- * The return is const and the function is declared as const.
- * The ListStore is ready to be used after class instantiation
- * and should not (cannot) be modified.
- */
- const Glib::RefPtr<Gtk::ListStore>
- get_font_list () const;
-
- /** Returns the ListStore with the styles
- *
- */
- const Glib::RefPtr<Gtk::ListStore>
- get_style_list () const;
-
- /** Inserts a font family or font-fallback list (for use when not
- * already in document or on system).
- */
- void
- insert_font_family ( Glib::ustring new_family );
-
- /** Updates font list to include fonts in document
- *
- */
- void
- update_font_list ( SPDocument* document);
-
- private:
- void
- update_font_list_recursive( SPObject *r, std::list<Glib::ustring> *l );
-
- public:
- static Inkscape::FontLister*
- get_instance ()
- {
- static Inkscape::FontLister* instance = new Inkscape::FontLister();
- return instance;
- }
-
- /** Takes a hand written font spec and returns a Pango generated one in
- * standard form.
- */
- Glib::ustring canonize_fontspec( Glib::ustring fontspec );
-
- /** Find closest system font to given font.
- */
- Glib::ustring system_fontspec( Glib::ustring fontspec );
-
- /** Gets font-family and style from fontspec.
- * font-family and style returned.
- */
- std::pair<Glib::ustring, Glib::ustring>
- ui_from_fontspec (Glib::ustring fontspec);
-
- /** Sets font-family and style after a selection change.
- * New font-family and style returned.
- */
- std::pair<Glib::ustring, Glib::ustring>
- selection_update ();
-
- /** Sets current_fontspec, etc. If check is false, won't
- * try to find best style match (assumes style in fontspec
- * valid for given font-family).
- */
- void
- set_fontspec (Glib::ustring fontspec, gboolean check=true);
-
- Glib::ustring
- get_fontspec ()
- {
- return current_fontspec;
- }
-
- /** Changes font-family, updating style list and attempting to find
- * closest style to current_style style (if check_style is true).
- * New font-family and style returned.
- * Does NOT update current_family and current_style.
- * (For potential use in font-selector which doesn't update until
- * "Apply" button clicked.)
- */
- std::pair<Glib::ustring, Glib::ustring>
- new_font_family (Glib::ustring family, gboolean check_style = true);
-
- /** Sets font-family, updating style list and attempting
- * to find closest style to old current_style.
- * New font-family and style returned.
- * Updates current_family and current_style.
- * Calls new_font_family().
- * (For use in text-toolbar where update is immediate.)
- */
- std::pair<Glib::ustring, Glib::ustring>
- set_font_family (Glib::ustring family, gboolean check_style = true);
-
- /** Sets font-family from row in list store.
- * The row can be used to determine if we are in the
- * document or system part of the font-family list.
- * This is needed to handle scrolling through the
- * font-family list correctly.
- * Calls set_font_family().
- */
- std::pair<Glib::ustring, Glib::ustring>
- set_font_family (int row, gboolean check_style = true);
-
- Glib::ustring
- get_font_family ()
- {
- return current_family;
- }
-
- int
- get_font_family_row ()
- {
- return current_family_row;
- }
-
- /** Sets style. Does not validate style for family.
- */
- void
- set_font_style (Glib::ustring style);
-
- Glib::ustring
- get_font_style ()
- {
- return current_style;
- }
-
- Glib::ustring
- fontspec_from_style (SPStyle* style);
-
- /** Fill css using current_fontspec.
- */
- void
- fill_css( SPCSSAttr *css, Glib::ustring fontspec = "" );
-
- Gtk::TreeModel::Row
- get_row_for_font (Glib::ustring family);
-
- Gtk::TreePath
- get_path_for_font (Glib::ustring family);
-
- Gtk::TreeModel::Row
- get_row_for_style (Glib::ustring style);
-
- Gtk::TreePath
- get_path_for_style (Glib::ustring style);
-
- std::pair<Gtk::TreePath, Gtk::TreePath>
- get_paths (Glib::ustring family, Glib::ustring style);
-
- /** Return best style match for new font given style for old font.
- */
- Glib::ustring
- get_best_style_match (Glib::ustring family, Glib::ustring style);
-
- /* Not Used */
- const NRNameList
- get_name_list () const
- {
- return families;
- }
-
- private:
-
- FontLister ();
-
- NRNameList families;
-
- Glib::RefPtr<Gtk::ListStore> font_list_store;
- Glib::RefPtr<Gtk::ListStore> style_list_store;
-
- /** Info for currently selected font (what is shown in the UI).
- * May include font-family lists and fonts not on system.
- */
- int current_family_row;
- Glib::ustring current_family;
- Glib::ustring current_style;
- Glib::ustring current_fontspec;
-
- /** fontspec of system font closest to current_fontspec.
- * (What the system will use to display current_fontspec.)
- */
- Glib::ustring current_fontspec_system;
-
- /** If a font-family is not on system, this list of styles is used.
- */
- GList *default_styles;
- };
-}
+namespace Inkscape {
+
+/**
+ * This class enumerates fonts using libnrtype into reusable data stores and
+ * allows for random access to the font-family list and the font-style list.
+ * Setting the font-family updates the font-style list. "Style" in this case
+ * refers to everything but family and size (e.g. italic/oblique, weight).
+ *
+ * This class handles font-family lists and fonts that are not on the system,
+ * where there is not an entry in the fontInstanceMap.
+ *
+ * This class uses the idea of "font_spec". This is a plain text string as used by
+ * Pango. It is similar to the CSS font shorthand except that font-family comes
+ * first and in this class the font-size is not used.
+ *
+ * This class uses the FontFactory class to get a list of system fonts
+ * and to find best matches via Pango. The Pango interface is only setup
+ * to deal with fonts that are on the system so care must be taken. For
+ * example, best matches should only be done with the first font-family
+ * in a font-family list. If the first font-family is not on the system
+ * then a generic font-family should be used (sans-serif -> Sans).
+ *
+ * This class is used by the UI interface (text-toolbar, font-select, etc.).
+ *
+ * "Font" includes family and style. It should not be used when one
+ * means font-family.
+ */
+
+class FontLister {
+public:
+ enum Exceptions {
+ FAMILY_NOT_FOUND,
+ STYLE_NOT_FOUND
+ };
+
+ virtual ~FontLister();
+
+ /**
+ * GtkTreeModelColumnRecord for the font-family list Gtk::ListStore
+ */
+ struct FontListClass : public Gtk::TreeModelColumnRecord {
+ /**
+ * Column containing the family name
+ */
+ Gtk::TreeModelColumn<Glib::ustring> family;
+
+ /**
+ * Column containing the styles for each family name.
+ */
+ Gtk::TreeModelColumn<GList *> styles;
+
+ /**
+ * Column containing flag if font is on system
+ */
+ Gtk::TreeModelColumn<bool> onSystem;
+
+ /**
+ * Not actually a column.
+ * Necessary for quick initialization of FontLister,
+ * we initially store the pango family and if the
+ * font style is actually used we'll cache it in
+ * %styles.
+ */
+ Gtk::TreeModelColumn<PangoFontFamily *> pango_family;
+
+ FontListClass()
+ {
+ add(family);
+ add(styles);
+ add(onSystem);
+ add(pango_family);
+ }
+ };
+
+ FontListClass FontList;
+
+ struct FontStyleListClass : public Gtk::TreeModelColumnRecord {
+ /**
+ * Column containing the styles as Font designer used.
+ */
+ Gtk::TreeModelColumn<Glib::ustring> displayStyle;
+
+ /**
+ * Column containing the styles in CSS/Pango format.
+ */
+ Gtk::TreeModelColumn<Glib::ustring> cssStyle;
+
+ FontStyleListClass()
+ {
+ add(cssStyle);
+ add(displayStyle);
+ }
+ };
+
+ FontStyleListClass FontStyleList;
+
+ /**
+ * @return the ListStore with the family names
+ *
+ * The return is const and the function is declared as const.
+ * The ListStore is ready to be used after class instantiation
+ * and should not be modified.
+ */
+ const Glib::RefPtr<Gtk::ListStore> get_font_list() const;
+
+ /**
+ * @return the ListStore with the styles
+ */
+ const Glib::RefPtr<Gtk::ListStore> get_style_list() const;
+
+ /**
+ * Inserts a font family or font-fallback list (for use when not
+ * already in document or on system).
+ */
+ void insert_font_family(Glib::ustring new_family);
+
+ /**
+ * Updates font list to include fonts in document.
+ */
+ void update_font_list(SPDocument *document);
+
+public:
+ static Inkscape::FontLister *get_instance();
+
+ /**
+ * Takes a hand written font spec and returns a Pango generated one in
+ * standard form.
+ */
+ Glib::ustring canonize_fontspec(Glib::ustring fontspec);
+
+ /**
+ * Find closest system font to given font.
+ */
+ Glib::ustring system_fontspec(Glib::ustring fontspec);
+
+ /**
+ * Gets font-family and style from fontspec.
+ * font-family and style returned.
+ */
+ std::pair<Glib::ustring, Glib::ustring> ui_from_fontspec(Glib::ustring fontspec);
+
+ /**
+ * Sets font-family and style after a selection change.
+ * New font-family and style returned.
+ */
+ std::pair<Glib::ustring, Glib::ustring> selection_update();
+
+ /**
+ * Sets current_fontspec, etc. If check is false, won't
+ * try to find best style match (assumes style in fontspec
+ * valid for given font-family).
+ */
+ void set_fontspec(Glib::ustring fontspec, bool check = true);
+
+ Glib::ustring get_fontspec()
+ {
+ return current_fontspec;
+ }
+
+ /**
+ * Changes font-family, updating style list and attempting to find
+ * closest style to current_style style (if check_style is true).
+ * New font-family and style returned.
+ * Does NOT update current_family and current_style.
+ * (For potential use in font-selector which doesn't update until
+ * "Apply" button clicked.)
+ */
+ std::pair<Glib::ustring, Glib::ustring> new_font_family(Glib::ustring family, bool check_style = true);
+
+ /**
+ * Sets font-family, updating style list and attempting
+ * to find closest style to old current_style.
+ * New font-family and style returned.
+ * Updates current_family and current_style.
+ * Calls new_font_family().
+ * (For use in text-toolbar where update is immediate.)
+ */
+ std::pair<Glib::ustring, Glib::ustring> set_font_family(Glib::ustring family, bool check_style = true);
+
+ /**
+ * Sets font-family from row in list store.
+ * The row can be used to determine if we are in the
+ * document or system part of the font-family list.
+ * This is needed to handle scrolling through the
+ * font-family list correctly.
+ * Calls set_font_family().
+ */
+ std::pair<Glib::ustring, Glib::ustring> set_font_family(int row, bool check_style = true);
+
+ Glib::ustring get_font_family()
+ {
+ return current_family;
+ }
+
+ int get_font_family_row()
+ {
+ return current_family_row;
+ }
+
+ /**
+ * Sets style. Does not validate style for family.
+ */
+ void set_font_style(Glib::ustring style);
+
+ Glib::ustring get_font_style()
+ {
+ return current_style;
+ }
+
+ Glib::ustring fontspec_from_style(SPStyle *style);
+
+ /**
+ * Fill css using current_fontspec.
+ */
+ void fill_css(SPCSSAttr *css, Glib::ustring fontspec = "");
+
+ Gtk::TreeModel::Row get_row_for_font(Glib::ustring family);
+
+ Gtk::TreePath get_path_for_font(Glib::ustring family);
+
+ Gtk::TreeModel::Row get_row_for_style(Glib::ustring style);
+
+ Gtk::TreePath get_path_for_style(Glib::ustring style);
+
+ std::pair<Gtk::TreePath, Gtk::TreePath> get_paths(Glib::ustring family, Glib::ustring style);
+
+ /**
+ * Return best style match for new font given style for old font.
+ */
+ Glib::ustring get_best_style_match(Glib::ustring family, Glib::ustring style);
+
+ void ensureRowStyles(GtkTreeModel* model, GtkTreeIter const* iter);
+
+private:
+ FontLister();
+
+ void update_font_list_recursive(SPObject *r, std::list<Glib::ustring> *l);
+
+ Glib::RefPtr<Gtk::ListStore> font_list_store;
+ Glib::RefPtr<Gtk::ListStore> style_list_store;
+
+ /**
+ * Info for currently selected font (what is shown in the UI).
+ * May include font-family lists and fonts not on system.
+ */
+ int current_family_row;
+ Glib::ustring current_family;
+ Glib::ustring current_style;
+ Glib::ustring current_fontspec;
+
+ /**
+ * fontspec of system font closest to current_fontspec.
+ * (What the system will use to display current_fontspec.)
+ */
+ Glib::ustring current_fontspec_system;
+
+ /**
+ * If a font-family is not on system, this list of styles is used.
+ */
+ GList *default_styles;
+};
+
+} // namespace Inkscape
// Helper functions
gboolean font_lister_separator_func(GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer /*data*/);
+ GtkTreeIter *iter,
+ gpointer /*data*/);
-void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/,
- GtkCellRenderer *cell,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer /*data*/);
+void font_lister_cell_data_func(GtkCellLayout * /*cell_layout*/,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer /*data*/);
#endif
@@ -328,4 +314,4 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/,
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp
index c1ebb32e0..e44809c65 100644
--- a/src/ui/dialog/text-edit.cpp
+++ b/src/ui/dialog/text-edit.cpp
@@ -344,9 +344,9 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ )
Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance();
- // This is done for us by text-toolbar. No need to do it twice.
- // fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP ));
- // fontlister->selection_update();
+ // This is normally done for us by text-toolbar but only when we are in text editing context
+ fontlister->update_font_list(sp_desktop_document(this->desktop));
+ fontlister->selection_update();
Glib::ustring fontspec = fontlister->get_fontspec();
diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp
index ccaf93e55..c9a52ef11 100644
--- a/src/widgets/font-selector.cpp
+++ b/src/widgets/font-selector.cpp
@@ -303,6 +303,9 @@ static void sp_font_selector_family_select_row(GtkTreeSelection *selection,
GtkTreeModel *model;
GtkTreeIter iter;
if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return;
+
+ Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance();
+ fontlister->ensureRowStyles(model, &iter);
// Next get family name with its style list
gchar *family;
@@ -310,7 +313,6 @@ static void sp_font_selector_family_select_row(GtkTreeSelection *selection,
gtk_tree_model_get (model, &iter, 0, &family, 1, &list, -1);
// Find best style match for selected family with current style (e.g. of selected text).
- Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance();
Glib::ustring style = fontlister->get_font_style();
Glib::ustring best = fontlister->get_best_style_match (family, style);
diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp
index 408babf06..88f698bc4 100644
--- a/src/widgets/text-toolbar.cpp
+++ b/src/widgets/text-toolbar.cpp
@@ -819,7 +819,7 @@ static void sp_text_set_sizes(GtkListStore* model_size, int unit)
* It is called whenever a text selection is changed, including stepping cursor
* through text, or setting focus to text.
*/
-static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl)
+static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection = false) // don't bother to update font list if subsel changed
{
#ifdef DEBUG_TEXT
static int count = 0;
@@ -859,7 +859,9 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/
INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontStyleAction" ) );
Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance();
- fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP ));
+ if (!subselection) {
+ fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP ));
+ }
fontlister->selection_update();
// Update font list, but only if widget already created.
@@ -1154,7 +1156,7 @@ static void sp_text_toolbox_selection_modified(Inkscape::Selection *selection, g
static void
sp_text_toolbox_subselection_changed (gpointer /*tc*/, GObject *tbl)
{
- sp_text_toolbox_selection_changed (NULL, tbl);
+ sp_text_toolbox_selection_changed (NULL, tbl, true);
}
// TODO: possibly share with font-selector by moving most code to font-lister (passing family name)
@@ -1640,7 +1642,7 @@ static void text_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolB
if (SP_IS_TEXT_CONTEXT(ec)) {
// Watch selection
- c_selection_changed = sp_desktop_selection(desktop)->connectChanged(bind(ptr_fun(sp_text_toolbox_selection_changed), holder));
+ c_selection_changed = sp_desktop_selection(desktop)->connectChanged(bind(ptr_fun(sp_text_toolbox_selection_changed), holder, false));
c_selection_modified = sp_desktop_selection (desktop)->connectModified(bind(ptr_fun(sp_text_toolbox_selection_modified), holder));
c_subselection_changed = desktop->connectToolSubselectionChanged(bind(ptr_fun(sp_text_toolbox_subselection_changed), holder));
} else {