Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/thebes/gfxGlyphExtents.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
 * This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#ifndef GFX_GLYPHEXTENTS_H
7
#define GFX_GLYPHEXTENTS_H
8
9
#include "gfxFont.h"
10
#include "gfxRect.h"
11
#include "nsTHashtable.h"
12
#include "nsHashKeys.h"
13
#include "nsTArray.h"
14
#include "mozilla/MemoryReporting.h"
15
16
class gfxContext;
17
18
namespace mozilla {
19
namespace gfx {
20
class DrawTarget;
21
} // namespace gfx
22
} // namespace mozilla
23
24
/**
25
 * This stores glyph bounds information for a particular gfxFont, at
26
 * a particular appunits-per-dev-pixel ratio (because the compressed glyph
27
 * width array is stored in appunits).
28
 * 
29
 * We store a hashtable from glyph IDs to float bounding rects. For the
30
 * common case where the glyph has no horizontal left bearing, and no
31
 * y overflow above the font ascent or below the font descent, and tight
32
 * bounding boxes are not required, we avoid storing the glyph ID in the hashtable
33
 * and instead consult an array of 16-bit glyph XMost values (in appunits).
34
 * This array always has an entry for the font's space glyph --- the width is
35
 * assumed to be zero.
36
 */
37
class gfxGlyphExtents {
38
    typedef mozilla::gfx::DrawTarget DrawTarget;
39
40
public:
41
    explicit gfxGlyphExtents(int32_t aAppUnitsPerDevUnit) :
42
0
        mAppUnitsPerDevUnit(aAppUnitsPerDevUnit) {
43
0
        MOZ_COUNT_CTOR(gfxGlyphExtents);
44
0
    }
45
    ~gfxGlyphExtents();
46
47
    enum { INVALID_WIDTH = 0xFFFF };
48
49
0
    void NotifyGlyphsChanged() {
50
0
        mTightGlyphExtents.Clear();
51
0
    }
52
53
    // returns INVALID_WIDTH => not a contained glyph
54
    // Otherwise the glyph has no before-bearing or vertical bearings,
55
    // and the result is its width measured from the baseline origin, in
56
    // appunits.
57
0
    uint16_t GetContainedGlyphWidthAppUnits(uint32_t aGlyphID) const {
58
0
        return mContainedGlyphWidths.Get(aGlyphID);
59
0
    }
60
61
0
    bool IsGlyphKnown(uint32_t aGlyphID) const {
62
0
        return mContainedGlyphWidths.Get(aGlyphID) != INVALID_WIDTH ||
63
0
            mTightGlyphExtents.GetEntry(aGlyphID) != nullptr;
64
0
    }
65
66
0
    bool IsGlyphKnownWithTightExtents(uint32_t aGlyphID) const {
67
0
        return mTightGlyphExtents.GetEntry(aGlyphID) != nullptr;
68
0
    }
69
70
    // Get glyph extents; a rectangle relative to the left baseline origin
71
    // Returns true on success. Can fail on OOM or when aContext is null
72
    // and extents were not (successfully) prefetched.
73
    bool GetTightGlyphExtentsAppUnits(gfxFont* aFont,
74
            DrawTarget* aDrawTarget, uint32_t aGlyphID, gfxRect* aExtents);
75
76
0
    void SetContainedGlyphWidthAppUnits(uint32_t aGlyphID, uint16_t aWidth) {
77
0
        mContainedGlyphWidths.Set(aGlyphID, aWidth);
78
0
    }
79
    void SetTightGlyphExtents(uint32_t aGlyphID, const gfxRect& aExtentsAppUnits);
80
81
0
    int32_t GetAppUnitsPerDevUnit() { return mAppUnitsPerDevUnit; }
82
83
    size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
84
    size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
85
86
private:
87
    class HashEntry : public nsUint32HashKey {
88
    public:
89
        // When constructing a new entry in the hashtable, we'll leave this
90
        // blank. The caller of Put() will fill this in.
91
        explicit HashEntry(KeyTypePointer aPtr)
92
          : nsUint32HashKey(aPtr)
93
          , x(0.0)
94
          , y(0.0)
95
          , width(0.0)
96
0
          , height(0.0) {}
97
        HashEntry(HashEntry&& aOther)
98
            : nsUint32HashKey(std::move(aOther))
99
            , x(aOther.x)
100
            , y(aOther.y)
101
            , width(aOther.width)
102
0
            , height(aOther.height) {
103
0
        }
104
105
        float x, y, width, height;
106
    };
107
108
    enum { BLOCK_SIZE_BITS = 7, BLOCK_SIZE = 1 << BLOCK_SIZE_BITS }; // 128-glyph blocks
109
110
    class GlyphWidths {
111
    public:
112
        void Set(uint32_t aIndex, uint16_t aValue);
113
0
        uint16_t Get(uint32_t aIndex) const {
114
0
            uint32_t block = aIndex >> BLOCK_SIZE_BITS;
115
0
            if (block >= mBlocks.Length())
116
0
                return INVALID_WIDTH;
117
0
            uintptr_t bits = mBlocks[block];
118
0
            if (!bits)
119
0
                return INVALID_WIDTH;
120
0
            uint32_t indexInBlock = aIndex & (BLOCK_SIZE - 1);
121
0
            if (bits & 0x1) {
122
0
                if (GetGlyphOffset(bits) != indexInBlock)
123
0
                    return INVALID_WIDTH;
124
0
                return GetWidth(bits);
125
0
            }
126
0
            uint16_t *widths = reinterpret_cast<uint16_t *>(bits);
127
0
            return widths[indexInBlock];
128
0
        }
129
130
        uint32_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
131
        
132
        ~GlyphWidths();
133
134
    private:
135
0
        static uint32_t GetGlyphOffset(uintptr_t aBits) {
136
0
            NS_ASSERTION(aBits & 0x1, "This is really a pointer...");
137
0
            return (aBits >> 1) & ((1 << BLOCK_SIZE_BITS) - 1);
138
0
        }
139
0
        static uint32_t GetWidth(uintptr_t aBits) {
140
0
            NS_ASSERTION(aBits & 0x1, "This is really a pointer...");
141
0
            return aBits >> (1 + BLOCK_SIZE_BITS);
142
0
        }
143
0
        static uintptr_t MakeSingle(uint32_t aGlyphOffset, uint16_t aWidth) {
144
0
            return (aWidth << (1 + BLOCK_SIZE_BITS)) + (aGlyphOffset << 1) + 1;
145
0
        }
146
147
        nsTArray<uintptr_t> mBlocks;
148
    };
149
150
    GlyphWidths             mContainedGlyphWidths;
151
    nsTHashtable<HashEntry> mTightGlyphExtents;
152
    int32_t                 mAppUnitsPerDevUnit;
153
154
private:
155
    // not implemented:
156
    gfxGlyphExtents(const gfxGlyphExtents& aOther) = delete;
157
    gfxGlyphExtents& operator=(const gfxGlyphExtents& aOther) = delete;
158
};
159
160
#endif