Index: ui/gfx/image/image_skia.cc |
diff --git a/ui/gfx/image/image_skia.cc b/ui/gfx/image/image_skia.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3c2e94f867221b4240065aef0652376daca0b435 |
--- /dev/null |
+++ b/ui/gfx/image/image_skia.cc |
@@ -0,0 +1,146 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ui/gfx/image/image_skia.h" |
+ |
+#include <limits> |
+#include <cmath> |
+ |
+#include "base/logging.h" |
+#include "base/stl_util.h" |
+ |
+namespace gfx { |
+ |
+ImageSkia::ImageSkia(const SkBitmap* bitmap) |
+ : size_(bitmap->width(), bitmap->height()), |
+ mip_map_build_pending_(false) { |
+ CHECK(bitmap); |
+ // TODO(pkotwicz): Add a CHECK to ensure that !bitmap->isNull() |
+ bitmaps_.push_back(bitmap); |
+} |
+ |
+ImageSkia::ImageSkia(const std::vector<const SkBitmap*>& bitmaps) |
+ : bitmaps_(bitmaps), |
+ mip_map_build_pending_(false) { |
+ CHECK(!bitmaps_.empty()); |
+ // TODO(pkotwicz): Add a CHECK to ensure that !bitmap->isNull() for each |
+ // vector element. |
+ // Assume that the smallest bitmap represents 1x scale factor. |
+ for (size_t i = 0; i < bitmaps_.size(); ++i) { |
+ gfx::Size bitmap_size(bitmaps_[i]->width(), bitmaps_[i]->height()); |
+ if (size_.IsEmpty() || bitmap_size.GetArea() < size_.GetArea()) |
+ size_ = bitmap_size; |
+ } |
+} |
+ |
+ImageSkia::~ImageSkia() { |
+ STLDeleteElements(&bitmaps_); |
+} |
+ |
+void ImageSkia::BuildMipMap() { |
+ mip_map_build_pending_ = true; |
+} |
+ |
+void ImageSkia::DrawToCanvasInt(gfx::Canvas* canvas, int x, int y) { |
+ SkPaint p; |
+ DrawToCanvasInt(canvas, x, y, p); |
+} |
+ |
+void ImageSkia::DrawToCanvasInt(gfx::Canvas* canvas, |
+ int x, int y, |
+ const SkPaint& paint) { |
+ |
+ if (IsZeroSized()) |
+ return; |
+ |
+ SkMatrix m = canvas->sk_canvas()->getTotalMatrix(); |
+ float scale_x = std::abs(SkScalarToFloat(m.getScaleX())); |
+ float scale_y = std::abs(SkScalarToFloat(m.getScaleY())); |
+ |
+ const SkBitmap* bitmap = GetBitmapForScale(scale_x, scale_y); |
+ |
+ if (mip_map_build_pending_) { |
+ const_cast<SkBitmap*>(bitmap)->buildMipMap(); |
+ mip_map_build_pending_ = false; |
+ } |
+ |
+ float bitmap_scale_x = static_cast<float>(bitmap->width()) / width(); |
+ float bitmap_scale_y = static_cast<float>(bitmap->height()) / height(); |
+ |
+ canvas->Save(); |
+ canvas->sk_canvas()->scale(1.0f / bitmap_scale_x, |
+ 1.0f / bitmap_scale_y); |
+ canvas->sk_canvas()->drawBitmap(*bitmap, SkFloatToScalar(x * bitmap_scale_x), |
+ SkFloatToScalar(y * bitmap_scale_y)); |
+ canvas->Restore(); |
+} |
+ |
+void ImageSkia::DrawToCanvasInt(gfx::Canvas* canvas, |
+ int src_x, int src_y, int src_w, int src_h, |
+ int dest_x, int dest_y, int dest_w, int dest_h, |
+ bool filter) { |
+ SkPaint p; |
+ DrawToCanvasInt(canvas, src_x, src_y, src_w, src_h, dest_x, dest_y, |
+ dest_w, dest_h, filter, p); |
+} |
+ |
+void ImageSkia::DrawToCanvasInt(gfx::Canvas* canvas, |
+ int src_x, int src_y, int src_w, int src_h, |
+ int dest_x, int dest_y, int dest_w, int dest_h, |
+ bool filter, |
+ const SkPaint& paint) { |
+ if (IsZeroSized()) |
+ return; |
+ |
+ SkMatrix m = canvas->sk_canvas()->getTotalMatrix(); |
+ float scale_x = std::abs(SkScalarToFloat(m.getScaleX())); |
+ float scale_y = std::abs(SkScalarToFloat(m.getScaleY())); |
+ |
+ const SkBitmap* bitmap = GetBitmapForScale(scale_x, scale_y); |
+ |
+ if (mip_map_build_pending_) { |
+ const_cast<SkBitmap*>(bitmap)->buildMipMap(); |
+ mip_map_build_pending_ = false; |
+ } |
+ |
+ float bitmap_scale_x = static_cast<float>(bitmap->width()) / width(); |
+ float bitmap_scale_y = static_cast<float>(bitmap->height()) / height(); |
+ |
+ canvas->Save(); |
+ canvas->sk_canvas()->scale(1.0f / bitmap_scale_x, |
+ 1.0f / bitmap_scale_y); |
+ canvas->DrawBitmapFloat(*bitmap, |
+ src_x * bitmap_scale_x, src_y * bitmap_scale_x, |
+ src_w * bitmap_scale_x, src_h * bitmap_scale_y, |
+ dest_x * bitmap_scale_x, dest_y * bitmap_scale_y, |
+ dest_w * bitmap_scale_x, dest_h * bitmap_scale_y, |
+ filter, paint); |
+ |
+ canvas->Restore(); |
+} |
+ |
+const SkBitmap* ImageSkia::GetBitmapForScale(float x_scale_factor, |
+ float y_scale_factor) const { |
+ // Get the desired bitmap width and height given |x_scale_factor|, |
+ // |y_scale_factor| and |size_| at 1x density. |
+ float desired_width = size_.width() * x_scale_factor; |
+ float desired_height = size_.height() * y_scale_factor; |
+ |
+ size_t closest_index = 0; |
+ float smallest_diff = std::numeric_limits<float>::max(); |
+ for (size_t i = 0; i < bitmaps_.size(); ++i) { |
+ if (bitmaps_[i]->isNull()) |
+ continue; |
+ |
+ float diff = std::abs(bitmaps_[i]->width() - desired_width) + |
+ std::abs(bitmaps_[i]->height() - desired_height); |
+ if (diff < smallest_diff) { |
+ closest_index = i; |
+ smallest_diff = diff; |
+ } |
+ } |
+ return bitmaps_[closest_index]; |
+} |
+ |
+} // namespace gfx |