@@ -1177,75 +1177,79 @@ void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) {
1177
1177
}
1178
1178
emboldenIfNeeded (fFace , fFace ->glyph , glyph->getGlyphID ());
1179
1179
1180
- switch ( fFace ->glyph ->format ) {
1181
- case FT_GLYPH_FORMAT_OUTLINE:
1182
- if (0 == fFace ->glyph ->outline .n_contours ) {
1183
- glyph->fWidth = 0 ;
1184
- glyph->fHeight = 0 ;
1185
- glyph->fTop = 0 ;
1186
- glyph->fLeft = 0 ;
1187
- } else {
1188
- FT_BBox bbox;
1189
-
1180
+ if (fFace ->glyph ->format == FT_GLYPH_FORMAT_OUTLINE) {
1181
+ using FT_PosLimits = std::numeric_limits<FT_Pos>;
1182
+ FT_BBox bounds = { FT_PosLimits::max (), FT_PosLimits::max (),
1183
+ FT_PosLimits::min (), FT_PosLimits::min () };
1190
1184
#ifdef FT_COLOR_H
1191
- SkRect bounds = SkRect::MakeEmpty ();
1192
-
1193
- FT_LayerIterator layerIterator;
1194
- layerIterator.p = NULL ;
1195
- FT_Bool haveLayers = false ;
1196
- FT_UInt layerGlyphIndex;
1197
- FT_UInt layerColorIndex;
1198
- while (FT_Get_Color_Glyph_Layer (fFace ,
1199
- glyph->getGlyphID (),
1200
- &layerGlyphIndex,
1201
- &layerColorIndex,
1202
- &layerIterator)) {
1203
- haveLayers = true ;
1204
- err = FT_Load_Glyph (fFace , layerGlyphIndex,
1205
- fLoadGlyphFlags | FT_LOAD_BITMAP_METRICS_ONLY);
1206
- if (err != 0 ) {
1207
- glyph->zeroMetrics ();
1208
- return ;
1209
- }
1210
- emboldenIfNeeded (fFace , fFace ->glyph , layerGlyphIndex);
1211
-
1212
- if (0 < fFace ->glyph ->outline .n_contours ) {
1213
- getBBoxForCurrentGlyph (glyph, &bbox, true );
1185
+ FT_Bool haveLayers = false ;
1186
+ FT_LayerIterator layerIterator = { 0 , 0 , nullptr };
1187
+ FT_UInt layerGlyphIndex;
1188
+ FT_UInt layerColorIndex;
1189
+ while (FT_Get_Color_Glyph_Layer (fFace , glyph->getGlyphID (),
1190
+ &layerGlyphIndex, &layerColorIndex, &layerIterator))
1191
+ {
1192
+ haveLayers = true ;
1193
+ err = FT_Load_Glyph (fFace , layerGlyphIndex,
1194
+ fLoadGlyphFlags | FT_LOAD_BITMAP_METRICS_ONLY);
1195
+ if (err != 0 ) {
1196
+ glyph->zeroMetrics ();
1197
+ return ;
1198
+ }
1199
+ emboldenIfNeeded (fFace , fFace ->glyph , layerGlyphIndex);
1214
1200
1215
- SkRect layerBounds = SkRect::MakeLTRB (SkFDot6ToScalar (bbox.xMin ),
1216
- SkFDot6ToScalar (-bbox.yMax ),
1217
- SkFDot6ToScalar (bbox.xMax ),
1218
- SkFDot6ToScalar (-bbox.yMin )
1219
- );
1201
+ if (0 < fFace ->glyph ->outline .n_contours ) {
1202
+ FT_BBox bbox;
1203
+ getBBoxForCurrentGlyph (glyph, &bbox, true );
1220
1204
1221
- bounds.join (layerBounds);
1222
- }
1205
+ // Union
1206
+ bounds.xMin = std::min (bbox.xMin , bounds.xMin );
1207
+ bounds.yMin = std::min (bbox.yMin , bounds.yMin );
1208
+ bounds.xMax = std::max (bbox.xMax , bounds.xMax );
1209
+ bounds.yMax = std::max (bbox.yMax , bounds.yMax );
1223
1210
}
1211
+ }
1224
1212
1225
- if (haveLayers) {
1226
- glyph->fMaskFormat = SkMask::kARGB32_Format ;
1227
-
1228
- SkIRect ibounds = bounds.roundOut ();
1229
- glyph->fWidth = SkToU16 (ibounds.width ());
1230
- glyph->fHeight = SkToU16 (ibounds.height ());
1231
- glyph->fTop = SkToS16 (ibounds.top ());
1232
- glyph->fLeft = SkToS16 (ibounds.left ());
1233
- } else {
1213
+ if (haveLayers) {
1214
+ glyph->fMaskFormat = SkMask::kARGB32_Format ;
1215
+ if (!(bounds.xMin < bounds.xMax && bounds.yMin < bounds.yMax )) {
1216
+ bounds = { 0 , 0 , 0 , 0 };
1217
+ }
1218
+ } else {
1234
1219
#endif
1235
- getBBoxForCurrentGlyph (glyph, &bbox, true );
1236
-
1237
- glyph->fWidth = SkToU16 (SkFDot6Floor (bbox.xMax - bbox.xMin ));
1238
- glyph->fHeight = SkToU16 (SkFDot6Floor (bbox.yMax - bbox.yMin ));
1239
- glyph->fTop = -SkToS16 (SkFDot6Floor (bbox.yMax ));
1240
- glyph->fLeft = SkToS16 (SkFDot6Floor (bbox.xMin ));
1241
- #ifdef FT_COLOR_H
1220
+ if (0 < fFace ->glyph ->outline .n_contours ) {
1221
+ getBBoxForCurrentGlyph (glyph, &bounds, true );
1222
+ } else {
1223
+ bounds = { 0 , 0 , 0 , 0 };
1242
1224
}
1225
+ #ifdef FT_COLOR_H
1226
+ }
1243
1227
#endif
1244
- updateGlyphIfLCD (glyph);
1228
+ // Round out, no longer dot6.
1229
+ bounds.xMin = SkFDot6Floor (bounds.xMin );
1230
+ bounds.yMin = SkFDot6Floor (bounds.yMin );
1231
+ bounds.xMax = SkFDot6Ceil (bounds.xMax );
1232
+ bounds.yMax = SkFDot6Ceil (bounds.yMax );
1233
+
1234
+ FT_Pos width = bounds.xMax - bounds.xMin ;
1235
+ FT_Pos height = bounds.yMax - bounds.yMin ;
1236
+ FT_Pos top = -bounds.yMax ; // Freetype y-up, Skia y-down.
1237
+ FT_Pos left = bounds.xMin ;
1238
+ if (!SkTFitsIn<decltype (glyph->fWidth )>(width ) ||
1239
+ !SkTFitsIn<decltype (glyph->fHeight )>(height) ||
1240
+ !SkTFitsIn<decltype (glyph->fTop )>(top ) ||
1241
+ !SkTFitsIn<decltype (glyph->fLeft )>(left ) )
1242
+ {
1243
+ width = height = top = left = 0 ;
1245
1244
}
1246
- break ;
1247
1245
1248
- case FT_GLYPH_FORMAT_BITMAP:
1246
+ glyph->fWidth = SkToU16 (width );
1247
+ glyph->fHeight = SkToU16 (height);
1248
+ glyph->fTop = SkToS16 (top );
1249
+ glyph->fLeft = SkToS16 (left );
1250
+ updateGlyphIfLCD (glyph);
1251
+
1252
+ } else if (fFace ->glyph ->format == FT_GLYPH_FORMAT_BITMAP) {
1249
1253
if (this ->isVertical ()) {
1250
1254
FT_Vector vector;
1251
1255
vector.x = fFace ->glyph ->metrics .vertBearingX - fFace ->glyph ->metrics .horiBearingX ;
@@ -1275,9 +1279,7 @@ void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) {
1275
1279
glyph->fTop = SkToS16 (irect.top ());
1276
1280
glyph->fLeft = SkToS16 (irect.left ());
1277
1281
}
1278
- break ;
1279
-
1280
- default :
1282
+ } else {
1281
1283
SkDEBUGFAIL (" unknown glyph format" );
1282
1284
glyph->zeroMetrics ();
1283
1285
return ;
0 commit comments