Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/include/vcl/glyphitemcache.hxx
Line
Count
Source (jump to first uncovered line)
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
#ifndef INCLUDED_VCL_GLYPHITEMCACHE_HXX
21
#define INCLUDED_VCL_GLYPHITEMCACHE_HXX
22
23
#include <sal/types.h>
24
#include <vcl/dllapi.h>
25
26
#include <o3tl/lru_map.hxx>
27
#include <vcl/glyphitem.hxx>
28
#include <vcl/dropcache.hxx>
29
#include <vcl/metric.hxx>
30
#include <vcl/outdev.hxx>
31
#include <vcl/vclptr.hxx>
32
33
#include <optional>
34
35
/**
36
A cache for SalLayoutGlyphs objects.
37
38
Allows caching for OutputDevice::DrawText() and similar calls. Pass the text and the output device
39
for the call to OutputDevice::ImplLayout(). Items are cached per output device and its font.
40
If something more changes, call clear().
41
*/
42
class VCL_DLLPUBLIC SalLayoutGlyphsCache final : public CacheOwner
43
{
44
public:
45
    // NOTE: The lifetime of the returned value is guaranteed only until the next call
46
    // to any function in this class.
47
    const SalLayoutGlyphs* GetLayoutGlyphs(const VclPtr<const OutputDevice>& outputDevice,
48
                                           const OUString& text,
49
                                           const vcl::text::TextLayoutCache* layoutCache = nullptr)
50
0
    {
51
0
        return GetLayoutGlyphs(outputDevice, text, 0, text.getLength(), 0, layoutCache);
52
0
    }
53
    const SalLayoutGlyphs* GetLayoutGlyphs(const VclPtr<const OutputDevice>& outputDevice,
54
                                           const OUString& text, sal_Int32 nIndex, sal_Int32 nLen,
55
                                           tools::Long nLogicWidth = 0,
56
                                           const vcl::text::TextLayoutCache* layoutCache = nullptr);
57
    const SalLayoutGlyphs* GetLayoutGlyphs(const VclPtr<const OutputDevice>& outputDevice,
58
                                           const OUString& text, sal_Int32 nIndex, sal_Int32 nLen,
59
                                           sal_Int32 nDrawMinCharPos, sal_Int32 nDrawEndCharPos,
60
                                           tools::Long nLogicWidth = 0,
61
                                           const vcl::text::TextLayoutCache* layoutCache = nullptr);
62
    void clear();
63
64
    /// Normally, we cannot cache glyphs when doing font fallback, because the font fallbacks
65
    /// can cache during the lifetime of the cache, and they are not included in the cache key.
66
    /// But during some processes, we can turn this on, as long as we remember to turn it off
67
    /// at the end.
68
    void SetCacheGlyphsWhenDoingFallbackFonts(bool bOK);
69
70
    static SalLayoutGlyphsCache* self();
71
    SalLayoutGlyphsCache(int size) // needs to be public for tools::DeleteOnDeinit
72
13
        : mCachedGlyphs(size)
73
13
    {
74
13
    }
75
76
    struct CachedGlyphsKey
77
    {
78
        OUString text;
79
        sal_Int32 index;
80
        sal_Int32 len;
81
        tools::Long logicWidth;
82
        FontMetric fontMetric;
83
        double fontScaleX;
84
        double fontScaleY;
85
        MapMode mapMode;
86
        LanguageType digitLanguage;
87
        vcl::text::ComplexTextLayoutFlags layoutMode;
88
        bool rtl : 1;
89
        bool disabledLigatures : 1; // because of fixed pitch
90
        bool artificialItalic : 1;
91
        bool artificialBold : 1;
92
        size_t hashValue;
93
        CachedGlyphsKey(const VclPtr<const OutputDevice>& dev, OUString t, sal_Int32 i, sal_Int32 l,
94
                        tools::Long w);
95
        bool operator==(const CachedGlyphsKey& other) const;
96
    };
97
98
private:
99
    virtual void dropCaches() override;
100
    virtual void dumpState(rtl::OStringBuffer& rState) override;
101
102
    struct CachedGlyphsHash
103
    {
104
25.5M
        size_t operator()(const CachedGlyphsKey& key) const { return key.hashValue; }
105
    };
106
    struct SAL_DLLPRIVATE GlyphsCost
107
    {
108
        size_t operator()(const SalLayoutGlyphs&) const;
109
    };
110
    typedef o3tl::lru_map<CachedGlyphsKey, SalLayoutGlyphs, CachedGlyphsHash,
111
                          std::equal_to<CachedGlyphsKey>, GlyphsCost>
112
        GlyphsCache;
113
    GlyphsCache mCachedGlyphs;
114
    // Last temporary glyphs returned (pointer is returned, so the object needs to be kept somewhere).
115
    std::optional<CachedGlyphsKey> mLastTemporaryKey;
116
    SalLayoutGlyphs mLastTemporaryGlyphs;
117
    // If set, info about the last call which wanted a substring of the full text.
118
    std::optional<CachedGlyphsKey> mLastSubstringKey;
119
    bool mbCacheGlyphsWhenDoingFallbackFonts = false;
120
121
    SalLayoutGlyphsCache(const SalLayoutGlyphsCache&) = delete;
122
    SalLayoutGlyphsCache& operator=(const SalLayoutGlyphsCache&) = delete;
123
};
124
125
#endif // INCLUDED_VCL_GLYPHITEMCACHE_HXX
126
127
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */