Plumb FreeType glyph loading flags for COLRv0.
Previously, FreeType was always instructed to hint or autohint the layer glyphs of COLRv0 fonts. Instead, pass the appropriate loading flags through so that the layer glyphs will be created similarly to how the base glyph would be handled. The behavior change is gated on SK_IGNORE_FREETYPE_COLRV0_LOAD_FLAGS_FIX because this will require rebaselining some Blink layout tests. Also ensure that COLRv1 subglyphs are never hinted or autohinted for now. These are a bit more complex and allowing hinting will need to be handled separately. Bug: skia:12956 Change-Id: Ia69f7a0e207b1af885ed5039f9e53007125b707e Reviewed-on: https://skia-review.googlesource.com/c/skia/+/510876 Reviewed-by: Ben Wagner <bungeman@google.com> Reviewed-by: Dominik Röttsches <drott@google.com> Commit-Queue: Ben Wagner <bungeman@google.com>
This commit is contained in:
parent
cd0e202767
commit
ed0e1a8af7
@ -1381,7 +1381,7 @@ void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) {
|
||||
}
|
||||
|
||||
SkSpan<SkColor> palette(fFaceRec->fSkPalette.get(), fFaceRec->fFTPaletteEntryCount);
|
||||
generateGlyphImage(fFace, palette, glyph, *bitmapMatrix);
|
||||
generateGlyphImage(fFace, glyph, fLoadGlyphFlags, palette, *bitmapMatrix);
|
||||
}
|
||||
|
||||
sk_sp<SkDrawable> SkScalerContext_FreeType::generateDrawable(const SkGlyph& glyph) {
|
||||
@ -1409,7 +1409,7 @@ sk_sp<SkDrawable> SkScalerContext_FreeType::generateDrawable(const SkGlyph& glyp
|
||||
|
||||
emboldenIfNeeded(fFace, fFace->glyph, glyph.getGlyphID());
|
||||
SkSpan<SkColor> palette(fFaceRec->fSkPalette.get(), fFaceRec->fFTPaletteEntryCount);
|
||||
return generateGlyphDrawable(fFace, palette, glyph);
|
||||
return generateGlyphDrawable(fFace, glyph, fLoadGlyphFlags, palette);
|
||||
}
|
||||
|
||||
bool SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, SkPath* path) {
|
||||
|
@ -1237,10 +1237,11 @@ bool colrv1_start_glyph_bounds(SkMatrix *ctm,
|
||||
} // namespace
|
||||
|
||||
#ifdef FT_COLOR_H
|
||||
bool SkScalerContext_FreeType_Base::drawColorGlyph(SkCanvas* canvas,
|
||||
FT_Face face,
|
||||
bool SkScalerContext_FreeType_Base::drawColorGlyph(FT_Face face,
|
||||
const SkGlyph& glyph,
|
||||
uint32_t loadGlyphFlags,
|
||||
SkSpan<SkColor> palette,
|
||||
const SkGlyph& glyph) {
|
||||
SkCanvas* canvas) {
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
|
||||
@ -1272,7 +1273,7 @@ bool SkScalerContext_FreeType_Base::drawColorGlyph(SkCanvas* canvas,
|
||||
paint.setColor(palette[layerColorIndex]);
|
||||
}
|
||||
SkPath path;
|
||||
if (this->generateFacePath(face, layerGlyphIndex, &path)) {
|
||||
if (this->generateFacePath(face, layerGlyphIndex, loadGlyphFlags, &path)) {
|
||||
canvas->drawPath(path, paint);
|
||||
}
|
||||
}
|
||||
@ -1280,11 +1281,11 @@ bool SkScalerContext_FreeType_Base::drawColorGlyph(SkCanvas* canvas,
|
||||
}
|
||||
#endif // FT_COLOR_H
|
||||
|
||||
void SkScalerContext_FreeType_Base::generateGlyphImage(
|
||||
FT_Face face,
|
||||
SkSpan<SkColor> customPalette,
|
||||
const SkGlyph& glyph,
|
||||
const SkMatrix& bitmapTransform)
|
||||
void SkScalerContext_FreeType_Base::generateGlyphImage(FT_Face face,
|
||||
const SkGlyph& glyph,
|
||||
uint32_t loadGlyphFlags,
|
||||
SkSpan<SkColor> customPalette,
|
||||
const SkMatrix& bitmapTransform)
|
||||
{
|
||||
const bool doBGR = SkToBool(fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag);
|
||||
const bool doVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);
|
||||
@ -1327,7 +1328,8 @@ void SkScalerContext_FreeType_Base::generateGlyphImage(
|
||||
SkFixedToScalar(glyph.getSubYFixed()));
|
||||
}
|
||||
|
||||
bool haveLayers = this->drawColorGlyph(&canvas, face, customPalette, glyph);
|
||||
bool haveLayers = this->drawColorGlyph(face, glyph, loadGlyphFlags,
|
||||
customPalette, &canvas);
|
||||
|
||||
if (!haveLayers) {
|
||||
SkDebugf("Could not get layers (neither v0, nor v1) from %s fontFace.",
|
||||
@ -1645,12 +1647,14 @@ bool generateGlyphPathStatic(FT_Face face, SkPath* path) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool generateFacePathStatic(FT_Face face, SkGlyphID glyphID, SkPath* path) {
|
||||
uint32_t flags = 0; //fLoadGlyphFlags;
|
||||
flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
|
||||
flags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline)
|
||||
bool generateFacePathStatic(FT_Face face, SkGlyphID glyphID, uint32_t loadGlyphFlags, SkPath* path){
|
||||
#ifdef SK_IGNORE_FREETYPE_COLRV0_LOAD_FLAGS_FIX
|
||||
loadGlyphFlags = 0;
|
||||
#endif
|
||||
loadGlyphFlags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
|
||||
loadGlyphFlags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline)
|
||||
|
||||
FT_Error err = FT_Load_Glyph(face, glyphID, flags);
|
||||
FT_Error err = FT_Load_Glyph(face, glyphID, loadGlyphFlags);
|
||||
if (err != 0) {
|
||||
path->reset();
|
||||
return false;
|
||||
@ -1668,16 +1672,17 @@ bool generateFacePathCOLRv1(FT_Face face, SkGlyphID glyphID, SkPath* path) {
|
||||
uint32_t flags = 0;
|
||||
flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
|
||||
flags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline)
|
||||
|
||||
flags |= FT_LOAD_NO_HINTING;
|
||||
flags |= FT_LOAD_NO_AUTOHINT;
|
||||
flags |= FT_LOAD_IGNORE_TRANSFORM;
|
||||
|
||||
|
||||
using DoneFTSize = SkFunctionWrapper<decltype(FT_Done_Size), FT_Done_Size>;
|
||||
std::unique_ptr<std::remove_pointer_t<FT_Size>, DoneFTSize> unscaledFtSize([face]() -> FT_Size {
|
||||
FT_Size size;
|
||||
FT_Error err = FT_New_Size(face, &size);
|
||||
if (err != 0) {
|
||||
SK_TRACEFTR(err, "FT_New_Size(%s) failed in generateFacePathStaticCOLRv1.", face->family_name);
|
||||
SK_TRACEFTR(err, "FT_New_Size(%s) failed in generateFacePathStaticCOLRv1.",
|
||||
face->family_name);
|
||||
return nullptr;
|
||||
}
|
||||
return size;
|
||||
@ -1733,8 +1738,9 @@ bool SkScalerContext_FreeType_Base::generateGlyphPath(FT_Face face, SkPath* path
|
||||
|
||||
bool SkScalerContext_FreeType_Base::generateFacePath(FT_Face face,
|
||||
SkGlyphID glyphID,
|
||||
uint32_t loadGlyphFlags,
|
||||
SkPath* path) {
|
||||
return generateFacePathStatic(face, glyphID, path);
|
||||
return generateFacePathStatic(face, glyphID, loadGlyphFlags, path);
|
||||
}
|
||||
|
||||
bool SkScalerContext_FreeType_Base::computeColrV1GlyphBoundingBox(FT_Face face,
|
||||
@ -1764,12 +1770,12 @@ bool SkScalerContext_FreeType_Base::computeColrV1GlyphBoundingBox(FT_Face face,
|
||||
}
|
||||
|
||||
sk_sp<SkDrawable> SkScalerContext_FreeType_Base::generateGlyphDrawable(
|
||||
FT_Face face, SkSpan<SkColor> palette, const SkGlyph& glyph) {
|
||||
FT_Face face, const SkGlyph& glyph, uint32_t loadGlyphFlags, SkSpan<SkColor> palette) {
|
||||
#ifdef FT_COLOR_H
|
||||
if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE && glyph.isColor()) {
|
||||
SkPictureRecorder recorder;
|
||||
SkCanvas* recordingCanvas = recorder.beginRecording(SkRect::Make(glyph.mask().fBounds));
|
||||
if (!this->drawColorGlyph(recordingCanvas, face, palette, glyph)) {
|
||||
if (!this->drawColorGlyph(face, glyph, loadGlyphFlags, palette, recordingCanvas)) {
|
||||
return nullptr;
|
||||
}
|
||||
return recorder.finishRecordingAsDrawable();
|
||||
|
@ -47,14 +47,14 @@ protected:
|
||||
: INHERITED(std::move(typeface), effects, desc)
|
||||
{}
|
||||
|
||||
bool drawColorGlyph(SkCanvas*, FT_Face, SkSpan<SkColor> palette, const SkGlyph&);
|
||||
void generateGlyphImage(FT_Face face,
|
||||
SkSpan<SkColor> palette,
|
||||
const SkGlyph& glyph,
|
||||
const SkMatrix& bitmapTransform);
|
||||
bool generateGlyphPath(FT_Face face, SkPath* path);
|
||||
bool generateFacePath(FT_Face face, SkGlyphID glyphID, SkPath* path);
|
||||
sk_sp<SkDrawable> generateGlyphDrawable(FT_Face face, SkSpan<SkColor> palette, const SkGlyph&);
|
||||
bool drawColorGlyph(FT_Face, const SkGlyph&, uint32_t loadGlyphFlags,
|
||||
SkSpan<SkColor> palette, SkCanvas*);
|
||||
void generateGlyphImage(FT_Face, const SkGlyph&, uint32_t loadGlyphFlags,
|
||||
SkSpan<SkColor> palette, const SkMatrix& bitmapTransform);
|
||||
bool generateGlyphPath(FT_Face, SkPath*);
|
||||
bool generateFacePath(FT_Face, SkGlyphID, uint32_t loadGlyphFlags, SkPath*);
|
||||
sk_sp<SkDrawable> generateGlyphDrawable(FT_Face, const SkGlyph&, uint32_t loadGlyphFlags,
|
||||
SkSpan<SkColor> palette);
|
||||
|
||||
// Computes a bounding box for a COLRv1 glyph id in FT_BBox 26.6 format and FreeType's y-up
|
||||
// coordinate space.
|
||||
|
Loading…
Reference in New Issue
Block a user