зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1547063 - Remove FcPattern usage from Skia. r=jfkthame
Differential Revision: https://phabricator.services.mozilla.com/D44493 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
3417aec992
Коммит
264178a181
|
@ -157,4 +157,6 @@
|
||||||
|
|
||||||
#define I_ACKNOWLEDGE_SKIA_DOES_NOT_SUPPORT_BIG_ENDIAN
|
#define I_ACKNOWLEDGE_SKIA_DOES_NOT_SUPPORT_BIG_ENDIAN
|
||||||
|
|
||||||
|
#define SK_USE_FREETYPE_EMBOLDEN
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,14 +5,11 @@
|
||||||
#include <cairo-ft.h>
|
#include <cairo-ft.h>
|
||||||
|
|
||||||
#include "SkTypeface.h"
|
#include "SkTypeface.h"
|
||||||
|
#include "SkSurfaceProps.h"
|
||||||
|
|
||||||
SK_API extern void SkInitCairoFT(bool fontHintingEnabled);
|
SK_API extern void SkInitCairoFT(bool fontHintingEnabled);
|
||||||
|
|
||||||
SK_API extern SkTypeface* SkCreateTypefaceFromCairoFTFont(cairo_scaled_font_t* scaledFont, FT_Face face = nullptr);
|
SK_API extern SkTypeface* SkCreateTypefaceFromCairoFTFont(cairo_scaled_font_t* scaledFont, FT_Face face = nullptr, void* faceContext = nullptr, SkPixelGeometry pixelGeometry = kUnknown_SkPixelGeometry, uint8_t lcdFilter = 0);
|
||||||
|
|
||||||
#ifdef CAIRO_HAS_FC_FONT
|
|
||||||
SK_API extern SkTypeface* SkCreateTypefaceFromCairoFTFontWithFontconfig(cairo_scaled_font_t* scaledFont, FcPattern* pattern, FT_Face face = nullptr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,10 @@ extern "C"
|
||||||
{
|
{
|
||||||
void mozilla_LockFTLibrary(FT_Library aLibrary);
|
void mozilla_LockFTLibrary(FT_Library aLibrary);
|
||||||
void mozilla_UnlockFTLibrary(FT_Library aLibrary);
|
void mozilla_UnlockFTLibrary(FT_Library aLibrary);
|
||||||
|
void mozilla_AddRefSharedFTFace(void* aContext);
|
||||||
|
void mozilla_ReleaseSharedFTFace(void* aContext);
|
||||||
|
void mozilla_LockSharedFTFace(void* aContext);
|
||||||
|
void mozilla_UnlockSharedFTFace(void* aContext);
|
||||||
FT_Error mozilla_LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex, int32_t aFlags);
|
FT_Error mozilla_LoadFTGlyph(FT_Face aFace, uint32_t aGlyphIndex, int32_t aFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,14 +92,10 @@ void SkInitCairoFT(bool fontHintingEnabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CAIRO_HAS_FC_FONT
|
|
||||||
typedef struct _FcPattern FcPattern;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class SkScalerContext_CairoFT : public SkScalerContext_FreeType_Base {
|
class SkScalerContext_CairoFT : public SkScalerContext_FreeType_Base {
|
||||||
public:
|
public:
|
||||||
SkScalerContext_CairoFT(sk_sp<SkTypeface> typeface, const SkScalerContextEffects& effects, const SkDescriptor* desc,
|
SkScalerContext_CairoFT(sk_sp<SkTypeface> typeface, const SkScalerContextEffects& effects, const SkDescriptor* desc,
|
||||||
cairo_font_face_t* fontFace, FcPattern* pattern);
|
cairo_font_face_t* fontFace, SkPixelGeometry pixelGeometry, FT_LcdFilter lcdFilter);
|
||||||
virtual ~SkScalerContext_CairoFT();
|
virtual ~SkScalerContext_CairoFT();
|
||||||
|
|
||||||
bool isValid() const {
|
bool isValid() const {
|
||||||
|
@ -115,10 +115,6 @@ private:
|
||||||
bool computeShapeMatrix(const SkMatrix& m);
|
bool computeShapeMatrix(const SkMatrix& m);
|
||||||
void prepareGlyph(FT_GlyphSlot glyph);
|
void prepareGlyph(FT_GlyphSlot glyph);
|
||||||
|
|
||||||
#ifdef CAIRO_HAS_FC_FONT
|
|
||||||
void parsePattern(FcPattern* pattern);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cairo_scaled_font_t* fScaledFont;
|
cairo_scaled_font_t* fScaledFont;
|
||||||
FT_Int32 fLoadGlyphFlags;
|
FT_Int32 fLoadGlyphFlags;
|
||||||
FT_LcdFilter fLcdFilter;
|
FT_LcdFilter fLcdFilter;
|
||||||
|
@ -180,7 +176,7 @@ public:
|
||||||
{
|
{
|
||||||
SkScalerContext_CairoFT* ctx =
|
SkScalerContext_CairoFT* ctx =
|
||||||
new SkScalerContext_CairoFT(sk_ref_sp(const_cast<SkCairoFTTypeface*>(this)),
|
new SkScalerContext_CairoFT(sk_ref_sp(const_cast<SkCairoFTTypeface*>(this)),
|
||||||
effects, desc, fFontFace, fPattern);
|
effects, desc, fFontFace, fPixelGeometry, fLcdFilter);
|
||||||
if (!ctx->isValid()) {
|
if (!ctx->isValid()) {
|
||||||
delete ctx;
|
delete ctx;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -190,11 +186,6 @@ public:
|
||||||
|
|
||||||
virtual void onFilterRec(SkScalerContextRec* rec) const override
|
virtual void onFilterRec(SkScalerContextRec* rec) const override
|
||||||
{
|
{
|
||||||
// No subpixel AA unless enabled in Fontconfig.
|
|
||||||
if (!fPattern && isLCD(*rec)) {
|
|
||||||
rec->fMaskFormat = SkMask::kA8_Format;
|
|
||||||
}
|
|
||||||
|
|
||||||
// rotated text looks bad with hinting, so we disable it as needed
|
// rotated text looks bad with hinting, so we disable it as needed
|
||||||
if (!gFontHintingEnabled || !isAxisAligned(*rec)) {
|
if (!gFontHintingEnabled || !isAxisAligned(*rec)) {
|
||||||
rec->setHinting(kNo_SkFontHinting);
|
rec->setHinting(kNo_SkFontHinting);
|
||||||
|
@ -251,18 +242,16 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkCairoFTTypeface(cairo_font_face_t* fontFace, FcPattern* pattern, FT_Face face)
|
SkCairoFTTypeface(cairo_font_face_t* fontFace, FT_Face face, void* faceContext, SkPixelGeometry pixelGeometry, FT_LcdFilter lcdFilter)
|
||||||
: SkTypeface(SkFontStyle::Normal())
|
: SkTypeface(SkFontStyle::Normal())
|
||||||
, fFontFace(fontFace)
|
, fFontFace(fontFace)
|
||||||
, fPattern(pattern)
|
|
||||||
, fFTFace(face)
|
, fFTFace(face)
|
||||||
|
, fFTFaceContext(faceContext)
|
||||||
|
, fPixelGeometry(pixelGeometry)
|
||||||
|
, fLcdFilter(lcdFilter)
|
||||||
{
|
{
|
||||||
|
mozilla_AddRefSharedFTFace(fFTFaceContext);
|
||||||
cairo_font_face_reference(fFontFace);
|
cairo_font_face_reference(fFontFace);
|
||||||
#ifdef CAIRO_HAS_FC_FONT
|
|
||||||
if (fPattern) {
|
|
||||||
FcPatternReference(fPattern);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_font_face_t* GetCairoFontFace() const { return fFontFace; }
|
cairo_font_face_t* GetCairoFontFace() const { return fFontFace; }
|
||||||
|
@ -275,15 +264,6 @@ public:
|
||||||
if (fFTFace) {
|
if (fFTFace) {
|
||||||
return !FT_IS_SCALABLE(fFTFace);
|
return !FT_IS_SCALABLE(fFTFace);
|
||||||
}
|
}
|
||||||
#ifdef CAIRO_HAS_FC_FONT
|
|
||||||
if (fPattern) {
|
|
||||||
FcBool outline;
|
|
||||||
if (FcPatternGetBool(fPattern, FC_OUTLINE, 0, &outline) != FcResultMatch ||
|
|
||||||
!outline) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,23 +271,21 @@ private:
|
||||||
~SkCairoFTTypeface()
|
~SkCairoFTTypeface()
|
||||||
{
|
{
|
||||||
cairo_font_face_destroy(fFontFace);
|
cairo_font_face_destroy(fFontFace);
|
||||||
#ifdef CAIRO_HAS_FC_FONT
|
mozilla_ReleaseSharedFTFace(fFTFaceContext);
|
||||||
if (fPattern) {
|
|
||||||
FcPatternDestroy(fPattern);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_font_face_t* fFontFace;
|
cairo_font_face_t* fFontFace;
|
||||||
FcPattern* fPattern;
|
|
||||||
FT_Face fFTFace;
|
FT_Face fFTFace;
|
||||||
|
void* fFTFaceContext;
|
||||||
|
SkPixelGeometry fPixelGeometry;
|
||||||
|
FT_LcdFilter fLcdFilter;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool FindByCairoFontFace(SkTypeface* typeface, void* context) {
|
static bool FindByCairoFontFace(SkTypeface* typeface, void* context) {
|
||||||
return static_cast<SkCairoFTTypeface*>(typeface)->GetCairoFontFace() == static_cast<cairo_font_face_t*>(context);
|
return static_cast<SkCairoFTTypeface*>(typeface)->GetCairoFontFace() == static_cast<cairo_font_face_t*>(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
SkTypeface* SkCreateTypefaceFromCairoFTFontWithFontconfig(cairo_scaled_font_t* scaledFont, FcPattern* pattern, FT_Face face)
|
SkTypeface* SkCreateTypefaceFromCairoFTFont(cairo_scaled_font_t* scaledFont, FT_Face face, void* faceContext, SkPixelGeometry pixelGeometry, uint8_t lcdFilter)
|
||||||
{
|
{
|
||||||
cairo_font_face_t* fontFace = cairo_scaled_font_get_font_face(scaledFont);
|
cairo_font_face_t* fontFace = cairo_scaled_font_get_font_face(scaledFont);
|
||||||
SkASSERT(cairo_font_face_status(fontFace) == CAIRO_STATUS_SUCCESS);
|
SkASSERT(cairo_font_face_status(fontFace) == CAIRO_STATUS_SUCCESS);
|
||||||
|
@ -315,22 +293,17 @@ SkTypeface* SkCreateTypefaceFromCairoFTFontWithFontconfig(cairo_scaled_font_t* s
|
||||||
|
|
||||||
sk_sp<SkTypeface> typeface = SkTypefaceCache::FindByProcAndRef(FindByCairoFontFace, fontFace);
|
sk_sp<SkTypeface> typeface = SkTypefaceCache::FindByProcAndRef(FindByCairoFontFace, fontFace);
|
||||||
if (!typeface) {
|
if (!typeface) {
|
||||||
typeface = sk_make_sp<SkCairoFTTypeface>(fontFace, pattern, face);
|
typeface = sk_make_sp<SkCairoFTTypeface>(fontFace, face, faceContext, pixelGeometry, (FT_LcdFilter)lcdFilter);
|
||||||
SkTypefaceCache::Add(typeface);
|
SkTypefaceCache::Add(typeface);
|
||||||
}
|
}
|
||||||
|
|
||||||
return typeface.release();
|
return typeface.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
SkTypeface* SkCreateTypefaceFromCairoFTFont(cairo_scaled_font_t* scaledFont, FT_Face face)
|
|
||||||
{
|
|
||||||
return SkCreateTypefaceFromCairoFTFontWithFontconfig(scaledFont, nullptr, face);
|
|
||||||
}
|
|
||||||
|
|
||||||
SkScalerContext_CairoFT::SkScalerContext_CairoFT(sk_sp<SkTypeface> typeface, const SkScalerContextEffects& effects, const SkDescriptor* desc,
|
SkScalerContext_CairoFT::SkScalerContext_CairoFT(sk_sp<SkTypeface> typeface, const SkScalerContextEffects& effects, const SkDescriptor* desc,
|
||||||
cairo_font_face_t* fontFace, FcPattern* pattern)
|
cairo_font_face_t* fontFace, SkPixelGeometry pixelGeometry, FT_LcdFilter lcdFilter)
|
||||||
: SkScalerContext_FreeType_Base(std::move(typeface), effects, desc)
|
: SkScalerContext_FreeType_Base(std::move(typeface), effects, desc)
|
||||||
, fLcdFilter(FT_LCD_FILTER_NONE)
|
, fLcdFilter(lcdFilter)
|
||||||
{
|
{
|
||||||
SkMatrix matrix;
|
SkMatrix matrix;
|
||||||
fRec.getSingleMatrix(&matrix);
|
fRec.getSingleMatrix(&matrix);
|
||||||
|
@ -345,14 +318,6 @@ SkScalerContext_CairoFT::SkScalerContext_CairoFT(sk_sp<SkTypeface> typeface, con
|
||||||
|
|
||||||
computeShapeMatrix(matrix);
|
computeShapeMatrix(matrix);
|
||||||
|
|
||||||
fRec.fFlags |= SkScalerContext::kEmbeddedBitmapText_Flag;
|
|
||||||
|
|
||||||
#ifdef CAIRO_HAS_FC_FONT
|
|
||||||
if (pattern) {
|
|
||||||
parsePattern(pattern);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FT_Int32 loadFlags = FT_LOAD_DEFAULT;
|
FT_Int32 loadFlags = FT_LOAD_DEFAULT;
|
||||||
|
|
||||||
if (SkMask::kBW_Format == fRec.fMaskFormat) {
|
if (SkMask::kBW_Format == fRec.fMaskFormat) {
|
||||||
|
@ -363,6 +328,24 @@ SkScalerContext_CairoFT::SkScalerContext_CairoFT(sk_sp<SkTypeface> typeface, con
|
||||||
}
|
}
|
||||||
loadFlags |= FT_LOAD_MONOCHROME;
|
loadFlags |= FT_LOAD_MONOCHROME;
|
||||||
} else {
|
} else {
|
||||||
|
if (isLCD(fRec)) {
|
||||||
|
switch (pixelGeometry) {
|
||||||
|
case kRGB_H_SkPixelGeometry:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case kRGB_V_SkPixelGeometry:
|
||||||
|
fRec.fFlags |= SkScalerContext::kLCD_Vertical_Flag;
|
||||||
|
break;
|
||||||
|
case kBGR_H_SkPixelGeometry:
|
||||||
|
fRec.fFlags |= SkScalerContext::kLCD_BGROrder_Flag;
|
||||||
|
break;
|
||||||
|
case kBGR_V_SkPixelGeometry:
|
||||||
|
fRec.fFlags |= SkScalerContext::kLCD_Vertical_Flag |
|
||||||
|
SkScalerContext::kLCD_BGROrder_Flag;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (fRec.getHinting()) {
|
switch (fRec.getHinting()) {
|
||||||
case kNo_SkFontHinting:
|
case kNo_SkFontHinting:
|
||||||
loadFlags |= FT_LOAD_NO_HINTING;
|
loadFlags |= FT_LOAD_NO_HINTING;
|
||||||
|
@ -421,105 +404,6 @@ SkScalerContext_CairoFT::~SkScalerContext_CairoFT()
|
||||||
cairo_scaled_font_destroy(fScaledFont);
|
cairo_scaled_font_destroy(fScaledFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CAIRO_HAS_FC_FONT
|
|
||||||
void SkScalerContext_CairoFT::parsePattern(FcPattern* pattern)
|
|
||||||
{
|
|
||||||
FcBool antialias, autohint, bitmap, embolden, hinting;
|
|
||||||
|
|
||||||
if (FcPatternGetBool(pattern, FC_AUTOHINT, 0, &autohint) == FcResultMatch && autohint) {
|
|
||||||
fRec.fFlags |= SkScalerContext::kForceAutohinting_Flag;
|
|
||||||
}
|
|
||||||
if (FcPatternGetBool(pattern, FC_EMBOLDEN, 0, &embolden) == FcResultMatch && embolden) {
|
|
||||||
fRec.fFlags |= SkScalerContext::kEmbolden_Flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match cairo-ft's handling of embeddedbitmap:
|
|
||||||
// If AA is explicitly disabled, leave bitmaps enabled.
|
|
||||||
// Otherwise, disable embedded bitmaps unless explicitly enabled.
|
|
||||||
if (FcPatternGetBool(pattern, FC_ANTIALIAS, 0, &antialias) == FcResultMatch && !antialias) {
|
|
||||||
fRec.fMaskFormat = SkMask::kBW_Format;
|
|
||||||
} else if (FcPatternGetBool(pattern, FC_EMBEDDED_BITMAP, 0, &bitmap) != FcResultMatch || !bitmap) {
|
|
||||||
fRec.fFlags &= ~SkScalerContext::kEmbeddedBitmapText_Flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fRec.fMaskFormat != SkMask::kBW_Format) {
|
|
||||||
int rgba;
|
|
||||||
if (!isLCD(fRec) ||
|
|
||||||
FcPatternGetInteger(pattern, FC_RGBA, 0, &rgba) != FcResultMatch) {
|
|
||||||
rgba = FC_RGBA_UNKNOWN;
|
|
||||||
}
|
|
||||||
switch (rgba) {
|
|
||||||
case FC_RGBA_RGB:
|
|
||||||
break;
|
|
||||||
case FC_RGBA_BGR:
|
|
||||||
fRec.fFlags |= SkScalerContext::kLCD_BGROrder_Flag;
|
|
||||||
break;
|
|
||||||
case FC_RGBA_VRGB:
|
|
||||||
fRec.fFlags |= SkScalerContext::kLCD_Vertical_Flag;
|
|
||||||
break;
|
|
||||||
case FC_RGBA_VBGR:
|
|
||||||
fRec.fFlags |= SkScalerContext::kLCD_Vertical_Flag |
|
|
||||||
SkScalerContext::kLCD_BGROrder_Flag;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fRec.fMaskFormat = SkMask::kA8_Format;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int filter;
|
|
||||||
if (isLCD(fRec)) {
|
|
||||||
if (FcPatternGetInteger(pattern, FC_LCD_FILTER, 0, &filter) != FcResultMatch) {
|
|
||||||
filter = FC_LCD_LEGACY;
|
|
||||||
}
|
|
||||||
switch (filter) {
|
|
||||||
case FC_LCD_NONE:
|
|
||||||
fLcdFilter = FT_LCD_FILTER_NONE;
|
|
||||||
break;
|
|
||||||
case FC_LCD_DEFAULT:
|
|
||||||
fLcdFilter = FT_LCD_FILTER_DEFAULT;
|
|
||||||
break;
|
|
||||||
case FC_LCD_LIGHT:
|
|
||||||
fLcdFilter = FT_LCD_FILTER_LIGHT;
|
|
||||||
break;
|
|
||||||
case FC_LCD_LEGACY:
|
|
||||||
default:
|
|
||||||
fLcdFilter = FT_LCD_FILTER_LEGACY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fRec.getHinting() != kNo_SkFontHinting) {
|
|
||||||
// Hinting was requested, so check if the fontconfig pattern needs to override it.
|
|
||||||
// If hinting is either explicitly enabled by fontconfig or not configured, try to
|
|
||||||
// parse the hint style. Otherwise, ensure hinting is disabled.
|
|
||||||
int hintstyle;
|
|
||||||
if (FcPatternGetBool(pattern, FC_HINTING, 0, &hinting) != FcResultMatch || hinting) {
|
|
||||||
if (FcPatternGetInteger(pattern, FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch) {
|
|
||||||
hintstyle = FC_HINT_FULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hintstyle = FC_HINT_NONE;
|
|
||||||
}
|
|
||||||
switch (hintstyle) {
|
|
||||||
case FC_HINT_NONE:
|
|
||||||
fRec.setHinting(kNo_SkFontHinting);
|
|
||||||
break;
|
|
||||||
case FC_HINT_SLIGHT:
|
|
||||||
fRec.setHinting(kSlight_SkFontHinting);
|
|
||||||
break;
|
|
||||||
case FC_HINT_MEDIUM:
|
|
||||||
default:
|
|
||||||
fRec.setHinting(kNormal_SkFontHinting);
|
|
||||||
break;
|
|
||||||
case FC_HINT_FULL:
|
|
||||||
fRec.setHinting(kFull_SkFontHinting);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool SkScalerContext_CairoFT::computeShapeMatrix(const SkMatrix& m)
|
bool SkScalerContext_CairoFT::computeShapeMatrix(const SkMatrix& m)
|
||||||
{
|
{
|
||||||
// Compute a shape matrix compatible with Cairo's _compute_transform.
|
// Compute a shape matrix compatible with Cairo's _compute_transform.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче