Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: src/ports/SkFontHost_FreeType.cpp

Issue 101423004: refactor emboldenGlyph (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: rebase to master Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/ports/SkFontHost_FreeType_common.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "SkColorPriv.h" 11 #include "SkColorPriv.h"
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 // Need scalar versions for generateFontMetrics 209 // Need scalar versions for generateFontMetrics
210 SkVector fScale; 210 SkVector fScale;
211 SkMatrix fMatrix22Scalar; 211 SkMatrix fMatrix22Scalar;
212 212
213 FT_Error setupSize(); 213 FT_Error setupSize();
214 void getBBoxForCurrentGlyph(SkGlyph* glyph, FT_BBox* bbox, 214 void getBBoxForCurrentGlyph(SkGlyph* glyph, FT_BBox* bbox,
215 bool snapToPixelBoundary = false); 215 bool snapToPixelBoundary = false);
216 bool getCBoxForLetter(char letter, FT_BBox* bbox); 216 bool getCBoxForLetter(char letter, FT_BBox* bbox);
217 // Caller must lock gFTMutex before calling this function. 217 // Caller must lock gFTMutex before calling this function.
218 void updateGlyphIfLCD(SkGlyph* glyph); 218 void updateGlyphIfLCD(SkGlyph* glyph);
219 // Caller must lock gFTMutex before calling this function.
220 // update FreeType2 glyph slot with glyph emboldened
221 void emboldenIfNeeded(FT_Face face, FT_GlyphSlot glyph);
219 }; 222 };
220 223
221 /////////////////////////////////////////////////////////////////////////// 224 ///////////////////////////////////////////////////////////////////////////
222 /////////////////////////////////////////////////////////////////////////// 225 ///////////////////////////////////////////////////////////////////////////
223 226
224 struct SkFaceRec { 227 struct SkFaceRec {
225 SkFaceRec* fNext; 228 SkFaceRec* fNext;
226 FT_Face fFace; 229 FT_Face fFace;
227 FT_StreamRec fFTStream; 230 FT_StreamRec fFTStream;
228 SkStream* fSkStream; 231 SkStream* fSkStream;
(...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 bbox->yMax += vector.y; 1132 bbox->yMax += vector.y;
1130 } 1133 }
1131 } 1134 }
1132 1135
1133 bool SkScalerContext_FreeType::getCBoxForLetter(char letter, FT_BBox* bbox) { 1136 bool SkScalerContext_FreeType::getCBoxForLetter(char letter, FT_BBox* bbox) {
1134 const FT_UInt glyph_id = FT_Get_Char_Index(fFace, letter); 1137 const FT_UInt glyph_id = FT_Get_Char_Index(fFace, letter);
1135 if (!glyph_id) 1138 if (!glyph_id)
1136 return false; 1139 return false;
1137 if (FT_Load_Glyph(fFace, glyph_id, fLoadGlyphFlags) != 0) 1140 if (FT_Load_Glyph(fFace, glyph_id, fLoadGlyphFlags) != 0)
1138 return false; 1141 return false;
1139 if ((fRec.fFlags & kEmbolden_Flag) && 1142 emboldenIfNeeded(fFace, fFace->glyph);
1140 !(fFace->style_flags & FT_STYLE_FLAG_BOLD)) {
1141 emboldenOutline(fFace, &fFace->glyph->outline);
1142 }
1143 FT_Outline_Get_CBox(&fFace->glyph->outline, bbox); 1143 FT_Outline_Get_CBox(&fFace->glyph->outline, bbox);
1144 return true; 1144 return true;
1145 } 1145 }
1146 1146
1147 void SkScalerContext_FreeType::updateGlyphIfLCD(SkGlyph* glyph) { 1147 void SkScalerContext_FreeType::updateGlyphIfLCD(SkGlyph* glyph) {
1148 if (isLCD(fRec)) { 1148 if (isLCD(fRec)) {
1149 if (fLCDIsVert) { 1149 if (fLCDIsVert) {
1150 glyph->fHeight += gLCDExtra; 1150 glyph->fHeight += gLCDExtra;
1151 glyph->fTop -= gLCDExtra >> 1; 1151 glyph->fTop -= gLCDExtra >> 1;
1152 } else { 1152 } else {
(...skipping 29 matching lines...) Expand all
1182 err = FT_Load_Glyph( fFace, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFl ags ); 1182 err = FT_Load_Glyph( fFace, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFl ags );
1183 if (err != 0) { 1183 if (err != 0) {
1184 #if 0 1184 #if 0
1185 SkDEBUGF(("SkScalerContext_FreeType::generateMetrics(%x): FT_Load_Glyph( glyph:%d flags:%x) returned 0x%x\n", 1185 SkDEBUGF(("SkScalerContext_FreeType::generateMetrics(%x): FT_Load_Glyph( glyph:%d flags:%x) returned 0x%x\n",
1186 fFaceRec->fFontID, glyph->getGlyphID(fBaseGlyphCount), fLoad GlyphFlags, err)); 1186 fFaceRec->fFontID, glyph->getGlyphID(fBaseGlyphCount), fLoad GlyphFlags, err));
1187 #endif 1187 #endif
1188 ERROR: 1188 ERROR:
1189 glyph->zeroMetrics(); 1189 glyph->zeroMetrics();
1190 return; 1190 return;
1191 } 1191 }
1192 emboldenIfNeeded(fFace, fFace->glyph);
1192 1193
1193 switch ( fFace->glyph->format ) { 1194 switch ( fFace->glyph->format ) {
1194 case FT_GLYPH_FORMAT_OUTLINE: 1195 case FT_GLYPH_FORMAT_OUTLINE:
1195 if (0 == fFace->glyph->outline.n_contours) { 1196 if (0 == fFace->glyph->outline.n_contours) {
1196 glyph->fWidth = 0; 1197 glyph->fWidth = 0;
1197 glyph->fHeight = 0; 1198 glyph->fHeight = 0;
1198 glyph->fTop = 0; 1199 glyph->fTop = 0;
1199 glyph->fLeft = 0; 1200 glyph->fLeft = 0;
1200 } else { 1201 } else {
1201 if (fRec.fFlags & kEmbolden_Flag && !(fFace->style_flags & FT_STYLE_ FLAG_BOLD)) {
1202 emboldenOutline(fFace, &fFace->glyph->outline);
1203 }
1204
1205 FT_BBox bbox; 1202 FT_BBox bbox;
1206 getBBoxForCurrentGlyph(glyph, &bbox, true); 1203 getBBoxForCurrentGlyph(glyph, &bbox, true);
1207 1204
1208 glyph->fWidth = SkToU16(SkFDot6Floor(bbox.xMax - bbox.xMin)); 1205 glyph->fWidth = SkToU16(SkFDot6Floor(bbox.xMax - bbox.xMin));
1209 glyph->fHeight = SkToU16(SkFDot6Floor(bbox.yMax - bbox.yMin)); 1206 glyph->fHeight = SkToU16(SkFDot6Floor(bbox.yMax - bbox.yMin));
1210 glyph->fTop = -SkToS16(SkFDot6Floor(bbox.yMax)); 1207 glyph->fTop = -SkToS16(SkFDot6Floor(bbox.yMax));
1211 glyph->fLeft = SkToS16(SkFDot6Floor(bbox.xMin)); 1208 glyph->fLeft = SkToS16(SkFDot6Floor(bbox.xMin));
1212 1209
1213 updateGlyphIfLCD(glyph); 1210 updateGlyphIfLCD(glyph);
1214 } 1211 }
1215 break; 1212 break;
1216 1213
1217 case FT_GLYPH_FORMAT_BITMAP: 1214 case FT_GLYPH_FORMAT_BITMAP:
1218 if (fRec.fFlags & kEmbolden_Flag) {
1219 FT_GlyphSlot_Own_Bitmap(fFace->glyph);
1220 FT_Bitmap_Embolden(gFTLibrary, &fFace->glyph->bitmap, kBitmapEmbolde nStrength, 0);
1221 }
1222
1223 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { 1215 if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
1224 FT_Vector vector; 1216 FT_Vector vector;
1225 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metric s.horiBearingX; 1217 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metric s.horiBearingX;
1226 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metri cs.horiBearingY; 1218 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metri cs.horiBearingY;
1227 FT_Vector_Transform(&vector, &fMatrix22); 1219 FT_Vector_Transform(&vector, &fMatrix22);
1228 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x); 1220 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x);
1229 fFace->glyph->bitmap_top += SkFDot6Floor(vector.y); 1221 fFace->glyph->bitmap_top += SkFDot6Floor(vector.y);
1230 } 1222 }
1231 1223
1232 if (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) { 1224 if (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 1283
1292 err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyphFla gs); 1284 err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyphFla gs);
1293 if (err != 0) { 1285 if (err != 0) {
1294 SkDEBUGF(("SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph: %d width:%d height:%d rb:%d flags:%d) returned 0x%x\n", 1286 SkDEBUGF(("SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph: %d width:%d height:%d rb:%d flags:%d) returned 0x%x\n",
1295 glyph.getGlyphID(fBaseGlyphCount), glyph.fWidth, glyph.fHeig ht, glyph.rowBytes(), fLoadGlyphFlags, err)); 1287 glyph.getGlyphID(fBaseGlyphCount), glyph.fWidth, glyph.fHeig ht, glyph.rowBytes(), fLoadGlyphFlags, err));
1296 ERROR: 1288 ERROR:
1297 memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight); 1289 memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
1298 return; 1290 return;
1299 } 1291 }
1300 1292
1293 emboldenIfNeeded(fFace, fFace->glyph);
1301 generateGlyphImage(fFace, glyph); 1294 generateGlyphImage(fFace, glyph);
1302 } 1295 }
1303 1296
1304 1297
1305 void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, 1298 void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph,
1306 SkPath* path) { 1299 SkPath* path) {
1307 SkAutoMutexAcquire ac(gFTMutex); 1300 SkAutoMutexAcquire ac(gFTMutex);
1308 1301
1309 SkASSERT(&glyph && path); 1302 SkASSERT(&glyph && path);
1310 1303
1311 if (this->setupSize()) { 1304 if (this->setupSize()) {
1312 path->reset(); 1305 path->reset();
1313 return; 1306 return;
1314 } 1307 }
1315 1308
1316 uint32_t flags = fLoadGlyphFlags; 1309 uint32_t flags = fLoadGlyphFlags;
1317 flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline 1310 flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
1318 flags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline) 1311 flags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline)
1319 1312
1320 FT_Error err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), flag s); 1313 FT_Error err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), flag s);
1321 1314
1322 if (err != 0) { 1315 if (err != 0) {
1323 SkDEBUGF(("SkScalerContext_FreeType::generatePath: FT_Load_Glyph(glyph:% d flags:%d) returned 0x%x\n", 1316 SkDEBUGF(("SkScalerContext_FreeType::generatePath: FT_Load_Glyph(glyph:% d flags:%d) returned 0x%x\n",
1324 glyph.getGlyphID(fBaseGlyphCount), flags, err)); 1317 glyph.getGlyphID(fBaseGlyphCount), flags, err));
1325 path->reset(); 1318 path->reset();
1326 return; 1319 return;
1327 } 1320 }
1321 emboldenIfNeeded(fFace, fFace->glyph);
1328 1322
1329 generateGlyphPath(fFace, path); 1323 generateGlyphPath(fFace, path);
1330 1324
1331 // The path's origin from FreeType is always the horizontal layout origin. 1325 // The path's origin from FreeType is always the horizontal layout origin.
1332 // Offset the path so that it is relative to the vertical origin if needed. 1326 // Offset the path so that it is relative to the vertical origin if needed.
1333 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { 1327 if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
1334 FT_Vector vector; 1328 FT_Vector vector;
1335 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.ho riBearingX; 1329 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.ho riBearingX;
1336 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.h oriBearingY; 1330 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.h oriBearingY;
1337 FT_Vector_Transform(&vector, &fMatrix22); 1331 FT_Vector_Transform(&vector, &fMatrix22);
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 my->fBottom = ymin * myy; 1453 my->fBottom = ymin * myy;
1460 my->fLeading = leading * myy; 1454 my->fLeading = leading * myy;
1461 my->fAvgCharWidth = avgCharWidth * myy; 1455 my->fAvgCharWidth = avgCharWidth * myy;
1462 my->fXMin = xmin; 1456 my->fXMin = xmin;
1463 my->fXMax = xmax; 1457 my->fXMax = xmax;
1464 my->fXHeight = x_height; 1458 my->fXHeight = x_height;
1465 my->fCapHeight = cap_height; 1459 my->fCapHeight = cap_height;
1466 } 1460 }
1467 } 1461 }
1468 1462
1463 void SkScalerContext_FreeType::emboldenIfNeeded(FT_Face face, FT_GlyphSlot glyph )
1464 {
1465 if (fRec.fFlags & SkScalerContext::kEmbolden_Flag) {
1466 switch ( glyph->format ) {
1467 case FT_GLYPH_FORMAT_OUTLINE:
1468 FT_Pos strength;
1469 strength = FT_MulFix(face->units_per_EM, face->size->metrics.y_s cale) / 24;
1470 FT_Outline_Embolden(&glyph->outline, strength);
1471 break;
1472 case FT_GLYPH_FORMAT_BITMAP:
1473 FT_GlyphSlot_Own_Bitmap(glyph);
1474 FT_Bitmap_Embolden(glyph->library, &glyph->bitmap, kBitmapEmbold enStrength, 0);
1475 break;
1476 default:
1477 SkDEBUGFAIL("unknown glyph format");
1478 }
1479 }
1480 }
1481
1469 /////////////////////////////////////////////////////////////////////////////// 1482 ///////////////////////////////////////////////////////////////////////////////
1470 1483
1471 #include "SkUtils.h" 1484 #include "SkUtils.h"
1472 1485
1473 static SkUnichar next_utf8(const void** chars) { 1486 static SkUnichar next_utf8(const void** chars) {
1474 return SkUTF8_NextUnichar((const char**)chars); 1487 return SkUTF8_NextUnichar((const char**)chars);
1475 } 1488 }
1476 1489
1477 static SkUnichar next_utf16(const void** chars) { 1490 static SkUnichar next_utf16(const void** chars) {
1478 return SkUTF16_NextUnichar((const uint16_t**)chars); 1491 return SkUTF16_NextUnichar((const uint16_t**)chars);
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1662 *style = (SkTypeface::Style) tempStyle; 1675 *style = (SkTypeface::Style) tempStyle;
1663 } 1676 }
1664 if (isFixedPitch) { 1677 if (isFixedPitch) {
1665 *isFixedPitch = FT_IS_FIXED_WIDTH(face); 1678 *isFixedPitch = FT_IS_FIXED_WIDTH(face);
1666 } 1679 }
1667 1680
1668 FT_Done_Face(face); 1681 FT_Done_Face(face);
1669 FT_Done_FreeType(library); 1682 FT_Done_FreeType(library);
1670 return true; 1683 return true;
1671 } 1684 }
OLDNEW
« no previous file with comments | « no previous file | src/ports/SkFontHost_FreeType_common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698