本文整理汇总了C++中SkPath::isInverseFillType方法的典型用法代码示例。如果您正苦于以下问题:C++ SkPath::isInverseFillType方法的具体用法?C++ SkPath::isInverseFillType怎么用?C++ SkPath::isInverseFillType使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SkPath
的用法示例。
在下文中一共展示了SkPath::isInverseFillType方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: FillPath
void SkScan::FillPath(const SkPath& path, const SkRegion& origClip,
SkBlitter* blitter) {
if (origClip.isEmpty()) {
return;
}
// Our edges are fixed-point, and don't like the bounds of the clip to
// exceed that. Here we trim the clip just so we don't overflow later on
const SkRegion* clipPtr = &origClip;
SkRegion finiteClip;
if (clip_to_limit(origClip, &finiteClip)) {
if (finiteClip.isEmpty()) {
return;
}
clipPtr = &finiteClip;
}
// don't reference "origClip" any more, just use clipPtr
SkRect bounds = path.getBounds();
bool irPreClipped = false;
if (!SkRectPriv::MakeLargeS32().contains(bounds)) {
if (!bounds.intersect(SkRectPriv::MakeLargeS32())) {
bounds.setEmpty();
}
irPreClipped = true;
}
SkIRect ir = conservative_round_to_int(bounds);
if (ir.isEmpty()) {
if (path.isInverseFillType()) {
blitter->blitRegion(*clipPtr);
}
return;
}
SkScanClipper clipper(blitter, clipPtr, ir, path.isInverseFillType(), irPreClipped);
blitter = clipper.getBlitter();
if (blitter) {
// we have to keep our calls to blitter in sorted order, so we
// must blit the above section first, then the middle, then the bottom.
if (path.isInverseFillType()) {
sk_blit_above(blitter, ir, *clipPtr);
}
SkASSERT(clipper.getClipRect() == nullptr ||
*clipper.getClipRect() == clipPtr->getBounds());
sk_fill_path(path, clipPtr->getBounds(), blitter, ir.fTop, ir.fBottom,
0, clipper.getClipRect() == nullptr);
if (path.isInverseFillType()) {
sk_blit_below(blitter, ir, *clipPtr);
}
} else {
// what does it mean to not have a blitter if path.isInverseFillType???
}
}
示例2: canStencilAndDrawElement
bool GrClipMaskManager::canStencilAndDrawElement(GrPipelineBuilder* pipelineBuilder,
GrTexture* target,
GrPathRenderer** pr,
const SkClipStack::Element* element) {
pipelineBuilder->setRenderTarget(target->asRenderTarget());
if (Element::kRect_Type == element->getType()) {
return true;
} else {
// We shouldn't get here with an empty clip element.
SkASSERT(Element::kEmpty_Type != element->getType());
SkPath path;
element->asPath(&path);
if (path.isInverseFillType()) {
path.toggleInverseFillType();
}
GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
GrPathRendererChain::DrawType type = element->isAA() ?
GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
GrPathRendererChain::kStencilAndColor_DrawType;
*pr = this->getContext()->getPathRenderer(fDrawTarget, pipelineBuilder, SkMatrix::I(), path,
stroke, false, type);
return SkToBool(*pr);
}
}
示例3: drawElement
bool GrClipMaskManager::drawElement(GrPipelineBuilder* pipelineBuilder,
const SkMatrix& viewMatrix,
GrTexture* target,
const SkClipStack::Element* element,
GrPathRenderer* pr) {
GrDrawTarget::AutoGeometryPush agp(fClipTarget);
pipelineBuilder->setRenderTarget(target->asRenderTarget());
// The color we use to draw does not matter since we will always be using a GrCoverageSetOpXP
// which ignores color.
GrColor color = GrColor_WHITE;
// TODO: Draw rrects directly here.
switch (element->getType()) {
case Element::kEmpty_Type:
SkDEBUGFAIL("Should never get here with an empty element.");
break;
case Element::kRect_Type:
// TODO: Do rects directly to the accumulator using a aa-rect GrProcessor that covers
// the entire mask bounds and writes 0 outside the rect.
if (element->isAA()) {
SkRect devRect = element->getRect();
viewMatrix.mapRect(&devRect);
this->getContext()->getAARectRenderer()->fillAARect(fClipTarget,
pipelineBuilder,
color,
viewMatrix,
element->getRect(),
devRect);
} else {
fClipTarget->drawSimpleRect(pipelineBuilder, color, viewMatrix, element->getRect());
}
return true;
default: {
SkPath path;
element->asPath(&path);
path.setIsVolatile(true);
if (path.isInverseFillType()) {
path.toggleInverseFillType();
}
SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
if (NULL == pr) {
GrPathRendererChain::DrawType type;
type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType :
GrPathRendererChain::kColor_DrawType;
pr = this->getContext()->getPathRenderer(fClipTarget, pipelineBuilder, viewMatrix,
path, stroke, false, type);
}
if (NULL == pr) {
return false;
}
pr->drawPath(fClipTarget, pipelineBuilder, color, viewMatrix, path, stroke,
element->isAA());
break;
}
}
return true;
}
示例4: canDrawPath
bool GrStrokePathRenderer::canDrawPath(const SkPath& path,
const SkStrokeRec& stroke,
const GrDrawTarget* target,
bool antiAlias) const {
// FIXME : put the proper condition once GrDrawTarget::isOpaque is implemented
const bool isOpaque = true; // target->isOpaque();
// FIXME : remove this requirement once we have AA circles and implement the
// circle joins/caps appropriately in the ::onDrawPath() function.
const bool requiresAACircle = (stroke.getCap() == SkPaint::kRound_Cap) ||
(stroke.getJoin() == SkPaint::kRound_Join);
// Indices being stored in uint16, we don't want to overflow the indices capacity
static const int maxVBSize = 1 << 16;
const int maxNbVerts = (path.countPoints() + 1) * 5;
// Check that the path contains no curved lines, only straight lines
static const uint32_t unsupportedMask = SkPath::kQuad_SegmentMask | SkPath::kCubic_SegmentMask;
// Must not be filled nor hairline nor semi-transparent
// Note : May require a check to path.isConvex() if AA is supported
return ((stroke.getStyle() == SkStrokeRec::kStroke_Style) && (maxNbVerts < maxVBSize) &&
!path.isInverseFillType() && isOpaque && !requiresAACircle && !antiAlias &&
((path.getSegmentMasks() & unsupportedMask) == 0));
}
示例5: stencil_element
static bool stencil_element(GrDrawContext* dc,
const GrFixedClip& clip,
const GrUserStencilSettings* ss,
const SkMatrix& viewMatrix,
const SkClipStack::Element* element) {
// TODO: Draw rrects directly here.
switch (element->getType()) {
case Element::kEmpty_Type:
SkDEBUGFAIL("Should never get here with an empty element.");
break;
case Element::kRect_Type:
return dc->drawContextPriv().drawAndStencilRect(clip, ss,
element->getOp(),
element->isInverseFilled(),
element->isAA(),
viewMatrix, element->getRect());
break;
default: {
SkPath path;
element->asPath(&path);
if (path.isInverseFillType()) {
path.toggleInverseFillType();
}
return dc->drawContextPriv().drawAndStencilPath(clip, ss,
element->getOp(),
element->isInverseFilled(),
element->isAA(), viewMatrix, path);
break;
}
}
return false;
}
示例6: draw_element
static void draw_element(GrDrawContext* dc,
const GrClip& clip, // TODO: can this just always be WideOpen?
const GrPaint &paint,
const SkMatrix& viewMatrix,
const SkClipStack::Element* element) {
// TODO: Draw rrects directly here.
switch (element->getType()) {
case Element::kEmpty_Type:
SkDEBUGFAIL("Should never get here with an empty element.");
break;
case Element::kRect_Type:
dc->drawRect(clip, paint, viewMatrix, element->getRect());
break;
default: {
SkPath path;
element->asPath(&path);
if (path.isInverseFillType()) {
path.toggleInverseFillType();
}
dc->drawPath(clip, paint, viewMatrix, path, GrStyle::SimpleFill());
break;
}
}
}
示例7: onStencilPath
void GrStencilAndCoverPathRenderer::onStencilPath(const SkPath& path,
const SkStrokeRec& stroke,
GrDrawTarget* target) {
SkASSERT(!path.isInverseFillType());
SkAutoTUnref<GrPath> p(fGpu->createPath(path));
target->stencilPath(p, stroke, path.getFillType());
}
示例8: op
bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect& bounds,
SkRegion::Op op, bool doAA) {
AUTO_RASTERCLIP_VALIDATE(*this);
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;
SkPath devPath;
if (matrix.isIdentity()) {
devPath = path;
} else {
path.transform(matrix, &devPath);
devPath.setIsVolatile(true);
}
if (SkRegion::kIntersect_Op == op) {
// since we are intersect, we can do better (tighter) with currRgn's
// bounds, than just using the device. However, if currRgn is complex,
// our region blitter may hork, so we do that case in two steps.
if (this->isRect()) {
// FIXME: we should also be able to do this when this->isBW(),
// but relaxing the test above triggers GM asserts in
// SkRgnBuilder::blitH(). We need to investigate what's going on.
return this->setPath(devPath, this->bwRgn(), doAA);
} else {
base.setRect(this->getBounds());
SkRasterClip clip(fForceConservativeRects);
clip.setPath(devPath, base, doAA);
return this->op(clip, op);
}
} else {
base.setRect(bounds);
if (SkRegion::kReplace_Op == op) {
return this->setPath(devPath, base, doAA);
} else {
SkRasterClip clip(fForceConservativeRects);
clip.setPath(devPath, base, doAA);
return this->op(clip, op);
}
}
}
示例9: canDrawPath
bool GrAndroidPathRenderer::canDrawPath(const SkPath& path,
const SkStrokeRec& stroke,
const GrDrawTarget* target,
bool antiAlias) const {
return ((stroke.isFillStyle() || stroke.getStyle() == SkStrokeRec::kStroke_Style)
&& !path.isInverseFillType() && path.isConvex());
}
示例10: canDrawPath
bool GrAADistanceFieldPathRenderer::canDrawPath(const GrDrawTarget* target,
const GrPipelineBuilder* pipelineBuilder,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) const {
// TODO: Support inverse fill
// TODO: Support strokes
if (!target->caps()->shaderCaps()->shaderDerivativeSupport() || !antiAlias
|| path.isInverseFillType() || path.isVolatile() || !stroke.isFillStyle()) {
return false;
}
// currently don't support perspective
if (viewMatrix.hasPerspective()) {
return false;
}
// only support paths smaller than 64x64, scaled to less than 256x256
// the goal is to accelerate rendering of lots of small paths that may be scaling
SkScalar maxScale = viewMatrix.getMaxScale();
const SkRect& bounds = path.getBounds();
SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
return maxDim < 64.f && maxDim * maxScale < 256.f;
}
示例11: onStencilPath
void GrStencilAndCoverPathRenderer::onStencilPath(const SkPath& path,
const SkStrokeRec& stroke,
GrDrawTarget* target) {
SkASSERT(!path.isInverseFillType());
SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke));
target->stencilPath(p, convert_skpath_filltype(path.getFillType()));
}
示例12: test_emptydrawing
/* Two invariants are tested: How does an empty/degenerate path draw?
* - if the path is drawn inverse, it should draw everywhere
* - if the path is drawn non-inverse, it should draw nowhere
*
* Things to iterate on:
* - path (empty, degenerate line/quad/cubic w/ and w/o close
* - paint style
* - path filltype
* - path stroke variants (e.g. caps, joins, width)
*/
static void test_emptydrawing(skiatest::Reporter* reporter) {
static void (*gMakeProc[])(SkPath*) = {
make_empty, make_M, make_MM, make_MZM, make_L, make_Q, make_C
};
static SkPath::FillType gFills[] = {
SkPath::kWinding_FillType,
SkPath::kEvenOdd_FillType,
SkPath::kInverseWinding_FillType,
SkPath::kInverseEvenOdd_FillType
};
for (int doClose = 0; doClose < 2; ++doClose) {
for (size_t i = 0; i < SK_ARRAY_COUNT(gMakeProc); ++i) {
SkPath path;
gMakeProc[i](&path);
if (doClose) {
path.close();
}
for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
path.setFillType(gFills[fill]);
bool shouldDraw = path.isInverseFillType();
iter_paint(reporter, path, shouldDraw);
}
}
}
}
示例13: TessellatingPathBatch
TessellatingPathBatch(const GrColor& color,
const SkPath& path,
const GrStrokeInfo& stroke,
const SkMatrix& viewMatrix,
const SkRect& clipBounds)
: INHERITED(ClassID())
, fColor(color)
, fPath(path)
, fStroke(stroke)
, fViewMatrix(viewMatrix) {
const SkRect& pathBounds = path.getBounds();
fClipBounds = clipBounds;
// Because the clip bounds are used to add a contour for inverse fills, they must also
// include the path bounds.
fClipBounds.join(pathBounds);
if (path.isInverseFillType()) {
fBounds = fClipBounds;
} else {
fBounds = path.getBounds();
}
if (!stroke.isFillStyle()) {
SkScalar radius = SkScalarHalf(stroke.getWidth());
if (stroke.getJoin() == SkPaint::kMiter_Join) {
SkScalar scale = stroke.getMiter();
if (scale > SK_Scalar1) {
radius = SkScalarMul(radius, scale);
}
}
fBounds.outset(radius, radius);
}
viewMatrix.mapRect(&fBounds);
}
示例14: SkHitTestPath
bool SkHitTestPath(const SkPath& path, SkRect& target, bool hires) {
if (target.isEmpty()) {
return false;
}
bool isInverse = path.isInverseFillType();
if (path.isEmpty()) {
return isInverse;
}
SkRect bounds = path.getBounds();
bool sects = SkRect::Intersects(target, bounds);
if (isInverse) {
if (!sects) {
return true;
}
} else {
if (!sects) {
return false;
}
if (target.contains(bounds)) {
return true;
}
}
SkPath devPath;
const SkPath* pathPtr;
SkRect devTarget;
if (hires) {
const SkScalar coordLimit = SkIntToScalar(16384);
const SkRect limit = { 0, 0, coordLimit, coordLimit };
SkMatrix matrix;
matrix.setRectToRect(bounds, limit, SkMatrix::kFill_ScaleToFit);
path.transform(matrix, &devPath);
matrix.mapRect(&devTarget, target);
pathPtr = &devPath;
} else {
devTarget = target;
pathPtr = &path;
}
SkIRect iTarget;
devTarget.round(&iTarget);
if (iTarget.isEmpty()) {
iTarget.fLeft = SkScalarFloorToInt(devTarget.fLeft);
iTarget.fTop = SkScalarFloorToInt(devTarget.fTop);
iTarget.fRight = iTarget.fLeft + 1;
iTarget.fBottom = iTarget.fTop + 1;
}
SkRegion clip(iTarget);
SkRegion rgn;
return rgn.setPath(*pathPtr, clip) ^ isInverse;
}
示例15: onCanDrawPath
bool GrPLSPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
// We have support for even-odd rendering, but are having some troublesome
// seams. Disable in the presence of even-odd for now.
SkPath path;
args.fShape->asPath(&path);
return args.fShaderCaps->shaderDerivativeSupport() && args.fAntiAlias &&
args.fShape->style().isSimpleFill() && !path.isInverseFillType() &&
path.getFillType() == SkPath::FillType::kWinding_FillType;
}