1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /** @file 3 * TODO: insert short description here 4 *//* 5 * Authors: see git history 6 * 7 * Copyright (C) 2018 Authors 8 * Released under GNU GPL v2+, read the file 'COPYING' for more information. 9 */ 10 /* 11 * FontFactory.h 12 * testICU 13 * 14 */ 15 16 #ifndef my_font_factory 17 #define my_font_factory 18 19 #include <functional> 20 #include <algorithm> 21 #include <utility> 22 23 #ifdef _WIN32 24 //#define USE_PANGO_WIN32 // disable for Bug 165665 25 #endif 26 27 #include <pango/pango.h> 28 #include "style.h" 29 30 /* Freetype */ 31 #ifdef USE_PANGO_WIN32 32 #include <pango/pangowin32.h> 33 #else 34 #include <pango/pangoft2.h> 35 #include <ft2build.h> 36 #include FT_FREETYPE_H 37 #endif 38 39 40 class font_instance; 41 42 namespace Glib 43 { 44 class ustring; 45 } 46 47 // the font_factory keeps a hashmap of all the loaded font_instances, and uses the PangoFontDescription 48 // as index (nota: since pango already does that, using the PangoFont could work too) 49 struct font_descr_hash : public std::unary_function<PangoFontDescription*,size_t> { 50 size_t operator()(PangoFontDescription *const &x) const; 51 }; 52 struct font_descr_equal : public std::binary_function<PangoFontDescription*, PangoFontDescription*, bool> { 53 bool operator()(PangoFontDescription *const &a, PangoFontDescription *const &b) const; 54 }; 55 56 // Constructs a PangoFontDescription from SPStyle. Font size is not included. 57 // User must free return value. 58 PangoFontDescription* ink_font_description_from_style(SPStyle const *style); 59 60 // Wraps calls to pango_font_description_get_family with some name substitution 61 const char *sp_font_description_get_family(PangoFontDescription const *fontDescr); 62 63 // Class for style strings: both CSS and as suggested by font. 64 class StyleNames { 65 66 public: 67 StyleNames() = default;; StyleNames(Glib::ustring name)68 StyleNames( Glib::ustring name ) : 69 CssName( name ), DisplayName( name ) {}; StyleNames(Glib::ustring cssname,Glib::ustring displayname)70 StyleNames( Glib::ustring cssname, Glib::ustring displayname ) : 71 CssName(std::move( cssname )), DisplayName(std::move( displayname )) {}; 72 73 public: 74 Glib::ustring CssName; // Style as Pango/CSS would write it. 75 Glib::ustring DisplayName; // Style as Font designer named it. 76 }; 77 78 // Map type for gathering UI family and style names 79 // typedef std::map<Glib::ustring, std::list<StyleNames> > FamilyToStylesMap; 80 81 class font_factory { 82 public: 83 static font_factory *lUsine; /**< The default font_factory; i cannot think of why we would 84 * need more than one. 85 * 86 * ("l'usine" is french for "the factory".) 87 */ 88 89 /** A little cache for fonts, so that you don't loose your time looking up fonts in the font list 90 * each font in the cache is refcounted once (and deref'd when removed from the cache). */ 91 struct font_entry { 92 font_instance *f; 93 double age; 94 }; 95 int nbEnt; ///< Number of entries. 96 int maxEnt; ///< Cache size. 97 font_entry *ents; 98 99 // Pango data. Backend-specific structures are cast to these opaque types. 100 PangoFontMap *fontServer; 101 PangoContext *fontContext; 102 #ifdef USE_PANGO_WIN32 103 PangoWin32FontCache *pangoFontCache; 104 HDC hScreenDC; 105 #endif 106 double fontSize; /**< The huge fontsize used as workaround for hinting. 107 * Different between freetype and win32. */ 108 109 font_factory(); 110 virtual ~font_factory(); 111 112 /// Returns the default font_factory. 113 static font_factory* Default(); 114 115 /// Constructs a pango string for use with the fontStringMap (see below) 116 Glib::ustring ConstructFontSpecification(PangoFontDescription *font); 117 Glib::ustring ConstructFontSpecification(font_instance *font); 118 119 /// Returns strings to be used in the UI for family and face (or "style" as the column is labeled) 120 Glib::ustring GetUIFamilyString(PangoFontDescription const *fontDescr); 121 Glib::ustring GetUIStyleString(PangoFontDescription const *fontDescr); 122 123 // Helpfully inserts all font families into the provided vector 124 void GetUIFamilies(std::vector<PangoFontFamily *>& out); 125 // Retrieves style information about a family in a newly allocated GList. 126 GList* GetUIStyles(PangoFontFamily * in); 127 128 /// Retrieve a font_instance from a style object, first trying to use the font-specification, the CSS information 129 font_instance* FaceFromStyle(SPStyle const *style); 130 131 // Various functions to get a font_instance from different descriptions. 132 font_instance* FaceFromDescr(char const *family, char const *style); 133 font_instance* FaceFromUIStrings(char const *uiFamily, char const *uiStyle); 134 font_instance* FaceFromPangoString(char const *pangoString); 135 font_instance* FaceFromFontSpecification(char const *fontSpecification); 136 font_instance* Face(PangoFontDescription *descr, bool canFail=true); 137 font_instance* Face(char const *family, 138 int variant=PANGO_VARIANT_NORMAL, int style=PANGO_STYLE_NORMAL, 139 int weight=PANGO_WEIGHT_NORMAL, int stretch=PANGO_STRETCH_NORMAL, 140 int size=10, int spacing=0); 141 142 /// Semi-private: tells the font_factory that the font_instance 'who' has died and should be removed from loadedFaces 143 void UnrefFace(font_instance* who); 144 145 // internal 146 void AddInCache(font_instance *who); 147 148 # ifdef _WIN32 149 void AddFontFilesWin32(char const *directory_path); 150 # endif 151 152 /// Add a directory from which to include additional fonts 153 void AddFontsDir(char const *utf8dir); 154 155 /// Add a an additional font. 156 void AddFontFile(char const *utf8file); 157 158 private: 159 void* loadedPtr; 160 161 162 // The following two commented out maps were an attempt to allow Inkscape to use font faces 163 // that could not be distinguished by CSS values alone. In practice, they never were that 164 // useful as PangoFontDescription, which is used throughout our code, cannot distinguish 165 // between faces anymore than raw CSS values (with the exception of two additional weight 166 // values). 167 // 168 // During various works, for example to handle font-family lists and fonts that are not 169 // installed on the system, the code has become less reliant on these maps. And in the work to 170 // catch style information to speed up start up times, the maps were not being filled. 171 // I've removed all code that used these maps as of Oct 2014 in the experimental branch. 172 // The commented out maps are left here as a reminder of the path that was attempted. 173 // 174 // One possible method to keep track of font faces would be to use the 'display name', keeping 175 // pointers to the appropriate PangoFontFace. The font_factory loadedFaces map indexing would 176 // have to be changed to incorporate 'display name' (InkscapeFontDescription?). 177 178 179 // These two maps are used for translating between what's in the UI and a pango 180 // font description. This is necessary because Pango cannot always 181 // reproduce these structures from the names it gave us in the first place. 182 183 // Key: A string produced by font_factory::ConstructFontSpecification 184 // Value: The associated PangoFontDescription 185 // typedef std::map<Glib::ustring, PangoFontDescription *> PangoStringToDescrMap; 186 // PangoStringToDescrMap fontInstanceMap; 187 188 // Key: Family name in UI + Style name in UI 189 // Value: The associated string that should be produced with font_factory::ConstructFontSpecification 190 // typedef std::map<Glib::ustring, Glib::ustring> UIStringToPangoStringMap; 191 // UIStringToPangoStringMap fontStringMap; 192 }; 193 194 195 #endif /* my_font_factory */ 196 197 198 /* 199 Local Variables: 200 mode:c++ 201 c-file-style:"stroustrup" 202 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) 203 indent-tabs-mode:nil 204 fill-column:99 205 End: 206 */ 207 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : 208