/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* Generated by tools/bookmaker from include/core/SkPaint.h and docs/SkPaint_Reference.bmh
   on 2018-08-28 10:32:58. Additional documentation and examples can be found at:
   https://skia.org/user/api/SkPaint_Reference

   You may edit either file directly. Structural changes to public interfaces require
   editing both files. After editing docs/SkPaint_Reference.bmh, run:
       bookmaker -b docs -i include/core/SkPaint.h -p
   to create an updated version of this file.
 */

#ifndef SkPaint_DEFINED
#define SkPaint_DEFINED

#include "../private/SkTo.h"
#include "SkBlendMode.h"
#include "SkColor.h"
#include "SkFilterQuality.h"
#include "SkFontMetrics.h"
#include "SkFontTypes.h"
#include "SkMatrix.h"
#include "SkRefCnt.h"

class GrTextBlob;
class SkAutoDescriptor;
class SkColorFilter;
class SkColorSpace;
class SkData;
class SkDescriptor;
class SkDrawLooper;
class SkGlyph;
class SkGlyphRunBuilder;
class SkGlyphRun;
class SkGlyphRunListPainter;
struct SkRect;
class SkGlyphCache;
class SkImageFilter;
class SkMaskFilter;
class SkPath;
class SkPathEffect;
struct SkPoint;
class SkFont;
class SkShader;
class SkSurfaceProps;
class SkTextBlob;
class SkTextBlobRunIterator;
class SkTypeface;

/** \class SkPaint
    SkPaint controls options applied when drawing and measuring. SkPaint collects all
    options outside of the SkCanvas clip and SkCanvas matrix.

    Various options apply to text, strokes and fills, and images.

    Some options may not be implemented on all platforms; in these cases, setting
    the option has no effect. Some options are conveniences that duplicate SkCanvas
    functionality; for instance, text size is identical to matrix scale.

    SkPaint options are rarely exclusive; each option modifies a stage of the drawing
    pipeline and multiple pipeline stages may be affected by a single SkPaint.

    SkPaint collects effects and filters that describe single-pass and multiple-pass
    algorithms that alter the drawing geometry, color, and transparency. For instance,
    SkPaint does not directly implement dashing or blur, but contains the objects that do so.

    The objects contained by SkPaint are opaque, and cannot be edited outside of the SkPaint
    to affect it. The implementation is free to defer computations associated with the
    SkPaint, or ignore them altogether. For instance, some GPU implementations draw all
    SkPath geometries with anti-aliasing, regardless of how SkPaint::kAntiAlias_Flag
    is set in SkPaint.

    SkPaint describes a single color, a single font, a single image quality, and so on.
    Multiple colors are drawn either by using multiple paints or with objects like
    SkShader attached to SkPaint.
*/
class SK_API SkPaint {
public:

    /** Constructs SkPaint with default values.

        @return  default initialized SkPaint
    */
    SkPaint();

    /** Makes a shallow copy of SkPaint. SkTypeface, SkPathEffect, SkShader,
        SkMaskFilter, SkColorFilter, SkDrawLooper, and SkImageFilter are shared
        between the original paint and the copy. Objects containing SkRefCnt increment
        their references by one.

        The referenced objects SkPathEffect, SkShader, SkMaskFilter, SkColorFilter,
        SkDrawLooper, and SkImageFilter cannot be modified after they are created.
        This prevents objects with SkRefCnt from being modified once SkPaint refers to them.

        @param paint  original to copy
        @return       shallow copy of paint
    */
    SkPaint(const SkPaint& paint);

    /** Implements a move constructor to avoid increasing the reference counts
        of objects referenced by the paint.

        After the call, paint is undefined, and can be safely destructed.

        @param paint  original to move
        @return       content of paint
    */
    SkPaint(SkPaint&& paint);

    /** Decreases SkPaint SkRefCnt of owned objects: SkTypeface, SkPathEffect, SkShader,
        SkMaskFilter, SkColorFilter, SkDrawLooper, and SkImageFilter. If the
        objects containing SkRefCnt go to zero, they are deleted.
    */
    ~SkPaint();

    /** Makes a shallow copy of SkPaint. SkTypeface, SkPathEffect, SkShader,
        SkMaskFilter, SkColorFilter, SkDrawLooper, and SkImageFilter are shared
        between the original paint and the copy. Objects containing SkRefCnt in the
        prior destination are decreased by one, and the referenced objects are deleted if the
        resulting count is zero. Objects containing SkRefCnt in the parameter paint
        are increased by one. paint is unmodified.

        @param paint  original to copy
        @return       content of paint
    */
    SkPaint& operator=(const SkPaint& paint);

    /** Moves the paint to avoid increasing the reference counts
        of objects referenced by the paint parameter. Objects containing SkRefCnt in the
        prior destination are decreased by one; those objects are deleted if the resulting count
        is zero.

        After the call, paint is undefined, and can be safely destructed.

        @param paint  original to move
        @return       content of paint
    */
    SkPaint& operator=(SkPaint&& paint);

    /** Compares a and b, and returns true if a and b are equivalent. May return false
        if SkTypeface, SkPathEffect, SkShader, SkMaskFilter, SkColorFilter,
        SkDrawLooper, or SkImageFilter have identical contents but different pointers.

        @param a  SkPaint to compare
        @param b  SkPaint to compare
        @return   true if SkPaint pair are equivalent
    */
    SK_API friend bool operator==(const SkPaint& a, const SkPaint& b);

    /** Compares a and b, and returns true if a and b are not equivalent. May return true
        if SkTypeface, SkPathEffect, SkShader, SkMaskFilter, SkColorFilter,
        SkDrawLooper, or SkImageFilter have identical contents but different pointers.

        @param a  SkPaint to compare
        @param b  SkPaint to compare
        @return   true if SkPaint pair are not equivalent
    */
    friend bool operator!=(const SkPaint& a, const SkPaint& b) {
        return !(a == b);
    }

    /** Returns a hash generated from SkPaint values and pointers.
        Identical hashes guarantee that the paints are
        equivalent, but differing hashes do not guarantee that the paints have differing
        contents.

        If operator==(const SkPaint& a, const SkPaint& b) returns true for two paints,
        their hashes are also equal.

        The hash returned is platform and implementation specific.

        @return  a shallow hash
    */
    uint32_t getHash() const;

    /** Sets all SkPaint contents to their initial values. This is equivalent to replacing
        SkPaint with the result of SkPaint().
    */
    void reset();

    /** Sets level of glyph outline adjustment.
        Does not check for valid values of hintingLevel.

        @param hintingLevel  one of: SkFontHinting::kNone, SkFontHinting::kSlight,
                                     SkFontHinting::kNormal, SkFontHinting::kFull
    */
    void setHinting(SkFontHinting hintingLevel);

    /** Returns level of glyph outline adjustment.

        @return  one of: SkFontHinting::kNone, SkFontHinting::kSlight, SkFontHinting::kNormal,
                         SkFontHinting::kFull
     */
    SkFontHinting getHinting() const { return (SkFontHinting)fBitfields.fHinting; }

    /** \enum SkPaint::Flags
        The bit values stored in Flags.
        The default value for Flags, normally zero, can be changed at compile time
        with a custom definition of SkPaintDefaults_Flags.
        All flags can be read and written explicitly; Flags allows manipulating
        multiple settings at once.
    */
    enum Flags {
        kAntiAlias_Flag          = 0x01,   //!< mask for setting anti-alias
        kDither_Flag             = 0x04,   //!< mask for setting dither
#ifdef SK_SUPPORT_LEGACY_PAINT_FONT_FIELDS
        kFakeBoldText_Flag       = 0x20,   //!< mask for setting fake bold
        kLinearText_Flag         = 0x40,   //!< mask for setting linear text
        kSubpixelText_Flag       = 0x80,   //!< mask for setting subpixel text
        kLCDRenderText_Flag      = 0x200,  //!< mask for setting LCD text
        kEmbeddedBitmapText_Flag = 0x400,  //!< mask for setting font embedded bitmaps
        kAutoHinting_Flag        = 0x800,  //!< mask for setting force hinting
                                           // 0x1000 used to be kVertical
        kAllFlags                = 0xFFFF, //!< mask of all Flags
#else
        kAllFlags                = 0x05,
#endif
    };

    #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
    /** Private.
     */
    enum ReserveFlags {
        kUnderlineText_ReserveFlag  = 0x08, //!< to be deprecated soon
        kStrikeThruText_ReserveFlag = 0x10, //!< to be deprecated soon
    };
    #endif

    /** Returns paint settings described by SkPaint::Flags. Each setting uses one
        bit, and can be tested with SkPaint::Flags members.

        @return  zero, one, or more bits described by SkPaint::Flags
    */
    uint32_t getFlags() const { return fBitfields.fFlags; }

    /** Replaces SkPaint::Flags with flags, the union of the SkPaint::Flags members.
        All SkPaint::Flags members may be cleared, or one or more may be set.

        @param flags  union of SkPaint::Flags for SkPaint
    */
    void setFlags(uint32_t flags);

    /** Returns true if pixels on the active edges of SkPath may be drawn with partial transparency.

        Equivalent to getFlags() masked with kAntiAlias_Flag.

        @return  kAntiAlias_Flag state
    */
    bool isAntiAlias() const {
        return SkToBool(this->getFlags() & kAntiAlias_Flag);
    }

    /** Requests, but does not require, that edge pixels draw opaque or with
        partial transparency.

        Sets kAntiAlias_Flag if aa is true.
        Clears kAntiAlias_Flag if aa is false.

        @param aa  setting for kAntiAlias_Flag
    */
    void setAntiAlias(bool aa);

    /** Returns true if color error may be distributed to smooth color transition.

        Equivalent to getFlags() masked with kDither_Flag.

        @return  kDither_Flag state
    */
    bool isDither() const {
        return SkToBool(this->getFlags() & kDither_Flag);
    }

    /** Requests, but does not require, to distribute color error.

        Sets kDither_Flag if dither is true.
        Clears kDither_Flag if dither is false.

        @param dither  setting for kDither_Flag
    */
    void setDither(bool dither);

#ifdef SK_SUPPORT_LEGACY_PAINT_FONT_FIELDS
    /** Returns true if text is converted to SkPath before drawing and measuring.

        Equivalent to getFlags() masked with kLinearText_Flag.

        @return  kLinearText_Flag state
    */
    bool isLinearText() const {
        return SkToBool(this->getFlags() & kLinearText_Flag);
    }

    /** Requests, but does not require, that glyphs are converted to SkPath
        before drawing and measuring.
        By default, kLinearText_Flag is clear.

        Sets kLinearText_Flag if linearText is true.
        Clears kLinearText_Flag if linearText is false.

        @param linearText  setting for kLinearText_Flag
    */
    void setLinearText(bool linearText);

    /** Returns true if glyphs at different sub-pixel positions may differ on pixel edge coverage.

        Equivalent to getFlags() masked with kSubpixelText_Flag.

        @return  kSubpixelText_Flag state
    */
    bool isSubpixelText() const {
        return SkToBool(this->getFlags() & kSubpixelText_Flag);
    }

    /** Requests, but does not require, that glyphs respect sub-pixel positioning.

        Sets kSubpixelText_Flag if subpixelText is true.
        Clears kSubpixelText_Flag if subpixelText is false.

        @param subpixelText  setting for kSubpixelText_Flag
    */
    void setSubpixelText(bool subpixelText);

    /** Returns true if glyphs may use LCD striping to improve glyph edges.

        Returns true if SkPaint::Flags kLCDRenderText_Flag is set.

        @return  kLCDRenderText_Flag state
    */
    bool isLCDRenderText() const {
        return SkToBool(this->getFlags() & kLCDRenderText_Flag);
    }

    /** Requests, but does not require, that glyphs use LCD striping for glyph edges.

        Sets kLCDRenderText_Flag if lcdText is true.
        Clears kLCDRenderText_Flag if lcdText is false.

        @param lcdText  setting for kLCDRenderText_Flag
    */
    void setLCDRenderText(bool lcdText);

    /** Returns true if font engine may return glyphs from font bitmaps instead of from outlines.

        Equivalent to getFlags() masked with kEmbeddedBitmapText_Flag.

        @return  kEmbeddedBitmapText_Flag state
    */
    bool isEmbeddedBitmapText() const {
        return SkToBool(this->getFlags() & kEmbeddedBitmapText_Flag);
    }

    /** Requests, but does not require, to use bitmaps in fonts instead of outlines.

        Sets kEmbeddedBitmapText_Flag if useEmbeddedBitmapText is true.
        Clears kEmbeddedBitmapText_Flag if useEmbeddedBitmapText is false.

        @param useEmbeddedBitmapText  setting for kEmbeddedBitmapText_Flag
    */
    void setEmbeddedBitmapText(bool useEmbeddedBitmapText);

    /** Returns true if SkPaint::Hinting is set to SkFontHinting::kNormal or
        SkFontHinting::kFull, and if platform uses FreeType as the font manager.
        If true, instructs the font manager to always hint glyphs.

        Equivalent to getFlags() masked with kAutoHinting_Flag.

        @return  kAutoHinting_Flag state
    */
    bool isAutohinted() const {
        return SkToBool(this->getFlags() & kAutoHinting_Flag);
    }

    /** Sets whether to always hint glyphs.
        If SkPaint::Hinting is set to SkFontHinting::kNormal or SkFontHinting::kFull
        and useAutohinter is set, instructs the font manager to always hint glyphs.
        useAutohinter has no effect if SkPaint::Hinting is set to SkFontHinting::kNone or
        SkFontHinting::kSlight.

        Only affects platforms that use FreeType as the font manager.

        Sets kAutoHinting_Flag if useAutohinter is true.
        Clears kAutoHinting_Flag if useAutohinter is false.

        @param useAutohinter  setting for kAutoHinting_Flag
    */
    void setAutohinted(bool useAutohinter);

    /** Returns true if approximate bold by increasing the stroke width when creating glyph bitmaps
        from outlines.

        Equivalent to getFlags() masked with kFakeBoldText_Flag.

        @return  kFakeBoldText_Flag state
    */
    bool isFakeBoldText() const {
        return SkToBool(this->getFlags() & kFakeBoldText_Flag);
    }

    /** Increases stroke width when creating glyph bitmaps to approximate a bold typeface.

        Sets kFakeBoldText_Flag if fakeBoldText is true.
        Clears kFakeBoldText_Flag if fakeBoldText is false.

        @param fakeBoldText  setting for kFakeBoldText_Flag
    */
    void setFakeBoldText(bool fakeBoldText);
#endif

    /** Returns SkFilterQuality, the image filtering level. A lower setting
        draws faster; a higher setting looks better when the image is scaled.

        @return  one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
                 kMedium_SkFilterQuality, kHigh_SkFilterQuality
    */
    SkFilterQuality getFilterQuality() const {
        return (SkFilterQuality)fBitfields.fFilterQuality;
    }

    /** Sets SkFilterQuality, the image filtering level. A lower setting
        draws faster; a higher setting looks better when the image is scaled.
        Does not check to see if quality is valid.

        @param quality  one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
                        kMedium_SkFilterQuality, kHigh_SkFilterQuality
    */
    void setFilterQuality(SkFilterQuality quality);

    /** \enum SkPaint::Style
        Set Style to fill, stroke, or both fill and stroke geometry.
        The stroke and fill
        share all paint attributes; for instance, they are drawn with the same color.

        Use kStrokeAndFill_Style to avoid hitting the same pixels twice with a stroke draw and
        a fill draw.
    */
    enum Style : uint8_t {
        kFill_Style,          //!< set to fill geometry
        kStroke_Style,        //!< set to stroke geometry
        kStrokeAndFill_Style, //!< sets to stroke and fill geometry
    };

    /** May be used to verify that SkPaint::Style is a legal value.
    */
    static constexpr int kStyleCount = kStrokeAndFill_Style + 1;

    /** Returns whether the geometry is filled, stroked, or filled and stroked.

        @return  one of:kFill_Style, kStroke_Style, kStrokeAndFill_Style
    */
    Style getStyle() const { return (Style)fBitfields.fStyle; }

    /** Sets whether the geometry is filled, stroked, or filled and stroked.
        Has no effect if style is not a legal SkPaint::Style value.

        @param style  one of: kFill_Style, kStroke_Style, kStrokeAndFill_Style
    */
    void setStyle(Style style);

    /** Retrieves alpha and RGB, unpremultiplied, packed into 32 bits.
        Use helpers SkColorGetA(), SkColorGetR(), SkColorGetG(), and SkColorGetB() to extract
        a color component.

        @return  unpremultiplied ARGB
    */
    SkColor getColor() const { return fColor4f.toSkColor(); }

    /** Retrieves alpha and RGB, unpremultiplied, as four floating point values. RGB are
        are extended sRGB values (sRGB gamut, and encoded with the sRGB transfer function).

        @return  unpremultiplied RGBA
    */
    SkColor4f getColor4f() const { return fColor4f; }

    /** Sets alpha and RGB used when stroking and filling. The color is a 32-bit value,
        unpremultiplied, packing 8-bit components for alpha, red, blue, and green.

        @param color  unpremultiplied ARGB
    */
    void setColor(SkColor color);

    /** Sets alpha and RGB used when stroking and filling. The color is four floating
        point values, unpremultiplied. The color values are interpreted as being in
        the colorSpace. If colorSpace is nullptr, then color is assumed to be in the
        sRGB color space.

        @param color       unpremultiplied RGBA
        @param colorSpace  SkColorSpace describing the encoding of color
    */
    void setColor4f(const SkColor4f& color, SkColorSpace* colorSpace);

    /** Retrieves alpha from the color used when stroking and filling.

        @return  alpha ranging from zero, fully transparent, to 255, fully opaque
    */
    uint8_t getAlpha() const { return sk_float_round2int(fColor4f.fA * 255); }

    /** Replaces alpha, leaving RGB
        unchanged. An out of range value triggers an assert in the debug
        build. a is a value from zero to 255.
        a set to zero makes color fully transparent; a set to 255 makes color
        fully opaque.

        @param a  alpha component of color
    */
    void setAlpha(U8CPU a);

    /** Sets color used when drawing solid fills. The color components range from 0 to 255.
        The color is unpremultiplied; alpha sets the transparency independent of RGB.

        @param a  amount of alpha, from fully transparent (0) to fully opaque (255)
        @param r  amount of red, from no red (0) to full red (255)
        @param g  amount of green, from no green (0) to full green (255)
        @param b  amount of blue, from no blue (0) to full blue (255)
    */
    void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);

    /** Returns the thickness of the pen used by SkPaint to
        outline the shape.

        @return  zero for hairline, greater than zero for pen thickness
    */
    SkScalar getStrokeWidth() const { return fWidth; }

    /** Sets the thickness of the pen used by the paint to
        outline the shape.
        Has no effect if width is less than zero.

        @param width  zero thickness for hairline; greater than zero for pen thickness
    */
    void setStrokeWidth(SkScalar width);

    /** Returns the limit at which a sharp corner is drawn beveled.

        @return  zero and greater miter limit
    */
    SkScalar getStrokeMiter() const { return fMiterLimit; }

    /** Sets the limit at which a sharp corner is drawn beveled.
        Valid values are zero and greater.
        Has no effect if miter is less than zero.

        @param miter  zero and greater miter limit
    */
    void setStrokeMiter(SkScalar miter);

    /** \enum SkPaint::Cap
        Cap draws at the beginning and end of an open path contour.
    */
    enum Cap {
        kButt_Cap,                  //!< no stroke extension
        kRound_Cap,                 //!< adds circle
        kSquare_Cap,                //!< adds square
        kLast_Cap    = kSquare_Cap, //!< largest Cap value
        kDefault_Cap = kButt_Cap,   //!< equivalent to kButt_Cap
    };

    /** May be used to verify that SkPaint::Cap is a legal value.
    */
    static constexpr int kCapCount = kLast_Cap + 1;

    /** \enum SkPaint::Join
        Join specifies how corners are drawn when a shape is stroked. Join
        affects the four corners of a stroked rectangle, and the connected segments in a
        stroked path.

        Choose miter join to draw sharp corners. Choose round join to draw a circle with a
        radius equal to the stroke width on top of the corner. Choose bevel join to minimally
        connect the thick strokes.

        The fill path constructed to describe the stroked path respects the join setting but may
        not contain the actual join. For instance, a fill path constructed with round joins does
        not necessarily include circles at each connected segment.
    */
    enum Join : uint8_t {
        kMiter_Join,                 //!< extends to miter limit
        kRound_Join,                 //!< adds circle
        kBevel_Join,                 //!< connects outside edges
        kLast_Join    = kBevel_Join, //!< equivalent to the largest value for Join
        kDefault_Join = kMiter_Join, //!< equivalent to kMiter_Join
    };

    /** May be used to verify that SkPaint::Join is a legal value.
    */
    static constexpr int kJoinCount = kLast_Join + 1;

    /** Returns the geometry drawn at the beginning and end of strokes.

        @return  one of: kButt_Cap, kRound_Cap, kSquare_Cap
    */
    Cap getStrokeCap() const { return (Cap)fBitfields.fCapType; }

    /** Sets the geometry drawn at the beginning and end of strokes.

        @param cap  one of: kButt_Cap, kRound_Cap, kSquare_Cap;
                    has no effect if cap is not valid
    */
    void setStrokeCap(Cap cap);

    /** Returns the geometry drawn at the corners of strokes.

        @return  one of: kMiter_Join, kRound_Join, kBevel_Join
    */
    Join getStrokeJoin() const { return (Join)fBitfields.fJoinType; }

    /** Sets the geometry drawn at the corners of strokes.

        @param join  one of: kMiter_Join, kRound_Join, kBevel_Join;
                     otherwise, has no effect
    */
    void setStrokeJoin(Join join);

    /** Returns the filled equivalent of the stroked path.

        @param src       SkPath read to create a filled version
        @param dst       resulting SkPath; may be the same as src, but may not be nullptr
        @param cullRect  optional limit passed to SkPathEffect
        @param resScale  if > 1, increase precision, else if (0 < resScale < 1) reduce precision
                         to favor speed and size
        @return          true if the path represents style fill, or false if it represents hairline
    */
    bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
                     SkScalar resScale = 1) const;

    /** Returns the filled equivalent of the stroked path.

        Replaces dst with the src path modified by SkPathEffect and style stroke.
        SkPathEffect, if any, is not culled. stroke width is created with default precision.

        @param src  SkPath read to create a filled version
        @param dst  resulting SkPath dst may be the same as src, but may not be nullptr
        @return     true if the path represents style fill, or false if it represents hairline
    */
    bool getFillPath(const SkPath& src, SkPath* dst) const {
        return this->getFillPath(src, dst, nullptr, 1);
    }

    /** Returns optional colors used when filling a path, such as a gradient.

        Does not alter SkShader SkRefCnt.

        @return  SkShader if previously set, nullptr otherwise
    */
    SkShader* getShader() const { return fShader.get(); }

    /** Returns optional colors used when filling a path, such as a gradient.

        Increases SkShader SkRefCnt by one.

        @return  SkShader if previously set, nullptr otherwise
    */
    sk_sp<SkShader> refShader() const;

    /** Sets optional colors used when filling a path, such as a gradient.

        Sets SkShader to shader, decreasing SkRefCnt of the previous SkShader.
        Increments shader SkRefCnt by one.

        @param shader  how geometry is filled with color; if nullptr, color is used instead
    */
    void setShader(sk_sp<SkShader> shader);

    /** Returns SkColorFilter if set, or nullptr.
        Does not alter SkColorFilter SkRefCnt.

        @return  SkColorFilter if previously set, nullptr otherwise
    */
    SkColorFilter* getColorFilter() const { return fColorFilter.get(); }

    /** Returns SkColorFilter if set, or nullptr.
        Increases SkColorFilter SkRefCnt by one.

        @return  SkColorFilter if set, or nullptr
    */
    sk_sp<SkColorFilter> refColorFilter() const;

    /** Sets SkColorFilter to filter, decreasing SkRefCnt of the previous
        SkColorFilter. Pass nullptr to clear SkColorFilter.

        Increments filter SkRefCnt by one.

        @param colorFilter  SkColorFilter to apply to subsequent draw
    */
    void setColorFilter(sk_sp<SkColorFilter> colorFilter);

    /** Returns SkBlendMode.
        By default, returns SkBlendMode::kSrcOver.

        @return  mode used to combine source color with destination color
    */
    SkBlendMode getBlendMode() const { return (SkBlendMode)fBlendMode; }

    /** Returns true if SkBlendMode is SkBlendMode::kSrcOver, the default.

        @return  true if SkBlendMode is SkBlendMode::kSrcOver
    */
    bool isSrcOver() const { return (SkBlendMode)fBlendMode == SkBlendMode::kSrcOver; }

    /** Sets SkBlendMode to mode.
        Does not check for valid input.

        @param mode  SkBlendMode used to combine source color and destination
    */
    void setBlendMode(SkBlendMode mode) { fBlendMode = (unsigned)mode; }

    /** Returns SkPathEffect if set, or nullptr.
        Does not alter SkPathEffect SkRefCnt.

        @return  SkPathEffect if previously set, nullptr otherwise
    */
    SkPathEffect* getPathEffect() const { return fPathEffect.get(); }

    /** Returns SkPathEffect if set, or nullptr.
        Increases SkPathEffect SkRefCnt by one.

        @return  SkPathEffect if previously set, nullptr otherwise
    */
    sk_sp<SkPathEffect> refPathEffect() const;

    /** Sets SkPathEffect to pathEffect, decreasing SkRefCnt of the previous
        SkPathEffect. Pass nullptr to leave the path geometry unaltered.

        Increments pathEffect SkRefCnt by one.

        @param pathEffect  replace SkPath with a modification when drawn
    */
    void setPathEffect(sk_sp<SkPathEffect> pathEffect);

    /** Returns SkMaskFilter if set, or nullptr.
        Does not alter SkMaskFilter SkRefCnt.

        @return  SkMaskFilter if previously set, nullptr otherwise
    */
    SkMaskFilter* getMaskFilter() const { return fMaskFilter.get(); }

    /** Returns SkMaskFilter if set, or nullptr.

        Increases SkMaskFilter SkRefCnt by one.

        @return  SkMaskFilter if previously set, nullptr otherwise
    */
    sk_sp<SkMaskFilter> refMaskFilter() const;

    /** Sets SkMaskFilter to maskFilter, decreasing SkRefCnt of the previous
        SkMaskFilter. Pass nullptr to clear SkMaskFilter and leave SkMaskFilter effect on
        mask alpha unaltered.

        Increments maskFilter SkRefCnt by one.

        @param maskFilter  modifies clipping mask generated from drawn geometry
    */
    void setMaskFilter(sk_sp<SkMaskFilter> maskFilter);

#ifndef SK_SUPPORT_LEGACY_PAINT_FONT_FIELDS
private:
#endif
    /** Returns SkTypeface if set, or nullptr.
        Does not alter SkTypeface SkRefCnt.

        @return  SkTypeface if previously set, nullptr otherwise
    */
    SkTypeface* getTypeface() const { return fTypeface.get(); }

    /** Increases SkTypeface SkRefCnt by one.

        @return  SkTypeface if previously set, nullptr otherwise
    */
    sk_sp<SkTypeface> refTypeface() const;

    /** Sets SkTypeface to typeface, decreasing SkRefCnt of the previous SkTypeface.
        Pass nullptr to clear SkTypeface and use the default typeface. Increments
        typeface SkRefCnt by one.

        @param typeface  font and style used to draw text
    */
    void setTypeface(sk_sp<SkTypeface> typeface);
#ifndef SK_SUPPORT_LEGACY_PAINT_FONT_FIELDS
public:
#endif

    /** Returns SkImageFilter if set, or nullptr.
        Does not alter SkImageFilter SkRefCnt.

        @return  SkImageFilter if previously set, nullptr otherwise
    */
    SkImageFilter* getImageFilter() const { return fImageFilter.get(); }

    /** Returns SkImageFilter if set, or nullptr.
        Increases SkImageFilter SkRefCnt by one.

        @return  SkImageFilter if previously set, nullptr otherwise
    */
    sk_sp<SkImageFilter> refImageFilter() const;

    /** Sets SkImageFilter to imageFilter, decreasing SkRefCnt of the previous
        SkImageFilter. Pass nullptr to clear SkImageFilter, and remove SkImageFilter effect
        on drawing.

        Increments imageFilter SkRefCnt by one.

        @param imageFilter  how SkImage is sampled when transformed
    */
    void setImageFilter(sk_sp<SkImageFilter> imageFilter);

    /** Returns SkDrawLooper if set, or nullptr.
        Does not alter SkDrawLooper SkRefCnt.

        @return  SkDrawLooper if previously set, nullptr otherwise
    */
    SkDrawLooper* getDrawLooper() const { return fDrawLooper.get(); }

    /** Returns SkDrawLooper if set, or nullptr.
        Increases SkDrawLooper SkRefCnt by one.

        @return  SkDrawLooper if previously set, nullptr otherwise
    */
    sk_sp<SkDrawLooper> refDrawLooper() const;

    /** Deprecated.
        (see skbug.com/6259)
    */
    SkDrawLooper* getLooper() const { return fDrawLooper.get(); }

    /** Sets SkDrawLooper to drawLooper, decreasing SkRefCnt of the previous
        drawLooper.  Pass nullptr to clear SkDrawLooper and leave SkDrawLooper effect on
        drawing unaltered.

        Increments drawLooper SkRefCnt by one.

        @param drawLooper  iterates through drawing one or more time, altering SkPaint
    */
    void setDrawLooper(sk_sp<SkDrawLooper> drawLooper);

    /** Deprecated.
        (see skbug.com/6259)
    */
    void setLooper(sk_sp<SkDrawLooper> drawLooper);

#ifndef SK_SUPPORT_LEGACY_PAINT_FONT_FIELDS
private:
#endif
    /** Returns text size in points.

        @return  typographic height of text
    */
    SkScalar getTextSize() const { return fTextSize; }

    /** Sets text size in points.
        Has no effect if textSize is not greater than or equal to zero.

        @param textSize  typographic height of text
    */
    void setTextSize(SkScalar textSize);

    /** Returns text scale on x-axis.
        Default value is 1.

        @return  text horizontal scale
    */
    SkScalar getTextScaleX() const { return fTextScaleX; }

    /** Sets text scale on x-axis.
        Default value is 1.

        @param scaleX  text horizontal scale
    */
    void setTextScaleX(SkScalar scaleX);

    /** Returns text skew on x-axis.
        Default value is zero.

        @return  additional shear on x-axis relative to y-axis
    */
    SkScalar getTextSkewX() const { return fTextSkewX; }

    /** Sets text skew on x-axis.
        Default value is zero.

        @param skewX  additional shear on x-axis relative to y-axis
    */
    void setTextSkewX(SkScalar skewX);

#ifdef SK_SUPPORT_LEGACY_PAINTTEXTENCODING
    /**
     *  Returns the text encoding. Text encoding describes how to interpret the text bytes pass
     *  to methods like SkFont::measureText() and SkCanvas::drawText().
     *  @return the text encoding
     */
    SkTextEncoding getTextEncoding() const {
        return (SkTextEncoding)fBitfields.fTextEncoding;
    }

    /**
     *  Sets the text encoding. Text encoding describes how to interpret the text bytes pass
     *  to methods like SkFont::measureText() and SkCanvas::drawText().
     *  @param encoding  the new text encoding
     */
    void setTextEncoding(SkTextEncoding encoding);
#endif
#ifndef SK_SUPPORT_LEGACY_PAINT_FONT_FIELDS
public:
#endif

#ifdef SK_SUPPORT_LEGACY_PAINT_TEXTMEASURE

    /** Deprecated; use SkFont::getMetrics instead
    */
    SkScalar getFontMetrics(SkFontMetrics* metrics) const;

    /** Deprecated; use SkFont::getSpacing instead
    */
    SkScalar getFontSpacing() const { return this->getFontMetrics(nullptr); }

    /** Deprecated; use SkFont::textToGlyphs instead
    */
    int textToGlyphs(const void* text, size_t byteLength,
                     SkGlyphID glyphs[]) const;

    /** Deprecated; use SkFont::containsText instead
    */
    bool containsText(const void* text, size_t byteLength) const;
#endif

#ifdef SK_SUPPORT_LEGACY_PAINT_FONT_FIELDS
    /** Converts glyphs into text if possible.
        Glyph values without direct Unicode equivalents are mapped to zero.
        Uses the SkTypeface, but is unaffected
        by SkTextEncoding; the text values returned are equivalent to kUTF32_SkTextEncoding.

        Only supported on platforms that use FreeType as the font engine.

        @param glyphs  array of indices into font
        @param count   length of glyph array
        @param text    storage for character codes, one per glyph
    */
    void glyphsToUnichars(const SkGlyphID glyphs[], int count, SkUnichar text[]) const;
#endif

#ifdef SK_SUPPORT_LEGACY_PAINT_TEXTMEASURE
    /** Deprecated; use SkFont::countText instead
    */
    int countText(const void* text, size_t byteLength) const;

    /** Deprecated; use SkFont::measureText instead
    */
    SkScalar measureText(const void* text, size_t length, SkRect* bounds) const;

    /** Deprecated; use SkFont::measureText instead
    */
    SkScalar measureText(const void* text, size_t length) const {
        return this->measureText(text, length, nullptr);
    }

    /** Deprecated; use SkFont::getWidthsBounds instead
    */
    int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
                      SkRect bounds[] = nullptr) const;

    /** Deprecated; use SkFont::getPath instead
    */
    void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
                     SkPath* path) const;

    /** Deprecated; use SkFont::getPath instead
    */
    void getPosTextPath(const void* text, size_t length,
                        const SkPoint pos[], SkPath* path) const;
#endif

    /** DEPRECATED -- call method on SkTextBlob
        Returns the number of intervals that intersect bounds.
        bounds describes a pair of lines parallel to the text advance.
        The return count is zero or a multiple of two, and is at most twice the number of glyphs in
        the string.
        Uses SkTypeface to get the glyph paths,
        and text size, fake bold, and SkPathEffect to scale and modify the glyph paths.
        Uses run array to position intervals.

        SkTextEncoding must be set to kGlyphID_SkTextEncoding.

        Pass nullptr for intervals to determine the size of the interval array.

        intervals are cached to improve performance for multiple calls.

        @param blob       glyphs, positions, and text paint attributes
        @param bounds     lower and upper line parallel to the advance
        @param intervals  returned intersections; may be nullptr
        @return           number of intersections; may be zero
    */
    int getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds[2],
                              SkScalar* intervals) const;

    /** Returns true if SkPaint prevents all drawing;
        otherwise, the SkPaint may or may not allow drawing.

        Returns true if, for example, SkBlendMode combined with alpha computes a
        new alpha of zero.

        @return  true if SkPaint prevents all drawing
    */
    bool nothingToDraw() const;

    /**     (to be made private)
        Returns true if SkPaint does not include elements requiring extensive computation
        to compute SkBaseDevice bounds of drawn geometry. For instance, SkPaint with SkPathEffect
        always returns false.

        @return  true if SkPaint allows for fast computation of bounds
    */
    bool canComputeFastBounds() const;

    /**     (to be made private)
        Only call this if canComputeFastBounds() returned true. This takes a
        raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
        effects in the paint (e.g. stroking). If needed, it uses the storage
        parameter. It returns the adjusted bounds that can then be used
        for SkCanvas::quickReject tests.

        The returned SkRect will either be orig or storage, thus the caller
        should not rely on storage being set to the result, but should always
        use the returned value. It is legal for orig and storage to be the same
        SkRect.
            For example:
            if (!path.isInverseFillType() && paint.canComputeFastBounds()) {
                SkRect storage;
                if (canvas->quickReject(paint.computeFastBounds(path.getBounds(), &storage))) {
                    return; // do not draw the path
                }
            }
            // draw the path

        @param orig     geometry modified by SkPaint when drawn
        @param storage  computed bounds of geometry; may not be nullptr
        @return         fast computed bounds
    */
    const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
        // Things like stroking, etc... will do math on the bounds rect, assuming that it's sorted.
        SkASSERT(orig.isSorted());
        SkPaint::Style style = this->getStyle();
        // ultra fast-case: filling with no effects that affect geometry
        if (kFill_Style == style) {
            uintptr_t effects = reinterpret_cast<uintptr_t>(this->getLooper());
            effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter());
            effects |= reinterpret_cast<uintptr_t>(this->getPathEffect());
            effects |= reinterpret_cast<uintptr_t>(this->getImageFilter());
            if (!effects) {
                return orig;
            }
        }

        return this->doComputeFastBounds(orig, storage, style);
    }

    /**     (to be made private)

        @param orig     geometry modified by SkPaint when drawn
        @param storage  computed bounds of geometry
        @return         fast computed bounds
    */
    const SkRect& computeFastStrokeBounds(const SkRect& orig,
                                          SkRect* storage) const {
        return this->doComputeFastBounds(orig, storage, kStroke_Style);
    }

    /**     (to be made private)
        Computes the bounds, overriding the SkPaint SkPaint::Style. This can be used to
        account for additional width required by stroking orig, without
        altering SkPaint::Style set to fill.

        @param orig     geometry modified by SkPaint when drawn
        @param storage  computed bounds of geometry
        @param style    overrides SkPaint::Style
        @return         fast computed bounds
    */
    const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
                                      Style style) const;

private:
    sk_sp<SkTypeface>     fTypeface;
    sk_sp<SkPathEffect>   fPathEffect;
    sk_sp<SkShader>       fShader;
    sk_sp<SkMaskFilter>   fMaskFilter;
    sk_sp<SkColorFilter>  fColorFilter;
    sk_sp<SkDrawLooper>   fDrawLooper;
    sk_sp<SkImageFilter>  fImageFilter;

    SkScalar        fTextSize;
    SkScalar        fTextScaleX;
    SkScalar        fTextSkewX;
    SkColor4f       fColor4f;
    SkScalar        fWidth;
    SkScalar        fMiterLimit;
    uint32_t        fBlendMode; // just need 5-6 bits
    union {
        struct {
            // all of these bitfields should add up to 32
            unsigned        fFlags : 16;
            unsigned        fCapType : 2;
            unsigned        fJoinType : 2;
            unsigned        fStyle : 2;
            unsigned        fTextEncoding : 2;  // 3 values
            unsigned        fHinting : 2;
            unsigned        fFilterQuality : 2;
            //unsigned      fFreeBits : 4;
        } fBitfields;
        uint32_t fBitfieldsUInt;
    };

    SkTextEncoding private_internal_getTextEncoding() const {
        return (SkTextEncoding)fBitfields.fTextEncoding;
    }
    void private_internal_setTextEncoding(SkTextEncoding e) {
        fBitfields.fTextEncoding = (unsigned)e;
    }

    SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
                          int* count, SkRect* bounds) const;

    /*
     * The luminance color is used to determine which Gamma Canonical color to map to.  This is
     * really only used by backends which want to cache glyph masks, and need some way to know if
     * they need to generate new masks based off a given color.
     */
    SkColor computeLuminanceColor() const;

    /*  This is the size we use when we ask for a glyph's path. We then
     *  post-transform it as we draw to match the request.
     *  This is done to try to re-use cache entries for the path.
     *
     *  This value is somewhat arbitrary. In theory, it could be 1, since
     *  we store paths as floats. However, we get the path from the font
     *  scaler, and it may represent its paths as fixed-point (or 26.6),
     *  so we shouldn't ask for something too big (might overflow 16.16)
     *  or too small (underflow 26.6).
     *
     *  This value could track kMaxSizeForGlyphCache, assuming the above
     *  constraints, but since we ask for unhinted paths, the two values
     *  need not match per-se.
     */
    static constexpr int kCanonicalTextSizeForPaths  = 64;

    static bool TooBigToUseCache(const SkMatrix& ctm, const SkMatrix& textM, SkScalar maxLimit);

    // Set flags/hinting/textSize up to use for drawing text as paths.
    // Returns scale factor to restore the original textSize, since will will
    // have change it to kCanonicalTextSizeForPaths.
    SkScalar setupForAsPaths();

    static SkScalar MaxCacheSize2(SkScalar maxLimit);

    friend class GrTextBlob;
    friend class GrTextContext;
    friend class GrGLPathRendering;
    friend class GrPathRendering;
    friend class SkAutoGlyphCacheNoGamma;
    friend class SkCanonicalizePaint;
    friend class SkCanvas;
    friend class SkDraw;
    friend class SkFont;
    friend class SkGlyphRunListPainter;
    friend class SkPaintPriv;
    friend class SkPicturePlayback;
    friend class SkPDFDevice;
    friend class SkScalerContext;  // for computeLuminanceColor()
    friend class SkTextBaseIter;
    friend class SkTextBlobCacheDiffCanvas;
};

#endif
