Bug 1470515 - refactor ScaledFontFreeType for Android WR. r=rhunt

--HG--
rename : gfx/2d/NativeFontResourceFontconfig.cpp => gfx/2d/NativeFontResourceFreeType.cpp
rename : gfx/2d/NativeFontResourceFontconfig.h => gfx/2d/NativeFontResourceFreeType.h
rename : gfx/2d/ScaledFontCairo.cpp => gfx/2d/ScaledFontFreeType.cpp
rename : gfx/2d/ScaledFontCairo.h => gfx/2d/ScaledFontFreeType.h
This commit is contained in:
Lee Salzman 2018-06-14 16:42:56 -07:00
Родитель a2f9b1e3eb
Коммит 9e14da3f5a
24 изменённых файлов: 620 добавлений и 372 удалений

Просмотреть файл

@ -46,9 +46,6 @@ typedef _cairo_surface cairo_surface_t;
struct _cairo_scaled_font;
typedef _cairo_scaled_font cairo_scaled_font_t;
struct _FcPattern;
typedef _FcPattern FcPattern;
struct FT_LibraryRec_;
typedef FT_LibraryRec_* FT_Library;
@ -1643,17 +1640,6 @@ public:
static already_AddRefed<DrawTarget>
CreateDrawTargetForData(BackendType aBackend, unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat, bool aUninitialized = false);
static already_AddRefed<ScaledFont>
CreateScaledFontForNativeFont(const NativeFont &aNativeFont,
const RefPtr<UnscaledFont>& aUnscaledFont,
Float aSize);
#ifdef MOZ_WIDGET_GTK
static already_AddRefed<ScaledFont>
CreateScaledFontForFontconfigFont(cairo_scaled_font_t* aScaledFont, FcPattern* aPattern,
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize);
#endif
#ifdef XP_DARWIN
static already_AddRefed<ScaledFont>
CreateScaledFontForMacFont(CGFontRef aCGFont, const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
@ -1682,15 +1668,17 @@ public:
CreateUnscaledFontFromFontDescriptor(FontType aType, const uint8_t* aData, uint32_t aDataLength, uint32_t aIndex);
/**
* This creates a scaled font with an associated cairo_scaled_font_t, and
* must be used when using the Cairo backend. The NativeFont and
* cairo_scaled_font_t* parameters must correspond to the same font.
* Creates a ScaledFont from the supplied NativeFont.
*
* If aScaledFont is supplied, this creates a scaled font with an associated
* cairo_scaled_font_t. The NativeFont and cairo_scaled_font_t* parameters must
* correspond to the same font.
*/
static already_AddRefed<ScaledFont>
CreateScaledFontWithCairo(const NativeFont &aNativeFont,
const RefPtr<UnscaledFont>& aUnscaledFont,
Float aSize,
cairo_scaled_font_t* aScaledFont);
CreateScaledFontForNativeFont(const NativeFont &aNativeFont,
const RefPtr<UnscaledFont>& aUnscaledFont,
Float aSize,
cairo_scaled_font_t* aScaledFont = nullptr);
/**
* This creates a simple data source surface for a certain size. It allocates

Просмотреть файл

@ -7,7 +7,6 @@
#include "DrawTargetSkia.h"
#include "SourceSurfaceSkia.h"
#include "ScaledFontBase.h"
#include "ScaledFontCairo.h"
#include "FilterNodeSoftware.h"
#include "HelpersSkia.h"
@ -990,6 +989,7 @@ DrawTargetSkia::ShouldLCDRenderText(FontType aFontType, AntialiasMode aAntialias
case FontType::DWRITE:
case FontType::FONTCONFIG:
return true;
case FontType::FREETYPE:
default:
// TODO: Figure out what to do for the other platforms.
return false;
@ -1352,8 +1352,7 @@ static bool
CanDrawFont(ScaledFont* aFont)
{
switch (aFont->GetType()) {
case FontType::SKIA:
case FontType::CAIRO:
case FontType::FREETYPE:
case FontType::FONTCONFIG:
case FontType::MAC:
case FontType::GDI:
@ -1415,8 +1414,7 @@ DrawTargetSkia::DrawGlyphs(ScaledFont* aFont,
bool useSubpixelText = true;
switch (aFont->GetType()) {
case FontType::SKIA:
case FontType::CAIRO:
case FontType::FREETYPE:
case FontType::FONTCONFIG:
// SkFontHost_cairo does not support subpixel text positioning,
// so only enable it for other font hosts.

Просмотреть файл

@ -9,17 +9,12 @@
#ifdef USE_CAIRO
#include "DrawTargetCairo.h"
#include "ScaledFontCairo.h"
#include "SourceSurfaceCairo.h"
#endif
#ifdef USE_SKIA
#include "DrawTargetSkia.h"
#include "ScaledFontBase.h"
#ifdef MOZ_ENABLE_FREETYPE
#define USE_SKIA_FREETYPE
#include "ScaledFontCairo.h"
#endif
#endif
#if defined(WIN32)
@ -35,10 +30,15 @@
#ifdef MOZ_WIDGET_GTK
#include "ScaledFontFontconfig.h"
#include "NativeFontResourceFontconfig.h"
#include "NativeFontResourceFreeType.h"
#include "UnscaledFontFreeType.h"
#endif
#ifdef MOZ_WIDGET_ANDROID
#include "ScaledFontFreeType.h"
#include "NativeFontResourceFreeType.h"
#endif
#ifdef WIN32
#include "DrawTargetD2D1.h"
#include "ScaledFontDWrite.h"
@ -578,32 +578,29 @@ Factory::GetMaxSurfaceSize(BackendType aType)
already_AddRefed<ScaledFont>
Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont,
const RefPtr<UnscaledFont>& aUnscaledFont,
Float aSize)
Float aSize,
cairo_scaled_font_t* aScaledFont)
{
switch (aNativeFont.mType) {
#ifdef WIN32
case NativeFontType::DWRITE_FONT_FACE:
case NativeFontType::GDI_LOGFONT:
{
return MakeAndAddRef<ScaledFontDWrite>(static_cast<IDWriteFontFace*>(aNativeFont.mFont), aUnscaledFont, aSize);
}
#if defined(USE_CAIRO) || defined(USE_SKIA)
case NativeFontType::GDI_FONT_FACE:
{
return MakeAndAddRef<ScaledFontWin>(static_cast<LOGFONT*>(aNativeFont.mFont), aUnscaledFont, aSize);
}
RefPtr<ScaledFontWin> font = MakeAndAddRef<ScaledFontWin>(static_cast<LOGFONT*>(aNativeFont.mFont), aUnscaledFont, aSize);
#ifdef USE_CAIRO
if (aScaledFont) {
font->SetCairoScaledFont(aScaledFont);
} else {
font->PopulateCairoScaledFont();
}
#endif
#endif
#ifdef XP_DARWIN
case NativeFontType::MAC_FONT_FACE:
{
return MakeAndAddRef<ScaledFontMac>(static_cast<CGFontRef>(aNativeFont.mFont), aUnscaledFont, aSize);
}
#endif
#if defined(USE_CAIRO) || defined(USE_SKIA_FREETYPE)
case NativeFontType::CAIRO_FONT_FACE:
{
return MakeAndAddRef<ScaledFontCairo>(static_cast<cairo_scaled_font_t*>(aNativeFont.mFont), aUnscaledFont, aSize);
return font.forget();
}
#elif defined(MOZ_WIDGET_GTK)
case NativeFontType::FONTCONFIG_PATTERN:
return MakeAndAddRef<ScaledFontFontconfig>(aScaledFont, static_cast<FcPattern*>(aNativeFont.mFont), aUnscaledFont, aSize);
#elif defined(MOZ_WIDGET_ANDROID)
case NativeFontType::FREETYPE_FACE:
return MakeAndAddRef<ScaledFontFreeType>(aScaledFont, static_cast<FT_Face>(aNativeFont.mFont), aUnscaledFont, aSize);
#endif
default:
gfxWarning() << "Invalid native font type specified.";
@ -631,6 +628,10 @@ Factory::CreateNativeFontResource(uint8_t *aData, uint32_t aSize, BackendType aB
case FontType::FONTCONFIG:
return NativeFontResourceFontconfig::Create(aData, aSize,
static_cast<FT_Library>(aFontContext));
#elif defined(MOZ_WIDGET_ANDROID)
case FontType::FREETYPE:
return NativeFontResourceFreeType::Create(aData, aSize,
static_cast<FT_Library>(aFontContext));
#endif
default:
gfxWarning() << "Unable to create requested font resource from truetype data";
@ -656,34 +657,6 @@ Factory::CreateUnscaledFontFromFontDescriptor(FontType aType, const uint8_t* aDa
}
}
already_AddRefed<ScaledFont>
Factory::CreateScaledFontWithCairo(const NativeFont& aNativeFont,
const RefPtr<UnscaledFont>& aUnscaledFont,
Float aSize,
cairo_scaled_font_t* aScaledFont)
{
#ifdef USE_CAIRO
// In theory, we could pull the NativeFont out of the cairo_scaled_font_t*,
// but that would require a lot of code that would be otherwise repeated in
// various backends.
// Therefore, we just reuse CreateScaledFontForNativeFont's implementation.
RefPtr<ScaledFont> font = CreateScaledFontForNativeFont(aNativeFont, aUnscaledFont, aSize);
static_cast<ScaledFontBase*>(font.get())->SetCairoScaledFont(aScaledFont);
return font.forget();
#else
return nullptr;
#endif
}
#ifdef MOZ_WIDGET_GTK
already_AddRefed<ScaledFont>
Factory::CreateScaledFontForFontconfigFont(cairo_scaled_font_t* aScaledFont, FcPattern* aPattern,
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize)
{
return MakeAndAddRef<ScaledFontFontconfig>(aScaledFont, aPattern, aUnscaledFont, aSize);
}
#endif
#ifdef XP_DARWIN
already_AddRefed<ScaledFont>
Factory::CreateScaledFontForMacFont(CGFontRef aCGFont,

Просмотреть файл

@ -4,24 +4,23 @@
* 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 "NativeFontResourceFontconfig.h"
#include "ScaledFontFontconfig.h"
#include "NativeFontResourceFreeType.h"
#include "UnscaledFontFreeType.h"
#include "Logging.h"
namespace mozilla {
namespace gfx {
NativeFontResourceFontconfig::NativeFontResourceFontconfig(UniquePtr<uint8_t[]>&& aFontData,
uint32_t aDataLength,
FT_Face aFace)
NativeFontResourceFreeType::NativeFontResourceFreeType(UniquePtr<uint8_t[]>&& aFontData,
uint32_t aDataLength,
FT_Face aFace)
: mFontData(std::move(aFontData))
, mDataLength(aDataLength)
, mFace(aFace)
{
}
NativeFontResourceFontconfig::~NativeFontResourceFontconfig()
NativeFontResourceFreeType::~NativeFontResourceFreeType()
{
if (mFace) {
Factory::ReleaseFTFace(mFace);
@ -29,8 +28,9 @@ NativeFontResourceFontconfig::~NativeFontResourceFontconfig()
}
}
already_AddRefed<NativeFontResourceFontconfig>
NativeFontResourceFontconfig::Create(uint8_t *aFontData, uint32_t aDataLength, FT_Library aFTLibrary)
template<class T>
already_AddRefed<T>
NativeFontResourceFreeType::CreateInternal(uint8_t *aFontData, uint32_t aDataLength, FT_Library aFTLibrary)
{
if (!aFontData || !aDataLength) {
return nullptr;
@ -50,11 +50,40 @@ NativeFontResourceFontconfig::Create(uint8_t *aFontData, uint32_t aDataLength, F
return nullptr;
}
RefPtr<NativeFontResourceFontconfig> resource =
new NativeFontResourceFontconfig(std::move(fontData), aDataLength, face);
RefPtr<T> resource = new T(std::move(fontData), aDataLength, face);
return resource.forget();
}
#ifdef MOZ_WIDGET_ANDROID
already_AddRefed<NativeFontResourceFreeType>
NativeFontResourceFreeType::Create(uint8_t *aFontData, uint32_t aDataLength, FT_Library aFTLibrary)
{
return CreateInternal<NativeFontResourceFreeType>(aFontData, aDataLength, aFTLibrary);
}
already_AddRefed<UnscaledFont>
NativeFontResourceFreeType::CreateUnscaledFont(uint32_t aIndex,
const uint8_t* aInstanceData, uint32_t aInstanceDataLength)
{
RefPtr<UnscaledFont> unscaledFont = new UnscaledFontFreeType(mFace, this);
return unscaledFont.forget();
}
#endif
FT_Face
NativeFontResourceFreeType::CloneFace()
{
return Factory::NewFTFaceFromData(mFace->glyph->library, mFontData.get(), mDataLength, 0);
}
#ifdef MOZ_WIDGET_GTK
NativeFontResourceFontconfig::NativeFontResourceFontconfig(UniquePtr<uint8_t[]>&& aFontData,
uint32_t aDataLength,
FT_Face aFace)
: NativeFontResourceFreeType(std::move(aFontData), aDataLength, aFace)
{
}
already_AddRefed<UnscaledFont>
NativeFontResourceFontconfig::CreateUnscaledFont(uint32_t aIndex,
const uint8_t* aInstanceData, uint32_t aInstanceDataLength)
@ -63,11 +92,12 @@ NativeFontResourceFontconfig::CreateUnscaledFont(uint32_t aIndex,
return unscaledFont.forget();
}
FT_Face
NativeFontResourceFontconfig::CloneFace()
already_AddRefed<NativeFontResourceFontconfig>
NativeFontResourceFontconfig::Create(uint8_t *aFontData, uint32_t aDataLength, FT_Library aFTLibrary)
{
return Factory::NewFTFaceFromData(mFace->glyph->library, mFontData.get(), mDataLength, 0);
return CreateInternal<NativeFontResourceFontconfig>(aFontData, aDataLength, aFTLibrary);
}
#endif
} // gfx
} // mozilla

Просмотреть файл

@ -4,8 +4,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_gfx_NativeFontResourceFontconfig_h
#define mozilla_gfx_NativeFontResourceFontconfig_h
#ifndef mozilla_gfx_NativeFontResourceFreeType_h
#define mozilla_gfx_NativeFontResourceFreeType_h
#include "2D.h"
@ -15,7 +15,40 @@
namespace mozilla {
namespace gfx {
class NativeFontResourceFontconfig final : public NativeFontResource
class NativeFontResourceFreeType : public NativeFontResource
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(NativeFontResourceFreeType, override)
#ifdef MOZ_WIDGET_ANDROID
static already_AddRefed<NativeFontResourceFreeType>
Create(uint8_t *aFontData, uint32_t aDataLength, FT_Library aFTLibrary = nullptr);
already_AddRefed<UnscaledFont>
CreateUnscaledFont(uint32_t aIndex,
const uint8_t* aInstanceData, uint32_t aInstanceDataLength) override;
#endif
~NativeFontResourceFreeType();
FT_Face CloneFace();
protected:
NativeFontResourceFreeType(UniquePtr<uint8_t[]>&& aFontData,
uint32_t aDataLength,
FT_Face aFace);
template<class T>
static already_AddRefed<T>
CreateInternal(uint8_t *aFontData, uint32_t aDataLength, FT_Library aFTLibrary);
UniquePtr<uint8_t[]> mFontData;
uint32_t mDataLength;
FT_Face mFace;
};
#ifdef MOZ_WIDGET_GTK
class NativeFontResourceFontconfig final : public NativeFontResourceFreeType
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(NativeFontResourceFontconfig, override)
@ -27,21 +60,16 @@ public:
CreateUnscaledFont(uint32_t aIndex,
const uint8_t* aInstanceData, uint32_t aInstanceDataLength) final;
~NativeFontResourceFontconfig();
FT_Face CloneFace();
private:
friend class NativeFontResourceFreeType;
NativeFontResourceFontconfig(UniquePtr<uint8_t[]>&& aFontData,
uint32_t aDataLength,
FT_Face aFace);
UniquePtr<uint8_t[]> mFontData;
uint32_t mDataLength;
FT_Face mFace;
};
#endif
} // gfx
} // mozilla
#endif // mozilla_gfx_NativeFontResourceFontconfig_h
#endif // mozilla_gfx_NativeFontResourceFreeType_h

Просмотреть файл

@ -3062,7 +3062,7 @@ RecordedFontData::GetFontDetails(RecordedFontDetails& fontDetails)
template<class S>
RecordedFontData::RecordedFontData(S &aStream)
: RecordedEventDerived(FONTDATA)
, mType(FontType::SKIA)
, mType(FontType::UNKNOWN)
, mData(nullptr)
{
ReadElement(aStream, mType);

Просмотреть файл

@ -45,9 +45,6 @@ public:
virtual SkTypeface* GetSkTypeface() { return mTypeface; }
#endif
// Not true, but required to instantiate a ScaledFontBase.
virtual FontType GetType() const override { return FontType::SKIA; }
#ifdef USE_CAIRO_SCALED_FONT
bool PopulateCairoScaledFont();
virtual cairo_scaled_font_t* GetCairoScaledFont() override { return mScaledFont; }

Просмотреть файл

@ -1,41 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "ScaledFontCairo.h"
#include "Logging.h"
#if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
#include "skia/include/ports/SkTypeface_cairo.h"
#endif
namespace mozilla {
namespace gfx {
// On Linux and Android our "platform" font is a cairo_scaled_font_t and we use
// an SkFontHost implementation that allows Skia to render using this.
// This is mainly because FT_Face is not good for sharing between libraries, which
// is a requirement when we consider runtime switchable backends and so on
ScaledFontCairo::ScaledFontCairo(cairo_scaled_font_t* aScaledFont,
const RefPtr<UnscaledFont>& aUnscaledFont,
Float aSize)
: ScaledFontBase(aUnscaledFont, aSize)
{
SetCairoScaledFont(aScaledFont);
}
#if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
SkTypeface* ScaledFontCairo::GetSkTypeface()
{
if (!mTypeface) {
mTypeface = SkCreateTypefaceFromCairoFTFont(mScaledFont);
}
return mTypeface;
}
#endif
} // namespace gfx
} // namespace mozilla

Просмотреть файл

@ -1,34 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_SCALEDFONTCAIRO_H_
#define MOZILLA_GFX_SCALEDFONTCAIRO_H_
#include "ScaledFontBase.h"
#include "cairo.h"
namespace mozilla {
namespace gfx {
class ScaledFontCairo : public ScaledFontBase
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontCairo, override)
ScaledFontCairo(cairo_scaled_font_t* aScaledFont,
const RefPtr<UnscaledFont>& aUnscaledFont,
Float aSize);
#if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
virtual SkTypeface* GetSkTypeface() override;
#endif
};
} // namespace gfx
} // namespace mozilla
#endif /* MOZILLA_GFX_SCALEDFONTCAIRO_H_ */

Просмотреть файл

@ -6,7 +6,7 @@
#include "ScaledFontFontconfig.h"
#include "UnscaledFontFreeType.h"
#include "NativeFontResourceFontconfig.h"
#include "NativeFontResourceFreeType.h"
#include "Logging.h"
#include "StackArray.h"
#include "mozilla/webrender/WebRenderTypes.h"
@ -16,7 +16,6 @@
#endif
#include <fontconfig/fcfreetype.h>
#include <dlfcn.h>
#include FT_MULTIPLE_MASTERS_H
@ -110,13 +109,6 @@ ScaledFontFontconfig::InstanceData::InstanceData(cairo_scaled_font_t* aScaledFon
}
}
cairo_font_options_destroy(fontOptions);
// Some fonts supply an adjusted size or otherwise use the font matrix for italicization.
// Record the scale and the skew to accomodate both of these cases.
cairo_matrix_t fontMatrix;
cairo_scaled_font_get_font_matrix(aScaledFont, &fontMatrix);
mScale = Float(fontMatrix.xx);
mSkew = Float(fontMatrix.xy);
}
void
@ -220,68 +212,6 @@ ScaledFontFontconfig::InstanceData::SetupFontOptions(cairo_font_options_t* aFont
}
}
void
ScaledFontFontconfig::InstanceData::SetupFontMatrix(cairo_matrix_t* aFontMatrix) const
{
// Build a font matrix that will reproduce a possibly adjusted size
// and any italics/skew. This is just the concatenation of a simple
// scale matrix with a matrix that skews on the X axis.
cairo_matrix_init(aFontMatrix, mScale, 0, mSkew, mScale, 0, 0);
}
void
ScaledFontFontconfig::GetVariationSettings(std::vector<FontVariation>* aVariations)
{
aVariations->clear();
typedef FT_Error (*GetVarFunc)(FT_Face, FT_MM_Var**);
typedef FT_Error (*DoneVarFunc)(FT_Library, FT_MM_Var*);
typedef FT_Error (*GetVarDesignCoordsFunc)(FT_Face, FT_UInt, FT_Fixed*);
static GetVarFunc getVar;
static DoneVarFunc doneVar;
static GetVarDesignCoordsFunc getCoords;
static bool firstTime = true;
if (firstTime) {
firstTime = false;
getVar = (GetVarFunc)dlsym(RTLD_DEFAULT, "FT_Get_MM_Var");
doneVar = (DoneVarFunc)dlsym(RTLD_DEFAULT, "FT_Done_MM_Var");
getCoords = (GetVarDesignCoordsFunc)dlsym(RTLD_DEFAULT, "FT_Get_Var_Design_Coordinates");
}
if (!getVar || !getCoords) {
return;
}
cairo_scaled_font_t* sf = GetCairoScaledFont();
FT_Face face = cairo_ft_scaled_font_lock_face(sf);
if (face && face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) {
FT_MM_Var* mmVar;
if ((*getVar)(face, &mmVar) == FT_Err_Ok) {
aVariations->reserve(mmVar->num_axis);
StackArray<FT_Fixed, 32> coords(mmVar->num_axis);
if ((*getCoords)(face, mmVar->num_axis, coords.data()) == FT_Err_Ok) {
bool changed = false;
for (uint32_t i = 0; i < mmVar->num_axis; i++) {
if (coords[i] != mmVar->axis[i].def) {
changed = true;
}
aVariations->push_back(FontVariation{uint32_t(mmVar->axis[i].tag),
float(coords[i] / 65536.0)});
}
if (!changed) {
aVariations->clear();
}
}
if (doneVar) {
(*doneVar)(face->glyph->library, mmVar);
} else {
free(mmVar);
}
}
}
cairo_ft_scaled_font_unlock_face(sf);
}
bool
ScaledFontFontconfig::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton)
{
@ -289,7 +219,10 @@ ScaledFontFontconfig::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBat
std::vector<FontVariation> variations;
if (HasVariationSettings()) {
GetVariationSettings(&variations);
FT_Face face = nullptr;
if (FcPatternGetFTFace(mPattern, FC_FT_FACE, 0, &face) == FcResultMatch) {
UnscaledFontFreeType::GetVariationSettingsFromFace(&variations, face);
}
}
aCb(reinterpret_cast<uint8_t*>(&instance), sizeof(instance),
@ -414,7 +347,10 @@ ScaledFontFontconfig::GetWRFontInstanceOptions(Maybe<wr::FontInstanceOptions>* a
*aOutPlatformOptions = Some(platformOptions);
if (HasVariationSettings()) {
GetVariationSettings(aOutVariations);
FT_Face face = nullptr;
if (FcPatternGetFTFace(mPattern, FC_FT_FACE, 0, &face) == FcResultMatch) {
UnscaledFontFreeType::GetVariationSettingsFromFace(aOutVariations, face);
}
}
return true;
@ -542,7 +478,7 @@ ScaledFontFontconfig::CreateFromInstanceData(const InstanceData& aInstanceData,
}
cairo_matrix_t sizeMatrix;
aInstanceData.SetupFontMatrix(&sizeMatrix);
cairo_matrix_init(&sizeMatrix, aSize, 0, 0, aSize, 0, 0);
cairo_matrix_t identityMatrix;
cairo_matrix_init_identity(&identityMatrix);
@ -571,42 +507,12 @@ ScaledFontFontconfig::CreateFromInstanceData(const InstanceData& aInstanceData,
// Only apply variations if we have an explicitly cloned face. Otherwise,
// if the pattern holds the pathname, Cairo will handle setting of variations.
if (varFace) {
scaledFont->ApplyVariations(aVariations, aNumVariations);
UnscaledFontFreeType::ApplyVariationsToFace(aVariations, aNumVariations, varFace);
}
return scaledFont.forget();
}
void
ScaledFontFontconfig::ApplyVariations(const FontVariation* aVariations,
uint32_t aNumVariations)
{
typedef FT_Error (*SetVarDesignCoordsFunc)(FT_Face, FT_UInt, FT_Fixed*);
static SetVarDesignCoordsFunc setCoords;
static bool firstTime = true;
if (firstTime) {
firstTime = false;
setCoords = (SetVarDesignCoordsFunc)dlsym(RTLD_DEFAULT, "FT_Set_Var_Design_Coordinates");
}
if (!setCoords) {
return;
}
cairo_scaled_font_t* sf = GetCairoScaledFont();
FT_Face face = cairo_ft_scaled_font_lock_face(sf);
if (face && face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) {
StackArray<FT_Fixed, 32> coords(aNumVariations);
for (uint32_t i = 0; i < aNumVariations; i++) {
coords[i] = std::round(aVariations[i].mValue * 65536.0f);
}
if ((*setCoords)(face, aNumVariations, coords.data()) != FT_Err_Ok) {
// ignore the problem?
}
}
cairo_ft_scaled_font_unlock_face(sf);
}
bool
ScaledFontFontconfig::HasVariationSettings()
{
@ -620,32 +526,14 @@ ScaledFontFontconfig::HasVariationSettings()
already_AddRefed<UnscaledFont>
UnscaledFontFontconfig::CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength, uint32_t aIndex)
{
if (aDataLength <= 1) {
if (aDataLength == 0) {
gfxWarning() << "Fontconfig font descriptor is truncated.";
return nullptr;
}
const char* path = reinterpret_cast<const char*>(aData);
if (path[aDataLength - 1] != '\0') {
gfxWarning() << "Pathname in Fontconfig font descriptor is not terminated.";
return nullptr;
}
RefPtr<UnscaledFont> unscaledFont = new UnscaledFontFontconfig(path, aIndex);
RefPtr<UnscaledFont> unscaledFont = new UnscaledFontFontconfig(std::string(path, aDataLength), aIndex);
return unscaledFont.forget();
}
bool
UnscaledFontFontconfig::GetWRFontDescriptor(WRFontDescriptorOutput aCb, void* aBaton)
{
if (mFile.empty()) {
return false;
}
const char* path = mFile.c_str();
size_t pathLength = strlen(path);
aCb(reinterpret_cast<const uint8_t*>(path), pathLength, mIndex, aBaton);
return true;
}
} // namespace gfx
} // namespace mozilla

Просмотреть файл

@ -39,16 +39,12 @@ public:
Maybe<wr::FontInstancePlatformOptions>* aOutPlatformOptions,
std::vector<FontVariation>* aOutVariations) override;
void ApplyVariations(const FontVariation* aVariations, uint32_t aNumVariations);
bool HasVariationSettings() override;
private:
friend class NativeFontResourceFontconfig;
friend class UnscaledFontFontconfig;
void GetVariationSettings(std::vector<FontVariation>* aVariations);
struct InstanceData
{
enum {
@ -64,14 +60,11 @@ private:
void SetupPattern(FcPattern* aPattern) const;
void SetupFontOptions(cairo_font_options_t* aFontOptions) const;
void SetupFontMatrix(cairo_matrix_t* aFontMatrix) const;
uint8_t mFlags;
uint8_t mHintStyle;
uint8_t mSubpixelOrder;
uint8_t mLcdFilter;
Float mScale;
Float mSkew;
};
static already_AddRefed<ScaledFont>

Просмотреть файл

@ -0,0 +1,226 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "ScaledFontFreeType.h"
#include "UnscaledFontFreeType.h"
#include "NativeFontResourceFreeType.h"
#include "Logging.h"
#include "StackArray.h"
#include "mozilla/webrender/WebRenderTypes.h"
#ifdef USE_SKIA
#include "skia/include/ports/SkTypeface_cairo.h"
#endif
#include FT_MULTIPLE_MASTERS_H
namespace mozilla {
namespace gfx {
// On Linux and Android our "platform" font is a cairo_scaled_font_t and we use
// an SkFontHost implementation that allows Skia to render using this.
// This is mainly because FT_Face is not good for sharing between libraries, which
// is a requirement when we consider runtime switchable backends and so on
ScaledFontFreeType::ScaledFontFreeType(cairo_scaled_font_t* aScaledFont,
FT_Face aFace,
const RefPtr<UnscaledFont>& aUnscaledFont,
Float aSize)
: ScaledFontBase(aUnscaledFont, aSize)
, mFace(aFace)
{
SetCairoScaledFont(aScaledFont);
}
#ifdef USE_SKIA
SkTypeface* ScaledFontFreeType::GetSkTypeface()
{
if (!mTypeface) {
mTypeface = SkCreateTypefaceFromCairoFTFont(mScaledFont);
}
return mTypeface;
}
#endif
bool
ScaledFontFreeType::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton)
{
std::vector<FontVariation> variations;
if (HasVariationSettings()) {
UnscaledFontFreeType::GetVariationSettingsFromFace(&variations, mFace);
}
aCb(nullptr, 0, variations.data(), variations.size(), aBaton);
return true;
}
bool
ScaledFontFreeType::GetWRFontInstanceOptions(Maybe<wr::FontInstanceOptions>* aOutOptions,
Maybe<wr::FontInstancePlatformOptions>* aOutPlatformOptions,
std::vector<FontVariation>* aOutVariations)
{
wr::FontInstanceOptions options;
options.render_mode = wr::FontRenderMode::Alpha;
// FIXME: Cairo-FT metrics are not compatible with subpixel positioning.
// options.flags = wr::FontInstanceFlags::SUBPIXEL_POSITION;
options.flags = 0;
options.bg_color = wr::ToColorU(Color());
wr::FontInstancePlatformOptions platformOptions;
platformOptions.lcd_filter = wr::FontLCDFilter::None;
platformOptions.hinting = wr::FontHinting::None;
*aOutOptions = Some(options);
*aOutPlatformOptions = Some(platformOptions);
if (HasVariationSettings()) {
UnscaledFontFreeType::GetVariationSettingsFromFace(aOutVariations, mFace);
}
return true;
}
static cairo_user_data_key_t sNativeFontResourceKey;
static void
ReleaseNativeFontResource(void* aData)
{
static_cast<NativeFontResource*>(aData)->Release();
}
static cairo_user_data_key_t sFaceKey;
static void
ReleaseFace(void* aData)
{
Factory::ReleaseFTFace(static_cast<FT_Face>(aData));
}
already_AddRefed<ScaledFont>
UnscaledFontFreeType::CreateScaledFont(Float aGlyphSize,
const uint8_t* aInstanceData,
uint32_t aInstanceDataLength,
const FontVariation* aVariations,
uint32_t aNumVariations)
{
FT_Face face = GetFace();
if (!face) {
gfxWarning() << "Attempted to deserialize FreeType scaled font without FreeType face";
return nullptr;
}
NativeFontResourceFreeType* nfr = static_cast<NativeFontResourceFreeType*>(mNativeFontResource.get());
FT_Face varFace = nullptr;
if (nfr && aNumVariations > 0) {
varFace = nfr->CloneFace();
if (varFace) {
face = varFace;
} else {
gfxWarning() << "Failed cloning face for variations";
}
}
StackArray<FT_Fixed, 32> coords(aNumVariations);
for (uint32_t i = 0; i < aNumVariations; i++) {
coords[i] = std::round(aVariations[i].mValue * 65536.0);
}
int flags = FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING;
cairo_font_face_t* font =
cairo_ft_font_face_create_for_ft_face(face, flags, coords.data(), aNumVariations);
if (cairo_font_face_status(font) != CAIRO_STATUS_SUCCESS) {
gfxWarning() << "Failed creating Cairo font face for FreeType face";
if (varFace) {
Factory::ReleaseFTFace(varFace);
}
return nullptr;
}
if (nfr) {
// Bug 1362117 - Cairo may keep the font face alive after the owning NativeFontResource
// was freed. To prevent this, we must bind the NativeFontResource to the font face so that
// it stays alive at least as long as the font face.
nfr->AddRef();
// Bug 1412545 - Setting Cairo font user data is not thread-safe. If FT_Faces match,
// cairo_ft_font_face_create_for_ft_face may share Cairo faces. We need to lock setting user data
// to prevent races if multiple threads are thus sharing the same Cairo face.
FT_Library library = face->glyph->library;
Factory::LockFTLibrary(library);
cairo_status_t err = CAIRO_STATUS_SUCCESS;
bool cleanupFace = false;
if (varFace) {
err = cairo_font_face_set_user_data(font,
&sFaceKey,
varFace,
ReleaseFace);
}
if (err != CAIRO_STATUS_SUCCESS) {
cleanupFace = true;
} else {
err = cairo_font_face_set_user_data(font,
&sNativeFontResourceKey,
nfr,
ReleaseNativeFontResource);
}
Factory::UnlockFTLibrary(library);
if (err != CAIRO_STATUS_SUCCESS) {
gfxWarning() << "Failed binding NativeFontResource to Cairo font face";
if (varFace && cleanupFace) {
Factory::ReleaseFTFace(varFace);
}
nfr->Release();
cairo_font_face_destroy(font);
return nullptr;
}
}
cairo_matrix_t sizeMatrix;
cairo_matrix_init(&sizeMatrix, aGlyphSize, 0, 0, aGlyphSize, 0, 0);
cairo_matrix_t identityMatrix;
cairo_matrix_init_identity(&identityMatrix);
cairo_font_options_t *fontOptions = cairo_font_options_create();
cairo_font_options_set_hint_metrics(fontOptions, CAIRO_HINT_METRICS_OFF);
cairo_scaled_font_t* cairoScaledFont =
cairo_scaled_font_create(font, &sizeMatrix, &identityMatrix, fontOptions);
cairo_font_options_destroy(fontOptions);
cairo_font_face_destroy(font);
if (cairo_scaled_font_status(cairoScaledFont) != CAIRO_STATUS_SUCCESS) {
gfxWarning() << "Failed creating Cairo scaled font for font face";
return nullptr;
}
RefPtr<ScaledFontFreeType> scaledFont =
new ScaledFontFreeType(cairoScaledFont, face, this, aGlyphSize);
cairo_scaled_font_destroy(cairoScaledFont);
// Only apply variations if we have an explicitly cloned face. Otherwise,
// if the pattern holds the pathname, Cairo will handle setting of variations.
if (varFace) {
ApplyVariationsToFace(aVariations, aNumVariations, varFace);
}
return scaledFont.forget();
}
bool
ScaledFontFreeType::HasVariationSettings()
{
// Check if the FT face has been cloned.
return mFace && mFace->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS &&
mFace != static_cast<UnscaledFontFreeType*>(mUnscaledFont.get())->GetFace();
}
} // namespace gfx
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,50 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_SCALEDFONTCAIRO_H_
#define MOZILLA_GFX_SCALEDFONTCAIRO_H_
#include "ScaledFontBase.h"
#include <cairo-ft.h>
namespace mozilla {
namespace gfx {
class ScaledFontFreeType : public ScaledFontBase
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontFreeType, override)
ScaledFontFreeType(cairo_scaled_font_t* aScaledFont,
FT_Face aFace,
const RefPtr<UnscaledFont>& aUnscaledFont,
Float aSize);
FontType GetType() const override { return FontType::FREETYPE; }
#ifdef USE_SKIA
virtual SkTypeface* GetSkTypeface() override;
#endif
bool CanSerialize() override { return true; }
bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override;
bool GetWRFontInstanceOptions(Maybe<wr::FontInstanceOptions>* aOutOptions,
Maybe<wr::FontInstancePlatformOptions>* aOutPlatformOptions,
std::vector<FontVariation>* aOutVariations) override;
bool HasVariationSettings() override;
private:
FT_Face mFace;
};
} // namespace gfx
} // namespace mozilla
#endif /* MOZILLA_GFX_SCALEDFONTCAIRO_H_ */

Просмотреть файл

@ -109,17 +109,10 @@ UnscaledFontGDI::CreateScaledFont(Float aGlyphSize,
}
NativeFont nativeFont;
nativeFont.mType = NativeFontType::GDI_FONT_FACE;
nativeFont.mType = NativeFontType::GDI_LOGFONT;
nativeFont.mFont = (void*)aInstanceData;
RefPtr<ScaledFont> font =
Factory::CreateScaledFontForNativeFont(nativeFont, this, aGlyphSize);
#ifdef USE_CAIRO_SCALED_FONT
static_cast<ScaledFontBase*>(font.get())->PopulateCairoScaledFont();
#endif
return font.forget();
return Factory::CreateScaledFontForNativeFont(nativeFont, this, aGlyphSize);
}
AntialiasMode

Просмотреть файл

@ -154,11 +154,9 @@ enum class FontType : int8_t {
DWRITE,
GDI,
MAC,
SKIA,
CAIRO,
COREGRAPHICS,
FONTCONFIG,
FREETYPE
FREETYPE,
UNKNOWN
};
enum class NativeSurfaceType : int8_t {
@ -170,11 +168,9 @@ enum class NativeSurfaceType : int8_t {
};
enum class NativeFontType : int8_t {
DWRITE_FONT_FACE,
GDI_FONT_FACE,
MAC_FONT_FACE,
SKIA_FONT_FACE,
CAIRO_FONT_FACE
GDI_LOGFONT,
FREETYPE_FACE,
FONTCONFIG_PATTERN,
};
enum class FontStyle : int8_t {

Просмотреть файл

@ -5,9 +5,15 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "UnscaledFontFreeType.h"
#include "NativeFontResourceFreeType.h"
#include "ScaledFontFreeType.h"
#include "Logging.h"
#include "StackArray.h"
#include FT_MULTIPLE_MASTERS_H
#include FT_TRUETYPE_TABLES_H
#include <dlfcn.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
@ -69,12 +75,111 @@ UnscaledFontFreeType::GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton)
return false;
}
const char* path = mFile.c_str();
size_t pathLength = strlen(path) + 1;
aCb(reinterpret_cast<const uint8_t*>(path), pathLength, mIndex, aBaton);
aCb(reinterpret_cast<const uint8_t*>(mFile.data()), mFile.size(), mIndex, aBaton);
return true;
}
bool
UnscaledFontFreeType::GetWRFontDescriptor(WRFontDescriptorOutput aCb, void* aBaton)
{
if (mFile.empty()) {
return false;
}
aCb(reinterpret_cast<const uint8_t*>(mFile.data()), mFile.size(), mIndex, aBaton);
return true;
}
void
UnscaledFontFreeType::GetVariationSettingsFromFace(std::vector<FontVariation>* aVariations,
FT_Face aFace)
{
if (!aFace || !(aFace->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) {
return;
}
typedef FT_Error (*GetVarFunc)(FT_Face, FT_MM_Var**);
typedef FT_Error (*DoneVarFunc)(FT_Library, FT_MM_Var*);
typedef FT_Error (*GetVarDesignCoordsFunc)(FT_Face, FT_UInt, FT_Fixed*);
#if MOZ_TREE_FREETYPE
GetVarFunc getVar = &FT_Get_MM_Var;
DoneVarFunc doneVar = &FT_Done_MM_Var;
GetVarDesignCoordsFunc getCoords = &FT_Get_Var_Design_Coordinates;
#else
static GetVarFunc getVar;
static DoneVarFunc doneVar;
static GetVarDesignCoordsFunc getCoords;
static bool firstTime = true;
if (firstTime) {
firstTime = false;
getVar = (GetVarFunc)dlsym(RTLD_DEFAULT, "FT_Get_MM_Var");
doneVar = (DoneVarFunc)dlsym(RTLD_DEFAULT, "FT_Done_MM_Var");
getCoords = (GetVarDesignCoordsFunc)dlsym(RTLD_DEFAULT, "FT_Get_Var_Design_Coordinates");
}
if (!getVar || !getCoords) {
return;
}
#endif
FT_MM_Var* mmVar = nullptr;
if ((*getVar)(aFace, &mmVar) == FT_Err_Ok) {
aVariations->reserve(mmVar->num_axis);
StackArray<FT_Fixed, 32> coords(mmVar->num_axis);
if ((*getCoords)(aFace, mmVar->num_axis, coords.data()) == FT_Err_Ok) {
bool changed = false;
for (uint32_t i = 0; i < mmVar->num_axis; i++) {
if (coords[i] != mmVar->axis[i].def) {
changed = true;
}
aVariations->push_back(FontVariation{uint32_t(mmVar->axis[i].tag),
float(coords[i] / 65536.0)});
}
if (!changed) {
aVariations->clear();
}
}
if (doneVar) {
(*doneVar)(aFace->glyph->library, mmVar);
} else {
free(mmVar);
}
}
}
void
UnscaledFontFreeType::ApplyVariationsToFace(const FontVariation* aVariations,
uint32_t aNumVariations,
FT_Face aFace)
{
if (!aFace || !(aFace->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) {
return;
}
typedef FT_Error (*SetVarDesignCoordsFunc)(FT_Face, FT_UInt, FT_Fixed*);
#ifdef MOZ_TREE_FREETYPE
SetVarDesignCoordsFunc setCoords = &FT_Set_Var_Design_Coordinates;
#else
typedef FT_Error (*SetVarDesignCoordsFunc)(FT_Face, FT_UInt, FT_Fixed*);
static SetVarDesignCoordsFunc setCoords;
static bool firstTime = true;
if (firstTime) {
firstTime = false;
setCoords = (SetVarDesignCoordsFunc)dlsym(RTLD_DEFAULT, "FT_Set_Var_Design_Coordinates");
}
if (!setCoords) {
return;
}
#endif
StackArray<FT_Fixed, 32> coords(aNumVariations);
for (uint32_t i = 0; i < aNumVariations; i++) {
coords[i] = std::round(aVariations[i].mValue * 65536.0f);
}
if ((*setCoords)(aFace, aNumVariations, coords.data()) != FT_Err_Ok) {
// ignore the problem?
}
}
} // namespace gfx
} // namespace mozilla

Просмотреть файл

@ -14,6 +14,9 @@
namespace mozilla {
namespace gfx {
class ScaledFontFreeType;
class ScaledFontFontconfig;
class UnscaledFontFreeType : public UnscaledFont
{
public:
@ -31,6 +34,20 @@ public:
, mFile(aFile)
, mIndex(aIndex)
{}
explicit UnscaledFontFreeType(std::string&& aFile,
uint32_t aIndex = 0)
: mFace(nullptr)
, mOwnsFace(false)
, mFile(std::move(aFile))
, mIndex(aIndex)
{}
UnscaledFontFreeType(FT_Face aFace,
NativeFontResource* aNativeFontResource)
: mFace(aFace)
, mOwnsFace(false)
, mIndex(0)
, mNativeFontResource(aNativeFontResource)
{}
~UnscaledFontFreeType()
{
if (mOwnsFace) {
@ -43,16 +60,42 @@ public:
FT_Face GetFace() const { return mFace; }
const char* GetFile() const { return mFile.c_str(); }
uint32_t GetIndex() const { return mIndex; }
const RefPtr<NativeFontResource>& GetNativeFontResource() const { return mNativeFontResource; }
bool GetFontFileData(FontFileDataOutput aDataCallback, void* aBaton) override;
bool GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton) override;
bool GetWRFontDescriptor(WRFontDescriptorOutput aCb, void* aBaton) override;
#ifdef MOZ_WIDGET_ANDROID
already_AddRefed<ScaledFont>
CreateScaledFont(Float aGlyphSize,
const uint8_t* aInstanceData,
uint32_t aInstanceDataLength,
const FontVariation* aVariations,
uint32_t aNumVariations) override;
#endif
protected:
FT_Face mFace;
bool mOwnsFace;
std::string mFile;
uint32_t mIndex;
RefPtr<NativeFontResource> mNativeFontResource;
private:
friend class ScaledFontFreeType;
friend class ScaledFontFontconfig;
static void
GetVariationSettingsFromFace(std::vector<FontVariation>* aVariations,
FT_Face aFace);
static void
ApplyVariationsToFace(const FontVariation* aVariations,
uint32_t aNumVariations,
FT_Face aFace);
};
#ifdef MOZ_WIDGET_GTK
@ -68,10 +111,13 @@ public:
uint32_t aIndex = 0)
: UnscaledFontFreeType(aFile, aIndex)
{}
explicit UnscaledFontFontconfig(std::string&& aFile,
uint32_t aIndex = 0)
: UnscaledFontFreeType(std::move(aFile), aIndex)
{}
UnscaledFontFontconfig(FT_Face aFace,
NativeFontResource* aNativeFontResource)
: UnscaledFontFreeType(aFace, false)
, mNativeFontResource(aNativeFontResource)
: UnscaledFontFreeType(aFace, aNativeFontResource)
{}
FontType GetType() const override { return FontType::FONTCONFIG; }
@ -85,11 +131,6 @@ public:
uint32_t aInstanceDataLength,
const FontVariation* aVariations,
uint32_t aNumVariations) override;
bool GetWRFontDescriptor(WRFontDescriptorOutput aCb, void* aBaton) override;
private:
RefPtr<NativeFontResource> mNativeFontResource;
};
#endif

Просмотреть файл

@ -106,15 +106,20 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk3'):
'UnscaledFontFreeType.h',
]
SOURCES += [
'NativeFontResourceFreeType.cpp',
'UnscaledFontFreeType.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3':
SOURCES += [
'NativeFontResourceFontconfig.cpp',
'ScaledFontFontconfig.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
SOURCES += [
'ScaledFontFreeType.cpp',
]
if CONFIG['MOZ_ENABLE_SKIA']:
SOURCES += [
'ConvolutionFilter.cpp',
@ -184,7 +189,6 @@ UNIFIED_SOURCES += [
'RecordedEvent.cpp',
'Scale.cpp',
'ScaledFontBase.cpp',
'ScaledFontCairo.cpp',
'SFNTData.cpp',
'SFNTNameTable.cpp',
'SourceSurfaceCairo.cpp',

Просмотреть файл

@ -289,9 +289,7 @@ WebRenderBridgeChild::GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont)
{
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(aScaledFont);
MOZ_ASSERT((aScaledFont->GetType() == gfx::FontType::DWRITE) ||
(aScaledFont->GetType() == gfx::FontType::MAC) ||
(aScaledFont->GetType() == gfx::FontType::FONTCONFIG));
MOZ_ASSERT(aScaledFont->CanSerialize());
wr::FontInstanceKey instanceKey = { wr::IdNamespace { 0 }, 0 };
if (mFontInstanceKeys.Get(aScaledFont, &instanceKey)) {

Просмотреть файл

@ -80,7 +80,7 @@ BuildKeyNameFromFontName(nsAString &aName)
class AutoFTFace {
public:
explicit AutoFTFace(FT2FontEntry* aFontEntry)
: mFace(nullptr), mFontDataBuf(nullptr), mOwnsFace(false)
: mFace(nullptr), mFontDataBuf(nullptr), mDataLength(0), mOwnsFace(false)
{
if (aFontEntry->mFTFace) {
mFace = aFontEntry->mFTFace;
@ -230,6 +230,8 @@ FT2FontEntry::Clone() const
return fe;
}
static cairo_user_data_key_t sFTFaceKey;
gfxFont*
FT2FontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle)
{
@ -241,15 +243,19 @@ FT2FontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle)
RefPtr<UnscaledFontFreeType> unscaledFont(mUnscaledFont);
if (!unscaledFont) {
unscaledFont =
mFilename.IsEmpty() ?
new UnscaledFontFreeType(mFTFace) :
!mFilename.IsEmpty() && mFilename[0] == '/' ?
new UnscaledFontFreeType(mFilename.BeginReading(),
mFTFontIndex);
mFTFontIndex) :
new UnscaledFontFreeType(mFTFace);
mUnscaledFont = unscaledFont;
}
gfxFont *font = new gfxFT2Font(unscaledFont, scaledFont, this,
aFontStyle);
cairo_font_face_t* face = cairo_scaled_font_get_font_face(scaledFont);
FT_Face ftFace = static_cast<FT_Face>(cairo_font_face_get_user_data(face, &sFTFaceKey));
gfxFont *font = new gfxFT2Font(unscaledFont, scaledFont,
ftFace ? ftFace : mFTFace,
this, aFontStyle);
cairo_scaled_font_destroy(scaledFont);
return font;
}
@ -471,7 +477,7 @@ FT2FontEntry::CairoFontFace(const gfxFontStyle* aStyle)
// Create a separate FT_Face because we need to apply custom
// variation settings to it.
FT_Face ftFace;
if (!mFilename.IsEmpty()) {
if (!mFilename.IsEmpty() && mFilename[0] == '/') {
ftFace = Factory::NewFTFace(nullptr, mFilename.get(), mFTFontIndex);
} else {
auto ufd = reinterpret_cast<FTUserFontData*>(
@ -487,8 +493,7 @@ FT2FontEntry::CairoFontFace(const gfxFontStyle* aStyle)
coords.Length());
// Set up user data to properly release the FT_Face when the cairo face
// is deleted.
static cairo_user_data_key_t sDestroyFaceKey;
if (cairo_font_face_set_user_data(cairoFace, &sDestroyFaceKey, ftFace,
if (cairo_font_face_set_user_data(cairoFace, &sFTFaceKey, ftFace,
(cairo_destroy_func_t)&Factory::ReleaseFTFace)) {
// set_user_data failed! discard, and fall back to default face
cairo_font_face_destroy(cairoFace);

Просмотреть файл

@ -163,10 +163,12 @@ gfxFT2Font::AddRange(const char16_t *aText, uint32_t aOffset,
gfxFT2Font::gfxFT2Font(const RefPtr<UnscaledFontFreeType>& aUnscaledFont,
cairo_scaled_font_t *aCairoFont,
FT_Face aFTFace,
FT2FontEntry *aFontEntry,
const gfxFontStyle *aFontStyle)
: gfxFT2FontBase(aUnscaledFont, aCairoFont, aFontEntry, aFontStyle)
, mCharGlyphCache(32)
, mFTFace(aFTFace)
{
NS_ASSERTION(mFontEntry, "Unable to find font entry for font. Something is whack.");
// TODO: use FreeType emboldening instead of multi-strike?
@ -182,12 +184,14 @@ gfxFT2Font::GetScaledFont(DrawTarget *aTarget)
{
if (!mAzureScaledFont) {
NativeFont nativeFont;
nativeFont.mType = NativeFontType::CAIRO_FONT_FACE;
nativeFont.mFont = GetCairoScaledFont();
nativeFont.mType = NativeFontType::FREETYPE_FACE;
nativeFont.mFont = mFTFace;
mAzureScaledFont =
Factory::CreateScaledFontForNativeFont(nativeFont,
GetUnscaledFont(),
GetAdjustedSize());
Factory::CreateScaledFontForNativeFont(nativeFont,
GetUnscaledFont(),
GetAdjustedSize(),
GetCairoScaledFont());
}
RefPtr<ScaledFont> scaledFont(mAzureScaledFont);

Просмотреть файл

@ -21,6 +21,7 @@ class gfxFT2Font : public gfxFT2FontBase {
public: // new functions
gfxFT2Font(const RefPtr<mozilla::gfx::UnscaledFontFreeType>& aUnscaledFont,
cairo_scaled_font_t *aCairoFont,
FT_Face aFTFace,
FT2FontEntry *aFontEntry,
const gfxFontStyle *aFontStyle);
virtual ~gfxFT2Font ();
@ -82,6 +83,7 @@ protected:
typedef nsBaseHashtableET<nsUint32HashKey, CachedGlyphData> CharGlyphMapEntryType;
typedef nsTHashtable<CharGlyphMapEntryType> CharGlyphMap;
CharGlyphMap mCharGlyphCache;
FT_Face mFTFace;
};
#endif /* GFX_FT2FONTS_H */

Просмотреть файл

@ -1458,11 +1458,15 @@ already_AddRefed<ScaledFont>
gfxFontconfigFont::GetScaledFont(mozilla::gfx::DrawTarget *aTarget)
{
if (!mAzureScaledFont) {
NativeFont nativeFont;
nativeFont.mType = NativeFontType::FONTCONFIG_PATTERN;
nativeFont.mFont = GetPattern();
mAzureScaledFont =
Factory::CreateScaledFontForFontconfigFont(GetCairoScaledFont(),
GetPattern(),
GetUnscaledFont(),
GetAdjustedSize());
Factory::CreateScaledFontForNativeFont(nativeFont,
GetUnscaledFont(),
GetAdjustedSize(),
GetCairoScaledFont());
}
RefPtr<ScaledFont> scaledFont(mAzureScaledFont);

Просмотреть файл

@ -141,16 +141,16 @@ gfxGDIFont::GetScaledFont(DrawTarget *aTarget)
{
if (!mAzureScaledFont) {
NativeFont nativeFont;
nativeFont.mType = NativeFontType::GDI_FONT_FACE;
nativeFont.mType = NativeFontType::GDI_LOGFONT;
LOGFONT lf;
GetObject(GetHFONT(), sizeof(LOGFONT), &lf);
nativeFont.mFont = &lf;
mAzureScaledFont =
Factory::CreateScaledFontWithCairo(nativeFont,
GetUnscaledFont(),
GetAdjustedSize(),
GetCairoScaledFont());
Factory::CreateScaledFontForNativeFont(nativeFont,
GetUnscaledFont(),
GetAdjustedSize(),
GetCairoScaledFont());
}
RefPtr<ScaledFont> scaledFont(mAzureScaledFont);