Bug 1874684 - Part 28: Return DateDuration from DifferenceISODateTime. r=mgaudet
[gecko.git] / gfx / thebes / gfxGlyphExtents.cpp
blob9c0792481dd3d2d7abe2179956875be8effb6872
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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() {
28 #ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
29 gGlyphExtentsWidthsTotalSize +=
30 mContainedGlyphWidths.SizeOfExcludingThis(&FontCacheMallocSizeOf);
31 gGlyphExtentsCount++;
32 #endif
33 MOZ_COUNT_DTOR(gfxGlyphExtents);
36 bool gfxGlyphExtents::GetTightGlyphExtentsAppUnitsLocked(
37 gfxFont* aFont, DrawTarget* aDrawTarget, uint32_t aGlyphID,
38 gfxRect* aExtents) {
39 HashEntry* entry = mTightGlyphExtents.GetEntry(aGlyphID);
40 if (!entry) {
41 // Some functions higher up in the call chain deliberately pass in a
42 // nullptr DrawTarget, e.g. GetBaselinePosition() passes nullptr to
43 // gfxTextRun::MeasureText() and that nullptr reaches here.
44 if (!aDrawTarget) {
45 NS_WARNING("Could not get glyph extents (no aDrawTarget)");
46 return false;
49 #ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
50 ++gGlyphExtentsSetupLazyTight;
51 #endif
52 // We need to temporarily release the read lock, as SetupGlyphExtents will
53 // take a write lock internally when it wants to set the new entry.
54 MOZ_PUSH_IGNORE_THREAD_SAFETY
55 mLock.ReadUnlock();
56 aFont->SetupGlyphExtents(aDrawTarget, aGlyphID, true, this);
57 mLock.ReadLock();
58 MOZ_POP_THREAD_SAFETY
60 entry = mTightGlyphExtents.GetEntry(aGlyphID);
61 if (!entry) {
62 NS_WARNING("Could not get glyph extents");
63 return false;
67 *aExtents = gfxRect(entry->x, entry->y, entry->width, entry->height);
68 return true;
71 gfxGlyphExtents::GlyphWidths::~GlyphWidths() {
72 uint32_t i, count = mBlocks.Length();
73 for (i = 0; i < count; ++i) {
74 uintptr_t bits = mBlocks[i];
75 if (bits && !(bits & 0x1)) {
76 delete[] reinterpret_cast<uint16_t*>(bits);
81 uint32_t gfxGlyphExtents::GlyphWidths::SizeOfExcludingThis(
82 MallocSizeOf aMallocSizeOf) const {
83 uint32_t i;
84 uint32_t size = mBlocks.ShallowSizeOfExcludingThis(aMallocSizeOf);
85 for (i = 0; i < mBlocks.Length(); ++i) {
86 uintptr_t bits = mBlocks[i];
87 if (bits && !(bits & 0x1)) {
88 size += aMallocSizeOf(reinterpret_cast<void*>(bits));
91 return size;
94 void gfxGlyphExtents::GlyphWidths::Set(uint32_t aGlyphID, uint16_t aWidth) {
95 uint32_t block = aGlyphID >> BLOCK_SIZE_BITS;
96 uint32_t len = mBlocks.Length();
97 if (block >= len) {
98 uintptr_t* elems = mBlocks.AppendElements(block + 1 - len);
99 if (!elems) return;
100 memset(elems, 0, sizeof(uintptr_t) * (block + 1 - len));
103 uintptr_t bits = mBlocks[block];
104 uint32_t glyphOffset = aGlyphID & (BLOCK_SIZE - 1);
105 if (!bits) {
106 mBlocks[block] = MakeSingle(glyphOffset, aWidth);
107 return;
110 uint16_t* newBlock;
111 if (bits & 0x1) {
112 // Expand the block to a real block. We could avoid this by checking
113 // glyphOffset == GetGlyphOffset(bits), but that never happens so don't
114 // bother
115 newBlock = new uint16_t[BLOCK_SIZE];
116 if (!newBlock) return;
117 uint32_t i;
118 for (i = 0; i < BLOCK_SIZE; ++i) {
119 newBlock[i] = INVALID_WIDTH;
121 newBlock[GetGlyphOffset(bits)] = GetWidth(bits);
122 mBlocks[block] = reinterpret_cast<uintptr_t>(newBlock);
123 } else {
124 newBlock = reinterpret_cast<uint16_t*>(bits);
126 newBlock[glyphOffset] = aWidth;
129 void gfxGlyphExtents::SetTightGlyphExtents(uint32_t aGlyphID,
130 const gfxRect& aExtentsAppUnits) {
131 AutoWriteLock lock(mLock);
132 HashEntry* entry = mTightGlyphExtents.PutEntry(aGlyphID);
133 if (!entry) {
134 return;
136 entry->x = aExtentsAppUnits.X();
137 entry->y = aExtentsAppUnits.Y();
138 entry->width = aExtentsAppUnits.Width();
139 entry->height = aExtentsAppUnits.Height();
142 size_t gfxGlyphExtents::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
143 AutoReadLock lock(mLock);
144 return mContainedGlyphWidths.SizeOfExcludingThis(aMallocSizeOf) +
145 mTightGlyphExtents.ShallowSizeOfExcludingThis(aMallocSizeOf);
148 size_t gfxGlyphExtents::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
149 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);