| 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 "SkTypes.h" // Keep this before any #ifdef ... | 9 #include "SkTypes.h" // Keep this before any #ifdef ... |
| 10 | 10 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 #include "SkSFNTHeader.h" | 41 #include "SkSFNTHeader.h" |
| 42 #include "SkStream.h" | 42 #include "SkStream.h" |
| 43 #include "SkString.h" | 43 #include "SkString.h" |
| 44 #include "SkTypefaceCache.h" | 44 #include "SkTypefaceCache.h" |
| 45 #include "SkTypeface_mac.h" | 45 #include "SkTypeface_mac.h" |
| 46 #include "SkUtils.h" | 46 #include "SkUtils.h" |
| 47 #include "SkUtils.h" | 47 #include "SkUtils.h" |
| 48 | 48 |
| 49 #include <dlfcn.h> | 49 #include <dlfcn.h> |
| 50 | 50 |
| 51 // Experimental code to use a global lock whenever we access CG, to see if this
reduces |
| 52 // crashes in Chrome |
| 53 #define USE_GLOBAL_MUTEX_FOR_CG_ACCESS |
| 54 |
| 55 #ifdef USE_GLOBAL_MUTEX_FOR_CG_ACCESS |
| 56 static SkMutex gCGMutex; |
| 57 #define AUTO_CG_LOCK() SkAutoMutexAcquire amc(gCGMutex) |
| 58 #else |
| 59 #define AUTO_CG_LOCK() |
| 60 #endif |
| 61 |
| 51 // Set to make glyph bounding boxes visible. | 62 // Set to make glyph bounding boxes visible. |
| 52 #define SK_SHOW_TEXT_BLIT_COVERAGE 0 | 63 #define SK_SHOW_TEXT_BLIT_COVERAGE 0 |
| 53 | 64 |
| 54 class SkScalerContext_Mac; | 65 class SkScalerContext_Mac; |
| 55 | 66 |
| 56 // CTFontManagerCopyAvailableFontFamilyNames() is not always available, so we | 67 // CTFontManagerCopyAvailableFontFamilyNames() is not always available, so we |
| 57 // provide a wrapper here that will return an empty array if need be. | 68 // provide a wrapper here that will return an empty array if need be. |
| 58 static CFArrayRef SkCTFontManagerCopyAvailableFontFamilyNames() { | 69 static CFArrayRef SkCTFontManagerCopyAvailableFontFamilyNames() { |
| 59 #ifdef SK_BUILD_FOR_IOS | 70 #ifdef SK_BUILD_FOR_IOS |
| 60 return CFArrayCreate(NULL, NULL, 0, NULL); | 71 return CFArrayCreate(NULL, NULL, 0, NULL); |
| (...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface, | 717 SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface, |
| 707 const SkDescriptor* desc) | 718 const SkDescriptor* desc) |
| 708 : INHERITED(typeface, desc) | 719 : INHERITED(typeface, desc) |
| 709 , fFBoundingBoxes() | 720 , fFBoundingBoxes() |
| 710 , fFBoundingBoxesGlyphOffset(0) | 721 , fFBoundingBoxesGlyphOffset(0) |
| 711 , fGeneratedFBoundingBoxes(false) | 722 , fGeneratedFBoundingBoxes(false) |
| 712 , fDoSubPosition(SkToBool(fRec.fFlags & kSubpixelPositioning_Flag)) | 723 , fDoSubPosition(SkToBool(fRec.fFlags & kSubpixelPositioning_Flag)) |
| 713 , fVertical(SkToBool(fRec.fFlags & kVertical_Flag)) | 724 , fVertical(SkToBool(fRec.fFlags & kVertical_Flag)) |
| 714 | 725 |
| 715 { | 726 { |
| 727 AUTO_CG_LOCK(); |
| 728 |
| 716 CTFontRef ctFont = typeface->fFontRef.get(); | 729 CTFontRef ctFont = typeface->fFontRef.get(); |
| 717 CFIndex numGlyphs = CTFontGetGlyphCount(ctFont); | 730 CFIndex numGlyphs = CTFontGetGlyphCount(ctFont); |
| 718 SkASSERT(numGlyphs >= 1 && numGlyphs <= 0xFFFF); | 731 SkASSERT(numGlyphs >= 1 && numGlyphs <= 0xFFFF); |
| 719 fGlyphCount = SkToU16(numGlyphs); | 732 fGlyphCount = SkToU16(numGlyphs); |
| 720 | 733 |
| 721 // CT on (at least) 10.9 will size color glyphs down from the requested size
, but not up. | 734 // CT on (at least) 10.9 will size color glyphs down from the requested size
, but not up. |
| 722 // As a result, it is necessary to know the actual device size and request t
hat. | 735 // As a result, it is necessary to know the actual device size and request t
hat. |
| 723 SkVector scale; | 736 SkVector scale; |
| 724 SkMatrix skTransform; | 737 SkMatrix skTransform; |
| 725 fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, &
skTransform, | 738 fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, &
skTransform, |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 978 } | 991 } |
| 979 | 992 |
| 980 return true; | 993 return true; |
| 981 } | 994 } |
| 982 | 995 |
| 983 unsigned SkScalerContext_Mac::generateGlyphCount(void) { | 996 unsigned SkScalerContext_Mac::generateGlyphCount(void) { |
| 984 return fGlyphCount; | 997 return fGlyphCount; |
| 985 } | 998 } |
| 986 | 999 |
| 987 uint16_t SkScalerContext_Mac::generateCharToGlyph(SkUnichar uni) { | 1000 uint16_t SkScalerContext_Mac::generateCharToGlyph(SkUnichar uni) { |
| 1001 AUTO_CG_LOCK(); |
| 1002 |
| 988 CGGlyph cgGlyph[2]; | 1003 CGGlyph cgGlyph[2]; |
| 989 UniChar theChar[2]; // UniChar is a UTF-16 16-bit code unit. | 1004 UniChar theChar[2]; // UniChar is a UTF-16 16-bit code unit. |
| 990 | 1005 |
| 991 // Get the glyph | 1006 // Get the glyph |
| 992 size_t numUniChar = SkUTF16_FromUnichar(uni, theChar); | 1007 size_t numUniChar = SkUTF16_FromUnichar(uni, theChar); |
| 993 SkASSERT(sizeof(CGGlyph) <= sizeof(uint16_t)); | 1008 SkASSERT(sizeof(CGGlyph) <= sizeof(uint16_t)); |
| 994 | 1009 |
| 995 // Undocumented behavior of CTFontGetGlyphsForCharacters with non-bmp code p
oints: | 1010 // Undocumented behavior of CTFontGetGlyphsForCharacters with non-bmp code p
oints: |
| 996 // When a surrogate pair is detected, the glyph index used is the index of t
he high surrogate. | 1011 // When a surrogate pair is detected, the glyph index used is the index of t
he high surrogate. |
| 997 // It is documented that if a mapping is unavailable, the glyph will be set
to 0. | 1012 // It is documented that if a mapping is unavailable, the glyph will be set
to 0. |
| 998 CTFontGetGlyphsForCharacters(fCTFont, theChar, cgGlyph, numUniChar); | 1013 CTFontGetGlyphsForCharacters(fCTFont, theChar, cgGlyph, numUniChar); |
| 999 return cgGlyph[0]; | 1014 return cgGlyph[0]; |
| 1000 } | 1015 } |
| 1001 | 1016 |
| 1002 void SkScalerContext_Mac::generateAdvance(SkGlyph* glyph) { | 1017 void SkScalerContext_Mac::generateAdvance(SkGlyph* glyph) { |
| 1003 this->generateMetrics(glyph); | 1018 this->generateMetrics(glyph); |
| 1004 } | 1019 } |
| 1005 | 1020 |
| 1006 void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) { | 1021 void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) { |
| 1022 AUTO_CG_LOCK(); |
| 1023 |
| 1007 const CGGlyph cgGlyph = (CGGlyph) glyph->getGlyphID(); | 1024 const CGGlyph cgGlyph = (CGGlyph) glyph->getGlyphID(); |
| 1008 glyph->zeroMetrics(); | 1025 glyph->zeroMetrics(); |
| 1009 | 1026 |
| 1010 // The following block produces cgAdvance in CG units (pixels, y up). | 1027 // The following block produces cgAdvance in CG units (pixels, y up). |
| 1011 CGSize cgAdvance; | 1028 CGSize cgAdvance; |
| 1012 if (fVertical) { | 1029 if (fVertical) { |
| 1013 CTFontGetAdvancesForGlyphs(fCTUnrotatedFont, kCTFontVerticalOrientation, | 1030 CTFontGetAdvancesForGlyphs(fCTUnrotatedFont, kCTFontVerticalOrientation, |
| 1014 &cgGlyph, &cgAdvance, 1); | 1031 &cgGlyph, &cgAdvance, 1); |
| 1015 // Vertical advances are returned as widths instead of heights. | 1032 // Vertical advances are returned as widths instead of heights. |
| 1016 SkTSwap(cgAdvance.height, cgAdvance.width); | 1033 SkTSwap(cgAdvance.height, cgAdvance.width); |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1313 } | 1330 } |
| 1314 | 1331 |
| 1315 /* | 1332 /* |
| 1316 * Our subpixel resolution is only 2 bits in each direction, so a scale of 4 | 1333 * Our subpixel resolution is only 2 bits in each direction, so a scale of 4 |
| 1317 * seems sufficient, and possibly even correct, to allow the hinted outline | 1334 * seems sufficient, and possibly even correct, to allow the hinted outline |
| 1318 * to be subpixel positioned. | 1335 * to be subpixel positioned. |
| 1319 */ | 1336 */ |
| 1320 #define kScaleForSubPixelPositionHinting (4.0f) | 1337 #define kScaleForSubPixelPositionHinting (4.0f) |
| 1321 | 1338 |
| 1322 void SkScalerContext_Mac::generatePath(const SkGlyph& glyph, SkPath* path) { | 1339 void SkScalerContext_Mac::generatePath(const SkGlyph& glyph, SkPath* path) { |
| 1340 AUTO_CG_LOCK(); |
| 1341 |
| 1323 CTFontRef font = fCTFont; | 1342 CTFontRef font = fCTFont; |
| 1324 SkScalar scaleX = SK_Scalar1; | 1343 SkScalar scaleX = SK_Scalar1; |
| 1325 SkScalar scaleY = SK_Scalar1; | 1344 SkScalar scaleY = SK_Scalar1; |
| 1326 | 1345 |
| 1327 /* | 1346 /* |
| 1328 * For subpixel positioning, we want to return an unhinted outline, so it | 1347 * For subpixel positioning, we want to return an unhinted outline, so it |
| 1329 * can be positioned nicely at fractional offsets. However, we special-case | 1348 * can be positioned nicely at fractional offsets. However, we special-case |
| 1330 * if the baseline of the (horizontal) text is axis-aligned. In those cases | 1349 * if the baseline of the (horizontal) text is axis-aligned. In those cases |
| 1331 * we want to retain hinting in the direction orthogonal to the baseline. | 1350 * we want to retain hinting in the direction orthogonal to the baseline. |
| 1332 * e.g. for horizontal baseline, we want to retain hinting in Y. | 1351 * e.g. for horizontal baseline, we want to retain hinting in Y. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1376 getVerticalOffset(cgGlyph, &offset); | 1395 getVerticalOffset(cgGlyph, &offset); |
| 1377 path->offset(offset.fX, offset.fY); | 1396 path->offset(offset.fX, offset.fY); |
| 1378 } | 1397 } |
| 1379 } | 1398 } |
| 1380 | 1399 |
| 1381 void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) { | 1400 void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* metrics) { |
| 1382 if (NULL == metrics) { | 1401 if (NULL == metrics) { |
| 1383 return; | 1402 return; |
| 1384 } | 1403 } |
| 1385 | 1404 |
| 1405 AUTO_CG_LOCK(); |
| 1406 |
| 1386 CGRect theBounds = CTFontGetBoundingBox(fCTFont); | 1407 CGRect theBounds = CTFontGetBoundingBox(fCTFont); |
| 1387 | 1408 |
| 1388 metrics->fTop = CGToScalar(-CGRectGetMaxY_inline(theBounds)); | 1409 metrics->fTop = CGToScalar(-CGRectGetMaxY_inline(theBounds)); |
| 1389 metrics->fAscent = CGToScalar(-CTFontGetAscent(fCTFont)); | 1410 metrics->fAscent = CGToScalar(-CTFontGetAscent(fCTFont)); |
| 1390 metrics->fDescent = CGToScalar( CTFontGetDescent(fCTFont)); | 1411 metrics->fDescent = CGToScalar( CTFontGetDescent(fCTFont)); |
| 1391 metrics->fBottom = CGToScalar(-CGRectGetMinY_inline(theBounds)); | 1412 metrics->fBottom = CGToScalar(-CGRectGetMinY_inline(theBounds)); |
| 1392 metrics->fLeading = CGToScalar( CTFontGetLeading(fCTFont)); | 1413 metrics->fLeading = CGToScalar( CTFontGetLeading(fCTFont)); |
| 1393 metrics->fAvgCharWidth = CGToScalar( CGRectGetWidth_inline(theBounds)); | 1414 metrics->fAvgCharWidth = CGToScalar( CGRectGetWidth_inline(theBounds)); |
| 1394 metrics->fXMin = CGToScalar( CGRectGetMinX_inline(theBounds)); | 1415 metrics->fXMin = CGToScalar( CGRectGetMinX_inline(theBounds)); |
| 1395 metrics->fXMax = CGToScalar( CGRectGetMaxX_inline(theBounds)); | 1416 metrics->fXMax = CGToScalar( CGRectGetMaxX_inline(theBounds)); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1537 CFStringGetCString(src, dst->writable_str(), length, kCFStringEncodingUTF8); | 1558 CFStringGetCString(src, dst->writable_str(), length, kCFStringEncodingUTF8); |
| 1538 // Resize to the actual UTF-8 length used, stripping the null character. | 1559 // Resize to the actual UTF-8 length used, stripping the null character. |
| 1539 dst->resize(strlen(dst->c_str())); | 1560 dst->resize(strlen(dst->c_str())); |
| 1540 } | 1561 } |
| 1541 | 1562 |
| 1542 SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( | 1563 SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( |
| 1543 PerGlyphInfo perGlyphInfo, | 1564 PerGlyphInfo perGlyphInfo, |
| 1544 const uint32_t* glyphIDs, | 1565 const uint32_t* glyphIDs, |
| 1545 uint32_t glyphIDsCount) const { | 1566 uint32_t glyphIDsCount) const { |
| 1546 | 1567 |
| 1568 AUTO_CG_LOCK(); |
| 1569 |
| 1547 CTFontRef originalCTFont = fFontRef.get(); | 1570 CTFontRef originalCTFont = fFontRef.get(); |
| 1548 AutoCFRelease<CTFontRef> ctFont(CTFontCreateCopyWithAttributes( | 1571 AutoCFRelease<CTFontRef> ctFont(CTFontCreateCopyWithAttributes( |
| 1549 originalCTFont, CTFontGetUnitsPerEm(originalCTFont), NULL, NULL)); | 1572 originalCTFont, CTFontGetUnitsPerEm(originalCTFont), NULL, NULL)); |
| 1550 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics; | 1573 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics; |
| 1551 | 1574 |
| 1552 { | 1575 { |
| 1553 AutoCFRelease<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont)); | 1576 AutoCFRelease<CFStringRef> fontName(CTFontCopyPostScriptName(ctFont)); |
| 1554 if (fontName.get()) { | 1577 if (fontName.get()) { |
| 1555 CFStringToSkString(fontName, &info->fFontName); | 1578 CFStringToSkString(fontName, &info->fFontName); |
| 1556 } | 1579 } |
| (...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2461 } | 2484 } |
| 2462 return face; | 2485 return face; |
| 2463 } | 2486 } |
| 2464 }; | 2487 }; |
| 2465 | 2488 |
| 2466 /////////////////////////////////////////////////////////////////////////////// | 2489 /////////////////////////////////////////////////////////////////////////////// |
| 2467 | 2490 |
| 2468 SkFontMgr* SkFontMgr::Factory() { | 2491 SkFontMgr* SkFontMgr::Factory() { |
| 2469 return SkNEW(SkFontMgr_Mac); | 2492 return SkNEW(SkFontMgr_Mac); |
| 2470 } | 2493 } |
| OLD | NEW |