xref: /aosp_15_r20/external/skia/src/ports/SkScalerContext_mac_ct.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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