1/*
2 * Copyright 2014 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 SkFont_DEFINED
9#define SkFont_DEFINED
10
11#include "SkRefCnt.h"
12#include "SkScalar.h"
13
14class SkPaint;
15class SkTypeface;
16
17enum SkTextEncoding {
18    kUTF8_SkTextEncoding,
19    kUTF16_SkTextEncoding,
20    kUTF32_SkTextEncoding,
21    kGlyphID_SkTextEncoding,
22};
23
24/*
25 1. The Hinting enum in SkPaint is gone entirely, absorbed into SkFont's flags.
26
27 2. SkPaint Flags look like this today
28
29 enum Flags {
30     kAntiAlias_Flag       = 0x01,   //!< mask to enable antialiasing
31     kDither_Flag          = 0x04,   //!< mask to enable dithering
32     kUnderlineText_Flag   = 0x08,   //!< mask to enable underline text
33     kStrikeThruText_Flag  = 0x10,   //!< mask to enable strike-thru text
34     kFakeBoldText_Flag    = 0x20,   //!< mask to enable fake-bold text
35     kLinearText_Flag      = 0x40,   //!< mask to enable linear-text
36     kSubpixelText_Flag    = 0x80,   //!< mask to enable subpixel text positioning
37     kDevKernText_Flag     = 0x100,  //!< mask to enable device kerning text
38     kLCDRenderText_Flag   = 0x200,  //!< mask to enable subpixel glyph renderering
39     kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes
40     kAutoHinting_Flag     = 0x800,  //!< mask to force Freetype's autohinter
41     kVerticalText_Flag    = 0x1000,
42     kGenA8FromLCD_Flag    = 0x2000, // hack for GDI -- do not use if you can help it
43 };
44
45 SkFont would absorb these:
46
47     kFakeBoldText_Flag    = 0x20,   //!< mask to enable fake-bold text
48     kLinearText_Flag      = 0x40,   //!< mask to enable linear-text
49     kSubpixelText_Flag    = 0x80,   //!< mask to enable subpixel text positioning
50     kDevKernText_Flag     = 0x100,  //!< mask to enable device kerning text
51     kLCDRenderText_Flag   = 0x200,  //!< mask to enable subpixel glyph renderering
52     kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes
53     kAutoHinting_Flag     = 0x800,  //!< mask to force Freetype's autohinter
54     kVerticalText_Flag    = 0x1000,
55     kGenA8FromLCD_Flag    = 0x2000, // hack for GDI -- do not use if you can help it
56
57 leaving these still in paint
58
59     kAntiAlias_Flag       = 0x01,   //!< mask to enable antialiasing
60     kDither_Flag          = 0x04,   //!< mask to enable dithering
61     kUnderlineText_Flag   = 0x08,   //!< mask to enable underline text
62     kStrikeThruText_Flag  = 0x10,   //!< mask to enable strike-thru text
63
64 3. Antialiasing
65
66    SkFont has a mask-type: BW, AA, LCD
67    SkPaint has antialias boolean
68
69    What to do if the font's mask-type disagrees with the paint?
70
71 */
72
73class SkFont : public SkRefCnt {
74public:
75    enum Flags {
76        /**
77         *  Use the system's automatic hinting mechanism to hint the typeface.
78         *  This is a last resort hinting method applied only if other hinting methods do not apply.
79         *  TODO: where to put auto-normal vs auto-light?
80         */
81        kEnableAutoHints_Flag       = 1 << 0,
82
83        /**
84         *  If the typeface contains explicit bytecodes for hinting, use them.
85         *  If both bytecode and auto hints are specified, attempt to use the bytecodes first;
86         *  if that fails (e.g. there are no codes), then attempt to autohint.
87         */
88        kEnableByteCodeHints_Flag   = 1 << 1,
89
90        /**
91         *  If the typeface contains explicit bitmaps for hinting, use them.
92         *  If both bytecode and auto hints are also specified, attempt to use the bitmaps first;
93         *  if that fails (e.g. there are no bitmaps), then attempt to bytecode or autohint.
94         */
95        kEmbeddedBitmaps_Flag       = 1 << 2,
96
97        /**
98         *  Use rounded metric values (e.g. advance).
99         *  If either auto or bytecode hinting was used, apply those results to the metrics of the
100         *  glyphs as well. If no hinting was applied, the metrics will just be rounded to the
101         *  nearest integer.
102         *
103         *  This applies to calls that return metrics (e.g. measureText) and to drawing the glyphs
104         *  (see SkCanvas drawText and drawPosText).
105         */
106        kUseNonlinearMetrics_Flag   = 1 << 3,
107
108        kVertical_Flag              = 1 << 4,
109        kGenA8FromLCD_Flag          = 1 << 5,
110        kEmbolden_Flag              = 1 << 6,
111        kDevKern_Flag               = 1 << 7,   // ifdef ANDROID ?
112    };
113
114    enum MaskType {
115        kBW_MaskType,
116        kA8_MaskType,
117        kLCD_MaskType,
118    };
119
120    static sk_sp<SkFont> Make(sk_sp<SkTypeface>, SkScalar size, MaskType, uint32_t flags);
121    static sk_sp<SkFont> Make(sk_sp<SkTypeface>, SkScalar size, SkScalar scaleX, SkScalar skewX,
122                              MaskType, uint32_t flags);
123
124    /**
125     *  Return a font with the same attributes of this font, but with the specified size.
126     *  If size is not supported (e.g. <= 0 or non-finite) NULL will be returned.
127     */
128    sk_sp<SkFont> makeWithSize(SkScalar size) const;
129    /**
130     *  Return a font with the same attributes of this font, but with the flags.
131     */
132    sk_sp<SkFont> makeWithFlags(uint32_t newFlags) const;
133
134    SkTypeface* getTypeface() const { return fTypeface.get(); }
135    SkScalar    getSize() const { return fSize; }
136    SkScalar    getScaleX() const { return fScaleX; }
137    SkScalar    getSkewX() const { return fSkewX; }
138    uint32_t    getFlags() const { return fFlags; }
139    MaskType    getMaskType() const { return (MaskType)fMaskType; }
140
141    bool isVertical() const { return SkToBool(fFlags & kVertical_Flag); }
142    bool isEmbolden() const { return SkToBool(fFlags & kEmbolden_Flag); }
143    bool isEnableAutoHints() const { return SkToBool(fFlags & kEnableAutoHints_Flag); }
144    bool isEnableByteCodeHints() const { return SkToBool(fFlags & kEnableByteCodeHints_Flag); }
145    bool isUseNonLinearMetrics() const { return SkToBool(fFlags & kUseNonlinearMetrics_Flag); }
146    bool isDevKern() const { return SkToBool(fFlags & kDevKern_Flag); }
147
148    int textToGlyphs(const void* text, size_t byteLength, SkTextEncoding,
149                     SkGlyphID glyphs[], int maxGlyphCount) const;
150
151    int countText(const void* text, size_t byteLength, SkTextEncoding encoding) {
152        return this->textToGlyphs(text, byteLength, encoding, nullptr, 0);
153    }
154
155    SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding) const;
156
157    static sk_sp<SkFont> Testing_CreateFromPaint(const SkPaint&);
158
159private:
160    enum {
161        kAllFlags = 0xFF,
162    };
163
164    SkFont(sk_sp<SkTypeface>, SkScalar size, SkScalar scaleX, SkScalar skewX, MaskType,
165           uint32_t flags);
166
167    sk_sp<SkTypeface> fTypeface;
168    SkScalar    fSize;
169    SkScalar    fScaleX;
170    SkScalar    fSkewX;
171    uint16_t    fFlags;
172    uint8_t     fMaskType;
173//  uint8_t     fPad;
174};
175
176#endif
177