summaryrefslogtreecommitdiffstats
path: root/src/libnrtype
diff options
context:
space:
mode:
Diffstat (limited to 'src/libnrtype')
-rw-r--r--src/libnrtype/FontFactory.cpp528
-rw-r--r--src/libnrtype/FontFactory.h58
-rw-r--r--src/libnrtype/FontInstance.cpp6
-rw-r--r--src/libnrtype/font-lister.cpp87
-rw-r--r--src/libnrtype/font-lister.h6
5 files changed, 537 insertions, 148 deletions
diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp
index 32f71aed0..2d56a1a41 100644
--- a/src/libnrtype/FontFactory.cpp
+++ b/src/libnrtype/FontFactory.cpp
@@ -11,6 +11,8 @@
#include "FontFactory.h"
#include <libnrtype/font-instance.h>
+#include <glibmm.h>
+
#ifdef HAVE_CONFIG_H
# include "config.h"
@@ -202,8 +204,8 @@ is_swash(char const *s)
* Q: Shouldn't this include the other tests such as is_outline, etc.?
* Q: Is there a problem with strcasecmp on Win32? Should it use stricmp?
*/
-static int
-style_name_compare(void const *aa, void const *bb)
+int
+style_name_compare(char const *aa, char const *bb)
{
char const *a = (char const *) aa;
char const *b = (char const *) bb;
@@ -254,8 +256,8 @@ static void font_factory_style_list_destructor(NRStyleList *list)
/**
* On Win32 performs a stricmp(a,b), otherwise does a strcasecmp(a,b)
*/
-static int
-family_name_compare(void const *a, void const *b)
+int
+family_name_compare(char const *a, char const *b)
{
#ifndef WIN32
return strcasecmp((*((char const **) a)), (*((char const **) b)));
@@ -323,6 +325,349 @@ font_factory::~font_factory(void)
//pango_ft2_shutdown_display();
#endif
//g_object_unref(fontContext);
+
+ // Delete the pango font pointers in the string to instance map
+ PangoStringToDescrMap::iterator it = fontInstanceMap.begin();
+ while (it != fontInstanceMap.end()) {
+ pango_font_description_free((*it).second);
+ it++;
+ }
+}
+
+
+Glib::ustring font_factory::ConstructFontSpecification(PangoFontDescription *font)
+{
+ Glib::ustring pangoString;
+
+ g_assert(font);
+
+ if (font) {
+ // Once the format for the font specification is decided, it must be
+ // kept.. if it is absolutely necessary to change it, the attribute
+ // it is written to needs to have a new version so the legacy files
+ // can be read.
+
+ PangoFontDescription *copy = pango_font_description_copy(font);
+
+ pango_font_description_unset_fields (copy, PANGO_FONT_MASK_SIZE);
+ pangoString = Glib::ustring(pango_font_description_to_string(copy));
+
+ pango_font_description_free(copy);
+
+ }
+
+ return pangoString;
+}
+
+Glib::ustring font_factory::ConstructFontSpecification(font_instance *font)
+{
+ Glib::ustring pangoString;
+
+ g_assert(font);
+
+ if (font) {
+ pangoString = ConstructFontSpecification(font->descr);
+ }
+
+ return pangoString;
+}
+
+Glib::ustring font_factory::GetUIFamilyString(PangoFontDescription const *fontDescr)
+{
+ Glib::ustring family;
+
+ g_assert(fontDescr);
+
+ if (fontDescr) {
+ // For now, keep it as family name taken from pango
+ family = pango_font_description_get_family(fontDescr);
+ }
+
+ return family;
+}
+
+Glib::ustring font_factory::GetUIStyleString(PangoFontDescription const *fontDescr)
+{
+ Glib::ustring style;
+
+ g_assert(fontDescr);
+
+ if (fontDescr) {
+ PangoFontDescription *fontDescrCopy = pango_font_description_copy(fontDescr);
+
+ pango_font_description_unset_fields(fontDescrCopy, PANGO_FONT_MASK_FAMILY);
+ pango_font_description_unset_fields(fontDescrCopy, PANGO_FONT_MASK_SIZE);
+
+ // For now, keep it as style name taken from pango
+ style = pango_font_description_to_string(fontDescrCopy);
+
+ pango_font_description_free(fontDescrCopy);
+ }
+
+ return style;
+}
+
+Glib::ustring font_factory::ReplaceFontSpecificationFamily(const Glib::ustring & fontSpec, const Glib::ustring & newFamily)
+{
+ Glib::ustring newFontSpec;
+
+ // Although we are using the string from pango_font_description_to_string for the
+ // font specification, we definitely cannot just set the new family in the
+ // PangoFontDescription structure and ask for a new string. This is because
+ // what constitutes a "family" in our own UI may be different from how Pango
+ // sees it.
+
+ // Find the PangoFontDescription associated to this fontSpec
+ PangoStringToDescrMap::iterator it = fontInstanceMap.find(fontSpec);
+
+ g_assert(it != fontInstanceMap.end());
+
+ if (it != fontInstanceMap.end()) {
+ PangoFontDescription *descr = pango_font_description_copy((*it).second);
+
+ // Grab the UI Family string from the descr
+ Glib::ustring uiFamily = GetUIFamilyString(descr);
+
+ // Replace the UI Family name with the new family name
+ std::size_t found = fontSpec.find(uiFamily);
+ if (found != Glib::ustring::npos) {
+ newFontSpec = fontSpec;
+ newFontSpec.erase(found, uiFamily.size());
+ newFontSpec.insert(found, newFamily);
+
+ // If the new font specification does not exist in the reference maps,
+ // search for the next best match for the faces in that style
+ it = fontInstanceMap.find(newFontSpec);
+ if (it == fontInstanceMap.end()) {
+
+ PangoFontDescription *newFontDescr = pango_font_description_from_string(newFontSpec.c_str());
+
+ PangoFontDescription *bestMatchForNewDescr = NULL;
+ Glib::ustring bestMatchFontDescription;
+
+ bool setFirstFamilyMatch = false;
+ for (it = fontInstanceMap.begin(); it != fontInstanceMap.end(); it++) {
+
+ Glib::ustring currentFontSpec = (*it).first;
+
+ // Save some time by only looking at the right family
+ if (currentFontSpec.find(newFamily) != Glib::ustring::npos) {
+ if (!setFirstFamilyMatch) {
+ // This ensures that the closest match is at least within the correct
+ // family rather than the first font in the list
+ bestMatchForNewDescr = pango_font_description_copy((*it).second);
+ bestMatchFontDescription = currentFontSpec;
+ setFirstFamilyMatch = true;
+ } else {
+ // Get the font description that corresponds, and
+ // then see if we've found a better match
+ PangoFontDescription *possibleMatch = pango_font_description_copy((*it).second);
+
+ if (pango_font_description_better_match(
+ newFontDescr, bestMatchForNewDescr, possibleMatch)) {
+
+ pango_font_description_free(bestMatchForNewDescr);
+ bestMatchForNewDescr = possibleMatch;
+ bestMatchFontDescription = currentFontSpec;
+ } else {
+ pango_font_description_free(possibleMatch);
+ }
+ }
+ }
+ }
+
+ newFontSpec = bestMatchFontDescription;
+
+ pango_font_description_free(newFontDescr);
+ pango_font_description_free(bestMatchForNewDescr);
+ }
+ }
+
+ pango_font_description_free(descr);
+ }
+
+ return newFontSpec;
+}
+
+Glib::ustring font_factory::FontSpecificationSetItalic(const Glib::ustring & fontSpec, bool turnOn)
+{
+ Glib::ustring newFontSpec;
+
+ // Find the PangoFontDesecription that goes with this font specification string
+ PangoStringToDescrMap::iterator it = fontInstanceMap.find(fontSpec);
+
+ g_assert(it != fontInstanceMap.end());
+
+ if (it != fontInstanceMap.end()) {
+ // If we did find one, make a copy and set/unset the italic as needed
+ PangoFontDescription *descr = pango_font_description_copy((*it).second);
+
+ PangoStyle style;
+ if (turnOn) {
+ style = PANGO_STYLE_ITALIC;
+ } else {
+ style = PANGO_STYLE_NORMAL;
+ }
+ pango_font_description_set_style(descr, style);
+
+ newFontSpec = ConstructFontSpecification(descr);
+ if (fontInstanceMap.find(newFontSpec) == fontInstanceMap.end()) {
+ // If the new font does not have an italic face, don't
+ // allow italics to be set!
+ newFontSpec = fontSpec;
+ }
+
+ pango_font_description_free(descr);
+ }
+
+ return newFontSpec;
+}
+
+Glib::ustring font_factory::FontSpecificationSetBold(const Glib::ustring & fontSpec, bool turnOn)
+{
+ Glib::ustring newFontSpec;
+
+ // Find the PangoFontDesecription that goes with this font specification string
+ PangoStringToDescrMap::iterator it = fontInstanceMap.find(fontSpec);
+
+ if (it != fontInstanceMap.end()) {
+ // If we did find one, make a copy and set/unset the bold as needed
+ PangoFontDescription *descr = pango_font_description_copy((*it).second);
+
+ PangoWeight weight;
+ if (turnOn) {
+ weight = PANGO_WEIGHT_BOLD;
+ } else {
+ weight = PANGO_WEIGHT_NORMAL;
+ }
+ pango_font_description_set_weight(descr, weight);
+
+ newFontSpec = ConstructFontSpecification(descr);
+ if (fontInstanceMap.find(newFontSpec) == fontInstanceMap.end()) {
+ // If the new font does not have a bold face, don't
+ // allow bold to be set!
+ newFontSpec = fontSpec;
+ }
+
+ pango_font_description_free(descr);
+ }
+
+ return newFontSpec;
+}
+
+/////
+
+static bool StyleNameCompareInternal(Glib::ustring style1, Glib::ustring style2)
+{
+ return (style_name_compare(style1.c_str(), style2.c_str()) < 0);
+}
+
+void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map)
+{
+ g_assert(map);
+
+ if (map) {
+
+ // Gather the family names as listed by Pango
+ PangoFontFamily** families = NULL;
+ int numFamilies = 0;
+ pango_font_map_list_families(fontServer, &families, &numFamilies);
+
+ for (int currentFamily=0; currentFamily < numFamilies; currentFamily++) {
+
+ // Gather the styles for this family
+ PangoFontFace** faces = NULL;
+ int numFaces = 0;
+ pango_font_family_list_faces(families[currentFamily], &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
+
+ if (pango_font_face_get_face_name(faces[currentFace]) == NULL) {
+ continue;
+ }
+
+ PangoFontDescription *faceDescr = pango_font_face_describe(faces[currentFace]);
+ if (faceDescr) {
+ Glib::ustring familyUIName = GetUIFamilyString(faceDescr);
+ Glib::ustring styleUIName = GetUIStyleString(faceDescr);
+
+ if (!familyUIName.empty() && !styleUIName.empty()) {
+ // Find the right place to put the style information, adding
+ // a map entry for the family name if it doesn't yet exist
+
+ FamilyToStylesMap::iterator iter = map->find(familyUIName);
+
+ if (iter == map->end()) {
+ map->insert(std::make_pair(familyUIName, std::list<Glib::ustring>()));
+ }
+
+ // Insert into the style list and save the info in the reference maps
+ // only if the style does not yet exist
+
+ bool exists = false;
+ std::list<Glib::ustring> &styleList = (*map)[familyUIName];
+
+ for (std::list<Glib::ustring>::iterator it=styleList.begin();
+ it != styleList.end();
+ it++) {
+ if (*it == styleUIName) {
+ exists = true;
+ break;
+ }
+ }
+
+ if (!exists) {
+ styleList.push_back(styleUIName);
+
+ // Add the string info needed in the reference maps
+ fontStringMap.insert(
+ std::make_pair(
+ Glib::ustring(familyUIName) + Glib::ustring(styleUIName),
+ ConstructFontSpecification(faceDescr)));
+ fontInstanceMap.insert(
+ std::make_pair(ConstructFontSpecification(faceDescr), faceDescr));
+ } else {
+ pango_font_description_free(faceDescr);
+ }
+ } else {
+ pango_font_description_free(faceDescr);
+ }
+ }
+ }
+ }
+
+ // Sort the style lists
+ for (FamilyToStylesMap::iterator iter = map->begin() ; iter != map->end(); iter++) {
+ (*iter).second.sort(StyleNameCompareInternal);
+ }
+ }
+}
+
+font_instance* font_factory::FaceFromStyle(SPStyle const *style)
+{
+ font_instance *font = NULL;
+
+ g_assert(style);
+
+ if (style) {
+ // First try to use the font specification if it is set
+ if (style->text->font_specification.set
+ && style->text->font_specification.value
+ && *style->text->font_specification.value) {
+
+ font = FaceFromFontSpecification(style->text->font_specification.value);
+ }
+
+ // If that failed, try using the CSS information in the style
+ if (!font) {
+ font = Face(style->text->font_family.value, font_style_to_pos(*style));
+ }
+ }
+
+ return font;
}
font_instance *font_factory::FaceFromDescr(char const *family, char const *style)
@@ -334,6 +679,81 @@ font_instance *font_factory::FaceFromDescr(char const *family, char const *style
return res;
}
+font_instance* font_factory::FaceFromUIStrings(char const *uiFamily, char const *uiStyle)
+{
+ font_instance *fontInstance = NULL;
+
+ g_assert(uiFamily && uiStyle);
+ if (uiFamily && uiStyle) {
+ Glib::ustring uiString = Glib::ustring(uiFamily) + Glib::ustring(uiStyle);
+
+ UIStringToPangoStringMap::iterator uiToPangoIter = fontStringMap.find(uiString);
+
+ if (uiToPangoIter != fontStringMap.end ()) {
+ PangoStringToDescrMap::iterator pangoToDescrIter = fontInstanceMap.find((*uiToPangoIter).second);
+ if (pangoToDescrIter != fontInstanceMap.end()) {
+ // We found the pango description - now we can make a font_instance
+ PangoFontDescription *tempDescr = pango_font_description_copy((*pangoToDescrIter).second);
+ fontInstance = Face(tempDescr);
+ pango_font_description_free(tempDescr);
+ }
+ }
+ }
+
+ return fontInstance;
+}
+
+font_instance* font_factory::FaceFromPangoString(char const *pangoString)
+{
+ font_instance *fontInstance = NULL;
+
+ g_assert(pangoString);
+
+ if (pangoString) {
+ PangoFontDescription *descr = NULL;
+
+ // First attempt to find the font specification in the reference map
+ PangoStringToDescrMap::iterator it = fontInstanceMap.find(Glib::ustring(pangoString));
+ if (it != fontInstanceMap.end()) {
+ descr = pango_font_description_copy((*it).second);
+ }
+
+ // Or create a font description from the string - this may fail or
+ // produce unexpected results if the string does not have a good format
+ if (!descr) {
+ descr = pango_font_description_from_string(pangoString);
+ }
+
+ if (descr && (pango_font_description_get_family(descr) != NULL)) {
+ fontInstance = Face(descr);
+ }
+
+ if (descr) {
+ pango_font_description_free(descr);
+ }
+ }
+
+ return fontInstance;
+}
+
+font_instance* font_factory::FaceFromFontSpecification(char const *fontSpecification)
+{
+ font_instance *font = NULL;
+
+ g_assert(fontSpecification);
+
+ if (fontSpecification) {
+ // How the string is used to reconstruct a font depends on how it
+ // was constructed in ConstructFontSpecification. As it stands,
+ // the font specification is a pango-created string
+ font = FaceFromPangoString(fontSpecification);
+ }
+
+ return font;
+}
+
+
+
font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail)
{
#ifdef USE_PANGO_WIN32
@@ -487,106 +907,6 @@ void font_factory::UnrefFace(font_instance *who)
}
}
-NRNameList *font_factory::Families(NRNameList *flist)
-{
- PangoFontFamily** fams = NULL;
- int nbFam = 0;
- pango_font_map_list_families(fontServer, &fams, &nbFam);
-
- PANGO_DEBUG("got %d families\n", nbFam);
-
- flist->length = nbFam;
- flist->names = (guchar **)g_malloc(nbFam*sizeof(guchar*));
- flist->destructor = font_factory_name_list_destructor;
-
- for (int i = 0;i < nbFam;i++) {
-// Note: on Windows, pango_font_family_get_name always returns lowercase name.
-// As a result the list of fonts in the dialog is lowercase.
-// We could work around by loading the font and taking pango_font_description_get_family from its descr (that gives correct case),
-// but this is slow, and it's better to fix Pango instead.
- flist->names[i]=(guchar*)strdup(pango_font_family_get_name(fams[i]));
- }
-
- qsort(flist->names, nbFam, sizeof(guchar *), family_name_compare);
-
- g_free(fams);
-
- return flist;
-}
-
-NRStyleList *font_factory::Styles(gchar const *family, NRStyleList *slist)
-{
- PangoFontFamily *theFam = NULL;
-
- // search available families
- {
- PangoFontFamily** fams = NULL;
- int nbFam = 0;
- pango_font_map_list_families(fontServer, &fams, &nbFam);
-
- for (int i = 0;i < nbFam;i++) {
- char const *fname = pango_font_family_get_name(fams[i]);
- if ( fname && strcmp(family,fname) == 0 ) {
- theFam = fams[i];
- break;
- }
- }
-
- g_free(fams);
- }
-
- // nothing found
- if ( theFam == NULL ) {
- slist->length = 0;
- slist->records = NULL;
- slist->destructor = NULL;
- return slist;
- }
-
- // search faces in the found family
- PangoFontFace** faces = NULL;
- int nFaces = 0;
- pango_font_family_list_faces(theFam, &faces, &nFaces);
-
- slist->records = (NRStyleRecord *) g_malloc(nFaces * sizeof(NRStyleRecord));
- slist->destructor = font_factory_style_list_destructor;
-
- int nr = 0;
- for (int i = 0; i < nFaces; i++) {
-
- // no unnamed faces
- if (pango_font_face_get_face_name(faces[i]) == NULL)
- continue;
- PangoFontDescription *nd = pango_font_face_describe(faces[i]);
- if (nd == NULL)
- continue;
- char const *descr = pango_font_description_to_string(nd);
- if (descr == NULL) {
- pango_font_description_free(nd);
- continue;
- }
-
- char const *name = g_strdup(pango_font_face_get_face_name(faces[i]));
- pango_font_description_free(nd);
-
- slist->records[nr].name = name;
- slist->records[nr].descr = descr;
- nr ++;
- }
-
- slist->length = nr;
-
- qsort(slist->records, slist->length, sizeof(NRStyleRecord), style_record_compare);
- /* effic: Consider doing strdown and all the is_italic etc. tests once off and store the
- * results in a table, rather than having the sort invoke multiple is_italic tests per
- * record.
- */
-
- g_free(faces);
-
- return slist;
-}
-
void font_factory::AddInCache(font_instance *who)
{
if ( who == NULL ) return;
diff --git a/src/libnrtype/FontFactory.h b/src/libnrtype/FontFactory.h
index ba0010246..9f4b31a2e 100644
--- a/src/libnrtype/FontFactory.h
+++ b/src/libnrtype/FontFactory.h
@@ -7,6 +7,8 @@
#ifndef my_font_factory
#define my_font_factory
+//#include <glibmm/ustring.h>
+
#include <functional>
#include <algorithm>
#include <ext/hash_map>
@@ -21,7 +23,9 @@
#include <pango/pango.h>
#include "nr-type-primitives.h"
#include "nr-type-pos-def.h"
+#include "font-style-to-pos.h"
#include <libnrtype/nrtype-forward.h>
+#include "../style.h"
/* Freetype */
#ifdef USE_PANGO_WIN32
@@ -31,6 +35,11 @@
#include <freetype/freetype.h>
#endif
+namespace Glib
+{
+ class ustring;
+}
+
// the font_factory keeps a hashmap of all the loaded font_instances, and uses the PangoFontDescription
// as index (nota: since pango already does that, using the PangoFont could work too)
struct font_descr_hash : public std::unary_function<PangoFontDescription*,size_t> {
@@ -40,6 +49,13 @@ struct font_descr_equal : public std::binary_function<PangoFontDescription*, Pan
bool operator()(PangoFontDescription *const &a, PangoFontDescription *const &b);
};
+// Comparison functions for style names
+int style_name_compare(char const *aa, char const *bb);
+int family_name_compare(char const *a, char const *b);
+
+// Map type for gathering UI family and style strings
+typedef std::map<Glib::ustring, std::list<Glib::ustring> > FamilyToStylesMap;
+
class font_factory {
public:
static font_factory *lUsine; /**< The default font_factory; i cannot think of why we would
@@ -75,9 +91,32 @@ public:
/// Returns the default font_factory.
static font_factory* Default();
+
+ /// Constructs a pango string for use with the fontStringMap (see below)
+ Glib::ustring ConstructFontSpecification(PangoFontDescription *font);
+ Glib::ustring ConstructFontSpecification(font_instance *font);
+
+ /// Returns strings to be used in the UI for family and face (or "style" as the column is labeled)
+ Glib::ustring GetUIFamilyString(PangoFontDescription const *fontDescr);
+ Glib::ustring GetUIStyleString(PangoFontDescription const *fontDescr);
+
+ /// Modifiers for the font specification (returns new font specification)
+ Glib::ustring ReplaceFontSpecificationFamily(const Glib::ustring & fontSpec, const Glib::ustring & newFamily);
+ Glib::ustring FontSpecificationSetItalic(const Glib::ustring & fontSpec, bool turnOn);
+ Glib::ustring FontSpecificationSetBold(const Glib::ustring & fontSpec, bool turnOn);
+
+ // Gathers all strings needed for UI while storing pango information in
+ // fontInstanceMap and fontStringMap
+ void GetUIFamiliesAndStyles(FamilyToStylesMap *map);
+
+ /// Retrieve a font_instance from a style object, first trying to use the font-specification, the CSS information
+ font_instance* FaceFromStyle(SPStyle const *style);
// Various functions to get a font_instance from different descriptions.
font_instance* FaceFromDescr(char const *family, char const *style);
+ font_instance* FaceFromUIStrings(char const *uiFamily, char const *uiStyle);
+ font_instance* FaceFromPangoString(char const *pangoString);
+ font_instance* FaceFromFontSpecification(char const *fontSpecification);
font_instance* Face(PangoFontDescription *descr, bool canFail=true);
font_instance* Face(char const *family,
int variant=PANGO_VARIANT_NORMAL, int style=PANGO_STYLE_NORMAL,
@@ -88,12 +127,23 @@ public:
/// Semi-private: tells the font_factory taht the font_instance 'who' has died and should be removed from loadedFaces
void UnrefFace(font_instance* who);
- // Queries for the font-selector.
- NRNameList* Families(NRNameList *flist);
- NRStyleList* Styles(const gchar *family, NRStyleList *slist);
-
// internal
void AddInCache(font_instance *who);
+
+private:
+ // These two maps are used for translating between what's in the UI and a pango
+ // font description. This is necessary because Pango cannot always
+ // reproduce these structures from the names it gave us in the first place.
+
+ // Key: A string produced by font_factory::ConstructFontSpecification
+ // Value: The associated PangoFontDescription
+ typedef std::map<Glib::ustring, PangoFontDescription *> PangoStringToDescrMap;
+ PangoStringToDescrMap fontInstanceMap;
+
+ // Key: Family name in UI + Style name in UI
+ // Value: The associated string that should be produced with font_factory::ConstructFontSpecification
+ typedef std::map<Glib::ustring, Glib::ustring> UIStringToPangoStringMap;
+ UIStringToPangoStringMap fontStringMap;
};
diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp
index 0b37b14ec..228a34f83 100644
--- a/src/libnrtype/FontInstance.cpp
+++ b/src/libnrtype/FontInstance.cpp
@@ -278,8 +278,10 @@ unsigned int font_instance::Attribute(const gchar *key, gchar *str, unsigned int
res="normal";
} else if ( v <= PANGO_WEIGHT_BOLD ) {
res="bold";
- } else {
- res="800";
+ } else if ( v <= PANGO_WEIGHT_ULTRABOLD ) {
+ res="800";
+ } else { // HEAVY
+ res="900";
}
free_res=false;
} else if ( strcmp(key,"stretch") == 0 ) {
diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp
index 1a2f6d9c8..a7160f5f0 100644
--- a/src/libnrtype/font-lister.cpp
+++ b/src/libnrtype/font-lister.cpp
@@ -15,46 +15,63 @@
#include <gtkmm/liststore.h>
#include "font-lister.h"
+#include "FontFactory.h"
namespace Inkscape
{
- FontLister::FontLister ()
- {
- font_list_store = Gtk::ListStore::create (FontList);
-
- if (font_factory::Default()->Families(&families))
- {
- for (unsigned int i = 0; i < families.length; ++i)
- {
- Gtk::TreeModel::iterator iter = font_list_store->append();
- (*iter)[FontList.font] = reinterpret_cast<const char*>(families.names[i]);
-
- NRStyleList styles;
- if (font_factory::Default()->Styles (reinterpret_cast<const char*>(families.names[i]), &styles));
-
- GList *Styles=0;
- for (unsigned int n = 0; n < styles.length; ++n)
- {
- NRStyleRecord style_record = styles.records[n];
- Styles = g_list_append (Styles, strdup(style_record.name));
- }
-
- (*iter)[FontList.styles] = Styles;
-
- font_list_store_iter_map.insert (std::make_pair (reinterpret_cast<const char*>(families.names[i]), Gtk::TreePath (iter)));
- }
- }
-
+ FontLister::FontLister ()
+ {
+ font_list_store = Gtk::ListStore::create (FontList);
+
+ 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);
+ }
+ 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.font] = reinterpret_cast<const char*>(g_strdup(familyName.c_str()));
+
+ // Now go through the styles
+ GList *styles = NULL;
+ std::list<Glib::ustring> &styleStrings = familyStyleMap[familyName];
+ for (std::list<Glib::ustring>::iterator it=styleStrings.begin();
+ it != styleStrings.end();
+ it++) {
+ styles = g_list_append(styles, g_strdup((*it).c_str()));
}
+
+ (*treeModelIter)[FontList.styles] = styles;
+
+ font_list_store_iter_map.insert(std::make_pair(familyName, Gtk::TreePath(treeModelIter)));
+ }
+ }
+ }
- FontLister::~FontLister ()
- {
- };
+ FontLister::~FontLister ()
+ {
+ };
- const Glib::RefPtr<Gtk::ListStore>
- FontLister::get_font_list () const
- {
- return font_list_store;
- }
+ const Glib::RefPtr<Gtk::ListStore>
+ FontLister::get_font_list () const
+ {
+ return font_list_store;
+ }
}
+
+
+
diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h
index 39953c11c..b2d2a3ecf 100644
--- a/src/libnrtype/font-lister.h
+++ b/src/libnrtype/font-lister.h
@@ -45,7 +45,7 @@ namespace Inkscape
public:
/** Column containing the family name
*/
- Gtk::TreeModelColumn<std::string> font;
+ Gtk::TreeModelColumn<Glib::ustring> font;
/** Column containing an std::vector<std::string> with style names
* for the corresponding family
@@ -60,7 +60,7 @@ namespace Inkscape
};
FontListClass FontList;
- typedef std::map<std::string, Gtk::TreePath> IterMapType;
+ typedef std::map<Glib::ustring, Gtk::TreePath> IterMapType;
/** Returns the ListStore with the font names
*
@@ -79,7 +79,7 @@ namespace Inkscape
}
Gtk::TreePath
- get_row_for_font (std::string family)
+ 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;