OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkAdvancedTypefaceMetrics.h" | 8 #include "SkAdvancedTypefaceMetrics.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1308 } | 1308 } |
1309 | 1309 |
1310 SkAutoMutexAcquire ac(gFTMutex); | 1310 SkAutoMutexAcquire ac(gFTMutex); |
1311 | 1311 |
1312 if (this->setupSize()) { | 1312 if (this->setupSize()) { |
1313 sk_bzero(metrics, sizeof(*metrics)); | 1313 sk_bzero(metrics, sizeof(*metrics)); |
1314 return; | 1314 return; |
1315 } | 1315 } |
1316 | 1316 |
1317 FT_Face face = fFace; | 1317 FT_Face face = fFace; |
1318 SkScalar scaleX = fScale.x(); | |
1319 SkScalar scaleY = fScale.y(); | |
1320 SkScalar mxy = -fMatrix22Scalar.getSkewX() * scaleY; | |
1321 SkScalar myy = fMatrix22Scalar.getScaleY() * scaleY; | |
1322 | 1318 |
1323 // fetch units/EM from "head" table if needed (ie for bitmap fonts) | 1319 // fetch units/EM from "head" table if needed (ie for bitmap fonts) |
1324 SkScalar upem = SkIntToScalar(face->units_per_EM); | 1320 SkScalar upem = SkIntToScalar(face->units_per_EM); |
1325 if (!upem) { | 1321 if (!upem) { |
1326 TT_Header* ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face, ft_sfnt_head); | 1322 TT_Header* ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face, ft_sfnt_head); |
1327 if (ttHeader) { | 1323 if (ttHeader) { |
1328 upem = SkIntToScalar(ttHeader->Units_Per_EM); | 1324 upem = SkIntToScalar(ttHeader->Units_Per_EM); |
1329 } | 1325 } |
1330 } | 1326 } |
1331 | 1327 |
1332 // use the os/2 table as a source of reasonable defaults. | 1328 // use the os/2 table as a source of reasonable defaults. |
1333 SkScalar x_height = 0.0f; | 1329 SkScalar x_height = 0.0f; |
1334 SkScalar avgCharWidth = 0.0f; | 1330 SkScalar avgCharWidth = 0.0f; |
1335 SkScalar cap_height = 0.0f; | 1331 SkScalar cap_height = 0.0f; |
1336 TT_OS2* os2 = (TT_OS2*) FT_Get_Sfnt_Table(face, ft_sfnt_os2); | 1332 TT_OS2* os2 = (TT_OS2*) FT_Get_Sfnt_Table(face, ft_sfnt_os2); |
1337 if (os2) { | 1333 if (os2) { |
1338 x_height = scaleX * SkIntToScalar(os2->sxHeight) / upem; | 1334 x_height = SkIntToScalar(os2->sxHeight) / upem * fScale.y(); |
1339 avgCharWidth = SkIntToScalar(os2->xAvgCharWidth) / upem; | 1335 avgCharWidth = SkIntToScalar(os2->xAvgCharWidth) / upem; |
1340 if (os2->version != 0xFFFF && os2->version >= 2) { | 1336 if (os2->version != 0xFFFF && os2->version >= 2) { |
1341 cap_height = scaleX * SkIntToScalar(os2->sCapHeight) / upem; | 1337 cap_height = SkIntToScalar(os2->sCapHeight) / upem * fScale.y(); |
1342 } | 1338 } |
1343 } | 1339 } |
1344 | 1340 |
1345 // pull from format-specific metrics as needed | 1341 // pull from format-specific metrics as needed |
1346 SkScalar ascent, descent, leading, xmin, xmax, ymin, ymax; | 1342 SkScalar ascent, descent, leading, xmin, xmax, ymin, ymax; |
1347 SkScalar underlineThickness, underlinePosition; | 1343 SkScalar underlineThickness, underlinePosition; |
1348 if (face->face_flags & FT_FACE_FLAG_SCALABLE) { // scalable outline font | 1344 if (face->face_flags & FT_FACE_FLAG_SCALABLE) { // scalable outline font |
1349 // FreeType will always use HHEA metrics if they're not zero. | 1345 // FreeType will always use HHEA metrics if they're not zero. |
1350 // It completely ignores the OS/2 fsSelection::UseTypoMetrics bit. | 1346 // It completely ignores the OS/2 fsSelection::UseTypoMetrics bit. |
1351 // It also ignores the VDMX tables, which are also of interest here | 1347 // It also ignores the VDMX tables, which are also of interest here |
(...skipping 30 matching lines...) Expand all Loading... |
1382 FT_BBox bbox; | 1378 FT_BBox bbox; |
1383 if (getCBoxForLetter('H', &bbox)) { | 1379 if (getCBoxForLetter('H', &bbox)) { |
1384 cap_height = SkIntToScalar(bbox.yMax) / 64.0f; | 1380 cap_height = SkIntToScalar(bbox.yMax) / 64.0f; |
1385 } | 1381 } |
1386 } | 1382 } |
1387 } else if (fStrikeIndex != -1) { // bitmap strike metrics | 1383 } else if (fStrikeIndex != -1) { // bitmap strike metrics |
1388 SkScalar xppem = SkIntToScalar(face->size->metrics.x_ppem); | 1384 SkScalar xppem = SkIntToScalar(face->size->metrics.x_ppem); |
1389 SkScalar yppem = SkIntToScalar(face->size->metrics.y_ppem); | 1385 SkScalar yppem = SkIntToScalar(face->size->metrics.y_ppem); |
1390 ascent = -SkIntToScalar(face->size->metrics.ascender) / (yppem * 64.0f); | 1386 ascent = -SkIntToScalar(face->size->metrics.ascender) / (yppem * 64.0f); |
1391 descent = -SkIntToScalar(face->size->metrics.descender) / (yppem * 64.0f
); | 1387 descent = -SkIntToScalar(face->size->metrics.descender) / (yppem * 64.0f
); |
1392 leading = (SkIntToScalar(face->size->metrics.height) / (yppem * 64.0f)) | 1388 leading = (SkIntToScalar(face->size->metrics.height) / (yppem * 64.0f))
+ ascent - descent; |
1393 + ascent - descent; | |
1394 xmin = 0.0f; | 1389 xmin = 0.0f; |
1395 xmax = SkIntToScalar(face->available_sizes[fStrikeIndex].width) / xppem; | 1390 xmax = SkIntToScalar(face->available_sizes[fStrikeIndex].width) / xppem; |
1396 ymin = descent + leading; | 1391 ymin = descent + leading; |
1397 ymax = ascent - descent; | 1392 ymax = ascent - descent; |
1398 underlineThickness = 0; | 1393 underlineThickness = 0; |
1399 underlinePosition = 0; | 1394 underlinePosition = 0; |
1400 | 1395 |
1401 metrics->fFlags &= ~SkPaint::FontMetrics::kUnderlineThinknessIsValid_Fla
g; | 1396 metrics->fFlags &= ~SkPaint::FontMetrics::kUnderlineThinknessIsValid_Fla
g; |
1402 metrics->fFlags &= ~SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag
; | 1397 metrics->fFlags &= ~SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag
; |
1403 } else { | 1398 } else { |
1404 sk_bzero(metrics, sizeof(*metrics)); | 1399 sk_bzero(metrics, sizeof(*metrics)); |
1405 return; | 1400 return; |
1406 } | 1401 } |
1407 | 1402 |
1408 // synthesize elements that were not provided by the os/2 table or format-sp
ecific metrics | 1403 // synthesize elements that were not provided by the os/2 table or format-sp
ecific metrics |
1409 if (!x_height) { | 1404 if (!x_height) { |
1410 x_height = -ascent; | 1405 x_height = -ascent * fScale.y(); |
1411 } | 1406 } |
1412 if (!avgCharWidth) { | 1407 if (!avgCharWidth) { |
1413 avgCharWidth = xmax - xmin; | 1408 avgCharWidth = xmax - xmin; |
1414 } | 1409 } |
1415 if (!cap_height) { | 1410 if (!cap_height) { |
1416 cap_height = -ascent; | 1411 cap_height = -ascent * fScale.y(); |
1417 } | 1412 } |
1418 | 1413 |
1419 // disallow negative linespacing | 1414 // disallow negative linespacing |
1420 if (leading < 0.0f) { | 1415 if (leading < 0.0f) { |
1421 leading = 0.0f; | 1416 leading = 0.0f; |
1422 } | 1417 } |
1423 | 1418 |
1424 SkScalar scale = myy; | 1419 metrics->fTop = ymax * fScale.y(); |
1425 if (this->isVertical()) { | 1420 metrics->fAscent = ascent * fScale.y(); |
1426 scale = mxy; | 1421 metrics->fDescent = descent * fScale.y(); |
1427 } | 1422 metrics->fBottom = ymin * fScale.y(); |
1428 metrics->fTop = ymax * scale; | 1423 metrics->fLeading = leading * fScale.y(); |
1429 metrics->fAscent = ascent * scale; | 1424 metrics->fAvgCharWidth = avgCharWidth * fScale.y(); |
1430 metrics->fDescent = descent * scale; | 1425 metrics->fXMin = xmin * fScale.y(); |
1431 metrics->fBottom = ymin * scale; | 1426 metrics->fXMax = xmax * fScale.y(); |
1432 metrics->fLeading = leading * scale; | |
1433 metrics->fAvgCharWidth = avgCharWidth * scale; | |
1434 metrics->fXMin = xmin * scale; | |
1435 metrics->fXMax = xmax * scale; | |
1436 metrics->fXHeight = x_height; | 1427 metrics->fXHeight = x_height; |
1437 metrics->fCapHeight = cap_height; | 1428 metrics->fCapHeight = cap_height; |
1438 metrics->fUnderlineThickness = underlineThickness * scale; | 1429 metrics->fUnderlineThickness = underlineThickness * fScale.y(); |
1439 metrics->fUnderlinePosition = underlinePosition * scale; | 1430 metrics->fUnderlinePosition = underlinePosition * fScale.y(); |
1440 } | 1431 } |
1441 | 1432 |
1442 /////////////////////////////////////////////////////////////////////////////// | 1433 /////////////////////////////////////////////////////////////////////////////// |
1443 | 1434 |
1444 // hand-tuned value to reduce outline embolden strength | 1435 // hand-tuned value to reduce outline embolden strength |
1445 #ifndef SK_OUTLINE_EMBOLDEN_DIVISOR | 1436 #ifndef SK_OUTLINE_EMBOLDEN_DIVISOR |
1446 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK | 1437 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK |
1447 #define SK_OUTLINE_EMBOLDEN_DIVISOR 34 | 1438 #define SK_OUTLINE_EMBOLDEN_DIVISOR 34 |
1448 #else | 1439 #else |
1449 #define SK_OUTLINE_EMBOLDEN_DIVISOR 24 | 1440 #define SK_OUTLINE_EMBOLDEN_DIVISOR 24 |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1832 SkDEBUGF(("Requested font axis not found: %s '%c%c%c%c'\n", | 1823 SkDEBUGF(("Requested font axis not found: %s '%c%c%c%c'\n", |
1833 name.c_str(), | 1824 name.c_str(), |
1834 (skTag >> 24) & 0xFF, | 1825 (skTag >> 24) & 0xFF, |
1835 (skTag >> 16) & 0xFF, | 1826 (skTag >> 16) & 0xFF, |
1836 (skTag >> 8) & 0xFF, | 1827 (skTag >> 8) & 0xFF, |
1837 (skTag) & 0xFF)); | 1828 (skTag) & 0xFF)); |
1838 } | 1829 } |
1839 } | 1830 } |
1840 ) | 1831 ) |
1841 } | 1832 } |
OLD | NEW |