Bug 1584268 - only instantiate Cairo fonts when drawing to Cairo target. r=jfkthame

This removes a lot of old cruft in thebes to instantiate Cairo scaled fonts.
Instead, we only instantiate the Cairo scaled font inside Moz2D when we actually
need it for DrawTargetCairo. This thus gets rid of the duplicated code we had
inside both Moz2D and thebes to deal with Cairo scaled fonts.

Differential Revision: https://phabricator.services.mozilla.com/D47297

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Lee Salzman 2019-10-01 21:56:30 +00:00
Родитель ea3d3a0084
Коммит 2b03a82ba0
42 изменённых файлов: 312 добавлений и 822 удалений

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

@ -111,11 +111,6 @@ struct NativeSurface {
void* mSurface;
};
struct NativeFont {
NativeFontType mType;
void* mFont;
};
/**
* This structure is used to send draw options that are universal to all drawing
* operations.
@ -920,7 +915,6 @@ class ScaledFont : public SupportsThreadSafeWeakPtr<ScaledFont> {
const RefPtr<UnscaledFont>& GetUnscaledFont() const { return mUnscaledFont; }
virtual cairo_scaled_font_t* GetCairoScaledFont() { return nullptr; }
virtual void SetCairoScaledFont(cairo_scaled_font_t* font) {}
Float GetSyntheticObliqueAngle() const { return mSyntheticObliqueAngle; }
void SetSyntheticObliqueAngle(Float aAngle) {
@ -1697,15 +1691,13 @@ class GFX2D_API Factory {
#ifdef MOZ_WIDGET_GTK
static already_AddRefed<ScaledFont> CreateScaledFontForFontconfigFont(
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
cairo_scaled_font_t* aScaledFont, RefPtr<SharedFTFace> aFace,
FcPattern* aPattern);
RefPtr<SharedFTFace> aFace, FcPattern* aPattern);
#endif
#ifdef MOZ_WIDGET_ANDROID
static already_AddRefed<ScaledFont> CreateScaledFontForFreeTypeFont(
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
cairo_scaled_font_t* aScaledFont, RefPtr<SharedFTFace> aFace,
bool aApplySyntheticBold = false);
RefPtr<SharedFTFace> aFace, bool aApplySyntheticBold = false);
#endif
/**
@ -1713,16 +1705,14 @@ class GFX2D_API Factory {
*
* @param aData Pointer to the data
* @param aSize Size of the TrueType data
* @param aBackendType Type of the reference DrawTarget the font should be
* created for.
* @param aFontType Type of NativeFontResource that should be created.
* @param aFontContext Optional native font context to be used to create the
* NativeFontResource.
* @return a NativeFontResource of nullptr if failed.
*/
static already_AddRefed<NativeFontResource> CreateNativeFontResource(
uint8_t* aData, uint32_t aSize, BackendType aBackendType,
FontType aFontType, void* aFontContext = nullptr);
uint8_t* aData, uint32_t aSize, FontType aFontType,
void* aFontContext = nullptr);
/**
* This creates an unscaled font of the given type based on font descriptor
@ -1732,17 +1722,6 @@ class GFX2D_API Factory {
FontType aType, const uint8_t* aData, uint32_t aDataLength,
uint32_t aIndex);
/**
* 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> 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
* new memory for the surface. This memory is freed when the surface is
@ -1894,6 +1873,10 @@ class GFX2D_API Factory {
bool aUseEmbeddedBitmap, int aRenderingMode,
IDWriteRenderingParams* aParams, Float aGamma, Float aContrast);
static already_AddRefed<ScaledFont> CreateScaledFontForGDIFont(
const void* aLogFont, const RefPtr<UnscaledFont>& aUnscaledFont,
Float aSize);
static void SetSystemTextQuality(uint8_t aQuality);
private:

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

@ -1195,7 +1195,7 @@ bool DrawTargetCairo::IsCurrentGroupOpaque() {
return cairo_surface_get_content(surf) == CAIRO_CONTENT_COLOR;
}
void DrawTargetCairo::SetFontOptions() {
void DrawTargetCairo::SetFontOptions(cairo_antialias_t aAAMode) {
// This will attempt to detect if the currently set scaled font on the
// context has enabled subpixel AA. If it is not permitted, then it will
// downgrade to grayscale AA.
@ -1211,7 +1211,7 @@ void DrawTargetCairo::SetFontOptions() {
// cairo_surface_set_subpixel_antialiasing extension.
// If allowing subpixel AA, then leave Cairo's default AA state.
if (mPermitSubpixelAA) {
if (mPermitSubpixelAA && aAAMode == CAIRO_ANTIALIAS_DEFAULT) {
return;
}
@ -1223,12 +1223,22 @@ void DrawTargetCairo::SetFontOptions() {
}
}
cairo_get_font_options(mContext, mFontOptions);
cairo_antialias_t oldAA = cairo_font_options_get_antialias(mFontOptions);
cairo_antialias_t newAA =
aAAMode == CAIRO_ANTIALIAS_DEFAULT ? oldAA : aAAMode;
// Nothing to change if switching to default AA.
if (newAA == CAIRO_ANTIALIAS_DEFAULT) {
return;
}
// If the current font requests subpixel AA, force it to gray since we don't
// allow subpixel AA.
cairo_get_font_options(mContext, mFontOptions);
cairo_antialias_t antialias = cairo_font_options_get_antialias(mFontOptions);
if (antialias == CAIRO_ANTIALIAS_SUBPIXEL) {
cairo_font_options_set_antialias(mFontOptions, CAIRO_ANTIALIAS_GRAY);
if (!mPermitSubpixelAA && newAA == CAIRO_ANTIALIAS_SUBPIXEL) {
newAA = CAIRO_ANTIALIAS_GRAY;
}
// Only override old AA with lower levels of AA.
if (oldAA == CAIRO_ANTIALIAS_DEFAULT || (int)newAA < (int)oldAA) {
cairo_font_options_set_antialias(mFontOptions, newAA);
cairo_set_font_options(mContext, mFontOptions);
}
}
@ -1266,7 +1276,9 @@ void DrawTargetCairo::FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
return;
}
if (!aFont) {
cairo_scaled_font_t* cairoScaledFont =
aFont ? aFont->GetCairoScaledFont() : nullptr;
if (!cairoScaledFont) {
gfxDevCrash(LogReason::InvalidFont) << "Invalid scaled font";
return;
}
@ -1274,7 +1286,7 @@ void DrawTargetCairo::FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
AutoPrepareForDrawing prep(this, mContext);
AutoClearDeviceOffset clear(aPattern);
cairo_set_scaled_font(mContext, aFont->GetCairoScaledFont());
cairo_set_scaled_font(mContext, cairoScaledFont);
cairo_pattern_t* pat =
GfxPatternToCairoPattern(aPattern, aOptions.mAlpha, GetTransform());
@ -1283,11 +1295,11 @@ void DrawTargetCairo::FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
cairo_set_source(mContext, pat);
cairo_pattern_destroy(pat);
cairo_set_antialias(mContext,
GfxAntialiasToCairoAntialias(aOptions.mAntialiasMode));
cairo_antialias_t aa = GfxAntialiasToCairoAntialias(aOptions.mAntialiasMode);
cairo_set_antialias(mContext, aa);
// Override any font-specific options as necessary.
SetFontOptions();
SetFontOptions(aa);
// Convert our GlyphBuffer into a vector of Cairo glyphs. This code can
// execute millions of times in short periods, so we want to avoid heap

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

@ -203,7 +203,7 @@ class DrawTargetCairo final : public DrawTarget {
// Set the Cairo context font options according to the current draw target
// font state.
void SetFontOptions();
void SetFontOptions(cairo_antialias_t aAAMode = CAIRO_ANTIALIAS_DEFAULT);
private: // data
cairo_t* mContext;

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

@ -542,46 +542,17 @@ uint32_t Factory::GetMaxSurfaceSize(BackendType aType) {
}
}
already_AddRefed<ScaledFont> Factory::CreateScaledFontForNativeFont(
const NativeFont& aNativeFont, const RefPtr<UnscaledFont>& aUnscaledFont,
Float aSize, cairo_scaled_font_t* aScaledFont) {
switch (aNativeFont.mType) {
#ifdef WIN32
case NativeFontType::GDI_LOGFONT: {
RefPtr<ScaledFontWin> font = MakeAndAddRef<ScaledFontWin>(
static_cast<LOGFONT*>(aNativeFont.mFont), aUnscaledFont, aSize);
# ifdef USE_CAIRO
if (aScaledFont) {
font->SetCairoScaledFont(aScaledFont);
} else {
font->PopulateCairoScaledFont();
}
# endif
return font.forget();
}
#endif
default:
gfxWarning() << "Invalid native font type specified.";
return nullptr;
}
}
already_AddRefed<NativeFontResource> Factory::CreateNativeFontResource(
uint8_t* aData, uint32_t aSize, BackendType aBackendType,
FontType aFontType, void* aFontContext) {
uint8_t* aData, uint32_t aSize, FontType aFontType, void* aFontContext) {
switch (aFontType) {
#ifdef WIN32
case FontType::DWRITE: {
bool needsCairo = aBackendType == BackendType::CAIRO;
return NativeFontResourceDWrite::Create(aData, aSize, needsCairo);
}
case FontType::DWRITE:
return NativeFontResourceDWrite::Create(aData, aSize);
case FontType::GDI:
return NativeFontResourceGDI::Create(aData, aSize);
#elif defined(XP_DARWIN)
case FontType::MAC: {
bool needsCairo = aBackendType == BackendType::CAIRO;
return NativeFontResourceMac::Create(aData, aSize, needsCairo);
}
case FontType::MAC:
return NativeFontResourceMac::Create(aData, aSize);
#elif defined(MOZ_WIDGET_GTK)
case FontType::FONTCONFIG:
return NativeFontResourceFontconfig::Create(
@ -632,20 +603,18 @@ already_AddRefed<ScaledFont> Factory::CreateScaledFontForMacFont(
#ifdef MOZ_WIDGET_GTK
already_AddRefed<ScaledFont> Factory::CreateScaledFontForFontconfigFont(
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
cairo_scaled_font_t* aScaledFont, RefPtr<SharedFTFace> aFace,
FcPattern* aPattern) {
return MakeAndAddRef<ScaledFontFontconfig>(aScaledFont, std::move(aFace),
aPattern, aUnscaledFont, aSize);
RefPtr<SharedFTFace> aFace, FcPattern* aPattern) {
return MakeAndAddRef<ScaledFontFontconfig>(std::move(aFace), aPattern,
aUnscaledFont, aSize);
}
#endif
#ifdef MOZ_WIDGET_ANDROID
already_AddRefed<ScaledFont> Factory::CreateScaledFontForFreeTypeFont(
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
cairo_scaled_font_t* aScaledFont, RefPtr<SharedFTFace> aFace,
bool aApplySyntheticBold) {
return MakeAndAddRef<ScaledFontFreeType>(
aScaledFont, std::move(aFace), aUnscaledFont, aSize, aApplySyntheticBold);
RefPtr<SharedFTFace> aFace, bool aApplySyntheticBold) {
return MakeAndAddRef<ScaledFontFreeType>(std::move(aFace), aUnscaledFont,
aSize, aApplySyntheticBold);
}
#endif
@ -1007,6 +976,12 @@ already_AddRefed<ScaledFont> Factory::CreateScaledFontForDWriteFont(
aParams, aGamma, aContrast, aStyle);
}
already_AddRefed<ScaledFont> Factory::CreateScaledFontForGDIFont(
const void* aLogFont, const RefPtr<UnscaledFont>& aUnscaledFont,
Float aSize) {
return MakeAndAddRef<ScaledFontWin>(static_cast<const LOGFONT*>(aLogFont),
aUnscaledFont, aSize);
}
#endif // WIN32
#ifdef USE_SKIA

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

@ -200,7 +200,7 @@ DWriteFontFileStream::ReleaseFileFragment(void* fragmentContext) {}
/* static */
already_AddRefed<NativeFontResourceDWrite> NativeFontResourceDWrite::Create(
uint8_t* aFontData, uint32_t aDataLength, bool aNeedsCairo) {
uint8_t* aFontData, uint32_t aDataLength) {
RefPtr<IDWriteFactory> factory = Factory::GetDWriteFactory();
if (!factory) {
gfxWarning() << "Failed to get DWrite Factory.";
@ -237,9 +237,8 @@ already_AddRefed<NativeFontResourceDWrite> NativeFontResourceDWrite::Create(
return nullptr;
}
RefPtr<NativeFontResourceDWrite> fontResource =
new NativeFontResourceDWrite(factory, fontFile.forget(), ffsRef.forget(),
faceType, numberOfFaces, aNeedsCairo);
RefPtr<NativeFontResourceDWrite> fontResource = new NativeFontResourceDWrite(
factory, fontFile.forget(), ffsRef.forget(), faceType, numberOfFaces);
return fontResource.forget();
}
@ -260,8 +259,7 @@ already_AddRefed<UnscaledFont> NativeFontResourceDWrite::CreateUnscaledFont(
return nullptr;
}
RefPtr<UnscaledFont> unscaledFont =
new UnscaledFontDWrite(fontFace, nullptr, mNeedsCairo);
RefPtr<UnscaledFont> unscaledFont = new UnscaledFontDWrite(fontFace, nullptr);
return unscaledFont.forget();
}

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

@ -25,12 +25,10 @@ class NativeFontResourceDWrite final : public NativeFontResource {
*
* @param aFontData the SFNT data.
* @param aDataLength length of data.
* @param aNeedsCairo whether the ScaledFont created needs a cairo scaled font
* @return Referenced NativeFontResourceDWrite or nullptr if invalid.
*/
static already_AddRefed<NativeFontResourceDWrite> Create(uint8_t* aFontData,
uint32_t aDataLength,
bool aNeedsCairo);
static already_AddRefed<NativeFontResourceDWrite> Create(
uint8_t* aFontData, uint32_t aDataLength);
already_AddRefed<UnscaledFont> CreateUnscaledFont(
uint32_t aIndex, const uint8_t* aInstanceData,
@ -40,21 +38,18 @@ class NativeFontResourceDWrite final : public NativeFontResource {
NativeFontResourceDWrite(
IDWriteFactory* aFactory, already_AddRefed<IDWriteFontFile> aFontFile,
already_AddRefed<IDWriteFontFileStream> aFontFileStream,
DWRITE_FONT_FACE_TYPE aFaceType, uint32_t aNumberOfFaces,
bool aNeedsCairo)
DWRITE_FONT_FACE_TYPE aFaceType, uint32_t aNumberOfFaces)
: mFactory(aFactory),
mFontFile(aFontFile),
mFontFileStream(aFontFileStream),
mFaceType(aFaceType),
mNumberOfFaces(aNumberOfFaces),
mNeedsCairo(aNeedsCairo) {}
mNumberOfFaces(aNumberOfFaces) {}
IDWriteFactory* mFactory;
RefPtr<IDWriteFontFile> mFontFile;
RefPtr<IDWriteFontFileStream> mFontFileStream;
DWRITE_FONT_FACE_TYPE mFaceType;
uint32_t mNumberOfFaces;
bool mNeedsCairo;
};
} // namespace gfx

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

@ -21,7 +21,7 @@ namespace gfx {
/* static */
already_AddRefed<NativeFontResourceMac> NativeFontResourceMac::Create(
uint8_t* aFontData, uint32_t aDataLength, bool aNeedsCairo) {
uint8_t* aFontData, uint32_t aDataLength) {
// copy font data
CFDataRef data = CFDataCreate(kCFAllocatorDefault, aFontData, aDataLength);
if (!data) {
@ -46,7 +46,7 @@ already_AddRefed<NativeFontResourceMac> NativeFontResourceMac::Create(
// passes ownership of fontRef to the NativeFontResourceMac instance
RefPtr<NativeFontResourceMac> fontResource =
new NativeFontResourceMac(fontRef, aNeedsCairo);
new NativeFontResourceMac(fontRef);
return fontResource.forget();
}
@ -54,8 +54,7 @@ already_AddRefed<NativeFontResourceMac> NativeFontResourceMac::Create(
already_AddRefed<UnscaledFont> NativeFontResourceMac::CreateUnscaledFont(
uint32_t aIndex, const uint8_t* aInstanceData,
uint32_t aInstanceDataLength) {
RefPtr<UnscaledFont> unscaledFont =
new UnscaledFontMac(mFontRef, true, mNeedsCairo);
RefPtr<UnscaledFont> unscaledFont = new UnscaledFontMac(mFontRef, true);
return unscaledFont.forget();
}

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

@ -19,8 +19,7 @@ class NativeFontResourceMac final : public NativeFontResource {
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(NativeFontResourceMac, override)
static already_AddRefed<NativeFontResourceMac> Create(uint8_t* aFontData,
uint32_t aDataLength,
bool aNeedsCairo);
uint32_t aDataLength);
already_AddRefed<UnscaledFont> CreateUnscaledFont(
uint32_t aIndex, const uint8_t* aInstanceData,
@ -29,11 +28,9 @@ class NativeFontResourceMac final : public NativeFontResource {
~NativeFontResourceMac() { CFRelease(mFontRef); }
private:
NativeFontResourceMac(CGFontRef aFontRef, bool aNeedsCairo)
: mFontRef(aFontRef), mNeedsCairo(aNeedsCairo) {}
explicit NativeFontResourceMac(CGFontRef aFontRef) : mFontRef(aFontRef) {}
CGFontRef mFontRef;
bool mNeedsCairo;
};
} // namespace gfx

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

@ -3114,9 +3114,7 @@ inline bool RecordedFontData::PlayEvent(Translator* aTranslator) const {
}
RefPtr<NativeFontResource> fontResource = Factory::CreateNativeFontResource(
mData, mFontDetails.size,
aTranslator->GetReferenceDrawTarget()->GetBackendType(), mType,
aTranslator->GetFontContext());
mData, mFontDetails.size, mType, aTranslator->GetFontContext());
if (!fontResource) {
return false;
}
@ -3317,6 +3315,7 @@ inline bool RecordedScaledFontCreation::PlayEvent(
RefPtr<ScaledFont> scaledFont = unscaledFont->CreateScaledFont(
mGlyphSize, mInstanceData.data(), mInstanceData.size(),
mVariations.data(), mVariations.size());
aTranslator->AddScaledFont(mRefPtr, scaledFont);
return true;
}

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

@ -68,10 +68,16 @@ SkTypeface* ScaledFontBase::GetSkTypeface() {
#endif
#ifdef USE_CAIRO_SCALED_FONT
bool ScaledFontBase::PopulateCairoScaledFont() {
cairo_font_face_t* cairoFontFace = GetCairoFontFace();
if (!cairoFontFace) {
return false;
cairo_scaled_font_t* ScaledFontBase::GetCairoScaledFont() {
if (mScaledFont) {
return mScaledFont;
}
cairo_font_options_t* fontOptions = cairo_font_options_create();
cairo_font_face_t* fontFace = CreateCairoFontFace(fontOptions);
if (!fontFace) {
cairo_font_options_destroy(fontOptions);
return nullptr;
}
cairo_matrix_t sizeMatrix;
@ -80,15 +86,20 @@ bool ScaledFontBase::PopulateCairoScaledFont() {
cairo_matrix_init_scale(&sizeMatrix, mSize, mSize);
cairo_matrix_init_identity(&identityMatrix);
cairo_font_options_t* fontOptions = cairo_font_options_create();
mScaledFont = cairo_scaled_font_create(cairoFontFace, &sizeMatrix,
&identityMatrix, fontOptions);
cairo_scaled_font_t* scaledFont = cairo_scaled_font_create(
fontFace, &sizeMatrix, &identityMatrix, fontOptions);
cairo_font_options_destroy(fontOptions);
cairo_font_face_destroy(cairoFontFace);
cairo_font_face_destroy(fontFace);
return (cairo_scaled_font_status(mScaledFont) == CAIRO_STATUS_SUCCESS);
if (cairo_scaled_font_status(scaledFont) != CAIRO_STATUS_SUCCESS) {
cairo_scaled_font_destroy(scaledFont);
return nullptr;
}
PrepareCairoScaledFont(scaledFont);
mScaledFont = scaledFont;
return mScaledFont;
}
#endif
@ -237,18 +248,5 @@ void ScaledFontBase::CopyGlyphsToBuilder(const GlyphBuffer& aBuffer,
MOZ_ASSERT(false, "Path not being copied");
}
#ifdef USE_CAIRO_SCALED_FONT
void ScaledFontBase::SetCairoScaledFont(cairo_scaled_font_t* font) {
MOZ_ASSERT(!mScaledFont);
if (font == mScaledFont) return;
if (mScaledFont) cairo_scaled_font_destroy(mScaledFont);
mScaledFont = font;
cairo_scaled_font_reference(mScaledFont);
}
#endif
} // namespace gfx
} // namespace mozilla

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

@ -48,11 +48,7 @@ class ScaledFontBase : public ScaledFont {
#endif
#ifdef USE_CAIRO_SCALED_FONT
bool PopulateCairoScaledFont();
virtual cairo_scaled_font_t* GetCairoScaledFont() override {
return mScaledFont;
}
virtual void SetCairoScaledFont(cairo_scaled_font_t* font) override;
virtual cairo_scaled_font_t* GetCairoScaledFont() override;
#endif
protected:
@ -63,8 +59,11 @@ class ScaledFontBase : public ScaledFont {
SkPath GetSkiaPathForGlyphs(const GlyphBuffer& aBuffer);
#endif
#ifdef USE_CAIRO_SCALED_FONT
// Overridders should ensure the cairo_font_face_t has been addrefed.
virtual cairo_font_face_t* GetCairoFontFace() { return nullptr; }
virtual cairo_font_face_t* CreateCairoFontFace(
cairo_font_options_t* aFontOptions) {
return nullptr;
}
virtual void PrepareCairoScaledFont(cairo_scaled_font_t* aFont) {}
cairo_scaled_font_t* mScaledFont;
#endif
Float mSize;

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

@ -650,11 +650,6 @@ already_AddRefed<ScaledFont> UnscaledFontDWrite::CreateScaledFont(
instanceData.mRenderingMode, nullptr, instanceData.mGamma,
instanceData.mContrast);
if (mNeedsCairo && !scaledFont->PopulateCairoScaledFont()) {
gfxWarning() << "Unable to create cairo scaled font DWrite font.";
return nullptr;
}
return scaledFont.forget();
}
@ -690,13 +685,20 @@ AntialiasMode ScaledFontDWrite::GetDefaultAAMode() {
}
#ifdef USE_CAIRO_SCALED_FONT
cairo_font_face_t* ScaledFontDWrite::GetCairoFontFace() {
cairo_font_face_t* ScaledFontDWrite::CreateCairoFontFace(
cairo_font_options_t* aFontOptions) {
if (!mFontFace) {
return nullptr;
}
return cairo_dwrite_font_face_create_for_dwrite_fontface(nullptr, mFontFace);
}
void ScaledFontDWrite::PrepareCairoScaledFont(cairo_scaled_font_t* aFont) {
if (mRenderingMode == DWRITE_RENDERING_MODE_GDI_CLASSIC) {
cairo_dwrite_scaled_font_set_force_GDI_classic(aFont, true);
}
}
#endif
} // namespace gfx

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

@ -88,9 +88,10 @@ class ScaledFontDWrite final : public ScaledFontBase {
Float mGamma;
Float mContrast;
protected:
#ifdef USE_CAIRO_SCALED_FONT
cairo_font_face_t* GetCairoFontFace() override;
cairo_font_face_t* CreateCairoFontFace(
cairo_font_options_t* aFontOptions) override;
void PrepareCairoScaledFont(cairo_scaled_font_t* aFont) override;
#endif
private:

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

@ -23,28 +23,19 @@
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
ScaledFontFontconfig::ScaledFontFontconfig(
cairo_scaled_font_t* aScaledFont, RefPtr<SharedFTFace>&& aFace,
FcPattern* aPattern, const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize)
: ScaledFontBase(aUnscaledFont, aSize),
mFace(std::move(aFace)),
mInstanceData(aScaledFont, aPattern) {
SetCairoScaledFont(aScaledFont);
}
ScaledFontFontconfig::ScaledFontFontconfig(
cairo_scaled_font_t* aScaledFont, RefPtr<SharedFTFace>&& aFace,
const InstanceData& aInstanceData,
RefPtr<SharedFTFace>&& aFace, FcPattern* aPattern,
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize)
: ScaledFontBase(aUnscaledFont, aSize),
mFace(std::move(aFace)),
mInstanceData(aInstanceData) {
SetCairoScaledFont(aScaledFont);
}
mInstanceData(aPattern) {}
ScaledFontFontconfig::ScaledFontFontconfig(
RefPtr<SharedFTFace>&& aFace, const InstanceData& aInstanceData,
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize)
: ScaledFontBase(aUnscaledFont, aSize),
mFace(std::move(aFace)),
mInstanceData(aInstanceData) {}
#ifdef USE_SKIA
SkTypeface* ScaledFontFontconfig::CreateSkTypeface() {
@ -77,12 +68,23 @@ void ScaledFontFontconfig::SetupSkFontDrawOptions(SkFont& aFont) {
}
#endif
#ifdef USE_CAIRO_SCALED_FONT
cairo_font_face_t* ScaledFontFontconfig::CreateCairoFontFace(
cairo_font_options_t* aFontOptions) {
int loadFlags;
unsigned int synthFlags;
mInstanceData.SetupFontOptions(aFontOptions, &loadFlags, &synthFlags);
return cairo_ft_font_face_create_for_ft_face(mFace->GetFace(), loadFlags,
synthFlags, mFace.get());
}
#endif
AntialiasMode ScaledFontFontconfig::GetDefaultAAMode() {
return mInstanceData.mAntialias;
}
ScaledFontFontconfig::InstanceData::InstanceData(
cairo_scaled_font_t* aScaledFont, FcPattern* aPattern)
ScaledFontFontconfig::InstanceData::InstanceData(FcPattern* aPattern)
: mFlags(0),
mAntialias(AntialiasMode::NONE),
mHinting(FontHinting::NONE),
@ -99,12 +101,12 @@ ScaledFontFontconfig::InstanceData::InstanceData(
mFlags |= EMBOLDEN;
}
cairo_font_options_t* fontOptions = cairo_font_options_create();
cairo_scaled_font_get_font_options(aScaledFont, fontOptions);
// For printer fonts, Cairo hint metrics and hinting will be disabled.
// For other fonts, allow hint metrics and hinting.
if (cairo_font_options_get_hint_metrics(fontOptions) !=
CAIRO_HINT_METRICS_OFF) {
FcBool printing;
if (FcPatternGetBool(aPattern, "gfx.printing", 0, &printing) !=
FcResultMatch ||
!printing) {
mFlags |= HINT_METRICS;
FcBool hinting;
@ -131,7 +133,6 @@ ScaledFontFontconfig::InstanceData::InstanceData(
}
}
}
cairo_font_options_destroy(fontOptions);
FcBool antialias;
if (FcPatternGetBool(aPattern, FC_ANTIALIAS, 0, &antialias) ==
@ -465,45 +466,13 @@ already_AddRefed<ScaledFont> UnscaledFontFontconfig::CreateScaledFont(
}
}
cairo_font_options_t* fontOptions = cairo_font_options_create();
int loadFlags;
unsigned int synthFlags;
instanceData.SetupFontOptions(fontOptions, &loadFlags, &synthFlags);
cairo_font_face_t* font = cairo_ft_font_face_create_for_ft_face(
face->GetFace(), loadFlags, synthFlags, face.get());
if (cairo_font_face_status(font) != CAIRO_STATUS_SUCCESS) {
gfxWarning() << "Failed creating Cairo font face for Fontconfig pattern";
cairo_font_options_destroy(fontOptions);
return nullptr;
}
cairo_matrix_t sizeMatrix;
cairo_matrix_init(&sizeMatrix, aSize, 0, 0, aSize, 0, 0);
cairo_matrix_t identityMatrix;
cairo_matrix_init_identity(&identityMatrix);
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;
}
// Only apply variations if we have an explicitly cloned face.
if (aNumVariations > 0 && face != GetFace()) {
ApplyVariationsToFace(aVariations, aNumVariations, face->GetFace());
}
RefPtr<ScaledFontFontconfig> scaledFont = new ScaledFontFontconfig(
cairoScaledFont, std::move(face), instanceData, this, aSize);
cairo_scaled_font_destroy(cairoScaledFont);
RefPtr<ScaledFontFontconfig> scaledFont =
new ScaledFontFontconfig(std::move(face), instanceData, this, aSize);
return scaledFont.forget();
}

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

@ -20,8 +20,7 @@ class UnscaledFontFontconfig;
class ScaledFontFontconfig : public ScaledFontBase {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontFontconfig, override)
ScaledFontFontconfig(cairo_scaled_font_t* aScaledFont,
RefPtr<SharedFTFace>&& aFace, FcPattern* aPattern,
ScaledFontFontconfig(RefPtr<SharedFTFace>&& aFace, FcPattern* aPattern,
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize);
FontType GetType() const override { return FontType::FONTCONFIG; }
@ -44,6 +43,12 @@ class ScaledFontFontconfig : public ScaledFontBase {
bool HasVariationSettings() override;
protected:
#ifdef USE_CAIRO_SCALED_FONT
cairo_font_face_t* CreateCairoFontFace(
cairo_font_options_t* aFontOptions) override;
#endif
private:
friend class NativeFontResourceFontconfig;
friend class UnscaledFontFontconfig;
@ -58,7 +63,7 @@ class ScaledFontFontconfig : public ScaledFontBase {
SUBPIXEL_BGR = 1 << 5,
};
InstanceData(cairo_scaled_font_t* aScaledFont, FcPattern* aPattern);
explicit InstanceData(FcPattern* aPattern);
InstanceData(const wr::FontInstanceOptions* aOptions,
const wr::FontInstancePlatformOptions* aPlatformOptions);
@ -72,8 +77,7 @@ class ScaledFontFontconfig : public ScaledFontBase {
uint8_t mLcdFilter;
};
ScaledFontFontconfig(cairo_scaled_font_t* aScaledFont,
RefPtr<SharedFTFace>&& aFace,
ScaledFontFontconfig(RefPtr<SharedFTFace>&& aFace,
const InstanceData& aInstanceData,
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize);

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

@ -19,19 +19,12 @@
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, RefPtr<SharedFTFace>&& aFace,
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
bool aApplySyntheticBold)
RefPtr<SharedFTFace>&& aFace, const RefPtr<UnscaledFont>& aUnscaledFont,
Float aSize, bool aApplySyntheticBold)
: ScaledFontBase(aUnscaledFont, aSize),
mFace(std::move(aFace)),
mApplySyntheticBold(aApplySyntheticBold) {
SetCairoScaledFont(aScaledFont);
}
mApplySyntheticBold(aApplySyntheticBold) {}
#ifdef USE_SKIA
SkTypeface* ScaledFontFreeType::CreateSkTypeface() {
@ -50,6 +43,26 @@ void ScaledFontFreeType::SetupSkFontDrawOptions(SkFont& aFont) {
}
#endif
#ifdef USE_CAIRO_SCALED_FONT
cairo_font_face_t* ScaledFontFreeType::CreateCairoFontFace(
cairo_font_options_t* aFontOptions) {
cairo_font_options_set_hint_metrics(aFontOptions, CAIRO_HINT_METRICS_OFF);
int loadFlags = FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING;
if (mFace->GetFace()->face_flags & FT_FACE_FLAG_TRICKY) {
loadFlags &= ~FT_LOAD_NO_AUTOHINT;
}
unsigned int synthFlags = 0;
if (mApplySyntheticBold) {
synthFlags |= CAIRO_FT_SYNTHESIZE_BOLD;
}
return cairo_ft_font_face_create_for_ft_face(mFace->GetFace(), loadFlags,
synthFlags, mFace.get());
}
#endif
bool ScaledFontFreeType::GetFontInstanceData(FontInstanceDataOutput aCb,
void* aBaton) {
std::vector<FontVariation> variations;
@ -132,48 +145,13 @@ already_AddRefed<ScaledFont> UnscaledFontFreeType::CreateScaledFont(
}
}
int flags = FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING;
if (face->GetFace()->face_flags & FT_FACE_FLAG_TRICKY) {
flags &= ~FT_LOAD_NO_AUTOHINT;
}
cairo_font_face_t* font = cairo_ft_font_face_create_for_ft_face(
face->GetFace(), flags, 0, face.get());
if (cairo_font_face_status(font) != CAIRO_STATUS_SUCCESS) {
gfxWarning() << "Failed creating Cairo font face for FreeType face";
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;
}
// Only apply variations if we have an explicitly cloned face.
if (aNumVariations > 0 && face != GetFace()) {
ApplyVariationsToFace(aVariations, aNumVariations, face->GetFace());
}
RefPtr<ScaledFontFreeType> scaledFont =
new ScaledFontFreeType(cairoScaledFont, std::move(face), this, aGlyphSize,
instanceData.mApplySyntheticBold);
cairo_scaled_font_destroy(cairoScaledFont);
RefPtr<ScaledFontFreeType> scaledFont = new ScaledFontFreeType(
std::move(face), this, aGlyphSize, instanceData.mApplySyntheticBold);
return scaledFont.forget();
}

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

@ -20,8 +20,7 @@ class ScaledFontFreeType : public ScaledFontBase {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontFreeType, override)
ScaledFontFreeType(cairo_scaled_font_t* aScaledFont,
RefPtr<SharedFTFace>&& aFace,
ScaledFontFreeType(RefPtr<SharedFTFace>&& aFace,
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
bool aApplySyntheticBold = false);
@ -45,6 +44,12 @@ class ScaledFontFreeType : public ScaledFontBase {
bool HasVariationSettings() override;
protected:
#ifdef USE_CAIRO_SCALED_FONT
cairo_font_face_t* CreateCairoFontFace(
cairo_font_options_t* aFontOptions) override;
#endif
private:
friend UnscaledFontFreeType;

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

@ -623,11 +623,6 @@ already_AddRefed<ScaledFont> UnscaledFontMac::CreateScaledFont(
instanceData.mFontSmoothingBackgroundColor,
instanceData.mUseFontSmoothing, instanceData.mApplySyntheticBold);
if (mNeedsCairo && !scaledFont->PopulateCairoScaledFont()) {
gfxWarning() << "Unable to create cairo scaled Mac font.";
return nullptr;
}
return scaledFont.forget();
}
@ -641,7 +636,8 @@ already_AddRefed<ScaledFont> UnscaledFontMac::CreateScaledFontFromWRFont(
}
#ifdef USE_CAIRO_SCALED_FONT
cairo_font_face_t* ScaledFontMac::GetCairoFontFace() {
cairo_font_face_t* ScaledFontMac::CreateCairoFontFace(
cairo_font_options_t* aFontOptions) {
MOZ_ASSERT(mFont);
return cairo_quartz_font_face_create_for_cgfont(mFont);
}

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

@ -50,7 +50,7 @@ class ScaledFontMac : public ScaledFontBase {
Color FontSmoothingBackgroundColor() { return mFontSmoothingBackgroundColor; }
#ifdef USE_CAIRO_SCALED_FONT
cairo_font_face_t* GetCairoFontFace() override;
cairo_font_face_t* CreateCairoFontFace(cairo_font_options_t* aFontOptions) override;
#endif
private:

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

@ -97,12 +97,8 @@ already_AddRefed<ScaledFont> UnscaledFontGDI::CreateScaledFont(
gfxWarning() << "GDI unscaled font instance data is truncated.";
return nullptr;
}
NativeFont nativeFont;
nativeFont.mType = NativeFontType::GDI_LOGFONT;
nativeFont.mFont = (void*)aInstanceData;
return Factory::CreateScaledFontForNativeFont(nativeFont, this, aGlyphSize);
return MakeAndAddRef<ScaledFontWin>(
reinterpret_cast<const LOGFONT*>(aInstanceData), this, aGlyphSize);
}
AntialiasMode ScaledFontWin::GetDefaultAAMode() {
@ -116,7 +112,8 @@ SkTypeface* ScaledFontWin::CreateSkTypeface() {
#endif
#ifdef USE_CAIRO_SCALED_FONT
cairo_font_face_t* ScaledFontWin::GetCairoFontFace() {
cairo_font_face_t* ScaledFontWin::CreateCairoFontFace(
cairo_font_options_t* aFontOptions) {
if (mLogFont.lfFaceName[0] == 0) {
return nullptr;
}

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

@ -31,7 +31,8 @@ class ScaledFontWin : public ScaledFontBase {
protected:
#ifdef USE_CAIRO_SCALED_FONT
cairo_font_face_t* GetCairoFontFace() override;
cairo_font_face_t* CreateCairoFontFace(
cairo_font_options_t* aFontOptions) override;
#endif
private:

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

@ -302,10 +302,6 @@ enum class NativeSurfaceType : int8_t {
OPENGL_TEXTURE
};
enum class NativeFontType : int8_t {
GDI_LOGFONT,
};
enum class FontStyle : int8_t { NORMAL, ITALIC, BOLD, BOLD_ITALIC };
enum class FontHinting : int8_t { NONE, LIGHT, NORMAL, FULL };

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

@ -20,10 +20,8 @@ class UnscaledFontDWrite final : public UnscaledFont {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(UnscaledFontDWrite, override)
UnscaledFontDWrite(const RefPtr<IDWriteFontFace>& aFontFace,
const RefPtr<IDWriteFont>& aFont, bool aNeedsCairo = false)
: mFontFace(aFontFace),
mFont(aFont),
mNeedsCairo(aNeedsCairo) {}
const RefPtr<IDWriteFont>& aFont)
: mFontFace(aFontFace), mFont(aFont) {}
FontType GetType() const override { return FontType::DWRITE; }
@ -50,7 +48,6 @@ class UnscaledFontDWrite final : public UnscaledFont {
RefPtr<IDWriteFontFace> mFontFace;
RefPtr<IDWriteFontFace> mFontFaceBold;
RefPtr<IDWriteFont> mFont;
bool mNeedsCairo;
};
} // namespace gfx

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

@ -22,9 +22,8 @@ namespace gfx {
class UnscaledFontMac final : public UnscaledFont {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(UnscaledFontMac, override)
explicit UnscaledFontMac(CGFontRef aFont, bool aIsDataFont = false,
bool aNeedsCairo = false)
: mFont(aFont), mIsDataFont(aIsDataFont), mNeedsCairo(aNeedsCairo) {
explicit UnscaledFontMac(CGFontRef aFont, bool aIsDataFont = false)
: mFont(aFont), mIsDataFont(aIsDataFont) {
CFRetain(mFont);
}
virtual ~UnscaledFontMac() { CFRelease(mFont); }
@ -56,7 +55,6 @@ class UnscaledFontMac final : public UnscaledFont {
private:
CGFontRef mFont;
bool mIsDataFont;
bool mNeedsCairo;
};
} // namespace gfx

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

@ -13,29 +13,10 @@
#include "harfbuzz/hb.h"
#include "mozilla/FontPropertyTypes.h"
#include "cairo-win32.h"
using namespace mozilla;
using namespace mozilla::gfx;
// This is also in gfxGDIFont.cpp. Would be nice to put it somewhere common,
// but we can't declare it in the gfxFont.h or gfxFontUtils.h headers
// because those are exported, and the cairo headers aren't.
static inline cairo_antialias_t GetCairoAntialiasOption(
gfxFont::AntialiasOption anAntialiasOption) {
switch (anAntialiasOption) {
default:
case gfxFont::kAntialiasDefault:
return CAIRO_ANTIALIAS_DEFAULT;
case gfxFont::kAntialiasNone:
return CAIRO_ANTIALIAS_NONE;
case gfxFont::kAntialiasGrayscale:
return CAIRO_ANTIALIAS_GRAY;
case gfxFont::kAntialiasSubpixel:
return CAIRO_ANTIALIAS_SUBPIXEL;
}
}
// Code to determine whether Windows is set to use ClearType font smoothing;
// based on private functions in cairo-win32-font.c
@ -100,7 +81,6 @@ gfxDWriteFont::gfxDWriteFont(const RefPtr<UnscaledFontDWrite>& aUnscaledFont,
AntialiasOption anAAOption)
: gfxFont(aUnscaledFont, aFontEntry, aFontStyle, anAAOption),
mFontFace(aFontFace ? aFontFace : aUnscaledFont->GetFontFace()),
mCairoFontFace(nullptr),
mMetrics(nullptr),
mSpaceGlyph(0),
mUseSubpixelPositions(false),
@ -114,15 +94,7 @@ gfxDWriteFont::gfxDWriteFont(const RefPtr<UnscaledFontDWrite>& aUnscaledFont,
ComputeMetrics(anAAOption);
}
gfxDWriteFont::~gfxDWriteFont() {
if (mCairoFontFace) {
cairo_font_face_destroy(mCairoFontFace);
}
if (mScaledFont) {
cairo_scaled_font_destroy(mScaledFont);
}
delete mMetrics;
}
gfxDWriteFont::~gfxDWriteFont() { delete mMetrics; }
static void ForceFontUpdate() {
// update device context font cache
@ -475,49 +447,6 @@ bool gfxDWriteFont::IsValid() const { return mFontFace != nullptr; }
IDWriteFontFace* gfxDWriteFont::GetFontFace() { return mFontFace.get(); }
cairo_font_face_t* gfxDWriteFont::CairoFontFace() {
if (!mCairoFontFace) {
#ifdef CAIRO_HAS_DWRITE_FONT
mCairoFontFace = cairo_dwrite_font_face_create_for_dwrite_fontface(
((gfxDWriteFontEntry*)mFontEntry.get())->mFont, mFontFace);
#endif
}
return mCairoFontFace;
}
cairo_scaled_font_t* gfxDWriteFont::InitCairoScaledFont() {
if (!mScaledFont) {
cairo_matrix_t sizeMatrix;
cairo_matrix_t identityMatrix;
cairo_matrix_init_scale(&sizeMatrix, mAdjustedSize, mAdjustedSize);
cairo_matrix_init_identity(&identityMatrix);
cairo_font_options_t* fontOptions = cairo_font_options_create();
if (mAntialiasOption != kAntialiasDefault) {
cairo_font_options_set_antialias(
fontOptions, GetCairoAntialiasOption(mAntialiasOption));
}
mScaledFont = cairo_scaled_font_create(CairoFontFace(), &sizeMatrix,
&identityMatrix, fontOptions);
cairo_font_options_destroy(fontOptions);
cairo_dwrite_scaled_font_allow_manual_show_glyphs(mScaledFont,
mAllowManualShowGlyphs);
cairo_dwrite_scaled_font_set_force_GDI_classic(mScaledFont,
GetForceGDIClassic());
}
NS_ASSERTION(mAdjustedSize == 0.0 || cairo_scaled_font_status(mScaledFont) ==
CAIRO_STATUS_SUCCESS,
"Failed to make scaled font");
return mScaledFont;
}
gfxFont::RunMetrics gfxDWriteFont::Measure(const gfxTextRun* aTextRun,
uint32_t aStart, uint32_t aEnd,
BoundingBoxType aBoundingBoxType,
@ -697,16 +626,6 @@ already_AddRefed<ScaledFont> gfxDWriteFont::GetScaledFont(
mAzureScaledFontUsedClearType = UsingClearType();
}
if (aTarget->GetBackendType() == BackendType::CAIRO) {
if (!mAzureScaledFont->GetCairoScaledFont()) {
cairo_scaled_font_t* cairoScaledFont = InitCairoScaledFont();
if (!cairoScaledFont) {
return nullptr;
}
mAzureScaledFont->SetCairoScaledFont(cairoScaledFont);
}
}
RefPtr<ScaledFont> scaledFont(mAzureScaledFont);
return scaledFont.forget();
}

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

@ -18,9 +18,6 @@
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/UnscaledFontDWrite.h"
struct _cairo_font_face;
typedef _cairo_font_face cairo_font_face_t;
/**
* \brief Class representing a font face for a font entry.
*/
@ -72,8 +69,6 @@ class gfxDWriteFont : public gfxFont {
bool ShouldRoundXOffset(cairo_t* aCairo) const override;
protected:
cairo_scaled_font_t* InitCairoScaledFont();
const Metrics& GetHorizontalMetrics() override;
bool GetFakeMetricsForArialBlack(DWRITE_FONT_METRICS* aFontMetrics);
@ -82,8 +77,6 @@ class gfxDWriteFont : public gfxFont {
bool HasBitmapStrikeForSize(uint32_t aSize);
cairo_font_face_t* CairoFontFace();
gfxFloat MeasureGlyphWidth(uint16_t aGlyph);
DWRITE_MEASURING_MODE GetMeasuringMode() const;
@ -92,8 +85,6 @@ class gfxDWriteFont : public gfxFont {
RefPtr<IDWriteFontFace> mFontFace;
RefPtr<IDWriteFontFace1> mFontFace1; // may be unavailable on older DWrite
cairo_font_face_t* mCairoFontFace;
Metrics* mMetrics;
// cache of glyph widths in 16.16 fixed-point pixels

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

@ -28,21 +28,17 @@ using namespace mozilla::gfx;
gfxFT2FontBase::gfxFT2FontBase(
const RefPtr<UnscaledFontFreeType>& aUnscaledFont,
cairo_scaled_font_t* aScaledFont,
RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace, gfxFontEntry* aFontEntry,
const gfxFontStyle* aFontStyle, int aLoadFlags, bool aEmbolden)
: gfxFont(aUnscaledFont, aFontEntry, aFontStyle, kAntialiasDefault,
aScaledFont),
: gfxFont(aUnscaledFont, aFontEntry, aFontStyle, kAntialiasDefault),
mFTFace(std::move(aFTFace)),
mSpaceGlyph(0),
mFTLoadFlags(aLoadFlags | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH |
FT_LOAD_COLOR),
mEmbolden(aEmbolden),
mFTSize(1.0) {
cairo_scaled_font_reference(mScaledFont);
}
mFTSize(1.0) {}
gfxFT2FontBase::~gfxFT2FontBase() { cairo_scaled_font_destroy(mScaledFont); }
gfxFT2FontBase::~gfxFT2FontBase() {}
FT_Face gfxFT2FontBase::LockFTFace() {
if (!mFTFace->Lock(this)) {
@ -56,61 +52,35 @@ FT_Face gfxFT2FontBase::LockFTFace() {
void gfxFT2FontBase::UnlockFTFace() { mFTFace->Unlock(); }
uint32_t gfxFT2FontBase::GetGlyph(uint32_t aCharCode) {
// FcFreeTypeCharIndex needs to lock the FT_Face and can end up searching
// through all the postscript glyph names in the font. Therefore use a
// lightweight cache, which is stored on the cairo_font_face_t.
cairo_font_face_t* face =
cairo_scaled_font_get_font_face(GetCairoScaledFont());
if (cairo_font_face_status(face) != CAIRO_STATUS_SUCCESS) return 0;
gfxFT2FontEntryBase::CmapCacheSlot* gfxFT2FontEntryBase::GetCmapCacheSlot(
uint32_t aCharCode) {
// This cache algorithm and size is based on what is done in
// cairo_scaled_font_text_to_glyphs and pango_fc_font_real_get_glyph. I
// think the concept is that adjacent characters probably come mostly from
// one Unicode block. This assumption is probably not so valid with
// scripts with large character sets as used for East Asian languages.
struct CmapCacheSlot {
uint32_t mCharCode;
uint32_t mGlyphIndex;
};
const uint32_t kNumSlots = 256;
static cairo_user_data_key_t sCmapCacheKey;
CmapCacheSlot* slots = static_cast<CmapCacheSlot*>(
cairo_font_face_get_user_data(face, &sCmapCacheKey));
if (!slots) {
// cairo's caches can keep some cairo_font_faces alive past our last
// destroy, so the destroy function (free) for the cache must be
// callable from cairo without any assumptions about what other
// modules have not been shutdown.
slots =
static_cast<CmapCacheSlot*>(calloc(kNumSlots, sizeof(CmapCacheSlot)));
if (!slots) return 0;
cairo_status_t status =
cairo_font_face_set_user_data(face, &sCmapCacheKey, slots, free);
if (status != CAIRO_STATUS_SUCCESS) { // OOM
free(slots);
return 0;
}
if (!mCmapCache) {
mCmapCache = mozilla::MakeUnique<CmapCacheSlot[]>(kNumCmapCacheSlots);
// Invalidate slot 0 by setting its char code to something that would
// never end up in slot 0. All other slots are already invalid
// because they have mCharCode = 0 and a glyph for char code 0 will
// always be in the slot 0.
slots[0].mCharCode = 1;
mCmapCache[0].mCharCode = 1;
}
return &mCmapCache[aCharCode % kNumCmapCacheSlots];
}
CmapCacheSlot* slot = &slots[aCharCode % kNumSlots];
uint32_t gfxFT2FontBase::GetGlyph(uint32_t aCharCode) {
// FcFreeTypeCharIndex needs to lock the FT_Face and can end up searching
// through all the postscript glyph names in the font. Therefore use a
// lightweight cache, which is stored on the font entry.
auto* slot = static_cast<gfxFT2FontEntryBase*>(mFontEntry.get())
->GetCmapCacheSlot(aCharCode);
if (slot->mCharCode != aCharCode) {
slot->mCharCode = aCharCode;
slot->mGlyphIndex = gfxFT2LockedFace(this).GetGlyph(aCharCode);
}
return slot->mGlyphIndex;
}

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

@ -6,19 +6,38 @@
#ifndef GFX_FT2FONTBASE_H
#define GFX_FT2FONTBASE_H
#include "cairo.h"
#include "gfxContext.h"
#include "gfxFont.h"
#include "gfxFontEntry.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/UnscaledFontFreeType.h"
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
class gfxFT2FontEntryBase : public gfxFontEntry {
public:
explicit gfxFT2FontEntryBase(const nsACString& aName)
: gfxFontEntry(aName) {}
struct CmapCacheSlot {
CmapCacheSlot() : mCharCode(0), mGlyphIndex(0) {}
uint32_t mCharCode;
uint32_t mGlyphIndex;
};
CmapCacheSlot* GetCmapCacheSlot(uint32_t aCharCode);
private:
enum { kNumCmapCacheSlots = 256 };
mozilla::UniquePtr<CmapCacheSlot[]> mCmapCache;
};
class gfxFT2FontBase : public gfxFont {
public:
gfxFT2FontBase(
const RefPtr<mozilla::gfx::UnscaledFontFreeType>& aUnscaledFont,
cairo_scaled_font_t* aScaledFont,
RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace, gfxFontEntry* aFontEntry,
const gfxFontStyle* aFontStyle, int aLoadFlags, bool aEmbolden);
virtual ~gfxFT2FontBase();

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

@ -144,55 +144,6 @@ FTUserFontData* FT2FontEntry::GetUserFontData() {
* then create a Cairo font_face and scaled_font for drawing.
*/
cairo_scaled_font_t* FT2FontEntry::CreateScaledFont(
const gfxFontStyle* aStyle, RefPtr<SharedFTFace> aFace, int* aOutLoadFlags,
unsigned int* aOutSynthFlags) {
int loadFlags = gfxPlatform::GetPlatform()->FontHintingEnabled()
? FT_LOAD_DEFAULT
: (FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
if (aFace->GetFace()->face_flags & FT_FACE_FLAG_TRICKY) {
loadFlags &= ~FT_LOAD_NO_AUTOHINT;
}
unsigned int synthFlags = 0;
if (aStyle->NeedsSyntheticBold(this)) {
synthFlags |= CAIRO_FT_SYNTHESIZE_BOLD;
}
*aOutLoadFlags = loadFlags;
*aOutSynthFlags = synthFlags;
cairo_font_face_t* cairoFace = cairo_ft_font_face_create_for_ft_face(
aFace->GetFace(), loadFlags, synthFlags, aFace.get());
if (!cairoFace) {
return nullptr;
}
cairo_scaled_font_t* scaledFont = nullptr;
cairo_matrix_t sizeMatrix;
cairo_matrix_t identityMatrix;
// XXX deal with adjusted size
cairo_matrix_init_scale(&sizeMatrix, aStyle->size, aStyle->size);
cairo_matrix_init_identity(&identityMatrix);
cairo_font_options_t* fontOptions = cairo_font_options_create();
if (gfxPlatform::GetPlatform()->RequiresLinearZoom()) {
cairo_font_options_set_hint_metrics(fontOptions, CAIRO_HINT_METRICS_OFF);
}
scaledFont = cairo_scaled_font_create(cairoFace, &sizeMatrix, &identityMatrix,
fontOptions);
cairo_font_options_destroy(fontOptions);
NS_ASSERTION(cairo_scaled_font_status(scaledFont) == CAIRO_STATUS_SUCCESS,
"Failed to make scaled font");
return scaledFont;
}
FT2FontEntry::~FT2FontEntry() {
if (mMMVar) {
FT_Done_MM_Var(mFTFace->GetFace()->glyph->library, mMMVar);
@ -240,12 +191,11 @@ gfxFont* FT2FontEntry::CreateFontInstance(const gfxFontStyle* aStyle) {
}
}
int loadFlags;
unsigned int synthFlags;
cairo_scaled_font_t* scaledFont =
CreateScaledFont(aStyle, face, &loadFlags, &synthFlags);
if (!scaledFont) {
return nullptr;
int loadFlags = gfxPlatform::GetPlatform()->FontHintingEnabled()
? FT_LOAD_DEFAULT
: (FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
if (face->GetFace()->face_flags & FT_FACE_FLAG_TRICKY) {
loadFlags &= ~FT_LOAD_NO_AUTOHINT;
}
RefPtr<UnscaledFontFreeType> unscaledFont(mUnscaledFont);
@ -258,9 +208,7 @@ gfxFont* FT2FontEntry::CreateFontInstance(const gfxFontStyle* aStyle) {
}
gfxFont* font =
new gfxFT2Font(unscaledFont, scaledFont, std::move(face), this, aStyle,
loadFlags, (synthFlags & CAIRO_FT_SYNTHESIZE_BOLD) != 0);
cairo_scaled_font_destroy(scaledFont);
new gfxFT2Font(unscaledFont, std::move(face), this, aStyle, loadFlags);
return font;
}

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

@ -7,8 +7,8 @@
#define GFX_FT2FONTLIST_H
#include "mozilla/MemoryReporting.h"
#include "gfxFT2FontBase.h"
#include "gfxPlatformFontList.h"
#include "mozilla/gfx/UnscaledFontFreeType.h"
namespace mozilla {
namespace dom {
@ -23,10 +23,10 @@ class nsZipArchive;
class WillShutdownObserver;
class FTUserFontData;
class FT2FontEntry : public gfxFontEntry {
class FT2FontEntry : public gfxFT2FontEntryBase {
public:
explicit FT2FontEntry(const nsACString& aFaceName)
: gfxFontEntry(aFaceName), mFTFontIndex(0) {}
: gfxFT2FontEntryBase(aFaceName), mFTFontIndex(0) {}
~FT2FontEntry();
@ -54,12 +54,6 @@ class FT2FontEntry : public gfxFontEntry {
gfxFont* CreateFontInstance(const gfxFontStyle* aStyle) override;
// Create a cairo_scaled_font for this face, with the given style.
// This may fail and return null, so caller must be prepared to handle this.
cairo_scaled_font_t* CreateScaledFont(
const gfxFontStyle* aStyle, RefPtr<mozilla::gfx::SharedFTFace> aFace,
int* aOutLoadFlags, unsigned int* aOutSynthFlags);
nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override;
hb_blob_t* GetFontTable(uint32_t aTableTag) override;

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

@ -153,12 +153,11 @@ void gfxFT2Font::AddRange(const char16_t* aText, uint32_t aOffset,
}
gfxFT2Font::gfxFT2Font(const RefPtr<UnscaledFontFreeType>& aUnscaledFont,
cairo_scaled_font_t* aCairoFont,
RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace,
FT2FontEntry* aFontEntry, const gfxFontStyle* aFontStyle,
int aLoadFlags, bool aEmbolden)
: gfxFT2FontBase(aUnscaledFont, aCairoFont, std::move(aFTFace), aFontEntry,
aFontStyle, aLoadFlags, aEmbolden),
int aLoadFlags)
: gfxFT2FontBase(aUnscaledFont, std::move(aFTFace), aFontEntry, aFontStyle,
aLoadFlags, aFontStyle->NeedsSyntheticBold(aFontEntry)),
mCharGlyphCache(32) {
NS_ASSERTION(mFontEntry,
"Unable to find font entry for font. Something is whack.");
@ -170,7 +169,7 @@ gfxFT2Font::~gfxFT2Font() {}
already_AddRefed<ScaledFont> gfxFT2Font::GetScaledFont(DrawTarget* aTarget) {
if (!mAzureScaledFont) {
mAzureScaledFont = Factory::CreateScaledFontForFreeTypeFont(
GetUnscaledFont(), GetAdjustedSize(), GetCairoScaledFont(), mFTFace,
GetUnscaledFont(), GetAdjustedSize(), mFTFace,
GetStyle()->NeedsSyntheticBold(GetFontEntry()));
InitializeScaledFont();
}

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

@ -7,7 +7,6 @@
#define GFX_FT2FONTS_H
#include "mozilla/MemoryReporting.h"
#include "cairo.h"
#include "gfxTypes.h"
#include "gfxFont.h"
#include "gfxFT2FontBase.h"
@ -20,10 +19,9 @@ class FT2FontEntry;
class gfxFT2Font : public gfxFT2FontBase {
public: // new functions
gfxFT2Font(const RefPtr<mozilla::gfx::UnscaledFontFreeType>& aUnscaledFont,
cairo_scaled_font_t* aCairoFont,
RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace,
FT2FontEntry* aFontEntry, const gfxFontStyle* aFontStyle,
int aLoadFlags, bool aEmbolden);
int aLoadFlags);
virtual ~gfxFT2Font();
FT2FontEntry* GetFontEntry();

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

@ -28,6 +28,7 @@
#include "mozilla/gfx/HelpersCairo.h"
#include <cairo-ft.h>
#include <fontconfig/fcfreetype.h>
#include <dlfcn.h>
#include <unistd.h>
@ -245,7 +246,7 @@ static void GetFontProperties(FcPattern* aFontPattern, WeightRange* aWeight,
gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsACString& aFaceName,
FcPattern* aFontPattern,
bool aIgnoreFcCharmap)
: gfxFontEntry(aFaceName),
: gfxFT2FontEntryBase(aFaceName),
mFontPattern(aFontPattern),
mFTFaceInitialized(false),
mIgnoreFcCharmap(aIgnoreFcCharmap),
@ -303,7 +304,7 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsACString& aFaceName,
StretchRange aStretch,
SlantStyleRange aStyle,
RefPtr<SharedFTFace>&& aFace)
: gfxFontEntry(aFaceName),
: gfxFT2FontEntryBase(aFaceName),
mFTFace(std::move(aFace)),
mFTFaceInitialized(true),
mIgnoreFcCharmap(true),
@ -322,7 +323,7 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsACString& aFaceName,
WeightRange aWeight,
StretchRange aStretch,
SlantStyleRange aStyle)
: gfxFontEntry(aFaceName),
: gfxFT2FontEntryBase(aFaceName),
mFontPattern(aFontPattern),
mFTFaceInitialized(false),
mHasVariationsInitialized(false),
@ -525,14 +526,9 @@ double gfxFontconfigFontEntry::GetAspect() {
return mAspect;
}
static void PrepareFontOptions(FcPattern* aPattern,
cairo_font_options_t* aFontOptions,
int* aOutLoadFlags, int* aOutLoadTarget,
static void PrepareFontOptions(FcPattern* aPattern, int* aOutLoadFlags,
unsigned int* aOutSynthFlags) {
NS_ASSERTION(aFontOptions, "null font options passed to PrepareFontOptions");
int loadFlags = FT_LOAD_DEFAULT;
int loadTarget = 0;
unsigned int synthFlags = 0;
// xxx - taken from the gfxFontconfigFonts code, needs to be reviewed
@ -578,11 +574,6 @@ static void PrepareFontOptions(FcPattern* aPattern,
// font will be used, but currently we don't have different gfxFonts for
// different surface font_options, so we'll create a font suitable for the
// Screen. Image and xlib surfaces default to CAIRO_HINT_METRICS_ON.
if (printing) {
cairo_font_options_set_hint_metrics(aFontOptions, CAIRO_HINT_METRICS_OFF);
} else {
cairo_font_options_set_hint_metrics(aFontOptions, CAIRO_HINT_METRICS_ON);
}
// The remaining options have been recorded on the pattern and the face.
// _cairo_ft_options_merge has some logic to decide which options from the
@ -611,7 +602,6 @@ static void PrepareFontOptions(FcPattern* aPattern,
hinting = FcTrue;
}
cairo_hint_style_t hint_style;
int fc_hintstyle = FC_HINT_NONE;
if ((!printing || hinting) &&
FcPatternGetInteger(aPattern, FC_HINT_STYLE, 0, &fc_hintstyle) !=
@ -620,108 +610,49 @@ static void PrepareFontOptions(FcPattern* aPattern,
}
switch (fc_hintstyle) {
case FC_HINT_NONE:
hint_style = CAIRO_HINT_STYLE_NONE;
loadTarget = FT_LOAD_NO_HINTING;
loadFlags = FT_LOAD_NO_HINTING;
break;
case FC_HINT_SLIGHT:
hint_style = CAIRO_HINT_STYLE_SLIGHT;
loadTarget = FT_LOAD_TARGET_LIGHT;
break;
case FC_HINT_MEDIUM:
default: // This fallback mirrors _get_pattern_ft_options in cairo.
hint_style = CAIRO_HINT_STYLE_MEDIUM;
break;
case FC_HINT_FULL:
hint_style = CAIRO_HINT_STYLE_FULL;
loadFlags = FT_LOAD_TARGET_LIGHT;
break;
}
cairo_font_options_set_hint_style(aFontOptions, hint_style);
int rgba;
if (FcPatternGetInteger(aPattern, FC_RGBA, 0, &rgba) != FcResultMatch) {
rgba = FC_RGBA_UNKNOWN;
}
cairo_subpixel_order_t subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
switch (rgba) {
case FC_RGBA_UNKNOWN:
case FC_RGBA_NONE:
default:
// There is no CAIRO_SUBPIXEL_ORDER_NONE. Subpixel antialiasing
// is disabled through cairo_antialias_t.
rgba = FC_RGBA_NONE;
// subpixel_order won't be used by the font as we won't use
// CAIRO_ANTIALIAS_SUBPIXEL, but don't leave it at default for
// caching reasons described above. Fall through:
MOZ_FALLTHROUGH;
case FC_RGBA_RGB:
subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB;
break;
case FC_RGBA_BGR:
subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR;
break;
case FC_RGBA_VRGB:
subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB;
break;
case FC_RGBA_VBGR:
subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR;
break;
}
cairo_font_options_set_subpixel_order(aFontOptions, subpixel_order);
FcBool fc_antialias;
if (FcPatternGetBool(aPattern, FC_ANTIALIAS, 0, &fc_antialias) !=
FcResultMatch) {
fc_antialias = FcTrue;
}
cairo_antialias_t antialias;
if (!fc_antialias) {
antialias = CAIRO_ANTIALIAS_NONE;
if (fc_hintstyle != FC_HINT_NONE) {
loadTarget = FT_LOAD_TARGET_MONO;
loadFlags = FT_LOAD_TARGET_MONO;
}
loadTarget |= FT_LOAD_MONOCHROME;
} else if (rgba == FC_RGBA_NONE) {
antialias = CAIRO_ANTIALIAS_GRAY;
} else {
antialias = CAIRO_ANTIALIAS_SUBPIXEL;
if (fc_hintstyle == FC_HINT_FULL) {
loadTarget = rgba == FC_RGBA_VRGB || rgba == FC_RGBA_VBGR
? FT_LOAD_TARGET_LCD_V
: FT_LOAD_TARGET_LCD;
loadFlags |= FT_LOAD_MONOCHROME;
} else if (fc_hintstyle == FC_HINT_FULL) {
int fc_rgba;
if (FcPatternGetInteger(aPattern, FC_RGBA, 0, &fc_rgba) != FcResultMatch) {
fc_rgba = FC_RGBA_UNKNOWN;
}
switch (fc_rgba) {
case FC_RGBA_RGB:
case FC_RGBA_BGR:
loadFlags = FT_LOAD_TARGET_LCD;
break;
case FC_RGBA_VRGB:
case FC_RGBA_VBGR:
loadFlags = FT_LOAD_TARGET_LCD_V;
break;
}
}
cairo_font_options_set_antialias(aFontOptions, antialias);
FcBool bitmap;
if (FcPatternGetBool(aPattern, FC_EMBEDDED_BITMAP, 0, &bitmap) !=
FcResultMatch) {
bitmap = FcFalse;
}
if (fc_antialias && (hint_style == CAIRO_HINT_STYLE_NONE || !bitmap)) {
if (fc_antialias && (fc_hintstyle == FC_HINT_NONE || !bitmap)) {
loadFlags |= FT_LOAD_NO_BITMAP;
}
int fc_lcd_filter;
if (FcPatternGetInteger(aPattern, FC_LCD_FILTER, 0, &fc_lcd_filter) ==
FcResultMatch) {
cairo_lcd_filter_t lcd_filter = CAIRO_LCD_FILTER_DEFAULT;
switch (fc_lcd_filter) {
case FC_LCD_NONE:
lcd_filter = CAIRO_LCD_FILTER_NONE;
break;
case FC_LCD_DEFAULT:
lcd_filter = CAIRO_LCD_FILTER_FIR5;
break;
case FC_LCD_LIGHT:
lcd_filter = CAIRO_LCD_FILTER_FIR3;
break;
case FC_LCD_LEGACY:
lcd_filter = CAIRO_LCD_FILTER_INTRA_PIXEL;
break;
}
cairo_font_options_set_lcd_filter(aFontOptions, lcd_filter);
}
FcBool autohint;
if (FcPatternGetBool(aPattern, FC_AUTOHINT, 0, &autohint) == FcResultMatch &&
autohint) {
@ -735,68 +666,9 @@ static void PrepareFontOptions(FcPattern* aPattern,
}
*aOutLoadFlags = loadFlags;
*aOutLoadTarget = loadTarget;
*aOutSynthFlags = synthFlags;
}
cairo_scaled_font_t* gfxFontconfigFontEntry::CreateScaledFont(
FcPattern* aRenderPattern, gfxFloat aAdjustedSize,
const gfxFontStyle* aStyle, RefPtr<SharedFTFace> aFTFace,
int* aOutLoadFlags, unsigned int* aOutSynthFlags) {
if (aStyle->NeedsSyntheticBold(this)) {
FcPatternAddBool(aRenderPattern, FC_EMBOLDEN, FcTrue);
}
// will synthetic oblique be applied using a transform?
bool needsOblique = IsUpright() &&
aStyle->style != FontSlantStyle::Normal() &&
aStyle->allowSyntheticStyle;
if (needsOblique) {
// disable embedded bitmaps (mimics behavior in 90-synthetic.conf)
FcPatternDel(aRenderPattern, FC_EMBEDDED_BITMAP);
FcPatternAddBool(aRenderPattern, FC_EMBEDDED_BITMAP, FcFalse);
}
if (HasVariations() && aFTFace != mFTFace) {
AutoTArray<gfxFontVariation, 8> settings;
GetVariationsForStyle(settings, *aStyle);
gfxFT2FontBase::SetupVarCoords(GetMMVar(), settings, aFTFace->GetFace());
}
cairo_font_options_t* fontOptions = cairo_font_options_create();
int loadFlags;
int loadTarget;
unsigned int synthFlags;
PrepareFontOptions(aRenderPattern, fontOptions, &loadFlags, &loadTarget,
&synthFlags);
*aOutLoadFlags = loadFlags | loadTarget;
*aOutSynthFlags = synthFlags;
cairo_font_face_t* face = cairo_ft_font_face_create_for_ft_face(
aFTFace->GetFace(), loadFlags, synthFlags, aFTFace.get());
cairo_scaled_font_t* scaledFont = nullptr;
cairo_matrix_t sizeMatrix;
cairo_matrix_t identityMatrix;
cairo_matrix_init_scale(&sizeMatrix, aAdjustedSize, aAdjustedSize);
cairo_matrix_init_identity(&identityMatrix);
scaledFont =
cairo_scaled_font_create(face, &sizeMatrix, &identityMatrix, fontOptions);
cairo_font_options_destroy(fontOptions);
NS_ASSERTION(cairo_scaled_font_status(scaledFont) == CAIRO_STATUS_SUCCESS,
"Failed to make scaled font");
cairo_font_face_destroy(face);
return scaledFont;
}
#ifdef MOZ_WIDGET_GTK
// defintion included below
static void ApplyGdkScreenFontOptions(FcPattern* aPattern);
@ -940,24 +812,23 @@ gfxFont* gfxFontconfigFontEntry::CreateFontInstance(
NS_WARNING("Failed to get FreeType face for pattern");
return nullptr;
}
if (face->GetFace()->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) {
if (HasVariations()) {
// For variation fonts, we create a new FT_Face here so that
// variation coordinates from the style can be applied without
// affecting other font instances created from the same entry
// (font resource).
if (face->GetData()) {
// For user fonts: create a new FT_Face from the font data, and then
// make a pattern from that.
face = face->GetData()->CloneFace();
} else {
// For system fonts: create a new FT_Face and store it in a copy of
// the original mFontPattern.
face = CreateFaceForPattern(mFontPattern);
if (!face) {
// I don't think CreateFaceForPattern above should ever fail,
// but just in case let's fall back here.
face = mFTFace;
}
// For user fonts: create a new FT_Face from the font data, and then make
// a pattern from that.
// For system fonts: create a new FT_Face and store it in a copy of the
// original mFontPattern.
RefPtr<SharedFTFace> varFace = face->GetData()
? face->GetData()->CloneFace()
: CreateFaceForPattern(mFontPattern);
if (varFace) {
AutoTArray<gfxFontVariation, 8> settings;
GetVariationsForStyle(settings, *aFontStyle);
gfxFT2FontBase::SetupVarCoords(GetMMVar(), settings, varFace->GetFace());
face = std::move(varFace);
}
}
@ -969,10 +840,21 @@ gfxFont* gfxFontconfigFontEntry::CreateFontInstance(
return nullptr;
}
if (aFontStyle->NeedsSyntheticBold(this)) {
FcPatternAddBool(renderPattern, FC_EMBOLDEN, FcTrue);
}
// will synthetic oblique be applied using a transform?
if (IsUpright() && aFontStyle->style != FontSlantStyle::Normal() &&
aFontStyle->allowSyntheticStyle) {
// disable embedded bitmaps (mimics behavior in 90-synthetic.conf)
FcPatternDel(renderPattern, FC_EMBEDDED_BITMAP);
FcPatternAddBool(renderPattern, FC_EMBEDDED_BITMAP, FcFalse);
}
int loadFlags;
unsigned int synthFlags;
cairo_scaled_font_t* scaledFont = CreateScaledFont(
renderPattern, size, aFontStyle, face, &loadFlags, &synthFlags);
PrepareFontOptions(renderPattern, &loadFlags, &synthFlags);
std::string file;
int index = 0;
@ -998,9 +880,8 @@ gfxFont* gfxFontconfigFontEntry::CreateFontInstance(
}
gfxFont* newFont = new gfxFontconfigFont(
unscaledFont, scaledFont, std::move(face), renderPattern, size, this,
aFontStyle, loadFlags, (synthFlags & CAIRO_FT_SYNTHESIZE_BOLD) != 0);
cairo_scaled_font_destroy(scaledFont);
unscaledFont, std::move(face), renderPattern, size, this, aFontStyle,
loadFlags, (synthFlags & CAIRO_FT_SYNTHESIZE_BOLD) != 0);
return newFont;
}
@ -1354,11 +1235,11 @@ void gfxFontconfigFontFamily::AddFacesToFontList(Func aAddPatternFunc) {
gfxFontconfigFont::gfxFontconfigFont(
const RefPtr<UnscaledFontFontconfig>& aUnscaledFont,
cairo_scaled_font_t* aScaledFont, RefPtr<SharedFTFace>&& aFTFace,
FcPattern* aPattern, gfxFloat aAdjustedSize, gfxFontEntry* aFontEntry,
const gfxFontStyle* aFontStyle, int aLoadFlags, bool aEmbolden)
: gfxFT2FontBase(aUnscaledFont, aScaledFont, std::move(aFTFace), aFontEntry,
aFontStyle, aLoadFlags, aEmbolden),
RefPtr<SharedFTFace>&& aFTFace, FcPattern* aPattern, gfxFloat aAdjustedSize,
gfxFontEntry* aFontEntry, const gfxFontStyle* aFontStyle, int aLoadFlags,
bool aEmbolden)
: gfxFT2FontBase(aUnscaledFont, std::move(aFTFace), aFontEntry, aFontStyle,
aLoadFlags, aEmbolden),
mPattern(aPattern) {
mAdjustedSize = aAdjustedSize;
InitMetrics();
@ -1370,8 +1251,7 @@ already_AddRefed<ScaledFont> gfxFontconfigFont::GetScaledFont(
mozilla::gfx::DrawTarget* aTarget) {
if (!mAzureScaledFont) {
mAzureScaledFont = Factory::CreateScaledFontForFontconfigFont(
GetUnscaledFont(), GetAdjustedSize(), GetCairoScaledFont(), mFTFace,
GetPattern());
GetUnscaledFont(), GetAdjustedSize(), mFTFace, GetPattern());
InitializeScaledFont();
}

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

@ -6,8 +6,6 @@
#ifndef GFXFCPLATFORMFONTLIST_H_
#define GFXFCPLATFORMFONTLIST_H_
#include "gfxFont.h"
#include "gfxFontEntry.h"
#include "gfxFT2FontBase.h"
#include "gfxPlatformFontList.h"
#include "mozilla/FontPropertyTypes.h"
@ -20,8 +18,6 @@
#include FT_FREETYPE_H
#include FT_TRUETYPE_TABLES_H
#include FT_MULTIPLE_MASTERS_H
#include <cairo.h>
#include <cairo-ft.h>
#if defined(MOZ_SANDBOX) && defined(XP_LINUX)
# include "mozilla/SandboxBroker.h"
@ -51,7 +47,7 @@ class nsAutoRefTraits<FcConfig> : public nsPointerRefTraits<FcConfig> {
// the common 'Fc' abbreviation but the gfxPangoFontGroup code already
// defines versions of these, so use the verbose name for now.
class gfxFontconfigFontEntry : public gfxFontEntry {
class gfxFontconfigFontEntry : public gfxFT2FontEntryBase {
public:
// used for system fonts with explicit patterns
explicit gfxFontconfigFontEntry(const nsACString& aFaceName,
@ -100,12 +96,6 @@ class gfxFontconfigFontEntry : public gfxFontEntry {
gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle) override;
// helper method for creating cairo font from pattern
cairo_scaled_font_t* CreateScaledFont(
FcPattern* aRenderPattern, gfxFloat aAdjustedSize,
const gfxFontStyle* aStyle, RefPtr<mozilla::gfx::SharedFTFace> aFTFace,
int* aOutLoadFlags, unsigned int* aOutSynthFlags);
// override to pull data from FTFace
virtual nsresult CopyFontTable(uint32_t aTableTag,
nsTArray<uint8_t>& aBuffer) override;
@ -207,15 +197,14 @@ class gfxFontconfigFont : public gfxFT2FontBase {
public:
gfxFontconfigFont(
const RefPtr<mozilla::gfx::UnscaledFontFontconfig>& aUnscaledFont,
cairo_scaled_font_t* aScaledFont,
RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace, FcPattern* aPattern,
gfxFloat aAdjustedSize, gfxFontEntry* aFontEntry,
const gfxFontStyle* aFontStyle, int aLoadFlags, bool aEmbolden);
FontType GetType() const override { return FONT_TYPE_FONTCONFIG; }
virtual FcPattern* GetPattern() const { return mPattern; }
FcPattern* GetPattern() const { return mPattern; }
virtual already_AddRefed<mozilla::gfx::ScaledFont> GetScaledFont(
already_AddRefed<mozilla::gfx::ScaledFont> GetScaledFont(
DrawTarget* aTarget) override;
bool ShouldHintMetrics() const override;

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

@ -773,9 +773,8 @@ void gfxFont::RunMetrics::CombineWith(const RunMetrics& aOther,
gfxFont::gfxFont(const RefPtr<UnscaledFont>& aUnscaledFont,
gfxFontEntry* aFontEntry, const gfxFontStyle* aFontStyle,
AntialiasOption anAAOption, cairo_scaled_font_t* aScaledFont)
: mScaledFont(aScaledFont),
mFontEntry(aFontEntry),
AntialiasOption anAAOption)
: mFontEntry(aFontEntry),
mUnscaledFont(aUnscaledFont),
mStyle(*aFontStyle),
mAdjustedSize(0.0),

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

@ -1390,7 +1390,6 @@ class gfxFont {
protected:
nsAutoRefCnt mRefCnt;
cairo_scaled_font_t* mScaledFont;
void NotifyReleased() {
gfxFontCache* cache = gfxFontCache::GetCache();
@ -1406,8 +1405,7 @@ class gfxFont {
gfxFont(const RefPtr<mozilla::gfx::UnscaledFont>& aUnscaledFont,
gfxFontEntry* aFontEntry, const gfxFontStyle* aFontStyle,
AntialiasOption anAAOption = kAntialiasDefault,
cairo_scaled_font_t* aScaledFont = nullptr);
AntialiasOption anAAOption = kAntialiasDefault);
public:
virtual ~gfxFont();
@ -1444,8 +1442,6 @@ class gfxFont {
const nsCString& GetName() const { return mFontEntry->Name(); }
const gfxFontStyle* GetStyle() const { return &mStyle; }
cairo_scaled_font_t* GetCairoScaledFont() { return mScaledFont; }
virtual mozilla::UniquePtr<gfxFont> CopyWithAntialiasOption(
AntialiasOption anAAOption) {
// platforms where this actually matters should override

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

@ -25,26 +25,10 @@ using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::unicode;
static inline cairo_antialias_t GetCairoAntialiasOption(
gfxFont::AntialiasOption anAntialiasOption) {
switch (anAntialiasOption) {
default:
case gfxFont::kAntialiasDefault:
return CAIRO_ANTIALIAS_DEFAULT;
case gfxFont::kAntialiasNone:
return CAIRO_ANTIALIAS_NONE;
case gfxFont::kAntialiasGrayscale:
return CAIRO_ANTIALIAS_GRAY;
case gfxFont::kAntialiasSubpixel:
return CAIRO_ANTIALIAS_SUBPIXEL;
}
}
gfxGDIFont::gfxGDIFont(GDIFontEntry* aFontEntry, const gfxFontStyle* aFontStyle,
AntialiasOption anAAOption)
: gfxFont(nullptr, aFontEntry, aFontStyle, anAAOption),
mFont(nullptr),
mFontFace(nullptr),
mMetrics(nullptr),
mSpaceGlyph(0),
mIsBitmap(false),
@ -59,12 +43,6 @@ gfxGDIFont::gfxGDIFont(GDIFontEntry* aFontEntry, const gfxFontStyle* aFontStyle,
}
gfxGDIFont::~gfxGDIFont() {
if (mScaledFont) {
cairo_scaled_font_destroy(mScaledFont);
}
if (mFontFace) {
cairo_font_face_destroy(mFontFace);
}
if (mFont) {
::DeleteObject(mFont);
}
@ -99,14 +77,11 @@ uint32_t gfxGDIFont::GetSpaceGlyph() { return mSpaceGlyph; }
already_AddRefed<ScaledFont> gfxGDIFont::GetScaledFont(DrawTarget* aTarget) {
if (!mAzureScaledFont) {
NativeFont nativeFont;
nativeFont.mType = NativeFontType::GDI_LOGFONT;
LOGFONT lf;
GetObject(GetHFONT(), sizeof(LOGFONT), &lf);
nativeFont.mFont = &lf;
mAzureScaledFont = Factory::CreateScaledFontForNativeFont(
nativeFont, GetUnscaledFont(), GetAdjustedSize(), GetCairoScaledFont());
mAzureScaledFont = Factory::CreateScaledFontForGDIFont(
&lf, GetUnscaledFont(), GetAdjustedSize());
InitializeScaledFont();
}
@ -354,35 +329,6 @@ void gfxGDIFont::Initialize() {
mMetrics->maxAdvance += GetSyntheticBoldOffset();
}
mFontFace = cairo_win32_font_face_create_for_logfontw_hfont(&logFont, mFont);
cairo_matrix_t sizeMatrix, ctm;
cairo_matrix_init_identity(&ctm);
cairo_matrix_init_scale(&sizeMatrix, mAdjustedSize, mAdjustedSize);
cairo_font_options_t* fontOptions = cairo_font_options_create();
if (mAntialiasOption != kAntialiasDefault) {
cairo_font_options_set_antialias(fontOptions,
GetCairoAntialiasOption(mAntialiasOption));
}
mScaledFont =
cairo_scaled_font_create(mFontFace, &sizeMatrix, &ctm, fontOptions);
cairo_font_options_destroy(fontOptions);
if (!mScaledFont ||
cairo_scaled_font_status(mScaledFont) != CAIRO_STATUS_SUCCESS) {
#ifdef DEBUG
char warnBuf[1024];
SprintfLiteral(warnBuf, "Failed to create scaled font: %s status: %d",
mFontEntry->Name().get(),
mScaledFont ? cairo_scaled_font_status(mScaledFont) : 0);
NS_WARNING(warnBuf);
#endif
mIsValid = false;
} else {
mIsValid = true;
}
#if 0
printf("Font: %p (%s) size: %f adjusted size: %f valid: %s\n", this,
GetName().get(), mStyle.size, mAdjustedSize, (mIsValid ? "yes" : "no"));

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

@ -13,7 +13,6 @@
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "cairo.h"
#include "usp10.h"
class gfxGDIFont : public gfxFont {
@ -25,8 +24,6 @@ class gfxGDIFont : public gfxFont {
HFONT GetHFONT() { return mFont; }
cairo_font_face_t* CairoFontFace() { return mFontFace; }
/* overrides for the pure virtual methods in gfxFont */
uint32_t GetSpaceGlyph() override;
@ -82,7 +79,6 @@ class gfxGDIFont : public gfxFont {
void FillLogFont(LOGFONTW& aLogFont, gfxFloat aSize);
HFONT mFont;
cairo_font_face_t* mFontFace;
Metrics* mMetrics;
uint32_t mSpaceGlyph;

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

@ -36,7 +36,6 @@ gfxMacFont::gfxMacFont(const RefPtr<UnscaledFontMac>& aUnscaledFont,
: gfxFont(aUnscaledFont, aFontEntry, aFontStyle),
mCGFont(nullptr),
mCTFont(nullptr),
mFontFace(nullptr),
mFontSmoothingBackgroundColor(aFontStyle->fontSmoothingBackgroundColor),
mVariationFont(aFontEntry->HasVariations()) {
mApplySyntheticBold = aFontStyle->NeedsSyntheticBold(aFontEntry);
@ -122,53 +121,13 @@ gfxMacFont::gfxMacFont(const RefPtr<UnscaledFontMac>& aUnscaledFont,
return;
}
mFontFace = cairo_quartz_font_face_create_for_cgfont(mCGFont);
cairo_status_t cairoerr = cairo_font_face_status(mFontFace);
if (cairoerr != CAIRO_STATUS_SUCCESS) {
mIsValid = false;
#ifdef DEBUG
char warnBuf[1024];
SprintfLiteral(warnBuf, "Failed to create Cairo font face: %s status: %d",
GetName().get(), cairoerr);
NS_WARNING(warnBuf);
#endif
return;
}
cairo_matrix_t sizeMatrix, ctm;
cairo_matrix_init_identity(&ctm);
cairo_matrix_init_scale(&sizeMatrix, mAdjustedSize, mAdjustedSize);
cairo_font_options_t* fontOptions = cairo_font_options_create();
// turn off font anti-aliasing based on user pref setting
if ((mAdjustedSize <=
(gfxFloat)gfxPlatformMac::GetPlatform()->GetAntiAliasingThreshold()) ||
// Turn off AA for Ahem for testing purposes when requested.
MOZ_UNLIKELY(StaticPrefs::gfx_font_rendering_ahem_antialias_none() &&
mFontEntry->FamilyName().EqualsLiteral("Ahem"))) {
cairo_font_options_set_antialias(fontOptions, CAIRO_ANTIALIAS_NONE);
if (mAdjustedSize <=
(gfxFloat)gfxPlatformMac::GetPlatform()->GetAntiAliasingThreshold()) {
mAntialiasOption = kAntialiasNone;
} else if (mStyle.useGrayscaleAntialiasing) {
cairo_font_options_set_antialias(fontOptions, CAIRO_ANTIALIAS_GRAY);
mAntialiasOption = kAntialiasGrayscale;
}
mScaledFont =
cairo_scaled_font_create(mFontFace, &sizeMatrix, &ctm, fontOptions);
cairo_font_options_destroy(fontOptions);
cairoerr = cairo_scaled_font_status(mScaledFont);
if (cairoerr != CAIRO_STATUS_SUCCESS) {
mIsValid = false;
#ifdef DEBUG
char warnBuf[1024];
SprintfLiteral(warnBuf, "Failed to create scaled font: %s status: %d",
GetName().get(), cairoerr);
NS_WARNING(warnBuf);
#endif
}
}
gfxMacFont::~gfxMacFont() {
@ -178,12 +137,6 @@ gfxMacFont::~gfxMacFont() {
if (mCTFont) {
::CFRelease(mCTFont);
}
if (mScaledFont) {
cairo_scaled_font_destroy(mScaledFont);
}
if (mFontFace) {
cairo_font_face_destroy(mFontFace);
}
}
bool gfxMacFont::ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
@ -585,7 +538,6 @@ already_AddRefed<ScaledFont> gfxMacFont::GetScaledFont(DrawTarget* aTarget) {
return nullptr;
}
InitializeScaledFont();
mAzureScaledFont->SetCairoScaledFont(mScaledFont);
}
RefPtr<ScaledFont> scaledFont(mAzureScaledFont);
@ -602,7 +554,6 @@ void gfxMacFont::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
FontCacheSizes* aSizes) const {
gfxFont::AddSizeOfExcludingThis(aMallocSizeOf, aSizes);
// mCGFont is shared with the font entry, so not counted here;
// and we don't have APIs to measure the cairo mFontFace object
}
void gfxMacFont::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,

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

@ -8,7 +8,6 @@
#include "mozilla/MemoryReporting.h"
#include "gfxFont.h"
#include "cairo.h"
#include <ApplicationServices/ApplicationServices.h>
#include "mozilla/gfx/UnscaledFontMac.h"
@ -85,8 +84,6 @@ class gfxMacFont : public gfxFont {
// glyph widths; otherwise null.
CTFontRef mCTFont;
cairo_font_face_t* mFontFace;
mozilla::UniquePtr<gfxFontShaper> mCoreTextShaper;
Metrics mMetrics;

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

@ -1343,6 +1343,13 @@ void gfxPlatform::WillShutdown() {
mScreenReferenceSurface = nullptr;
mScreenReferenceDrawTarget = nullptr;
#ifdef USE_SKIA
// Always clear out the Skia font cache here, in case it is referencing any
// SharedFTFaces that would otherwise outlive destruction of the FT_Library
// that owns them.
SkGraphics::PurgeFontCache();
#endif
// The cairo folks think we should only clean up in debug builds,
// but we're generally in the habit of trying to shut down as
// cleanly as possible even in production code, so call this
@ -1351,12 +1358,6 @@ void gfxPlatform::WillShutdown() {
// because cairo can assert and thus crash on shutdown, don't do this in
// release builds
#ifdef NS_FREE_PERMANENT_DATA
# ifdef USE_SKIA
// must do Skia cleanup before Cairo cleanup, because Skia may be referencing
// Cairo objects e.g. through SkCairoFTTypeface
SkGraphics::PurgeFontCache();
# endif
# if MOZ_TREE_CAIRO
cairo_debug_reset_static_data();
# endif

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

@ -255,9 +255,7 @@ static RefPtr<UnscaledFont> GetUnscaledFont(Translator* aTranslator,
#endif
// makes a copy of the data
RefPtr<NativeFontResource> fontResource = Factory::CreateNativeFontResource(
(uint8_t*)data.mData, data.mSize,
aTranslator->GetReferenceDrawTarget()->GetBackendType(), type,
aTranslator->GetFontContext());
(uint8_t*)data.mData, data.mSize, type, aTranslator->GetFontContext());
RefPtr<UnscaledFont> unscaledFont;
if (!fontResource) {
gfxDevCrash(LogReason::NativeFontResourceNotFound)