summaryrefslogtreecommitdiffstats
path: root/src/libnrtype/FontFactory.h
blob: e3bf1d269053ccefbca64086a79d353e9fc5c221 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
// SPDX-License-Identifier: GPL-2.0-or-later
/** @file
 * TODO: insert short description here
 *//*
 * Authors: see git history
 *
 * Copyright (C) 2018 Authors
 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
 */
/*
 *  FontFactory.h
 *  testICU
 *
 */

#ifndef my_font_factory
#define my_font_factory

#include <functional>
#include <algorithm>
#include <utility>

#ifdef _WIN32
//#define USE_PANGO_WIN32 // disable for Bug 165665
#endif

#include <pango/pango.h>
#include "style.h"

/* Freetype */
#ifdef USE_PANGO_WIN32
#include <pango/pangowin32.h>
#else
#include <pango/pangoft2.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#endif


class font_instance;

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> {
    size_t operator()(PangoFontDescription *const &x) const;
};
struct font_descr_equal : public std::binary_function<PangoFontDescription*, PangoFontDescription*, bool> {
    bool operator()(PangoFontDescription *const &a, PangoFontDescription *const &b) const;
};

// Constructs a PangoFontDescription from SPStyle. Font size is not included.
// User must free return value.
PangoFontDescription* ink_font_description_from_style(SPStyle const *style);

// Wraps calls to pango_font_description_get_family with some name substitution
const char *sp_font_description_get_family(PangoFontDescription const *fontDescr);

// Class for style strings: both CSS and as suggested by font.
class StyleNames {

public:
    StyleNames() = default;;
    StyleNames( Glib::ustring name ) :
        CssName( name ), DisplayName( name ) {};
    StyleNames( Glib::ustring cssname, Glib::ustring displayname ) :
        CssName(std::move( cssname )), DisplayName(std::move( displayname )) {};

public:
    Glib::ustring CssName;     // Style as Pango/CSS would write it.
    Glib::ustring DisplayName; // Style as Font designer named it.
};

// Map type for gathering UI family and style names
// typedef std::map<Glib::ustring, std::list<StyleNames> > FamilyToStylesMap;

class font_factory {
public:
    static font_factory *lUsine; /**< The default font_factory; i cannot think of why we would
                                  *   need more than one.
                                  *
                                  *   ("l'usine" is french for "the factory".)
                                  */

    /** A little cache for fonts, so that you don't loose your time looking up fonts in the font list
     *  each font in the cache is refcounted once (and deref'd when removed from the cache). */
    struct font_entry {
        font_instance *f;
        double age;
    };
    int nbEnt;   ///< Number of entries.
    int maxEnt;  ///< Cache size.
    font_entry *ents;

    // Pango data.  Backend-specific structures are cast to these opaque types.
    PangoFontMap *fontServer;
    PangoContext *fontContext;
#ifdef USE_PANGO_WIN32
    PangoWin32FontCache *pangoFontCache;
    HDC hScreenDC;
#endif
    double fontSize; /**< The huge fontsize used as workaround for hinting.
                      *   Different between freetype and win32. */

    font_factory();
    virtual ~font_factory();

    /// 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);

    // Helpfully inserts all font families into the provided vector
    void                  GetUIFamilies(std::vector<PangoFontFamily *>& out);
    // Retrieves style information about a family in a newly allocated GList.
    GList*                GetUIStyles(PangoFontFamily * in);

    /// 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,
                               int weight=PANGO_WEIGHT_NORMAL, int stretch=PANGO_STRETCH_NORMAL,
                               int size=10, int spacing=0);

    /// Semi-private: tells the font_factory that the font_instance 'who' has died and should be removed from loadedFaces
    void                  UnrefFace(font_instance* who);

    // internal
    void                  AddInCache(font_instance *who);

# ifdef _WIN32
    void                  AddFontFilesWin32(char const *directory_path);
# endif

    /// Add a directory from which to include additional fonts
    void                  AddFontsDir(char const *utf8dir);

    /// Add a an additional font.
    void                  AddFontFile(char const *utf8file);

private:
    void*                 loadedPtr;


    // The following two commented out maps were an attempt to allow Inkscape to use font faces
    // that could not be distinguished by CSS values alone. In practice, they never were that
    // useful as PangoFontDescription, which is used throughout our code, cannot distinguish
    // between faces anymore than raw CSS values (with the exception of two additional weight
    // values).
    //
    // During various works, for example to handle font-family lists and fonts that are not
    // installed on the system, the code has become less reliant on these maps. And in the work to
    // catch style information to speed up start up times, the maps were not being filled.
    // I've removed all code that used these maps as of Oct 2014 in the experimental branch.
    // The commented out maps are left here as a reminder of the path that was attempted.
    //
    // One possible method to keep track of font faces would be to use the 'display name', keeping
    // pointers to the appropriate PangoFontFace. The font_factory loadedFaces map indexing would
    // have to be changed to incorporate 'display name' (InkscapeFontDescription?).


    // 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;
};


#endif /* my_font_factory */


/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
  indent-tabs-mode:nil
  fill-column:99
  End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :