236 SkGlyph* SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) {
237 SkGlyph* glyph;
238
239 int hi = 0;
240 int count = fGlyphArray.count();
241
242 if (count) {
243 SkGlyph** gptr = fGlyphArray.begin();
244 int lo = 0;
245
246 hi = count - 1;
247 while (lo < hi) {
248 int mid = (hi + lo) >> 1;
249 if (gptr[mid]->fID < id) {
250 lo = mid + 1;
251 } else {
252 hi = mid;
253 }
254 }
255 glyph = gptr[hi];
256 if (glyph->fID == id) {
257 if (kFull_MetricsType == mtype && glyph->isJustAdvance()) {
258 fScalerContext->getMetrics(glyph);
259 }
260 return glyph;
261 }
262
263
264 if (glyph->fID < id) {
265 hi += 1;
266 }
267 }
268
269
270 fMemoryUsed += sizeof(SkGlyph);
271
272 glyph = (SkGlyph*)fGlyphAlloc.alloc(sizeof(SkGlyph),
273 SkChunkAlloc::kThrow_AllocFailType);
274 glyph->init(id);
275 *fGlyphArray.insert(hi) = glyph;
276
277 if (kJustAdvance_MetricsType == mtype) {
278 fScalerContext->getAdvance(glyph);
279 fAdvanceCount += 1;
280 } else {
281 SkASSERT(kFull_MetricsType == mtype);
282 fScalerContext->getMetrics(glyph); <=====
283 fMetricsCount += 1;
284 }
285
286 return glyph;
287 }
202 enum MetricsType {
203 kJustAdvance_MetricsType, <=== 0?
204 kFull_MetricsType <=== 1?
205 };
271 void SkScalerContext::getMetrics(SkGlyph* glyph) {
272 this->getGlyphContext(*glyph)->generateMetrics(glyph); <=========
273
274
275
276
277
278 if ((fRec.fFlags & SkScalerContext::kDevKernText_Flag) == 0) {
279
280 glyph->fLsbDelta = glyph->fRsbDelta = 0;
281 }
282
283
284 if (0 == glyph->fWidth || 0 == glyph->fHeight) {
285 glyph->fWidth = 0;
286 glyph->fHeight = 0;
287 glyph->fTop = 0;
288 glyph->fLeft = 0;
289 glyph->fMaskFormat = 0;
290 return;
291 }
292
293 if (fGenerateImageFromPath) {
294 SkPath devPath, fillPath;
295 SkMatrix fillToDevMatrix;
296
297 this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix);
298
299 if (fRasterizer) {
300 SkMask mask;
301
302 if (fRasterizer->rasterize(fillPath, fillToDevMatrix, NULL,
303 fMaskFilter, &mask,
304 SkMask::kJustComputeBounds_CreateMode)) {
305 glyph->fLeft = mask.fBounds.fLeft;
306 glyph->fTop = mask.fBounds.fTop;
307 glyph->fWidth = SkToU16(mask.fBounds.width());
308 glyph->fHeight = SkToU16(mask.fBounds.height());
309 } else {
310 goto SK_ERROR;
311 }
312 } else {
313
314 SkIRect ir;
315 devPath.getBounds().roundOut(&ir);
316
317 if (ir.isEmpty() || !ir.is16Bit()) {
318 goto SK_ERROR;
319 }
320 glyph->fLeft = ir.fLeft;
321 glyph->fTop = ir.fTop;
322 glyph->fWidth = SkToU16(ir.width());
323 glyph->fHeight = SkToU16(ir.height());
324 }
325 }
326
327 if (SkMask::kARGB32_Format != glyph->fMaskFormat) {
328 glyph->fMaskFormat = fRec.fMaskFormat;
329 }
330
331 if (fMaskFilter) {
332 SkMask src, dst;
333 SkMatrix matrix;
334
335 glyph->toMask(&src);
336 fRec.getMatrixFrom2x2(&matrix);
337
338 src.fImage = NULL;
339 if (fMaskFilter->filterMask(&dst, src, matrix, NULL)) {
340 SkASSERT(dst.fImage == NULL);
341 glyph->fLeft = dst.fBounds.fLeft;
342 glyph->fTop = dst.fBounds.fTop;
343 glyph->fWidth = SkToU16(dst.fBounds.width());
344 glyph->fHeight = SkToU16(dst.fBounds.height());
345 glyph->fMaskFormat = dst.fFormat;
346 }
347 }
348 return;
349
350 SK_ERROR:
351
352 glyph->fLeft = 0;
353 glyph->fTop = 0;
354 glyph->fWidth = 0;
355 glyph->fHeight = 0;
356
357
358 glyph->fMaskFormat = fRec.fMaskFormat;
359 }
1036 void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) {
1037 SkAutoMutexAcquire ac(gFTMutex);
1038
1039 glyph->fRsbDelta = 0;
1040 glyph->fLsbDelta = 0;
1041
1042 FT_Error err;
1043
1044 if (this->setupSize()) {
1045 goto ERROR;
1046 }
1047
1048 err = FT_Load_Glyph( fFace, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFlags );
1049 if (err != 0) {
1050 SkDEBUGF(("SkScalerContext_FreeType::generateMetrics(%x): FT_Load_Glyph(glyph:%d flags:%d) returned 0x%x\n",
1051 fFaceRec->fFontID, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFlags, err));
1052 ERROR:
1053 glyph->zeroMetrics();
1054 return;
1055 }
1056
1057 SkFixed vLeft, vTop;
1058
1059 switch ( fFace->glyph->format ) {
1060 case FT_GLYPH_FORMAT_OUTLINE: {
1061 FT_BBox bbox;
1062
1063 if (0 == fFace->glyph->outline.n_contours) {
1064 glyph->fWidth = 0;
1065 glyph->fHeight = 0;
1066 glyph->fTop = 0;
1067 glyph->fLeft = 0;
1068 break;
1069 }
1070
1071 if ((fRec.fFlags & kEmbolden_Flag) && !(fFace->style_flags & FT_STYLE_FLAG_BOLD)) {
1072 emboldenOutline(&fFace->glyph->outline);
1073 }
1074
1075 getBBoxForCurrentGlyph(glyph, &bbox, true);
1076
1077 glyph->fWidth = SkToU16((bbox.xMax - bbox.xMin) >> 6);
1078 glyph->fHeight = SkToU16((bbox.yMax - bbox.yMin) >> 6);
1079 glyph->fTop = -SkToS16(bbox.yMax >> 6);
1080 glyph->fLeft = SkToS16(bbox.xMin >> 6);
1081
1082 if ((fRec.fFlags & SkScalerContext::kVertical_Flag)) {
1083 vLeft = Dot6ToFixed(bbox.xMin);
1084 vTop = Dot6ToFixed(bbox.yMax);
1085 }
1086
1087 updateGlyphIfLCD(glyph);
1088
1089 break;
1090 }
1091
1092 case FT_GLYPH_FORMAT_BITMAP:
1093 if ((fRec.fFlags & kEmbolden_Flag) && !(fFace->style_flags & FT_STYLE_FLAG_BOLD)) {
1094 FT_GlyphSlot_Own_Bitmap(fFace->glyph);
1095 FT_Bitmap_Embolden(gFTLibrary, &fFace->glyph->bitmap, kBitmapEmboldenStrength, 0);
1096 }
1097
1098 if (fUseVertMetrics) {
1099 FT_Vector vector;
1100 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.horiBearingX;
1101 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.horiBearingY;
1102 FT_Vector_Transform(&vector, &fMatrix22);
1103 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x);
1104 fFace->glyph->bitmap_top += SkFDot6Floor(vector.y);
1105 }
1106
1107 glyph->fWidth = SkToU16(fFace->glyph->bitmap.width);
1108 glyph->fHeight = SkToU16(fFace->glyph->bitmap.rows);
1109 glyph->fTop = -SkToS16(fFace->glyph->bitmap_top);
1110 glyph->fLeft = SkToS16(fFace->glyph->bitmap_left);
1111 break;
1112
1113 default:
1114 SkDEBUGFAIL("unknown glyph format");
1115 goto ERROR;
1116 }
1117
1118 if ((fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) == 0) {
1119 glyph->fAdvanceX = SkFDot6ToFixed(fFace->glyph->advance.x);
1120 glyph->fAdvanceY = -SkFDot6ToFixed(fFace->glyph->advance.y);
1121 if (fRec.fFlags & kDevKernText_Flag) {
1122 glyph->fRsbDelta = SkToS8(fFace->glyph->rsb_delta);
1123 glyph->fLsbDelta = SkToS8(fFace->glyph->lsb_delta);
1124 }
1125 } else {
1126 glyph->fAdvanceX = SkFixedMul(fMatrix22.xx, fFace->glyph->linearHoriAdvance);
1127 glyph->fAdvanceY = -SkFixedMul(fMatrix22.yx, fFace->glyph->linearHoriAdvance);
1128 }
1129
1130 if (fUseVertMetrics) {
1131 if (fDoLinearMetrics) {
1132 glyph->fAdvanceX = -SkFixedMul(fMatrix22.xy, fFace->glyph->linearVertAdvance);
1133 glyph->fAdvanceY = SkFixedMul(fMatrix22.yy, fFace->glyph->linearVertAdvance);
1134 } else {
1135 glyph->fAdvanceX = -SkFDot6ToFixed(fFace->glyph->advance.x);
1136 glyph->fAdvanceY = SkFDot6ToFixed(fFace->glyph->advance.y);
1137 }
1138
1139 } else if ((fRec.fFlags & SkScalerContext::kVertical_Flag)
1140 && fFace->glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
1141
1142 TODO
1143
1144 FT_Matrix identityMatrix;
1145 identityMatrix.xx = identityMatrix.yy = SK_Fixed1;
1146 identityMatrix.xy = identityMatrix.yx = 0;
1147
1148
1149
1150 if (memcmp(&fMatrix22, &identityMatrix, sizeof(FT_Matrix)) != 0) {
1151
1152 FT_Set_Transform(fFace, &identityMatrix, NULL);
1153
1154 err = FT_Load_Glyph( fFace, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFlags );
1155 if (err != 0) {
1156 SkDEBUGF(("SkScalerContext_FreeType::generateMetrics(%x): FT_Load_Glyph(glyph:%d flags:%d) returned 0x%x\n",
1157 fFaceRec->fFontID, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFlags, err));
1158 goto ERROR;
1159 }
1160
1161 if ((fRec.fFlags & kEmbolden_Flag) && !(fFace->style_flags & FT_STYLE_FLAG_BOLD)) {
1162 emboldenOutline(&fFace->glyph->outline);
1163 }
1164 }
1165
1166
1167 FT_BBox bbox;
1168 getBBoxForCurrentGlyph(glyph, &bbox);
1169
1170
1171
1172 SkFixed vGap = (fFace->glyph->linearVertAdvance - Dot6ToFixed(bbox.yMax - bbox.yMin)) / 2;
1173
1174
1175 FT_Vector vOrigin;
1176 vOrigin.x = fFace->glyph->linearHoriAdvance / 2;
1177 vOrigin.y = vGap + Dot6ToFixed(bbox.yMax);
1178
1179
1180 FT_Vector_Transform(&vOrigin, &fMatrix22);
1181
1182
1183
1184 glyph->fLeft = SkFixedRoundToInt(vLeft - vOrigin.x);
1185 glyph->fTop = -SkFixedRoundToInt(vTop - vOrigin.y);
1186
1187 updateGlyphIfLCD(glyph);
1188
1189
1190 glyph->fAdvanceX = -SkFixedMul(fMatrix22.xy, fFace->glyph->linearVertAdvance);
1191 glyph->fAdvanceY = SkFixedMul(fMatrix22.yy, fFace->glyph->linearVertAdvance);
1192 }
1193
1194
1195 #ifdef ENABLE_GLYPH_SPEW
1196 SkDEBUGF(("FT_Set_Char_Size(this:%p sx:%x sy:%x ", this, fScaleX, fScaleY));
1197 SkDEBUGF(("Metrics(glyph:%d flags:0x%x) w:%d\n", glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFlags, glyph->fWidth));
1198 #endif
1199 }