18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkScalerContext_DEFINED
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkScalerContext_DEFINED
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMask.h"
1297efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com#include "SkMaskGamma.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMatrix.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h"
150da48618a758ef46c2174bdc1eaeb6dd8a693a2ereed@google.com#include "SkTypeface.h"
166e502fe0677feaf960e4a37603da3bbeada38389bungeman@google.com
17c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org#ifdef SK_BUILD_FOR_ANDROID
18c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org    #include "SkPaintOptionsAndroid.h"
19c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org#endif
20c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org
21bbe50131413098bffed9186660c41f047d881596bungeman@google.comstruct SkGlyph;
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkDescriptor;
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkMaskFilter;
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkPathEffect;
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkRasterizer;
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
27a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com/*
28a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com *  To allow this to be forward-declared, it must be its own typename, rather
29a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com *  than a nested struct inside SkScalerContext (where it started).
30a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com */
31a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.comstruct SkScalerContextRec {
32a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    uint32_t    fOrigFontID;
33a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    uint32_t    fFontID;
34a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    SkScalar    fTextSize, fPreScaleX, fPreSkewX;
35a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    SkScalar    fPost2x2[2][2];
36a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    SkScalar    fFrameWidth, fMiterLimit;
37fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
38a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    //These describe the parameters to create (uniquely identify) the pre-blend.
39a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    uint32_t    fLumBits;
40a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    uint8_t     fDeviceGamma; //2.6, (0.0, 4.0) gamma, 0.0 for sRGB
41a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    uint8_t     fPaintGamma;  //2.6, (0.0, 4.0) gamma, 0.0 for sRGB
42a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    uint8_t     fContrast;    //0.8+1, [0.0, 1.0] artificial contrast
43a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    uint8_t     fReservedAlign;
44fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
45a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    SkScalar getDeviceGamma() const {
46a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com        return SkIntToScalar(fDeviceGamma) / (1 << 6);
47a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    }
48a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    void setDeviceGamma(SkScalar dg) {
49a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com        SkASSERT(0 <= dg && dg < SkIntToScalar(4));
50a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com        fDeviceGamma = SkScalarFloorToInt(dg * (1 << 6));
51a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    }
52fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
53a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    SkScalar getPaintGamma() const {
54a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com        return SkIntToScalar(fPaintGamma) / (1 << 6);
55a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    }
56a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    void setPaintGamma(SkScalar pg) {
57a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com        SkASSERT(0 <= pg && pg < SkIntToScalar(4));
58a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com        fPaintGamma = SkScalarFloorToInt(pg * (1 << 6));
59a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    }
60fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
61a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    SkScalar getContrast() const {
62a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com        return SkIntToScalar(fContrast) / ((1 << 8) - 1);
63a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    }
64a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    void setContrast(SkScalar c) {
65a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com        SkASSERT(0 <= c && c <= SK_Scalar1);
66a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com        fContrast = SkScalarRoundToInt(c * ((1 << 8) - 1));
67a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    }
68fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
69a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    /**
70a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com     *  Causes the luminance color and contrast to be ignored, and the
71a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com     *  paint and device gamma to be effectively 1.0.
72a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com     */
73a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    void ignorePreBlend() {
74dbfac8a72393eaf01670aeb3244de0e18d8faf98junov@google.com        setLuminanceColor(SK_ColorTRANSPARENT);
75a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com        setPaintGamma(SK_Scalar1);
76a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com        setDeviceGamma(SK_Scalar1);
77a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com        setContrast(0);
78a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    }
79fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
80a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    uint8_t     fMaskFormat;
81a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    uint8_t     fStrokeJoin;
82a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    uint16_t    fFlags;
83a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    // Warning: when adding members note that the size of this structure
84a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    // must be a multiple of 4. SkDescriptor requires that its arguments be
85a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    // multiples of four and this structure is put in an SkDescriptor in
86a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    // SkPaint::MakeRec.
87fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
88a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    void    getMatrixFrom2x2(SkMatrix*) const;
89a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    void    getLocalMatrix(SkMatrix*) const;
90a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    void    getSingleMatrix(SkMatrix*) const;
91fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
92a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    inline SkPaint::Hinting getHinting() const;
93a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    inline void setHinting(SkPaint::Hinting);
94fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
95a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    SkMask::Format getFormat() const {
96a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com        return static_cast<SkMask::Format>(fMaskFormat);
97a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    }
98fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
99a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    SkColor getLuminanceColor() const {
100a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com        return fLumBits;
101a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    }
102fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
103a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    void setLuminanceColor(SkColor c) {
104a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com        fLumBits = c;
105a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    }
106a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com};
107a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com
10897efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com//The following typedef hides from the rest of the implementation the number of
10997efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com//most significant bits to consider when creating mask gamma tables. Two bits
11097efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com//per channel was chosen as a balance between fidelity (more bits) and cache
111fd668cfffe3fdcfbf6e0b858343a62818d337590bungeman@google.com//sizes (fewer bits). Three bits per channel was chosen when #303942; (used by
112fd668cfffe3fdcfbf6e0b858343a62818d337590bungeman@google.com//the Chrome UI) turned out too green.
113fd668cfffe3fdcfbf6e0b858343a62818d337590bungeman@google.comtypedef SkTMaskGamma<3, 3, 3> SkMaskGamma;
11497efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkScalerContext {
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
117a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    typedef SkScalerContextRec Rec;
118a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com
1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    enum Flags {
120b6bb5cb7c2573a9829a0d3aa7b16a55830a7e816reed@google.com        kFrameAndFill_Flag        = 0x0001,
121b6bb5cb7c2573a9829a0d3aa7b16a55830a7e816reed@google.com        kDevKernText_Flag         = 0x0002,
122b6bb5cb7c2573a9829a0d3aa7b16a55830a7e816reed@google.com        kEmbeddedBitmapText_Flag  = 0x0004,
123b6bb5cb7c2573a9829a0d3aa7b16a55830a7e816reed@google.com        kEmbolden_Flag            = 0x0008,
124b6bb5cb7c2573a9829a0d3aa7b16a55830a7e816reed@google.com        kSubpixelPositioning_Flag = 0x0010,
125f6f56878bc96386882721b15ba610984185d3dc9bungeman@google.com        kForceAutohinting_Flag    = 0x0020,  // Use auto instead of bytcode hinting if hinting.
126b6bb5cb7c2573a9829a0d3aa7b16a55830a7e816reed@google.com        kVertical_Flag            = 0x0040,
127ffe49f5380dd5062073efeda70f2f91682c828careed@google.com
128309485b7b51f4cae4c0361ab4da00fe9cc89515cagl@chromium.org        // together, these two flags resulting in a two bit value which matches
129309485b7b51f4cae4c0361ab4da00fe9cc89515cagl@chromium.org        // up with the SkPaint::Hinting enum.
130ffe49f5380dd5062073efeda70f2f91682c828careed@google.com        kHinting_Shift            = 7, // to shift into the other flags above
131b6bb5cb7c2573a9829a0d3aa7b16a55830a7e816reed@google.com        kHintingBit1_Flag         = 0x0080,
132b6bb5cb7c2573a9829a0d3aa7b16a55830a7e816reed@google.com        kHintingBit2_Flag         = 0x0100,
133ffe49f5380dd5062073efeda70f2f91682c828careed@google.com
1340abbff9987b9452fd30cce198bea34fdb210ac41bungeman@google.com        // Pixel geometry information.
1350abbff9987b9452fd30cce198bea34fdb210ac41bungeman@google.com        // only meaningful if fMaskFormat is LCD16 or LCD32
136b6bb5cb7c2573a9829a0d3aa7b16a55830a7e816reed@google.com        kLCD_Vertical_Flag        = 0x0200,    // else Horizontal
137b6bb5cb7c2573a9829a0d3aa7b16a55830a7e816reed@google.com        kLCD_BGROrder_Flag        = 0x0400,    // else RGB order
138ffe49f5380dd5062073efeda70f2f91682c828careed@google.com
1390abbff9987b9452fd30cce198bea34fdb210ac41bungeman@google.com        // Generate A8 from LCD source (for GDI and CoreGraphics).
1400abbff9987b9452fd30cce198bea34fdb210ac41bungeman@google.com        // only meaningful if fMaskFormat is kA8
1410abbff9987b9452fd30cce198bea34fdb210ac41bungeman@google.com        kGenA8FromLCD_Flag        = 0x0800, // could be 0x200 (bit meaning dependent on fMaskFormat)
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
143fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
144ffe49f5380dd5062073efeda70f2f91682c828careed@google.com    // computed values
145e2ca20740b1b3c9e71c085017b64fc9d2f553d93reed@android.com    enum {
146ffe49f5380dd5062073efeda70f2f91682c828careed@google.com        kHinting_Mask   = kHintingBit1_Flag | kHintingBit2_Flag,
147e2ca20740b1b3c9e71c085017b64fc9d2f553d93reed@android.com    };
148ffe49f5380dd5062073efeda70f2f91682c828careed@google.com
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1500da48618a758ef46c2174bdc1eaeb6dd8a693a2ereed@google.com    SkScalerContext(SkTypeface*, const SkDescriptor*);
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual ~SkScalerContext();
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1530da48618a758ef46c2174bdc1eaeb6dd8a693a2ereed@google.com    SkTypeface* getTypeface() const { return fTypeface.get(); }
1540da48618a758ef46c2174bdc1eaeb6dd8a693a2ereed@google.com
15598539c607b05f7e25406ae873bf1b24154a36a6freed@google.com    SkMask::Format getMaskFormat() const {
15698539c607b05f7e25406ae873bf1b24154a36a6freed@google.com        return (SkMask::Format)fRec.fMaskFormat;
15798539c607b05f7e25406ae873bf1b24154a36a6freed@google.com    }
15898539c607b05f7e25406ae873bf1b24154a36a6freed@google.com
159abf00aaaa0262905ad19b0a0ed654c87276490fcreed@google.com    bool isSubpixel() const {
160abf00aaaa0262905ad19b0a0ed654c87276490fcreed@google.com        return SkToBool(fRec.fFlags & kSubpixelPositioning_Flag);
161abf00aaaa0262905ad19b0a0ed654c87276490fcreed@google.com    }
162fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
163a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com    // remember our glyph offset/base
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void setBaseGlyphCount(unsigned baseGlyphCount) {
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fBaseGlyphCount = baseGlyphCount;
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
168a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com    /** Return the corresponding glyph for the specified unichar. Since contexts
169a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com        may be chained (under the hood), the glyphID that is returned may in
170a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com        fact correspond to a different font/context. In that case, we use the
171a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com        base-glyph-count to know how to translate back into local glyph space.
172a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com     */
173ffe49f5380dd5062073efeda70f2f91682c828careed@google.com    uint16_t charToGlyphID(SkUnichar uni);
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1759d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com    /** Map the glyphID to its glyph index, and then to its char code. Unmapped
1769d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com        glyphs return zero.
1779d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com    */
1789d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com    SkUnichar glyphIDToChar(uint16_t glyphID);
1799d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com
1800bc7bf5fe418191473f8325d89dd9e74be3ff928ctguil@chromium.org    unsigned    getGlyphCount() { return this->generateGlyphCount(); }
1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void        getAdvance(SkGlyph*);
1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void        getMetrics(SkGlyph*);
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void        getImage(const SkGlyph&);
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void        getPath(const SkGlyph&, SkPath*);
1850a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com    void        getFontMetrics(SkPaint::FontMetrics*);
1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1872d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    /** Return the size in bytes of the associated gamma lookup table
1882d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth     */
1892d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    static size_t GetGammaLUTSize(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma,
1902d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                  int* width, int* height);
1912d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
1922d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    /** Get the associated gamma lookup table. The 'data' pointer must point to pre-allocated
1932d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        memory, with size in bytes greater than or equal to the return value of getGammaLUTSize().
1942d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth     */
1952d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    static void   GetGammaLUTData(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma,
1962d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                  void* data);
1972d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
19860abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
19960abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com    unsigned getBaseGlyphCount(SkUnichar charCode);
20015eeca00684b4d5baad8e47c5b2f77404b978cb0djsollen@google.com
20115eeca00684b4d5baad8e47c5b2f77404b978cb0djsollen@google.com    // This function must be public for SkTypeface_android.h, but should not be
20215eeca00684b4d5baad8e47c5b2f77404b978cb0djsollen@google.com    // called by other callers
2034bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com    SkFontID findTypefaceIdForChar(SkUnichar uni);
20460abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com#endif
20560abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com
206eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    static void MakeRec(const SkPaint&, const SkDeviceProperties* deviceProperties,
207eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org                        const SkMatrix*, Rec* rec);
20897efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com    static inline void PostMakeRec(const SkPaint&, Rec*);
20910d2d4d1062ef56526f187e6716c5e747689b598reed@google.com
21097efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com    static SkMaskGamma::PreBlend GetMaskPreBlend(const Rec& rec);
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected:
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Rec         fRec;
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned    fBaseGlyphCount;
2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
216d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    /** Generates the contents of glyph.fAdvanceX and glyph.fAdvanceY.
217d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  May call getMetrics if that would be just as fast.
218d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     */
219d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    virtual void generateAdvance(SkGlyph* glyph) = 0;
220d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com
221d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    /** Generates the contents of glyph.fWidth, fHeight, fTop, fLeft,
222d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  as well as fAdvanceX and fAdvanceY if not already set.
223d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *
224d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  TODO: fMaskFormat is set by getMetrics later; cannot be set here.
225d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     */
226d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    virtual void generateMetrics(SkGlyph* glyph) = 0;
227d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com
228d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    /** Generates the contents of glyph.fImage.
229d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  When called, glyph.fImage will be pointing to a pre-allocated,
230d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  uninitialized region of memory of size glyph.computeImageSize().
231d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  This method may change glyph.fMaskFormat if the new image size is
232d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  less than or equal to the old image size.
233d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *
234d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  Because glyph.computeImageSize() will determine the size of fImage,
235d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  generateMetrics will be called before generateImage.
236d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     */
237d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    virtual void generateImage(const SkGlyph& glyph) = 0;
238d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com
239d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    /** Sets the passed path to the glyph outline.
240d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  If this cannot be done the path is set to empty;
241d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  this is indistinguishable from a glyph with an empty path.
242d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  This does not set glyph.fPath.
243d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *
244d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  TODO: path is always glyph.fPath, no reason to pass separately.
245d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     */
246d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    virtual void generatePath(const SkGlyph& glyph, SkPath* path) = 0;
247d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com
248d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    /** Retrieves font metrics.
249d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  TODO: there is now a vertical bit, no need for two parameters.
250d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     */
2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                     SkPaint::FontMetrics* mY) = 0;
253d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com
254d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    /** Returns the number of glyphs in the font. */
255d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    virtual unsigned generateGlyphCount() = 0;
256d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com
257d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    /** Returns the glyph id for the given unichar.
258d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  If there is no 1:1 mapping from the unichar to a glyph id, returns 0.
259d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     */
260d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    virtual uint16_t generateCharToGlyph(SkUnichar unichar) = 0;
261d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com
262d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    /** Returns the unichar for the given glyph id.
263d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  If there is no 1:1 mapping from the glyph id to a unichar, returns 0.
264d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     *  The default implementation always returns 0, indicating failure.
265d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com     */
266d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com    virtual SkUnichar generateGlyphToChar(uint16_t glyphId);
2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
268a767fa06ca28be9df1ff6e08a299e0bec839a2dcreed@google.com    void forceGenerateImageFromPath() { fGenerateImageFromPath = true; }
269a767fa06ca28be9df1ff6e08a299e0bec839a2dcreed@google.com
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
2710da48618a758ef46c2174bdc1eaeb6dd8a693a2ereed@google.com    // never null
2720da48618a758ef46c2174bdc1eaeb6dd8a693a2ereed@google.com    SkAutoTUnref<SkTypeface> fTypeface;
27301c34ee59906f729f6ca7d35f0c0e5e2f5e693feskia.committer@gmail.com
274c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org#ifdef SK_BUILD_FOR_ANDROID
275c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org    SkPaintOptionsAndroid fPaintOptionsAndroid;
276c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org#endif
277c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org
2780da48618a758ef46c2174bdc1eaeb6dd8a693a2ereed@google.com    // optional object, which may be null
2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPathEffect*   fPathEffect;
2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkMaskFilter*   fMaskFilter;
2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkRasterizer*   fRasterizer;
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
283a767fa06ca28be9df1ff6e08a299e0bec839a2dcreed@google.com    // if this is set, we draw the image from a path, rather than
284a767fa06ca28be9df1ff6e08a299e0bec839a2dcreed@google.com    // calling generateImage.
285a767fa06ca28be9df1ff6e08a299e0bec839a2dcreed@google.com    bool fGenerateImageFromPath;
286a767fa06ca28be9df1ff6e08a299e0bec839a2dcreed@google.com
2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                         SkPath* devPath, SkMatrix* fillToDevMatrix);
2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
290a45bcc802229ba5e128d8ae7528b41219507970areed@google.com    // Return the context associated with the next logical typeface, or NULL if
291a45bcc802229ba5e128d8ae7528b41219507970areed@google.com    // there are no more entries in the fallback chain.
292a45bcc802229ba5e128d8ae7528b41219507970areed@google.com    SkScalerContext* allocNextContext() const;
293a45bcc802229ba5e128d8ae7528b41219507970areed@google.com
294a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com    // return the next context, treating fNextContext as a cache of the answer
295a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com    SkScalerContext* getNextContext();
2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
297a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com    // returns the right context from our link-list for this glyph. If no match
298a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com    // is found, just returns the original context (this)
299a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com    SkScalerContext* getGlyphContext(const SkGlyph& glyph);
300a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com
3014bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com    // returns the right context from our link-list for this char. If no match
3024bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com    // is found it returns NULL. If a match is found then the glyphID param is
3034bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com    // set to the glyphID that maps to the provided char.
3044bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com    SkScalerContext* getContextFromChar(SkUnichar uni, uint16_t* glyphID);
3054bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com
306a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com    // link-list of context, to handle missing chars. null-terminated.
307a14ea0e930c82daa2364ece4bd0b06256272302areed@android.com    SkScalerContext* fNextContext;
30897efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com
309a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com    // SkMaskGamma::PreBlend converts linear masks to gamma correcting masks.
310a76de72a6036da0a6b051b14411b80941971f881bungeman@google.comprotected:
311a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com    // Visible to subclasses so that generateImage can apply the pre-blend directly.
312a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com    const SkMaskGamma::PreBlend fPreBlend;
313a76de72a6036da0a6b051b14411b80941971f881bungeman@google.comprivate:
314a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com    // When there is a filter, previous steps must create a linear mask
315a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com    // and the pre-blend applied as a final step.
316a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com    const SkMaskGamma::PreBlend fPreBlendForFilter;
3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kRec_SkDescriptorTag            SkSetFourByteTag('s', 'r', 'e', 'c')
3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kPathEffect_SkDescriptorTag     SkSetFourByteTag('p', 't', 'h', 'e')
3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kMaskFilter_SkDescriptorTag     SkSetFourByteTag('m', 's', 'k', 'f')
3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define kRasterizer_SkDescriptorTag     SkSetFourByteTag('r', 'a', 's', 't')
323c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org#ifdef SK_BUILD_FOR_ANDROID
324c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org#define kAndroidOpts_SkDescriptorTag    SkSetFourByteTag('a', 'n', 'd', 'r')
325c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org#endif
3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
327cb6ccdde5120ec45df208c0b958b263d8252a505reed@google.com///////////////////////////////////////////////////////////////////////////////
328cb6ccdde5120ec45df208c0b958b263d8252a505reed@google.com
329cb6ccdde5120ec45df208c0b958b263d8252a505reed@google.comenum SkAxisAlignment {
330cb6ccdde5120ec45df208c0b958b263d8252a505reed@google.com    kNone_SkAxisAlignment,
331cb6ccdde5120ec45df208c0b958b263d8252a505reed@google.com    kX_SkAxisAlignment,
332cb6ccdde5120ec45df208c0b958b263d8252a505reed@google.com    kY_SkAxisAlignment
333cb6ccdde5120ec45df208c0b958b263d8252a505reed@google.com};
334cb6ccdde5120ec45df208c0b958b263d8252a505reed@google.com
335cb6ccdde5120ec45df208c0b958b263d8252a505reed@google.com/**
336cb6ccdde5120ec45df208c0b958b263d8252a505reed@google.com *  Return the axis (if any) that the baseline for horizontal text will land on
337cb6ccdde5120ec45df208c0b958b263d8252a505reed@google.com *  after running through the specified matrix.
338cb6ccdde5120ec45df208c0b958b263d8252a505reed@google.com *
339cb6ccdde5120ec45df208c0b958b263d8252a505reed@google.com *  As an example, the identity matrix will return kX_SkAxisAlignment
340cb6ccdde5120ec45df208c0b958b263d8252a505reed@google.com */
3412e68478d8654c8a4048b45ad16ac039dadb25c33reed@google.comSkAxisAlignment SkComputeAxisAlignmentForHText(const SkMatrix& matrix);
342cb6ccdde5120ec45df208c0b958b263d8252a505reed@google.com
343a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com///////////////////////////////////////////////////////////////////////////////
344a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com
345a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.comSkPaint::Hinting SkScalerContextRec::getHinting() const {
346a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    unsigned hint = (fFlags & SkScalerContext::kHinting_Mask) >>
347a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com                                            SkScalerContext::kHinting_Shift;
348a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    return static_cast<SkPaint::Hinting>(hint);
349a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com}
350a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com
351a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.comvoid SkScalerContextRec::setHinting(SkPaint::Hinting hinting) {
352a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com    fFlags = (fFlags & ~SkScalerContext::kHinting_Mask) |
353a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com                                (hinting << SkScalerContext::kHinting_Shift);
354a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com}
355a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com
356a9d4e84c435f61be3c02d7f54acab973e8b7761creed@google.com
3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
358