Coverage Report

Created: 2026-07-30 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/poppler/splash/SplashFontEngine.cc
Line
Count
Source
1
//========================================================================
2
//
3
// SplashFontEngine.cc
4
//
5
//========================================================================
6
7
//========================================================================
8
//
9
// Modified under the Poppler project - http://poppler.freedesktop.org
10
//
11
// All changes made under the Poppler project to this file are licensed
12
// under GPL version 2 or later
13
//
14
// Copyright (C) 2006 Takashi Iwai <tiwai@suse.de>
15
// Copyright (C) 2009 Petr Gajdos <pgajdos@novell.com>
16
// Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
17
// Copyright (C) 2009, 2024-2026 Albert Astals Cid <aacid@kde.org>
18
// Copyright (C) 2011 Andreas Hartmetz <ahartmetz@gmail.com>
19
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
20
// Copyright (C) 2015 Dmytro Morgun <lztoad@gmail.com>
21
// Copyright (C) 2017 Adrian Johnson <ajohnson@redneon.com>
22
// Copyright (C) 2018 Oliver Sander <oliver.sander@tu-dresden.de>
23
// Copyright (C) 2019 Christian Persch <chpe@src.gnome.org>
24
// Copyright (C) 2024-2026 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
25
//
26
// To see a description of the changes please see the Changelog file that
27
// came with your tarball or type make ChangeLog if you are building from git
28
//
29
//========================================================================
30
31
#include <config.h>
32
33
#include <algorithm>
34
35
#include "SplashMath.h"
36
#include "SplashFTFontEngine.h"
37
#include "SplashFontFile.h"
38
#include "SplashFontFileID.h"
39
#include "SplashFont.h"
40
#include "SplashFontEngine.h"
41
42
//------------------------------------------------------------------------
43
// SplashFontEngine
44
//------------------------------------------------------------------------
45
46
SplashFontEngine::SplashFontEngine(bool enableFreeType, bool enableFreeTypeHinting, bool enableSlightHinting, bool aa)
47
0
{
48
0
    std::ranges::fill(fontCache, nullptr);
49
50
0
    if (enableFreeType) {
51
0
        ftEngine = SplashFTFontEngine::init(aa, enableFreeTypeHinting, enableSlightHinting);
52
0
    } else {
53
0
        ftEngine = nullptr;
54
0
    }
55
0
}
56
57
SplashFontEngine::~SplashFontEngine()
58
0
{
59
0
    for (auto *font : fontCache) {
60
0
        delete font;
61
0
    }
62
63
0
    delete ftEngine;
64
0
}
65
66
std::shared_ptr<SplashFontFile> SplashFontEngine::getFontFile(const SplashFontFileID &id)
67
0
{
68
0
    for (auto *font : fontCache) {
69
0
        if (font) {
70
0
            std::shared_ptr<SplashFontFile> fontFile = font->getFontFile();
71
0
            if (fontFile && fontFile->getID().matches(id)) {
72
0
                return fontFile;
73
0
            }
74
0
        }
75
0
    }
76
0
    return nullptr;
77
0
}
78
79
std::shared_ptr<SplashFontFile> SplashFontEngine::loadType1Font(std::unique_ptr<SplashFontFileID> idA, std::unique_ptr<SplashFontSrc> src, const std::array<const char *, 256> &enc, int faceIndex)
80
0
{
81
0
    if (ftEngine) {
82
0
        return ftEngine->loadType1Font(std::move(idA), std::move(src), enc, faceIndex);
83
0
    }
84
85
0
    return nullptr;
86
0
}
87
88
std::shared_ptr<SplashFontFile> SplashFontEngine::loadType1CFont(std::unique_ptr<SplashFontFileID> idA, std::unique_ptr<SplashFontSrc> src, const std::array<const char *, 256> &enc, int faceIndex)
89
0
{
90
0
    if (ftEngine) {
91
0
        return ftEngine->loadType1CFont(std::move(idA), std::move(src), enc, faceIndex);
92
0
    }
93
94
0
    return nullptr;
95
0
}
96
97
std::shared_ptr<SplashFontFile> SplashFontEngine::loadOpenTypeT1CFont(std::unique_ptr<SplashFontFileID> idA, std::unique_ptr<SplashFontSrc> src, const std::array<const char *, 256> &enc, int faceIndex)
98
0
{
99
0
    if (ftEngine) {
100
0
        return ftEngine->loadOpenTypeT1CFont(std::move(idA), std::move(src), enc, faceIndex);
101
0
    }
102
103
0
    return nullptr;
104
0
}
105
106
std::shared_ptr<SplashFontFile> SplashFontEngine::loadCIDFont(std::unique_ptr<SplashFontFileID> idA, std::unique_ptr<SplashFontSrc> src, int faceIndex)
107
0
{
108
0
    if (ftEngine) {
109
0
        return ftEngine->loadCIDFont(std::move(idA), std::move(src), faceIndex);
110
0
    }
111
112
0
    return nullptr;
113
0
}
114
115
std::shared_ptr<SplashFontFile> SplashFontEngine::loadOpenTypeCFFFont(std::unique_ptr<SplashFontFileID> idA, std::unique_ptr<SplashFontSrc> src, std::vector<int> &&codeToGID, int faceIndex)
116
0
{
117
0
    if (ftEngine) {
118
0
        return ftEngine->loadOpenTypeCFFFont(std::move(idA), std::move(src), std::move(codeToGID), faceIndex);
119
0
    }
120
121
0
    return nullptr;
122
0
}
123
124
std::shared_ptr<SplashFontFile> SplashFontEngine::loadTrueTypeFont(std::unique_ptr<SplashFontFileID> idA, std::unique_ptr<SplashFontSrc> src, std::vector<int> &&codeToGID, int faceIndex)
125
0
{
126
0
    if (ftEngine) {
127
0
        return ftEngine->loadTrueTypeFont(std::move(idA), std::move(src), std::move(codeToGID), faceIndex);
128
0
    }
129
130
0
    return nullptr;
131
0
}
132
133
bool SplashFontEngine::getAA()
134
0
{
135
0
    return (ftEngine == nullptr) ? false : ftEngine->getAA();
136
0
}
137
138
void SplashFontEngine::setAA(bool aa)
139
0
{
140
0
    if (ftEngine != nullptr) {
141
0
        ftEngine->setAA(aa);
142
0
    }
143
0
}
144
145
SplashFont *SplashFontEngine::getFont(std::shared_ptr<SplashFontFile> fontFile, const std::array<double, 4> &textMat, const std::array<double, 6> &ctm)
146
0
{
147
0
    std::array<double, 4> mat;
148
149
0
    mat[0] = textMat[0] * ctm[0] + textMat[1] * ctm[2];
150
0
    mat[1] = -(textMat[0] * ctm[1] + textMat[1] * ctm[3]);
151
0
    mat[2] = textMat[2] * ctm[0] + textMat[3] * ctm[2];
152
0
    mat[3] = -(textMat[2] * ctm[1] + textMat[3] * ctm[3]);
153
0
    if (!splashCheckDet(mat[0], mat[1], mat[2], mat[3], 0.01)) {
154
        // avoid a singular (or close-to-singular) matrix
155
0
        mat[0] = 0.01;
156
0
        mat[1] = 0;
157
0
        mat[2] = 0;
158
0
        mat[3] = 0.01;
159
0
    }
160
161
    // Try to find the font in the cache
162
0
    auto fontIt = std::ranges::find_if(fontCache, [&](const SplashFont *font) { return font && font->matches(fontFile, mat, textMat); }); // NOLINT(readability-qualified-auto) https://github.com/llvm/llvm-project/issues/175731
163
164
    // The requested font has been found in the cache
165
0
    if (fontIt != fontCache.end()) {
166
0
        std::rotate(fontCache.begin(), fontIt, fontIt + 1);
167
0
        return fontCache[0];
168
0
    }
169
170
    // The requested font has not been found in the cache
171
0
    auto *newFont = fontFile->makeFont(mat, textMat);
172
0
    if (fontCache.back()) {
173
0
        delete fontCache.back();
174
0
    }
175
0
    std::ranges::rotate(fontCache, fontCache.end() - 1);
176
177
0
    fontCache[0] = newFont;
178
0
    return fontCache[0];
179
0
}