summaryrefslogtreecommitdiffstats
path: root/gfx/skia/skia/src/ports/SkScalerContext_mac_ct.h
blob: be034bd2c77ef29b959e5c01a9defb915dbd2e7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
 * Copyright 2020 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkScalerContext_mac_ct_DEFINED
#define SkScalerContext_mac_ct_DEFINED

#include "include/core/SkTypes.h"
#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)

#include "include/core/SkRefCnt.h"
#include "include/core/SkSize.h"
#include "src/base/SkAutoMalloc.h"
#include "src/core/SkScalerContext.h"
#include "src/utils/mac/SkUniqueCFRef.h"

#ifdef SK_BUILD_FOR_MAC
#import <ApplicationServices/ApplicationServices.h>
#endif

#ifdef SK_BUILD_FOR_IOS
#include <CoreText/CoreText.h>
#include <CoreText/CTFontManager.h>
#include <CoreGraphics/CoreGraphics.h>
#include <CoreFoundation/CoreFoundation.h>
#endif

#include <memory>

class SkDescriptor;
class SkGlyph;
class SkPath;
class SkTypeface_Mac;
struct SkFontMetrics;


typedef uint32_t CGRGBPixel;

class SkScalerContext_Mac : public SkScalerContext {
public:
    SkScalerContext_Mac(sk_sp<SkTypeface_Mac>, const SkScalerContextEffects&, const SkDescriptor*);

protected:
    bool generateAdvance(SkGlyph* glyph) override;
    void generateMetrics(SkGlyph* glyph, SkArenaAlloc*) override;
    void generateImage(const SkGlyph& glyph) override;
    bool generatePath(const SkGlyph& glyph, SkPath* path) override;
    void generateFontMetrics(SkFontMetrics*) override;

private:
    class Offscreen {
    public:
        Offscreen(SkColor foregroundColor);

        CGRGBPixel* getCG(const SkScalerContext_Mac& context, const SkGlyph& glyph,
                          CGGlyph glyphID, size_t* rowBytesPtr, bool generateA8FromLCD,
                          bool lightOnDark);

    private:
        enum {
            kSize = 32 * 32 * sizeof(CGRGBPixel)
        };
        SkAutoSMalloc<kSize> fImageStorage;
        SkUniqueCFRef<CGColorSpaceRef> fRGBSpace;

        // cached state
        SkUniqueCFRef<CGContextRef> fCG;
        SkUniqueCFRef<CGColorRef> fCGForegroundColor;
        SkColor fSKForegroundColor;
        SkISize fSize;
        bool fDoAA;
        bool fDoLCD;
    };
    Offscreen fOffscreen;

    /** Unrotated variant of fCTFont.
     *
     *  In 10.10.1 CTFontGetAdvancesForGlyphs applies the font transform to the width of the
     *  advances, but always sets the height to 0. This font is used to get the advances of the
     *  unrotated glyph, and then the rotation is applied separately.
     *
     *  CT vertical metrics are pre-rotated (in em space, before transform) 90deg clock-wise.
     *  This makes kCTFontOrientationDefault dangerous, because the metrics from
     *  kCTFontOrientationHorizontal are in a different space from kCTFontOrientationVertical.
     *  With kCTFontOrientationVertical the advances must be unrotated.
     *
     *  Sometimes, creating a copy of a CTFont with the same size but different trasform will select
     *  different underlying font data. As a result, avoid ever creating more than one CTFont per
     *  SkScalerContext to ensure that only one CTFont is used.
     *
     *  As a result of the above (and other constraints) this font contains the size, but not the
     *  transform. The transform must always be applied separately.
     */
    SkUniqueCFRef<CTFontRef> fCTFont;

    /** The transform without the font size. */
    CGAffineTransform fTransform;
    CGAffineTransform fInvTransform;

    SkUniqueCFRef<CGFontRef> fCGFont;
    const bool fDoSubPosition;

    friend class Offscreen;

    using INHERITED = SkScalerContext;
};

#endif
#endif //SkScalerContext_mac_ct_DEFINED