summaryrefslogtreecommitdiffstats
path: root/gfx/thebes/gfxFT2FontBase.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/thebes/gfxFT2FontBase.h')
-rw-r--r--gfx/thebes/gfxFT2FontBase.h152
1 files changed, 152 insertions, 0 deletions
diff --git a/gfx/thebes/gfxFT2FontBase.h b/gfx/thebes/gfxFT2FontBase.h
new file mode 100644
index 0000000000..08a79c2ada
--- /dev/null
+++ b/gfx/thebes/gfxFT2FontBase.h
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * 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/. */
+
+#ifndef GFX_FT2FONTBASE_H
+#define GFX_FT2FONTBASE_H
+
+#include "gfxContext.h"
+#include "gfxFont.h"
+#include "gfxFontEntry.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/UnscaledFontFreeType.h"
+#include "nsTHashMap.h"
+#include "nsHashKeys.h"
+
+class gfxFT2FontBase;
+
+class gfxFT2FontEntryBase : public gfxFontEntry {
+ public:
+ explicit gfxFT2FontEntryBase(const nsACString& aName) : gfxFontEntry(aName) {}
+
+ uint32_t GetGlyph(uint32_t aCharCode, gfxFT2FontBase* aFont);
+
+ static bool FaceHasTable(mozilla::gfx::SharedFTFace*, uint32_t aTableTag);
+ static nsresult CopyFaceTable(mozilla::gfx::SharedFTFace*, uint32_t aTableTag,
+ nsTArray<uint8_t>&);
+
+ private:
+ enum { kNumCmapCacheSlots = 256 };
+
+ struct CmapCacheSlot {
+ CmapCacheSlot() : mCharCode(0), mGlyphIndex(0) {}
+
+ uint32_t mCharCode;
+ uint32_t mGlyphIndex;
+ };
+
+ mozilla::UniquePtr<CmapCacheSlot[]> mCmapCache MOZ_GUARDED_BY(mLock);
+};
+
+class gfxFT2FontBase : public gfxFont {
+ public:
+ gfxFT2FontBase(
+ const RefPtr<mozilla::gfx::UnscaledFontFreeType>& aUnscaledFont,
+ RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace, gfxFontEntry* aFontEntry,
+ const gfxFontStyle* aFontStyle, int aLoadFlags, bool aEmbolden);
+
+ uint32_t GetGlyph(uint32_t aCharCode) {
+ auto* entry = static_cast<gfxFT2FontEntryBase*>(mFontEntry.get());
+ return entry->GetGlyph(aCharCode, this);
+ }
+
+ bool ProvidesGetGlyph() const override { return true; }
+ virtual uint32_t GetGlyph(uint32_t unicode,
+ uint32_t variation_selector) override;
+
+ bool ProvidesGlyphWidths() const override { return true; }
+ int32_t GetGlyphWidth(uint16_t aGID) override {
+ return GetCachedGlyphMetrics(aGID).mAdvance;
+ }
+
+ bool GetGlyphBounds(uint16_t aGID, gfxRect* aBounds, bool aTight) override;
+
+ FontType GetType() const override { return FONT_TYPE_FT2; }
+
+ bool ShouldRoundXOffset(cairo_t* aCairo) const override;
+
+ static void SetupVarCoords(FT_MM_Var* aMMVar,
+ const nsTArray<gfxFontVariation>& aVariations,
+ FT_Face aFTFace);
+
+ FT_Face LockFTFace() const;
+ void UnlockFTFace() const;
+
+ private:
+ uint32_t GetCharExtents(uint32_t aChar, gfxFloat* aWidth,
+ gfxRect* aBounds = nullptr);
+
+ // Get advance (and optionally bounds) of a single glyph from FreeType,
+ // and return true, or return false if we failed.
+ bool GetFTGlyphExtents(uint16_t aGID, int32_t* aWidth,
+ mozilla::gfx::IntRect* aBounds = nullptr);
+
+ protected:
+ ~gfxFT2FontBase() override;
+ void InitMetrics();
+ const Metrics& GetHorizontalMetrics() const override { return mMetrics; }
+ FT_Vector GetEmboldenStrength(FT_Face aFace) const;
+
+ RefPtr<mozilla::gfx::SharedFTFace> mFTFace;
+
+ Metrics mMetrics;
+ int mFTLoadFlags;
+ bool mEmbolden;
+ gfxFloat mFTSize;
+
+ // For variation/multiple-master fonts, this will be an array of the values
+ // for each axis, as specified by mStyle.variationSettings (or the font's
+ // default for axes not present in variationSettings). Values here are in
+ // freetype's 16.16 fixed-point format, and clamped to the valid min/max
+ // range reported by the face.
+ nsTArray<FT_Fixed> mCoords;
+
+ // Store cached glyph metrics for reasonably small glyph sizes. The bounds
+ // are stored unscaled to losslessly compress 26.6 fixed point to an int16_t.
+ // Larger glyphs are handled directly via GetFTGlyphExtents.
+ struct GlyphMetrics {
+ // Set the X coord to INT16_MIN to signal the bounds are invalid, or
+ // INT16_MAX to signal that the bounds would overflow an int16_t.
+ enum { INVALID = INT16_MIN, LARGE = INT16_MAX };
+
+ GlyphMetrics() : mAdvance(0), mX(INVALID), mY(0), mWidth(0), mHeight(0) {}
+
+ bool HasValidBounds() const { return mX != INVALID; }
+ bool HasCachedBounds() const { return mX != LARGE; }
+
+ // If the bounds can fit in an int16_t, set them. Otherwise, leave the
+ // bounds invalid to signal that GetFTGlyphExtents should be queried
+ // directly.
+ void SetBounds(const mozilla::gfx::IntRect& aBounds) {
+ if (aBounds.x > INT16_MIN && aBounds.x < INT16_MAX &&
+ aBounds.y > INT16_MIN && aBounds.y < INT16_MAX &&
+ aBounds.width <= UINT16_MAX && aBounds.height <= UINT16_MAX) {
+ mX = aBounds.x;
+ mY = aBounds.y;
+ mWidth = aBounds.width;
+ mHeight = aBounds.height;
+ } else {
+ mX = LARGE;
+ }
+ }
+
+ mozilla::gfx::IntRect GetBounds() const {
+ return mozilla::gfx::IntRect(mX, mY, mWidth, mHeight);
+ }
+
+ int32_t mAdvance;
+ int16_t mX;
+ int16_t mY;
+ uint16_t mWidth;
+ uint16_t mHeight;
+ };
+
+ const GlyphMetrics& GetCachedGlyphMetrics(
+ uint16_t aGID, mozilla::gfx::IntRect* aBounds = nullptr);
+
+ mozilla::UniquePtr<nsTHashMap<nsUint32HashKey, GlyphMetrics>> mGlyphMetrics
+ MOZ_GUARDED_BY(mLock);
+};
+
+#endif /* GFX_FT2FONTBASE_H */