OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
(...skipping 1153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1164 err = FT_Load_Glyph( fFace, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFl
ags ); | 1164 err = FT_Load_Glyph( fFace, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFl
ags ); |
1165 if (err != 0) { | 1165 if (err != 0) { |
1166 #if 0 | 1166 #if 0 |
1167 SkDEBUGF(("SkScalerContext_FreeType::generateMetrics(%x): FT_Load_Glyph(
glyph:%d flags:%x) returned 0x%x\n", | 1167 SkDEBUGF(("SkScalerContext_FreeType::generateMetrics(%x): FT_Load_Glyph(
glyph:%d flags:%x) returned 0x%x\n", |
1168 fFaceRec->fFontID, glyph->getGlyphID(fBaseGlyphCount), fLoad
GlyphFlags, err)); | 1168 fFaceRec->fFontID, glyph->getGlyphID(fBaseGlyphCount), fLoad
GlyphFlags, err)); |
1169 #endif | 1169 #endif |
1170 ERROR: | 1170 ERROR: |
1171 glyph->zeroMetrics(); | 1171 glyph->zeroMetrics(); |
1172 return; | 1172 return; |
1173 } | 1173 } |
| 1174 emboldenIfNeeded(fFace, fFace->glyph); |
1174 | 1175 |
1175 switch ( fFace->glyph->format ) { | 1176 switch ( fFace->glyph->format ) { |
1176 case FT_GLYPH_FORMAT_OUTLINE: | 1177 case FT_GLYPH_FORMAT_OUTLINE: |
1177 if (0 == fFace->glyph->outline.n_contours) { | 1178 if (0 == fFace->glyph->outline.n_contours) { |
1178 glyph->fWidth = 0; | 1179 glyph->fWidth = 0; |
1179 glyph->fHeight = 0; | 1180 glyph->fHeight = 0; |
1180 glyph->fTop = 0; | 1181 glyph->fTop = 0; |
1181 glyph->fLeft = 0; | 1182 glyph->fLeft = 0; |
1182 } else { | 1183 } else { |
1183 if (fRec.fFlags & kEmbolden_Flag && !(fFace->style_flags & FT_STYLE_
FLAG_BOLD)) { | |
1184 emboldenOutline(fFace, &fFace->glyph->outline); | |
1185 } | |
1186 | |
1187 FT_BBox bbox; | 1184 FT_BBox bbox; |
1188 getBBoxForCurrentGlyph(glyph, &bbox, true); | 1185 getBBoxForCurrentGlyph(glyph, &bbox, true); |
1189 | 1186 |
1190 glyph->fWidth = SkToU16(SkFDot6Floor(bbox.xMax - bbox.xMin)); | 1187 glyph->fWidth = SkToU16(SkFDot6Floor(bbox.xMax - bbox.xMin)); |
1191 glyph->fHeight = SkToU16(SkFDot6Floor(bbox.yMax - bbox.yMin)); | 1188 glyph->fHeight = SkToU16(SkFDot6Floor(bbox.yMax - bbox.yMin)); |
1192 glyph->fTop = -SkToS16(SkFDot6Floor(bbox.yMax)); | 1189 glyph->fTop = -SkToS16(SkFDot6Floor(bbox.yMax)); |
1193 glyph->fLeft = SkToS16(SkFDot6Floor(bbox.xMin)); | 1190 glyph->fLeft = SkToS16(SkFDot6Floor(bbox.xMin)); |
1194 | 1191 |
1195 updateGlyphIfLCD(glyph); | 1192 updateGlyphIfLCD(glyph); |
1196 } | 1193 } |
1197 break; | 1194 break; |
1198 | 1195 |
1199 case FT_GLYPH_FORMAT_BITMAP: | 1196 case FT_GLYPH_FORMAT_BITMAP: |
1200 if (fRec.fFlags & kEmbolden_Flag) { | |
1201 FT_GlyphSlot_Own_Bitmap(fFace->glyph); | |
1202 FT_Bitmap_Embolden(gFTLibrary, &fFace->glyph->bitmap, kBitmapEmbolde
nStrength, 0); | |
1203 } | |
1204 | |
1205 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { | 1197 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { |
1206 FT_Vector vector; | 1198 FT_Vector vector; |
1207 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metric
s.horiBearingX; | 1199 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metric
s.horiBearingX; |
1208 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metri
cs.horiBearingY; | 1200 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metri
cs.horiBearingY; |
1209 FT_Vector_Transform(&vector, &fMatrix22); | 1201 FT_Vector_Transform(&vector, &fMatrix22); |
1210 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x); | 1202 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x); |
1211 fFace->glyph->bitmap_top += SkFDot6Floor(vector.y); | 1203 fFace->glyph->bitmap_top += SkFDot6Floor(vector.y); |
1212 } | 1204 } |
1213 | 1205 |
1214 if (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) { | 1206 if (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1273 | 1265 |
1274 err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyphFla
gs); | 1266 err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyphFla
gs); |
1275 if (err != 0) { | 1267 if (err != 0) { |
1276 SkDEBUGF(("SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph:
%d width:%d height:%d rb:%d flags:%d) returned 0x%x\n", | 1268 SkDEBUGF(("SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph:
%d width:%d height:%d rb:%d flags:%d) returned 0x%x\n", |
1277 glyph.getGlyphID(fBaseGlyphCount), glyph.fWidth, glyph.fHeig
ht, glyph.rowBytes(), fLoadGlyphFlags, err)); | 1269 glyph.getGlyphID(fBaseGlyphCount), glyph.fWidth, glyph.fHeig
ht, glyph.rowBytes(), fLoadGlyphFlags, err)); |
1278 ERROR: | 1270 ERROR: |
1279 memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight); | 1271 memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight); |
1280 return; | 1272 return; |
1281 } | 1273 } |
1282 | 1274 |
| 1275 emboldenIfNeeded(fFace, fFace->glyph); |
1283 generateGlyphImage(fFace, glyph); | 1276 generateGlyphImage(fFace, glyph); |
1284 } | 1277 } |
1285 | 1278 |
1286 | 1279 |
1287 void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, | 1280 void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, |
1288 SkPath* path) { | 1281 SkPath* path) { |
1289 SkAutoMutexAcquire ac(gFTMutex); | 1282 SkAutoMutexAcquire ac(gFTMutex); |
1290 | 1283 |
1291 SkASSERT(&glyph && path); | 1284 SkASSERT(&glyph && path); |
1292 | 1285 |
1293 if (this->setupSize()) { | 1286 if (this->setupSize()) { |
1294 path->reset(); | 1287 path->reset(); |
1295 return; | 1288 return; |
1296 } | 1289 } |
1297 | 1290 |
1298 uint32_t flags = fLoadGlyphFlags; | 1291 uint32_t flags = fLoadGlyphFlags; |
1299 flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get
the outline | 1292 flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get
the outline |
1300 flags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline) | 1293 flags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline) |
1301 | 1294 |
1302 FT_Error err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), flag
s); | 1295 FT_Error err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), flag
s); |
1303 | 1296 |
1304 if (err != 0) { | 1297 if (err != 0) { |
1305 SkDEBUGF(("SkScalerContext_FreeType::generatePath: FT_Load_Glyph(glyph:%
d flags:%d) returned 0x%x\n", | 1298 SkDEBUGF(("SkScalerContext_FreeType::generatePath: FT_Load_Glyph(glyph:%
d flags:%d) returned 0x%x\n", |
1306 glyph.getGlyphID(fBaseGlyphCount), flags, err)); | 1299 glyph.getGlyphID(fBaseGlyphCount), flags, err)); |
1307 path->reset(); | 1300 path->reset(); |
1308 return; | 1301 return; |
1309 } | 1302 } |
| 1303 emboldenIfNeeded(fFace, fFace->glyph); |
1310 | 1304 |
1311 generateGlyphPath(fFace, path); | 1305 generateGlyphPath(fFace, path); |
1312 | 1306 |
1313 // The path's origin from FreeType is always the horizontal layout origin. | 1307 // The path's origin from FreeType is always the horizontal layout origin. |
1314 // Offset the path so that it is relative to the vertical origin if needed. | 1308 // Offset the path so that it is relative to the vertical origin if needed. |
1315 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { | 1309 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { |
1316 FT_Vector vector; | 1310 FT_Vector vector; |
1317 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.ho
riBearingX; | 1311 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.ho
riBearingX; |
1318 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.h
oriBearingY; | 1312 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.h
oriBearingY; |
1319 FT_Vector_Transform(&vector, &fMatrix22); | 1313 FT_Vector_Transform(&vector, &fMatrix22); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1373 xmin = SkIntToScalar(face->bbox.xMin) / upem; | 1367 xmin = SkIntToScalar(face->bbox.xMin) / upem; |
1374 xmax = SkIntToScalar(face->bbox.xMax) / upem; | 1368 xmax = SkIntToScalar(face->bbox.xMax) / upem; |
1375 ymin = -SkIntToScalar(face->bbox.yMin) / upem; | 1369 ymin = -SkIntToScalar(face->bbox.yMin) / upem; |
1376 ymax = -SkIntToScalar(face->bbox.yMax) / upem; | 1370 ymax = -SkIntToScalar(face->bbox.yMax) / upem; |
1377 // we may be able to synthesize x_height from outline | 1371 // we may be able to synthesize x_height from outline |
1378 if (!x_height) { | 1372 if (!x_height) { |
1379 const FT_UInt x_glyph = FT_Get_Char_Index(fFace, 'x'); | 1373 const FT_UInt x_glyph = FT_Get_Char_Index(fFace, 'x'); |
1380 if (x_glyph) { | 1374 if (x_glyph) { |
1381 FT_BBox bbox; | 1375 FT_BBox bbox; |
1382 FT_Load_Glyph(fFace, x_glyph, fLoadGlyphFlags); | 1376 FT_Load_Glyph(fFace, x_glyph, fLoadGlyphFlags); |
1383 if ((fRec.fFlags & kEmbolden_Flag) && !(fFace->style_flags & FT_
STYLE_FLAG_BOLD)) { | 1377 emboldenIfNeeded(fFace, fFace->glyph); |
1384 emboldenOutline(fFace, &fFace->glyph->outline); | |
1385 } | |
1386 FT_Outline_Get_CBox(&fFace->glyph->outline, &bbox); | 1378 FT_Outline_Get_CBox(&fFace->glyph->outline, &bbox); |
1387 x_height = SkIntToScalar(bbox.yMax) / 64.0f; | 1379 x_height = SkIntToScalar(bbox.yMax) / 64.0f; |
1388 } | 1380 } |
1389 } | 1381 } |
1390 } else if (fStrikeIndex != -1) { // bitmap strike metrics | 1382 } else if (fStrikeIndex != -1) { // bitmap strike metrics |
1391 SkScalar xppem = SkIntToScalar(face->size->metrics.x_ppem); | 1383 SkScalar xppem = SkIntToScalar(face->size->metrics.x_ppem); |
1392 SkScalar yppem = SkIntToScalar(face->size->metrics.y_ppem); | 1384 SkScalar yppem = SkIntToScalar(face->size->metrics.y_ppem); |
1393 ascent = -SkIntToScalar(face->size->metrics.ascender) / (yppem * 64.0f); | 1385 ascent = -SkIntToScalar(face->size->metrics.ascender) / (yppem * 64.0f); |
1394 descent = -SkIntToScalar(face->size->metrics.descender) / (yppem * 64.0f
); | 1386 descent = -SkIntToScalar(face->size->metrics.descender) / (yppem * 64.0f
); |
1395 leading = (SkIntToScalar(face->size->metrics.height) / (yppem * 64.0f)) | 1387 leading = (SkIntToScalar(face->size->metrics.height) / (yppem * 64.0f)) |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1641 *style = (SkTypeface::Style) tempStyle; | 1633 *style = (SkTypeface::Style) tempStyle; |
1642 } | 1634 } |
1643 if (isFixedPitch) { | 1635 if (isFixedPitch) { |
1644 *isFixedPitch = FT_IS_FIXED_WIDTH(face); | 1636 *isFixedPitch = FT_IS_FIXED_WIDTH(face); |
1645 } | 1637 } |
1646 | 1638 |
1647 FT_Done_Face(face); | 1639 FT_Done_Face(face); |
1648 FT_Done_FreeType(library); | 1640 FT_Done_FreeType(library); |
1649 return true; | 1641 return true; |
1650 } | 1642 } |
OLD | NEW |