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, SkArenaAlloc*) override; 49 void generateImage(const SkGlyph& glyph) override; 50 bool generatePath(const SkGlyph& glyph, SkPath* path) override; 51 void generateFontMetrics(SkFontMetrics*) override; 52 53 private: 54 class Offscreen { 55 public: 56 Offscreen(SkColor foregroundColor); 57 58 CGRGBPixel* getCG(const SkScalerContext_Mac& context, const SkGlyph& glyph, 59 CGGlyph glyphID, size_t* rowBytesPtr, bool generateA8FromLCD); 60 61 private: 62 enum { 63 kSize = 32 * 32 * sizeof(CGRGBPixel) 64 }; 65 SkAutoSMalloc<kSize> fImageStorage; 66 SkUniqueCFRef<CGColorSpaceRef> fRGBSpace; 67 68 // cached state 69 SkUniqueCFRef<CGContextRef> fCG; 70 SkUniqueCFRef<CGColorRef> fCGForegroundColor; 71 SkColor fSKForegroundColor; 72 SkISize fSize; 73 bool fDoAA; 74 bool fDoLCD; 75 }; 76 Offscreen fOffscreen; 77 78 /** Unrotated variant of fCTFont. 79 * 80 * In 10.10.1 CTFontGetAdvancesForGlyphs applies the font transform to the width of the 81 * advances, but always sets the height to 0. This font is used to get the advances of the 82 * unrotated glyph, and then the rotation is applied separately. 83 * 84 * CT vertical metrics are pre-rotated (in em space, before transform) 90deg clock-wise. 85 * This makes kCTFontOrientationDefault dangerous, because the metrics from 86 * kCTFontOrientationHorizontal are in a different space from kCTFontOrientationVertical. 87 * With kCTFontOrientationVertical the advances must be unrotated. 88 * 89 * Sometimes, creating a copy of a CTFont with the same size but different trasform will select 90 * different underlying font data. As a result, avoid ever creating more than one CTFont per 91 * SkScalerContext to ensure that only one CTFont is used. 92 * 93 * As a result of the above (and other constraints) this font contains the size, but not the 94 * transform. The transform must always be applied separately. 95 */ 96 SkUniqueCFRef<CTFontRef> fCTFont; 97 98 /** The transform without the font size. */ 99 CGAffineTransform fTransform; 100 CGAffineTransform fInvTransform; 101 102 SkUniqueCFRef<CGFontRef> fCGFont; 103 const bool fDoSubPosition; 104 105 friend class Offscreen; 106 107 using INHERITED = SkScalerContext; 108 }; 109 110 #endif 111 #endif //SkScalerContext_mac_ct_DEFINED 112