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
;
12 # define DEBUG_TEXT_RUN_STORAGE_METRICS
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
;
27 gfxGlyphExtents::~gfxGlyphExtents() {
28 #ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
29 gGlyphExtentsWidthsTotalSize
+=
30 mContainedGlyphWidths
.SizeOfExcludingThis(&FontCacheMallocSizeOf
);
33 MOZ_COUNT_DTOR(gfxGlyphExtents
);
36 bool gfxGlyphExtents::GetTightGlyphExtentsAppUnitsLocked(
37 gfxFont
* aFont
, DrawTarget
* aDrawTarget
, uint32_t aGlyphID
,
39 HashEntry
* entry
= mTightGlyphExtents
.GetEntry(aGlyphID
);
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.
45 NS_WARNING("Could not get glyph extents (no aDrawTarget)");
49 #ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
50 ++gGlyphExtentsSetupLazyTight
;
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
56 aFont
->SetupGlyphExtents(aDrawTarget
, aGlyphID
, true, this);
60 entry
= mTightGlyphExtents
.GetEntry(aGlyphID
);
62 NS_WARNING("Could not get glyph extents");
67 *aExtents
= gfxRect(entry
->x
, entry
->y
, entry
->width
, entry
->height
);
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 {
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
));
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();
98 uintptr_t* elems
= mBlocks
.AppendElements(block
+ 1 - len
);
100 memset(elems
, 0, sizeof(uintptr_t) * (block
+ 1 - len
));
103 uintptr_t bits
= mBlocks
[block
];
104 uint32_t glyphOffset
= aGlyphID
& (BLOCK_SIZE
- 1);
106 mBlocks
[block
] = MakeSingle(glyphOffset
, aWidth
);
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
115 newBlock
= new uint16_t[BLOCK_SIZE
];
116 if (!newBlock
) return;
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
);
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
);
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
);