зеркало из 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 SK_USE_FREETYPE_EMBOLDEN
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,14 +5,11 @@
|
|||
#include <cairo-ft.h>
|
||||
|
||||
#include "SkTypeface.h"
|
||||
#include "SkSurfaceProps.h"
|
||||
|
||||
SK_API extern void SkInitCairoFT(bool fontHintingEnabled);
|
||||
|
||||
SK_API extern SkTypeface* SkCreateTypefaceFromCairoFTFont(cairo_scaled_font_t* scaledFont, FT_Face face = nullptr);
|
||||
|
||||
#ifdef CAIRO_HAS_FC_FONT
|
||||
SK_API extern SkTypeface* SkCreateTypefaceFromCairoFTFontWithFontconfig(cairo_scaled_font_t* scaledFont, FcPattern* pattern, FT_Face face = nullptr);
|
||||
#endif
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -67,6 +67,10 @@ extern "C"
|
|||
{
|
||||
void mozilla_LockFTLibrary(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);
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
public:
|
||||
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();
|
||||
|
||||
bool isValid() const {
|
||||
|
@ -115,10 +115,6 @@ private:
|
|||
bool computeShapeMatrix(const SkMatrix& m);
|
||||
void prepareGlyph(FT_GlyphSlot glyph);
|
||||
|
||||
#ifdef CAIRO_HAS_FC_FONT
|
||||
void parsePattern(FcPattern* pattern);
|
||||
#endif
|
||||
|
||||
cairo_scaled_font_t* fScaledFont;
|
||||
FT_Int32 fLoadGlyphFlags;
|
||||
FT_LcdFilter fLcdFilter;
|
||||
|
@ -180,7 +176,7 @@ public:
|
|||
{
|
||||
SkScalerContext_CairoFT* ctx =
|
||||
new SkScalerContext_CairoFT(sk_ref_sp(const_cast<SkCairoFTTypeface*>(this)),
|
||||
effects, desc, fFontFace, fPattern);
|
||||
effects, desc, fFontFace, fPixelGeometry, fLcdFilter);
|
||||
if (!ctx->isValid()) {
|
||||
delete ctx;
|
||||
return nullptr;
|
||||
|
@ -190,11 +186,6 @@ public:
|
|||
|
||||
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
|
||||
if (!gFontHintingEnabled || !isAxisAligned(*rec)) {
|
||||
rec->setHinting(kNo_SkFontHinting);
|
||||
|
@ -251,18 +242,16 @@ public:
|
|||
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())
|
||||
, fFontFace(fontFace)
|
||||
, fPattern(pattern)
|
||||
, fFTFace(face)
|
||||
, fFTFaceContext(faceContext)
|
||||
, fPixelGeometry(pixelGeometry)
|
||||
, fLcdFilter(lcdFilter)
|
||||
{
|
||||
mozilla_AddRefSharedFTFace(fFTFaceContext);
|
||||
cairo_font_face_reference(fFontFace);
|
||||
#ifdef CAIRO_HAS_FC_FONT
|
||||
if (fPattern) {
|
||||
FcPatternReference(fPattern);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
cairo_font_face_t* GetCairoFontFace() const { return fFontFace; }
|
||||
|
@ -275,15 +264,6 @@ public:
|
|||
if (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;
|
||||
}
|
||||
|
||||
|
@ -291,23 +271,21 @@ private:
|
|||
~SkCairoFTTypeface()
|
||||
{
|
||||
cairo_font_face_destroy(fFontFace);
|
||||
#ifdef CAIRO_HAS_FC_FONT
|
||||
if (fPattern) {
|
||||
FcPatternDestroy(fPattern);
|
||||
}
|
||||
#endif
|
||||
mozilla_ReleaseSharedFTFace(fFTFaceContext);
|
||||
}
|
||||
|
||||
cairo_font_face_t* fFontFace;
|
||||
FcPattern* fPattern;
|
||||
FT_Face fFTFace;
|
||||
void* fFTFaceContext;
|
||||
SkPixelGeometry fPixelGeometry;
|
||||
FT_LcdFilter fLcdFilter;
|
||||
};
|
||||
|
||||
static bool FindByCairoFontFace(SkTypeface* typeface, void* 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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
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)
|
||||
, fLcdFilter(FT_LCD_FILTER_NONE)
|
||||
, fLcdFilter(lcdFilter)
|
||||
{
|
||||
SkMatrix matrix;
|
||||
fRec.getSingleMatrix(&matrix);
|
||||
|
@ -345,14 +318,6 @@ SkScalerContext_CairoFT::SkScalerContext_CairoFT(sk_sp<SkTypeface> typeface, con
|
|||
|
||||
computeShapeMatrix(matrix);
|
||||
|
||||
fRec.fFlags |= SkScalerContext::kEmbeddedBitmapText_Flag;
|
||||
|
||||
#ifdef CAIRO_HAS_FC_FONT
|
||||
if (pattern) {
|
||||
parsePattern(pattern);
|
||||
}
|
||||
#endif
|
||||
|
||||
FT_Int32 loadFlags = FT_LOAD_DEFAULT;
|
||||
|
||||
if (SkMask::kBW_Format == fRec.fMaskFormat) {
|
||||
|
@ -363,6 +328,24 @@ SkScalerContext_CairoFT::SkScalerContext_CairoFT(sk_sp<SkTypeface> typeface, con
|
|||
}
|
||||
loadFlags |= FT_LOAD_MONOCHROME;
|
||||
} 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()) {
|
||||
case kNo_SkFontHinting:
|
||||
loadFlags |= FT_LOAD_NO_HINTING;
|
||||
|
@ -421,105 +404,6 @@ SkScalerContext_CairoFT::~SkScalerContext_CairoFT()
|
|||
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)
|
||||
{
|
||||
// Compute a shape matrix compatible with Cairo's _compute_transform.
|
||||
|
|
Загрузка…
Ссылка в новой задаче