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