static void convolve_gaussian(GrDrawContext* drawContext, GrRenderTarget* rt, const GrClip& clip, const SkRect& srcRect, const SkRect& dstRect, GrTexture* texture, Gr1DKernelEffect::Direction direction, int radius, float sigma, bool cropToSrcRect) { float bounds[2] = { 0.0f, 1.0f }; if (!cropToSrcRect) { convolve_gaussian_1d(drawContext, rt, clip, srcRect, dstRect, texture, direction, radius, sigma, false, bounds); return; } SkRect lowerSrcRect = srcRect, lowerDstRect = dstRect; SkRect middleSrcRect = srcRect, middleDstRect = dstRect; SkRect upperSrcRect = srcRect, upperDstRect = dstRect; SkScalar size; SkScalar rad = SkIntToScalar(radius); if (direction == Gr1DKernelEffect::kX_Direction) { bounds[0] = SkScalarToFloat(srcRect.left()) / texture->width(); bounds[1] = SkScalarToFloat(srcRect.right()) / texture->width(); size = srcRect.width(); lowerSrcRect.fRight = srcRect.left() + rad; lowerDstRect.fRight = dstRect.left() + rad; upperSrcRect.fLeft = srcRect.right() - rad; upperDstRect.fLeft = dstRect.right() - rad; middleSrcRect.inset(rad, 0); middleDstRect.inset(rad, 0); } else { bounds[0] = SkScalarToFloat(srcRect.top()) / texture->height(); bounds[1] = SkScalarToFloat(srcRect.bottom()) / texture->height(); size = srcRect.height(); lowerSrcRect.fBottom = srcRect.top() + rad; lowerDstRect.fBottom = dstRect.top() + rad; upperSrcRect.fTop = srcRect.bottom() - rad; upperDstRect.fTop = dstRect.bottom() - rad; middleSrcRect.inset(0, rad); middleDstRect.inset(0, rad); } if (radius >= size * SK_ScalarHalf) { // Blur radius covers srcRect; use bounds over entire draw convolve_gaussian_1d(drawContext, rt, clip, srcRect, dstRect, texture, direction, radius, sigma, true, bounds); } else { // Draw upper and lower margins with bounds; middle without. convolve_gaussian_1d(drawContext, rt, clip, lowerSrcRect, lowerDstRect, texture, direction, radius, sigma, true, bounds); convolve_gaussian_1d(drawContext, rt, clip, upperSrcRect, upperDstRect, texture, direction, radius, sigma, true, bounds); convolve_gaussian_1d(drawContext, rt, clip, middleSrcRect, middleDstRect, texture, direction, radius, sigma, false, bounds); } }
static void convolve_gaussian(GrDrawContext* drawContext, const GrClip& clip, const SkIRect& srcRect, GrTexture* texture, Gr1DKernelEffect::Direction direction, int radius, float sigma, const SkIRect* srcBounds, const SkIPoint& srcOffset) { float bounds[2] = { 0.0f, 1.0f }; SkIRect dstRect = SkIRect::MakeWH(srcRect.width(), srcRect.height()); if (!srcBounds) { convolve_gaussian_1d(drawContext, clip, dstRect, srcOffset, texture, direction, radius, sigma, false, bounds); return; } SkIRect midRect = *srcBounds, leftRect, rightRect; midRect.offset(srcOffset); SkIRect topRect, bottomRect; if (direction == Gr1DKernelEffect::kX_Direction) { bounds[0] = SkIntToFloat(srcBounds->left()) / texture->width(); bounds[1] = SkIntToFloat(srcBounds->right()) / texture->width(); topRect = SkIRect::MakeLTRB(0, 0, dstRect.right(), midRect.top()); bottomRect = SkIRect::MakeLTRB(0, midRect.bottom(), dstRect.right(), dstRect.bottom()); midRect.inset(radius, 0); leftRect = SkIRect::MakeLTRB(0, midRect.top(), midRect.left(), midRect.bottom()); rightRect = SkIRect::MakeLTRB(midRect.right(), midRect.top(), dstRect.width(), midRect.bottom()); dstRect.fTop = midRect.top(); dstRect.fBottom = midRect.bottom(); } else { bounds[0] = SkIntToFloat(srcBounds->top()) / texture->height(); bounds[1] = SkIntToFloat(srcBounds->bottom()) / texture->height(); topRect = SkIRect::MakeLTRB(0, 0, midRect.left(), dstRect.bottom()); bottomRect = SkIRect::MakeLTRB(midRect.right(), 0, dstRect.right(), dstRect.bottom()); midRect.inset(0, radius); leftRect = SkIRect::MakeLTRB(midRect.left(), 0, midRect.right(), midRect.top()); rightRect = SkIRect::MakeLTRB(midRect.left(), midRect.bottom(), midRect.right(), dstRect.height()); dstRect.fLeft = midRect.left(); dstRect.fRight = midRect.right(); } if (!topRect.isEmpty()) { drawContext->clear(&topRect, 0, false); } if (!bottomRect.isEmpty()) { drawContext->clear(&bottomRect, 0, false); } if (midRect.isEmpty()) { // Blur radius covers srcBounds; use bounds over entire draw convolve_gaussian_1d(drawContext, clip, dstRect, srcOffset, texture, direction, radius, sigma, true, bounds); } else { // Draw right and left margins with bounds; middle without. convolve_gaussian_1d(drawContext, clip, leftRect, srcOffset, texture, direction, radius, sigma, true, bounds); convolve_gaussian_1d(drawContext, clip, rightRect, srcOffset, texture, direction, radius, sigma, true, bounds); convolve_gaussian_1d(drawContext, clip, midRect, srcOffset, texture, direction, radius, sigma, false, bounds); } }