| Index: ui/gfx/image/image_skia_operations.cc
|
| diff --git a/ui/gfx/image/image_skia_operations.cc b/ui/gfx/image/image_skia_operations.cc
|
| index 383623515779eeec0d85494df9ad7216c27f2f4c..e2b67d31864ee58223d2b4c86696286afaacf02a 100644
|
| --- a/ui/gfx/image/image_skia_operations.cc
|
| +++ b/ui/gfx/image/image_skia_operations.cc
|
| @@ -10,6 +10,7 @@
|
| #include "base/logging.h"
|
| #include "base/macros.h"
|
| #include "skia/ext/image_operations.h"
|
| +#include "third_party/skia/include/core/SkClipOp.h"
|
| #include "third_party/skia/include/core/SkDrawLooper.h"
|
| #include "ui/gfx/canvas.h"
|
| #include "ui/gfx/geometry/insets.h"
|
| @@ -370,11 +371,8 @@ class ResizeSource : public ImageSkiaSource {
|
| // |source| that represent requested scale factors.
|
| class DropShadowSource : public ImageSkiaSource {
|
| public:
|
| - DropShadowSource(const ImageSkia& source,
|
| - const ShadowValues& shadows_in_dip)
|
| - : source_(source),
|
| - shaodws_in_dip_(shadows_in_dip) {
|
| - }
|
| + DropShadowSource(const ImageSkia& source, const ShadowValues& shadows_in_dip)
|
| + : source_(source), shadows_in_dip_(shadows_in_dip) {}
|
| ~DropShadowSource() override {}
|
|
|
| // gfx::ImageSkiaSource overrides:
|
| @@ -382,8 +380,8 @@ class DropShadowSource : public ImageSkiaSource {
|
| const ImageSkiaRep& image_rep = source_.GetRepresentation(scale);
|
|
|
| ShadowValues shadows_in_pixel;
|
| - for (size_t i = 0; i < shaodws_in_dip_.size(); ++i)
|
| - shadows_in_pixel.push_back(shaodws_in_dip_[i].Scale(scale));
|
| + for (size_t i = 0; i < shadows_in_dip_.size(); ++i)
|
| + shadows_in_pixel.push_back(shadows_in_dip_[i].Scale(scale));
|
|
|
| const SkBitmap shadow_bitmap = SkBitmapOperations::CreateDropShadow(
|
| image_rep.sk_bitmap(),
|
| @@ -393,12 +391,61 @@ class DropShadowSource : public ImageSkiaSource {
|
|
|
| private:
|
| const ImageSkia source_;
|
| - const ShadowValues shaodws_in_dip_;
|
| + const ShadowValues shadows_in_dip_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(DropShadowSource);
|
| };
|
|
|
| -// An image source that is 1dp wide, suitable for tiling horizontally.
|
| +class ShadowNineboxSource : public CanvasImageSource {
|
| + public:
|
| + ShadowNineboxSource(const std::vector<ShadowValue>& shadows,
|
| + float corner_radius)
|
| + : CanvasImageSource(CalculateSize(shadows, corner_radius), false),
|
| + shadows_(shadows),
|
| + corner_radius_(corner_radius) {
|
| + DCHECK(!shadows.empty());
|
| + }
|
| + ~ShadowNineboxSource() override {}
|
| +
|
| + // CanvasImageSource overrides:
|
| + void Draw(Canvas* canvas) override {
|
| + SkPaint paint;
|
| + paint.setLooper(CreateShadowDrawLooperCorrectBlur(shadows_));
|
| + Insets insets = -ShadowValue::GetMargin(shadows_);
|
| + gfx::Rect bounds(size());
|
| + bounds.Inset(insets);
|
| + SkRRect r_rect = SkRRect::MakeRectXY(gfx::RectToSkRect(bounds),
|
| + corner_radius_, corner_radius_);
|
| +
|
| + // Clip out the center so it's not painted with the shadow.
|
| + canvas->sk_canvas()->clipRRect(r_rect, kDifference_SkClipOp, true);
|
| + // Clipping alone is not enough --- due to anti aliasing there will still be
|
| + // some of the fill color in the rounded corners. We must make the fill
|
| + // color transparent.
|
| + paint.setColor(SK_ColorTRANSPARENT);
|
| + canvas->sk_canvas()->drawRRect(r_rect, paint);
|
| + }
|
| +
|
| + private:
|
| + static Size CalculateSize(const std::vector<ShadowValue>& shadows,
|
| + float corner_radius) {
|
| + // The "content" area (the middle tile in the 3x3 grid) is a single pixel.
|
| + gfx::Rect bounds(0, 0, 1, 1);
|
| + // We need enough space to render the full range of blur.
|
| + bounds.Inset(-ShadowValue::GetBlurRegion(shadows));
|
| + // We also need space for the full roundrect corner rounding.
|
| + bounds.Inset(-gfx::Insets(corner_radius));
|
| + return bounds.size();
|
| + }
|
| +
|
| + const std::vector<ShadowValue> shadows_;
|
| +
|
| + const float corner_radius_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ShadowNineboxSource);
|
| +};
|
| +
|
| +// An image source that is 1px wide, suitable for tiling horizontally.
|
| class HorizontalShadowSource : public CanvasImageSource {
|
| public:
|
| HorizontalShadowSource(const std::vector<ShadowValue>& shadows,
|
| @@ -592,11 +639,17 @@ ImageSkia ImageSkiaOperations::CreateImageWithDropShadow(
|
| }
|
|
|
| // static
|
| +ImageSkia ImageSkiaOperations::CreateShadowNinebox(const ShadowValues& shadows,
|
| + float corner_radius) {
|
| + auto source = new ShadowNineboxSource(shadows, corner_radius);
|
| + return ImageSkia(source, source->size());
|
| +}
|
| +
|
| +// static
|
| ImageSkia ImageSkiaOperations::CreateHorizontalShadow(
|
| const std::vector<ShadowValue>& shadows,
|
| bool fades_down) {
|
| - HorizontalShadowSource* source =
|
| - new HorizontalShadowSource(shadows, fades_down);
|
| + auto source = new HorizontalShadowSource(shadows, fades_down);
|
| return ImageSkia(source, source->size());
|
| }
|
|
|
|
|