1 | //======================================================================== |
2 | // |
3 | // CairoFontEngine.h |
4 | // |
5 | // Copyright 2003 Glyph & Cog, LLC |
6 | // Copyright 2004 Red Hat, Inc |
7 | // |
8 | //======================================================================== |
9 | |
10 | //======================================================================== |
11 | // |
12 | // Modified under the Poppler project - http://poppler.freedesktop.org |
13 | // |
14 | // All changes made under the Poppler project to this file are licensed |
15 | // under GPL version 2 or later |
16 | // |
17 | // Copyright (C) 2005, 2006 Kristian Høgsberg <krh@redhat.com> |
18 | // Copyright (C) 2005, 2018, 2019, 2021 Albert Astals Cid <aacid@kde.org> |
19 | // Copyright (C) 2006, 2007 Jeff Muizelaar <jeff@infidigm.net> |
20 | // Copyright (C) 2006, 2010 Carlos Garcia Campos <carlosgc@gnome.org> |
21 | // Copyright (C) 2008, 2017, 2022 Adrian Johnson <ajohnson@redneon.com> |
22 | // Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de> |
23 | // Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de> |
24 | // Copyright (C) 2022 Oliver Sander <oliver.sander@tu-dresden.de> |
25 | // Copyright (C) 2022 Marek Kasik <mkasik@redhat.com> |
26 | // |
27 | // To see a description of the changes please see the Changelog file that |
28 | // came with your tarball or type make ChangeLog if you are building from git |
29 | // |
30 | //======================================================================== |
31 | |
32 | #ifndef CAIROFONTENGINE_H |
33 | #define CAIROFONTENGINE_H |
34 | |
35 | #include <memory> |
36 | #include <mutex> |
37 | #include <unordered_map> |
38 | #include <vector> |
39 | |
40 | #include "poppler-config.h" |
41 | #include <cairo-ft.h> |
42 | |
43 | #include "GfxFont.h" |
44 | #include "PDFDoc.h" |
45 | |
46 | class CairoFontEngine; |
47 | |
48 | class CairoFont |
49 | { |
50 | public: |
51 | CairoFont(Ref refA, cairo_font_face_t *cairo_font_faceA, std::vector<int> &&codeToGIDA, bool substituteA, bool printingA); |
52 | virtual ~CairoFont(); |
53 | CairoFont(const CairoFont &) = delete; |
54 | CairoFont &operator=(const CairoFont &other) = delete; |
55 | |
56 | virtual bool matches(Ref &other, bool printing); |
57 | cairo_font_face_t *getFontFace(); |
58 | unsigned long getGlyph(CharCode code, const Unicode *u, int uLen); |
59 | double getSubstitutionCorrection(const std::shared_ptr<GfxFont> &gfxFont); |
60 | |
61 | bool isSubstitute() { return substitute; } |
62 | |
63 | Ref getRef() { return ref; } |
64 | |
65 | protected: |
66 | Ref ref; |
67 | cairo_font_face_t *cairo_font_face; |
68 | |
69 | std::vector<int> codeToGID; |
70 | |
71 | bool substitute; |
72 | bool printing; |
73 | }; |
74 | |
75 | //------------------------------------------------------------------------ |
76 | |
77 | struct FreeTypeFontFace |
78 | { |
79 | FT_Face face; |
80 | cairo_font_face_t *cairo_font_face; |
81 | }; |
82 | |
83 | class CairoFreeTypeFont : public CairoFont |
84 | { |
85 | public: |
86 | static CairoFreeTypeFont *create(const std::shared_ptr<GfxFont> &gfxFont, XRef *xref, FT_Library lib, CairoFontEngine *fontEngine, bool useCIDs); |
87 | ~CairoFreeTypeFont() override; |
88 | |
89 | private: |
90 | CairoFreeTypeFont(Ref ref, cairo_font_face_t *cairo_font_face, std::vector<int> &&codeToGID, bool substitute); |
91 | |
92 | static std::optional<FreeTypeFontFace> getFreeTypeFontFace(CairoFontEngine *fontEngine, FT_Library lib, const std::string &filename, std::vector<unsigned char> &&data); |
93 | }; |
94 | |
95 | //------------------------------------------------------------------------ |
96 | |
97 | class CairoType3Font : public CairoFont |
98 | { |
99 | public: |
100 | static CairoType3Font *create(const std::shared_ptr<GfxFont> &gfxFont, PDFDoc *doc, CairoFontEngine *fontEngine, bool printing, XRef *xref); |
101 | ~CairoType3Font() override; |
102 | |
103 | bool matches(Ref &other, bool printing) override; |
104 | |
105 | private: |
106 | CairoType3Font(Ref ref, cairo_font_face_t *cairo_font_face, std::vector<int> &&codeToGIDA, bool printing, XRef *xref); |
107 | }; |
108 | |
109 | //------------------------------------------------------------------------ |
110 | |
111 | //------------------------------------------------------------------------ |
112 | // CairoFontEngine |
113 | //------------------------------------------------------------------------ |
114 | |
115 | class CairoFontEngine |
116 | { |
117 | public: |
118 | // Create a font engine. |
119 | explicit CairoFontEngine(FT_Library libA); |
120 | ~CairoFontEngine(); |
121 | CairoFontEngine(const CairoFontEngine &) = delete; |
122 | CairoFontEngine &operator=(const CairoFontEngine &other) = delete; |
123 | |
124 | std::shared_ptr<CairoFont> getFont(const std::shared_ptr<GfxFont> &gfxFont, PDFDoc *doc, bool printing, XRef *xref); |
125 | |
126 | static std::optional<FreeTypeFontFace> getExternalFontFace(FT_Library ftlib, const std::string &filename); |
127 | |
128 | private: |
129 | FT_Library lib; |
130 | bool useCIDs; |
131 | mutable std::mutex mutex; |
132 | |
133 | // Cache of CairoFont for current document |
134 | // Most recently used is at the end of the vector. |
135 | static const size_t cairoFontCacheSize = 64; |
136 | std::vector<std::shared_ptr<CairoFont>> fontCache; |
137 | |
138 | // Global cache of cairo_font_face_t for external font files. |
139 | static std::unordered_map<std::string, FreeTypeFontFace> fontFileCache; |
140 | static std::recursive_mutex fontFileCacheMutex; |
141 | }; |
142 | |
143 | #endif |
144 | |