diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h index 37f08d5384f2..fb561b752c2d 100644 --- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -1520,12 +1520,13 @@ public: * * @param aData Pointer to the data * @param aSize Size of the TrueType data - * @param aType Type of NativeFontResource that should be created. + * @param aBackendType Type of the reference DrawTarget the font should be created for. + * @param aFontType Type of NativeFontResource that should be created. * @param aFontContext Optional native font context to be used to create the NativeFontResource. * @return a NativeFontResource of nullptr if failed. */ static already_AddRefed - CreateNativeFontResource(uint8_t *aData, uint32_t aSize, FontType aType, void* aFontContext = nullptr); + CreateNativeFontResource(uint8_t *aData, uint32_t aSize, BackendType aBackendType, FontType aFontType, void* aFontContext = nullptr); /** * This creates an unscaled font of the given type based on font descriptor @@ -1661,16 +1662,13 @@ public: * Returns true on success, or false on failure and leaves the D2D1/Direct3D11 devices unset. */ static bool SetDirect3D11Device(ID3D11Device *aDevice); - static bool SetDWriteFactory(IDWriteFactory *aFactory); static ID3D11Device *GetDirect3D11Device(); static ID2D1Device *GetD2D1Device(); static uint32_t GetD2D1DeviceSeq(); static IDWriteFactory *GetDWriteFactory(); + static IDWriteFactory* EnsureDWriteFactory(); static bool SupportsD2D1(); - static already_AddRefed - CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams); - static uint64_t GetD2DVRAMUsageDrawTarget(); static uint64_t GetD2DVRAMUsageSourceSurface(); static void D2DCleanup(); @@ -1681,7 +1679,10 @@ public: const RefPtr& aUnscaledFont, Float aSize, bool aUseEmbeddedBitmap, - bool aForceGDIMode); + bool aForceGDIMode, + IDWriteRenderingParams *aParams, + Float aGamma, + Float aContrast); static void UpdateSystemTextQuality(); @@ -1689,6 +1690,8 @@ private: static ID2D1Device *mD2D1Device; static ID3D11Device *mD3D11Device; static IDWriteFactory *mDWriteFactory; + static bool mDWriteFactoryInitialized; + static Mutex* mDWriteFactoryLock; #endif static DrawEventRecorder *mRecorder; diff --git a/gfx/2d/DrawTargetD2D1.cpp b/gfx/2d/DrawTargetD2D1.cpp index 0df50ac8cea4..d099b652f707 100644 --- a/gfx/2d/DrawTargetD2D1.cpp +++ b/gfx/2d/DrawTargetD2D1.cpp @@ -17,6 +17,8 @@ #include "Tools.h" #include "nsAppRunner.h" +#include "mozilla/Mutex.h" + using namespace std; // decltype is not usable for overloaded functions. @@ -32,7 +34,6 @@ namespace gfx { uint64_t DrawTargetD2D1::mVRAMUsageDT; uint64_t DrawTargetD2D1::mVRAMUsageSS; -IDWriteFactory *DrawTargetD2D1::mDWriteFactory; ID2D1Factory1* DrawTargetD2D1::mFactory = nullptr; ID2D1Factory1 *D2DFactory1() @@ -608,7 +609,7 @@ DrawTargetD2D1::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pattern &aPattern, const DrawOptions &aOptions, - const GlyphRenderingOptions *aRenderingOptions) + const GlyphRenderingOptions*) { if (aFont->GetType() != FontType::DWRITE) { gfxDebug() << *this << ": Ignoring drawing call for incompatible font."; @@ -617,16 +618,7 @@ DrawTargetD2D1::FillGlyphs(ScaledFont *aFont, ScaledFontDWrite *font = static_cast(aFont); - IDWriteRenderingParams *params = nullptr; - if (aRenderingOptions) { - if (aRenderingOptions->GetType() != FontType::DWRITE) { - gfxDebug() << *this << ": Ignoring incompatible GlyphRenderingOptions."; - // This should never happen. - MOZ_ASSERT(false); - } else { - params = static_cast(aRenderingOptions)->mParams; - } - } + IDWriteRenderingParams *params = font->mParams; AntialiasMode aaMode = font->GetDefaultAAMode(); @@ -1256,33 +1248,6 @@ DrawTargetD2D1::factory() return mFactory; } -IDWriteFactory* -DrawTargetD2D1::GetDWriteFactory() -{ - if (mDWriteFactory) { - return mDWriteFactory; - } - - decltype(DWriteCreateFactory)* createDWriteFactory; - HMODULE dwriteModule = LoadLibraryW(L"dwrite.dll"); - createDWriteFactory = (decltype(DWriteCreateFactory)*) - GetProcAddress(dwriteModule, "DWriteCreateFactory"); - - if (!createDWriteFactory) { - gfxWarning() << "Failed to locate DWriteCreateFactory function."; - return nullptr; - } - - HRESULT hr = createDWriteFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), - reinterpret_cast(&mDWriteFactory)); - - if (FAILED(hr)) { - gfxWarning() << "Failed to create DWrite Factory."; - } - - return mDWriteFactory; -} - void DrawTargetD2D1::CleanupD2D() { diff --git a/gfx/2d/DrawTargetD2D1.h b/gfx/2d/DrawTargetD2D1.h index 2107da2e6b0c..da6e8f28d52c 100644 --- a/gfx/2d/DrawTargetD2D1.h +++ b/gfx/2d/DrawTargetD2D1.h @@ -155,7 +155,6 @@ public: static ID2D1Factory1 *factory(); static void CleanupD2D(); - static IDWriteFactory *GetDWriteFactory(); operator std::string() const { std::stringstream stream; @@ -294,7 +293,6 @@ private: bool mDidComplexBlendWithListInList; static ID2D1Factory1 *mFactory; - static IDWriteFactory *mDWriteFactory; // This value is uesed to verify if the DrawTarget is created by a stale device. uint32_t mDeviceSeq; diff --git a/gfx/2d/Factory.cpp b/gfx/2d/Factory.cpp index bef27f1d9672..6a0941023bd4 100644 --- a/gfx/2d/Factory.cpp +++ b/gfx/2d/Factory.cpp @@ -45,6 +45,7 @@ #include #include "HelpersD2D.h" #include "HelpersWinFonts.h" +#include "mozilla/Mutex.h" #endif #include "DrawTargetDual.h" @@ -203,6 +204,8 @@ static uint32_t mDeviceSeq = 0; ID3D11Device *Factory::mD3D11Device = nullptr; ID2D1Device *Factory::mD2D1Device = nullptr; IDWriteFactory *Factory::mDWriteFactory = nullptr; +bool Factory::mDWriteFactoryInitialized = false; +Mutex* Factory::mDWriteFactoryLock = nullptr; #endif DrawEventRecorder *Factory::mRecorder; @@ -229,6 +232,10 @@ Factory::Init(const Config& aConfig) #ifdef MOZ_ENABLE_FREETYPE mFTLock = new Mutex("Factory::mFTLock"); #endif + +#ifdef WIN32 + mDWriteFactoryLock = new Mutex("Factory::mDWriteFactoryLock"); +#endif } void @@ -247,6 +254,13 @@ Factory::ShutDown() mFTLock = nullptr; } #endif + +#ifdef WIN32 + if (mDWriteFactoryLock) { + delete mDWriteFactoryLock; + mDWriteFactoryLock = nullptr; + } +#endif } bool @@ -553,38 +567,26 @@ Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont, } already_AddRefed -Factory::CreateNativeFontResource(uint8_t *aData, uint32_t aSize, FontType aType, void* aFontContext) +Factory::CreateNativeFontResource(uint8_t *aData, uint32_t aSize, BackendType aBackendType, FontType aFontType, void* aFontContext) { - switch (aType) { + switch (aFontType) { #ifdef WIN32 case FontType::DWRITE: { - return NativeFontResourceDWrite::Create(aData, aSize, - /* aNeedsCairo = */ false); + bool needsCairo = aBackendType == BackendType::CAIRO || + aBackendType == BackendType::SKIA; + return NativeFontResourceDWrite::Create(aData, aSize, needsCairo); } -#endif - case FontType::CAIRO: -#ifdef USE_SKIA - case FontType::SKIA: -#endif - { -#ifdef WIN32 - if (GetDWriteFactory()) { - return NativeFontResourceDWrite::Create(aData, aSize, - /* aNeedsCairo = */ true); - } else { - return NativeFontResourceGDI::Create(aData, aSize); - } + case FontType::GDI: + return NativeFontResourceGDI::Create(aData, aSize); #elif defined(XP_DARWIN) - return NativeFontResourceMac::Create(aData, aSize); + case FontType::MAC: + return NativeFontResourceMac::Create(aData, aSize); #elif defined(MOZ_WIDGET_GTK) - return NativeFontResourceFontconfig::Create(aData, aSize, - static_cast(aFontContext)); -#else - gfxWarning() << "Unable to create cairo scaled font from truetype data"; - return nullptr; + case FontType::FONTCONFIG: + return NativeFontResourceFontconfig::Create(aData, aSize, + static_cast(aFontContext)); #endif - } default: gfxWarning() << "Unable to create requested font resource from truetype data"; return nullptr; @@ -756,13 +758,6 @@ Factory::CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceForma return nullptr; } -bool -Factory::SetDWriteFactory(IDWriteFactory *aFactory) -{ - mDWriteFactory = aFactory; - return true; -} - bool Factory::SetDirect3D11Device(ID3D11Device *aDevice) { @@ -818,18 +813,43 @@ Factory::GetDWriteFactory() return mDWriteFactory; } +IDWriteFactory* +Factory::EnsureDWriteFactory() +{ + MOZ_ASSERT(mDWriteFactoryLock); + MutexAutoLock lock(*mDWriteFactoryLock); + + if (mDWriteFactoryInitialized) { + return mDWriteFactory; + } + + mDWriteFactoryInitialized = true; + + HMODULE dwriteModule = LoadLibraryW(L"dwrite.dll"); + decltype(DWriteCreateFactory)* createDWriteFactory = (decltype(DWriteCreateFactory)*) + GetProcAddress(dwriteModule, "DWriteCreateFactory"); + + if (!createDWriteFactory) { + gfxWarning() << "Failed to locate DWriteCreateFactory function."; + return nullptr; + } + + HRESULT hr = createDWriteFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), + reinterpret_cast(&mDWriteFactory)); + + if (FAILED(hr)) { + gfxWarning() << "Failed to create DWrite Factory."; + } + + return mDWriteFactory; +} + bool Factory::SupportsD2D1() { return !!D2DFactory1(); } -already_AddRefed -Factory::CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams) -{ - return MakeAndAddRef(aParams); -} - BYTE sSystemTextQuality = CLEARTYPE_QUALITY; void Factory::UpdateSystemTextQuality() @@ -867,10 +887,14 @@ Factory::CreateScaledFontForDWriteFont(IDWriteFontFace* aFontFace, const RefPtr& aUnscaledFont, float aSize, bool aUseEmbeddedBitmap, - bool aForceGDIMode) + bool aForceGDIMode, + IDWriteRenderingParams* aParams, + Float aGamma, + Float aContrast) { return MakeAndAddRef(aFontFace, aUnscaledFont, aSize, aUseEmbeddedBitmap, aForceGDIMode, + aParams, aGamma, aContrast, aStyle); } diff --git a/gfx/2d/InlineTranslator.cpp b/gfx/2d/InlineTranslator.cpp index ecb051883416..e3524e6b98e1 100644 --- a/gfx/2d/InlineTranslator.cpp +++ b/gfx/2d/InlineTranslator.cpp @@ -76,20 +76,5 @@ InlineTranslator::CreateDrawTarget(ReferencePtr aRefPtr, return drawTarget.forget(); } -FontType -InlineTranslator::GetDesiredFontType() -{ - switch (mBaseDT->GetBackendType()) { - case BackendType::DIRECT2D: - return FontType::DWRITE; - case BackendType::CAIRO: - return FontType::CAIRO; - case BackendType::SKIA: - return FontType::SKIA; - default: - return FontType::CAIRO; - } -} - } // namespace gfx } // namespace mozilla diff --git a/gfx/2d/InlineTranslator.h b/gfx/2d/InlineTranslator.h index b5305f703def..f218c1c7f99e 100644 --- a/gfx/2d/InlineTranslator.h +++ b/gfx/2d/InlineTranslator.h @@ -173,8 +173,6 @@ public: mozilla::gfx::DrawTarget* GetReferenceDrawTarget() final { return mBaseDT; } - mozilla::gfx::FontType GetDesiredFontType() final; - void* GetFontContext() final { return mFontContext; } private: diff --git a/gfx/2d/NativeFontResourceDWrite.cpp b/gfx/2d/NativeFontResourceDWrite.cpp index 02395601b599..4b934c23d8aa 100644 --- a/gfx/2d/NativeFontResourceDWrite.cpp +++ b/gfx/2d/NativeFontResourceDWrite.cpp @@ -9,7 +9,6 @@ #include -#include "DrawTargetD2D1.h" #include "Logging.h" #include "mozilla/RefPtr.h" @@ -70,7 +69,7 @@ public: { if (!mInstance) { mInstance = new DWriteFontFileLoader(); - DrawTargetD2D1::GetDWriteFactory()-> + Factory::GetDWriteFactory()-> RegisterFontFileLoader(mInstance); } return mInstance; @@ -222,7 +221,7 @@ already_AddRefed NativeFontResourceDWrite::Create(uint8_t *aFontData, uint32_t aDataLength, bool aNeedsCairo) { - IDWriteFactory *factory = DrawTargetD2D1::GetDWriteFactory(); + IDWriteFactory *factory = Factory::EnsureDWriteFactory(); if (!factory) { gfxWarning() << "Failed to get DWrite Factory."; return nullptr; diff --git a/gfx/2d/RecordedEvent.h b/gfx/2d/RecordedEvent.h index 97708cdc31fa..4058df57a1b7 100644 --- a/gfx/2d/RecordedEvent.h +++ b/gfx/2d/RecordedEvent.h @@ -24,7 +24,7 @@ const uint32_t kMagicInt = 0xc001feed; // loss of backwards compatibility. Old streams will not work in a player // using a newer major revision. And new streams will not work in a player // using an older major revision. -const uint16_t kMajorRevision = 9; +const uint16_t kMajorRevision = 10; // A change in minor revision means additions of new events. New streams will // not play in older players. const uint16_t kMinorRevision = 0; @@ -111,7 +111,6 @@ public: const IntSize &aSize, SurfaceFormat aFormat); virtual DrawTarget *GetReferenceDrawTarget() = 0; - virtual FontType GetDesiredFontType() = 0; virtual void* GetFontContext() { return nullptr; } }; diff --git a/gfx/2d/RecordedEventImpl.h b/gfx/2d/RecordedEventImpl.h index 2876b94cb7c4..942731b124d4 100644 --- a/gfx/2d/RecordedEventImpl.h +++ b/gfx/2d/RecordedEventImpl.h @@ -847,7 +847,9 @@ public: } explicit RecordedFontData(UnscaledFont *aUnscaledFont) - : RecordedEventDerived(FONTDATA), mData(nullptr) + : RecordedEventDerived(FONTDATA) + , mType(aUnscaledFont->GetType()) + , mData(nullptr) { mGetFontFileDataSucceeded = aUnscaledFont->GetFontFileData(&FontDataProc, this); } @@ -871,6 +873,7 @@ public: private: friend class RecordedEvent; + FontType mType; uint8_t* mData; RecordedFontDetails mFontDetails; @@ -2642,8 +2645,8 @@ RecordedFontData::PlayEvent(Translator *aTranslator) const { RefPtr fontResource = Factory::CreateNativeFontResource(mData, mFontDetails.size, - aTranslator->GetDesiredFontType(), - aTranslator->GetFontContext()); + aTranslator->GetReferenceDrawTarget()->GetBackendType(), + mType, aTranslator->GetFontContext()); if (!fontResource) { return false; } @@ -2658,6 +2661,7 @@ RecordedFontData::Record(S &aStream) const { MOZ_ASSERT(mGetFontFileDataSucceeded); + WriteElement(aStream, mType); WriteElement(aStream, mFontDetails.fontDataKey); WriteElement(aStream, mFontDetails.size); aStream.write((const char*)mData, mFontDetails.size); @@ -2696,8 +2700,10 @@ RecordedFontData::GetFontDetails(RecordedFontDetails& fontDetails) inline RecordedFontData::RecordedFontData(istream &aStream) : RecordedEventDerived(FONTDATA) + , mType(FontType::SKIA) , mData(nullptr) { + ReadElement(aStream, mType); ReadElement(aStream, mFontDetails.fontDataKey); ReadElement(aStream, mFontDetails.size); mData = new uint8_t[mFontDetails.size]; diff --git a/gfx/2d/ScaledFontDWrite.cpp b/gfx/2d/ScaledFontDWrite.cpp index 05278bd909ff..ed4b5d59dc6a 100644 --- a/gfx/2d/ScaledFontDWrite.cpp +++ b/gfx/2d/ScaledFontDWrite.cpp @@ -3,11 +3,11 @@ * 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 "DrawTargetD2D1.h" #include "ScaledFontDWrite.h" #include "UnscaledFontDWrite.h" #include "PathD2D.h" #include "gfxFont.h" +#include "Logging.h" using namespace std; @@ -108,16 +108,24 @@ ScaledFontDWrite::ScaledFontDWrite(IDWriteFontFace *aFontFace, Float aSize, bool aUseEmbeddedBitmap, bool aForceGDIMode, + IDWriteRenderingParams* aParams, + Float aGamma, + Float aContrast, const gfxFontStyle* aStyle) : ScaledFontBase(aUnscaledFont, aSize) , mFontFace(aFontFace) , mUseEmbeddedBitmap(aUseEmbeddedBitmap) , mForceGDIMode(aForceGDIMode) + , mParams(aParams) + , mGamma(aGamma) + , mContrast(aContrast) { - mStyle = SkFontStyle(aStyle->weight, - DWriteFontStretchFromStretch(aStyle->stretch), - aStyle->style == NS_FONT_STYLE_NORMAL ? - SkFontStyle::kUpright_Slant : SkFontStyle::kItalic_Slant); + if (aStyle) { + mStyle = SkFontStyle(aStyle->weight, + DWriteFontStretchFromStretch(aStyle->stretch), + aStyle->style == NS_FONT_STYLE_NORMAL ? + SkFontStyle::kUpright_Slant : SkFontStyle::kItalic_Slant); + } } already_AddRefed @@ -143,12 +151,12 @@ SkTypeface* ScaledFontDWrite::GetSkTypeface() { if (!mTypeface) { - IDWriteFactory *factory = DrawTargetD2D1::GetDWriteFactory(); + IDWriteFactory *factory = Factory::GetDWriteFactory(); if (!factory) { return nullptr; } - mTypeface = SkCreateTypefaceFromDWriteFont(factory, mFontFace, mStyle, mForceGDIMode); + mTypeface = SkCreateTypefaceFromDWriteFont(factory, mFontFace, mStyle, mForceGDIMode, mGamma, mContrast); } return mTypeface; } @@ -272,12 +280,34 @@ UnscaledFontDWrite::GetFontFileData(FontFileDataOutput aDataCallback, void *aBat return true; } +bool +ScaledFontDWrite::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) +{ + InstanceData instance(this); + aCb(reinterpret_cast(&instance), sizeof(instance), aBaton); + return true; +} + already_AddRefed UnscaledFontDWrite::CreateScaledFont(Float aGlyphSize, const uint8_t* aInstanceData, uint32_t aInstanceDataLength) { - RefPtr scaledFont = new ScaledFontDWrite(mFontFace, this, aGlyphSize); + if (aInstanceDataLength < sizeof(ScaledFontDWrite::InstanceData)) { + gfxWarning() << "DWrite scaled font instance data is truncated."; + return nullptr; + } + + const ScaledFontDWrite::InstanceData *instanceData = + reinterpret_cast(aInstanceData); + RefPtr scaledFont = + new ScaledFontDWrite(mFontFace, this, aGlyphSize, + instanceData->mUseEmbeddedBitmap, + instanceData->mForceGDIMode, + nullptr, + instanceData->mGamma, + instanceData->mContrast); + if (mNeedsCairo && !scaledFont->PopulateCairoScaledFont()) { gfxWarning() << "Unable to create cairo scaled font DWrite font."; return nullptr; diff --git a/gfx/2d/ScaledFontDWrite.h b/gfx/2d/ScaledFontDWrite.h index bce40f5ce77a..e7866a974fb1 100644 --- a/gfx/2d/ScaledFontDWrite.h +++ b/gfx/2d/ScaledFontDWrite.h @@ -15,6 +15,9 @@ struct gfxFontStyle; namespace mozilla { namespace gfx { +class NativeFontResourceDWrite; +class UnscaledFontDWrite; + class ScaledFontDWrite final : public ScaledFontBase { public: @@ -26,6 +29,8 @@ public: , mFontFace(aFont) , mUseEmbeddedBitmap(false) , mForceGDIMode(false) + , mGamma(2.2f) + , mContrast(1.0f) {} ScaledFontDWrite(IDWriteFontFace *aFontFace, @@ -33,7 +38,10 @@ public: Float aSize, bool aUseEmbeddedBitmap, bool aForceGDIMode, - const gfxFontStyle* aStyle); + IDWriteRenderingParams *aParams, + Float aContrast, + Float aGamma, + const gfxFontStyle* aStyle = nullptr); FontType GetType() const override { return FontType::DWRITE; } @@ -46,6 +54,8 @@ public: bool CanSerialize() override { return true; } + bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override; + AntialiasMode GetDefaultAAMode() override; bool UseEmbeddedBitmaps() { return mUseEmbeddedBitmap; } @@ -59,29 +69,39 @@ public: RefPtr mFontFace; bool mUseEmbeddedBitmap; bool mForceGDIMode; + // DrawTargetD2D1 requires the IDWriteRenderingParams, + // but we also separately need to store the gamma and contrast + // since Skia needs to be able to access these without having + // to use the full set of DWrite parameters (which would be + // required to recreate an IDWriteRenderingParams) in a + // DrawTargetRecording playback. + RefPtr mParams; + Float mGamma; + Float mContrast; protected: #ifdef USE_CAIRO_SCALED_FONT cairo_font_face_t* GetCairoFontFace() override; #endif -}; - -class GlyphRenderingOptionsDWrite : public GlyphRenderingOptions -{ -public: - MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptionsDWrite, override) - explicit GlyphRenderingOptionsDWrite(IDWriteRenderingParams *aParams) - : mParams(aParams) - { - } - - FontType GetType() const override { return FontType::DWRITE; } private: - friend class DrawTargetD2D; - friend class DrawTargetD2D1; + friend class NativeFontResourceDWrite; + friend class UnscaledFontDWrite; - RefPtr mParams; + struct InstanceData + { + InstanceData(ScaledFontDWrite* aScaledFont) + : mUseEmbeddedBitmap(aScaledFont->mUseEmbeddedBitmap) + , mForceGDIMode(aScaledFont->mForceGDIMode) + , mGamma(aScaledFont->mGamma) + , mContrast(aScaledFont->mContrast) + {} + + bool mUseEmbeddedBitmap; + bool mForceGDIMode; + Float mGamma; + Float mContrast; + }; }; } diff --git a/gfx/skia/skia/include/ports/SkTypeface_win.h b/gfx/skia/skia/include/ports/SkTypeface_win.h index cb760ae31b58..d3b5ffae4496 100644 --- a/gfx/skia/skia/include/ports/SkTypeface_win.h +++ b/gfx/skia/skia/include/ports/SkTypeface_win.h @@ -53,7 +53,9 @@ struct IDWriteFontFallback; SK_API SkTypeface* SkCreateTypefaceFromDWriteFont(IDWriteFactory* aFactory, IDWriteFontFace* aFontFace, SkFontStyle aStyle, - bool aForceGDI); + bool aForceGDI, + float aGamma, + float aContrast); SK_API sk_sp SkFontMgr_New_GDI(); SK_API sk_sp SkFontMgr_New_DirectWrite(IDWriteFactory* factory = NULL, diff --git a/gfx/skia/skia/src/ports/SkFontHost_win.cpp b/gfx/skia/skia/src/ports/SkFontHost_win.cpp index b9148027ab7f..f976e019cb38 100644 --- a/gfx/skia/skia/src/ports/SkFontHost_win.cpp +++ b/gfx/skia/skia/src/ports/SkFontHost_win.cpp @@ -341,9 +341,11 @@ SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT& origLF) { SkTypeface* SkCreateTypefaceFromDWriteFont(IDWriteFactory* aFactory, IDWriteFontFace* aFontFace, SkFontStyle aStyle, - bool aForceGDI) + bool aForceGDI, + float aGamma, + float aContrast) { - return DWriteFontTypeface::Create(aFactory, aFontFace, aStyle, aForceGDI); + return DWriteFontTypeface::Create(aFactory, aFontFace, aStyle, aForceGDI, aGamma, aContrast); } /** diff --git a/gfx/skia/skia/src/ports/SkTypeface_win_dw.cpp b/gfx/skia/skia/src/ports/SkTypeface_win_dw.cpp index 60ad429dad32..b9ea8f8834ac 100644 --- a/gfx/skia/skia/src/ports/SkTypeface_win_dw.cpp +++ b/gfx/skia/skia/src/ports/SkTypeface_win_dw.cpp @@ -251,10 +251,6 @@ SkScalerContext* DWriteFontTypeface::onCreateScalerContext(const SkScalerContext return new SkScalerContext_DW(sk_ref_sp(const_cast(this)), effects, desc); } -#ifdef MOZ_SKIA -IDWriteRenderingParams* GetDwriteRenderingParams(bool aGDI); -#endif - void DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const { if (rec->fFlags & SkScalerContext::kLCD_Vertical_Flag) { rec->fMaskFormat = SkMask::kA8_Format; @@ -288,13 +284,11 @@ void DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const { } } #elif defined(MOZ_SKIA) - IDWriteRenderingParams* params = GetDwriteRenderingParams(ForceGDI()); - SkASSERT(params); - rec->setContrast(params->GetEnhancedContrast()); + rec->setContrast(fContrast); // GDI gamma should be 2.3 // See the LUT gamma values comment for GDI fonts. - float gamma = ForceGDI() ? 2.3f : params->GetGamma(); + float gamma = ForceGDI() ? 2.3f : fGamma; rec->setDeviceGamma(gamma); rec->setPaintGamma(gamma); #endif diff --git a/gfx/skia/skia/src/ports/SkTypeface_win_dw.h b/gfx/skia/skia/src/ports/SkTypeface_win_dw.h index 035d133be772..831da779e382 100644 --- a/gfx/skia/skia/src/ports/SkTypeface_win_dw.h +++ b/gfx/skia/skia/src/ports/SkTypeface_win_dw.h @@ -53,6 +53,8 @@ private: , fDWriteFont(SkSafeRefComPtr(font)) , fDWriteFontFace(SkRefComPtr(fontFace)) , fForceGDI(false) + , fGamma(2.2f) + , fContrast(1.0f) { if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace1))) { // IUnknown::QueryInterface states that if it fails, punk will be set to nullptr. @@ -81,12 +83,16 @@ public: static DWriteFontTypeface* Create(IDWriteFactory* factory, IDWriteFontFace* fontFace, SkFontStyle aStyle, - bool aForceGDI) { + bool aForceGDI, + float aGamma, + float aContrast) { DWriteFontTypeface* typeface = new DWriteFontTypeface(aStyle, factory, fontFace, nullptr, nullptr, nullptr, nullptr); typeface->fForceGDI = aForceGDI; + typeface->fGamma = aGamma; + typeface->fContrast = aContrast; return typeface; } @@ -139,6 +145,8 @@ protected: private: typedef SkTypeface INHERITED; bool fForceGDI; + float fGamma; + float fContrast; }; #endif diff --git a/gfx/thebes/gfxDWriteCommon.cpp b/gfx/thebes/gfxDWriteCommon.cpp index 3047818bb6b1..7d4db7582da4 100644 --- a/gfx/thebes/gfxDWriteCommon.cpp +++ b/gfx/thebes/gfxDWriteCommon.cpp @@ -158,7 +158,7 @@ gfxDWriteFontFileLoader::CreateCustomFontFile(FallibleTArray& aFontData MOZ_ASSERT(aFontFile); MOZ_ASSERT(aFontFileStream); - IDWriteFactory *factory = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory(); + IDWriteFactory *factory = mozilla::gfx::Factory::GetDWriteFactory(); if (!factory) { gfxCriticalError() << "Failed to get DWrite Factory in CreateCustomFontFile."; return E_FAIL; diff --git a/gfx/thebes/gfxDWriteCommon.h b/gfx/thebes/gfxDWriteCommon.h index a355b59c672a..65c2df7bcbe4 100644 --- a/gfx/thebes/gfxDWriteCommon.h +++ b/gfx/thebes/gfxDWriteCommon.h @@ -127,7 +127,7 @@ public: { if (!mInstance) { mInstance = new gfxDWriteFontFileLoader(); - gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()-> + mozilla::gfx::Factory::GetDWriteFactory()-> RegisterFontFileLoader(mInstance); } return mInstance; diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp index 4a5bf38c8d2d..3af5739d8cca 100644 --- a/gfx/thebes/gfxDWriteFontList.cpp +++ b/gfx/thebes/gfxDWriteFontList.cpp @@ -613,7 +613,7 @@ gfxDWriteFontEntry::CreateFontFace(IDWriteFontFace **aFontFace, hr = mFont->CreateFontFace(getter_AddRefs(mFontFace)); } else if (mFontFile) { IDWriteFontFile *fontFile = mFontFile.get(); - hr = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()-> + hr = Factory::GetDWriteFactory()-> CreateFontFace(mFaceType, 1, &fontFile, @@ -644,7 +644,7 @@ gfxDWriteFontEntry::CreateFontFace(IDWriteFontFace **aFontFace, if (FAILED(mFontFace->GetFiles(&numberOfFiles, files.Elements()))) { return NS_ERROR_FAILURE; } - HRESULT hr = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()-> + HRESULT hr = Factory::GetDWriteFactory()-> CreateFontFace(mFontFace->GetType(), numberOfFiles, files.Elements(), @@ -883,7 +883,7 @@ gfxDWriteFontList::InitFontListForPlatform() mFontSubstitutes.Clear(); mNonExistingFonts.Clear(); - hr = gfxWindowsPlatform::GetPlatform()->GetDWriteFactory()-> + hr = Factory::GetDWriteFactory()-> GetGdiInterop(getter_AddRefs(mGDIInterop)); if (FAILED(hr)) { Telemetry::Accumulate(Telemetry::DWRITEFONT_INIT_PROBLEM, @@ -894,7 +894,7 @@ gfxDWriteFontList::InitFontListForPlatform() QueryPerformanceCounter(&t2); // base-class/interop initialization RefPtr factory = - gfxWindowsPlatform::GetPlatform()->GetDWriteFactory(); + Factory::GetDWriteFactory(); hr = factory->GetSystemFontCollection(getter_AddRefs(mSystemFonts)); NS_ASSERTION(SUCCEEDED(hr), "GetSystemFontCollection failed!"); @@ -1425,7 +1425,7 @@ gfxDWriteFontList::GlobalFontFallback(const uint32_t aCh, HRESULT hr; RefPtr dwFactory = - gfxWindowsPlatform::GetPlatform()->GetDWriteFactory(); + Factory::GetDWriteFactory(); if (!dwFactory) { return nullptr; } diff --git a/gfx/thebes/gfxDWriteFonts.cpp b/gfx/thebes/gfxDWriteFonts.cpp index 4db079af6927..8a83d9fe2ab2 100644 --- a/gfx/thebes/gfxDWriteFonts.cpp +++ b/gfx/thebes/gfxDWriteFonts.cpp @@ -599,19 +599,6 @@ gfxDWriteFont::GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID) return width; } -already_AddRefed -gfxDWriteFont::GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams) -{ - if (mUseClearType) { - return Factory::CreateDWriteGlyphRenderingOptions( - gfxWindowsPlatform::GetPlatform()->GetRenderingParams(GetForceGDIClassic() ? - gfxWindowsPlatform::TEXT_RENDERING_GDI_CLASSIC : gfxWindowsPlatform::TEXT_RENDERING_NORMAL)); - } else { - return Factory::CreateDWriteGlyphRenderingOptions(gfxWindowsPlatform::GetPlatform()-> - GetRenderingParams(gfxWindowsPlatform::TEXT_RENDERING_NO_CLEARTYPE)); - } -} - bool gfxDWriteFont::GetForceGDIClassic() { @@ -707,10 +694,17 @@ gfxDWriteFont::GetScaledFont(mozilla::gfx::DrawTarget *aTarget) GetUnscaledFont(), GetAdjustedSize(), GetCairoScaledFont()); - } else if (aTarget->GetBackendType() == BackendType::SKIA) { + } else { gfxDWriteFontEntry *fe = static_cast(mFontEntry.get()); bool useEmbeddedBitmap = (fe->IsCJKFont() && HasBitmapStrikeForSize(NS_lround(mAdjustedSize))); + bool forceGDI = GetForceGDIClassic(); + + IDWriteRenderingParams* params = gfxWindowsPlatform::GetPlatform()->GetRenderingParams( + mUseClearType ? + (forceGDI ? + gfxWindowsPlatform::TEXT_RENDERING_GDI_CLASSIC : gfxWindowsPlatform::TEXT_RENDERING_NORMAL) : + gfxWindowsPlatform::TEXT_RENDERING_NO_CLEARTYPE); const gfxFontStyle* fontStyle = GetStyle(); mAzureScaledFont = @@ -718,11 +712,10 @@ gfxDWriteFont::GetScaledFont(mozilla::gfx::DrawTarget *aTarget) GetUnscaledFont(), GetAdjustedSize(), useEmbeddedBitmap, - GetForceGDIClassic()); - } else { - mAzureScaledFont = Factory::CreateScaledFontForNativeFont(nativeFont, - GetUnscaledFont(), - GetAdjustedSize()); + forceGDI, + params, + params->GetGamma(), + params->GetEnhancedContrast()); } mAzureScaledFontIsCairo = wantCairo; diff --git a/gfx/thebes/gfxDWriteFonts.h b/gfx/thebes/gfxDWriteFonts.h index 16d75b84fbee..76b8bba4b523 100644 --- a/gfx/thebes/gfxDWriteFonts.h +++ b/gfx/thebes/gfxDWriteFonts.h @@ -61,9 +61,6 @@ public: virtual int32_t GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID) override; - virtual already_AddRefed - GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams = nullptr) override; - virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf, FontCacheSizes* aSizes) const override; virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index ebac024fd6bd..4d5080f6c8b4 100755 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -80,14 +80,6 @@ using namespace mozilla::layers; using namespace mozilla::widget; using namespace mozilla::image; -IDWriteRenderingParams* GetDwriteRenderingParams(bool aGDI) -{ - gfxWindowsPlatform::TextRenderingMode mode = aGDI ? - gfxWindowsPlatform::TEXT_RENDERING_GDI_CLASSIC : - gfxWindowsPlatform::TEXT_RENDERING_NORMAL; - return gfxWindowsPlatform::GetPlatform()->GetRenderingParams(mode); -} - DCFromDrawTarget::DCFromDrawTarget(DrawTarget& aDrawTarget) { mDC = nullptr; @@ -363,7 +355,7 @@ gfxWindowsPlatform::InitAcceleration() UpdateRenderMode(); // If we have Skia and we didn't init dwrite already, do it now. - if (!mDWriteFactory && GetDefaultContentBackend() == BackendType::SKIA) { + if (!DWriteAvailable() && GetDefaultContentBackend() == BackendType::SKIA) { InitDWriteSupport(); } @@ -389,26 +381,10 @@ bool gfxWindowsPlatform::InitDWriteSupport() { mozilla::ScopedGfxFeatureReporter reporter("DWrite"); - decltype(DWriteCreateFactory)* createDWriteFactory = (decltype(DWriteCreateFactory)*) - GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory"); - if (!createDWriteFactory) { + if (!Factory::EnsureDWriteFactory()) { return false; } - // I need a direct pointer to be able to cast to IUnknown**, I also need to - // remember to release this because the nsRefPtr will AddRef it. - RefPtr factory; - HRESULT hr = createDWriteFactory( - DWRITE_FACTORY_TYPE_SHARED, - __uuidof(IDWriteFactory), - (IUnknown **)((IDWriteFactory **)getter_AddRefs(factory))); - if (FAILED(hr) || !factory) { - return false; - } - - mDWriteFactory = factory; - Factory::SetDWriteFactory(mDWriteFactory); - SetupClearTypeParams(); reporter.SetSuccessful(); return true; @@ -515,7 +491,7 @@ gfxWindowsPlatform::CreatePlatformFontList() // bug 630201 - older pre-RTM versions of Direct2D/DirectWrite cause odd // crashers so blacklist them altogether - if (IsNotWin7PreRTM() && GetDWriteFactory()) { + if (IsNotWin7PreRTM() && DWriteAvailable()) { pfl = new gfxDWriteFontList(); if (NS_SUCCEEDED(pfl->InitFontList())) { return pfl; @@ -579,22 +555,7 @@ already_AddRefed gfxWindowsPlatform::GetScaledFontForFont(DrawTarget* aTarget, gfxFont *aFont) { if (aFont->GetType() == gfxFont::FONT_TYPE_DWRITE) { - gfxDWriteFont *font = static_cast(aFont); - - NativeFont nativeFont; - nativeFont.mType = NativeFontType::DWRITE_FONT_FACE; - nativeFont.mFont = font->GetFontFace(); - - if (aTarget->GetBackendType() == BackendType::CAIRO) { - return Factory::CreateScaledFontWithCairo(nativeFont, - font->GetUnscaledFont(), - font->GetAdjustedSize(), - font->GetCairoScaledFont()); - } - - return Factory::CreateScaledFontForNativeFont(nativeFont, - font->GetUnscaledFont(), - font->GetAdjustedSize()); + return aFont->GetScaledFont(aTarget); } NS_ASSERTION(aFont->GetType() == gfxFont::FONT_TYPE_GDI, @@ -1142,7 +1103,7 @@ gfxWindowsPlatform::FontsPrefsChanged(const char *aPref) void gfxWindowsPlatform::SetupClearTypeParams() { - if (GetDWriteFactory()) { + if (DWriteAvailable()) { // any missing prefs will default to invalid (-1) and be ignored; // out-of-range values will also be ignored FLOAT gamma = -1.0; @@ -1197,7 +1158,7 @@ gfxWindowsPlatform::SetupClearTypeParams() } RefPtr defaultRenderingParams; - GetDWriteFactory()->CreateRenderingParams(getter_AddRefs(defaultRenderingParams)); + Factory::GetDWriteFactory()->CreateRenderingParams(getter_AddRefs(defaultRenderingParams)); // For EnhancedContrast, we override the default if the user has not set it // in the registry (by using the ClearType Tuner). if (contrast < 0.0 || contrast > 10.0) { @@ -1253,14 +1214,14 @@ gfxWindowsPlatform::SetupClearTypeParams() mRenderingParams[TEXT_RENDERING_NO_CLEARTYPE] = defaultRenderingParams; - HRESULT hr = GetDWriteFactory()->CreateCustomRenderingParams( + HRESULT hr = Factory::GetDWriteFactory()->CreateCustomRenderingParams( gamma, contrast, level, dwriteGeometry, renderMode, getter_AddRefs(mRenderingParams[TEXT_RENDERING_NORMAL])); if (FAILED(hr) || !mRenderingParams[TEXT_RENDERING_NORMAL]) { mRenderingParams[TEXT_RENDERING_NORMAL] = defaultRenderingParams; } - hr = GetDWriteFactory()->CreateCustomRenderingParams( + hr = Factory::GetDWriteFactory()->CreateCustomRenderingParams( gamma, contrast, level, dwriteGeometry, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC, getter_AddRefs(mRenderingParams[TEXT_RENDERING_GDI_CLASSIC])); @@ -1565,7 +1526,7 @@ gfxWindowsPlatform::InitializeD2D() } // Using Direct2D depends on DWrite support. - if (!mDWriteFactory && !InitDWriteSupport()) { + if (!DWriteAvailable() && !InitDWriteSupport()) { d2d1.SetFailed(FeatureStatus::Failed, "Failed to initialize DirectWrite support", NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_DWRITE")); return; diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h index aaed607b683f..12f637842379 100644 --- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -192,8 +192,7 @@ public: void SetupClearTypeParams(); - IDWriteFactory *GetDWriteFactory() { return mDWriteFactory; } - inline bool DWriteEnabled() { return !!mDWriteFactory; } + inline bool DWriteAvailable() const { return !!mozilla::gfx::Factory::GetDWriteFactory(); } inline DWRITE_MEASURING_MODE DWriteMeasuringMode() { return mMeasuringMode; } IDWriteRenderingParams *GetRenderingParams(TextRenderingMode aRenderMode) @@ -259,7 +258,6 @@ private: void InitializeD2DConfig(); void InitializeDirectDrawConfig(); - RefPtr mDWriteFactory; RefPtr mRenderingParams[TEXT_RENDERING_COUNT]; DWRITE_MEASURING_MODE mMeasuringMode; diff --git a/layout/printing/PrintTranslator.cpp b/layout/printing/PrintTranslator.cpp index 0bda505bae69..a2f1f5cbf7b5 100644 --- a/layout/printing/PrintTranslator.cpp +++ b/layout/printing/PrintTranslator.cpp @@ -83,20 +83,5 @@ PrintTranslator::CreateDrawTarget(ReferencePtr aRefPtr, return drawTarget.forget(); } -FontType -PrintTranslator::GetDesiredFontType() -{ - switch (mBaseDT->GetBackendType()) { - case BackendType::DIRECT2D: - return FontType::DWRITE; - case BackendType::CAIRO: - return FontType::CAIRO; - case BackendType::SKIA: - return FontType::SKIA; - default: - return FontType::CAIRO; - } -} - } // namespace layout } // namespace mozilla diff --git a/layout/printing/PrintTranslator.h b/layout/printing/PrintTranslator.h index 96f68b78098e..4558518ab74e 100644 --- a/layout/printing/PrintTranslator.h +++ b/layout/printing/PrintTranslator.h @@ -175,8 +175,6 @@ public: mozilla::gfx::DrawTarget* GetReferenceDrawTarget() final { return mBaseDT; } - mozilla::gfx::FontType GetDesiredFontType() final; - private: RefPtr mDeviceContext; RefPtr mBaseDT;