Bug 1355931 - move font serialization from ScaledFont to UnscaledFont. r=jrmuizel

MozReview-Commit-ID: 3d1XMoe2BKj
This commit is contained in:
Lee Salzman 2017-04-14 14:11:00 -04:00
parent a363fb8c8b
commit 28471864af
31 changed files with 763 additions and 639 deletions

View File

@ -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

View File

@ -388,32 +388,39 @@ DrawTargetRecording::FillGlyphs(ScaledFont *aFont,
{
EnsurePatternDependenciesStored(aPattern);
if (!aFont->GetUserData(reinterpret_cast<UserDataKey*>(mRecorder.get()))) {
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);
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
// is not present on the system.
if (!mRecorder->HasStoredFontData(fontDetails.fontDataKey)) {
mRecorder->RecordEvent(fontData);
mRecorder->AddStoredFontData(fontDetails.fontDataKey);
}
mRecorder->RecordEvent(RecordedUnscaledFontCreation(unscaledFont, fontDetails));
} else {
gfxWarning() << "DrawTargetRecording::FillGlyphs failed to serialise ScaledFont";
// If that fails, record just the font description and try to load it from
// the system on the other side.
RecordedFontDescriptor fontDesc(unscaledFont);
if (fontDesc.IsValid()) {
mRecorder->RecordEvent(fontDesc);
} else {
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));

View File

@ -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;
}
}

View File

@ -131,6 +131,7 @@ enum class LogReason : int {
ProcessingError,
InvalidDrawTarget,
NativeFontResourceNotFound,
UnscaledFontNotFound,
// End
MustBeLessThanThis = 101,
};

View File

@ -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

View File

@ -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,

View File

@ -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,
const uint8_t* aInstanceData, uint32_t aInstanceDataLength)
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

View File

@ -23,9 +23,9 @@ public:
static already_AddRefed<NativeFontResourceFontconfig>
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;
~NativeFontResourceFontconfig();

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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()
{

View File

@ -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;

View File

@ -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);

View File

@ -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);
@ -242,13 +243,13 @@ ScaledFontDWrite::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton
UINT32 refKeySize;
// XXX - This can currently crash for webfonts, as when we get the reference
// key out of the file, that can be an invalid reference key for the loader
// we use it with. The fix to this is not obvious but it will probably
// we use it with. The fix to this is not obvious but it will probably
// have to happen inside thebes.
file->GetReferenceKey(&referenceKey, &refKeySize);
RefPtr<IDWriteFontFileLoader> loader;
file->GetLoader(getter_AddRefs(loader));
RefPtr<IDWriteFontFileStream> stream;
loader->CreateStreamFromKey(referenceKey, refKeySize, getter_AddRefs(stream));
@ -258,20 +259,33 @@ ScaledFontDWrite::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton
MOZ_ASSERT(false);
return false;
}
uint32_t fileSize = static_cast<uint32_t>(fileSize64);
const void *fragmentStart;
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()
{

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;
}
// XXX: should we be taking a reference
mFont = CGFontRetain(aFont);
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

View File

@ -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:

View File

@ -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();

View File

@ -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:

View File

@ -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

View 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

View File

@ -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

View File

@ -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;
};

View File

@ -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;
};

View File

@ -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 += [

View File

@ -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;
}

View File

@ -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,14 +41,16 @@ gfxMacFont::gfxMacFont(const RefPtr<UnscaledFontMac>& aUnscaledFont,
mIsValid = false;
return;
}
CFDictionaryRef variations =
CreateVariationDictionaryOrNull(baseFont, aFontStyle->variationSettings);
if (variations) {
mCGFont = ::CGFontCreateCopyWithVariations(baseFont, variations);
::CFRelease(variations);
} else {
::CFRetain(baseFont);
mCGFont = baseFont;
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;
}
} else {
mCGFont = aUnscaledFont->GetFont();

View File

@ -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;
};