|
/*
|
* 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 SkDraw_DEFINED
|
#define SkDraw_DEFINED
|
|
#include "SkCanvas.h"
|
#include "SkGlyphRunPainter.h"
|
#include "SkMask.h"
|
#include "SkPaint.h"
|
#include "SkPixmap.h"
|
#include "SkStrokeRec.h"
|
#include "SkVertices.h"
|
|
class SkBitmap;
|
class SkClipStack;
|
class SkBaseDevice;
|
class SkBlitter;
|
class SkMatrix;
|
class SkPath;
|
class SkRegion;
|
class SkRasterClip;
|
struct SkRect;
|
class SkRRect;
|
|
class SkDraw : public SkGlyphRunListPainter::BitmapDevicePainter {
|
public:
|
SkDraw();
|
|
void drawPaint(const SkPaint&) const;
|
void drawPoints(SkCanvas::PointMode, size_t count, const SkPoint[],
|
const SkPaint&, SkBaseDevice*) const;
|
void drawRect(const SkRect& prePaintRect, const SkPaint&, const SkMatrix* paintMatrix,
|
const SkRect* postPaintRect) const;
|
void drawRect(const SkRect& rect, const SkPaint& paint) const {
|
this->drawRect(rect, paint, nullptr, nullptr);
|
}
|
void drawRRect(const SkRRect&, const SkPaint&) const;
|
/**
|
* To save on mallocs, we allow a flag that tells us that srcPath is
|
* mutable, so that we don't have to make copies of it as we transform it.
|
*
|
* If prePathMatrix is not null, it should logically be applied before any
|
* stroking or other effects. If there are no effects on the paint that
|
* affect the geometry/rasterization, then the pre matrix can just be
|
* pre-concated with the current matrix.
|
*/
|
void drawPath(const SkPath& path, const SkPaint& paint,
|
const SkMatrix* prePathMatrix = nullptr, bool pathIsMutable = false) const {
|
this->drawPath(path, paint, prePathMatrix, pathIsMutable, false);
|
}
|
|
/* If dstOrNull is null, computes a dst by mapping the bitmap's bounds through the matrix. */
|
void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull,
|
const SkPaint&) const;
|
void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) const;
|
void drawGlyphRunList(const SkGlyphRunList& glyphRunList,
|
SkGlyphRunListPainter* glyphPainter) const;
|
void drawVertices(SkVertices::VertexMode mode, int vertexCount,
|
const SkPoint vertices[], const SkPoint textures[],
|
const SkColor colors[], const SkVertices::BoneIndices boneIndices[],
|
const SkVertices::BoneWeights boneWeights[], SkBlendMode bmode,
|
const uint16_t indices[], int ptCount,
|
const SkPaint& paint, const SkVertices::Bone bones[], int boneCount) const;
|
|
/**
|
* Overwrite the target with the path's coverage (i.e. its mask).
|
* Will overwrite the entire device, so it need not be zero'd first.
|
*
|
* Only device A8 is supported right now.
|
*/
|
void drawPathCoverage(const SkPath& src, const SkPaint& paint,
|
SkBlitter* customBlitter = nullptr) const {
|
bool isHairline = paint.getStyle() == SkPaint::kStroke_Style &&
|
paint.getStrokeWidth() > 0;
|
this->drawPath(src, paint, nullptr, false, !isHairline, customBlitter);
|
}
|
|
void paintPaths(SkSpan<const SkPathPos> pathsAndPositions,
|
SkScalar scale,
|
const SkPaint& paint) const override;
|
|
void paintMasks(SkSpan<const SkMask> masks, const SkPaint& paint) const override;
|
|
static bool ComputeMaskBounds(const SkRect& devPathBounds, const SkIRect* clipBounds,
|
const SkMaskFilter* filter, const SkMatrix* filterMatrix,
|
SkIRect* bounds);
|
|
/** Helper function that creates a mask from a path and an optional maskfilter.
|
Note however, that the resulting mask will not have been actually filtered,
|
that must be done afterwards (by calling filterMask). The maskfilter is provided
|
solely to assist in computing the mask's bounds (if the mode requests that).
|
*/
|
static bool DrawToMask(const SkPath& devPath, const SkIRect* clipBounds,
|
const SkMaskFilter*, const SkMatrix* filterMatrix,
|
SkMask* mask, SkMask::CreateMode mode,
|
SkStrokeRec::InitStyle style);
|
|
void drawDevMask(const SkMask& mask, const SkPaint&) const;
|
|
enum RectType {
|
kHair_RectType,
|
kFill_RectType,
|
kStroke_RectType,
|
kPath_RectType
|
};
|
|
/**
|
* Based on the paint's style, strokeWidth, and the matrix, classify how
|
* to draw the rect. If no special-case is available, returns
|
* kPath_RectType.
|
*
|
* Iff RectType == kStroke_RectType, then strokeSize is set to the device
|
* width and height of the stroke.
|
*/
|
static RectType ComputeRectType(const SkPaint&, const SkMatrix&,
|
SkPoint* strokeSize);
|
|
static bool ShouldDrawTextAsPaths(const SkFont&, const SkPaint&, const SkMatrix&,
|
SkScalar sizeLimit = 1024);
|
|
static SkScalar ComputeResScaleForStroking(const SkMatrix& );
|
private:
|
void drawBitmapAsMask(const SkBitmap&, const SkPaint&) const;
|
|
void drawPath(const SkPath&,
|
const SkPaint&,
|
const SkMatrix* preMatrix,
|
bool pathIsMutable,
|
bool drawCoverage,
|
SkBlitter* customBlitter = nullptr) const;
|
|
void drawLine(const SkPoint[2], const SkPaint&) const;
|
|
void drawDevPath(const SkPath& devPath,
|
const SkPaint& paint,
|
bool drawCoverage,
|
SkBlitter* customBlitter,
|
bool doFill) const;
|
/**
|
* Return the current clip bounds, in local coordinates, with slop to account
|
* for antialiasing or hairlines (i.e. device-bounds outset by 1, and then
|
* run through the inverse of the matrix).
|
*
|
* If the matrix cannot be inverted, or the current clip is empty, return
|
* false and ignore bounds parameter.
|
*/
|
bool SK_WARN_UNUSED_RESULT computeConservativeLocalClipBounds(SkRect* bounds) const;
|
|
public:
|
SkPixmap fDst;
|
const SkMatrix* fMatrix{nullptr}; // required
|
const SkRasterClip* fRC{nullptr}; // required
|
|
// optional, will be same dimensions as fDst if present
|
const SkPixmap* fCoverage{nullptr};
|
|
#ifdef SK_DEBUG
|
void validate() const;
|
#else
|
void validate() const {}
|
#endif
|
};
|
|
#endif
|