diff options
Diffstat (limited to '')
-rw-r--r-- | src/libnrtype/FontFactory.h | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/src/libnrtype/FontFactory.h b/src/libnrtype/FontFactory.h new file mode 100644 index 0000000..e3bf1d2 --- /dev/null +++ b/src/libnrtype/FontFactory.h @@ -0,0 +1,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 : |