/*
* 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.
*/
#ifndef SkCanvas_DEFINED
#define SkCanvas_DEFINED
#include "SkBlendMode.h"
#include "SkClipOp.h"
#include "SkDeque.h"
#include "SkPaint.h"
#include "SkRasterHandleAllocator.h"
#include "SkSurfaceProps.h"
class GrContext;
class GrRenderTargetContext;
class SkAndroidFrameworkUtils;
class SkBaseDevice;
class SkBitmap;
class SkClipStack;
class SkData;
class SkDraw;
class SkDrawable;
class SkDrawFilter;
struct SkDrawShadowRec;
class SkImage;
class SkImageFilter;
class SkMetaData;
class SkPath;
class SkPicture;
class SkPixmap;
class SkRasterClip;
class SkRegion;
class SkRRect;
struct SkRSXform;
class SkSurface;
class SkSurface_Base;
class SkTextBlob;
class SkVertices;
/** \class SkCanvas
SkCanvas provides an interface for drawing, and how the drawing is clipped and transformed.
SkCanvas contains a stack of SkMatrix and clip values.
SkCanvas and SkPaint together provide the state to draw into SkSurface or SkBaseDevice.
Each SkCanvas draw call transforms the geometry of the object by the concatenation of all
SkMatrix values in the stack. The transformed geometry is clipped by the intersection
of all of clip values in the stack. The SkCanvas draw calls use SkPaint to supply drawing
state such as color, SkTypeface, text size, stroke width, SkShader and so on.
To draw to a pixel-based destination, create raster surface or GPU surface.
Request SkCanvas from SkSurface to obtain the interface to draw.
SkCanvas generated by raster surface draws to memory visible to the CPU.
SkCanvas generated by GPU surface uses Vulkan or OpenGL to draw to the GPU.
To draw to a document, obtain SkCanvas from svg canvas, document pdf, or SkPictureRecorder.
SkDocument based SkCanvas and other SkCanvas Subclasses reference SkBaseDevice describing the
destination.
SkCanvas can be constructed to draw to SkBitmap without first creating raster surface.
This approach may be deprecated in the future.
*/
class SK_API SkCanvas : SkNoncopyable {
enum PrivateSaveLayerFlags {
kDontClipToLayer_PrivateSaveLayerFlag = 1U << 31,
};
public:
/** Allocates raster SkCanvas that will draw directly into pixels.
SkCanvas is returned if all parameters are valid.
Valid parameters include:
info dimensions are zero or positive;
info contains SkColorType and SkAlphaType supported by raster surface;
pixels is not nullptr;
rowBytes is zero or large enough to contain info width pixels of SkColorType.
Pass zero for rowBytes to compute rowBytes from info width and size of pixel.
If rowBytes is greater than zero, it must be equal to or greater than
info width times bytes required for SkColorType.
Pixel buffer size should be info height times computed rowBytes.
Pixels are not initialized.
To access pixels after drawing, call flush() or peekPixels().
@param info width, height, SkColorType, SkAlphaType, SkColorSpace, of raster surface;
width, or height, or both, may be zero
@param pixels pointer to destination pixels buffer
@param rowBytes interval from one SkSurface row to the next, or zero
@param props LCD striping orientation and setting for device independent fonts;
may be nullptr
@return SkCanvas if all parameters are valid; otherwise, nullptr
*/
static std::unique_ptr<SkCanvas> MakeRasterDirect(const SkImageInfo& info, void* pixels,
size_t rowBytes,
const SkSurfaceProps* props = nullptr);
/** Allocates raster SkCanvas specified by inline image specification. Subsequent SkCanvas
calls draw into pixels.
SkColorType is set to kN32_SkColorType.
SkAlphaType is set to kPremul_SkAlphaType.
To access pixels after drawing, call flush() or peekPixels().
SkCanvas is returned if all parameters are valid.
Valid parameters include:
width and height are zero or positive;
pixels is not nullptr;
rowBytes is zero or large enough to contain width pixels of kN32_SkColorType.
Pass zero for rowBytes to compute rowBytes from width and size of pixel.
If rowBytes is greater than zero, it must be equal to or greater than
width times bytes required for SkColorType.
Pixel buffer size should be height times rowBytes.
@param width pixel column count on raster surface created; must be zero or greater
@param height pixel row count on raster surface created; must be zero or greater
@param pixels pointer to destination pixels buffer; buffer size should be height
times rowBytes
@param rowBytes interval from one SkSurface row to the next, or zero
@return SkCanvas if all parameters are valid; otherwise, nullptr
*/
static std::unique_ptr<SkCanvas> MakeRasterDirectN32(int width, int height, SkPMColor* pixels,
size_t rowBytes) {
return MakeRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes);
}
/** Creates an empty SkCanvas with no backing device or pixels, with
a width and height of zero.
@return empty SkCanvas
*/
SkCanvas();
/** Creates SkCanvas of the specified dimensions without a SkSurface.
Used by Subclasses with custom implementations for draw methods.
If props equals nullptr, SkSurfaceProps are created with
SkSurfaceProps::InitType settings, which choose the pixel striping
direction and order. Since a platform may dynamically change its direction when
the device is rotated, and since a platform may have multiple monitors with
different characteristics, it is best not to rely on this legacy behavior.
@param width zero or greater
@param height zero or greater
@param props LCD striping orientation and setting for device independent fonts;
may be nullptr
@return SkCanvas placeholder with dimensions
*/
SkCanvas(int width, int height, const SkSurfaceProps* props = nullptr);
/** To be deprecated soon.
*/
explicit SkCanvas(SkBaseDevice* device);
/** Construct a canvas that draws into bitmap.
Sets SkSurfaceProps::kLegacyFontHost_InitType in constructed SkSurface.
SkBitmap is copied so that subsequently editing bitmap will not affect
constructed SkCanvas.
May be deprecated in the future.
@param bitmap width, height, SkColorType, SkAlphaType, and pixel
storage of raster surface
@return SkCanvas that can be used to draw into bitmap
*/
explicit SkCanvas(const SkBitmap& bitmap);
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
enum class ColorBehavior {
kLegacy, //!< Is a placeholder to allow specialized constructor; has no meaning.
};
/** Android framework only.
@param bitmap specifies a bitmap for the canvas to draw into
@param behavior specializes this constructor; value is unused
@return SkCanvas that can be used to draw into bitmap
*/
SkCanvas(const SkBitmap& bitmap, ColorBehavior behavior);
#endif
/** Construct a canvas that draws into bitmap.
Use props to match the device characteristics, like LCD striping.
bitmap is copied so that subsequently editing bitmap will not affect
constructed SkCanvas.
@param bitmap width, height, SkColorType, SkAlphaType,
and pixel storage of raster surface
@param props order and orientation of RGB striping; and whether to use
device independent fonts
@return SkCanvas that can be used to draw into bitmap
*/
SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props);
/** Draws saved layer, if any.
Frees up resources used by SkCanvas.
*/
virtual ~SkCanvas();
/** Returns storage to associate additional data with the canvas.
The storage is freed when SkCanvas is deleted.
@return storage that can be read from and written to
*/
SkMetaData& getMetaData();
/** Returns SkImageInfo for SkCanvas. If SkCanvas is not associated with raster surface or
GPU surface, returned SkColorType is set to kUnknown_SkColorType.
@return dimensions and SkColorType of SkCanvas
*/
SkImageInfo imageInfo() const;
/** If SkCanvas is associated with raster surface or
GPU surface, copies SkSurfaceProps and returns true. Otherwise,
return false and leave props unchanged.
@param props storage for writable SkSurfaceProps
@return true if SkSurfaceProps was copied
*/
bool getProps(SkSurfaceProps* props) const;
/** Triggers the immediate execution of all pending draw operations.
If SkCanvas is associated with GPU surface, resolves all pending GPU operations.
If SkCanvas is associated with raster surface, has no effect; raster draw
operations are never deferred.
*/
void flush();
/** Gets the size of the base or root layer in global canvas coordinates. The
origin of the base layer is always (0,0). The area available for drawing may be
smaller (due to clipping or saveLayer).
@return integral width and height of base layer
*/
virtual SkISize getBaseLayerSize() const;
/** Creates SkSurface matching info and props, and associates it with SkCanvas.
Returns nullptr if no match found.
If props is nullptr, matches SkSurfaceProps in SkCanvas. If props is nullptr and SkCanvas
does not have SkSurfaceProps, creates SkSurface with default SkSurfaceProps.
@param info width, height, SkColorType, SkAlphaType, and SkColorSpace
@param props SkSurfaceProps to match; may be nullptr to match SkCanvas
@return SkSurface matching info and props, or nullptr if no match is available
*/
sk_sp<SkSurface> makeSurface(const SkImageInfo& info, const SkSurfaceProps* props = nullptr);
/** Returns GPU context of the GPU surface associated with SkCanvas.
@return GPU context, if available; nullptr otherwise
*/
virtual GrContext* getGrContext();
/** Returns the pixel base address, SkImageInfo, rowBytes, and origin if the pixels
can be read directly. The returned address is only valid
while SkCanvas is in scope and unchanged. Any SkCanvas call or SkSurface call
may invalidate the returned address and other returned values.
If pixels are inaccessible, info, rowBytes, and origin are unchanged.
@param info storage for writable pixels' SkImageInfo; may be nullptr
@param rowBytes storage for writable pixels' row bytes; may be nullptr
@param origin storage for SkCanvas top layer origin, its top-left corner;
may be nullptr
@return address of pixels, or nullptr if inaccessible
*/
void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = nullptr);
/** Returns custom context that tracks the SkMatrix and clip.
Use SkRasterHandleAllocator to blend Skia drawing with custom drawing, typically performed
by the host platform user interface. The custom context returned is generated by
SkRasterHandleAllocator::MakeCanvas, which creates a custom canvas with raster storage for
the drawing destination.
@return context of custom allocation
*/
SkRasterHandleAllocator::Handle accessTopRasterHandle() const;
/** Returns true if SkCanvas has direct access to its pixels.
Pixels are readable when SkBaseDevice is raster. Pixels are not readable when SkCanvas
is returned from GPU surface, returned by SkDocument::beginPage, returned by
SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility class
like SkDumpCanvas.
pixmap is valid only while SkCanvas is in scope and unchanged. Any
SkCanvas or SkSurface call may invalidate the pixmap values.
@param pixmap storage for pixel state if pixels are readable; otherwise, ignored
@return true if SkCanvas has direct access to pixels
*/
bool peekPixels(SkPixmap* pixmap);
/** Copies SkRect of pixels from SkCanvas into dstPixels. SkMatrix and clip are
ignored.
Source SkRect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Destination SkRect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
Copies each readable pixel intersecting both rectangles, without scaling,
converting to dstInfo.colorType() and dstInfo.alphaType() if required.
Pixels are readable when SkBaseDevice is raster, or backed by a GPU.
Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
class like SkDumpCanvas.
The destination pixel storage must be allocated by the caller.
Pixel values are converted only if SkColorType and SkAlphaType
do not match. Only pixels within both source and destination rectangles
are copied. dstPixels contents outside SkRect intersection are unchanged.
Pass negative values for srcX or srcY to offset pixels across or down destination.
Does not copy, and returns false if:
- Source and destination rectangles do not intersect.
- SkCanvas pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType().
- SkCanvas pixels are not readable; for instance, SkCanvas is document-based.
- dstRowBytes is too small to contain one row of pixels.
@param dstInfo width, height, SkColorType, and SkAlphaType of dstPixels
@param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger
@param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger
@param srcX offset into readable pixels in x; may be negative
@param srcY offset into readable pixels in y; may be negative
@return true if pixels were copied
*/
bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY);
/** Copies SkRect of pixels from SkCanvas into pixmap. SkMatrix and clip are
ignored.
Source SkRect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Destination SkRect corners are (0, 0) and (pixmap.width(), pixmap.height()).
Copies each readable pixel intersecting both rectangles, without scaling,
converting to pixmap.colorType() and pixmap.alphaType() if required.
Pixels are readable when SkBaseDevice is raster, or backed by a GPU.
Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
class like SkDumpCanvas.
Caller must allocate pixel storage in pixmap if needed.
Pixel values are converted only if SkColorType and SkAlphaType
do not match. Only pixels within both source and destination SkRect
are copied. pixmap pixels contents outside SkRect intersection are unchanged.
Pass negative values for srcX or srcY to offset pixels across or down pixmap.
Does not copy, and returns false if:
- Source and destination rectangles do not intersect.
- SkCanvas pixels could not be converted to pixmap.colorType() or pixmap.alphaType().
- SkCanvas pixels are not readable; for instance, SkCanvas is document-based.
- SkPixmap pixels could not be allocated.
- pixmap.rowBytes() is too small to contain one row of pixels.
@param pixmap storage for pixels copied from SkCanvas
@param srcX offset into readable pixels in x; may be negative
@param srcY offset into readable pixels in y; may be negative
@return true if pixels were copied
*/
bool readPixels(const SkPixmap& pixmap, int srcX, int srcY);
/** Copies SkRect of pixels from SkCanvas into bitmap. SkMatrix and clip are
ignored.
Source SkRect corners are (srcX, srcY) and (imageInfo().width(), imageInfo().height()).
Destination SkRect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Copies each readable pixel intersecting both rectangles, without scaling,
converting to bitmap.colorType() and bitmap.alphaType() if required.
Pixels are readable when SkBaseDevice is raster, or backed by a GPU.
Pixels are not readable when SkCanvas is returned by SkDocument::beginPage,
returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
class like SkDumpCanvas.
Caller must allocate pixel storage in bitmap if needed.
SkBitmap values are converted only if SkColorType and SkAlphaType
do not match. Only pixels within both source and destination rectangles
are copied. SkBitmap pixels outside SkRect intersection are unchanged.
Pass negative values for srcX or srcY to offset pixels across or down bitmap.
Does not copy, and returns false if:
- Source and destination rectangles do not intersect.
- SkCanvas pixels could not be converted to bitmap.colorType() or bitmap.alphaType().
- SkCanvas pixels are not readable; for instance, SkCanvas is document-based.
- bitmap pixels could not be allocated.
- bitmap.rowBytes() is too small to contain one row of pixels.
@param bitmap storage for pixels copied from SkCanvas
@param srcX offset into readable pixels in x; may be negative
@param srcY offset into readable pixels in y; may be negative
@return true if pixels were copied
*/
bool readPixels(const SkBitmap& bitmap, int srcX, int srcY);
/** Copies SkRect from pixels to SkCanvas. SkMatrix and clip are ignored.
Source SkRect corners are (0, 0) and (info.width(), info.height()).
Destination SkRect corners are (x, y) and
(imageInfo().width(), imageInfo().height()).
Copies each readable pixel intersecting both rectangles, without scaling,
converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Pixels are writable when SkBaseDevice is raster, or backed by a GPU.
Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
class like SkDumpCanvas.
Pixel values are converted only if SkColorType and SkAlphaType
do not match. Only pixels within both source and destination rectangles
are copied. SkCanvas pixels outside SkRect intersection are unchanged.
Pass negative values for x or y to offset pixels to the left or
above SkCanvas pixels.
Does not copy, and returns false if:
- Source and destination rectangles do not intersect.
- pixels could not be converted to SkCanvas imageInfo().colorType() or
imageInfo().alphaType().
- SkCanvas pixels are not writable; for instance, SkCanvas is document-based.
- rowBytes is too small to contain one row of pixels.
@param info width, height, SkColorType, and SkAlphaType of pixels
@param pixels pixels to copy, of size info.height() times rowBytes, or larger
@param rowBytes size of one row of pixels; info.width() times pixel size, or larger
@param x offset into SkCanvas writable pixels in x; may be negative
@param y offset into SkCanvas writable pixels in y; may be negative
@return true if pixels were written to SkCanvas
*/
bool writePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, int x, int y);
/** Copies SkRect from pixels to SkCanvas. SkMatrix and clip are ignored.
Source SkRect corners are (0, 0) and (bitmap.width(), bitmap.height()).
Destination SkRect corners are (x, y) and
(imageInfo().width(), imageInfo().height()).
Copies each readable pixel intersecting both rectangles, without scaling,
converting to imageInfo().colorType() and imageInfo().alphaType() if required.
Pixels are writable when SkBaseDevice is raster, or backed by a GPU.
Pixels are not writable when SkCanvas is returned by SkDocument::beginPage,
returned by SkPictureRecorder::beginRecording, or SkCanvas is the base of a utility
class like SkDumpCanvas.
Pixel values are converted only if SkColorType and SkAlphaType
do not match. Only pixels within both source and destination rectangles
are copied. SkCanvas pixels outside SkRect intersection are unchanged.
Pass negative values for x or y to offset pixels to the left or
above SkCanvas pixels.
Does not copy, and returns false if:
- Source and destination rectangles do not intersect.
- bitmap does not have allocated pixels.
- bitmap pixels could not be converted to SkCanvas imageInfo().colorType() or
imageInfo().alphaType().
- SkCanvas pixels are not writable; for instance, SkCanvas is document based.
- bitmap pixels are inaccessible; for instance, bitmap wraps a texture.
@param bitmap contains pixels copied to SkCanvas
@param x offset into SkCanvas writable pixels in x; may be negative
@param y offset into SkCanvas writable pixels in y; may be negative
@return true if pixels were written to SkCanvas
*/
bool writePixels(const SkBitmap& bitmap, int x, int y);
/** Saves SkMatrix, clip, and SkDrawFilter (SkDrawFilter deprecated on most platforms).
Calling restore() discards changes to SkMatrix, clip, and SkDrawFilter,
restoring the SkMatrix, clip, and SkDrawFilter to their state when save() was called.
SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(), setMatrix(),
and resetMatrix(). Clip may be changed by clipRect(), clipRRect(), clipPath(), clipRegion().
Saved SkCanvas state is put on a stack; multiple calls to save() should be balance
by an equal number of calls to restore().
Call restoreToCount() with result to restore this and subsequent saves.
@return depth of saved stack
*/
int save();
/** Saves SkMatrix, clip, and SkDrawFilter (SkDrawFilter deprecated on most platforms),
and allocates a SkBitmap for subsequent drawing.
Calling restore() discards changes to SkMatrix, clip, and SkDrawFilter,
and draws the SkBitmap.
SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
clipPath(), clipRegion().
SkRect bounds suggests but does not define the SkBitmap size. To clip drawing to
a specific rectangle, use clipRect().
Optional SkPaint paint applies color alpha, SkColorFilter, SkImageFilter, and
SkBlendMode when restore() is called.
Call restoreToCount() with returned value to restore this and subsequent saves.
@param bounds hint to limit the size of the layer; may be nullptr
@param paint graphics state for layer; may be nullptr
@return depth of saved stack
*/
int saveLayer(const SkRect* bounds, const SkPaint* paint);
/** Saves SkMatrix, clip, and SkDrawFilter (SkDrawFilter deprecated on most platforms),
and allocates a SkBitmap for subsequent drawing.
Calling restore() discards changes to SkMatrix, clip, and SkDrawFilter,
and draws the SkBitmap.
SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
clipPath(), clipRegion().
SkRect bounds suggests but does not define the layer size. To clip drawing to
a specific rectangle, use clipRect().
Optional SkPaint paint applies color alpha, SkColorFilter, SkImageFilter, and
SkBlendMode when restore() is called.
Call restoreToCount() with returned value to restore this and subsequent saves.
@param bounds hint to limit the size of layer; may be nullptr
@param paint graphics state for layer; may be nullptr
@return depth of saved stack
*/
int saveLayer(const SkRect& bounds, const SkPaint* paint) {
return this->saveLayer(&bounds, paint);
}
/** Saves SkMatrix, clip, and SkDrawFilter (SkDrawFilter deprecated on most platforms),
and allocates a SkBitmap for subsequent drawing.
LCD text is preserved when the layer is drawn to the prior layer.
Calling restore() discards changes to SkMatrix, clip, and SkDrawFilter,
and draws layer.
SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
clipPath(), clipRegion().
SkRect bounds suggests but does not define the layer size. To clip drawing to
a specific rectangle, use clipRect().
Optional SkPaint paint applies color alpha, SkColorFilter, SkImageFilter, and
SkBlendMode when restore() is called.
Call restoreToCount() with returned value to restore this and subsequent saves.
Draw text on an opaque background so that LCD text blends correctly with the
prior layer. LCD text drawn on a background with transparency may result in
incorrect blending.
@param bounds hint to limit the size of layer; may be nullptr
@param paint graphics state for layer; may be nullptr
@return depth of saved stack
*/
int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint);
/** Saves SkMatrix, clip, and SkDrawFilter (SkDrawFilter deprecated on most platforms),
and allocates SkBitmap for subsequent drawing.
Calling restore() discards changes to SkMatrix, clip, and SkDrawFilter,
and blends layer with alpha opacity onto prior layer.
SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
clipPath(), clipRegion().
SkRect bounds suggests but does not define layer size. To clip drawing to
a specific rectangle, use clipRect().
alpha of zero is fully transparent, 255 is fully opaque.
Call restoreToCount() with returned value to restore this and subsequent saves.
@param bounds hint to limit the size of layer; may be nullptr
@param alpha opacity of layer
@return depth of saved stack
*/
int saveLayerAlpha(const SkRect* bounds, U8CPU alpha);
/** \enum
SaveLayerFlags provides options that may be used in any combination in SaveLayerRec,
defining how layer allocated by saveLayer() operates.
*/
enum {
/** Creates layer for LCD text. Flag is ignored if layer SkPaint contains
SkImageFilter or SkColorFilter.
*/
kPreserveLCDText_SaveLayerFlag = 1 << 1,
/** Initializes layer with the contents of the previous layer. */
kInitWithPrevious_SaveLayerFlag = 1 << 2,
#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
/** To be deprecated soon. */
kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
#endif
};
typedef uint32_t SaveLayerFlags;
/** \struct SkCanvas::SaveLayerRec
SaveLayerRec contains the state used to create the layer.
*/
struct SaveLayerRec {
/** Sets fBounds, fPaint, and fBackdrop to nullptr. Clears fSaveLayerFlags.
@return empty SaveLayerRec
*/
SaveLayerRec() {}
/** Sets fBounds, fPaint, and fSaveLayerFlags; sets fBackdrop to nullptr.
@param bounds layer dimensions; may be nullptr
@param paint applied to layer when overlaying prior layer; may be nullptr
@param saveLayerFlags SaveLayerRec options to modify layer
@return SaveLayerRec with empty backdrop
*/
SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
: fBounds(bounds)
, fPaint(paint)
, fSaveLayerFlags(saveLayerFlags)
{}
/** Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
@param bounds layer dimensions; may be nullptr
@param paint applied to layer when overlaying prior layer;
may be nullptr
@param backdrop prior layer copied with SkImageFilter; may be nullptr
@param saveLayerFlags SaveLayerRec options to modify layer
@return SaveLayerRec fully specified
*/
SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
SaveLayerFlags saveLayerFlags)
: fBounds(bounds)
, fPaint(paint)
, fBackdrop(backdrop)
, fSaveLayerFlags(saveLayerFlags)
{}
/** EXPERIMENTAL: Not ready for general use.
Sets fBounds, fPaint, fBackdrop, fClipMask, fClipMatrix, and fSaveLayerFlags.
clipMatrix uses color alpha channel of image, transformed by clipMatrix, to clip
layer when drawn to SkCanvas.
Implementation is not complete; has no effect if SkBaseDevice is GPU-backed.
@param bounds layer dimensions; may be nullptr
@param paint graphics state applied to layer when overlaying prior
layer; may be nullptr
@param backdrop prior layer copied with SkImageFilter;
may be nullptr
@param clipMask clip applied to layer; may be nullptr
@param clipMatrix matrix applied to clipMask; may be nullptr to use
identity matrix
@param saveLayerFlags SaveLayerRec options to modify layer
@return SaveLayerRec fully specified
*/
SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
const SkImage* clipMask, const SkMatrix* clipMatrix,
SaveLayerFlags saveLayerFlags)
: fBounds(bounds)
, fPaint(paint)
, fBackdrop(backdrop)
, fClipMask(clipMask)
, fClipMatrix(clipMatrix)
, fSaveLayerFlags(saveLayerFlags)
{}
/** fBounds is used as a hint to limit the size of layer; may be nullptr.
fBounds suggests but does not define layer size. To clip drawing to
a specific rectangle, use clipRect().
*/
const SkRect* fBounds = nullptr;
/** fPaint modifies how layer overlays the prior layer; may be nullptr.
color alpha, SkBlendMode, SkColorFilter, SkDrawLooper, SkImageFilter, and
SkMaskFilter affect layer draw.
*/
const SkPaint* fPaint = nullptr;
/** fBackdrop applies SkImageFilter to the prior layer when copying to the layer;
may be nullptr. Use kInitWithPrevious_SaveLayerFlag to copy the
prior layer without an SkImageFilter.
*/
const SkImageFilter* fBackdrop = nullptr;
/** restore() clips layer by the color alpha channel of fClipMask when
layer is copied to SkBaseDevice. fClipMask may be nullptr. .
*/
const SkImage* fClipMask = nullptr;
/** fClipMatrix transforms fClipMask before it clips layer. If
fClipMask describes a translucent gradient, it may be scaled and rotated
without introducing artifacts. fClipMatrix may be nullptr.
*/
const SkMatrix* fClipMatrix = nullptr;
/** fSaveLayerFlags are used to create layer without transparency,
create layer for LCD text, and to create layer with the
contents of the previous layer.
*/
SaveLayerFlags fSaveLayerFlags = 0;
};
/** Saves SkMatrix, clip, and SkDrawFilter (SkDrawFilter deprecated on most platforms),
and allocates SkBitmap for subsequent drawing.
Calling restore() discards changes to SkMatrix, clip, and SkDrawFilter,
and blends SkBitmap with color alpha opacity onto the prior layer.
SkMatrix may be changed by translate(), scale(), rotate(), skew(), concat(),
setMatrix(), and resetMatrix(). Clip may be changed by clipRect(), clipRRect(),
clipPath(), clipRegion().
SaveLayerRec contains the state used to create the layer.
Call restoreToCount() with returned value to restore this and subsequent saves.
@param layerRec layer state
@return depth of save state stack
*/
int saveLayer(const SaveLayerRec& layerRec);
/** Removes changes to SkMatrix, clip, and SkDrawFilter since SkCanvas state was
last saved. The state is removed from the stack.
Does nothing if the stack is empty.
*/
void restore();
/** Returns the number of saved states, each containing: SkMatrix, clip, and SkDrawFilter.
Equals the number of save() calls less the number of restore() calls plus one.
The save count of a new canvas is one.
@return depth of save state stack
*/
int getSaveCount() const;
/** Restores state to SkMatrix, clip, and SkDrawFilter values when save(), saveLayer(),
saveLayerPreserveLCDTextRequests(), or saveLayerAlpha() returned saveCount.
Does nothing if saveCount is greater than state stack count.
Restores state to initial values if saveCount is less than or equal to one.
@param saveCount depth of state stack to restore
*/
void restoreToCount(int saveCount);
/** Translate SkMatrix by dx along the x-axis and dy along the y-axis.
Mathematically, replace SkMatrix with a translation matrix
premultiplied with SkMatrix.
This has the effect of moving the drawing by (dx, dy) before transforming
the result with SkMatrix.
@param dx distance to translate in x
@param dy distance to translate in y
*/
void translate(SkScalar dx, SkScalar dy);
/** Scale SkMatrix by sx on the x-axis and sy on the y-axis.
Mathematically, replace SkMatrix with a scale matrix
premultiplied with SkMatrix.
This has the effect of scaling the drawing by (sx, sy) before transforming
the result with SkMatrix.
@param sx amount to scale in x
@param sy amount to scale in y
*/
void scale(SkScalar sx, SkScalar sy);
/** Rotate SkMatrix by degrees. Positive degrees rotates clockwise.
Mathematically, replace SkMatrix with a rotation matrix
premultiplied with SkMatrix.
This has the effect of rotating the drawing by degrees before transforming
the result with SkMatrix.
@param degrees amount to rotate, in degrees
*/
void rotate(SkScalar degrees);
/** Rotate SkMatrix by degrees about a point at (px, py). Positive degrees rotates
clockwise.
Mathematically, construct a rotation matrix. Premultiply the rotation matrix by
a translation matrix, then replace SkMatrix with the resulting matrix
premultiplied with SkMatrix.
This has the effect of rotating the drawing about a given point before
transforming the result with SkMatrix.
@param degrees amount to rotate, in degrees
@param px x-coordinate of the point to rotate about
@param py y-coordinate of the point to rotate about
*/
void rotate(SkScalar degrees, SkScalar px, SkScalar py);
/** Skew SkMatrix by sx on the x-axis and sy on the y-axis. A positive value of sx
skews the drawing right as y increases; a positive value of sy skews the drawing
down as x increases.
Mathematically, replace SkMatrix with a skew matrix premultiplied with SkMatrix.
This has the effect of skewing the drawing by (sx, sy) before transforming
the result with SkMatrix.
@param sx amount to skew in x
@param sy amount to skew in y
*/
void skew(SkScalar sx, SkScalar sy);
/** Replace SkMatrix with matrix premultiplied with existing SkMatrix.
This has the effect of transforming the drawn geometry by matrix, before
transforming the result with existing SkMatrix.
@param matrix matrix to premultiply with existing SkMatrix
*/
void concat(const SkMatrix& matrix);
/** Replace SkMatrix with matrix.
Unlike concat(), any prior matrix state is overwritten.
@param matrix matrix to copy, replacing existing SkMatrix
*/
void setMatrix(const SkMatrix& matrix);
/** Sets SkMatrix to the identity matrix.
Any prior matrix state is overwritten.
*/
void resetMatrix();
/** Replace clip with the intersection or difference of clip and rect,
with an aliased or anti-aliased clip edge. rect is transformed by SkMatrix
before it is combined with clip.
@param rect SkRect to combine with clip
@param op SkClipOp to apply to clip
@param doAntiAlias true if clip is to be anti-aliased
*/
void clipRect(const SkRect& rect, SkClipOp op, bool doAntiAlias);
/** Replace clip with the intersection or difference of clip and rect.
Resulting clip is aliased; pixels are fully contained by the clip.
rect is transformed by SkMatrix before it is combined with clip.
@param rect SkRect to combine with clip
@param op SkClipOp to apply to clip
*/
void clipRect(const SkRect& rect, SkClipOp op) {
this->clipRect(rect, op, false);
}
/** Replace clip with the intersection of clip and rect.
Resulting clip is aliased; pixels are fully contained by the clip.
rect is transformed by SkMatrix
before it is combined with clip.
@param rect SkRect to combine with clip
@param doAntiAlias true if clip is to be anti-aliased
*/
void clipRect(const SkRect& rect, bool doAntiAlias = false) {
this->clipRect(rect, SkClipOp::kIntersect, doAntiAlias);
}
/** Sets the maximum clip rectangle, which can be set by clipRect(), clipRRect() and
clipPath() and intersect the current clip with the specified rect.
The maximum clip affects only future clipping operations; it is not retroactive.
The clip restriction is not recorded in pictures.
Pass an empty rect to disable maximum clip.
This is private API to be used only by Android framework.
@param rect maximum allowed clip in device coordinates
*/
void androidFramework_setDeviceClipRestriction(const SkIRect& rect);
/** Replace clip with the intersection or difference of clip and rrect,
with an aliased or anti-aliased clip edge.
rrect is transformed by SkMatrix
before it is combined with clip.
@param rrect SkRRect to combine with clip
@param op SkClipOp to apply to clip
@param doAntiAlias true if clip is to be anti-aliased
*/
void clipRRect(const SkRRect& rrect, SkClipOp op, bool doAntiAlias);
/** Replace clip with the intersection or difference of clip and rrect.
Resulting clip is aliased; pixels are fully contained by the clip.
rrect is transformed by SkMatrix before it is combined with clip.
@param rrect SkRRect to combine with clip
@param op SkClipOp to apply to clip
*/
void clipRRect(const SkRRect& rrect, SkClipOp op) {
this->clipRRect(rrect, op, false);
}
/** Replace clip with the intersection of clip and rrect,
with an aliased or anti-aliased clip edge.
rrect is transformed by SkMatrix before it is combined with clip.
@param rrect SkRRect to combine with clip
@param doAntiAlias true if clip is to be anti-aliased
*/
void clipRRect(const SkRRect& rrect, bool doAntiAlias = false) {
this->clipRRect(rrect, SkClipOp::kIntersect, doAntiAlias);
}
/** Replace clip with the intersection or difference of clip and path,
with an aliased or anti-aliased clip edge. SkPath::FillType determines if path
describes the area inside or outside its contours; and if path contour overlaps
itself or another path contour, whether the overlaps form part of the area.
path is transformed by SkMatrix before it is combined with clip.
@param path SkPath to combine with clip
@param op SkClipOp to apply to clip
@param doAntiAlias true if clip is to be anti-aliased
*/
void clipPath(const SkPath& path, SkClipOp op, bool doAntiAlias);
/** Replace clip with the intersection or difference of clip and path.
Resulting clip is aliased; pixels are fully contained by the clip.
SkPath::FillType determines if path
describes the area inside or outside its contours; and if path contour overlaps
itself or another path contour, whether the overlaps form part of the area.
path is transformed by SkMatrix
before it is combined with clip.
@param path SkPath to combine with clip
@param op SkClipOp to apply to clip
*/
void clipPath(const SkPath& path, SkClipOp op) {
this->clipPath(path, op, false);
}
/** Replace clip with the intersection of clip and path.
Resulting clip is aliased; pixels are fully contained by the clip.
SkPath::FillType determines if path
describes the area inside or outside its contours; and if path contour overlaps
itself or another path contour, whether the overlaps form part of the area.
path is transformed by SkMatrix before it is combined with clip.
@param path SkPath to combine with clip
@param doAntiAlias true if clip is to be anti-aliased
*/
void clipPath(const SkPath& path, bool doAntiAlias = false) {
this->clipPath(path, SkClipOp::kIntersect, doAntiAlias);
}
/** EXPERIMENTAL: Only used for testing.
Set to simplify clip stack using PathOps.
*/
void setAllowSimplifyClip(bool allow) {
fAllowSimplifyClip = allow;
}
/** Replace clip with the intersection or difference of clip and SkRegion deviceRgn.
Resulting clip is aliased; pixels are fully contained by the clip.
deviceRgn is unaffected by SkMatrix.
@param deviceRgn SkRegion to combine with clip
@param op SkClipOp to apply to clip
*/
void clipRegion(const SkRegion& deviceRgn, SkClipOp op = SkClipOp::kIntersect);
/** Return true if SkRect rect, transformed by SkMatrix, can be quickly determined to be
outside of clip. May return false even though rect is outside of clip.
Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
@param rect SkRect to compare with clip
@return true if rect, transformed by SkMatrix, does not intersect clip
*/
bool quickReject(const SkRect& rect) const;
/** Return true if path, transformed by SkMatrix, can be quickly determined to be
outside of clip. May return false even though path is outside of clip.
Use to check if an area to be drawn is clipped out, to skip subsequent draw calls.
@param path SkPath to compare with clip
@return true if path, transformed by SkMatrix, does not intersect clip
*/
bool quickReject(const SkPath& path) const;
/** Return bounds of clip, transformed by inverse of SkMatrix. If clip is empty,
return SkRect::MakeEmpty, where all SkRect sides equal zero.
SkRect returned is outset by one to account for partial pixel coverage if clip
is anti-aliased.
@return bounds of clip in local coordinates
*/
SkRect getLocalClipBounds() const;
/** Return bounds of clip, transformed by inverse of SkMatrix. If clip is empty,
return false, and set bounds to SkRect::MakeEmpty, where all SkRect sides equal zero.
bounds is outset by one to account for partial pixel coverage if clip
is anti-aliased.
@param bounds SkRect of clip in local coordinates
@return true if clip bounds is not empty
*/
bool getLocalClipBounds(SkRect* bounds) const {
*bounds = this->getLocalClipBounds();
return !bounds->isEmpty();
}
/** Return SkIRect bounds of clip, unaffected by SkMatrix. If clip is empty,
return SkRect::MakeEmpty, where all SkRect sides equal zero.
Unlike getLocalClipBounds(), returned SkIRect is not outset.
@return bounds of clip in SkBaseDevice coordinates
*/
SkIRect getDeviceClipBounds() const;
/** Return SkIRect bounds of clip, unaffected by SkMatrix. If clip is empty,
return false, and set bounds to SkRect::MakeEmpty, where all SkRect sides equal zero.
Unlike getLocalClipBounds(), bounds is not outset.
@param bounds SkRect of clip in device coordinates
@return true if clip bounds is not empty
*/
bool getDeviceClipBounds(SkIRect* bounds) const {
*bounds = this->getDeviceClipBounds();
return !bounds->isEmpty();
}
/** Fill clip with color color.
mode determines how ARGB is combined with destination.
@param color unpremultiplied ARGB
@param mode SkBlendMode used to combine source color and destination
*/
void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver);
/** Fill clip with color color using SkBlendMode::kSrc.
This has the effect of replacing all pixels contained by clip with color.
@param color unpremultiplied ARGB
*/
void clear(SkColor color) {
this->drawColor(color, SkBlendMode::kSrc);
}
/** Make SkCanvas contents undefined. Subsequent calls that read SkCanvas pixels,
such as drawing with SkBlendMode, return undefined results. discard() does
not change clip or SkMatrix.
discard() may do nothing, depending on the implementation of SkSurface or SkBaseDevice
that created SkCanvas.
discard() allows optimized performance on subsequent draws by removing
cached data associated with SkSurface or SkBaseDevice.
It is not necessary to call discard() once done with SkCanvas;
any cached data is deleted when owning SkSurface or SkBaseDevice is deleted.
*/
void discard() { this->onDiscard(); }
/** Fill clip with SkPaint paint. SkPaint components SkMaskFilter, SkShader,
SkColorFilter, SkImageFilter, and SkBlendMode affect drawing;
SkPathEffect in paint is ignored.
@param paint graphics state used to fill SkCanvas
*/
void drawPaint(const SkPaint& paint);
/** \enum SkCanvas::PointMode
Selects if an array of points are drawn as discrete points, as lines, or as
an open polygon.
*/
enum PointMode {
kPoints_PointMode, //!< Draw each point separately.
kLines_PointMode, //!< Draw each pair of points as a line segment.
kPolygon_PointMode, //!< Draw the array of points as a open polygon.
};
/** Draw pts using clip, SkMatrix and SkPaint paint.
count is the number of points; if count is less than one, has no effect.
mode may be one of: kPoints_PointMode, kLines_PointMode, or kPolygon_PointMode.
If mode is kPoints_PointMode, the shape of point drawn depends on paint
SkPaint::Cap. If paint is set to SkPaint::kRound_Cap, each point draws a
circle of diameter SkPaint stroke width. If paint is set to SkPaint::kSquare_Cap
or SkPaint::kButt_Cap, each point draws a square of width and height
SkPaint stroke width.
If mode is kLines_PointMode, each pair of points draws a line segment.
One line is drawn for every two points; each point is used once. If count is odd,
the final point is ignored.
If mode is kPolygon_PointMode, each adjacent pair of points draws a line segment.
count minus one lines are drawn; the first and last point are used once.
Each line segment respects paint SkPaint::Cap and SkPaint stroke width.
SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
Always draws each element one at a time; is not affected by
SkPaint::Join, and unlike drawPath(), does not create a mask from all points
and lines before drawing.
@param mode whether pts draws points or lines
@param count number of points in the array
@param pts array of points to draw
@param paint stroke, blend, color, and so on, used to draw
*/
void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint);
/** Draw point at (x, y) using clip, SkMatrix and SkPaint paint.
The shape of point drawn depends on paint SkPaint::Cap.
If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
SkPaint stroke width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
draw a square of width and height SkPaint stroke width.
SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
@param x left edge of circle or square
@param y top edge of circle or square
@param paint stroke, blend, color, and so on, used to draw
*/
void drawPoint(SkScalar x, SkScalar y, const SkPaint& paint);
/** Draw point p using clip, SkMatrix and SkPaint paint.
The shape of point drawn depends on paint SkPaint::Cap.
If paint is set to SkPaint::kRound_Cap, draw a circle of diameter
SkPaint stroke width. If paint is set to SkPaint::kSquare_Cap or SkPaint::kButt_Cap,
draw a square of width and height SkPaint stroke width.
SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
@param p top-left edge of circle or square
@param paint stroke, blend, color, and so on, used to draw
*/
void drawPoint(SkPoint p, const SkPaint& paint) {
this->drawPoint(p.x(), p.y(), paint);
}
/** Draws line segment from (x0, y0) to (x1, y1) using clip, SkMatrix, and SkPaint paint.
In paint: SkPaint stroke width describes the line thickness;
SkPaint::Cap draws the end rounded or square;
SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
@param x0 start of line segment on x-axis
@param y0 start of line segment on y-axis
@param x1 end of line segment on x-axis
@param y1 end of line segment on y-axis
@param paint stroke, blend, color, and so on, used to draw
*/
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint);
/** Draws line segment from p0 to p1 using clip, SkMatrix, and SkPaint paint.
In paint: SkPaint stroke width describes the line thickness;
SkPaint::Cap draws the end rounded or square;
SkPaint::Style is ignored, as if were set to SkPaint::kStroke_Style.
@param p0 start of line segment
@param p1 end of line segment
@param paint stroke, blend, color, and so on, used to draw
*/
void drawLine(SkPoint p0, SkPoint p1, const SkPaint& paint) {
this->drawLine(p0.x(), p0.y(), p1.x(), p1.y(), paint);
}
/** Draw SkRect rect using clip, SkMatrix, and SkPaint paint.
In paint: SkPaint::Style determines if rectangle is stroked or filled;
if stroked, SkPaint stroke width describes the line thickness, and
SkPaint::Join draws the corners rounded or square.
@param rect rectangle to draw
@param paint stroke or fill, blend, color, and so on, used to draw
*/
void drawRect(const SkRect& rect, const SkPaint& paint);
/** Draw SkIRect rect using clip, SkMatrix, and SkPaint paint.
In paint: SkPaint::Style determines if rectangle is stroked or filled;
if stroked, SkPaint stroke width describes the line thickness, and
SkPaint::Join draws the corners rounded or square.
@param rect rectangle to draw
@param paint stroke or fill, blend, color, and so on, used to draw
*/
void drawIRect(const SkIRect& rect, const SkPaint& paint) {
SkRect r;
r.set(rect); // promotes the ints to scalars
this->drawRect(r, paint);
}
/** Draw SkRegion region using clip, SkMatrix, and SkPaint paint.
In paint: SkPaint::Style determines if rectangle is stroked or filled;
if stroked, SkPaint stroke width describes the line thickness, and
SkPaint::Join draws the corners rounded or square.
@param region region to draw
@param paint SkPaint stroke or fill, blend, color, and so on, used to draw
*/
void drawRegion(const SkRegion& region, const SkPaint& paint);
/** Draw oval oval using clip, SkMatrix, and SkPaint.
In paint: SkPaint::Style determines if oval is stroked or filled;
if stroked, SkPaint stroke width describes the line thickness.
@param oval SkRect bounds of oval
@param paint SkPaint stroke or fill, blend, color, and so on, used to draw
*/
void drawOval(const SkRect& oval, const SkPaint& paint);
/** Draw SkRRect rrect using clip, SkMatrix, and SkPaint paint.
In paint: SkPaint::Style determines if rrect is stroked or filled;
if stroked, SkPaint stroke width describes the line thickness.
rrect may represent a rectangle, circle, oval, uniformly rounded rectangle, or
may have any combination of positive non-square radii for the four corners.
@param rrect SkRRect with up to eight corner radii to draw
@param paint SkPaint stroke or fill, blend, color, and so on, used to draw
*/
void drawRRect(const SkRRect& rrect, const SkPaint& paint);
/** Draw SkRRect outer and inner
using clip, SkMatrix, and SkPaint paint.
outer must contain inner or the drawing is undefined.
In paint: SkPaint::Style determines if SkRRect is stroked or filled;
if stroked, SkPaint stroke width describes the line thickness.
If stroked and SkRRect corner has zero length radii, SkPaint::Join can
draw corners rounded or square.
GPU-backed platforms optimize drawing when both outer and inner are
concave and outer contains inner. These platforms may not be able to draw
SkPath built with identical data as fast.
@param outer SkRRect outer bounds to draw
@param inner SkRRect inner bounds to draw
@param paint SkPaint stroke or fill, blend, color, and so on, used to draw
*/
void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);
/** Draw circle at (cx, cy) with radius using clip, SkMatrix, and SkPaint paint.
If radius is zero or less, nothing is drawn.
In paint: SkPaint::Style determines if circle is stroked or filled;
if stroked, SkPaint stroke width describes the line thickness.
@param cx circle center on the x-axis
@param cy circle center on the y-axis
@param radius half the diameter of circle
@param paint SkPaint stroke or fill, blend, color, and so on, used to draw
*/
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint& paint);
/** Draw circle at center with radius using clip, SkMatrix, and SkPaint paint.
If radius is zero or less, nothing is drawn.
In paint: SkPaint::Style determines if circle is stroked or filled;
if stroked, SkPaint stroke width describes the line thickness.
@param center circle center
@param radius half the diameter of circle
@param paint SkPaint stroke or fill, blend, color, and so on, used to draw
*/
void drawCircle(SkPoint center, SkScalar radius, const SkPaint& paint) {
this->drawCircle(center.x(), center.y(), radius, paint);
}
/** Draw arc using clip, SkMatrix, and SkPaint paint.
Arc is part of oval bounded by oval, sweeping from startAngle to startAngle plus
sweepAngle. startAngle and sweepAngle are in degrees.
startAngle of zero places start point at the right middle edge of oval.
A positive sweepAngle places arc end point clockwise from start point;
a negative sweepAngle places arc end point counterclockwise from start point.
sweepAngle may exceed 360 degrees, a full circle.
If useCenter is true, draw a wedge that includes lines from oval
center to arc end points. If useCenter is false, draw arc between end points.
If SkRect oval is empty or sweepAngle is zero, nothing is drawn.
@param oval SkRect bounds of oval containing arc to draw
@param startAngle angle in degrees where arc begins
@param sweepAngle sweep angle in degrees; positive is clockwise
@param useCenter if true, include the center of the oval
@param paint SkPaint stroke or fill, blend, color, and so on, used to draw
*/
void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
bool useCenter, const SkPaint& paint);
/** Draw SkRRect bounded by SkRect rect, with corner radii (rx, ry) using clip,
SkMatrix, and SkPaint paint.
In paint: SkPaint::Style determines if SkRRect is stroked or filled;
if stroked, SkPaint stroke width describes the line thickness.
If rx or ry are less than zero, they are treated as if they are zero.
If rx plus ry exceeds rect width or rect height, radii are scaled down to fit.
If rx and ry are zero, SkRRect is drawn as SkRect and if stroked is affected by
SkPaint::Join.
@param rect SkRect bounds of SkRRect to draw
@param rx axis length in x of oval describing rounded corners
@param ry axis length in y of oval describing rounded corners
@param paint stroke, blend, color, and so on, used to draw
*/
void drawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, const SkPaint& paint);
/** Draw SkPath path using clip, SkMatrix, and SkPaint paint.
SkPath contains an array of path contour, each of which may be open or closed.
In paint: SkPaint::Style determines if SkRRect is stroked or filled:
if filled, SkPath::FillType determines whether path contour describes inside or
outside of fill; if stroked, SkPaint stroke width describes the line thickness,
SkPaint::Cap describes line ends, and SkPaint::Join describes how
corners are drawn.
@param path SkPath to draw
@param paint stroke, blend, color, and so on, used to draw
*/
void drawPath(const SkPath& path, const SkPaint& paint);
/** Draw SkImage image, with its top-left corner at (left, top),
using clip, SkMatrix, and optional SkPaint paint.
If paint is supplied, apply SkColorFilter, color alpha, SkImageFilter, SkBlendMode,
and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from image bounds. If generated
mask extends beyond image bounds, replicate image edge colors, just as SkShader
made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
image edge color when it samples outside of its bounds.
@param image uncompressed rectangular map of pixels
@param left left side of image
@param top top side of image
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
*/
void drawImage(const SkImage* image, SkScalar left, SkScalar top,
const SkPaint* paint = nullptr);
/** Draw SkImage image, with its top-left corner at (left, top),
using clip, SkMatrix, and optional SkPaint paint.
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from image bounds. If generated
mask extends beyond image bounds, replicate image edge colors, just as SkShader
made from SkImage::makeShader with SkShader::kClamp_TileMode set replicates the
image edge color when it samples outside of its bounds.
@param image uncompressed rectangular map of pixels
@param left left side of image
@param top pop side of image
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
*/
void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
const SkPaint* paint = nullptr) {
this->drawImage(image.get(), left, top, paint);
}
/** \enum SkCanvas::SrcRectConstraint
SrcRectConstraint controls the behavior at the edge of source SkRect,
provided to drawImageRect(), trading off speed for precision.
SkImageFilter in SkPaint may sample multiple pixels in the image. Source SkRect
restricts the bounds of pixels that may be read. SkImageFilter may slow down if
it cannot read outside the bounds, when sampling near the edge of source SkRect.
SrcRectConstraint specifies whether an SkImageFilter is allowed to read pixels
outside source SkRect.
*/
enum SrcRectConstraint {
/** sampling only inside of its bounds, possibly with a performance penalty. */
kStrict_SrcRectConstraint,
/** by half the width of SkImageFilter, permitting it to run faster but with
error at the image edges.
*/
kFast_SrcRectConstraint,
};
/** Draw SkRect src of SkImage image, scaled and translated to fill SkRect dst.
Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from image bounds.
If generated mask extends beyond image bounds, replicate image edge colors, just
as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
replicates the image edge color when it samples outside of its bounds.
constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
sample within src; set to kFast_SrcRectConstraint allows sampling outside to
improve performance.
@param image SkImage containing pixels, dimensions, and format
@param src source SkRect of image to draw from
@param dst destination SkRect of image to draw to
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
@param constraint filter strictly within src or draw faster
*/
void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst,
const SkPaint* paint,
SrcRectConstraint constraint = kStrict_SrcRectConstraint);
/** Draw SkIRect isrc of SkImage image, scaled and translated to fill SkRect dst.
Note that isrc is on integer pixel boundaries; dst may include fractional
boundaries. Additionally transform draw using clip, SkMatrix, and optional SkPaint
paint.
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from image bounds.
If generated mask extends beyond image bounds, replicate image edge colors, just
as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
replicates the image edge color when it samples outside of its bounds.
constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
improve performance.
@param image SkImage containing pixels, dimensions, and format
@param isrc source SkIRect of image to draw from
@param dst destination SkRect of image to draw to
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
@param constraint filter strictly within isrc or draw faster
*/
void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst,
const SkPaint* paint,
SrcRectConstraint constraint = kStrict_SrcRectConstraint);
/** Draw SkImage image, scaled and translated to fill SkRect dst, using clip, SkMatrix,
and optional SkPaint paint.
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from image bounds.
If generated mask extends beyond image bounds, replicate image edge colors, just
as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
replicates the image edge color when it samples outside of its bounds.
constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
sample within image; set to kFast_SrcRectConstraint allows sampling outside to
improve performance.
@param image SkImage containing pixels, dimensions, and format
@param dst destination SkRect of image to draw to
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
@param constraint filter strictly within image or draw faster
*/
void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint,
SrcRectConstraint constraint = kStrict_SrcRectConstraint);
/** Draw SkRect src of SkImage image, scaled and translated to fill SkRect dst.
Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from image bounds.
If generated mask extends beyond image bounds, replicate image edge colors, just
as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
replicates the image edge color when it samples outside of its bounds.
constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
sample within src; set to kFast_SrcRectConstraint allows sampling outside to
improve performance.
@param image SkImage containing pixels, dimensions, and format
@param src source SkRect of image to draw from
@param dst destination SkRect of image to draw to
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
@param constraint filter strictly within src or draw faster
*/
void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
const SkPaint* paint,
SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
this->drawImageRect(image.get(), src, dst, paint, constraint);
}
/** Draw SkIRect isrc of SkImage image, scaled and translated to fill SkRect dst.
isrc is on integer pixel boundaries; dst may include fractional boundaries.
Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from image bounds.
If generated mask extends beyond image bounds, replicate image edge colors, just
as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
replicates the image edge color when it samples outside of its bounds.
constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
sample within image; set to kFast_SrcRectConstraint allows sampling outside to
improve performance.
@param image SkImage containing pixels, dimensions, and format
@param isrc source SkIRect of image to draw from
@param dst destination SkRect of image to draw to
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
@param constraint filter strictly within image or draw faster
*/
void drawImageRect(const sk_sp<SkImage>& image, const SkIRect& isrc, const SkRect& dst,
const SkPaint* paint,
SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
this->drawImageRect(image.get(), isrc, dst, paint, constraint);
}
/** Draw SkImage image, scaled and translated to fill SkRect dst,
using clip, SkMatrix, and optional SkPaint paint.
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from image bounds.
If generated mask extends beyond image bounds, replicate image edge colors, just
as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
replicates the image edge color when it samples outside of its bounds.
constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
sample within image; set to kFast_SrcRectConstraint allows sampling outside to
improve performance.
@param image SkImage containing pixels, dimensions, and format
@param dst destination SkRect of image to draw to
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
@param constraint filter strictly within image or draw faster
*/
void drawImageRect(const sk_sp<SkImage>& image, const SkRect& dst, const SkPaint* paint,
SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
this->drawImageRect(image.get(), dst, paint, constraint);
}
/** Draw SkImage image stretched proportionally to fit into SkRect dst.
SkIRect center divides the image into nine sections: four sides, four corners, and
the center. Corners are unmodified or scaled down proportionately if their sides
are larger than dst; center and four sides are scaled to fit remaining space, if any.
Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from image bounds.
If generated mask extends beyond image bounds, replicate image edge colors, just
as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
replicates the image edge color when it samples outside of its bounds.
@param image SkImage containing pixels, dimensions, and format
@param center SkIRect edge of image corners and sides
@param dst destination SkRect of image to draw to
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
*/
void drawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
const SkPaint* paint = nullptr);
/** Draw SkImage image stretched proportionally to fit into SkRect dst.
SkIRect center divides the image into nine sections: four sides, four corners, and
the center. Corners are not scaled, or scaled down proportionately if their sides
are larger than dst; center and four sides are scaled to fit remaining space, if any.
Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If image is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from bitmap bounds. If paint's
SkFilterQuality is higher than kLow_SkFilterQuality, it will be treated as if it
were kLow_SkFilterQuality.
If generated mask extends beyond image bounds, replicate image edge colors, just
as SkShader made from SkImage::makeShader with SkShader::kClamp_TileMode set
replicates the image edge color when it samples outside of its bounds.
@param image SkImage containing pixels, dimensions, and format
@param center SkIRect edge of image corners and sides
@param dst destination SkRect of image to draw to
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
*/
void drawImageNine(const sk_sp<SkImage>& image, const SkIRect& center, const SkRect& dst,
const SkPaint* paint = nullptr) {
this->drawImageNine(image.get(), center, dst, paint);
}
/** Draw SkBitmap bitmap, with its top-left corner at (left, top),
using clip, SkMatrix, and optional SkPaint paint.
If SkPaint paint is not nullptr, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from bitmap bounds.
If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
just as SkShader made from SkShader::MakeBitmapShader with
SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
outside of its bounds.
@param bitmap SkBitmap containing pixels, dimensions, and format
@param left left side of bitmap
@param top top side of bitmap
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
*/
void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
const SkPaint* paint = nullptr);
/** Draw SkRect src of SkBitmap bitmap, scaled and translated to fill SkRect dst.
Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from bitmap bounds.
If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
just as SkShader made from SkShader::MakeBitmapShader with
SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
outside of its bounds.
constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
sample within src; set to kFast_SrcRectConstraint allows sampling outside to
improve performance.
@param bitmap SkBitmap containing pixels, dimensions, and format
@param src source SkRect of image to draw from
@param dst destination SkRect of image to draw to
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
@param constraint filter strictly within src or draw faster
*/
void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst,
const SkPaint* paint,
SrcRectConstraint constraint = kStrict_SrcRectConstraint);
/** Draw SkIRect isrc of SkBitmap bitmap, scaled and translated to fill SkRect dst.
isrc is on integer pixel boundaries; dst may include fractional boundaries.
Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from bitmap bounds.
If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
just as SkShader made from SkShader::MakeBitmapShader with
SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
outside of its bounds.
constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
sample within isrc; set to kFast_SrcRectConstraint allows sampling outside to
improve performance.
@param bitmap SkBitmap containing pixels, dimensions, and format
@param isrc source SkIRect of image to draw from
@param dst destination SkRect of image to draw to
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
@param constraint sample strictly within isrc, or draw faster
*/
void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst,
const SkPaint* paint,
SrcRectConstraint constraint = kStrict_SrcRectConstraint);
/** Draw SkBitmap bitmap, scaled and translated to fill SkRect dst.
bitmap bounds is on integer pixel boundaries; dst may include fractional boundaries.
Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from bitmap bounds.
If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
just as SkShader made from SkShader::MakeBitmapShader with
SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
outside of its bounds.
constraint set to kStrict_SrcRectConstraint limits SkPaint SkFilterQuality to
sample within bitmap; set to kFast_SrcRectConstraint allows sampling outside to
improve performance.
@param bitmap SkBitmap containing pixels, dimensions, and format
@param dst destination SkRect of image to draw to
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
@param constraint filter strictly within bitmap or draw faster
*/
void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint,
SrcRectConstraint constraint = kStrict_SrcRectConstraint);
/** Draw SkBitmap bitmap stretched proportionally to fit into SkRect dst.
SkIRect center divides the bitmap into nine sections: four sides, four corners,
and the center. Corners are not scaled, or scaled down proportionately if their
sides are larger than dst; center and four sides are scaled to fit remaining
space, if any.
Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from bitmap bounds. If paint's
SkFilterQuality is higher than kLow_SkFilterQuality, it will be treated as if it
were kLow_SkFilterQuality.
If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
just as SkShader made from SkShader::MakeBitmapShader with
SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
outside of its bounds.
@param bitmap SkBitmap containing pixels, dimensions, and format
@param center SkIRect edge of image corners and sides
@param dst destination SkRect of image to draw to
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
*/
void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
const SkPaint* paint = nullptr);
/** \struct SkCanvas::Lattice
SkCanvas::Lattice divides SkBitmap or SkImage into a rectangular grid.
Grid entries on even columns and even rows are fixed; these entries are
always drawn at their original size if the destination is large enough.
If the destination side is too small to hold the fixed entries, all fixed
entries are proportionately scaled down to fit.
The grid entries not on even columns and rows are scaled to fit the
remaining space, if any.
*/
struct Lattice {
/** \enum SkCanvas::Lattice::RectType
Optional setting per rectangular grid entry to make it transparent,
or to fill the grid entry with a color.
*/
enum RectType : uint8_t {
kDefault = 0, //!< Draws SkBitmap into lattice rectangle.
kTransparent, //!< Skips lattice rectangle by making it transparent.
kFixedColor, //!< Draws one of fColors into lattice rectangle.
};
/** Array of x-coordinates that divide the bitmap vertically.
Array entries must be unique, increasing, greater than or equal to
fBounds left edge, and less than fBounds right edge.
Set the first element to fBounds left to collapse the left column of
fixed grid entries.
*/
const int* fXDivs;
/** Array of y-coordinates that divide the bitmap horizontally.
Array entries must be unique, increasing, greater than or equal to
fBounds top edge, and less than fBounds bottom edge.
Set the first element to fBounds top to collapse the top row of fixed
grid entries.
*/
const int* fYDivs;
/** Optional array of fill types, one per rectangular grid entry:
array length must be (fXCount + 1) * (fYCount + 1).
Each RectType is one of: kDefault, kTransparent, kFixedColor.
Array entries correspond to the rectangular grid entries, ascending
left to right and then top to bottom.
*/
const RectType* fRectTypes;
/** Number of entries in fXDivs array; one less than the number of
horizontal divisions.
*/
int fXCount;
/** Number of entries in fYDivs array; one less than the number of vertical
divisions.
*/
int fYCount;
/** Optional subset SkIRect source to draw from.
If nullptr, source bounds is dimensions of SkBitmap or SkImage.
*/
const SkIRect* fBounds;
/** Optional array of colors, one per rectangular grid entry.
Array length must be (fXCount + 1) * (fYCount + 1).
Array entries correspond to the rectangular grid entries, ascending
left to right, then top to bottom.
*/
const SkColor* fColors;
};
/** Draw SkBitmap bitmap stretched proportionally to fit into SkRect dst.
SkCanvas::Lattice lattice divides bitmap into a rectangular grid.
Each intersection of an even-numbered row and column is fixed; like the corners
of drawBitmapNine(), fixed lattice elements never scale larger than their initial
size and shrink proportionately when all fixed elements exceed the bitmap
dimension. All other grid elements scale to fill the available space, if any.
Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from bitmap bounds. If paint's
SkFilterQuality is higher than kLow_SkFilterQuality, it will be treated as if it
were kLow_SkFilterQuality.
If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
just as SkShader made from SkShader::MakeBitmapShader with
SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
outside of its bounds.
@param bitmap SkBitmap containing pixels, dimensions, and format
@param lattice division of bitmap into fixed and variable rectangles
@param dst destination SkRect of image to draw to
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
*/
void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
const SkPaint* paint = nullptr);
/** Draw SkImage image stretched proportionally to fit into SkRect dst.
SkCanvas::Lattice lattice divides image into a rectangular grid.
Each intersection of an even-numbered row and column is fixed; like the corners
of drawBitmapNine(), fixed lattice elements never scale larger than their initial
size and shrink proportionately when all fixed elements exceed the bitmap
dimension. All other grid elements scale to fill the available space, if any.
Additionally transform draw using clip, SkMatrix, and optional SkPaint paint.
If SkPaint paint is supplied, apply SkColorFilter, color alpha, SkImageFilter,
SkBlendMode, and SkDrawLooper. If bitmap is kAlpha_8_SkColorType, apply SkShader.
If paint contains SkMaskFilter, generate mask from bitmap bounds. If paint's
SkFilterQuality is higher than kLow_SkFilterQuality, it will be treated as if it
were kLow_SkFilterQuality.
If generated mask extends beyond bitmap bounds, replicate bitmap edge colors,
just as SkShader made from SkShader::MakeBitmapShader with
SkShader::kClamp_TileMode set replicates the bitmap edge color when it samples
outside of its bounds.
@param image SkImage containing pixels, dimensions, and format
@param lattice division of bitmap into fixed and variable rectangles
@param dst destination SkRect of image to draw to
@param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
and so on; or nullptr
*/
void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
const SkPaint* paint = nullptr);
/** Draw text, with origin at (x, y), using clip, SkMatrix, and SkPaint paint.
text meaning depends on SkPaint::TextEncoding; by default, text is encoded as
UTF-8.
x and y meaning depends on SkPaint::Align and SkPaint vertical text; by default
text draws left to right, positioning the first glyph left side bearing at x
and its baseline at y. Text size is affected by SkMatrix and SkPaint text size.
All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
filled 12 point black glyphs.
@param text character code points or glyphs drawn
@param byteLength byte length of text array
@param x start of text on x-axis
@param y start of text on y-axis
@param paint text size, blend, color, and so on, used to draw
*/
void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
const SkPaint& paint);
/** Draw null terminated string, with origin at (x, y), using clip, SkMatrix, and
SkPaint paint.
string meaning depends on SkPaint::TextEncoding; by default, strings are encoded
as UTF-8. Other values of SkPaint::TextEncoding are unlikely to produce the desired
results, since zero bytes may be embedded in the string.
x and y meaning depends on SkPaint::Align and SkPaint vertical text; by default
string draws left to right, positioning the first glyph left side bearing at x
and its baseline at y. Text size is affected by SkMatrix and SkPaint text size.
All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
filled 12 point black glyphs.
@param string character code points or glyphs drawn,
ending with a char value of zero
@param x start of string on x-axis
@param y start of string on y-axis
@param paint text size, blend, color, and so on, used to draw
*/
void drawString(const char* string, SkScalar x, SkScalar y, const SkPaint& paint) {
if (!string) {
return;
}
this->drawText(string, strlen(string), x, y, paint);
}
/** Draw null terminated string, with origin at (x, y), using clip, SkMatrix, and
SkPaint paint.
string meaning depends on SkPaint::TextEncoding; by default, strings are encoded
as UTF-8. Other values of SkPaint::TextEncoding are unlikely to produce the desired
results, since zero bytes may be embedded in the string.
x and y meaning depends on SkPaint::Align and SkPaint vertical text; by default
string draws left to right, positioning the first glyph left side bearing at x
and its baseline at y. Text size is affected by SkMatrix and SkPaint text size.
All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
filled 12 point black glyphs.
@param string character code points or glyphs drawn,
ending with a char value of zero
@param x start of string on x-axis
@param y start of string on y-axis
@param paint text size, blend, color, and so on, used to draw
*/
void drawString(const SkString& string, SkScalar x, SkScalar y, const SkPaint& paint);
/** Draw each glyph in text with the origin in pos array, using clip, SkMatrix, and
SkPaint paint. The number of entries in pos array must match the number of glyphs
described by byteLength of text.
text meaning depends on SkPaint::TextEncoding; by default, text is encoded as
UTF-8. pos elements' meaning depends on SkPaint::Align and SkPaint vertical text;
by default each glyph left side bearing is positioned at x and its
baseline is positioned at y. Text size is affected by SkMatrix and
SkPaint text size.
All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
filled 12 point black glyphs.
Layout engines such as Harfbuzz typically position each glyph
rather than using the font advance widths.
@param text character code points or glyphs drawn
@param byteLength byte length of text array
@param pos array of glyph origins
@param paint text size, blend, color, and so on, used to draw
*/
void drawPosText(const void* text, size_t byteLength, const SkPoint pos[],
const SkPaint& paint);
/** Draw each glyph in text with its (x, y) origin composed from xpos array and
constY, using clip, SkMatrix, and SkPaint paint. The number of entries in xpos array
must match the number of glyphs described by byteLength of text.
text meaning depends on SkPaint::TextEncoding; by default, text is encoded as
UTF-8. xpos elements' meaning depends on SkPaint::Align and SkPaint vertical text;
by default each glyph left side bearing is positioned at an xpos element and
its baseline is positioned at constY. Text size is affected by SkMatrix and
SkPaint text size.
All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
filled 12 point black glyphs.
Layout engines such as Harfbuzz typically position each glyph
rather than using the font advance widths if all glyphs share the same
baseline.
@param text character code points or glyphs drawn
@param byteLength byte length of text array
@param xpos array of x positions, used to position each glyph
@param constY shared y coordinate for all of x positions
@param paint text size, blend, color, and so on, used to draw
*/
void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
const SkPaint& paint);
/** Draw text on SkPath path, using clip, SkMatrix, and SkPaint paint.
Origin of text is at distance hOffset along the path, offset by a perpendicular
vector of length vOffset. If the path section corresponding the glyph advance is
curved, the glyph is drawn curved to match; control points in the glyph are
mapped to projected points parallel to the path. If the text advance is larger
than the path length, the excess text is clipped.
text meaning depends on SkPaint::TextEncoding; by default, text is encoded as
UTF-8. Origin meaning depends on SkPaint::Align and SkPaint vertical text; by
default text positions the first glyph left side bearing at origin x and its
baseline at origin y. Text size is affected by SkMatrix and SkPaint text size.
All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
filled 12 point black glyphs.
@param text character code points or glyphs drawn
@param byteLength byte length of text array
@param path SkPath providing text baseline
@param hOffset distance along path to offset origin
@param vOffset offset of text above (if negative) or below (if positive) the path
@param paint text size, blend, color, and so on, used to draw
*/
void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset,
SkScalar vOffset, const SkPaint& paint);
/** Draw text on SkPath path, using clip, SkMatrix, and SkPaint paint.
Origin of text is at beginning of path offset by matrix, if provided, before it
is mapped to path. If the path section corresponding the glyph advance is
curved, the glyph is drawn curved to match; control points in the glyph are
mapped to projected points parallel to the path. If the text advance is larger
than the path length, the excess text is clipped.
text meaning depends on SkPaint::TextEncoding; by default, text is encoded as
UTF-8. Origin meaning depends on SkPaint::Align and SkPaint vertical text; by
default text positions the first glyph left side bearing at origin x and its
baseline at origin y. Text size is affected by SkMatrix and SkPaint text size.
All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
filled 12 point black glyphs.
@param text character code points or glyphs drawn
@param byteLength byte length of text array
@param path SkPath providing text baseline
@param matrix transform of glyphs before mapping to path; may be nullptr
to use identity SkMatrix
@param paint text size, blend, color, and so on, used to draw
*/
void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
const SkMatrix* matrix, const SkPaint& paint);
/** Draw text, transforming each glyph by the corresponding SkRSXform,
using clip, SkMatrix, and SkPaint paint.
SkRSXform array specifies a separate square scale, rotation, and translation for
each glyph. Note that this per-glyph xform does not affect the shader (if present)
on the paint, just the glyph's geometry.
Optional SkRect cullRect is a conservative bounds of text, taking into account
SkRSXform and paint. If cullRect is outside of clip, canvas can skip drawing.
All elements of paint: SkPathEffect, SkMaskFilter, SkShader,
SkColorFilter, SkImageFilter, and SkDrawLooper; apply to text. By default, draws
filled 12 point black glyphs.
@param text character code points or glyphs drawn
@param byteLength byte length of text array
@param xform SkRSXform rotates, scales, and translates each glyph individually
@param cullRect SkRect bounds of text for efficient clipping; or nullptr
@param paint text size, blend, color, and so on, used to draw
*/
void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
const SkRect* cullRect, const SkPaint& paint);
/** Draw SkTextBlob blob at (x, y), using clip, SkMatrix, and SkPaint paint.
blob contains glyphs, their positions, and paint attributes specific to text:
SkTypeface, SkPaint text size, SkPaint text scale x, SkPaint text skew x,
SkPaint::Align, SkPaint::Hinting, SkPaint anti-alias, SkPaint fake bold,
SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
SkPaint subpixel text, and SkPaint vertical text.
SkPaint::TextEncoding must be set to SkPaint::kGlyphID_TextEncoding.
Elements of paint: SkPathEffect, SkMaskFilter, SkShader, SkColorFilter,
SkImageFilter, and SkDrawLooper; apply to blob.
@param blob glyphs, positions, and their paints' text size, typeface, and so on
@param x horizontal offset applied to blob
@param y vertical offset applied to blob
@param paint blend, color, stroking, and so on, used to draw
*/
void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint);
/** Draw SkTextBlob blob at (x, y), using clip, SkMatrix, and SkPaint paint.
blob contains glyphs, their positions, and paint attributes specific to text:
SkTypeface, SkPaint text size, SkPaint text scale x, SkPaint text skew x,
SkPaint::Align, SkPaint::Hinting, SkPaint anti-alias, SkPaint fake bold,
SkPaint font embedded bitmaps, SkPaint full hinting spacing, LCD text, SkPaint linear text,
SkPaint subpixel text, and SkPaint vertical text.
SkPaint::TextEncoding must be set to SkPaint::kGlyphID_TextEncoding.
Elements of paint: SkPathEffect, SkMaskFilter, SkShader, SkColorFilter,
SkImageFilter, and SkDrawLooper; apply to blob.
@param blob glyphs, positions, and their paints' text size, typeface, and so on
@param x horizontal offset applied to blob
@param y vertical offset applied to blob
@param paint blend, color, stroking, and so on, used to draw
*/
void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint) {
this->drawTextBlob(blob.get(), x, y, paint);
}
/** Draw SkPicture picture, using clip and SkMatrix.
Clip and SkMatrix are unchanged by picture contents, as if
save() was called before and restore() was called after drawPicture().
SkPicture records a series of draw commands for later playback.
@param picture recorded drawing commands to play
*/
void drawPicture(const SkPicture* picture) {
this->drawPicture(picture, nullptr, nullptr);
}
/** Draw SkPicture picture, using clip and SkMatrix.
Clip and SkMatrix are unchanged by picture contents, as if
save() was called before and restore() was called after drawPicture().
SkPicture records a series of draw commands for later playback.
@param picture recorded drawing commands to play
*/
void drawPicture(const sk_sp<SkPicture>& picture) {
this->drawPicture(picture.get());
}
/** Draw SkPicture picture, using clip and SkMatrix; transforming picture with
SkMatrix matrix, if provided; and use SkPaint paint color alpha, SkColorFilter,
SkImageFilter, and SkBlendMode, if provided.
matrix transformation is equivalent to: save(), concat(), drawPicture(), restore().
paint use is equivalent to: saveLayer(), drawPicture(), restore().
@param picture recorded drawing commands to play
@param matrix SkMatrix to rotate, scale, translate, and so on; may be nullptr
@param paint SkPaint to apply transparency, filtering, and so on; may be nullptr
*/
void drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint);
/** Draw SkPicture picture, using clip and SkMatrix; transforming picture with
SkMatrix matrix, if provided; and use SkPaint paint color alpha, SkColorFilter,
SkImageFilter, and SkBlendMode, if provided.
matrix transformation is equivalent to: save(), concat(), drawPicture(), restore().
paint use is equivalent to: saveLayer(), drawPicture(), restore().
@param picture recorded drawing commands to play
@param matrix SkMatrix to rotate, scale, translate, and so on; may be nullptr
@param paint SkPaint to apply transparency, filtering, and so on; may be nullptr
*/
void drawPicture(const sk_sp<SkPicture>& picture, const SkMatrix* matrix, const SkPaint* paint) {
this->drawPicture(picture.get(), matrix, paint);
}
/** Draw vertices vertices, a triangle mesh, using clip and SkMatrix.
If vertices texs and vertices colors are defined in vertices, and SkPaint paint
contains SkShader, SkBlendMode mode combines vertices colors with SkShader.
@param vertices triangle mesh to draw
@param mode combines vertices colors with SkShader, if both are present
@param paint specifies the SkShader, used as vertices texture; may be nullptr
*/
void drawVertices(const SkVertices* vertices, SkBlendMode mode, const SkPaint& paint);
/** Draw vertices vertices, a triangle mesh, using clip and SkMatrix.
If vertices texs and vertices colors are defined in vertices, and SkPaint paint
contains SkShader, SkBlendMode mode combines vertices colors with SkShader.
@param vertices triangle mesh to draw
@param mode combines vertices colors with SkShader, if both are present
@param paint specifies the SkShader, used as vertices texture, may be nullptr
*/
void drawVertices(const sk_sp<SkVertices>& vertices, SkBlendMode mode, const SkPaint& paint);
/** Draws a Coons_Patch: the interpolation of four cubics with shared corners,
associating a color, and optionally a texture coordinate, with each corner.
Coons_Patch uses clip and SkMatrix, paint SkShader, SkColorFilter,
color alpha, SkImageFilter, and SkBlendMode. If SkShader is provided it is treated
as Coons_Patch texture; SkBlendMode mode combines color colors and SkShader if
both are provided.
SkPoint array cubics specifies four SkPath cubic starting at the top-left corner,
in clockwise order, sharing every fourth point. The last SkPath cubic ends at the
first point.
Color array color associates colors with corners in top-left, top-right,
bottom-right, bottom-left order.
If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to
corners in top-left, top-right, bottom-right, bottom-left order.
@param cubics SkPath cubic array, sharing common points
@param colors color array, one for each corner
@param texCoords SkPoint array of texture coordinates, mapping SkShader to corners;
may be nullptr
@param mode SkBlendMode for colors, and for SkShader if paint has one
@param paint SkShader, SkColorFilter, SkBlendMode, used to draw
*/
void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);
/** Draws SkPath cubic Coons_Patch: the interpolation of four cubics with shared corners,
associating a color, and optionally a texture coordinate, with each corner.
Coons_Patch uses clip and SkMatrix, paint SkShader, SkColorFilter,
color alpha, SkImageFilter, and SkBlendMode. If SkShader is provided it is treated
as Coons_Patch texture; SkBlendMode mode combines color colors and SkShader if
both are provided.
SkPoint array cubics specifies four SkPath cubic starting at the top-left corner,
in clockwise order, sharing every fourth point. The last SkPath cubic ends at the
first point.
Color array color associates colors with corners in top-left, top-right,
bottom-right, bottom-left order.
If paint contains SkShader, SkPoint array texCoords maps SkShader as texture to
corners in top-left, top-right, bottom-right, bottom-left order.
@param cubics SkPath cubic array, sharing common points
@param colors color array, one for each corner
@param texCoords SkPoint array of texture coordinates, mapping SkShader to corners;
may be nullptr
@param paint SkShader, SkColorFilter, SkBlendMode, used to draw
*/
void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], const SkPaint& paint) {
this->drawPatch(cubics, colors, texCoords, SkBlendMode::kModulate, paint);
}
/** Draw a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
paint uses SkPaint anti-alias, color alpha, SkColorFilter, SkImageFilter, and SkBlendMode
to draw, if present. For each entry in the array, SkRect tex locates sprite in
atlas, and SkRSXform xform transforms it into destination space.
xform, text, and colors if present, must contain count entries.
Optional colors are applied for each sprite using SkBlendMode.
Optional cullRect is a conservative bounds of all transformed sprites.
If cullRect is outside of clip, canvas can skip drawing.
@param atlas SkImage containing sprites
@param xform SkRSXform mappings for sprites in atlas
@param tex SkRect locations of sprites in atlas
@param colors one per sprite, blended with sprite using SkBlendMode; may be nullptr
@param count number of sprites to draw
@param mode SkBlendMode combining colors and sprites
@param cullRect bounds of transformed sprites for efficient clipping; may be nullptr
@param paint SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
*/
void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
const SkPaint* paint);
/** Draw a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
paint uses SkPaint anti-alias, color alpha, SkColorFilter, SkImageFilter, and SkBlendMode
to draw, if present. For each entry in the array, SkRect tex locates sprite in
atlas, and SkRSXform xform transforms it into destination space.
xform, text, and colors if present, must contain count entries.
Optional colors is applied for each sprite using SkBlendMode.
Optional cullRect is a conservative bounds of all transformed sprites.
If cullRect is outside of clip, canvas can skip drawing.
@param atlas SkImage containing sprites
@param xform SkRSXform mappings for sprites in atlas
@param tex SkRect locations of sprites in atlas
@param colors one per sprite, blended with sprite using SkBlendMode; may be nullptr
@param count number of sprites to draw
@param mode SkBlendMode combining colors and sprites
@param cullRect bounds of transformed sprites for efficient clipping; may be nullptr
@param paint SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
*/
void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
const SkColor colors[], int count, SkBlendMode mode, const SkRect* cullRect,
const SkPaint* paint) {
this->drawAtlas(atlas.get(), xform, tex, colors, count, mode, cullRect, paint);
}
/** Draw a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
paint uses SkPaint anti-alias, color alpha, SkColorFilter, SkImageFilter, and SkBlendMode
to draw, if present. For each entry in the array, SkRect tex locates sprite in
atlas, and SkRSXform xform transforms it into destination space.
xform and text must contain count entries.
Optional cullRect is a conservative bounds of all transformed sprites.
If cullRect is outside of clip, canvas can skip drawing.
@param atlas SkImage containing sprites
@param xform SkRSXform mappings for sprites in atlas
@param tex SkRect locations of sprites in atlas
@param count number of sprites to draw
@param cullRect bounds of transformed sprites for efficient clipping; may be nullptr
@param paint SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
*/
void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
const SkRect* cullRect, const SkPaint* paint) {
this->drawAtlas(atlas, xform, tex, nullptr, count, SkBlendMode::kDst, cullRect, paint);
}
/** Draw a set of sprites from atlas, using clip, SkMatrix, and optional SkPaint paint.
paint uses SkPaint anti-alias, color alpha, SkColorFilter, SkImageFilter, and SkBlendMode
to draw, if present. For each entry in the array, SkRect tex locates sprite in
atlas, and SkRSXform xform transforms it into destination space.
xform and text must contain count entries.
Optional cullRect is a conservative bounds of all transformed sprites.
If cullRect is outside of clip, canvas can skip drawing.
@param atlas SkImage containing sprites
@param xform SkRSXform mappings for sprites in atlas
@param tex SkRect locations of sprites in atlas
@param count number of sprites to draw
@param cullRect bounds of transformed sprites for efficient clipping; may be nullptr
@param paint SkColorFilter, SkImageFilter, SkBlendMode, and so on; may be nullptr
*/
void drawAtlas(const sk_sp<SkImage>& atlas, const SkRSXform xform[], const SkRect tex[],
int count, const SkRect* cullRect, const SkPaint* paint) {
this->drawAtlas(atlas.get(), xform, tex, nullptr, count, SkBlendMode::kDst,
cullRect, paint);
}
/** Draw SkDrawable drawable using clip and SkMatrix, concatenated with
optional matrix.
If SkCanvas has an asynchronous implementation, as is the case
when it is recording into SkPicture, then drawable will be referenced,
so that SkDrawable::draw() can be called when the operation is finalized. To force
immediate drawing, call SkDrawable::draw() instead.
@param drawable custom struct encapsulating drawing commands
@param matrix transformation applied to drawing; may be nullptr
*/
void drawDrawable(SkDrawable* drawable, const SkMatrix* matrix = nullptr);
/** Draw SkDrawable drawable using clip and SkMatrix, offset by (x, y).
If SkCanvas has an asynchronous implementation, as is the case
when it is recording into SkPicture, then drawable will be referenced,
so that SkDrawable::draw() can be called when the operation is finalized. To force
immediate drawing, call SkDrawable::draw() instead.
@param drawable custom struct encapsulating drawing commands
@param x offset into SkCanvas writable pixels in x
@param y offset into SkCanvas writable pixels in y
*/
void drawDrawable(SkDrawable* drawable, SkScalar x, SkScalar y);
/** Associate SkRect on SkCanvas with an annotation; a key-value pair, where the key is
a null-terminated utf8 string, and optional value is stored as SkData.
Only some canvas implementations, such as recording to SkPicture, or drawing to
document pdf, use annotations.
@param rect SkRect extent of canvas to annotate
@param key string used for lookup
@param value data holding value stored in annotation
*/
void drawAnnotation(const SkRect& rect, const char key[], SkData* value);
/** Associate SkRect on SkCanvas when an annotation; a key-value pair, where the key is
a null-terminated utf8 string, and optional value is stored as SkData.
Only some canvas implementations, such as recording to SkPicture, or drawing to
document pdf, use annotations.
@param rect SkRect extent of canvas to annotate
@param key string used for lookup
@param value data holding value stored in annotation
*/
void drawAnnotation(const SkRect& rect, const char key[], const sk_sp<SkData>& value) {
this->drawAnnotation(rect, key, value.get());
}
//////////////////////////////////////////////////////////////////////////
#ifdef SK_SUPPORT_LEGACY_DRAWFILTER
/** To be deprecated soon.
*/
SkDrawFilter* getDrawFilter() const;
/** To be deprecated soon.
*/
virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
#endif
/** Returns true if clip is empty; that is, nothing will draw.
May do work when called; it should not be called
more often than needed. However, once called, subsequent calls perform no
work until clip changes.
@return true if clip is empty
*/
virtual bool isClipEmpty() const;
/** Returns true if clip is SkRect and not empty.
Returns false if the clip is empty, or if it is not SkRect.
@return true if clip is SkRect and not empty
*/
virtual bool isClipRect() const;
/** Returns SkMatrix.
This does not account for translation by SkBaseDevice or SkSurface.
@return SkMatrix in SkCanvas
*/
const SkMatrix& getTotalMatrix() const;
///////////////////////////////////////////////////////////////////////////
// don't call
virtual GrRenderTargetContext* internal_private_accessTopLayerRenderTargetContext();
SkIRect internal_private_getTopLayerBounds() const { return getTopLayerBounds(); }
// don't call
static void Internal_Private_SetIgnoreSaveLayerBounds(bool);
static bool Internal_Private_GetIgnoreSaveLayerBounds();
static void Internal_Private_SetTreatSpriteAsBitmap(bool);
static bool Internal_Private_GetTreatSpriteAsBitmap();
// TEMP helpers until we switch virtual over to const& for src-rect
void legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
const SkPaint* paint,
SrcRectConstraint constraint = kStrict_SrcRectConstraint);
void legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
const SkPaint* paint,
SrcRectConstraint constraint = kStrict_SrcRectConstraint);
/**
* Returns the global clip as a region. If the clip contains AA, then only the bounds
* of the clip may be returned.
*/
void temporary_internal_getRgnClip(SkRegion* region);
void private_draw_shadow_rec(const SkPath&, const SkDrawShadowRec&);
protected:
// default impl defers to getDevice()->newSurface(info)
virtual sk_sp<SkSurface> onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props);
// default impl defers to its device
virtual bool onPeekPixels(SkPixmap* pixmap);
virtual bool onAccessTopLayerPixels(SkPixmap* pixmap);
virtual SkImageInfo onImageInfo() const;
virtual bool onGetProps(SkSurfaceProps* props) const;
virtual void onFlush();
// Subclass save/restore notifiers.
// Overriders should call the corresponding INHERITED method up the inheritance chain.
// getSaveLayerStrategy()'s return value may suppress full layer allocation.
enum SaveLayerStrategy {
kFullLayer_SaveLayerStrategy,
kNoLayer_SaveLayerStrategy,
};
virtual void willSave() {}
// Overriders should call the corresponding INHERITED method up the inheritance chain.
virtual SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& ) {
return kFullLayer_SaveLayerStrategy;
}
virtual void willRestore() {}
virtual void didRestore() {}
virtual void didConcat(const SkMatrix& ) {}
virtual void didSetMatrix(const SkMatrix& ) {}
virtual void didTranslate(SkScalar dx, SkScalar dy) {
this->didConcat(SkMatrix::MakeTrans(dx, dy));
}
virtual void onDrawAnnotation(const SkRect& rect, const char key[], SkData* value);
virtual void onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);
virtual void onDrawText(const void* text, size_t byteLength, SkScalar x,
SkScalar y, const SkPaint& paint);
virtual void onDrawPosText(const void* text, size_t byteLength,
const SkPoint pos[], const SkPaint& paint);
virtual void onDrawPosTextH(const void* text, size_t byteLength,
const SkScalar xpos[], SkScalar constY,
const SkPaint& paint);
virtual void onDrawTextOnPath(const void* text, size_t byteLength,
const SkPath& path, const SkMatrix* matrix,
const SkPaint& paint);
virtual void onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
const SkRect* cullRect, const SkPaint& paint);
virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
const SkPaint& paint);
virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], SkBlendMode mode, const SkPaint& paint);
virtual void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix);
virtual void onDrawPaint(const SkPaint& paint);
virtual void onDrawRect(const SkRect& rect, const SkPaint& paint);
virtual void onDrawRegion(const SkRegion& region, const SkPaint& paint);
virtual void onDrawOval(const SkRect& rect, const SkPaint& paint);
virtual void onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle,
bool useCenter, const SkPaint& paint);
virtual void onDrawRRect(const SkRRect& rrect, const SkPaint& paint);
virtual void onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
const SkPaint& paint);
virtual void onDrawVerticesObject(const SkVertices* vertices, SkBlendMode mode,
const SkPaint& paint);
virtual void onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect rect[],
const SkColor colors[], int count, SkBlendMode mode,
const SkRect* cull, const SkPaint* paint);
virtual void onDrawPath(const SkPath& path, const SkPaint& paint);
virtual void onDrawImage(const SkImage* image, SkScalar dx, SkScalar dy, const SkPaint* paint);
virtual void onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
const SkPaint* paint, SrcRectConstraint constraint);
virtual void onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
const SkPaint* paint);
virtual void onDrawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
const SkPaint* paint);
virtual void onDrawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy,
const SkPaint* paint);
virtual void onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
const SkPaint* paint, SrcRectConstraint constraint);
virtual void onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
const SkPaint* paint);
virtual void onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
const SkRect& dst, const SkPaint* paint);
virtual void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&);
enum ClipEdgeStyle {
kHard_ClipEdgeStyle,
kSoft_ClipEdgeStyle
};
virtual void onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle);
virtual void onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle);
virtual void onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle);
virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp op);
virtual void onDiscard();
virtual void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
const SkPaint* paint);
// Clip rectangle bounds. Called internally by saveLayer.
// returns false if the entire rectangle is entirely clipped out
// If non-NULL, The imageFilter parameter will be used to expand the clip
// and offscreen bounds for any margin required by the filter DAG.
bool clipRectBounds(const SkRect* bounds, SaveLayerFlags flags, SkIRect* intersection,
const SkImageFilter* imageFilter = nullptr);
private:
/** After calling saveLayer(), there can be any number of devices that make
up the top-most drawing area. LayerIter can be used to iterate through
those devices. Note that the iterator is only valid until the next API
call made on the canvas. Ownership of all pointers in the iterator stays
with the canvas, so none of them should be modified or deleted.
*/
class LayerIter /*: SkNoncopyable*/ {
public:
/** Initialize iterator with canvas, and set values for 1st device */
LayerIter(SkCanvas*);
~LayerIter();
/** Return true if the iterator is done */
bool done() const { return fDone; }
/** Cycle to the next device */
void next();
// These reflect the current device in the iterator
SkBaseDevice* device() const;
const SkMatrix& matrix() const;
void clip(SkRegion*) const;
const SkPaint& paint() const;
int x() const;
int y() const;
private:
// used to embed the SkDrawIter object directly in our instance, w/o
// having to expose that class def to the public. There is an assert
// in our constructor to ensure that fStorage is large enough
// (though needs to be a compile-time-assert!). We use intptr_t to work
// safely with 32 and 64 bit machines (to ensure the storage is enough)
intptr_t fStorage[32];
class SkDrawIter* fImpl; // this points at fStorage
SkPaint fDefaultPaint;
bool fDone;
};
static bool BoundsAffectsClip(SaveLayerFlags);
static SaveLayerFlags LegacySaveFlagsToSaveLayerFlags(uint32_t legacySaveFlags);
static void DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
SkBaseDevice* dst, const SkIPoint& dstOrigin,
const SkMatrix& ctm);
enum ShaderOverrideOpacity {
kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image)
kOpaque_ShaderOverrideOpacity, //!< the overriding shader is opaque
kNotOpaque_ShaderOverrideOpacity, //!< the overriding shader may not be opaque
};
// notify our surface (if we have one) that we are about to draw, so it
// can perform copy-on-write or invalidate any cached images
void predrawNotify(bool willOverwritesEntireSurface = false);
void predrawNotify(const SkRect* rect, const SkPaint* paint, ShaderOverrideOpacity);
void predrawNotify(const SkRect* rect, const SkPaint* paint, bool shaderOverrideIsOpaque) {
this->predrawNotify(rect, paint, shaderOverrideIsOpaque ? kOpaque_ShaderOverrideOpacity
: kNotOpaque_ShaderOverrideOpacity);
}
SkBaseDevice* getDevice() const;
SkBaseDevice* getTopDevice() const;
class MCRec;
SkDeque fMCStack;
// points to top of stack
MCRec* fMCRec;
// the first N recs that can fit here mean we won't call malloc
enum {
kMCRecSize = 128, // most recent measurement
kMCRecCount = 32, // common depth for save/restores
kDeviceCMSize = 224, // most recent measurement
};
intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)];
intptr_t fDeviceCMStorage[kDeviceCMSize / sizeof(intptr_t)];
const SkSurfaceProps fProps;
int fSaveCount; // value returned by getSaveCount()
SkMetaData* fMetaData;
std::unique_ptr<SkRasterHandleAllocator> fAllocator;
SkSurface_Base* fSurfaceBase;
SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
void setSurfaceBase(SkSurface_Base* sb) {
fSurfaceBase = sb;
}
friend class SkSurface_Base;
friend class SkSurface_Gpu;
SkIRect fClipRestrictionRect = SkIRect::MakeEmpty();
void doSave();
void checkForDeferredSave();
void internalSetMatrix(const SkMatrix&);
friend class SkAndroidFrameworkUtils;
friend class SkDrawIter; // needs setupDrawForLayerDevice()
friend class AutoDrawLooper;
friend class SkDebugCanvas; // needs experimental fAllowSimplifyClip
friend class SkSurface_Raster; // needs getDevice()
friend class SkNoDrawCanvas; // InitFlags
friend class SkPictureImageFilter; // SkCanvas(SkBaseDevice*, SkSurfaceProps*, InitFlags)
friend class SkPictureRecord; // predrawNotify (why does it need it? <reed>)
friend class SkPicturePlayback; // SaveFlagsToSaveLayerFlags
friend class SkOverdrawCanvas;
friend class SkRasterHandleAllocator;
enum InitFlags {
kDefault_InitFlags = 0,
kConservativeRasterClip_InitFlag = 1 << 0,
};
SkCanvas(const SkIRect& bounds, InitFlags);
SkCanvas(SkBaseDevice* device, InitFlags);
SkCanvas(const SkBitmap&, std::unique_ptr<SkRasterHandleAllocator>,
SkRasterHandleAllocator::Handle);
void resetForNextPicture(const SkIRect& bounds);
// needs gettotalclip()
friend class SkCanvasStateUtils;
// call this each time we attach ourselves to a device
// - constructor
// - internalSaveLayer
void setupDevice(SkBaseDevice*);
SkBaseDevice* init(SkBaseDevice*, InitFlags);
/**
* Gets the bounds of the top level layer in global canvas coordinates. We don't want this
* to be public because it exposes decisions about layer sizes that are internal to the canvas.
*/
SkIRect getTopLayerBounds() const;
void internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
const SkRect& dst, const SkPaint* paint,
SrcRectConstraint);
void internalDrawPaint(const SkPaint& paint);
void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*, SkImage* clipImage,
const SkMatrix& clipMatrix);
// shared by save() and saveLayer()
void internalSave();
void internalRestore();
/*
* Returns true if drawing the specified rect (or all if it is null) with the specified
* paint (or default if null) would overwrite the entire root device of the canvas
* (i.e. the canvas' surface if it had one).
*/
bool wouldOverwriteEntireSurface(const SkRect*, const SkPaint*, ShaderOverrideOpacity) const;
/**
* Returns true if the paint's imagefilter can be invoked directly, without needed a layer.
*/
bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint&);
/**
* Returns true if the clip (for any active layer) contains antialiasing.
* If the clip is empty, this will return false.
*/
bool androidFramework_isClipAA() const;
/**
* Keep track of the device clip bounds and if the matrix is scale-translate. This allows
* us to do a fast quick reject in the common case.
*/
bool fIsScaleTranslate;
SkRect fDeviceClipBounds;
bool fAllowSoftClip;
bool fAllowSimplifyClip;
class AutoValidateClip : ::SkNoncopyable {
public:
explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
fCanvas->validateClip();
}
~AutoValidateClip() { fCanvas->validateClip(); }
private:
const SkCanvas* fCanvas;
};
#ifdef SK_DEBUG
void validateClip() const;
#else
void validateClip() const {}
#endif
typedef SkRefCnt INHERITED;
};
/** \class SkAutoCanvasRestore
Stack helper class calls SkCanvas::restoreToCount() when SkAutoCanvasRestore
goes out of scope. Use this to guarantee that the canvas is restored to a known
state.
*/
class SkAutoCanvasRestore : SkNoncopyable {
public:
/** Preserves SkCanvas save count. Optionally saves SkCanvas clip and SkCanvas matrix.
@param canvas SkCanvas to guard
@param doSave call SkCanvas::save()
@return utility to restore SkCanvas state on destructor
*/
SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas), fSaveCount(0) {
if (fCanvas) {
fSaveCount = canvas->getSaveCount();
if (doSave) {
canvas->save();
}
}
}
/** Restores SkCanvas to saved state. Destructor is called when container goes out of
scope.
*/
~SkAutoCanvasRestore() {
if (fCanvas) {
fCanvas->restoreToCount(fSaveCount);
}
}
/** Restores SkCanvas to saved state immediately. Subsequent calls and
~SkAutoCanvasRestore have no effect.
*/
void restore() {
if (fCanvas) {
fCanvas->restoreToCount(fSaveCount);
fCanvas = nullptr;
}
}
private:
SkCanvas* fCanvas;
int fSaveCount;
};
#define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore)
#endif