Bug 1492908 [wpt PR 13122] - Update wpt metadata, a=testonly
[gecko.git] / gfx / thebes / gfxGlyphExtents.cpp
blobcb8f5838b6cb62a3203f1291bb2e96a3372a6deb
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/. */
6 #include "gfxGlyphExtents.h"
7 #include "gfxTextRun.h"
9 using namespace mozilla;
11 #ifdef DEBUG_roc
12 #define DEBUG_TEXT_RUN_STORAGE_METRICS
13 #endif
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
27 gfxGlyphExtents::~gfxGlyphExtents()
29 #ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
30 gGlyphExtentsWidthsTotalSize +=
31 mContainedGlyphWidths.SizeOfExcludingThis(&FontCacheMallocSizeOf);
32 gGlyphExtentsCount++;
33 #endif
34 MOZ_COUNT_DTOR(gfxGlyphExtents);
37 bool
38 gfxGlyphExtents::GetTightGlyphExtentsAppUnits(gfxFont* aFont,
39 DrawTarget* aDrawTarget, uint32_t aGlyphID, gfxRect* aExtents)
41 HashEntry *entry = mTightGlyphExtents.GetEntry(aGlyphID);
42 if (!entry) {
43 // Some functions higher up in the call chain deliberately pass in a
44 // nullptr DrawTarget, e.g. GetBaselinePosition() passes nullptr to
45 // gfxTextRun::MeasureText() and that nullptr reaches here.
46 if (!aDrawTarget) {
47 NS_WARNING("Could not get glyph extents (no aDrawTarget)");
48 return false;
51 if (aFont->SetupCairoFont(aDrawTarget)) {
52 #ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
53 ++gGlyphExtentsSetupLazyTight;
54 #endif
55 aFont->SetupGlyphExtents(aDrawTarget, aGlyphID, true, this);
56 entry = mTightGlyphExtents.GetEntry(aGlyphID);
58 if (!entry) {
59 NS_WARNING("Could not get glyph extents");
60 return false;
64 *aExtents = gfxRect(entry->x, entry->y, entry->width, entry->height);
65 return true;
68 gfxGlyphExtents::GlyphWidths::~GlyphWidths()
70 uint32_t i, count = mBlocks.Length();
71 for (i = 0; i < count; ++i) {
72 uintptr_t bits = mBlocks[i];
73 if (bits && !(bits & 0x1)) {
74 delete[] reinterpret_cast<uint16_t *>(bits);
79 uint32_t
80 gfxGlyphExtents::GlyphWidths::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
82 uint32_t i;
83 uint32_t size = mBlocks.ShallowSizeOfExcludingThis(aMallocSizeOf);
84 for (i = 0; i < mBlocks.Length(); ++i) {
85 uintptr_t bits = mBlocks[i];
86 if (bits && !(bits & 0x1)) {
87 size += aMallocSizeOf(reinterpret_cast<void*>(bits));
90 return size;
93 void
94 gfxGlyphExtents::GlyphWidths::Set(uint32_t aGlyphID, uint16_t aWidth)
96 uint32_t block = aGlyphID >> BLOCK_SIZE_BITS;
97 uint32_t len = mBlocks.Length();
98 if (block >= len) {
99 uintptr_t *elems = mBlocks.AppendElements(block + 1 - len);
100 if (!elems)
101 return;
102 memset(elems, 0, sizeof(uintptr_t)*(block + 1 - len));
105 uintptr_t bits = mBlocks[block];
106 uint32_t glyphOffset = aGlyphID & (BLOCK_SIZE - 1);
107 if (!bits) {
108 mBlocks[block] = MakeSingle(glyphOffset, aWidth);
109 return;
112 uint16_t *newBlock;
113 if (bits & 0x1) {
114 // Expand the block to a real block. We could avoid this by checking
115 // glyphOffset == GetGlyphOffset(bits), but that never happens so don't bother
116 newBlock = new uint16_t[BLOCK_SIZE];
117 if (!newBlock)
118 return;
119 uint32_t i;
120 for (i = 0; i < BLOCK_SIZE; ++i) {
121 newBlock[i] = INVALID_WIDTH;
123 newBlock[GetGlyphOffset(bits)] = GetWidth(bits);
124 mBlocks[block] = reinterpret_cast<uintptr_t>(newBlock);
125 } else {
126 newBlock = reinterpret_cast<uint16_t *>(bits);
128 newBlock[glyphOffset] = aWidth;
131 void
132 gfxGlyphExtents::SetTightGlyphExtents(uint32_t aGlyphID, const gfxRect& aExtentsAppUnits)
134 HashEntry *entry = mTightGlyphExtents.PutEntry(aGlyphID);
135 if (!entry)
136 return;
137 entry->x = aExtentsAppUnits.X();
138 entry->y = aExtentsAppUnits.Y();
139 entry->width = aExtentsAppUnits.Width();
140 entry->height = aExtentsAppUnits.Height();
143 size_t
144 gfxGlyphExtents::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
146 return mContainedGlyphWidths.SizeOfExcludingThis(aMallocSizeOf) +
147 mTightGlyphExtents.ShallowSizeOfExcludingThis(aMallocSizeOf);
150 size_t
151 gfxGlyphExtents::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
153 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);