Revert "Revert[2] "Remove SkDraw from device-draw methods, and enable device-centric clipping."""
This reverts commitcfaa63237b
. Reason for revert: speculative revert to fix Google3 Original change's description: > Revert[2] "Remove SkDraw from device-draw methods, and enable device-centric clipping."" > > passes new (augmented) CanvasClipType unittest > fixed rasterclipstack::setnewsize > > This reverts commitea5e676a7b
. > > 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> > TBR=bsalomon@google.com,reed@google.com,reviews@skia.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=skia: Change-Id: Ibd7ee6383999f008eb6ee59c1c3f1c06a86044ea Reviewed-on: https://skia-review.googlesource.com/9230 Reviewed-by: Cary Clark <caryclark@google.com> Commit-Queue: Cary Clark <caryclark@google.com>
This commit is contained in:
parent
94fc0fe016
commit
baf06bc89a
@ -1359,10 +1359,6 @@ 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:
|
||||
@ -1527,7 +1523,7 @@ private:
|
||||
|
||||
SkBaseDevice* device() const;
|
||||
const SkMatrix& matrix() const;
|
||||
void clip(SkRegion*) const;
|
||||
const SkRasterClip& clip() const;
|
||||
const SkPaint& paint() const;
|
||||
int x() const;
|
||||
int y() const;
|
||||
@ -1549,7 +1545,7 @@ private:
|
||||
|
||||
static void DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
|
||||
SkBaseDevice* dst, const SkIPoint& dstOrigin,
|
||||
const SkMatrix& ctm);
|
||||
const SkMatrix& ctm, const SkClipStack* clipStack);
|
||||
|
||||
enum ShaderOverrideOpacity {
|
||||
kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image)
|
||||
@ -1571,6 +1567,7 @@ private:
|
||||
|
||||
class MCRec;
|
||||
|
||||
sk_sp<SkClipStack> fClipStack;
|
||||
SkDeque fMCStack;
|
||||
// points to top of stack
|
||||
MCRec* fMCRec;
|
||||
@ -1598,7 +1595,9 @@ private:
|
||||
friend class SkSurface_Base;
|
||||
friend class SkSurface_Gpu;
|
||||
|
||||
bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
|
||||
SkIRect fClipRestrictionRect = SkIRect::MakeEmpty();
|
||||
void updateDeviceCMCache();
|
||||
|
||||
void doSave();
|
||||
void checkForDeferredSave();
|
||||
@ -1668,11 +1667,14 @@ private:
|
||||
*/
|
||||
bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint&);
|
||||
|
||||
/**
|
||||
* Returns true if the clip (for any active layer) contains antialiasing.
|
||||
* If the clip is empty, this will return false.
|
||||
/** 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)
|
||||
*/
|
||||
bool androidFramework_isClipAA() const;
|
||||
const SkClipStack* getClipStack() const {
|
||||
return fClipStack.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep track of the device clip bounds and if the matrix is scale-translate. This allows
|
||||
@ -1683,6 +1685,7 @@ 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
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkBitmapDevice::BDDraw : public SkDraw {
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
class ModifiedDraw : public SkDraw {
|
||||
public:
|
||||
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();
|
||||
ModifiedDraw(const SkMatrix& cmt, const SkRasterClip& rc, const SkDraw& draw) : SkDraw(draw) {
|
||||
SkASSERT(cmt == *draw.fMatrix);
|
||||
fRC = &rc;
|
||||
}
|
||||
};
|
||||
#define PREPARE_DRAW(draw) ModifiedDraw(this->ctm(), fRCStack.rc(), draw)
|
||||
#else
|
||||
#define PREPARE_DRAW(draw) draw
|
||||
#endif
|
||||
|
||||
void SkBitmapDevice::drawPaint(const SkPaint& paint) {
|
||||
BDDraw(this).drawPaint(paint);
|
||||
void SkBitmapDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
|
||||
PREPARE_DRAW(draw).drawPaint(paint);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
void SkBitmapDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint pts[], const SkPaint& paint) {
|
||||
BDDraw(this).drawPoints(mode, count, pts, paint, nullptr);
|
||||
PREPARE_DRAW(draw).drawPoints(mode, count, pts, paint, nullptr);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawRect(const SkRect& r, const SkPaint& paint) {
|
||||
BDDraw(this).drawRect(r, paint);
|
||||
void SkBitmapDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) {
|
||||
PREPARE_DRAW(draw).drawRect(r, paint);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawOval(const SkRect& oval, const SkPaint& paint) {
|
||||
void SkBitmapDevice::drawOval(const SkDraw& draw, 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(path, paint, nullptr, true);
|
||||
this->drawPath(draw, path, paint, nullptr, true);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
|
||||
void SkBitmapDevice::drawRRect(const SkDraw& draw, 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(path, paint, nullptr, true);
|
||||
this->drawPath(draw, path, paint, nullptr, true);
|
||||
#else
|
||||
BDDraw(this).drawRRect(rrect, paint);
|
||||
PREPARE_DRAW(draw).drawRRect(rrect, paint);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawPath(const SkPath& path,
|
||||
void SkBitmapDevice::drawPath(const SkDraw& draw, const SkPath& path,
|
||||
const SkPaint& paint, const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable) {
|
||||
BDDraw(this).drawPath(path, paint, prePathMatrix, pathIsMutable);
|
||||
PREPARE_DRAW(draw).drawPath(path, paint, prePathMatrix, pathIsMutable);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawBitmap(const SkBitmap& bitmap,
|
||||
void SkBitmapDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint& paint) {
|
||||
LogDrawScaleFactor(SkMatrix::Concat(this->ctm(), matrix), paint.getFilterQuality());
|
||||
BDDraw(this).drawBitmap(bitmap, matrix, nullptr, paint);
|
||||
LogDrawScaleFactor(SkMatrix::Concat(*draw.fMatrix, matrix), paint.getFilterQuality());
|
||||
PREPARE_DRAW(draw).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 SkBitmap& bitmap,
|
||||
void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, 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 SkBitmap& bitmap,
|
||||
}
|
||||
matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
|
||||
|
||||
LogDrawScaleFactor(SkMatrix::Concat(this->ctm(), matrix), paint.getFilterQuality());
|
||||
LogDrawScaleFactor(SkMatrix::Concat(*draw.fMatrix, matrix), paint.getFilterQuality());
|
||||
|
||||
const SkRect* dstPtr = &dst;
|
||||
const SkBitmap* bitmapPtr = &bitmap;
|
||||
@ -335,7 +335,7 @@ void SkBitmapDevice::drawBitmapRect(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)) {
|
||||
BDDraw(this).drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
|
||||
PREPARE_DRAW(draw).drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -360,43 +360,45 @@ void SkBitmapDevice::drawBitmapRect(const SkBitmap& bitmap,
|
||||
|
||||
// Call ourself, in case the subclass wanted to share this setup code
|
||||
// but handle the drawRect code themselves.
|
||||
this->drawRect(*dstPtr, paintWithShader);
|
||||
this->drawRect(draw, *dstPtr, paintWithShader);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawSprite(const SkBitmap& bitmap,
|
||||
void SkBitmapDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
int x, int y, const SkPaint& paint) {
|
||||
BDDraw(this).drawSprite(bitmap, x, y, paint);
|
||||
PREPARE_DRAW(draw).drawSprite(bitmap, x, y, paint);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawText(const void* text, size_t len,
|
||||
void SkBitmapDevice::drawText(const SkDraw& draw, const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) {
|
||||
BDDraw(this).drawText((const char*)text, len, x, y, paint, &fSurfaceProps);
|
||||
PREPARE_DRAW(draw).drawText((const char*)text, len, x, y, 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::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::drawVertices(SkCanvas::VertexMode vmode,
|
||||
void SkBitmapDevice::drawVertices(const SkDraw& draw, 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) {
|
||||
BDDraw(this).drawVertices(vmode, vertexCount, verts, textures, colors, bmode, indices,
|
||||
indexCount, paint);
|
||||
PREPARE_DRAW(draw).drawVertices(vmode, vertexCount, verts, textures, colors, bmode,
|
||||
indices, indexCount, paint);
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawDevice(SkBaseDevice* device,
|
||||
void SkBitmapDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
|
||||
int x, int y, const SkPaint& paint) {
|
||||
SkASSERT(!paint.getImageFilter());
|
||||
BDDraw(this).drawSprite(static_cast<SkBitmapDevice*>(device)->fBitmap, x, y, paint);
|
||||
PREPARE_DRAW(draw).drawSprite(static_cast<SkBitmapDevice*>(device)->fBitmap, x, y, paint);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkBitmapDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y,
|
||||
void SkBitmapDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x, int y,
|
||||
const SkPaint& paint) {
|
||||
SkASSERT(!srcImg->isTextureBacked());
|
||||
|
||||
@ -405,9 +407,9 @@ void SkBitmapDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y,
|
||||
SkImageFilter* filter = paint.getImageFilter();
|
||||
if (filter) {
|
||||
SkIPoint offset = SkIPoint::Make(0, 0);
|
||||
SkMatrix matrix = this->ctm();
|
||||
SkMatrix matrix = *draw.fMatrix;
|
||||
matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
|
||||
const SkIRect clipBounds = fRCStack.rc().getBounds().makeOffset(-x, -y);
|
||||
const SkIRect clipBounds = draw.fRC->getBounds().makeOffset(-x, -y);
|
||||
sk_sp<SkImageFilterCache> cache(this->getImageFilterCache());
|
||||
SkImageFilter::OutputProperties outputProperties(fBitmap.colorSpace());
|
||||
SkImageFilter::Context ctx(matrix, clipBounds, cache.get(), outputProperties);
|
||||
@ -417,12 +419,12 @@ void SkBitmapDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y,
|
||||
SkPaint tmpUnfiltered(paint);
|
||||
tmpUnfiltered.setImageFilter(nullptr);
|
||||
if (resultImg->getROPixels(&resultBM)) {
|
||||
this->drawSprite(resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
|
||||
this->drawSprite(draw, resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (srcImg->getROPixels(&resultBM)) {
|
||||
this->drawSprite(resultBM, x, y, paint);
|
||||
this->drawSprite(draw, resultBM, x, y, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -509,34 +511,9 @@ 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,6 +21,7 @@
|
||||
#include "SkSize.h"
|
||||
#include "SkSurfaceProps.h"
|
||||
|
||||
class SkDraw;
|
||||
class SkImageFilterCache;
|
||||
class SkMatrix;
|
||||
class SkPaint;
|
||||
@ -69,12 +70,12 @@ protected:
|
||||
and are handling any looping from the paint, and any effects from the
|
||||
DrawFilter.
|
||||
*/
|
||||
void drawPaint(const SkPaint& paint) override;
|
||||
void drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
void drawPaint(const SkDraw&, const SkPaint& paint) override;
|
||||
void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint[], 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;
|
||||
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;
|
||||
|
||||
/**
|
||||
* If pathIsMutable, then the implementation is allowed to cast path to a
|
||||
@ -87,34 +88,34 @@ protected:
|
||||
* affect the geometry/rasterization, then the pre matrix can just be
|
||||
* pre-concated with the current matrix.
|
||||
*/
|
||||
void drawPath(const SkPath&, const SkPaint&, const SkMatrix* prePathMatrix,
|
||||
void drawPath(const SkDraw&, const SkPath&, const SkPaint&, const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable) override;
|
||||
void drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) override;
|
||||
void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) 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;
|
||||
|
||||
/**
|
||||
* The default impl. will create a bitmap-shader from the bitmap,
|
||||
* and call drawRect with it.
|
||||
*/
|
||||
void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&,
|
||||
void drawBitmapRect(const SkDraw&, 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 void* text, size_t len, SkScalar x, SkScalar y,
|
||||
void drawText(const SkDraw&, const void* text, size_t len, SkScalar x, SkScalar y,
|
||||
const SkPaint&) override;
|
||||
void drawPosText(const void* text, size_t len, const SkScalar pos[],
|
||||
void drawPosText(const SkDraw&, const void* text, size_t len, const SkScalar pos[],
|
||||
int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) override;
|
||||
void drawVertices(SkCanvas::VertexMode, int vertexCount, const SkPoint verts[],
|
||||
void drawVertices(const SkDraw&, 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(SkBaseDevice*, int x, int y, const SkPaint&) override;
|
||||
void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) override;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) override;
|
||||
void drawSpecial(const SkDraw&, 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;
|
||||
@ -133,10 +134,7 @@ 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;
|
||||
@ -144,9 +142,8 @@ private:
|
||||
friend class SkDraw;
|
||||
friend class SkDrawIter;
|
||||
friend class SkDeviceFilteredPaint;
|
||||
friend class SkSurface_Raster;
|
||||
|
||||
class BDDraw;
|
||||
friend class SkSurface_Raster;
|
||||
|
||||
// used to change the backend's pixels (and possibly config/rowbytes)
|
||||
// but cannot change the width/height, so there should be no change to
|
||||
|
@ -75,13 +75,9 @@ 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()) {
|
||||
@ -196,8 +192,10 @@ struct DeviceCM {
|
||||
SkMatrix fMatrixStorage;
|
||||
SkMatrix fStashedMatrix; // original CTM; used by imagefilter in saveLayer
|
||||
|
||||
DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, const SkMatrix& stashed)
|
||||
DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas,
|
||||
bool conservativeRasterClip, const SkMatrix& stashed)
|
||||
: fNext(nullptr)
|
||||
, fClip(conservativeRasterClip)
|
||||
, fStashedMatrix(stashed)
|
||||
{
|
||||
SkSafeRef(device);
|
||||
@ -216,6 +214,48 @@ 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.
|
||||
@ -235,15 +275,15 @@ public:
|
||||
reference counted, since the real owner is either our fLayer field,
|
||||
or a previous one in a lower level.)
|
||||
*/
|
||||
DeviceCM* fTopLayer;
|
||||
SkConservativeClip fRasterClip;
|
||||
SkMatrix fMatrix;
|
||||
int fDeferredSaveCount;
|
||||
DeviceCM* fTopLayer;
|
||||
SkRasterClip fRasterClip;
|
||||
SkMatrix fMatrix;
|
||||
int fDeferredSaveCount;
|
||||
|
||||
// This is the current cumulative depth (aggregate of all done translateZ calls)
|
||||
SkScalar fCurDrawDepth;
|
||||
|
||||
MCRec() {
|
||||
MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) {
|
||||
fFilter = nullptr;
|
||||
fLayer = nullptr;
|
||||
fTopLayer = nullptr;
|
||||
@ -280,26 +320,70 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class SkDrawIter {
|
||||
static SkIRect compute_device_bounds(SkBaseDevice* device) {
|
||||
return SkIRect::MakeXYWH(device->getOrigin().x(), device->getOrigin().y(),
|
||||
device->width(), device->height());
|
||||
}
|
||||
|
||||
class SkDrawIter : public SkDraw {
|
||||
public:
|
||||
SkDrawIter(SkCanvas* canvas)
|
||||
: fDevice(nullptr), fCurrLayer(canvas->fMCRec->fTopLayer), fPaint(nullptr)
|
||||
{}
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@ -307,6 +391,9 @@ public:
|
||||
private:
|
||||
const DeviceCM* fCurrLayer;
|
||||
const SkPaint* fPaint; // May be null.
|
||||
SkClipStack* fMultiDeviceCS;
|
||||
|
||||
typedef SkDraw INHERITED;
|
||||
};
|
||||
|
||||
#define FOR_EACH_TOP_DEVICE( code ) \
|
||||
@ -570,6 +657,7 @@ 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
|
||||
@ -583,22 +671,29 @@ 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;
|
||||
new (fMCRec) MCRec(fConservativeRasterClip);
|
||||
fMCRec->fRasterClip.setDeviceClipRestriction(&fClipRestrictionRect);
|
||||
fIsScaleTranslate = true;
|
||||
|
||||
SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage));
|
||||
fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage;
|
||||
new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fMCRec->fMatrix);
|
||||
new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRasterClip,
|
||||
fMCRec->fMatrix);
|
||||
|
||||
fMCRec->fTopLayer = fMCRec->fLayer;
|
||||
|
||||
@ -611,7 +706,9 @@ 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;
|
||||
@ -620,6 +717,7 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
|
||||
SkCanvas::SkCanvas()
|
||||
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
|
||||
, fProps(SkSurfaceProps::kLegacyFontHost_InitType)
|
||||
, fConservativeRasterClip(false)
|
||||
{
|
||||
inc_canvas();
|
||||
|
||||
@ -648,6 +746,7 @@ private:
|
||||
SkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props)
|
||||
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
|
||||
, fProps(SkSurfacePropsCopyOrDefault(props))
|
||||
, fConservativeRasterClip(false)
|
||||
{
|
||||
inc_canvas();
|
||||
|
||||
@ -658,6 +757,7 @@ 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();
|
||||
|
||||
@ -667,6 +767,7 @@ SkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags)
|
||||
SkCanvas::SkCanvas(SkBaseDevice* device)
|
||||
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
|
||||
, fProps(device->surfaceProps())
|
||||
, fConservativeRasterClip(false)
|
||||
{
|
||||
inc_canvas();
|
||||
|
||||
@ -676,6 +777,7 @@ SkCanvas::SkCanvas(SkBaseDevice* device)
|
||||
SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags)
|
||||
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
|
||||
, fProps(device->surfaceProps())
|
||||
, fConservativeRasterClip(false)
|
||||
{
|
||||
inc_canvas();
|
||||
|
||||
@ -685,6 +787,7 @@ 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();
|
||||
|
||||
@ -697,6 +800,7 @@ 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();
|
||||
|
||||
@ -863,6 +967,26 @@ 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();
|
||||
@ -933,7 +1057,10 @@ 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) {
|
||||
@ -964,7 +1091,6 @@ 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();
|
||||
}
|
||||
@ -977,6 +1103,7 @@ 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);
|
||||
}
|
||||
@ -1009,7 +1136,7 @@ int SkCanvas::saveLayer(const SaveLayerRec& origRec) {
|
||||
|
||||
void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
|
||||
SkBaseDevice* dst, const SkIPoint& dstOrigin,
|
||||
const SkMatrix& ctm) {
|
||||
const SkMatrix& ctm, const SkClipStack* clipStack) {
|
||||
SkDraw draw;
|
||||
SkRasterClip rc;
|
||||
rc.setRect(SkIRect::MakeWH(dst->width(), dst->height()));
|
||||
@ -1018,6 +1145,7 @@ void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filt
|
||||
}
|
||||
draw.fMatrix = &SkMatrix::I();
|
||||
draw.fRC = &rc;
|
||||
draw.fClipStack = clipStack;
|
||||
|
||||
SkPaint p;
|
||||
if (filter) {
|
||||
@ -1028,7 +1156,7 @@ void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filt
|
||||
int y = src->getOrigin().y() - dstOrigin.y();
|
||||
auto special = src->snapSpecial();
|
||||
if (special) {
|
||||
dst->drawSpecial(special.get(), x, y, p);
|
||||
dst->drawSpecial(draw, special.get(), x, y, p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1092,6 +1220,8 @@ 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;
|
||||
@ -1135,8 +1265,12 @@ 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, stashedMatrix);
|
||||
new DeviceCM(newDevice.get(), paint, this, fConservativeRasterClip, stashedMatrix);
|
||||
|
||||
// only have a "next" if this new layer doesn't affect the clip (rare)
|
||||
layer->fNext = BoundsAffectsClip(saveLayerFlags) ? nullptr : fMCRec->fTopLayer;
|
||||
@ -1145,9 +1279,10 @@ 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);
|
||||
fMCRec->fMatrix, this->getClipStack());
|
||||
}
|
||||
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
newDevice->setOrigin(fMCRec->fMatrix, ir.fLeft, ir.fTop);
|
||||
|
||||
newDevice->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect);
|
||||
@ -1160,6 +1295,7 @@ 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) {
|
||||
@ -1175,6 +1311,10 @@ 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
|
||||
@ -1185,9 +1325,11 @@ 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
|
||||
@ -1200,6 +1342,7 @@ 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
|
||||
@ -1305,10 +1448,10 @@ void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPa
|
||||
if (filter) {
|
||||
sk_sp<SkSpecialImage> specialImage = srcDev->snapSpecial();
|
||||
if (specialImage) {
|
||||
dstDev->drawSpecial(specialImage.get(), pos.x(), pos.y(), *paint);
|
||||
dstDev->drawSpecial(iter, specialImage.get(), pos.x(), pos.y(), *paint);
|
||||
}
|
||||
} else {
|
||||
dstDev->drawDevice(srcDev, pos.x(), pos.y(), *paint);
|
||||
dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1320,12 +1463,15 @@ 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);
|
||||
}
|
||||
@ -1361,19 +1507,25 @@ 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) {
|
||||
@ -1417,25 +1569,36 @@ 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());
|
||||
}
|
||||
}
|
||||
@ -1453,13 +1616,19 @@ 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) {
|
||||
@ -1490,12 +1659,24 @@ 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());
|
||||
@ -1507,10 +1688,18 @@ 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());
|
||||
}
|
||||
@ -1523,61 +1712,51 @@ 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 {
|
||||
SkBaseDevice* dev = this->getTopDevice();
|
||||
// if no device we return true
|
||||
return !dev || dev->onGetClipType() == SkBaseDevice::kEmpty_ClipType;
|
||||
return fMCRec->fRasterClip.isEmpty();
|
||||
}
|
||||
|
||||
bool SkCanvas::isClipRect() const {
|
||||
SkBaseDevice* dev = this->getTopDevice();
|
||||
// if no device we return false
|
||||
return dev && dev->onGetClipType() == SkBaseDevice::kRect_ClipType;
|
||||
return fMCRec->fRasterClip.isRect();
|
||||
}
|
||||
|
||||
static inline bool is_nan_or_clipped(const Sk4f& devRect, const Sk4f& devClip) {
|
||||
@ -1678,13 +1857,38 @@ SkRect SkCanvas::onGetLocalClipBounds() const {
|
||||
}
|
||||
|
||||
SkIRect SkCanvas::onGetDeviceClipBounds() const {
|
||||
return fMCRec->fRasterClip.getBounds();
|
||||
const SkRasterClip& clip = fMCRec->fRasterClip;
|
||||
if (clip.isEmpty()) {
|
||||
return SkIRect::MakeEmpty();
|
||||
}
|
||||
return clip.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;
|
||||
@ -1954,7 +2158,7 @@ void SkCanvas::internalDrawPaint(const SkPaint& paint) {
|
||||
LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, nullptr, false)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawPaint(looper.paint());
|
||||
iter.fDevice->drawPaint(iter, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -1988,7 +2192,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(mode, count, pts, looper.paint());
|
||||
iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2020,7 +2224,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(r, looper.paint());
|
||||
iter.fDevice->drawRect(iter, r, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2028,7 +2232,7 @@ void SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) {
|
||||
this->predrawNotify(&r, &paint, false);
|
||||
SkDrawIter iter(this);
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawRect(r, paint);
|
||||
iter.fDevice->drawRect(iter, r, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2045,7 +2249,7 @@ void SkCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, ®ionRect)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawRegion(region, looper.paint());
|
||||
iter.fDevice->drawRegion(iter, region, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2063,7 +2267,7 @@ void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, &oval)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawOval(oval, looper.paint());
|
||||
iter.fDevice->drawOval(iter, oval, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2084,7 +2288,7 @@ void SkCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle,
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, &oval)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawArc(oval, startAngle, sweepAngle, useCenter, looper.paint());
|
||||
iter.fDevice->drawArc(iter, oval, startAngle, sweepAngle, useCenter, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2112,7 +2316,7 @@ void SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, &rrect.getBounds())
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawRRect(rrect, looper.paint());
|
||||
iter.fDevice->drawRRect(iter, rrect, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2129,7 +2333,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(outer, inner, looper.paint());
|
||||
iter.fDevice->drawDRRect(iter, outer, inner, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2159,7 +2363,7 @@ void SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, &pathBounds)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawPath(path, looper.paint());
|
||||
iter.fDevice->drawPath(iter, path, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2221,12 +2425,12 @@ void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const S
|
||||
const SkPaint& pnt = looper.paint();
|
||||
if (special) {
|
||||
SkPoint pt;
|
||||
iter.fDevice->ctm().mapXY(x, y, &pt);
|
||||
iter.fDevice->drawSpecial(special.get(),
|
||||
iter.fMatrix->mapXY(x, y, &pt);
|
||||
iter.fDevice->drawSpecial(iter, special.get(),
|
||||
SkScalarRoundToInt(pt.fX),
|
||||
SkScalarRoundToInt(pt.fY), pnt);
|
||||
} else {
|
||||
iter.fDevice->drawImage(image, x, y, pnt);
|
||||
iter.fDevice->drawImage(iter, image, x, y, pnt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2254,7 +2458,7 @@ void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const Sk
|
||||
image->isOpaque())
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawImageRect(image, src, dst, looper.paint(), constraint);
|
||||
iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint(), constraint);
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2302,12 +2506,12 @@ void SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, cons
|
||||
const SkPaint& pnt = looper.paint();
|
||||
if (special) {
|
||||
SkPoint pt;
|
||||
iter.fDevice->ctm().mapXY(x, y, &pt);
|
||||
iter.fDevice->drawSpecial(special.get(),
|
||||
iter.fMatrix->mapXY(x, y, &pt);
|
||||
iter.fDevice->drawSpecial(iter, special.get(),
|
||||
SkScalarRoundToInt(pt.fX),
|
||||
SkScalarRoundToInt(pt.fY), pnt);
|
||||
} else {
|
||||
iter.fDevice->drawBitmap(bitmap, matrix, looper.paint());
|
||||
iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2338,7 +2542,7 @@ void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
|
||||
bitmap.isOpaque())
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawBitmapRect(bitmap, src, dst, looper.paint(), constraint);
|
||||
iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), constraint);
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2370,7 +2574,7 @@ void SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, cons
|
||||
LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawImageNine(image, center, dst, looper.paint());
|
||||
iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2396,7 +2600,7 @@ void SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, c
|
||||
LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawBitmapNine(bitmap, center, dst, looper.paint());
|
||||
iter.fDevice->drawBitmapNine(iter, bitmap, center, dst, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2419,7 +2623,7 @@ void SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice,
|
||||
LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawImageLattice(image, lattice, dst, looper.paint());
|
||||
iter.fDevice->drawImageLattice(iter, image, lattice, dst, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2442,7 +2646,7 @@ void SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattic
|
||||
LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawBitmapLattice(bitmap, lattice, dst, looper.paint());
|
||||
iter.fDevice->drawBitmapLattice(iter, bitmap, lattice, dst, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2474,7 +2678,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(text, byteLength, x, y, dfp.paint());
|
||||
iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2488,7 +2692,7 @@ void SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint
|
||||
|
||||
while (iter.next()) {
|
||||
SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
|
||||
iter.fDevice->drawPosText(text, byteLength, &pos->fX, 2, textOffset,
|
||||
iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 2, textOffset,
|
||||
dfp.paint());
|
||||
}
|
||||
|
||||
@ -2504,7 +2708,7 @@ void SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScala
|
||||
|
||||
while (iter.next()) {
|
||||
SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
|
||||
iter.fDevice->drawPosText(text, byteLength, xpos, 1, textOffset,
|
||||
iter.fDevice->drawPosText(iter, text, byteLength, xpos, 1, textOffset,
|
||||
dfp.paint());
|
||||
}
|
||||
|
||||
@ -2516,7 +2720,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(text, byteLength, path,
|
||||
iter.fDevice->drawTextOnPath(iter, text, byteLength, path,
|
||||
matrix, looper.paint());
|
||||
}
|
||||
|
||||
@ -2532,7 +2736,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(text, byteLength, xform, looper.paint());
|
||||
iter.fDevice->drawTextRSXform(iter, text, byteLength, xform, looper.paint());
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2561,7 +2765,7 @@ void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
|
||||
while (iter.next()) {
|
||||
SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
|
||||
iter.fDevice->drawTextBlob(blob, x, y, dfp.paint(), drawFilter);
|
||||
iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint(), drawFilter);
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2621,7 +2825,7 @@ void SkCanvas::onDrawVertices(VertexMode vmode, int vertexCount,
|
||||
LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr)
|
||||
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawVertices(vmode, vertexCount, verts, texs,
|
||||
iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs,
|
||||
colors, bmode, indices, indexCount,
|
||||
looper.paint());
|
||||
}
|
||||
@ -2636,7 +2840,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(vertices, bmode, looper.paint(), flags);
|
||||
iter.fDevice->drawVerticesObject(iter, vertices, bmode, looper.paint(), flags);
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2676,7 +2880,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(cubics, colors, texCoords, bmode, paint);
|
||||
iter.fDevice->drawPatch(iter, cubics, colors, texCoords, bmode, paint);
|
||||
}
|
||||
|
||||
LOOPER_END
|
||||
@ -2720,7 +2924,7 @@ void SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const
|
||||
|
||||
LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, nullptr)
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawAtlas(atlas, xform, tex, colors, count, bmode, pnt);
|
||||
iter.fDevice->drawAtlas(iter, atlas, xform, tex, colors, count, bmode, pnt);
|
||||
}
|
||||
LOOPER_END
|
||||
}
|
||||
@ -2731,7 +2935,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(rect, key, value);
|
||||
iter.fDevice->drawAnnotation(iter, rect, key, value);
|
||||
}
|
||||
LOOPER_END
|
||||
}
|
||||
@ -3106,7 +3310,7 @@ SkBaseDevice* SkCanvas::LayerIter::device() const {
|
||||
}
|
||||
|
||||
const SkMatrix& SkCanvas::LayerIter::matrix() const {
|
||||
return fImpl->fDevice->ctm();
|
||||
return fImpl->getMatrix();
|
||||
}
|
||||
|
||||
const SkPaint& SkCanvas::LayerIter::paint() const {
|
||||
@ -3117,10 +3321,7 @@ const SkPaint& SkCanvas::LayerIter::paint() const {
|
||||
return *paint;
|
||||
}
|
||||
|
||||
void SkCanvas::LayerIter::clip(SkRegion* rgn) const {
|
||||
return fImpl->fDevice->onAsRgnClip(rgn);
|
||||
}
|
||||
|
||||
const SkRasterClip& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); }
|
||||
int SkCanvas::LayerIter::x() const { return fImpl->getX(); }
|
||||
int SkCanvas::LayerIter::y() const { return fImpl->getY(); }
|
||||
|
||||
|
@ -9,16 +9,6 @@
|
||||
#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();
|
||||
}
|
||||
@ -62,47 +52,13 @@ void SkClipStackDevice::onSetDeviceClipRestriction(SkIRect* clipRestriction) {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public:
|
||||
|
||||
const SkClipStack& cs() const { return fClipStack; }
|
||||
|
||||
SkIRect devClipBounds() const;
|
||||
SkIRect devClipBounds(const SkDraw&) const;
|
||||
|
||||
protected:
|
||||
void onSave() override;
|
||||
@ -29,9 +29,6 @@ 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,36 +71,35 @@ static inline bool is_int(float x) {
|
||||
return x == (float) sk_float_round2int(x);
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawRegion(const SkRegion& region, const SkPaint& paint) {
|
||||
const SkMatrix& ctm = this->ctm();
|
||||
bool isNonTranslate = ctm.getType() & ~(SkMatrix::kTranslate_Mask);
|
||||
void SkBaseDevice::drawRegion(const SkDraw& draw, const SkRegion& region, const SkPaint& paint) {
|
||||
bool isNonTranslate = draw.fMatrix->getType() & ~(SkMatrix::kTranslate_Mask);
|
||||
bool complexPaint = paint.getStyle() != SkPaint::kFill_Style || paint.getMaskFilter() ||
|
||||
paint.getPathEffect();
|
||||
bool antiAlias = paint.isAntiAlias() && (!is_int(ctm.getTranslateX()) ||
|
||||
!is_int(ctm.getTranslateY()));
|
||||
bool antiAlias = paint.isAntiAlias() && (!is_int(draw.fMatrix->getTranslateX()) ||
|
||||
!is_int(draw.fMatrix->getTranslateY()));
|
||||
if (isNonTranslate || complexPaint || antiAlias) {
|
||||
SkPath path;
|
||||
region.getBoundaryPath(&path);
|
||||
return this->drawPath(path, paint, nullptr, false);
|
||||
return this->drawPath(draw, path, paint, nullptr, false);
|
||||
}
|
||||
|
||||
SkRegion::Iterator it(region);
|
||||
while (!it.done()) {
|
||||
this->drawRect(SkRect::Make(it.rect()), paint);
|
||||
this->drawRect(draw, SkRect::Make(it.rect()), paint);
|
||||
it.next();
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawArc(const SkRect& oval, SkScalar startAngle,
|
||||
void SkBaseDevice::drawArc(const SkDraw& draw, 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(path, paint);
|
||||
this->drawPath(draw, path, paint);
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawDRRect(const SkRRect& outer,
|
||||
void SkBaseDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
|
||||
const SkRRect& inner, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
path.addRRect(outer);
|
||||
@ -110,25 +109,25 @@ void SkBaseDevice::drawDRRect(const SkRRect& outer,
|
||||
|
||||
const SkMatrix* preMatrix = nullptr;
|
||||
const bool pathIsMutable = true;
|
||||
this->drawPath(path, paint, preMatrix, pathIsMutable);
|
||||
this->drawPath(draw, path, paint, preMatrix, pathIsMutable);
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||
void SkBaseDevice::drawPatch(const SkDraw& draw, 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, &this->ctm());
|
||||
SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, draw.fMatrix);
|
||||
|
||||
// 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(SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
|
||||
this->drawVertices(draw, SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
|
||||
data.fTexCoords, data.fColors, bmode, data.fIndices, data.fIndexCount,
|
||||
paint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
const SkPaint &paint, SkDrawFilter* drawFilter) {
|
||||
|
||||
SkPaint runPaint = paint;
|
||||
@ -151,14 +150,14 @@ void SkBaseDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
|
||||
switch (it.positioning()) {
|
||||
case SkTextBlob::kDefault_Positioning:
|
||||
this->drawText(it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint);
|
||||
this->drawText(draw, it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint);
|
||||
break;
|
||||
case SkTextBlob::kHorizontal_Positioning:
|
||||
this->drawPosText(it.glyphs(), textLen, it.pos(), 1,
|
||||
this->drawPosText(draw, it.glyphs(), textLen, it.pos(), 1,
|
||||
SkPoint::Make(x, y + offset.y()), runPaint);
|
||||
break;
|
||||
case SkTextBlob::kFull_Positioning:
|
||||
this->drawPosText(it.glyphs(), textLen, it.pos(), 2,
|
||||
this->drawPosText(draw, it.glyphs(), textLen, it.pos(), 2,
|
||||
SkPoint::Make(x, y), runPaint);
|
||||
break;
|
||||
default:
|
||||
@ -172,66 +171,66 @@ void SkBaseDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawImage(const SkImage* image, SkScalar x, SkScalar y,
|
||||
void SkBaseDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint) {
|
||||
SkBitmap bm;
|
||||
if (as_IB(image)->getROPixels(&bm, this->imageInfo().colorSpace())) {
|
||||
this->drawBitmap(bm, SkMatrix::MakeTrans(x, y), paint);
|
||||
this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawImageRect(const SkImage* image, const SkRect* src,
|
||||
void SkBaseDevice::drawImageRect(const SkDraw& draw, 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(bm, src, dst, paint, constraint);
|
||||
this->drawBitmapRect(draw, bm, src, dst, paint, constraint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawImageNine(const SkImage* image, const SkIRect& center,
|
||||
void SkBaseDevice::drawImageNine(const SkDraw& draw, 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(image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
this->drawImageRect(draw, image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
|
||||
void SkBaseDevice::drawBitmapNine(const SkDraw& draw, 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(bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
this->drawBitmapRect(draw, bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawImageLattice(const SkImage* image,
|
||||
void SkBaseDevice::drawImageLattice(const SkDraw& draw, 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(image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
this->drawImageRect(draw, image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawBitmapLattice(const SkBitmap& bitmap,
|
||||
void SkBaseDevice::drawBitmapLattice(const SkDraw& draw, 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(bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
this->drawBitmapRect(draw, bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
|
||||
void SkBaseDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkRSXform xform[],
|
||||
const SkRect tex[], const SkColor colors[], int count,
|
||||
SkBlendMode mode, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
@ -261,23 +260,23 @@ void SkBaseDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
|
||||
path.rewind();
|
||||
path.addPoly(quad, 4, true);
|
||||
path.setConvexity(SkPath::kConvex_Convexity);
|
||||
this->drawPath(path, pnt, nullptr, true);
|
||||
this->drawPath(draw, path, pnt, nullptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawVerticesObject(sk_sp<SkVertices> vertices,
|
||||
void SkBaseDevice::drawVerticesObject(const SkDraw& draw, 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(vertices->mode(), vertices->vertexCount(), vertices->positions(), texs,
|
||||
this->drawVertices(draw, vertices->mode(), vertices->vertexCount(), vertices->positions(), texs,
|
||||
colors, mode, vertices->indices(), vertices->indexCount(), paint);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkBaseDevice::drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) {}
|
||||
void SkBaseDevice::drawSpecial(const SkDraw&, 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; }
|
||||
@ -393,13 +392,13 @@ static void morphpath(SkPath* dst, const SkPath& src, SkPathMeasure& meas,
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawTextOnPath(const void* text, size_t byteLength,
|
||||
void SkBaseDevice::drawTextOnPath(const SkDraw& draw, 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) {
|
||||
if (text == nullptr || byteLength == 0 || draw.fRC->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -434,7 +433,7 @@ void SkBaseDevice::drawTextOnPath(const void* text, size_t byteLength,
|
||||
m.postConcat(*matrix);
|
||||
}
|
||||
morphpath(&tmp, *iterPath, meas, m);
|
||||
this->drawPath(tmp, iter.getPaint(), nullptr, true);
|
||||
this->drawPath(draw, tmp, iter.getPaint(), nullptr, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -449,7 +448,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 void* text, size_t len,
|
||||
void SkBaseDevice::drawTextRSXform(const SkDraw& draw, const void* text, size_t len,
|
||||
const SkRSXform xform[], const SkPaint& paint) {
|
||||
CountTextProc proc = nullptr;
|
||||
switch (paint.getTextEncoding()) {
|
||||
@ -467,15 +466,19 @@ void SkBaseDevice::drawTextRSXform(const void* text, size_t len,
|
||||
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(this->ctm(), localM);
|
||||
currM.setConcat(*draw.fMatrix, localM);
|
||||
localD.fMatrix = &currM;
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
SkAutoDeviceCTMRestore adc(this, currM);
|
||||
#endif
|
||||
|
||||
int subLen = proc((const char*)text);
|
||||
this->drawText(text, subLen, 0, 0, paint);
|
||||
this->drawText(localD, text, subLen, 0, 0, paint);
|
||||
text = (const char*)text + subLen;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "SkSurfaceProps.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkDraw;
|
||||
class SkDrawFilter;
|
||||
class SkImageFilterCache;
|
||||
struct SkIRect;
|
||||
@ -149,37 +150,29 @@ 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 SkPaint& paint) = 0;
|
||||
virtual void drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
virtual void drawPaint(const SkDraw&, const SkPaint& paint) = 0;
|
||||
virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint[], const SkPaint& paint) = 0;
|
||||
virtual void drawRect(const SkRect& r,
|
||||
virtual void drawRect(const SkDraw&, const SkRect& r,
|
||||
const SkPaint& paint) = 0;
|
||||
virtual void drawRegion(const SkRegion& r,
|
||||
virtual void drawRegion(const SkDraw&, const SkRegion& r,
|
||||
const SkPaint& paint);
|
||||
virtual void drawOval(const SkRect& oval,
|
||||
virtual void drawOval(const SkDraw&, 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 SkRect& oval, SkScalar startAngle,
|
||||
virtual void drawArc(const SkDraw&, const SkRect& oval, SkScalar startAngle,
|
||||
SkScalar sweepAngle, bool useCenter, const SkPaint& paint);
|
||||
virtual void drawRRect(const SkRRect& rr,
|
||||
virtual void drawRRect(const SkDraw&, const SkRRect& rr,
|
||||
const SkPaint& paint) = 0;
|
||||
|
||||
// Default impl calls drawPath()
|
||||
virtual void drawDRRect(const SkRRect& outer,
|
||||
virtual void drawDRRect(const SkDraw&, const SkRRect& outer,
|
||||
const SkRRect& inner, const SkPaint&);
|
||||
|
||||
/**
|
||||
@ -193,77 +186,77 @@ protected:
|
||||
* affect the geometry/rasterization, then the pre matrix can just be
|
||||
* pre-concated with the current matrix.
|
||||
*/
|
||||
virtual void drawPath(const SkPath& path,
|
||||
virtual void drawPath(const SkDraw&, const SkPath& path,
|
||||
const SkPaint& paint,
|
||||
const SkMatrix* prePathMatrix = NULL,
|
||||
bool pathIsMutable = false) = 0;
|
||||
virtual void drawBitmap(const SkBitmap& bitmap,
|
||||
virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint& paint) = 0;
|
||||
virtual void drawSprite(const SkBitmap& bitmap,
|
||||
virtual void drawSprite(const SkDraw&, 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 SkBitmap&,
|
||||
virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
|
||||
const SkRect* srcOrNull, const SkRect& dst,
|
||||
const SkPaint& paint,
|
||||
SkCanvas::SrcRectConstraint) = 0;
|
||||
virtual void drawBitmapNine(const SkBitmap&, const SkIRect& center,
|
||||
virtual void drawBitmapNine(const SkDraw&, const SkBitmap&, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
virtual void drawBitmapLattice(const SkBitmap&, const SkCanvas::Lattice&,
|
||||
virtual void drawBitmapLattice(const SkDraw&, const SkBitmap&, const SkCanvas::Lattice&,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
|
||||
virtual void drawImage(const SkImage*, SkScalar x, SkScalar y, const SkPaint&);
|
||||
virtual void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
|
||||
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,
|
||||
const SkPaint&, SkCanvas::SrcRectConstraint);
|
||||
virtual void drawImageNine(const SkImage*, const SkIRect& center,
|
||||
virtual void drawImageNine(const SkDraw&, const SkImage*, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
virtual void drawImageLattice(const SkImage*, const SkCanvas::Lattice&,
|
||||
virtual void drawImageLattice(const SkDraw&, 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 void* text, size_t len,
|
||||
virtual void drawText(const SkDraw&, const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) = 0;
|
||||
virtual void drawPosText(const void* text, size_t len,
|
||||
virtual void drawPosText(const SkDraw&, const void* text, size_t len,
|
||||
const SkScalar pos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint& paint) = 0;
|
||||
virtual void drawVertices(SkCanvas::VertexMode, int vertexCount,
|
||||
virtual void drawVertices(const SkDraw&, 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(sk_sp<SkVertices>, SkBlendMode, const SkPaint&,
|
||||
virtual void drawVerticesObject(const SkDraw&, sk_sp<SkVertices>, SkBlendMode, const SkPaint&,
|
||||
uint32_t flags);
|
||||
// default implementation unrolls the blob runs.
|
||||
virtual void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
|
||||
virtual void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint, SkDrawFilter* drawFilter);
|
||||
// default implementation calls drawVertices
|
||||
virtual void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||
virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
|
||||
const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint);
|
||||
|
||||
// default implementation calls drawPath
|
||||
virtual void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[],
|
||||
virtual void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[],
|
||||
const SkColor[], int count, SkBlendMode, const SkPaint&);
|
||||
|
||||
virtual void drawAnnotation(const SkRect&, const char[], SkData*) {}
|
||||
virtual void drawAnnotation(const SkDraw&, 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(SkBaseDevice*, int x, int y,
|
||||
virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
|
||||
const SkPaint&) = 0;
|
||||
|
||||
virtual void drawTextOnPath(const void* text, size_t len, const SkPath&,
|
||||
virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath&,
|
||||
const SkMatrix*, const SkPaint&);
|
||||
virtual void drawTextRSXform(const void* text, size_t len, const SkRSXform[],
|
||||
virtual void drawTextRSXform(const SkDraw&, const void* text, size_t len, const SkRSXform[],
|
||||
const SkPaint&);
|
||||
|
||||
virtual void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&);
|
||||
virtual void drawSpecial(const SkDraw&, 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,6 +11,7 @@ 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,9 +578,11 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
// then path then
|
||||
path.setIsVolatile((count-1) == i);
|
||||
if (device) {
|
||||
device->drawPath(path, newPaint, &preMatrix, (count-1) == i);
|
||||
device->drawPath(*this, path, newPaint, &preMatrix,
|
||||
(count-1) == i);
|
||||
} else {
|
||||
this->drawPath(path, newPaint, &preMatrix, (count-1) == i);
|
||||
this->drawPath(path, newPaint, &preMatrix,
|
||||
(count-1) == i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -592,7 +594,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
r.fRight = r.fLeft + width;
|
||||
r.fBottom = r.fTop + width;
|
||||
if (device) {
|
||||
device->drawRect(r, newPaint);
|
||||
device->drawRect(*this, r, newPaint);
|
||||
} else {
|
||||
this->drawRect(r, newPaint);
|
||||
}
|
||||
@ -623,7 +625,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
|
||||
if (!pointData.fFirst.isEmpty()) {
|
||||
if (device) {
|
||||
device->drawPath(pointData.fFirst, newP);
|
||||
device->drawPath(*this, pointData.fFirst, newP);
|
||||
} else {
|
||||
this->drawPath(pointData.fFirst, newP);
|
||||
}
|
||||
@ -631,7 +633,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
|
||||
if (!pointData.fLast.isEmpty()) {
|
||||
if (device) {
|
||||
device->drawPath(pointData.fLast, newP);
|
||||
device->drawPath(*this, pointData.fLast, newP);
|
||||
} else {
|
||||
this->drawPath(pointData.fLast, newP);
|
||||
}
|
||||
@ -648,10 +650,11 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
}
|
||||
|
||||
if (device) {
|
||||
device->drawPoints(SkCanvas::kPoints_PointMode,
|
||||
pointData.fNumPoints,
|
||||
pointData.fPoints,
|
||||
newP);
|
||||
device->drawPoints(*this,
|
||||
SkCanvas::kPoints_PointMode,
|
||||
pointData.fNumPoints,
|
||||
pointData.fPoints,
|
||||
newP);
|
||||
} else {
|
||||
this->drawPoints(SkCanvas::kPoints_PointMode,
|
||||
pointData.fNumPoints,
|
||||
@ -673,7 +676,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(r, newP);
|
||||
device->drawRect(*this, r, newP);
|
||||
} else {
|
||||
this->drawRect(r, newP);
|
||||
}
|
||||
@ -695,7 +698,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
path.moveTo(pts[i]);
|
||||
path.lineTo(pts[i+1]);
|
||||
if (device) {
|
||||
device->drawPath(path, p, nullptr, true);
|
||||
device->drawPath(*this, path, p, nullptr, true);
|
||||
} else {
|
||||
this->drawPath(path, p, nullptr, true);
|
||||
}
|
||||
@ -1420,7 +1423,8 @@ void SkDraw::drawText_asPaths(const char text[], size_t byteLength, SkScalar x,
|
||||
while (iter.next(&iterPath, &xpos)) {
|
||||
matrix.postTranslate(xpos - prevXPos, 0);
|
||||
if (iterPath) {
|
||||
this->drawPath(*iterPath, iter.getPaint(), &matrix, false);
|
||||
const SkPaint& pnt = iter.getPaint();
|
||||
this->drawPath(*iterPath, pnt, &matrix, false);
|
||||
}
|
||||
prevXPos = xpos;
|
||||
}
|
||||
|
@ -149,6 +149,7 @@ 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,125 +8,10 @@
|
||||
#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;
|
||||
@ -141,20 +26,23 @@ 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) : fBW(bounds) {
|
||||
SkRasterClip::SkRasterClip(const SkIRect& bounds, bool forceConservativeRects) : fBW(bounds) {
|
||||
fForceConservativeRects = forceConservativeRects;
|
||||
fIsBW = true;
|
||||
fIsEmpty = this->computeIsEmpty(); // bounds might be empty, so compute
|
||||
fIsRect = !fIsEmpty;
|
||||
SkDEBUGCODE(this->validate();)
|
||||
}
|
||||
|
||||
SkRasterClip::SkRasterClip() {
|
||||
SkRasterClip::SkRasterClip(bool forceConservativeRects) {
|
||||
fForceConservativeRects = forceConservativeRects;
|
||||
fIsBW = true;
|
||||
fIsEmpty = true;
|
||||
fIsRect = false;
|
||||
@ -166,6 +54,8 @@ 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;
|
||||
}
|
||||
@ -224,9 +114,65 @@ 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 {
|
||||
@ -244,6 +190,9 @@ 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);
|
||||
@ -257,6 +206,24 @@ 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;
|
||||
@ -279,7 +246,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;
|
||||
SkRasterClip clip(fForceConservativeRects);
|
||||
clip.setPath(devPath, base, doAA);
|
||||
return this->op(clip, op);
|
||||
}
|
||||
@ -289,7 +256,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;
|
||||
SkRasterClip clip(fForceConservativeRects);
|
||||
clip.setPath(devPath, base, doAA);
|
||||
return this->op(clip, op);
|
||||
}
|
||||
@ -364,6 +331,23 @@ 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;
|
||||
@ -443,6 +427,8 @@ const SkRegion& SkRasterClip::forceGetBW() {
|
||||
void SkRasterClip::convertToAA() {
|
||||
AUTO_RASTERCLIP_VALIDATE(*this);
|
||||
|
||||
SkASSERT(!fForceConservativeRects);
|
||||
|
||||
SkASSERT(fIsBW);
|
||||
fAA.setRegion(fBW);
|
||||
fIsBW = false;
|
||||
|
@ -13,39 +13,6 @@
|
||||
|
||||
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.
|
||||
@ -57,8 +24,8 @@ public:
|
||||
*/
|
||||
class SkRasterClip {
|
||||
public:
|
||||
SkRasterClip();
|
||||
SkRasterClip(const SkIRect&);
|
||||
SkRasterClip(bool forceConservativeRects = false);
|
||||
SkRasterClip(const SkIRect&, bool forceConservativeRects = false);
|
||||
SkRasterClip(const SkRegion&);
|
||||
SkRasterClip(const SkRasterClip&);
|
||||
~SkRasterClip();
|
||||
@ -70,6 +37,8 @@ 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; }
|
||||
@ -132,6 +101,7 @@ 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,12 +73,8 @@ public:
|
||||
}
|
||||
|
||||
void setNewSize(int w, int h) {
|
||||
fRootBounds.setXYWH(0, 0, w, h);
|
||||
|
||||
SkASSERT(fStack.count() == 1);
|
||||
Rec& rec = fStack.top();
|
||||
SkASSERT(rec.fDeferredCount == 0);
|
||||
rec.fRC.setRect(fRootBounds);
|
||||
fRootBounds.setXYWH(0, 0, w, h);
|
||||
}
|
||||
|
||||
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()));
|
||||
|
||||
SkASSERT(!op->combineIfPossible(candidate.fOp.get(), *this->caps()));
|
||||
#endif
|
||||
} 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() \
|
||||
#define CHECK_SHOULD_DRAW(draw) \
|
||||
do { \
|
||||
if (gShouldDrawProc && !gShouldDrawProc()) return; \
|
||||
this->prepareDraw(); \
|
||||
this->prepareDraw(draw); \
|
||||
} while (0)
|
||||
#else
|
||||
#define CHECK_SHOULD_DRAW() this->prepareDraw()
|
||||
#define CHECK_SHOULD_DRAW(draw) this->prepareDraw(draw)
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -174,16 +174,17 @@ sk_sp<GrRenderTargetContext> SkGpuDevice::MakeRenderTargetContext(
|
||||
origin, surfaceProps, budgeted);
|
||||
}
|
||||
|
||||
sk_sp<SkSpecialImage> SkGpuDevice::filterTexture(SkSpecialImage* srcImg,
|
||||
sk_sp<SkSpecialImage> SkGpuDevice::filterTexture(const SkDraw& draw,
|
||||
SkSpecialImage* srcImg,
|
||||
int left, int top,
|
||||
SkIPoint* offset,
|
||||
const SkImageFilter* filter) {
|
||||
SkASSERT(srcImg->isTextureBacked());
|
||||
SkASSERT(filter);
|
||||
|
||||
SkMatrix matrix = this->ctm();
|
||||
SkMatrix matrix = *draw.fMatrix;
|
||||
matrix.postTranslate(SkIntToScalar(-left), SkIntToScalar(-top));
|
||||
const SkIRect clipBounds = this->devClipBounds().makeOffset(-left, -top);
|
||||
const SkIRect clipBounds = this->devClipBounds(draw).makeOffset(-left, -top);
|
||||
sk_sp<SkImageFilterCache> cache(this->getImageFilterCache());
|
||||
SkImageFilter::OutputProperties outputProperties(fRenderTargetContext->getColorSpace());
|
||||
SkImageFilter::Context ctx(matrix, clipBounds, cache.get(), outputProperties);
|
||||
@ -232,10 +233,15 @@ 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() {
|
||||
void SkGpuDevice::prepareDraw(const SkDraw& draw) {
|
||||
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() {
|
||||
@ -279,18 +285,18 @@ void SkGpuDevice::replaceRenderTargetContext(bool shouldRetainContent) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkGpuDevice::drawPaint(const SkPaint& paint) {
|
||||
void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPaint", fContext.get());
|
||||
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fRenderTargetContext->drawPaint(fClip, std::move(grPaint), this->ctm());
|
||||
fRenderTargetContext->drawPaint(fClip, std::move(grPaint), *draw.fMatrix);
|
||||
}
|
||||
|
||||
// must be in SkCanvas::PointMode order
|
||||
@ -327,11 +333,11 @@ static bool needs_antialiasing(SkCanvas::PointMode mode, size_t count, const SkP
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawPoints(SkCanvas::PointMode mode,
|
||||
void SkGpuDevice::drawPoints(const SkDraw& draw, 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();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
SkScalar width = paint.getStrokeWidth();
|
||||
if (width < 0) {
|
||||
@ -341,7 +347,7 @@ void SkGpuDevice::drawPoints(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, this->ctm(),
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
@ -350,31 +356,25 @@ void SkGpuDevice::drawPoints(SkCanvas::PointMode mode,
|
||||
path.moveTo(pts[0]);
|
||||
path.lineTo(pts[1]);
|
||||
fRenderTargetContext->drawPath(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
|
||||
this->ctm(), path, style);
|
||||
*draw.fMatrix, path, style);
|
||||
return;
|
||||
}
|
||||
|
||||
SkScalar scales[2];
|
||||
bool isHairline = (0 == width) || (1 == width && this->ctm().getMinMaxScales(scales) &&
|
||||
bool isHairline = (0 == width) || (1 == width && draw.fMatrix->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, 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;
|
||||
(paint.isAntiAlias() && needs_antialiasing(mode, count, pts, *draw.fMatrix))) {
|
||||
draw.drawPoints(mode, count, pts, paint, this);
|
||||
return;
|
||||
}
|
||||
|
||||
GrPrimitiveType primitiveType = gPointMode2PrimitiveType[mode];
|
||||
|
||||
const SkMatrix* viewMatrix = &this->ctm();
|
||||
const SkMatrix* viewMatrix = draw.fMatrix;
|
||||
#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(SkCanvas::PointMode mode,
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkGpuDevice::drawRect(const SkRect& rect, const SkPaint& paint) {
|
||||
void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawRect", fContext.get());
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
|
||||
// A couple reasons we might need to call drawPath.
|
||||
@ -420,37 +420,37 @@ void SkGpuDevice::drawRect(const SkRect& rect, const SkPaint& paint) {
|
||||
path.addRect(rect);
|
||||
GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
|
||||
fClip, path, paint,
|
||||
this->ctm(), nullptr,
|
||||
this->devClipBounds(), true);
|
||||
*draw.fMatrix, nullptr,
|
||||
this->devClipBounds(draw), true);
|
||||
return;
|
||||
}
|
||||
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
GrStyle style(paint);
|
||||
fRenderTargetContext->drawRect(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
|
||||
this->ctm(), rect, &style);
|
||||
*draw.fMatrix, rect, &style);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkGpuDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
|
||||
void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawRRect", fContext.get());
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SkMaskFilter* mf = paint.getMaskFilter();
|
||||
if (mf && mf->asFragmentProcessor(nullptr, nullptr, this->ctm())) {
|
||||
if (mf && mf->asFragmentProcessor(nullptr, nullptr, *draw.fMatrix)) {
|
||||
mf = nullptr; // already handled in SkPaintToGrPaint
|
||||
}
|
||||
|
||||
@ -459,19 +459,19 @@ void SkGpuDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
|
||||
// try to hit the fast path for drawing filtered round rects
|
||||
|
||||
SkRRect devRRect;
|
||||
if (rrect.transform(this->ctm(), &devRRect)) {
|
||||
if (rrect.transform(*draw.fMatrix, &devRRect)) {
|
||||
if (devRRect.allCornersCircular()) {
|
||||
SkRect maskRect;
|
||||
if (mf->canFilterMaskGPU(devRRect, this->devClipBounds(),
|
||||
this->ctm(), &maskRect)) {
|
||||
if (mf->canFilterMaskGPU(devRRect, this->devClipBounds(draw),
|
||||
*draw.fMatrix, &maskRect)) {
|
||||
SkIRect finalIRect;
|
||||
maskRect.roundOut(&finalIRect);
|
||||
|
||||
// we used to test finalIRect for quickReject, but that seems unlikely
|
||||
// given that the original shape was not rejected...
|
||||
|
||||
if (draw.fRC->quickReject(finalIRect)) {
|
||||
// clipped out
|
||||
return;
|
||||
}
|
||||
if (mf->directFilterRRectMaskGPU(fContext.get(), fRenderTargetContext.get(),
|
||||
std::move(grPaint), fClip, this->ctm(),
|
||||
std::move(grPaint), fClip, *draw.fMatrix,
|
||||
style.strokeRec(), rrect, devRRect)) {
|
||||
return;
|
||||
}
|
||||
@ -490,43 +490,43 @@ void SkGpuDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
|
||||
path.addRRect(rrect);
|
||||
GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
|
||||
fClip, path, paint,
|
||||
this->ctm(), nullptr,
|
||||
this->devClipBounds(), true);
|
||||
*draw.fMatrix, nullptr,
|
||||
this->devClipBounds(draw), true);
|
||||
return;
|
||||
}
|
||||
|
||||
SkASSERT(!style.pathEffect());
|
||||
|
||||
fRenderTargetContext->drawRRect(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
|
||||
this->ctm(), rrect, style);
|
||||
*draw.fMatrix, rrect, style);
|
||||
}
|
||||
|
||||
|
||||
void SkGpuDevice::drawDRRect(const SkRRect& outer,
|
||||
void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
|
||||
const SkRRect& inner, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawDRRect", fContext.get());
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
if (outer.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (inner.isEmpty()) {
|
||||
return this->drawRRect(outer, paint);
|
||||
return this->drawRRect(draw, outer, paint);
|
||||
}
|
||||
|
||||
SkStrokeRec stroke(paint);
|
||||
|
||||
if (stroke.isFillStyle() && !paint.getMaskFilter() && !paint.getPathEffect()) {
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fRenderTargetContext->drawDRRect(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
|
||||
this->ctm(), outer, inner);
|
||||
*draw.fMatrix, outer, inner);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -538,78 +538,78 @@ void SkGpuDevice::drawDRRect(const SkRRect& outer,
|
||||
|
||||
GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
|
||||
fClip, path, paint,
|
||||
this->ctm(), nullptr,
|
||||
this->devClipBounds(), true);
|
||||
*draw.fMatrix, nullptr,
|
||||
this->devClipBounds(draw), true);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkGpuDevice::drawRegion(const SkRegion& region, const SkPaint& paint) {
|
||||
void SkGpuDevice::drawRegion(const SkDraw& draw, const SkRegion& region, const SkPaint& paint) {
|
||||
if (paint.getMaskFilter()) {
|
||||
SkPath path;
|
||||
region.getBoundaryPath(&path);
|
||||
return this->drawPath(path, paint, nullptr, false);
|
||||
return this->drawPath(draw, path, paint, nullptr, false);
|
||||
}
|
||||
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fRenderTargetContext->drawRegion(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
|
||||
this->ctm(), region, GrStyle(paint));
|
||||
*draw.fMatrix, region, GrStyle(paint));
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawOval(const SkRect& oval, const SkPaint& paint) {
|
||||
void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawOval", fContext.get());
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(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(path, paint, nullptr, true);
|
||||
this->drawPath(draw, path, paint, nullptr, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (paint.getMaskFilter()) {
|
||||
// The RRect path can handle special case blurring
|
||||
SkRRect rr = SkRRect::MakeOval(oval);
|
||||
return this->drawRRect(rr, paint);
|
||||
return this->drawRRect(draw, rr, paint);
|
||||
}
|
||||
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fRenderTargetContext->drawOval(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
|
||||
this->ctm(), oval, GrStyle(paint));
|
||||
*draw.fMatrix, oval, GrStyle(paint));
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawArc(const SkRect& oval, SkScalar startAngle,
|
||||
void SkGpuDevice::drawArc(const SkDraw& draw, 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();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
if (paint.getMaskFilter()) {
|
||||
this->INHERITED::drawArc(oval, startAngle, sweepAngle, useCenter, paint);
|
||||
this->INHERITED::drawArc(draw, oval, startAngle, sweepAngle, useCenter, paint);
|
||||
return;
|
||||
}
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fRenderTargetContext->drawArc(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
|
||||
this->ctm(), oval, startAngle, sweepAngle, useCenter,
|
||||
*draw.fMatrix, oval, startAngle, sweepAngle, useCenter,
|
||||
GrStyle(paint));
|
||||
}
|
||||
|
||||
@ -617,10 +617,11 @@ void SkGpuDevice::drawArc(const SkRect& oval, SkScalar startAngle,
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
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();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
// Adding support for round capping would require a
|
||||
// GrRenderTargetContext::fillRRectWithLocalMatrix entry point
|
||||
@ -658,7 +659,7 @@ void SkGpuDevice::drawStrokedLine(const SkPoint points[2],
|
||||
|
||||
SkMatrix local = m;
|
||||
|
||||
m.postConcat(this->ctm());
|
||||
m.postConcat(*draw.fMatrix);
|
||||
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), newPaint, m, &grPaint)) {
|
||||
@ -669,7 +670,7 @@ void SkGpuDevice::drawStrokedLine(const SkPoint points[2],
|
||||
fClip, std::move(grPaint), GrBoolToAA(newPaint.isAntiAlias()), m, rect, local);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawPath(const SkPath& origSrcPath,
|
||||
void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
|
||||
const SkPaint& paint, const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
@ -677,40 +678,40 @@ void SkGpuDevice::drawPath(const SkPath& origSrcPath,
|
||||
SkPoint points[2];
|
||||
if (SkPaint::kStroke_Style == paint.getStyle() && paint.getStrokeWidth() > 0 &&
|
||||
!paint.getMaskFilter() && SkPaint::kRound_Cap != paint.getStrokeCap() &&
|
||||
this->ctm().preservesRightAngles() && origSrcPath.isLine(points)) {
|
||||
draw.fMatrix->preservesRightAngles() && origSrcPath.isLine(points)) {
|
||||
// Path-based stroking looks better for thin rects
|
||||
SkScalar strokeWidth = this->ctm().getMaxScale() * paint.getStrokeWidth();
|
||||
SkScalar strokeWidth = draw.fMatrix->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, paint);
|
||||
this->drawStrokedLine(points, draw, paint);
|
||||
return;
|
||||
}
|
||||
}
|
||||
bool isClosed;
|
||||
SkRect rect;
|
||||
if (origSrcPath.isRect(&rect, &isClosed) && isClosed) {
|
||||
this->drawRect(rect, paint);
|
||||
this->drawRect(draw, rect, paint);
|
||||
return;
|
||||
}
|
||||
if (origSrcPath.isOval(&rect)) {
|
||||
this->drawOval(rect, paint);
|
||||
this->drawOval(draw, rect, paint);
|
||||
return;
|
||||
}
|
||||
SkRRect rrect;
|
||||
if (origSrcPath.isRRect(&rrect)) {
|
||||
this->drawRRect(rrect, paint);
|
||||
this->drawRRect(draw, rrect, paint);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPath", fContext.get());
|
||||
|
||||
GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
|
||||
fClip, origSrcPath, paint,
|
||||
this->ctm(), prePathMatrix,
|
||||
this->devClipBounds(), pathIsMutable);
|
||||
*draw.fMatrix, prePathMatrix,
|
||||
this->devClipBounds(draw), pathIsMutable);
|
||||
}
|
||||
|
||||
static const int kBmpSmallTileSize = 1 << 10;
|
||||
@ -856,13 +857,14 @@ bool SkGpuDevice::shouldTileImage(const SkImage* image, const SkRect* srcRectPtr
|
||||
&outClippedSrcRect);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawBitmap(const SkBitmap& bitmap,
|
||||
void SkGpuDevice::drawBitmap(const SkDraw& origDraw,
|
||||
const SkBitmap& bitmap,
|
||||
const SkMatrix& m,
|
||||
const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(origDraw);
|
||||
SkMatrix viewMatrix;
|
||||
viewMatrix.setConcat(this->ctm(), m);
|
||||
viewMatrix.setConcat(*origDraw.fMatrix, m);
|
||||
|
||||
int maxTileSize = fContext->caps()->maxTileSize();
|
||||
|
||||
@ -1119,10 +1121,10 @@ void SkGpuDevice::drawBitmapTile(const SkBitmap& bitmap,
|
||||
fRenderTargetContext->drawRect(fClip, std::move(grPaint), aa, viewMatrix, dstRect);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawSprite(const SkBitmap& bitmap,
|
||||
void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
int left, int top, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawSprite", fContext.get());
|
||||
|
||||
if (fContext->abandoned()) {
|
||||
@ -1134,22 +1136,23 @@ void SkGpuDevice::drawSprite(const SkBitmap& bitmap,
|
||||
return;
|
||||
}
|
||||
|
||||
this->drawSpecial(srcImg.get(), left, top, paint);
|
||||
this->drawSpecial(draw, srcImg.get(), left, top, paint);
|
||||
}
|
||||
|
||||
|
||||
void SkGpuDevice::drawSpecial(SkSpecialImage* special1,
|
||||
void SkGpuDevice::drawSpecial(const SkDraw& draw,
|
||||
SkSpecialImage* special1,
|
||||
int left, int top,
|
||||
const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawSpecial", fContext.get());
|
||||
|
||||
SkIPoint offset = { 0, 0 };
|
||||
|
||||
sk_sp<SkSpecialImage> result;
|
||||
if (paint.getImageFilter()) {
|
||||
result = this->filterTexture(special1, left, top,
|
||||
result = this->filterTexture(draw, special1, left, top,
|
||||
&offset,
|
||||
paint.getImageFilter());
|
||||
if (!result) {
|
||||
@ -1201,11 +1204,11 @@ void SkGpuDevice::drawSpecial(SkSpecialImage* special1,
|
||||
SkRect::Make(subset));
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawBitmapRect(const SkBitmap& bitmap,
|
||||
void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
const SkRect* src, const SkRect& origDst,
|
||||
const SkPaint& paint, SkCanvas::SrcRectConstraint constraint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(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
|
||||
@ -1253,7 +1256,7 @@ void SkGpuDevice::drawBitmapRect(const SkBitmap& bitmap,
|
||||
GrSamplerParams params;
|
||||
bool doBicubic;
|
||||
GrSamplerParams::FilterMode textureFilterMode =
|
||||
GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), this->ctm(), srcToDstMatrix,
|
||||
GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), *draw.fMatrix, srcToDstMatrix,
|
||||
&doBicubic);
|
||||
|
||||
int tileFilterPad;
|
||||
@ -1268,16 +1271,16 @@ void SkGpuDevice::drawBitmapRect(const SkBitmap& bitmap,
|
||||
params.setFilterMode(textureFilterMode);
|
||||
|
||||
int maxTileSizeForFilter = fContext->caps()->maxTileSize() - 2 * tileFilterPad;
|
||||
if (this->shouldTileImageID(bitmap.getGenerationID(), bitmap.getSubset(), this->ctm(),
|
||||
if (this->shouldTileImageID(bitmap.getGenerationID(), bitmap.getSubset(), *draw.fMatrix,
|
||||
srcToDstMatrix, params, src, maxTileSizeForFilter, &tileSize,
|
||||
&clippedSrcRect)) {
|
||||
this->drawTiledBitmap(bitmap, this->ctm(), srcToDstMatrix, *src, clippedSrcRect,
|
||||
this->drawTiledBitmap(bitmap, *draw.fMatrix, srcToDstMatrix, *src, clippedSrcRect,
|
||||
params, paint, constraint, tileSize, doBicubic);
|
||||
return;
|
||||
}
|
||||
}
|
||||
GrBitmapTextureMaker maker(fContext.get(), bitmap);
|
||||
this->drawTextureProducer(&maker, src, dst, constraint, this->ctm(), fClip, paint);
|
||||
this->drawTextureProducer(&maker, src, dst, constraint, *draw.fMatrix, fClip, paint);
|
||||
}
|
||||
|
||||
sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkBitmap& bitmap) {
|
||||
@ -1346,7 +1349,7 @@ sk_sp<SkSpecialImage> SkGpuDevice::snapSpecial() {
|
||||
&this->surfaceProps());
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawDevice(SkBaseDevice* device,
|
||||
void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
|
||||
int left, int top, const SkPaint& paint) {
|
||||
SkASSERT(!paint.getImageFilter());
|
||||
|
||||
@ -1355,7 +1358,7 @@ void SkGpuDevice::drawDevice(SkBaseDevice* device,
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawDevice", fContext.get());
|
||||
|
||||
// drawDevice is defined to be in device coords.
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
SkGpuDevice* dev = static_cast<SkGpuDevice*>(device);
|
||||
sk_sp<SkSpecialImage> srcImg(dev->snapSpecial());
|
||||
@ -1363,17 +1366,17 @@ void SkGpuDevice::drawDevice(SkBaseDevice* device,
|
||||
return;
|
||||
}
|
||||
|
||||
this->drawSpecial(srcImg.get(), left, top, paint);
|
||||
this->drawSpecial(draw, srcImg.get(), left, top, paint);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawImage(const SkImage* image, SkScalar x, SkScalar y,
|
||||
void SkGpuDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
SkMatrix viewMatrix = this->ctm();
|
||||
SkMatrix viewMatrix = *draw.fMatrix;
|
||||
viewMatrix.preTranslate(x, y);
|
||||
uint32_t pinnedUniqueID;
|
||||
if (sk_sp<GrTexture> tex = as_IB(image)->refPinnedTexture(&pinnedUniqueID)) {
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
GrTextureAdjuster adjuster(tex.get(), image->alphaType(), image->bounds(), pinnedUniqueID,
|
||||
as_IB(image)->onImageInfo().colorSpace());
|
||||
this->drawTextureProducer(&adjuster, nullptr, nullptr, SkCanvas::kFast_SrcRectConstraint,
|
||||
@ -1382,66 +1385,66 @@ void SkGpuDevice::drawImage(const SkImage* image, SkScalar x, SkScalar y,
|
||||
} else {
|
||||
SkBitmap bm;
|
||||
if (this->shouldTileImage(image, nullptr, SkCanvas::kFast_SrcRectConstraint,
|
||||
paint.getFilterQuality(), this->ctm(), SkMatrix::I())) {
|
||||
paint.getFilterQuality(), *draw.fMatrix, 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(bm, SkMatrix::MakeTrans(x, y), paint);
|
||||
this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
|
||||
} else if (SkImageCacherator* cacher = as_IB(image)->peekCacherator()) {
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(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(bm, SkMatrix::MakeTrans(x, y), paint);
|
||||
this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawImageRect(const SkImage* image, const SkRect* src,
|
||||
void SkGpuDevice::drawImageRect(const SkDraw& draw, 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();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
GrTextureAdjuster adjuster(tex.get(), image->alphaType(), image->bounds(), pinnedUniqueID,
|
||||
as_IB(image)->onImageInfo().colorSpace());
|
||||
this->drawTextureProducer(&adjuster, src, &dst, constraint, this->ctm(), fClip, paint);
|
||||
this->drawTextureProducer(&adjuster, src, &dst, constraint, *draw.fMatrix, 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(), this->ctm(),
|
||||
if (this->shouldTileImage(image, src, constraint, paint.getFilterQuality(), *draw.fMatrix,
|
||||
srcToDstRect)) {
|
||||
// only support tiling as bitmap at the moment, so force raster-version
|
||||
if (!as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
|
||||
return;
|
||||
}
|
||||
this->drawBitmapRect(bm, src, dst, paint, constraint);
|
||||
this->drawBitmapRect(draw, bm, src, dst, paint, constraint);
|
||||
} else if (SkImageCacherator* cacher = as_IB(image)->peekCacherator()) {
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
GrImageTextureMaker maker(fContext.get(), cacher, image, SkImage::kAllow_CachingHint);
|
||||
this->drawTextureProducer(&maker, src, &dst, constraint, this->ctm(), fClip, paint);
|
||||
this->drawTextureProducer(&maker, src, &dst, constraint, *draw.fMatrix, fClip, paint);
|
||||
} else if (as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
|
||||
this->drawBitmapRect(bm, src, dst, paint, constraint);
|
||||
this->drawBitmapRect(draw, bm, src, dst, paint, constraint);
|
||||
}
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawProducerNine(GrTextureProducer* producer,
|
||||
void SkGpuDevice::drawProducerNine(const SkDraw& draw, GrTextureProducer* producer,
|
||||
const SkIRect& center, const SkRect& dst, const SkPaint& paint) {
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawProducerNine", fContext.get());
|
||||
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
bool useFallback = paint.getMaskFilter() || paint.isAntiAlias() ||
|
||||
fRenderTargetContext->isUnifiedMultisampled();
|
||||
bool doBicubic;
|
||||
GrSamplerParams::FilterMode textureFilterMode =
|
||||
GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), this->ctm(), SkMatrix::I(),
|
||||
GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), *draw.fMatrix, SkMatrix::I(),
|
||||
&doBicubic);
|
||||
if (useFallback || doBicubic || GrSamplerParams::kNone_FilterMode != textureFilterMode) {
|
||||
SkLatticeIter iter(producer->width(), producer->height(), center, dst);
|
||||
@ -1449,7 +1452,7 @@ void SkGpuDevice::drawProducerNine(GrTextureProducer* producer,
|
||||
SkRect srcR, dstR;
|
||||
while (iter.next(&srcR, &dstR)) {
|
||||
this->drawTextureProducer(producer, &srcR, &dstR, SkCanvas::kStrict_SrcRectConstraint,
|
||||
this->ctm(), fClip, paint);
|
||||
*draw.fMatrix, fClip, paint);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1462,51 +1465,51 @@ void SkGpuDevice::drawProducerNine(GrTextureProducer* producer,
|
||||
&kMode, fRenderTargetContext->getColorSpace()));
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaintWithTexture(this->context(), fRenderTargetContext.get(), paint,
|
||||
this->ctm(), std::move(fp), producer->isAlphaOnly(),
|
||||
*draw.fMatrix, 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), this->ctm(),
|
||||
fRenderTargetContext->drawImageLattice(fClip, std::move(grPaint), *draw.fMatrix,
|
||||
producer->width(), producer->height(), std::move(iter),
|
||||
dst);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawImageNine(const SkImage* image,
|
||||
void SkGpuDevice::drawImageNine(const SkDraw& draw, 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();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
GrTextureAdjuster adjuster(tex.get(), image->alphaType(), image->bounds(), pinnedUniqueID,
|
||||
as_IB(image)->onImageInfo().colorSpace());
|
||||
this->drawProducerNine(&adjuster, center, dst, paint);
|
||||
this->drawProducerNine(draw, &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(&maker, center, dst, paint);
|
||||
this->drawProducerNine(draw, &maker, center, dst, paint);
|
||||
} else if (as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
|
||||
this->drawBitmapNine(bm, center, dst, paint);
|
||||
this->drawBitmapNine(draw, bm, center, dst, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
|
||||
void SkGpuDevice::drawBitmapNine(const SkDraw& draw, const SkBitmap& bitmap, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GrBitmapTextureMaker maker(fContext.get(), bitmap);
|
||||
this->drawProducerNine(&maker, center, dst, paint);
|
||||
this->drawProducerNine(draw, &maker, center, dst, paint);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawProducerLattice(GrTextureProducer* producer,
|
||||
void SkGpuDevice::drawProducerLattice(const SkDraw& draw, GrTextureProducer* producer,
|
||||
const SkCanvas::Lattice& lattice, const SkRect& dst,
|
||||
const SkPaint& paint) {
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawProducerLattice", fContext.get());
|
||||
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
static const GrSamplerParams::FilterMode kMode = GrSamplerParams::kNone_FilterMode;
|
||||
sk_sp<GrFragmentProcessor> fp(
|
||||
@ -1516,45 +1519,45 @@ void SkGpuDevice::drawProducerLattice(GrTextureProducer* producer,
|
||||
&kMode, fRenderTargetContext->getColorSpace()));
|
||||
GrPaint grPaint;
|
||||
if (!SkPaintToGrPaintWithTexture(this->context(), fRenderTargetContext.get(), paint,
|
||||
this->ctm(), std::move(fp), producer->isAlphaOnly(),
|
||||
*draw.fMatrix, std::move(fp), producer->isAlphaOnly(),
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<SkLatticeIter> iter(
|
||||
new SkLatticeIter(lattice, dst));
|
||||
fRenderTargetContext->drawImageLattice(fClip, std::move(grPaint), this->ctm(),
|
||||
fRenderTargetContext->drawImageLattice(fClip, std::move(grPaint), *draw.fMatrix,
|
||||
producer->width(), producer->height(), std::move(iter),
|
||||
dst);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawImageLattice(const SkImage* image,
|
||||
void SkGpuDevice::drawImageLattice(const SkDraw& draw, 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();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
GrTextureAdjuster adjuster(tex.get(), image->alphaType(), image->bounds(), pinnedUniqueID,
|
||||
as_IB(image)->onImageInfo().colorSpace());
|
||||
this->drawProducerLattice(&adjuster, lattice, dst, paint);
|
||||
this->drawProducerLattice(draw, &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(&maker, lattice, dst, paint);
|
||||
this->drawProducerLattice(draw, &maker, lattice, dst, paint);
|
||||
} else if (as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
|
||||
this->drawBitmapLattice(bm, lattice, dst, paint);
|
||||
this->drawBitmapLattice(draw, bm, lattice, dst, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawBitmapLattice(const SkBitmap& bitmap,
|
||||
void SkGpuDevice::drawBitmapLattice(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
const SkCanvas::Lattice& lattice, const SkRect& dst,
|
||||
const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GrBitmapTextureMaker maker(fContext.get(), bitmap);
|
||||
this->drawProducerLattice(&maker, lattice, dst, paint);
|
||||
this->drawProducerLattice(draw, &maker, lattice, dst, paint);
|
||||
}
|
||||
|
||||
bool init_vertices_paint(const SkPaint& skPaint, const SkMatrix& matrix, SkBlendMode bmode,
|
||||
@ -1582,14 +1585,14 @@ bool init_vertices_paint(const SkPaint& skPaint, const SkMatrix& matrix, SkBlend
|
||||
}
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawVertices(SkCanvas::VertexMode vmode,
|
||||
void SkGpuDevice::drawVertices(const SkDraw& draw, 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();
|
||||
CHECK_SHOULD_DRAW(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.
|
||||
@ -1639,7 +1642,7 @@ void SkGpuDevice::drawVertices(SkCanvas::VertexMode vmode,
|
||||
}
|
||||
fRenderTargetContext->drawVertices(fClip,
|
||||
std::move(grPaint),
|
||||
this->ctm(),
|
||||
*draw.fMatrix,
|
||||
kLines_GrPrimitiveType,
|
||||
vertexCount,
|
||||
vertices,
|
||||
@ -1653,13 +1656,13 @@ void SkGpuDevice::drawVertices(SkCanvas::VertexMode vmode,
|
||||
GrPrimitiveType primType = SkVertexModeToGrPrimitiveType(vmode);
|
||||
|
||||
GrPaint grPaint;
|
||||
if (!init_vertices_paint(paint, this->ctm(), bmode, SkToBool(texs), SkToBool(colors),
|
||||
if (!init_vertices_paint(paint, *draw.fMatrix, bmode, SkToBool(texs), SkToBool(colors),
|
||||
fRenderTargetContext.get(), &grPaint)) {
|
||||
return;
|
||||
}
|
||||
fRenderTargetContext->drawVertices(fClip,
|
||||
std::move(grPaint),
|
||||
this->ctm(),
|
||||
*draw.fMatrix,
|
||||
primType,
|
||||
vertexCount,
|
||||
vertices,
|
||||
@ -1670,10 +1673,10 @@ void SkGpuDevice::drawVertices(SkCanvas::VertexMode vmode,
|
||||
GrRenderTargetContext::ColorArrayType::kSkColor);
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawVerticesObject(sk_sp<SkVertices> vertices,
|
||||
void SkGpuDevice::drawVerticesObject(const SkDraw& draw, sk_sp<SkVertices> vertices,
|
||||
SkBlendMode mode, const SkPaint& paint, uint32_t flags) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawVerticesObject", fContext.get());
|
||||
|
||||
SkASSERT(vertices);
|
||||
@ -1682,30 +1685,30 @@ void SkGpuDevice::drawVerticesObject(sk_sp<SkVertices> vertices,
|
||||
bool hasTexs = vertices->hasTexCoords() & !(SkCanvas::kIgnoreTexCoords_VerticesFlag & flags);
|
||||
if (!hasTexs && !hasColors) {
|
||||
// The dreaded wireframe mode. Fallback to drawVertices and go so slooooooow.
|
||||
this->drawVertices(vertices->mode(), vertices->vertexCount(), vertices->positions(),
|
||||
this->drawVertices(draw, vertices->mode(), vertices->vertexCount(), vertices->positions(),
|
||||
nullptr, nullptr, mode, vertices->indices(), vertices->indexCount(),
|
||||
paint);
|
||||
}
|
||||
if (!init_vertices_paint(paint, this->ctm(), mode, hasTexs, hasColors,
|
||||
if (!init_vertices_paint(paint, *draw.fMatrix, mode, hasTexs, hasColors,
|
||||
fRenderTargetContext.get(), &grPaint)) {
|
||||
return;
|
||||
}
|
||||
fRenderTargetContext->drawVertices(fClip, std::move(grPaint), this->ctm(),
|
||||
fRenderTargetContext->drawVertices(fClip, std::move(grPaint), *draw.fMatrix,
|
||||
std::move(vertices), flags);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkGpuDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
|
||||
void SkGpuDevice::drawAtlas(const SkDraw& draw, 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(atlas, xform, texRect, colors, count, mode, paint);
|
||||
this->INHERITED::drawAtlas(draw, atlas, xform, texRect, colors, count, mode, paint);
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawText", fContext.get());
|
||||
|
||||
SkPaint p(paint);
|
||||
@ -1714,58 +1717,58 @@ void SkGpuDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
|
||||
GrPaint grPaint;
|
||||
if (colors) {
|
||||
if (!SkPaintToGrPaintWithXfermode(this->context(), fRenderTargetContext.get(), p,
|
||||
this->ctm(), (SkBlendMode)mode, true, &grPaint)) {
|
||||
*draw.fMatrix, (SkBlendMode)mode, true, &grPaint)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), p, this->ctm(),
|
||||
if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), p, *draw.fMatrix,
|
||||
&grPaint)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SkDEBUGCODE(this->validate();)
|
||||
fRenderTargetContext->drawAtlas(fClip, std::move(grPaint), this->ctm(), count, xform, texRect,
|
||||
fRenderTargetContext->drawAtlas(fClip, std::move(grPaint), *draw.fMatrix, count, xform, texRect,
|
||||
colors);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkGpuDevice::drawText(const void* text,
|
||||
void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
|
||||
size_t byteLength, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
CHECK_SHOULD_DRAW();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawText", fContext.get());
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
fRenderTargetContext->drawText(fClip, paint, this->ctm(),
|
||||
(const char*)text, byteLength, x, y, this->devClipBounds());
|
||||
fRenderTargetContext->drawText(fClip, paint, *draw.fMatrix,
|
||||
(const char*)text, byteLength, x, y, this->devClipBounds(draw));
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawPosText(const void* text, size_t byteLength,
|
||||
void SkGpuDevice::drawPosText(const SkDraw& draw, 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();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
fRenderTargetContext->drawPosText(fClip, paint, this->ctm(),
|
||||
fRenderTargetContext->drawPosText(fClip, paint, *draw.fMatrix,
|
||||
(const char*)text, byteLength, pos, scalarsPerPos, offset,
|
||||
this->devClipBounds());
|
||||
this->devClipBounds(draw));
|
||||
}
|
||||
|
||||
void SkGpuDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
void SkGpuDevice::drawTextBlob(const SkDraw& draw, 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();
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
fRenderTargetContext->drawTextBlob(fClip, paint, this->ctm(),
|
||||
blob, x, y, drawFilter, this->devClipBounds());
|
||||
fRenderTargetContext->drawTextBlob(fClip, paint, *draw.fMatrix,
|
||||
blob, x, y, drawFilter, this->devClipBounds(draw));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -65,55 +65,55 @@ public:
|
||||
|
||||
GrRenderTargetContext* accessRenderTargetContext() override;
|
||||
|
||||
void drawPaint(const SkPaint& paint) override;
|
||||
void drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint[],
|
||||
void drawPaint(const SkDraw&, const SkPaint& paint) override;
|
||||
void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, const SkPoint[],
|
||||
const SkPaint& paint) override;
|
||||
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,
|
||||
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,
|
||||
const SkPaint& paint) override;
|
||||
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,
|
||||
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,
|
||||
bool useCenter, const SkPaint& paint) override;
|
||||
void drawPath(const SkPath& path, const SkPaint& paint,
|
||||
void drawPath(const SkDraw&, const SkPath& path, const SkPaint& paint,
|
||||
const SkMatrix* prePathMatrix, bool pathIsMutable) override;
|
||||
void drawBitmap(const SkBitmap& bitmap, const SkMatrix&,
|
||||
void drawBitmap(const SkDraw&, const SkBitmap& bitmap, const SkMatrix&,
|
||||
const SkPaint&) override;
|
||||
void drawBitmapRect(const SkBitmap&, const SkRect* srcOrNull, const SkRect& dst,
|
||||
void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect* srcOrNull, const SkRect& dst,
|
||||
const SkPaint& paint, SkCanvas::SrcRectConstraint) override;
|
||||
void drawSprite(const SkBitmap& bitmap, int x, int y,
|
||||
void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
|
||||
const SkPaint& paint) override;
|
||||
void drawText(const void* text, size_t len, SkScalar x, SkScalar y,
|
||||
void drawText(const SkDraw&, const void* text, size_t len, SkScalar x, SkScalar y,
|
||||
const SkPaint&) override;
|
||||
void drawPosText(const void* text, size_t len, const SkScalar pos[],
|
||||
void drawPosText(const SkDraw&, const void* text, size_t len, const SkScalar pos[],
|
||||
int scalarsPerPos, const SkPoint& offset, const SkPaint&) override;
|
||||
void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
|
||||
void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint, SkDrawFilter* drawFilter) override;
|
||||
void drawVertices(SkCanvas::VertexMode, int vertexCount, const SkPoint verts[],
|
||||
void drawVertices(const SkDraw&, 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(sk_sp<SkVertices>, SkBlendMode, const SkPaint&,
|
||||
void drawVerticesObject(const SkDraw&, sk_sp<SkVertices>, SkBlendMode, const SkPaint&,
|
||||
uint32_t flags) override;
|
||||
void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[],
|
||||
void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[],
|
||||
const SkColor[], int count, SkBlendMode, const SkPaint&) override;
|
||||
void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override;
|
||||
void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) override;
|
||||
|
||||
void drawImage(const SkImage*, SkScalar x, SkScalar y, const SkPaint&) override;
|
||||
void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
|
||||
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,
|
||||
const SkPaint&, SkCanvas::SrcRectConstraint) override;
|
||||
|
||||
void drawImageNine(const SkImage* image, const SkIRect& center,
|
||||
void drawImageNine(const SkDraw& draw, const SkImage* image, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint& paint) override;
|
||||
void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
|
||||
void drawBitmapNine(const SkDraw& draw, const SkBitmap& bitmap, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint& paint) override;
|
||||
|
||||
void drawImageLattice(const SkImage*, const SkCanvas::Lattice&,
|
||||
void drawImageLattice(const SkDraw&, const SkImage*, const SkCanvas::Lattice&,
|
||||
const SkRect& dst, const SkPaint&) override;
|
||||
void drawBitmapLattice(const SkBitmap&, const SkCanvas::Lattice&,
|
||||
void drawBitmapLattice(const SkDraw&, const SkBitmap&, const SkCanvas::Lattice&,
|
||||
const SkRect& dst, const SkPaint&) override;
|
||||
|
||||
void drawSpecial(SkSpecialImage*,
|
||||
void drawSpecial(const SkDraw&, 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();
|
||||
void prepareDraw(const SkDraw&);
|
||||
|
||||
/**
|
||||
* Helper functions called by drawBitmapCommon. By the time these are called the SkDraw's
|
||||
@ -179,7 +179,8 @@ private:
|
||||
SkCanvas::SrcRectConstraint constraint, SkFilterQuality quality,
|
||||
const SkMatrix& viewMatrix, const SkMatrix& srcToDstRect) const;
|
||||
|
||||
sk_sp<SkSpecialImage> filterTexture(SkSpecialImage*,
|
||||
sk_sp<SkSpecialImage> filterTexture(const SkDraw&,
|
||||
SkSpecialImage*,
|
||||
int left, int top,
|
||||
SkIPoint* offset,
|
||||
const SkImageFilter* filter);
|
||||
@ -227,14 +228,14 @@ private:
|
||||
bool drawFilledDRRect(const SkMatrix& viewMatrix, const SkRRect& outer,
|
||||
const SkRRect& inner, const SkPaint& paint);
|
||||
|
||||
void drawProducerNine(GrTextureProducer*, const SkIRect& center,
|
||||
void drawProducerNine(const SkDraw&, GrTextureProducer*, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
|
||||
void drawProducerLattice(GrTextureProducer*, const SkCanvas::Lattice& lattice,
|
||||
void drawProducerLattice(const SkDraw&, 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 SkPaint&);
|
||||
void drawStrokedLine(const SkPoint pts[2], const SkDraw&, const SkPaint&);
|
||||
|
||||
static sk_sp<GrRenderTargetContext> MakeRenderTargetContext(GrContext*,
|
||||
SkBudgeted,
|
||||
|
@ -48,23 +48,6 @@
|
||||
|
||||
// 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) {
|
||||
@ -398,26 +381,23 @@ 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 SkClipStack& clipStack,
|
||||
const SkMatrix& matrix,
|
||||
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* 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,
|
||||
const SkMatrix& matrix,
|
||||
const SkPaint& paint, bool hasText = false)
|
||||
: fDevice(device),
|
||||
fContentEntry(nullptr),
|
||||
fBlendMode(SkBlendMode::kSrcOver),
|
||||
fDstFormXObject(nullptr) {
|
||||
init(clipStack, matrix, paint, hasText);
|
||||
}
|
||||
ScopedContentEntry(SkPDFDevice* dev, const SkPaint& paint, bool hasText = false)
|
||||
: ScopedContentEntry(dev, dev->cs(), dev->ctm(), paint, hasText) {}
|
||||
|
||||
~ScopedContentEntry() {
|
||||
if (fContentEntry) {
|
||||
@ -471,6 +451,18 @@ 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);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -511,44 +503,25 @@ void SkPDFDevice::cleanUp() {
|
||||
fShaderResources.unrefAll();
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawAnnotation(const SkRect& rect, const char key[], SkData* value) {
|
||||
void SkPDFDevice::drawAnnotation(const SkDraw& d, const SkRect& rect, const char key[],
|
||||
SkData* value) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
if (rect.isEmpty()) {
|
||||
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);
|
||||
this->handlePointAnnotation({ rect.x(), rect.y() }, *d.fMatrix, key, value);
|
||||
} else {
|
||||
this->handleRectAnnotation(rect, d, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawPaint(const SkPaint& paint) {
|
||||
void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) {
|
||||
SkPaint newPaint = paint;
|
||||
replace_srcmode_on_opaque_paint(&newPaint);
|
||||
|
||||
newPaint.setStyle(SkPaint::kFill_Style);
|
||||
ScopedContentEntry content(this, newPaint);
|
||||
this->internalDrawPaint(newPaint, content.entry());
|
||||
ScopedContentEntry content(this, d, newPaint);
|
||||
internalDrawPaint(newPaint, content.entry());
|
||||
}
|
||||
|
||||
void SkPDFDevice::internalDrawPaint(const SkPaint& paint,
|
||||
@ -569,7 +542,8 @@ void SkPDFDevice::internalDrawPaint(const SkPaint& paint,
|
||||
&contentEntry->fContent);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawPoints(SkCanvas::PointMode mode,
|
||||
void SkPDFDevice::drawPoints(const SkDraw& d,
|
||||
SkCanvas::PointMode mode,
|
||||
size_t count,
|
||||
const SkPoint* points,
|
||||
const SkPaint& srcPaint) {
|
||||
@ -584,11 +558,10 @@ void SkPDFDevice::drawPoints(SkCanvas::PointMode mode,
|
||||
// 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 (this->cs().isEmpty(size(*this))) {
|
||||
if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
|
||||
return;
|
||||
}
|
||||
draw_points(mode, count, points, passedPaint,
|
||||
this->devClipBounds(), this->ctm(), this);
|
||||
d.drawPoints(mode, count, points, passedPaint, this);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -608,7 +581,7 @@ void SkPDFDevice::drawPoints(SkCanvas::PointMode mode,
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
SkRect r = SkRect::MakeXYWH(points[i].fX, points[i].fY, 0, 0);
|
||||
r.inset(-halfStroke, -halfStroke);
|
||||
this->drawRect(r, modifiedPaint);
|
||||
drawRect(d, r, modifiedPaint);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
@ -616,7 +589,7 @@ void SkPDFDevice::drawPoints(SkCanvas::PointMode mode,
|
||||
}
|
||||
}
|
||||
|
||||
ScopedContentEntry content(this, *paint);
|
||||
ScopedContentEntry content(this, d, *paint);
|
||||
if (!content.entry()) {
|
||||
return;
|
||||
}
|
||||
@ -698,7 +671,8 @@ static sk_sp<SkPDFDict> create_link_named_dest(const SkData* nameData,
|
||||
return annotation;
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawRect(const SkRect& rect,
|
||||
void SkPDFDevice::drawRect(const SkDraw& d,
|
||||
const SkRect& rect,
|
||||
const SkPaint& srcPaint) {
|
||||
SkPaint paint = srcPaint;
|
||||
replace_srcmode_on_opaque_paint(&paint);
|
||||
@ -706,16 +680,16 @@ void SkPDFDevice::drawRect(const SkRect& rect,
|
||||
r.sort();
|
||||
|
||||
if (paint.getPathEffect()) {
|
||||
if (this->cs().isEmpty(size(*this))) {
|
||||
if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
|
||||
return;
|
||||
}
|
||||
SkPath path;
|
||||
path.addRect(r);
|
||||
this->drawPath(path, paint, nullptr, true);
|
||||
drawPath(d, path, paint, nullptr, true);
|
||||
return;
|
||||
}
|
||||
|
||||
ScopedContentEntry content(this, paint);
|
||||
ScopedContentEntry content(this, d, paint);
|
||||
if (!content.entry()) {
|
||||
return;
|
||||
}
|
||||
@ -724,44 +698,37 @@ void SkPDFDevice::drawRect(const SkRect& rect,
|
||||
&content.entry()->fContent);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawRRect(const SkRRect& rrect,
|
||||
void SkPDFDevice::drawRRect(const SkDraw& draw,
|
||||
const SkRRect& rrect,
|
||||
const SkPaint& srcPaint) {
|
||||
SkPaint paint = srcPaint;
|
||||
replace_srcmode_on_opaque_paint(&paint);
|
||||
SkPath path;
|
||||
path.addRRect(rrect);
|
||||
this->drawPath(path, paint, nullptr, true);
|
||||
this->drawPath(draw, path, paint, nullptr, true);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawOval(const SkRect& oval,
|
||||
void SkPDFDevice::drawOval(const SkDraw& draw,
|
||||
const SkRect& oval,
|
||||
const SkPaint& srcPaint) {
|
||||
SkPaint paint = srcPaint;
|
||||
replace_srcmode_on_opaque_paint(&paint);
|
||||
SkPath path;
|
||||
path.addOval(oval);
|
||||
this->drawPath(path, paint, nullptr, true);
|
||||
this->drawPath(draw, path, paint, nullptr, true);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawPath(const SkPath& origPath,
|
||||
void SkPDFDevice::drawPath(const SkDraw& d,
|
||||
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,
|
||||
bool pathIsMutable) {
|
||||
SkPaint paint = srcPaint;
|
||||
replace_srcmode_on_opaque_paint(&paint);
|
||||
SkPath modifiedPath;
|
||||
SkPath* pathPtr = const_cast<SkPath*>(&origPath);
|
||||
|
||||
SkMatrix matrix = ctm;
|
||||
SkMatrix matrix = *d.fMatrix;
|
||||
if (prePathMatrix) {
|
||||
if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
|
||||
if (!pathIsMutable) {
|
||||
@ -775,7 +742,7 @@ void SkPDFDevice::internalDrawPath(const SkClipStack& clipStack,
|
||||
}
|
||||
|
||||
if (paint.getPathEffect()) {
|
||||
if (clipStack.isEmpty(size(*this))) {
|
||||
if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
|
||||
return;
|
||||
}
|
||||
if (!pathIsMutable) {
|
||||
@ -792,15 +759,15 @@ void SkPDFDevice::internalDrawPath(const SkClipStack& clipStack,
|
||||
noEffectPaint.setStyle(SkPaint::kStroke_Style);
|
||||
noEffectPaint.setStrokeWidth(0);
|
||||
}
|
||||
this->internalDrawPath(clipStack, ctm, *pathPtr, noEffectPaint, nullptr, true);
|
||||
drawPath(d, *pathPtr, noEffectPaint, nullptr, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->handleInversePath(origPath, paint, pathIsMutable, prePathMatrix)) {
|
||||
if (handleInversePath(d, origPath, paint, pathIsMutable, prePathMatrix)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScopedContentEntry content(this, clipStack, matrix, paint);
|
||||
ScopedContentEntry content(this, d.fClipStack, matrix, paint);
|
||||
if (!content.entry()) {
|
||||
return;
|
||||
}
|
||||
@ -819,7 +786,8 @@ void SkPDFDevice::internalDrawPath(const SkClipStack& clipStack,
|
||||
}
|
||||
|
||||
|
||||
void SkPDFDevice::drawImageRect(const SkImage* image,
|
||||
void SkPDFDevice::drawImageRect(const SkDraw& d,
|
||||
const SkImage* image,
|
||||
const SkRect* src,
|
||||
const SkRect& dst,
|
||||
const SkPaint& srcPaint,
|
||||
@ -847,15 +815,17 @@ void SkPDFDevice::drawImageRect(const SkImage* image,
|
||||
if (!imageSubset.isValid()) {
|
||||
return;
|
||||
}
|
||||
transform.postConcat(this->ctm());
|
||||
this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
|
||||
transform.postConcat(*d.fMatrix);
|
||||
this->internalDrawImage(transform, d.fClipStack,
|
||||
std::move(imageSubset), paint);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawBitmapRect(const SkBitmap& bitmap,
|
||||
void SkPDFDevice::drawBitmapRect(const SkDraw& d,
|
||||
const SkBitmap& bitmap,
|
||||
const SkRect* src,
|
||||
const SkRect& dst,
|
||||
const SkPaint& srcPaint,
|
||||
SkCanvas::SrcRectConstraint) {
|
||||
const SkPaint& srcPaint,
|
||||
SkCanvas::SrcRectConstraint) {
|
||||
if (bitmap.drawsNothing()) {
|
||||
return;
|
||||
}
|
||||
@ -883,14 +853,16 @@ void SkPDFDevice::drawBitmapRect(const SkBitmap& bitmap,
|
||||
if (!imageSubset.isValid()) {
|
||||
return;
|
||||
}
|
||||
transform.postConcat(this->ctm());
|
||||
this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
|
||||
transform.postConcat(*d.fMatrix);
|
||||
this->internalDrawImage(transform, d.fClipStack,
|
||||
std::move(imageSubset), paint);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawBitmap(const SkBitmap& bitmap,
|
||||
void SkPDFDevice::drawBitmap(const SkDraw& d,
|
||||
const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix,
|
||||
const SkPaint& srcPaint) {
|
||||
if (bitmap.drawsNothing() || this->cs().isEmpty(size(*this))) {
|
||||
if (bitmap.drawsNothing() || d.fClipStack->isEmpty(this->getGlobalBounds())) {
|
||||
return;
|
||||
}
|
||||
SkPaint paint = srcPaint;
|
||||
@ -902,15 +874,17 @@ void SkPDFDevice::drawBitmap(const SkBitmap& bitmap,
|
||||
return;
|
||||
}
|
||||
SkMatrix transform = matrix;
|
||||
transform.postConcat(this->ctm());
|
||||
this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
|
||||
transform.postConcat(*d.fMatrix);
|
||||
this->internalDrawImage(
|
||||
transform, d.fClipStack, std::move(imageSubset), paint);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawSprite(const SkBitmap& bitmap,
|
||||
void SkPDFDevice::drawSprite(const SkDraw& d,
|
||||
const SkBitmap& bitmap,
|
||||
int x,
|
||||
int y,
|
||||
const SkPaint& srcPaint) {
|
||||
if (bitmap.drawsNothing() || this->cs().isEmpty(size(*this))) {
|
||||
if (bitmap.drawsNothing() || d.fClipStack->isEmpty(this->getGlobalBounds())) {
|
||||
return;
|
||||
}
|
||||
SkPaint paint = srcPaint;
|
||||
@ -922,10 +896,12 @@ void SkPDFDevice::drawSprite(const SkBitmap& bitmap,
|
||||
return;
|
||||
}
|
||||
SkMatrix transform = SkMatrix::MakeTrans(SkIntToScalar(x), SkIntToScalar(y));
|
||||
this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
|
||||
this->internalDrawImage(
|
||||
transform, d.fClipStack, std::move(imageSubset), paint);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawImage(const SkImage* image,
|
||||
void SkPDFDevice::drawImage(const SkDraw& draw,
|
||||
const SkImage* image,
|
||||
SkScalar x,
|
||||
SkScalar y,
|
||||
const SkPaint& srcPaint) {
|
||||
@ -941,8 +917,9 @@ void SkPDFDevice::drawImage(const SkImage* image,
|
||||
return;
|
||||
}
|
||||
SkMatrix transform = SkMatrix::MakeTrans(x, y);
|
||||
transform.postConcat(this->ctm());
|
||||
this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
|
||||
transform.postConcat(*draw.fMatrix);
|
||||
this->internalDrawImage(
|
||||
transform, draw.fClipStack, std::move(imageSubset), paint);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -1236,7 +1213,7 @@ static void update_font(SkWStream* wStream, int fontIndex, SkScalar textSize) {
|
||||
}
|
||||
|
||||
void SkPDFDevice::internalDrawText(
|
||||
const void* sourceText, size_t sourceByteCount,
|
||||
const SkDraw& d, 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) {
|
||||
@ -1320,7 +1297,7 @@ void SkPDFDevice::internalDrawText(
|
||||
}
|
||||
offset.offset(alignmentFactor * advance, 0);
|
||||
}
|
||||
ScopedContentEntry content(this, paint, true);
|
||||
ScopedContentEntry content(this, d, paint, true);
|
||||
if (!content.entry()) {
|
||||
return;
|
||||
}
|
||||
@ -1419,20 +1396,20 @@ void SkPDFDevice::internalDrawText(
|
||||
}
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawText(const void* text, size_t len,
|
||||
void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) {
|
||||
this->internalDrawText(text, len, nullptr, SkTextBlob::kDefault_Positioning,
|
||||
this->internalDrawText(d, text, len, nullptr, SkTextBlob::kDefault_Positioning,
|
||||
SkPoint{x, y}, paint, nullptr, 0, nullptr);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawPosText(const void* text, size_t len,
|
||||
void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len,
|
||||
const SkScalar pos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint& paint) {
|
||||
this->internalDrawText(text, len, pos, (SkTextBlob::GlyphPositioning)scalarsPerPos,
|
||||
this->internalDrawText(d, text, len, pos, (SkTextBlob::GlyphPositioning)scalarsPerPos,
|
||||
offset, paint, nullptr, 0, nullptr);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
void SkPDFDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
const SkPaint &paint, SkDrawFilter* drawFilter) {
|
||||
for (SkTextBlobRunIterator it(blob); !it.done(); it.next()) {
|
||||
SkPaint runPaint(paint);
|
||||
@ -1442,24 +1419,25 @@ void SkPDFDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
}
|
||||
runPaint.setFlags(this->filterTextFlags(runPaint));
|
||||
SkPoint offset = it.offset() + SkPoint{x, y};
|
||||
this->internalDrawText(it.glyphs(), sizeof(SkGlyphID) * it.glyphCount(),
|
||||
this->internalDrawText(draw, it.glyphs(), sizeof(SkGlyphID) * it.glyphCount(),
|
||||
it.pos(), it.positioning(), offset, runPaint,
|
||||
it.clusters(), it.textSize(), it.text());
|
||||
}
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawVertices(SkCanvas::VertexMode,
|
||||
void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode,
|
||||
int vertexCount, const SkPoint verts[],
|
||||
const SkPoint texs[], const SkColor colors[],
|
||||
SkBlendMode, const uint16_t indices[],
|
||||
int indexCount, const SkPaint& paint) {
|
||||
if (this->cs().isEmpty(size(*this))) {
|
||||
if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
|
||||
return;
|
||||
}
|
||||
// TODO: implement drawVertices
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawDevice(SkBaseDevice* device, int x, int y, const SkPaint& paint) {
|
||||
void SkPDFDevice::drawDevice(const SkDraw& d, 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
|
||||
@ -1468,7 +1446,7 @@ void SkPDFDevice::drawDevice(SkBaseDevice* device, int x, int y, const SkPaint&
|
||||
if (device->peekPixels(&pmap)) {
|
||||
SkBitmap bitmap;
|
||||
bitmap.installPixels(pmap);
|
||||
this->drawSprite(bitmap, x, y, paint);
|
||||
this->drawSprite(d, bitmap, x, y, paint);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1494,8 +1472,9 @@ void SkPDFDevice::drawDevice(SkBaseDevice* device, int x, int y, const SkPaint&
|
||||
return;
|
||||
}
|
||||
|
||||
SkMatrix matrix = SkMatrix::MakeTrans(SkIntToScalar(x), SkIntToScalar(y));
|
||||
ScopedContentEntry content(this, this->cs(), matrix, paint);
|
||||
SkMatrix matrix;
|
||||
matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y));
|
||||
ScopedContentEntry content(this, d.fClipStack, matrix, paint);
|
||||
if (!content.entry()) {
|
||||
return;
|
||||
}
|
||||
@ -1551,8 +1530,11 @@ 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,
|
||||
{0, 0}, SkRect::Make(size(*this)));
|
||||
translation, SkRect::Make(this->getGlobalBounds()));
|
||||
gsState.updateMatrix(entry.fState.fMatrix);
|
||||
gsState.updateDrawingState(entry.fState);
|
||||
|
||||
@ -1573,14 +1555,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 SkPath& origPath,
|
||||
bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
|
||||
const SkPaint& paint, bool pathIsMutable,
|
||||
const SkMatrix* prePathMatrix) {
|
||||
if (!origPath.isInverseFillType()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->cs().isEmpty(size(*this))) {
|
||||
if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1600,7 +1582,7 @@ bool SkPDFDevice::handleInversePath(const SkPath& origPath,
|
||||
// To be consistent with the raster output, hairline strokes
|
||||
// are rendered as non-inverted.
|
||||
modifiedPath.toggleInverseFillType();
|
||||
this->drawPath(modifiedPath, paint, nullptr, true);
|
||||
drawPath(d, modifiedPath, paint, nullptr, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1608,14 +1590,16 @@ bool SkPDFDevice::handleInversePath(const SkPath& origPath,
|
||||
// Get bounds of clip in current transform space
|
||||
// (clip bounds are given in device space).
|
||||
SkMatrix transformInverse;
|
||||
SkMatrix totalMatrix = this->ctm();
|
||||
SkMatrix totalMatrix = *d.fMatrix;
|
||||
if (prePathMatrix) {
|
||||
totalMatrix.preConcat(*prePathMatrix);
|
||||
}
|
||||
if (!totalMatrix.invert(&transformInverse)) {
|
||||
return false;
|
||||
}
|
||||
SkRect bounds = this->cs().bounds(size(*this));
|
||||
SkRect bounds = d.fClipStack->bounds(this->getGlobalBounds());
|
||||
SkIPoint deviceOrigin = this->getOrigin();
|
||||
bounds.offset(-deviceOrigin.x(), -deviceOrigin.y());
|
||||
transformInverse.mapRect(&bounds);
|
||||
|
||||
// Extend the bounds by the line width (plus some padding)
|
||||
@ -1627,10 +1611,48 @@ bool SkPDFDevice::handleInversePath(const SkPath& origPath,
|
||||
return false;
|
||||
}
|
||||
|
||||
this->drawPath(modifiedPath, noInversePaint, prePathMatrix, true);
|
||||
drawPath(d, 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) {
|
||||
@ -1682,10 +1704,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(size(*this))) {
|
||||
if (!invertClip && clipStack->isEmpty(this->getGlobalBounds())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1693,9 +1715,11 @@ 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, SkMatrix::I(), paint);
|
||||
ScopedContentEntry content(this, clipStack, identity, paint);
|
||||
if (!content.entry()) {
|
||||
return;
|
||||
}
|
||||
@ -1711,12 +1735,13 @@ 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
|
||||
@ -1756,7 +1781,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;
|
||||
}
|
||||
|
||||
@ -1801,6 +1826,8 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
|
||||
|
||||
SkClipStack clipStack = fContentEntries.front()->fState.fClipStack;
|
||||
|
||||
SkMatrix identity;
|
||||
identity.reset();
|
||||
SkPaint stockPaint;
|
||||
|
||||
sk_sp<SkPDFObject> srcFormXObject;
|
||||
@ -1812,7 +1839,7 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
|
||||
// reduces to Dst.
|
||||
if (shape == nullptr || blendMode == SkBlendMode::kDstOut ||
|
||||
blendMode == SkBlendMode::kSrcATop) {
|
||||
ScopedContentEntry content(this, fExistingClipStack, SkMatrix::I(), stockPaint);
|
||||
ScopedContentEntry content(this, &fExistingClipStack, identity, stockPaint);
|
||||
// TODO: addXObjectResource take sk_sp
|
||||
SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst.get()),
|
||||
&content.entry()->fContent);
|
||||
@ -1833,23 +1860,28 @@ 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->internalDrawPath(clipStack, SkMatrix::I(), *shape, filledPaint, nullptr, true);
|
||||
this->drawFormXObjectWithMask(this->addXObjectResource(dst.get()),
|
||||
this->makeFormXObjectFromDevice(),
|
||||
fExistingClipStack,
|
||||
SkBlendMode::kSrcOver, true);
|
||||
this->drawPath(d, *shape, filledPaint, nullptr, true);
|
||||
drawFormXObjectWithMask(addXObjectResource(dst.get()),
|
||||
this->makeFormXObjectFromDevice(),
|
||||
&fExistingClipStack,
|
||||
SkBlendMode::kSrcOver, true);
|
||||
|
||||
} else {
|
||||
this->drawFormXObjectWithMask(this->addXObjectResource(dst.get()),
|
||||
srcFormXObject,
|
||||
fExistingClipStack,
|
||||
SkBlendMode::kSrcOver, true);
|
||||
drawFormXObjectWithMask(addXObjectResource(dst.get()), srcFormXObject,
|
||||
&fExistingClipStack,
|
||||
SkBlendMode::kSrcOver, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1857,7 +1889,7 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
|
||||
return;
|
||||
} else if (blendMode == SkBlendMode::kSrc ||
|
||||
blendMode == SkBlendMode::kDstATop) {
|
||||
ScopedContentEntry content(this, fExistingClipStack, SkMatrix::I(), stockPaint);
|
||||
ScopedContentEntry content(this, &fExistingClipStack, identity, stockPaint);
|
||||
if (content.entry()) {
|
||||
SkPDFUtils::DrawFormXObject(
|
||||
this->addXObjectResource(srcFormXObject.get()),
|
||||
@ -1867,8 +1899,8 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
|
||||
return;
|
||||
}
|
||||
} else if (blendMode == SkBlendMode::kSrcATop) {
|
||||
ScopedContentEntry content(this, fExistingClipStack,
|
||||
SkMatrix::I(), stockPaint);
|
||||
ScopedContentEntry content(this, &fExistingClipStack,
|
||||
identity, stockPaint);
|
||||
if (content.entry()) {
|
||||
SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst.get()),
|
||||
&content.entry()->fContent);
|
||||
@ -1888,7 +1920,7 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
|
||||
blendMode == SkBlendMode::kSrcATop) {
|
||||
drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()),
|
||||
std::move(dst),
|
||||
fExistingClipStack,
|
||||
&fExistingClipStack,
|
||||
SkBlendMode::kSrcOver,
|
||||
blendMode == SkBlendMode::kSrcOut);
|
||||
return;
|
||||
@ -1897,12 +1929,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;
|
||||
}
|
||||
@ -1954,7 +1986,9 @@ 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(size(*this));
|
||||
SkRect clipStackBounds = clipStack.bounds(this->getGlobalBounds());
|
||||
SkIPoint deviceOrigin = this->getOrigin();
|
||||
clipStackBounds.offset(-deviceOrigin.x(), -deviceOrigin.y());
|
||||
|
||||
// We need to apply the initial transform to bounds in order to get
|
||||
// bounds in a consistent coordinate system.
|
||||
@ -2061,7 +2095,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()) {
|
||||
@ -2203,8 +2237,8 @@ void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix,
|
||||
#include "SkSpecialImage.h"
|
||||
#include "SkImageFilter.h"
|
||||
|
||||
void SkPDFDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y,
|
||||
const SkPaint& paint) {
|
||||
void SkPDFDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x, int y,
|
||||
const SkPaint& paint) {
|
||||
SkASSERT(!srcImg->isTextureBacked());
|
||||
|
||||
SkBitmap resultBM;
|
||||
@ -2212,10 +2246,10 @@ void SkPDFDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y,
|
||||
SkImageFilter* filter = paint.getImageFilter();
|
||||
if (filter) {
|
||||
SkIPoint offset = SkIPoint::Make(0, 0);
|
||||
SkMatrix matrix = this->ctm();
|
||||
SkMatrix matrix = *draw.fMatrix;
|
||||
matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
|
||||
const SkIRect clipBounds =
|
||||
this->cs().bounds(this->imageInfo().bounds()).roundOut().makeOffset(-x, -y);
|
||||
draw.fClipStack->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).
|
||||
@ -2227,12 +2261,12 @@ void SkPDFDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y,
|
||||
SkPaint tmpUnfiltered(paint);
|
||||
tmpUnfiltered.setImageFilter(nullptr);
|
||||
if (resultImg->getROPixels(&resultBM)) {
|
||||
this->drawSprite(resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
|
||||
this->drawSprite(draw, resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (srcImg->getROPixels(&resultBM)) {
|
||||
this->drawSprite(resultBM, x, y, paint);
|
||||
this->drawSprite(draw, resultBM, x, y, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,44 +79,46 @@ public:
|
||||
and are handling any looping from the paint, and any effects from the
|
||||
DrawFilter.
|
||||
*/
|
||||
void drawPaint(const SkPaint& paint) override;
|
||||
void drawPoints(SkCanvas::PointMode mode,
|
||||
void drawPaint(const SkDraw&, const SkPaint& paint) override;
|
||||
void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
|
||||
size_t count, const SkPoint[],
|
||||
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;
|
||||
void drawPath(const SkPath& origpath,
|
||||
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,
|
||||
const SkPaint& paint, const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable) override;
|
||||
void drawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
|
||||
void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, const SkRect* src,
|
||||
const SkRect& dst, const SkPaint&, SkCanvas::SrcRectConstraint) override;
|
||||
void drawBitmap(const SkBitmap& bitmap,
|
||||
void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint&) override;
|
||||
void drawSprite(const SkBitmap& bitmap, int x, int y,
|
||||
void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
|
||||
const SkPaint& paint) override;
|
||||
void drawImage(const SkImage*,
|
||||
void drawImage(const SkDraw&,
|
||||
const SkImage*,
|
||||
SkScalar x,
|
||||
SkScalar y,
|
||||
const SkPaint&) override;
|
||||
void drawImageRect(const SkImage*,
|
||||
void drawImageRect(const SkDraw&,
|
||||
const SkImage*,
|
||||
const SkRect* src,
|
||||
const SkRect& dst,
|
||||
const SkPaint&,
|
||||
SkCanvas::SrcRectConstraint) override;
|
||||
void drawText(const void* text, size_t len,
|
||||
void drawText(const SkDraw&, const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint&) override;
|
||||
void drawPosText(const void* text, size_t len,
|
||||
void drawPosText(const SkDraw&, const void* text, size_t len,
|
||||
const SkScalar pos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint&) override;
|
||||
void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
|
||||
void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
|
||||
const SkPaint &, SkDrawFilter*) override;
|
||||
void drawVertices(SkCanvas::VertexMode,
|
||||
void drawVertices(const SkDraw&, 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(SkBaseDevice*, int x, int y,
|
||||
void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
|
||||
const SkPaint&) override;
|
||||
|
||||
// PDF specific methods.
|
||||
@ -172,9 +174,9 @@ public:
|
||||
protected:
|
||||
sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&) override;
|
||||
|
||||
void drawAnnotation(const SkRect&, const char key[], SkData* value) override;
|
||||
void drawAnnotation(const SkDraw&, const SkRect&, const char key[], SkData* value) override;
|
||||
|
||||
void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) override;
|
||||
void drawSpecial(const SkDraw&, 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;
|
||||
@ -240,7 +242,7 @@ private:
|
||||
|
||||
void drawFormXObjectWithMask(int xObjectIndex,
|
||||
sk_sp<SkPDFObject> mask,
|
||||
const SkClipStack& clipStack,
|
||||
const SkClipStack* clipStack,
|
||||
SkBlendMode,
|
||||
bool invertClip);
|
||||
|
||||
@ -248,7 +250,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,
|
||||
@ -267,27 +269,22 @@ private:
|
||||
int getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID);
|
||||
|
||||
|
||||
void internalDrawText( const void*, size_t, const SkScalar pos[],
|
||||
void internalDrawText(const SkDraw&, 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);
|
||||
|
||||
void internalDrawPath(const SkClipStack&,
|
||||
const SkMatrix&,
|
||||
const SkPath&,
|
||||
const SkPaint&,
|
||||
const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable);
|
||||
|
||||
bool handleInversePath(const SkPath& origPath,
|
||||
bool handleInversePath(const SkDraw& d, 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,9 +278,14 @@ struct SkSVGDevice::MxCp {
|
||||
const SkMatrix* fMatrix;
|
||||
const SkClipStack* fClipStack;
|
||||
|
||||
MxCp(SkSVGDevice* device) {
|
||||
MxCp(SkSVGDevice* device, const SkDraw& draw) {
|
||||
#ifdef SK_USE_DEVICE_CLIPPING
|
||||
fMatrix = &device->ctm();
|
||||
fClipStack = &device->cs();
|
||||
#else
|
||||
fMatrix = draw.fMatrix;
|
||||
fClipStack = draw.fClipStack;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@ -602,13 +607,13 @@ SkSVGDevice::SkSVGDevice(const SkISize& size, SkXMLWriter* writer)
|
||||
SkSVGDevice::~SkSVGDevice() {
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawPaint(const SkPaint& paint) {
|
||||
AutoElement rect("rect", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
void SkSVGDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
|
||||
AutoElement rect("rect", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
rect.addRectAttributes(SkRect::MakeWH(SkIntToScalar(this->width()),
|
||||
SkIntToScalar(this->height())));
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
void SkSVGDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint pts[], const SkPaint& paint) {
|
||||
SkPath path;
|
||||
|
||||
@ -623,7 +628,7 @@ void SkSVGDevice::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
path.rewind();
|
||||
path.moveTo(pts[i]);
|
||||
path.lineTo(pts[i+1]);
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
elem.addPathAttributes(path);
|
||||
}
|
||||
break;
|
||||
@ -631,37 +636,37 @@ void SkSVGDevice::drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
if (count > 1) {
|
||||
path.addPoly(pts, SkToInt(count), false);
|
||||
path.moveTo(pts[0]);
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
elem.addPathAttributes(path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawRect(const SkRect& r, const SkPaint& paint) {
|
||||
AutoElement rect("rect", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
void SkSVGDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) {
|
||||
AutoElement rect("rect", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
rect.addRectAttributes(r);
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawOval(const SkRect& oval, const SkPaint& paint) {
|
||||
AutoElement ellipse("ellipse", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
void SkSVGDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
|
||||
AutoElement ellipse("ellipse", fWriter, fResourceBucket.get(), MxCp(this, draw), 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 SkRRect& rr, const SkPaint& paint) {
|
||||
void SkSVGDevice::drawRRect(const SkDraw& draw, const SkRRect& rr, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
path.addRRect(rr);
|
||||
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
elem.addPathAttributes(path);
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawPath(const SkPath& path, const SkPaint& paint,
|
||||
void SkSVGDevice::drawPath(const SkDraw& draw, const SkPath& path, const SkPaint& paint,
|
||||
const SkMatrix* prePathMatrix, bool pathIsMutable) {
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
elem.addPathAttributes(path);
|
||||
|
||||
// TODO: inverse fill types?
|
||||
@ -706,9 +711,9 @@ void SkSVGDevice::drawBitmapCommon(const MxCp& mc, const SkBitmap& bm, const SkP
|
||||
}
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawBitmap(const SkBitmap& bitmap,
|
||||
void SkSVGDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint& paint) {
|
||||
MxCp mc(this);
|
||||
MxCp mc(this, draw);
|
||||
SkMatrix adjustedMatrix = *mc.fMatrix;
|
||||
adjustedMatrix.preConcat(matrix);
|
||||
mc.fMatrix = &adjustedMatrix;
|
||||
@ -716,9 +721,9 @@ void SkSVGDevice::drawBitmap(const SkBitmap& bitmap,
|
||||
drawBitmapCommon(mc, bitmap, paint);
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawSprite(const SkBitmap& bitmap,
|
||||
void SkSVGDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
int x, int y, const SkPaint& paint) {
|
||||
MxCp mc(this);
|
||||
MxCp mc(this, draw);
|
||||
SkMatrix adjustedMatrix = *mc.fMatrix;
|
||||
adjustedMatrix.preTranslate(SkIntToScalar(x), SkIntToScalar(y));
|
||||
mc.fMatrix = &adjustedMatrix;
|
||||
@ -726,10 +731,10 @@ void SkSVGDevice::drawSprite(const SkBitmap& bitmap,
|
||||
drawBitmapCommon(mc, bitmap, paint);
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawBitmapRect(const SkBitmap& bm, const SkRect* srcOrNull,
|
||||
void SkSVGDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bm, const SkRect* srcOrNull,
|
||||
const SkRect& dst, const SkPaint& paint,
|
||||
SkCanvas::SrcRectConstraint) {
|
||||
MxCp mc(this);
|
||||
MxCp mc(this, draw);
|
||||
|
||||
SkClipStack adjustedClipStack;
|
||||
if (srcOrNull && *srcOrNull != SkRect::Make(bm.bounds())) {
|
||||
@ -749,9 +754,9 @@ void SkSVGDevice::drawBitmapRect(const SkBitmap& bm, const SkRect* srcOrNull,
|
||||
drawBitmapCommon(mc, bm, paint);
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawText(const void* text, size_t len,
|
||||
void SkSVGDevice::drawText(const SkDraw& draw, const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) {
|
||||
AutoElement elem("text", fWriter, fResourceBucket.get(), MxCp(this), paint);
|
||||
AutoElement elem("text", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
elem.addTextAttributes(paint);
|
||||
|
||||
SVGTextBuilder builder(text, len, paint, SkPoint::Make(x, y), 0);
|
||||
@ -760,12 +765,12 @@ void SkSVGDevice::drawText(const void* text, size_t len,
|
||||
elem.addText(builder.text());
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawPosText(const void* text, size_t len,
|
||||
void SkSVGDevice::drawPosText(const SkDraw& draw, 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), paint);
|
||||
AutoElement elem("text", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
|
||||
elem.addTextAttributes(paint);
|
||||
|
||||
SVGTextBuilder builder(text, len, paint, offset, scalarsPerPos, pos);
|
||||
@ -774,7 +779,7 @@ void SkSVGDevice::drawPosText(const void* text, size_t len,
|
||||
elem.addText(builder.text());
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawTextOnPath(const void* text, size_t len, const SkPath& path,
|
||||
void SkSVGDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath& path,
|
||||
const SkMatrix* matrix, const SkPaint& paint) {
|
||||
SkString pathID = fResourceBucket->addPath();
|
||||
|
||||
@ -811,7 +816,7 @@ void SkSVGDevice::drawTextOnPath(const void* text, size_t len, const SkPath& pat
|
||||
}
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawVertices(SkCanvas::VertexMode, int vertexCount,
|
||||
void SkSVGDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
|
||||
const SkPoint verts[], const SkPoint texs[],
|
||||
const SkColor colors[], SkBlendMode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
@ -820,7 +825,7 @@ void SkSVGDevice::drawVertices(SkCanvas::VertexMode, int vertexCount,
|
||||
SkDebugf("unsupported operation: drawVertices()\n");
|
||||
}
|
||||
|
||||
void SkSVGDevice::drawDevice(SkBaseDevice*, int x, int y,
|
||||
void SkSVGDevice::drawDevice(const SkDraw&, 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 SkPaint& paint) override;
|
||||
void drawPoints(SkCanvas::PointMode mode, size_t count,
|
||||
void drawPaint(const SkDraw&, const SkPaint& paint) override;
|
||||
void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint[], 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;
|
||||
void drawPath(const SkPath& path,
|
||||
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,
|
||||
const SkPaint& paint,
|
||||
const SkMatrix* prePathMatrix = nullptr,
|
||||
bool pathIsMutable = false) override;
|
||||
|
||||
void drawBitmap(const SkBitmap& bitmap,
|
||||
void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint& paint) override;
|
||||
void drawSprite(const SkBitmap& bitmap,
|
||||
void drawSprite(const SkDraw&, const SkBitmap& bitmap,
|
||||
int x, int y, const SkPaint& paint) override;
|
||||
void drawBitmapRect(const SkBitmap&,
|
||||
void drawBitmapRect(const SkDraw&, const SkBitmap&,
|
||||
const SkRect* srcOrNull, const SkRect& dst,
|
||||
const SkPaint& paint, SkCanvas::SrcRectConstraint) override;
|
||||
|
||||
void drawText(const void* text, size_t len,
|
||||
void drawText(const SkDraw&, const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) override;
|
||||
void drawPosText(const void* text, size_t len,
|
||||
void drawPosText(const SkDraw&, const void* text, size_t len,
|
||||
const SkScalar pos[], int scalarsPerPos,
|
||||
const SkPoint& offset, const SkPaint& paint) override;
|
||||
void drawTextOnPath(const void* text, size_t len,
|
||||
void drawTextOnPath(const SkDraw&, const void* text, size_t len,
|
||||
const SkPath& path, const SkMatrix* matrix,
|
||||
const SkPaint& paint) override;
|
||||
void drawVertices(SkCanvas::VertexMode, int vertexCount,
|
||||
void drawVertices(const SkDraw&, 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(SkBaseDevice*, int x, int y,
|
||||
void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
|
||||
const SkPaint&) override;
|
||||
|
||||
private:
|
||||
|
@ -130,6 +130,28 @@ 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;
|
||||
@ -171,7 +193,9 @@ SkCanvasState* SkCanvasStateUtils::CaptureCanvasState(SkCanvas* canvas) {
|
||||
SkASSERT(canvas);
|
||||
|
||||
// Check the clip can be decomposed into rectangles (i.e. no soft clips).
|
||||
if (canvas->androidFramework_isClipAA()) {
|
||||
ClipValidator validator;
|
||||
canvas->replayClips(&validator);
|
||||
if (validator.failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -222,9 +246,7 @@ SkCanvasState* SkCanvasStateUtils::CaptureCanvasState(SkCanvas* canvas) {
|
||||
layerState->raster.rowBytes = pmap.rowBytes();
|
||||
layerState->raster.pixels = pmap.writable_addr();
|
||||
|
||||
SkRegion rgn;
|
||||
layer.clip(&rgn);
|
||||
setup_MC_state(&layerState->mcState, layer.matrix(), rgn);
|
||||
setup_MC_state(&layerState->mcState, layer.matrix(), layer.clip().bwRgn());
|
||||
layerCount++;
|
||||
}
|
||||
|
||||
|
@ -1139,34 +1139,23 @@ HRESULT SkXPSDevice::createXpsQuad(const SkPoint (&points)[4],
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
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,
|
||||
void SkXPSDevice::drawPoints(const SkDraw& d, SkCanvas::PointMode mode,
|
||||
size_t count, const SkPoint points[],
|
||||
const SkPaint& paint) {
|
||||
draw(this, &SkDraw::drawPoints, mode, count, points, paint, this);
|
||||
//This will call back into the device to do the drawing.
|
||||
d.drawPoints(mode, count, points, paint, this);
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawVertices(SkCanvas::VertexMode vertexMode,
|
||||
void SkXPSDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode,
|
||||
int vertexCount, const SkPoint verts[],
|
||||
const SkPoint texs[], const SkColor colors[],
|
||||
SkBlendMode blendMode, const uint16_t indices[],
|
||||
SkBlendMode, const uint16_t indices[],
|
||||
int indexCount, const SkPaint& paint) {
|
||||
draw(this, &SkDraw::drawVertices, vertexMode, vertexCount, verts, texs, colors,
|
||||
blendMode, indices, indexCount, paint);
|
||||
//TODO: override this for XPS
|
||||
SkDEBUGF(("XPS drawVertices not yet implemented."));
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawPaint(const SkPaint& origPaint) {
|
||||
void SkXPSDevice::drawPaint(const SkDraw& d, const SkPaint& origPaint) {
|
||||
const SkRect r = SkRect::MakeSize(this->fCurrentCanvasSize);
|
||||
|
||||
//If trying to paint with a stroke, ignore that and fill.
|
||||
@ -1176,38 +1165,39 @@ void SkXPSDevice::drawPaint(const SkPaint& origPaint) {
|
||||
paint.writable()->setStyle(SkPaint::kFill_Style);
|
||||
}
|
||||
|
||||
this->internalDrawRect(r, false, *fillPaint);
|
||||
this->internalDrawRect(d, r, false, *fillPaint);
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawRect(const SkRect& r,
|
||||
void SkXPSDevice::drawRect(const SkDraw& d,
|
||||
const SkRect& r,
|
||||
const SkPaint& paint) {
|
||||
this->internalDrawRect(r, true, paint);
|
||||
this->internalDrawRect(d, r, true, paint);
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawRRect(const SkRRect& rr,
|
||||
void SkXPSDevice::drawRRect(const SkDraw& d,
|
||||
const SkRRect& rr,
|
||||
const SkPaint& paint) {
|
||||
SkPath path;
|
||||
path.addRRect(rr);
|
||||
this->drawPath(path, paint, nullptr, true);
|
||||
this->drawPath(d, path, paint, nullptr, true);
|
||||
}
|
||||
|
||||
static SkIRect size(const SkBaseDevice& dev) { return {0, 0, dev.width(), dev.height()}; }
|
||||
|
||||
void SkXPSDevice::internalDrawRect(const SkRect& r,
|
||||
void SkXPSDevice::internalDrawRect(const SkDraw& d,
|
||||
const SkRect& r,
|
||||
bool transformRect,
|
||||
const SkPaint& paint) {
|
||||
//Exit early if there is nothing to draw.
|
||||
if (this->cs().isEmpty(size(*this)) ||
|
||||
if (d.fRC->isEmpty() ||
|
||||
(paint.getAlpha() == 0 && paint.isSrcOver())) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Path the rect if we can't optimize it.
|
||||
if (rect_must_be_pathed(paint, this->ctm())) {
|
||||
if (rect_must_be_pathed(paint, *d.fMatrix)) {
|
||||
SkPath tmp;
|
||||
tmp.addRect(r);
|
||||
tmp.setFillType(SkPath::kWinding_FillType);
|
||||
this->drawPath(tmp, paint, nullptr, true);
|
||||
this->drawPath(d, tmp, paint, nullptr, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1228,13 +1218,13 @@ void SkXPSDevice::internalDrawRect(const SkRect& r,
|
||||
//Set the brushes.
|
||||
BOOL fill = FALSE;
|
||||
BOOL stroke = FALSE;
|
||||
HRV(this->shadePath(shadedPath.get(), paint, this->ctm(), &fill, &stroke));
|
||||
HRV(this->shadePath(shadedPath.get(), paint, *d.fMatrix, &fill, &stroke));
|
||||
|
||||
bool xpsTransformsPath = true;
|
||||
//Transform the geometry.
|
||||
if (transformRect && xpsTransformsPath) {
|
||||
SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
|
||||
HRV(this->createXpsTransform(this->ctm(), &xpsTransform));
|
||||
HRV(this->createXpsTransform(*d.fMatrix, &xpsTransform));
|
||||
if (xpsTransform.get()) {
|
||||
HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()),
|
||||
"Could not set transform for rect.");
|
||||
@ -1253,7 +1243,7 @@ void SkXPSDevice::internalDrawRect(const SkRect& r,
|
||||
{ r.fRight, r.fTop },
|
||||
};
|
||||
if (!xpsTransformsPath && transformRect) {
|
||||
this->ctm().mapPoints(points, SK_ARRAY_COUNT(points));
|
||||
d.fMatrix->mapPoints(points, SK_ARRAY_COUNT(points));
|
||||
}
|
||||
HRV(this->createXpsQuad(points, stroke, fill, &rectFigure));
|
||||
}
|
||||
@ -1267,7 +1257,7 @@ void SkXPSDevice::internalDrawRect(const SkRect& r,
|
||||
HRVM(shadedFigures->Append(rectFigure.get()),
|
||||
"Could not add shaded figure for rect.");
|
||||
|
||||
HRV(this->clip(shadedPath.get()));
|
||||
HRV(this->clip(shadedPath.get(), d));
|
||||
|
||||
//Add the shaded path to the current visuals.
|
||||
SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
|
||||
@ -1404,7 +1394,8 @@ void SkXPSDevice::convertToPpm(const SkMaskFilter* filter,
|
||||
clipRect.roundOut(clipIRect);
|
||||
}
|
||||
|
||||
HRESULT SkXPSDevice::applyMask(const SkMask& mask,
|
||||
HRESULT SkXPSDevice::applyMask(const SkDraw& d,
|
||||
const SkMask& mask,
|
||||
const SkVector& ppuScale,
|
||||
IXpsOMPath* shadedPath) {
|
||||
//Get the geometry object.
|
||||
@ -1443,7 +1434,7 @@ HRESULT SkXPSDevice::applyMask(const SkMask& mask,
|
||||
HRM(shadedFigures->Append(shadedFigure.get()),
|
||||
"Could not add mask shaded figure.");
|
||||
|
||||
HR(this->clip(shadedPath));
|
||||
HR(this->clip(shadedPath, d));
|
||||
|
||||
//Add the path to the active visual collection.
|
||||
SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
|
||||
@ -1503,14 +1494,15 @@ HRESULT SkXPSDevice::shadePath(IXpsOMPath* shadedPath,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawPath(const SkPath& platonicPath,
|
||||
void SkXPSDevice::drawPath(const SkDraw& d,
|
||||
const SkPath& platonicPath,
|
||||
const SkPaint& origPaint,
|
||||
const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable) {
|
||||
SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
|
||||
|
||||
// nothing to draw
|
||||
if (this->cs().isEmpty(size(*this)) ||
|
||||
if (d.fRC->isEmpty() ||
|
||||
(paint->getAlpha() == 0 && paint->isSrcOver())) {
|
||||
return;
|
||||
}
|
||||
@ -1520,7 +1512,7 @@ void SkXPSDevice::drawPath(const SkPath& platonicPath,
|
||||
|| paint->getStyle() != SkPaint::kFill_Style;
|
||||
|
||||
//Apply pre-path matrix [Platonic-path -> Skeletal-path].
|
||||
SkMatrix matrix = this->ctm();
|
||||
SkMatrix matrix = *d.fMatrix;
|
||||
SkPath* skeletalPath = const_cast<SkPath*>(&platonicPath);
|
||||
if (prePathMatrix) {
|
||||
if (paintHasPathEffect || paint->getRasterizer()) {
|
||||
@ -1582,7 +1574,7 @@ void SkXPSDevice::drawPath(const SkPath& platonicPath,
|
||||
BOOL stroke;
|
||||
HRV(this->shadePath(shadedPath.get(),
|
||||
*paint,
|
||||
this->ctm(),
|
||||
*d.fMatrix,
|
||||
&fill,
|
||||
&stroke));
|
||||
|
||||
@ -1593,7 +1585,7 @@ void SkXPSDevice::drawPath(const SkPath& platonicPath,
|
||||
this->convertToPpm(filter,
|
||||
&matrix,
|
||||
&ppuScale,
|
||||
this->cs().bounds(size(*this)).roundOut(),
|
||||
d.fRC->getBounds(),
|
||||
&clipIRect);
|
||||
|
||||
SkMask* mask = nullptr;
|
||||
@ -1613,13 +1605,13 @@ void SkXPSDevice::drawPath(const SkPath& platonicPath,
|
||||
|
||||
//[Mask -> Mask]
|
||||
SkMask filteredMask;
|
||||
if (filter && filter->filterMask(&filteredMask, *mask, this->ctm(), nullptr)) {
|
||||
if (filter && filter->filterMask(&filteredMask, *mask, *d.fMatrix, nullptr)) {
|
||||
mask = &filteredMask;
|
||||
}
|
||||
SkAutoMaskFreeImage filteredAmi(filteredMask.fImage);
|
||||
|
||||
//Draw mask.
|
||||
HRV(this->applyMask(*mask, ppuScale, shadedPath.get()));
|
||||
HRV(this->applyMask(d, *mask, ppuScale, shadedPath.get()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1631,7 +1623,7 @@ void SkXPSDevice::drawPath(const SkPath& platonicPath,
|
||||
this->convertToPpm(filter,
|
||||
&matrix,
|
||||
&ppuScale,
|
||||
this->cs().bounds(size(*this)).roundOut(),
|
||||
d.fRC->getBounds(),
|
||||
&clipIRect);
|
||||
|
||||
//[Fillable-path -> Pixel-path]
|
||||
@ -1667,7 +1659,7 @@ void SkXPSDevice::drawPath(const SkPath& platonicPath,
|
||||
SkAutoMaskFreeImage filteredAmi(filteredMask.fImage);
|
||||
|
||||
//Draw mask.
|
||||
HRV(this->applyMask(*mask, ppuScale, shadedPath.get()));
|
||||
HRV(this->applyMask(d, *mask, ppuScale, shadedPath.get()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1742,7 +1734,7 @@ void SkXPSDevice::drawPath(const SkPath& platonicPath,
|
||||
HRV(this->addXpsPathGeometry(shadedFigures.get(),
|
||||
stroke, fill, *devicePath));
|
||||
|
||||
HRV(this->clip(shadedPath.get()));
|
||||
HRV(this->clip(shadedPath.get(), d));
|
||||
|
||||
//Add the path to the active visual collection.
|
||||
SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
|
||||
@ -1752,10 +1744,16 @@ void SkXPSDevice::drawPath(const SkPath& platonicPath,
|
||||
"Could not add shaded path to current visuals.");
|
||||
}
|
||||
|
||||
HRESULT SkXPSDevice::clip(IXpsOMVisual* xpsVisual) {
|
||||
HRESULT SkXPSDevice::clip(IXpsOMVisual* xpsVisual, const SkDraw& d) {
|
||||
SkPath clipPath;
|
||||
// clipPath.addRect(this->cs().bounds(size(*this)));
|
||||
(void)this->cs().asPath(&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()));
|
||||
}
|
||||
|
||||
return this->clipToPath(xpsVisual, clipPath, XPS_FILL_RULE_EVENODD);
|
||||
}
|
||||
HRESULT SkXPSDevice::clipToPath(IXpsOMVisual* xpsVisual,
|
||||
@ -1784,9 +1782,9 @@ HRESULT SkXPSDevice::clipToPath(IXpsOMVisual* xpsVisual,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawBitmap(const SkBitmap& bitmap,
|
||||
void SkXPSDevice::drawBitmap(const SkDraw& d, const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint& paint) {
|
||||
if (this->cs().isEmpty(size(*this))) {
|
||||
if (d.fRC->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1813,7 +1811,7 @@ void SkXPSDevice::drawBitmap(const SkBitmap& bitmap,
|
||||
"Could not get the figures for bitmap.");
|
||||
|
||||
SkMatrix transform = matrix;
|
||||
transform.postConcat(this->ctm());
|
||||
transform.postConcat(*d.fMatrix);
|
||||
|
||||
SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
|
||||
HRV(this->createXpsTransform(transform, &xpsTransform));
|
||||
@ -1853,10 +1851,12 @@ void SkXPSDevice::drawBitmap(const SkBitmap& bitmap,
|
||||
HRVM(currentVisuals->Append(shadedPath.get()),
|
||||
"Could not add bitmap to current visuals.");
|
||||
|
||||
HRV(this->clip(shadedPath.get()));
|
||||
HRV(this->clip(shadedPath.get(), d));
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& paint) {
|
||||
void SkXPSDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap,
|
||||
int x, int y,
|
||||
const SkPaint& paint) {
|
||||
//TODO: override this for XPS
|
||||
SkDEBUGF(("XPS drawSprite not yet implemented."));
|
||||
}
|
||||
@ -1929,7 +1929,8 @@ HRESULT SkXPSDevice::CreateTypefaceUse(const SkPaint& paint,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SkXPSDevice::AddGlyphs(IXpsOMObjectFactory* xpsFactory,
|
||||
HRESULT SkXPSDevice::AddGlyphs(const SkDraw& d,
|
||||
IXpsOMObjectFactory* xpsFactory,
|
||||
IXpsOMCanvas* canvas,
|
||||
TypefaceUse* font,
|
||||
LPCWSTR text,
|
||||
@ -2000,7 +2001,7 @@ HRESULT SkXPSDevice::AddGlyphs(IXpsOMObjectFactory* xpsFactory,
|
||||
HRM(canvas->GetVisuals(&visuals), "Could not get glyph canvas visuals.");
|
||||
|
||||
if (!useCanvasForClip) {
|
||||
HR(this->clip(glyphs.get()));
|
||||
HR(this->clip(glyphs.get(), d));
|
||||
HRM(visuals->Append(glyphs.get()), "Could not add glyphs to canvas.");
|
||||
} else {
|
||||
SkTScopedComPtr<IXpsOMCanvas> glyphCanvas;
|
||||
@ -2013,7 +2014,7 @@ HRESULT SkXPSDevice::AddGlyphs(IXpsOMObjectFactory* xpsFactory,
|
||||
|
||||
HRM(glyphCanvasVisuals->Append(glyphs.get()),
|
||||
"Could not add glyphs to page.");
|
||||
HR(this->clip(glyphCanvas.get()));
|
||||
HR(this->clip(glyphCanvas.get(), d));
|
||||
|
||||
HRM(visuals->Append(glyphCanvas.get()),
|
||||
"Could not add glyph canvas to page.");
|
||||
@ -2090,15 +2091,16 @@ private:
|
||||
GlyphRun* const fXpsGlyphs;
|
||||
};
|
||||
|
||||
void SkXPSDevice::drawText(const void* text, size_t byteLen,
|
||||
void SkXPSDevice::drawText(const SkDraw& d,
|
||||
const void* text, size_t byteLen,
|
||||
SkScalar x, SkScalar y,
|
||||
const SkPaint& paint) {
|
||||
if (byteLen < 1) return;
|
||||
|
||||
if (text_must_be_pathed(paint, this->ctm())) {
|
||||
if (text_must_be_pathed(paint, *d.fMatrix)) {
|
||||
SkPath path;
|
||||
paint.getTextPath(text, byteLen, x, y, &path);
|
||||
this->drawPath(path, paint, nullptr, true);
|
||||
this->drawPath(d, path, paint, nullptr, true);
|
||||
//TODO: add automation "text"
|
||||
return;
|
||||
}
|
||||
@ -2135,7 +2137,8 @@ void SkXPSDevice::drawText(const void* text, size_t byteLen,
|
||||
xpsGlyphs[0].horizontalOffset = 0.0f;
|
||||
xpsGlyphs[0].verticalOffset = 0.0f;
|
||||
|
||||
HRV(AddGlyphs(this->fXpsFactory.get(),
|
||||
HRV(AddGlyphs(d,
|
||||
this->fXpsFactory.get(),
|
||||
this->fCurrentXpsCanvas.get(),
|
||||
typeface,
|
||||
nullptr,
|
||||
@ -2143,20 +2146,21 @@ void SkXPSDevice::drawText(const void* text, size_t byteLen,
|
||||
&origin,
|
||||
SkScalarToFLOAT(paint.getTextSize()),
|
||||
XPS_STYLE_SIMULATION_NONE,
|
||||
this->ctm(),
|
||||
*d.fMatrix,
|
||||
paint));
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawPosText(const void* text, size_t byteLen,
|
||||
void SkXPSDevice::drawPosText(const SkDraw& d,
|
||||
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, this->ctm())) {
|
||||
if (text_must_be_pathed(paint, *d.fMatrix)) {
|
||||
SkPath path;
|
||||
//TODO: make this work, Draw currently does not handle as well.
|
||||
//paint.getTextPath(text, byteLength, x, y, &path);
|
||||
//this->drawPath(path, paint, nullptr, true);
|
||||
//this->drawPath(d, path, paint, nullptr, true);
|
||||
//TODO: add automation "text"
|
||||
return;
|
||||
}
|
||||
@ -2193,7 +2197,8 @@ void SkXPSDevice::drawPosText(const void* text, size_t byteLen,
|
||||
xpsGlyphs[0].horizontalOffset = 0.0f;
|
||||
xpsGlyphs[0].verticalOffset = 0.0f;
|
||||
|
||||
HRV(AddGlyphs(this->fXpsFactory.get(),
|
||||
HRV(AddGlyphs(d,
|
||||
this->fXpsFactory.get(),
|
||||
this->fCurrentXpsCanvas.get(),
|
||||
typeface,
|
||||
nullptr,
|
||||
@ -2201,18 +2206,24 @@ void SkXPSDevice::drawPosText(const void* text, size_t byteLen,
|
||||
&origin,
|
||||
SkScalarToFLOAT(paint.getTextSize()),
|
||||
XPS_STYLE_SIMULATION_NONE,
|
||||
this->ctm(),
|
||||
*d.fMatrix,
|
||||
paint));
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawDevice( SkBaseDevice* dev,
|
||||
void SkXPSDevice::drawDevice(const SkDraw& d, SkBaseDevice* dev,
|
||||
int x, int y,
|
||||
const SkPaint&) {
|
||||
SkXPSDevice* that = static_cast<SkXPSDevice*>(dev);
|
||||
|
||||
SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
|
||||
// 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};
|
||||
XPS_MATRIX rawTransform = {
|
||||
1.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
1.0f,
|
||||
static_cast<FLOAT>(x),
|
||||
static_cast<FLOAT>(y),
|
||||
};
|
||||
HRVM(this->fXpsFactory->CreateMatrixTransform(&rawTransform, &xpsTransform),
|
||||
"Could not create layer transform.");
|
||||
HRVM(that->fCurrentXpsCanvas->SetTransformLocal(xpsTransform.get()),
|
||||
@ -2245,17 +2256,18 @@ SkBaseDevice* SkXPSDevice::onCreateDevice(const CreateInfo& info, const SkPaint*
|
||||
return dev;
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawOval( const SkRect& o, const SkPaint& p) {
|
||||
void SkXPSDevice::drawOval(const SkDraw& d, const SkRect& o, const SkPaint& p) {
|
||||
SkPath path;
|
||||
path.addOval(o);
|
||||
this->drawPath(path, p, nullptr, true);
|
||||
this->drawPath(d, path, p, nullptr, true);
|
||||
}
|
||||
|
||||
void SkXPSDevice::drawBitmapRect(const SkBitmap& bitmap,
|
||||
const SkRect* src,
|
||||
const SkRect& dst,
|
||||
const SkPaint& paint,
|
||||
SkCanvas::SrcRectConstraint constraint) {
|
||||
void SkXPSDevice::drawBitmapRect(const SkDraw& draw,
|
||||
const SkBitmap& bitmap,
|
||||
const SkRect* src,
|
||||
const SkRect& dst,
|
||||
const SkPaint& paint,
|
||||
SkCanvas::SrcRectConstraint constraint) {
|
||||
SkRect srcBounds = src ? *src : SkRect::Make(bitmap.bounds());
|
||||
SkMatrix matrix = SkMatrix::MakeRectToRect(srcBounds, dst, SkMatrix::kFill_ScaleToFit);
|
||||
|
||||
@ -2267,6 +2279,6 @@ void SkXPSDevice::drawBitmapRect(const SkBitmap& bitmap,
|
||||
SkPaint paintWithShader(paint);
|
||||
paintWithShader.setStyle(SkPaint::kFill_Style);
|
||||
paintWithShader.setShader(std::move(bitmapShader));
|
||||
this->drawRect(dst, paintWithShader);
|
||||
this->drawRect(draw, dst, paintWithShader);
|
||||
}
|
||||
#endif//defined(SK_BUILD_FOR_WIN32)
|
||||
|
@ -16,10 +16,9 @@
|
||||
#include <XpsObjectModel.h>
|
||||
|
||||
#include "SkAutoCoInitialize.h"
|
||||
#include "SkBitSet.h"
|
||||
#include "SkBitmapDevice.h"
|
||||
#include "SkBitSet.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkClipStackDevice.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPath.h"
|
||||
@ -36,7 +35,7 @@
|
||||
|
||||
The drawing context for the XPS backend.
|
||||
*/
|
||||
class SkXPSDevice : public SkClipStackDevice {
|
||||
class SkXPSDevice : public SkBaseDevice {
|
||||
public:
|
||||
SK_API SkXPSDevice(SkISize);
|
||||
SK_API virtual ~SkXPSDevice();
|
||||
@ -74,39 +73,79 @@ public:
|
||||
bool endPortfolio();
|
||||
|
||||
protected:
|
||||
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 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 = 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,
|
||||
void drawPaint(const SkDraw&, const SkPaint& paint) override;
|
||||
|
||||
void drawPoints(
|
||||
const SkDraw&,
|
||||
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&,
|
||||
const SkPaint& paint) override;
|
||||
|
||||
void drawPath(
|
||||
const SkDraw&,
|
||||
const SkPath& platonicPath,
|
||||
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 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,
|
||||
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 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(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(SkBaseDevice*, int x, int y,
|
||||
const SkPaint&) override;
|
||||
|
||||
|
||||
private:
|
||||
class TypefaceUse : ::SkNoncopyable {
|
||||
@ -159,6 +198,7 @@ private:
|
||||
IXpsOMImageResource** image);
|
||||
|
||||
void internalDrawRect(
|
||||
const SkDraw&,
|
||||
const SkRect& r,
|
||||
bool transformRect,
|
||||
const SkPaint& paint);
|
||||
@ -217,6 +257,7 @@ private:
|
||||
TypefaceUse** fontResource);
|
||||
|
||||
HRESULT AddGlyphs(
|
||||
const SkDraw& d,
|
||||
IXpsOMObjectFactory* xpsFactory,
|
||||
IXpsOMCanvas* canvas,
|
||||
TypefaceUse* font,
|
||||
@ -248,14 +289,16 @@ private:
|
||||
const SkColor color,
|
||||
IXpsOMVisualCollection* visuals);
|
||||
|
||||
HRESULT clip(IXpsOMVisual* xpsVisual);
|
||||
|
||||
HRESULT clip(
|
||||
IXpsOMVisual* xpsVisual,
|
||||
const SkDraw& d);
|
||||
HRESULT clipToPath(
|
||||
IXpsOMVisual* xpsVisual,
|
||||
const SkPath& clipPath,
|
||||
XPS_FILL_RULE fillRule);
|
||||
|
||||
HRESULT drawInverseWindingPath(
|
||||
const SkDraw& d,
|
||||
const SkPath& devicePath,
|
||||
IXpsOMPath* xpsPath);
|
||||
|
||||
@ -272,6 +315,7 @@ private:
|
||||
const SkIRect& clip, SkIRect* clipIRect);
|
||||
|
||||
HRESULT applyMask(
|
||||
const SkDraw& d,
|
||||
const SkMask& mask,
|
||||
const SkVector& ppuScale,
|
||||
IXpsOMPath* shadedPath);
|
||||
@ -282,7 +326,7 @@ private:
|
||||
SkXPSDevice(const SkXPSDevice&);
|
||||
void operator=(const SkXPSDevice&);
|
||||
|
||||
typedef SkClipStackDevice INHERITED;
|
||||
typedef SkBaseDevice INHERITED;
|
||||
};
|
||||
|
||||
#endif // SK_BUILD_FOR_WIN
|
||||
|
@ -30,9 +30,9 @@ public:
|
||||
FakeDevice() : INHERITED(make_bm(100, 100), SkSurfaceProps(0, kUnknown_SkPixelGeometry)) {
|
||||
}
|
||||
|
||||
void drawRect(const SkRect& r, const SkPaint& paint) override {
|
||||
fLastMatrix = this->ctm();
|
||||
this->INHERITED::drawRect(r, paint);
|
||||
void drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) override {
|
||||
fLastMatrix = *draw.fMatrix;
|
||||
this->INHERITED::drawRect(draw, r, paint);
|
||||
}
|
||||
|
||||
SkMatrix fLastMatrix;
|
||||
|
@ -307,7 +307,7 @@ void SkDebugCanvas::drawTo(SkCanvas* originalCanvas, int index, int m) {
|
||||
}
|
||||
if (pathOpsMode) {
|
||||
this->resetClipStackData();
|
||||
const SkClipStack* clipStack = nullptr;//HACK filterCanvas.getClipStack();
|
||||
const SkClipStack* clipStack = filterCanvas.getClipStack();
|
||||
SkClipStack::Iter iter(*clipStack, SkClipStack::Iter::kBottom_IterStart);
|
||||
const SkClipStack::Element* element;
|
||||
SkPath devPath;
|
||||
|
Loading…
Reference in New Issue
Block a user