tor-browser

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

gfxFT2FontBase.h (5450B)


      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 #ifndef GFX_FT2FONTBASE_H
      7 #define GFX_FT2FONTBASE_H
      8 
      9 #include "gfxContext.h"
     10 #include "gfxFont.h"
     11 #include "gfxFontEntry.h"
     12 #include "mozilla/gfx/2D.h"
     13 #include "mozilla/gfx/UnscaledFontFreeType.h"
     14 #include "nsTHashMap.h"
     15 #include "nsHashKeys.h"
     16 
     17 class gfxFT2FontBase;
     18 
     19 namespace mozilla {
     20 namespace gfx {
     21 class FTUserFontData;
     22 }
     23 }  // namespace mozilla
     24 
     25 class gfxFT2FontEntryBase : public gfxFontEntry {
     26 public:
     27  explicit gfxFT2FontEntryBase(const nsACString& aName) : gfxFontEntry(aName) {}
     28 
     29  uint32_t GetGlyph(uint32_t aCharCode, gfxFT2FontBase* aFont);
     30 
     31  static bool FaceHasTable(mozilla::gfx::SharedFTFace*, uint32_t aTableTag);
     32  static nsresult CopyFaceTable(mozilla::gfx::SharedFTFace*, uint32_t aTableTag,
     33                                nsTArray<uint8_t>&);
     34 
     35  virtual mozilla::gfx::FTUserFontData* GetUserFontData() = 0;
     36 
     37  size_t ComputedSizeOfExcludingThis(
     38      mozilla::MallocSizeOf aMallocSizeOf) override;
     39 
     40 private:
     41  enum { kNumCmapCacheSlots = 256 };
     42 
     43  struct CmapCacheSlot {
     44    CmapCacheSlot() : mCharCode(0), mGlyphIndex(0) {}
     45 
     46    uint32_t mCharCode;
     47    uint32_t mGlyphIndex;
     48  };
     49 
     50  mozilla::UniquePtr<CmapCacheSlot[]> mCmapCache MOZ_GUARDED_BY(mLock);
     51 };
     52 
     53 class gfxFT2FontBase : public gfxFont {
     54 public:
     55  gfxFT2FontBase(
     56      const RefPtr<mozilla::gfx::UnscaledFontFreeType>& aUnscaledFont,
     57      RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace, gfxFontEntry* aFontEntry,
     58      const gfxFontStyle* aFontStyle, int aLoadFlags, bool aEmbolden);
     59 
     60  uint32_t GetGlyph(uint32_t aCharCode) {
     61    auto* entry = static_cast<gfxFT2FontEntryBase*>(mFontEntry.get());
     62    return entry->GetGlyph(aCharCode, this);
     63  }
     64 
     65  bool ProvidesGetGlyph() const override { return true; }
     66  virtual uint32_t GetGlyph(uint32_t unicode,
     67                            uint32_t variation_selector) override;
     68 
     69  bool ProvidesGlyphWidths() const override { return true; }
     70  int32_t GetGlyphWidth(uint16_t aGID) override {
     71    return GetCachedGlyphMetrics(aGID).mAdvance;
     72  }
     73 
     74  bool GetGlyphBounds(uint16_t aGID, gfxRect* aBounds, bool aTight) override;
     75 
     76  FontType GetType() const override { return FONT_TYPE_FT2; }
     77 
     78  bool ShouldRoundXOffset(cairo_t* aCairo) const override;
     79 
     80  static void SetupVarCoords(FT_MM_Var* aMMVar,
     81                             const nsTArray<gfxFontVariation>& aVariations,
     82                             FT_Face aFTFace);
     83 
     84  FT_Face LockFTFace() const;
     85  void UnlockFTFace() const;
     86 
     87 private:
     88  uint32_t GetCharExtents(uint32_t aChar, gfxFloat* aWidth,
     89                          gfxRect* aBounds = nullptr);
     90 
     91  // Get advance (and optionally bounds) of a single glyph from FreeType,
     92  // and return true, or return false if we failed.
     93  bool GetFTGlyphExtents(uint16_t aGID, int32_t* aWidth,
     94                         mozilla::gfx::IntRect* aBounds = nullptr);
     95 
     96 protected:
     97  ~gfxFT2FontBase() override;
     98  void InitMetrics();
     99  const Metrics& GetHorizontalMetrics() const override { return mMetrics; }
    100  FT_Vector GetEmboldenStrength(FT_Face aFace) const;
    101 
    102  RefPtr<mozilla::gfx::SharedFTFace> mFTFace;
    103 
    104  Metrics mMetrics;
    105  int mFTLoadFlags;
    106  bool mEmbolden;
    107  gfxFloat mFTSize;
    108 
    109  // For variation/multiple-master fonts, this will be an array of the values
    110  // for each axis, as specified by mStyle.variationSettings (or the font's
    111  // default for axes not present in variationSettings). Values here are in
    112  // freetype's 16.16 fixed-point format, and clamped to the valid min/max
    113  // range reported by the face.
    114  nsTArray<FT_Fixed> mCoords;
    115 
    116  // Store cached glyph metrics for reasonably small glyph sizes. The bounds
    117  // are stored unscaled to losslessly compress 26.6 fixed point to an int16_t.
    118  // Larger glyphs are handled directly via GetFTGlyphExtents.
    119  struct GlyphMetrics {
    120    // Set the X coord to INT16_MIN to signal the bounds are invalid, or
    121    // INT16_MAX to signal that the bounds would overflow an int16_t.
    122    enum { INVALID = INT16_MIN, LARGE = INT16_MAX };
    123 
    124    GlyphMetrics() : mAdvance(0), mX(INVALID), mY(0), mWidth(0), mHeight(0) {}
    125 
    126    bool HasValidBounds() const { return mX != INVALID; }
    127    bool HasCachedBounds() const { return mX != LARGE; }
    128 
    129    // If the bounds can fit in an int16_t, set them. Otherwise, leave the
    130    // bounds invalid to signal that GetFTGlyphExtents should be queried
    131    // directly.
    132    void SetBounds(const mozilla::gfx::IntRect& aBounds) {
    133      if (aBounds.x > INT16_MIN && aBounds.x < INT16_MAX &&
    134          aBounds.y > INT16_MIN && aBounds.y < INT16_MAX &&
    135          aBounds.width <= UINT16_MAX && aBounds.height <= UINT16_MAX) {
    136        mX = aBounds.x;
    137        mY = aBounds.y;
    138        mWidth = aBounds.width;
    139        mHeight = aBounds.height;
    140      } else {
    141        mX = LARGE;
    142      }
    143    }
    144 
    145    mozilla::gfx::IntRect GetBounds() const {
    146      return mozilla::gfx::IntRect(mX, mY, mWidth, mHeight);
    147    }
    148 
    149    int32_t mAdvance;
    150    int16_t mX;
    151    int16_t mY;
    152    uint16_t mWidth;
    153    uint16_t mHeight;
    154  };
    155 
    156  const GlyphMetrics& GetCachedGlyphMetrics(
    157      uint16_t aGID, mozilla::gfx::IntRect* aBounds = nullptr);
    158 
    159  mozilla::UniquePtr<nsTHashMap<nsUint32HashKey, GlyphMetrics>> mGlyphMetrics
    160      MOZ_GUARDED_BY(mLock);
    161 };
    162 
    163 #endif /* GFX_FT2FONTBASE_H */