diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2013-02-09 09:30:08 +0000 |
|---|---|---|
| committer | tavmjong-free <tavmjong@free.fr> | 2013-02-09 09:30:08 +0000 |
| commit | e330f37cfa5949bb505bb846a467f10c2c711d8f (patch) | |
| tree | a19768df4d83e7bdfebe9087e3cfb9bc31e6becf /src/libnrtype | |
| parent | partially reverted previous commit (diff) | |
| download | inkscape-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.cpp | 149 | ||||
| -rw-r--r-- | src/libnrtype/font-lister.h | 40 |
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; }; } |
