#include "GrPath.h"
#include "SkStrokeRec.h"
+/*
+ * For now paths only natively support winding and even odd fill types
+ */
+static GrPathRendering::FillType convert_skpath_filltype(SkPath::FillType fill) {
+ switch (fill) {
+ default:
+ SkFAIL("Incomplete Switch\n");
+ case SkPath::kWinding_FillType:
+ case SkPath::kInverseWinding_FillType:
+ return GrPathRendering::kWinding_FillType;
+ case SkPath::kEvenOdd_FillType:
+ case SkPath::kInverseEvenOdd_FillType:
+ return GrPathRendering::kEvenOdd_FillType;
+ }
+}
+
GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrContext* context) {
SkASSERT(context);
SkASSERT(context->getGpu());
target->getDrawState().getStencil().isDisabled();
}
-GrPathRenderer::StencilSupport GrStencilAndCoverPathRenderer::onGetStencilSupport(
- const SkPath&,
- const SkStrokeRec& ,
- const GrDrawTarget*) const {
+GrPathRenderer::StencilSupport
+GrStencilAndCoverPathRenderer::onGetStencilSupport(const SkPath&,
+ const SkStrokeRec& ,
+ const GrDrawTarget*) const {
return GrPathRenderer::kStencilOnly_StencilSupport;
}
GrDrawTarget* target) {
SkASSERT(!path.isInverseFillType());
SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke));
- target->stencilPath(p, path.getFillType());
+ target->stencilPath(p, convert_skpath_filltype(path.getFillType()));
}
bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
0x0000,
0xffff);
- *drawState->stencil() = kInvertedStencilPass;
+ drawState->setStencil(kInvertedStencilPass);
+
+ // fake inverse with a stencil and cover
+ target->stencilPath(p, convert_skpath_filltype(path.getFillType()));
+
+ GrDrawState::AutoViewMatrixRestore avmr;
+ SkRect bounds = SkRect::MakeLTRB(0, 0,
+ SkIntToScalar(drawState->getRenderTarget()->width()),
+ SkIntToScalar(drawState->getRenderTarget()->height()));
+ SkMatrix vmi;
+ // mapRect through persp matrix may not be correct
+ if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
+ vmi.mapRect(&bounds);
+ // theoretically could set bloat = 0, instead leave it because of matrix inversion
+ // precision.
+ SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf;
+ bounds.outset(bloat, bloat);
+ } else {
+ avmr.setIdentity(drawState);
+ }
+ target->drawSimpleRect(bounds);
} else {
GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
kZero_StencilOp,
0x0000,
0xffff);
- *drawState->stencil() = kStencilPass;
+ drawState->setStencil(kStencilPass);
+ target->drawPath(p, convert_skpath_filltype(path.getFillType()));
}
- target->drawPath(p, path.getFillType());
-
target->drawState()->stencil()->setDisabled();
return true;
}