Home | History | Annotate | Download | only in core
      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 "SkRefCnt.h"
     16 
     17 class SkAutoDescriptor;
     18 class SkAutoGlyphCache;
     19 class SkColorFilter;
     20 class SkData;
     21 class SkDescriptor;
     22 class SkDrawLooper;
     23 class SkReadBuffer;
     24 class SkWriteBuffer;
     25 class SkGlyph;
     26 struct SkRect;
     27 class SkGlyphCache;
     28 class SkImageFilter;
     29 class SkMaskFilter;
     30 class SkPath;
     31 class SkPathEffect;
     32 struct SkPoint;
     33 class SkShader;
     34 class SkSurfaceProps;
     35 class SkTextBlob;
     36 class SkTypeface;
     37 
     38 /** \class SkPaint
     39     SkPaint controls options applied when drawing and measuring. SkPaint collects all
     40     options outside of the SkCanvas clip and SkCanvas matrix.
     41 
     42     Various options apply to text, strokes and fills, and images.
     43 
     44     Some options may not be implemented on all platforms; in these cases, setting
     45     the option has no effect. Some options are conveniences that duplicate SkCanvas
     46     functionality; for instance, text size is identical to matrix scale.
     47 
     48     SkPaint options are rarely exclusive; each option modifies a stage of the drawing
     49     pipeline and multiple pipeline stages may be affected by a single SkPaint.
     50 
     51     SkPaint collects effects and filters that describe single-pass and multiple-pass
     52     algorithms that alter the drawing geometry, color, and transparency. For instance,
     53     SkPaint does not directly implement dashing or blur, but contains the objects that do so.
     54 
     55     The objects contained by SkPaint are opaque, and cannot be edited outside of the SkPaint
     56     to affect it. The implementation is free to defer computations associated with the
     57     SkPaint, or ignore them altogether. For instance, some GPU implementations draw all
     58     SkPath geometries with anti-aliasing, regardless of how SkPaint::kAntiAlias_Flag
     59     is set in SkPaint.
     60 
     61     SkPaint describes a single color, a single font, a single image quality, and so on.
     62     Multiple colors are drawn either by using multiple paints or with objects like
     63     SkShader attached to SkPaint.
     64 */
     65 class SK_API SkPaint {
     66 public:
     67 
     68     /** Constructs SkPaint with default values.
     69 
     70         @return  default initialized SkPaint
     71     */
     72     SkPaint();
     73 
     74     /** Makes a shallow copy of SkPaint. SkTypeface, SkPathEffect, SkShader,
     75         SkMaskFilter, SkColorFilter, SkDrawLooper, and SkImageFilter are shared
     76         between the original paint and the copy. Objects containing SkRefCnt increment
     77         their references by one.
     78 
     79         The referenced objects SkPathEffect, SkShader, SkMaskFilter, SkColorFilter,
     80         SkDrawLooper, and SkImageFilter cannot be modified after they are created.
     81         This prevents objects with SkRefCnt from being modified once SkPaint refers to them.
     82 
     83         @param paint  original to copy
     84         @return       shallow copy of paint
     85     */
     86     SkPaint(const SkPaint& paint);
     87 
     88     /** Implements a move constructor to avoid increasing the reference counts
     89         of objects referenced by the paint.
     90 
     91         After the call, paint is undefined, and can be safely destructed.
     92 
     93         @param paint  original to move
     94         @return       content of paint
     95     */
     96     SkPaint(SkPaint&& paint);
     97 
     98     /** Decreases SkPaint SkRefCnt of owned objects: SkTypeface, SkPathEffect, SkShader,
     99         SkMaskFilter, SkColorFilter, SkDrawLooper, and SkImageFilter. If the
    100         objects containing SkRefCnt go to zero, they are deleted.
    101     */
    102     ~SkPaint();
    103 
    104     /** Makes a shallow copy of SkPaint. SkTypeface, SkPathEffect, SkShader,
    105         SkMaskFilter, SkColorFilter, SkDrawLooper, and SkImageFilter are shared
    106         between the original paint and the copy. Objects containing SkRefCnt in the
    107         prior destination are decreased by one, and the referenced objects are deleted if the
    108         resulting count is zero. Objects containing SkRefCnt in the parameter paint
    109         are increased by one. paint is unmodified.
    110 
    111         @param paint  original to copy
    112         @return       content of paint
    113     */
    114     SkPaint& operator=(const SkPaint& paint);
    115 
    116     /** Moves the paint to avoid increasing the reference counts
    117         of objects referenced by the paint parameter. Objects containing SkRefCnt in the
    118         prior destination are decreased by one; those objects are deleted if the resulting count
    119         is zero.
    120 
    121         After the call, paint is undefined, and can be safely destructed.
    122 
    123         @param paint  original to move
    124         @return       content of paint
    125     */
    126     SkPaint& operator=(SkPaint&& paint);
    127 
    128     /** Compares a and b, and returns true if a and b are equivalent. May return false
    129         if SkTypeface, SkPathEffect, SkShader, SkMaskFilter, SkColorFilter,
    130         SkDrawLooper, or SkImageFilter have identical contents but different pointers.
    131 
    132         @param a  SkPaint to compare
    133         @param b  SkPaint to compare
    134         @return   true if SkPaint pair are equivalent
    135     */
    136     SK_API friend bool operator==(const SkPaint& a, const SkPaint& b);
    137 
    138     /** Compares a and b, and returns true if a and b are not equivalent. May return true
    139         if SkTypeface, SkPathEffect, SkShader, SkMaskFilter, SkColorFilter,
    140         SkDrawLooper, or SkImageFilter have identical contents but different pointers.
    141 
    142         @param a  SkPaint to compare
    143         @param b  SkPaint to compare
    144         @return   true if SkPaint pair are not equivalent
    145     */
    146     friend bool operator!=(const SkPaint& a, const SkPaint& b) {
    147         return !(a == b);
    148     }
    149 
    150     /** Returns a hash generated from SkPaint values and pointers.
    151         Identical hashes guarantee that the paints are
    152         equivalent, but differing hashes do not guarantee that the paints have differing
    153         contents.
    154 
    155         If operator==(const SkPaint& a, const SkPaint& b) returns true for two paints,
    156         their hashes are also equal.
    157 
    158         The hash returned is platform and implementation specific.
    159 
    160         @return  a shallow hash
    161     */
    162     uint32_t getHash() const;
    163 
    164     /** Serializes SkPaint into a buffer. A companion unflatten() call
    165         can reconstitute the paint at a later time.
    166 
    167         @param buffer  SkWriteBuffer receiving the flattened SkPaint data
    168     */
    169     void flatten(SkWriteBuffer& buffer) const;
    170 
    171     /** Populates SkPaint, typically from a serialized stream, created by calling
    172         flatten() at an earlier time.
    173 
    174         SkReadBuffer class is not public, so unflatten() cannot be meaningfully called
    175         by the client.
    176 
    177         @param buffer  serialized data describing SkPaint content
    178         @return        false if the buffer contains invalid data
    179     */
    180     bool unflatten(SkReadBuffer& buffer);
    181 
    182     /** Sets all SkPaint contents to their initial values. This is equivalent to replacing
    183         SkPaint with the result of SkPaint().
    184     */
    185     void reset();
    186 
    187     /** \enum SkPaint::Hinting
    188         Hinting adjusts the glyph outlines so that the shape provides a uniform
    189         look at a given point size on font engines that support it. Hinting may have a
    190         muted effect or no effect at all depending on the platform.
    191 
    192         The four levels roughly control corresponding features on platforms that use FreeType
    193         as the font engine.
    194     */
    195     enum Hinting {
    196         /** Leaves glyph outlines unchanged from their native representation.
    197             With FreeType, this is equivalent to the FT_LOAD_NO_HINTING
    198             bit-field constant supplied to FT_Load_Glyph, which indicates that the vector
    199             outline being loaded should not be fitted to the pixel grid but simply scaled
    200             to 26.6 fractional pixels.
    201         */
    202         kNo_Hinting     = 0,
    203 
    204         /** Modifies glyph outlines minimally to improve constrast.
    205             With FreeType, this is equivalent in spirit to the
    206             FT_LOAD_TARGET_LIGHT value supplied to FT_Load_Glyph. It chooses a
    207             lighter hinting algorithm for non-monochrome modes.
    208             Generated glyphs may be fuzzy but better resemble their original shape.
    209         */
    210         kSlight_Hinting = 1,
    211 
    212         /** Modifies glyph outlines to improve constrast. This is the default.
    213             With FreeType, this supplies FT_LOAD_TARGET_NORMAL to FT_Load_Glyph,
    214             choosing the default hinting algorithm, which is optimized for standard
    215             gray-level rendering.
    216         */
    217         kNormal_Hinting = 2,
    218 
    219         /** Modifies glyph outlines for maxiumum constrast. With FreeType, this selects
    220             FT_LOAD_TARGET_LCD or FT_LOAD_TARGET_LCD_V if kLCDRenderText_Flag is set.
    221             FT_LOAD_TARGET_LCD is a variant of FT_LOAD_TARGET_NORMAL optimized for
    222             horizontally decimated LCD displays; FT_LOAD_TARGET_LCD_V is a
    223             variant of FT_LOAD_TARGET_NORMAL optimized for vertically decimated LCD displays.
    224         */
    225         kFull_Hinting   = 3,
    226     };
    227 
    228     /** Returns level of glyph outline adjustment.
    229 
    230         @return  one of: kNo_Hinting, kSlight_Hinting, kNormal_Hinting, kFull_Hinting
    231     */
    232     Hinting getHinting() const {
    233         return static_cast<Hinting>(fBitfields.fHinting);
    234     }
    235 
    236     /** Sets level of glyph outline adjustment.
    237         Does not check for valid values of hintingLevel.
    238 
    239         @param hintingLevel  one of: kNo_Hinting, kSlight_Hinting, kNormal_Hinting, kFull_Hinting
    240     */
    241     void setHinting(Hinting hintingLevel);
    242 
    243     /** \enum SkPaint::Flags
    244         The bit values stored in Flags.
    245         The default value for Flags, normally zero, can be changed at compile time
    246         with a custom definition of SkPaintDefaults_Flags.
    247         All flags can be read and written explicitly; Flags allows manipulating
    248         multiple settings at once.
    249     */
    250     enum Flags {
    251         kAntiAlias_Flag          = 0x01,   //!< mask for setting anti-alias
    252         kDither_Flag             = 0x04,   //!< mask for setting dither
    253         kFakeBoldText_Flag       = 0x20,   //!< mask for setting fake bold
    254         kLinearText_Flag         = 0x40,   //!< mask for setting linear text
    255         kSubpixelText_Flag       = 0x80,   //!< mask for setting subpixel text
    256         kDevKernText_Flag        = 0x100,  //!< mask for setting full hinting spacing
    257         kLCDRenderText_Flag      = 0x200,  //!< mask for setting LCD text
    258         kEmbeddedBitmapText_Flag = 0x400,  //!< mask for setting font embedded bitmaps
    259         kAutoHinting_Flag        = 0x800,  //!< mask for setting auto-hinting
    260         kVerticalText_Flag       = 0x1000, //!< mask for setting vertical text
    261 
    262         /** Hack for GDI -- do not use if you can help it */
    263         kGenA8FromLCD_Flag       = 0x2000,
    264 
    265         /** mask of all Flags, including private flags and flags reserved for future use */
    266         kAllFlags                = 0xFFFF,
    267     };
    268 
    269     #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
    270     enum ReserveFlags {
    271         kUnderlineText_ReserveFlag  = 0x08, //!< deprecated
    272         kStrikeThruText_ReserveFlag = 0x10, //!< deprecated
    273     };
    274     #endif
    275 
    276     /** Returns paint settings described by SkPaint::Flags. Each setting uses one
    277         bit, and can be tested with SkPaint::Flags members.
    278 
    279         @return  zero, one, or more bits described by SkPaint::Flags
    280     */
    281     uint32_t getFlags() const { return fBitfields.fFlags; }
    282 
    283     /** Replaces SkPaint::Flags with flags, the union of the SkPaint::Flags members.
    284         All SkPaint::Flags members may be cleared, or one or more may be set.
    285 
    286         @param flags  union of SkPaint::Flags for SkPaint
    287     */
    288     void setFlags(uint32_t flags);
    289 
    290     /** If true, pixels on the active edges of SkPath may be drawn with partial transparency.
    291 
    292         Equivalent to getFlags() masked with kAntiAlias_Flag.
    293 
    294         @return  kAntiAlias_Flag state
    295     */
    296     bool isAntiAlias() const {
    297         return SkToBool(this->getFlags() & kAntiAlias_Flag);
    298     }
    299 
    300     /** Requests, but does not require, that SkPath edge pixels draw opaque or with
    301         partial transparency.
    302 
    303         Sets kAntiAlias_Flag if aa is true.
    304         Clears kAntiAlias_Flag if aa is false.
    305 
    306         @param aa  setting for kAntiAlias_Flag
    307     */
    308     void setAntiAlias(bool aa);
    309 
    310     /** If true, color error may be distributed to smooth color transition.
    311 
    312         Equivalent to getFlags() masked with kDither_Flag.
    313 
    314         @return  kDither_Flag state
    315     */
    316     bool isDither() const {
    317         return SkToBool(this->getFlags() & kDither_Flag);
    318     }
    319 
    320     /** Requests, but does not require, to distribute color error.
    321 
    322         Sets kDither_Flag if dither is true.
    323         Clears kDither_Flag if dither is false.
    324 
    325         @param dither  setting for kDither_Flag
    326     */
    327     void setDither(bool dither);
    328 
    329     /** If true, text is converted to SkPath before drawing and measuring.
    330 
    331         Equivalent to getFlags() masked with kLinearText_Flag.
    332 
    333         @return  kLinearText_Flag state
    334     */
    335     bool isLinearText() const {
    336         return SkToBool(this->getFlags() & kLinearText_Flag);
    337     }
    338 
    339     /** If true, text is converted to SkPath before drawing and measuring.
    340         By default, kLinearText_Flag is clear.
    341 
    342         Sets kLinearText_Flag if linearText is true.
    343         Clears kLinearText_Flag if linearText is false.
    344 
    345         @param linearText  setting for kLinearText_Flag
    346     */
    347     void setLinearText(bool linearText);
    348 
    349     /** If true, glyphs at different sub-pixel positions may differ on pixel edge coverage.
    350 
    351         Equivalent to getFlags() masked with kSubpixelText_Flag.
    352 
    353         @return  kSubpixelText_Flag state
    354     */
    355     bool isSubpixelText() const {
    356         return SkToBool(this->getFlags() & kSubpixelText_Flag);
    357     }
    358 
    359     /** Requests, but does not require, that glyphs respect sub-pixel positioning.
    360 
    361         Sets kSubpixelText_Flag if subpixelText is true.
    362         Clears kSubpixelText_Flag if subpixelText is false.
    363 
    364         @param subpixelText  setting for kSubpixelText_Flag
    365     */
    366     void setSubpixelText(bool subpixelText);
    367 
    368     /** If true, glyphs may use LCD striping to improve glyph edges.
    369 
    370         Returns true if SkPaint::Flags kLCDRenderText_Flag is set.
    371 
    372         @return  kLCDRenderText_Flag state
    373     */
    374     bool isLCDRenderText() const {
    375         return SkToBool(this->getFlags() & kLCDRenderText_Flag);
    376     }
    377 
    378     /** Requests, but does not require, that glyphs use LCD striping for glyph edges.
    379 
    380         Sets kLCDRenderText_Flag if lcdText is true.
    381         Clears kLCDRenderText_Flag if lcdText is false.
    382 
    383         @param lcdText  setting for kLCDRenderText_Flag
    384     */
    385     void setLCDRenderText(bool lcdText);
    386 
    387     /** If true, font engine may return glyphs from font bitmaps instead of from outlines.
    388 
    389         Equivalent to getFlags() masked with kEmbeddedBitmapText_Flag.
    390 
    391         @return  kEmbeddedBitmapText_Flag state
    392     */
    393     bool isEmbeddedBitmapText() const {
    394         return SkToBool(this->getFlags() & kEmbeddedBitmapText_Flag);
    395     }
    396 
    397     /** Requests, but does not require, to use bitmaps in fonts instead of outlines.
    398 
    399         Sets kEmbeddedBitmapText_Flag if useEmbeddedBitmapText is true.
    400         Clears kEmbeddedBitmapText_Flag if useEmbeddedBitmapText is false.
    401 
    402         @param useEmbeddedBitmapText  setting for kEmbeddedBitmapText_Flag
    403     */
    404     void setEmbeddedBitmapText(bool useEmbeddedBitmapText);
    405 
    406     /** If true, and if SkPaint::Hinting is set to kNormal_Hinting or kFull_Hinting, and if
    407         platform uses FreeType as the font manager, instruct the font manager to always hint
    408         glyphs.
    409 
    410         Equivalent to getFlags() masked with kAutoHinting_Flag.
    411 
    412         @return  kAutoHinting_Flag state
    413     */
    414     bool isAutohinted() const {
    415         return SkToBool(this->getFlags() & kAutoHinting_Flag);
    416     }
    417 
    418     /** If SkPaint::Hinting is set to kNormal_Hinting or kFull_Hinting and useAutohinter is set,
    419         instruct the font manager to always hint glyphs.
    420         auto-hinting has no effect if SkPaint::Hinting is set to kNo_Hinting or
    421         kSlight_Hinting.
    422 
    423         Only affects platforms that use FreeType as the font manager.
    424 
    425         Sets kAutoHinting_Flag if useAutohinter is true.
    426         Clears kAutoHinting_Flag if useAutohinter is false.
    427 
    428         @param useAutohinter  setting for kAutoHinting_Flag
    429     */
    430     void setAutohinted(bool useAutohinter);
    431 
    432     /** If true, glyphs are drawn top to bottom instead of left to right.
    433 
    434         Equivalent to getFlags() masked with kVerticalText_Flag.
    435 
    436         @return  kVerticalText_Flag state
    437     */
    438     bool isVerticalText() const {
    439         return SkToBool(this->getFlags() & kVerticalText_Flag);
    440     }
    441 
    442     /** If true, text advance positions the next glyph below the previous glyph instead of to the
    443         right of previous glyph.
    444 
    445         Sets kVerticalText_Flag if vertical is true.
    446         Clears kVerticalText_Flag if vertical is false.
    447 
    448         @param verticalText  setting for kVerticalText_Flag
    449     */
    450     void setVerticalText(bool verticalText);
    451 
    452     /** If true, approximate bold by increasing the stroke width when creating glyph bitmaps
    453         from outlines.
    454 
    455         Equivalent to getFlags() masked with kFakeBoldText_Flag.
    456 
    457         @return  kFakeBoldText_Flag state
    458     */
    459     bool isFakeBoldText() const {
    460         return SkToBool(this->getFlags() & kFakeBoldText_Flag);
    461     }
    462 
    463     /** Use increased stroke width when creating glyph bitmaps to approximate a bold typeface.
    464 
    465         Sets kFakeBoldText_Flag if fakeBoldText is true.
    466         Clears kFakeBoldText_Flag if fakeBoldText is false.
    467 
    468         @param fakeBoldText  setting for kFakeBoldText_Flag
    469     */
    470     void setFakeBoldText(bool fakeBoldText);
    471 
    472     /** Returns if character spacing may be adjusted by the hinting difference.
    473 
    474         Equivalent to getFlags() masked with kDevKernText_Flag.
    475 
    476         @return  kDevKernText_Flag state
    477     */
    478     bool isDevKernText() const {
    479         return SkToBool(this->getFlags() & kDevKernText_Flag);
    480     }
    481 
    482     /** Requests, but does not require, to use hinting to adjust glyph spacing.
    483 
    484         Sets kDevKernText_Flag if devKernText is true.
    485         Clears kDevKernText_Flag if devKernText is false.
    486 
    487         @param devKernText  setting for devKernText
    488     */
    489     void setDevKernText(bool devKernText);
    490 
    491     /** Returns SkFilterQuality, the image filtering level. A lower setting
    492         draws faster; a higher setting looks better when the image is scaled.
    493 
    494         @return  one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
    495                  kMedium_SkFilterQuality, kHigh_SkFilterQuality
    496     */
    497     SkFilterQuality getFilterQuality() const {
    498         return (SkFilterQuality)fBitfields.fFilterQuality;
    499     }
    500 
    501     /** Sets SkFilterQuality, the image filtering level. A lower setting
    502         draws faster; a higher setting looks better when the image is scaled.
    503         Does not check to see if quality is valid.
    504 
    505         @param quality  one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
    506                         kMedium_SkFilterQuality, kHigh_SkFilterQuality
    507     */
    508     void setFilterQuality(SkFilterQuality quality);
    509 
    510     /** \enum SkPaint::Style
    511         Set Style to fill, stroke, or both fill and stroke geometry.
    512         The stroke and fill
    513         share all paint attributes; for instance, they are drawn with the same color.
    514 
    515         Use kStrokeAndFill_Style to avoid hitting the same pixels twice with a stroke draw and
    516         a fill draw.
    517     */
    518     enum Style {
    519         /** Set to fill geometry.
    520             Applies to SkRect, SkRegion, SkRRect, circles, ovals, SkPath, and text.
    521             SkBitmap, SkImage, patches, SkRegion, sprites, and vertices are painted as if
    522             kFill_Style is set, and ignore the set Style.
    523             The FillType specifies additional rules to fill the area outside the path edge,
    524             and to create an unfilled hole inside the shape.
    525             Style is set to kFill_Style by default.
    526         */
    527         kFill_Style,
    528 
    529         /** Set to stroke geometry.
    530             Applies to SkRect, SkRegion, SkRRect, arcs, circles, ovals, SkPath, and text.
    531             Arcs, lines, and points, are always drawn as if kStroke_Style is set,
    532             and ignore the set Style.
    533             The stroke construction is unaffected by the FillType.
    534         */
    535         kStroke_Style,
    536 
    537         /** Set to stroke and fill geometry.
    538             Applies to SkRect, SkRegion, SkRRect, circles, ovals, SkPath, and text.
    539             SkPath is treated as if it is set to SkPath::kWinding_FillType,
    540             and the set FillType is ignored.
    541         */
    542         kStrokeAndFill_Style,
    543     };
    544 
    545     enum {
    546         /** The number of different Style values defined.
    547             May be used to verify that Style is a legal value.
    548         */
    549         kStyleCount = kStrokeAndFill_Style + 1,
    550     };
    551 
    552     /** Whether the geometry is filled, stroked, or filled and stroked.
    553 
    554         @return  one of:kFill_Style, kStroke_Style, kStrokeAndFill_Style
    555     */
    556     Style getStyle() const { return (Style)fBitfields.fStyle; }
    557 
    558     /** Sets whether the geometry is filled, stroked, or filled and stroked.
    559         Has no effect if style is not a legal SkPaint::Style value.
    560 
    561         @param style  one of: kFill_Style, kStroke_Style, kStrokeAndFill_Style
    562     */
    563     void setStyle(Style style);
    564 
    565     /** Retrieves alpha and RGB, unpremultiplied, packed into 32 bits.
    566         Use helpers SkColorGetA(), SkColorGetR(), SkColorGetG(), and SkColorGetB() to extract
    567         a color component.
    568 
    569         @return  unpremultiplied ARGB
    570     */
    571     SkColor getColor() const { return fColor; }
    572 
    573     /** Sets alpha and RGB used when stroking and filling. The color is a 32-bit value,
    574         unpremultiplied, packing 8-bit components for alpha, red, blue, and green.
    575 
    576         @param color  unpremultiplied ARGB
    577     */
    578     void setColor(SkColor color);
    579 
    580     /** Retrieves alpha from the color used when stroking and filling.
    581 
    582         @return  alpha ranging from zero, fully transparent, to 255, fully opaque
    583     */
    584     uint8_t getAlpha() const { return SkToU8(SkColorGetA(fColor)); }
    585 
    586     /** Replaces alpha, leaving RGB
    587         unchanged. An out of range value triggers an assert in the debug
    588         build. a is a value from zero to 255.
    589         a set to zero makes color fully transparent; a set to 255 makes color
    590         fully opaque.
    591 
    592         @param a  alpha component of color
    593     */
    594     void setAlpha(U8CPU a);
    595 
    596     /** Sets color used when drawing solid fills. The color components range from 0 to 255.
    597         The color is unpremultiplied; alpha sets the transparency independent of RGB.
    598 
    599         @param a  amount of color alpha, from fully transparent (0) to fully opaque (255)
    600         @param r  amount of color rgb red, from no red (0) to full red (255)
    601         @param g  amount of color rgb green, from no green (0) to full green (255)
    602         @param b  amount of color rgb blue, from no blue (0) to full blue (255)
    603     */
    604     void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
    605 
    606     /** Returns the thickness of the pen used by SkPaint to
    607         outline the shape.
    608 
    609         @return  zero for hairline, greater than zero for pen thickness
    610     */
    611     SkScalar getStrokeWidth() const { return fWidth; }
    612 
    613     /** Sets the thickness of the pen used by the paint to
    614         outline the shape.
    615         Has no effect if width is less than zero.
    616 
    617         @param width  zero thickness for hairline; greater than zero for pen thickness
    618     */
    619     void setStrokeWidth(SkScalar width);
    620 
    621     /** The limit at which a sharp corner is drawn beveled.
    622 
    623         @return  zero and greater miter limit
    624     */
    625     SkScalar getStrokeMiter() const { return fMiterLimit; }
    626 
    627     /** The limit at which a sharp corner is drawn beveled.
    628         Valid values are zero and greater.
    629         Has no effect if miter is less than zero.
    630 
    631         @param miter  zero and greater miter limit
    632     */
    633     void setStrokeMiter(SkScalar miter);
    634 
    635     /** \enum SkPaint::Cap
    636         Cap draws at the beginning and end of an open path contour.
    637     */
    638     enum Cap {
    639         kButt_Cap,                  //!< Does not extend the stroke past the beginning or the end.
    640 
    641         /** Adds a circle with a diameter equal to stroke width at the beginning
    642             and end.
    643         */
    644         kRound_Cap,
    645 
    646         /** Adds a square with sides equal to stroke width at the beginning
    647             and end. The square sides are parallel to the initial and final direction
    648             of the stroke.
    649         */
    650         kSquare_Cap,
    651         kLast_Cap    = kSquare_Cap, //!< Equivalent to the largest value for Cap.
    652 
    653         /** Equivalent to kButt_Cap.
    654             Cap is set to kButt_Cap by default.
    655         */
    656         kDefault_Cap = kButt_Cap,
    657     };
    658 
    659     /** The number of different SkPaint::Cap values defined.
    660         May be used to verify that SkPaint::Cap is a legal value.*/
    661     static constexpr int kCapCount = kLast_Cap + 1;
    662 
    663     /** \enum SkPaint::Join
    664         Join specifies how corners are drawn when a shape is stroked. Join
    665         affects the four corners of a stroked rectangle, and the connected segments in a
    666         stroked path.
    667 
    668         Choose miter join to draw sharp corners. Choose round join to draw a circle with a
    669         radius equal to the stroke width on top of the corner. Choose bevel join to minimally
    670         connect the thick strokes.
    671 
    672         The fill path constructed to describe the stroked path respects the join setting but may
    673         not contain the actual join. For instance, a fill path constructed with round joins does
    674         not necessarily include circles at each connected segment.
    675     */
    676     enum Join {
    677         /** Extends the outside corner to the extent allowed by miter limit.
    678             If the extension exceeds miter limit, kBevel_Join is used instead.
    679         */
    680         kMiter_Join,
    681 
    682         /** Adds a circle with a diameter of stroke width at the sharp corner. */
    683         kRound_Join,
    684         kBevel_Join,                 //!< Connects the outside edges of the sharp corner.
    685         kLast_Join    = kBevel_Join, //!< Equivalent to the largest value for Join.
    686 
    687         /** Equivalent to kMiter_Join.
    688             Join is set to kMiter_Join by default.
    689         */
    690         kDefault_Join = kMiter_Join,
    691     };
    692 
    693     /** The number of different SkPaint::Join values defined.
    694         May be used to verify that SkPaint::Join is a legal value.*/
    695     static constexpr int kJoinCount = kLast_Join + 1;
    696 
    697     /** The geometry drawn at the beginning and end of strokes.
    698 
    699         @return  one of: kButt_Cap, kRound_Cap, kSquare_Cap
    700     */
    701     Cap getStrokeCap() const { return (Cap)fBitfields.fCapType; }
    702 
    703     /** The geometry drawn at the beginning and end of strokes.
    704 
    705         @param cap  one of: kButt_Cap, kRound_Cap, kSquare_Cap;
    706                     has no effect if cap is not valid
    707     */
    708     void setStrokeCap(Cap cap);
    709 
    710     /** The geometry drawn at the corners of strokes.
    711 
    712         @return  one of: kMiter_Join, kRound_Join, kBevel_Join
    713     */
    714     Join getStrokeJoin() const { return (Join)fBitfields.fJoinType; }
    715 
    716     /** The geometry drawn at the corners of strokes.
    717 
    718         @param join  one of: kMiter_Join, kRound_Join, kBevel_Join;
    719                      otherwise, has no effect
    720     */
    721     void setStrokeJoin(Join join);
    722 
    723     /** The filled equivalent of the stroked path.
    724 
    725         @param src       SkPath read to create a filled version
    726         @param dst       resulting SkPath; may be the same as src, but may not be nullptr
    727         @param cullRect  optional limit passed to SkPathEffect
    728         @param resScale  if > 1, increase precision, else if (0 < res < 1) reduce precision
    729                          to favor speed and size
    730         @return          true if the path represents style fill, or false if it represents hairline
    731     */
    732     bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
    733                      SkScalar resScale = 1) const;
    734 
    735     /** The filled equivalent of the stroked path.
    736 
    737         Replaces dst with the src path modified by SkPathEffect and style stroke.
    738         SkPathEffect, if any, is not culled. stroke width is created with default precision.
    739 
    740         @param src  SkPath read to create a filled version
    741         @param dst  resulting SkPath dst may be the same as src, but may not be nullptr
    742         @return     true if the path represents style fill, or false if it represents hairline
    743     */
    744     bool getFillPath(const SkPath& src, SkPath* dst) const {
    745         return this->getFillPath(src, dst, nullptr, 1);
    746     }
    747 
    748     /** Optional colors used when filling a path, such as a gradient.
    749 
    750         Does not alter SkShader SkRefCnt.
    751 
    752         @return  SkShader if previously set, nullptr otherwise
    753     */
    754     SkShader* getShader() const { return fShader.get(); }
    755 
    756     /** Optional colors used when filling a path, such as a gradient.
    757 
    758         Increases SkShader SkRefCnt by one.
    759 
    760         @return  SkShader if previously set, nullptr otherwise
    761     */
    762     sk_sp<SkShader> refShader() const;
    763 
    764     /** Optional colors used when filling a path, such as a gradient.
    765 
    766         Sets SkShader to shader, decreasing SkRefCnt of the previous SkShader.
    767         Increments shader SkRefCnt by one.
    768 
    769         @param shader  how geometry is filled with color; if nullptr, color is used instead
    770     */
    771     void setShader(sk_sp<SkShader> shader);
    772 
    773     /** Returns SkColorFilter if set, or nullptr.
    774         Does not alter SkColorFilter SkRefCnt.
    775 
    776         @return  SkColorFilter if previously set, nullptr otherwise
    777     */
    778     SkColorFilter* getColorFilter() const { return fColorFilter.get(); }
    779 
    780     /** Returns SkColorFilter if set, or nullptr.
    781         Increases SkColorFilter SkRefCnt by one.
    782 
    783         @return  SkColorFilter if set, or nullptr
    784     */
    785     sk_sp<SkColorFilter> refColorFilter() const;
    786 
    787     /** Sets SkColorFilter to filter, decreasing SkRefCnt of the previous
    788         SkColorFilter. Pass nullptr to clear SkColorFilter.
    789 
    790         Increments filter SkRefCnt by one.
    791 
    792         @param colorFilter  SkColorFilter to apply to subsequent draw
    793     */
    794     void setColorFilter(sk_sp<SkColorFilter> colorFilter);
    795 
    796     /** Returns SkBlendMode.
    797         By default, returns SkBlendMode::kSrcOver.
    798 
    799         @return  mode used to combine source color with destination color
    800     */
    801     SkBlendMode getBlendMode() const { return (SkBlendMode)fBlendMode; }
    802 
    803     /** Returns true if SkBlendMode is SkBlendMode::kSrcOver, the default.
    804 
    805         @return  true if SkBlendMode is SkBlendMode::kSrcOver
    806     */
    807     bool isSrcOver() const { return (SkBlendMode)fBlendMode == SkBlendMode::kSrcOver; }
    808 
    809     /** Sets SkBlendMode to mode.
    810         Does not check for valid input.
    811 
    812         @param mode  SkBlendMode used to combine source color and destination
    813     */
    814     void setBlendMode(SkBlendMode mode) { fBlendMode = (unsigned)mode; }
    815 
    816     /** Returns SkPathEffect if set, or nullptr.
    817         Does not alter SkPathEffect SkRefCnt.
    818 
    819         @return  SkPathEffect if previously set, nullptr otherwise
    820     */
    821     SkPathEffect* getPathEffect() const { return fPathEffect.get(); }
    822 
    823     /** Returns SkPathEffect if set, or nullptr.
    824         Increases SkPathEffect SkRefCnt by one.
    825 
    826         @return  SkPathEffect if previously set, nullptr otherwise
    827     */
    828     sk_sp<SkPathEffect> refPathEffect() const;
    829 
    830     /** Sets SkPathEffect to pathEffect, decreasing SkRefCnt of the previous
    831         SkPathEffect. Pass nullptr to leave the path geometry unaltered.
    832 
    833         Increments pathEffect SkRefCnt by one.
    834 
    835         @param pathEffect  replace SkPath with a modification when drawn
    836     */
    837     void setPathEffect(sk_sp<SkPathEffect> pathEffect);
    838 
    839     /** Returns SkMaskFilter if set, or nullptr.
    840         Does not alter SkMaskFilter SkRefCnt.
    841 
    842         @return  SkMaskFilter if previously set, nullptr otherwise
    843     */
    844     SkMaskFilter* getMaskFilter() const { return fMaskFilter.get(); }
    845 
    846     /** Returns SkMaskFilter if set, or nullptr.
    847 
    848         Increases SkMaskFilter SkRefCnt by one.
    849 
    850         @return  SkMaskFilter if previously set, nullptr otherwise
    851     */
    852     sk_sp<SkMaskFilter> refMaskFilter() const;
    853 
    854     /** Sets SkMaskFilter to maskFilter, decreasing SkRefCnt of the previous
    855         SkMaskFilter. Pass nullptr to clear SkMaskFilter and leave SkMaskFilter effect on
    856         mask alpha unaltered.
    857 
    858         Increments maskFilter SkRefCnt by one.
    859 
    860         @param maskFilter  modifies clipping mask generated from drawn geometry
    861     */
    862     void setMaskFilter(sk_sp<SkMaskFilter> maskFilter);
    863 
    864     /** Returns SkTypeface if set, or nullptr.
    865         Increments SkTypeface SkRefCnt by one.
    866 
    867         @return  SkTypeface if previously set, nullptr otherwise
    868     */
    869     SkTypeface* getTypeface() const { return fTypeface.get(); }
    870 
    871     /** Increases SkTypeface SkRefCnt by one.
    872 
    873         @return  SkTypeface if previously set, nullptr otherwise
    874     */
    875     sk_sp<SkTypeface> refTypeface() const;
    876 
    877     /** Sets SkTypeface to typeface, decreasing SkRefCnt of the previous SkTypeface.
    878         Pass nullptr to clear SkTypeface and use the default typeface. Increments
    879         typeface SkRefCnt by one.
    880 
    881         @param typeface  font and style used to draw text
    882     */
    883     void setTypeface(sk_sp<SkTypeface> typeface);
    884 
    885     /** Returns SkImageFilter if set, or nullptr.
    886         Does not alter SkImageFilter SkRefCnt.
    887 
    888         @return  SkImageFilter if previously set, nullptr otherwise
    889     */
    890     SkImageFilter* getImageFilter() const { return fImageFilter.get(); }
    891 
    892     /** Returns SkImageFilter if set, or nullptr.
    893         Increases SkImageFilter SkRefCnt by one.
    894 
    895         @return  SkImageFilter if previously set, nullptr otherwise
    896     */
    897     sk_sp<SkImageFilter> refImageFilter() const;
    898 
    899     /** Sets SkImageFilter to imageFilter, decreasing SkRefCnt of the previous
    900         SkImageFilter. Pass nullptr to clear SkImageFilter, and remove SkImageFilter effect
    901         on drawing.
    902 
    903         Increments imageFilter SkRefCnt by one.
    904 
    905         @param imageFilter  how SkImage is sampled when transformed
    906     */
    907     void setImageFilter(sk_sp<SkImageFilter> imageFilter);
    908 
    909     /** Returns SkDrawLooper if set, or nullptr.
    910         Does not alter SkDrawLooper SkRefCnt.
    911 
    912         @return  SkDrawLooper if previously set, nullptr otherwise
    913     */
    914     SkDrawLooper* getDrawLooper() const { return fDrawLooper.get(); }
    915 
    916     /** Returns SkDrawLooper if set, or nullptr.
    917         Increases SkDrawLooper SkRefCnt by one.
    918 
    919         @return  SkDrawLooper if previously set, nullptr otherwise
    920     */
    921     sk_sp<SkDrawLooper> refDrawLooper() const;
    922 
    923     /** Deprecated.
    924         (see skbug.com/6259)
    925     */
    926     SkDrawLooper* getLooper() const { return fDrawLooper.get(); }
    927 
    928     /** Sets SkDrawLooper to drawLooper, decreasing SkRefCnt of the previous
    929         drawLooper.  Pass nullptr to clear SkDrawLooper and leave SkDrawLooper effect on
    930         drawing unaltered.
    931 
    932         Increments drawLooper SkRefCnt by one.
    933 
    934         @param drawLooper  iterates through drawing one or more time, altering SkPaint
    935     */
    936     void setDrawLooper(sk_sp<SkDrawLooper> drawLooper);
    937 
    938     /** Deprecated.
    939         (see skbug.com/6259)
    940     */
    941     void setLooper(sk_sp<SkDrawLooper> drawLooper);
    942 
    943     /** \enum SkPaint::Align
    944         Align adjusts the text relative to the text position.
    945         Align affects glyphs drawn with: SkCanvas::drawText, SkCanvas::drawPosText,
    946         SkCanvas::drawPosTextH, SkCanvas::drawTextOnPath,
    947         SkCanvas::drawTextOnPathHV, SkCanvas::drawTextRSXform, SkCanvas::drawTextBlob,
    948         and SkCanvas::drawString;
    949         as well as calls that place text glyphs like getTextWidths() and getTextPath().
    950 
    951         The text position is set by the font for both horizontal and vertical text.
    952         Typically, for horizontal text, the position is to the left side of the glyph on the
    953         base line; and for vertical text, the position is the horizontal center of the glyph
    954         at the caps height.
    955 
    956         Align adjusts the glyph position to center it or move it to abut the position
    957         using the metrics returned by the font.
    958 
    959         Align defaults to kLeft_Align.
    960     */
    961     enum Align {
    962         /** Leaves the glyph at the position computed by the font offset by the text position. */
    963         kLeft_Align,
    964 
    965         /** Moves the glyph half its width if Flags has kVerticalText_Flag clear, and
    966             half its height if Flags has kVerticalText_Flag set.
    967         */
    968         kCenter_Align,
    969 
    970         /** Moves the glyph by its width if Flags has kVerticalText_Flag clear,
    971             and by its height if Flags has kVerticalText_Flag set.
    972         */
    973         kRight_Align,
    974     };
    975 
    976     enum {
    977         kAlignCount = 3, //!< The number of different Align values defined.
    978     };
    979 
    980     /** Returns SkPaint::Align.
    981         Returns kLeft_Align if SkPaint::Align has not been set.
    982 
    983         @return  text placement relative to position
    984     */
    985     Align   getTextAlign() const { return (Align)fBitfields.fTextAlign; }
    986 
    987     /** Sets SkPaint::Align to align.
    988         Has no effect if align is an invalid value.
    989 
    990         @param align  text placement relative to position
    991     */
    992     void    setTextAlign(Align align);
    993 
    994     /** Returns text size in points.
    995 
    996         @return  typographic height of text
    997     */
    998     SkScalar getTextSize() const { return fTextSize; }
    999 
   1000     /** Sets text size in points.
   1001         Has no effect if textSize is not greater than or equal to zero.
   1002 
   1003         @param textSize  typographic height of text
   1004     */
   1005     void setTextSize(SkScalar textSize);
   1006 
   1007     /** Returns text scale x.
   1008         Default value is 1.
   1009 
   1010         @return  text horizontal scale
   1011     */
   1012     SkScalar getTextScaleX() const { return fTextScaleX; }
   1013 
   1014     /** Sets text scale x.
   1015         Default value is 1.
   1016 
   1017         @param scaleX  text horizontal scale
   1018     */
   1019     void setTextScaleX(SkScalar scaleX);
   1020 
   1021     /** Returns text skew x.
   1022         Default value is zero.
   1023 
   1024         @return  additional shear in x-axis relative to y-axis
   1025     */
   1026     SkScalar getTextSkewX() const { return fTextSkewX; }
   1027 
   1028     /** Sets text skew x.
   1029         Default value is zero.
   1030 
   1031         @param skewX  additional shear in x-axis relative to y-axis
   1032     */
   1033     void setTextSkewX(SkScalar skewX);
   1034 
   1035     /** \enum SkPaint::TextEncoding
   1036         TextEncoding determines whether text specifies character codes and their encoded
   1037         size, or glyph indices. Characters are encoded as specified by the Unicode standard.
   1038 
   1039         Character codes encoded size are specified by UTF-8, UTF-16, or UTF-32.
   1040         All character code formats are able to represent all of Unicode, differing only
   1041         in the total storage required.
   1042 
   1043         UTF-8 (RFC 3629) encodes each character as one or more 8-bit bytes.
   1044 
   1045         UTF-16 (RFC 2781) encodes each character as one or two 16-bit words.
   1046 
   1047         UTF-32 encodes each character as one 32-bit word.
   1048 
   1049         font manager uses font data to convert character code points into glyph indices.
   1050         A glyph index is a 16-bit word.
   1051 
   1052         TextEncoding is set to kUTF8_TextEncoding by default.
   1053     */
   1054     enum TextEncoding {
   1055         kUTF8_TextEncoding,    //!< Uses bytes to represent UTF-8 or ASCII.
   1056         kUTF16_TextEncoding,   //!< Uses two byte words to represent most of Unicode.
   1057         kUTF32_TextEncoding,   //!< Uses four byte words to represent all of Unicode.
   1058         kGlyphID_TextEncoding, //!< Uses two byte words to represent glyph indices.
   1059     };
   1060 
   1061     /** Returns SkPaint::TextEncoding.
   1062         SkPaint::TextEncoding determines how character code points are mapped to font glyph indices.
   1063 
   1064         @return  one of: kUTF8_TextEncoding, kUTF16_TextEncoding, kUTF32_TextEncoding, or
   1065                  kGlyphID_TextEncoding
   1066     */
   1067     TextEncoding getTextEncoding() const {
   1068       return (TextEncoding)fBitfields.fTextEncoding;
   1069     }
   1070 
   1071     /** Sets SkPaint::TextEncoding to encoding.
   1072         SkPaint::TextEncoding determines how character code points are mapped to font glyph indices.
   1073         Invalid values for encoding are ignored.
   1074 
   1075         @param encoding  one of: kUTF8_TextEncoding, kUTF16_TextEncoding, kUTF32_TextEncoding, or
   1076                          kGlyphID_TextEncoding
   1077     */
   1078     void setTextEncoding(TextEncoding encoding);
   1079 
   1080     /** \struct SkPaint::FontMetrics
   1081         FontMetrics is filled out by getFontMetrics(). FontMetrics contents reflect the values
   1082         computed by font manager using SkTypeface. Values are set to zero if they are
   1083         not available.
   1084 
   1085         All vertical values relative to the baseline are given y-down. As such, zero is on the
   1086         baseline, negative values are above the baseline, and positive values are below the
   1087         baseline.
   1088 
   1089         fUnderlineThickness and fUnderlinePosition have a bit set in fFlags if their values
   1090         are valid, since their value may be zero.
   1091 
   1092         fStrikeoutThickness and fStrikeoutPosition have a bit set in fFlags if their values
   1093         are valid, since their value may be zero.
   1094     */
   1095     struct FontMetrics {
   1096 
   1097         /** \enum SkPaint::FontMetrics::FontMetricsFlags
   1098             FontMetricsFlags are set in fFlags when underline and strikeout metrics are valid;
   1099             the underline or strikeout metric may be valid and zero.
   1100             Fonts with embedded bitmaps may not have valid underline or strikeout metrics.
   1101         */
   1102         enum FontMetricsFlags {
   1103             kUnderlineThicknessIsValid_Flag = 1 << 0, //!< Set if fUnderlineThickness is valid.
   1104             kUnderlinePositionIsValid_Flag  = 1 << 1, //!< Set if fUnderlinePosition is valid.
   1105             kStrikeoutThicknessIsValid_Flag = 1 << 2, //!< Set if fStrikeoutThickness is valid.
   1106             kStrikeoutPositionIsValid_Flag  = 1 << 3, //!< Set if fStrikeoutPosition is valid.
   1107         };
   1108 
   1109         uint32_t fFlags;              //!< fFlags is set when underline metrics are valid.
   1110 
   1111         /** Greatest extent above the baseline for any glyph.
   1112             Typically less than zero.
   1113         */
   1114         SkScalar fTop;
   1115 
   1116         /** Recommended distance above the baseline to reserve for a line of text.
   1117             Typically less than zero.
   1118         */
   1119         SkScalar fAscent;
   1120 
   1121         /** Recommended distance below the baseline to reserve for a line of text.
   1122             Typically greater than zero.
   1123         */
   1124         SkScalar fDescent;
   1125 
   1126         /** Greatest extent below the baseline for any glyph.
   1127             Typically greater than zero.
   1128         */
   1129         SkScalar fBottom;
   1130 
   1131         /** Recommended distance to add between lines of text.
   1132             Typically greater than or equal to zero.
   1133         */
   1134         SkScalar fLeading;
   1135 
   1136         /** Average character width, if it is available.
   1137             Zero if no average width is stored in the font.
   1138         */
   1139         SkScalar fAvgCharWidth;
   1140 
   1141         SkScalar fMaxCharWidth;       //!< Maximum character width.
   1142 
   1143         /** Minimum bounding box x value for all glyphs.
   1144             Typically less than zero.
   1145         */
   1146         SkScalar fXMin;
   1147 
   1148         /** Maximum bounding box x value for all glyphs.
   1149             Typically greater than zero.
   1150         */
   1151         SkScalar fXMax;
   1152 
   1153         /** Height of a lower-case 'x'.
   1154             May be zero if no lower-case height is stored in the font.
   1155         */
   1156         SkScalar fXHeight;
   1157 
   1158         /** Height of an upper-case letter.
   1159             May be zero if no upper-case height is stored in the font.
   1160         */
   1161         SkScalar fCapHeight;
   1162 
   1163         /** Underline thickness.
   1164 
   1165             If the metric is valid, the kUnderlineThicknessIsValid_Flag is set in fFlags.
   1166             If kUnderlineThicknessIsValid_Flag is clear, fUnderlineThickness is zero.
   1167         */
   1168         SkScalar fUnderlineThickness;
   1169 
   1170         /** Position of the top of the underline stroke relative to the baseline.
   1171             Typically positive when valid.
   1172 
   1173             If the metric is valid, the kUnderlinePositionIsValid_Flag is set in fFlags.
   1174             If kUnderlinePositionIsValid_Flag is clear, fUnderlinePosition is zero.
   1175         */
   1176         SkScalar fUnderlinePosition;
   1177 
   1178         /** Strikeout thickness.
   1179 
   1180             If the metric is valid, the kStrikeoutThicknessIsValid_Flag is set in fFlags.
   1181             If kStrikeoutThicknessIsValid_Flag is clear, fStrikeoutThickness is zero.
   1182         */
   1183         SkScalar fStrikeoutThickness;
   1184 
   1185         /** Position of the bottom of the strikeout stroke relative to the baseline.
   1186             Typically negative when valid.
   1187 
   1188             If the metric is valid, the kStrikeoutPositionIsValid_Flag is set in fFlags.
   1189             If kStrikeoutPositionIsValid_Flag is clear, fStrikeoutPosition is zero.
   1190         */
   1191         SkScalar fStrikeoutPosition;
   1192 
   1193         /** If SkPaint::FontMetrics has a valid underline thickness, return true, and set
   1194             thickness to that value. If the underline thickness is not valid,
   1195             return false, and ignore thickness.
   1196 
   1197             @param thickness  storage for underline width
   1198             @return           true if font specifies underline width
   1199         */
   1200         bool hasUnderlineThickness(SkScalar* thickness) const {
   1201             if (SkToBool(fFlags & kUnderlineThicknessIsValid_Flag)) {
   1202                 *thickness = fUnderlineThickness;
   1203                 return true;
   1204             }
   1205             return false;
   1206         }
   1207 
   1208         /** If SkPaint::FontMetrics has a valid underline position, return true, and set
   1209             position to that value. If the underline position is not valid,
   1210             return false, and ignore position.
   1211 
   1212             @param position  storage for underline position
   1213             @return          true if font specifies underline position
   1214         */
   1215         bool hasUnderlinePosition(SkScalar* position) const {
   1216             if (SkToBool(fFlags & kUnderlinePositionIsValid_Flag)) {
   1217                 *position = fUnderlinePosition;
   1218                 return true;
   1219             }
   1220             return false;
   1221         }
   1222 
   1223         /** If SkPaint::FontMetrics has a valid strikeout thickness, return true, and set
   1224             thickness to that value. If the underline thickness is not valid,
   1225             return false, and ignore thickness.
   1226 
   1227             @param thickness  storage for strikeout width
   1228             @return           true if font specifies strikeout width
   1229         */
   1230         bool hasStrikeoutThickness(SkScalar* thickness) const {
   1231             if (SkToBool(fFlags & kStrikeoutThicknessIsValid_Flag)) {
   1232                 *thickness = fStrikeoutThickness;
   1233                 return true;
   1234             }
   1235             return false;
   1236         }
   1237 
   1238         /** If SkPaint::FontMetrics has a valid strikeout position, return true, and set
   1239             position to that value. If the underline position is not valid,
   1240             return false, and ignore position.
   1241 
   1242             @param position  storage for strikeout position
   1243             @return          true if font specifies strikeout position
   1244         */
   1245         bool hasStrikeoutPosition(SkScalar* position) const {
   1246             if (SkToBool(fFlags & kStrikeoutPositionIsValid_Flag)) {
   1247                 *position = fStrikeoutPosition;
   1248                 return true;
   1249             }
   1250             return false;
   1251         }
   1252 
   1253     };
   1254 
   1255     /** Returns SkPaint::FontMetrics associated with SkTypeface.
   1256         The return value is the recommended spacing between lines: the sum of metrics
   1257         descent, ascent, and leading.
   1258         If metrics is not nullptr, SkPaint::FontMetrics is copied to metrics.
   1259         Results are scaled by text size but does not take into account
   1260         dimensions required by text scale x, text skew x, fake bold,
   1261         style stroke, and SkPathEffect.
   1262         Results can be additionally scaled by scale; a scale of zero
   1263         is ignored.
   1264 
   1265         @param metrics  storage for SkPaint::FontMetrics from SkTypeface; may be nullptr
   1266         @param scale    additional multiplier for returned values
   1267         @return         recommended spacing between lines
   1268     */
   1269     SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const;
   1270 
   1271     /** Returns the recommended spacing between lines: the sum of metrics
   1272         descent, ascent, and leading.
   1273         Result is scaled by text size but does not take into account
   1274         dimensions required by stroking and SkPathEffect.
   1275         Returns the same result as getFontMetrics().
   1276 
   1277         @return  recommended spacing between lines
   1278     */
   1279     SkScalar getFontSpacing() const { return this->getFontMetrics(nullptr, 0); }
   1280 
   1281     /** Converts text into glyph indices.
   1282         Returns the number of glyph indices represented by text.
   1283         SkPaint::TextEncoding specifies how text represents characters or glyphs.
   1284         glyphs may be nullptr, to compute the glyph count.
   1285 
   1286         Does not check text for valid character codes or valid glyph indices.
   1287 
   1288         If byteLength equals zero, returns zero.
   1289         If byteLength includes a partial character, the partial character is ignored.
   1290 
   1291         If SkPaint::TextEncoding is kUTF8_TextEncoding and
   1292         text contains an invalid UTF-8 sequence, zero is returned.
   1293 
   1294         @param text        character storage encoded with SkPaint::TextEncoding
   1295         @param byteLength  length of character storage in bytes
   1296         @param glyphs      storage for glyph indices; may be nullptr
   1297         @return            number of glyphs represented by text of length byteLength
   1298     */
   1299     int textToGlyphs(const void* text, size_t byteLength,
   1300                      SkGlyphID glyphs[]) const;
   1301 
   1302     /** Returns true if all text corresponds to a non-zero glyph index.
   1303         Returns false if any characters in text are not supported in
   1304         SkTypeface.
   1305 
   1306         If SkPaint::TextEncoding is kGlyphID_TextEncoding,
   1307         returns true if all glyph indices in text are non-zero;
   1308         does not check to see if text contains valid glyph indices for SkTypeface.
   1309 
   1310         Returns true if byteLength is zero.
   1311 
   1312         @param text        array of characters or glyphs
   1313         @param byteLength  number of bytes in text array
   1314         @return            true if all text corresponds to a non-zero glyph index
   1315     */
   1316     bool containsText(const void* text, size_t byteLength) const;
   1317 
   1318     /** Converts glyphs into text if possible.
   1319         Glyph values without direct Unicode equivalents are mapped to zero.
   1320         Uses the SkTypeface, but is unaffected
   1321         by SkPaint::TextEncoding; the text values returned are equivalent to kUTF32_TextEncoding.
   1322 
   1323         Only supported on platforms that use FreeType as the font engine.
   1324 
   1325         @param glyphs  array of indices into font
   1326         @param count   length of glyph array
   1327         @param text    storage for character codes, one per glyph
   1328     */
   1329     void glyphsToUnichars(const SkGlyphID glyphs[], int count, SkUnichar text[]) const;
   1330 
   1331     /** Returns the number of glyphs in text.
   1332         Uses SkPaint::TextEncoding to count the glyphs.
   1333         Returns the same result as textToGlyphs().
   1334 
   1335         @param text        character storage encoded with SkPaint::TextEncoding
   1336         @param byteLength  length of character storage in bytes
   1337         @return            number of glyphs represented by text of length byteLength
   1338     */
   1339     int countText(const void* text, size_t byteLength) const {
   1340         return this->textToGlyphs(text, byteLength, nullptr);
   1341     }
   1342 
   1343     /** Returns the advance width of text if kVerticalText_Flag is clear,
   1344         and the height of text if kVerticalText_Flag is set.
   1345         The advance is the normal distance to move before drawing additional text.
   1346         Uses SkPaint::TextEncoding to decode text, SkTypeface to get the font metrics,
   1347         and text size, text scale x, text skew x, stroke width, and
   1348         SkPathEffect to scale the metrics and bounds.
   1349         Returns the bounding box of text if bounds is not nullptr.
   1350         The bounding box is computed as if the text was drawn at the origin.
   1351 
   1352         @param text    character codes or glyph indices to be measured
   1353         @param length  number of bytes of text to measure
   1354         @param bounds  returns bounding box relative to (0, 0) if not nullptr
   1355         @return        advance width or height
   1356     */
   1357     SkScalar measureText(const void* text, size_t length, SkRect* bounds) const;
   1358 
   1359     /** Returns the advance width of text if kVerticalText_Flag is clear,
   1360         and the height of text if kVerticalText_Flag is set.
   1361         The advance is the normal distance to move before drawing additional text.
   1362         Uses SkPaint::TextEncoding to decode text, SkTypeface to get the font metrics,
   1363         and text size to scale the metrics.
   1364         Does not scale the advance or bounds by fake bold or SkPathEffect.
   1365 
   1366         @param text    character codes or glyph indices to be measured
   1367         @param length  number of bytes of text to measure
   1368         @return        advance width or height
   1369     */
   1370     SkScalar measureText(const void* text, size_t length) const {
   1371         return this->measureText(text, length, nullptr);
   1372     }
   1373 
   1374     /** Returns the bytes of text that fit within maxWidth.
   1375         If kVerticalText_Flag is clear, the text fragment fits if its advance width is less than or
   1376         equal to maxWidth.
   1377         If kVerticalText_Flag is set, the text fragment fits if its advance height is less than or
   1378         equal to maxWidth.
   1379         Measures only while the advance is less than or equal to maxWidth.
   1380         Returns the advance or the text fragment in measuredWidth if it not nullptr.
   1381         Uses SkPaint::TextEncoding to decode text, SkTypeface to get the font metrics,
   1382         and text size to scale the metrics.
   1383         Does not scale the advance or bounds by fake bold or SkPathEffect.
   1384 
   1385         @param text           character codes or glyph indices to be measured
   1386         @param length         number of bytes of text to measure
   1387         @param maxWidth       advance limit; text is measured while advance is less than maxWidth
   1388         @param measuredWidth  returns the width of the text less than or equal to maxWidth
   1389         @return               bytes of text that fit, always less than or equal to length
   1390     */
   1391     size_t  breakText(const void* text, size_t length, SkScalar maxWidth,
   1392                       SkScalar* measuredWidth = nullptr) const;
   1393 
   1394     /** Retrieves the advance and bounds for each glyph in text, and returns
   1395         the glyph count in text.
   1396         Both widths and bounds may be nullptr.
   1397         If widths is not nullptr, widths must be an array of glyph count entries.
   1398         if bounds is not nullptr, bounds must be an array of glyph count entries.
   1399         If kVerticalText_Flag is clear, widths returns the horizontal advance.
   1400         If kVerticalText_Flag is set, widths returns the vertical advance.
   1401         Uses SkPaint::TextEncoding to decode text, SkTypeface to get the font metrics,
   1402         and text size to scale the widths and bounds.
   1403         Does not scale the advance by fake bold or SkPathEffect.
   1404         Does include fake bold and SkPathEffect in the bounds.
   1405 
   1406         @param text        character codes or glyph indices to be measured
   1407         @param byteLength  number of bytes of text to measure
   1408         @param widths      returns text advances for each glyph; may be nullptr
   1409         @param bounds      returns bounds for each glyph relative to (0, 0); may be nullptr
   1410         @return            glyph count in text
   1411     */
   1412     int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
   1413                       SkRect bounds[] = nullptr) const;
   1414 
   1415     /** Returns the geometry as SkPath equivalent to the drawn text.
   1416         Uses SkPaint::TextEncoding to decode text, SkTypeface to get the glyph paths,
   1417         and text size, fake bold, and SkPathEffect to scale and modify the glyph paths.
   1418         All of the glyph paths are stored in path.
   1419         Uses x, y, and SkPaint::Align to position path.
   1420 
   1421         @param text    character codes or glyph indices
   1422         @param length  number of bytes of text
   1423         @param x       x-coordinate of the origin of the text
   1424         @param y       y-coordinate of the origin of the text
   1425         @param path    geometry of the glyphs
   1426     */
   1427     void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
   1428                      SkPath* path) const;
   1429 
   1430     /** Returns the geometry as SkPath equivalent to the drawn text.
   1431         Uses SkPaint::TextEncoding to decode text, SkTypeface to get the glyph paths,
   1432         and text size, fake bold, and SkPathEffect to scale and modify the glyph paths.
   1433         All of the glyph paths are stored in path.
   1434         Uses pos array and SkPaint::Align to position path.
   1435         pos contains a position for each glyph.
   1436 
   1437         @param text    character codes or glyph indices
   1438         @param length  number of bytes of text
   1439         @param pos     positions of each glyph
   1440         @param path    geometry of the glyphs
   1441     */
   1442     void getPosTextPath(const void* text, size_t length,
   1443                         const SkPoint pos[], SkPath* path) const;
   1444 
   1445     /** Returns the number of intervals that intersect bounds.
   1446         bounds describes a pair of lines parallel to the text advance.
   1447         The return count is zero or a multiple of two, and is at most twice the number of glyphs in
   1448         the string.
   1449         Uses SkPaint::TextEncoding to decode text, SkTypeface to get the glyph paths,
   1450         and text size, fake bold, and SkPathEffect to scale and modify the glyph paths.
   1451         Uses x, y, and SkPaint::Align to position intervals.
   1452 
   1453         Pass nullptr for intervals to determine the size of the interval array.
   1454 
   1455         intervals are cached to improve performance for multiple calls.
   1456 
   1457         @param text       character codes or glyph indices
   1458         @param length     number of bytes of text
   1459         @param x          x-coordinate of the origin of the text
   1460         @param y          y-coordinate of the origin of the text
   1461         @param bounds     lower and upper line parallel to the advance
   1462         @param intervals  returned intersections; may be nullptr
   1463         @return           number of intersections; may be zero
   1464     */
   1465     int getTextIntercepts(const void* text, size_t length, SkScalar x, SkScalar y,
   1466                           const SkScalar bounds[2], SkScalar* intervals) const;
   1467 
   1468     /** Returns the number of intervals that intersect bounds.
   1469         bounds describes a pair of lines parallel to the text advance.
   1470         The return count is zero or a multiple of two, and is at most twice the number of glyphs in
   1471         the string.
   1472         Uses SkPaint::TextEncoding to decode text, SkTypeface to get the glyph paths,
   1473         and text size, fake bold, and SkPathEffect to scale and modify the glyph paths.
   1474         Uses pos array and SkPaint::Align to position intervals.
   1475 
   1476         Pass nullptr for intervals to determine the size of the interval array.
   1477 
   1478         intervals are cached to improve performance for multiple calls.
   1479 
   1480         @param text       character codes or glyph indices
   1481         @param length     number of bytes of text
   1482         @param pos        positions of each glyph
   1483         @param bounds     lower and upper line parallel to the advance
   1484         @param intervals  returned intersections; may be nullptr
   1485         @return           number of intersections; may be zero
   1486     */
   1487     int getPosTextIntercepts(const void* text, size_t length, const SkPoint pos[],
   1488                              const SkScalar bounds[2], SkScalar* intervals) const;
   1489 
   1490     /** Returns the number of intervals that intersect bounds.
   1491         bounds describes a pair of lines parallel to the text advance.
   1492         The return count is zero or a multiple of two, and is at most twice the number of glyphs in
   1493         the string.
   1494         Uses SkPaint::TextEncoding to decode text, SkTypeface to get the glyph paths,
   1495         and text size, fake bold, and SkPathEffect to scale and modify the glyph paths.
   1496         Uses xpos array, constY, and SkPaint::Align to position intervals.
   1497 
   1498         Pass nullptr for intervals to determine the size of the interval array.
   1499 
   1500         intervals are cached to improve performance for multiple calls.
   1501 
   1502         @param text       character codes or glyph indices
   1503         @param length     number of bytes of text
   1504         @param xpos       positions of each glyph in x
   1505         @param constY     position of each glyph in y
   1506         @param bounds     lower and upper line parallel to the advance
   1507         @param intervals  returned intersections; may be nullptr
   1508         @return           number of intersections; may be zero
   1509     */
   1510     int getPosTextHIntercepts(const void* text, size_t length, const SkScalar xpos[],
   1511                               SkScalar constY, const SkScalar bounds[2], SkScalar* intervals) const;
   1512 
   1513     /** Returns the number of intervals that intersect bounds.
   1514         bounds describes a pair of lines parallel to the text advance.
   1515         The return count is zero or a multiple of two, and is at most twice the number of glyphs in
   1516         the string.
   1517         Uses SkTypeface to get the glyph paths,
   1518         and text size, fake bold, and SkPathEffect to scale and modify the glyph paths.
   1519         Uses run array and SkPaint::Align to position intervals.
   1520 
   1521         SkPaint::TextEncoding must be set to SkPaint::kGlyphID_TextEncoding.
   1522 
   1523         Pass nullptr for intervals to determine the size of the interval array.
   1524 
   1525         intervals are cached to improve performance for multiple calls.
   1526 
   1527         @param blob       glyphs, positions, and text paint attributes
   1528         @param bounds     lower and upper line parallel to the advance
   1529         @param intervals  returned intersections; may be nullptr
   1530         @return           number of intersections; may be zero
   1531     */
   1532     int getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds[2],
   1533                               SkScalar* intervals) const;
   1534 
   1535     /** Returns the union of bounds of all glyphs.
   1536         Returned dimensions are computed by font manager from font data,
   1537         ignoring SkPaint::Hinting. Includes text size, text scale x,
   1538         and text skew x, but not fake bold or SkPathEffect.
   1539 
   1540         If text size is large, text scale x is one, and text skew x is zero,
   1541         returns the same bounds as SkPaint::FontMetrics { FontMetrics::fXMin,
   1542         FontMetrics::fTop, FontMetrics::fXMax, FontMetrics::fBottom }.
   1543 
   1544         @return  union of bounds of all glyphs
   1545     */
   1546     SkRect getFontBounds() const;
   1547 
   1548     /** Returns true if SkPaint prevents all drawing;
   1549         otherwise, the SkPaint may or may not allow drawing.
   1550 
   1551         Returns true if, for example, SkBlendMode combined with color alpha computes a
   1552         new alpha of zero.
   1553 
   1554         @return  true if SkPaint prevents all drawing
   1555     */
   1556     bool nothingToDraw() const;
   1557 
   1558     /**     (to be made private)
   1559         Returns true if SkPaint does not include elements requiring extensive computation
   1560         to compute SkBaseDevice bounds of drawn geometry. For instance, SkPaint with SkPathEffect
   1561         always returns false.
   1562 
   1563         @return  true if SkPaint allows for fast computation of bounds
   1564     */
   1565     bool canComputeFastBounds() const;
   1566 
   1567     /**     (to be made private)
   1568         Only call this if canComputeFastBounds() returned true. This takes a
   1569         raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
   1570         effects in the paint (e.g. stroking). If needed, it uses the storage
   1571         parameter. It returns the adjusted bounds that can then be used
   1572         for SkCanvas::quickReject tests.
   1573 
   1574         The returned SkRect will either be orig or storage, thus the caller
   1575         should not rely on storage being set to the result, but should always
   1576         use the returned value. It is legal for orig and storage to be the same
   1577         SkRect.
   1578             e.g.
   1579             if (paint.canComputeFastBounds()) {
   1580             SkRect r, storage;
   1581             path.computeBounds(&r, SkPath::kFast_BoundsType);
   1582             const SkRect& fastR = paint.computeFastBounds(r, &storage);
   1583             if (canvas->quickReject(fastR, ...)) {
   1584             // don't draw the path
   1585             }
   1586             }
   1587 
   1588         @param orig     geometry modified by SkPaint when drawn
   1589         @param storage  computed bounds of geometry; may not be nullptr
   1590         @return         fast computed bounds
   1591     */
   1592     const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
   1593         // Things like stroking, etc... will do math on the bounds rect, assuming that it's sorted.
   1594         SkASSERT(orig.isSorted());
   1595         SkPaint::Style style = this->getStyle();
   1596         // ultra fast-case: filling with no effects that affect geometry
   1597         if (kFill_Style == style) {
   1598             uintptr_t effects = reinterpret_cast<uintptr_t>(this->getLooper());
   1599             effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter());
   1600             effects |= reinterpret_cast<uintptr_t>(this->getPathEffect());
   1601             effects |= reinterpret_cast<uintptr_t>(this->getImageFilter());
   1602             if (!effects) {
   1603                 return orig;
   1604             }
   1605         }
   1606 
   1607         return this->doComputeFastBounds(orig, storage, style);
   1608     }
   1609 
   1610     /**     (to be made private)
   1611 
   1612         @param orig     geometry modified by SkPaint when drawn
   1613         @param storage  computed bounds of geometry
   1614         @return         fast computed bounds
   1615     */
   1616     const SkRect& computeFastStrokeBounds(const SkRect& orig,
   1617                                           SkRect* storage) const {
   1618         return this->doComputeFastBounds(orig, storage, kStroke_Style);
   1619     }
   1620 
   1621     /**     (to be made private)
   1622         Computes the bounds, overriding the SkPaint SkPaint::Style. This can be used to
   1623         account for additional width required by stroking orig, without
   1624         altering SkPaint::Style set to fill.
   1625 
   1626         @param orig     geometry modified by SkPaint when drawn
   1627         @param storage  computed bounds of geometry
   1628         @param style    overrides SkPaint::Style
   1629         @return         fast computed bounds
   1630     */
   1631     const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
   1632                                       Style style) const;
   1633 
   1634     /** macro expands to: void toString(SkString* str) const;
   1635         Creates string representation of SkPaint. The representation is read by
   1636         internal debugging tools. The interface and implementation may be
   1637         suppressed by defining SK_IGNORE_TO_STRING.
   1638 
   1639         @param str  storage for string representation of SkPaint
   1640     */
   1641     SK_TO_STRING_NONVIRT()
   1642 
   1643 private:
   1644     typedef const SkGlyph& (*GlyphCacheProc)(SkGlyphCache*, const char**);
   1645 
   1646     sk_sp<SkTypeface>     fTypeface;
   1647     sk_sp<SkPathEffect>   fPathEffect;
   1648     sk_sp<SkShader>       fShader;
   1649     sk_sp<SkMaskFilter>   fMaskFilter;
   1650     sk_sp<SkColorFilter>  fColorFilter;
   1651     sk_sp<SkDrawLooper>   fDrawLooper;
   1652     sk_sp<SkImageFilter>  fImageFilter;
   1653 
   1654     SkScalar        fTextSize;
   1655     SkScalar        fTextScaleX;
   1656     SkScalar        fTextSkewX;
   1657     SkColor         fColor;
   1658     SkScalar        fWidth;
   1659     SkScalar        fMiterLimit;
   1660     uint32_t        fBlendMode; // just need 5-6 bits
   1661     union {
   1662         struct {
   1663             // all of these bitfields should add up to 32
   1664             unsigned        fFlags : 16;
   1665             unsigned        fTextAlign : 2;
   1666             unsigned        fCapType : 2;
   1667             unsigned        fJoinType : 2;
   1668             unsigned        fStyle : 2;
   1669             unsigned        fTextEncoding : 2;  // 3 values
   1670             unsigned        fHinting : 2;
   1671             unsigned        fFilterQuality : 2;
   1672             //unsigned      fFreeBits : 2;
   1673         } fBitfields;
   1674         uint32_t fBitfieldsUInt;
   1675     };
   1676 
   1677     static GlyphCacheProc GetGlyphCacheProc(TextEncoding encoding,
   1678                                             bool isDevKern,
   1679                                             bool needFullMetrics);
   1680 
   1681     SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
   1682                           int* count, SkRect* bounds) const;
   1683 
   1684     /*
   1685      * The luminance color is used to determine which Gamma Canonical color to map to.  This is
   1686      * really only used by backends which want to cache glyph masks, and need some way to know if
   1687      * they need to generate new masks based off a given color.
   1688      */
   1689     SkColor computeLuminanceColor() const;
   1690 
   1691     enum {
   1692         /*  This is the size we use when we ask for a glyph's path. We then
   1693          *  post-transform it as we draw to match the request.
   1694          *  This is done to try to re-use cache entries for the path.
   1695          *
   1696          *  This value is somewhat arbitrary. In theory, it could be 1, since
   1697          *  we store paths as floats. However, we get the path from the font
   1698          *  scaler, and it may represent its paths as fixed-point (or 26.6),
   1699          *  so we shouldn't ask for something too big (might overflow 16.16)
   1700          *  or too small (underflow 26.6).
   1701          *
   1702          *  This value could track kMaxSizeForGlyphCache, assuming the above
   1703          *  constraints, but since we ask for unhinted paths, the two values
   1704          *  need not match per-se.
   1705          */
   1706         kCanonicalTextSizeForPaths  = 64,
   1707     };
   1708 
   1709     static bool TooBigToUseCache(const SkMatrix& ctm, const SkMatrix& textM, SkScalar maxLimit);
   1710 
   1711     // Set flags/hinting/textSize up to use for drawing text as paths.
   1712     // Returns scale factor to restore the original textSize, since will will
   1713     // have change it to kCanonicalTextSizeForPaths.
   1714     SkScalar setupForAsPaths();
   1715 
   1716     static SkScalar MaxCacheSize2(SkScalar maxLimit);
   1717 
   1718     friend class GrAtlasTextBlob;
   1719     friend class GrAtlasTextContext;
   1720     friend class GrGLPathRendering;
   1721     friend class GrPathRendering;
   1722     friend class GrTextUtils;
   1723     friend class SkAutoGlyphCache;
   1724     friend class SkAutoGlyphCacheNoGamma;
   1725     friend class SkCanonicalizePaint;
   1726     friend class SkCanvas;
   1727     friend class SkDraw;
   1728     friend class SkPDFDevice;
   1729     friend class SkScalerContext;  // for computeLuminanceColor()
   1730     friend class SkTextBaseIter;
   1731 };
   1732 
   1733 #endif
   1734