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.h" |
| 6 |
| 7 #include <limits> |
| 8 #include <cmath> |
| 9 |
| 10 #include "base/logging.h" |
| 11 #include "base/stl_util.h" |
| 12 |
| 13 namespace gfx { |
| 14 |
| 15 ImageSkia::ImageSkia(const SkBitmap* bitmap) |
| 16 : size_(bitmap->width(), bitmap->height()), |
| 17 mip_map_build_pending_(false) { |
| 18 CHECK(bitmap); |
| 19 // TODO(pkotwicz): Add a CHECK to ensure that !bitmap->isNull() |
| 20 bitmaps_.push_back(bitmap); |
| 21 } |
| 22 |
| 23 ImageSkia::ImageSkia(const std::vector<const SkBitmap*>& bitmaps) |
| 24 : bitmaps_(bitmaps), |
| 25 mip_map_build_pending_(false) { |
| 26 CHECK(!bitmaps_.empty()); |
| 27 // TODO(pkotwicz): Add a CHECK to ensure that !bitmap->isNull() for each |
| 28 // vector element. |
| 29 // Assume that the smallest bitmap represents 1x scale factor. |
| 30 for (size_t i = 0; i < bitmaps_.size(); ++i) { |
| 31 gfx::Size bitmap_size(bitmaps_[i]->width(), bitmaps_[i]->height()); |
| 32 if (size_.IsEmpty() || bitmap_size.GetArea() < size_.GetArea()) |
| 33 size_ = bitmap_size; |
| 34 } |
| 35 } |
| 36 |
| 37 ImageSkia::~ImageSkia() { |
| 38 STLDeleteElements(&bitmaps_); |
| 39 } |
| 40 |
| 41 void ImageSkia::BuildMipMap() { |
| 42 mip_map_build_pending_ = true; |
| 43 } |
| 44 |
| 45 void ImageSkia::DrawToCanvasInt(gfx::Canvas* canvas, int x, int y) { |
| 46 SkPaint p; |
| 47 DrawToCanvasInt(canvas, x, y, p); |
| 48 } |
| 49 |
| 50 void ImageSkia::DrawToCanvasInt(gfx::Canvas* canvas, |
| 51 int x, int y, |
| 52 const SkPaint& paint) { |
| 53 |
| 54 if (IsZeroSized()) |
| 55 return; |
| 56 |
| 57 SkMatrix m = canvas->sk_canvas()->getTotalMatrix(); |
| 58 float scale_x = std::abs(SkScalarToFloat(m.getScaleX())); |
| 59 float scale_y = std::abs(SkScalarToFloat(m.getScaleY())); |
| 60 |
| 61 const SkBitmap* bitmap = GetBitmapForScale(scale_x, scale_y); |
| 62 |
| 63 if (mip_map_build_pending_) { |
| 64 const_cast<SkBitmap*>(bitmap)->buildMipMap(); |
| 65 mip_map_build_pending_ = false; |
| 66 } |
| 67 |
| 68 float bitmap_scale_x = static_cast<float>(bitmap->width()) / width(); |
| 69 float bitmap_scale_y = static_cast<float>(bitmap->height()) / height(); |
| 70 |
| 71 canvas->Save(); |
| 72 canvas->sk_canvas()->scale(1.0f / bitmap_scale_x, |
| 73 1.0f / bitmap_scale_y); |
| 74 canvas->sk_canvas()->drawBitmap(*bitmap, SkFloatToScalar(x * bitmap_scale_x), |
| 75 SkFloatToScalar(y * bitmap_scale_y)); |
| 76 canvas->Restore(); |
| 77 } |
| 78 |
| 79 void ImageSkia::DrawToCanvasInt(gfx::Canvas* canvas, |
| 80 int src_x, int src_y, int src_w, int src_h, |
| 81 int dest_x, int dest_y, int dest_w, int dest_h, |
| 82 bool filter) { |
| 83 SkPaint p; |
| 84 DrawToCanvasInt(canvas, src_x, src_y, src_w, src_h, dest_x, dest_y, |
| 85 dest_w, dest_h, filter, p); |
| 86 } |
| 87 |
| 88 void ImageSkia::DrawToCanvasInt(gfx::Canvas* canvas, |
| 89 int src_x, int src_y, int src_w, int src_h, |
| 90 int dest_x, int dest_y, int dest_w, int dest_h, |
| 91 bool filter, |
| 92 const SkPaint& paint) { |
| 93 if (IsZeroSized()) |
| 94 return; |
| 95 |
| 96 SkMatrix m = canvas->sk_canvas()->getTotalMatrix(); |
| 97 float scale_x = std::abs(SkScalarToFloat(m.getScaleX())); |
| 98 float scale_y = std::abs(SkScalarToFloat(m.getScaleY())); |
| 99 |
| 100 const SkBitmap* bitmap = GetBitmapForScale(scale_x, scale_y); |
| 101 |
| 102 if (mip_map_build_pending_) { |
| 103 const_cast<SkBitmap*>(bitmap)->buildMipMap(); |
| 104 mip_map_build_pending_ = false; |
| 105 } |
| 106 |
| 107 float bitmap_scale_x = static_cast<float>(bitmap->width()) / width(); |
| 108 float bitmap_scale_y = static_cast<float>(bitmap->height()) / height(); |
| 109 |
| 110 canvas->Save(); |
| 111 canvas->sk_canvas()->scale(1.0f / bitmap_scale_x, |
| 112 1.0f / bitmap_scale_y); |
| 113 canvas->DrawBitmapFloat(*bitmap, |
| 114 src_x * bitmap_scale_x, src_y * bitmap_scale_x, |
| 115 src_w * bitmap_scale_x, src_h * bitmap_scale_y, |
| 116 dest_x * bitmap_scale_x, dest_y * bitmap_scale_y, |
| 117 dest_w * bitmap_scale_x, dest_h * bitmap_scale_y, |
| 118 filter, paint); |
| 119 |
| 120 canvas->Restore(); |
| 121 } |
| 122 |
| 123 const SkBitmap* ImageSkia::GetBitmapForScale(float x_scale_factor, |
| 124 float y_scale_factor) const { |
| 125 // Get the desired bitmap width and height given |x_scale_factor|, |
| 126 // |y_scale_factor| and |size_| at 1x density. |
| 127 float desired_width = size_.width() * x_scale_factor; |
| 128 float desired_height = size_.height() * y_scale_factor; |
| 129 |
| 130 size_t closest_index = 0; |
| 131 float smallest_diff = std::numeric_limits<float>::max(); |
| 132 for (size_t i = 0; i < bitmaps_.size(); ++i) { |
| 133 if (bitmaps_[i]->isNull()) |
| 134 continue; |
| 135 |
| 136 float diff = std::abs(bitmaps_[i]->width() - desired_width) + |
| 137 std::abs(bitmaps_[i]->height() - desired_height); |
| 138 if (diff < smallest_diff) { |
| 139 closest_index = i; |
| 140 smallest_diff = diff; |
| 141 } |
| 142 } |
| 143 return bitmaps_[closest_index]; |
| 144 } |
| 145 |
| 146 } // namespace gfx |
OLD | NEW |