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