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