--- /dev/null
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkClipStack.h"
+#include "SkDevice.h"
+#include "SkPath.h"
+#include "SkPathOps.h"
+#include "SkPicture.h"
+#include "SkRect.h"
+
+namespace skiagm {
+
+class PathOpsSkpClipGM : public GM {
+public:
+ PathOpsSkpClipGM() {
+ }
+
+protected:
+ virtual SkString onShortName() SK_OVERRIDE {
+ return SkString("pathopsskpclip");
+ }
+
+ virtual SkISize onISize() SK_OVERRIDE {
+ return make_isize(1200, 900);
+ }
+
+ virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+ SkPicture* pict = SkNEW(SkPicture);
+ SkCanvas* rec = pict->beginRecording(1200, 900);
+ SkPath p;
+ SkRect r = {
+ SkIntToScalar(100),
+ SkIntToScalar(200),
+ SkIntToScalar(400),
+ SkIntToScalar(700)
+ };
+ p.addRoundRect(r, SkIntToScalar(50), SkIntToScalar(50));
+ rec->clipPath(p, SkRegion::kIntersect_Op, true);
+ rec->translate(SkIntToScalar(250), SkIntToScalar(250));
+ rec->clipPath(p, SkRegion::kIntersect_Op, true);
+ rec->drawColor(0xffff0000);
+ pict->endRecording();
+
+ canvas->setAllowSimplifyClip(true);
+ canvas->save();
+ canvas->drawPicture(*pict);
+ canvas->restore();
+
+ canvas->setAllowSimplifyClip(false);
+ canvas->save();
+ canvas->translate(SkIntToScalar(1200 / 2), 0);
+ canvas->drawPicture(*pict);
+ canvas->restore();
+ SkSafeUnref(pict);
+ }
+
+private:
+ typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static GM* MyFactory(void*) { return new PathOpsSkpClipGM; }
+static GMRegistry reg(MyFactory);
+
+}
'<(skia_src_path)/lazy/SkPurgeableMemoryBlock.h',
'<(skia_src_path)/lazy/SkPurgeableMemoryBlock_common.cpp',
'<(skia_src_path)/lazy/SkPurgeableImageCache.cpp',
+
+ # Path ops
+ '<(skia_include_path)/pathops/SkPathOps.h',
+
+ '<(skia_src_path)/pathops/SkAddIntersections.cpp',
+ '<(skia_src_path)/pathops/SkDCubicIntersection.cpp',
+ '<(skia_src_path)/pathops/SkDCubicLineIntersection.cpp',
+ '<(skia_src_path)/pathops/SkDCubicToQuads.cpp',
+ '<(skia_src_path)/pathops/SkDLineIntersection.cpp',
+ '<(skia_src_path)/pathops/SkDQuadImplicit.cpp',
+ '<(skia_src_path)/pathops/SkDQuadIntersection.cpp',
+ '<(skia_src_path)/pathops/SkDQuadLineIntersection.cpp',
+ '<(skia_src_path)/pathops/SkIntersections.cpp',
+ '<(skia_src_path)/pathops/SkOpAngle.cpp',
+ '<(skia_src_path)/pathops/SkOpContour.cpp',
+ '<(skia_src_path)/pathops/SkOpEdgeBuilder.cpp',
+ '<(skia_src_path)/pathops/SkOpSegment.cpp',
+ '<(skia_src_path)/pathops/SkPathOpsBounds.cpp',
+ '<(skia_src_path)/pathops/SkPathOpsCommon.cpp',
+ '<(skia_src_path)/pathops/SkPathOpsCubic.cpp',
+ '<(skia_src_path)/pathops/SkPathOpsDebug.cpp',
+ '<(skia_src_path)/pathops/SkPathOpsLine.cpp',
+ '<(skia_src_path)/pathops/SkPathOpsOp.cpp',
+ '<(skia_src_path)/pathops/SkPathOpsPoint.cpp',
+ '<(skia_src_path)/pathops/SkPathOpsQuad.cpp',
+ '<(skia_src_path)/pathops/SkPathOpsRect.cpp',
+ '<(skia_src_path)/pathops/SkPathOpsSimplify.cpp',
+ '<(skia_src_path)/pathops/SkPathOpsTriangle.cpp',
+ '<(skia_src_path)/pathops/SkPathOpsTypes.cpp',
+ '<(skia_src_path)/pathops/SkPathWriter.cpp',
+ '<(skia_src_path)/pathops/SkQuarticRoot.cpp',
+ '<(skia_src_path)/pathops/SkReduceOrder.cpp',
+ '<(skia_src_path)/pathops/SkAddIntersections.h',
+ '<(skia_src_path)/pathops/SkDQuadImplicit.h',
+ '<(skia_src_path)/pathops/SkIntersectionHelper.h',
+ '<(skia_src_path)/pathops/SkIntersections.h',
+ '<(skia_src_path)/pathops/SkLineParameters.h',
+ '<(skia_src_path)/pathops/SkOpAngle.h',
+ '<(skia_src_path)/pathops/SkOpContour.h',
+ '<(skia_src_path)/pathops/SkOpEdgeBuilder.h',
+ '<(skia_src_path)/pathops/SkOpSegment.h',
+ '<(skia_src_path)/pathops/SkOpSpan.h',
+ '<(skia_src_path)/pathops/SkPathOpsBounds.h',
+ '<(skia_src_path)/pathops/SkPathOpsCommon.h',
+ '<(skia_src_path)/pathops/SkPathOpsCubic.h',
+ '<(skia_src_path)/pathops/SkPathOpsCurve.h',
+ '<(skia_src_path)/pathops/SkPathOpsDebug.h',
+ '<(skia_src_path)/pathops/SkPathOpsLine.h',
+ '<(skia_src_path)/pathops/SkPathOpsPoint.h',
+ '<(skia_src_path)/pathops/SkPathOpsQuad.h',
+ '<(skia_src_path)/pathops/SkPathOpsRect.h',
+ '<(skia_src_path)/pathops/SkPathOpsSpan.h',
+ '<(skia_src_path)/pathops/SkPathOpsTriangle.h',
+ '<(skia_src_path)/pathops/SkPathOpsTypes.h',
+ '<(skia_src_path)/pathops/SkPathWriter.h',
+ '<(skia_src_path)/pathops/SkQuarticRoot.h',
+ '<(skia_src_path)/pathops/SkReduceOrder.h',
],
}
fAllowSoftClip = allow;
}
+ /** EXPERIMENTAL -- only used for testing
+ Set to simplify clip stack using path ops.
+ */
+ void setAllowSimplifyClip(bool allow) {
+ fAllowSimplifyClip = allow;
+ }
+
/** Modify the current clip with the specified region. Note that unlike
clipRect() and clipPath() which transform their arguments by the current
matrix, clipRegion() assumes its argument is already in device
mutable SkRectCompareType fLocalBoundsCompareType;
mutable bool fLocalBoundsCompareTypeDirty;
bool fAllowSoftClip;
+ bool fAllowSimplifyClip;
const SkRectCompareType& getLocalClipBoundsCompareType() const {
if (fLocalBoundsCompareTypeDirty) {
}
void computeLocalClipBoundsCompareType() const;
+
class AutoValidateClip : ::SkNoncopyable {
public:
explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
#include "SkDrawFilter.h"
#include "SkDrawLooper.h"
#include "SkMetaData.h"
+#include "SkPathOps.h"
#include "SkPicture.h"
#include "SkRasterClip.h"
#include "SkRRect.h"
fLocalBoundsCompareType.setEmpty();
fLocalBoundsCompareTypeDirty = true;
fAllowSoftClip = true;
+ fAllowSimplifyClip = false;
fDeviceCMDirty = false;
fSaveLayerCount = 0;
fMetaData = NULL;
// if we called path.swap() we could avoid a deep copy of this path
fClipStack.clipDevPath(devPath, op, doAA);
+ if (fAllowSimplifyClip) {
+ devPath.reset();
+ devPath.setFillType(SkPath::kInverseEvenOdd_FillType);
+ const SkClipStack* clipStack = getClipStack();
+ SkClipStack::Iter iter(*clipStack, SkClipStack::Iter::kBottom_IterStart);
+ const SkClipStack::Element* element;
+ while ((element = iter.next())) {
+ SkClipStack::Element::Type type = element->getType();
+ if (type == SkClipStack::Element::kEmpty_Type) {
+ continue;
+ }
+ SkPath operand;
+ if (type == SkClipStack::Element::kRect_Type) {
+ operand.addRect(element->getRect());
+ } else if (type == SkClipStack::Element::kPath_Type) {
+ operand = element->getPath();
+ } else {
+ SkDEBUGFAIL("Unexpected type.");
+ }
+ SkRegion::Op elementOp = element->getOp();
+ if (elementOp == SkRegion::kReplace_Op) {
+ devPath = operand;
+ } else {
+ Op(devPath, operand, (SkPathOp) elementOp, &devPath);
+ }
+ }
+ op = SkRegion::kReplace_Op;
+ }
+
return clipPathHelper(this, fMCRec->fRasterClip, devPath, op, doAA);
}