Protect FreeType face with mixed glyph formats.
It is possible for a single glyph to have multiple representations. In a COLRv0 or COLRv1 font the outlines of the sub glyphs must be used as layers or clips. Ensure that bitmaps and SVG representations are explicitly excluded when loading glyphs with the express purpose of retrieving any available outline. Note that this does not touch the flags used in generatePath because in that case a path should only be loaded if the glyph representation for rendering is actually outline based. Change-Id: I499e23aa20dacead81c7f76980039f139fa8edce Reviewed-on: https://skia-review.googlesource.com/c/skia/+/530676 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Ben Wagner <bungeman@google.com>
This commit is contained in:
parent
21ca05d8bf
commit
dc07bc6562
@ -1088,7 +1088,7 @@ bool SkScalerContext_FreeType::getCBoxForLetter(char letter, FT_BBox* bbox) {
|
||||
if (!glyph_id) {
|
||||
return false;
|
||||
}
|
||||
if (FT_Load_Glyph(fFace, glyph_id, fLoadGlyphFlags) != 0) {
|
||||
if (FT_Load_Glyph(fFace, glyph_id, fLoadGlyphFlags)) {
|
||||
return false;
|
||||
}
|
||||
if (fFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE) {
|
||||
@ -1209,13 +1209,16 @@ void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph, SkArenaAlloc* all
|
||||
FT_LayerIterator layerIterator = { 0, 0, nullptr };
|
||||
FT_UInt layerGlyphIndex;
|
||||
FT_UInt layerColorIndex;
|
||||
FT_Int32 flags = fLoadGlyphFlags;
|
||||
flags |= FT_LOAD_BITMAP_METRICS_ONLY; // Don't decode any bitmaps.
|
||||
flags |= FT_LOAD_NO_BITMAP; // Ignore embedded bitmaps.
|
||||
flags &= ~FT_LOAD_RENDER; // Don't scan convert.
|
||||
flags &= ~FT_LOAD_COLOR; // Ignore SVG.
|
||||
// For COLRv0 compute the glyph bounding box from the union of layer bounding boxes.
|
||||
while (FT_Get_Color_Glyph_Layer(fFace, glyph->getGlyphID(), &layerGlyphIndex,
|
||||
&layerColorIndex, &layerIterator)) {
|
||||
haveLayers = true;
|
||||
if (FT_Load_Glyph(fFace, layerGlyphIndex,
|
||||
fLoadGlyphFlags | FT_LOAD_BITMAP_METRICS_ONLY))
|
||||
{
|
||||
if (FT_Load_Glyph(fFace, layerGlyphIndex, flags)) {
|
||||
glyph->zeroMetrics();
|
||||
return;
|
||||
}
|
||||
|
@ -1660,8 +1660,10 @@ bool generateGlyphPathStatic(FT_Face face, SkPath* path) {
|
||||
}
|
||||
|
||||
bool generateFacePathStatic(FT_Face face, SkGlyphID glyphID, uint32_t loadGlyphFlags, SkPath* path){
|
||||
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)
|
||||
loadGlyphFlags |= FT_LOAD_BITMAP_METRICS_ONLY; // Don't decode any bitmaps.
|
||||
loadGlyphFlags |= FT_LOAD_NO_BITMAP; // Ignore embedded bitmaps.
|
||||
loadGlyphFlags &= ~FT_LOAD_RENDER; // Don't scan convert.
|
||||
loadGlyphFlags &= ~FT_LOAD_COLOR; // Ignore SVG.
|
||||
if (FT_Load_Glyph(face, glyphID, loadGlyphFlags)) {
|
||||
path->reset();
|
||||
return false;
|
||||
@ -1672,8 +1674,10 @@ bool generateFacePathStatic(FT_Face face, SkGlyphID glyphID, uint32_t loadGlyphF
|
||||
#ifdef TT_SUPPORT_COLRV1
|
||||
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_BITMAP_METRICS_ONLY; // Don't decode any bitmaps.
|
||||
flags |= FT_LOAD_NO_BITMAP; // Ignore embedded bitmaps.
|
||||
flags &= ~FT_LOAD_RENDER; // Don't scan convert.
|
||||
flags &= ~FT_LOAD_COLOR; // Ignore SVG.
|
||||
flags |= FT_LOAD_NO_HINTING;
|
||||
flags |= FT_LOAD_NO_AUTOHINT;
|
||||
flags |= FT_LOAD_IGNORE_TRANSFORM;
|
||||
|
Loading…
Reference in New Issue
Block a user