diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /gfx/thebes/gfxGlyphExtents.cpp | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | uxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz |
Add m-esr52 at 52.6.0
Diffstat (limited to 'gfx/thebes/gfxGlyphExtents.cpp')
-rw-r--r-- | gfx/thebes/gfxGlyphExtents.cpp | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/gfx/thebes/gfxGlyphExtents.cpp b/gfx/thebes/gfxGlyphExtents.cpp new file mode 100644 index 0000000000..cb8f5838b6 --- /dev/null +++ b/gfx/thebes/gfxGlyphExtents.cpp @@ -0,0 +1,154 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gfxGlyphExtents.h" +#include "gfxTextRun.h" + +using namespace mozilla; + +#ifdef DEBUG_roc +#define DEBUG_TEXT_RUN_STORAGE_METRICS +#endif + +#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS +extern uint32_t gTextRunStorageHighWaterMark; +extern uint32_t gTextRunStorage; +extern uint32_t gFontCount; +extern uint32_t gGlyphExtentsCount; +extern uint32_t gGlyphExtentsWidthsTotalSize; +extern uint32_t gGlyphExtentsSetupEagerSimple; +extern uint32_t gGlyphExtentsSetupEagerTight; +extern uint32_t gGlyphExtentsSetupLazyTight; +extern uint32_t gGlyphExtentsSetupFallBackToTight; +#endif + +gfxGlyphExtents::~gfxGlyphExtents() +{ +#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS + gGlyphExtentsWidthsTotalSize += + mContainedGlyphWidths.SizeOfExcludingThis(&FontCacheMallocSizeOf); + gGlyphExtentsCount++; +#endif + MOZ_COUNT_DTOR(gfxGlyphExtents); +} + +bool +gfxGlyphExtents::GetTightGlyphExtentsAppUnits(gfxFont* aFont, + DrawTarget* aDrawTarget, uint32_t aGlyphID, gfxRect* aExtents) +{ + HashEntry *entry = mTightGlyphExtents.GetEntry(aGlyphID); + if (!entry) { + // Some functions higher up in the call chain deliberately pass in a + // nullptr DrawTarget, e.g. GetBaselinePosition() passes nullptr to + // gfxTextRun::MeasureText() and that nullptr reaches here. + if (!aDrawTarget) { + NS_WARNING("Could not get glyph extents (no aDrawTarget)"); + return false; + } + + if (aFont->SetupCairoFont(aDrawTarget)) { +#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS + ++gGlyphExtentsSetupLazyTight; +#endif + aFont->SetupGlyphExtents(aDrawTarget, aGlyphID, true, this); + entry = mTightGlyphExtents.GetEntry(aGlyphID); + } + if (!entry) { + NS_WARNING("Could not get glyph extents"); + return false; + } + } + + *aExtents = gfxRect(entry->x, entry->y, entry->width, entry->height); + return true; +} + +gfxGlyphExtents::GlyphWidths::~GlyphWidths() +{ + uint32_t i, count = mBlocks.Length(); + for (i = 0; i < count; ++i) { + uintptr_t bits = mBlocks[i]; + if (bits && !(bits & 0x1)) { + delete[] reinterpret_cast<uint16_t *>(bits); + } + } +} + +uint32_t +gfxGlyphExtents::GlyphWidths::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const +{ + uint32_t i; + uint32_t size = mBlocks.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (i = 0; i < mBlocks.Length(); ++i) { + uintptr_t bits = mBlocks[i]; + if (bits && !(bits & 0x1)) { + size += aMallocSizeOf(reinterpret_cast<void*>(bits)); + } + } + return size; +} + +void +gfxGlyphExtents::GlyphWidths::Set(uint32_t aGlyphID, uint16_t aWidth) +{ + uint32_t block = aGlyphID >> BLOCK_SIZE_BITS; + uint32_t len = mBlocks.Length(); + if (block >= len) { + uintptr_t *elems = mBlocks.AppendElements(block + 1 - len); + if (!elems) + return; + memset(elems, 0, sizeof(uintptr_t)*(block + 1 - len)); + } + + uintptr_t bits = mBlocks[block]; + uint32_t glyphOffset = aGlyphID & (BLOCK_SIZE - 1); + if (!bits) { + mBlocks[block] = MakeSingle(glyphOffset, aWidth); + return; + } + + uint16_t *newBlock; + if (bits & 0x1) { + // Expand the block to a real block. We could avoid this by checking + // glyphOffset == GetGlyphOffset(bits), but that never happens so don't bother + newBlock = new uint16_t[BLOCK_SIZE]; + if (!newBlock) + return; + uint32_t i; + for (i = 0; i < BLOCK_SIZE; ++i) { + newBlock[i] = INVALID_WIDTH; + } + newBlock[GetGlyphOffset(bits)] = GetWidth(bits); + mBlocks[block] = reinterpret_cast<uintptr_t>(newBlock); + } else { + newBlock = reinterpret_cast<uint16_t *>(bits); + } + newBlock[glyphOffset] = aWidth; +} + +void +gfxGlyphExtents::SetTightGlyphExtents(uint32_t aGlyphID, const gfxRect& aExtentsAppUnits) +{ + HashEntry *entry = mTightGlyphExtents.PutEntry(aGlyphID); + if (!entry) + return; + entry->x = aExtentsAppUnits.X(); + entry->y = aExtentsAppUnits.Y(); + entry->width = aExtentsAppUnits.Width(); + entry->height = aExtentsAppUnits.Height(); +} + +size_t +gfxGlyphExtents::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const +{ + return mContainedGlyphWidths.SizeOfExcludingThis(aMallocSizeOf) + + mTightGlyphExtents.ShallowSizeOfExcludingThis(aMallocSizeOf); +} + +size_t +gfxGlyphExtents::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const +{ + return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); +} |