1 /* 2 * Copyright 2020 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkScalerContext_mac_ct_DEFINED 9 #define SkScalerContext_mac_ct_DEFINED 10 11 #include "include/core/SkTypes.h" 12 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 13 14 #include "include/core/SkRefCnt.h" 15 #include "include/core/SkSize.h" 16 #include "src/core/SkAutoMalloc.h" 17 #include "src/core/SkScalerContext.h" 18 #include "src/utils/mac/SkUniqueCFRef.h" 19 20 #ifdef SK_BUILD_FOR_MAC 21 #import <ApplicationServices/ApplicationServices.h> 22 #endif 23 24 #ifdef SK_BUILD_FOR_IOS 25 #include <CoreText/CoreText.h> 26 #include <CoreText/CTFontManager.h> 27 #include <CoreGraphics/CoreGraphics.h> 28 #include <CoreFoundation/CoreFoundation.h> 29 #endif 30 31 #include <memory> 32 33 class SkDescriptor; 34 class SkGlyph; 35 class SkPath; 36 class SkTypeface_Mac; 37 struct SkFontMetrics; 38 39 40 typedef uint32_t CGRGBPixel; 41 42 class SkScalerContext_Mac : public SkScalerContext { 43 public: 44 SkScalerContext_Mac(sk_sp<SkTypeface_Mac>, const SkScalerContextEffects&, const SkDescriptor*); 45 46 protected: 47 bool generateAdvance(SkGlyph* glyph) override; 48 void generateMetrics(SkGlyph* glyph) override; 49 void generateImage(const SkGlyph& glyph) override; 50 bool generatePath(SkGlyphID glyph, SkPath* path) override; 51 void generateFontMetrics(SkFontMetrics*) override; 52 53 private: 54 class Offscreen { 55 public: Offscreen()56 Offscreen() 57 : fRGBSpace(nullptr) 58 , fCG(nullptr) 59 , fDoAA(false) 60 , fDoLCD(false) 61 { 62 fSize.set(0, 0); 63 } 64 65 CGRGBPixel* getCG(const SkScalerContext_Mac& context, const SkGlyph& glyph, 66 CGGlyph glyphID, size_t* rowBytesPtr, bool generateA8FromLCD); 67 68 private: 69 enum { 70 kSize = 32 * 32 * sizeof(CGRGBPixel) 71 }; 72 SkAutoSMalloc<kSize> fImageStorage; 73 SkUniqueCFRef<CGColorSpaceRef> fRGBSpace; 74 75 // cached state 76 SkUniqueCFRef<CGContextRef> fCG; 77 SkISize fSize; 78 bool fDoAA; 79 bool fDoLCD; 80 }; 81 Offscreen fOffscreen; 82 83 /** Unrotated variant of fCTFont. 84 * 85 * In 10.10.1 CTFontGetAdvancesForGlyphs applies the font transform to the width of the 86 * advances, but always sets the height to 0. This font is used to get the advances of the 87 * unrotated glyph, and then the rotation is applied separately. 88 * 89 * CT vertical metrics are pre-rotated (in em space, before transform) 90deg clock-wise. 90 * This makes kCTFontOrientationDefault dangerous, because the metrics from 91 * kCTFontOrientationHorizontal are in a different space from kCTFontOrientationVertical. 92 * With kCTFontOrientationVertical the advances must be unrotated. 93 * 94 * Sometimes, creating a copy of a CTFont with the same size but different trasform will select 95 * different underlying font data. As a result, avoid ever creating more than one CTFont per 96 * SkScalerContext to ensure that only one CTFont is used. 97 * 98 * As a result of the above (and other constraints) this font contains the size, but not the 99 * transform. The transform must always be applied separately. 100 */ 101 SkUniqueCFRef<CTFontRef> fCTFont; 102 103 /** The transform without the font size. */ 104 CGAffineTransform fTransform; 105 CGAffineTransform fInvTransform; 106 107 SkUniqueCFRef<CGFontRef> fCGFont; 108 const bool fDoSubPosition; 109 110 friend class Offscreen; 111 112 using INHERITED = SkScalerContext; 113 }; 114 115 #endif 116 #endif //SkScalerContext_mac_ct_DEFINED 117