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
;
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()
29 #ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
30 gGlyphExtentsWidthsTotalSize
+=
31 mContainedGlyphWidths
.SizeOfExcludingThis(&FontCacheMallocSizeOf
);
34 MOZ_COUNT_DTOR(gfxGlyphExtents
);
38 gfxGlyphExtents::GetTightGlyphExtentsAppUnits(gfxFont
* aFont
,
39 DrawTarget
* aDrawTarget
, uint32_t aGlyphID
, gfxRect
* aExtents
)
41 HashEntry
*entry
= mTightGlyphExtents
.GetEntry(aGlyphID
);
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.
47 NS_WARNING("Could not get glyph extents (no aDrawTarget)");
51 if (aFont
->SetupCairoFont(aDrawTarget
)) {
52 #ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
53 ++gGlyphExtentsSetupLazyTight
;
55 aFont
->SetupGlyphExtents(aDrawTarget
, aGlyphID
, true, this);
56 entry
= mTightGlyphExtents
.GetEntry(aGlyphID
);
59 NS_WARNING("Could not get glyph extents");
64 *aExtents
= gfxRect(entry
->x
, entry
->y
, entry
->width
, entry
->height
);
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
);
80 gfxGlyphExtents::GlyphWidths::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf
) const
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
));
94 gfxGlyphExtents::GlyphWidths::Set(uint32_t aGlyphID
, uint16_t aWidth
)
96 uint32_t block
= aGlyphID
>> BLOCK_SIZE_BITS
;
97 uint32_t len
= mBlocks
.Length();
99 uintptr_t *elems
= mBlocks
.AppendElements(block
+ 1 - len
);
102 memset(elems
, 0, sizeof(uintptr_t)*(block
+ 1 - len
));
105 uintptr_t bits
= mBlocks
[block
];
106 uint32_t glyphOffset
= aGlyphID
& (BLOCK_SIZE
- 1);
108 mBlocks
[block
] = MakeSingle(glyphOffset
, aWidth
);
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
];
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
);
126 newBlock
= reinterpret_cast<uint16_t *>(bits
);
128 newBlock
[glyphOffset
] = aWidth
;
132 gfxGlyphExtents::SetTightGlyphExtents(uint32_t aGlyphID
, const gfxRect
& aExtentsAppUnits
)
134 HashEntry
*entry
= mTightGlyphExtents
.PutEntry(aGlyphID
);
137 entry
->x
= aExtentsAppUnits
.X();
138 entry
->y
= aExtentsAppUnits
.Y();
139 entry
->width
= aExtentsAppUnits
.Width();
140 entry
->height
= aExtentsAppUnits
.Height();
144 gfxGlyphExtents::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf
) const
146 return mContainedGlyphWidths
.SizeOfExcludingThis(aMallocSizeOf
) +
147 mTightGlyphExtents
.ShallowSizeOfExcludingThis(aMallocSizeOf
);
151 gfxGlyphExtents::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const
153 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf
);