• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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