summaryrefslogtreecommitdiffstats
path: root/src/libnrtype/font-instance.h
blob: fb99d158f8374648e34f817a7f69c5a5ed8d7410 (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
// 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.
 */
#ifndef SEEN_LIBNRTYPE_FONT_INSTANCE_H
#define SEEN_LIBNRTYPE_FONT_INSTANCE_H

#include <map>

#include <pango/pango-types.h>
#include <pango/pango-font.h>

#include <2geom/d2.h>

#include "FontFactory.h"
#include "font-style.h"
#include "OpenTypeUtil.h"

namespace Inkscape { class Pixbuf; }

class font_factory;
struct font_glyph;

// the font_instance are the template of several raster_font; they provide metrics and outlines
// that are drawn by the raster_font, so the raster_font needs info relative to the way the
// font need to be drawn. note that fontsize is a scale factor in the transform matrix
// of the style
class font_instance {
public:
    // the real source of the font
    PangoFont*            pFont = nullptr;
    // depending on the rendering backend, different temporary data

    // that's the font's fingerprint; this particular PangoFontDescription gives the entry at which this font_instance
    // resides in the font_factory loadedFaces unordered_map
    PangoFontDescription* descr = nullptr;
    // refcount
    int                   refCount = 0;
    // font_factory owning this font_instance
    font_factory*         parent = nullptr;

    // common glyph definitions for all the rasterfonts
    std::map<int, int>    id_to_no;
    int                   nbGlyph = 0;
    int                   maxGlyph = 0;

    font_glyph*           glyphs = nullptr;

    // font is loaded with GSUB in 2 pass
    bool    fulloaded = false;

    // Map of OpenType tables found in font.
    std::map<Glib::ustring, OTSubstitution> openTypeTables;

    // Maps for font variations.
    std::map<Glib::ustring, OTVarAxis> openTypeVarAxes;      // Axes with ranges

    // Map of SVG in OpenType glyphs
    std::map<int, SVGTableEntry> openTypeSVGGlyphs;

    // Does OpenType font contain SVG glyphs?
    bool   fontHasSVG = false;

    font_instance();
    virtual ~font_instance();

    void                 Ref();
    void                 Unref();

    bool                 IsOutlineFont(); // utility
    void                 InstallFace(PangoFont* iFace); // utility; should reset the pFont field if loading failed
    // in case the PangoFont is a bitmap font, for example. that way, the calling function
    // will be able to check the validity of the font before installing it in loadedFaces
    void                 InitTheFace(bool loadgsub = false);

    int                  MapUnicodeChar(gunichar c); // calls the relevant unicode->glyph index function
    void                 LoadGlyph(int glyph_id);    // the main backend-dependent function
    // loads the given glyph's info

    // nota: all coordinates returned by these functions are on a [0..1] scale; you need to multiply
    // by the fontsize to get the real sizes

    // Return 2geom pathvector for glyph. Deallocated when font instance dies.
    Geom::PathVector*    PathVector(int glyph_id);

    // Return font has SVG OpenType enties.
    bool                 FontHasSVG() { return fontHasSVG; };

    // Return pixbuf of SVG glyph or nullptr if no SVG glyph exists.
    Inkscape::Pixbuf*    PixBuf(int glyph_id);


    // Horizontal advance if 'vertical' is false, vertical advance if true.
    double               Advance(int glyph_id, bool vertical);

    double               GetTypoAscent()  { return _ascent; }
    double               GetTypoDescent() { return _descent; }
    double               GetXHeight()     { return _xheight; }
    double               GetMaxAscent()   { return _ascent_max; }
    double               GetMaxDescent()  { return _descent_max; }
    const double*        GetBaselines()   { return _baselines; }
    int                  GetDesignUnits() { return _design_units; }

    bool                 FontMetrics(double &ascent, double &descent, double &leading);
    bool                 FontDecoration(double &underline_position, double &underline_thickness,
                                        double &linethrough_position, double &linethrough_thickness);
    bool                 FontSlope(double &run, double &rise);
                                // for generating slanted cursors for oblique fonts
    Geom::OptRect        BBox(int glyph_id);

private:
    void                 FreeTheFace();
    // Find ascent, descent, x-height, and baselines.
    void                 FindFontMetrics();

    // Temp: make public
public:
#ifdef USE_PANGO_WIN32
    HFONT                 theFace = nullptr;
#else
    // we need to keep around an rw copy of the (read-only) hb font to extract the freetype face
    hb_font_t*            hb_font_copy = nullptr;
    FT_Face               theFace = nullptr;
                // it's a pointer in fact; no worries to ref/unref it, pango does its magic
                // as long as pFont is valid, theFace is too
#endif

private:
    // Font metrics in em-box units
    double  _ascent;       // Typographic ascent.
    double  _descent;      // Typographic descent.
    double  _xheight;      // x-height of font.
    double  _ascent_max;   // Maximum ascent of all glyphs in font.
    double  _descent_max;  // Maximum descent of all glyphs in font.
    int     _design_units; // Design units, (units per em, typically 1000 or 2048).

    // Baselines
    double _baselines[SP_CSS_BASELINE_SIZE];
};


#endif /* !SEEN_LIBNRTYPE_FONT_INSTANCE_H */

/*
  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 :