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 #ifdef SK_BUILD_FOR_MAC | 9 #ifdef SK_BUILD_FOR_MAC |
10 #import <ApplicationServices/ApplicationServices.h> | 10 #import <ApplicationServices/ApplicationServices.h> |
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 | 668 |
669 /** Converts from FUnits (em space, y up) to SkGlyph units (pixels, y down). | 669 /** Converts from FUnits (em space, y up) to SkGlyph units (pixels, y down). |
670 * | 670 * |
671 * Used on Snow Leopard to correct CTFontGetVerticalTranslationsForGlyphs. | 671 * Used on Snow Leopard to correct CTFontGetVerticalTranslationsForGlyphs. |
672 * Used on Lion to correct CTFontGetBoundingRectsForGlyphs. | 672 * Used on Lion to correct CTFontGetBoundingRectsForGlyphs. |
673 */ | 673 */ |
674 SkMatrix fFUnitMatrix; | 674 SkMatrix fFUnitMatrix; |
675 | 675 |
676 Offscreen fOffscreen; | 676 Offscreen fOffscreen; |
677 AutoCFRelease<CTFontRef> fCTFont; | 677 AutoCFRelease<CTFontRef> fCTFont; |
| 678 CGAffineTransform fTransform; |
678 CGAffineTransform fInvTransform; | 679 CGAffineTransform fInvTransform; |
679 | 680 |
680 /** Unrotated variant of fCTFont. | 681 /** Unrotated variant of fCTFont. |
681 * | 682 * |
682 * In 10.10.1 CTFontGetAdvancesForGlyphs applies the font transform to the
width of the | 683 * In 10.10.1 CTFontGetAdvancesForGlyphs applies the font transform to the
width of the |
683 * advances, but always sets the height to 0. This font is used to get the
advances of the | 684 * advances, but always sets the height to 0. This font is used to get the
advances of the |
684 * unrotated glyph, and then the rotation is applied separately. | 685 * unrotated glyph, and then the rotation is applied separately. |
685 * | 686 * |
686 * CT vertical metrics are pre-rotated (in em space, before transform) 90de
g clock-wise. | 687 * CT vertical metrics are pre-rotated (in em space, before transform) 90de
g clock-wise. |
687 * This makes kCTFontDefaultOrientation dangerous, because the metrics from | 688 * This makes kCTFontDefaultOrientation dangerous, because the metrics from |
(...skipping 29 matching lines...) Expand all Loading... |
717 CFIndex numGlyphs = CTFontGetGlyphCount(ctFont); | 718 CFIndex numGlyphs = CTFontGetGlyphCount(ctFont); |
718 SkASSERT(numGlyphs >= 1 && numGlyphs <= 0xFFFF); | 719 SkASSERT(numGlyphs >= 1 && numGlyphs <= 0xFFFF); |
719 fGlyphCount = SkToU16(numGlyphs); | 720 fGlyphCount = SkToU16(numGlyphs); |
720 | 721 |
721 // CT on (at least) 10.9 will size color glyphs down from the requested size
, but not up. | 722 // 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. | 723 // As a result, it is necessary to know the actual device size and request t
hat. |
723 SkVector scale; | 724 SkVector scale; |
724 SkMatrix skTransform; | 725 SkMatrix skTransform; |
725 fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, &
skTransform, | 726 fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, &
skTransform, |
726 NULL, NULL, &fFUnitMatrix); | 727 NULL, NULL, &fFUnitMatrix); |
727 CGAffineTransform transform = MatrixToCGAffineTransform(skTransform); | 728 fTransform = MatrixToCGAffineTransform(skTransform); |
728 fInvTransform = CGAffineTransformInvert(transform); | 729 fInvTransform = CGAffineTransformInvert(fTransform); |
729 | 730 |
730 AutoCFRelease<CTFontDescriptorRef> ctFontDesc; | 731 AutoCFRelease<CTFontDescriptorRef> ctFontDesc; |
731 if (fVertical) { | 732 if (fVertical) { |
732 // Setting the vertical orientation here affects the character to glyph
mapping. | 733 // Setting the vertical orientation here is required for vertical metric
s on some versions. |
733 AutoCFRelease<CFMutableDictionaryRef> cfAttributes(CFDictionaryCreateMut
able( | 734 AutoCFRelease<CFMutableDictionaryRef> cfAttributes(CFDictionaryCreateMut
able( |
734 kCFAllocatorDefault, 0, | 735 kCFAllocatorDefault, 0, |
735 &kCFTypeDictionaryKeyCallBacks, | 736 &kCFTypeDictionaryKeyCallBacks, |
736 &kCFTypeDictionaryValueCallBacks)); | 737 &kCFTypeDictionaryValueCallBacks)); |
737 if (cfAttributes) { | 738 if (cfAttributes) { |
738 CTFontOrientation ctOrientation = kCTFontVerticalOrientation; | 739 CTFontOrientation ctOrientation = kCTFontVerticalOrientation; |
739 AutoCFRelease<CFNumberRef> cfVertical(CFNumberCreate( | 740 AutoCFRelease<CFNumberRef> cfVertical(CFNumberCreate( |
740 kCFAllocatorDefault, kCFNumberSInt32Type, &ctOrientation)); | 741 kCFAllocatorDefault, kCFNumberSInt32Type, &ctOrientation)); |
741 CFDictionaryAddValue(cfAttributes, kCTFontOrientationAttribute, cfVe
rtical); | 742 CFDictionaryAddValue(cfAttributes, kCTFontOrientationAttribute, cfVe
rtical); |
742 ctFontDesc.reset(CTFontDescriptorCreateWithAttributes(cfAttributes))
; | 743 ctFontDesc.reset(CTFontDescriptorCreateWithAttributes(cfAttributes))
; |
743 } | 744 } |
744 } | 745 } |
745 | 746 |
746 // The transform contains everything except the requested text size. | 747 // The transform contains everything except the requested text size. |
747 // Some properties, like 'trak', are based on the text size (before applying
the matrix). | 748 // Some properties, like 'trak', are based on the text size (before applying
the matrix). |
748 CGFloat textSize = ScalarToCG(scale.y()); | 749 CGFloat textSize = ScalarToCG(scale.y()); |
749 | 750 |
750 fCTFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, &transform, c
tFontDesc)); | 751 fCTFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, &fTransform,
ctFontDesc)); |
751 fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, NULL)); | 752 fCGFont.reset(CTFontCopyGraphicsFont(fCTFont, NULL)); |
752 fCTUnrotatedFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, | 753 fCTUnrotatedFont.reset(CTFontCreateCopyWithAttributes(ctFont, textSize, |
753 &CGAffineTransformIden
tity, NULL)); | 754 &CGAffineTransformIden
tity, NULL)); |
754 | 755 |
755 // The fUnitMatrix includes the text size (and em) as it is used to scale th
e raw font data. | 756 // The fUnitMatrix includes the text size (and em) as it is used to scale th
e raw font data. |
756 SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFo
nt))); | 757 SkScalar emPerFUnit = SkScalarInvert(SkIntToScalar(CGFontGetUnitsPerEm(fCGFo
nt))); |
757 fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit); | 758 fFUnitMatrix.preScale(emPerFUnit, -emPerFUnit); |
758 } | 759 } |
759 | 760 |
760 extern "C" { | 761 extern "C" { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 | 853 |
853 // force our checks below to happen | 854 // force our checks below to happen |
854 fDoAA = !doAA; | 855 fDoAA = !doAA; |
855 fDoLCD = !doLCD; | 856 fDoLCD = !doLCD; |
856 | 857 |
857 if (sk_legacy_CTFontDrawGlyphs == ctFontDrawGlyphs) { | 858 if (sk_legacy_CTFontDrawGlyphs == ctFontDrawGlyphs) { |
858 // CTFontDrawGlyphs will apply the font, font size, and font matrix
to the CGContext. | 859 // CTFontDrawGlyphs will apply the font, font size, and font matrix
to the CGContext. |
859 // Our 'fake' one does not, so set up the CGContext here. | 860 // Our 'fake' one does not, so set up the CGContext here. |
860 CGContextSetFont(fCG, context.fCGFont); | 861 CGContextSetFont(fCG, context.fCGFont); |
861 CGContextSetFontSize(fCG, CTFontGetSize(context.fCTFont)); | 862 CGContextSetFontSize(fCG, CTFontGetSize(context.fCTFont)); |
862 CGContextSetTextMatrix(fCG, CTFontGetMatrix(context.fCTFont)); | |
863 } | 863 } |
| 864 CGContextSetTextMatrix(fCG, context.fTransform); |
864 } | 865 } |
865 | 866 |
866 if (fDoAA != doAA) { | 867 if (fDoAA != doAA) { |
867 CGContextSetShouldAntialias(fCG, doAA); | 868 CGContextSetShouldAntialias(fCG, doAA); |
868 fDoAA = doAA; | 869 fDoAA = doAA; |
869 } | 870 } |
870 if (fDoLCD != doLCD) { | 871 if (fDoLCD != doLCD) { |
871 CGContextSetShouldSmoothFonts(fCG, doLCD); | 872 CGContextSetShouldSmoothFonts(fCG, doLCD); |
872 fDoLCD = doLCD; | 873 fDoLCD = doLCD; |
873 } | 874 } |
(...skipping 14 matching lines...) Expand all Loading... |
888 | 889 |
889 // CoreText and CoreGraphics always draw using the horizontal baseline origi
n. | 890 // CoreText and CoreGraphics always draw using the horizontal baseline origi
n. |
890 if (context.fVertical) { | 891 if (context.fVertical) { |
891 SkPoint offset; | 892 SkPoint offset; |
892 context.getVerticalOffset(glyphID, &offset); | 893 context.getVerticalOffset(glyphID, &offset); |
893 subX += offset.fX; | 894 subX += offset.fX; |
894 subY += offset.fY; | 895 subY += offset.fY; |
895 } | 896 } |
896 | 897 |
897 CGPoint point = CGPointMake(-glyph.fLeft + subX, glyph.fTop + glyph.fHeight
- subY); | 898 CGPoint point = CGPointMake(-glyph.fLeft + subX, glyph.fTop + glyph.fHeight
- subY); |
898 if (darwinVersion() < 14) { | 899 // Prior to 10.10, CTFontDrawGlyphs acted like CGContextShowGlyphsAtPosition
s and took |
899 // Prior to 10.10, CTFontDrawGlyphs acted like CGContextShowGlyphsAtPosi
tions and took | 900 // 'positions' which are in text space. The glyph location (in device space)
must be |
900 // 'positions' which are in text space. The glyph location (in device sp
ace) must be | 901 // mapped into text space, so that CG can convert it back into device space. |
901 // mapped into text space, so that CG can convert it back into device sp
ace. | 902 // In 10.10.1, this is handled directly in CTFontDrawGlyphs. |
902 // In 10.10 and later, this is handled directly in CTFontDrawGlyphs. | 903 |
903 point = CGPointApplyAffineTransform(point, context.fInvTransform); | 904 // However, in 10.10.2 color glyphs no longer rotate based on the font trans
form. |
904 } | 905 // So always make the font transform identity and place the transform on the
context. |
905 ctFontDrawGlyphs(context.fCTFont, &glyphID, &point, 1, fCG); | 906 point = CGPointApplyAffineTransform(point, context.fInvTransform); |
| 907 |
| 908 ctFontDrawGlyphs(context.fCTUnrotatedFont, &glyphID, &point, 1, fCG); |
906 | 909 |
907 SkASSERT(rowBytesPtr); | 910 SkASSERT(rowBytesPtr); |
908 *rowBytesPtr = rowBytes; | 911 *rowBytesPtr = rowBytes; |
909 return image; | 912 return image; |
910 } | 913 } |
911 | 914 |
912 void SkScalerContext_Mac::getVerticalOffset(CGGlyph glyphID, SkPoint* offset) co
nst { | 915 void SkScalerContext_Mac::getVerticalOffset(CGGlyph glyphID, SkPoint* offset) co
nst { |
913 // Snow Leopard returns cgVertOffset in completely un-transformed FUnits (em
space, y up). | 916 // Snow Leopard returns cgVertOffset in completely un-transformed FUnits (em
space, y up). |
914 // Lion and Leopard return cgVertOffset in CG units (pixels, y up). | 917 // Lion and Leopard return cgVertOffset in CG units (pixels, y up). |
915 CGSize cgVertOffset; | 918 CGSize cgVertOffset; |
(...skipping 1365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2281 } | 2284 } |
2282 return face; | 2285 return face; |
2283 } | 2286 } |
2284 }; | 2287 }; |
2285 | 2288 |
2286 /////////////////////////////////////////////////////////////////////////////// | 2289 /////////////////////////////////////////////////////////////////////////////// |
2287 | 2290 |
2288 SkFontMgr* SkFontMgr::Factory() { | 2291 SkFontMgr* SkFontMgr::Factory() { |
2289 return SkNEW(SkFontMgr_Mac); | 2292 return SkNEW(SkFontMgr_Mac); |
2290 } | 2293 } |
OLD | NEW |