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 SkPaint_DEFINED
9 #define SkPaint_DEFINED
10 
11 #include "SkBlendMode.h"
12 #include "SkColor.h"
13 #include "SkFilterQuality.h"
14 #include "SkMatrix.h"
15 #include "SkXfermode.h"
16 
17 //#define SK_SUPPORT_LEGACY_XFERMODE_OBJECT
18 
19 class SkAutoDescriptor;
20 class SkAutoGlyphCache;
21 class SkColorFilter;
22 class SkData;
23 class SkDescriptor;
24 class SkDrawLooper;
25 class SkReadBuffer;
26 class SkWriteBuffer;
27 class SkGlyph;
28 struct SkRect;
29 class SkGlyphCache;
30 class SkImageFilter;
31 class SkMaskFilter;
32 class SkPath;
33 class SkPathEffect;
34 struct SkPoint;
35 class SkRasterizer;
36 struct SkScalerContextEffects;
37 class SkShader;
38 class SkSurfaceProps;
39 class SkTextBlob;
40 class SkTypeface;
41 
42 #define kBicubicFilterBitmap_Flag kHighQualityFilterBitmap_Flag
43 
44 /** \class SkPaint
45 
46     The SkPaint class holds the style and color information about how to draw
47     geometries, text and bitmaps.
48 */
49 class SK_API SkPaint {
50 public:
51     SkPaint();
52     SkPaint(const SkPaint& paint);
53     SkPaint(SkPaint&& paint);
54     ~SkPaint();
55 
56     SkPaint& operator=(const SkPaint&);
57     SkPaint& operator=(SkPaint&&);
58 
59     /** operator== may give false negatives: two paints that draw equivalently
60         may return false.  It will never give false positives: two paints that
61         are not equivalent always return false.
62     */
63     SK_API friend bool operator==(const SkPaint& a, const SkPaint& b);
64     friend bool operator!=(const SkPaint& a, const SkPaint& b) {
65         return !(a == b);
66     }
67 
68     /** getHash() is a shallow hash, with the same limitations as operator==.
69      *  If operator== returns true for two paints, getHash() returns the same value for each.
70      */
71     uint32_t getHash() const;
72 
73     void flatten(SkWriteBuffer&) const;
74     void unflatten(SkReadBuffer&);
75 
76     /** Restores the paint to its initial settings.
77     */
78     void reset();
79 
80     /** Specifies the level of hinting to be performed. These names are taken
81         from the Gnome/Cairo names for the same. They are translated into
82         Freetype concepts the same as in cairo-ft-font.c:
83            kNo_Hinting     -> FT_LOAD_NO_HINTING
84            kSlight_Hinting -> FT_LOAD_TARGET_LIGHT
85            kNormal_Hinting -> <default, no option>
86            kFull_Hinting   -> <same as kNormalHinting, unless we are rendering
87                               subpixel glyphs, in which case TARGET_LCD or
88                               TARGET_LCD_V is used>
89     */
90     enum Hinting {
91         kNo_Hinting            = 0,
92         kSlight_Hinting        = 1,
93         kNormal_Hinting        = 2,     //!< this is the default
94         kFull_Hinting          = 3
95     };
96 
getHinting()97     Hinting getHinting() const {
98         return static_cast<Hinting>(fBitfields.fHinting);
99     }
100 
101     void setHinting(Hinting hintingLevel);
102 
103     /** Specifies the bit values that are stored in the paint's flags.
104     */
105     enum Flags {
106         kAntiAlias_Flag       = 0x01,   //!< mask to enable antialiasing
107         kDither_Flag          = 0x04,   //!< mask to enable dithering
108         kUnderlineText_Flag   = 0x08,   //!< mask to enable underline text
109         kStrikeThruText_Flag  = 0x10,   //!< mask to enable strike-thru text
110         kFakeBoldText_Flag    = 0x20,   //!< mask to enable fake-bold text
111         kLinearText_Flag      = 0x40,   //!< mask to enable linear-text
112         kSubpixelText_Flag    = 0x80,   //!< mask to enable subpixel text positioning
113         kDevKernText_Flag     = 0x100,  //!< mask to enable device kerning text
114         kLCDRenderText_Flag   = 0x200,  //!< mask to enable subpixel glyph renderering
115         kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes
116         kAutoHinting_Flag     = 0x800,  //!< mask to force Freetype's autohinter
117         kVerticalText_Flag    = 0x1000,
118         kGenA8FromLCD_Flag    = 0x2000, // hack for GDI -- do not use if you can help it
119         // when adding extra flags, note that the fFlags member is specified
120         // with a bit-width and you'll have to expand it.
121 
122         kAllFlags = 0xFFFF
123     };
124 
125     /** Return the paint's flags. Use the Flag enum to test flag values.
126         @return the paint's flags (see enums ending in _Flag for bit masks)
127     */
getFlags()128     uint32_t getFlags() const { return fBitfields.fFlags; }
129 
130     /** Set the paint's flags. Use the Flag enum to specific flag values.
131         @param flags    The new flag bits for the paint (see Flags enum)
132     */
133     void setFlags(uint32_t flags);
134 
135     /** Helper for getFlags(), returning true if kAntiAlias_Flag bit is set
136         @return true if the antialias bit is set in the paint's flags.
137         */
isAntiAlias()138     bool isAntiAlias() const {
139         return SkToBool(this->getFlags() & kAntiAlias_Flag);
140     }
141 
142     /** Helper for setFlags(), setting or clearing the kAntiAlias_Flag bit
143         @param aa   true to enable antialiasing, false to disable it
144         */
145     void setAntiAlias(bool aa);
146 
147     /** Helper for getFlags(), returning true if kDither_Flag bit is set
148         @return true if the dithering bit is set in the paint's flags.
149         */
isDither()150     bool isDither() const {
151         return SkToBool(this->getFlags() & kDither_Flag);
152     }
153 
154     /** Helper for setFlags(), setting or clearing the kDither_Flag bit
155         @param dither   true to enable dithering, false to disable it
156         */
157     void setDither(bool dither);
158 
159     /** Helper for getFlags(), returning true if kLinearText_Flag bit is set
160         @return true if the lineartext bit is set in the paint's flags
161     */
isLinearText()162     bool isLinearText() const {
163         return SkToBool(this->getFlags() & kLinearText_Flag);
164     }
165 
166     /** Helper for setFlags(), setting or clearing the kLinearText_Flag bit
167         @param linearText true to set the linearText bit in the paint's flags,
168                           false to clear it.
169     */
170     void setLinearText(bool linearText);
171 
172     /** Helper for getFlags(), returning true if kSubpixelText_Flag bit is set
173         @return true if the lineartext bit is set in the paint's flags
174     */
isSubpixelText()175     bool isSubpixelText() const {
176         return SkToBool(this->getFlags() & kSubpixelText_Flag);
177     }
178 
179     /**
180      *  Helper for setFlags(), setting or clearing the kSubpixelText_Flag.
181      *  @param subpixelText true to set the subpixelText bit in the paint's
182      *                      flags, false to clear it.
183      */
184     void setSubpixelText(bool subpixelText);
185 
isLCDRenderText()186     bool isLCDRenderText() const {
187         return SkToBool(this->getFlags() & kLCDRenderText_Flag);
188     }
189 
190     /**
191      *  Helper for setFlags(), setting or clearing the kLCDRenderText_Flag.
192      *  Note: antialiasing must also be on for lcd rendering
193      *  @param lcdText true to set the LCDRenderText bit in the paint's flags,
194      *                 false to clear it.
195      */
196     void setLCDRenderText(bool lcdText);
197 
isEmbeddedBitmapText()198     bool isEmbeddedBitmapText() const {
199         return SkToBool(this->getFlags() & kEmbeddedBitmapText_Flag);
200     }
201 
202     /** Helper for setFlags(), setting or clearing the kEmbeddedBitmapText_Flag bit
203         @param useEmbeddedBitmapText true to set the kEmbeddedBitmapText bit in the paint's flags,
204                                      false to clear it.
205     */
206     void setEmbeddedBitmapText(bool useEmbeddedBitmapText);
207 
isAutohinted()208     bool isAutohinted() const {
209         return SkToBool(this->getFlags() & kAutoHinting_Flag);
210     }
211 
212     /** Helper for setFlags(), setting or clearing the kAutoHinting_Flag bit
213         @param useAutohinter true to set the kEmbeddedBitmapText bit in the
214                                   paint's flags,
215                              false to clear it.
216     */
217     void setAutohinted(bool useAutohinter);
218 
isVerticalText()219     bool isVerticalText() const {
220         return SkToBool(this->getFlags() & kVerticalText_Flag);
221     }
222 
223     /**
224      *  Helper for setting or clearing the kVerticalText_Flag bit in
225      *  setFlags(...).
226      *
227      *  If this bit is set, then advances are treated as Y values rather than
228      *  X values, and drawText will places its glyphs vertically rather than
229      *  horizontally.
230      */
231     void setVerticalText(bool);
232 
233     /** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set
234         @return true if the underlineText bit is set in the paint's flags.
235     */
isUnderlineText()236     bool isUnderlineText() const {
237         return SkToBool(this->getFlags() & kUnderlineText_Flag);
238     }
239 
240     /** Helper for setFlags(), setting or clearing the kUnderlineText_Flag bit
241         @param underlineText true to set the underlineText bit in the paint's
242                              flags, false to clear it.
243     */
244     void setUnderlineText(bool underlineText);
245 
246     /** Helper for getFlags(), returns true if kStrikeThruText_Flag bit is set
247         @return true if the strikeThruText bit is set in the paint's flags.
248     */
isStrikeThruText()249     bool isStrikeThruText() const {
250         return SkToBool(this->getFlags() & kStrikeThruText_Flag);
251     }
252 
253     /** Helper for setFlags(), setting or clearing the kStrikeThruText_Flag bit
254         @param strikeThruText   true to set the strikeThruText bit in the
255                                 paint's flags, false to clear it.
256     */
257     void setStrikeThruText(bool strikeThruText);
258 
259     /** Helper for getFlags(), returns true if kFakeBoldText_Flag bit is set
260         @return true if the kFakeBoldText_Flag bit is set in the paint's flags.
261     */
isFakeBoldText()262     bool isFakeBoldText() const {
263         return SkToBool(this->getFlags() & kFakeBoldText_Flag);
264     }
265 
266     /** Helper for setFlags(), setting or clearing the kFakeBoldText_Flag bit
267         @param fakeBoldText true to set the kFakeBoldText_Flag bit in the paint's
268                             flags, false to clear it.
269     */
270     void setFakeBoldText(bool fakeBoldText);
271 
272     /** Helper for getFlags(), returns true if kDevKernText_Flag bit is set
273         @return true if the kernText bit is set in the paint's flags.
274     */
isDevKernText()275     bool isDevKernText() const {
276         return SkToBool(this->getFlags() & kDevKernText_Flag);
277     }
278 
279     /** Helper for setFlags(), setting or clearing the kKernText_Flag bit
280         @param kernText true to set the kKernText_Flag bit in the paint's
281                             flags, false to clear it.
282     */
283     void setDevKernText(bool devKernText);
284 
285     /**
286      *  Return the filter level. This affects the quality (and performance) of
287      *  drawing scaled images.
288      */
getFilterQuality()289     SkFilterQuality getFilterQuality() const {
290         return (SkFilterQuality)fBitfields.fFilterQuality;
291     }
292 
293     /**
294      *  Set the filter quality. This affects the quality (and performance) of
295      *  drawing scaled images.
296      */
297     void setFilterQuality(SkFilterQuality quality);
298 
299     /** Styles apply to rect, oval, path, and text.
300         Bitmaps are always drawn in "fill", and lines are always drawn in
301         "stroke".
302 
303         Note: strokeandfill implicitly draws the result with
304         SkPath::kWinding_FillType, so if the original path is even-odd, the
305         results may not appear the same as if it was drawn twice, filled and
306         then stroked.
307     */
308     enum Style {
309         kFill_Style,            //!< fill the geometry
310         kStroke_Style,          //!< stroke the geometry
311         kStrokeAndFill_Style,   //!< fill and stroke the geometry
312     };
313     enum {
314         kStyleCount = kStrokeAndFill_Style + 1
315     };
316 
317     /** Return the paint's style, used for controlling how primitives'
318         geometries are interpreted (except for drawBitmap, which always assumes
319         kFill_Style).
320         @return the paint's Style
321     */
getStyle()322     Style getStyle() const { return (Style)fBitfields.fStyle; }
323 
324     /** Set the paint's style, used for controlling how primitives'
325         geometries are interpreted (except for drawBitmap, which always assumes
326         Fill).
327         @param style    The new style to set in the paint
328     */
329     void setStyle(Style style);
330 
331     /** Return the paint's color. Note that the color is a 32bit value
332         containing alpha as well as r,g,b. This 32bit value is not
333         premultiplied, meaning that its alpha can be any value, regardless of
334         the values of r,g,b.
335         @return the paint's color (and alpha).
336     */
getColor()337     SkColor getColor() const { return fColor; }
338 
339     /** Set the paint's color. Note that the color is a 32bit value containing
340         alpha as well as r,g,b. This 32bit value is not premultiplied, meaning
341         that its alpha can be any value, regardless of the values of r,g,b.
342         @param color    The new color (including alpha) to set in the paint.
343     */
344     void setColor(SkColor color);
345 
346     /** Helper to getColor() that just returns the color's alpha value.
347         @return the alpha component of the paint's color.
348         */
getAlpha()349     uint8_t getAlpha() const { return SkToU8(SkColorGetA(fColor)); }
350 
351     /** Helper to setColor(), that only assigns the color's alpha value,
352         leaving its r,g,b values unchanged.
353         @param a    set the alpha component (0..255) of the paint's color.
354     */
355     void setAlpha(U8CPU a);
356 
357     /** Helper to setColor(), that takes a,r,g,b and constructs the color value
358         using SkColorSetARGB()
359         @param a    The new alpha component (0..255) of the paint's color.
360         @param r    The new red component (0..255) of the paint's color.
361         @param g    The new green component (0..255) of the paint's color.
362         @param b    The new blue component (0..255) of the paint's color.
363     */
364     void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
365 
366     /** Return the width for stroking.
367         <p />
368         A value of 0 strokes in hairline mode.
369         Hairlines always draw 1-pixel wide, regardless of the matrix.
370         @return the paint's stroke width, used whenever the paint's style is
371                 Stroke or StrokeAndFill.
372     */
getStrokeWidth()373     SkScalar getStrokeWidth() const { return fWidth; }
374 
375     /** Set the width for stroking.
376         Pass 0 to stroke in hairline mode.
377         Hairlines always draw 1-pixel wide, regardless of the matrix.
378         @param width set the paint's stroke width, used whenever the paint's
379                      style is Stroke or StrokeAndFill.
380     */
381     void setStrokeWidth(SkScalar width);
382 
383     /** Return the paint's stroke miter value. This is used to control the
384         behavior of miter joins when the joins angle is sharp.
385         @return the paint's miter limit, used whenever the paint's style is
386                 Stroke or StrokeAndFill.
387     */
getStrokeMiter()388     SkScalar getStrokeMiter() const { return fMiterLimit; }
389 
390     /** Set the paint's stroke miter value. This is used to control the
391         behavior of miter joins when the joins angle is sharp. This value must
392         be >= 0.
393         @param miter    set the miter limit on the paint, used whenever the
394                         paint's style is Stroke or StrokeAndFill.
395     */
396     void setStrokeMiter(SkScalar miter);
397 
398     /** Cap enum specifies the settings for the paint's strokecap. This is the
399         treatment that is applied to the beginning and end of each non-closed
400         contour (e.g. lines).
401 
402         If the cap is round or square, the caps are drawn when the contour has
403         a zero length. Zero length contours can be created by following moveTo
404         with a lineTo at the same point, or a moveTo followed by a close.
405 
406         A dash with an on interval of zero also creates a zero length contour.
407 
408         The zero length contour draws the square cap without rotation, since
409         the no direction can be inferred.
410     */
411     enum Cap {
412         kButt_Cap,      //!< begin/end contours with no extension
413         kRound_Cap,     //!< begin/end contours with a semi-circle extension
414         kSquare_Cap,    //!< begin/end contours with a half square extension
415 
416         kLast_Cap = kSquare_Cap,
417         kDefault_Cap = kButt_Cap
418     };
419     static constexpr int kCapCount = kLast_Cap + 1;
420 
421     /** Join enum specifies the settings for the paint's strokejoin. This is
422         the treatment that is applied to corners in paths and rectangles.
423     */
424     enum Join {
425         kMiter_Join,    //!< connect path segments with a sharp join
426         kRound_Join,    //!< connect path segments with a round join
427         kBevel_Join,    //!< connect path segments with a flat bevel join
428 
429         kLast_Join = kBevel_Join,
430         kDefault_Join = kMiter_Join
431     };
432     static constexpr int kJoinCount = kLast_Join + 1;
433 
434     /** Return the paint's stroke cap type, controlling how the start and end
435         of stroked lines and paths are treated.
436         @return the line cap style for the paint, used whenever the paint's
437                 style is Stroke or StrokeAndFill.
438     */
getStrokeCap()439     Cap getStrokeCap() const { return (Cap)fBitfields.fCapType; }
440 
441     /** Set the paint's stroke cap type.
442         @param cap  set the paint's line cap style, used whenever the paint's
443                     style is Stroke or StrokeAndFill.
444     */
445     void setStrokeCap(Cap cap);
446 
447     /** Return the paint's stroke join type.
448         @return the paint's line join style, used whenever the paint's style is
449                 Stroke or StrokeAndFill.
450     */
getStrokeJoin()451     Join getStrokeJoin() const { return (Join)fBitfields.fJoinType; }
452 
453     /** Set the paint's stroke join type.
454         @param join set the paint's line join style, used whenever the paint's
455                     style is Stroke or StrokeAndFill.
456     */
457     void setStrokeJoin(Join join);
458 
459     /**
460      *  Applies any/all effects (patheffect, stroking) to src, returning the
461      *  result in dst. The result is that drawing src with this paint will be
462      *  the same as drawing dst with a default paint (at least from the
463      *  geometric perspective).
464      *
465      *  @param src  input path
466      *  @param dst  output path (may be the same as src)
467      *  @param cullRect If not null, the dst path may be culled to this rect.
468      *  @param resScale If > 1, increase precision, else if (0 < res < 1) reduce precision
469      *              in favor of speed/size.
470      *  @return     true if the path should be filled, or false if it should be
471      *              drawn with a hairline (width == 0)
472      */
473     bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
474                      SkScalar resScale = 1) const;
475 
getFillPath(const SkPath & src,SkPath * dst)476     bool getFillPath(const SkPath& src, SkPath* dst) const {
477         return this->getFillPath(src, dst, NULL, 1);
478     }
479 
480     /** Get the paint's shader object.
481         <p />
482       The shader's reference count is not affected.
483         @return the paint's shader (or NULL)
484     */
getShader()485     SkShader* getShader() const { return fShader.get(); }
486 
487     /** Set or clear the shader object.
488      *  Shaders specify the source color(s) for what is being drawn. If a paint
489      *  has no shader, then the paint's color is used. If the paint has a
490      *  shader, then the shader's color(s) are use instead, but they are
491      *  modulated by the paint's alpha. This makes it easy to create a shader
492      *  once (e.g. bitmap tiling or gradient) and then change its transparency
493      *  w/o having to modify the original shader... only the paint's alpha needs
494      *  to be modified.
495      *
496      *  There is an exception to this only-respect-paint's-alpha rule: If the shader only generates
497      *  alpha (e.g. SkShader::CreateBitmapShader(bitmap, ...) where bitmap's colortype is kAlpha_8)
498      *  then the shader will use the paint's entire color to "colorize" its output (modulating the
499      *  bitmap's alpha with the paint's color+alpha).
500      *
501      *  Pass NULL to clear any previous shader.
502      *  As a convenience, the parameter passed is also returned.
503      *  If a previous shader exists, its reference count is decremented.
504      *  If shader is not NULL, its reference count is incremented.
505      *  @param shader   May be NULL. The shader to be installed in the paint
506      *  @return         shader
507      */
508     void setShader(sk_sp<SkShader>);
509 #ifdef SK_SUPPORT_LEGACY_CREATESHADER_PTR
510     SkShader* setShader(SkShader* shader);
511 #endif
512 
513     /** Get the paint's colorfilter. If there is a colorfilter, its reference
514         count is not changed.
515         @return the paint's colorfilter (or NULL)
516     */
getColorFilter()517     SkColorFilter* getColorFilter() const { return fColorFilter.get(); }
518 
519     /** Set or clear the paint's colorfilter, returning the parameter.
520         <p />
521         If the paint already has a filter, its reference count is decremented.
522         If filter is not NULL, its reference count is incremented.
523         @param filter   May be NULL. The filter to be installed in the paint
524         @return         filter
525     */
526 #ifdef SK_SUPPORT_LEGACY_COLORFILTER_PTR
527     SkColorFilter* setColorFilter(SkColorFilter* filter);
528 #endif
529     void setColorFilter(sk_sp<SkColorFilter>);
530 
531 #ifdef SK_SUPPORT_LEGACY_XFERMODE_OBJECT
532     /** Get the paint's xfermode object.
533         <p />
534       The xfermode's reference count is not affected.
535         @return the paint's xfermode (or NULL)
536     */
537     SkXfermode* getXfermode() const;
538 
539     /** Set or clear the xfermode object.
540         <p />
541         Pass NULL to clear any previous xfermode.
542         As a convenience, the parameter passed is also returned.
543         If a previous xfermode exists, its reference count is decremented.
544         If xfermode is not NULL, its reference count is incremented.
545         @param xfermode May be NULL. The new xfermode to be installed in the
546                         paint
547         @return         xfermode
548     */
549     void setXfermode(sk_sp<SkXfermode>);
550 #ifdef SK_SUPPORT_LEGACY_XFERMODE_PTR
551     SkXfermode* setXfermode(SkXfermode* xfermode);
552 #endif
553 
554     /** Create an xfermode based on the specified Mode, and assign it into the
555         paint, returning the mode that was set. If the Mode is SrcOver, then
556         the paint's xfermode is set to null.
557      */
558     SkXfermode* setXfermodeMode(SkXfermode::Mode);
559 #endif
560 
getBlendMode()561     SkBlendMode getBlendMode() const { return (SkBlendMode)fBlendMode; }
isSrcOver()562     bool isSrcOver() const { return (SkBlendMode)fBlendMode == SkBlendMode::kSrcOver; }
setBlendMode(SkBlendMode mode)563     void setBlendMode(SkBlendMode mode) { fBlendMode = (unsigned)mode; }
564 
565     /** Get the paint's patheffect object.
566         <p />
567       The patheffect reference count is not affected.
568         @return the paint's patheffect (or NULL)
569     */
getPathEffect()570     SkPathEffect* getPathEffect() const { return fPathEffect.get(); }
571 
572     /** Set or clear the patheffect object.
573         <p />
574         Pass NULL to clear any previous patheffect.
575         As a convenience, the parameter passed is also returned.
576         If a previous patheffect exists, its reference count is decremented.
577         If patheffect is not NULL, its reference count is incremented.
578         @param effect   May be NULL. The new patheffect to be installed in the
579                         paint
580         @return         effect
581     */
582     void setPathEffect(sk_sp<SkPathEffect>);
583 #ifdef SK_SUPPORT_LEGACY_PATHEFFECT_PTR
584     SkPathEffect* setPathEffect(SkPathEffect* effect);
585 #endif
586 
587     /** Get the paint's maskfilter object.
588         <p />
589       The maskfilter reference count is not affected.
590         @return the paint's maskfilter (or NULL)
591     */
getMaskFilter()592     SkMaskFilter* getMaskFilter() const { return fMaskFilter.get(); }
593 
594     /** Set or clear the maskfilter object.
595         <p />
596         Pass NULL to clear any previous maskfilter.
597         As a convenience, the parameter passed is also returned.
598         If a previous maskfilter exists, its reference count is decremented.
599         If maskfilter is not NULL, its reference count is incremented.
600         @param maskfilter   May be NULL. The new maskfilter to be installed in
601                             the paint
602         @return             maskfilter
603     */
604 #ifdef SK_SUPPORT_LEGACY_MASKFILTER_PTR
605     SkMaskFilter* setMaskFilter(SkMaskFilter* maskfilter);
606 #endif
607     void setMaskFilter(sk_sp<SkMaskFilter>);
608 
609     // These attributes are for text/fonts
610 
611     /** Get the paint's typeface object.
612         <p />
613         The typeface object identifies which font to use when drawing or
614         measuring text. The typeface reference count is not affected.
615         @return the paint's typeface (or NULL)
616     */
getTypeface()617     SkTypeface* getTypeface() const { return fTypeface.get(); }
618 
619     /** Set or clear the typeface object.
620         <p />
621         Pass NULL to clear any previous typeface.
622         As a convenience, the parameter passed is also returned.
623         If a previous typeface exists, its reference count is decremented.
624         If typeface is not NULL, its reference count is incremented.
625         @param typeface May be NULL. The new typeface to be installed in the
626                         paint
627         @return         typeface
628     */
629     void setTypeface(sk_sp<SkTypeface>);
630 #ifdef SK_SUPPORT_LEGACY_TYPEFACE_PTR
631     SkTypeface* setTypeface(SkTypeface* typeface);
632 #endif
633 
634     /** Get the paint's rasterizer (or NULL).
635         <p />
636         The raster controls how paths/text are turned into alpha masks.
637         @return the paint's rasterizer (or NULL)
638     */
getRasterizer()639     SkRasterizer* getRasterizer() const { return fRasterizer.get(); }
640 
641     /** Set or clear the rasterizer object.
642         <p />
643         Pass NULL to clear any previous rasterizer.
644         As a convenience, the parameter passed is also returned.
645         If a previous rasterizer exists in the paint, its reference count is
646         decremented. If rasterizer is not NULL, its reference count is
647         incremented.
648         @param rasterizer May be NULL. The new rasterizer to be installed in
649                           the paint.
650         @return           rasterizer
651     */
652 #ifdef SK_SUPPORT_LEGACY_MINOR_EFFECT_PTR
653     SkRasterizer* setRasterizer(SkRasterizer* rasterizer);
654 #endif
655     void setRasterizer(sk_sp<SkRasterizer>);
656 
getImageFilter()657     SkImageFilter* getImageFilter() const { return fImageFilter.get(); }
658     SkImageFilter* setImageFilter(SkImageFilter*);
659     void setImageFilter(sk_sp<SkImageFilter>);
660 
661     /**
662      *  Return the paint's SkDrawLooper (if any). Does not affect the looper's
663      *  reference count.
664      */
getDrawLooper()665     SkDrawLooper* getDrawLooper() const { return fDrawLooper.get(); }
getLooper()666     SkDrawLooper* getLooper() const { return fDrawLooper.get(); }
667     /**
668      *  Set or clear the looper object.
669      *  <p />
670      *  Pass NULL to clear any previous looper.
671      *  If a previous looper exists in the paint, its reference count is
672      *  decremented. If looper is not NULL, its reference count is
673      *  incremented.
674      *  @param looper May be NULL. The new looper to be installed in the paint.
675      */
676     void setDrawLooper(sk_sp<SkDrawLooper>);
677 #ifdef SK_SUPPORT_LEGACY_MINOR_EFFECT_PTR
678     SkDrawLooper* setLooper(SkDrawLooper* looper);
679 #endif
680     void setLooper(sk_sp<SkDrawLooper>);
681 
682     enum Align {
683         kLeft_Align,
684         kCenter_Align,
685         kRight_Align,
686     };
687     enum {
688         kAlignCount = 3
689     };
690 
691     /** Return the paint's Align value for drawing text.
692         @return the paint's Align value for drawing text.
693     */
getTextAlign()694     Align   getTextAlign() const { return (Align)fBitfields.fTextAlign; }
695 
696     /** Set the paint's text alignment.
697         @param align set the paint's Align value for drawing text.
698     */
699     void    setTextAlign(Align align);
700 
701     /** Return the paint's text size.
702         @return the paint's text size.
703     */
getTextSize()704     SkScalar getTextSize() const { return fTextSize; }
705 
706     /** Set the paint's text size. This value must be > 0
707         @param textSize set the paint's text size.
708     */
709     void setTextSize(SkScalar textSize);
710 
711     /** Return the paint's horizontal scale factor for text. The default value
712         is 1.0.
713         @return the paint's scale factor in X for drawing/measuring text
714     */
getTextScaleX()715     SkScalar getTextScaleX() const { return fTextScaleX; }
716 
717     /** Set the paint's horizontal scale factor for text. The default value
718         is 1.0. Values > 1.0 will stretch the text wider. Values < 1.0 will
719         stretch the text narrower.
720         @param scaleX   set the paint's scale factor in X for drawing/measuring
721                         text.
722     */
723     void setTextScaleX(SkScalar scaleX);
724 
725     /** Return the paint's horizontal skew factor for text. The default value
726         is 0.
727         @return the paint's skew factor in X for drawing text.
728     */
getTextSkewX()729     SkScalar getTextSkewX() const { return fTextSkewX; }
730 
731     /** Set the paint's horizontal skew factor for text. The default value
732         is 0. For approximating oblique text, use values around -0.25.
733         @param skewX set the paint's skew factor in X for drawing text.
734     */
735     void setTextSkewX(SkScalar skewX);
736 
737     /** Describes how to interpret the text parameters that are passed to paint
738         methods like measureText() and getTextWidths().
739     */
740     enum TextEncoding {
741         kUTF8_TextEncoding,     //!< the text parameters are UTF8
742         kUTF16_TextEncoding,    //!< the text parameters are UTF16
743         kUTF32_TextEncoding,    //!< the text parameters are UTF32
744         kGlyphID_TextEncoding   //!< the text parameters are glyph indices
745     };
746 
getTextEncoding()747     TextEncoding getTextEncoding() const {
748       return (TextEncoding)fBitfields.fTextEncoding;
749     }
750 
751     void setTextEncoding(TextEncoding encoding);
752 
753     struct FontMetrics {
754         /** Flags which indicate the confidence level of various metrics.
755             A set flag indicates that the metric may be trusted.
756         */
757         enum FontMetricsFlags {
758             kUnderlineThinknessIsValid_Flag = 1 << 0,
759             kUnderlinePositionIsValid_Flag = 1 << 1,
760         };
761 
762         uint32_t    fFlags;       //!< Bit field to identify which values are unknown
763         SkScalar    fTop;       //!< The greatest distance above the baseline for any glyph (will be <= 0)
764         SkScalar    fAscent;    //!< The recommended distance above the baseline (will be <= 0)
765         SkScalar    fDescent;   //!< The recommended distance below the baseline (will be >= 0)
766         SkScalar    fBottom;    //!< The greatest distance below the baseline for any glyph (will be >= 0)
767         SkScalar    fLeading;   //!< The recommended distance to add between lines of text (will be >= 0)
768         SkScalar    fAvgCharWidth;  //!< the average character width (>= 0)
769         SkScalar    fMaxCharWidth;  //!< the max character width (>= 0)
770         SkScalar    fXMin;      //!< The minimum bounding box x value for all glyphs
771         SkScalar    fXMax;      //!< The maximum bounding box x value for all glyphs
772         SkScalar    fXHeight;   //!< The height of an 'x' in px, or 0 if no 'x' in face
773         SkScalar    fCapHeight;  //!< The cap height (> 0), or 0 if cannot be determined.
774         SkScalar    fUnderlineThickness; //!< underline thickness, or 0 if cannot be determined
775 
776         /**  Underline Position - position of the top of the Underline stroke
777                 relative to the baseline, this can have following values
778                 - Negative - means underline should be drawn above baseline.
779                 - Positive - means below baseline.
780                 - Zero     - mean underline should be drawn on baseline.
781          */
782         SkScalar    fUnderlinePosition; //!< underline position, or 0 if cannot be determined
783 
784         /**  If the fontmetrics has a valid underlinethickness, return true, and set the
785                 thickness param to that value. If it doesn't return false and ignore the
786                 thickness param.
787         */
hasUnderlineThicknessFontMetrics788         bool hasUnderlineThickness(SkScalar* thickness) const {
789             if (SkToBool(fFlags & kUnderlineThinknessIsValid_Flag)) {
790                 *thickness = fUnderlineThickness;
791                 return true;
792             }
793             return false;
794         }
795 
796         /**  If the fontmetrics has a valid underlineposition, return true, and set the
797                 thickness param to that value. If it doesn't return false and ignore the
798                 thickness param.
799         */
hasUnderlinePositionFontMetrics800         bool hasUnderlinePosition(SkScalar* position) const {
801             if (SkToBool(fFlags & kUnderlinePositionIsValid_Flag)) {
802                 *position = fUnderlinePosition;
803                 return true;
804             }
805             return false;
806         }
807 
808     };
809 
810     /** Return the recommend spacing between lines (which will be
811         fDescent - fAscent + fLeading).
812         If metrics is not null, return in it the font metrics for the
813         typeface/pointsize/etc. currently set in the paint.
814         @param metrics      If not null, returns the font metrics for the
815                             current typeface/pointsize/etc setting in this
816                             paint.
817         @param scale        If not 0, return width as if the canvas were scaled
818                             by this value
819         @param return the recommended spacing between lines
820     */
821     SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const;
822 
823     /** Return the recommend line spacing. This will be
824         fDescent - fAscent + fLeading
825     */
getFontSpacing()826     SkScalar getFontSpacing() const { return this->getFontMetrics(NULL, 0); }
827 
828     /** Convert the specified text into glyph IDs, returning the number of
829         glyphs ID written. If glyphs is NULL, it is ignore and only the count
830         is returned.
831     */
832     int textToGlyphs(const void* text, size_t byteLength,
833                      SkGlyphID glyphs[]) const;
834 
835     /** Return true if all of the specified text has a corresponding non-zero
836         glyph ID. If any of the code-points in the text are not supported in
837         the typeface (i.e. the glyph ID would be zero), then return false.
838 
839         If the text encoding for the paint is kGlyph_TextEncoding, then this
840         returns true if all of the specified glyph IDs are non-zero.
841      */
842     bool containsText(const void* text, size_t byteLength) const;
843 
844     /** Convert the glyph array into Unichars. Unconvertable glyphs are mapped
845         to zero. Note: this does not look at the text-encoding setting in the
846         paint, only at the typeface.
847     */
848     void glyphsToUnichars(const SkGlyphID glyphs[], int count, SkUnichar text[]) const;
849 
850     /** Return the number of drawable units in the specified text buffer.
851         This looks at the current TextEncoding field of the paint. If you also
852         want to have the text converted into glyph IDs, call textToGlyphs
853         instead.
854     */
countText(const void * text,size_t byteLength)855     int countText(const void* text, size_t byteLength) const {
856         return this->textToGlyphs(text, byteLength, NULL);
857     }
858 
859     /** Return the width of the text. This will return the vertical measure
860      *  if isVerticalText() is true, in which case the returned value should
861      *  be treated has a height instead of a width.
862      *
863      *  @param text         The text to be measured
864      *  @param length       Number of bytes of text to measure
865      *  @param bounds       If not NULL, returns the bounds of the text,
866      *                      relative to (0, 0).
867      *  @return             The advance width of the text
868      */
869     SkScalar measureText(const void* text, size_t length, SkRect* bounds) const;
870 
871     /** Return the width of the text. This will return the vertical measure
872      *  if isVerticalText() is true, in which case the returned value should
873      *  be treated has a height instead of a width.
874      *
875      *  @param text     Address of the text
876      *  @param length   Number of bytes of text to measure
877      *  @return         The advance width of the text
878      */
measureText(const void * text,size_t length)879     SkScalar measureText(const void* text, size_t length) const {
880         return this->measureText(text, length, NULL);
881     }
882 
883     /** Return the number of bytes of text that were measured. If
884      *  isVerticalText() is true, then the vertical advances are used for
885      *  the measurement.
886      *
887      *  @param text     The text to be measured
888      *  @param length   Number of bytes of text to measure
889      *  @param maxWidth Maximum width. Only the subset of text whose accumulated
890      *                  widths are <= maxWidth are measured.
891      *  @param measuredWidth Optional. If non-null, this returns the actual
892      *                  width of the measured text.
893      *  @return         The number of bytes of text that were measured. Will be
894      *                  <= length.
895      */
896     size_t  breakText(const void* text, size_t length, SkScalar maxWidth,
897                       SkScalar* measuredWidth = NULL) const;
898 
899     /** Return the advances for the text. These will be vertical advances if
900      *  isVerticalText() returns true.
901      *
902      *  @param text         the text
903      *  @param byteLength   number of bytes to of text
904      *  @param widths       If not null, returns the array of advances for
905      *                      the glyphs. If not NULL, must be at least a large
906      *                      as the number of unichars in the specified text.
907      *  @param bounds       If not null, returns the bounds for each of
908      *                      character, relative to (0, 0)
909      *  @return the number of unichars in the specified text.
910      */
911     int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
912                       SkRect bounds[] = NULL) const;
913 
914     /** Return the path (outline) for the specified text.
915      *  Note: just like SkCanvas::drawText, this will respect the Align setting
916      *        in the paint.
917      *
918      *  @param text         the text
919      *  @param length       number of bytes of text
920      *  @param x            The x-coordinate of the origin of the text.
921      *  @param y            The y-coordinate of the origin of the text.
922      *  @param path         The outline of the text.
923      */
924     void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
925                      SkPath* path) const;
926 
927     /** Return the path (outline) for the specified text.
928      *  Note: just like SkCanvas::drawText, this will respect the Align setting
929      *        in the paint.
930      *
931      *  @param text         the text
932      *  @param length       number of bytes of text
933      *  @param pos          array of positions, used to position each character
934      *  @param path         The outline of the text.
935      */
936     void getPosTextPath(const void* text, size_t length,
937                         const SkPoint pos[], SkPath* path) const;
938 
939     /** Return the number of intervals that intersect the intercept along the axis of the advance.
940      *  The return count is zero or a multiple of two, and is at most the number of glyphs * 2 in
941      *  the string. The caller may pass nullptr for intervals to determine the size of the interval
942      *  array, or may conservatively pre-allocate an array with length * 2 entries. The computed
943      *  intervals are cached by glyph to improve performance for multiple calls.
944      *  This permits constructing an underline that skips the descenders.
945      *
946      *  @param text         the text
947      *  @param length       number of bytes of text
948      *  @param x            The x-coordinate of the origin of the text.
949      *  @param y            The y-coordinate of the origin of the text.
950      *  @param bounds       The lower and upper line parallel to the advance.
951      *  @param array        If not null, the found intersections.
952      *
953      *  @return             The number of intersections, which may be zero.
954      */
955     int getTextIntercepts(const void* text, size_t length, SkScalar x, SkScalar y,
956                           const SkScalar bounds[2], SkScalar* intervals) const;
957 
958     /** Return the number of intervals that intersect the intercept along the axis of the advance.
959      *  The return count is zero or a multiple of two, and is at most the number of glyphs * 2 in
960      *  string. The caller may pass nullptr for intervals to determine the size of the interval
961      *  array, or may conservatively pre-allocate an array with length * 2 entries. The computed
962      *  intervals are cached by glyph to improve performance for multiple calls.
963      *  This permits constructing an underline that skips the descenders.
964      *
965      *  @param text         the text
966      *  @param length       number of bytes of text
967      *  @param pos          array of positions, used to position each character
968      *  @param bounds       The lower and upper line parallel to the advance.
969      *  @param array        If not null, the glyph bounds contained by the advance parallel lines.
970      *
971      *  @return             The number of intersections, which may be zero.
972      */
973     int getPosTextIntercepts(const void* text, size_t length, const SkPoint pos[],
974                              const SkScalar bounds[2], SkScalar* intervals) const;
975 
976     /** Return the number of intervals that intersect the intercept along the axis of the advance.
977      *  The return count is zero or a multiple of two, and is at most the number of glyphs * 2 in
978      *  string. The caller may pass nullptr for intervals to determine the size of the interval
979      *  array, or may conservatively pre-allocate an array with length * 2 entries. The computed
980      *  intervals are cached by glyph to improve performance for multiple calls.
981      *  This permits constructing an underline that skips the descenders.
982      *
983      *  @param text         The text.
984      *  @param length       Number of bytes of text.
985      *  @param xpos         Array of x-positions, used to position each character.
986      *  @param constY       The shared Y coordinate for all of the positions.
987      *  @param bounds       The lower and upper line parallel to the advance.
988      *  @param array        If not null, the glyph bounds contained by the advance parallel lines.
989      *
990      *  @return             The number of intersections, which may be zero.
991      */
992     int getPosTextHIntercepts(const void* text, size_t length, const SkScalar xpos[],
993                               SkScalar constY, const SkScalar bounds[2], SkScalar* intervals) const;
994 
995     /** Return the number of intervals that intersect the intercept along the axis of the advance.
996      *  The return count is zero or a multiple of two, and is at most the number of glyphs * 2 in
997      *  text blob. The caller may pass nullptr for intervals to determine the size of the interval
998      *  array. The computed intervals are cached by glyph to improve performance for multiple calls.
999      *  This permits constructing an underline that skips the descenders.
1000      *
1001      *  @param blob         The text blob.
1002      *  @param bounds       The lower and upper line parallel to the advance.
1003      *  @param array        If not null, the glyph bounds contained by the advance parallel lines.
1004      *
1005      *  @return             The number of intersections, which may be zero.
1006      */
1007     int getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds[2],
1008                               SkScalar* intervals) const;
1009 
1010     /**
1011      *  Return a rectangle that represents the union of the bounds of all
1012      *  of the glyphs, but each one positioned at (0,0). This may be conservatively large, and
1013      *  will not take into account any hinting, but will respect any text-scale-x or text-skew-x
1014      *  on this paint.
1015      */
1016     SkRect getFontBounds() const;
1017 
1018     // returns true if the paint's settings (e.g. xfermode + alpha) resolve to
1019     // mean that we need not draw at all (e.g. SrcOver + 0-alpha)
1020     bool nothingToDraw() const;
1021 
1022     ///////////////////////////////////////////////////////////////////////////
1023     // would prefer to make these private...
1024 
1025     /** Returns true if the current paint settings allow for fast computation of
1026      bounds (i.e. there is nothing complex like a patheffect that would make
1027      the bounds computation expensive.
1028      */
1029     bool canComputeFastBounds() const;
1030 
1031     /** Only call this if canComputeFastBounds() returned true. This takes a
1032      raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
1033      effects in the paint (e.g. stroking). If needed, it uses the storage
1034      rect parameter. It returns the adjusted bounds that can then be used
1035      for quickReject tests.
1036 
1037      The returned rect will either be orig or storage, thus the caller
1038      should not rely on storage being set to the result, but should always
1039      use the retured value. It is legal for orig and storage to be the same
1040      rect.
1041 
1042      e.g.
1043      if (paint.canComputeFastBounds()) {
1044      SkRect r, storage;
1045      path.computeBounds(&r, SkPath::kFast_BoundsType);
1046      const SkRect& fastR = paint.computeFastBounds(r, &storage);
1047      if (canvas->quickReject(fastR, ...)) {
1048      // don't draw the path
1049      }
1050      }
1051      */
computeFastBounds(const SkRect & orig,SkRect * storage)1052     const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
1053         SkPaint::Style style = this->getStyle();
1054         // ultra fast-case: filling with no effects that affect geometry
1055         if (kFill_Style == style) {
1056             uintptr_t effects = reinterpret_cast<uintptr_t>(this->getLooper());
1057             effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter());
1058             effects |= reinterpret_cast<uintptr_t>(this->getPathEffect());
1059             effects |= reinterpret_cast<uintptr_t>(this->getImageFilter());
1060             if (!effects) {
1061                 return orig;
1062             }
1063         }
1064 
1065         return this->doComputeFastBounds(orig, storage, style);
1066     }
1067 
computeFastStrokeBounds(const SkRect & orig,SkRect * storage)1068     const SkRect& computeFastStrokeBounds(const SkRect& orig,
1069                                           SkRect* storage) const {
1070         return this->doComputeFastBounds(orig, storage, kStroke_Style);
1071     }
1072 
1073     // Take the style explicitly, so the caller can force us to be stroked
1074     // without having to make a copy of the paint just to change that field.
1075     const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
1076                                       Style) const;
1077 
1078     /**
1079      *  Return a matrix that applies the paint's text values: size, scale, skew
1080      */
SetTextMatrix(SkMatrix * matrix,SkScalar size,SkScalar scaleX,SkScalar skewX)1081     static SkMatrix* SetTextMatrix(SkMatrix* matrix, SkScalar size,
1082                                    SkScalar scaleX, SkScalar skewX) {
1083         matrix->setScale(size * scaleX, size);
1084         if (skewX) {
1085             matrix->postSkew(skewX, 0);
1086         }
1087         return matrix;
1088     }
1089 
setTextMatrix(SkMatrix * matrix)1090     SkMatrix* setTextMatrix(SkMatrix* matrix) const {
1091         return SetTextMatrix(matrix, fTextSize, fTextScaleX, fTextSkewX);
1092     }
1093 
1094     typedef const SkGlyph& (*GlyphCacheProc)(SkGlyphCache*, const char**);
1095 
1096     SK_TO_STRING_NONVIRT()
1097 
1098 private:
1099     sk_sp<SkTypeface>     fTypeface;
1100     sk_sp<SkPathEffect>   fPathEffect;
1101     sk_sp<SkShader>       fShader;
1102     sk_sp<SkMaskFilter>   fMaskFilter;
1103     sk_sp<SkColorFilter>  fColorFilter;
1104     sk_sp<SkRasterizer>   fRasterizer;
1105     sk_sp<SkDrawLooper>   fDrawLooper;
1106     sk_sp<SkImageFilter>  fImageFilter;
1107 
1108     SkScalar        fTextSize;
1109     SkScalar        fTextScaleX;
1110     SkScalar        fTextSkewX;
1111     SkColor         fColor;
1112     SkScalar        fWidth;
1113     SkScalar        fMiterLimit;
1114     uint32_t        fBlendMode; // just need 5-6 bits for SkXfermode::Mode
1115     union {
1116         struct {
1117             // all of these bitfields should add up to 32
1118             unsigned        fFlags : 16;
1119             unsigned        fTextAlign : 2;
1120             unsigned        fCapType : 2;
1121             unsigned        fJoinType : 2;
1122             unsigned        fStyle : 2;
1123             unsigned        fTextEncoding : 2;  // 3 values
1124             unsigned        fHinting : 2;
1125             unsigned        fFilterQuality : 2;
1126             //unsigned      fFreeBits : 2;
1127         } fBitfields;
1128         uint32_t fBitfieldsUInt;
1129     };
1130 
1131     static GlyphCacheProc GetGlyphCacheProc(TextEncoding encoding,
1132                                             bool isDevKern,
1133                                             bool needFullMetrics);
1134 
1135     SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
1136                           int* count, SkRect* bounds) const;
1137 
1138     enum ScalerContextFlags : uint32_t {
1139         kNone_ScalerContextFlags = 0,
1140 
1141         kFakeGamma_ScalerContextFlag = 1 << 0,
1142         kBoostContrast_ScalerContextFlag = 1 << 1,
1143 
1144         kFakeGammaAndBoostContrast_ScalerContextFlags =
1145             kFakeGamma_ScalerContextFlag | kBoostContrast_ScalerContextFlag,
1146     };
1147 
1148     /*
1149      * Allocs an SkDescriptor on the heap and return it to the caller as a refcnted
1150      * SkData.  Caller is responsible for managing the lifetime of this object.
1151      */
1152     void getScalerContextDescriptor(SkScalerContextEffects*, SkAutoDescriptor*,
1153                                     const SkSurfaceProps& surfaceProps,
1154                                     uint32_t scalerContextFlags, const SkMatrix*) const;
1155 
1156     SkGlyphCache* detachCache(const SkSurfaceProps* surfaceProps, uint32_t scalerContextFlags,
1157                               const SkMatrix*) const;
1158 
1159     void descriptorProc(const SkSurfaceProps* surfaceProps, uint32_t scalerContextFlags,
1160                         const SkMatrix* deviceMatrix,
1161                         void (*proc)(SkTypeface*, const SkScalerContextEffects&,
1162                                      const SkDescriptor*, void*),
1163                         void* context) const;
1164 
1165     /*
1166      * The luminance color is used to determine which Gamma Canonical color to map to.  This is
1167      * really only used by backends which want to cache glyph masks, and need some way to know if
1168      * they need to generate new masks based off a given color.
1169      */
1170     SkColor computeLuminanceColor() const;
1171 
1172     enum {
1173         /*  This is the size we use when we ask for a glyph's path. We then
1174          *  post-transform it as we draw to match the request.
1175          *  This is done to try to re-use cache entries for the path.
1176          *
1177          *  This value is somewhat arbitrary. In theory, it could be 1, since
1178          *  we store paths as floats. However, we get the path from the font
1179          *  scaler, and it may represent its paths as fixed-point (or 26.6),
1180          *  so we shouldn't ask for something too big (might overflow 16.16)
1181          *  or too small (underflow 26.6).
1182          *
1183          *  This value could track kMaxSizeForGlyphCache, assuming the above
1184          *  constraints, but since we ask for unhinted paths, the two values
1185          *  need not match per-se.
1186          */
1187         kCanonicalTextSizeForPaths  = 64,
1188 
1189         /*
1190          *  Above this size (taking into account CTM and textSize), we never use
1191          *  the cache for bits or metrics (we might overflow), so we just ask
1192          *  for a caononical size and post-transform that.
1193          */
1194         kMaxSizeForGlyphCache       = 256,
1195     };
1196 
1197     static bool TooBigToUseCache(const SkMatrix& ctm, const SkMatrix& textM);
1198 
1199     // Set flags/hinting/textSize up to use for drawing text as paths.
1200     // Returns scale factor to restore the original textSize, since will will
1201     // have change it to kCanonicalTextSizeForPaths.
1202     SkScalar setupForAsPaths();
1203 
MaxCacheSize2()1204     static SkScalar MaxCacheSize2() {
1205         static const SkScalar kMaxSize = SkIntToScalar(kMaxSizeForGlyphCache);
1206         static const SkScalar kMag2Max = kMaxSize * kMaxSize;
1207         return kMag2Max;
1208     }
1209 
1210     friend class SkAutoGlyphCache;
1211     friend class SkAutoGlyphCacheNoGamma;
1212     friend class SkCanvas;
1213     friend class SkDraw;
1214     friend class SkPDFDevice;
1215     friend class GrAtlasTextBlob;
1216     friend class GrAtlasTextContext;
1217     friend class GrStencilAndCoverTextContext;
1218     friend class GrPathRendering;
1219     friend class GrTextUtils;
1220     friend class GrGLPathRendering;
1221     friend class SkScalerContext;
1222     friend class SkTextBaseIter;
1223     friend class SkCanonicalizePaint;
1224 };
1225 
1226 #endif
1227