Revert[2] "Remove SkDraw from device-draw methods, and enable device-centric clipping.""
passes new (augmented) CanvasClipType unittest
fixed rasterclipstack::setnewsize
This reverts commit ea5e676a7b
.
BUG=skia:
Change-Id: I004653e0f4d01454662f8516fccab0046486f273
Reviewed-on: https://skia-review.googlesource.com/9185
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
parent
b7115c68ba
commit
cfaa63237b
@ -1359,6 +1359,10 @@ public:
|
||||
*/
|
||||
void temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds);
|
||||
|
||||
/**
|
||||
* 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*);
|
||||
|
||||
protected:
|
||||
@ -1523,7 +1527,7 @@ private:
|
||||
|
||||
SkBaseDevice* device() const;
|
||||
const SkMatrix& matrix() const;
|
||||
const SkRasterClip& clip() const;
|
||||
void clip(SkRegion*) const;
|
||||
const SkPaint& paint() const;
|
||||
int x() const;
|
||||
int y() const;
|
||||
@ -1545,7 +1549,7 @@ private:
|
||||
|
||||
static void DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
|
||||
SkBaseDevice* dst, const SkIPoint& dstOrigin,
|
||||
const SkMatrix& ctm, const SkClipStack* clipStack);
|
||||
const SkMatrix& ctm);
|
||||
|
||||
enum ShaderOverrideOpacity {
|
||||
kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image)
|
||||
@ -1567,7 +1571,6 @@ private:
|
||||
|
||||
class MCRec;
|
||||
|
||||
sk_sp<SkClipStack> fClipStack;
|
||||
SkDeque fMCStack;
|
||||
// points to top of stack
|
||||
MCRec* fMCRec;
|
||||
@ -1595,9 +1598,7 @@ private:
|
||||
friend class SkSurface_Base;
|
||||
friend class SkSurface_Gpu;
|
||||
|
||||
bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
|
||||
SkIRect fClipRestrictionRect = SkIRect::MakeEmpty();
|
||||
void updateDeviceCMCache();
|
||||
|
||||
void doSave();
|
||||
void checkForDeferredSave();
|
||||
@ -1667,14 +1668,11 @@ private:
|
||||
*/
|
||||
bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint&);
|
||||
|
||||
/** Return the clip stack. The clip stack stores all the individual
|
||||
* clips organized by the save/restore frame in which they were
|
||||
* added.
|
||||
* @return the current clip stack ("list" of individual clip elements)
|
||||
/**
|
||||
* Returns true if the clip (for any active layer) contains antialiasing.
|
||||
* If the clip is empty, this will return false.
|
||||
*/
|
||||
const SkClipStack* getClipStack() const {
|
||||
return fClipStack.get();
|
||||
}
|
||||
bool androidFramework_isClipAA() const;
|
||||
|
||||
/**
|
||||
* Keep track of the device clip bounds and if the matrix is scale-translate. This allows
|
||||
@ -1685,7 +1683,6 @@ private:
|
||||
|
||||
bool fAllowSoftClip;
|
||||
bool fAllowSimplifyClip;
|
||||
const bool fConservativeRasterClip;
|
||||
|
||||
class AutoValidateClip : ::SkNoncopyable {
|
||||
public:
|
||||
|
@ -190,63 +190,63 @@ bool SkBitmapDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, s
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
class ModifiedDraw : public SkDraw {
|
||||
class SkBitmapDevice::BDDraw : public SkDraw {
|
||||
public:
|
||||
ModifiedDraw(const SkMatrix& cmt, const SkRasterClip& rc, const SkDraw& draw) : SkDraw(draw) {
|
||||
SkASSERT(cmt == *draw.fMatrix);
|
||||
fRC = &rc;
|
||||
BDDraw(SkBitmapDevice* dev) {
|
||||
// we need fDst to be set, and if we're actually drawing, to dirty the genID
|
||||
if (!dev->accessPixels(&fDst)) {
|
||||
// NoDrawDevice uses us (why?) so we have to catch this case w/ no pixels
|
||||
fDst.reset(dev->imageInfo(), nullptr, 0);
|
||||
}
|
||||
fMatrix = &dev->ctm();
|
||||
fRC = &dev->fRCStack.rc();
|
||||
}
|
||||
};
|
||||
#define PREPARE_DRAW(draw) ModifiedDraw(this->ctm(), fRCStack.rc(), draw)
|
||||
#else
|
||||
#define PREPARE_DRAW(draw) draw
|
||||
#endif
|
||||
|
||||
void SkBitmapDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
|
||||
PREPARE_DRAW(draw).drawPaint(paint);
|
||||
void SkBitmapDevice::drawPaint(const SkPaint& paint) {
|
||||
BDDraw(this).drawPaint(paint);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
|
||||
void SkBitmapDevice::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint pts[], const SkPaint& paint) {
|
||||
PREPARE_DRAW(draw).drawPoints(mode, count, pts, paint, nullptr);
|
||||
BDDraw(this).drawPoints(mode, count, pts, paint, nullptr);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) {
|
||||
PREPARE_DRAW(draw).drawRect(r, paint);
|
||||
void SkBitmapDevice::drawRect(const SkRect& r, const SkPaint& paint) {
|
||||
BDDraw(this).drawRect(r, paint);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
|
||||
void SkBitmapDevice::drawOval(const SkRect& oval, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
path.addOval(oval);
|
||||
// call the VIRTUAL version, so any subclasses who do handle drawPath aren't
|
||||
// required to override drawOval.
|
||||
this->drawPath(draw, path, paint, nullptr, true);
|
||||
this->drawPath(path, paint, nullptr, true);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPaint& paint) {
|
||||
void SkBitmapDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
|
||||
#ifdef SK_IGNORE_BLURRED_RRECT_OPT
|
||||
SkPath path;
|
||||
|
||||
path.addRRect(rrect);
|
||||
// call the VIRTUAL version, so any subclasses who do handle drawPath aren't
|
||||
// required to override drawRRect.
|
||||
this->drawPath(draw, path, paint, nullptr, true);
|
||||
this->drawPath(path, paint, nullptr, true);
|
||||
#else
|
||||
PREPARE_DRAW(draw).drawRRect(rrect, paint);
|
||||
BDDraw(this).drawRRect(rrect, paint);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawPath(const SkDraw& draw, const SkPath& path,
|
||||
void SkBitmapDevice::drawPath(const SkPath& path,
|
||||
const SkPaint& paint, const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable) {
|
||||
PREPARE_DRAW(draw).drawPath(path, paint, prePathMatrix, pathIsMutable);
|
||||
BDDraw(this).drawPath(path, paint, prePathMatrix, pathIsMutable);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
void SkBitmapDevice::drawBitmap(const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint& paint) {
|
||||
LogDrawScaleFactor(SkMatrix::Concat(*draw.fMatrix, matrix), paint.getFilterQuality());
|
||||
PREPARE_DRAW(draw).drawBitmap(bitmap, matrix, nullptr, paint);
|
||||
LogDrawScaleFactor(SkMatrix::Concat(this->ctm(), matrix), paint.getFilterQuality());
|
||||
BDDraw(this).drawBitmap(bitmap, matrix, nullptr, paint);
|
||||
}
|
||||
|
||||
static inline bool CanApplyDstMatrixAsCTM(const SkMatrix& m, const SkPaint& paint) {
|
||||
@ -258,7 +258,7 @@ static inline bool CanApplyDstMatrixAsCTM(const SkMatrix& m, const SkPaint& pain
|
||||
return m.getType() <= SkMatrix::kTranslate_Mask;
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
void SkBitmapDevice::drawBitmapRect(const SkBitmap& bitmap,
|
||||
const SkRect* src, const SkRect& dst,
|
||||
const SkPaint& paint, SkCanvas::SrcRectConstraint constraint) {
|
||||
SkMatrix matrix;
|
||||
@ -275,7 +275,7 @@ void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
}
|
||||
matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
|
||||
|
||||
LogDrawScaleFactor(SkMatrix::Concat(*draw.fMatrix, matrix), paint.getFilterQuality());
|
||||
LogDrawScaleFactor(SkMatrix::Concat(this->ctm(), matrix), paint.getFilterQuality());
|
||||
|
||||
const SkRect* dstPtr = &dst;
|
||||
const SkBitmap* bitmapPtr = &bitmap;
|
||||
@ -335,7 +335,7 @@ void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
// matrix with the CTM, and try to call drawSprite if it can. If not,
|
||||
// it will make a shader and call drawRect, as we do below.
|
||||
if (CanApplyDstMatrixAsCTM(matrix, paint)) {
|
||||
PREPARE_DRAW(draw).drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
|
||||
BDDraw(this).drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -360,45 +360,43 @@ void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
|
||||
// Call ourself, in case the subclass wanted to share this setup code
|
||||
// but handle the drawRect code themselves.
|
||||
this->drawRect(draw, *dstPtr, paintWithShader);
|
||||
this->drawRect(*dstPtr, paintWithShader);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
void SkBitmapDevice::drawSprite(const SkBitmap& bitmap,
|
||||
int x, int y, const SkPaint& paint) {
|
||||
PREPARE_DRAW(draw).drawSprite(bitmap, x, y, paint);
|
||||
BDDraw(this).drawSprite(bitmap, x, y, paint);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawText(const SkDraw& draw, const void* text, size_t len,
|
||||
void SkBitmapDevice::drawText(const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) {
|
||||
PREPARE_DRAW(draw).drawText((const char*)text, len, x, y, paint, &fSurfaceProps);
|
||||
BDDraw(this).drawText((const char*)text, len, x, y, paint, &fSurfaceProps);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
|
||||
const SkScalar xpos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint& paint) {
|
||||
PREPARE_DRAW(draw).drawPosText((const char*)text, len, xpos, scalarsPerPos, offset,
|
||||
paint, &fSurfaceProps);
|
||||
void SkBitmapDevice::drawPosText(const void* text, size_t len, const SkScalar xpos[],
|
||||
int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) {
|
||||
BDDraw(this).drawPosText((const char*)text, len, xpos, scalarsPerPos, offset, paint, &fSurfaceProps);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
|
||||
void SkBitmapDevice::drawVertices(SkCanvas::VertexMode vmode,
|
||||
int vertexCount,
|
||||
const SkPoint verts[], const SkPoint textures[],
|
||||
const SkColor colors[], SkBlendMode bmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint) {
|
||||
PREPARE_DRAW(draw).drawVertices(vmode, vertexCount, verts, textures, colors, bmode,
|
||||
indices, indexCount, paint);
|
||||
BDDraw(this).drawVertices(vmode, vertexCount, verts, textures, colors, bmode, indices,
|
||||
indexCount, paint);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
|
||||
void SkBitmapDevice::drawDevice(SkBaseDevice* device,
|
||||
int x, int y, const SkPaint& paint) {
|
||||
SkASSERT(!paint.getImageFilter());
|
||||
PREPARE_DRAW(draw).drawSprite(static_cast<SkBitmapDevice*>(device)->fBitmap, x, y, paint);
|
||||
BDDraw(this).drawSprite(static_cast<SkBitmapDevice*>(device)->fBitmap, x, y, paint);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkBitmapDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x, int y,
|
||||
void SkBitmapDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y,
|
||||
const SkPaint& paint) {
|
||||
SkASSERT(!srcImg->isTextureBacked());
|
||||
|
||||
@ -407,9 +405,9 @@ void SkBitmapDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int
|
||||
SkImageFilter* filter = paint.getImageFilter();
|
||||
if (filter) {
|
||||
SkIPoint offset = SkIPoint::Make(0, 0);
|
||||
SkMatrix matrix = *draw.fMatrix;
|
||||
SkMatrix matrix = this->ctm();
|
||||
matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
|
||||
const SkIRect clipBounds = draw.fRC->getBounds().makeOffset(-x, -y);
|
||||
const SkIRect clipBounds = fRCStack.rc().getBounds().makeOffset(-x, -y);
|
||||
sk_sp<SkImageFilterCache> cache(this->getImageFilterCache());
|
||||
SkImageFilter::OutputProperties outputProperties(fBitmap.colorSpace());
|
||||
SkImageFilter::Context ctx(matrix, clipBounds, cache.get(), outputProperties);
|
||||
@ -419,12 +417,12 @@ void SkBitmapDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int
|
||||
SkPaint tmpUnfiltered(paint);
|
||||
tmpUnfiltered.setImageFilter(nullptr);
|
||||
if (resultImg->getROPixels(&resultBM)) {
|
||||
this->drawSprite(draw, resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
|
||||
this->drawSprite(resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (srcImg->getROPixels(&resultBM)) {
|
||||
this->drawSprite(draw, resultBM, x, y, paint);
|
||||
this->drawSprite(resultBM, x, y, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -511,9 +509,34 @@ void SkBitmapDevice::onSetDeviceClipRestriction(SkIRect* mutableClipRestriction)
|
||||
}
|
||||
}
|
||||
|
||||
bool SkBitmapDevice::onClipIsAA() const {
|
||||
const SkRasterClip& rc = fRCStack.rc();
|
||||
return !rc.isEmpty() && rc.isAA();
|
||||
}
|
||||
|
||||
void SkBitmapDevice::onAsRgnClip(SkRegion* rgn) const {
|
||||
const SkRasterClip& rc = fRCStack.rc();
|
||||
if (rc.isAA()) {
|
||||
rgn->setRect(rc.getBounds());
|
||||
} else {
|
||||
*rgn = rc.bwRgn();
|
||||
}
|
||||
}
|
||||
|
||||
void SkBitmapDevice::validateDevBounds(const SkIRect& drawClipBounds) {
|
||||
#ifdef SK_DEBUG
|
||||
const SkIRect& stackBounds = fRCStack.rc().getBounds();
|
||||
SkASSERT(drawClipBounds == stackBounds);
|
||||
#endif
|
||||
}
|
||||
|
||||
SkBaseDevice::ClipType SkBitmapDevice::onGetClipType() const {
|
||||
const SkRasterClip& rc = fRCStack.rc();
|
||||
if (rc.isEmpty()) {
|
||||
return kEmpty_ClipType;
|
||||
} else if (rc.isRect()) {
|
||||
return kRect_ClipType;
|
||||
} else {
|
||||
return kComplex_ClipType;
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "SkSize.h"
|
||||
#include "SkSurfaceProps.h"
|
||||
|
||||
class SkDraw;
|
||||
class SkImageFilterCache;
|
||||
class SkMatrix;
|
||||
class SkPaint;
|
||||
@ -70,12 +69,12 @@ protected:
|
||||
and are handling any looping from the paint, and any effects from the
|
||||
DrawFilter.
|
||||
*/
|
||||
void drawPaint(const SkDraw&, const SkPaint& paint) override;
|
||||
void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
|
||||
void drawPaint(const SkPaint& paint) override;
|
||||
void drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint[], const SkPaint& paint) override;
|
||||
void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint) override;
|
||||
void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) override;
|
||||
void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) override;
|
||||
void drawRect(const SkRect& r, const SkPaint& paint) override;
|
||||
void drawOval(const SkRect& oval, const SkPaint& paint) override;
|
||||
void drawRRect(const SkRRect& rr, const SkPaint& paint) override;
|
||||
|
||||
/**
|
||||
* If pathIsMutable, then the implementation is allowed to cast path to a
|
||||
@ -88,34 +87,34 @@ protected:
|
||||
* affect the geometry/rasterization, then the pre matrix can just be
|
||||
* pre-concated with the current matrix.
|
||||
*/
|
||||
void drawPath(const SkDraw&, const SkPath&, const SkPaint&, const SkMatrix* prePathMatrix,
|
||||
void drawPath(const SkPath&, const SkPaint&, const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable) override;
|
||||
void drawBitmap(const SkDraw&, const SkBitmap&, const SkMatrix&, const SkPaint&) override;
|
||||
void drawSprite(const SkDraw&, const SkBitmap&, int x, int y, const SkPaint&) override;
|
||||
void drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) override;
|
||||
void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) override;
|
||||
|
||||
/**
|
||||
* The default impl. will create a bitmap-shader from the bitmap,
|
||||
* and call drawRect with it.
|
||||
*/
|
||||
void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*, const SkRect&,
|
||||
void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&,
|
||||
const SkPaint&, SkCanvas::SrcRectConstraint) override;
|
||||
|
||||
/**
|
||||
* Does not handle text decoration.
|
||||
* Decorations (underline and stike-thru) will be handled by SkCanvas.
|
||||
*/
|
||||
void drawText(const SkDraw&, const void* text, size_t len, SkScalar x, SkScalar y,
|
||||
void drawText(const void* text, size_t len, SkScalar x, SkScalar y,
|
||||
const SkPaint&) override;
|
||||
void drawPosText(const SkDraw&, const void* text, size_t len, const SkScalar pos[],
|
||||
void drawPosText(const void* text, size_t len, const SkScalar pos[],
|
||||
int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) override;
|
||||
void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, const SkPoint verts[],
|
||||
void drawVertices(SkCanvas::VertexMode, int vertexCount, const SkPoint verts[],
|
||||
const SkPoint texs[], const SkColor colors[], SkBlendMode,
|
||||
const uint16_t indices[], int indexCount, const SkPaint&) override;
|
||||
void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) override;
|
||||
void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&) override;
|
||||
void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) override;
|
||||
sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
|
||||
sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
|
||||
sk_sp<SkSpecialImage> snapSpecial() override;
|
||||
@ -134,7 +133,10 @@ protected:
|
||||
void onClipPath(const SkPath& path, SkClipOp, bool aa) override;
|
||||
void onClipRegion(const SkRegion& deviceRgn, SkClipOp) override;
|
||||
void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) override;
|
||||
bool onClipIsAA() const override;
|
||||
void onAsRgnClip(SkRegion*) const override;
|
||||
void validateDevBounds(const SkIRect& r) override;
|
||||
ClipType onGetClipType() const override;
|
||||
|
||||
private:
|
||||
friend class SkCanvas;
|
||||
@ -142,9 +144,10 @@ private:
|
||||
friend class SkDraw;
|
||||
friend class SkDrawIter;
|
||||
friend class SkDeviceFilteredPaint;
|
||||
|
||||
friend class SkSurface_Raster;
|
||||
|
||||
class BDDraw;
|
||||
|
||||
// used to change the backend's pixels (and possibly config/rowbytes)
|
||||
// but cannot change the width/height, so there should be no change to
|
||||
// any clip information.
|
||||
|
@ -75,9 +75,13 @@ bool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* pa
|
||||
|
||||
const SkISize size = this->getBaseLayerSize();
|
||||
const SkRect bounds = SkRect::MakeIWH(size.width(), size.height());
|
||||
|
||||
#if 0
|
||||
// Replace with device method?
|
||||
if (!this->getClipStack()->quickContains(bounds)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rect) {
|
||||
if (!this->getTotalMatrix().isScaleTranslate()) {
|
||||
@ -192,10 +196,8 @@ struct DeviceCM {
|
||||
SkMatrix fMatrixStorage;
|
||||
SkMatrix fStashedMatrix; // original CTM; used by imagefilter in saveLayer
|
||||
|
||||
DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas,
|
||||
bool conservativeRasterClip, const SkMatrix& stashed)
|
||||
DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, const SkMatrix& stashed)
|
||||
: fNext(nullptr)
|
||||
, fClip(conservativeRasterClip)
|
||||
, fStashedMatrix(stashed)
|
||||
{
|
||||
SkSafeRef(device);
|
||||
@ -214,48 +216,6 @@ struct DeviceCM {
|
||||
SkASSERT(fDevice);
|
||||
fClip.setRect(bounds);
|
||||
}
|
||||
|
||||
void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip,
|
||||
SkRasterClip* updateClip) {
|
||||
int x = fDevice->getOrigin().x();
|
||||
int y = fDevice->getOrigin().y();
|
||||
int width = fDevice->width();
|
||||
int height = fDevice->height();
|
||||
|
||||
if ((x | y) == 0) {
|
||||
fMatrix = &totalMatrix;
|
||||
fClip = totalClip;
|
||||
} else {
|
||||
fMatrixStorage = totalMatrix;
|
||||
fMatrixStorage.postTranslate(SkIntToScalar(-x),
|
||||
SkIntToScalar(-y));
|
||||
fMatrix = &fMatrixStorage;
|
||||
totalClip.translate(-x, -y, &fClip);
|
||||
}
|
||||
|
||||
fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op);
|
||||
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
SkASSERT(*fMatrix == fDevice->ctm());
|
||||
// TODO: debug tiles-rt-8888 so we can enable this all the time
|
||||
// fDevice->validateDevBounds(fClip.getBounds());
|
||||
#endif
|
||||
|
||||
// intersect clip, but don't translate it (yet)
|
||||
|
||||
if (updateClip) {
|
||||
updateClip->op(SkIRect::MakeXYWH(x, y, width, height),
|
||||
SkRegion::kDifference_Op);
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
if (!fClip.isEmpty()) {
|
||||
SkIRect deviceR;
|
||||
deviceR.set(0, 0, width, height);
|
||||
SkASSERT(deviceR.contains(fClip.getBounds()));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
/* This is the record we keep for each save/restore level in the stack.
|
||||
@ -276,14 +236,14 @@ public:
|
||||
or a previous one in a lower level.)
|
||||
*/
|
||||
DeviceCM* fTopLayer;
|
||||
SkRasterClip fRasterClip;
|
||||
SkConservativeClip fRasterClip;
|
||||
SkMatrix fMatrix;
|
||||
int fDeferredSaveCount;
|
||||
|
||||
// This is the current cumulative depth (aggregate of all done translateZ calls)
|
||||
SkScalar fCurDrawDepth;
|
||||
|
||||
MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) {
|
||||
MCRec() {
|
||||
fFilter = nullptr;
|
||||
fLayer = nullptr;
|
||||
fTopLayer = nullptr;
|
||||
@ -320,70 +280,26 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static SkIRect compute_device_bounds(SkBaseDevice* device) {
|
||||
return SkIRect::MakeXYWH(device->getOrigin().x(), device->getOrigin().y(),
|
||||
device->width(), device->height());
|
||||
}
|
||||
|
||||
class SkDrawIter : public SkDraw {
|
||||
class SkDrawIter {
|
||||
public:
|
||||
SkDrawIter(SkCanvas* canvas) : fDevice(nullptr) {
|
||||
canvas->updateDeviceCMCache();
|
||||
|
||||
fClipStack = canvas->getClipStack();
|
||||
fCurrLayer = canvas->fMCRec->fTopLayer;
|
||||
|
||||
fMultiDeviceCS = nullptr;
|
||||
if (fCurrLayer->fNext) {
|
||||
fMultiDeviceCS = canvas->fClipStack.get();
|
||||
fMultiDeviceCS->save();
|
||||
}
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
fClipStack = nullptr; // for testing
|
||||
#endif
|
||||
}
|
||||
|
||||
~SkDrawIter() {
|
||||
if (fMultiDeviceCS) {
|
||||
fMultiDeviceCS->restore();
|
||||
}
|
||||
}
|
||||
SkDrawIter(SkCanvas* canvas)
|
||||
: fDevice(nullptr), fCurrLayer(canvas->fMCRec->fTopLayer), fPaint(nullptr)
|
||||
{}
|
||||
|
||||
bool next() {
|
||||
if (fMultiDeviceCS && fDevice) {
|
||||
// remove the previous device's bounds
|
||||
fMultiDeviceCS->clipDevRect(compute_device_bounds(fDevice), kDifference_SkClipOp);
|
||||
}
|
||||
|
||||
// skip over recs with empty clips
|
||||
while (fCurrLayer && fCurrLayer->fClip.isEmpty()) {
|
||||
fCurrLayer = fCurrLayer->fNext;
|
||||
}
|
||||
|
||||
const DeviceCM* rec = fCurrLayer;
|
||||
if (rec && rec->fDevice) {
|
||||
|
||||
fMatrix = rec->fMatrix;
|
||||
fRC = &rec->fClip;
|
||||
fDevice = rec->fDevice;
|
||||
if (!fDevice->accessPixels(&fDst)) {
|
||||
fDst.reset(fDevice->imageInfo(), nullptr, 0);
|
||||
}
|
||||
fPaint = rec->fPaint;
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
fCurrLayer = rec->fNext;
|
||||
// fCurrLayer may be nullptr now
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const SkRasterClip& getClip() const { return *fRC; }
|
||||
int getX() const { return fDevice->getOrigin().x(); }
|
||||
int getY() const { return fDevice->getOrigin().y(); }
|
||||
const SkMatrix& getMatrix() const { return *fMatrix; }
|
||||
const SkPaint* getPaint() const { return fPaint; }
|
||||
|
||||
SkBaseDevice* fDevice;
|
||||
@ -391,9 +307,6 @@ public:
|
||||
private:
|
||||
const DeviceCM* fCurrLayer;
|
||||
const SkPaint* fPaint; // May be null.
|
||||
SkClipStack* fMultiDeviceCS;
|
||||
|
||||
typedef SkDraw INHERITED;
|
||||
};
|
||||
|
||||
#define FOR_EACH_TOP_DEVICE( code ) \
|
||||
@ -657,7 +570,6 @@ static inline SkRect qr_clip_bounds(const SkIRect& bounds) {
|
||||
|
||||
void SkCanvas::resetForNextPicture(const SkIRect& bounds) {
|
||||
this->restoreToCount(1);
|
||||
fClipStack->reset();
|
||||
fMCRec->reset(bounds);
|
||||
|
||||
// We're peering through a lot of structs here. Only at this scope do we
|
||||
@ -671,29 +583,22 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
|
||||
if (device && device->forceConservativeRasterClip()) {
|
||||
flags = InitFlags(flags | kConservativeRasterClip_InitFlag);
|
||||
}
|
||||
// Since init() is only called once by our constructors, it is safe to perform this
|
||||
// const-cast.
|
||||
*const_cast<bool*>(&fConservativeRasterClip) = SkToBool(flags & kConservativeRasterClip_InitFlag);
|
||||
|
||||
fAllowSimplifyClip = false;
|
||||
fDeviceCMDirty = true;
|
||||
fSaveCount = 1;
|
||||
fMetaData = nullptr;
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
fLights = nullptr;
|
||||
#endif
|
||||
|
||||
fClipStack.reset(new SkClipStack);
|
||||
|
||||
fMCRec = (MCRec*)fMCStack.push_back();
|
||||
new (fMCRec) MCRec(fConservativeRasterClip);
|
||||
new (fMCRec) MCRec;
|
||||
fMCRec->fRasterClip.setDeviceClipRestriction(&fClipRestrictionRect);
|
||||
fIsScaleTranslate = true;
|
||||
|
||||
SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage));
|
||||
fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage;
|
||||
new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRasterClip,
|
||||
fMCRec->fMatrix);
|
||||
new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fMCRec->fMatrix);
|
||||
|
||||
fMCRec->fTopLayer = fMCRec->fLayer;
|
||||
|
||||
@ -706,9 +611,7 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
|
||||
fMCRec->fRasterClip.setRect(device->getGlobalBounds());
|
||||
fDeviceClipBounds = qr_clip_bounds(device->getGlobalBounds());
|
||||
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect);
|
||||
#endif
|
||||
}
|
||||
|
||||
return device;
|
||||
@ -717,7 +620,6 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
|
||||
SkCanvas::SkCanvas()
|
||||
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
|
||||
, fProps(SkSurfaceProps::kLegacyFontHost_InitType)
|
||||
, fConservativeRasterClip(false)
|
||||
{
|
||||
inc_canvas();
|
||||
|
||||
@ -746,7 +648,6 @@ private:
|
||||
SkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props)
|
||||
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
|
||||
, fProps(SkSurfacePropsCopyOrDefault(props))
|
||||
, fConservativeRasterClip(false)
|
||||
{
|
||||
inc_canvas();
|
||||
|
||||
@ -757,7 +658,6 @@ SkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props)
|
||||
SkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags)
|
||||
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
|
||||
, fProps(SkSurfaceProps::kLegacyFontHost_InitType)
|
||||
, fConservativeRasterClip(false)
|
||||
{
|
||||
inc_canvas();
|
||||
|
||||
@ -767,7 +667,6 @@ SkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags)
|
||||
SkCanvas::SkCanvas(SkBaseDevice* device)
|
||||
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
|
||||
, fProps(device->surfaceProps())
|
||||
, fConservativeRasterClip(false)
|
||||
{
|
||||
inc_canvas();
|
||||
|
||||
@ -777,7 +676,6 @@ SkCanvas::SkCanvas(SkBaseDevice* device)
|
||||
SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags)
|
||||
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
|
||||
, fProps(device->surfaceProps())
|
||||
, fConservativeRasterClip(false)
|
||||
{
|
||||
inc_canvas();
|
||||
|
||||
@ -787,7 +685,6 @@ SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags)
|
||||
SkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
|
||||
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
|
||||
, fProps(props)
|
||||
, fConservativeRasterClip(false)
|
||||
{
|
||||
inc_canvas();
|
||||
|
||||
@ -800,7 +697,6 @@ SkCanvas::SkCanvas(const SkBitmap& bitmap, std::unique_ptr<SkRasterHandleAllocat
|
||||
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
|
||||
, fProps(SkSurfaceProps::kLegacyFontHost_InitType)
|
||||
, fAllocator(std::move(alloc))
|
||||
, fConservativeRasterClip(false)
|
||||
{
|
||||
inc_canvas();
|
||||
|
||||
@ -967,26 +863,6 @@ bool SkCanvas::writePixels(const SkImageInfo& srcInfo, const void* pixels, size_
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkCanvas::updateDeviceCMCache() {
|
||||
if (fDeviceCMDirty) {
|
||||
const SkMatrix& totalMatrix = this->getTotalMatrix();
|
||||
const SkRasterClip& totalClip = fMCRec->fRasterClip;
|
||||
DeviceCM* layer = fMCRec->fTopLayer;
|
||||
|
||||
if (nullptr == layer->fNext) { // only one layer
|
||||
layer->updateMC(totalMatrix, totalClip, nullptr);
|
||||
} else {
|
||||
SkRasterClip clip(totalClip);
|
||||
do {
|
||||
layer->updateMC(totalMatrix, clip, &clip);
|
||||
} while ((layer = layer->fNext) != nullptr);
|
||||
}
|
||||
fDeviceCMDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkCanvas::checkForDeferredSave() {
|
||||
if (fMCRec->fDeferredSaveCount > 0) {
|
||||
this->doSave();
|
||||
@ -1057,10 +933,7 @@ void SkCanvas::internalSave() {
|
||||
new (newTop) MCRec(*fMCRec); // balanced in restore()
|
||||
fMCRec = newTop;
|
||||
|
||||
fClipStack->save();
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
FOR_EACH_TOP_DEVICE(device->save());
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SkCanvas::BoundsAffectsClip(SaveLayerFlags saveLayerFlags) {
|
||||
@ -1091,6 +964,7 @@ bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlag
|
||||
// early exit if the layer's bounds are clipped out
|
||||
if (!ir.intersect(clipBounds)) {
|
||||
if (BoundsAffectsClip(saveLayerFlags)) {
|
||||
fMCRec->fTopLayer->fDevice->clipRegion(SkRegion(), SkClipOp::kIntersect); // empty
|
||||
fMCRec->fRasterClip.setEmpty();
|
||||
fDeviceClipBounds.setEmpty();
|
||||
}
|
||||
@ -1103,7 +977,6 @@ bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlag
|
||||
|
||||
if (BoundsAffectsClip(saveLayerFlags)) {
|
||||
// Simplify the current clips since they will be applied properly during restore()
|
||||
fClipStack->clipDevRect(ir, kReplace_SkClipOp);
|
||||
fMCRec->fRasterClip.setRect(ir);
|
||||
fDeviceClipBounds = qr_clip_bounds(ir);
|
||||
}
|
||||
@ -1136,7 +1009,7 @@ int SkCanvas::saveLayer(const SaveLayerRec& origRec) {
|
||||
|
||||
void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
|
||||
SkBaseDevice* dst, const SkIPoint& dstOrigin,
|
||||
const SkMatrix& ctm, const SkClipStack* clipStack) {
|
||||
const SkMatrix& ctm) {
|
||||
SkDraw draw;
|
||||
SkRasterClip rc;
|
||||
rc.setRect(SkIRect::MakeWH(dst->width(), dst->height()));
|
||||
@ -1145,7 +1018,6 @@ void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filt
|
||||
}
|
||||
draw.fMatrix = &SkMatrix::I();
|
||||
draw.fRC = &rc;
|
||||
draw.fClipStack = clipStack;
|
||||
|
||||
SkPaint p;
|
||||
if (filter) {
|
||||
@ -1156,7 +1028,7 @@ void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filt
|
||||
int y = src->getOrigin().y() - dstOrigin.y();
|
||||
auto special = src->snapSpecial();
|
||||
if (special) {
|
||||
dst->drawSpecial(draw, special.get(), x, y, p);
|
||||
dst->drawSpecial(special.get(), x, y, p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1220,8 +1092,6 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
|
||||
// that would invoke a possibly overridden virtual
|
||||
this->internalSave();
|
||||
|
||||
fDeviceCMDirty = true;
|
||||
|
||||
SkIRect ir;
|
||||
if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, imageFilter)) {
|
||||
return;
|
||||
@ -1265,12 +1135,8 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
|
||||
return;
|
||||
}
|
||||
}
|
||||
#ifndef SK_USE_DEVICE_CLIPPING
|
||||
newDevice->setOrigin(fMCRec->fMatrix, ir.fLeft, ir.fTop);
|
||||
#endif
|
||||
|
||||
DeviceCM* layer =
|
||||
new DeviceCM(newDevice.get(), paint, this, fConservativeRasterClip, stashedMatrix);
|
||||
new DeviceCM(newDevice.get(), paint, this, stashedMatrix);
|
||||
|
||||
// only have a "next" if this new layer doesn't affect the clip (rare)
|
||||
layer->fNext = BoundsAffectsClip(saveLayerFlags) ? nullptr : fMCRec->fTopLayer;
|
||||
@ -1279,10 +1145,9 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
|
||||
|
||||
if ((rec.fSaveLayerFlags & kInitWithPrevious_SaveLayerFlag) || rec.fBackdrop) {
|
||||
DrawDeviceWithFilter(priorDevice, rec.fBackdrop, newDevice.get(), { ir.fLeft, ir.fTop },
|
||||
fMCRec->fMatrix, this->getClipStack());
|
||||
fMCRec->fMatrix);
|
||||
}
|
||||
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
newDevice->setOrigin(fMCRec->fMatrix, ir.fLeft, ir.fTop);
|
||||
|
||||
newDevice->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect);
|
||||
@ -1295,7 +1160,6 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
|
||||
layer->fDevice->clipRegion(hole, SkClipOp::kDifference);
|
||||
} while (layer->fNext);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
|
||||
@ -1311,10 +1175,6 @@ int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
|
||||
void SkCanvas::internalRestore() {
|
||||
SkASSERT(fMCStack.count() != 0);
|
||||
|
||||
fDeviceCMDirty = true;
|
||||
|
||||
fClipStack->restore();
|
||||
|
||||
// reserve our layer (if any)
|
||||
DeviceCM* layer = fMCRec->fLayer; // may be null
|
||||
// now detach it from fMCRec so we can pop(). Gets freed after its drawn
|
||||
@ -1325,11 +1185,9 @@ void SkCanvas::internalRestore() {
|
||||
fMCStack.pop_back();
|
||||
fMCRec = (MCRec*)fMCStack.back();
|
||||
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
if (fMCRec) {
|
||||
FOR_EACH_TOP_DEVICE(device->restore(fMCRec->fMatrix));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Time to draw the layer's offscreen. We can't call the public drawSprite,
|
||||
since if we're being recorded, we don't want to record this (the
|
||||
@ -1342,7 +1200,6 @@ void SkCanvas::internalRestore() {
|
||||
// restore what we smashed in internalSaveLayer
|
||||
fMCRec->fMatrix = layer->fStashedMatrix;
|
||||
// reset this, since internalDrawDevice will have set it to true
|
||||
fDeviceCMDirty = true;
|
||||
delete layer;
|
||||
} else {
|
||||
// we're at the root
|
||||
@ -1448,10 +1305,10 @@ void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPa
|
||||
if (filter) {
|
||||
sk_sp<SkSpecialImage> specialImage = srcDev->snapSpecial();
|
||||
if (specialImage) {
|
||||
dstDev->drawSpecial(iter, specialImage.get(), pos.x(), pos.y(), *paint);
|
||||
dstDev->drawSpecial(specialImage.get(), pos.x(), pos.y(), *paint);
|
||||
}
|
||||
} else {
|
||||
dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint);
|
||||
dstDev->drawDevice(srcDev, pos.x(), pos.y(), *paint);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1463,15 +1320,12 @@ void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPa
|
||||
void SkCanvas::translate(SkScalar dx, SkScalar dy) {
|
||||
if (dx || dy) {
|
||||
this->checkForDeferredSave();
|
||||
fDeviceCMDirty = true;
|
||||
fMCRec->fMatrix.preTranslate(dx,dy);
|
||||
|
||||
// Translate shouldn't affect the is-scale-translateness of the matrix.
|
||||
SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate());
|
||||
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix));
|
||||
#endif
|
||||
|
||||
this->didTranslate(dx,dy);
|
||||
}
|
||||
@ -1507,25 +1361,19 @@ void SkCanvas::concat(const SkMatrix& matrix) {
|
||||
}
|
||||
|
||||
this->checkForDeferredSave();
|
||||
fDeviceCMDirty = true;
|
||||
fMCRec->fMatrix.preConcat(matrix);
|
||||
fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate();
|
||||
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix));
|
||||
#endif
|
||||
|
||||
this->didConcat(matrix);
|
||||
}
|
||||
|
||||
void SkCanvas::internalSetMatrix(const SkMatrix& matrix) {
|
||||
fDeviceCMDirty = true;
|
||||
fMCRec->fMatrix = matrix;
|
||||
fIsScaleTranslate = matrix.isScaleTranslate();
|
||||
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix));
|
||||
#endif
|
||||
}
|
||||
|
||||
void SkCanvas::setMatrix(const SkMatrix& matrix) {
|
||||
@ -1569,36 +1417,25 @@ void SkCanvas::clipRect(const SkRect& rect, SkClipOp op, bool doAA) {
|
||||
void SkCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
|
||||
const bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
|
||||
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
FOR_EACH_TOP_DEVICE(device->clipRect(rect, op, isAA));
|
||||
#endif
|
||||
|
||||
AutoValidateClip avc(this);
|
||||
fClipStack->clipRect(rect, fMCRec->fMatrix, op, isAA);
|
||||
fMCRec->fRasterClip.op(rect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op,
|
||||
isAA);
|
||||
fDeviceCMDirty = true;
|
||||
fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
|
||||
}
|
||||
|
||||
void SkCanvas::androidFramework_setDeviceClipRestriction(const SkIRect& rect) {
|
||||
fClipRestrictionRect = rect;
|
||||
fClipStack->setDeviceClipRestriction(fClipRestrictionRect);
|
||||
if (fClipRestrictionRect.isEmpty()) {
|
||||
// we notify the device, but we *dont* resolve deferred saves (since we're just
|
||||
// removing the restriction if the rect is empty. how I hate this api.
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect));
|
||||
#endif
|
||||
} else {
|
||||
this->checkForDeferredSave();
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect));
|
||||
#endif
|
||||
AutoValidateClip avc(this);
|
||||
fClipStack->clipDevRect(fClipRestrictionRect, kIntersect_SkClipOp);
|
||||
fMCRec->fRasterClip.op(fClipRestrictionRect, SkRegion::kIntersect_Op);
|
||||
fDeviceCMDirty = true;
|
||||
fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
|
||||
}
|
||||
}
|
||||
@ -1616,19 +1453,13 @@ void SkCanvas::clipRRect(const SkRRect& rrect, SkClipOp op, bool doAA) {
|
||||
void SkCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
|
||||
AutoValidateClip avc(this);
|
||||
|
||||
fDeviceCMDirty = true;
|
||||
|
||||
bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
|
||||
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
FOR_EACH_TOP_DEVICE(device->clipRRect(rrect, op, isAA));
|
||||
#endif
|
||||
|
||||
fClipStack->clipRRect(rrect, fMCRec->fMatrix, op, isAA);
|
||||
fMCRec->fRasterClip.op(rrect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op,
|
||||
isAA);
|
||||
fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
|
||||
return;
|
||||
}
|
||||
|
||||
void SkCanvas::clipPath(const SkPath& path, SkClipOp op, bool doAA) {
|
||||
@ -1659,24 +1490,12 @@ void SkCanvas::clipPath(const SkPath& path, SkClipOp op, bool doAA) {
|
||||
void SkCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
|
||||
AutoValidateClip avc(this);
|
||||
|
||||
fDeviceCMDirty = true;
|
||||
bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
|
||||
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
FOR_EACH_TOP_DEVICE(device->clipPath(path, op, isAA));
|
||||
#endif
|
||||
|
||||
fClipStack->clipPath(path, fMCRec->fMatrix, op, isAA);
|
||||
|
||||
const SkPath* rasterClipPath = &path;
|
||||
const SkMatrix* matrix = &fMCRec->fMatrix;
|
||||
SkPath tempPath;
|
||||
if (fAllowSimplifyClip) {
|
||||
isAA = getClipStack()->asPath(&tempPath);
|
||||
rasterClipPath = &tempPath;
|
||||
matrix = &SkMatrix::I();
|
||||
op = kReplace_SkClipOp;
|
||||
}
|
||||
fMCRec->fRasterClip.op(*rasterClipPath, *matrix, this->getTopLayerBounds(), (SkRegion::Op)op,
|
||||
isAA);
|
||||
fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
|
||||
@ -1688,18 +1507,10 @@ void SkCanvas::clipRegion(const SkRegion& rgn, SkClipOp op) {
|
||||
}
|
||||
|
||||
void SkCanvas::onClipRegion(const SkRegion& rgn, SkClipOp op) {
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
FOR_EACH_TOP_DEVICE(device->clipRegion(rgn, op));
|
||||
#endif
|
||||
|
||||
AutoValidateClip avc(this);
|
||||
|
||||
fDeviceCMDirty = true;
|
||||
|
||||
// todo: signal fClipStack that we have a region, and therefore (I guess)
|
||||
// we have to ignore it, and use the region directly?
|
||||
fClipStack->clipDevRect(rgn.getBounds(), op);
|
||||
|
||||
fMCRec->fRasterClip.op(rgn, (SkRegion::Op)op);
|
||||
fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
|
||||
}
|
||||
@ -1712,51 +1523,61 @@ void SkCanvas::validateClip() const {
|
||||
SkASSERT(this->isClipEmpty());
|
||||
return;
|
||||
}
|
||||
|
||||
SkIRect ir;
|
||||
ir.set(0, 0, device->width(), device->height());
|
||||
SkRasterClip tmpClip(ir, fConservativeRasterClip);
|
||||
|
||||
SkClipStack::B2TIter iter(*fClipStack);
|
||||
const SkClipStack::Element* element;
|
||||
while ((element = iter.next()) != nullptr) {
|
||||
switch (element->getType()) {
|
||||
case SkClipStack::Element::kRect_Type:
|
||||
element->getRect().round(&ir);
|
||||
tmpClip.op(ir, (SkRegion::Op)element->getOp());
|
||||
break;
|
||||
case SkClipStack::Element::kEmpty_Type:
|
||||
tmpClip.setEmpty();
|
||||
break;
|
||||
default: {
|
||||
SkPath path;
|
||||
element->asPath(&path);
|
||||
tmpClip.op(path, SkMatrix::I(), this->getTopLayerBounds(),
|
||||
(SkRegion::Op)element->getOp(), element->isAA());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void SkCanvas::replayClips(ClipVisitor* visitor) const {
|
||||
#if 0
|
||||
SkClipStack::B2TIter iter(*fClipStack);
|
||||
const SkClipStack::Element* element;
|
||||
|
||||
while ((element = iter.next()) != nullptr) {
|
||||
element->replay(visitor);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SkCanvas::androidFramework_isClipAA() const {
|
||||
bool containsAA = false;
|
||||
|
||||
FOR_EACH_TOP_DEVICE(containsAA |= device->onClipIsAA());
|
||||
|
||||
return containsAA;
|
||||
}
|
||||
|
||||
class RgnAccumulator {
|
||||
SkRegion* fRgn;
|
||||
public:
|
||||
RgnAccumulator(SkRegion* total) : fRgn(total) {}
|
||||
void accumulate(SkBaseDevice* device, SkRegion* rgn) {
|
||||
SkIPoint origin = device->getOrigin();
|
||||
if (origin.x() | origin.y()) {
|
||||
rgn->translate(origin.x(), origin.y());
|
||||
}
|
||||
fRgn->op(*rgn, SkRegion::kUnion_Op);
|
||||
}
|
||||
};
|
||||
|
||||
void SkCanvas::temporary_internal_getRgnClip(SkRegion* rgn) {
|
||||
RgnAccumulator accum(rgn);
|
||||
SkRegion tmp;
|
||||
|
||||
rgn->setEmpty();
|
||||
FOR_EACH_TOP_DEVICE(device->onAsRgnClip(&tmp); accum.accumulate(device, &tmp));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool SkCanvas::isClipEmpty() const {
|
||||
return fMCRec->fRasterClip.isEmpty();
|
||||
SkBaseDevice* dev = this->getTopDevice();
|
||||
// if no device we return true
|
||||
return !dev || dev->onGetClipType() == SkBaseDevice::kEmpty_ClipType;
|
||||
}
|
||||
|
||||
bool SkCanvas::isClipRect() const {
|
||||
return fMCRec->fRasterClip.isRect();
|
||||
SkBaseDevice* dev = this->getTopDevice();
|
||||
// if no device we return false
|
||||
return dev && dev->onGetClipType() == SkBaseDevice::kRect_ClipType;
|
||||
}
|
||||
|
||||
static inline bool is_nan_or_clipped(const Sk4f& devRect, const Sk4f& devClip) {
|
||||
@ -1857,38 +1678,13 @@ SkRect SkCanvas::onGetLocalClipBounds() const {
|
||||
}
|
||||
|
||||
SkIRect SkCanvas::onGetDeviceClipBounds() const {
|
||||
const SkRasterClip& clip = fMCRec->fRasterClip;
|
||||
if (clip.isEmpty()) {
|
||||
return SkIRect::MakeEmpty();
|
||||
}
|
||||
return clip.getBounds();
|
||||
return fMCRec->fRasterClip.getBounds();
|
||||
}
|
||||
|
||||
const SkMatrix& SkCanvas::getTotalMatrix() const {
|
||||
return fMCRec->fMatrix;
|
||||
}
|
||||
|
||||
void SkCanvas::temporary_internal_getRgnClip(SkRegion* rgn) {
|
||||
// we know that ganesh doesn't track the rgn, so ask for its clipstack
|
||||
if (this->getGrContext()) {
|
||||
const SkClipStack* cs = this->getClipStack();
|
||||
SkClipStack::BoundsType boundType;
|
||||
bool isIntersectionOfRects;
|
||||
SkRect bounds;
|
||||
cs->getBounds(&bounds, &boundType, &isIntersectionOfRects);
|
||||
if (isIntersectionOfRects && SkClipStack::kNormal_BoundsType == boundType) {
|
||||
rgn->setRect(bounds.round());
|
||||
return;
|
||||
}
|
||||
SkPath path;
|
||||
cs->asPath(&path);
|
||||
SkISize size = this->getBaseLayerSize();
|
||||
rgn->setPath(path, SkRegion(SkIRect::MakeWH(size.width(), size.height())));
|
||||
} else {
|
||||
*rgn = fMCRec->fRasterClip.forceGetBW();
|
||||
}
|
||||
}
|
||||
|
||||
GrRenderTargetContext* SkCanvas::internal_private_accessTopLayerRenderTargetContext() {
|
||||
SkBaseDevice* dev = this->getTopDevice();
|
||||
return dev ? dev->accessRenderTargetContext() : nullptr;
|
||||
@ -2158,7 +1954,7 @@ void SkCanvas::internalDrawPaint(const SkPaint& paint) {
|
||||
LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, nullptr, false)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawPaint(iter, looper.paint());
|
||||
iter.fDevice->drawPaint(looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2192,7 +1988,7 @@ void SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint());
|
||||
iter.fDevice->drawPoints(mode, count, pts, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2224,7 +2020,7 @@ void SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) {
|
||||
LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, &r, false)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawRect(iter, r, looper.paint());
|
||||
iter.fDevice->drawRect(r, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2232,7 +2028,7 @@ void SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) {
|
||||
this->predrawNotify(&r, &paint, false);
|
||||
SkDrawIter iter(this);
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawRect(iter, r, paint);
|
||||
iter.fDevice->drawRect(r, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2249,7 +2045,7 @@ void SkCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, ®ionRect)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawRegion(iter, region, looper.paint());
|
||||
iter.fDevice->drawRegion(region, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2267,7 +2063,7 @@ void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, &oval)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawOval(iter, oval, looper.paint());
|
||||
iter.fDevice->drawOval(oval, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2288,7 +2084,7 @@ void SkCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle,
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, &oval)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawArc(iter, oval, startAngle, sweepAngle, useCenter, looper.paint());
|
||||
iter.fDevice->drawArc(oval, startAngle, sweepAngle, useCenter, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2316,7 +2112,7 @@ void SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, &rrect.getBounds())
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawRRect(iter, rrect, looper.paint());
|
||||
iter.fDevice->drawRRect(rrect, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2333,7 +2129,7 @@ void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const Sk
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, &outer.getBounds())
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawDRRect(iter, outer, inner, looper.paint());
|
||||
iter.fDevice->drawDRRect(outer, inner, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2363,7 +2159,7 @@ void SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, &pathBounds)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawPath(iter, path, looper.paint());
|
||||
iter.fDevice->drawPath(path, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2425,12 +2221,12 @@ void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const S
|
||||
const SkPaint& pnt = looper.paint();
|
||||
if (special) {
|
||||
SkPoint pt;
|
||||
iter.fMatrix->mapXY(x, y, &pt);
|
||||
iter.fDevice->drawSpecial(iter, special.get(),
|
||||
iter.fDevice->ctm().mapXY(x, y, &pt);
|
||||
iter.fDevice->drawSpecial(special.get(),
|
||||
SkScalarRoundToInt(pt.fX),
|
||||
SkScalarRoundToInt(pt.fY), pnt);
|
||||
} else {
|
||||
iter.fDevice->drawImage(iter, image, x, y, pnt);
|
||||
iter.fDevice->drawImage(image, x, y, pnt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2458,7 +2254,7 @@ void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const Sk
|
||||
image->isOpaque())
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint(), constraint);
|
||||
iter.fDevice->drawImageRect(image, src, dst, looper.paint(), constraint);
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2506,12 +2302,12 @@ void SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, cons
|
||||
const SkPaint& pnt = looper.paint();
|
||||
if (special) {
|
||||
SkPoint pt;
|
||||
iter.fMatrix->mapXY(x, y, &pt);
|
||||
iter.fDevice->drawSpecial(iter, special.get(),
|
||||
iter.fDevice->ctm().mapXY(x, y, &pt);
|
||||
iter.fDevice->drawSpecial(special.get(),
|
||||
SkScalarRoundToInt(pt.fX),
|
||||
SkScalarRoundToInt(pt.fY), pnt);
|
||||
} else {
|
||||
iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint());
|
||||
iter.fDevice->drawBitmap(bitmap, matrix, looper.paint());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2542,7 +2338,7 @@ void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
|
||||
bitmap.isOpaque())
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), constraint);
|
||||
iter.fDevice->drawBitmapRect(bitmap, src, dst, looper.paint(), constraint);
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2574,7 +2370,7 @@ void SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, cons
|
||||
LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint());
|
||||
iter.fDevice->drawImageNine(image, center, dst, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2600,7 +2396,7 @@ void SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, c
|
||||
LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawBitmapNine(iter, bitmap, center, dst, looper.paint());
|
||||
iter.fDevice->drawBitmapNine(bitmap, center, dst, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2623,7 +2419,7 @@ void SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice,
|
||||
LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawImageLattice(iter, image, lattice, dst, looper.paint());
|
||||
iter.fDevice->drawImageLattice(image, lattice, dst, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2646,7 +2442,7 @@ void SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattic
|
||||
LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawBitmapLattice(iter, bitmap, lattice, dst, looper.paint());
|
||||
iter.fDevice->drawBitmapLattice(bitmap, lattice, dst, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2678,7 +2474,7 @@ void SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkSca
|
||||
|
||||
while (iter.next()) {
|
||||
SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
|
||||
iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint());
|
||||
iter.fDevice->drawText(text, byteLength, x, y, dfp.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2692,7 +2488,7 @@ void SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint
|
||||
|
||||
while (iter.next()) {
|
||||
SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
|
||||
iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 2, textOffset,
|
||||
iter.fDevice->drawPosText(text, byteLength, &pos->fX, 2, textOffset,
|
||||
dfp.paint());
|
||||
}
|
||||
|
||||
@ -2708,7 +2504,7 @@ void SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScala
|
||||
|
||||
while (iter.next()) {
|
||||
SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
|
||||
iter.fDevice->drawPosText(iter, text, byteLength, xpos, 1, textOffset,
|
||||
iter.fDevice->drawPosText(text, byteLength, xpos, 1, textOffset,
|
||||
dfp.paint());
|
||||
}
|
||||
|
||||
@ -2720,7 +2516,7 @@ void SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPat
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawTextOnPath(iter, text, byteLength, path,
|
||||
iter.fDevice->drawTextOnPath(text, byteLength, path,
|
||||
matrix, looper.paint());
|
||||
}
|
||||
|
||||
@ -2736,7 +2532,7 @@ void SkCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRS
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawTextRSXform(iter, text, byteLength, xform, looper.paint());
|
||||
iter.fDevice->drawTextRSXform(text, byteLength, xform, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2765,7 +2561,7 @@ void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
|
||||
while (iter.next()) {
|
||||
SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
|
||||
iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint(), drawFilter);
|
||||
iter.fDevice->drawTextBlob(blob, x, y, dfp.paint(), drawFilter);
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2825,7 +2621,7 @@ void SkCanvas::onDrawVertices(VertexMode vmode, int vertexCount,
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs,
|
||||
iter.fDevice->drawVertices(vmode, vertexCount, verts, texs,
|
||||
colors, bmode, indices, indexCount,
|
||||
looper.paint());
|
||||
}
|
||||
@ -2840,7 +2636,7 @@ void SkCanvas::onDrawVerticesObject(sk_sp<SkVertices> vertices, SkBlendMode bmod
|
||||
|
||||
while (iter.next()) {
|
||||
// In the common case of one iteration we could std::move vertices here.
|
||||
iter.fDevice->drawVerticesObject(iter, vertices, bmode, looper.paint(), flags);
|
||||
iter.fDevice->drawVerticesObject(vertices, bmode, looper.paint(), flags);
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2880,7 +2676,7 @@ void SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawPatch(iter, cubics, colors, texCoords, bmode, paint);
|
||||
iter.fDevice->drawPatch(cubics, colors, texCoords, bmode, paint);
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2924,7 +2720,7 @@ void SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const
|
||||
|
||||
LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, nullptr)
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawAtlas(iter, atlas, xform, tex, colors, count, bmode, pnt);
|
||||
iter.fDevice->drawAtlas(atlas, xform, tex, colors, count, bmode, pnt);
|
||||
}
|
||||
LOOPER_END
|
||||
}
|
||||
@ -2935,7 +2731,7 @@ void SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* va
|
||||
SkPaint paint;
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, nullptr)
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawAnnotation(iter, rect, key, value);
|
||||
iter.fDevice->drawAnnotation(rect, key, value);
|
||||
}
|
||||
LOOPER_END
|
||||
}
|
||||
@ -3310,7 +3106,7 @@ SkBaseDevice* SkCanvas::LayerIter::device() const {
|
||||
}
|
||||
|
||||
const SkMatrix& SkCanvas::LayerIter::matrix() const {
|
||||
return fImpl->getMatrix();
|
||||
return fImpl->fDevice->ctm();
|
||||
}
|
||||
|
||||
const SkPaint& SkCanvas::LayerIter::paint() const {
|
||||
@ -3321,7 +3117,10 @@ const SkPaint& SkCanvas::LayerIter::paint() const {
|
||||
return *paint;
|
||||
}
|
||||
|
||||
const SkRasterClip& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); }
|
||||
void SkCanvas::LayerIter::clip(SkRegion* rgn) const {
|
||||
return fImpl->fDevice->onAsRgnClip(rgn);
|
||||
}
|
||||
|
||||
int SkCanvas::LayerIter::x() const { return fImpl->getX(); }
|
||||
int SkCanvas::LayerIter::y() const { return fImpl->getY(); }
|
||||
|
||||
|
@ -9,6 +9,16 @@
|
||||
#include "SkDraw.h"
|
||||
#include "SkRasterClip.h"
|
||||
|
||||
SkIRect SkClipStackDevice::devClipBounds() const {
|
||||
SkIRect r = fClipStack.bounds(this->imageInfo().bounds()).roundOut();
|
||||
if (!r.isEmpty()) {
|
||||
SkASSERT(this->imageInfo().bounds().contains(r));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkClipStackDevice::onSave() {
|
||||
fClipStack.save();
|
||||
}
|
||||
@ -52,13 +62,47 @@ void SkClipStackDevice::onSetDeviceClipRestriction(SkIRect* clipRestriction) {
|
||||
}
|
||||
}
|
||||
|
||||
SkIRect SkClipStackDevice::devClipBounds(const SkDraw& draw) const {
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
SkIRect r = fClipStack.bounds(this->imageInfo().bounds()).roundOut();
|
||||
SkASSERT(this->imageInfo().bounds().contains(r));
|
||||
SkASSERT(draw.fRC->getBounds().contains(r));
|
||||
return r;
|
||||
#else
|
||||
return draw.fRC->getBounds();
|
||||
#endif
|
||||
bool SkClipStackDevice::onClipIsAA() const {
|
||||
SkClipStack::B2TIter iter(fClipStack);
|
||||
const SkClipStack::Element* element;
|
||||
|
||||
while ((element = iter.next()) != nullptr) {
|
||||
if (element->isAA()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SkClipStackDevice::onAsRgnClip(SkRegion* rgn) const {
|
||||
SkClipStack::BoundsType boundType;
|
||||
bool isIntersectionOfRects;
|
||||
SkRect bounds;
|
||||
fClipStack.getBounds(&bounds, &boundType, &isIntersectionOfRects);
|
||||
if (isIntersectionOfRects && SkClipStack::kNormal_BoundsType == boundType) {
|
||||
rgn->setRect(bounds.round());
|
||||
} else {
|
||||
SkPath path;
|
||||
fClipStack.asPath(&path);
|
||||
rgn->setPath(path, SkRegion(SkIRect::MakeWH(this->width(), this->height())));
|
||||
}
|
||||
}
|
||||
|
||||
SkBaseDevice::ClipType SkClipStackDevice::onGetClipType() const {
|
||||
if (fClipStack.isWideOpen()) {
|
||||
return kRect_ClipType;
|
||||
}
|
||||
if (fClipStack.isEmpty(SkIRect::MakeWH(this->width(), this->height()))) {
|
||||
return kEmpty_ClipType;
|
||||
} else {
|
||||
SkClipStack::BoundsType boundType;
|
||||
bool isIntersectionOfRects;
|
||||
SkRect bounds;
|
||||
fClipStack.getBounds(&bounds, &boundType, &isIntersectionOfRects);
|
||||
if (isIntersectionOfRects && SkClipStack::kNormal_BoundsType == boundType) {
|
||||
return kRect_ClipType;
|
||||
} else {
|
||||
return kComplex_ClipType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public:
|
||||
|
||||
const SkClipStack& cs() const { return fClipStack; }
|
||||
|
||||
SkIRect devClipBounds(const SkDraw&) const;
|
||||
SkIRect devClipBounds() const;
|
||||
|
||||
protected:
|
||||
void onSave() override;
|
||||
@ -29,6 +29,9 @@ protected:
|
||||
void onClipPath(const SkPath& path, SkClipOp, bool aa) override;
|
||||
void onClipRegion(const SkRegion& deviceRgn, SkClipOp) override;
|
||||
void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) override;
|
||||
bool onClipIsAA() const override;
|
||||
void onAsRgnClip(SkRegion*) const override;
|
||||
ClipType onGetClipType() const override;
|
||||
|
||||
private:
|
||||
SkClipStack fClipStack;
|
||||
|
@ -71,35 +71,36 @@ static inline bool is_int(float x) {
|
||||
return x == (float) sk_float_round2int(x);
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawRegion(const SkDraw& draw, const SkRegion& region, const SkPaint& paint) {
|
||||
bool isNonTranslate = draw.fMatrix->getType() & ~(SkMatrix::kTranslate_Mask);
|
||||
void SkBaseDevice::drawRegion(const SkRegion& region, const SkPaint& paint) {
|
||||
const SkMatrix& ctm = this->ctm();
|
||||
bool isNonTranslate = ctm.getType() & ~(SkMatrix::kTranslate_Mask);
|
||||
bool complexPaint = paint.getStyle() != SkPaint::kFill_Style || paint.getMaskFilter() ||
|
||||
paint.getPathEffect();
|
||||
bool antiAlias = paint.isAntiAlias() && (!is_int(draw.fMatrix->getTranslateX()) ||
|
||||
!is_int(draw.fMatrix->getTranslateY()));
|
||||
bool antiAlias = paint.isAntiAlias() && (!is_int(ctm.getTranslateX()) ||
|
||||
!is_int(ctm.getTranslateY()));
|
||||
if (isNonTranslate || complexPaint || antiAlias) {
|
||||
SkPath path;
|
||||
region.getBoundaryPath(&path);
|
||||
return this->drawPath(draw, path, paint, nullptr, false);
|
||||
return this->drawPath(path, paint, nullptr, false);
|
||||
}
|
||||
|
||||
SkRegion::Iterator it(region);
|
||||
while (!it.done()) {
|
||||
this->drawRect(draw, SkRect::Make(it.rect()), paint);
|
||||
this->drawRect(SkRect::Make(it.rect()), paint);
|
||||
it.next();
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawArc(const SkDraw& draw, const SkRect& oval, SkScalar startAngle,
|
||||
void SkBaseDevice::drawArc(const SkRect& oval, SkScalar startAngle,
|
||||
SkScalar sweepAngle, bool useCenter, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
bool isFillNoPathEffect = SkPaint::kFill_Style == paint.getStyle() && !paint.getPathEffect();
|
||||
SkPathPriv::CreateDrawArcPath(&path, oval, startAngle, sweepAngle, useCenter,
|
||||
isFillNoPathEffect);
|
||||
this->drawPath(draw, path, paint);
|
||||
this->drawPath(path, paint);
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
|
||||
void SkBaseDevice::drawDRRect(const SkRRect& outer,
|
||||
const SkRRect& inner, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
path.addRRect(outer);
|
||||
@ -109,25 +110,25 @@ void SkBaseDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
|
||||
|
||||
const SkMatrix* preMatrix = nullptr;
|
||||
const bool pathIsMutable = true;
|
||||
this->drawPath(draw, path, paint, preMatrix, pathIsMutable);
|
||||
this->drawPath(path, paint, preMatrix, pathIsMutable);
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawPatch(const SkDraw& draw, const SkPoint cubics[12], const SkColor colors[4],
|
||||
void SkBaseDevice::drawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||
const SkPoint texCoords[4], SkBlendMode bmode, const SkPaint& paint) {
|
||||
SkPatchUtils::VertexData data;
|
||||
|
||||
SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, draw.fMatrix);
|
||||
SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, &this->ctm());
|
||||
|
||||
// It automatically adjusts lodX and lodY in case it exceeds the number of indices.
|
||||
// If it fails to generate the vertices, then we do not draw.
|
||||
if (SkPatchUtils::getVertexData(&data, cubics, colors, texCoords, lod.width(), lod.height())) {
|
||||
this->drawVertices(draw, SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
|
||||
this->drawVertices(SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
|
||||
data.fTexCoords, data.fColors, bmode, data.fIndices, data.fIndexCount,
|
||||
paint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
void SkBaseDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
const SkPaint &paint, SkDrawFilter* drawFilter) {
|
||||
|
||||
SkPaint runPaint = paint;
|
||||
@ -150,14 +151,14 @@ void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSc
|
||||
|
||||
switch (it.positioning()) {
|
||||
case SkTextBlob::kDefault_Positioning:
|
||||
this->drawText(draw, it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint);
|
||||
this->drawText(it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint);
|
||||
break;
|
||||
case SkTextBlob::kHorizontal_Positioning:
|
||||
this->drawPosText(draw, it.glyphs(), textLen, it.pos(), 1,
|
||||
this->drawPosText(it.glyphs(), textLen, it.pos(), 1,
|
||||
SkPoint::Make(x, y + offset.y()), runPaint);
|
||||
break;
|
||||
case SkTextBlob::kFull_Positioning:
|
||||
this->drawPosText(draw, it.glyphs(), textLen, it.pos(), 2,
|
||||
this->drawPosText(it.glyphs(), textLen, it.pos(), 2,
|
||||
SkPoint::Make(x, y), runPaint);
|
||||
break;
|
||||
default:
|
||||
@ -171,66 +172,66 @@ void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSc
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x, SkScalar y,
|
||||
void SkBaseDevice::drawImage(const SkImage* image, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint) {
|
||||
SkBitmap bm;
|
||||
if (as_IB(image)->getROPixels(&bm, this->imageInfo().colorSpace())) {
|
||||
this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
|
||||
this->drawBitmap(bm, SkMatrix::MakeTrans(x, y), paint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src,
|
||||
void SkBaseDevice::drawImageRect(const SkImage* image, const SkRect* src,
|
||||
const SkRect& dst, const SkPaint& paint,
|
||||
SkCanvas::SrcRectConstraint constraint) {
|
||||
SkBitmap bm;
|
||||
if (as_IB(image)->getROPixels(&bm, this->imageInfo().colorSpace())) {
|
||||
this->drawBitmapRect(draw, bm, src, dst, paint, constraint);
|
||||
this->drawBitmapRect(bm, src, dst, paint, constraint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawImageNine(const SkDraw& draw, const SkImage* image, const SkIRect& center,
|
||||
void SkBaseDevice::drawImageNine(const SkImage* image, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint& paint) {
|
||||
SkLatticeIter iter(image->width(), image->height(), center, dst);
|
||||
|
||||
SkRect srcR, dstR;
|
||||
while (iter.next(&srcR, &dstR)) {
|
||||
this->drawImageRect(draw, image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
this->drawImageRect(image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawBitmapNine(const SkDraw& draw, const SkBitmap& bitmap, const SkIRect& center,
|
||||
void SkBaseDevice::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint& paint) {
|
||||
SkLatticeIter iter(bitmap.width(), bitmap.height(), center, dst);
|
||||
|
||||
SkRect srcR, dstR;
|
||||
while (iter.next(&srcR, &dstR)) {
|
||||
this->drawBitmapRect(draw, bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
this->drawBitmapRect(bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawImageLattice(const SkDraw& draw, const SkImage* image,
|
||||
void SkBaseDevice::drawImageLattice(const SkImage* image,
|
||||
const SkCanvas::Lattice& lattice, const SkRect& dst,
|
||||
const SkPaint& paint) {
|
||||
SkLatticeIter iter(lattice, dst);
|
||||
|
||||
SkRect srcR, dstR;
|
||||
while (iter.next(&srcR, &dstR)) {
|
||||
this->drawImageRect(draw, image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
this->drawImageRect(image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawBitmapLattice(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
void SkBaseDevice::drawBitmapLattice(const SkBitmap& bitmap,
|
||||
const SkCanvas::Lattice& lattice, const SkRect& dst,
|
||||
const SkPaint& paint) {
|
||||
SkLatticeIter iter(lattice, dst);
|
||||
|
||||
SkRect srcR, dstR;
|
||||
while (iter.next(&srcR, &dstR)) {
|
||||
this->drawBitmapRect(draw, bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
this->drawBitmapRect(bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkRSXform xform[],
|
||||
void SkBaseDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
|
||||
const SkRect tex[], const SkColor colors[], int count,
|
||||
SkBlendMode mode, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
@ -260,23 +261,23 @@ void SkBaseDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkR
|
||||
path.rewind();
|
||||
path.addPoly(quad, 4, true);
|
||||
path.setConvexity(SkPath::kConvex_Convexity);
|
||||
this->drawPath(draw, path, pnt, nullptr, true);
|
||||
this->drawPath(path, pnt, nullptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawVerticesObject(const SkDraw& draw, sk_sp<SkVertices> vertices,
|
||||
void SkBaseDevice::drawVerticesObject(sk_sp<SkVertices> vertices,
|
||||
SkBlendMode mode, const SkPaint& paint, uint32_t flags) {
|
||||
const SkPoint* texs =
|
||||
(flags & SkCanvas::kIgnoreTexCoords_VerticesFlag) ? nullptr : vertices->texCoords();
|
||||
const SkColor* colors =
|
||||
(flags & SkCanvas::kIgnoreColors_VerticesFlag) ? nullptr : vertices->colors();
|
||||
this->drawVertices(draw, vertices->mode(), vertices->vertexCount(), vertices->positions(), texs,
|
||||
this->drawVertices(vertices->mode(), vertices->vertexCount(), vertices->positions(), texs,
|
||||
colors, mode, vertices->indices(), vertices->indexCount(), paint);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkBaseDevice::drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&) {}
|
||||
void SkBaseDevice::drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) {}
|
||||
sk_sp<SkSpecialImage> SkBaseDevice::makeSpecial(const SkBitmap&) { return nullptr; }
|
||||
sk_sp<SkSpecialImage> SkBaseDevice::makeSpecial(const SkImage*) { return nullptr; }
|
||||
sk_sp<SkSpecialImage> SkBaseDevice::snapSpecial() { return nullptr; }
|
||||
@ -392,13 +393,13 @@ static void morphpath(SkPath* dst, const SkPath& src, SkPathMeasure& meas,
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawTextOnPath(const SkDraw& draw, const void* text, size_t byteLength,
|
||||
void SkBaseDevice::drawTextOnPath(const void* text, size_t byteLength,
|
||||
const SkPath& follow, const SkMatrix* matrix,
|
||||
const SkPaint& paint) {
|
||||
SkASSERT(byteLength == 0 || text != nullptr);
|
||||
|
||||
// nothing to draw
|
||||
if (text == nullptr || byteLength == 0 || draw.fRC->isEmpty()) {
|
||||
if (text == nullptr || byteLength == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -433,7 +434,7 @@ void SkBaseDevice::drawTextOnPath(const SkDraw& draw, const void* text, size_t b
|
||||
m.postConcat(*matrix);
|
||||
}
|
||||
morphpath(&tmp, *iterPath, meas, m);
|
||||
this->drawPath(draw, tmp, iter.getPaint(), nullptr, true);
|
||||
this->drawPath(tmp, iter.getPaint(), nullptr, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -448,7 +449,7 @@ static int count_utf16(const char* text) {
|
||||
static int return_4(const char* text) { return 4; }
|
||||
static int return_2(const char* text) { return 2; }
|
||||
|
||||
void SkBaseDevice::drawTextRSXform(const SkDraw& draw, const void* text, size_t len,
|
||||
void SkBaseDevice::drawTextRSXform(const void* text, size_t len,
|
||||
const SkRSXform xform[], const SkPaint& paint) {
|
||||
CountTextProc proc = nullptr;
|
||||
switch (paint.getTextEncoding()) {
|
||||
@ -466,19 +467,15 @@ void SkBaseDevice::drawTextRSXform(const SkDraw& draw, const void* text, size_t
|
||||
break;
|
||||
}
|
||||
|
||||
SkDraw localD(draw);
|
||||
SkMatrix localM, currM;
|
||||
const void* stopText = (const char*)text + len;
|
||||
while ((const char*)text < (const char*)stopText) {
|
||||
localM.setRSXform(*xform++);
|
||||
currM.setConcat(*draw.fMatrix, localM);
|
||||
localD.fMatrix = &currM;
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
currM.setConcat(this->ctm(), localM);
|
||||
SkAutoDeviceCTMRestore adc(this, currM);
|
||||
#endif
|
||||
|
||||
int subLen = proc((const char*)text);
|
||||
this->drawText(localD, text, subLen, 0, 0, paint);
|
||||
this->drawText(text, subLen, 0, 0, paint);
|
||||
text = (const char*)text + subLen;
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "SkSurfaceProps.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkDraw;
|
||||
class SkDrawFilter;
|
||||
class SkImageFilterCache;
|
||||
struct SkIRect;
|
||||
@ -150,29 +149,37 @@ protected:
|
||||
virtual void onClipPath(const SkPath& path, SkClipOp, bool aa) {}
|
||||
virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp) {}
|
||||
virtual void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) {}
|
||||
virtual bool onClipIsAA() const = 0;
|
||||
virtual void onAsRgnClip(SkRegion*) const = 0;
|
||||
enum ClipType {
|
||||
kEmpty_ClipType,
|
||||
kRect_ClipType,
|
||||
kComplex_ClipType
|
||||
};
|
||||
virtual ClipType onGetClipType() const = 0;
|
||||
|
||||
/** These are called inside the per-device-layer loop for each draw call.
|
||||
When these are called, we have already applied any saveLayer operations,
|
||||
and are handling any looping from the paint, and any effects from the
|
||||
DrawFilter.
|
||||
*/
|
||||
virtual void drawPaint(const SkDraw&, const SkPaint& paint) = 0;
|
||||
virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
|
||||
virtual void drawPaint(const SkPaint& paint) = 0;
|
||||
virtual void drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint[], const SkPaint& paint) = 0;
|
||||
virtual void drawRect(const SkDraw&, const SkRect& r,
|
||||
virtual void drawRect(const SkRect& r,
|
||||
const SkPaint& paint) = 0;
|
||||
virtual void drawRegion(const SkDraw&, const SkRegion& r,
|
||||
virtual void drawRegion(const SkRegion& r,
|
||||
const SkPaint& paint);
|
||||
virtual void drawOval(const SkDraw&, const SkRect& oval,
|
||||
virtual void drawOval(const SkRect& oval,
|
||||
const SkPaint& paint) = 0;
|
||||
/** By the time this is called we know that abs(sweepAngle) is in the range [0, 360). */
|
||||
virtual void drawArc(const SkDraw&, const SkRect& oval, SkScalar startAngle,
|
||||
virtual void drawArc(const SkRect& oval, SkScalar startAngle,
|
||||
SkScalar sweepAngle, bool useCenter, const SkPaint& paint);
|
||||
virtual void drawRRect(const SkDraw&, const SkRRect& rr,
|
||||
virtual void drawRRect(const SkRRect& rr,
|
||||
const SkPaint& paint) = 0;
|
||||
|
||||
// Default impl calls drawPath()
|
||||
virtual void drawDRRect(const SkDraw&, const SkRRect& outer,
|
||||
virtual void drawDRRect(const SkRRect& outer,
|
||||
const SkRRect& inner, const SkPaint&);
|
||||
|
||||
/**
|
||||
@ -186,77 +193,77 @@ protected:
|
||||
* affect the geometry/rasterization, then the pre matrix can just be
|
||||
* pre-concated with the current matrix.
|
||||
*/
|
||||
virtual void drawPath(const SkDraw&, const SkPath& path,
|
||||
virtual void drawPath(const SkPath& path,
|
||||
const SkPaint& paint,
|
||||
const SkMatrix* prePathMatrix = NULL,
|
||||
bool pathIsMutable = false) = 0;
|
||||
virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
|
||||
virtual void drawBitmap(const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint& paint) = 0;
|
||||
virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
|
||||
virtual void drawSprite(const SkBitmap& bitmap,
|
||||
int x, int y, const SkPaint& paint) = 0;
|
||||
|
||||
/**
|
||||
* The default impl. will create a bitmap-shader from the bitmap,
|
||||
* and call drawRect with it.
|
||||
*/
|
||||
virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
|
||||
virtual void drawBitmapRect(const SkBitmap&,
|
||||
const SkRect* srcOrNull, const SkRect& dst,
|
||||
const SkPaint& paint,
|
||||
SkCanvas::SrcRectConstraint) = 0;
|
||||
virtual void drawBitmapNine(const SkDraw&, const SkBitmap&, const SkIRect& center,
|
||||
virtual void drawBitmapNine(const SkBitmap&, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
virtual void drawBitmapLattice(const SkDraw&, const SkBitmap&, const SkCanvas::Lattice&,
|
||||
virtual void drawBitmapLattice(const SkBitmap&, const SkCanvas::Lattice&,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
|
||||
virtual void drawImage(const SkDraw&, const SkImage*, SkScalar x, SkScalar y, const SkPaint&);
|
||||
virtual void drawImageRect(const SkDraw&, const SkImage*, const SkRect* src, const SkRect& dst,
|
||||
virtual void drawImage(const SkImage*, SkScalar x, SkScalar y, const SkPaint&);
|
||||
virtual void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
|
||||
const SkPaint&, SkCanvas::SrcRectConstraint);
|
||||
virtual void drawImageNine(const SkDraw&, const SkImage*, const SkIRect& center,
|
||||
virtual void drawImageNine(const SkImage*, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
virtual void drawImageLattice(const SkDraw&, const SkImage*, const SkCanvas::Lattice&,
|
||||
virtual void drawImageLattice(const SkImage*, const SkCanvas::Lattice&,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
|
||||
/**
|
||||
* Does not handle text decoration.
|
||||
* Decorations (underline and stike-thru) will be handled by SkCanvas.
|
||||
*/
|
||||
virtual void drawText(const SkDraw&, const void* text, size_t len,
|
||||
virtual void drawText(const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) = 0;
|
||||
virtual void drawPosText(const SkDraw&, const void* text, size_t len,
|
||||
virtual void drawPosText(const void* text, size_t len,
|
||||
const SkScalar pos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint& paint) = 0;
|
||||
virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
|
||||
virtual void drawVertices(SkCanvas::VertexMode, int vertexCount,
|
||||
const SkPoint verts[], const SkPoint texs[],
|
||||
const SkColor colors[], SkBlendMode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint) = 0;
|
||||
virtual void drawVerticesObject(const SkDraw&, sk_sp<SkVertices>, SkBlendMode, const SkPaint&,
|
||||
virtual void drawVerticesObject(sk_sp<SkVertices>, SkBlendMode, const SkPaint&,
|
||||
uint32_t flags);
|
||||
// default implementation unrolls the blob runs.
|
||||
virtual void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
|
||||
virtual void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint, SkDrawFilter* drawFilter);
|
||||
// default implementation calls drawVertices
|
||||
virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
|
||||
virtual void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||
const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint);
|
||||
|
||||
// default implementation calls drawPath
|
||||
virtual void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[],
|
||||
virtual void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[],
|
||||
const SkColor[], int count, SkBlendMode, const SkPaint&);
|
||||
|
||||
virtual void drawAnnotation(const SkDraw&, const SkRect&, const char[], SkData*) {}
|
||||
virtual void drawAnnotation(const SkRect&, const char[], SkData*) {}
|
||||
|
||||
/** The SkDevice passed will be an SkDevice which was returned by a call to
|
||||
onCreateDevice on this device with kNeverTile_TileExpectation.
|
||||
*/
|
||||
virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
|
||||
virtual void drawDevice(SkBaseDevice*, int x, int y,
|
||||
const SkPaint&) = 0;
|
||||
|
||||
virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath&,
|
||||
virtual void drawTextOnPath(const void* text, size_t len, const SkPath&,
|
||||
const SkMatrix*, const SkPaint&);
|
||||
virtual void drawTextRSXform(const SkDraw&, const void* text, size_t len, const SkRSXform[],
|
||||
virtual void drawTextRSXform(const void* text, size_t len, const SkRSXform[],
|
||||
const SkPaint&);
|
||||
|
||||
virtual void drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&);
|
||||
virtual void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&);
|
||||
virtual sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&);
|
||||
virtual sk_sp<SkSpecialImage> makeSpecial(const SkImage*);
|
||||
virtual sk_sp<SkSpecialImage> snapSpecial();
|
||||
|
@ -11,7 +11,6 @@ SkDeviceLooper::SkDeviceLooper(const SkPixmap& base, const SkRasterClip& rc, con
|
||||
bool aa)
|
||||
: fBaseDst(base)
|
||||
, fBaseRC(rc)
|
||||
, fSubsetRC(rc.isForceConservativeRects())
|
||||
, fDelta(aa ? kAA_Delta : kBW_Delta)
|
||||
{
|
||||
// sentinels that next() has not yet been called, and so our mapper functions
|
||||
|
@ -578,11 +578,9 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
// then path then
|
||||
path.setIsVolatile((count-1) == i);
|
||||
if (device) {
|
||||
device->drawPath(*this, path, newPaint, &preMatrix,
|
||||
(count-1) == i);
|
||||
device->drawPath(path, newPaint, &preMatrix, (count-1) == i);
|
||||
} else {
|
||||
this->drawPath(path, newPaint, &preMatrix,
|
||||
(count-1) == i);
|
||||
this->drawPath(path, newPaint, &preMatrix, (count-1) == i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -594,7 +592,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
r.fRight = r.fLeft + width;
|
||||
r.fBottom = r.fTop + width;
|
||||
if (device) {
|
||||
device->drawRect(*this, r, newPaint);
|
||||
device->drawRect(r, newPaint);
|
||||
} else {
|
||||
this->drawRect(r, newPaint);
|
||||
}
|
||||
@ -625,7 +623,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
|
||||
if (!pointData.fFirst.isEmpty()) {
|
||||
if (device) {
|
||||
device->drawPath(*this, pointData.fFirst, newP);
|
||||
device->drawPath(pointData.fFirst, newP);
|
||||
} else {
|
||||
this->drawPath(pointData.fFirst, newP);
|
||||
}
|
||||
@ -633,7 +631,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
|
||||
if (!pointData.fLast.isEmpty()) {
|
||||
if (device) {
|
||||
device->drawPath(*this, pointData.fLast, newP);
|
||||
device->drawPath(pointData.fLast, newP);
|
||||
} else {
|
||||
this->drawPath(pointData.fLast, newP);
|
||||
}
|
||||
@ -650,8 +648,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
}
|
||||
|
||||
if (device) {
|
||||
device->drawPoints(*this,
|
||||
SkCanvas::kPoints_PointMode,
|
||||
device->drawPoints(SkCanvas::kPoints_PointMode,
|
||||
pointData.fNumPoints,
|
||||
pointData.fPoints,
|
||||
newP);
|
||||
@ -676,7 +673,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
pointData.fPoints[i].fX + pointData.fSize.fX,
|
||||
pointData.fPoints[i].fY + pointData.fSize.fY);
|
||||
if (device) {
|
||||
device->drawRect(*this, r, newP);
|
||||
device->drawRect(r, newP);
|
||||
} else {
|
||||
this->drawRect(r, newP);
|
||||
}
|
||||
@ -698,7 +695,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
path.moveTo(pts[i]);
|
||||
path.lineTo(pts[i+1]);
|
||||
if (device) {
|
||||
device->drawPath(*this, path, p, nullptr, true);
|
||||
device->drawPath(path, p, nullptr, true);
|
||||
} else {
|
||||
this->drawPath(path, p, nullptr, true);
|
||||
}
|
||||
@ -1423,8 +1420,7 @@ void SkDraw::drawText_asPaths(const char text[], size_t byteLength, SkScalar x,
|
||||
while (iter.next(&iterPath, &xpos)) {
|
||||
matrix.postTranslate(xpos - prevXPos, 0);
|
||||
if (iterPath) {
|
||||
const SkPaint& pnt = iter.getPaint();
|
||||
this->drawPath(*iterPath, pnt, &matrix, false);
|
||||
this->drawPath(*iterPath, iter.getPaint(), &matrix, false);
|
||||
}
|
||||
prevXPos = xpos;
|
||||
}
|
||||
|
@ -149,7 +149,6 @@ public:
|
||||
SkPixmap fDst;
|
||||
const SkMatrix* fMatrix; // required
|
||||
const SkRasterClip* fRC; // required
|
||||
const SkClipStack* fClipStack; // optional, may be null
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void validate() const;
|
||||
|
@ -8,10 +8,125 @@
|
||||
#include "SkRasterClip.h"
|
||||
#include "SkPath.h"
|
||||
|
||||
enum MutateResult {
|
||||
kDoNothing_MutateResult,
|
||||
kReplaceClippedAgainstGlobalBounds_MutateResult,
|
||||
kContinue_MutateResult,
|
||||
};
|
||||
|
||||
static MutateResult mutate_conservative_op(SkRegion::Op* op, bool inverseFilled) {
|
||||
if (inverseFilled) {
|
||||
switch (*op) {
|
||||
case SkRegion::kIntersect_Op:
|
||||
case SkRegion::kDifference_Op:
|
||||
// These ops can only shrink the current clip. So leaving
|
||||
// the clip unchanged conservatively respects the contract.
|
||||
return kDoNothing_MutateResult;
|
||||
case SkRegion::kUnion_Op:
|
||||
case SkRegion::kReplace_Op:
|
||||
case SkRegion::kReverseDifference_Op:
|
||||
case SkRegion::kXOR_Op: {
|
||||
// These ops can grow the current clip up to the extents of
|
||||
// the input clip, which is inverse filled, so we just set
|
||||
// the current clip to the device bounds.
|
||||
*op = SkRegion::kReplace_Op;
|
||||
return kReplaceClippedAgainstGlobalBounds_MutateResult;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Not inverse filled
|
||||
switch (*op) {
|
||||
case SkRegion::kIntersect_Op:
|
||||
case SkRegion::kUnion_Op:
|
||||
case SkRegion::kReplace_Op:
|
||||
return kContinue_MutateResult;
|
||||
case SkRegion::kDifference_Op:
|
||||
// Difference can only shrink the current clip.
|
||||
// Leaving clip unchanged conservatively fullfills the contract.
|
||||
return kDoNothing_MutateResult;
|
||||
case SkRegion::kReverseDifference_Op:
|
||||
// To reverse, we swap in the bounds with a replace op.
|
||||
// As with difference, leave it unchanged.
|
||||
*op = SkRegion::kReplace_Op;
|
||||
return kContinue_MutateResult;
|
||||
case SkRegion::kXOR_Op:
|
||||
// Be conservative, based on (A XOR B) always included in (A union B),
|
||||
// which is always included in (bounds(A) union bounds(B))
|
||||
*op = SkRegion::kUnion_Op;
|
||||
return kContinue_MutateResult;
|
||||
}
|
||||
}
|
||||
SkFAIL("should not get here");
|
||||
return kDoNothing_MutateResult;
|
||||
}
|
||||
|
||||
void SkConservativeClip::op(const SkRect& localRect, const SkMatrix& ctm, const SkIRect& devBounds,
|
||||
SkRegion::Op op, bool doAA) {
|
||||
SkRect devRect;
|
||||
|
||||
SkIRect bounds(devBounds);
|
||||
this->applyClipRestriction(op, &bounds);
|
||||
SkIRect ir;
|
||||
switch (mutate_conservative_op(&op, false)) {
|
||||
case kDoNothing_MutateResult:
|
||||
return;
|
||||
case kReplaceClippedAgainstGlobalBounds_MutateResult:
|
||||
ir = bounds;
|
||||
break;
|
||||
case kContinue_MutateResult:
|
||||
ctm.mapRect(&devRect, localRect);
|
||||
ir = doAA ? devRect.roundOut() : devRect.round();
|
||||
break;
|
||||
}
|
||||
this->op(ir, op);
|
||||
}
|
||||
|
||||
void SkConservativeClip::op(const SkRRect& rrect, const SkMatrix& ctm, const SkIRect& devBounds,
|
||||
SkRegion::Op op, bool doAA) {
|
||||
SkIRect bounds(devBounds);
|
||||
this->applyClipRestriction(op, &bounds);
|
||||
this->op(rrect.getBounds(), ctm, bounds, op, doAA);
|
||||
}
|
||||
|
||||
void SkConservativeClip::op(const SkPath& path, const SkMatrix& ctm, const SkIRect& devBounds,
|
||||
SkRegion::Op op, bool doAA) {
|
||||
SkIRect bounds(devBounds);
|
||||
this->applyClipRestriction(op, &bounds);
|
||||
|
||||
SkIRect ir;
|
||||
switch (mutate_conservative_op(&op, path.isInverseFillType())) {
|
||||
case kDoNothing_MutateResult:
|
||||
return;
|
||||
case kReplaceClippedAgainstGlobalBounds_MutateResult:
|
||||
ir = bounds;
|
||||
break;
|
||||
case kContinue_MutateResult: {
|
||||
SkRect bounds = path.getBounds();
|
||||
ctm.mapRect(&bounds);
|
||||
ir = bounds.roundOut();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this->op(ir, op);
|
||||
}
|
||||
|
||||
void SkConservativeClip::op(const SkRegion& rgn, SkRegion::Op op) {
|
||||
this->op(rgn.getBounds(), op);
|
||||
}
|
||||
|
||||
void SkConservativeClip::op(const SkIRect& devRect, SkRegion::Op op) {
|
||||
// This may still create a complex region (which we would then take the bounds
|
||||
// Perhaps we should inline the op-logic directly to never create the rgn...
|
||||
SkRegion result;
|
||||
result.op(SkRegion(fBounds), SkRegion(devRect), op);
|
||||
fBounds = result.getBounds();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkRasterClip::SkRasterClip(const SkRasterClip& src) {
|
||||
AUTO_RASTERCLIP_VALIDATE(src);
|
||||
|
||||
fForceConservativeRects = src.fForceConservativeRects;
|
||||
fIsBW = src.fIsBW;
|
||||
if (fIsBW) {
|
||||
fBW = src.fBW;
|
||||
@ -26,23 +141,20 @@ SkRasterClip::SkRasterClip(const SkRasterClip& src) {
|
||||
}
|
||||
|
||||
SkRasterClip::SkRasterClip(const SkRegion& rgn) : fBW(rgn) {
|
||||
fForceConservativeRects = false;
|
||||
fIsBW = true;
|
||||
fIsEmpty = this->computeIsEmpty(); // bounds might be empty, so compute
|
||||
fIsRect = !fIsEmpty;
|
||||
SkDEBUGCODE(this->validate();)
|
||||
}
|
||||
|
||||
SkRasterClip::SkRasterClip(const SkIRect& bounds, bool forceConservativeRects) : fBW(bounds) {
|
||||
fForceConservativeRects = forceConservativeRects;
|
||||
SkRasterClip::SkRasterClip(const SkIRect& bounds) : fBW(bounds) {
|
||||
fIsBW = true;
|
||||
fIsEmpty = this->computeIsEmpty(); // bounds might be empty, so compute
|
||||
fIsRect = !fIsEmpty;
|
||||
SkDEBUGCODE(this->validate();)
|
||||
}
|
||||
|
||||
SkRasterClip::SkRasterClip(bool forceConservativeRects) {
|
||||
fForceConservativeRects = forceConservativeRects;
|
||||
SkRasterClip::SkRasterClip() {
|
||||
fIsBW = true;
|
||||
fIsEmpty = true;
|
||||
fIsRect = false;
|
||||
@ -54,8 +166,6 @@ SkRasterClip::~SkRasterClip() {
|
||||
}
|
||||
|
||||
bool SkRasterClip::operator==(const SkRasterClip& other) const {
|
||||
// This impl doesn't care if fForceConservativeRects is the same in both, only the current state
|
||||
|
||||
if (fIsBW != other.fIsBW) {
|
||||
return false;
|
||||
}
|
||||
@ -114,65 +224,9 @@ bool SkRasterClip::setConservativeRect(const SkRect& r, const SkIRect& clipR, bo
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum MutateResult {
|
||||
kDoNothing_MutateResult,
|
||||
kReplaceClippedAgainstGlobalBounds_MutateResult,
|
||||
kContinue_MutateResult,
|
||||
};
|
||||
|
||||
static MutateResult mutate_conservative_op(SkRegion::Op* op, bool inverseFilled) {
|
||||
if (inverseFilled) {
|
||||
switch (*op) {
|
||||
case SkRegion::kIntersect_Op:
|
||||
case SkRegion::kDifference_Op:
|
||||
// These ops can only shrink the current clip. So leaving
|
||||
// the clip unchanged conservatively respects the contract.
|
||||
return kDoNothing_MutateResult;
|
||||
case SkRegion::kUnion_Op:
|
||||
case SkRegion::kReplace_Op:
|
||||
case SkRegion::kReverseDifference_Op:
|
||||
case SkRegion::kXOR_Op: {
|
||||
// These ops can grow the current clip up to the extents of
|
||||
// the input clip, which is inverse filled, so we just set
|
||||
// the current clip to the device bounds.
|
||||
*op = SkRegion::kReplace_Op;
|
||||
return kReplaceClippedAgainstGlobalBounds_MutateResult;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Not inverse filled
|
||||
switch (*op) {
|
||||
case SkRegion::kIntersect_Op:
|
||||
case SkRegion::kUnion_Op:
|
||||
case SkRegion::kReplace_Op:
|
||||
return kContinue_MutateResult;
|
||||
case SkRegion::kDifference_Op:
|
||||
// Difference can only shrink the current clip.
|
||||
// Leaving clip unchanged conservatively fullfills the contract.
|
||||
return kDoNothing_MutateResult;
|
||||
case SkRegion::kReverseDifference_Op:
|
||||
// To reverse, we swap in the bounds with a replace op.
|
||||
// As with difference, leave it unchanged.
|
||||
*op = SkRegion::kReplace_Op;
|
||||
return kContinue_MutateResult;
|
||||
case SkRegion::kXOR_Op:
|
||||
// Be conservative, based on (A XOR B) always included in (A union B),
|
||||
// which is always included in (bounds(A) union bounds(B))
|
||||
*op = SkRegion::kUnion_Op;
|
||||
return kContinue_MutateResult;
|
||||
}
|
||||
}
|
||||
SkFAIL("should not get here");
|
||||
return kDoNothing_MutateResult;
|
||||
}
|
||||
|
||||
bool SkRasterClip::setPath(const SkPath& path, const SkRegion& clip, bool doAA) {
|
||||
AUTO_RASTERCLIP_VALIDATE(*this);
|
||||
|
||||
if (fForceConservativeRects) {
|
||||
return this->setConservativeRect(path.getBounds(), clip.getBounds(), path.isInverseFillType());
|
||||
}
|
||||
|
||||
if (this->isBW() && !doAA) {
|
||||
(void)fBW.setPath(path, clip);
|
||||
} else {
|
||||
@ -190,9 +244,6 @@ bool SkRasterClip::op(const SkRRect& rrect, const SkMatrix& matrix, const SkIRec
|
||||
SkRegion::Op op, bool doAA) {
|
||||
SkIRect bounds(devBounds);
|
||||
this->applyClipRestriction(op, &bounds);
|
||||
if (fForceConservativeRects) {
|
||||
return this->op(rrect.getBounds(), matrix, bounds, op, doAA);
|
||||
}
|
||||
|
||||
SkPath path;
|
||||
path.addRRect(rrect);
|
||||
@ -206,24 +257,6 @@ bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect&
|
||||
SkIRect bounds(devBounds);
|
||||
this->applyClipRestriction(op, &bounds);
|
||||
|
||||
if (fForceConservativeRects) {
|
||||
SkIRect ir;
|
||||
switch (mutate_conservative_op(&op, path.isInverseFillType())) {
|
||||
case kDoNothing_MutateResult:
|
||||
return !this->isEmpty();
|
||||
case kReplaceClippedAgainstGlobalBounds_MutateResult:
|
||||
ir = bounds;
|
||||
break;
|
||||
case kContinue_MutateResult: {
|
||||
SkRect bounds = path.getBounds();
|
||||
matrix.mapRect(&bounds);
|
||||
ir = bounds.roundOut();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this->op(ir, op);
|
||||
}
|
||||
|
||||
// base is used to limit the size (and therefore memory allocation) of the
|
||||
// region that results from scan converting devPath.
|
||||
SkRegion base;
|
||||
@ -246,7 +279,7 @@ bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect&
|
||||
return this->setPath(devPath, this->bwRgn(), doAA);
|
||||
} else {
|
||||
base.setRect(this->getBounds());
|
||||
SkRasterClip clip(fForceConservativeRects);
|
||||
SkRasterClip clip;
|
||||
clip.setPath(devPath, base, doAA);
|
||||
return this->op(clip, op);
|
||||
}
|
||||
@ -256,7 +289,7 @@ bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect&
|
||||
if (SkRegion::kReplace_Op == op) {
|
||||
return this->setPath(devPath, base, doAA);
|
||||
} else {
|
||||
SkRasterClip clip(fForceConservativeRects);
|
||||
SkRasterClip clip;
|
||||
clip.setPath(devPath, base, doAA);
|
||||
return this->op(clip, op);
|
||||
}
|
||||
@ -331,23 +364,6 @@ bool SkRasterClip::op(const SkRect& localRect, const SkMatrix& matrix, const SkI
|
||||
AUTO_RASTERCLIP_VALIDATE(*this);
|
||||
SkRect devRect;
|
||||
|
||||
if (fForceConservativeRects) {
|
||||
SkIRect bounds(devBounds);
|
||||
this->applyClipRestriction(op, &bounds);
|
||||
SkIRect ir;
|
||||
switch (mutate_conservative_op(&op, false)) {
|
||||
case kDoNothing_MutateResult:
|
||||
return !this->isEmpty();
|
||||
case kReplaceClippedAgainstGlobalBounds_MutateResult:
|
||||
ir = bounds;
|
||||
break;
|
||||
case kContinue_MutateResult:
|
||||
matrix.mapRect(&devRect, localRect);
|
||||
ir = devRect.roundOut();
|
||||
break;
|
||||
}
|
||||
return this->op(ir, op);
|
||||
}
|
||||
const bool isScaleTrans = matrix.isScaleTranslate();
|
||||
if (!isScaleTrans) {
|
||||
SkPath path;
|
||||
@ -427,8 +443,6 @@ const SkRegion& SkRasterClip::forceGetBW() {
|
||||
void SkRasterClip::convertToAA() {
|
||||
AUTO_RASTERCLIP_VALIDATE(*this);
|
||||
|
||||
SkASSERT(!fForceConservativeRects);
|
||||
|
||||
SkASSERT(fIsBW);
|
||||
fAA.setRegion(fBW);
|
||||
fIsBW = false;
|
||||
|
@ -13,6 +13,39 @@
|
||||
|
||||
class SkRRect;
|
||||
|
||||
class SkConservativeClip {
|
||||
SkIRect fBounds;
|
||||
const SkIRect* fClipRestrictionRect;
|
||||
|
||||
inline void applyClipRestriction(SkRegion::Op op, SkIRect* bounds) {
|
||||
if (op >= SkRegion::kUnion_Op && fClipRestrictionRect
|
||||
&& !fClipRestrictionRect->isEmpty()) {
|
||||
if (!bounds->intersect(*fClipRestrictionRect)) {
|
||||
bounds->setEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
SkConservativeClip() : fBounds(SkIRect::MakeEmpty()), fClipRestrictionRect(nullptr) {}
|
||||
|
||||
bool isEmpty() const { return fBounds.isEmpty(); }
|
||||
bool isRect() const { return true; }
|
||||
const SkIRect& getBounds() const { return fBounds; }
|
||||
|
||||
void setEmpty() { fBounds.setEmpty(); }
|
||||
void setRect(const SkIRect& r) { fBounds = r; }
|
||||
void setDeviceClipRestriction(const SkIRect* rect) {
|
||||
fClipRestrictionRect = rect;
|
||||
}
|
||||
|
||||
void op(const SkRect&, const SkMatrix&, const SkIRect& limit, SkRegion::Op, bool isAA);
|
||||
void op(const SkRRect&, const SkMatrix&, const SkIRect& limit, SkRegion::Op, bool isAA);
|
||||
void op(const SkPath&, const SkMatrix&, const SkIRect& limit, SkRegion::Op, bool isAA);
|
||||
void op(const SkRegion&, SkRegion::Op);
|
||||
void op(const SkIRect&, SkRegion::Op);
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps a SkRegion and SkAAClip, so we have a single object that can represent either our
|
||||
* BW or antialiased clips.
|
||||
@ -24,8 +57,8 @@ class SkRRect;
|
||||
*/
|
||||
class SkRasterClip {
|
||||
public:
|
||||
SkRasterClip(bool forceConservativeRects = false);
|
||||
SkRasterClip(const SkIRect&, bool forceConservativeRects = false);
|
||||
SkRasterClip();
|
||||
SkRasterClip(const SkIRect&);
|
||||
SkRasterClip(const SkRegion&);
|
||||
SkRasterClip(const SkRasterClip&);
|
||||
~SkRasterClip();
|
||||
@ -37,8 +70,6 @@ public:
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool isForceConservativeRects() const { return fForceConservativeRects; }
|
||||
|
||||
bool isBW() const { return fIsBW; }
|
||||
bool isAA() const { return !fIsBW; }
|
||||
const SkRegion& bwRgn() const { SkASSERT(fIsBW); return fBW; }
|
||||
@ -101,7 +132,6 @@ public:
|
||||
private:
|
||||
SkRegion fBW;
|
||||
SkAAClip fAA;
|
||||
bool fForceConservativeRects;
|
||||
bool fIsBW;
|
||||
// these 2 are caches based on querying the right obj based on fIsBW
|
||||
bool fIsEmpty;
|
||||
|
@ -73,8 +73,12 @@ public:
|
||||
}
|
||||
|
||||
void setNewSize(int w, int h) {
|
||||
SkASSERT(fStack.count() == 1);
|
||||
fRootBounds.setXYWH(0, 0, w, h);
|
||||
|
||||
SkASSERT(fStack.count() == 1);
|
||||
Rec& rec = fStack.top();
|
||||
SkASSERT(rec.fDeferredCount == 0);
|
||||
rec.fRC.setRect(fRootBounds);
|
||||
}
|
||||
|
||||
const SkRasterClip& rc() const { return fStack.top().fRC; }
|
||||
|
@ -547,10 +547,10 @@ void GrRenderTargetOpList::forwardCombine() {
|
||||
if (j == i +1) {
|
||||
// We assume op would have combined with candidate when the candidate was added
|
||||
// via backwards combining in recordOp.
|
||||
#ifndef SK_USE_DEVICE_CLIPPING
|
||||
|
||||
// not sure why this fires with device-clipping in gm/complexclip4.cpp
|
||||
SkASSERT(!op->combineIfPossible(candidate.fOp.get(), *this->caps()));
|
||||
#endif
|
||||
// SkASSERT(!op->combineIfPossible(candidate.fOp.get(), *this->caps()));
|
||||
|
||||
} else if (op->combineIfPossible(candidate.fOp.get(), *this->caps())) {
|
||||
GrOP_INFO("\t\tCombining with (%s, B%u)\n", candidate.fOp->name(),
|
||||
candidate.fOp->uniqueID());
|
||||
|
@ -58,13 +58,13 @@
|
||||
|
||||
#if 0
|
||||
extern bool (*gShouldDrawProc)();
|
||||
#define CHECK_SHOULD_DRAW(draw) \
|
||||
#define CHECK_SHOULD_DRAW() \
|
||||
do { \
|
||||
if (gShouldDrawProc && !gShouldDrawProc()) return; \
|
||||
this->prepareDraw(draw); \
|
||||
this->prepareDraw(); \
|
||||
} while (0)
|
||||
#else
|
||||
#define CHECK_SHOULD_DRAW(draw) this->prepareDraw(draw)
|
||||
#define CHECK_SHOULD_DRAW() this->prepareDraw()
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -174,17 +174,16 @@ sk_sp<GrRenderTargetContext> SkGpuDevice::MakeRenderTargetContext(
|
||||
origin, surfaceProps, budgeted);
|
||||
}
|
||||
|
||||
sk_sp<SkSpecialImage> SkGpuDevice::filterTexture(const SkDraw& draw,
|
||||
SkSpecialImage* srcImg,
|
||||
sk_sp<SkSpecialImage> SkGpuDevice::filterTexture(SkSpecialImage* srcImg,
|
||||
int left, int top,
|
||||
SkIPoint* offset,
|
||||
const SkImageFilter* filter) {
|
||||
SkASSERT(srcImg->isTextureBacked());
|
||||
SkASSERT(filter);
|
||||
|
||||
SkMatrix matrix = *draw.fMatrix;
|
||||
SkMatrix matrix = this->ctm();
|
||||
matrix.postTranslate(SkIntToScalar(-left), SkIntToScalar(-top));
|
||||
const SkIRect clipBounds = this->devClipBounds(draw).makeOffset(-left, -top);
|
||||
const SkIRect clipBounds = this->devClipBounds().makeOffset(-left, -top);
|
||||
sk_sp<SkImageFilterCache> cache(this->getImageFilterCache());
|
||||
SkImageFilter::OutputProperties outputProperties(fRenderTargetContext->getColorSpace());
|
||||
SkImageFilter::Context ctx(matrix, clipBounds, cache.get(), outputProperties);
|
||||
@ -233,15 +232,10 @@ bool SkGpuDevice::onAccessPixels(SkPixmap* pmap) {
|
||||
|
||||
// call this every draw call, to ensure that the context reflects our state,
|
||||
// and not the state from some other canvas/device
|
||||
void SkGpuDevice::prepareDraw(const SkDraw& draw) {
|
||||
void SkGpuDevice::prepareDraw() {
|
||||
ASSERT_SINGLE_OWNER
|
||||
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
SkASSERT(*draw.fMatrix == this->ctm());
|
||||
fClip.reset(&this->cs(), nullptr);
|
||||
#else
|
||||
fClip.reset(draw.fClipStack, &this->getOrigin());
|
||||
#endif
|
||||
}
|
||||
|
||||
GrRenderTargetContext* SkGpuDevice::accessRenderTargetContext() {
|
||||
@ -285,18 +279,18 @@ void SkGpuDevice::replaceRenderTargetContext(bool shouldRetainContent) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
|
||||
void SkGpuDevice::drawPaint(const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPaint", fContext.get());
|
||||
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fRenderTargetContext->drawPaint(fClip, std::move(grPaint), *draw.fMatrix);
|
||||
fRenderTargetContext->drawPaint(fClip, std::move(grPaint), this->ctm());
|
||||
}
|
||||
|
||||
// must be in SkCanvas::PointMode order
|
||||
@ -333,11 +327,11 @@ static bool needs_antialiasing(SkCanvas::PointMode mode, size_t count, const SkP
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
|
||||
void SkGpuDevice::drawPoints(SkCanvas::PointMode mode,
|
||||
size_t count, const SkPoint pts[], const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPoints", fContext.get());
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
|
||||
SkScalar width = paint.getStrokeWidth();
|
||||
if (width < 0) {
|
||||
@ -347,7 +341,7 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
|
||||
if (paint.getPathEffect() && 2 == count && SkCanvas::kLines_PointMode == mode) {
|
||||
GrStyle style(paint, SkPaint::kStroke_Style);
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
@ -356,25 +350,31 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
|
||||
path.moveTo(pts[0]);
|
||||
path.lineTo(pts[1]);
|
||||
fRenderTargetContext->drawPath(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
|
||||
*draw.fMatrix, path, style);
|
||||
this->ctm(), path, style);
|
||||
return;
|
||||
}
|
||||
|
||||
SkScalar scales[2];
|
||||
bool isHairline = (0 == width) || (1 == width && draw.fMatrix->getMinMaxScales(scales) &&
|
||||
bool isHairline = (0 == width) || (1 == width && this->ctm().getMinMaxScales(scales) &&
|
||||
SkScalarNearlyEqual(scales[0], 1.f) &&
|
||||
SkScalarNearlyEqual(scales[1], 1.f));
|
||||
// we only handle non-antialiased hairlines and paints without path effects or mask filters,
|
||||
// else we let the SkDraw call our drawPath()
|
||||
if (!isHairline || paint.getPathEffect() || paint.getMaskFilter() ||
|
||||
(paint.isAntiAlias() && needs_antialiasing(mode, count, pts, *draw.fMatrix))) {
|
||||
(paint.isAntiAlias() && needs_antialiasing(mode, count, pts, this->ctm())))
|
||||
{
|
||||
SkRasterClip rc(this->devClipBounds());
|
||||
SkDraw draw;
|
||||
draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(this->width(), this->height()), nullptr, 0);
|
||||
draw.fMatrix = &this->ctm();
|
||||
draw.fRC = &rc;
|
||||
draw.drawPoints(mode, count, pts, paint, this);
|
||||
return;
|
||||
}
|
||||
|
||||
GrPrimitiveType primitiveType = gPointMode2PrimitiveType[mode];
|
||||
|
||||
const SkMatrix* viewMatrix = draw.fMatrix;
|
||||
const SkMatrix* viewMatrix = &this->ctm();
|
||||
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
|
||||
// This offsetting in device space matches the expectations of the Android framework for non-AA
|
||||
// points and lines.
|
||||
@ -407,10 +407,10 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, const SkPaint& paint) {
|
||||
void SkGpuDevice::drawRect(const SkRect& rect, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawRect", fContext.get());
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
|
||||
|
||||
// A couple reasons we might need to call drawPath.
|
||||
@ -420,37 +420,37 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, const SkPaint
|
||||
path.addRect(rect);
|
||||
GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
|
||||
fClip, path, paint,
|
||||
*draw.fMatrix, nullptr,
|
||||
this->devClipBounds(draw), true);
|
||||
this->ctm(), nullptr,
|
||||
this->devClipBounds(), true);
|
||||
return;
|
||||
}
|
||||
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
GrStyle style(paint);
|
||||
fRenderTargetContext->drawRect(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
|
||||
*draw.fMatrix, rect, &style);
|
||||
this->ctm(), rect, &style);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPaint& paint) {
|
||||
void SkGpuDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawRRect", fContext.get());
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SkMaskFilter* mf = paint.getMaskFilter();
|
||||
if (mf && mf->asFragmentProcessor(nullptr, nullptr, *draw.fMatrix)) {
|
||||
if (mf && mf->asFragmentProcessor(nullptr, nullptr, this->ctm())) {
|
||||
mf = nullptr; // already handled in SkPaintToGrPaint
|
||||
}
|
||||
|
||||
@ -459,19 +459,19 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPa
|
||||
// try to hit the fast path for drawing filtered round rects
|
||||
|
||||
SkRRect devRRect;
|
||||
if (rrect.transform(*draw.fMatrix, &devRRect)) {
|
||||
if (rrect.transform(this->ctm(), &devRRect)) {
|
||||
if (devRRect.allCornersCircular()) {
|
||||
SkRect maskRect;
|
||||
if (mf->canFilterMaskGPU(devRRect, this->devClipBounds(draw),
|
||||
*draw.fMatrix, &maskRect)) {
|
||||
if (mf->canFilterMaskGPU(devRRect, this->devClipBounds(),
|
||||
this->ctm(), &maskRect)) {
|
||||
SkIRect finalIRect;
|
||||
maskRect.roundOut(&finalIRect);
|
||||
if (draw.fRC->quickReject(finalIRect)) {
|
||||
// clipped out
|
||||
return;
|
||||
}
|
||||
|
||||
// we used to test finalIRect for quickReject, but that seems unlikely
|
||||
// given that the original shape was not rejected...
|
||||
|
||||
if (mf->directFilterRRectMaskGPU(fContext.get(), fRenderTargetContext.get(),
|
||||
std::move(grPaint), fClip, *draw.fMatrix,
|
||||
std::move(grPaint), fClip, this->ctm(),
|
||||
style.strokeRec(), rrect, devRRect)) {
|
||||
return;
|
||||
}
|
||||
@ -490,43 +490,43 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPa
|
||||
path.addRRect(rrect);
|
||||
GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
|
||||
fClip, path, paint,
|
||||
*draw.fMatrix, nullptr,
|
||||
this->devClipBounds(draw), true);
|
||||
this->ctm(), nullptr,
|
||||
this->devClipBounds(), true);
|
||||
return;
|
||||
}
|
||||
|
||||
SkASSERT(!style.pathEffect());
|
||||
|
||||
fRenderTargetContext->drawRRect(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
|
||||
*draw.fMatrix, rrect, style);
|
||||
this->ctm(), rrect, style);
|
||||
}
|
||||
|
||||
|
||||
void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
|
||||
void SkGpuDevice::drawDRRect(const SkRRect& outer,
|
||||
const SkRRect& inner, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawDRRect", fContext.get());
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
|
||||
if (outer.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (inner.isEmpty()) {
|
||||
return this->drawRRect(draw, outer, paint);
|
||||
return this->drawRRect(outer, paint);
|
||||
}
|
||||
|
||||
SkStrokeRec stroke(paint);
|
||||
|
||||
if (stroke.isFillStyle() && !paint.getMaskFilter() && !paint.getPathEffect()) {
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fRenderTargetContext->drawDRRect(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
|
||||
*draw.fMatrix, outer, inner);
|
||||
this->ctm(), outer, inner);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -538,78 +538,78 @@ void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
|
||||
|
||||
GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
|
||||
fClip, path, paint,
|
||||
*draw.fMatrix, nullptr,
|
||||
this->devClipBounds(draw), true);
|
||||
this->ctm(), nullptr,
|
||||
this->devClipBounds(), true);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkGpuDevice::drawRegion(const SkDraw& draw, const SkRegion& region, const SkPaint& paint) {
|
||||
void SkGpuDevice::drawRegion(const SkRegion& region, const SkPaint& paint) {
|
||||
if (paint.getMaskFilter()) {
|
||||
SkPath path;
|
||||
region.getBoundaryPath(&path);
|
||||
return this->drawPath(draw, path, paint, nullptr, false);
|
||||
return this->drawPath(path, paint, nullptr, false);
|
||||
}
|
||||
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fRenderTargetContext->drawRegion(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
|
||||
*draw.fMatrix, region, GrStyle(paint));
|
||||
this->ctm(), region, GrStyle(paint));
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
|
||||
void SkGpuDevice::drawOval(const SkRect& oval, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawOval", fContext.get());
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
|
||||
// Presumably the path effect warps this to something other than an oval
|
||||
if (paint.getPathEffect()) {
|
||||
SkPath path;
|
||||
path.setIsVolatile(true);
|
||||
path.addOval(oval);
|
||||
this->drawPath(draw, path, paint, nullptr, true);
|
||||
this->drawPath(path, paint, nullptr, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (paint.getMaskFilter()) {
|
||||
// The RRect path can handle special case blurring
|
||||
SkRRect rr = SkRRect::MakeOval(oval);
|
||||
return this->drawRRect(draw, rr, paint);
|
||||
return this->drawRRect(rr, paint);
|
||||
}
|
||||
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fRenderTargetContext->drawOval(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
|
||||
*draw.fMatrix, oval, GrStyle(paint));
|
||||
this->ctm(), oval, GrStyle(paint));
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawArc(const SkDraw& draw, const SkRect& oval, SkScalar startAngle,
|
||||
void SkGpuDevice::drawArc(const SkRect& oval, SkScalar startAngle,
|
||||
SkScalar sweepAngle, bool useCenter, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawArc", fContext.get());
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
|
||||
if (paint.getMaskFilter()) {
|
||||
this->INHERITED::drawArc(draw, oval, startAngle, sweepAngle, useCenter, paint);
|
||||
this->INHERITED::drawArc(oval, startAngle, sweepAngle, useCenter, paint);
|
||||
return;
|
||||
}
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fRenderTargetContext->drawArc(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
|
||||
*draw.fMatrix, oval, startAngle, sweepAngle, useCenter,
|
||||
this->ctm(), oval, startAngle, sweepAngle, useCenter,
|
||||
GrStyle(paint));
|
||||
}
|
||||
|
||||
@ -617,11 +617,10 @@ void SkGpuDevice::drawArc(const SkDraw& draw, const SkRect& oval, SkScalar start
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void SkGpuDevice::drawStrokedLine(const SkPoint points[2],
|
||||
const SkDraw& draw,
|
||||
const SkPaint& origPaint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawStrokedLine", fContext.get());
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
|
||||
// Adding support for round capping would require a
|
||||
// GrRenderTargetContext::fillRRectWithLocalMatrix entry point
|
||||
@ -659,7 +658,7 @@ void SkGpuDevice::drawStrokedLine(const SkPoint points[2],
|
||||
|
||||
SkMatrix local = m;
|
||||
|
||||
m.postConcat(*draw.fMatrix);
|
||||
m.postConcat(this->ctm());
|
||||
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), newPaint, m, &grPaint)) {
|
||||
@ -670,7 +669,7 @@ void SkGpuDevice::drawStrokedLine(const SkPoint points[2],
|
||||
fClip, std::move(grPaint), GrBoolToAA(newPaint.isAntiAlias()), m, rect, local);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
|
||||
void SkGpuDevice::drawPath(const SkPath& origSrcPath,
|
||||
const SkPaint& paint, const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
@ -678,40 +677,40 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
|
||||
SkPoint points[2];
|
||||
if (SkPaint::kStroke_Style == paint.getStyle() && paint.getStrokeWidth() > 0 &&
|
||||
!paint.getMaskFilter() && SkPaint::kRound_Cap != paint.getStrokeCap() &&
|
||||
draw.fMatrix->preservesRightAngles() && origSrcPath.isLine(points)) {
|
||||
this->ctm().preservesRightAngles() && origSrcPath.isLine(points)) {
|
||||
// Path-based stroking looks better for thin rects
|
||||
SkScalar strokeWidth = draw.fMatrix->getMaxScale() * paint.getStrokeWidth();
|
||||
SkScalar strokeWidth = this->ctm().getMaxScale() * paint.getStrokeWidth();
|
||||
if (strokeWidth >= 1.0f) {
|
||||
// Round capping support is currently disabled b.c. it would require a RRect
|
||||
// GrDrawOp that takes a localMatrix.
|
||||
this->drawStrokedLine(points, draw, paint);
|
||||
this->drawStrokedLine(points, paint);
|
||||
return;
|
||||
}
|
||||
}
|
||||
bool isClosed;
|
||||
SkRect rect;
|
||||
if (origSrcPath.isRect(&rect, &isClosed) && isClosed) {
|
||||
this->drawRect(draw, rect, paint);
|
||||
this->drawRect(rect, paint);
|
||||
return;
|
||||
}
|
||||
if (origSrcPath.isOval(&rect)) {
|
||||
this->drawOval(draw, rect, paint);
|
||||
this->drawOval(rect, paint);
|
||||
return;
|
||||
}
|
||||
SkRRect rrect;
|
||||
if (origSrcPath.isRRect(&rrect)) {
|
||||
this->drawRRect(draw, rrect, paint);
|
||||
this->drawRRect(rrect, paint);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPath", fContext.get());
|
||||
|
||||
GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
|
||||
fClip, origSrcPath, paint,
|
||||
*draw.fMatrix, prePathMatrix,
|
||||
this->devClipBounds(draw), pathIsMutable);
|
||||
this->ctm(), prePathMatrix,
|
||||
this->devClipBounds(), pathIsMutable);
|
||||
}
|
||||
|
||||
static const int kBmpSmallTileSize = 1 << 10;
|
||||
@ -857,14 +856,13 @@ bool SkGpuDevice::shouldTileImage(const SkImage* image, const SkRect* srcRectPtr
|
||||
&outClippedSrcRect);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawBitmap(const SkDraw& origDraw,
|
||||
const SkBitmap& bitmap,
|
||||
void SkGpuDevice::drawBitmap(const SkBitmap& bitmap,
|
||||
const SkMatrix& m,
|
||||
const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW(origDraw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
SkMatrix viewMatrix;
|
||||
viewMatrix.setConcat(*origDraw.fMatrix, m);
|
||||
viewMatrix.setConcat(this->ctm(), m);
|
||||
|
||||
int maxTileSize = fContext->caps()->maxTileSize();
|
||||
|
||||
@ -1121,10 +1119,10 @@ void SkGpuDevice::drawBitmapTile(const SkBitmap& bitmap,
|
||||
fRenderTargetContext->drawRect(fClip, std::move(grPaint), aa, viewMatrix, dstRect);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
void SkGpuDevice::drawSprite(const SkBitmap& bitmap,
|
||||
int left, int top, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawSprite", fContext.get());
|
||||
|
||||
if (fContext->abandoned()) {
|
||||
@ -1136,23 +1134,22 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
return;
|
||||
}
|
||||
|
||||
this->drawSpecial(draw, srcImg.get(), left, top, paint);
|
||||
this->drawSpecial(srcImg.get(), left, top, paint);
|
||||
}
|
||||
|
||||
|
||||
void SkGpuDevice::drawSpecial(const SkDraw& draw,
|
||||
SkSpecialImage* special1,
|
||||
void SkGpuDevice::drawSpecial(SkSpecialImage* special1,
|
||||
int left, int top,
|
||||
const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawSpecial", fContext.get());
|
||||
|
||||
SkIPoint offset = { 0, 0 };
|
||||
|
||||
sk_sp<SkSpecialImage> result;
|
||||
if (paint.getImageFilter()) {
|
||||
result = this->filterTexture(draw, special1, left, top,
|
||||
result = this->filterTexture(special1, left, top,
|
||||
&offset,
|
||||
paint.getImageFilter());
|
||||
if (!result) {
|
||||
@ -1204,11 +1201,11 @@ void SkGpuDevice::drawSpecial(const SkDraw& draw,
|
||||
SkRect::Make(subset));
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
void SkGpuDevice::drawBitmapRect(const SkBitmap& bitmap,
|
||||
const SkRect* src, const SkRect& origDst,
|
||||
const SkPaint& paint, SkCanvas::SrcRectConstraint constraint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
|
||||
// The src rect is inferred to be the bmp bounds if not provided. Otherwise, the src rect must
|
||||
// be clipped to the bmp bounds. To determine tiling parameters we need the filter mode which
|
||||
@ -1256,7 +1253,7 @@ void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
GrSamplerParams params;
|
||||
bool doBicubic;
|
||||
GrSamplerParams::FilterMode textureFilterMode =
|
||||
GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), *draw.fMatrix, srcToDstMatrix,
|
||||
GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), this->ctm(), srcToDstMatrix,
|
||||
&doBicubic);
|
||||
|
||||
int tileFilterPad;
|
||||
@ -1271,16 +1268,16 @@ void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
params.setFilterMode(textureFilterMode);
|
||||
|
||||
int maxTileSizeForFilter = fContext->caps()->maxTileSize() - 2 * tileFilterPad;
|
||||
if (this->shouldTileImageID(bitmap.getGenerationID(), bitmap.getSubset(), *draw.fMatrix,
|
||||
if (this->shouldTileImageID(bitmap.getGenerationID(), bitmap.getSubset(), this->ctm(),
|
||||
srcToDstMatrix, params, src, maxTileSizeForFilter, &tileSize,
|
||||
&clippedSrcRect)) {
|
||||
this->drawTiledBitmap(bitmap, *draw.fMatrix, srcToDstMatrix, *src, clippedSrcRect,
|
||||
this->drawTiledBitmap(bitmap, this->ctm(), srcToDstMatrix, *src, clippedSrcRect,
|
||||
params, paint, constraint, tileSize, doBicubic);
|
||||
return;
|
||||
}
|
||||
}
|
||||
GrBitmapTextureMaker maker(fContext.get(), bitmap);
|
||||
this->drawTextureProducer(&maker, src, dst, constraint, *draw.fMatrix, fClip, paint);
|
||||
this->drawTextureProducer(&maker, src, dst, constraint, this->ctm(), fClip, paint);
|
||||
}
|
||||
|
||||
sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkBitmap& bitmap) {
|
||||
@ -1349,7 +1346,7 @@ sk_sp<SkSpecialImage> SkGpuDevice::snapSpecial() {
|
||||
&this->surfaceProps());
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
|
||||
void SkGpuDevice::drawDevice(SkBaseDevice* device,
|
||||
int left, int top, const SkPaint& paint) {
|
||||
SkASSERT(!paint.getImageFilter());
|
||||
|
||||
@ -1358,7 +1355,7 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawDevice", fContext.get());
|
||||
|
||||
// drawDevice is defined to be in device coords.
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
|
||||
SkGpuDevice* dev = static_cast<SkGpuDevice*>(device);
|
||||
sk_sp<SkSpecialImage> srcImg(dev->snapSpecial());
|
||||
@ -1366,17 +1363,17 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
|
||||
return;
|
||||
}
|
||||
|
||||
this->drawSpecial(draw, srcImg.get(), left, top, paint);
|
||||
this->drawSpecial(srcImg.get(), left, top, paint);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x, SkScalar y,
|
||||
void SkGpuDevice::drawImage(const SkImage* image, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
SkMatrix viewMatrix = *draw.fMatrix;
|
||||
SkMatrix viewMatrix = this->ctm();
|
||||
viewMatrix.preTranslate(x, y);
|
||||
uint32_t pinnedUniqueID;
|
||||
if (sk_sp<GrTexture> tex = as_IB(image)->refPinnedTexture(&pinnedUniqueID)) {
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
GrTextureAdjuster adjuster(tex.get(), image->alphaType(), image->bounds(), pinnedUniqueID,
|
||||
as_IB(image)->onImageInfo().colorSpace());
|
||||
this->drawTextureProducer(&adjuster, nullptr, nullptr, SkCanvas::kFast_SrcRectConstraint,
|
||||
@ -1385,66 +1382,66 @@ void SkGpuDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x
|
||||
} else {
|
||||
SkBitmap bm;
|
||||
if (this->shouldTileImage(image, nullptr, SkCanvas::kFast_SrcRectConstraint,
|
||||
paint.getFilterQuality(), *draw.fMatrix, SkMatrix::I())) {
|
||||
paint.getFilterQuality(), this->ctm(), SkMatrix::I())) {
|
||||
// only support tiling as bitmap at the moment, so force raster-version
|
||||
if (!as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
|
||||
return;
|
||||
}
|
||||
this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
|
||||
this->drawBitmap(bm, SkMatrix::MakeTrans(x, y), paint);
|
||||
} else if (SkImageCacherator* cacher = as_IB(image)->peekCacherator()) {
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
GrImageTextureMaker maker(fContext.get(), cacher, image, SkImage::kAllow_CachingHint);
|
||||
this->drawTextureProducer(&maker, nullptr, nullptr, SkCanvas::kFast_SrcRectConstraint,
|
||||
viewMatrix, fClip, paint);
|
||||
} else if (as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
|
||||
this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
|
||||
this->drawBitmap(bm, SkMatrix::MakeTrans(x, y), paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src,
|
||||
void SkGpuDevice::drawImageRect(const SkImage* image, const SkRect* src,
|
||||
const SkRect& dst, const SkPaint& paint,
|
||||
SkCanvas::SrcRectConstraint constraint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
uint32_t pinnedUniqueID;
|
||||
if (sk_sp<GrTexture> tex = as_IB(image)->refPinnedTexture(&pinnedUniqueID)) {
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
GrTextureAdjuster adjuster(tex.get(), image->alphaType(), image->bounds(), pinnedUniqueID,
|
||||
as_IB(image)->onImageInfo().colorSpace());
|
||||
this->drawTextureProducer(&adjuster, src, &dst, constraint, *draw.fMatrix, fClip, paint);
|
||||
this->drawTextureProducer(&adjuster, src, &dst, constraint, this->ctm(), fClip, paint);
|
||||
return;
|
||||
}
|
||||
SkBitmap bm;
|
||||
SkMatrix srcToDstRect;
|
||||
srcToDstRect.setRectToRect((src ? *src : SkRect::MakeIWH(image->width(), image->height())),
|
||||
dst, SkMatrix::kFill_ScaleToFit);
|
||||
if (this->shouldTileImage(image, src, constraint, paint.getFilterQuality(), *draw.fMatrix,
|
||||
if (this->shouldTileImage(image, src, constraint, paint.getFilterQuality(), this->ctm(),
|
||||
srcToDstRect)) {
|
||||
// only support tiling as bitmap at the moment, so force raster-version
|
||||
if (!as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
|
||||
return;
|
||||
}
|
||||
this->drawBitmapRect(draw, bm, src, dst, paint, constraint);
|
||||
this->drawBitmapRect(bm, src, dst, paint, constraint);
|
||||
} else if (SkImageCacherator* cacher = as_IB(image)->peekCacherator()) {
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
GrImageTextureMaker maker(fContext.get(), cacher, image, SkImage::kAllow_CachingHint);
|
||||
this->drawTextureProducer(&maker, src, &dst, constraint, *draw.fMatrix, fClip, paint);
|
||||
this->drawTextureProducer(&maker, src, &dst, constraint, this->ctm(), fClip, paint);
|
||||
} else if (as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
|
||||
this->drawBitmapRect(draw, bm, src, dst, paint, constraint);
|
||||
this->drawBitmapRect(bm, src, dst, paint, constraint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawProducerNine(const SkDraw& draw, GrTextureProducer* producer,
|
||||
void SkGpuDevice::drawProducerNine(GrTextureProducer* producer,
|
||||
const SkIRect& center, const SkRect& dst, const SkPaint& paint) {
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawProducerNine", fContext.get());
|
||||
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
|
||||
bool useFallback = paint.getMaskFilter() || paint.isAntiAlias() ||
|
||||
fRenderTargetContext->isUnifiedMultisampled();
|
||||
bool doBicubic;
|
||||
GrSamplerParams::FilterMode textureFilterMode =
|
||||
GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), *draw.fMatrix, SkMatrix::I(),
|
||||
GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), this->ctm(), SkMatrix::I(),
|
||||
&doBicubic);
|
||||
if (useFallback || doBicubic || GrSamplerParams::kNone_FilterMode != textureFilterMode) {
|
||||
SkLatticeIter iter(producer->width(), producer->height(), center, dst);
|
||||
@ -1452,7 +1449,7 @@ void SkGpuDevice::drawProducerNine(const SkDraw& draw, GrTextureProducer* produc
|
||||
SkRect srcR, dstR;
|
||||
while (iter.next(&srcR, &dstR)) {
|
||||
this->drawTextureProducer(producer, &srcR, &dstR, SkCanvas::kStrict_SrcRectConstraint,
|
||||
*draw.fMatrix, fClip, paint);
|
||||
this->ctm(), fClip, paint);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1465,51 +1462,51 @@ void SkGpuDevice::drawProducerNine(const SkDraw& draw, GrTextureProducer* produc
|
||||
&kMode, fRenderTargetContext->getColorSpace()));
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaintWithTexture(this->context(), fRenderTargetContext.get(), paint,
|
||||
*draw.fMatrix, std::move(fp), producer->isAlphaOnly(),
|
||||
this->ctm(), std::move(fp), producer->isAlphaOnly(),
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<SkLatticeIter> iter(
|
||||
new SkLatticeIter(producer->width(), producer->height(), center, dst));
|
||||
fRenderTargetContext->drawImageLattice(fClip, std::move(grPaint), *draw.fMatrix,
|
||||
fRenderTargetContext->drawImageLattice(fClip, std::move(grPaint), this->ctm(),
|
||||
producer->width(), producer->height(), std::move(iter),
|
||||
dst);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawImageNine(const SkDraw& draw, const SkImage* image,
|
||||
void SkGpuDevice::drawImageNine(const SkImage* image,
|
||||
const SkIRect& center, const SkRect& dst, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
uint32_t pinnedUniqueID;
|
||||
if (sk_sp<GrTexture> tex = as_IB(image)->refPinnedTexture(&pinnedUniqueID)) {
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
GrTextureAdjuster adjuster(tex.get(), image->alphaType(), image->bounds(), pinnedUniqueID,
|
||||
as_IB(image)->onImageInfo().colorSpace());
|
||||
this->drawProducerNine(draw, &adjuster, center, dst, paint);
|
||||
this->drawProducerNine(&adjuster, center, dst, paint);
|
||||
} else {
|
||||
SkBitmap bm;
|
||||
if (SkImageCacherator* cacher = as_IB(image)->peekCacherator()) {
|
||||
GrImageTextureMaker maker(fContext.get(), cacher, image, SkImage::kAllow_CachingHint);
|
||||
this->drawProducerNine(draw, &maker, center, dst, paint);
|
||||
this->drawProducerNine(&maker, center, dst, paint);
|
||||
} else if (as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
|
||||
this->drawBitmapNine(draw, bm, center, dst, paint);
|
||||
this->drawBitmapNine(bm, center, dst, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawBitmapNine(const SkDraw& draw, const SkBitmap& bitmap, const SkIRect& center,
|
||||
void SkGpuDevice::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GrBitmapTextureMaker maker(fContext.get(), bitmap);
|
||||
this->drawProducerNine(draw, &maker, center, dst, paint);
|
||||
this->drawProducerNine(&maker, center, dst, paint);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawProducerLattice(const SkDraw& draw, GrTextureProducer* producer,
|
||||
void SkGpuDevice::drawProducerLattice(GrTextureProducer* producer,
|
||||
const SkCanvas::Lattice& lattice, const SkRect& dst,
|
||||
const SkPaint& paint) {
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawProducerLattice", fContext.get());
|
||||
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
|
||||
static const GrSamplerParams::FilterMode kMode = GrSamplerParams::kNone_FilterMode;
|
||||
sk_sp<GrFragmentProcessor> fp(
|
||||
@ -1519,45 +1516,45 @@ void SkGpuDevice::drawProducerLattice(const SkDraw& draw, GrTextureProducer* pro
|
||||
&kMode, fRenderTargetContext->getColorSpace()));
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaintWithTexture(this->context(), fRenderTargetContext.get(), paint,
|
||||
*draw.fMatrix, std::move(fp), producer->isAlphaOnly(),
|
||||
this->ctm(), std::move(fp), producer->isAlphaOnly(),
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<SkLatticeIter> iter(
|
||||
new SkLatticeIter(lattice, dst));
|
||||
fRenderTargetContext->drawImageLattice(fClip, std::move(grPaint), *draw.fMatrix,
|
||||
fRenderTargetContext->drawImageLattice(fClip, std::move(grPaint), this->ctm(),
|
||||
producer->width(), producer->height(), std::move(iter),
|
||||
dst);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawImageLattice(const SkDraw& draw, const SkImage* image,
|
||||
void SkGpuDevice::drawImageLattice(const SkImage* image,
|
||||
const SkCanvas::Lattice& lattice, const SkRect& dst,
|
||||
const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
uint32_t pinnedUniqueID;
|
||||
if (sk_sp<GrTexture> tex = as_IB(image)->refPinnedTexture(&pinnedUniqueID)) {
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
GrTextureAdjuster adjuster(tex.get(), image->alphaType(), image->bounds(), pinnedUniqueID,
|
||||
as_IB(image)->onImageInfo().colorSpace());
|
||||
this->drawProducerLattice(draw, &adjuster, lattice, dst, paint);
|
||||
this->drawProducerLattice(&adjuster, lattice, dst, paint);
|
||||
} else {
|
||||
SkBitmap bm;
|
||||
if (SkImageCacherator* cacher = as_IB(image)->peekCacherator()) {
|
||||
GrImageTextureMaker maker(fContext.get(), cacher, image, SkImage::kAllow_CachingHint);
|
||||
this->drawProducerLattice(draw, &maker, lattice, dst, paint);
|
||||
this->drawProducerLattice(&maker, lattice, dst, paint);
|
||||
} else if (as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
|
||||
this->drawBitmapLattice(draw, bm, lattice, dst, paint);
|
||||
this->drawBitmapLattice(bm, lattice, dst, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawBitmapLattice(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
void SkGpuDevice::drawBitmapLattice(const SkBitmap& bitmap,
|
||||
const SkCanvas::Lattice& lattice, const SkRect& dst,
|
||||
const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GrBitmapTextureMaker maker(fContext.get(), bitmap);
|
||||
this->drawProducerLattice(draw, &maker, lattice, dst, paint);
|
||||
this->drawProducerLattice(&maker, lattice, dst, paint);
|
||||
}
|
||||
|
||||
bool init_vertices_paint(const SkPaint& skPaint, const SkMatrix& matrix, SkBlendMode bmode,
|
||||
@ -1585,14 +1582,14 @@ bool init_vertices_paint(const SkPaint& skPaint, const SkMatrix& matrix, SkBlend
|
||||
}
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
|
||||
void SkGpuDevice::drawVertices(SkCanvas::VertexMode vmode,
|
||||
int vertexCount, const SkPoint vertices[],
|
||||
const SkPoint texs[], const SkColor colors[],
|
||||
SkBlendMode bmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawVertices", fContext.get());
|
||||
|
||||
// If both textures and vertex-colors are nullptr, strokes hairlines with the paint's color.
|
||||
@ -1642,7 +1639,7 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
|
||||
}
|
||||
fRenderTargetContext->drawVertices(fClip,
|
||||
std::move(grPaint),
|
||||
*draw.fMatrix,
|
||||
this->ctm(),
|
||||
kLines_GrPrimitiveType,
|
||||
vertexCount,
|
||||
vertices,
|
||||
@ -1656,13 +1653,13 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
|
||||
GrPrimitiveType primType = SkVertexModeToGrPrimitiveType(vmode);
|
||||
|
||||
GrPaint grPaint;
|
||||
if (!init_vertices_paint(paint, *draw.fMatrix, bmode, SkToBool(texs), SkToBool(colors),
|
||||
if (!init_vertices_paint(paint, this->ctm(), bmode, SkToBool(texs), SkToBool(colors),
|
||||
fRenderTargetContext.get(), &grPaint)) {
|
||||
return;
|
||||
}
|
||||
fRenderTargetContext->drawVertices(fClip,
|
||||
std::move(grPaint),
|
||||
*draw.fMatrix,
|
||||
this->ctm(),
|
||||
primType,
|
||||
vertexCount,
|
||||
vertices,
|
||||
@ -1673,10 +1670,10 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
|
||||
GrRenderTargetContext::ColorArrayType::kSkColor);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawVerticesObject(const SkDraw& draw, sk_sp<SkVertices> vertices,
|
||||
void SkGpuDevice::drawVerticesObject(sk_sp<SkVertices> vertices,
|
||||
SkBlendMode mode, const SkPaint& paint, uint32_t flags) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawVerticesObject", fContext.get());
|
||||
|
||||
SkASSERT(vertices);
|
||||
@ -1685,30 +1682,30 @@ void SkGpuDevice::drawVerticesObject(const SkDraw& draw, sk_sp<SkVertices> verti
|
||||
bool hasTexs = vertices->hasTexCoords() & !(SkCanvas::kIgnoreTexCoords_VerticesFlag & flags);
|
||||
if (!hasTexs && !hasColors) {
|
||||
// The dreaded wireframe mode. Fallback to drawVertices and go so slooooooow.
|
||||
this->drawVertices(draw, vertices->mode(), vertices->vertexCount(), vertices->positions(),
|
||||
this->drawVertices(vertices->mode(), vertices->vertexCount(), vertices->positions(),
|
||||
nullptr, nullptr, mode, vertices->indices(), vertices->indexCount(),
|
||||
paint);
|
||||
}
|
||||
if (!init_vertices_paint(paint, *draw.fMatrix, mode, hasTexs, hasColors,
|
||||
if (!init_vertices_paint(paint, this->ctm(), mode, hasTexs, hasColors,
|
||||
fRenderTargetContext.get(), &grPaint)) {
|
||||
return;
|
||||
}
|
||||
fRenderTargetContext->drawVertices(fClip, std::move(grPaint), *draw.fMatrix,
|
||||
fRenderTargetContext->drawVertices(fClip, std::move(grPaint), this->ctm(),
|
||||
std::move(vertices), flags);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkGpuDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkRSXform xform[],
|
||||
void SkGpuDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
|
||||
const SkRect texRect[], const SkColor colors[], int count,
|
||||
SkBlendMode mode, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
if (paint.isAntiAlias()) {
|
||||
this->INHERITED::drawAtlas(draw, atlas, xform, texRect, colors, count, mode, paint);
|
||||
this->INHERITED::drawAtlas(atlas, xform, texRect, colors, count, mode, paint);
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawText", fContext.get());
|
||||
|
||||
SkPaint p(paint);
|
||||
@ -1717,58 +1714,58 @@ void SkGpuDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkRS
|
||||
GrPaint grPaint;
|
||||
if (colors) {
|
||||
if (!SkPaintToGrPaintWithXfermode(this->context(), fRenderTargetContext.get(), p,
|
||||
*draw.fMatrix, (SkBlendMode)mode, true, &grPaint)) {
|
||||
this->ctm(), (SkBlendMode)mode, true, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), p, *draw.fMatrix,
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), p, this->ctm(),
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SkDEBUGCODE(this->validate();)
|
||||
fRenderTargetContext->drawAtlas(fClip, std::move(grPaint), *draw.fMatrix, count, xform, texRect,
|
||||
fRenderTargetContext->drawAtlas(fClip, std::move(grPaint), this->ctm(), count, xform, texRect,
|
||||
colors);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
|
||||
void SkGpuDevice::drawText(const void* text,
|
||||
size_t byteLength, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawText", fContext.get());
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
fRenderTargetContext->drawText(fClip, paint, *draw.fMatrix,
|
||||
(const char*)text, byteLength, x, y, this->devClipBounds(draw));
|
||||
fRenderTargetContext->drawText(fClip, paint, this->ctm(),
|
||||
(const char*)text, byteLength, x, y, this->devClipBounds());
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteLength,
|
||||
void SkGpuDevice::drawPosText(const void* text, size_t byteLength,
|
||||
const SkScalar pos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPosText", fContext.get());
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
fRenderTargetContext->drawPosText(fClip, paint, *draw.fMatrix,
|
||||
fRenderTargetContext->drawPosText(fClip, paint, this->ctm(),
|
||||
(const char*)text, byteLength, pos, scalarsPerPos, offset,
|
||||
this->devClipBounds(draw));
|
||||
this->devClipBounds());
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
void SkGpuDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint, SkDrawFilter* drawFilter) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawTextBlob", fContext.get());
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
CHECK_SHOULD_DRAW();
|
||||
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
fRenderTargetContext->drawTextBlob(fClip, paint, *draw.fMatrix,
|
||||
blob, x, y, drawFilter, this->devClipBounds(draw));
|
||||
fRenderTargetContext->drawTextBlob(fClip, paint, this->ctm(),
|
||||
blob, x, y, drawFilter, this->devClipBounds());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -65,55 +65,55 @@ public:
|
||||
|
||||
GrRenderTargetContext* accessRenderTargetContext() override;
|
||||
|
||||
void drawPaint(const SkDraw&, const SkPaint& paint) override;
|
||||
void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, const SkPoint[],
|
||||
void drawPaint(const SkPaint& paint) override;
|
||||
void drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint[],
|
||||
const SkPaint& paint) override;
|
||||
void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint) override;
|
||||
void drawRRect(const SkDraw&, const SkRRect& r, const SkPaint& paint) override;
|
||||
void drawDRRect(const SkDraw& draw, const SkRRect& outer, const SkRRect& inner,
|
||||
void drawRect(const SkRect& r, const SkPaint& paint) override;
|
||||
void drawRRect(const SkRRect& r, const SkPaint& paint) override;
|
||||
void drawDRRect(const SkRRect& outer, const SkRRect& inner,
|
||||
const SkPaint& paint) override;
|
||||
void drawRegion(const SkDraw&, const SkRegion& r, const SkPaint& paint) override;
|
||||
void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) override;
|
||||
void drawArc(const SkDraw&, const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
|
||||
void drawRegion(const SkRegion& r, const SkPaint& paint) override;
|
||||
void drawOval(const SkRect& oval, const SkPaint& paint) override;
|
||||
void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
|
||||
bool useCenter, const SkPaint& paint) override;
|
||||
void drawPath(const SkDraw&, const SkPath& path, const SkPaint& paint,
|
||||
void drawPath(const SkPath& path, const SkPaint& paint,
|
||||
const SkMatrix* prePathMatrix, bool pathIsMutable) override;
|
||||
void drawBitmap(const SkDraw&, const SkBitmap& bitmap, const SkMatrix&,
|
||||
void drawBitmap(const SkBitmap& bitmap, const SkMatrix&,
|
||||
const SkPaint&) override;
|
||||
void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect* srcOrNull, const SkRect& dst,
|
||||
void drawBitmapRect(const SkBitmap&, const SkRect* srcOrNull, const SkRect& dst,
|
||||
const SkPaint& paint, SkCanvas::SrcRectConstraint) override;
|
||||
void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
|
||||
void drawSprite(const SkBitmap& bitmap, int x, int y,
|
||||
const SkPaint& paint) override;
|
||||
void drawText(const SkDraw&, const void* text, size_t len, SkScalar x, SkScalar y,
|
||||
void drawText(const void* text, size_t len, SkScalar x, SkScalar y,
|
||||
const SkPaint&) override;
|
||||
void drawPosText(const SkDraw&, const void* text, size_t len, const SkScalar pos[],
|
||||
void drawPosText(const void* text, size_t len, const SkScalar pos[],
|
||||
int scalarsPerPos, const SkPoint& offset, const SkPaint&) override;
|
||||
void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
|
||||
void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint, SkDrawFilter* drawFilter) override;
|
||||
void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, const SkPoint verts[],
|
||||
void drawVertices(SkCanvas::VertexMode, int vertexCount, const SkPoint verts[],
|
||||
const SkPoint texs[], const SkColor colors[], SkBlendMode,
|
||||
const uint16_t indices[], int indexCount, const SkPaint&) override;
|
||||
void drawVerticesObject(const SkDraw&, sk_sp<SkVertices>, SkBlendMode, const SkPaint&,
|
||||
void drawVerticesObject(sk_sp<SkVertices>, SkBlendMode, const SkPaint&,
|
||||
uint32_t flags) override;
|
||||
void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[],
|
||||
void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[],
|
||||
const SkColor[], int count, SkBlendMode, const SkPaint&) override;
|
||||
void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) override;
|
||||
void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override;
|
||||
|
||||
void drawImage(const SkDraw&, const SkImage*, SkScalar x, SkScalar y, const SkPaint&) override;
|
||||
void drawImageRect(const SkDraw&, const SkImage*, const SkRect* src, const SkRect& dst,
|
||||
void drawImage(const SkImage*, SkScalar x, SkScalar y, const SkPaint&) override;
|
||||
void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
|
||||
const SkPaint&, SkCanvas::SrcRectConstraint) override;
|
||||
|
||||
void drawImageNine(const SkDraw& draw, const SkImage* image, const SkIRect& center,
|
||||
void drawImageNine(const SkImage* image, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint& paint) override;
|
||||
void drawBitmapNine(const SkDraw& draw, const SkBitmap& bitmap, const SkIRect& center,
|
||||
void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint& paint) override;
|
||||
|
||||
void drawImageLattice(const SkDraw&, const SkImage*, const SkCanvas::Lattice&,
|
||||
void drawImageLattice(const SkImage*, const SkCanvas::Lattice&,
|
||||
const SkRect& dst, const SkPaint&) override;
|
||||
void drawBitmapLattice(const SkDraw&, const SkBitmap&, const SkCanvas::Lattice&,
|
||||
void drawBitmapLattice(const SkBitmap&, const SkCanvas::Lattice&,
|
||||
const SkRect& dst, const SkPaint&) override;
|
||||
|
||||
void drawSpecial(const SkDraw&, SkSpecialImage*,
|
||||
void drawSpecial(SkSpecialImage*,
|
||||
int left, int top, const SkPaint& paint) override;
|
||||
sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
|
||||
sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
|
||||
@ -157,7 +157,7 @@ private:
|
||||
bool forceConservativeRasterClip() const override { return true; }
|
||||
|
||||
// sets the render target and clip on context
|
||||
void prepareDraw(const SkDraw&);
|
||||
void prepareDraw();
|
||||
|
||||
/**
|
||||
* Helper functions called by drawBitmapCommon. By the time these are called the SkDraw's
|
||||
@ -179,8 +179,7 @@ private:
|
||||
SkCanvas::SrcRectConstraint constraint, SkFilterQuality quality,
|
||||
const SkMatrix& viewMatrix, const SkMatrix& srcToDstRect) const;
|
||||
|
||||
sk_sp<SkSpecialImage> filterTexture(const SkDraw&,
|
||||
SkSpecialImage*,
|
||||
sk_sp<SkSpecialImage> filterTexture(SkSpecialImage*,
|
||||
int left, int top,
|
||||
SkIPoint* offset,
|
||||
const SkImageFilter* filter);
|
||||
@ -228,14 +227,14 @@ private:
|
||||
bool drawFilledDRRect(const SkMatrix& viewMatrix, const SkRRect& outer,
|
||||
const SkRRect& inner, const SkPaint& paint);
|
||||
|
||||
void drawProducerNine(const SkDraw&, GrTextureProducer*, const SkIRect& center,
|
||||
void drawProducerNine(GrTextureProducer*, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
|
||||
void drawProducerLattice(const SkDraw&, GrTextureProducer*, const SkCanvas::Lattice& lattice,
|
||||
void drawProducerLattice(GrTextureProducer*, const SkCanvas::Lattice& lattice,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
|
||||
bool drawDashLine(const SkPoint pts[2], const SkPaint& paint);
|
||||
void drawStrokedLine(const SkPoint pts[2], const SkDraw&, const SkPaint&);
|
||||
void drawStrokedLine(const SkPoint pts[2], const SkPaint&);
|
||||
|
||||
static sk_sp<GrRenderTargetContext> MakeRenderTargetContext(GrContext*,
|
||||
SkBudgeted,
|
||||
|
@ -48,6 +48,23 @@
|
||||
|
||||
// Utility functions
|
||||
|
||||
static void draw_points(SkCanvas::PointMode mode,
|
||||
size_t count,
|
||||
const SkPoint* points,
|
||||
const SkPaint& paint,
|
||||
const SkIRect& bounds,
|
||||
const SkMatrix& ctm,
|
||||
SkBaseDevice* device) {
|
||||
SkRasterClip rc(bounds);
|
||||
SkDraw draw;
|
||||
draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(bounds.right(), bounds.bottom()), nullptr, 0);
|
||||
draw.fMatrix = &ctm;
|
||||
draw.fRC = &rc;
|
||||
draw.drawPoints(mode, count, points, paint, device);
|
||||
}
|
||||
|
||||
static SkIRect size(const SkBaseDevice& dev) { return {0, 0, dev.width(), dev.height()}; }
|
||||
|
||||
// If the paint will definitely draw opaquely, replace kSrc with
|
||||
// kSrcOver. http://crbug.com/473572
|
||||
static void replace_srcmode_on_opaque_paint(SkPaint* paint) {
|
||||
@ -381,23 +398,26 @@ SkPDFCanon* SkPDFDevice::getCanon() const { return fDocument->canon(); }
|
||||
// drawing method and maintain the state needed between set up and finish.
|
||||
class ScopedContentEntry {
|
||||
public:
|
||||
ScopedContentEntry(SkPDFDevice* device, const SkDraw& draw,
|
||||
const SkPaint& paint, bool hasText = false)
|
||||
: fDevice(device),
|
||||
fContentEntry(nullptr),
|
||||
fBlendMode(SkBlendMode::kSrcOver),
|
||||
fDstFormXObject(nullptr) {
|
||||
init(draw.fClipStack, *draw.fMatrix, paint, hasText);
|
||||
}
|
||||
ScopedContentEntry(SkPDFDevice* device, const SkClipStack* clipStack,
|
||||
ScopedContentEntry(SkPDFDevice* device,
|
||||
const SkClipStack& clipStack,
|
||||
const SkMatrix& matrix,
|
||||
const SkPaint& paint, bool hasText = false)
|
||||
: fDevice(device),
|
||||
fContentEntry(nullptr),
|
||||
fBlendMode(SkBlendMode::kSrcOver),
|
||||
fDstFormXObject(nullptr) {
|
||||
init(clipStack, matrix, paint, hasText);
|
||||
const SkPaint& paint,
|
||||
bool hasText = false)
|
||||
: fDevice(device)
|
||||
, fContentEntry(nullptr)
|
||||
, fBlendMode(SkBlendMode::kSrcOver)
|
||||
, fDstFormXObject(nullptr)
|
||||
{
|
||||
if (matrix.hasPerspective()) {
|
||||
NOT_IMPLEMENTED(!matrix.hasPerspective(), false);
|
||||
return;
|
||||
}
|
||||
fBlendMode = paint.getBlendMode();
|
||||
fContentEntry =
|
||||
fDevice->setUpContentEntry(clipStack, matrix, paint, hasText, &fDstFormXObject);
|
||||
}
|
||||
ScopedContentEntry(SkPDFDevice* dev, const SkPaint& paint, bool hasText = false)
|
||||
: ScopedContentEntry(dev, dev->cs(), dev->ctm(), paint, hasText) {}
|
||||
|
||||
~ScopedContentEntry() {
|
||||
if (fContentEntry) {
|
||||
@ -451,18 +471,6 @@ private:
|
||||
SkBlendMode fBlendMode;
|
||||
sk_sp<SkPDFObject> fDstFormXObject;
|
||||
SkPath fShape;
|
||||
|
||||
void init(const SkClipStack* clipStack,
|
||||
const SkMatrix& matrix, const SkPaint& paint, bool hasText) {
|
||||
// Shape has to be flatten before we get here.
|
||||
if (matrix.hasPerspective()) {
|
||||
NOT_IMPLEMENTED(!matrix.hasPerspective(), false);
|
||||
return;
|
||||
}
|
||||
fBlendMode = paint.getBlendMode();
|
||||
fContentEntry = fDevice->setUpContentEntry(clipStack, matrix, paint, hasText,
|
||||
&fDstFormXObject);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -503,25 +511,44 @@ void SkPDFDevice::cleanUp() {
|
||||
fShaderResources.unrefAll();
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawAnnotation(const SkDraw& d, const SkRect& rect, const char key[],
|
||||
SkData* value) {
|
||||
void SkPDFDevice::drawAnnotation(const SkRect& rect, const char key[], SkData* value) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
if (rect.isEmpty()) {
|
||||
this->handlePointAnnotation({ rect.x(), rect.y() }, *d.fMatrix, key, value);
|
||||
} else {
|
||||
this->handleRectAnnotation(rect, d, key, value);
|
||||
if (!strcmp(SkAnnotationKeys::Define_Named_Dest_Key(), key)) {
|
||||
SkPoint transformedPoint;
|
||||
this->ctm().mapXY(rect.x(), rect.y(), &transformedPoint);
|
||||
fNamedDestinations.emplace_back(value, transformedPoint);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Convert to path to handle non-90-degree rotations.
|
||||
SkPath path;
|
||||
path.addRect(rect);
|
||||
path.transform(this->ctm(), &path);
|
||||
SkPath clip;
|
||||
(void)this->cs().asPath(&clip);
|
||||
Op(clip, path, kIntersect_SkPathOp, &path);
|
||||
// PDF wants a rectangle only.
|
||||
SkRect transformedRect = path.getBounds();
|
||||
if (transformedRect.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!strcmp(SkAnnotationKeys::URL_Key(), key)) {
|
||||
fLinkToURLs.emplace_back(transformedRect, value);
|
||||
} else if (!strcmp(SkAnnotationKeys::Link_Named_Dest_Key(), key)) {
|
||||
fLinkToDestinations.emplace_back(transformedRect, value);
|
||||
}
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) {
|
||||
void SkPDFDevice::drawPaint(const SkPaint& paint) {
|
||||
SkPaint newPaint = paint;
|
||||
replace_srcmode_on_opaque_paint(&newPaint);
|
||||
|
||||
newPaint.setStyle(SkPaint::kFill_Style);
|
||||
ScopedContentEntry content(this, d, newPaint);
|
||||
internalDrawPaint(newPaint, content.entry());
|
||||
ScopedContentEntry content(this, newPaint);
|
||||
this->internalDrawPaint(newPaint, content.entry());
|
||||
}
|
||||
|
||||
void SkPDFDevice::internalDrawPaint(const SkPaint& paint,
|
||||
@ -542,8 +569,7 @@ void SkPDFDevice::internalDrawPaint(const SkPaint& paint,
|
||||
&contentEntry->fContent);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawPoints(const SkDraw& d,
|
||||
SkCanvas::PointMode mode,
|
||||
void SkPDFDevice::drawPoints(SkCanvas::PointMode mode,
|
||||
size_t count,
|
||||
const SkPoint* points,
|
||||
const SkPaint& srcPaint) {
|
||||
@ -558,10 +584,11 @@ void SkPDFDevice::drawPoints(const SkDraw& d,
|
||||
// We only use this when there's a path effect because of the overhead
|
||||
// of multiple calls to setUpContentEntry it causes.
|
||||
if (passedPaint.getPathEffect()) {
|
||||
if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
|
||||
if (this->cs().isEmpty(size(*this))) {
|
||||
return;
|
||||
}
|
||||
d.drawPoints(mode, count, points, passedPaint, this);
|
||||
draw_points(mode, count, points, passedPaint,
|
||||
this->devClipBounds(), this->ctm(), this);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -581,7 +608,7 @@ void SkPDFDevice::drawPoints(const SkDraw& d,
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
SkRect r = SkRect::MakeXYWH(points[i].fX, points[i].fY, 0, 0);
|
||||
r.inset(-halfStroke, -halfStroke);
|
||||
drawRect(d, r, modifiedPaint);
|
||||
this->drawRect(r, modifiedPaint);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
@ -589,7 +616,7 @@ void SkPDFDevice::drawPoints(const SkDraw& d,
|
||||
}
|
||||
}
|
||||
|
||||
ScopedContentEntry content(this, d, *paint);
|
||||
ScopedContentEntry content(this, *paint);
|
||||
if (!content.entry()) {
|
||||
return;
|
||||
}
|
||||
@ -671,8 +698,7 @@ static sk_sp<SkPDFDict> create_link_named_dest(const SkData* nameData,
|
||||
return annotation;
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawRect(const SkDraw& d,
|
||||
const SkRect& rect,
|
||||
void SkPDFDevice::drawRect(const SkRect& rect,
|
||||
const SkPaint& srcPaint) {
|
||||
SkPaint paint = srcPaint;
|
||||
replace_srcmode_on_opaque_paint(&paint);
|
||||
@ -680,16 +706,16 @@ void SkPDFDevice::drawRect(const SkDraw& d,
|
||||
r.sort();
|
||||
|
||||
if (paint.getPathEffect()) {
|
||||
if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
|
||||
if (this->cs().isEmpty(size(*this))) {
|
||||
return;
|
||||
}
|
||||
SkPath path;
|
||||
path.addRect(r);
|
||||
drawPath(d, path, paint, nullptr, true);
|
||||
this->drawPath(path, paint, nullptr, true);
|
||||
return;
|
||||
}
|
||||
|
||||
ScopedContentEntry content(this, d, paint);
|
||||
ScopedContentEntry content(this, paint);
|
||||
if (!content.entry()) {
|
||||
return;
|
||||
}
|
||||
@ -698,27 +724,34 @@ void SkPDFDevice::drawRect(const SkDraw& d,
|
||||
&content.entry()->fContent);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawRRect(const SkDraw& draw,
|
||||
const SkRRect& rrect,
|
||||
void SkPDFDevice::drawRRect(const SkRRect& rrect,
|
||||
const SkPaint& srcPaint) {
|
||||
SkPaint paint = srcPaint;
|
||||
replace_srcmode_on_opaque_paint(&paint);
|
||||
SkPath path;
|
||||
path.addRRect(rrect);
|
||||
this->drawPath(draw, path, paint, nullptr, true);
|
||||
this->drawPath(path, paint, nullptr, true);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawOval(const SkDraw& draw,
|
||||
const SkRect& oval,
|
||||
void SkPDFDevice::drawOval(const SkRect& oval,
|
||||
const SkPaint& srcPaint) {
|
||||
SkPaint paint = srcPaint;
|
||||
replace_srcmode_on_opaque_paint(&paint);
|
||||
SkPath path;
|
||||
path.addOval(oval);
|
||||
this->drawPath(draw, path, paint, nullptr, true);
|
||||
this->drawPath(path, paint, nullptr, true);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawPath(const SkDraw& d,
|
||||
void SkPDFDevice::drawPath(const SkPath& origPath,
|
||||
const SkPaint& srcPaint,
|
||||
const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable) {
|
||||
this->internalDrawPath(
|
||||
this->cs(), this->ctm(), origPath, srcPaint, prePathMatrix, pathIsMutable);
|
||||
}
|
||||
|
||||
void SkPDFDevice::internalDrawPath(const SkClipStack& clipStack,
|
||||
const SkMatrix& ctm,
|
||||
const SkPath& origPath,
|
||||
const SkPaint& srcPaint,
|
||||
const SkMatrix* prePathMatrix,
|
||||
@ -728,7 +761,7 @@ void SkPDFDevice::drawPath(const SkDraw& d,
|
||||
SkPath modifiedPath;
|
||||
SkPath* pathPtr = const_cast<SkPath*>(&origPath);
|
||||
|
||||
SkMatrix matrix = *d.fMatrix;
|
||||
SkMatrix matrix = ctm;
|
||||
if (prePathMatrix) {
|
||||
if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
|
||||
if (!pathIsMutable) {
|
||||
@ -742,7 +775,7 @@ void SkPDFDevice::drawPath(const SkDraw& d,
|
||||
}
|
||||
|
||||
if (paint.getPathEffect()) {
|
||||
if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
|
||||
if (clipStack.isEmpty(size(*this))) {
|
||||
return;
|
||||
}
|
||||
if (!pathIsMutable) {
|
||||
@ -759,15 +792,15 @@ void SkPDFDevice::drawPath(const SkDraw& d,
|
||||
noEffectPaint.setStyle(SkPaint::kStroke_Style);
|
||||
noEffectPaint.setStrokeWidth(0);
|
||||
}
|
||||
drawPath(d, *pathPtr, noEffectPaint, nullptr, true);
|
||||
this->internalDrawPath(clipStack, ctm, *pathPtr, noEffectPaint, nullptr, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (handleInversePath(d, origPath, paint, pathIsMutable, prePathMatrix)) {
|
||||
if (this->handleInversePath(origPath, paint, pathIsMutable, prePathMatrix)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScopedContentEntry content(this, d.fClipStack, matrix, paint);
|
||||
ScopedContentEntry content(this, clipStack, matrix, paint);
|
||||
if (!content.entry()) {
|
||||
return;
|
||||
}
|
||||
@ -786,8 +819,7 @@ void SkPDFDevice::drawPath(const SkDraw& d,
|
||||
}
|
||||
|
||||
|
||||
void SkPDFDevice::drawImageRect(const SkDraw& d,
|
||||
const SkImage* image,
|
||||
void SkPDFDevice::drawImageRect(const SkImage* image,
|
||||
const SkRect* src,
|
||||
const SkRect& dst,
|
||||
const SkPaint& srcPaint,
|
||||
@ -815,13 +847,11 @@ void SkPDFDevice::drawImageRect(const SkDraw& d,
|
||||
if (!imageSubset.isValid()) {
|
||||
return;
|
||||
}
|
||||
transform.postConcat(*d.fMatrix);
|
||||
this->internalDrawImage(transform, d.fClipStack,
|
||||
std::move(imageSubset), paint);
|
||||
transform.postConcat(this->ctm());
|
||||
this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawBitmapRect(const SkDraw& d,
|
||||
const SkBitmap& bitmap,
|
||||
void SkPDFDevice::drawBitmapRect(const SkBitmap& bitmap,
|
||||
const SkRect* src,
|
||||
const SkRect& dst,
|
||||
const SkPaint& srcPaint,
|
||||
@ -853,16 +883,14 @@ void SkPDFDevice::drawBitmapRect(const SkDraw& d,
|
||||
if (!imageSubset.isValid()) {
|
||||
return;
|
||||
}
|
||||
transform.postConcat(*d.fMatrix);
|
||||
this->internalDrawImage(transform, d.fClipStack,
|
||||
std::move(imageSubset), paint);
|
||||
transform.postConcat(this->ctm());
|
||||
this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawBitmap(const SkDraw& d,
|
||||
const SkBitmap& bitmap,
|
||||
void SkPDFDevice::drawBitmap(const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix,
|
||||
const SkPaint& srcPaint) {
|
||||
if (bitmap.drawsNothing() || d.fClipStack->isEmpty(this->getGlobalBounds())) {
|
||||
if (bitmap.drawsNothing() || this->cs().isEmpty(size(*this))) {
|
||||
return;
|
||||
}
|
||||
SkPaint paint = srcPaint;
|
||||
@ -874,17 +902,15 @@ void SkPDFDevice::drawBitmap(const SkDraw& d,
|
||||
return;
|
||||
}
|
||||
SkMatrix transform = matrix;
|
||||
transform.postConcat(*d.fMatrix);
|
||||
this->internalDrawImage(
|
||||
transform, d.fClipStack, std::move(imageSubset), paint);
|
||||
transform.postConcat(this->ctm());
|
||||
this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawSprite(const SkDraw& d,
|
||||
const SkBitmap& bitmap,
|
||||
void SkPDFDevice::drawSprite(const SkBitmap& bitmap,
|
||||
int x,
|
||||
int y,
|
||||
const SkPaint& srcPaint) {
|
||||
if (bitmap.drawsNothing() || d.fClipStack->isEmpty(this->getGlobalBounds())) {
|
||||
if (bitmap.drawsNothing() || this->cs().isEmpty(size(*this))) {
|
||||
return;
|
||||
}
|
||||
SkPaint paint = srcPaint;
|
||||
@ -896,12 +922,10 @@ void SkPDFDevice::drawSprite(const SkDraw& d,
|
||||
return;
|
||||
}
|
||||
SkMatrix transform = SkMatrix::MakeTrans(SkIntToScalar(x), SkIntToScalar(y));
|
||||
this->internalDrawImage(
|
||||
transform, d.fClipStack, std::move(imageSubset), paint);
|
||||
this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawImage(const SkDraw& draw,
|
||||
const SkImage* image,
|
||||
void SkPDFDevice::drawImage(const SkImage* image,
|
||||
SkScalar x,
|
||||
SkScalar y,
|
||||
const SkPaint& srcPaint) {
|
||||
@ -917,9 +941,8 @@ void SkPDFDevice::drawImage(const SkDraw& draw,
|
||||
return;
|
||||
}
|
||||
SkMatrix transform = SkMatrix::MakeTrans(x, y);
|
||||
transform.postConcat(*draw.fMatrix);
|
||||
this->internalDrawImage(
|
||||
transform, draw.fClipStack, std::move(imageSubset), paint);
|
||||
transform.postConcat(this->ctm());
|
||||
this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -1213,7 +1236,7 @@ static void update_font(SkWStream* wStream, int fontIndex, SkScalar textSize) {
|
||||
}
|
||||
|
||||
void SkPDFDevice::internalDrawText(
|
||||
const SkDraw& d, const void* sourceText, size_t sourceByteCount,
|
||||
const void* sourceText, size_t sourceByteCount,
|
||||
const SkScalar pos[], SkTextBlob::GlyphPositioning positioning,
|
||||
SkPoint offset, const SkPaint& srcPaint, const uint32_t* clusters,
|
||||
uint32_t textByteLength, const char* utf8Text) {
|
||||
@ -1297,7 +1320,7 @@ void SkPDFDevice::internalDrawText(
|
||||
}
|
||||
offset.offset(alignmentFactor * advance, 0);
|
||||
}
|
||||
ScopedContentEntry content(this, d, paint, true);
|
||||
ScopedContentEntry content(this, paint, true);
|
||||
if (!content.entry()) {
|
||||
return;
|
||||
}
|
||||
@ -1396,20 +1419,20 @@ void SkPDFDevice::internalDrawText(
|
||||
}
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len,
|
||||
void SkPDFDevice::drawText(const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) {
|
||||
this->internalDrawText(d, text, len, nullptr, SkTextBlob::kDefault_Positioning,
|
||||
this->internalDrawText(text, len, nullptr, SkTextBlob::kDefault_Positioning,
|
||||
SkPoint{x, y}, paint, nullptr, 0, nullptr);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len,
|
||||
void SkPDFDevice::drawPosText(const void* text, size_t len,
|
||||
const SkScalar pos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint& paint) {
|
||||
this->internalDrawText(d, text, len, pos, (SkTextBlob::GlyphPositioning)scalarsPerPos,
|
||||
this->internalDrawText(text, len, pos, (SkTextBlob::GlyphPositioning)scalarsPerPos,
|
||||
offset, paint, nullptr, 0, nullptr);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
void SkPDFDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
const SkPaint &paint, SkDrawFilter* drawFilter) {
|
||||
for (SkTextBlobRunIterator it(blob); !it.done(); it.next()) {
|
||||
SkPaint runPaint(paint);
|
||||
@ -1419,25 +1442,24 @@ void SkPDFDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSca
|
||||
}
|
||||
runPaint.setFlags(this->filterTextFlags(runPaint));
|
||||
SkPoint offset = it.offset() + SkPoint{x, y};
|
||||
this->internalDrawText(draw, it.glyphs(), sizeof(SkGlyphID) * it.glyphCount(),
|
||||
this->internalDrawText(it.glyphs(), sizeof(SkGlyphID) * it.glyphCount(),
|
||||
it.pos(), it.positioning(), offset, runPaint,
|
||||
it.clusters(), it.textSize(), it.text());
|
||||
}
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode,
|
||||
void SkPDFDevice::drawVertices(SkCanvas::VertexMode,
|
||||
int vertexCount, const SkPoint verts[],
|
||||
const SkPoint texs[], const SkColor colors[],
|
||||
SkBlendMode, const uint16_t indices[],
|
||||
int indexCount, const SkPaint& paint) {
|
||||
if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
|
||||
if (this->cs().isEmpty(size(*this))) {
|
||||
return;
|
||||
}
|
||||
// TODO: implement drawVertices
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawDevice(const SkDraw& d, SkBaseDevice* device,
|
||||
int x, int y, const SkPaint& paint) {
|
||||
void SkPDFDevice::drawDevice(SkBaseDevice* device, int x, int y, const SkPaint& paint) {
|
||||
SkASSERT(!paint.getImageFilter());
|
||||
|
||||
// Check if the source device is really a bitmapdevice (because that's what we returned
|
||||
@ -1446,7 +1468,7 @@ void SkPDFDevice::drawDevice(const SkDraw& d, SkBaseDevice* device,
|
||||
if (device->peekPixels(&pmap)) {
|
||||
SkBitmap bitmap;
|
||||
bitmap.installPixels(pmap);
|
||||
this->drawSprite(d, bitmap, x, y, paint);
|
||||
this->drawSprite(bitmap, x, y, paint);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1472,9 +1494,8 @@ void SkPDFDevice::drawDevice(const SkDraw& d, SkBaseDevice* device,
|
||||
return;
|
||||
}
|
||||
|
||||
SkMatrix matrix;
|
||||
matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y));
|
||||
ScopedContentEntry content(this, d.fClipStack, matrix, paint);
|
||||
SkMatrix matrix = SkMatrix::MakeTrans(SkIntToScalar(x), SkIntToScalar(y));
|
||||
ScopedContentEntry content(this, this->cs(), matrix, paint);
|
||||
if (!content.entry()) {
|
||||
return;
|
||||
}
|
||||
@ -1530,11 +1551,8 @@ std::unique_ptr<SkStreamAsset> SkPDFDevice::content() const {
|
||||
|
||||
GraphicStackState gsState(fExistingClipStack, &buffer);
|
||||
for (const auto& entry : fContentEntries) {
|
||||
SkPoint translation;
|
||||
translation.iset(this->getOrigin());
|
||||
translation.negate();
|
||||
gsState.updateClip(entry.fState.fClipStack,
|
||||
translation, SkRect::Make(this->getGlobalBounds()));
|
||||
{0, 0}, SkRect::Make(size(*this)));
|
||||
gsState.updateMatrix(entry.fState.fMatrix);
|
||||
gsState.updateDrawingState(entry.fState);
|
||||
|
||||
@ -1555,14 +1573,14 @@ std::unique_ptr<SkStreamAsset> SkPDFDevice::content() const {
|
||||
* either as a (incorrect) fallback or because the path was not inverse
|
||||
* in the first place.
|
||||
*/
|
||||
bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
|
||||
bool SkPDFDevice::handleInversePath(const SkPath& origPath,
|
||||
const SkPaint& paint, bool pathIsMutable,
|
||||
const SkMatrix* prePathMatrix) {
|
||||
if (!origPath.isInverseFillType()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
|
||||
if (this->cs().isEmpty(size(*this))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1582,7 +1600,7 @@ bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
|
||||
// To be consistent with the raster output, hairline strokes
|
||||
// are rendered as non-inverted.
|
||||
modifiedPath.toggleInverseFillType();
|
||||
drawPath(d, modifiedPath, paint, nullptr, true);
|
||||
this->drawPath(modifiedPath, paint, nullptr, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1590,16 +1608,14 @@ bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
|
||||
// Get bounds of clip in current transform space
|
||||
// (clip bounds are given in device space).
|
||||
SkMatrix transformInverse;
|
||||
SkMatrix totalMatrix = *d.fMatrix;
|
||||
SkMatrix totalMatrix = this->ctm();
|
||||
if (prePathMatrix) {
|
||||
totalMatrix.preConcat(*prePathMatrix);
|
||||
}
|
||||
if (!totalMatrix.invert(&transformInverse)) {
|
||||
return false;
|
||||
}
|
||||
SkRect bounds = d.fClipStack->bounds(this->getGlobalBounds());
|
||||
SkIPoint deviceOrigin = this->getOrigin();
|
||||
bounds.offset(-deviceOrigin.x(), -deviceOrigin.y());
|
||||
SkRect bounds = this->cs().bounds(size(*this));
|
||||
transformInverse.mapRect(&bounds);
|
||||
|
||||
// Extend the bounds by the line width (plus some padding)
|
||||
@ -1611,48 +1627,10 @@ bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
|
||||
return false;
|
||||
}
|
||||
|
||||
drawPath(d, modifiedPath, noInversePaint, prePathMatrix, true);
|
||||
this->drawPath(modifiedPath, noInversePaint, prePathMatrix, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkPDFDevice::handlePointAnnotation(const SkPoint& point,
|
||||
const SkMatrix& matrix,
|
||||
const char key[], SkData* value) {
|
||||
SkASSERT(value);
|
||||
if (!strcmp(SkAnnotationKeys::Define_Named_Dest_Key(), key)) {
|
||||
SkPoint transformedPoint;
|
||||
matrix.mapXY(point.x(), point.y(), &transformedPoint);
|
||||
fNamedDestinations.emplace_back(value, transformedPoint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkPDFDevice::handleRectAnnotation(const SkRect& rect,
|
||||
const SkDraw& d,
|
||||
const char key[], SkData* value) {
|
||||
SkASSERT(value);
|
||||
// Convert to path to handle non-90-degree rotations.
|
||||
SkPath path;
|
||||
path.addRect(rect);
|
||||
path.transform(*d.fMatrix, &path);
|
||||
SkPath clip;
|
||||
(void)d.fClipStack->asPath(&clip);
|
||||
SkIPoint deviceOrigin = this->getOrigin();
|
||||
clip.offset(-deviceOrigin.x(), -deviceOrigin.y());
|
||||
// Offset here to make clip and path share coordinates.
|
||||
// We remove the offset in SkPDFDevice::drawDevice().
|
||||
Op(clip, path, kIntersect_SkPathOp, &path);
|
||||
// PDF wants a rectangle only.
|
||||
SkRect transformedRect = path.getBounds();
|
||||
|
||||
if (!transformedRect.isEmpty()) {
|
||||
if (!strcmp(SkAnnotationKeys::URL_Key(), key)) {
|
||||
fLinkToURLs.emplace_back(transformedRect, value);
|
||||
} else if (!strcmp(SkAnnotationKeys::Link_Named_Dest_Key(), key)) {
|
||||
fLinkToDestinations.emplace_back(transformedRect, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkPDFDevice::appendAnnotations(SkPDFArray* array) const {
|
||||
array->reserve(fLinkToURLs.count() + fLinkToDestinations.count());
|
||||
for (const RectWithData& rectWithURL : fLinkToURLs) {
|
||||
@ -1704,10 +1682,10 @@ sk_sp<SkPDFObject> SkPDFDevice::makeFormXObjectFromDevice() {
|
||||
|
||||
void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex,
|
||||
sk_sp<SkPDFObject> mask,
|
||||
const SkClipStack* clipStack,
|
||||
const SkClipStack& clipStack,
|
||||
SkBlendMode mode,
|
||||
bool invertClip) {
|
||||
if (!invertClip && clipStack->isEmpty(this->getGlobalBounds())) {
|
||||
if (!invertClip && clipStack.isEmpty(size(*this))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1715,11 +1693,9 @@ void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex,
|
||||
std::move(mask), invertClip,
|
||||
SkPDFGraphicState::kAlpha_SMaskMode, fDocument->canon());
|
||||
|
||||
SkMatrix identity;
|
||||
identity.reset();
|
||||
SkPaint paint;
|
||||
paint.setBlendMode(mode);
|
||||
ScopedContentEntry content(this, clipStack, identity, paint);
|
||||
ScopedContentEntry content(this, clipStack, SkMatrix::I(), paint);
|
||||
if (!content.entry()) {
|
||||
return;
|
||||
}
|
||||
@ -1735,13 +1711,12 @@ void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex,
|
||||
&content.entry()->fContent);
|
||||
}
|
||||
|
||||
SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* clipStack,
|
||||
SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack& clipStack,
|
||||
const SkMatrix& matrix,
|
||||
const SkPaint& paint,
|
||||
bool hasText,
|
||||
sk_sp<SkPDFObject>* dst) {
|
||||
*dst = nullptr;
|
||||
SkASSERT(clipStack);
|
||||
SkBlendMode blendMode = paint.getBlendMode();
|
||||
|
||||
// For the following modes, we want to handle source and destination
|
||||
@ -1781,7 +1756,7 @@ SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* cli
|
||||
} else {
|
||||
entry = fContentEntries.emplace_front();
|
||||
}
|
||||
populateGraphicStateEntryFromPaint(matrix, *clipStack, paint, hasText, &entry->fState);
|
||||
populateGraphicStateEntryFromPaint(matrix, clipStack, paint, hasText, &entry->fState);
|
||||
return entry;
|
||||
}
|
||||
|
||||
@ -1826,8 +1801,6 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
|
||||
|
||||
SkClipStack clipStack = fContentEntries.front()->fState.fClipStack;
|
||||
|
||||
SkMatrix identity;
|
||||
identity.reset();
|
||||
SkPaint stockPaint;
|
||||
|
||||
sk_sp<SkPDFObject> srcFormXObject;
|
||||
@ -1839,7 +1812,7 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
|
||||
// reduces to Dst.
|
||||
if (shape == nullptr || blendMode == SkBlendMode::kDstOut ||
|
||||
blendMode == SkBlendMode::kSrcATop) {
|
||||
ScopedContentEntry content(this, &fExistingClipStack, identity, stockPaint);
|
||||
ScopedContentEntry content(this, fExistingClipStack, SkMatrix::I(), stockPaint);
|
||||
// TODO: addXObjectResource take sk_sp
|
||||
SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst.get()),
|
||||
&content.entry()->fContent);
|
||||
@ -1860,27 +1833,22 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
|
||||
// the non-transparent parts of the device and the outlines (shape) of
|
||||
// all images and devices drawn.
|
||||
drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), dst,
|
||||
&fExistingClipStack, SkBlendMode::kSrcOver, true);
|
||||
fExistingClipStack, SkBlendMode::kSrcOver, true);
|
||||
} else {
|
||||
if (shape != nullptr) {
|
||||
// Draw shape into a form-xobject.
|
||||
SkRasterClip rc;
|
||||
SkDraw d;
|
||||
d.fMatrix = &identity;
|
||||
d.fRC = &rc;
|
||||
d.fClipStack = &clipStack;
|
||||
SkPaint filledPaint;
|
||||
filledPaint.setColor(SK_ColorBLACK);
|
||||
filledPaint.setStyle(SkPaint::kFill_Style);
|
||||
this->drawPath(d, *shape, filledPaint, nullptr, true);
|
||||
drawFormXObjectWithMask(addXObjectResource(dst.get()),
|
||||
this->internalDrawPath(clipStack, SkMatrix::I(), *shape, filledPaint, nullptr, true);
|
||||
this->drawFormXObjectWithMask(this->addXObjectResource(dst.get()),
|
||||
this->makeFormXObjectFromDevice(),
|
||||
&fExistingClipStack,
|
||||
fExistingClipStack,
|
||||
SkBlendMode::kSrcOver, true);
|
||||
|
||||
} else {
|
||||
drawFormXObjectWithMask(addXObjectResource(dst.get()), srcFormXObject,
|
||||
&fExistingClipStack,
|
||||
this->drawFormXObjectWithMask(this->addXObjectResource(dst.get()),
|
||||
srcFormXObject,
|
||||
fExistingClipStack,
|
||||
SkBlendMode::kSrcOver, true);
|
||||
}
|
||||
}
|
||||
@ -1889,7 +1857,7 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
|
||||
return;
|
||||
} else if (blendMode == SkBlendMode::kSrc ||
|
||||
blendMode == SkBlendMode::kDstATop) {
|
||||
ScopedContentEntry content(this, &fExistingClipStack, identity, stockPaint);
|
||||
ScopedContentEntry content(this, fExistingClipStack, SkMatrix::I(), stockPaint);
|
||||
if (content.entry()) {
|
||||
SkPDFUtils::DrawFormXObject(
|
||||
this->addXObjectResource(srcFormXObject.get()),
|
||||
@ -1899,8 +1867,8 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
|
||||
return;
|
||||
}
|
||||
} else if (blendMode == SkBlendMode::kSrcATop) {
|
||||
ScopedContentEntry content(this, &fExistingClipStack,
|
||||
identity, stockPaint);
|
||||
ScopedContentEntry content(this, fExistingClipStack,
|
||||
SkMatrix::I(), stockPaint);
|
||||
if (content.entry()) {
|
||||
SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst.get()),
|
||||
&content.entry()->fContent);
|
||||
@ -1920,7 +1888,7 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
|
||||
blendMode == SkBlendMode::kSrcATop) {
|
||||
drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()),
|
||||
std::move(dst),
|
||||
&fExistingClipStack,
|
||||
fExistingClipStack,
|
||||
SkBlendMode::kSrcOver,
|
||||
blendMode == SkBlendMode::kSrcOut);
|
||||
return;
|
||||
@ -1929,12 +1897,12 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
|
||||
int resourceID = addXObjectResource(dst.get());
|
||||
if (blendMode == SkBlendMode::kModulate) {
|
||||
drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()),
|
||||
std::move(dst), &fExistingClipStack,
|
||||
std::move(dst), fExistingClipStack,
|
||||
SkBlendMode::kSrcOver, false);
|
||||
mode = SkBlendMode::kMultiply;
|
||||
}
|
||||
drawFormXObjectWithMask(resourceID, std::move(srcFormXObject),
|
||||
&fExistingClipStack, mode,
|
||||
fExistingClipStack, mode,
|
||||
blendMode == SkBlendMode::kDstOut);
|
||||
return;
|
||||
}
|
||||
@ -1986,9 +1954,7 @@ void SkPDFDevice::populateGraphicStateEntryFromPaint(
|
||||
|
||||
// PDF doesn't support kClamp_TileMode, so we simulate it by making
|
||||
// a pattern the size of the current clip.
|
||||
SkRect clipStackBounds = clipStack.bounds(this->getGlobalBounds());
|
||||
SkIPoint deviceOrigin = this->getOrigin();
|
||||
clipStackBounds.offset(-deviceOrigin.x(), -deviceOrigin.y());
|
||||
SkRect clipStackBounds = clipStack.bounds(size(*this));
|
||||
|
||||
// We need to apply the initial transform to bounds in order to get
|
||||
// bounds in a consistent coordinate system.
|
||||
@ -2095,7 +2061,7 @@ static sk_sp<SkImage> color_filter(const SkImageSubset& imageSubset,
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix,
|
||||
const SkClipStack* clipStack,
|
||||
const SkClipStack& clipStack,
|
||||
SkImageSubset imageSubset,
|
||||
const SkPaint& paint) {
|
||||
if (imageSubset.dimensions().isZero()) {
|
||||
@ -2237,7 +2203,7 @@ void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix,
|
||||
#include "SkSpecialImage.h"
|
||||
#include "SkImageFilter.h"
|
||||
|
||||
void SkPDFDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x, int y,
|
||||
void SkPDFDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y,
|
||||
const SkPaint& paint) {
|
||||
SkASSERT(!srcImg->isTextureBacked());
|
||||
|
||||
@ -2246,10 +2212,10 @@ void SkPDFDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x,
|
||||
SkImageFilter* filter = paint.getImageFilter();
|
||||
if (filter) {
|
||||
SkIPoint offset = SkIPoint::Make(0, 0);
|
||||
SkMatrix matrix = *draw.fMatrix;
|
||||
SkMatrix matrix = this->ctm();
|
||||
matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
|
||||
const SkIRect clipBounds =
|
||||
draw.fClipStack->bounds(this->imageInfo().bounds()).roundOut().makeOffset(-x, -y);
|
||||
this->cs().bounds(this->imageInfo().bounds()).roundOut().makeOffset(-x, -y);
|
||||
sk_sp<SkImageFilterCache> cache(this->getImageFilterCache());
|
||||
// TODO: Should PDF be operating in a specified color space? For now, run the filter
|
||||
// in the same color space as the source (this is different from all other backends).
|
||||
@ -2261,12 +2227,12 @@ void SkPDFDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x,
|
||||
SkPaint tmpUnfiltered(paint);
|
||||
tmpUnfiltered.setImageFilter(nullptr);
|
||||
if (resultImg->getROPixels(&resultBM)) {
|
||||
this->drawSprite(draw, resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
|
||||
this->drawSprite(resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (srcImg->getROPixels(&resultBM)) {
|
||||
this->drawSprite(draw, resultBM, x, y, paint);
|
||||
this->drawSprite(resultBM, x, y, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,46 +79,44 @@ public:
|
||||
and are handling any looping from the paint, and any effects from the
|
||||
DrawFilter.
|
||||
*/
|
||||
void drawPaint(const SkDraw&, const SkPaint& paint) override;
|
||||
void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
|
||||
void drawPaint(const SkPaint& paint) override;
|
||||
void drawPoints(SkCanvas::PointMode mode,
|
||||
size_t count, const SkPoint[],
|
||||
const SkPaint& paint) override;
|
||||
void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint) override;
|
||||
void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) override;
|
||||
void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) override;
|
||||
void drawPath(const SkDraw&, const SkPath& origpath,
|
||||
void drawRect(const SkRect& r, const SkPaint& paint) override;
|
||||
void drawOval(const SkRect& oval, const SkPaint& paint) override;
|
||||
void drawRRect(const SkRRect& rr, const SkPaint& paint) override;
|
||||
void drawPath(const SkPath& origpath,
|
||||
const SkPaint& paint, const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable) override;
|
||||
void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, const SkRect* src,
|
||||
void drawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
|
||||
const SkRect& dst, const SkPaint&, SkCanvas::SrcRectConstraint) override;
|
||||
void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
|
||||
void drawBitmap(const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint&) override;
|
||||
void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
|
||||
void drawSprite(const SkBitmap& bitmap, int x, int y,
|
||||
const SkPaint& paint) override;
|
||||
void drawImage(const SkDraw&,
|
||||
const SkImage*,
|
||||
void drawImage(const SkImage*,
|
||||
SkScalar x,
|
||||
SkScalar y,
|
||||
const SkPaint&) override;
|
||||
void drawImageRect(const SkDraw&,
|
||||
const SkImage*,
|
||||
void drawImageRect(const SkImage*,
|
||||
const SkRect* src,
|
||||
const SkRect& dst,
|
||||
const SkPaint&,
|
||||
SkCanvas::SrcRectConstraint) override;
|
||||
void drawText(const SkDraw&, const void* text, size_t len,
|
||||
void drawText(const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint&) override;
|
||||
void drawPosText(const SkDraw&, const void* text, size_t len,
|
||||
void drawPosText(const void* text, size_t len,
|
||||
const SkScalar pos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint&) override;
|
||||
void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
|
||||
void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
|
||||
const SkPaint &, SkDrawFilter*) override;
|
||||
void drawVertices(const SkDraw&, SkCanvas::VertexMode,
|
||||
void drawVertices(SkCanvas::VertexMode,
|
||||
int vertexCount, const SkPoint verts[],
|
||||
const SkPoint texs[], const SkColor colors[],
|
||||
SkBlendMode, const uint16_t indices[],
|
||||
int indexCount, const SkPaint& paint) override;
|
||||
void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
|
||||
void drawDevice(SkBaseDevice*, int x, int y,
|
||||
const SkPaint&) override;
|
||||
|
||||
// PDF specific methods.
|
||||
@ -174,9 +172,9 @@ public:
|
||||
protected:
|
||||
sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&) override;
|
||||
|
||||
void drawAnnotation(const SkDraw&, const SkRect&, const char key[], SkData* value) override;
|
||||
void drawAnnotation(const SkRect&, const char key[], SkData* value) override;
|
||||
|
||||
void drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&) override;
|
||||
void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) override;
|
||||
sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
|
||||
sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
|
||||
sk_sp<SkSpecialImage> snapSpecial() override;
|
||||
@ -242,7 +240,7 @@ private:
|
||||
|
||||
void drawFormXObjectWithMask(int xObjectIndex,
|
||||
sk_sp<SkPDFObject> mask,
|
||||
const SkClipStack* clipStack,
|
||||
const SkClipStack& clipStack,
|
||||
SkBlendMode,
|
||||
bool invertClip);
|
||||
|
||||
@ -250,7 +248,7 @@ private:
|
||||
// returns nullptr and does not create a content entry.
|
||||
// setUpContentEntry and finishContentEntry can be used directly, but
|
||||
// the preferred method is to use the ScopedContentEntry helper class.
|
||||
ContentEntry* setUpContentEntry(const SkClipStack* clipStack,
|
||||
ContentEntry* setUpContentEntry(const SkClipStack& clipStack,
|
||||
const SkMatrix& matrix,
|
||||
const SkPaint& paint,
|
||||
bool hasText,
|
||||
@ -269,22 +267,27 @@ private:
|
||||
int getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID);
|
||||
|
||||
|
||||
void internalDrawText(const SkDraw&, const void*, size_t, const SkScalar pos[],
|
||||
void internalDrawText( const void*, size_t, const SkScalar pos[],
|
||||
SkTextBlob::GlyphPositioning, SkPoint, const SkPaint&,
|
||||
const uint32_t*, uint32_t, const char*);
|
||||
|
||||
void internalDrawPaint(const SkPaint& paint, ContentEntry* contentEntry);
|
||||
|
||||
void internalDrawImage(const SkMatrix& origMatrix,
|
||||
const SkClipStack* clipStack,
|
||||
const SkClipStack& clipStack,
|
||||
SkImageSubset imageSubset,
|
||||
const SkPaint& paint);
|
||||
|
||||
bool handleInversePath(const SkDraw& d, const SkPath& origPath,
|
||||
void internalDrawPath(const SkClipStack&,
|
||||
const SkMatrix&,
|
||||
const SkPath&,
|
||||
const SkPaint&,
|
||||
const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable);
|
||||
|
||||
bool handleInversePath(const SkPath& origPath,
|
||||
const SkPaint& paint, bool pathIsMutable,
|
||||
const SkMatrix* prePathMatrix = nullptr);
|
||||
void handlePointAnnotation(const SkPoint&, const SkMatrix&, const char key[], SkData* value);
|
||||
void handleRectAnnotation(const SkRect&, const SkDraw& d, const char key[], SkData* value);
|
||||
|
||||
typedef SkClipStackDevice INHERITED;
|
||||
|
||||
|
@ -278,14 +278,9 @@ struct SkSVGDevice::MxCp {
|
||||
const SkMatrix* fMatrix;
|
||||
const SkClipStack* fClipStack;
|
||||
|
||||
MxCp(SkSVGDevice* device, const SkDraw& draw) {
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
MxCp(SkSVGDevice* device) {
|
||||
fMatrix = &device->ctm();
|
||||
fClipStack = &device->cs();
|
||||
#else
|
||||
fMatrix = draw.fMatrix;
|
||||
fClipStack = draw.fClipStack;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@ -607,13 +602,13 @@ SkSVGDevice::SkSVGDevice(const SkISize& size, SkXMLWriter* writer)
|
||||
SkSVGDevice::~SkSVGDevice() {
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
|
||||
AutoElement rect("rect", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
void SkSVGDevice::drawPaint(const SkPaint& paint) {
|
||||
AutoElement rect("rect", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
rect.addRectAttributes(SkRect::MakeWH(SkIntToScalar(this->width()),
|
||||
SkIntToScalar(this->height())));
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
|
||||
void SkSVGDevice::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint pts[], const SkPaint& paint) {
|
||||
SkPath path;
|
||||
|
||||
@ -628,7 +623,7 @@ void SkSVGDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_
|
||||
path.rewind();
|
||||
path.moveTo(pts[i]);
|
||||
path.lineTo(pts[i+1]);
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
elem.addPathAttributes(path);
|
||||
}
|
||||
break;
|
||||
@ -636,37 +631,37 @@ void SkSVGDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_
|
||||
if (count > 1) {
|
||||
path.addPoly(pts, SkToInt(count), false);
|
||||
path.moveTo(pts[0]);
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
elem.addPathAttributes(path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) {
|
||||
AutoElement rect("rect", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
void SkSVGDevice::drawRect(const SkRect& r, const SkPaint& paint) {
|
||||
AutoElement rect("rect", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
rect.addRectAttributes(r);
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
|
||||
AutoElement ellipse("ellipse", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
void SkSVGDevice::drawOval(const SkRect& oval, const SkPaint& paint) {
|
||||
AutoElement ellipse("ellipse", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
ellipse.addAttribute("cx", oval.centerX());
|
||||
ellipse.addAttribute("cy", oval.centerY());
|
||||
ellipse.addAttribute("rx", oval.width() / 2);
|
||||
ellipse.addAttribute("ry", oval.height() / 2);
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawRRect(const SkDraw& draw, const SkRRect& rr, const SkPaint& paint) {
|
||||
void SkSVGDevice::drawRRect(const SkRRect& rr, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
path.addRRect(rr);
|
||||
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
elem.addPathAttributes(path);
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawPath(const SkDraw& draw, const SkPath& path, const SkPaint& paint,
|
||||
void SkSVGDevice::drawPath(const SkPath& path, const SkPaint& paint,
|
||||
const SkMatrix* prePathMatrix, bool pathIsMutable) {
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
elem.addPathAttributes(path);
|
||||
|
||||
// TODO: inverse fill types?
|
||||
@ -711,9 +706,9 @@ void SkSVGDevice::drawBitmapCommon(const MxCp& mc, const SkBitmap& bm, const SkP
|
||||
}
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
void SkSVGDevice::drawBitmap(const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint& paint) {
|
||||
MxCp mc(this, draw);
|
||||
MxCp mc(this);
|
||||
SkMatrix adjustedMatrix = *mc.fMatrix;
|
||||
adjustedMatrix.preConcat(matrix);
|
||||
mc.fMatrix = &adjustedMatrix;
|
||||
@ -721,9 +716,9 @@ void SkSVGDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
drawBitmapCommon(mc, bitmap, paint);
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
void SkSVGDevice::drawSprite(const SkBitmap& bitmap,
|
||||
int x, int y, const SkPaint& paint) {
|
||||
MxCp mc(this, draw);
|
||||
MxCp mc(this);
|
||||
SkMatrix adjustedMatrix = *mc.fMatrix;
|
||||
adjustedMatrix.preTranslate(SkIntToScalar(x), SkIntToScalar(y));
|
||||
mc.fMatrix = &adjustedMatrix;
|
||||
@ -731,10 +726,10 @@ void SkSVGDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
drawBitmapCommon(mc, bitmap, paint);
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bm, const SkRect* srcOrNull,
|
||||
void SkSVGDevice::drawBitmapRect(const SkBitmap& bm, const SkRect* srcOrNull,
|
||||
const SkRect& dst, const SkPaint& paint,
|
||||
SkCanvas::SrcRectConstraint) {
|
||||
MxCp mc(this, draw);
|
||||
MxCp mc(this);
|
||||
|
||||
SkClipStack adjustedClipStack;
|
||||
if (srcOrNull && *srcOrNull != SkRect::Make(bm.bounds())) {
|
||||
@ -754,9 +749,9 @@ void SkSVGDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bm, const S
|
||||
drawBitmapCommon(mc, bm, paint);
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawText(const SkDraw& draw, const void* text, size_t len,
|
||||
void SkSVGDevice::drawText(const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) {
|
||||
AutoElement elem("text", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
AutoElement elem("text", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
elem.addTextAttributes(paint);
|
||||
|
||||
SVGTextBuilder builder(text, len, paint, SkPoint::Make(x, y), 0);
|
||||
@ -765,12 +760,12 @@ void SkSVGDevice::drawText(const SkDraw& draw, const void* text, size_t len,
|
||||
elem.addText(builder.text());
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
|
||||
void SkSVGDevice::drawPosText(const void* text, size_t len,
|
||||
const SkScalar pos[], int scalarsPerPos, const SkPoint& offset,
|
||||
const SkPaint& paint) {
|
||||
SkASSERT(scalarsPerPos == 1 || scalarsPerPos == 2);
|
||||
|
||||
AutoElement elem("text", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
AutoElement elem("text", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
elem.addTextAttributes(paint);
|
||||
|
||||
SVGTextBuilder builder(text, len, paint, offset, scalarsPerPos, pos);
|
||||
@ -779,7 +774,7 @@ void SkSVGDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
|
||||
elem.addText(builder.text());
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath& path,
|
||||
void SkSVGDevice::drawTextOnPath(const void* text, size_t len, const SkPath& path,
|
||||
const SkMatrix* matrix, const SkPaint& paint) {
|
||||
SkString pathID = fResourceBucket->addPath();
|
||||
|
||||
@ -816,7 +811,7 @@ void SkSVGDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len, co
|
||||
}
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
|
||||
void SkSVGDevice::drawVertices(SkCanvas::VertexMode, int vertexCount,
|
||||
const SkPoint verts[], const SkPoint texs[],
|
||||
const SkColor colors[], SkBlendMode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
@ -825,7 +820,7 @@ void SkSVGDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCo
|
||||
SkDebugf("unsupported operation: drawVertices()\n");
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
|
||||
void SkSVGDevice::drawDevice(SkBaseDevice*, int x, int y,
|
||||
const SkPaint&) {
|
||||
// todo
|
||||
SkDebugf("unsupported operation: drawDevice()\n");
|
||||
|
@ -18,40 +18,40 @@ public:
|
||||
static SkBaseDevice* Create(const SkISize& size, SkXMLWriter* writer);
|
||||
|
||||
protected:
|
||||
void drawPaint(const SkDraw&, const SkPaint& paint) override;
|
||||
void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
|
||||
void drawPaint(const SkPaint& paint) override;
|
||||
void drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint[], const SkPaint& paint) override;
|
||||
void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint) override;
|
||||
void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) override;
|
||||
void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) override;
|
||||
void drawPath(const SkDraw&, const SkPath& path,
|
||||
void drawRect(const SkRect& r, const SkPaint& paint) override;
|
||||
void drawOval(const SkRect& oval, const SkPaint& paint) override;
|
||||
void drawRRect(const SkRRect& rr, const SkPaint& paint) override;
|
||||
void drawPath(const SkPath& path,
|
||||
const SkPaint& paint,
|
||||
const SkMatrix* prePathMatrix = nullptr,
|
||||
bool pathIsMutable = false) override;
|
||||
|
||||
void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
|
||||
void drawBitmap(const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint& paint) override;
|
||||
void drawSprite(const SkDraw&, const SkBitmap& bitmap,
|
||||
void drawSprite(const SkBitmap& bitmap,
|
||||
int x, int y, const SkPaint& paint) override;
|
||||
void drawBitmapRect(const SkDraw&, const SkBitmap&,
|
||||
void drawBitmapRect(const SkBitmap&,
|
||||
const SkRect* srcOrNull, const SkRect& dst,
|
||||
const SkPaint& paint, SkCanvas::SrcRectConstraint) override;
|
||||
|
||||
void drawText(const SkDraw&, const void* text, size_t len,
|
||||
void drawText(const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) override;
|
||||
void drawPosText(const SkDraw&, const void* text, size_t len,
|
||||
void drawPosText(const void* text, size_t len,
|
||||
const SkScalar pos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint& paint) override;
|
||||
void drawTextOnPath(const SkDraw&, const void* text, size_t len,
|
||||
void drawTextOnPath(const void* text, size_t len,
|
||||
const SkPath& path, const SkMatrix* matrix,
|
||||
const SkPaint& paint) override;
|
||||
void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
|
||||
void drawVertices(SkCanvas::VertexMode, int vertexCount,
|
||||
const SkPoint verts[], const SkPoint texs[],
|
||||
const SkColor colors[], SkBlendMode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint) override;
|
||||
|
||||
void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
|
||||
void drawDevice(SkBaseDevice*, int x, int y,
|
||||
const SkPaint&) override;
|
||||
|
||||
private:
|
||||
|
@ -130,28 +130,6 @@ private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ClipValidator : public SkCanvas::ClipVisitor {
|
||||
public:
|
||||
ClipValidator() : fFailed(false) {}
|
||||
bool failed() { return fFailed; }
|
||||
|
||||
// ClipVisitor
|
||||
void clipRect(const SkRect& rect, SkClipOp op, bool antialias) override {
|
||||
fFailed |= antialias;
|
||||
}
|
||||
|
||||
void clipRRect(const SkRRect& rrect, SkClipOp op, bool antialias) override {
|
||||
fFailed |= antialias;
|
||||
}
|
||||
|
||||
void clipPath(const SkPath&, SkClipOp, bool antialias) override {
|
||||
fFailed |= antialias;
|
||||
}
|
||||
|
||||
private:
|
||||
bool fFailed;
|
||||
};
|
||||
|
||||
static void setup_MC_state(SkMCState* state, const SkMatrix& matrix, const SkRegion& clip) {
|
||||
// initialize the struct
|
||||
state->clipRectCount = 0;
|
||||
@ -193,9 +171,7 @@ SkCanvasState* SkCanvasStateUtils::CaptureCanvasState(SkCanvas* canvas) {
|
||||
SkASSERT(canvas);
|
||||
|
||||
// Check the clip can be decomposed into rectangles (i.e. no soft clips).
|
||||
ClipValidator validator;
|
||||
canvas->replayClips(&validator);
|
||||
if (validator.failed()) {
|
||||
if (canvas->androidFramework_isClipAA()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -246,7 +222,9 @@ SkCanvasState* SkCanvasStateUtils::CaptureCanvasState(SkCanvas* canvas) {
|
||||
layerState->raster.rowBytes = pmap.rowBytes();
|
||||
layerState->raster.pixels = pmap.writable_addr();
|
||||
|
||||
setup_MC_state(&layerState->mcState, layer.matrix(), layer.clip().bwRgn());
|
||||
SkRegion rgn;
|
||||
layer.clip(&rgn);
|
||||
setup_MC_state(&layerState->mcState, layer.matrix(), rgn);
|
||||
layerCount++;
|
||||
}
|
||||
|
||||
|
@ -1139,23 +1139,34 @@ HRESULT SkXPSDevice::createXpsQuad(const SkPoint (&points)[4],
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawPoints(const SkDraw& d, SkCanvas::PointMode mode,
|
||||
template <typename F, typename... Args>
|
||||
void draw(SkClipStackDevice* dev, F f, Args&&... args) {
|
||||
SkIRect r = dev->devClipBounds();
|
||||
SkRasterClip rc(r);
|
||||
SkDraw draw;
|
||||
draw.fMatrix = &dev->ctm();
|
||||
draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(r.right(), r.bottom()), nullptr, 0);
|
||||
draw.fRC = &rc;
|
||||
(draw.*f)(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
|
||||
void SkXPSDevice::drawPoints(SkCanvas::PointMode mode,
|
||||
size_t count, const SkPoint points[],
|
||||
const SkPaint& paint) {
|
||||
//This will call back into the device to do the drawing.
|
||||
d.drawPoints(mode, count, points, paint, this);
|
||||
draw(this, &SkDraw::drawPoints, mode, count, points, paint, this);
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode,
|
||||
void SkXPSDevice::drawVertices(SkCanvas::VertexMode vertexMode,
|
||||
int vertexCount, const SkPoint verts[],
|
||||
const SkPoint texs[], const SkColor colors[],
|
||||
SkBlendMode, const uint16_t indices[],
|
||||
SkBlendMode blendMode, const uint16_t indices[],
|
||||
int indexCount, const SkPaint& paint) {
|
||||
//TODO: override this for XPS
|
||||
SkDEBUGF(("XPS drawVertices not yet implemented."));
|
||||
draw(this, &SkDraw::drawVertices, vertexMode, vertexCount, verts, texs, colors,
|
||||
blendMode, indices, indexCount, paint);
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawPaint(const SkDraw& d, const SkPaint& origPaint) {
|
||||
void SkXPSDevice::drawPaint(const SkPaint& origPaint) {
|
||||
const SkRect r = SkRect::MakeSize(this->fCurrentCanvasSize);
|
||||
|
||||
//If trying to paint with a stroke, ignore that and fill.
|
||||
@ -1165,39 +1176,38 @@ void SkXPSDevice::drawPaint(const SkDraw& d, const SkPaint& origPaint) {
|
||||
paint.writable()->setStyle(SkPaint::kFill_Style);
|
||||
}
|
||||
|
||||
this->internalDrawRect(d, r, false, *fillPaint);
|
||||
this->internalDrawRect(r, false, *fillPaint);
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawRect(const SkDraw& d,
|
||||
const SkRect& r,
|
||||
void SkXPSDevice::drawRect(const SkRect& r,
|
||||
const SkPaint& paint) {
|
||||
this->internalDrawRect(d, r, true, paint);
|
||||
this->internalDrawRect(r, true, paint);
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawRRect(const SkDraw& d,
|
||||
const SkRRect& rr,
|
||||
void SkXPSDevice::drawRRect(const SkRRect& rr,
|
||||
const SkPaint& paint) {
|
||||
SkPath path;
|
||||
path.addRRect(rr);
|
||||
this->drawPath(d, path, paint, nullptr, true);
|
||||
this->drawPath(path, paint, nullptr, true);
|
||||
}
|
||||
|
||||
void SkXPSDevice::internalDrawRect(const SkDraw& d,
|
||||
const SkRect& r,
|
||||
static SkIRect size(const SkBaseDevice& dev) { return {0, 0, dev.width(), dev.height()}; }
|
||||
|
||||
void SkXPSDevice::internalDrawRect(const SkRect& r,
|
||||
bool transformRect,
|
||||
const SkPaint& paint) {
|
||||
//Exit early if there is nothing to draw.
|
||||
if (d.fRC->isEmpty() ||
|
||||
if (this->cs().isEmpty(size(*this)) ||
|
||||
(paint.getAlpha() == 0 && paint.isSrcOver())) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Path the rect if we can't optimize it.
|
||||
if (rect_must_be_pathed(paint, *d.fMatrix)) {
|
||||
if (rect_must_be_pathed(paint, this->ctm())) {
|
||||
SkPath tmp;
|
||||
tmp.addRect(r);
|
||||
tmp.setFillType(SkPath::kWinding_FillType);
|
||||
this->drawPath(d, tmp, paint, nullptr, true);
|
||||
this->drawPath(tmp, paint, nullptr, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1218,13 +1228,13 @@ void SkXPSDevice::internalDrawRect(const SkDraw& d,
|
||||
//Set the brushes.
|
||||
BOOL fill = FALSE;
|
||||
BOOL stroke = FALSE;
|
||||
HRV(this->shadePath(shadedPath.get(), paint, *d.fMatrix, &fill, &stroke));
|
||||
HRV(this->shadePath(shadedPath.get(), paint, this->ctm(), &fill, &stroke));
|
||||
|
||||
bool xpsTransformsPath = true;
|
||||
//Transform the geometry.
|
||||
if (transformRect && xpsTransformsPath) {
|
||||
SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
|
||||
HRV(this->createXpsTransform(*d.fMatrix, &xpsTransform));
|
||||
HRV(this->createXpsTransform(this->ctm(), &xpsTransform));
|
||||
if (xpsTransform.get()) {
|
||||
HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()),
|
||||
"Could not set transform for rect.");
|
||||
@ -1243,7 +1253,7 @@ void SkXPSDevice::internalDrawRect(const SkDraw& d,
|
||||
{ r.fRight, r.fTop },
|
||||
};
|
||||
if (!xpsTransformsPath && transformRect) {
|
||||
d.fMatrix->mapPoints(points, SK_ARRAY_COUNT(points));
|
||||
this->ctm().mapPoints(points, SK_ARRAY_COUNT(points));
|
||||
}
|
||||
HRV(this->createXpsQuad(points, stroke, fill, &rectFigure));
|
||||
}
|
||||
@ -1257,7 +1267,7 @@ void SkXPSDevice::internalDrawRect(const SkDraw& d,
|
||||
HRVM(shadedFigures->Append(rectFigure.get()),
|
||||
"Could not add shaded figure for rect.");
|
||||
|
||||
HRV(this->clip(shadedPath.get(), d));
|
||||
HRV(this->clip(shadedPath.get()));
|
||||
|
||||
//Add the shaded path to the current visuals.
|
||||
SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
|
||||
@ -1394,8 +1404,7 @@ void SkXPSDevice::convertToPpm(const SkMaskFilter* filter,
|
||||
clipRect.roundOut(clipIRect);
|
||||
}
|
||||
|
||||
HRESULT SkXPSDevice::applyMask(const SkDraw& d,
|
||||
const SkMask& mask,
|
||||
HRESULT SkXPSDevice::applyMask(const SkMask& mask,
|
||||
const SkVector& ppuScale,
|
||||
IXpsOMPath* shadedPath) {
|
||||
//Get the geometry object.
|
||||
@ -1434,7 +1443,7 @@ HRESULT SkXPSDevice::applyMask(const SkDraw& d,
|
||||
HRM(shadedFigures->Append(shadedFigure.get()),
|
||||
"Could not add mask shaded figure.");
|
||||
|
||||
HR(this->clip(shadedPath, d));
|
||||
HR(this->clip(shadedPath));
|
||||
|
||||
//Add the path to the active visual collection.
|
||||
SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
|
||||
@ -1494,15 +1503,14 @@ HRESULT SkXPSDevice::shadePath(IXpsOMPath* shadedPath,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawPath(const SkDraw& d,
|
||||
const SkPath& platonicPath,
|
||||
void SkXPSDevice::drawPath(const SkPath& platonicPath,
|
||||
const SkPaint& origPaint,
|
||||
const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable) {
|
||||
SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
|
||||
|
||||
// nothing to draw
|
||||
if (d.fRC->isEmpty() ||
|
||||
if (this->cs().isEmpty(size(*this)) ||
|
||||
(paint->getAlpha() == 0 && paint->isSrcOver())) {
|
||||
return;
|
||||
}
|
||||
@ -1512,7 +1520,7 @@ void SkXPSDevice::drawPath(const SkDraw& d,
|
||||
|| paint->getStyle() != SkPaint::kFill_Style;
|
||||
|
||||
//Apply pre-path matrix [Platonic-path -> Skeletal-path].
|
||||
SkMatrix matrix = *d.fMatrix;
|
||||
SkMatrix matrix = this->ctm();
|
||||
SkPath* skeletalPath = const_cast<SkPath*>(&platonicPath);
|
||||
if (prePathMatrix) {
|
||||
if (paintHasPathEffect || paint->getRasterizer()) {
|
||||
@ -1574,7 +1582,7 @@ void SkXPSDevice::drawPath(const SkDraw& d,
|
||||
BOOL stroke;
|
||||
HRV(this->shadePath(shadedPath.get(),
|
||||
*paint,
|
||||
*d.fMatrix,
|
||||
this->ctm(),
|
||||
&fill,
|
||||
&stroke));
|
||||
|
||||
@ -1585,7 +1593,7 @@ void SkXPSDevice::drawPath(const SkDraw& d,
|
||||
this->convertToPpm(filter,
|
||||
&matrix,
|
||||
&ppuScale,
|
||||
d.fRC->getBounds(),
|
||||
this->cs().bounds(size(*this)).roundOut(),
|
||||
&clipIRect);
|
||||
|
||||
SkMask* mask = nullptr;
|
||||
@ -1605,13 +1613,13 @@ void SkXPSDevice::drawPath(const SkDraw& d,
|
||||
|
||||
//[Mask -> Mask]
|
||||
SkMask filteredMask;
|
||||
if (filter && filter->filterMask(&filteredMask, *mask, *d.fMatrix, nullptr)) {
|
||||
if (filter && filter->filterMask(&filteredMask, *mask, this->ctm(), nullptr)) {
|
||||
mask = &filteredMask;
|
||||
}
|
||||
SkAutoMaskFreeImage filteredAmi(filteredMask.fImage);
|
||||
|
||||
//Draw mask.
|
||||
HRV(this->applyMask(d, *mask, ppuScale, shadedPath.get()));
|
||||
HRV(this->applyMask(*mask, ppuScale, shadedPath.get()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1623,7 +1631,7 @@ void SkXPSDevice::drawPath(const SkDraw& d,
|
||||
this->convertToPpm(filter,
|
||||
&matrix,
|
||||
&ppuScale,
|
||||
d.fRC->getBounds(),
|
||||
this->cs().bounds(size(*this)).roundOut(),
|
||||
&clipIRect);
|
||||
|
||||
//[Fillable-path -> Pixel-path]
|
||||
@ -1659,7 +1667,7 @@ void SkXPSDevice::drawPath(const SkDraw& d,
|
||||
SkAutoMaskFreeImage filteredAmi(filteredMask.fImage);
|
||||
|
||||
//Draw mask.
|
||||
HRV(this->applyMask(d, *mask, ppuScale, shadedPath.get()));
|
||||
HRV(this->applyMask(*mask, ppuScale, shadedPath.get()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1734,7 +1742,7 @@ void SkXPSDevice::drawPath(const SkDraw& d,
|
||||
HRV(this->addXpsPathGeometry(shadedFigures.get(),
|
||||
stroke, fill, *devicePath));
|
||||
|
||||
HRV(this->clip(shadedPath.get(), d));
|
||||
HRV(this->clip(shadedPath.get()));
|
||||
|
||||
//Add the path to the active visual collection.
|
||||
SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
|
||||
@ -1744,16 +1752,10 @@ void SkXPSDevice::drawPath(const SkDraw& d,
|
||||
"Could not add shaded path to current visuals.");
|
||||
}
|
||||
|
||||
HRESULT SkXPSDevice::clip(IXpsOMVisual* xpsVisual, const SkDraw& d) {
|
||||
HRESULT SkXPSDevice::clip(IXpsOMVisual* xpsVisual) {
|
||||
SkPath clipPath;
|
||||
if (d.fRC->isBW()) {
|
||||
SkAssertResult(d.fRC->bwRgn().getBoundaryPath(&clipPath));
|
||||
} else {
|
||||
// Don't have a way to turn a AAClip into a path, so we just use the bounds.
|
||||
// TODO: consider using fClipStack instead?
|
||||
clipPath.addRect(SkRect::Make(d.fRC->getBounds()));
|
||||
}
|
||||
|
||||
// clipPath.addRect(this->cs().bounds(size(*this)));
|
||||
(void)this->cs().asPath(&clipPath);
|
||||
return this->clipToPath(xpsVisual, clipPath, XPS_FILL_RULE_EVENODD);
|
||||
}
|
||||
HRESULT SkXPSDevice::clipToPath(IXpsOMVisual* xpsVisual,
|
||||
@ -1782,9 +1784,9 @@ HRESULT SkXPSDevice::clipToPath(IXpsOMVisual* xpsVisual,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawBitmap(const SkDraw& d, const SkBitmap& bitmap,
|
||||
void SkXPSDevice::drawBitmap(const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint& paint) {
|
||||
if (d.fRC->isEmpty()) {
|
||||
if (this->cs().isEmpty(size(*this))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1811,7 +1813,7 @@ void SkXPSDevice::drawBitmap(const SkDraw& d, const SkBitmap& bitmap,
|
||||
"Could not get the figures for bitmap.");
|
||||
|
||||
SkMatrix transform = matrix;
|
||||
transform.postConcat(*d.fMatrix);
|
||||
transform.postConcat(this->ctm());
|
||||
|
||||
SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
|
||||
HRV(this->createXpsTransform(transform, &xpsTransform));
|
||||
@ -1851,12 +1853,10 @@ void SkXPSDevice::drawBitmap(const SkDraw& d, const SkBitmap& bitmap,
|
||||
HRVM(currentVisuals->Append(shadedPath.get()),
|
||||
"Could not add bitmap to current visuals.");
|
||||
|
||||
HRV(this->clip(shadedPath.get(), d));
|
||||
HRV(this->clip(shadedPath.get()));
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap,
|
||||
int x, int y,
|
||||
const SkPaint& paint) {
|
||||
void SkXPSDevice::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& paint) {
|
||||
//TODO: override this for XPS
|
||||
SkDEBUGF(("XPS drawSprite not yet implemented."));
|
||||
}
|
||||
@ -1929,8 +1929,7 @@ HRESULT SkXPSDevice::CreateTypefaceUse(const SkPaint& paint,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SkXPSDevice::AddGlyphs(const SkDraw& d,
|
||||
IXpsOMObjectFactory* xpsFactory,
|
||||
HRESULT SkXPSDevice::AddGlyphs(IXpsOMObjectFactory* xpsFactory,
|
||||
IXpsOMCanvas* canvas,
|
||||
TypefaceUse* font,
|
||||
LPCWSTR text,
|
||||
@ -2001,7 +2000,7 @@ HRESULT SkXPSDevice::AddGlyphs(const SkDraw& d,
|
||||
HRM(canvas->GetVisuals(&visuals), "Could not get glyph canvas visuals.");
|
||||
|
||||
if (!useCanvasForClip) {
|
||||
HR(this->clip(glyphs.get(), d));
|
||||
HR(this->clip(glyphs.get()));
|
||||
HRM(visuals->Append(glyphs.get()), "Could not add glyphs to canvas.");
|
||||
} else {
|
||||
SkTScopedComPtr<IXpsOMCanvas> glyphCanvas;
|
||||
@ -2014,7 +2013,7 @@ HRESULT SkXPSDevice::AddGlyphs(const SkDraw& d,
|
||||
|
||||
HRM(glyphCanvasVisuals->Append(glyphs.get()),
|
||||
"Could not add glyphs to page.");
|
||||
HR(this->clip(glyphCanvas.get(), d));
|
||||
HR(this->clip(glyphCanvas.get()));
|
||||
|
||||
HRM(visuals->Append(glyphCanvas.get()),
|
||||
"Could not add glyph canvas to page.");
|
||||
@ -2091,16 +2090,15 @@ private:
|
||||
GlyphRun* const fXpsGlyphs;
|
||||
};
|
||||
|
||||
void SkXPSDevice::drawText(const SkDraw& d,
|
||||
const void* text, size_t byteLen,
|
||||
void SkXPSDevice::drawText(const void* text, size_t byteLen,
|
||||
SkScalar x, SkScalar y,
|
||||
const SkPaint& paint) {
|
||||
if (byteLen < 1) return;
|
||||
|
||||
if (text_must_be_pathed(paint, *d.fMatrix)) {
|
||||
if (text_must_be_pathed(paint, this->ctm())) {
|
||||
SkPath path;
|
||||
paint.getTextPath(text, byteLen, x, y, &path);
|
||||
this->drawPath(d, path, paint, nullptr, true);
|
||||
this->drawPath(path, paint, nullptr, true);
|
||||
//TODO: add automation "text"
|
||||
return;
|
||||
}
|
||||
@ -2137,8 +2135,7 @@ void SkXPSDevice::drawText(const SkDraw& d,
|
||||
xpsGlyphs[0].horizontalOffset = 0.0f;
|
||||
xpsGlyphs[0].verticalOffset = 0.0f;
|
||||
|
||||
HRV(AddGlyphs(d,
|
||||
this->fXpsFactory.get(),
|
||||
HRV(AddGlyphs(this->fXpsFactory.get(),
|
||||
this->fCurrentXpsCanvas.get(),
|
||||
typeface,
|
||||
nullptr,
|
||||
@ -2146,21 +2143,20 @@ void SkXPSDevice::drawText(const SkDraw& d,
|
||||
&origin,
|
||||
SkScalarToFLOAT(paint.getTextSize()),
|
||||
XPS_STYLE_SIMULATION_NONE,
|
||||
*d.fMatrix,
|
||||
this->ctm(),
|
||||
paint));
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawPosText(const SkDraw& d,
|
||||
const void* text, size_t byteLen,
|
||||
void SkXPSDevice::drawPosText(const void* text, size_t byteLen,
|
||||
const SkScalar pos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint& paint) {
|
||||
if (byteLen < 1) return;
|
||||
|
||||
if (text_must_be_pathed(paint, *d.fMatrix)) {
|
||||
if (text_must_be_pathed(paint, this->ctm())) {
|
||||
SkPath path;
|
||||
//TODO: make this work, Draw currently does not handle as well.
|
||||
//paint.getTextPath(text, byteLength, x, y, &path);
|
||||
//this->drawPath(d, path, paint, nullptr, true);
|
||||
//this->drawPath(path, paint, nullptr, true);
|
||||
//TODO: add automation "text"
|
||||
return;
|
||||
}
|
||||
@ -2197,8 +2193,7 @@ void SkXPSDevice::drawPosText(const SkDraw& d,
|
||||
xpsGlyphs[0].horizontalOffset = 0.0f;
|
||||
xpsGlyphs[0].verticalOffset = 0.0f;
|
||||
|
||||
HRV(AddGlyphs(d,
|
||||
this->fXpsFactory.get(),
|
||||
HRV(AddGlyphs(this->fXpsFactory.get(),
|
||||
this->fCurrentXpsCanvas.get(),
|
||||
typeface,
|
||||
nullptr,
|
||||
@ -2206,24 +2201,18 @@ void SkXPSDevice::drawPosText(const SkDraw& d,
|
||||
&origin,
|
||||
SkScalarToFLOAT(paint.getTextSize()),
|
||||
XPS_STYLE_SIMULATION_NONE,
|
||||
*d.fMatrix,
|
||||
this->ctm(),
|
||||
paint));
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawDevice(const SkDraw& d, SkBaseDevice* dev,
|
||||
void SkXPSDevice::drawDevice( SkBaseDevice* dev,
|
||||
int x, int y,
|
||||
const SkPaint&) {
|
||||
SkXPSDevice* that = static_cast<SkXPSDevice*>(dev);
|
||||
|
||||
SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
|
||||
XPS_MATRIX rawTransform = {
|
||||
1.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
static_cast<FLOAT>(x),
|
||||
static_cast<FLOAT>(y),
|
||||
};
|
||||
// TODO(halcanary): assert that current transform is identity rather than calling setter.
|
||||
XPS_MATRIX rawTransform = {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f};
|
||||
HRVM(this->fXpsFactory->CreateMatrixTransform(&rawTransform, &xpsTransform),
|
||||
"Could not create layer transform.");
|
||||
HRVM(that->fCurrentXpsCanvas->SetTransformLocal(xpsTransform.get()),
|
||||
@ -2256,14 +2245,13 @@ SkBaseDevice* SkXPSDevice::onCreateDevice(const CreateInfo& info, const SkPaint*
|
||||
return dev;
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawOval(const SkDraw& d, const SkRect& o, const SkPaint& p) {
|
||||
void SkXPSDevice::drawOval( const SkRect& o, const SkPaint& p) {
|
||||
SkPath path;
|
||||
path.addOval(o);
|
||||
this->drawPath(d, path, p, nullptr, true);
|
||||
this->drawPath(path, p, nullptr, true);
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawBitmapRect(const SkDraw& draw,
|
||||
const SkBitmap& bitmap,
|
||||
void SkXPSDevice::drawBitmapRect(const SkBitmap& bitmap,
|
||||
const SkRect* src,
|
||||
const SkRect& dst,
|
||||
const SkPaint& paint,
|
||||
@ -2279,6 +2267,6 @@ void SkXPSDevice::drawBitmapRect(const SkDraw& draw,
|
||||
SkPaint paintWithShader(paint);
|
||||
paintWithShader.setStyle(SkPaint::kFill_Style);
|
||||
paintWithShader.setShader(std::move(bitmapShader));
|
||||
this->drawRect(draw, dst, paintWithShader);
|
||||
this->drawRect(dst, paintWithShader);
|
||||
}
|
||||
#endif//defined(SK_BUILD_FOR_WIN32)
|
||||
|
@ -16,9 +16,10 @@
|
||||
#include <XpsObjectModel.h>
|
||||
|
||||
#include "SkAutoCoInitialize.h"
|
||||
#include "SkBitmapDevice.h"
|
||||
#include "SkBitSet.h"
|
||||
#include "SkBitmapDevice.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkClipStackDevice.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPath.h"
|
||||
@ -35,7 +36,7 @@
|
||||
|
||||
The drawing context for the XPS backend.
|
||||
*/
|
||||
class SkXPSDevice : public SkBaseDevice {
|
||||
class SkXPSDevice : public SkClipStackDevice {
|
||||
public:
|
||||
SK_API SkXPSDevice(SkISize);
|
||||
SK_API virtual ~SkXPSDevice();
|
||||
@ -73,79 +74,39 @@ public:
|
||||
bool endPortfolio();
|
||||
|
||||
protected:
|
||||
void drawPaint(const SkDraw&, const SkPaint& paint) override;
|
||||
|
||||
void drawPoints(
|
||||
const SkDraw&,
|
||||
SkCanvas::PointMode mode,
|
||||
size_t count, const SkPoint[],
|
||||
void drawPaint(const SkPaint& paint) override;
|
||||
void drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint[], const SkPaint& paint) override;
|
||||
void drawRect(const SkRect& r,
|
||||
const SkPaint& paint) override;
|
||||
|
||||
void drawRect(
|
||||
const SkDraw&,
|
||||
const SkRect& r,
|
||||
void drawOval(const SkRect& oval,
|
||||
const SkPaint& paint) override;
|
||||
|
||||
void drawRRect(
|
||||
const SkDraw&,
|
||||
const SkRRect&,
|
||||
void drawRRect(const SkRRect& rr,
|
||||
const SkPaint& paint) override;
|
||||
|
||||
void drawPath(
|
||||
const SkDraw&,
|
||||
const SkPath& platonicPath,
|
||||
void drawPath(const SkPath& path,
|
||||
const SkPaint& paint,
|
||||
const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable) override;
|
||||
|
||||
void drawBitmap(
|
||||
const SkDraw&,
|
||||
const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix,
|
||||
const SkPaint& paint) override;
|
||||
|
||||
void drawSprite(
|
||||
const SkDraw&,
|
||||
const SkBitmap& bitmap,
|
||||
int x, int y,
|
||||
const SkPaint& paint) override;
|
||||
|
||||
void drawText(
|
||||
const SkDraw&,
|
||||
const void* text, size_t len,
|
||||
SkScalar x, SkScalar y,
|
||||
const SkPaint& paint) override;
|
||||
|
||||
void drawPosText(
|
||||
const SkDraw&,
|
||||
const void* text, size_t len,
|
||||
const SkMatrix* prePathMatrix = NULL,
|
||||
bool pathIsMutable = false) override;
|
||||
void drawBitmap(const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint& paint) override;
|
||||
void drawSprite(const SkBitmap& bitmap,
|
||||
int x, int y, const SkPaint& paint) override;
|
||||
void drawBitmapRect(const SkBitmap&,
|
||||
const SkRect* srcOrNull, const SkRect& dst,
|
||||
const SkPaint& paint,
|
||||
SkCanvas::SrcRectConstraint) override;
|
||||
void drawText(const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) override;
|
||||
void drawPosText(const void* text, size_t len,
|
||||
const SkScalar pos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint& paint) override;
|
||||
|
||||
void drawVertices(
|
||||
const SkDraw&,
|
||||
SkCanvas::VertexMode,
|
||||
int vertexCount, const SkPoint verts[],
|
||||
const SkPoint texs[], const SkColor colors[],
|
||||
SkBlendMode,
|
||||
void drawVertices(SkCanvas::VertexMode, int vertexCount,
|
||||
const SkPoint verts[], const SkPoint texs[],
|
||||
const SkColor colors[], SkBlendMode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint) override;
|
||||
|
||||
void drawDevice(
|
||||
const SkDraw&,
|
||||
SkBaseDevice* device,
|
||||
int x, int y,
|
||||
const SkPaint& paint) override;
|
||||
|
||||
void drawOval(const SkDraw&, const SkRect&, const SkPaint&) override;
|
||||
|
||||
void drawBitmapRect(const SkDraw&,
|
||||
const SkBitmap&,
|
||||
const SkRect*,
|
||||
const SkRect&,
|
||||
const SkPaint&,
|
||||
SkCanvas::SrcRectConstraint) override;
|
||||
|
||||
void drawDevice(SkBaseDevice*, int x, int y,
|
||||
const SkPaint&) override;
|
||||
|
||||
private:
|
||||
class TypefaceUse : ::SkNoncopyable {
|
||||
@ -198,7 +159,6 @@ private:
|
||||
IXpsOMImageResource** image);
|
||||
|
||||
void internalDrawRect(
|
||||
const SkDraw&,
|
||||
const SkRect& r,
|
||||
bool transformRect,
|
||||
const SkPaint& paint);
|
||||
@ -257,7 +217,6 @@ private:
|
||||
TypefaceUse** fontResource);
|
||||
|
||||
HRESULT AddGlyphs(
|
||||
const SkDraw& d,
|
||||
IXpsOMObjectFactory* xpsFactory,
|
||||
IXpsOMCanvas* canvas,
|
||||
TypefaceUse* font,
|
||||
@ -289,16 +248,14 @@ private:
|
||||
const SkColor color,
|
||||
IXpsOMVisualCollection* visuals);
|
||||
|
||||
HRESULT clip(
|
||||
IXpsOMVisual* xpsVisual,
|
||||
const SkDraw& d);
|
||||
HRESULT clip(IXpsOMVisual* xpsVisual);
|
||||
|
||||
HRESULT clipToPath(
|
||||
IXpsOMVisual* xpsVisual,
|
||||
const SkPath& clipPath,
|
||||
XPS_FILL_RULE fillRule);
|
||||
|
||||
HRESULT drawInverseWindingPath(
|
||||
const SkDraw& d,
|
||||
const SkPath& devicePath,
|
||||
IXpsOMPath* xpsPath);
|
||||
|
||||
@ -315,7 +272,6 @@ private:
|
||||
const SkIRect& clip, SkIRect* clipIRect);
|
||||
|
||||
HRESULT applyMask(
|
||||
const SkDraw& d,
|
||||
const SkMask& mask,
|
||||
const SkVector& ppuScale,
|
||||
IXpsOMPath* shadedPath);
|
||||
@ -326,7 +282,7 @@ private:
|
||||
SkXPSDevice(const SkXPSDevice&);
|
||||
void operator=(const SkXPSDevice&);
|
||||
|
||||
typedef SkBaseDevice INHERITED;
|
||||
typedef SkClipStackDevice INHERITED;
|
||||
};
|
||||
|
||||
#endif // SK_BUILD_FOR_WIN
|
||||
|
@ -30,9 +30,9 @@ public:
|
||||
FakeDevice() : INHERITED(make_bm(100, 100), SkSurfaceProps(0, kUnknown_SkPixelGeometry)) {
|
||||
}
|
||||
|
||||
void drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) override {
|
||||
fLastMatrix = *draw.fMatrix;
|
||||
this->INHERITED::drawRect(draw, r, paint);
|
||||
void drawRect(const SkRect& r, const SkPaint& paint) override {
|
||||
fLastMatrix = this->ctm();
|
||||
this->INHERITED::drawRect(r, paint);
|
||||
}
|
||||
|
||||
SkMatrix fLastMatrix;
|
||||
|
@ -307,7 +307,7 @@ void SkDebugCanvas::drawTo(SkCanvas* originalCanvas, int index, int m) {
|
||||
}
|
||||
if (pathOpsMode) {
|
||||
this->resetClipStackData();
|
||||
const SkClipStack* clipStack = filterCanvas.getClipStack();
|
||||
const SkClipStack* clipStack = nullptr;//HACK filterCanvas.getClipStack();
|
||||
SkClipStack::Iter iter(*clipStack, SkClipStack::Iter::kBottom_IterStart);
|
||||
const SkClipStack::Element* element;
|
||||
SkPath devPath;
|
||||
|
Loading…
Reference in New Issue
Block a user