static void copyToMask(const SkRegion& rgn, SkMask* mask) { mask->fFormat = SkMask::kA8_Format; if (rgn.isEmpty()) { mask->fBounds.setEmpty(); mask->fRowBytes = 0; mask->fImage = nullptr; return; } mask->fBounds = rgn.getBounds(); mask->fRowBytes = mask->fBounds.width(); mask->fImage = SkMask::AllocImage(mask->computeImageSize()); sk_bzero(mask->fImage, mask->computeImageSize()); SkImageInfo info = SkImageInfo::Make(mask->fBounds.width(), mask->fBounds.height(), kAlpha_8_SkColorType, kPremul_SkAlphaType); SkBitmap bitmap; bitmap.installPixels(info, mask->fImage, mask->fRowBytes); // canvas expects its coordinate system to always be 0,0 in the top/left // so we translate the rgn to match that before drawing into the mask. // SkRegion tmpRgn(rgn); tmpRgn.translate(-rgn.getBounds().fLeft, -rgn.getBounds().fTop); SkCanvas canvas(bitmap); canvas.clipRegion(tmpRgn); canvas.drawColor(SK_ColorBLACK); }
static bool containsrect_proc(SkRegion& a, SkRegion& b) { SkIRect r = a.getBounds(); r.inset(r.width()/4, r.height()/4); (void)a.contains(r); r = b.getBounds(); r.inset(r.width()/4, r.height()/4); return b.contains(r); }
bool SkMaskFilter::filterPath(const SkPath& devPath, const SkMatrix& matrix, const SkRegion& clip, SkBounder* bounder, SkBlitter* blitter) { SkMask srcM, dstM; if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), this, &matrix, &srcM, SkMask::kComputeBoundsAndRenderImage_CreateMode)) { return false; } SkAutoMaskImage autoSrc(&srcM, false); if (!this->filterMask(&dstM, srcM, matrix, NULL)) return false; SkAutoMaskImage autoDst(&dstM, false); SkRegion::Cliperator clipper(clip, dstM.fBounds); if (!clipper.done() && (bounder == NULL || bounder->doIRect(dstM.fBounds))) { const SkIRect& cr = clipper.rect(); do { blitter->blitMask(dstM, cr); clipper.next(); } while (!clipper.done()); } return true; }
void PicturePile::drawWithClipRecursive(SkCanvas* canvas, SkRegion& clipRegion, int index) { // TODO: Add some debug visualizations of this if (index < 0 || clipRegion.isEmpty()) return; PictureContainer& pc = m_pile[index]; IntRect intersection = clipRegion.getBounds(); intersection.intersect(pc.area); if (pc.picture && !intersection.isEmpty()) { // SAMSUNG CHANGE ++ : Animation GIF frame remain in Base Picture // As the previous logic : Base Picture draws picture already drawn by other pile due to only using RECT. // It uses PATH and RECT, both now. SkPath pathClip; clipRegion.getBoundaryPath(&pathClip); // SAMSUNG CHANGE -- clipRegion.op(intersection, SkRegion::kDifference_Op); drawWithClipRecursive(canvas, clipRegion, index - 1); int saved = canvas->save(); canvas->clipRect(intersection); canvas->clipPath(pathClip); // SAMSUNG CHANGE : Animation GIF frame remain in Base Picture canvas->translate(pc.area.x(), pc.area.y()); canvas->drawPicture(*pc.picture); canvas->restoreToCount(saved); } else drawWithClipRecursive(canvas, clipRegion, index - 1); }
static void toString(const SkRegion& rgn, SkString* str) { str->append("Region:["); toString(rgn.getBounds(), str); str->append("]"); if (rgn.isComplex()) { str->append(".complex"); } }
bool SkBaseDevice::clipIsWideOpen() const { if (kRect_ClipType == this->onGetClipType()) { SkRegion rgn; this->onAsRgnClip(&rgn); SkASSERT(rgn.isRect()); return rgn.getBounds() == SkIRect::MakeWH(this->width(), this->height()); } else { return false; } }
static bool containsxy_proc(SkRegion& a, SkRegion& b) { const SkIRect& r = a.getBounds(); const int dx = r.width() / 8; const int dy = r.height() / 8; for (int y = r.fTop; y < r.fBottom; y += dy) { for (int x = r.fLeft; x < r.fRight; x += dx) { (void)a.contains(x, y); } } return true; }
AAClipBuilderBench(void* param, bool doPath, bool doAA) : INHERITED(param) { fDoPath = doPath; fDoAA = doAA; fName.printf("aaclip_build_%s_%s", doPath ? "path" : "rect", doAA ? "AA" : "BW"); fRegion.setRect(0, 0, 640, 480); fRect.set(fRegion.getBounds()); fRect.inset(SK_Scalar1/4, SK_Scalar1/4); fPath.addRoundRect(fRect, SkIntToScalar(20), SkIntToScalar(20)); }
void sk_blit_below(SkBlitter* blitter, const SkIRect& ir, const SkRegion& clip) { const SkIRect& cr = clip.getBounds(); SkIRect tmp; tmp.fLeft = cr.fLeft; tmp.fRight = cr.fRight; tmp.fTop = ir.fBottom; tmp.fBottom = cr.fBottom; if (!tmp.isEmpty()) { blitter->blitRectRegion(tmp, clip); } }
DEFINE_BATCH_CLASS_ID RegionBatch(GrColor color, const SkMatrix& viewMatrix, const SkRegion& region) : INHERITED(ClassID()) , fViewMatrix(viewMatrix) { RegionInfo& info = fRegions.push_back(); info.fColor = color; info.fRegion = region; SkRect bounds = SkRect::Make(region.getBounds()); this->setTransformedBounds(bounds, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo); }
static bool clip_to_limit(const SkRegion& orig, SkRegion* reduced) { // need to limit coordinates such that the width/height of our rect can be represented // in SkFixed (16.16). See skbug.com/7998 const int32_t limit = 32767 >> 1; SkIRect limitR; limitR.set(-limit, -limit, limit, limit); if (limitR.contains(orig.getBounds())) { return false; } reduced->op(orig, limitR, SkRegion::kIntersect_Op); return true; }
void SkConservativeClip::opIRect(const SkIRect& devRect, SkRegion::Op op) { if (SkRegion::kIntersect_Op == op) { if (!fBounds.intersect(devRect)) { fBounds.setEmpty(); } return; } // This may still create a complex region (which we would then take the bounds // Perhaps we should inline the op-logic directly to never create the rgn... SkRegion result; result.op(SkRegion(fBounds), SkRegion(devRect), op); fBounds = result.getBounds(); this->applyClipRestriction(op, &fBounds); }
bool SkRasterClip::setPath(const SkPath& path, const SkRegion& clip, bool doAA) { AUTO_RASTERCLIP_VALIDATE(*this); if (fForceConservativeRects) { return this->setConservativeRect(path.getBounds(), clip.getBounds(), path.isInverseFillType()); } if (this->isBW() && !doAA) { (void)fBW.setPath(path, clip); } else { // TODO: since we are going to over-write fAA completely (aren't we?) // we should just clear our BW data (if any) and set fIsAA=true if (this->isBW()) { this->convertToAA(); } (void)fAA.setPath(path, &clip, doAA); } return this->updateCacheAndReturnNonEmpty(); }
void updateMC(const SkMatrix& totalMatrix, const SkRegion& totalClip, const SkClipStack& clipStack, SkRegion* updateClip) { int x = fDevice->getOrigin().x(); int y = fDevice->getOrigin().y(); int width = fDevice->width(); int height = fDevice->height(); if ((x | y) == 0) { fMatrix = &totalMatrix; fClip = totalClip; } else { fMatrixStorage = totalMatrix; fMatrixStorage.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y)); fMatrix = &fMatrixStorage; totalClip.translate(-x, -y, &fClip); } fClip.op(0, 0, width, height, SkRegion::kIntersect_Op); // intersect clip, but don't translate it (yet) if (updateClip) { updateClip->op(x, y, x + width, y + height, SkRegion::kDifference_Op); } fDevice->setMatrixClip(*fMatrix, fClip, clipStack); #ifdef SK_DEBUG if (!fClip.isEmpty()) { SkIRect deviceR; deviceR.set(0, 0, width, height); SkASSERT(deviceR.contains(fClip.getBounds())); } #endif // default is to assume no external matrix fMVMatrix = NULL; fExtMatrix = NULL; }
static void Surface_setTransparentRegion( JNIEnv* env, jobject clazz, jobject argRegion) { const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); if (surface == 0) return; SkRegion* nativeRegion = (SkRegion*)env->GetIntField(argRegion, no.native_region); const SkIRect& b(nativeRegion->getBounds()); Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom)); if (nativeRegion->isComplex()) { SkRegion::Iterator it(*nativeRegion); while (!it.done()) { const SkIRect& r(it.rect()); reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom); it.next(); } } status_t err = surface->setTransparentRegionHint(reg); if (err<0 && err!=NO_INIT) { doThrowIAE(env); } }
static void nativeSetTransparentRegionHint(JNIEnv* env, jclass clazz, jlong nativeObject, jobject regionObj) { SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj); if (!region) { doThrowIAE(env); return; } const SkIRect& b(region->getBounds()); Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom)); if (region->isComplex()) { SkRegion::Iterator it(*region); while (!it.done()) { const SkIRect& r(it.rect()); reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom); it.next(); } } status_t err = ctrl->setTransparentRegionHint(reg); if (err < 0 && err != NO_INIT) { doThrowIAE(env); } }
static jboolean Region_getBounds(JNIEnv* env, jobject, jlong regionHandle, jobject rectBounds) { SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle); GraphicsJNI::irect_to_jrect(region->getBounds(), env, rectBounds); bool result = !region->isEmpty(); return boolTojboolean(result); }
void SkConservativeClip::opRegion(const SkRegion& rgn, SkRegion::Op op) { this->opIRect(rgn.getBounds(), op); }
static bool sectsrect_proc(SkRegion& a, SkRegion& b) { SkIRect r = a.getBounds(); r.inset(r.width()/4, r.height()/4); return a.intersects(r); }
static bool diffrectbig_proc(SkRegion& a, SkRegion& b) { SkRegion result; return result.op(a, a.getBounds(), SkRegion::kDifference_Op); }
void GLExtras::drawRegion(const SkRegion& region, bool fill, bool drawBorder, const TransformationMatrix* drawMat, Color color) { if (region.isEmpty()) return; if (fill) { SkRegion::Iterator rgnIter(region); while (!rgnIter.done()) { const SkIRect& ir = rgnIter.rect(); SkRect r; r.set(ir.fLeft, ir.fTop, ir.fRight, ir.fBottom); drawRing(r, color, drawMat); rgnIter.next(); } } if (fill && !drawBorder) return; SkPath path; if (!region.getBoundaryPath(&path)) return; SkPath::Iter iter(path, true); SkPath::Verb verb; SkPoint pts[4]; SkRegion clip; SkIRect startRect; while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { if (verb == SkPath::kLine_Verb) { SkRect r; r.set(pts, 2); SkIRect line; int borderWidth = RING_BORDER_WIDTH; if (!fill) borderWidth *= 2; line.fLeft = r.fLeft - borderWidth; line.fRight = r.fRight + borderWidth; line.fTop = r.fTop - borderWidth; line.fBottom = r.fBottom + borderWidth; if (clip.intersects(line)) { clip.op(line, SkRegion::kReverseDifference_Op); if (clip.isEmpty()) continue; // Nothing to draw, continue line = clip.getBounds(); if (SkIRect::Intersects(startRect, line)) { clip.op(startRect, SkRegion::kDifference_Op); if (clip.isEmpty()) continue; // Nothing to draw, continue line = clip.getBounds(); } } else { clip.setRect(line); } r.set(line.fLeft, line.fTop, line.fRight, line.fBottom); drawRing(r, color, drawMat); if (startRect.isEmpty()) { startRect.set(line.fLeft, line.fTop, line.fRight, line.fBottom); } } if (verb == SkPath::kMove_Verb) { startRect.setEmpty(); } } }