tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

gfxGlyphExtents.cpp (4844B)


      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/. */
      5 
      6 #include "gfxGlyphExtents.h"
      7 #include "gfxTextRun.h"
      8 
      9 using namespace mozilla;
     10 
     11 #ifdef DEBUG_roc
     12 #  define DEBUG_TEXT_RUN_STORAGE_METRICS
     13 #endif
     14 
     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
     26 
     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);
     34 }
     35 
     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;
     47    }
     48 
     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
     59 
     60    entry = mTightGlyphExtents.GetEntry(aGlyphID);
     61    if (!entry) {
     62      NS_WARNING("Could not get glyph extents");
     63      return false;
     64    }
     65  }
     66 
     67  *aExtents = gfxRect(entry->x, entry->y, entry->width, entry->height);
     68  return true;
     69 }
     70 
     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);
     77    }
     78  }
     79 }
     80 
     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));
     89    }
     90  }
     91  return size;
     92 }
     93 
     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));
    101  }
    102 
    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;
    108  }
    109 
    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;
    120    }
    121    newBlock[GetGlyphOffset(bits)] = GetWidth(bits);
    122    mBlocks[block] = reinterpret_cast<uintptr_t>(newBlock);
    123  } else {
    124    newBlock = reinterpret_cast<uint16_t*>(bits);
    125  }
    126  newBlock[glyphOffset] = aWidth;
    127 }
    128 
    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;
    135  }
    136  entry->x = aExtentsAppUnits.X();
    137  entry->y = aExtentsAppUnits.Y();
    138  entry->width = aExtentsAppUnits.Width();
    139  entry->height = aExtentsAppUnits.Height();
    140 }
    141 
    142 size_t gfxGlyphExtents::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
    143  AutoReadLock lock(mLock);
    144  return mContainedGlyphWidths.SizeOfExcludingThis(aMallocSizeOf) +
    145         mTightGlyphExtents.ShallowSizeOfExcludingThis(aMallocSizeOf);
    146 }
    147 
    148 size_t gfxGlyphExtents::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
    149  return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
    150 }