bool SkMaskFilterBase::filterPath(const SkPath& devPath, const SkMatrix& matrix, const SkRasterClip& clip, SkBlitter* blitter, SkStrokeRec::InitStyle style) const { SkRect rects[2]; int rectCount = 0; if (SkStrokeRec::kFill_InitStyle == style) { rectCount = countNestedRects(devPath, rects); } if (rectCount > 0) { NinePatch patch; switch (this->filterRectsToNine(rects, rectCount, matrix, clip.getBounds(), &patch)) { case kFalse_FilterReturn: SkASSERT(nullptr == patch.fMask.fImage); return false; case kTrue_FilterReturn: draw_nine(patch.fMask, patch.fOuterRect, patch.fCenter, 1 == rectCount, clip, blitter); return true; case kUnimplemented_FilterReturn: SkASSERT(nullptr == patch.fMask.fImage); // fall through break; } } SkMask srcM, dstM; if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), this, &matrix, &srcM, SkMask::kComputeBoundsAndRenderImage_CreateMode, style)) { return false; } SkAutoMaskFreeImage autoSrc(srcM.fImage); if (!this->filterMask(&dstM, srcM, matrix, nullptr)) { return false; } SkAutoMaskFreeImage autoDst(dstM.fImage); // if we get here, we need to (possibly) resolve the clip and blitter SkAAClipBlitterWrapper wrapper(clip, blitter); blitter = wrapper.getBlitter(); SkRegion::Cliperator clipper(wrapper.getRgn(), dstM.fBounds); if (!clipper.done()) { const SkIRect& cr = clipper.rect(); do { blitter->blitMask(dstM, cr); clipper.next(); } while (!clipper.done()); } return true; }
bool SkRasterClip::setPath(const SkPath& path, const SkRasterClip& clip, bool doAA) { if (clip.isBW()) { return this->setPath(path, clip.bwRgn(), doAA); } else { SkRegion tmp; tmp.setRect(clip.getBounds()); if (!this->setPath(path, clip, doAA)) { return false; } return this->op(clip, SkRegion::kIntersect_Op); } }
bool SkMaskFilterBase::filterRRect(const SkRRect& devRRect, const SkMatrix& matrix, const SkRasterClip& clip, SkBlitter* blitter) const { // Attempt to speed up drawing by creating a nine patch. If a nine patch // cannot be used, return false to allow our caller to recover and perform // the drawing another way. NinePatch patch; patch.fMask.fImage = nullptr; if (kTrue_FilterReturn != this->filterRRectToNine(devRRect, matrix, clip.getBounds(), &patch)) { SkASSERT(nullptr == patch.fMask.fImage); return false; } draw_nine(patch.fMask, patch.fOuterRect, patch.fCenter, true, clip, blitter); return true; }
void SkScan::FillTriangle(const SkPoint pts[], const SkRasterClip& clip, SkBlitter* blitter) { if (clip.isEmpty()) { return; } SkRect r; r.set(pts, 3); // If r is too large (larger than can easily fit in SkFixed) then we need perform geometric // clipping. This is a bit of work, so we just call the general FillPath() to handle it. // Use FixedMax/2 as the limit so we can subtract two edges and still store that in Fixed. const SkScalar limit = SK_MaxS16 >> 1; if (!SkRect::MakeLTRB(-limit, -limit, limit, limit).contains(r)) { SkPath path; path.addPoly(pts, 3, false); FillPath(path, clip, blitter); return; } SkIRect ir = conservative_round_to_int(r); if (ir.isEmpty() || !SkIRect::Intersects(ir, clip.getBounds())) { return; } SkAAClipBlitterWrapper wrap; const SkRegion* clipRgn; if (clip.isBW()) { clipRgn = &clip.bwRgn(); } else { wrap.init(clip, blitter); clipRgn = &wrap.getRgn(); blitter = wrap.getBlitter(); } SkScanClipper clipper(blitter, clipRgn, ir); blitter = clipper.getBlitter(); if (blitter) { sk_fill_triangle(pts, clipper.getClipRect(), blitter, ir); } }