Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkScalerContext.h
1 /*
2  * Copyright 2006 The Android Open Source Project
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_DEFINED
9 #define SkScalerContext_DEFINED
10
11 #include "SkMask.h"
12 #include "SkMaskGamma.h"
13 #include "SkMatrix.h"
14 #include "SkPaint.h"
15 #include "SkTypeface.h"
16
17 struct SkGlyph;
18 class SkDescriptor;
19 class SkMaskFilter;
20 class SkPathEffect;
21 class SkRasterizer;
22
23 /*
24  *  To allow this to be forward-declared, it must be its own typename, rather
25  *  than a nested struct inside SkScalerContext (where it started).
26  */
27 struct SkScalerContextRec {
28     uint32_t    fFontID;
29     SkScalar    fTextSize, fPreScaleX, fPreSkewX;
30     SkScalar    fPost2x2[2][2];
31     SkScalar    fFrameWidth, fMiterLimit;
32
33     //These describe the parameters to create (uniquely identify) the pre-blend.
34     uint32_t    fLumBits;
35     uint8_t     fDeviceGamma; //2.6, (0.0, 4.0) gamma, 0.0 for sRGB
36     uint8_t     fPaintGamma;  //2.6, (0.0, 4.0) gamma, 0.0 for sRGB
37     uint8_t     fContrast;    //0.8+1, [0.0, 1.0] artificial contrast
38     uint8_t     fReservedAlign;
39
40     SkScalar getDeviceGamma() const {
41         return SkIntToScalar(fDeviceGamma) / (1 << 6);
42     }
43     void setDeviceGamma(SkScalar dg) {
44         SkASSERT(0 <= dg && dg < SkIntToScalar(4));
45         fDeviceGamma = SkScalarFloorToInt(dg * (1 << 6));
46     }
47
48     SkScalar getPaintGamma() const {
49         return SkIntToScalar(fPaintGamma) / (1 << 6);
50     }
51     void setPaintGamma(SkScalar pg) {
52         SkASSERT(0 <= pg && pg < SkIntToScalar(4));
53         fPaintGamma = SkScalarFloorToInt(pg * (1 << 6));
54     }
55
56     SkScalar getContrast() const {
57         return SkIntToScalar(fContrast) / ((1 << 8) - 1);
58     }
59     void setContrast(SkScalar c) {
60         SkASSERT(0 <= c && c <= SK_Scalar1);
61         fContrast = SkScalarRoundToInt(c * ((1 << 8) - 1));
62     }
63
64     /**
65      *  Causes the luminance color and contrast to be ignored, and the
66      *  paint and device gamma to be effectively 1.0.
67      */
68     void ignorePreBlend() {
69         setLuminanceColor(SK_ColorTRANSPARENT);
70         setPaintGamma(SK_Scalar1);
71         setDeviceGamma(SK_Scalar1);
72         setContrast(0);
73     }
74
75     uint8_t     fMaskFormat;
76     uint8_t     fStrokeJoin;
77     uint16_t    fFlags;
78     // Warning: when adding members note that the size of this structure
79     // must be a multiple of 4. SkDescriptor requires that its arguments be
80     // multiples of four and this structure is put in an SkDescriptor in
81     // SkPaint::MakeRec.
82
83     void    getMatrixFrom2x2(SkMatrix*) const;
84     void    getLocalMatrix(SkMatrix*) const;
85     void    getSingleMatrix(SkMatrix*) const;
86
87     inline SkPaint::Hinting getHinting() const;
88     inline void setHinting(SkPaint::Hinting);
89
90     SkMask::Format getFormat() const {
91         return static_cast<SkMask::Format>(fMaskFormat);
92     }
93
94     SkColor getLuminanceColor() const {
95         return fLumBits;
96     }
97
98     void setLuminanceColor(SkColor c) {
99         fLumBits = c;
100     }
101 };
102
103 //The following typedef hides from the rest of the implementation the number of
104 //most significant bits to consider when creating mask gamma tables. Two bits
105 //per channel was chosen as a balance between fidelity (more bits) and cache
106 //sizes (fewer bits). Three bits per channel was chosen when #303942; (used by
107 //the Chrome UI) turned out too green.
108 typedef SkTMaskGamma<3, 3, 3> SkMaskGamma;
109
110 class SkScalerContext {
111 public:
112     typedef SkScalerContextRec Rec;
113
114     enum Flags {
115         kFrameAndFill_Flag        = 0x0001,
116         kDevKernText_Flag         = 0x0002,
117         kEmbeddedBitmapText_Flag  = 0x0004,
118         kEmbolden_Flag            = 0x0008,
119         kSubpixelPositioning_Flag = 0x0010,
120         kForceAutohinting_Flag    = 0x0020,  // Use auto instead of bytcode hinting if hinting.
121         kVertical_Flag            = 0x0040,
122
123         // together, these two flags resulting in a two bit value which matches
124         // up with the SkPaint::Hinting enum.
125         kHinting_Shift            = 7, // to shift into the other flags above
126         kHintingBit1_Flag         = 0x0080,
127         kHintingBit2_Flag         = 0x0100,
128
129         // Pixel geometry information.
130         // only meaningful if fMaskFormat is LCD16 or LCD32
131         kLCD_Vertical_Flag        = 0x0200,    // else Horizontal
132         kLCD_BGROrder_Flag        = 0x0400,    // else RGB order
133
134         // Generate A8 from LCD source (for GDI and CoreGraphics).
135         // only meaningful if fMaskFormat is kA8
136         kGenA8FromLCD_Flag        = 0x0800, // could be 0x200 (bit meaning dependent on fMaskFormat)
137     };
138
139     // computed values
140     enum {
141         kHinting_Mask   = kHintingBit1_Flag | kHintingBit2_Flag,
142     };
143
144
145     SkScalerContext(SkTypeface*, const SkDescriptor*);
146     virtual ~SkScalerContext();
147
148     SkTypeface* getTypeface() const { return fTypeface.get(); }
149
150     SkMask::Format getMaskFormat() const {
151         return (SkMask::Format)fRec.fMaskFormat;
152     }
153
154     bool isSubpixel() const {
155         return SkToBool(fRec.fFlags & kSubpixelPositioning_Flag);
156     }
157
158     bool isVertical() const {
159         return SkToBool(fRec.fFlags & kVertical_Flag);
160     }
161
162     /** Return the corresponding glyph for the specified unichar. Since contexts
163         may be chained (under the hood), the glyphID that is returned may in
164         fact correspond to a different font/context. In that case, we use the
165         base-glyph-count to know how to translate back into local glyph space.
166      */
167     uint16_t charToGlyphID(SkUnichar uni) {
168         return generateCharToGlyph(uni);
169     }
170
171     /** Map the glyphID to its glyph index, and then to its char code. Unmapped
172         glyphs return zero.
173     */
174     SkUnichar glyphIDToChar(uint16_t glyphID) {
175         return (glyphID < getGlyphCount()) ? generateGlyphToChar(glyphID) : 0;
176     }
177
178     unsigned    getGlyphCount() { return this->generateGlyphCount(); }
179     void        getAdvance(SkGlyph*);
180     void        getMetrics(SkGlyph*);
181     void        getImage(const SkGlyph&);
182     void        getPath(const SkGlyph&, SkPath*);
183     void        getFontMetrics(SkPaint::FontMetrics*);
184
185     /** Return the size in bytes of the associated gamma lookup table
186      */
187     static size_t GetGammaLUTSize(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma,
188                                   int* width, int* height);
189
190     /** Get the associated gamma lookup table. The 'data' pointer must point to pre-allocated
191         memory, with size in bytes greater than or equal to the return value of getGammaLUTSize().
192      */
193     static void   GetGammaLUTData(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma,
194                                   void* data);
195
196     static void MakeRec(const SkPaint&, const SkDeviceProperties* deviceProperties,
197                         const SkMatrix*, Rec* rec);
198     static inline void PostMakeRec(const SkPaint&, Rec*);
199
200     static SkMaskGamma::PreBlend GetMaskPreBlend(const Rec& rec);
201
202 protected:
203     Rec         fRec;
204
205     /** Generates the contents of glyph.fAdvanceX and glyph.fAdvanceY.
206      *  May call getMetrics if that would be just as fast.
207      */
208     virtual void generateAdvance(SkGlyph* glyph) = 0;
209
210     /** Generates the contents of glyph.fWidth, fHeight, fTop, fLeft,
211      *  as well as fAdvanceX and fAdvanceY if not already set.
212      *
213      *  TODO: fMaskFormat is set by getMetrics later; cannot be set here.
214      */
215     virtual void generateMetrics(SkGlyph* glyph) = 0;
216
217     /** Generates the contents of glyph.fImage.
218      *  When called, glyph.fImage will be pointing to a pre-allocated,
219      *  uninitialized region of memory of size glyph.computeImageSize().
220      *  This method may change glyph.fMaskFormat if the new image size is
221      *  less than or equal to the old image size.
222      *
223      *  Because glyph.computeImageSize() will determine the size of fImage,
224      *  generateMetrics will be called before generateImage.
225      */
226     virtual void generateImage(const SkGlyph& glyph) = 0;
227
228     /** Sets the passed path to the glyph outline.
229      *  If this cannot be done the path is set to empty;
230      *  this is indistinguishable from a glyph with an empty path.
231      *  This does not set glyph.fPath.
232      *
233      *  TODO: path is always glyph.fPath, no reason to pass separately.
234      */
235     virtual void generatePath(const SkGlyph& glyph, SkPath* path) = 0;
236
237     /** Retrieves font metrics. */
238     virtual void generateFontMetrics(SkPaint::FontMetrics*) = 0;
239
240     /** Returns the number of glyphs in the font. */
241     virtual unsigned generateGlyphCount() = 0;
242
243     /** Returns the glyph id for the given unichar.
244      *  If there is no 1:1 mapping from the unichar to a glyph id, returns 0.
245      */
246     virtual uint16_t generateCharToGlyph(SkUnichar unichar) = 0;
247
248     /** Returns the unichar for the given glyph id.
249      *  If there is no 1:1 mapping from the glyph id to a unichar, returns 0.
250      *  The default implementation always returns 0, indicating failure.
251      */
252     virtual SkUnichar generateGlyphToChar(uint16_t glyphId);
253
254     void forceGenerateImageFromPath() { fGenerateImageFromPath = true; }
255
256 private:
257     // never null
258     SkAutoTUnref<SkTypeface> fTypeface;
259
260     // optional object, which may be null
261     SkPathEffect*   fPathEffect;
262     SkMaskFilter*   fMaskFilter;
263     SkRasterizer*   fRasterizer;
264
265     // if this is set, we draw the image from a path, rather than
266     // calling generateImage.
267     bool fGenerateImageFromPath;
268
269     void internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
270                          SkPath* devPath, SkMatrix* fillToDevMatrix);
271
272     // returns the right context from our link-list for this char. If no match
273     // is found it returns NULL. If a match is found then the glyphID param is
274     // set to the glyphID that maps to the provided char.
275     SkScalerContext* getContextFromChar(SkUnichar uni, uint16_t* glyphID);
276
277     // SkMaskGamma::PreBlend converts linear masks to gamma correcting masks.
278 protected:
279     // Visible to subclasses so that generateImage can apply the pre-blend directly.
280     const SkMaskGamma::PreBlend fPreBlend;
281 private:
282     // When there is a filter, previous steps must create a linear mask
283     // and the pre-blend applied as a final step.
284     const SkMaskGamma::PreBlend fPreBlendForFilter;
285 };
286
287 #define kRec_SkDescriptorTag            SkSetFourByteTag('s', 'r', 'e', 'c')
288 #define kPathEffect_SkDescriptorTag     SkSetFourByteTag('p', 't', 'h', 'e')
289 #define kMaskFilter_SkDescriptorTag     SkSetFourByteTag('m', 's', 'k', 'f')
290 #define kRasterizer_SkDescriptorTag     SkSetFourByteTag('r', 'a', 's', 't')
291
292 ///////////////////////////////////////////////////////////////////////////////
293
294 enum SkAxisAlignment {
295     kNone_SkAxisAlignment,
296     kX_SkAxisAlignment,
297     kY_SkAxisAlignment
298 };
299
300 /**
301  *  Return the axis (if any) that the baseline for horizontal text will land on
302  *  after running through the specified matrix.
303  *
304  *  As an example, the identity matrix will return kX_SkAxisAlignment
305  */
306 SkAxisAlignment SkComputeAxisAlignmentForHText(const SkMatrix& matrix);
307
308 ///////////////////////////////////////////////////////////////////////////////
309
310 SkPaint::Hinting SkScalerContextRec::getHinting() const {
311     unsigned hint = (fFlags & SkScalerContext::kHinting_Mask) >>
312                                             SkScalerContext::kHinting_Shift;
313     return static_cast<SkPaint::Hinting>(hint);
314 }
315
316 void SkScalerContextRec::setHinting(SkPaint::Hinting hinting) {
317     fFlags = (fFlags & ~SkScalerContext::kHinting_Mask) |
318                                 (hinting << SkScalerContext::kHinting_Shift);
319 }
320
321
322 #endif