summaryrefslogtreecommitdiffstats
path: root/src/libnrtype
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2013-02-09 09:30:08 +0000
committertavmjong-free <tavmjong@free.fr>2013-02-09 09:30:08 +0000
commite330f37cfa5949bb505bb846a467f10c2c711d8f (patch)
treea19768df4d83e7bdfebe9087e3cfb9bc31e6becf /src/libnrtype
parentpartially reverted previous commit (diff)
downloadinkscape-e330f37cfa5949bb505bb846a467f10c2c711d8f.tar.gz
inkscape-e330f37cfa5949bb505bb846a467f10c2c711d8f.zip
Add function to add document font-family entries to store.
Remove font-family to interator map as we can now have duplicate font-family names in store. (bzr r12111)
Diffstat (limited to 'src/libnrtype')
-rw-r--r--src/libnrtype/font-lister.cpp149
-rw-r--r--src/libnrtype/font-lister.h40
2 files changed, 165 insertions, 24 deletions
diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp
index 6df576866..9949be208 100644
--- a/src/libnrtype/font-lister.cpp
+++ b/src/libnrtype/font-lister.cpp
@@ -14,6 +14,11 @@
#include "font-lister.h"
#include "FontFactory.h"
+#include "sp-object.h"
+#include "sp-root.h"
+#include "document.h"
+#include "xml/repr.h"
+
namespace Inkscape
{
FontLister::FontLister ()
@@ -53,11 +58,153 @@ namespace Inkscape
(*treeModelIter)[FontList.styles] = styles;
(*treeModelIter)[FontList.onSystem] = true;
- font_list_store_iter_map.insert(std::make_pair(familyName, Gtk::TreePath(treeModelIter)));
}
}
}
+ // 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.font] << std::endl;
+ // return false;
+ // }
+ // return true;
+ // }
+ // font_list_store->foreach_iter( sigc::mem_fun(*this, &FontLister::print_document_font ));
+
+ void
+ FontLister::update_font_list( SPDocument* document ) {
+
+ SPObject *r = document->getRoot();
+ if( !r ) {
+ return;
+ }
+
+ /* 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.font] << std::endl;
+ iter = font_list_store->erase( iter );
+ } else {
+ // std::cout << " First on system: " << row[FontList.font] << std::endl;
+ break;
+ }
+ }
+
+ /* Create default styles for use when font-family is unknown on system. */
+ static GList *default_styles = NULL;
+ if( default_styles == NULL ) {
+ default_styles = g_list_append( default_styles, g_strdup("Normal") );
+ default_styles = g_list_append( default_styles, g_strdup("Italic") );
+ default_styles = g_list_append( default_styles, g_strdup("Bold") );
+ default_styles = g_list_append( default_styles, g_strdup("Bold Italic") );
+ default_styles = g_list_append( default_styles, g_strdup("Loopy") );
+ }
+
+ /* 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.font] = "separatoR";
+ (*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;
+
+ /* 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[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] && tokens[0].compare( row[FontList.font] ) == 0 ) {
+ styles = row[FontList.styles];
+ break;
+ }
+ ++iter2;
+ }
+ }
+
+ Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend();
+ (*treeModelIter)[FontList.font] = 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 ) {
+
+ const gchar *style = r->getRepr()->attribute("style");
+ if( style != NULL ) {
+
+ std::vector<Glib::ustring> tokens = Glib::Regex::split_simple(";", style );
+ for( size_t i=0; i < tokens.size(); ++i ) {
+
+ Glib::ustring token = tokens[i];
+ size_t found = token.find("font-family:");
+
+ if( found != Glib::ustring::npos ) {
+
+ // Remove "font-family:"
+ token.erase(found,12);
+
+ // Remove any leading single or double quote
+ if( token[0] == '\'' || token[0] == '"' ) {
+ token.erase(0,1);
+ }
+
+ // Remove any trailing single or double quote
+ if( token[token.length()-1] == '\'' || token[token.length()-1] == '"' ) {
+ token.erase(token.length()-1);
+ }
+
+ l->push_back( token );
+ }
+ }
+ }
+
+ for (SPObject *child = r->firstChild(); child; child = child->getNext()) {
+ update_font_list_recursive( child, l );
+ }
+ }
+
+ Gtk::TreePath
+ 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() ) {
+
+ Gtk::TreeModel::Row row = *iter;
+
+ if( family.compare( row[FontList.font] ) == 0 ) {
+ return font_list_store->get_path( iter );
+ }
+
+ ++iter;
+ }
+
+ throw FAMILY_NOT_FOUND;
+ }
+
FontLister::~FontLister ()
{
};
diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h
index 7a7db5615..d4c48dd52 100644
--- a/src/libnrtype/font-lister.h
+++ b/src/libnrtype/font-lister.h
@@ -7,9 +7,11 @@
* Authors:
* Chris Lahey <clahey@ximian.com>
* Lauris Kaplinski <lauris@kaplinski.com>
+ * Tavmjong Bah <tavmjong@free.fr>
*
* Copyright (C) 1999-2001 Ximian, Inc.
* Copyright (C) 2002 Lauris Kaplinski
+ * Copyright (C) 2013 Tavmjong Bah
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
@@ -21,6 +23,9 @@
#include <glibmm/ustring.h>
#include "nr-type-primitives.h"
+class SPObject;
+class SPDocument;
+
namespace Inkscape
{
/**
@@ -66,22 +71,7 @@ namespace Inkscape
}
};
- /* Case-insensitive < compare for standard strings */
- class StringLessThan
- {
- public:
- bool operator () (std::string str1, std::string str2) const
- {
- std::string s1=str1; // Can't transform the originals!
- std::string s2=str2;
- std::transform(s1.begin(), s1.end(), s1.begin(), (int(*)(int)) toupper);
- std::transform(s2.begin(), s2.end(), s2.begin(), (int(*)(int)) toupper);
- return s1<s2;
- }
- };
-
FontListClass FontList;
- typedef std::map<Glib::ustring, Gtk::TreePath, StringLessThan> IterMapType;
/** Returns the ListStore with the font names
*
@@ -92,6 +82,17 @@ namespace Inkscape
const Glib::RefPtr<Gtk::ListStore>
get_font_list () const;
+ /** 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 ()
{
@@ -100,12 +101,7 @@ namespace Inkscape
}
Gtk::TreePath
- get_row_for_font (Glib::ustring family)
- {
- IterMapType::iterator iter = font_list_store_iter_map.find (family);
- if (iter == font_list_store_iter_map.end ()) throw FAMILY_NOT_FOUND;
- return (*iter).second;
- }
+ get_row_for_font (Glib::ustring family);
const NRNameList
get_name_list () const
@@ -113,7 +109,6 @@ namespace Inkscape
return families;
}
-
private:
FontLister ();
@@ -121,7 +116,6 @@ namespace Inkscape
NRNameList families;
Glib::RefPtr<Gtk::ListStore> font_list_store;
- IterMapType font_list_store_iter_map;
};
}