123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- /*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #include "include/effects/SkDropShadowImageFilter.h"
- #include "include/core/SkCanvas.h"
- #include "include/effects/SkBlurImageFilter.h"
- #include "src/core/SkImageFilterPriv.h"
- #include "src/core/SkReadBuffer.h"
- #include "src/core/SkSpecialImage.h"
- #include "src/core/SkSpecialSurface.h"
- #include "src/core/SkWriteBuffer.h"
- sk_sp<SkImageFilter> SkDropShadowImageFilter::Make(SkScalar dx, SkScalar dy,
- SkScalar sigmaX, SkScalar sigmaY,
- SkColor color, ShadowMode shadowMode,
- sk_sp<SkImageFilter> input,
- const CropRect* cropRect) {
- return sk_sp<SkImageFilter>(new SkDropShadowImageFilter(dx, dy, sigmaX, sigmaY,
- color, shadowMode,
- std::move(input),
- cropRect));
- }
- SkDropShadowImageFilter::SkDropShadowImageFilter(SkScalar dx, SkScalar dy,
- SkScalar sigmaX, SkScalar sigmaY, SkColor color,
- ShadowMode shadowMode, sk_sp<SkImageFilter> input,
- const CropRect* cropRect)
- : INHERITED(&input, 1, cropRect)
- , fDx(dx)
- , fDy(dy)
- , fSigmaX(sigmaX)
- , fSigmaY(sigmaY)
- , fColor(color)
- , fShadowMode(shadowMode) {
- }
- sk_sp<SkFlattenable> SkDropShadowImageFilter::CreateProc(SkReadBuffer& buffer) {
- SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
- SkScalar dx = buffer.readScalar();
- SkScalar dy = buffer.readScalar();
- SkScalar sigmaX = buffer.readScalar();
- SkScalar sigmaY = buffer.readScalar();
- SkColor color = buffer.readColor();
- ShadowMode shadowMode = buffer.read32LE(kLast_ShadowMode);
- return Make(dx, dy, sigmaX, sigmaY, color, shadowMode, common.getInput(0), &common.cropRect());
- }
- void SkDropShadowImageFilter::flatten(SkWriteBuffer& buffer) const {
- this->INHERITED::flatten(buffer);
- buffer.writeScalar(fDx);
- buffer.writeScalar(fDy);
- buffer.writeScalar(fSigmaX);
- buffer.writeScalar(fSigmaY);
- buffer.writeColor(fColor);
- buffer.writeInt(static_cast<int>(fShadowMode));
- }
- sk_sp<SkSpecialImage> SkDropShadowImageFilter::onFilterImage(SkSpecialImage* source,
- const Context& ctx,
- SkIPoint* offset) const {
- SkIPoint inputOffset = SkIPoint::Make(0, 0);
- sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset));
- if (!input) {
- return nullptr;
- }
- const SkIRect inputBounds = SkIRect::MakeXYWH(inputOffset.x(), inputOffset.y(),
- input->width(), input->height());
- SkIRect bounds;
- if (!this->applyCropRect(ctx, inputBounds, &bounds)) {
- return nullptr;
- }
- sk_sp<SkSpecialSurface> surf(source->makeSurface(ctx.outputProperties(), bounds.size()));
- if (!surf) {
- return nullptr;
- }
- SkCanvas* canvas = surf->getCanvas();
- SkASSERT(canvas);
- canvas->clear(0x0);
- SkVector sigma = SkVector::Make(fSigmaX, fSigmaY);
- ctx.ctm().mapVectors(&sigma, 1);
- sigma.fX = SkMaxScalar(0, sigma.fX);
- sigma.fY = SkMaxScalar(0, sigma.fY);
- SkPaint paint;
- paint.setAntiAlias(true);
- paint.setImageFilter(SkBlurImageFilter::Make(sigma.fX, sigma.fY, nullptr));
- paint.setColorFilter(SkColorFilters::Blend(fColor, SkBlendMode::kSrcIn));
- SkVector offsetVec = SkVector::Make(fDx, fDy);
- ctx.ctm().mapVectors(&offsetVec, 1);
- canvas->translate(SkIntToScalar(inputOffset.fX - bounds.fLeft),
- SkIntToScalar(inputOffset.fY - bounds.fTop));
- input->draw(canvas, offsetVec.fX, offsetVec.fY, &paint);
- if (fShadowMode == kDrawShadowAndForeground_ShadowMode) {
- input->draw(canvas, 0, 0, nullptr);
- }
- offset->fX = bounds.fLeft;
- offset->fY = bounds.fTop;
- return surf->makeImageSnapshot();
- }
- SkRect SkDropShadowImageFilter::computeFastBounds(const SkRect& src) const {
- SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src) : src;
- SkRect shadowBounds = bounds;
- shadowBounds.offset(fDx, fDy);
- shadowBounds.outset(fSigmaX * 3, fSigmaY * 3);
- if (fShadowMode == kDrawShadowAndForeground_ShadowMode) {
- bounds.join(shadowBounds);
- } else {
- bounds = shadowBounds;
- }
- return bounds;
- }
- SkIRect SkDropShadowImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
- MapDirection dir, const SkIRect* inputRect) const {
- SkVector offsetVec = SkVector::Make(fDx, fDy);
- if (kReverse_MapDirection == dir) {
- offsetVec.negate();
- }
- ctm.mapVectors(&offsetVec, 1);
- SkIRect dst = src.makeOffset(SkScalarCeilToInt(offsetVec.x()),
- SkScalarCeilToInt(offsetVec.y()));
- SkVector sigma = SkVector::Make(fSigmaX, fSigmaY);
- ctm.mapVectors(&sigma, 1);
- dst.outset(
- SkScalarCeilToInt(SkScalarAbs(sigma.x() * 3)),
- SkScalarCeilToInt(SkScalarAbs(sigma.y() * 3)));
- if (fShadowMode == kDrawShadowAndForeground_ShadowMode) {
- dst.join(src);
- }
- return dst;
- }
|