From cdd3b6302617388e564492ddcffc5862b58964a8 Mon Sep 17 00:00:00 2001 From: Edwin Flores Date: Fri, 22 Apr 2016 13:23:25 +0100 Subject: [PATCH] Bug 1256678 - Fall back to loading GDI fonts from system in DrawTargetRecording - r=bas --- gfx/2d/2D.h | 3 ++ gfx/2d/DrawTargetRecording.cpp | 11 ++++++ gfx/2d/RecordedEvent.cpp | 64 ++++++++++++++++++++++++++++++++++ gfx/2d/RecordedEvent.h | 46 ++++++++++++++++++++++++ gfx/2d/ScaledFontWin.cpp | 7 ++++ gfx/2d/ScaledFontWin.h | 2 ++ 6 files changed, 133 insertions(+) diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h index 7de9e4fcc1dc..98b4903bb6dd 100644 --- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -645,6 +645,7 @@ public: virtual ~ScaledFont() {} typedef void (*FontFileDataOutput)(const uint8_t *aData, uint32_t aLength, uint32_t aIndex, Float aGlyphSize, void *aBaton); + typedef void (*FontDescriptorOutput)(const uint8_t *aData, uint32_t aLength, Float aFontSize, void *aBaton); virtual FontType GetType() const = 0; @@ -664,6 +665,8 @@ public: virtual bool GetFontFileData(FontFileDataOutput, void *) { return false; } + virtual bool GetFontDescriptor(FontDescriptorOutput, void *) { return false; } + void AddUserData(UserDataKey *key, void *userData, void (*destroy)(void*)) { mUserData.Add(key, userData, destroy); } diff --git a/gfx/2d/DrawTargetRecording.cpp b/gfx/2d/DrawTargetRecording.cpp index 84f3764271c9..6d72f82d4a9d 100644 --- a/gfx/2d/DrawTargetRecording.cpp +++ b/gfx/2d/DrawTargetRecording.cpp @@ -395,11 +395,22 @@ DrawTargetRecording::FillGlyphs(ScaledFont *aFont, RecordedFontData fontData(aFont); RecordedFontDetails fontDetails; if (fontData.GetFontDetails(fontDetails)) { + // Try to serialise the whole font, just in case this is a web font that + // is not present on the system. if (!mRecorder->HasStoredFontData(fontDetails.fontDataKey)) { mRecorder->RecordEvent(fontData); mRecorder->AddStoredFontData(fontDetails.fontDataKey); } mRecorder->RecordEvent(RecordedScaledFontCreation(aFont, fontDetails)); + } else { + // If that fails, record just the font description and try to load it from + // the system on the other side. + RecordedFontDescriptor fontDesc(aFont); + if (fontDesc.IsValid()) { + mRecorder->RecordEvent(fontDesc); + } else { + gfxWarning() << "DrawTargetRecording::FillGlyphs failed to serialise ScaledFont"; + } } #endif RecordingFontUserData *userData = new RecordingFontUserData; diff --git a/gfx/2d/RecordedEvent.cpp b/gfx/2d/RecordedEvent.cpp index b0e5d0853a7e..3c4ca7e60692 100644 --- a/gfx/2d/RecordedEvent.cpp +++ b/gfx/2d/RecordedEvent.cpp @@ -10,6 +10,7 @@ #include "Tools.h" #include "Filters.h" #include "Logging.h" +#include "ScaledFontBase.h" #include "SFNTData.h" namespace mozilla { @@ -80,6 +81,7 @@ RecordedEvent::LoadEventFromStream(std::istream &aStream, EventType aType) LOAD_EVENT_TYPE(FILTERNODESETINPUT, RecordedFilterNodeSetInput); LOAD_EVENT_TYPE(CREATESIMILARDRAWTARGET, RecordedCreateSimilarDrawTarget); LOAD_EVENT_TYPE(FONTDATA, RecordedFontData); + LOAD_EVENT_TYPE(FONTDESC, RecordedFontDescriptor); LOAD_EVENT_TYPE(PUSHLAYER, RecordedPushLayer); LOAD_EVENT_TYPE(POPLAYER, RecordedPopLayer); default: @@ -159,6 +161,8 @@ RecordedEvent::GetEventName(EventType aType) return "CreateSimilarDrawTarget"; case FONTDATA: return "FontData"; + case FONTDESC: + return "FontDescriptor"; case PUSHLAYER: return "PushLayer"; case POPLAYER: @@ -1523,6 +1527,66 @@ RecordedFontData::RecordedFontData(istream &aStream) aStream.read((char*)mData, mFontDetails.size); } +RecordedFontDescriptor::~RecordedFontDescriptor() +{ +} + +void +RecordedFontDescriptor::PlayEvent(Translator *aTranslator) const +{ + MOZ_ASSERT(mType == FontType::GDI); + + NativeFont nativeFont; + nativeFont.mType = (NativeFontType)mType; + nativeFont.mFont = (void*)&mData[0]; + + RefPtr font = + Factory::CreateScaledFontForNativeFont(nativeFont, mFontSize); + +#ifdef USE_CAIRO_SCALED_FONT + static_cast(font.get())->PopulateCairoScaledFont(); +#endif + + aTranslator->AddScaledFont(mRefPtr, font); +} + +void +RecordedFontDescriptor::RecordToStream(std::ostream &aStream) const +{ + MOZ_ASSERT(mHasDesc); + WriteElement(aStream, mType); + WriteElement(aStream, mFontSize); + WriteElement(aStream, mRefPtr); + WriteElement(aStream, (size_t)mData.size()); + aStream.write((char*)&mData[0], mData.size()); +} + +void +RecordedFontDescriptor::OutputSimpleEventInfo(stringstream &aStringStream) const +{ + aStringStream << "[" << mRefPtr << "] Font Descriptor"; +} + +void +RecordedFontDescriptor::SetFontDescriptor(const uint8_t* aData, uint32_t aSize, Float aFontSize) +{ + mData.assign(aData, aData + aSize); + mFontSize = aFontSize; +} + +RecordedFontDescriptor::RecordedFontDescriptor(istream &aStream) + : RecordedEvent(FONTDATA) +{ + ReadElement(aStream, mType); + ReadElement(aStream, mFontSize); + ReadElement(aStream, mRefPtr); + + size_t size; + ReadElement(aStream, size); + mData.resize(size); + aStream.read((char*)&mData[0], size); +} + void RecordedScaledFontCreation::PlayEvent(Translator *aTranslator) const { diff --git a/gfx/2d/RecordedEvent.h b/gfx/2d/RecordedEvent.h index 0debe6427712..e4eabe1f0411 100644 --- a/gfx/2d/RecordedEvent.h +++ b/gfx/2d/RecordedEvent.h @@ -192,6 +192,7 @@ public: FILTERNODESETINPUT, CREATESIMILARDRAWTARGET, FONTDATA, + FONTDESC, PUSHLAYER, POPLAYER, }; @@ -1042,6 +1043,51 @@ private: MOZ_IMPLICIT RecordedFontData(std::istream &aStream); }; +class RecordedFontDescriptor : public RecordedEvent { +public: + + static void FontDescCb(const uint8_t *aData, uint32_t aSize, + Float aFontSize, void* aBaton) + { + auto recordedFontDesc = static_cast(aBaton); + recordedFontDesc->SetFontDescriptor(aData, aSize, aFontSize); + } + + explicit RecordedFontDescriptor(ScaledFont* aScaledFont) + : RecordedEvent(FONTDESC) + , mType(aScaledFont->GetType()) + , mRefPtr(aScaledFont) + { + mHasDesc = aScaledFont->GetFontDescriptor(FontDescCb, this); + } + + ~RecordedFontDescriptor(); + + bool IsValid() const { return mHasDesc; } + + virtual void PlayEvent(Translator *aTranslator) const; + + virtual void RecordToStream(std::ostream &aStream) const; + virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const; + + virtual std::string GetName() const { return "Font Desc"; } + virtual ReferencePtr GetObjectRef() const { return mRefPtr; } + +private: + friend class RecordedEvent; + + void SetFontDescriptor(const uint8_t* aData, uint32_t aSize, Float aFontSize); + + bool mHasDesc; + + FontType mType; + Float mFontSize; + std::vector mData; + ReferencePtr mRefPtr; + + MOZ_IMPLICIT RecordedFontDescriptor(std::istream &aStream); +}; + class RecordedScaledFontCreation : public RecordedEvent { public: diff --git a/gfx/2d/ScaledFontWin.cpp b/gfx/2d/ScaledFontWin.cpp index c3cb6a4f53ab..1fedebe63822 100644 --- a/gfx/2d/ScaledFontWin.cpp +++ b/gfx/2d/ScaledFontWin.cpp @@ -75,6 +75,13 @@ ScaledFontWin::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton) return true; } +bool +ScaledFontWin::GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton) +{ + aCb(reinterpret_cast(&mLogFont), sizeof(mLogFont), mSize, aBaton); + return true; +} + #ifdef USE_SKIA SkTypeface* ScaledFontWin::GetSkTypeface() { diff --git a/gfx/2d/ScaledFontWin.h b/gfx/2d/ScaledFontWin.h index d7c00695df04..e5b55d630a5f 100644 --- a/gfx/2d/ScaledFontWin.h +++ b/gfx/2d/ScaledFontWin.h @@ -21,6 +21,8 @@ public: bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton) override; + virtual bool GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton) override; + #ifdef USE_SKIA virtual SkTypeface* GetSkTypeface(); #endif