Index: src/core/SkCanvas.cpp |
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp |
index 6beb26e4cad9c42d70b99e44f7d62f867a15e222..dcc7047dbcee58ecf56d9d914a09b109afa3baeb 100644 |
--- a/src/core/SkCanvas.cpp |
+++ b/src/core/SkCanvas.cpp |
@@ -5,7 +5,6 @@ |
* found in the LICENSE file. |
*/ |
- |
#include "SkCanvas.h" |
#include "SkCanvasPriv.h" |
#include "SkBitmapDevice.h" |
@@ -67,6 +66,19 @@ void SkCanvas::predrawNotify() { |
/////////////////////////////////////////////////////////////////////////////// |
+static uint32_t filter_paint_flags(const SkSurfaceProps& props, uint32_t flags) { |
+ const uint32_t propFlags = props.flags(); |
+ if (propFlags & SkSurfaceProps::kDisallowDither_Flag) { |
+ flags &= ~SkPaint::kDither_Flag; |
+ } |
+ if (propFlags & SkSurfaceProps::kDisallowAntiAlias_Flag) { |
+ flags &= ~SkPaint::kAntiAlias_Flag; |
+ } |
+ return flags; |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
/* This is the record we keep for each SkBaseDevice that the user installs. |
The clip/matrix/proc are fields that reflect the top of the save/restore |
stack. Whenever the canvas changes, it marks a dirty flag, and then before |
@@ -250,12 +262,12 @@ private: |
class AutoDrawLooper { |
public: |
- AutoDrawLooper(SkCanvas* canvas, const SkPaint& paint, |
+ AutoDrawLooper(SkCanvas* canvas, const SkSurfaceProps& props, const SkPaint& paint, |
bool skipLayerForImageFilter = false, |
const SkRect* bounds = NULL) : fOrigPaint(paint) { |
fCanvas = canvas; |
fFilter = canvas->getDrawFilter(); |
- fPaint = NULL; |
+ fPaint = &fOrigPaint; |
fSaveCount = canvas->getSaveCount(); |
fDoClearImageFilter = false; |
fDone = false; |
@@ -280,6 +292,15 @@ public: |
// can we be marked as simple? |
fIsSimple = !fFilter && !fDoClearImageFilter; |
} |
+ |
+ uint32_t oldFlags = paint.getFlags(); |
+ fNewPaintFlags = filter_paint_flags(props, oldFlags); |
+ if (fIsSimple && (fNewPaintFlags != oldFlags)) { |
+ SkPaint* paint = fLazyPaint.set(fOrigPaint); |
+ paint->setFlags(fNewPaintFlags); |
+ fPaint = paint; |
+ // if we're not simple, doNext() will take care of calling setFlags() |
+ } |
} |
~AutoDrawLooper() { |
@@ -299,7 +320,6 @@ public: |
return false; |
} else if (fIsSimple) { |
fDone = true; |
- fPaint = &fOrigPaint; |
return !fPaint->nothingToDraw(); |
} else { |
return this->doNext(drawType); |
@@ -313,6 +333,7 @@ private: |
SkDrawFilter* fFilter; |
const SkPaint* fPaint; |
int fSaveCount; |
+ uint32_t fNewPaintFlags; |
bool fDoClearImageFilter; |
bool fDone; |
bool fIsSimple; |
@@ -328,6 +349,7 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { |
SkASSERT(fLooperContext || fFilter || fDoClearImageFilter); |
SkPaint* paint = fLazyPaint.set(fOrigPaint); |
+ paint->setFlags(fNewPaintFlags); |
if (fDoClearImageFilter) { |
paint->setImageFilter(NULL); |
@@ -362,19 +384,17 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { |
return true; |
} |
-#include "SkColorPriv.h" |
- |
////////// macros to place around the internal draw calls ////////////////// |
#define LOOPER_BEGIN_DRAWDEVICE(paint, type) \ |
this->predrawNotify(); \ |
- AutoDrawLooper looper(this, paint, true); \ |
+ AutoDrawLooper looper(this, fProps, paint, true); \ |
while (looper.next(type)) { \ |
SkDrawIter iter(this); |
#define LOOPER_BEGIN(paint, type, bounds) \ |
this->predrawNotify(); \ |
- AutoDrawLooper looper(this, paint, false, bounds); \ |
+ AutoDrawLooper looper(this, fProps, paint, false, bounds); \ |
while (looper.next(type)) { \ |
SkDrawIter iter(this); |
@@ -382,6 +402,10 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { |
//////////////////////////////////////////////////////////////////////////// |
+void SkCanvas::setupDevice(SkBaseDevice* device) { |
+ device->setPixelGeometry(fProps.pixelGeometry()); |
+} |
+ |
SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { |
fConservativeRasterClip = SkToBool(flags & kConservativeRasterClip_InitFlag); |
fCachedLocalClipBounds.setEmpty(); |
@@ -393,10 +417,6 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { |
fCullCount = 0; |
fMetaData = NULL; |
- if (device && device->forceConservativeRasterClip()) { |
- fConservativeRasterClip = true; |
- } |
- |
fMCRec = (MCRec*)fMCStack.push_back(); |
new (fMCRec) MCRec(fConservativeRasterClip); |
@@ -406,6 +426,10 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { |
fSurfaceBase = NULL; |
if (device) { |
+ this->setupDevice(device); |
+ if (device->forceConservativeRasterClip()) { |
+ fConservativeRasterClip = true; |
+ } |
device->onAttachToCanvas(this); |
fMCRec->fLayer->fDevice = SkRef(device); |
fMCRec->fRasterClip.setRect(SkIRect::MakeWH(device->width(), device->height())); |
@@ -415,6 +439,7 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) { |
SkCanvas::SkCanvas() |
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
+ , fProps(SkSurfaceProps::kLegacyFontHost_InitType) |
{ |
inc_canvas(); |
@@ -438,6 +463,7 @@ private: |
SkCanvas::SkCanvas(int width, int height) |
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
+ , fProps(SkSurfaceProps::kLegacyFontHost_InitType) |
{ |
inc_canvas(); |
@@ -446,14 +472,16 @@ SkCanvas::SkCanvas(int width, int height) |
SkCanvas::SkCanvas(int width, int height, InitFlags flags) |
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
+ , fProps(SkSurfaceProps::kLegacyFontHost_InitType) |
{ |
inc_canvas(); |
this->init(SkNEW_ARGS(SkNoPixelsBitmapDevice, (width, height)), flags)->unref(); |
} |
-SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) |
+SkCanvas::SkCanvas(SkBaseDevice* device, const SkSurfaceProps* props, InitFlags flags) |
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
+ , fProps(SkSurfacePropsCopyOrDefault(props)) |
{ |
inc_canvas(); |
@@ -462,18 +490,31 @@ SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags) |
SkCanvas::SkCanvas(SkBaseDevice* device) |
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
+ , fProps(SkSurfaceProps::kLegacyFontHost_InitType) |
{ |
inc_canvas(); |
this->init(device, kDefault_InitFlags); |
} |
-SkCanvas::SkCanvas(const SkBitmap& bitmap) |
+SkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) |
: fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
+ , fProps(props) |
{ |
inc_canvas(); |
+ |
+ SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); |
+ this->init(device, kDefault_InitFlags); |
+} |
- this->init(SkNEW_ARGS(SkBitmapDevice, (bitmap)), kDefault_InitFlags)->unref(); |
+SkCanvas::SkCanvas(const SkBitmap& bitmap) |
+ : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage)) |
+ , fProps(SkSurfaceProps::kLegacyFontHost_InitType) |
+{ |
+ inc_canvas(); |
+ |
+ SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); |
+ this->init(device, kDefault_InitFlags); |
} |
SkCanvas::~SkCanvas() { |
@@ -564,6 +605,7 @@ SkBaseDevice* SkCanvas::setRootDevice(SkBaseDevice* device) { |
SkRefCnt_SafeAssign(rec->fLayer->fDevice, device); |
rootDevice = device; |
+ this->setupDevice(device); |
fDeviceCMDirty = true; |
@@ -899,6 +941,7 @@ int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, Save |
SkDebugf("Unable to create device for layer."); |
return count; |
} |
+ this->setupDevice(device); |
device->setOrigin(ir.fLeft, ir.fTop); |
DeviceCM* layer = SkNEW_ARGS(DeviceCM, |
@@ -994,13 +1037,16 @@ bool SkCanvas::isDrawingToLayer() const { |
return fSaveLayerCount > 0; |
} |
-SkSurface* SkCanvas::newSurface(const SkImageInfo& info) { |
- return this->onNewSurface(info); |
+SkSurface* SkCanvas::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) { |
+ if (NULL == props) { |
+ props = &fProps; |
+ } |
+ return this->onNewSurface(info, *props); |
} |
-SkSurface* SkCanvas::onNewSurface(const SkImageInfo& info) { |
+SkSurface* SkCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) { |
SkBaseDevice* dev = this->getDevice(); |
- return dev ? dev->newSurface(info) : NULL; |
+ return dev ? dev->newSurface(info, props) : NULL; |
} |
SkImageInfo SkCanvas::imageInfo() const { |