summaryrefslogtreecommitdiffstats
path: root/src/extension/internal/pdfinput/poppler-cairo-font-engine.h
blob: d3e1a94e845771a4314c6939d353756dbed14ee5 (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
// SPDX-License-Identifier: GPL-2.0-or-later
//========================================================================
//
// CairoFontEngine.h
//
// Copyright 2003 Glyph & Cog, LLC
// Copyright 2004 Red Hat, Inc
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2005, 2006 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2005, 2018, 2019, 2021 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2006, 2007 Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2006, 2010 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2008, 2017, 2022 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
// Copyright (C) 2022 Oliver Sander <oliver.sander@tu-dresden.de>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#ifndef CAIROFONTENGINE_H
#define CAIROFONTENGINE_H

#include <cairo-ft.h>
#include <memory>
#include <mutex>
#include <optional>
#include <unordered_map>
#include <vector>

#include "GfxFont.h"
#include "PDFDoc.h"
#include "poppler-config.h"
#include "poppler-transition-api.h"

class CairoFontEngine;

class CairoFont
{
public:
    CairoFont(Ref refA, cairo_font_face_t *cairo_font_faceA, std::vector<int> &&codeToGIDA, bool substituteA,
              bool printingA);
    virtual ~CairoFont();
    CairoFont(const CairoFont &) = delete;
    CairoFont &operator=(const CairoFont &other) = delete;

    virtual bool matches(Ref &other, bool printing);
    cairo_font_face_t *getFontFace();
    unsigned long getGlyph(CharCode code, const Unicode *u, int uLen);
#if POPPLER_CHECK_VERSION(22, 4, 0)
    double getSubstitutionCorrection(const std::shared_ptr<GfxFont> &gfxFont);
#else
    double getSubstitutionCorrection(GfxFont *gfxFont);
#endif

    bool isSubstitute() { return substitute; }

protected:
    Ref ref;
    cairo_font_face_t *cairo_font_face;

    std::vector<int> codeToGID;

    bool substitute;
    bool printing;
};

//------------------------------------------------------------------------

struct FreeTypeFontFace
{
    FT_Face face;
    cairo_font_face_t *cairo_font_face;
};

class CairoFreeTypeFont : public CairoFont
{
public:
#if POPPLER_CHECK_VERSION(22, 4, 0)
    static CairoFreeTypeFont *create(const std::shared_ptr<GfxFont> &gfxFont, XRef *xref, FT_Library lib,
                                     CairoFontEngine *fontEngine, bool useCIDs);
#else
    static CairoFreeTypeFont *create(GfxFont *gfxFont, XRef *xref, FT_Library lib, CairoFontEngine *fontEngine,
                                     bool useCIDs);
#endif
    ~CairoFreeTypeFont() override;

private:
    CairoFreeTypeFont(Ref ref, cairo_font_face_t *cairo_font_face, std::vector<int> &&codeToGID, bool substitute);

    static std::optional<FreeTypeFontFace> getFreeTypeFontFace(CairoFontEngine *fontEngine, FT_Library lib,
                                                               const std::string &filename,
                                                               std::vector<unsigned char> &&data);
};

//------------------------------------------------------------------------

class CairoType3Font : public CairoFont
{
public:
#if POPPLER_CHECK_VERSION(22, 4, 0)
    static CairoType3Font *create(const std::shared_ptr<GfxFont> &gfxFont, PDFDoc *doc, CairoFontEngine *fontEngine,
                                  bool printing, XRef *xref);
#else
    static CairoType3Font *create(GfxFont *gfxFont, PDFDoc *doc, CairoFontEngine *fontEngine, bool printing,
                                  XRef *xref);
#endif
    ~CairoType3Font() override;

    bool matches(Ref &other, bool printing) override;

private:
    CairoType3Font(Ref ref, cairo_font_face_t *cairo_font_face, std::vector<int> &&codeToGIDA, bool printing,
                   XRef *xref);
};

//------------------------------------------------------------------------

//------------------------------------------------------------------------
// CairoFontEngine
//------------------------------------------------------------------------

class CairoFontEngine
{
public:
    // Create a font engine.
    explicit CairoFontEngine(FT_Library libA);
    ~CairoFontEngine();
    CairoFontEngine(const CairoFontEngine &) = delete;
    CairoFontEngine &operator=(const CairoFontEngine &other) = delete;

#if POPPLER_CHECK_VERSION(22, 4, 0)
    std::shared_ptr<CairoFont> getFont(const std::shared_ptr<GfxFont> &gfxFont, PDFDoc *doc, bool printing, XRef *xref);
#else
    std::shared_ptr<CairoFont> getFont(GfxFont *gfxFont, PDFDoc *doc, bool printing, XRef *xref);
#endif

    static std::optional<FreeTypeFontFace> getExternalFontFace(FT_Library ftlib, const std::string &filename);

private:
    FT_Library lib;
    bool useCIDs;
    mutable std::mutex mutex;

    // Cache of CairoFont for current document
    // Most recently used is at the end of the vector.
    static const size_t cairoFontCacheSize = 64;
    std::vector<std::shared_ptr<CairoFont>> fontCache;

    // Global cache of cairo_font_face_t for external font files.
    static std::unordered_map<std::string, FreeTypeFontFace> fontFileCache;
    static std::recursive_mutex fontFileCacheMutex;
};

#endif