OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ui/gfx/image/image_skia_operations.h" |
| 6 |
| 7 #include "base/command_line.h" |
| 8 #include "base/logging.h" |
| 9 #include "skia/ext/platform_canvas.h" |
| 10 #include "ui/base/layout.h" |
| 11 #include "ui/base/ui_base_switches.h" |
| 12 #include "ui/gfx/image/image_skia.h" |
| 13 #include "ui/gfx/image/image_skia_rep.h" |
| 14 #include "ui/gfx/image/image_skia_source.h" |
| 15 #include "ui/gfx/rect.h" |
| 16 #include "ui/gfx/size.h" |
| 17 #include "ui/gfx/skbitmap_operations.h" |
| 18 #include "ui/gfx/skia_util.h" |
| 19 |
| 20 namespace gfx { |
| 21 namespace { |
| 22 |
| 23 bool ScalingEnabled() { |
| 24 static bool scale_images = !CommandLine::ForCurrentProcess()->HasSwitch( |
| 25 switches::kDisableScalingInImageSkiaOperations); |
| 26 return scale_images; |
| 27 } |
| 28 |
| 29 // Creates 2x scaled image of the give |source|. |
| 30 ImageSkiaRep Create2XImageSkiaRep(const ImageSkiaRep& source) { |
| 31 gfx::Size size(source.GetWidth() * 2.0f, source.GetHeight() * 2.0f); |
| 32 skia::PlatformCanvas canvas(size.width(), size.height(), false); |
| 33 SkRect resized_bounds = RectToSkRect(gfx::Rect(size)); |
| 34 canvas.drawBitmapRect(source.sk_bitmap(), NULL, resized_bounds); |
| 35 SkBitmap resized_bitmap = canvas.getDevice()->accessBitmap(false); |
| 36 return ImageSkiaRep(resized_bitmap, ui::SCALE_FACTOR_200P); |
| 37 } |
| 38 |
| 39 // A utility function to synchronize the scale factor of the two images. |
| 40 // When the command line option "--disable-scaling-in-image-skia-operation" |
| 41 // is provided, this function will fail if the scale factors of the two images |
| 42 // are different. This assumes that the platform only supports |
| 43 // 1x and 2x scale factors. |
| 44 // TODO(oshima): Remove and replace this with plain CHECK once |
| 45 // 2x images for all resources are provided. |
| 46 void MatchScale(ImageSkiaRep* first, ImageSkiaRep* second) { |
| 47 if (first->scale_factor() != second->scale_factor()) { |
| 48 CHECK(ScalingEnabled()); |
| 49 ImageSkiaRep* target = NULL; |
| 50 if (first->scale_factor() == ui::SCALE_FACTOR_100P) { |
| 51 target = first; |
| 52 } else { |
| 53 target = second; |
| 54 } |
| 55 *target = Create2XImageSkiaRep(*target); |
| 56 } |
| 57 } |
| 58 |
| 59 class BlendingImageSource : public gfx::ImageSkiaSource { |
| 60 public: |
| 61 BlendingImageSource(const ImageSkia& first, |
| 62 const ImageSkia& second, |
| 63 double alpha) |
| 64 : first_(first), |
| 65 second_(second), |
| 66 alpha_(alpha) { |
| 67 } |
| 68 |
| 69 // gfx::ImageSkiaSource overrides: |
| 70 virtual ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) OVERRIDE { |
| 71 ImageSkiaRep first_rep = first_.GetRepresentation(scale_factor); |
| 72 ImageSkiaRep second_rep = second_.GetRepresentation(scale_factor); |
| 73 MatchScale(&first_rep, &second_rep); |
| 74 SkBitmap blended = SkBitmapOperations::CreateBlendedBitmap( |
| 75 first_rep.sk_bitmap(), second_rep.sk_bitmap(), alpha_); |
| 76 return ImageSkiaRep(blended, first_rep.scale_factor()); |
| 77 } |
| 78 |
| 79 private: |
| 80 const ImageSkia first_; |
| 81 const ImageSkia second_; |
| 82 double alpha_; |
| 83 |
| 84 DISALLOW_COPY_AND_ASSIGN(BlendingImageSource); |
| 85 }; |
| 86 |
| 87 class MaskedImageSource : public gfx::ImageSkiaSource { |
| 88 public: |
| 89 MaskedImageSource(const ImageSkia& rgb, const ImageSkia& alpha) |
| 90 : rgb_(rgb), |
| 91 alpha_(alpha) { |
| 92 } |
| 93 |
| 94 // gfx::ImageSkiaSource overrides: |
| 95 virtual ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) OVERRIDE { |
| 96 ImageSkiaRep rgb_rep = rgb_.GetRepresentation(scale_factor); |
| 97 ImageSkiaRep alpha_rep = alpha_.GetRepresentation(scale_factor); |
| 98 MatchScale(&rgb_rep, &alpha_rep); |
| 99 return ImageSkiaRep(SkBitmapOperations::CreateMaskedBitmap( |
| 100 rgb_rep.sk_bitmap(), alpha_rep.sk_bitmap()), |
| 101 rgb_rep.scale_factor()); |
| 102 } |
| 103 |
| 104 private: |
| 105 const ImageSkia rgb_; |
| 106 const ImageSkia alpha_; |
| 107 |
| 108 DISALLOW_COPY_AND_ASSIGN(MaskedImageSource); |
| 109 }; |
| 110 |
| 111 class TiledImageSource : public gfx::ImageSkiaSource { |
| 112 public: |
| 113 TiledImageSource(const ImageSkia& source, |
| 114 int src_x, int src_y, |
| 115 int dst_w, int dst_h) |
| 116 : source_(source), |
| 117 src_x_(src_x), |
| 118 src_y_(src_y), |
| 119 dst_w_(dst_w), |
| 120 dst_h_(dst_h) { |
| 121 } |
| 122 |
| 123 // gfx::ImageSkiaSource overrides: |
| 124 virtual ImageSkiaRep GetImageForScale(ui::ScaleFactor scale_factor) OVERRIDE { |
| 125 ImageSkiaRep source_rep = source_.GetRepresentation(scale_factor); |
| 126 float scale = ui::GetScaleFactorScale(source_rep.scale_factor()); |
| 127 return ImageSkiaRep( |
| 128 SkBitmapOperations::CreateTiledBitmap( |
| 129 source_rep.sk_bitmap(), |
| 130 src_x_ * scale, src_y_ * scale, dst_w_ * scale, dst_h_ * scale), |
| 131 source_rep.scale_factor()); |
| 132 } |
| 133 |
| 134 private: |
| 135 const ImageSkia& source_; |
| 136 const int src_x_; |
| 137 const int src_y_; |
| 138 const int dst_w_; |
| 139 const int dst_h_; |
| 140 |
| 141 DISALLOW_COPY_AND_ASSIGN(TiledImageSource); |
| 142 }; |
| 143 |
| 144 } // namespace; |
| 145 |
| 146 // static |
| 147 ImageSkia ImageSkiaOperations::CreateBlendedImage(const ImageSkia& first, |
| 148 const ImageSkia& second, |
| 149 double alpha) { |
| 150 return ImageSkia(new BlendingImageSource(first, second, alpha), first.size()); |
| 151 } |
| 152 |
| 153 // static |
| 154 ImageSkia ImageSkiaOperations::CreateMaskedImage(const ImageSkia& rgb, |
| 155 const ImageSkia& alpha) { |
| 156 return ImageSkia(new MaskedImageSource(rgb, alpha), rgb.size()); |
| 157 } |
| 158 |
| 159 // static |
| 160 ImageSkia ImageSkiaOperations::CreateTiledImage(const ImageSkia& source, |
| 161 int src_x, int src_y, |
| 162 int dst_w, int dst_h) { |
| 163 return ImageSkia(new TiledImageSource(source, src_x, src_y, dst_w, dst_h), |
| 164 gfx::Size(dst_w, dst_h)); |
| 165 } |
| 166 |
| 167 } // namespace gfx |
OLD | NEW |