1 /*
2 * FontFactory.h
3 * testICU
4 *
5 */
7 #ifndef my_font_factory
8 #define my_font_factory
10 //#include <glibmm/ustring.h>
12 #include <functional>
13 #include <algorithm>
14 #include <ext/hash_map>
16 #ifdef HAVE_CONFIG_H
17 # include <config.h>
18 #endif
19 #ifdef _WIN32
20 #define USE_PANGO_WIN32
21 #endif
23 #include <pango/pango.h>
24 #include "nr-type-primitives.h"
25 #include "nr-type-pos-def.h"
26 #include "font-style-to-pos.h"
27 #include <libnrtype/nrtype-forward.h>
28 #include "../style.h"
30 /* Freetype */
31 #ifdef USE_PANGO_WIN32
32 #include <pango/pangowin32.h>
33 #else
34 #include <pango/pangoft2.h>
35 #include <freetype/freetype.h>
36 #endif
38 namespace Glib
39 {
40 class ustring;
41 }
43 // the font_factory keeps a hashmap of all the loaded font_instances, and uses the PangoFontDescription
44 // as index (nota: since pango already does that, using the PangoFont could work too)
45 struct font_descr_hash : public std::unary_function<PangoFontDescription*,size_t> {
46 size_t operator()(PangoFontDescription *const &x) const;
47 };
48 struct font_descr_equal : public std::binary_function<PangoFontDescription*, PangoFontDescription*, bool> {
49 bool operator()(PangoFontDescription *const &a, PangoFontDescription *const &b);
50 };
52 // Comparison functions for style names
53 int style_name_compare(char const *aa, char const *bb);
54 int family_name_compare(char const *a, char const *b);
56 // Map type for gathering UI family and style strings
57 typedef std::map<Glib::ustring, std::list<Glib::ustring> > FamilyToStylesMap;
59 class font_factory {
60 public:
61 static font_factory *lUsine; /**< The default font_factory; i cannot think of why we would
62 * need more than one.
63 *
64 * ("l'usine" is french for "the factory".)
65 */
67 /** A little cache for fonts, so that you don't loose your time looking up fonts in the font list
68 * each font in the cache is refcounted once (and deref'd when removed from the cache). */
69 struct font_entry {
70 font_instance *f;
71 double age;
72 };
73 int nbEnt; ///< Number of entries.
74 int maxEnt; ///< Cache size.
75 font_entry *ents;
77 // Pango data. Backend-specific structures are cast to these opaque types.
78 PangoFontMap *fontServer;
79 PangoContext *fontContext;
80 #ifdef USE_PANGO_WIN32
81 PangoWin32FontCache *pangoFontCache;
82 HDC hScreenDC;
83 #endif
84 double fontSize; /**< The huge fontsize used as workaround for hinting.
85 * Different between freetype and win32. */
87 __gnu_cxx::hash_map<PangoFontDescription*, font_instance*, font_descr_hash, font_descr_equal> loadedFaces;
89 font_factory();
90 virtual ~font_factory();
92 /// Returns the default font_factory.
93 static font_factory* Default();
95 /// Constructs a pango string for use with the fontStringMap (see below)
96 Glib::ustring ConstructFontSpecification(PangoFontDescription *font);
97 Glib::ustring ConstructFontSpecification(font_instance *font);
99 /// Returns strings to be used in the UI for family and face (or "style" as the column is labeled)
100 Glib::ustring GetUIFamilyString(PangoFontDescription const *fontDescr);
101 Glib::ustring GetUIStyleString(PangoFontDescription const *fontDescr);
103 /// Modifiers for the font specification (returns new font specification)
104 Glib::ustring ReplaceFontSpecificationFamily(const Glib::ustring & fontSpec, const Glib::ustring & newFamily);
105 Glib::ustring FontSpecificationSetItalic(const Glib::ustring & fontSpec, bool turnOn);
106 Glib::ustring FontSpecificationSetBold(const Glib::ustring & fontSpec, bool turnOn);
108 // Gathers all strings needed for UI while storing pango information in
109 // fontInstanceMap and fontStringMap
110 void GetUIFamiliesAndStyles(FamilyToStylesMap *map);
112 /// Retrieve a font_instance from a style object, first trying to use the font-specification, the CSS information
113 font_instance* FaceFromStyle(SPStyle const *style);
115 // Various functions to get a font_instance from different descriptions.
116 font_instance* FaceFromDescr(char const *family, char const *style);
117 font_instance* FaceFromUIStrings(char const *uiFamily, char const *uiStyle);
118 font_instance* FaceFromPangoString(char const *pangoString);
119 font_instance* FaceFromFontSpecification(char const *fontSpecification);
120 font_instance* Face(PangoFontDescription *descr, bool canFail=true);
121 font_instance* Face(char const *family,
122 int variant=PANGO_VARIANT_NORMAL, int style=PANGO_STYLE_NORMAL,
123 int weight=PANGO_WEIGHT_NORMAL, int stretch=PANGO_STRETCH_NORMAL,
124 int size=10, int spacing=0);
125 font_instance* Face(char const *family, NRTypePosDef apos);
127 /// Semi-private: tells the font_factory taht the font_instance 'who' has died and should be removed from loadedFaces
128 void UnrefFace(font_instance* who);
130 // internal
131 void AddInCache(font_instance *who);
133 private:
134 // These two maps are used for translating between what's in the UI and a pango
135 // font description. This is necessary because Pango cannot always
136 // reproduce these structures from the names it gave us in the first place.
138 // Key: A string produced by font_factory::ConstructFontSpecification
139 // Value: The associated PangoFontDescription
140 typedef std::map<Glib::ustring, PangoFontDescription *> PangoStringToDescrMap;
141 PangoStringToDescrMap fontInstanceMap;
143 // Key: Family name in UI + Style name in UI
144 // Value: The associated string that should be produced with font_factory::ConstructFontSpecification
145 typedef std::map<Glib::ustring, Glib::ustring> UIStringToPangoStringMap;
146 UIStringToPangoStringMap fontStringMap;
147 };
150 #endif /* my_font_factory */
153 /*
154 Local Variables:
155 mode:c++
156 c-file-style:"stroustrup"
157 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
158 indent-tabs-mode:nil
159 fill-column:99
160 End:
161 */
162 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :