summaryrefslogtreecommitdiffstats
path: root/gfx/thebes/gfxDWriteFontList.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/thebes/gfxDWriteFontList.h')
-rw-r--r--gfx/thebes/gfxDWriteFontList.h445
1 files changed, 445 insertions, 0 deletions
diff --git a/gfx/thebes/gfxDWriteFontList.h b/gfx/thebes/gfxDWriteFontList.h
new file mode 100644
index 000000000..6bf094afa
--- /dev/null
+++ b/gfx/thebes/gfxDWriteFontList.h
@@ -0,0 +1,445 @@
+/* -*- 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/. */
+
+#ifndef GFX_DWRITEFONTLIST_H
+#define GFX_DWRITEFONTLIST_H
+
+#include "mozilla/MemoryReporting.h"
+#include "gfxDWriteCommon.h"
+
+#include "gfxFont.h"
+#include "gfxUserFontSet.h"
+#include "cairo-win32.h"
+
+#include "gfxPlatformFontList.h"
+#include "gfxPlatform.h"
+#include <algorithm>
+
+
+/**
+ * gfxDWriteFontFamily is a class that describes one of the fonts on the
+ * users system. It holds each gfxDWriteFontEntry (maps more directly to
+ * a font face) which holds font type, charset info and character map info.
+ */
+class gfxDWriteFontEntry;
+
+/**
+ * \brief Class representing directwrite font family.
+ */
+class gfxDWriteFontFamily : public gfxFontFamily
+{
+public:
+ /**
+ * Constructs a new DWriteFont Family.
+ *
+ * \param aName Name identifying the family
+ * \param aFamily IDWriteFontFamily object representing the directwrite
+ * family object.
+ */
+ gfxDWriteFontFamily(const nsAString& aName,
+ IDWriteFontFamily *aFamily)
+ : gfxFontFamily(aName), mDWFamily(aFamily), mForceGDIClassic(false) {}
+ virtual ~gfxDWriteFontFamily();
+
+ void FindStyleVariations(FontInfoData *aFontInfoData = nullptr) final;
+
+ void LocalizedName(nsAString& aLocalizedName) final;
+
+ void ReadFaceNames(gfxPlatformFontList *aPlatformFontList,
+ bool aNeedFullnamePostscriptNames,
+ FontInfoData *aFontInfoData = nullptr) final;
+
+ void SetForceGDIClassic(bool aForce) { mForceGDIClassic = aForce; }
+
+ void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
+ FontListSizes* aSizes) const final;
+ void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
+ FontListSizes* aSizes) const final;
+
+protected:
+ /** This font family's directwrite fontfamily object */
+ RefPtr<IDWriteFontFamily> mDWFamily;
+ bool mForceGDIClassic;
+};
+
+/**
+ * \brief Class representing DirectWrite FontEntry (a unique font style/family)
+ */
+class gfxDWriteFontEntry : public gfxFontEntry
+{
+public:
+ /**
+ * Constructs a font entry.
+ *
+ * \param aFaceName The name of the corresponding font face.
+ * \param aFont DirectWrite font object
+ */
+ gfxDWriteFontEntry(const nsAString& aFaceName,
+ IDWriteFont *aFont)
+ : gfxFontEntry(aFaceName), mFont(aFont), mFontFile(nullptr),
+ mForceGDIClassic(false)
+ {
+ DWRITE_FONT_STYLE dwriteStyle = aFont->GetStyle();
+ mStyle = (dwriteStyle == DWRITE_FONT_STYLE_ITALIC ?
+ NS_FONT_STYLE_ITALIC :
+ (dwriteStyle == DWRITE_FONT_STYLE_OBLIQUE ?
+ NS_FONT_STYLE_OBLIQUE : NS_FONT_STYLE_NORMAL));
+ mStretch = FontStretchFromDWriteStretch(aFont->GetStretch());
+ uint16_t weight = NS_ROUNDUP(aFont->GetWeight() - 50, 100);
+
+ weight = std::max<uint16_t>(100, weight);
+ weight = std::min<uint16_t>(900, weight);
+ mWeight = weight;
+
+ mIsCJK = UNINITIALIZED_VALUE;
+ }
+
+ /**
+ * Constructs a font entry using a font. But with custom font values.
+ * This is used for creating correct font entries for @font-face with local
+ * font source.
+ *
+ * \param aFaceName The name of the corresponding font face.
+ * \param aFont DirectWrite font object
+ * \param aWeight Weight of the font
+ * \param aStretch Stretch of the font
+ * \param aStyle italic or oblique of font
+ */
+ gfxDWriteFontEntry(const nsAString& aFaceName,
+ IDWriteFont *aFont,
+ uint16_t aWeight,
+ int16_t aStretch,
+ uint8_t aStyle)
+ : gfxFontEntry(aFaceName), mFont(aFont), mFontFile(nullptr),
+ mForceGDIClassic(false)
+ {
+ mWeight = aWeight;
+ mStretch = aStretch;
+ mStyle = aStyle;
+ mIsLocalUserFont = true;
+ mIsCJK = UNINITIALIZED_VALUE;
+ }
+
+ /**
+ * Constructs a font entry using a font file.
+ *
+ * \param aFaceName The name of the corresponding font face.
+ * \param aFontFile DirectWrite fontfile object
+ * \param aFontFileStream DirectWrite fontfile stream object
+ * \param aWeight Weight of the font
+ * \param aStretch Stretch of the font
+ * \param aStyle italic or oblique of font
+ */
+ gfxDWriteFontEntry(const nsAString& aFaceName,
+ IDWriteFontFile *aFontFile,
+ IDWriteFontFileStream *aFontFileStream,
+ uint16_t aWeight,
+ int16_t aStretch,
+ uint8_t aStyle)
+ : gfxFontEntry(aFaceName), mFont(nullptr), mFontFile(aFontFile),
+ mFontFileStream(aFontFileStream), mForceGDIClassic(false)
+ {
+ mWeight = aWeight;
+ mStretch = aStretch;
+ mStyle = aStyle;
+ mIsDataUserFont = true;
+ mIsCJK = UNINITIALIZED_VALUE;
+ }
+
+ virtual ~gfxDWriteFontEntry();
+
+ virtual bool IsSymbolFont();
+
+ virtual hb_blob_t* GetFontTable(uint32_t aTableTag) override;
+
+ nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr);
+
+ bool IsCJKFont();
+
+ void SetForceGDIClassic(bool aForce) { mForceGDIClassic = aForce; }
+ bool GetForceGDIClassic() { return mForceGDIClassic; }
+
+ virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
+ FontListSizes* aSizes) const;
+ virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
+ FontListSizes* aSizes) const;
+
+protected:
+ friend class gfxDWriteFont;
+ friend class gfxDWriteFontList;
+
+ virtual nsresult CopyFontTable(uint32_t aTableTag,
+ nsTArray<uint8_t>& aBuffer) override;
+
+ virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle,
+ bool aNeedsBold);
+
+ nsresult CreateFontFace(
+ IDWriteFontFace **aFontFace,
+ DWRITE_FONT_SIMULATIONS aSimulations = DWRITE_FONT_SIMULATIONS_NONE);
+
+ static bool InitLogFont(IDWriteFont *aFont, LOGFONTW *aLogFont);
+
+ /**
+ * A fontentry only needs to have either of these. If it has both only
+ * the IDWriteFont will be used.
+ */
+ RefPtr<IDWriteFont> mFont;
+ RefPtr<IDWriteFontFile> mFontFile;
+
+ // For custom fonts, we hold a reference to the IDWriteFontFileStream for
+ // for the IDWriteFontFile, so that the data is available.
+ RefPtr<IDWriteFontFileStream> mFontFileStream;
+
+ // font face corresponding to the mFont/mFontFile *without* any DWrite
+ // style simulations applied
+ RefPtr<IDWriteFontFace> mFontFace;
+
+ DWRITE_FONT_FACE_TYPE mFaceType;
+
+ int8_t mIsCJK;
+ bool mForceGDIClassic;
+};
+
+// custom text renderer used to determine the fallback font for a given char
+class DWriteFontFallbackRenderer final : public IDWriteTextRenderer
+{
+public:
+ DWriteFontFallbackRenderer(IDWriteFactory *aFactory)
+ : mRefCount(0)
+ {
+ HRESULT hr = S_OK;
+
+ hr = aFactory->GetSystemFontCollection(getter_AddRefs(mSystemFonts));
+ NS_ASSERTION(SUCCEEDED(hr), "GetSystemFontCollection failed!");
+ }
+
+ ~DWriteFontFallbackRenderer()
+ {}
+
+ // IDWriteTextRenderer methods
+ IFACEMETHOD(DrawGlyphRun)(
+ void* clientDrawingContext,
+ FLOAT baselineOriginX,
+ FLOAT baselineOriginY,
+ DWRITE_MEASURING_MODE measuringMode,
+ DWRITE_GLYPH_RUN const* glyphRun,
+ DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
+ IUnknown* clientDrawingEffect
+ );
+
+ IFACEMETHOD(DrawUnderline)(
+ void* clientDrawingContext,
+ FLOAT baselineOriginX,
+ FLOAT baselineOriginY,
+ DWRITE_UNDERLINE const* underline,
+ IUnknown* clientDrawingEffect
+ )
+ {
+ return E_NOTIMPL;
+ }
+
+
+ IFACEMETHOD(DrawStrikethrough)(
+ void* clientDrawingContext,
+ FLOAT baselineOriginX,
+ FLOAT baselineOriginY,
+ DWRITE_STRIKETHROUGH const* strikethrough,
+ IUnknown* clientDrawingEffect
+ )
+ {
+ return E_NOTIMPL;
+ }
+
+
+ IFACEMETHOD(DrawInlineObject)(
+ void* clientDrawingContext,
+ FLOAT originX,
+ FLOAT originY,
+ IDWriteInlineObject* inlineObject,
+ BOOL isSideways,
+ BOOL isRightToLeft,
+ IUnknown* clientDrawingEffect
+ )
+ {
+ return E_NOTIMPL;
+ }
+
+ // IDWritePixelSnapping methods
+
+ IFACEMETHOD(IsPixelSnappingDisabled)(
+ void* clientDrawingContext,
+ BOOL* isDisabled
+ )
+ {
+ *isDisabled = FALSE;
+ return S_OK;
+ }
+
+ IFACEMETHOD(GetCurrentTransform)(
+ void* clientDrawingContext,
+ DWRITE_MATRIX* transform
+ )
+ {
+ const DWRITE_MATRIX ident = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
+ *transform = ident;
+ return S_OK;
+ }
+
+ IFACEMETHOD(GetPixelsPerDip)(
+ void* clientDrawingContext,
+ FLOAT* pixelsPerDip
+ )
+ {
+ *pixelsPerDip = 1.0f;
+ return S_OK;
+ }
+
+ // IUnknown methods
+
+ IFACEMETHOD_(unsigned long, AddRef) ()
+ {
+ return InterlockedIncrement(&mRefCount);
+ }
+
+ IFACEMETHOD_(unsigned long, Release) ()
+ {
+ unsigned long newCount = InterlockedDecrement(&mRefCount);
+ if (newCount == 0)
+ {
+ delete this;
+ return 0;
+ }
+
+ return newCount;
+ }
+
+ IFACEMETHOD(QueryInterface) (IID const& riid, void** ppvObject)
+ {
+ if (__uuidof(IDWriteTextRenderer) == riid) {
+ *ppvObject = this;
+ } else if (__uuidof(IDWritePixelSnapping) == riid) {
+ *ppvObject = this;
+ } else if (__uuidof(IUnknown) == riid) {
+ *ppvObject = this;
+ } else {
+ *ppvObject = nullptr;
+ return E_FAIL;
+ }
+
+ this->AddRef();
+ return S_OK;
+ }
+
+ const nsString& FallbackFamilyName() { return mFamilyName; }
+
+protected:
+ long mRefCount;
+ RefPtr<IDWriteFontCollection> mSystemFonts;
+ nsString mFamilyName;
+};
+
+
+
+class gfxDWriteFontList : public gfxPlatformFontList {
+public:
+ gfxDWriteFontList();
+
+ static gfxDWriteFontList* PlatformFontList() {
+ return static_cast<gfxDWriteFontList*>(sPlatformFontList);
+ }
+
+ // initialize font lists
+ virtual nsresult InitFontListForPlatform() override;
+
+ virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName,
+ uint16_t aWeight,
+ int16_t aStretch,
+ uint8_t aStyle);
+
+ virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName,
+ uint16_t aWeight,
+ int16_t aStretch,
+ uint8_t aStyle,
+ const uint8_t* aFontData,
+ uint32_t aLength);
+
+ bool GetStandardFamilyName(const nsAString& aFontName,
+ nsAString& aFamilyName);
+
+ IDWriteGdiInterop *GetGDIInterop() { return mGDIInterop; }
+ bool UseGDIFontTableAccess() { return mGDIFontTableAccess; }
+
+ bool FindAndAddFamilies(const nsAString& aFamily,
+ nsTArray<gfxFontFamily*>* aOutput,
+ gfxFontStyle* aStyle = nullptr,
+ gfxFloat aDevToCssSize = 1.0) override;
+
+ gfxFloat GetForceGDIClassicMaxFontSize() { return mForceGDIClassicMaxFontSize; }
+
+ virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
+ FontListSizes* aSizes) const;
+ virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
+ FontListSizes* aSizes) const;
+
+protected:
+ virtual gfxFontFamily*
+ GetDefaultFontForPlatform(const gfxFontStyle* aStyle) override;
+
+ // attempt to use platform-specific fallback for the given character,
+ // return null if no usable result found
+ gfxFontEntry*
+ PlatformGlobalFontFallback(const uint32_t aCh,
+ Script aRunScript,
+ const gfxFontStyle* aMatchStyle,
+ gfxFontFamily** aMatchedFamily) override;
+
+private:
+ friend class gfxDWriteFontFamily;
+
+ nsresult GetFontSubstitutes();
+
+ void GetDirectWriteSubstitutes();
+
+ virtual bool UsesSystemFallback() { return true; }
+
+ void GetFontsFromCollection(IDWriteFontCollection* aCollection);
+
+#ifdef MOZ_BUNDLED_FONTS
+ already_AddRefed<IDWriteFontCollection>
+ CreateBundledFontsCollection(IDWriteFactory* aFactory);
+#endif
+
+ /**
+ * Fonts listed in the registry as substitutes but for which no actual
+ * font family is found.
+ */
+ nsTArray<nsString> mNonExistingFonts;
+
+ /**
+ * Table of font substitutes, we grab this from the registry to get
+ * alternative font names.
+ */
+ FontFamilyTable mFontSubstitutes;
+
+ virtual already_AddRefed<FontInfoData> CreateFontInfoData();
+
+ gfxFloat mForceGDIClassicMaxFontSize;
+
+ // whether to use GDI font table access routines
+ bool mGDIFontTableAccess;
+ RefPtr<IDWriteGdiInterop> mGDIInterop;
+
+ RefPtr<DWriteFontFallbackRenderer> mFallbackRenderer;
+ RefPtr<IDWriteTextFormat> mFallbackFormat;
+
+ RefPtr<IDWriteFontCollection> mSystemFonts;
+#ifdef MOZ_BUNDLED_FONTS
+ RefPtr<IDWriteFontCollection> mBundledFonts;
+#endif
+};
+
+
+#endif /* GFX_DWRITEFONTLIST_H */