Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/thebes/gfxGlyphExtents.cpp
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
#include "gfxGlyphExtents.h"
7
#include "gfxTextRun.h"
8
9
using namespace mozilla;
10
11
#ifdef DEBUG_roc
12
#define DEBUG_TEXT_RUN_STORAGE_METRICS
13
#endif
14
15
#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
16
extern uint32_t gTextRunStorageHighWaterMark;
17
extern uint32_t gTextRunStorage;
18
extern uint32_t gFontCount;
19
extern uint32_t gGlyphExtentsCount;
20
extern uint32_t gGlyphExtentsWidthsTotalSize;
21
extern uint32_t gGlyphExtentsSetupEagerSimple;
22
extern uint32_t gGlyphExtentsSetupEagerTight;
23
extern uint32_t gGlyphExtentsSetupLazyTight;
24
extern uint32_t gGlyphExtentsSetupFallBackToTight;
25
#endif
26
27
gfxGlyphExtents::~gfxGlyphExtents()
28
0
{
29
#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
30
    gGlyphExtentsWidthsTotalSize +=
31
        mContainedGlyphWidths.SizeOfExcludingThis(&FontCacheMallocSizeOf);
32
    gGlyphExtentsCount++;
33
#endif
34
    MOZ_COUNT_DTOR(gfxGlyphExtents);
35
0
}
36
37
bool
38
gfxGlyphExtents::GetTightGlyphExtentsAppUnits(gfxFont* aFont,
39
    DrawTarget* aDrawTarget, uint32_t aGlyphID, gfxRect* aExtents)
40
0
{
41
0
    HashEntry *entry = mTightGlyphExtents.GetEntry(aGlyphID);
42
0
    if (!entry) {
43
0
        // Some functions higher up in the call chain deliberately pass in a
44
0
        // nullptr DrawTarget, e.g. GetBaselinePosition() passes nullptr to
45
0
        // gfxTextRun::MeasureText() and that nullptr reaches here.
46
0
        if (!aDrawTarget) {
47
0
            NS_WARNING("Could not get glyph extents (no aDrawTarget)");
48
0
            return false;
49
0
        }
50
0
51
0
        if (aFont->SetupCairoFont(aDrawTarget)) {
52
#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
53
            ++gGlyphExtentsSetupLazyTight;
54
#endif
55
            aFont->SetupGlyphExtents(aDrawTarget, aGlyphID, true, this);
56
0
            entry = mTightGlyphExtents.GetEntry(aGlyphID);
57
0
        }
58
0
        if (!entry) {
59
0
            NS_WARNING("Could not get glyph extents");
60
0
            return false;
61
0
        }
62
0
    }
63
0
64
0
    *aExtents = gfxRect(entry->x, entry->y, entry->width, entry->height);
65
0
    return true;
66
0
}
67
68
gfxGlyphExtents::GlyphWidths::~GlyphWidths()
69
0
{
70
0
    uint32_t i, count = mBlocks.Length();
71
0
    for (i = 0; i < count; ++i) {
72
0
        uintptr_t bits = mBlocks[i];
73
0
        if (bits && !(bits & 0x1)) {
74
0
            delete[] reinterpret_cast<uint16_t *>(bits);
75
0
        }
76
0
    }
77
0
}
78
79
uint32_t
80
gfxGlyphExtents::GlyphWidths::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
81
0
{
82
0
    uint32_t i;
83
0
    uint32_t size = mBlocks.ShallowSizeOfExcludingThis(aMallocSizeOf);
84
0
    for (i = 0; i < mBlocks.Length(); ++i) {
85
0
        uintptr_t bits = mBlocks[i];
86
0
        if (bits && !(bits & 0x1)) {
87
0
            size += aMallocSizeOf(reinterpret_cast<void*>(bits));
88
0
        }
89
0
    }
90
0
    return size;
91
0
}
92
93
void
94
gfxGlyphExtents::GlyphWidths::Set(uint32_t aGlyphID, uint16_t aWidth)
95
0
{
96
0
    uint32_t block = aGlyphID >> BLOCK_SIZE_BITS;
97
0
    uint32_t len = mBlocks.Length();
98
0
    if (block >= len) {
99
0
        uintptr_t *elems = mBlocks.AppendElements(block + 1 - len);
100
0
        if (!elems)
101
0
            return;
102
0
        memset(elems, 0, sizeof(uintptr_t)*(block + 1 - len));
103
0
    }
104
0
105
0
    uintptr_t bits = mBlocks[block];
106
0
    uint32_t glyphOffset = aGlyphID & (BLOCK_SIZE - 1);
107
0
    if (!bits) {
108
0
        mBlocks[block] = MakeSingle(glyphOffset, aWidth);
109
0
        return;
110
0
    }
111
0
112
0
    uint16_t *newBlock;
113
0
    if (bits & 0x1) {
114
0
        // Expand the block to a real block. We could avoid this by checking
115
0
        // glyphOffset == GetGlyphOffset(bits), but that never happens so don't bother
116
0
        newBlock = new uint16_t[BLOCK_SIZE];
117
0
        if (!newBlock)
118
0
            return;
119
0
        uint32_t i;
120
0
        for (i = 0; i < BLOCK_SIZE; ++i) {
121
0
            newBlock[i] = INVALID_WIDTH;
122
0
        }
123
0
        newBlock[GetGlyphOffset(bits)] = GetWidth(bits);
124
0
        mBlocks[block] = reinterpret_cast<uintptr_t>(newBlock);
125
0
    } else {
126
0
        newBlock = reinterpret_cast<uint16_t *>(bits);
127
0
    }
128
0
    newBlock[glyphOffset] = aWidth;
129
0
}
130
131
void
132
gfxGlyphExtents::SetTightGlyphExtents(uint32_t aGlyphID, const gfxRect& aExtentsAppUnits)
133
0
{
134
0
    HashEntry *entry = mTightGlyphExtents.PutEntry(aGlyphID);
135
0
    if (!entry)
136
0
        return;
137
0
    entry->x = aExtentsAppUnits.X();
138
0
    entry->y = aExtentsAppUnits.Y();
139
0
    entry->width = aExtentsAppUnits.Width();
140
0
    entry->height = aExtentsAppUnits.Height();
141
0
}
142
143
size_t
144
gfxGlyphExtents::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
145
0
{
146
0
    return mContainedGlyphWidths.SizeOfExcludingThis(aMallocSizeOf) +
147
0
        mTightGlyphExtents.ShallowSizeOfExcludingThis(aMallocSizeOf);
148
0
}
149
150
size_t
151
gfxGlyphExtents::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
152
0
{
153
0
    return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
154
0
}