mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
Bug 1355931 - move font serialization from ScaledFont to UnscaledFont. r=jrmuizel
MozReview-Commit-ID: 3d1XMoe2BKj
This commit is contained in:
parent
a363fb8c8b
commit
28471864af
68
gfx/2d/2D.h
68
gfx/2d/2D.h
@ -63,6 +63,7 @@ namespace mozilla {
|
||||
|
||||
namespace gfx {
|
||||
|
||||
class ScaledFont;
|
||||
class SourceSurface;
|
||||
class DataSourceSurface;
|
||||
class DrawTarget;
|
||||
@ -711,6 +712,25 @@ public:
|
||||
|
||||
static uint32_t DeletionCounter() { return sDeletionCounter; }
|
||||
|
||||
typedef void (*FontFileDataOutput)(const uint8_t *aData, uint32_t aLength, uint32_t aIndex,
|
||||
void *aBaton);
|
||||
typedef void (*FontInstanceDataOutput)(const uint8_t* aData, uint32_t aLength, void* aBaton);
|
||||
typedef void (*FontDescriptorOutput)(const uint8_t* aData, uint32_t aLength, void* aBaton);
|
||||
|
||||
virtual bool GetFontFileData(FontFileDataOutput, void *) { return false; }
|
||||
|
||||
virtual bool GetFontInstanceData(FontInstanceDataOutput, void *) { return false; }
|
||||
|
||||
virtual bool GetFontDescriptor(FontDescriptorOutput, void *) { return false; }
|
||||
|
||||
virtual already_AddRefed<ScaledFont>
|
||||
CreateScaledFont(Float aGlyphSize,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
UnscaledFont() {}
|
||||
|
||||
@ -728,17 +748,6 @@ public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFont)
|
||||
virtual ~ScaledFont() {}
|
||||
|
||||
typedef struct {
|
||||
uint32_t mTag;
|
||||
Float mValue;
|
||||
} VariationSetting;
|
||||
|
||||
typedef void (*FontFileDataOutput)(const uint8_t *aData, uint32_t aLength, uint32_t aIndex, Float aGlyphSize,
|
||||
uint32_t aVariationCount, const VariationSetting* aVariations,
|
||||
void *aBaton);
|
||||
typedef void (*FontInstanceDataOutput)(const uint8_t* aData, uint32_t aLength, void* aBaton);
|
||||
typedef void (*FontDescriptorOutput)(const uint8_t* aData, uint32_t aLength, Float aFontSize, void* aBaton);
|
||||
|
||||
virtual FontType GetType() const = 0;
|
||||
virtual Float GetSize() const = 0;
|
||||
virtual AntialiasMode GetDefaultAAMode();
|
||||
@ -761,12 +770,15 @@ public:
|
||||
*/
|
||||
virtual void GetGlyphDesignMetrics(const uint16_t* aGlyphIndices, uint32_t aNumGlyphs, GlyphMetrics* aGlyphMetrics) = 0;
|
||||
|
||||
virtual bool GetFontFileData(FontFileDataOutput, void *) { return false; }
|
||||
struct VariationSetting {
|
||||
uint32_t mTag;
|
||||
float mValue;
|
||||
};
|
||||
|
||||
typedef void (*FontInstanceDataOutput)(const uint8_t* aData, uint32_t aLength, void* aBaton);
|
||||
|
||||
virtual bool GetFontInstanceData(FontInstanceDataOutput, void *) { return false; }
|
||||
|
||||
virtual bool GetFontDescriptor(FontDescriptorOutput, void *) { return false; }
|
||||
|
||||
virtual bool CanSerialize() { return false; }
|
||||
|
||||
void AddUserData(UserDataKey *key, void *userData, void (*destroy)(void*)) {
|
||||
@ -797,20 +809,19 @@ public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(NativeFontResource)
|
||||
|
||||
/**
|
||||
* Creates a ScaledFont using the font corresponding to the index and
|
||||
* the given glyph size.
|
||||
* Creates a UnscaledFont using the font corresponding to the index.
|
||||
*
|
||||
* @param aIndex index for the font within the resource.
|
||||
* @param aGlyphSize the size of ScaledFont required.
|
||||
* @param aInstanceData pointer to read-only buffer of any available instance data.
|
||||
* @param aInstanceDataLength the size of the instance data.
|
||||
* @return an already_addrefed ScaledFont, containing nullptr if failed.
|
||||
* @return an already_addrefed UnscaledFont, containing nullptr if failed.
|
||||
*/
|
||||
virtual already_AddRefed<ScaledFont>
|
||||
CreateScaledFont(uint32_t aIndex, Float aGlyphSize,
|
||||
const uint8_t* aInstanceData, uint32_t aInstanceDataLength) = 0;
|
||||
virtual already_AddRefed<UnscaledFont>
|
||||
CreateUnscaledFont(uint32_t aIndex,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength) = 0;
|
||||
|
||||
virtual ~NativeFontResource() {};
|
||||
virtual ~NativeFontResource() {}
|
||||
};
|
||||
|
||||
/** This class is designed to allow passing additional glyph rendering
|
||||
@ -1469,23 +1480,18 @@ public:
|
||||
*
|
||||
* @param aData Pointer to the data
|
||||
* @param aSize Size of the TrueType data
|
||||
* @param aVariationCount Number of VariationSetting records provided.
|
||||
* @param aVariations Pointer to VariationSetting records.
|
||||
* @param aType Type of NativeFontResource that should be created.
|
||||
* @return a NativeFontResource of nullptr if failed.
|
||||
*/
|
||||
static already_AddRefed<NativeFontResource>
|
||||
CreateNativeFontResource(uint8_t *aData, uint32_t aSize,
|
||||
uint32_t aVariationCount,
|
||||
const ScaledFont::VariationSetting* aVariations,
|
||||
FontType aType);
|
||||
CreateNativeFontResource(uint8_t *aData, uint32_t aSize, FontType aType);
|
||||
|
||||
/**
|
||||
* This creates a scaled font of the given type based on font descriptor
|
||||
* This creates an unscaled font of the given type based on font descriptor
|
||||
* data retrieved from ScaledFont::GetFontDescriptor.
|
||||
*/
|
||||
static already_AddRefed<ScaledFont>
|
||||
CreateScaledFontFromFontDescriptor(FontType aType, const uint8_t* aData, uint32_t aDataLength, Float aSize);
|
||||
static already_AddRefed<UnscaledFont>
|
||||
CreateUnscaledFontFromFontDescriptor(FontType aType, const uint8_t* aData, uint32_t aDataLength);
|
||||
|
||||
/**
|
||||
* This creates a scaled font with an associated cairo_scaled_font_t, and
|
||||
|
@ -388,8 +388,11 @@ DrawTargetRecording::FillGlyphs(ScaledFont *aFont,
|
||||
{
|
||||
EnsurePatternDependenciesStored(aPattern);
|
||||
|
||||
if (!aFont->GetUserData(reinterpret_cast<UserDataKey*>(mRecorder.get()))) {
|
||||
RecordedFontData fontData(aFont);
|
||||
UserDataKey* userDataKey = reinterpret_cast<UserDataKey*>(mRecorder.get());
|
||||
if (!aFont->GetUserData(userDataKey)) {
|
||||
UnscaledFont* unscaledFont = aFont->GetUnscaledFont();
|
||||
if (!mRecorder->HasStoredObject(unscaledFont)) {
|
||||
RecordedFontData fontData(unscaledFont);
|
||||
RecordedFontDetails fontDetails;
|
||||
if (fontData.GetFontDetails(fontDetails)) {
|
||||
// Try to serialise the whole font, just in case this is a web font that
|
||||
@ -398,22 +401,26 @@ DrawTargetRecording::FillGlyphs(ScaledFont *aFont,
|
||||
mRecorder->RecordEvent(fontData);
|
||||
mRecorder->AddStoredFontData(fontDetails.fontDataKey);
|
||||
}
|
||||
mRecorder->RecordEvent(RecordedScaledFontCreation(aFont, fontDetails));
|
||||
mRecorder->RecordEvent(RecordedUnscaledFontCreation(unscaledFont, 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);
|
||||
RecordedFontDescriptor fontDesc(unscaledFont);
|
||||
if (fontDesc.IsValid()) {
|
||||
mRecorder->RecordEvent(fontDesc);
|
||||
} else {
|
||||
gfxWarning() << "DrawTargetRecording::FillGlyphs failed to serialise ScaledFont";
|
||||
gfxWarning() << "DrawTargetRecording::FillGlyphs failed to serialise UnscaledFont";
|
||||
}
|
||||
}
|
||||
mRecorder->AddStoredObject(unscaledFont);
|
||||
}
|
||||
|
||||
mRecorder->RecordEvent(RecordedScaledFontCreation(aFont, unscaledFont));
|
||||
|
||||
RecordingFontUserData *userData = new RecordingFontUserData;
|
||||
userData->refPtr = aFont;
|
||||
userData->recorder = mRecorder;
|
||||
aFont->AddUserData(reinterpret_cast<UserDataKey*>(mRecorder.get()), userData,
|
||||
&RecordingFontUserDataDestroyFunc);
|
||||
aFont->AddUserData(userDataKey, userData, &RecordingFontUserDataDestroyFunc);
|
||||
}
|
||||
|
||||
mRecorder->RecordEvent(RecordedFillGlyphs(this, aFont, aPattern, aOptions, aBuffer.mGlyphs, aBuffer.mNumGlyphs));
|
||||
|
@ -24,6 +24,7 @@
|
||||
#if defined(WIN32)
|
||||
#include "ScaledFontWin.h"
|
||||
#include "NativeFontResourceGDI.h"
|
||||
#include "UnscaledFontGDI.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_DARWIN
|
||||
@ -34,6 +35,7 @@
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#include "ScaledFontFontconfig.h"
|
||||
#include "NativeFontResourceFontconfig.h"
|
||||
#include "UnscaledFontFreeType.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
@ -505,10 +507,7 @@ Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont,
|
||||
}
|
||||
|
||||
already_AddRefed<NativeFontResource>
|
||||
Factory::CreateNativeFontResource(uint8_t *aData, uint32_t aSize,
|
||||
uint32_t aVariationCount,
|
||||
const ScaledFont::VariationSetting* aVariations,
|
||||
FontType aType)
|
||||
Factory::CreateNativeFontResource(uint8_t *aData, uint32_t aSize, FontType aType)
|
||||
{
|
||||
switch (aType) {
|
||||
#ifdef WIN32
|
||||
@ -528,12 +527,10 @@ Factory::CreateNativeFontResource(uint8_t *aData, uint32_t aSize,
|
||||
return NativeFontResourceDWrite::Create(aData, aSize,
|
||||
/* aNeedsCairo = */ true);
|
||||
} else {
|
||||
return NativeFontResourceGDI::Create(aData, aSize,
|
||||
/* aNeedsCairo = */ true);
|
||||
return NativeFontResourceGDI::Create(aData, aSize);
|
||||
}
|
||||
#elif defined(XP_DARWIN)
|
||||
return NativeFontResourceMac::Create(aData, aSize,
|
||||
aVariationCount, aVariations);
|
||||
return NativeFontResourceMac::Create(aData, aSize);
|
||||
#elif defined(MOZ_WIDGET_GTK)
|
||||
return NativeFontResourceFontconfig::Create(aData, aSize);
|
||||
#else
|
||||
@ -547,20 +544,20 @@ Factory::CreateNativeFontResource(uint8_t *aData, uint32_t aSize,
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
Factory::CreateScaledFontFromFontDescriptor(FontType aType, const uint8_t* aData, uint32_t aDataLength, Float aSize)
|
||||
already_AddRefed<UnscaledFont>
|
||||
Factory::CreateUnscaledFontFromFontDescriptor(FontType aType, const uint8_t* aData, uint32_t aDataLength)
|
||||
{
|
||||
switch (aType) {
|
||||
#ifdef WIN32
|
||||
case FontType::GDI:
|
||||
return ScaledFontWin::CreateFromFontDescriptor(aData, aDataLength, aSize);
|
||||
return UnscaledFontGDI::CreateFromFontDescriptor(aData, aDataLength);
|
||||
#endif
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
case FontType::FONTCONFIG:
|
||||
return ScaledFontFontconfig::CreateFromFontDescriptor(aData, aDataLength, aSize);
|
||||
return UnscaledFontFontconfig::CreateFromFontDescriptor(aData, aDataLength);
|
||||
#endif
|
||||
default:
|
||||
gfxWarning() << "Invalid type specified for ScaledFont font descriptor";
|
||||
gfxWarning() << "Invalid type specified for UnscaledFont font descriptor";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -131,6 +131,7 @@ enum class LogReason : int {
|
||||
ProcessingError,
|
||||
InvalidDrawTarget,
|
||||
NativeFontResourceNotFound,
|
||||
UnscaledFontNotFound,
|
||||
// End
|
||||
MustBeLessThanThis = 101,
|
||||
};
|
||||
|
@ -5,6 +5,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "NativeFontResourceDWrite.h"
|
||||
#include "UnscaledFontDWrite.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
@ -258,9 +259,10 @@ NativeFontResourceDWrite::Create(uint8_t *aFontData, uint32_t aDataLength,
|
||||
return fontResource.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
NativeFontResourceDWrite::CreateScaledFont(uint32_t aIndex, Float aGlyphSize,
|
||||
const uint8_t* aInstanceData, uint32_t aInstanceDataLength)
|
||||
already_AddRefed<UnscaledFont>
|
||||
NativeFontResourceDWrite::CreateUnscaledFont(uint32_t aIndex,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength)
|
||||
{
|
||||
if (aIndex >= mNumberOfFaces) {
|
||||
gfxWarning() << "Font face index is too high for font resource.";
|
||||
@ -275,13 +277,12 @@ NativeFontResourceDWrite::CreateScaledFont(uint32_t aIndex, Float aGlyphSize,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ScaledFontBase> scaledFont = new ScaledFontDWrite(fontFace, nullptr, aGlyphSize);
|
||||
if (mNeedsCairo && !scaledFont->PopulateCairoScaledFont()) {
|
||||
gfxWarning() << "Unable to create cairo scaled font DWrite font.";
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<UnscaledFont> unscaledFont =
|
||||
new UnscaledFontDWrite(fontFace,
|
||||
DWRITE_FONT_SIMULATIONS_NONE,
|
||||
mNeedsCairo);
|
||||
|
||||
return scaledFont.forget();
|
||||
return unscaledFont.forget();
|
||||
}
|
||||
|
||||
} // gfx
|
||||
|
@ -31,9 +31,10 @@ public:
|
||||
static already_AddRefed<NativeFontResourceDWrite>
|
||||
Create(uint8_t *aFontData, uint32_t aDataLength, bool aNeedsCairo);
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
CreateScaledFont(uint32_t aIndex, Float aGlyphSize,
|
||||
const uint8_t* aInstanceData, uint32_t aInstanceDataLength) final;
|
||||
already_AddRefed<UnscaledFont>
|
||||
CreateUnscaledFont(uint32_t aIndex,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength) final;
|
||||
|
||||
private:
|
||||
NativeFontResourceDWrite(IDWriteFactory *aFactory,
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "NativeFontResourceFontconfig.h"
|
||||
#include "ScaledFontFontconfig.h"
|
||||
#include "UnscaledFontFreeType.h"
|
||||
#include "Logging.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -48,17 +49,12 @@ NativeFontResourceFontconfig::Create(uint8_t *aFontData, uint32_t aDataLength)
|
||||
return resource.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
NativeFontResourceFontconfig::CreateScaledFont(uint32_t aIndex, Float aGlyphSize,
|
||||
already_AddRefed<UnscaledFont>
|
||||
NativeFontResourceFontconfig::CreateUnscaledFont(uint32_t aIndex,
|
||||
const uint8_t* aInstanceData, uint32_t aInstanceDataLength)
|
||||
{
|
||||
if (aInstanceDataLength < sizeof(ScaledFontFontconfig::InstanceData)) {
|
||||
gfxWarning() << "Fontconfig scaled font instance data is truncated.";
|
||||
return nullptr;
|
||||
}
|
||||
return ScaledFontFontconfig::CreateFromInstanceData(
|
||||
*reinterpret_cast<const ScaledFontFontconfig::InstanceData*>(aInstanceData),
|
||||
mFace, nullptr, 0, aGlyphSize);
|
||||
RefPtr<UnscaledFont> unscaledFont = new UnscaledFontFontconfig(mFace);
|
||||
return unscaledFont.forget();
|
||||
}
|
||||
|
||||
} // gfx
|
||||
|
@ -23,8 +23,8 @@ public:
|
||||
static already_AddRefed<NativeFontResourceFontconfig>
|
||||
Create(uint8_t *aFontData, uint32_t aDataLength);
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
CreateScaledFont(uint32_t aIndex, Float aGlyphSize,
|
||||
already_AddRefed<UnscaledFont>
|
||||
CreateUnscaledFont(uint32_t aIndex,
|
||||
const uint8_t* aInstanceData, uint32_t aInstanceDataLength) final;
|
||||
|
||||
~NativeFontResourceFontconfig();
|
||||
|
@ -9,14 +9,14 @@
|
||||
#include "Logging.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "ScaledFontWin.h"
|
||||
#include "UnscaledFontGDI.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
/* static */
|
||||
already_AddRefed<NativeFontResourceGDI>
|
||||
NativeFontResourceGDI::Create(uint8_t *aFontData, uint32_t aDataLength,
|
||||
bool aNeedsCairo)
|
||||
NativeFontResourceGDI::Create(uint8_t *aFontData, uint32_t aDataLength)
|
||||
{
|
||||
DWORD numberOfFontsAdded;
|
||||
HANDLE fontResourceHandle = ::AddFontMemResourceEx(aFontData, aDataLength,
|
||||
@ -27,7 +27,7 @@ NativeFontResourceGDI::Create(uint8_t *aFontData, uint32_t aDataLength,
|
||||
}
|
||||
|
||||
RefPtr<NativeFontResourceGDI> fontResouce =
|
||||
new NativeFontResourceGDI(fontResourceHandle, aNeedsCairo);
|
||||
new NativeFontResourceGDI(fontResourceHandle);
|
||||
|
||||
return fontResouce.forget();
|
||||
}
|
||||
@ -37,26 +37,19 @@ NativeFontResourceGDI::~NativeFontResourceGDI()
|
||||
::RemoveFontMemResourceEx(mFontResourceHandle);
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
NativeFontResourceGDI::CreateScaledFont(uint32_t aIndex, Float aGlyphSize,
|
||||
const uint8_t* aInstanceData, uint32_t aInstanceDataLength)
|
||||
already_AddRefed<UnscaledFont>
|
||||
NativeFontResourceGDI::CreateUnscaledFont(uint32_t aIndex,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength)
|
||||
{
|
||||
if (aInstanceDataLength < sizeof(LOGFONT)) {
|
||||
gfxWarning() << "GDI scaled font instance data is truncated.";
|
||||
gfxWarning() << "GDI unscaled font instance data is truncated.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const LOGFONT* logFont = reinterpret_cast<const LOGFONT*>(aInstanceData);
|
||||
|
||||
// Constructor for ScaledFontWin dereferences and copies the LOGFONT, so we
|
||||
// are safe to pass this reference.
|
||||
RefPtr<ScaledFontBase> scaledFont = new ScaledFontWin(logFont, nullptr, aGlyphSize);
|
||||
if (mNeedsCairo && !scaledFont->PopulateCairoScaledFont()) {
|
||||
gfxWarning() << "Unable to create cairo scaled font GDI font.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return scaledFont.forget();
|
||||
RefPtr<UnscaledFont> unscaledFont = new UnscaledFontGDI(*logFont);
|
||||
return unscaledFont.forget();
|
||||
}
|
||||
|
||||
} // gfx
|
||||
|
@ -26,27 +26,24 @@ public:
|
||||
*
|
||||
* @param aFontData the SFNT data.
|
||||
* @param aDataLength length of data.
|
||||
* @param aNeedsCairo whether the ScaledFont created need a cairo scaled font
|
||||
* @return Referenced NativeFontResourceGDI or nullptr if invalid.
|
||||
*/
|
||||
static already_AddRefed<NativeFontResourceGDI>
|
||||
Create(uint8_t *aFontData, uint32_t aDataLength, bool aNeedsCairo);
|
||||
Create(uint8_t *aFontData, uint32_t aDataLength);
|
||||
|
||||
~NativeFontResourceGDI();
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
CreateScaledFont(uint32_t aIndex, Float aGlyphSize,
|
||||
const uint8_t* aInstanceData, uint32_t aInstanceDataLength) final;
|
||||
already_AddRefed<UnscaledFont>
|
||||
CreateUnscaledFont(uint32_t aIndex,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength) final;
|
||||
|
||||
private:
|
||||
NativeFontResourceGDI(HANDLE aFontResourceHandle,
|
||||
bool aNeedsCairo)
|
||||
explicit NativeFontResourceGDI(HANDLE aFontResourceHandle)
|
||||
: mFontResourceHandle(aFontResourceHandle)
|
||||
, mNeedsCairo(aNeedsCairo)
|
||||
{}
|
||||
|
||||
HANDLE mFontResourceHandle;
|
||||
bool mNeedsCairo;
|
||||
};
|
||||
|
||||
} // gfx
|
||||
|
@ -5,6 +5,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "NativeFontResourceMac.h"
|
||||
#include "UnscaledFontMac.h"
|
||||
#include "Types.h"
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
@ -15,152 +16,12 @@
|
||||
|
||||
#include "nsCocoaFeatures.h"
|
||||
|
||||
// Simple helper class to automatically release a CFObject when it goes out
|
||||
// of scope.
|
||||
template<class T>
|
||||
class AutoRelease
|
||||
{
|
||||
public:
|
||||
explicit AutoRelease(T aObject)
|
||||
: mObject(aObject)
|
||||
{
|
||||
}
|
||||
|
||||
~AutoRelease()
|
||||
{
|
||||
if (mObject) {
|
||||
CFRelease(mObject);
|
||||
}
|
||||
}
|
||||
|
||||
operator T()
|
||||
{
|
||||
return mObject;
|
||||
}
|
||||
|
||||
T forget()
|
||||
{
|
||||
T obj = mObject;
|
||||
mObject = nullptr;
|
||||
return obj;
|
||||
}
|
||||
|
||||
private:
|
||||
T mObject;
|
||||
};
|
||||
|
||||
// This is essentially identical to the similarly-named helper function
|
||||
// in gfx/thebes/gfxMacFont.cpp. Maybe we should put it somewhere that
|
||||
// can be shared by both Moz2d and Thebes callers?
|
||||
static CFDictionaryRef
|
||||
CreateVariationDictionaryOrNull(CGFontRef aCGFont, uint32_t aVariationCount,
|
||||
const mozilla::gfx::ScaledFont::VariationSetting* aVariations)
|
||||
{
|
||||
// Avoid calling potentially buggy variation APIs on pre-Sierra macOS
|
||||
// versions (see bug 1331683)
|
||||
if (!nsCocoaFeatures::OnSierraOrLater()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoRelease<CTFontRef>
|
||||
ctFont(CTFontCreateWithGraphicsFont(aCGFont, 0, nullptr, nullptr));
|
||||
AutoRelease<CFArrayRef> axes(CTFontCopyVariationAxes(ctFont));
|
||||
if (!axes) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CFIndex axisCount = CFArrayGetCount(axes);
|
||||
AutoRelease<CFMutableDictionaryRef>
|
||||
dict(CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks));
|
||||
|
||||
// Number of variation settings passed in the aVariations parameter.
|
||||
// This will typically be a very low value, so we just linear-search them.
|
||||
bool allDefaultValues = true;
|
||||
|
||||
for (CFIndex i = 0; i < axisCount; ++i) {
|
||||
// We sanity-check the axis info found in the CTFont, and bail out
|
||||
// (returning null) if it doesn't have the expected types.
|
||||
CFTypeRef axisInfo = CFArrayGetValueAtIndex(axes, i);
|
||||
if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
|
||||
return nullptr;
|
||||
}
|
||||
CFDictionaryRef axis = static_cast<CFDictionaryRef>(axisInfo);
|
||||
|
||||
CFTypeRef axisTag =
|
||||
CFDictionaryGetValue(axis, kCTFontVariationAxisIdentifierKey);
|
||||
if (!axisTag || CFGetTypeID(axisTag) != CFNumberGetTypeID()) {
|
||||
return nullptr;
|
||||
}
|
||||
int64_t tagLong;
|
||||
if (!CFNumberGetValue(static_cast<CFNumberRef>(axisTag),
|
||||
kCFNumberSInt64Type, &tagLong)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CFTypeRef axisName =
|
||||
CFDictionaryGetValue(axis, kCTFontVariationAxisNameKey);
|
||||
if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Clamp axis values to the supported range.
|
||||
CFTypeRef min = CFDictionaryGetValue(axis, kCTFontVariationAxisMinimumValueKey);
|
||||
CFTypeRef max = CFDictionaryGetValue(axis, kCTFontVariationAxisMaximumValueKey);
|
||||
CFTypeRef def = CFDictionaryGetValue(axis, kCTFontVariationAxisDefaultValueKey);
|
||||
if (!min || CFGetTypeID(min) != CFNumberGetTypeID() ||
|
||||
!max || CFGetTypeID(max) != CFNumberGetTypeID() ||
|
||||
!def || CFGetTypeID(def) != CFNumberGetTypeID()) {
|
||||
return nullptr;
|
||||
}
|
||||
double minDouble;
|
||||
double maxDouble;
|
||||
double defDouble;
|
||||
if (!CFNumberGetValue(static_cast<CFNumberRef>(min), kCFNumberDoubleType,
|
||||
&minDouble) ||
|
||||
!CFNumberGetValue(static_cast<CFNumberRef>(max), kCFNumberDoubleType,
|
||||
&maxDouble) ||
|
||||
!CFNumberGetValue(static_cast<CFNumberRef>(def), kCFNumberDoubleType,
|
||||
&defDouble)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
double value = defDouble;
|
||||
for (uint32_t j = 0; j < aVariationCount; ++j) {
|
||||
if (aVariations[j].mTag == tagLong) {
|
||||
value = std::min(std::max<double>(aVariations[j].mValue,
|
||||
minDouble),
|
||||
maxDouble);
|
||||
if (value != defDouble) {
|
||||
allDefaultValues = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
AutoRelease<CFNumberRef> valueNumber(CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberDoubleType,
|
||||
&value));
|
||||
CFDictionaryAddValue(dict, axisName, valueNumber);
|
||||
}
|
||||
|
||||
if (allDefaultValues) {
|
||||
// We didn't actually set any non-default values, so throw away the
|
||||
// variations dictionary and just use the default rendering.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return dict.forget();
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
/* static */
|
||||
already_AddRefed<NativeFontResourceMac>
|
||||
NativeFontResourceMac::Create(uint8_t *aFontData, uint32_t aDataLength,
|
||||
uint32_t aVariationCount,
|
||||
const ScaledFont::VariationSetting* aVariations)
|
||||
NativeFontResourceMac::Create(uint8_t *aFontData, uint32_t aDataLength)
|
||||
{
|
||||
// copy font data
|
||||
CFDataRef data = CFDataCreate(kCFAllocatorDefault, aFontData, aDataLength);
|
||||
@ -184,20 +45,6 @@ NativeFontResourceMac::Create(uint8_t *aFontData, uint32_t aDataLength,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aVariationCount > 0) {
|
||||
MOZ_ASSERT(aVariations);
|
||||
AutoRelease<CFDictionaryRef>
|
||||
varDict(CreateVariationDictionaryOrNull(fontRef, aVariationCount,
|
||||
aVariations));
|
||||
if (varDict) {
|
||||
CGFontRef varFont = CGFontCreateCopyWithVariations(fontRef, varDict);
|
||||
if (varFont) {
|
||||
CFRelease(fontRef);
|
||||
fontRef = varFont;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// passes ownership of fontRef to the NativeFontResourceMac instance
|
||||
RefPtr<NativeFontResourceMac> fontResource =
|
||||
new NativeFontResourceMac(fontRef);
|
||||
@ -205,18 +52,14 @@ NativeFontResourceMac::Create(uint8_t *aFontData, uint32_t aDataLength,
|
||||
return fontResource.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
NativeFontResourceMac::CreateScaledFont(uint32_t aIndex, Float aGlyphSize,
|
||||
const uint8_t* aInstanceData, uint32_t aInstanceDataLength)
|
||||
already_AddRefed<UnscaledFont>
|
||||
NativeFontResourceMac::CreateUnscaledFont(uint32_t aIndex,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength)
|
||||
{
|
||||
RefPtr<ScaledFontBase> scaledFont = new ScaledFontMac(mFontRef, nullptr, aGlyphSize);
|
||||
RefPtr<UnscaledFont> unscaledFont = new UnscaledFontMac(mFontRef);
|
||||
|
||||
if (!scaledFont->PopulateCairoScaledFont()) {
|
||||
gfxWarning() << "Unable to create cairo scaled Mac font.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return scaledFont.forget();
|
||||
return unscaledFont.forget();
|
||||
}
|
||||
|
||||
} // gfx
|
||||
|
@ -20,13 +20,12 @@ public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(NativeFontResourceMac)
|
||||
|
||||
static already_AddRefed<NativeFontResourceMac>
|
||||
Create(uint8_t *aFontData, uint32_t aDataLength,
|
||||
uint32_t aVariationCount,
|
||||
const ScaledFont::VariationSetting* aVariations);
|
||||
Create(uint8_t *aFontData, uint32_t aDataLength);
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
CreateScaledFont(uint32_t aIndex, Float aGlyphSize,
|
||||
const uint8_t* aInstanceData, uint32_t aInstanceDataLength) final;
|
||||
already_AddRefed<UnscaledFont>
|
||||
CreateUnscaledFont(uint32_t aIndex,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength) final;
|
||||
|
||||
~NativeFontResourceMac()
|
||||
{
|
||||
|
@ -84,6 +84,8 @@ RecordedEvent::LoadEventFromStream(std::istream &aStream, EventType aType)
|
||||
LOAD_EVENT_TYPE(FONTDESC, RecordedFontDescriptor);
|
||||
LOAD_EVENT_TYPE(PUSHLAYER, RecordedPushLayer);
|
||||
LOAD_EVENT_TYPE(POPLAYER, RecordedPopLayer);
|
||||
LOAD_EVENT_TYPE(UNSCALEDFONTCREATION, RecordedUnscaledFontCreation);
|
||||
LOAD_EVENT_TYPE(UNSCALEDFONTDESTRUCTION, RecordedUnscaledFontDestruction);
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
@ -167,6 +169,10 @@ RecordedEvent::GetEventName(EventType aType)
|
||||
return "PushLayer";
|
||||
case POPLAYER:
|
||||
return "PopLayer";
|
||||
case UNSCALEDFONTCREATION:
|
||||
return "UnscaledFontCreation";
|
||||
case UNSCALEDFONTDESTRUCTION:
|
||||
return "UnscaledFontDestruction";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
@ -1522,7 +1528,6 @@ RecordedSnapshot::OutputSimpleEventInfo(stringstream &aStringStream) const
|
||||
RecordedFontData::~RecordedFontData()
|
||||
{
|
||||
delete[] mData;
|
||||
delete[] mVariations;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1530,7 +1535,6 @@ RecordedFontData::PlayEvent(Translator *aTranslator) const
|
||||
{
|
||||
RefPtr<NativeFontResource> fontResource =
|
||||
Factory::CreateNativeFontResource(mData, mFontDetails.size,
|
||||
mFontDetails.variationCount, mVariations,
|
||||
aTranslator->GetDesiredFontType());
|
||||
if (!fontResource) {
|
||||
return false;
|
||||
@ -1548,8 +1552,6 @@ RecordedFontData::RecordToStream(std::ostream &aStream) const
|
||||
WriteElement(aStream, mFontDetails.fontDataKey);
|
||||
WriteElement(aStream, mFontDetails.size);
|
||||
aStream.write((const char*)mData, mFontDetails.size);
|
||||
WriteElement(aStream, mFontDetails.variationCount);
|
||||
aStream.write((const char*)mVariations, mFontDetails.variationCount * sizeof(ScaledFont::VariationSetting));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1559,23 +1561,14 @@ RecordedFontData::OutputSimpleEventInfo(stringstream &aStringStream) const
|
||||
}
|
||||
|
||||
void
|
||||
RecordedFontData::SetFontData(const uint8_t *aData, uint32_t aSize, uint32_t aIndex,
|
||||
Float aGlyphSize, uint32_t aVariationCount,
|
||||
const ScaledFont::VariationSetting* aVariations)
|
||||
RecordedFontData::SetFontData(const uint8_t *aData, uint32_t aSize, uint32_t aIndex)
|
||||
{
|
||||
mData = new uint8_t[aSize];
|
||||
memcpy(mData, aData, aSize);
|
||||
uint32_t varDataSize = aVariationCount * sizeof(ScaledFont::VariationSetting);
|
||||
mFontDetails.fontDataKey =
|
||||
SFNTData::GetUniqueKey(aData, aSize, varDataSize, aVariations);
|
||||
SFNTData::GetUniqueKey(aData, aSize, 0, nullptr);
|
||||
mFontDetails.size = aSize;
|
||||
mFontDetails.index = aIndex;
|
||||
mFontDetails.glyphSize = aGlyphSize;
|
||||
mFontDetails.variationCount = aVariationCount;
|
||||
if (aVariationCount > 0) {
|
||||
mVariations = new ScaledFont::VariationSetting[aVariationCount];
|
||||
memcpy(mVariations, aVariations, varDataSize);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1587,28 +1580,18 @@ RecordedFontData::GetFontDetails(RecordedFontDetails& fontDetails)
|
||||
|
||||
fontDetails.fontDataKey = mFontDetails.fontDataKey;
|
||||
fontDetails.size = mFontDetails.size;
|
||||
fontDetails.glyphSize = mFontDetails.glyphSize;
|
||||
fontDetails.index = mFontDetails.index;
|
||||
fontDetails.variationCount = mFontDetails.variationCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
RecordedFontData::RecordedFontData(istream &aStream)
|
||||
: RecordedEvent(FONTDATA)
|
||||
, mData(nullptr)
|
||||
, mVariations(nullptr)
|
||||
{
|
||||
ReadElement(aStream, mFontDetails.fontDataKey);
|
||||
ReadElement(aStream, mFontDetails.size);
|
||||
mData = new uint8_t[mFontDetails.size];
|
||||
aStream.read((char*)mData, mFontDetails.size);
|
||||
ReadElement(aStream, mFontDetails.variationCount);
|
||||
if (mFontDetails.variationCount > 0) {
|
||||
mVariations = new ScaledFont::VariationSetting[mFontDetails.variationCount];
|
||||
aStream.read((char*)mVariations, mFontDetails.variationCount * sizeof(ScaledFont::VariationSetting));
|
||||
} else {
|
||||
mVariations = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
RecordedFontDescriptor::~RecordedFontDescriptor()
|
||||
@ -1618,15 +1601,15 @@ RecordedFontDescriptor::~RecordedFontDescriptor()
|
||||
bool
|
||||
RecordedFontDescriptor::PlayEvent(Translator *aTranslator) const
|
||||
{
|
||||
RefPtr<ScaledFont> font =
|
||||
Factory::CreateScaledFontFromFontDescriptor(mType, mData.data(), mData.size(), mFontSize);
|
||||
RefPtr<UnscaledFont> font =
|
||||
Factory::CreateUnscaledFontFromFontDescriptor(mType, mData.data(), mData.size());
|
||||
if (!font) {
|
||||
gfxDevCrash(LogReason::InvalidFont) <<
|
||||
"Failed creating ScaledFont of type " << int(mType) << " from font descriptor";
|
||||
"Failed creating UnscaledFont of type " << int(mType) << " from font descriptor";
|
||||
return false;
|
||||
}
|
||||
|
||||
aTranslator->AddScaledFont(mRefPtr, font);
|
||||
aTranslator->AddUnscaledFont(mRefPtr, font);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1635,7 +1618,6 @@ 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.data(), mData.size());
|
||||
@ -1648,17 +1630,15 @@ RecordedFontDescriptor::OutputSimpleEventInfo(stringstream &aStringStream) const
|
||||
}
|
||||
|
||||
void
|
||||
RecordedFontDescriptor::SetFontDescriptor(const uint8_t* aData, uint32_t aSize, Float aFontSize)
|
||||
RecordedFontDescriptor::SetFontDescriptor(const uint8_t* aData, uint32_t aSize)
|
||||
{
|
||||
mData.assign(aData, aData + aSize);
|
||||
mFontSize = aFontSize;
|
||||
}
|
||||
|
||||
RecordedFontDescriptor::RecordedFontDescriptor(istream &aStream)
|
||||
: RecordedEvent(FONTDATA)
|
||||
: RecordedEvent(FONTDESC)
|
||||
{
|
||||
ReadElement(aStream, mType);
|
||||
ReadElement(aStream, mFontSize);
|
||||
ReadElement(aStream, mRefPtr);
|
||||
|
||||
size_t size;
|
||||
@ -1668,7 +1648,7 @@ RecordedFontDescriptor::RecordedFontDescriptor(istream &aStream)
|
||||
}
|
||||
|
||||
bool
|
||||
RecordedScaledFontCreation::PlayEvent(Translator *aTranslator) const
|
||||
RecordedUnscaledFontCreation::PlayEvent(Translator *aTranslator) const
|
||||
{
|
||||
NativeFontResource *fontResource = aTranslator->LookupNativeFontResource(mFontDataKey);
|
||||
if (!fontResource) {
|
||||
@ -1677,8 +1657,84 @@ RecordedScaledFontCreation::PlayEvent(Translator *aTranslator) const
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<UnscaledFont> unscaledFont =
|
||||
fontResource->CreateUnscaledFont(mIndex, mInstanceData.data(), mInstanceData.size());
|
||||
aTranslator->AddUnscaledFont(mRefPtr, unscaledFont);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RecordedUnscaledFontCreation::RecordToStream(std::ostream &aStream) const
|
||||
{
|
||||
WriteElement(aStream, mRefPtr);
|
||||
WriteElement(aStream, mFontDataKey);
|
||||
WriteElement(aStream, mIndex);
|
||||
WriteElement(aStream, (size_t)mInstanceData.size());
|
||||
aStream.write((char*)mInstanceData.data(), mInstanceData.size());
|
||||
}
|
||||
|
||||
void
|
||||
RecordedUnscaledFontCreation::OutputSimpleEventInfo(stringstream &aStringStream) const
|
||||
{
|
||||
aStringStream << "[" << mRefPtr << "] UnscaledFont Created";
|
||||
}
|
||||
|
||||
void
|
||||
RecordedUnscaledFontCreation::SetFontInstanceData(const uint8_t *aData, uint32_t aSize)
|
||||
{
|
||||
mInstanceData.assign(aData, aData + aSize);
|
||||
}
|
||||
|
||||
RecordedUnscaledFontCreation::RecordedUnscaledFontCreation(istream &aStream)
|
||||
: RecordedEvent(UNSCALEDFONTCREATION)
|
||||
{
|
||||
ReadElement(aStream, mRefPtr);
|
||||
ReadElement(aStream, mFontDataKey);
|
||||
ReadElement(aStream, mIndex);
|
||||
|
||||
size_t size;
|
||||
ReadElement(aStream, size);
|
||||
mInstanceData.resize(size);
|
||||
aStream.read((char*)mInstanceData.data(), size);
|
||||
}
|
||||
|
||||
bool
|
||||
RecordedUnscaledFontDestruction::PlayEvent(Translator *aTranslator) const
|
||||
{
|
||||
aTranslator->RemoveUnscaledFont(mRefPtr);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RecordedUnscaledFontDestruction::RecordToStream(ostream &aStream) const
|
||||
{
|
||||
WriteElement(aStream, mRefPtr);
|
||||
}
|
||||
|
||||
RecordedUnscaledFontDestruction::RecordedUnscaledFontDestruction(istream &aStream)
|
||||
: RecordedEvent(UNSCALEDFONTDESTRUCTION)
|
||||
{
|
||||
ReadElement(aStream, mRefPtr);
|
||||
}
|
||||
|
||||
void
|
||||
RecordedUnscaledFontDestruction::OutputSimpleEventInfo(stringstream &aStringStream) const
|
||||
{
|
||||
aStringStream << "[" << mRefPtr << "] UnscaledFont Destroyed";
|
||||
}
|
||||
|
||||
bool
|
||||
RecordedScaledFontCreation::PlayEvent(Translator *aTranslator) const
|
||||
{
|
||||
UnscaledFont* unscaledFont = aTranslator->LookupUnscaledFont(mUnscaledFont);
|
||||
if (!unscaledFont) {
|
||||
gfxDevCrash(LogReason::UnscaledFontNotFound) <<
|
||||
"UnscaledFont lookup failed for key |" << hexa(mUnscaledFont) << "|.";
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<ScaledFont> scaledFont =
|
||||
fontResource->CreateScaledFont(mIndex, mGlyphSize, mInstanceData.data(), mInstanceData.size());
|
||||
unscaledFont->CreateScaledFont(mGlyphSize, mInstanceData.data(), mInstanceData.size());
|
||||
aTranslator->AddScaledFont(mRefPtr, scaledFont);
|
||||
return true;
|
||||
}
|
||||
@ -1687,8 +1743,7 @@ void
|
||||
RecordedScaledFontCreation::RecordToStream(std::ostream &aStream) const
|
||||
{
|
||||
WriteElement(aStream, mRefPtr);
|
||||
WriteElement(aStream, mFontDataKey);
|
||||
WriteElement(aStream, mIndex);
|
||||
WriteElement(aStream, mUnscaledFont);
|
||||
WriteElement(aStream, mGlyphSize);
|
||||
WriteElement(aStream, (size_t)mInstanceData.size());
|
||||
aStream.write((char*)mInstanceData.data(), mInstanceData.size());
|
||||
@ -1710,8 +1765,7 @@ RecordedScaledFontCreation::RecordedScaledFontCreation(istream &aStream)
|
||||
: RecordedEvent(SCALEDFONTCREATION)
|
||||
{
|
||||
ReadElement(aStream, mRefPtr);
|
||||
ReadElement(aStream, mFontDataKey);
|
||||
ReadElement(aStream, mIndex);
|
||||
ReadElement(aStream, mUnscaledFont);
|
||||
ReadElement(aStream, mGlyphSize);
|
||||
|
||||
size_t size;
|
||||
|
@ -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 = 8;
|
||||
const uint16_t kMajorRevision = 9;
|
||||
// A change in minor revision means additions of new events. New streams will
|
||||
// not play in older players.
|
||||
const uint16_t kMinorRevision = 0;
|
||||
@ -67,8 +67,6 @@ struct RecordedFontDetails
|
||||
uint64_t fontDataKey;
|
||||
uint32_t size;
|
||||
uint32_t index;
|
||||
uint32_t variationCount;
|
||||
Float glyphSize;
|
||||
};
|
||||
|
||||
// Used by the Azure drawing debugger (player2d)
|
||||
@ -90,6 +88,7 @@ public:
|
||||
virtual FilterNode *LookupFilterNode(ReferencePtr aRefPtr) = 0;
|
||||
virtual GradientStops *LookupGradientStops(ReferencePtr aRefPtr) = 0;
|
||||
virtual ScaledFont *LookupScaledFont(ReferencePtr aRefPtr) = 0;
|
||||
virtual UnscaledFont* LookupUnscaledFont(ReferencePtr aRefPtr) = 0;
|
||||
virtual NativeFontResource *LookupNativeFontResource(uint64_t aKey) = 0;
|
||||
virtual void AddDrawTarget(ReferencePtr aRefPtr, DrawTarget *aDT) = 0;
|
||||
virtual void RemoveDrawTarget(ReferencePtr aRefPtr) = 0;
|
||||
@ -103,6 +102,8 @@ public:
|
||||
virtual void RemoveGradientStops(ReferencePtr aRefPtr) = 0;
|
||||
virtual void AddScaledFont(ReferencePtr aRefPtr, ScaledFont *aScaledFont) = 0;
|
||||
virtual void RemoveScaledFont(ReferencePtr aRefPtr) = 0;
|
||||
virtual void AddUnscaledFont(ReferencePtr aRefPtr, UnscaledFont* aUnscaledFont) = 0;
|
||||
virtual void RemoveUnscaledFont(ReferencePtr aRefPtr) = 0;
|
||||
virtual void AddNativeFontResource(uint64_t aKey,
|
||||
NativeFontResource *aNativeFontResource) = 0;
|
||||
|
||||
@ -197,6 +198,8 @@ public:
|
||||
FONTDESC,
|
||||
PUSHLAYER,
|
||||
POPLAYER,
|
||||
UNSCALEDFONTCREATION,
|
||||
UNSCALEDFONTDESTRUCTION,
|
||||
};
|
||||
static const uint32_t kTotalEventTypes = RecordedEvent::FILTERNODESETINPUT + 1;
|
||||
|
||||
@ -1015,24 +1018,22 @@ class RecordedFontData : public RecordedEvent {
|
||||
public:
|
||||
|
||||
static void FontDataProc(const uint8_t *aData, uint32_t aSize,
|
||||
uint32_t aIndex, Float aGlyphSize,
|
||||
uint32_t aVariationCount,
|
||||
const ScaledFont::VariationSetting* aVariations,
|
||||
void* aBaton)
|
||||
uint32_t aIndex, void* aBaton)
|
||||
{
|
||||
auto recordedFontData = static_cast<RecordedFontData*>(aBaton);
|
||||
recordedFontData->SetFontData(aData, aSize, aIndex, aGlyphSize,
|
||||
aVariationCount, aVariations);
|
||||
recordedFontData->SetFontData(aData, aSize, aIndex);
|
||||
}
|
||||
|
||||
explicit RecordedFontData(ScaledFont *aScaledFont)
|
||||
: RecordedEvent(FONTDATA), mData(nullptr), mVariations(nullptr)
|
||||
explicit RecordedFontData(UnscaledFont *aUnscaledFont)
|
||||
: RecordedEvent(FONTDATA), mData(nullptr)
|
||||
{
|
||||
mGetFontFileDataSucceeded = aScaledFont->GetFontFileData(&FontDataProc, this);
|
||||
mGetFontFileDataSucceeded = aUnscaledFont->GetFontFileData(&FontDataProc, this);
|
||||
}
|
||||
|
||||
~RecordedFontData();
|
||||
|
||||
bool IsValid() const { return mGetFontFileDataSucceeded; }
|
||||
|
||||
virtual bool PlayEvent(Translator *aTranslator) const;
|
||||
|
||||
virtual void RecordToStream(std::ostream &aStream) const;
|
||||
@ -1041,9 +1042,7 @@ public:
|
||||
virtual std::string GetName() const { return "Font Data"; }
|
||||
virtual ReferencePtr GetObjectRef() const { return nullptr; };
|
||||
|
||||
void SetFontData(const uint8_t *aData, uint32_t aSize, uint32_t aIndex,
|
||||
Float aGlyphSize, uint32_t aVariationCount,
|
||||
const ScaledFont::VariationSetting* aVariations);
|
||||
void SetFontData(const uint8_t *aData, uint32_t aSize, uint32_t aIndex);
|
||||
|
||||
bool GetFontDetails(RecordedFontDetails& fontDetails);
|
||||
|
||||
@ -1051,7 +1050,6 @@ private:
|
||||
friend class RecordedEvent;
|
||||
|
||||
uint8_t* mData;
|
||||
ScaledFont::VariationSetting* mVariations;
|
||||
RecordedFontDetails mFontDetails;
|
||||
|
||||
bool mGetFontFileDataSucceeded;
|
||||
@ -1063,18 +1061,18 @@ class RecordedFontDescriptor : public RecordedEvent {
|
||||
public:
|
||||
|
||||
static void FontDescCb(const uint8_t* aData, uint32_t aSize,
|
||||
Float aFontSize, void* aBaton)
|
||||
void* aBaton)
|
||||
{
|
||||
auto recordedFontDesc = static_cast<RecordedFontDescriptor*>(aBaton);
|
||||
recordedFontDesc->SetFontDescriptor(aData, aSize, aFontSize);
|
||||
recordedFontDesc->SetFontDescriptor(aData, aSize);
|
||||
}
|
||||
|
||||
explicit RecordedFontDescriptor(ScaledFont* aScaledFont)
|
||||
explicit RecordedFontDescriptor(UnscaledFont* aUnscaledFont)
|
||||
: RecordedEvent(FONTDESC)
|
||||
, mType(aScaledFont->GetType())
|
||||
, mRefPtr(aScaledFont)
|
||||
, mType(aUnscaledFont->GetType())
|
||||
, mRefPtr(aUnscaledFont)
|
||||
{
|
||||
mHasDesc = aScaledFont->GetFontDescriptor(FontDescCb, this);
|
||||
mHasDesc = aUnscaledFont->GetFontDescriptor(FontDescCb, this);
|
||||
}
|
||||
|
||||
~RecordedFontDescriptor();
|
||||
@ -1092,18 +1090,77 @@ public:
|
||||
private:
|
||||
friend class RecordedEvent;
|
||||
|
||||
void SetFontDescriptor(const uint8_t* aData, uint32_t aSize, Float aFontSize);
|
||||
void SetFontDescriptor(const uint8_t* aData, uint32_t aSize);
|
||||
|
||||
bool mHasDesc;
|
||||
|
||||
FontType mType;
|
||||
Float mFontSize;
|
||||
std::vector<uint8_t> mData;
|
||||
ReferencePtr mRefPtr;
|
||||
|
||||
MOZ_IMPLICIT RecordedFontDescriptor(std::istream &aStream);
|
||||
};
|
||||
|
||||
class RecordedUnscaledFontCreation : public RecordedEvent {
|
||||
public:
|
||||
static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize, void* aBaton)
|
||||
{
|
||||
auto recordedUnscaledFontCreation = static_cast<RecordedUnscaledFontCreation*>(aBaton);
|
||||
recordedUnscaledFontCreation->SetFontInstanceData(aData, aSize);
|
||||
}
|
||||
|
||||
RecordedUnscaledFontCreation(UnscaledFont* aUnscaledFont,
|
||||
RecordedFontDetails aFontDetails)
|
||||
: RecordedEvent(UNSCALEDFONTCREATION)
|
||||
, mRefPtr(aUnscaledFont)
|
||||
, mFontDataKey(aFontDetails.fontDataKey)
|
||||
, mIndex(aFontDetails.index)
|
||||
{
|
||||
aUnscaledFont->GetFontInstanceData(FontInstanceDataProc, this);
|
||||
}
|
||||
|
||||
virtual bool PlayEvent(Translator *aTranslator) const;
|
||||
|
||||
virtual void RecordToStream(std::ostream &aStream) const;
|
||||
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
|
||||
|
||||
virtual std::string GetName() const { return "UnscaledFont Creation"; }
|
||||
virtual ReferencePtr GetObjectRef() const { return mRefPtr; }
|
||||
|
||||
void SetFontInstanceData(const uint8_t *aData, uint32_t aSize);
|
||||
|
||||
private:
|
||||
friend class RecordedEvent;
|
||||
|
||||
ReferencePtr mRefPtr;
|
||||
uint64_t mFontDataKey;
|
||||
uint32_t mIndex;
|
||||
std::vector<uint8_t> mInstanceData;
|
||||
|
||||
MOZ_IMPLICIT RecordedUnscaledFontCreation(std::istream &aStream);
|
||||
};
|
||||
|
||||
class RecordedUnscaledFontDestruction : public RecordedEvent {
|
||||
public:
|
||||
MOZ_IMPLICIT RecordedUnscaledFontDestruction(ReferencePtr aRefPtr)
|
||||
: RecordedEvent(UNSCALEDFONTDESTRUCTION), mRefPtr(aRefPtr)
|
||||
{}
|
||||
|
||||
virtual bool PlayEvent(Translator *aTranslator) const;
|
||||
|
||||
virtual void RecordToStream(std::ostream &aStream) const;
|
||||
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
|
||||
|
||||
virtual std::string GetName() const { return "UnscaledFont Destruction"; }
|
||||
virtual ReferencePtr GetObjectRef() const { return mRefPtr; }
|
||||
private:
|
||||
friend class RecordedEvent;
|
||||
|
||||
ReferencePtr mRefPtr;
|
||||
|
||||
MOZ_IMPLICIT RecordedUnscaledFontDestruction(std::istream &aStream);
|
||||
};
|
||||
|
||||
class RecordedScaledFontCreation : public RecordedEvent {
|
||||
public:
|
||||
|
||||
@ -1114,12 +1171,11 @@ public:
|
||||
}
|
||||
|
||||
RecordedScaledFontCreation(ScaledFont* aScaledFont,
|
||||
RecordedFontDetails aFontDetails)
|
||||
UnscaledFont* aUnscaledFont)
|
||||
: RecordedEvent(SCALEDFONTCREATION)
|
||||
, mRefPtr(aScaledFont)
|
||||
, mFontDataKey(aFontDetails.fontDataKey)
|
||||
, mGlyphSize(aFontDetails.glyphSize)
|
||||
, mIndex(aFontDetails.index)
|
||||
, mUnscaledFont(aUnscaledFont)
|
||||
, mGlyphSize(aScaledFont->GetSize())
|
||||
{
|
||||
aScaledFont->GetFontInstanceData(FontInstanceDataProc, this);
|
||||
}
|
||||
@ -1138,9 +1194,8 @@ private:
|
||||
friend class RecordedEvent;
|
||||
|
||||
ReferencePtr mRefPtr;
|
||||
uint64_t mFontDataKey;
|
||||
ReferencePtr mUnscaledFont;
|
||||
Float mGlyphSize;
|
||||
uint32_t mIndex;
|
||||
std::vector<uint8_t> mInstanceData;
|
||||
|
||||
MOZ_IMPLICIT RecordedScaledFontCreation(std::istream &aStream);
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "DrawTargetD2D1.h"
|
||||
#include "ScaledFontDWrite.h"
|
||||
#include "UnscaledFontDWrite.h"
|
||||
#include "PathD2D.h"
|
||||
#include "gfxFont.h"
|
||||
|
||||
@ -221,7 +222,7 @@ ScaledFontDWrite::CopyGlyphsToSink(const GlyphBuffer &aBuffer, ID2D1GeometrySink
|
||||
}
|
||||
|
||||
bool
|
||||
ScaledFontDWrite::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton)
|
||||
UnscaledFontDWrite::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton)
|
||||
{
|
||||
UINT32 fileCount = 0;
|
||||
mFontFace->GetFiles(&fileCount, nullptr);
|
||||
@ -264,14 +265,27 @@ ScaledFontDWrite::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton
|
||||
void *context;
|
||||
stream->ReadFileFragment(&fragmentStart, 0, fileSize, &context);
|
||||
|
||||
aDataCallback((uint8_t*)fragmentStart, fileSize, mFontFace->GetIndex(), mSize,
|
||||
0, nullptr, aBaton);
|
||||
aDataCallback((uint8_t*)fragmentStart, fileSize, mFontFace->GetIndex(), aBaton);
|
||||
|
||||
stream->ReleaseFileFragment(context);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
UnscaledFontDWrite::CreateScaledFont(Float aGlyphSize,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength)
|
||||
{
|
||||
RefPtr<ScaledFontBase> scaledFont = new ScaledFontDWrite(mFontFace, this, aGlyphSize);
|
||||
if (mNeedsCairo && !scaledFont->PopulateCairoScaledFont()) {
|
||||
gfxWarning() << "Unable to create cairo scaled font DWrite font.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return scaledFont.forget();
|
||||
}
|
||||
|
||||
AntialiasMode
|
||||
ScaledFontDWrite::GetDefaultAAMode()
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ namespace gfx {
|
||||
class ScaledFontDWrite final : public ScaledFontBase
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontDwrite)
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontDWrite, override)
|
||||
ScaledFontDWrite(IDWriteFontFace *aFont,
|
||||
const RefPtr<UnscaledFont>& aUnscaledFont,
|
||||
Float aSize)
|
||||
@ -35,26 +35,24 @@ public:
|
||||
bool aForceGDIMode,
|
||||
const gfxFontStyle* aStyle);
|
||||
|
||||
virtual FontType GetType() const { return FontType::DWRITE; }
|
||||
FontType GetType() const override { return FontType::DWRITE; }
|
||||
|
||||
virtual already_AddRefed<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget);
|
||||
virtual void CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, const Matrix *aTransformHint);
|
||||
already_AddRefed<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget) override;
|
||||
void CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, const Matrix *aTransformHint) override;
|
||||
|
||||
void CopyGlyphsToSink(const GlyphBuffer &aBuffer, ID2D1GeometrySink *aSink);
|
||||
|
||||
virtual void GetGlyphDesignMetrics(const uint16_t* aGlyphIndices, uint32_t aNumGlyphs, GlyphMetrics* aGlyphMetrics);
|
||||
void GetGlyphDesignMetrics(const uint16_t* aGlyphIndices, uint32_t aNumGlyphs, GlyphMetrics* aGlyphMetrics) override;
|
||||
|
||||
virtual bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton);
|
||||
bool CanSerialize() override { return true; }
|
||||
|
||||
virtual bool CanSerialize() override { return true; }
|
||||
|
||||
virtual AntialiasMode GetDefaultAAMode() override;
|
||||
AntialiasMode GetDefaultAAMode() override;
|
||||
|
||||
bool UseEmbeddedBitmaps() { return mUseEmbeddedBitmap; }
|
||||
bool ForceGDIMode() { return mForceGDIMode; }
|
||||
|
||||
#ifdef USE_SKIA
|
||||
virtual SkTypeface* GetSkTypeface();
|
||||
SkTypeface* GetSkTypeface() override;
|
||||
SkFontStyle mStyle;
|
||||
#endif
|
||||
|
||||
@ -71,13 +69,13 @@ protected:
|
||||
class GlyphRenderingOptionsDWrite : public GlyphRenderingOptions
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptionsDWrite)
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptionsDWrite, override)
|
||||
explicit GlyphRenderingOptionsDWrite(IDWriteRenderingParams *aParams)
|
||||
: mParams(aParams)
|
||||
{
|
||||
}
|
||||
|
||||
virtual FontType GetType() const { return FontType::DWRITE; }
|
||||
FontType GetType() const override { return FontType::DWRITE; }
|
||||
|
||||
private:
|
||||
friend class DrawTargetD2D;
|
||||
|
@ -4,14 +4,13 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ScaledFontFontconfig.h"
|
||||
#include "UnscaledFontFreeType.h"
|
||||
#include "Logging.h"
|
||||
|
||||
#ifdef USE_SKIA
|
||||
#include "skia/include/ports/SkTypeface_cairo.h"
|
||||
#endif
|
||||
|
||||
#include FT_TRUETYPE_TABLES_H
|
||||
|
||||
#include <fontconfig/fcfreetype.h>
|
||||
|
||||
namespace mozilla {
|
||||
@ -48,27 +47,6 @@ SkTypeface* ScaledFontFontconfig::GetSkTypeface()
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
ScaledFontFontconfig::GetFontFileData(FontFileDataOutput aDataCallback, void* aBaton)
|
||||
{
|
||||
bool success = false;
|
||||
// Lock the Cairo scaled font to force it to resolve the Fontconfig pattern to an FT_Face.
|
||||
if (FT_Face face = cairo_ft_scaled_font_lock_face(GetCairoScaledFont())) {
|
||||
FT_ULong length = 0;
|
||||
// Request the SFNT file. This may not always succeed for all font types.
|
||||
if (FT_Load_Sfnt_Table(face, 0, 0, nullptr, &length) == FT_Err_Ok) {
|
||||
uint8_t* fontData = new uint8_t[length];
|
||||
if (FT_Load_Sfnt_Table(face, 0, 0, fontData, &length) == FT_Err_Ok) {
|
||||
aDataCallback(fontData, length, 0, mSize, 0, nullptr, aBaton);
|
||||
success = true;
|
||||
}
|
||||
delete[] fontData;
|
||||
}
|
||||
cairo_ft_scaled_font_unlock_face(GetCairoScaledFont());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
ScaledFontFontconfig::InstanceData::InstanceData(cairo_scaled_font_t* aScaledFont, FcPattern* aPattern)
|
||||
: mFlags(0)
|
||||
, mHintStyle(FC_HINT_NONE)
|
||||
@ -253,52 +231,35 @@ ScaledFontFontconfig::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBat
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ScaledFontFontconfig::GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton)
|
||||
already_AddRefed<ScaledFont>
|
||||
UnscaledFontFontconfig::CreateScaledFont(Float aGlyphSize,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength)
|
||||
{
|
||||
// Check if the Fontconfig pattern uses a font file and index to specify which
|
||||
// font to load. If so, record these as a font descriptor along with any instance
|
||||
// data required to rebuild a scaled font from it.
|
||||
FcChar8* pathname = nullptr;
|
||||
if (FcPatternGetString(mPattern, FC_FILE, 0, &pathname) != FcResultMatch) {
|
||||
return false;
|
||||
if (aInstanceDataLength < sizeof(ScaledFontFontconfig::InstanceData)) {
|
||||
gfxWarning() << "Fontconfig scaled font instance data is truncated.";
|
||||
return nullptr;
|
||||
}
|
||||
int index = 0;
|
||||
FcPatternGetInteger(mPattern, FC_INDEX, 0, &index);
|
||||
if (index < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t pathLength = strlen(reinterpret_cast<char*>(pathname)) + 1;
|
||||
size_t dataLength = sizeof(FontDescriptor) + pathLength;
|
||||
uint8_t* data = new uint8_t[dataLength];
|
||||
FontDescriptor* desc = reinterpret_cast<FontDescriptor*>(data);
|
||||
desc->mPathLength = pathLength;
|
||||
desc->mIndex = index;
|
||||
desc->mInstanceData = InstanceData(GetCairoScaledFont(), mPattern);
|
||||
memcpy(data + sizeof(FontDescriptor), pathname, pathLength);
|
||||
|
||||
aCb(data, dataLength, mSize, aBaton);
|
||||
delete[] data;
|
||||
return true;
|
||||
const ScaledFontFontconfig::InstanceData *instanceData =
|
||||
reinterpret_cast<const ScaledFontFontconfig::InstanceData*>(aInstanceData);
|
||||
return ScaledFontFontconfig::CreateFromInstanceData(*instanceData, this, aGlyphSize);
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
ScaledFontFontconfig::CreateFromInstanceData(const InstanceData& aInstanceData,
|
||||
FT_Face aFace, const char* aPathname, uint32_t aIndex,
|
||||
UnscaledFontFontconfig* aUnscaledFont,
|
||||
Float aSize)
|
||||
|
||||
{
|
||||
FcPattern* pattern = FcPatternCreate();
|
||||
if (!pattern) {
|
||||
gfxWarning() << "Failing initializing Fontconfig pattern for scaled font";
|
||||
return nullptr;
|
||||
}
|
||||
if (aFace) {
|
||||
FcPatternAddFTFace(pattern, FC_FT_FACE, aFace);
|
||||
if (aUnscaledFont->GetFace()) {
|
||||
FcPatternAddFTFace(pattern, FC_FT_FACE, aUnscaledFont->GetFace());
|
||||
} else {
|
||||
FcPatternAddString(pattern, FC_FILE, reinterpret_cast<const FcChar8*>(aPathname));
|
||||
FcPatternAddInteger(pattern, FC_INDEX, aIndex);
|
||||
FcPatternAddString(pattern, FC_FILE, reinterpret_cast<const FcChar8*>(aUnscaledFont->GetFile()));
|
||||
FcPatternAddInteger(pattern, FC_INDEX, aUnscaledFont->GetIndex());
|
||||
}
|
||||
FcPatternAddDouble(pattern, FC_PIXEL_SIZE, aSize);
|
||||
aInstanceData.SetupPattern(pattern);
|
||||
@ -332,15 +293,15 @@ ScaledFontFontconfig::CreateFromInstanceData(const InstanceData& aInstanceData,
|
||||
}
|
||||
|
||||
RefPtr<ScaledFontFontconfig> scaledFont =
|
||||
new ScaledFontFontconfig(cairoScaledFont, pattern, nullptr, aSize);
|
||||
new ScaledFontFontconfig(cairoScaledFont, pattern, aUnscaledFont, aSize);
|
||||
|
||||
FcPatternDestroy(pattern);
|
||||
|
||||
return scaledFont.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
ScaledFontFontconfig::CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength, Float aSize)
|
||||
already_AddRefed<UnscaledFont>
|
||||
UnscaledFontFontconfig::CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength)
|
||||
{
|
||||
if (aDataLength < sizeof(FontDescriptor)) {
|
||||
gfxWarning() << "Fontconfig font descriptor is truncated.";
|
||||
@ -352,12 +313,14 @@ ScaledFontFontconfig::CreateFromFontDescriptor(const uint8_t* aData, uint32_t aD
|
||||
gfxWarning() << "Pathname in Fontconfig font descriptor has invalid size.";
|
||||
return nullptr;
|
||||
}
|
||||
const char* pathname = reinterpret_cast<const char*>(aData + sizeof(FontDescriptor));
|
||||
if (pathname[desc->mPathLength - 1] != '\0') {
|
||||
const char* path = reinterpret_cast<const char*>(aData + sizeof(FontDescriptor));
|
||||
if (path[desc->mPathLength - 1] != '\0') {
|
||||
gfxWarning() << "Pathname in Fontconfig font descriptor is not terminated.";
|
||||
return nullptr;
|
||||
}
|
||||
return CreateFromInstanceData(desc->mInstanceData, nullptr, pathname, desc->mIndex, aSize);
|
||||
|
||||
RefPtr<UnscaledFont> unscaledFont = new UnscaledFontFontconfig(path, desc->mIndex);
|
||||
return unscaledFont.forget();
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
|
@ -14,6 +14,7 @@ namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class NativeFontResourceFontconfig;
|
||||
class UnscaledFontFontconfig;
|
||||
|
||||
class ScaledFontFontconfig : public ScaledFontBase
|
||||
{
|
||||
@ -31,17 +32,11 @@ public:
|
||||
|
||||
bool CanSerialize() override { return true; }
|
||||
|
||||
bool GetFontFileData(FontFileDataOutput aDataCallback, void* aBaton) override;
|
||||
|
||||
bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override;
|
||||
|
||||
bool GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton) override;
|
||||
|
||||
static already_AddRefed<ScaledFont>
|
||||
CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength, Float aSize);
|
||||
|
||||
private:
|
||||
friend class NativeFontResourceFontconfig;
|
||||
friend class UnscaledFontFontconfig;
|
||||
|
||||
struct InstanceData
|
||||
{
|
||||
@ -68,16 +63,9 @@ private:
|
||||
Float mSkew;
|
||||
};
|
||||
|
||||
struct FontDescriptor
|
||||
{
|
||||
uint32_t mPathLength;
|
||||
uint32_t mIndex;
|
||||
InstanceData mInstanceData;
|
||||
};
|
||||
|
||||
static already_AddRefed<ScaledFont>
|
||||
CreateFromInstanceData(const InstanceData& aInstanceData,
|
||||
FT_Face aFace, const char* aPathname, uint32_t aIndex,
|
||||
UnscaledFontFontconfig* aUnscaledFont,
|
||||
Float aSize);
|
||||
|
||||
FcPattern* mPattern;
|
||||
|
@ -4,6 +4,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ScaledFontMac.h"
|
||||
#include "UnscaledFontMac.h"
|
||||
#ifdef USE_SKIA
|
||||
#include "PathSkia.h"
|
||||
#include "skia/include/core/SkPaint.h"
|
||||
@ -31,6 +32,40 @@ CGPathRef CGFontGetGlyphPath(CGFontRef fontRef, CGAffineTransform *textTransform
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
// Simple helper class to automatically release a CFObject when it goes out
|
||||
// of scope.
|
||||
template<class T>
|
||||
class AutoRelease
|
||||
{
|
||||
public:
|
||||
explicit AutoRelease(T aObject)
|
||||
: mObject(aObject)
|
||||
{
|
||||
}
|
||||
|
||||
~AutoRelease()
|
||||
{
|
||||
if (mObject) {
|
||||
CFRelease(mObject);
|
||||
}
|
||||
}
|
||||
|
||||
operator T()
|
||||
{
|
||||
return mObject;
|
||||
}
|
||||
|
||||
T forget()
|
||||
{
|
||||
T obj = mObject;
|
||||
mObject = nullptr;
|
||||
return obj;
|
||||
}
|
||||
|
||||
private:
|
||||
T mObject;
|
||||
};
|
||||
|
||||
ScaledFontMac::CTFontDrawGlyphsFuncT* ScaledFontMac::CTFontDrawGlyphsPtr = nullptr;
|
||||
bool ScaledFontMac::sSymbolLookupDone = false;
|
||||
|
||||
@ -69,7 +104,8 @@ CreateCTFontFromCGFontWithVariations(CGFontRef aCGFont, CGFloat aSize)
|
||||
|
||||
ScaledFontMac::ScaledFontMac(CGFontRef aFont,
|
||||
const RefPtr<UnscaledFont>& aUnscaledFont,
|
||||
Float aSize)
|
||||
Float aSize,
|
||||
bool aOwnsFont)
|
||||
: ScaledFontBase(aUnscaledFont, aSize)
|
||||
{
|
||||
if (!sSymbolLookupDone) {
|
||||
@ -78,8 +114,11 @@ ScaledFontMac::ScaledFontMac(CGFontRef aFont,
|
||||
sSymbolLookupDone = true;
|
||||
}
|
||||
|
||||
if (!aOwnsFont) {
|
||||
// XXX: should we be taking a reference
|
||||
mFont = CGFontRetain(aFont);
|
||||
}
|
||||
|
||||
if (CTFontDrawGlyphsPtr != nullptr) {
|
||||
// only create mCTFont if we're going to be using the CTFontDrawGlyphs API
|
||||
mCTFont = CreateCTFontFromCGFontWithVariations(aFont, aSize);
|
||||
@ -214,7 +253,7 @@ static void CollectVariationSetting(const void *key, const void *value, void *co
|
||||
}
|
||||
|
||||
bool
|
||||
ScaledFontMac::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton)
|
||||
UnscaledFontMac::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton)
|
||||
{
|
||||
// We'll reconstruct a TTF font from the tables we can get from the CGFont
|
||||
CFArrayRef tags = CGFontCopyTableTags(mFont);
|
||||
@ -281,6 +320,15 @@ ScaledFontMac::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton)
|
||||
// set checkSumAdjust to the computed checksum
|
||||
memcpy(&buf.data[checkSumAdjustmentOffset], &fontChecksum, sizeof(fontChecksum));
|
||||
|
||||
// we always use an index of 0
|
||||
aDataCallback(buf.data, buf.offset, 0, aBaton);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ScaledFontMac::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton)
|
||||
{
|
||||
// Collect any variation settings that were incorporated into the CTFont.
|
||||
uint32_t variationCount = 0;
|
||||
VariationSetting* variations = nullptr;
|
||||
@ -302,12 +350,158 @@ ScaledFontMac::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton)
|
||||
}
|
||||
}
|
||||
|
||||
// we always use an index of 0
|
||||
aDataCallback(buf.data, buf.offset, 0, mSize, variationCount, variations, aBaton);
|
||||
aCb(reinterpret_cast<uint8_t*>(variations), variationCount * sizeof(VariationSetting), aBaton);
|
||||
delete[] variations;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static CFDictionaryRef
|
||||
CreateVariationDictionaryOrNull(CGFontRef aCGFont, uint32_t aVariationCount,
|
||||
const ScaledFont::VariationSetting* aVariations)
|
||||
{
|
||||
// Avoid calling potentially buggy variation APIs on pre-Sierra macOS
|
||||
// versions (see bug 1331683)
|
||||
if (!nsCocoaFeatures::OnSierraOrLater()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoRelease<CTFontRef>
|
||||
ctFont(CTFontCreateWithGraphicsFont(aCGFont, 0, nullptr, nullptr));
|
||||
AutoRelease<CFArrayRef> axes(CTFontCopyVariationAxes(ctFont));
|
||||
if (!axes) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CFIndex axisCount = CFArrayGetCount(axes);
|
||||
AutoRelease<CFMutableDictionaryRef>
|
||||
dict(CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks));
|
||||
|
||||
// Number of variation settings passed in the aVariations parameter.
|
||||
// This will typically be a very low value, so we just linear-search them.
|
||||
bool allDefaultValues = true;
|
||||
|
||||
for (CFIndex i = 0; i < axisCount; ++i) {
|
||||
// We sanity-check the axis info found in the CTFont, and bail out
|
||||
// (returning null) if it doesn't have the expected types.
|
||||
CFTypeRef axisInfo = CFArrayGetValueAtIndex(axes, i);
|
||||
if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
|
||||
return nullptr;
|
||||
}
|
||||
CFDictionaryRef axis = static_cast<CFDictionaryRef>(axisInfo);
|
||||
|
||||
CFTypeRef axisTag =
|
||||
CFDictionaryGetValue(axis, kCTFontVariationAxisIdentifierKey);
|
||||
if (!axisTag || CFGetTypeID(axisTag) != CFNumberGetTypeID()) {
|
||||
return nullptr;
|
||||
}
|
||||
int64_t tagLong;
|
||||
if (!CFNumberGetValue(static_cast<CFNumberRef>(axisTag),
|
||||
kCFNumberSInt64Type, &tagLong)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CFTypeRef axisName =
|
||||
CFDictionaryGetValue(axis, kCTFontVariationAxisNameKey);
|
||||
if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Clamp axis values to the supported range.
|
||||
CFTypeRef min = CFDictionaryGetValue(axis, kCTFontVariationAxisMinimumValueKey);
|
||||
CFTypeRef max = CFDictionaryGetValue(axis, kCTFontVariationAxisMaximumValueKey);
|
||||
CFTypeRef def = CFDictionaryGetValue(axis, kCTFontVariationAxisDefaultValueKey);
|
||||
if (!min || CFGetTypeID(min) != CFNumberGetTypeID() ||
|
||||
!max || CFGetTypeID(max) != CFNumberGetTypeID() ||
|
||||
!def || CFGetTypeID(def) != CFNumberGetTypeID()) {
|
||||
return nullptr;
|
||||
}
|
||||
double minDouble;
|
||||
double maxDouble;
|
||||
double defDouble;
|
||||
if (!CFNumberGetValue(static_cast<CFNumberRef>(min), kCFNumberDoubleType,
|
||||
&minDouble) ||
|
||||
!CFNumberGetValue(static_cast<CFNumberRef>(max), kCFNumberDoubleType,
|
||||
&maxDouble) ||
|
||||
!CFNumberGetValue(static_cast<CFNumberRef>(def), kCFNumberDoubleType,
|
||||
&defDouble)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
double value = defDouble;
|
||||
for (uint32_t j = 0; j < aVariationCount; ++j) {
|
||||
if (aVariations[j].mTag == tagLong) {
|
||||
value = std::min(std::max<double>(aVariations[j].mValue,
|
||||
minDouble),
|
||||
maxDouble);
|
||||
if (value != defDouble) {
|
||||
allDefaultValues = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
AutoRelease<CFNumberRef> valueNumber(CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberDoubleType,
|
||||
&value));
|
||||
CFDictionaryAddValue(dict, axisName, valueNumber);
|
||||
}
|
||||
|
||||
if (allDefaultValues) {
|
||||
// We didn't actually set any non-default values, so throw away the
|
||||
// variations dictionary and just use the default rendering.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return dict.forget();
|
||||
}
|
||||
|
||||
CGFontRef
|
||||
UnscaledFontMac::CreateCGFontWithVariations(CGFontRef aFont,
|
||||
uint32_t aVariationCount,
|
||||
const ScaledFont::VariationSetting* aVariations)
|
||||
{
|
||||
MOZ_ASSERT(aVariationCount > 0);
|
||||
MOZ_ASSERT(aVariations);
|
||||
|
||||
AutoRelease<CFDictionaryRef>
|
||||
varDict(CreateVariationDictionaryOrNull(aFont, aVariationCount, aVariations));
|
||||
if (!varDict) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return CGFontCreateCopyWithVariations(aFont, varDict);
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
UnscaledFontMac::CreateScaledFont(Float aGlyphSize,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength)
|
||||
{
|
||||
uint32_t variationCount =
|
||||
aInstanceDataLength / sizeof(ScaledFont::VariationSetting);
|
||||
const ScaledFont::VariationSetting* variations =
|
||||
reinterpret_cast<const ScaledFont::VariationSetting*>(aInstanceData);
|
||||
|
||||
CGFontRef fontRef = mFont;
|
||||
if (variationCount > 0) {
|
||||
CGFontRef varFont =
|
||||
CreateCGFontWithVariations(mFont, variationCount, variations);
|
||||
if (varFont) {
|
||||
fontRef = varFont;
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<ScaledFontMac> scaledFont =
|
||||
new ScaledFontMac(fontRef, this, aGlyphSize, fontRef != mFont);
|
||||
|
||||
if (!scaledFont->PopulateCairoScaledFont()) {
|
||||
gfxWarning() << "Unable to create cairo scaled Mac font.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return scaledFont.forget();
|
||||
}
|
||||
|
||||
#ifdef USE_CAIRO_SCALED_FONT
|
||||
|
@ -40,20 +40,22 @@ private:
|
||||
class ScaledFontMac : public ScaledFontBase
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontMac)
|
||||
ScaledFontMac(CGFontRef aFont, const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize);
|
||||
virtual ~ScaledFontMac();
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontMac, override)
|
||||
ScaledFontMac(CGFontRef aFont, const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize, bool aOwnsFont = false);
|
||||
~ScaledFontMac();
|
||||
|
||||
virtual FontType GetType() const { return FontType::MAC; }
|
||||
FontType GetType() const override { return FontType::MAC; }
|
||||
#ifdef USE_SKIA
|
||||
virtual SkTypeface* GetSkTypeface();
|
||||
SkTypeface* GetSkTypeface() override;
|
||||
#endif
|
||||
virtual already_AddRefed<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget);
|
||||
virtual bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton);
|
||||
virtual bool CanSerialize() { return true; }
|
||||
already_AddRefed<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget) override;
|
||||
|
||||
bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override;
|
||||
|
||||
bool CanSerialize() override { return true; }
|
||||
|
||||
#ifdef USE_CAIRO_SCALED_FONT
|
||||
cairo_font_face_t* GetCairoFontFace();
|
||||
cairo_font_face_t* GetCairoFontFace() override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
@ -4,6 +4,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ScaledFontWin.h"
|
||||
#include "UnscaledFontGDI.h"
|
||||
|
||||
#include "AutoHelpersWin.h"
|
||||
#include "Logging.h"
|
||||
@ -31,7 +32,7 @@ ScaledFontWin::ScaledFontWin(const LOGFONT* aFont,
|
||||
}
|
||||
|
||||
bool
|
||||
ScaledFontWin::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton)
|
||||
UnscaledFontGDI::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton)
|
||||
{
|
||||
AutoDC dc;
|
||||
AutoSelectFont font(dc.GetDC(), &mLogFont);
|
||||
@ -56,7 +57,7 @@ ScaledFontWin::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton)
|
||||
return false;
|
||||
}
|
||||
|
||||
aDataCallback(fontData.get(), tableSize, 0, mSize, 0, nullptr, aBaton);
|
||||
aDataCallback(fontData.get(), tableSize, 0, aBaton);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -68,21 +69,41 @@ ScaledFontWin::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton)
|
||||
}
|
||||
|
||||
bool
|
||||
ScaledFontWin::GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton)
|
||||
UnscaledFontGDI::GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton)
|
||||
{
|
||||
aCb(reinterpret_cast<uint8_t*>(&mLogFont), sizeof(mLogFont), mSize, aBaton);
|
||||
aCb(reinterpret_cast<uint8_t*>(&mLogFont), sizeof(mLogFont), aBaton);
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
ScaledFontWin::CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength, Float aSize)
|
||||
already_AddRefed<UnscaledFont>
|
||||
UnscaledFontGDI::CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength)
|
||||
{
|
||||
if (aDataLength < sizeof(LOGFONT)) {
|
||||
gfxWarning() << "GDI font descriptor is truncated.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const LOGFONT* logFont = reinterpret_cast<const LOGFONT*>(aData);
|
||||
RefPtr<UnscaledFont> unscaledFont = new UnscaledFontGDI(*logFont);
|
||||
return unscaledFont.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
UnscaledFontGDI::CreateScaledFont(Float aGlyphSize,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength)
|
||||
{
|
||||
if (aInstanceDataLength < sizeof(LOGFONT)) {
|
||||
gfxWarning() << "GDI unscaled font instance data is truncated.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NativeFont nativeFont;
|
||||
nativeFont.mType = NativeFontType::GDI_FONT_FACE;
|
||||
nativeFont.mFont = (void*)aData;
|
||||
nativeFont.mFont = (void*)aInstanceData;
|
||||
|
||||
RefPtr<ScaledFont> font =
|
||||
Factory::CreateScaledFontForNativeFont(nativeFont, nullptr, aSize);
|
||||
Factory::CreateScaledFontForNativeFont(nativeFont, this, aGlyphSize);
|
||||
|
||||
#ifdef USE_CAIRO_SCALED_FONT
|
||||
static_cast<ScaledFontBase*>(font.get())->PopulateCairoScaledFont();
|
||||
|
@ -15,26 +15,19 @@ namespace gfx {
|
||||
class ScaledFontWin : public ScaledFontBase
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontWin)
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontWin, override)
|
||||
ScaledFontWin(const LOGFONT* aFont,
|
||||
const RefPtr<UnscaledFont>& aUnscaledFont,
|
||||
Float aSize);
|
||||
|
||||
virtual FontType GetType() const { return FontType::GDI; }
|
||||
|
||||
bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton) override;
|
||||
FontType GetType() const override { return FontType::GDI; }
|
||||
|
||||
bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override;
|
||||
|
||||
virtual bool GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton) override;
|
||||
|
||||
static already_AddRefed<ScaledFont>
|
||||
CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength, Float aSize);
|
||||
|
||||
virtual AntialiasMode GetDefaultAAMode() override;
|
||||
AntialiasMode GetDefaultAAMode() override;
|
||||
|
||||
#ifdef USE_SKIA
|
||||
virtual SkTypeface* GetSkTypeface();
|
||||
SkTypeface* GetSkTypeface() override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
@ -19,9 +19,11 @@ public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(UnscaledFontDWrite, override)
|
||||
explicit UnscaledFontDWrite(const RefPtr<IDWriteFontFace>& aFontFace,
|
||||
DWRITE_FONT_SIMULATIONS aSimulations =
|
||||
DWRITE_FONT_SIMULATIONS_NONE)
|
||||
: mFontFace(aFontFace),
|
||||
mSimulations(aSimulations)
|
||||
DWRITE_FONT_SIMULATIONS_NONE,
|
||||
bool aNeedsCairo = false)
|
||||
: mFontFace(aFontFace)
|
||||
, mSimulations(aSimulations)
|
||||
, mNeedsCairo(aNeedsCairo)
|
||||
{}
|
||||
|
||||
FontType GetType() const override { return FontType::DWRITE; }
|
||||
@ -29,9 +31,17 @@ public:
|
||||
const RefPtr<IDWriteFontFace> GetFontFace() const { return mFontFace; }
|
||||
DWRITE_FONT_SIMULATIONS GetSimulations() const { return mSimulations; }
|
||||
|
||||
bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton) override;
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
CreateScaledFont(Float aGlyphSize,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength) override;
|
||||
|
||||
private:
|
||||
RefPtr<IDWriteFontFace> mFontFace;
|
||||
DWRITE_FONT_SIMULATIONS mSimulations;
|
||||
bool mNeedsCairo;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
53
gfx/2d/UnscaledFontFreeType.cpp
Normal file
53
gfx/2d/UnscaledFontFreeType.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#include "UnscaledFontFreeType.h"
|
||||
|
||||
#include FT_TRUETYPE_TABLES_H
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
bool
|
||||
UnscaledFontFreeType::GetFontFileData(FontFileDataOutput aDataCallback, void* aBaton)
|
||||
{
|
||||
bool success = false;
|
||||
FT_ULong length = 0;
|
||||
// Request the SFNT file. This may not always succeed for all font types.
|
||||
if (FT_Load_Sfnt_Table(mFace, 0, 0, nullptr, &length) == FT_Err_Ok) {
|
||||
uint8_t* fontData = new uint8_t[length];
|
||||
if (FT_Load_Sfnt_Table(mFace, 0, 0, fontData, &length) == FT_Err_Ok) {
|
||||
aDataCallback(fontData, length, 0, aBaton);
|
||||
success = true;
|
||||
}
|
||||
delete[] fontData;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
UnscaledFontFreeType::GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton)
|
||||
{
|
||||
if (mFile.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* path = mFile.c_str();
|
||||
size_t pathLength = strlen(path) + 1;
|
||||
size_t dataLength = sizeof(FontDescriptor) + pathLength;
|
||||
uint8_t* data = new uint8_t[dataLength];
|
||||
FontDescriptor* desc = reinterpret_cast<FontDescriptor*>(data);
|
||||
desc->mPathLength = pathLength;
|
||||
desc->mIndex = mIndex;
|
||||
memcpy(data + sizeof(FontDescriptor), path, pathLength);
|
||||
|
||||
aCb(data, dataLength, aBaton);
|
||||
delete[] data;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
@ -17,16 +17,25 @@ class UnscaledFontFreeType : public UnscaledFont
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(UnscaledFontFreeType, override)
|
||||
explicit UnscaledFontFreeType(FT_Face aFace)
|
||||
explicit UnscaledFontFreeType(FT_Face aFace,
|
||||
bool aOwnsFace = false)
|
||||
: mFace(aFace)
|
||||
, mOwnsFace(aOwnsFace)
|
||||
, mIndex(0)
|
||||
{}
|
||||
explicit UnscaledFontFreeType(const char* aFile,
|
||||
uint32_t aIndex = 0)
|
||||
: mFace(nullptr)
|
||||
, mOwnsFace(false)
|
||||
, mFile(aFile)
|
||||
, mIndex(aIndex)
|
||||
{}
|
||||
~UnscaledFontFreeType()
|
||||
{
|
||||
if (mOwnsFace) {
|
||||
FT_Done_Face(mFace);
|
||||
}
|
||||
}
|
||||
|
||||
FontType GetType() const override { return FontType::FREETYPE; }
|
||||
|
||||
@ -34,8 +43,19 @@ public:
|
||||
const char* GetFile() const { return mFile.c_str(); }
|
||||
uint32_t GetIndex() const { return mIndex; }
|
||||
|
||||
struct FontDescriptor
|
||||
{
|
||||
uint32_t mPathLength;
|
||||
uint32_t mIndex;
|
||||
};
|
||||
|
||||
bool GetFontFileData(FontFileDataOutput aDataCallback, void* aBaton) override;
|
||||
|
||||
bool GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton) override;
|
||||
|
||||
private:
|
||||
FT_Face mFace;
|
||||
bool mOwnsFace;
|
||||
std::string mFile;
|
||||
uint32_t mIndex;
|
||||
};
|
||||
@ -45,8 +65,9 @@ class UnscaledFontFontconfig : public UnscaledFontFreeType
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(UnscaledFontFontconfig, override)
|
||||
explicit UnscaledFontFontconfig(FT_Face aFace)
|
||||
: UnscaledFontFreeType(aFace)
|
||||
explicit UnscaledFontFontconfig(FT_Face aFace,
|
||||
bool aOwnsFace = false)
|
||||
: UnscaledFontFreeType(aFace, aOwnsFace)
|
||||
{}
|
||||
explicit UnscaledFontFontconfig(const char* aFile,
|
||||
uint32_t aIndex = 0)
|
||||
@ -54,6 +75,14 @@ public:
|
||||
{}
|
||||
|
||||
FontType GetType() const override { return FontType::FONTCONFIG; }
|
||||
|
||||
static already_AddRefed<UnscaledFont>
|
||||
CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength);
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
CreateScaledFont(Float aGlyphSize,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength) override;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -24,6 +24,18 @@ public:
|
||||
|
||||
const LOGFONT& GetLogFont() const { return mLogFont; }
|
||||
|
||||
bool GetFontFileData(FontFileDataOutput aDataCallback, void* aBaton) override;
|
||||
|
||||
bool GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton) override;
|
||||
|
||||
static already_AddRefed<UnscaledFont>
|
||||
CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength);
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
CreateScaledFont(Float aGlyphSize,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength) override;
|
||||
|
||||
private:
|
||||
LOGFONT mLogFont;
|
||||
};
|
||||
|
@ -36,6 +36,18 @@ public:
|
||||
|
||||
CGFontRef GetFont() const { return mFont; }
|
||||
|
||||
bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton) override;
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
CreateScaledFont(Float aGlyphSize,
|
||||
const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength) override;
|
||||
|
||||
static CGFontRef
|
||||
CreateCGFontWithVariations(CGFontRef aFont,
|
||||
uint32_t aVariationCount,
|
||||
const ScaledFont::VariationSetting* aVariations);
|
||||
|
||||
private:
|
||||
CGFontRef mFont;
|
||||
};
|
||||
|
@ -98,6 +98,9 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gtk3'):
|
||||
EXPORTS.mozilla.gfx += [
|
||||
'UnscaledFontFreeType.h',
|
||||
]
|
||||
SOURCES += [
|
||||
'UnscaledFontFreeType.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3'):
|
||||
SOURCES += [
|
||||
|
@ -156,13 +156,11 @@ struct FontFileData
|
||||
{
|
||||
wr::ByteBuffer mFontBuffer;
|
||||
uint32_t mFontIndex;
|
||||
float mGlyphSize;
|
||||
};
|
||||
|
||||
static void
|
||||
WriteFontFileData(const uint8_t* aData, uint32_t aLength, uint32_t aIndex,
|
||||
float aGlyphSize, uint32_t aVariationCount,
|
||||
const ScaledFont::VariationSetting* aVariations, void* aBaton)
|
||||
void* aBaton)
|
||||
{
|
||||
FontFileData* data = static_cast<FontFileData*>(aBaton);
|
||||
|
||||
@ -172,7 +170,6 @@ WriteFontFileData(const uint8_t* aData, uint32_t aLength, uint32_t aIndex,
|
||||
memcpy(data->mFontBuffer.mData, aData, aLength);
|
||||
|
||||
data->mFontIndex = aIndex;
|
||||
data->mGlyphSize = aGlyphSize;
|
||||
}
|
||||
|
||||
void
|
||||
@ -228,7 +225,7 @@ WebRenderBridgeChild::GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont)
|
||||
}
|
||||
|
||||
FontFileData data;
|
||||
if (!aScaledFont->GetFontFileData(WriteFontFileData, &data) ||
|
||||
if (!unscaled->GetFontFileData(WriteFontFileData, &data) ||
|
||||
!data.mFontBuffer.mData) {
|
||||
return key;
|
||||
}
|
||||
|
@ -23,142 +23,6 @@
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
// Simple helper class to automatically release a CFObject when it goes out
|
||||
// of scope.
|
||||
template<class T>
|
||||
class AutoRelease
|
||||
{
|
||||
public:
|
||||
explicit AutoRelease(T aObject)
|
||||
: mObject(aObject)
|
||||
{
|
||||
}
|
||||
|
||||
~AutoRelease()
|
||||
{
|
||||
if (mObject) {
|
||||
CFRelease(mObject);
|
||||
}
|
||||
}
|
||||
|
||||
operator T()
|
||||
{
|
||||
return mObject;
|
||||
}
|
||||
|
||||
T forget()
|
||||
{
|
||||
T obj = mObject;
|
||||
mObject = nullptr;
|
||||
return obj;
|
||||
}
|
||||
|
||||
private:
|
||||
T mObject;
|
||||
};
|
||||
|
||||
static CFDictionaryRef
|
||||
CreateVariationDictionaryOrNull(CGFontRef aCGFont,
|
||||
const nsTArray<gfxFontVariation>& aVariations)
|
||||
{
|
||||
// Avoid calling potentially buggy variation APIs on pre-Sierra macOS
|
||||
// versions (see bug 1331683)
|
||||
if (!nsCocoaFeatures::OnSierraOrLater()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoRelease<CTFontRef>
|
||||
ctFont(CTFontCreateWithGraphicsFont(aCGFont, 0, nullptr, nullptr));
|
||||
AutoRelease<CFArrayRef> axes(CTFontCopyVariationAxes(ctFont));
|
||||
if (!axes) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CFIndex axisCount = CFArrayGetCount(axes);
|
||||
AutoRelease<CFMutableDictionaryRef>
|
||||
dict(CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks));
|
||||
|
||||
// Number of variation settings passed in the aVariations parameter.
|
||||
// This will typically be a very low value, so we just linear-search them.
|
||||
uint32_t numVars = aVariations.Length();
|
||||
bool allDefaultValues = true;
|
||||
|
||||
for (CFIndex i = 0; i < axisCount; ++i) {
|
||||
// We sanity-check the axis info found in the CTFont, and bail out
|
||||
// (returning null) if it doesn't have the expected types.
|
||||
CFTypeRef axisInfo = CFArrayGetValueAtIndex(axes, i);
|
||||
if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) {
|
||||
return nullptr;
|
||||
}
|
||||
CFDictionaryRef axis = static_cast<CFDictionaryRef>(axisInfo);
|
||||
|
||||
CFTypeRef axisTag =
|
||||
CFDictionaryGetValue(axis, kCTFontVariationAxisIdentifierKey);
|
||||
if (!axisTag || CFGetTypeID(axisTag) != CFNumberGetTypeID()) {
|
||||
return nullptr;
|
||||
}
|
||||
int64_t tagLong;
|
||||
if (!CFNumberGetValue(static_cast<CFNumberRef>(axisTag),
|
||||
kCFNumberSInt64Type, &tagLong)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CFTypeRef axisName =
|
||||
CFDictionaryGetValue(axis, kCTFontVariationAxisNameKey);
|
||||
if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Clamp axis values to the supported range.
|
||||
CFTypeRef min = CFDictionaryGetValue(axis, kCTFontVariationAxisMinimumValueKey);
|
||||
CFTypeRef max = CFDictionaryGetValue(axis, kCTFontVariationAxisMaximumValueKey);
|
||||
CFTypeRef def = CFDictionaryGetValue(axis, kCTFontVariationAxisDefaultValueKey);
|
||||
if (!min || CFGetTypeID(min) != CFNumberGetTypeID() ||
|
||||
!max || CFGetTypeID(max) != CFNumberGetTypeID() ||
|
||||
!def || CFGetTypeID(def) != CFNumberGetTypeID()) {
|
||||
return nullptr;
|
||||
}
|
||||
double minDouble;
|
||||
double maxDouble;
|
||||
double defDouble;
|
||||
if (!CFNumberGetValue(static_cast<CFNumberRef>(min), kCFNumberDoubleType,
|
||||
&minDouble) ||
|
||||
!CFNumberGetValue(static_cast<CFNumberRef>(max), kCFNumberDoubleType,
|
||||
&maxDouble) ||
|
||||
!CFNumberGetValue(static_cast<CFNumberRef>(def), kCFNumberDoubleType,
|
||||
&defDouble)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
double value = defDouble;
|
||||
for (uint32_t j = 0; j < numVars; ++j) {
|
||||
if (aVariations[j].mTag == tagLong) {
|
||||
value = std::min(std::max<double>(aVariations[j].mValue,
|
||||
minDouble),
|
||||
maxDouble);
|
||||
if (value != defDouble) {
|
||||
allDefaultValues = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
AutoRelease<CFNumberRef> valueNumber(CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberDoubleType,
|
||||
&value));
|
||||
CFDictionaryAddValue(dict, axisName, valueNumber);
|
||||
}
|
||||
|
||||
if (allDefaultValues) {
|
||||
// We didn't actually set any non-default values, so throw away the
|
||||
// variations dictionary and just use the default rendering.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return dict.forget();
|
||||
}
|
||||
|
||||
gfxMacFont::gfxMacFont(const RefPtr<UnscaledFontMac>& aUnscaledFont,
|
||||
MacOSFontEntry *aFontEntry,
|
||||
const gfxFontStyle *aFontStyle,
|
||||
@ -177,12 +41,14 @@ gfxMacFont::gfxMacFont(const RefPtr<UnscaledFontMac>& aUnscaledFont,
|
||||
mIsValid = false;
|
||||
return;
|
||||
}
|
||||
CFDictionaryRef variations =
|
||||
CreateVariationDictionaryOrNull(baseFont, aFontStyle->variationSettings);
|
||||
if (variations) {
|
||||
mCGFont = ::CGFontCreateCopyWithVariations(baseFont, variations);
|
||||
::CFRelease(variations);
|
||||
} else {
|
||||
MOZ_ASSERT(sizeof(ScaledFont::VariationSetting) == sizeof(gfxFontVariation));
|
||||
mCGFont =
|
||||
UnscaledFontMac::CreateCGFontWithVariations(
|
||||
baseFont,
|
||||
aFontStyle->variationSettings.Length(),
|
||||
reinterpret_cast<const ScaledFont::VariationSetting*>(
|
||||
aFontStyle->variationSettings.Elements()));
|
||||
if (!mCGFont) {
|
||||
::CFRetain(baseFont);
|
||||
mCGFont = baseFont;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ using gfx::SourceSurface;
|
||||
using gfx::FilterNode;
|
||||
using gfx::GradientStops;
|
||||
using gfx::ScaledFont;
|
||||
using gfx::UnscaledFont;
|
||||
using gfx::NativeFontResource;
|
||||
|
||||
class PrintTranslator final : public Translator
|
||||
@ -78,6 +79,13 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
UnscaledFont* LookupUnscaledFont(ReferencePtr aRefPtr) final
|
||||
{
|
||||
UnscaledFont* result = mUnscaledFonts.GetWeak(aRefPtr);
|
||||
MOZ_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
NativeFontResource* LookupNativeFontResource(uint64_t aKey) final
|
||||
{
|
||||
NativeFontResource* result = mNativeFontResources.GetWeak(aKey);
|
||||
@ -115,6 +123,11 @@ public:
|
||||
mScaledFonts.Put(aRefPtr, aScaledFont);
|
||||
}
|
||||
|
||||
void AddUnscaledFont(ReferencePtr aRefPtr, UnscaledFont* aUnscaledFont) final
|
||||
{
|
||||
mUnscaledFonts.Put(aRefPtr, aUnscaledFont);
|
||||
}
|
||||
|
||||
void AddNativeFontResource(uint64_t aKey,
|
||||
NativeFontResource *aScaledFontResouce) final
|
||||
{
|
||||
@ -151,6 +164,11 @@ public:
|
||||
mScaledFonts.Remove(aRefPtr);
|
||||
}
|
||||
|
||||
void RemoveUnscaledFont(ReferencePtr aRefPtr) final
|
||||
{
|
||||
mUnscaledFonts.Remove(aRefPtr);
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget> CreateDrawTarget(ReferencePtr aRefPtr,
|
||||
const gfx::IntSize &aSize,
|
||||
gfx::SurfaceFormat aFormat) final;
|
||||
@ -169,6 +187,7 @@ private:
|
||||
nsRefPtrHashtable<nsPtrHashKey<void>, FilterNode> mFilterNodes;
|
||||
nsRefPtrHashtable<nsPtrHashKey<void>, GradientStops> mGradientStops;
|
||||
nsRefPtrHashtable<nsPtrHashKey<void>, ScaledFont> mScaledFonts;
|
||||
nsRefPtrHashtable<nsPtrHashKey<void>, UnscaledFont> mUnscaledFonts;
|
||||
nsRefPtrHashtable<nsUint64HashKey, NativeFontResource> mNativeFontResources;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user