Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/vcl/inc/font/LogicalFontInstance.hxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#pragma once
21
22
#include <sal/config.h>
23
24
#include <basegfx/polygon/b2dpolypolygon.hxx>
25
#include <basegfx/range/b2drectangle.hxx>
26
#include <o3tl/hash_combine.hxx>
27
#include <rtl/ref.hxx>
28
#include <salhelper/simplereferenceobject.hxx>
29
#include <tools/gen.hxx>
30
#include <tools/fontenum.hxx>
31
#include <tools/degree.hxx>
32
33
#include <font/FontSelectPattern.hxx>
34
#include <font/FontMetricData.hxx>
35
#include <glyphid.hxx>
36
37
#include <optional>
38
#include <unordered_map>
39
40
#include <hb.h>
41
42
class ConvertChar;
43
class ImplFontCache;
44
namespace vcl::font
45
{
46
class PhysicalFontFace;
47
}
48
49
constexpr float ARTIFICIAL_ITALIC_MATRIX_XX = 1 << 16;
50
constexpr float ARTIFICIAL_ITALIC_MATRIX_XY = (1 << 16) / 3.f;
51
constexpr float ARTIFICIAL_ITALIC_SKEW = ARTIFICIAL_ITALIC_MATRIX_XY / ARTIFICIAL_ITALIC_MATRIX_XX;
52
53
// extend std namespace to add custom hash needed for LogicalFontInstance
54
55
namespace std
56
{
57
template <> struct hash<pair<sal_UCS4, FontWeight>>
58
{
59
    size_t operator()(const pair<sal_UCS4, FontWeight>& rData) const
60
0
    {
61
0
        std::size_t seed = 0;
62
0
        o3tl::hash_combine(seed, rData.first);
63
0
        o3tl::hash_combine(seed, rData.second);
64
0
        return seed;
65
0
    }
66
};
67
}
68
69
// TODO: allow sharing of metrics for related fonts
70
71
class VCL_PLUGIN_PUBLIC LogicalFontInstance : public salhelper::SimpleReferenceObject
72
{
73
    // just declaring the factory function doesn't work AKA
74
    // friend LogicalFontInstance* PhysicalFontFace::CreateFontInstance(const FontSelectPattern&) const;
75
    friend class vcl::font::PhysicalFontFace;
76
    friend class ImplFontCache;
77
78
public: // TODO: make data members private
79
    virtual ~LogicalFontInstance() override;
80
81
    FontMetricDataRef mxFontMetric; // Font attributes
82
    const ConvertChar* mpConversion; // used e.g. for StarBats->StarSymbol
83
84
    tools::Long mnLineHeight;
85
    Degree10 mnOwnOrientation; // text angle if lower layers don't rotate text themselves
86
    Degree10 mnOrientation; // text angle in 3600 system
87
    bool mbInit; // true if maFontMetric member is valid
88
89
    SAL_DLLPRIVATE void AddFallbackForUnicode(sal_UCS4 cChar, FontWeight eWeight,
90
                                              const OUString& rFontName, bool bEmbolden,
91
                                              const ItalicMatrix& rMatrix);
92
    SAL_DLLPRIVATE bool GetFallbackForUnicode(sal_UCS4 cInChar, FontWeight eInWeight,
93
                                              OUString* pOutFontName, bool* pOutEmbolden,
94
                                              ItalicMatrix* pOutItalicMatrix) const;
95
    SAL_DLLPRIVATE void IgnoreFallbackForUnicode(sal_UCS4, FontWeight eWeight,
96
                                                 std::u16string_view rFontName);
97
98
    inline hb_font_t* GetHbFont();
99
    SAL_DLLPRIVATE bool IsGraphiteFont();
100
0
    void SetAverageWidthFactor(double nFactor) { m_nAveWidthFactor = std::abs(nFactor); }
101
368k
    double GetAverageWidthFactor() const { return m_nAveWidthFactor; }
102
63.5M
    const vcl::font::FontSelectPattern& GetFontSelectPattern() const { return m_aFontSelData; }
103
104
    void SetVariations(const std::vector<hb_variation_t>& rVariations)
105
0
    {
106
0
        m_aVariations = rVariations;
107
0
        mxVariations.reset();
108
0
    }
109
    const std::vector<hb_variation_t>& GetVariations() const;
110
111
    void SetOpticalSizing(bool bOpticalSizing)
112
0
    {
113
0
        m_bOpticalSizing = bOpticalSizing;
114
0
        mxVariations.reset();
115
0
    }
116
0
    bool GetOpticalSizing() const { return m_bOpticalSizing; }
117
118
    void SetPointSize(float fPointSize)
119
219k
    {
120
219k
        m_fPointSize = fPointSize;
121
219k
        mxVariations.reset();
122
219k
    }
123
14.5M
    float GetPointSize() const { return m_fPointSize; }
124
125
37.4M
    const vcl::font::PhysicalFontFace* GetFontFace() const { return m_pFontFace.get(); }
126
910k
    vcl::font::PhysicalFontFace* GetFontFace() { return m_pFontFace.get(); }
127
103M
    const ImplFontCache* GetFontCache() const { return mpFontCache; }
128
129
    bool GetGlyphBoundRect(sal_GlyphId, basegfx::B2DRectangle&, bool) const;
130
    virtual bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const = 0;
131
    SAL_DLLPRIVATE basegfx::B2DPolyPolygon GetGlyphOutlineUntransformed(sal_GlyphId) const;
132
133
    sal_GlyphId GetGlyphIndex(uint32_t, uint32_t = 0) const;
134
135
    SAL_DLLPRIVATE double GetGlyphWidth(sal_GlyphId, bool = false, bool = true) const;
136
137
    double GetKashidaWidth() const;
138
139
    SAL_DLLPRIVATE void GetScale(double* nXScale, double* nYScale) const;
140
141
    bool NeedsArtificialItalic() const;
142
    bool NeedsArtificialBold() const;
143
144
protected:
145
    explicit LogicalFontInstance(const vcl::font::PhysicalFontFace&,
146
                                 const vcl::font::FontSelectPattern&);
147
148
    SAL_DLLPRIVATE hb_font_t* InitHbFont();
149
210k
    virtual void ImplInitHbFont(hb_font_t*) {}
150
151
private:
152
    SAL_DLLPRIVATE hb_font_t* GetHbFontUntransformed() const;
153
154
    struct MapEntry
155
    {
156
        OUString sFontName;
157
        bool bEmbolden;
158
        ItalicMatrix aItalicMatrix;
159
    };
160
    // cache of Unicode characters and replacement font names and attributes
161
    // TODO: a fallback map can be shared with many other ImplFontEntries
162
    // TODO: at least the ones which just differ in orientation, stretching or height
163
    typedef ::std::unordered_map<::std::pair<sal_UCS4, FontWeight>, MapEntry> UnicodeFallbackList;
164
    UnicodeFallbackList maUnicodeFallbackList;
165
    mutable ImplFontCache* mpFontCache;
166
    const vcl::font::FontSelectPattern m_aFontSelData;
167
    hb_font_t* m_pHbFont;
168
    mutable hb_font_t* m_pHbFontUntransformed = nullptr;
169
    double m_nAveWidthFactor;
170
    rtl::Reference<vcl::font::PhysicalFontFace> m_pFontFace;
171
    std::optional<bool> m_xbIsGraphiteFont;
172
    std::vector<hb_variation_t> m_aVariations;
173
    mutable std::optional<std::vector<hb_variation_t>> mxVariations;
174
    bool m_bOpticalSizing = false;
175
    float m_fPointSize = 0;
176
177
    mutable hb_draw_funcs_t* m_pHbDrawFuncs = nullptr;
178
    basegfx::B2DPolygon m_aDrawPolygon;
179
};
180
181
inline hb_font_t* LogicalFontInstance::GetHbFont()
182
27.1M
{
183
27.1M
    if (!m_pHbFont)
184
210k
        m_pHbFont = InitHbFont();
185
27.1M
    return m_pHbFont;
186
27.1M
}
187
188
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */