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 #ifndef SEEN_LIBNRTYPE_FONT_INSTANCE_H
11 #define SEEN_LIBNRTYPE_FONT_INSTANCE_H
12 
13 #include <map>
14 
15 #include <pango/pango-types.h>
16 #include <pango/pango-font.h>
17 
18 #include <2geom/d2.h>
19 
20 #include "FontFactory.h"
21 #include "font-style.h"
22 #include "OpenTypeUtil.h"
23 
24 namespace Inkscape { class Pixbuf; }
25 
26 class font_factory;
27 struct font_glyph;
28 
29 // the font_instance are the template of several raster_font; they provide metrics and outlines
30 // that are drawn by the raster_font, so the raster_font needs info relative to the way the
31 // font need to be drawn. note that fontsize is a scale factor in the transform matrix
32 // of the style
33 class font_instance {
34 public:
35     // the real source of the font
36     PangoFont*            pFont = nullptr;
37     // depending on the rendering backend, different temporary data
38 
39     // that's the font's fingerprint; this particular PangoFontDescription gives the entry at which this font_instance
40     // resides in the font_factory loadedFaces unordered_map
41     PangoFontDescription* descr = nullptr;
42     // refcount
43     int                   refCount = 0;
44     // font_factory owning this font_instance
45     font_factory*         parent = nullptr;
46 
47     // common glyph definitions for all the rasterfonts
48     std::map<int, int>    id_to_no;
49     int                   nbGlyph = 0;
50     int                   maxGlyph = 0;
51 
52     font_glyph*           glyphs = nullptr;
53 
54     // font is loaded with GSUB in 2 pass
55     bool    fulloaded = false;
56 
57     // Map of OpenType tables found in font.
58     std::map<Glib::ustring, OTSubstitution> openTypeTables;
59 
60     // Maps for font variations.
61     std::map<Glib::ustring, OTVarAxis> openTypeVarAxes;      // Axes with ranges
62 
63     // Map of SVG in OpenType glyphs
64     std::map<int, SVGTableEntry> openTypeSVGGlyphs;
65 
66     // Does OpenType font contain SVG glyphs?
67     bool   fontHasSVG = false;
68 
69     font_instance();
70     virtual ~font_instance();
71 
72     void                 Ref();
73     void                 Unref();
74 
75     bool                 IsOutlineFont(); // utility
76     void                 InstallFace(PangoFont* iFace); // utility; should reset the pFont field if loading failed
77     // in case the PangoFont is a bitmap font, for example. that way, the calling function
78     // will be able to check the validity of the font before installing it in loadedFaces
79     void                 InitTheFace(bool loadgsub = false);
80 
81     int                  MapUnicodeChar(gunichar c); // calls the relevant unicode->glyph index function
82     void                 LoadGlyph(int glyph_id);    // the main backend-dependent function
83     // loads the given glyph's info
84 
85     // nota: all coordinates returned by these functions are on a [0..1] scale; you need to multiply
86     // by the fontsize to get the real sizes
87 
88     // Return 2geom pathvector for glyph. Deallocated when font instance dies.
89     Geom::PathVector*    PathVector(int glyph_id);
90 
91     // Return font has SVG OpenType enties.
FontHasSVG()92     bool                 FontHasSVG() { return fontHasSVG; };
93 
94     // Return pixbuf of SVG glyph or nullptr if no SVG glyph exists.
95     Inkscape::Pixbuf*    PixBuf(int glyph_id);
96 
97 
98     // Horizontal advance if 'vertical' is false, vertical advance if true.
99     double               Advance(int glyph_id, bool vertical);
100 
GetTypoAscent()101     double               GetTypoAscent()  { return _ascent; }
GetTypoDescent()102     double               GetTypoDescent() { return _descent; }
GetXHeight()103     double               GetXHeight()     { return _xheight; }
GetMaxAscent()104     double               GetMaxAscent()   { return _ascent_max; }
GetMaxDescent()105     double               GetMaxDescent()  { return _descent_max; }
GetBaselines()106     const double*        GetBaselines()   { return _baselines; }
GetDesignUnits()107     int                  GetDesignUnits() { return _design_units; }
108 
109     bool                 FontMetrics(double &ascent, double &descent, double &leading);
110     bool                 FontDecoration(double &underline_position, double &underline_thickness,
111                                         double &linethrough_position, double &linethrough_thickness);
112     bool                 FontSlope(double &run, double &rise);
113                                 // for generating slanted cursors for oblique fonts
114     Geom::OptRect        BBox(int glyph_id);
115 
116 private:
117     void                 FreeTheFace();
118     // Find ascent, descent, x-height, and baselines.
119     void                 FindFontMetrics();
120 
121     // Temp: make public
122 public:
123 #ifdef USE_PANGO_WIN32
124     HFONT                 theFace = nullptr;
125 #else
126     FT_Face               theFace = nullptr;
127                 // it's a pointer in fact; no worries to ref/unref it, pango does its magic
128                 // as long as pFont is valid, theFace is too
129 #endif
130 
131 private:
132     // Font metrics in em-box units
133     double  _ascent;       // Typographic ascent.
134     double  _descent;      // Typographic descent.
135     double  _xheight;      // x-height of font.
136     double  _ascent_max;   // Maximum ascent of all glyphs in font.
137     double  _descent_max;  // Maximum descent of all glyphs in font.
138     int     _design_units; // Design units, (units per em, typically 1000 or 2048).
139 
140     // Baselines
141     double _baselines[SP_CSS_BASELINE_SIZE];
142 };
143 
144 
145 #endif /* !SEEN_LIBNRTYPE_FONT_INSTANCE_H */
146 
147 /*
148   Local Variables:
149   mode:c++
150   c-file-style:"stroustrup"
151   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
152   indent-tabs-mode:nil
153   fill-column:99
154   End:
155 */
156 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
157