• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SkPaint_DEFINED
18 #define SkPaint_DEFINED
19 
20 #include "SkColor.h"
21 #include "SkMath.h"
22 #include "SkXfermode.h"
23 
24 class SkAutoGlyphCache;
25 class SkColorFilter;
26 class SkDescriptor;
27 class SkFlattenableReadBuffer;
28 class SkFlattenableWriteBuffer;
29 struct SkGlyph;
30 struct SkRect;
31 class SkGlyphCache;
32 class SkMaskFilter;
33 class SkMatrix;
34 class SkPath;
35 class SkPathEffect;
36 class SkRasterizer;
37 class SkShader;
38 class SkDrawLooper;
39 class SkTypeface;
40 
41 typedef const SkGlyph& (*SkDrawCacheProc)(SkGlyphCache*, const char**,
42                                            SkFixed x, SkFixed y);
43 
44 typedef const SkGlyph& (*SkMeasureCacheProc)(SkGlyphCache*, const char**);
45 
46 /** \class SkPaint
47 
48     The SkPaint class holds the style and color information about how to draw
49     geometries, text and bitmaps.
50 */
51 class SkPaint {
52 public:
53     SkPaint();
54     SkPaint(const SkPaint& paint);
55     ~SkPaint();
56 
57     SkPaint& operator=(const SkPaint&);
58 
59     friend int operator==(const SkPaint& a, const SkPaint& b);
60     friend int operator!=(const SkPaint& a, const SkPaint& b)
61     {
62         return !(a == b);
63     }
64 
65     void flatten(SkFlattenableWriteBuffer&) const;
66     void unflatten(SkFlattenableReadBuffer&);
67 
68     /** Restores the paint to its initial settings.
69     */
70     void reset();
71 
72     /** Specifies the level of hinting to be performed. These names are taken
73         from the Gnome/Cairo names for the same. They are translated into
74         Freetype concepts the same as in cairo-ft-font.c:
75            kNo_Hinting     -> FT_LOAD_NO_HINTING
76            kSlight_Hinting -> FT_LOAD_TARGET_LIGHT
77            kNormal_Hinting -> <default, no option>
78            kFull_Hinting   -> <same as kNormalHinting, unless we are rendering
79                               subpixel glyphs, in which case TARGET_LCD or
80                               TARGET_LCD_V is used>
81     */
82     enum Hinting {
83         kNo_Hinting            = 0,
84         kSlight_Hinting        = 1,
85         kNormal_Hinting        = 2,     //!< this is the default
86         kFull_Hinting          = 3,
87     };
88 
getHinting()89     Hinting getHinting() const
90     {
91         return static_cast<Hinting>(fHinting);
92     }
93 
setHinting(Hinting hintingLevel)94     void setHinting(Hinting hintingLevel)
95     {
96         fHinting = hintingLevel;
97     }
98 
99     /** Specifies the bit values that are stored in the paint's flags.
100     */
101     enum Flags {
102         kAntiAlias_Flag       = 0x01,   //!< mask to enable antialiasing
103         kFilterBitmap_Flag    = 0x02,   //!< mask to enable bitmap filtering
104         kDither_Flag          = 0x04,   //!< mask to enable dithering
105         kUnderlineText_Flag   = 0x08,   //!< mask to enable underline text
106         kStrikeThruText_Flag  = 0x10,   //!< mask to enable strike-thru text
107         kFakeBoldText_Flag    = 0x20,   //!< mask to enable fake-bold text
108         kLinearText_Flag      = 0x40,   //!< mask to enable linear-text
109         kSubpixelText_Flag    = 0x80,   //!< mask to enable subpixel text positioning
110         kDevKernText_Flag     = 0x100,  //!< mask to enable device kerning text
111         kLCDRenderText_Flag   = 0x200,  //!< mask to enable subpixel glyph renderering
112         // when adding extra flags, note that the fFlags member is specified
113         // with a bit-width and you'll have to expand it.
114 
115         kAllFlags = 0x3FF
116     };
117 
118     /** Return the paint's flags. Use the Flag enum to test flag values.
119         @return the paint's flags (see enums ending in _Flag for bit masks)
120     */
getFlags()121     uint32_t getFlags() const { return fFlags; }
122 
123     /** Set the paint's flags. Use the Flag enum to specific flag values.
124         @param flags    The new flag bits for the paint (see Flags enum)
125     */
126     void setFlags(uint32_t flags);
127 
128     /** Helper for getFlags(), returning true if kAntiAlias_Flag bit is set
129         @return true if the antialias bit is set in the paint's flags.
130         */
isAntiAlias()131     bool isAntiAlias() const
132     {
133         return SkToBool(this->getFlags() & kAntiAlias_Flag);
134     }
135 
136     /** Helper for setFlags(), setting or clearing the kAntiAlias_Flag bit
137         @param aa   true to enable antialiasing, false to disable it
138         */
139     void setAntiAlias(bool aa);
140 
141     /** Helper for getFlags(), returning true if kDither_Flag bit is set
142         @return true if the dithering bit is set in the paint's flags.
143         */
isDither()144     bool isDither() const
145     {
146         return SkToBool(this->getFlags() & kDither_Flag);
147     }
148 
149     /** Helper for setFlags(), setting or clearing the kDither_Flag bit
150         @param dither   true to enable dithering, false to disable it
151         */
152     void setDither(bool dither);
153 
154     /** Helper for getFlags(), returning true if kLinearText_Flag bit is set
155         @return true if the lineartext bit is set in the paint's flags
156     */
isLinearText()157     bool isLinearText() const
158     {
159         return SkToBool(this->getFlags() & kLinearText_Flag);
160     }
161 
162     /** Helper for setFlags(), setting or clearing the kLinearText_Flag bit
163         @param linearText true to set the linearText bit in the paint's flags,
164                           false to clear it.
165     */
166     void setLinearText(bool linearText);
167 
168     /** Helper for getFlags(), returning true if kSubpixelText_Flag bit is set
169         @return true if the lineartext bit is set in the paint's flags
170     */
isSubpixelText()171     bool isSubpixelText() const
172     {
173         return SkToBool(this->getFlags() & kSubpixelText_Flag);
174     }
175 
176     /** Helper for setFlags(), setting or clearing the kSubpixelText_Flag
177        bit @param subpixelText true to set the subpixelText bit in the paint's flags,
178                                false to clear it.
179     */
180     void setSubpixelText(bool subpixelText);
181 
isLCDRenderText()182     bool isLCDRenderText() const
183     {
184         return SkToBool(this->getFlags() & kLCDRenderText_Flag);
185     }
186 
187     /** Helper for setFlags(), setting or clearing the kLCDRenderText_Flag bit
188         @param subpixelRender true to set the subpixelRenderText bit in the paint's flags,
189                               false to clear it.
190     */
191     void setLCDRenderText(bool subpixelRender);
192 
193     /** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set
194         @return true if the underlineText bit is set in the paint's flags.
195     */
isUnderlineText()196     bool isUnderlineText() const
197     {
198         return SkToBool(this->getFlags() & kUnderlineText_Flag);
199     }
200 
201     /** Helper for setFlags(), setting or clearing the kUnderlineText_Flag bit
202         @param underlineText true to set the underlineText bit in the paint's
203                              flags, false to clear it.
204     */
205     void setUnderlineText(bool underlineText);
206 
207     /** Helper for getFlags(), returns true if kStrikeThruText_Flag bit is set
208         @return true if the strikeThruText bit is set in the paint's flags.
209     */
isStrikeThruText()210     bool    isStrikeThruText() const
211     {
212         return SkToBool(this->getFlags() & kStrikeThruText_Flag);
213     }
214 
215     /** Helper for setFlags(), setting or clearing the kStrikeThruText_Flag bit
216         @param strikeThruText   true to set the strikeThruText bit in the
217                                 paint's flags, false to clear it.
218     */
219     void setStrikeThruText(bool strikeThruText);
220 
221     /** Helper for getFlags(), returns true if kFakeBoldText_Flag bit is set
222         @return true if the kFakeBoldText_Flag bit is set in the paint's flags.
223     */
isFakeBoldText()224     bool isFakeBoldText() const
225     {
226         return SkToBool(this->getFlags() & kFakeBoldText_Flag);
227     }
228 
229     /** Helper for setFlags(), setting or clearing the kFakeBoldText_Flag bit
230         @param fakeBoldText true to set the kFakeBoldText_Flag bit in the paint's
231                             flags, false to clear it.
232     */
233     void setFakeBoldText(bool fakeBoldText);
234 
235     /** Helper for getFlags(), returns true if kDevKernText_Flag bit is set
236         @return true if the kernText bit is set in the paint's flags.
237     */
isDevKernText()238     bool isDevKernText() const
239     {
240         return SkToBool(this->getFlags() & kDevKernText_Flag);
241     }
242 
243     /** Helper for setFlags(), setting or clearing the kKernText_Flag bit
244         @param kernText true to set the kKernText_Flag bit in the paint's
245                             flags, false to clear it.
246     */
247     void setDevKernText(bool devKernText);
248 
isFilterBitmap()249     bool isFilterBitmap() const
250     {
251         return SkToBool(this->getFlags() & kFilterBitmap_Flag);
252     }
253 
254     void setFilterBitmap(bool filterBitmap);
255 
256     /** Styles apply to rect, oval, path, and text.
257         Bitmaps are always drawn in "fill", and lines are always drawn in
258         "stroke".
259 
260         Note: strokeandfill implicitly draws the result with
261         SkPath::kWinding_FillType, so if the original path is even-odd, the
262         results may not appear the same as if it was drawn twice, filled and
263         then stroked.
264     */
265     enum Style {
266         kFill_Style,            //!< fill the geometry
267         kStroke_Style,          //!< stroke the geometry
268         kStrokeAndFill_Style,   //!< fill and stroke the geometry
269 
270         kStyleCount,
271     };
272 
273     /** Return the paint's style, used for controlling how primitives'
274         geometries are interpreted (except for drawBitmap, which always assumes
275         kFill_Style).
276         @return the paint's Style
277     */
getStyle()278     Style getStyle() const { return (Style)fStyle; }
279 
280     /** Set the paint's style, used for controlling how primitives'
281         geometries are interpreted (except for drawBitmap, which always assumes
282         Fill).
283         @param style    The new style to set in the paint
284     */
285     void setStyle(Style style);
286 
287     /** Return the paint's color. Note that the color is a 32bit value
288         containing alpha as well as r,g,b. This 32bit value is not
289         premultiplied, meaning that its alpha can be any value, regardless of
290         the values of r,g,b.
291         @return the paint's color (and alpha).
292     */
getColor()293     SkColor getColor() const { return fColor; }
294 
295     /** Set the paint's color. Note that the color is a 32bit value containing
296         alpha as well as r,g,b. This 32bit value is not premultiplied, meaning
297         that its alpha can be any value, regardless of the values of r,g,b.
298         @param color    The new color (including alpha) to set in the paint.
299     */
300     void setColor(SkColor color);
301 
302     /** Helper to getColor() that just returns the color's alpha value.
303         @return the alpha component of the paint's color.
304         */
getAlpha()305     uint8_t getAlpha() const { return SkToU8(SkColorGetA(fColor)); }
306 
307     /** Helper to setColor(), that only assigns the color's alpha value,
308         leaving its r,g,b values unchanged.
309         @param a    set the alpha component (0..255) of the paint's color.
310     */
311     void setAlpha(U8CPU a);
312 
313     /** Helper to setColor(), that takes a,r,g,b and constructs the color value
314         using SkColorSetARGB()
315         @param a    The new alpha component (0..255) of the paint's color.
316         @param r    The new red component (0..255) of the paint's color.
317         @param g    The new green component (0..255) of the paint's color.
318         @param b    The new blue component (0..255) of the paint's color.
319     */
320     void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
321 
322     /** Return the width for stroking.
323         <p />
324         A value of 0 strokes in hairline mode.
325         Hairlines always draw 1-pixel wide, regardless of the matrix.
326         @return the paint's stroke width, used whenever the paint's style is
327                 Stroke or StrokeAndFill.
328     */
getStrokeWidth()329     SkScalar getStrokeWidth() const { return fWidth; }
330 
331     /** Set the width for stroking.
332         Pass 0 to stroke in hairline mode.
333         Hairlines always draw 1-pixel wide, regardless of the matrix.
334         @param width set the paint's stroke width, used whenever the paint's
335                      style is Stroke or StrokeAndFill.
336     */
337     void setStrokeWidth(SkScalar width);
338 
339     /** Return the paint's stroke miter value. This is used to control the
340         behavior of miter joins when the joins angle is sharp.
341         @return the paint's miter limit, used whenever the paint's style is
342                 Stroke or StrokeAndFill.
343     */
getStrokeMiter()344     SkScalar getStrokeMiter() const { return fMiterLimit; }
345 
346     /** Set the paint's stroke miter value. This is used to control the
347         behavior of miter joins when the joins angle is sharp. This value must
348         be >= 0.
349         @param miter    set the miter limit on the paint, used whenever the
350                         paint's style is Stroke or StrokeAndFill.
351     */
352     void setStrokeMiter(SkScalar miter);
353 
354     /** Cap enum specifies the settings for the paint's strokecap. This is the
355         treatment that is applied to the beginning and end of each non-closed
356         contour (e.g. lines).
357     */
358     enum Cap {
359         kButt_Cap,      //!< begin/end contours with no extension
360         kRound_Cap,     //!< begin/end contours with a semi-circle extension
361         kSquare_Cap,    //!< begin/end contours with a half square extension
362 
363         kCapCount,
364         kDefault_Cap = kButt_Cap
365     };
366 
367     /** Join enum specifies the settings for the paint's strokejoin. This is
368         the treatment that is applied to corners in paths and rectangles.
369     */
370     enum Join {
371         kMiter_Join,    //!< connect path segments with a sharp join
372         kRound_Join,    //!< connect path segments with a round join
373         kBevel_Join,    //!< connect path segments with a flat bevel join
374 
375         kJoinCount,
376         kDefault_Join = kMiter_Join
377     };
378 
379     /** Return the paint's stroke cap type, controlling how the start and end
380         of stroked lines and paths are treated.
381         @return the line cap style for the paint, used whenever the paint's
382                 style is Stroke or StrokeAndFill.
383     */
getStrokeCap()384     Cap getStrokeCap() const { return (Cap)fCapType; }
385 
386     /** Set the paint's stroke cap type.
387         @param cap  set the paint's line cap style, used whenever the paint's
388                     style is Stroke or StrokeAndFill.
389     */
390     void setStrokeCap(Cap cap);
391 
392     /** Return the paint's stroke join type.
393         @return the paint's line join style, used whenever the paint's style is
394                 Stroke or StrokeAndFill.
395     */
getStrokeJoin()396     Join getStrokeJoin() const { return (Join)fJoinType; }
397 
398     /** Set the paint's stroke join type.
399         @param join set the paint's line join style, used whenever the paint's
400                     style is Stroke or StrokeAndFill.
401     */
402     void setStrokeJoin(Join join);
403 
404     /** Applies any/all effects (patheffect, stroking) to src, returning the
405         result in dst. The result is that drawing src with this paint will be
406         the same as drawing dst with a default paint (at least from the
407         geometric perspective).
408         @param src  input path
409         @param dst  output path (may be the same as src)
410         @return     true if the path should be filled, or false if it should be
411                     drawn with a hairline (width == 0)
412     */
413     bool getFillPath(const SkPath& src, SkPath* dst) const;
414 
415     /** Returns true if the current paint settings allow for fast computation of
416         bounds (i.e. there is nothing complex like a patheffect that would make
417         the bounds computation expensive.
418     */
canComputeFastBounds()419     bool canComputeFastBounds() const {
420         // use bit-or since no need for early exit
421         return (reinterpret_cast<uintptr_t>(this->getMaskFilter()) |
422                 reinterpret_cast<uintptr_t>(this->getLooper()) |
423                 reinterpret_cast<uintptr_t>(this->getRasterizer()) |
424                 reinterpret_cast<uintptr_t>(this->getPathEffect())) == 0;
425     }
426 
427     /** Only call this if canComputeFastBounds() returned true. This takes a
428         raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
429         effects in the paint (e.g. stroking). If needed, it uses the storage
430         rect parameter. It returns the adjusted bounds that can then be used
431         for quickReject tests.
432 
433         The returned rect will either be orig or storage, thus the caller
434         should not rely on storage being set to the result, but should always
435         use the retured value. It is legal for orig and storage to be the same
436         rect.
437 
438         e.g.
439         if (paint.canComputeFastBounds()) {
440             SkRect r, storage;
441             path.computeBounds(&r, SkPath::kFast_BoundsType);
442             const SkRect& fastR = paint.computeFastBounds(r, &storage);
443             if (canvas->quickReject(fastR, ...)) {
444                 // don't draw the path
445             }
446         }
447     */
computeFastBounds(const SkRect & orig,SkRect * storage)448     const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
449         return this->getStyle() == kFill_Style ? orig :
450                     this->computeStrokeFastBounds(orig, storage);
451     }
452 
453     /** Get the paint's shader object.
454         <p />
455       The shader's reference count is not affected.
456         @return the paint's shader (or NULL)
457     */
getShader()458     SkShader* getShader() const { return fShader; }
459 
460     /** Set or clear the shader object.
461         <p />
462         Pass NULL to clear any previous shader.
463         As a convenience, the parameter passed is also returned.
464         If a previous shader exists, its reference count is decremented.
465         If shader is not NULL, its reference count is incremented.
466         @param shader   May be NULL. The shader to be installed in the paint
467         @return         shader
468     */
469     SkShader* setShader(SkShader* shader);
470 
471     /** Get the paint's colorfilter. If there is a colorfilter, its reference
472         count is not changed.
473         @return the paint's colorfilter (or NULL)
474     */
getColorFilter()475     SkColorFilter* getColorFilter() const { return fColorFilter; }
476 
477     /** Set or clear the paint's colorfilter, returning the parameter.
478         <p />
479         If the paint already has a filter, its reference count is decremented.
480         If filter is not NULL, its reference count is incremented.
481         @param filter   May be NULL. The filter to be installed in the paint
482         @return         filter
483     */
484     SkColorFilter* setColorFilter(SkColorFilter* filter);
485 
486     /** Get the paint's xfermode object.
487         <p />
488       The xfermode's reference count is not affected.
489         @return the paint's xfermode (or NULL)
490     */
getXfermode()491     SkXfermode* getXfermode() const { return fXfermode; }
492 
493     /** Set or clear the xfermode object.
494         <p />
495         Pass NULL to clear any previous xfermode.
496         As a convenience, the parameter passed is also returned.
497         If a previous xfermode exists, its reference count is decremented.
498         If xfermode is not NULL, its reference count is incremented.
499         @param xfermode May be NULL. The new xfermode to be installed in the
500                         paint
501         @return         xfermode
502     */
503     SkXfermode* setXfermode(SkXfermode* xfermode);
504 
505     /** Create an xfermode based on the specified Mode, and assign it into the
506         paint, returning the mode that was set. If the Mode is SrcOver, then
507         the paint's xfermode is set to null.
508      */
509     SkXfermode* setXfermodeMode(SkXfermode::Mode);
510 
511     /** Get the paint's patheffect object.
512         <p />
513       The patheffect reference count is not affected.
514         @return the paint's patheffect (or NULL)
515     */
getPathEffect()516     SkPathEffect* getPathEffect() const { return fPathEffect; }
517 
518     /** Set or clear the patheffect object.
519         <p />
520         Pass NULL to clear any previous patheffect.
521         As a convenience, the parameter passed is also returned.
522         If a previous patheffect exists, its reference count is decremented.
523         If patheffect is not NULL, its reference count is incremented.
524         @param effect   May be NULL. The new patheffect to be installed in the
525                         paint
526         @return         effect
527     */
528     SkPathEffect* setPathEffect(SkPathEffect* effect);
529 
530     /** Get the paint's maskfilter object.
531         <p />
532       The maskfilter reference count is not affected.
533         @return the paint's maskfilter (or NULL)
534     */
getMaskFilter()535     SkMaskFilter* getMaskFilter() const { return fMaskFilter; }
536 
537     /** Set or clear the maskfilter object.
538         <p />
539         Pass NULL to clear any previous maskfilter.
540         As a convenience, the parameter passed is also returned.
541         If a previous maskfilter exists, its reference count is decremented.
542         If maskfilter is not NULL, its reference count is incremented.
543         @param maskfilter   May be NULL. The new maskfilter to be installed in
544                             the paint
545         @return             maskfilter
546     */
547     SkMaskFilter* setMaskFilter(SkMaskFilter* maskfilter);
548 
549     // These attributes are for text/fonts
550 
551     /** Get the paint's typeface object.
552         <p />
553         The typeface object identifies which font to use when drawing or
554         measuring text. The typeface reference count is not affected.
555         @return the paint's typeface (or NULL)
556     */
getTypeface()557     SkTypeface* getTypeface() const { return fTypeface; }
558 
559     /** Set or clear the typeface object.
560         <p />
561         Pass NULL to clear any previous typeface.
562         As a convenience, the parameter passed is also returned.
563         If a previous typeface exists, its reference count is decremented.
564         If typeface is not NULL, its reference count is incremented.
565         @param typeface May be NULL. The new typeface to be installed in the
566                         paint
567         @return         typeface
568     */
569     SkTypeface* setTypeface(SkTypeface* typeface);
570 
571     /** Get the paint's rasterizer (or NULL).
572         <p />
573         The raster controls how paths/text are turned into alpha masks.
574         @return the paint's rasterizer (or NULL)
575     */
getRasterizer()576     SkRasterizer* getRasterizer() const { return fRasterizer; }
577 
578     /** Set or clear the rasterizer object.
579         <p />
580         Pass NULL to clear any previous rasterizer.
581         As a convenience, the parameter passed is also returned.
582         If a previous rasterizer exists in the paint, its reference count is
583         decremented. If rasterizer is not NULL, its reference count is
584         incremented.
585         @param rasterizer May be NULL. The new rasterizer to be installed in
586                           the paint.
587         @return           rasterizer
588     */
589     SkRasterizer* setRasterizer(SkRasterizer* rasterizer);
590 
getLooper()591     SkDrawLooper* getLooper() const { return fLooper; }
592     SkDrawLooper* setLooper(SkDrawLooper*);
593 
594     enum Align {
595         kLeft_Align,
596         kCenter_Align,
597         kRight_Align,
598 
599         kAlignCount
600     };
601     /** Return the paint's Align value for drawing text.
602         @return the paint's Align value for drawing text.
603     */
getTextAlign()604     Align   getTextAlign() const { return (Align)fTextAlign; }
605     /** Set the paint's text alignment.
606         @param align set the paint's Align value for drawing text.
607     */
608     void    setTextAlign(Align align);
609 
610     /** Return the paint's text size.
611         @return the paint's text size.
612     */
getTextSize()613     SkScalar getTextSize() const { return fTextSize; }
614 
615     /** Set the paint's text size. This value must be > 0
616         @param textSize set the paint's text size.
617     */
618     void setTextSize(SkScalar textSize);
619 
620     /** Return the paint's horizontal scale factor for text. The default value
621         is 1.0.
622         @return the paint's scale factor in X for drawing/measuring text
623     */
getTextScaleX()624     SkScalar getTextScaleX() const { return fTextScaleX; }
625 
626     /** Set the paint's horizontal scale factor for text. The default value
627         is 1.0. Values > 1.0 will stretch the text wider. Values < 1.0 will
628         stretch the text narrower.
629         @param scaleX   set the paint's scale factor in X for drawing/measuring
630                         text.
631     */
632     void setTextScaleX(SkScalar scaleX);
633 
634     /** Return the paint's horizontal skew factor for text. The default value
635         is 0.
636         @return the paint's skew factor in X for drawing text.
637     */
getTextSkewX()638     SkScalar getTextSkewX() const { return fTextSkewX; }
639 
640     /** Set the paint's horizontal skew factor for text. The default value
641         is 0. For approximating oblique text, use values around -0.25.
642         @param skewX set the paint's skew factor in X for drawing text.
643     */
644     void setTextSkewX(SkScalar skewX);
645 
646     /** Describes how to interpret the text parameters that are passed to paint
647         methods like measureText() and getTextWidths().
648     */
649     enum TextEncoding {
650         kUTF8_TextEncoding,     //!< the text parameters are UTF8
651         kUTF16_TextEncoding,    //!< the text parameters are UTF16
652         kGlyphID_TextEncoding   //!< the text parameters are glyph indices
653     };
654 
getTextEncoding()655     TextEncoding getTextEncoding() const
656     {
657         return (TextEncoding)fTextEncoding;
658     }
659 
660     void setTextEncoding(TextEncoding encoding);
661 
662     struct FontMetrics {
663         SkScalar    fTop;       //!< The greatest distance above the baseline for any glyph (will be <= 0)
664         SkScalar    fAscent;    //!< The recommended distance above the baseline (will be <= 0)
665         SkScalar    fDescent;   //!< The recommended distance below the baseline (will be >= 0)
666         SkScalar    fBottom;    //!< The greatest distance below the baseline for any glyph (will be >= 0)
667         SkScalar    fLeading;   //!< The recommended distance to add between lines of text (will be >= 0)
668         SkScalar    fAvgCharWidth;  //!< the average charactor width (>= 0)
669         SkScalar    fXMin;      //!< The minimum bounding box x value for all glyphs
670         SkScalar    fXMax;      //!< The maximum bounding box x value for all glyphs
671         SkScalar    fXHeight;   //!< the height of an 'x' in px, or 0 if no 'x' in face
672     };
673 
674     /** Return the recommend spacing between lines (which will be
675         fDescent - fAscent + fLeading).
676         If metrics is not null, return in it the font metrics for the
677         typeface/pointsize/etc. currently set in the paint.
678         @param metrics      If not null, returns the font metrics for the
679                             current typeface/pointsize/etc setting in this
680                             paint.
681         @param scale        If not 0, return width as if the canvas were scaled
682                             by this value
683         @param return the recommended spacing between lines
684     */
685     SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const;
686 
687     /** Return the recommend line spacing. This will be
688         fDescent - fAscent + fLeading
689     */
getFontSpacing()690     SkScalar getFontSpacing() const { return this->getFontMetrics(NULL, 0); }
691 
692     /** Convert the specified text into glyph IDs, returning the number of
693         glyphs ID written. If glyphs is NULL, it is ignore and only the count
694         is returned.
695     */
696     int textToGlyphs(const void* text, size_t byteLength,
697                      uint16_t glyphs[]) const;
698 
699     /** Return the number of drawable units in the specified text buffer.
700         This looks at the current TextEncoding field of the paint. If you also
701         want to have the text converted into glyph IDs, call textToGlyphs
702         instead.
703     */
countText(const void * text,size_t byteLength)704     int countText(const void* text, size_t byteLength) const
705     {
706         return this->textToGlyphs(text, byteLength, NULL);
707     }
708 
709     /** Return the width of the text.
710         @param text         The text to be measured
711         @param length       Number of bytes of text to measure
712         @param bounds       If not NULL, returns the bounds of the text,
713                             relative to (0, 0).
714         @param scale        If not 0, return width as if the canvas were scaled
715                             by this value
716         @return             The advance width of the text
717     */
718     SkScalar    measureText(const void* text, size_t length,
719                             SkRect* bounds, SkScalar scale = 0) const;
720 
721     /** Return the width of the text.
722         @param text         Address of the text
723         @param length       Number of bytes of text to measure
724         @return The width of the text
725     */
measureText(const void * text,size_t length)726     SkScalar measureText(const void* text, size_t length) const
727     {
728         return this->measureText(text, length, NULL, 0);
729     }
730 
731     /** Specify the direction the text buffer should be processed in breakText()
732     */
733     enum TextBufferDirection {
734         /** When measuring text for breakText(), begin at the start of the text
735             buffer and proceed forward through the data. This is the default.
736         */
737         kForward_TextBufferDirection,
738         /** When measuring text for breakText(), begin at the end of the text
739             buffer and proceed backwards through the data.
740         */
741         kBackward_TextBufferDirection
742     };
743 
744     /** Return the width of the text.
745         @param text     The text to be measured
746         @param length   Number of bytes of text to measure
747         @param maxWidth Maximum width. Only the subset of text whose accumulated
748                         widths are <= maxWidth are measured.
749         @param measuredWidth Optional. If non-null, this returns the actual
750                         width of the measured text.
751         @param tbd      Optional. The direction the text buffer should be
752                         traversed during measuring.
753         @return         The number of bytes of text that were measured. Will be
754                         <= length.
755     */
756     size_t  breakText(const void* text, size_t length, SkScalar maxWidth,
757                       SkScalar* measuredWidth = NULL,
758                       TextBufferDirection tbd = kForward_TextBufferDirection)
759                       const;
760 
761     /** Return the advance widths for the characters in the string.
762         @param text         the text
763         @param byteLength   number of bytes to of text
764         @param widths       If not null, returns the array of advance widths of
765                             the glyphs. If not NULL, must be at least a large
766                             as the number of unichars in the specified text.
767         @param bounds       If not null, returns the bounds for each of
768                             character, relative to (0, 0)
769         @return the number of unichars in the specified text.
770     */
771     int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
772                       SkRect bounds[] = NULL) const;
773 
774     /** Return the path (outline) for the specified text.
775         Note: just like SkCanvas::drawText, this will respect the Align setting
776               in the paint.
777     */
778     void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
779                      SkPath* path) const;
780 
781 private:
782     SkTypeface*     fTypeface;
783     SkScalar        fTextSize;
784     SkScalar        fTextScaleX;
785     SkScalar        fTextSkewX;
786 
787     SkPathEffect*   fPathEffect;
788     SkShader*       fShader;
789     SkXfermode*     fXfermode;
790     SkMaskFilter*   fMaskFilter;
791     SkColorFilter*  fColorFilter;
792     SkRasterizer*   fRasterizer;
793     SkDrawLooper*   fLooper;
794 
795     SkColor         fColor;
796     SkScalar        fWidth;
797     SkScalar        fMiterLimit;
798     unsigned        fFlags : 10;
799     unsigned        fTextAlign : 2;
800     unsigned        fCapType : 2;
801     unsigned        fJoinType : 2;
802     unsigned        fStyle : 2;
803     unsigned        fTextEncoding : 2;  // 3 values
804     unsigned        fHinting : 2;
805 
806     SkDrawCacheProc    getDrawCacheProc() const;
807     SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir,
808                                            bool needFullMetrics) const;
809 
810     SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
811                           int* count, SkRect* bounds) const;
812 
813     SkGlyphCache*   detachCache(const SkMatrix*) const;
814 
815     void descriptorProc(const SkMatrix* deviceMatrix,
816                         void (*proc)(const SkDescriptor*, void*),
817                         void* context) const;
818 
819     const SkRect& computeStrokeFastBounds(const SkRect& orig,
820                                           SkRect* storage) const;
821 
822     enum {
823         kCanonicalTextSizeForPaths = 64
824     };
825     friend class SkCanvas;
826     friend class SkDraw;
827     friend class SkAutoGlyphCache;
828     friend class SkTextToPathIter;
829 };
830 
831 //////////////////////////////////////////////////////////////////////////
832 
833 #include "SkPathEffect.h"
834 
835 /** \class SkStrokePathEffect
836 
837     SkStrokePathEffect simulates stroking inside a patheffect, allowing the
838     caller to have explicit control of when to stroke a path. Typically this is
839     used if the caller wants to stroke before another patheffect is applied
840     (using SkComposePathEffect or SkSumPathEffect).
841 */
842 class SkStrokePathEffect : public SkPathEffect {
843 public:
844     SkStrokePathEffect(const SkPaint&);
845     SkStrokePathEffect(SkScalar width, SkPaint::Style, SkPaint::Join,
846                        SkPaint::Cap, SkScalar miterLimit = -1);
847 
848     // overrides
849     // This method is not exported to java.
850     virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
851 
852     // overrides for SkFlattenable
853     // This method is not exported to java.
854     virtual void flatten(SkFlattenableWriteBuffer&);
855     // This method is not exported to java.
856     virtual Factory getFactory();
857 
858 private:
859     SkScalar    fWidth, fMiter;
860     uint8_t     fStyle, fJoin, fCap;
861 
862     static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
863     SkStrokePathEffect(SkFlattenableReadBuffer&);
864 
865     typedef SkPathEffect INHERITED;
866 
867     // illegal
868     SkStrokePathEffect(const SkStrokePathEffect&);
869     SkStrokePathEffect& operator=(const SkStrokePathEffect&);
870 };
871 
872 #endif
873 
874