static void add_rect_to_clip(const GrClip& clip, const SkRect& devRect, GrClip* out) { switch (clip.clipType()) { case GrClip::kClipStack_ClipType: { SkClipStack* stack = new SkClipStack; *stack = *clip.clipStack(); // The stack is actually in clip space not device space. SkRect clipRect = devRect; SkPoint origin = { SkIntToScalar(clip.origin().fX), SkIntToScalar(clip.origin().fY) }; clipRect.offset(origin); SkIRect iclipRect; clipRect.roundOut(&iclipRect); clipRect = SkRect::Make(iclipRect); stack->clipDevRect(clipRect, SkRegion::kIntersect_Op, false); out->setClipStack(stack, &clip.origin()); break; } case GrClip::kWideOpen_ClipType: *out = GrClip(devRect); break; case GrClip::kIRect_ClipType: { SkIRect intersect; devRect.roundOut(&intersect); if (intersect.intersect(clip.irect())) { *out = GrClip(intersect); } else { *out = clip; } break; } } }
// Ensure that the 'getConservativeBounds' calls are returning bounds clamped // to the render target static void test_clip_bounds(skiatest::Reporter* reporter, GrContext* context) { static const int kXSize = 100; static const int kYSize = 100; GrTextureDesc desc; desc.fFlags = kRenderTarget_GrTextureFlagBit; desc.fConfig = kAlpha_8_GrPixelConfig; desc.fWidth = kXSize; desc.fHeight = kYSize; GrTexture* texture = context->createUncachedTexture(desc, NULL, 0); if (!texture) { return; } SkAutoUnref au(texture); SkIRect intScreen = SkIRect::MakeWH(kXSize, kYSize); SkRect screen; screen = SkRect::MakeWH(SkIntToScalar(kXSize), SkIntToScalar(kYSize)); SkRect clipRect(screen); clipRect.outset(10, 10); // create a clip stack that will (trivially) reduce to a single rect that // is larger than the screen SkClipStack stack; stack.clipDevRect(clipRect, SkRegion::kReplace_Op, false); bool isIntersectionOfRects = true; SkRect devStackBounds; stack.getConservativeBounds(0, 0, kXSize, kYSize, &devStackBounds, &isIntersectionOfRects); // make sure that the SkClipStack is behaving itself REPORTER_ASSERT(reporter, screen == devStackBounds); REPORTER_ASSERT(reporter, isIntersectionOfRects); // wrap the SkClipStack in a GrClipData GrClipData clipData; clipData.fClipStack = &stack; SkIRect devGrClipDataBound; clipData.getConservativeBounds(texture, &devGrClipDataBound, &isIntersectionOfRects); // make sure that GrClipData is behaving itself REPORTER_ASSERT(reporter, intScreen == devGrClipDataBound); REPORTER_ASSERT(reporter, isIntersectionOfRects); }
void SkSVGDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bm, const SkRect* srcOrNull, const SkRect& dst, const SkPaint& paint, SK_VIRTUAL_CONSTRAINT_TYPE) { SkMatrix adjustedMatrix; adjustedMatrix.setRectToRect(srcOrNull ? *srcOrNull : SkRect::Make(bm.bounds()), dst, SkMatrix::kFill_ScaleToFit); adjustedMatrix.postConcat(*draw.fMatrix); SkDraw adjustedDraw(draw); adjustedDraw.fMatrix = &adjustedMatrix; SkClipStack adjustedClipStack; if (srcOrNull && *srcOrNull != SkRect::Make(bm.bounds())) { SkRect devClipRect; draw.fMatrix->mapRect(&devClipRect, dst); adjustedClipStack = *draw.fClipStack; adjustedClipStack.clipDevRect(devClipRect, SkRegion::kIntersect_Op, paint.isAntiAlias()); adjustedDraw.fClipStack = &adjustedClipStack; } drawBitmapCommon(adjustedDraw, bm, paint); }