зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1442669 - guard against excessively large glyphs in SkFontHost_cairo. r=jfkthame
MozReview-Commit-ID: 1X2524Q5K8E
This commit is contained in:
Родитель
82c740d1b1
Коммит
0626b8ac56
|
@ -642,10 +642,19 @@ void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
|
||||||
|
|
||||||
prepareGlyph(face->glyph);
|
prepareGlyph(face->glyph);
|
||||||
|
|
||||||
|
if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
|
||||||
|
glyph->fAdvanceX = -SkFDot6ToFloat(face->glyph->advance.x);
|
||||||
|
glyph->fAdvanceY = SkFDot6ToFloat(face->glyph->advance.y);
|
||||||
|
} else {
|
||||||
|
glyph->fAdvanceX = SkFDot6ToFloat(face->glyph->advance.x);
|
||||||
|
glyph->fAdvanceY = -SkFDot6ToFloat(face->glyph->advance.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
SkIRect bounds;
|
||||||
switch (face->glyph->format) {
|
switch (face->glyph->format) {
|
||||||
case FT_GLYPH_FORMAT_OUTLINE:
|
case FT_GLYPH_FORMAT_OUTLINE:
|
||||||
if (!face->glyph->outline.n_contours) {
|
if (!face->glyph->outline.n_contours) {
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_BBox bbox;
|
FT_BBox bbox;
|
||||||
|
@ -654,10 +663,10 @@ void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
|
||||||
bbox.yMin &= ~63;
|
bbox.yMin &= ~63;
|
||||||
bbox.xMax = (bbox.xMax + 63) & ~63;
|
bbox.xMax = (bbox.xMax + 63) & ~63;
|
||||||
bbox.yMax = (bbox.yMax + 63) & ~63;
|
bbox.yMax = (bbox.yMax + 63) & ~63;
|
||||||
glyph->fWidth = SkToU16(SkFDot6Floor(bbox.xMax - bbox.xMin));
|
bounds = SkIRect::MakeLTRB(SkFDot6Floor(bbox.xMin),
|
||||||
glyph->fHeight = SkToU16(SkFDot6Floor(bbox.yMax - bbox.yMin));
|
-SkFDot6Floor(bbox.yMax),
|
||||||
glyph->fTop = -SkToS16(SkFDot6Floor(bbox.yMax));
|
SkFDot6Floor(bbox.xMax),
|
||||||
glyph->fLeft = SkToS16(SkFDot6Floor(bbox.xMin));
|
-SkFDot6Floor(bbox.yMin));
|
||||||
|
|
||||||
if (isLCD(fRec)) {
|
if (isLCD(fRec)) {
|
||||||
// In FreeType < 2.8.1, LCD filtering, if explicitly used, may
|
// In FreeType < 2.8.1, LCD filtering, if explicitly used, may
|
||||||
|
@ -669,11 +678,9 @@ void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
|
||||||
// here. generateGlyphImage will detect if the mask is smaller
|
// here. generateGlyphImage will detect if the mask is smaller
|
||||||
// than the bounds and clip things appropriately.
|
// than the bounds and clip things appropriately.
|
||||||
if (fRec.fFlags & kLCD_Vertical_Flag) {
|
if (fRec.fFlags & kLCD_Vertical_Flag) {
|
||||||
glyph->fTop -= 1;
|
bounds.outset(0, 1);
|
||||||
glyph->fHeight += 2;
|
|
||||||
} else {
|
} else {
|
||||||
glyph->fLeft -= 1;
|
bounds.outset(1, 0);
|
||||||
glyph->fWidth += 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -702,15 +709,15 @@ void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
|
||||||
SkRect destRect;
|
SkRect destRect;
|
||||||
fShapeMatrix.mapRect(&destRect, srcRect);
|
fShapeMatrix.mapRect(&destRect, srcRect);
|
||||||
SkIRect glyphRect = destRect.roundOut();
|
SkIRect glyphRect = destRect.roundOut();
|
||||||
glyph->fWidth = SkToU16(glyphRect.width());
|
bounds = SkIRect::MakeXYWH(SkScalarRoundToInt(destRect.fLeft),
|
||||||
glyph->fHeight = SkToU16(glyphRect.height());
|
SkScalarRoundToInt(destRect.fTop),
|
||||||
glyph->fTop = SkToS16(SkScalarRoundToInt(destRect.fTop));
|
glyphRect.width(),
|
||||||
glyph->fLeft = SkToS16(SkScalarRoundToInt(destRect.fLeft));
|
glyphRect.height());
|
||||||
} else {
|
} else {
|
||||||
glyph->fWidth = SkToU16(face->glyph->bitmap.width);
|
bounds = SkIRect::MakeXYWH(face->glyph->bitmap_left,
|
||||||
glyph->fHeight = SkToU16(face->glyph->bitmap.rows);
|
-face->glyph->bitmap_top,
|
||||||
glyph->fTop = -SkToS16(face->glyph->bitmap_top);
|
face->glyph->bitmap.width,
|
||||||
glyph->fLeft = SkToS16(face->glyph->bitmap_left);
|
face->glyph->bitmap.rows);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -718,12 +725,11 @@ void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
|
if (SkIRect::MakeXYWH(SHRT_MIN, SHRT_MIN, USHRT_MAX, USHRT_MAX).contains(bounds)) {
|
||||||
glyph->fAdvanceX = -SkFDot6ToFloat(face->glyph->advance.x);
|
glyph->fWidth = SkToU16(bounds.width());
|
||||||
glyph->fAdvanceY = SkFDot6ToFloat(face->glyph->advance.y);
|
glyph->fHeight = SkToU16(bounds.height());
|
||||||
} else {
|
glyph->fLeft = SkToS16(bounds.left());
|
||||||
glyph->fAdvanceX = SkFDot6ToFloat(face->glyph->advance.x);
|
glyph->fTop = SkToS16(bounds.top());
|
||||||
glyph->fAdvanceY = -SkFDot6ToFloat(face->glyph->advance.y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче