| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/native_theme_chromeos.h" | 5 #include "chrome/browser/chromeos/native_theme_chromeos.h" |
| 6 | 6 |
| 7 #include <limits> | |
| 8 | |
| 9 #include "app/resource_bundle.h" | 7 #include "app/resource_bundle.h" |
| 10 #include "base/logging.h" | 8 #include "base/logging.h" |
| 11 #include "gfx/insets.h" | 9 #include "gfx/insets.h" |
| 12 #include "gfx/rect.h" | 10 #include "gfx/rect.h" |
| 13 #include "gfx/size.h" | 11 #include "gfx/size.h" |
| 14 #include "gfx/skbitmap_operations.h" | 12 #include "gfx/skbitmap_operations.h" |
| 15 #include "grit/theme_resources.h" | 13 #include "grit/theme_resources.h" |
| 16 #include "third_party/skia/include/core/SkShader.h" | 14 #include "third_party/skia/include/core/SkShader.h" |
| 17 | 15 |
| 18 namespace { | |
| 19 | |
| 20 bool IntersectsClipRectInt( | |
| 21 skia::PlatformCanvas* canvas, int x, int y, int w, int h) { | |
| 22 SkRect clip; | |
| 23 return canvas->getClipBounds(&clip) && | |
| 24 clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w), | |
| 25 SkIntToScalar(y + h)); | |
| 26 } | |
| 27 | |
| 28 void DrawBitmapInt( | |
| 29 skia::PlatformCanvas* canvas, const SkBitmap& bitmap, | |
| 30 int src_x, int src_y, int src_w, int src_h, | |
| 31 int dest_x, int dest_y, int dest_w, int dest_h) { | |
| 32 DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() && | |
| 33 src_y + src_h < std::numeric_limits<int16_t>::max()); | |
| 34 if (src_w <= 0 || src_h <= 0 || dest_w <= 0 || dest_h <= 0) { | |
| 35 NOTREACHED() << "Attempting to draw bitmap to/from an empty rect!"; | |
| 36 return; | |
| 37 } | |
| 38 | |
| 39 if (!IntersectsClipRectInt(canvas, dest_x, dest_y, dest_w, dest_h)) | |
| 40 return; | |
| 41 | |
| 42 SkRect dest_rect = { SkIntToScalar(dest_x), | |
| 43 SkIntToScalar(dest_y), | |
| 44 SkIntToScalar(dest_x + dest_w), | |
| 45 SkIntToScalar(dest_y + dest_h) }; | |
| 46 | |
| 47 if (src_w == dest_w && src_h == dest_h) { | |
| 48 // Workaround for apparent bug in Skia that causes image to occasionally | |
| 49 // shift. | |
| 50 SkIRect src_rect = { src_x, src_y, src_x + src_w, src_y + src_h }; | |
| 51 canvas->drawBitmapRect(bitmap, &src_rect, dest_rect); | |
| 52 return; | |
| 53 } | |
| 54 | |
| 55 // Make a bitmap shader that contains the bitmap we want to draw. This is | |
| 56 // basically what SkCanvas.drawBitmap does internally, but it gives us | |
| 57 // more control over quality and will use the mipmap in the source image if | |
| 58 // it has one, whereas drawBitmap won't. | |
| 59 SkShader* shader = SkShader::CreateBitmapShader(bitmap, | |
| 60 SkShader::kRepeat_TileMode, | |
| 61 SkShader::kRepeat_TileMode); | |
| 62 SkMatrix shader_scale; | |
| 63 shader_scale.setScale(SkFloatToScalar(static_cast<float>(dest_w) / src_w), | |
| 64 SkFloatToScalar(static_cast<float>(dest_h) / src_h)); | |
| 65 shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y)); | |
| 66 shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y)); | |
| 67 shader->setLocalMatrix(shader_scale); | |
| 68 | |
| 69 // The rect will be filled by the bitmap. | |
| 70 SkPaint p; | |
| 71 p.setFilterBitmap(true); | |
| 72 p.setShader(shader); | |
| 73 shader->unref(); | |
| 74 canvas->drawRect(dest_rect, p); | |
| 75 } | |
| 76 | |
| 77 } | |
| 78 | |
| 79 /* static */ | 16 /* static */ |
| 80 gfx::NativeThemeLinux* gfx::NativeThemeLinux::instance() { | 17 gfx::NativeThemeLinux* gfx::NativeThemeLinux::instance() { |
| 81 // The global NativeThemeChromeos instance. | 18 // The global NativeThemeChromeos instance. |
| 82 static NativeThemeChromeos s_native_theme; | 19 static NativeThemeChromeos s_native_theme; |
| 83 return &s_native_theme; | 20 return &s_native_theme; |
| 84 } | 21 } |
| 85 | 22 |
| 86 NativeThemeChromeos::NativeThemeChromeos() { | 23 NativeThemeChromeos::NativeThemeChromeos() { |
| 87 } | 24 } |
| 88 | 25 |
| 89 NativeThemeChromeos::~NativeThemeChromeos() { | 26 NativeThemeChromeos::~NativeThemeChromeos() { |
| 90 } | 27 } |
| 91 | 28 |
| 92 gfx::Size NativeThemeChromeos::GetSize(Part part) const { | 29 gfx::Size NativeThemeChromeos::GetPartSize(Part part) const { |
| 93 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 30 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 94 int scrollbar_width = rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND)->width(); | 31 int scrollbar_width = rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND)->width(); |
| 95 int width = 0, height = 0; | 32 int width = 0, height = 0; |
| 96 switch (part) { | 33 switch (part) { |
| 97 case kScrollbarUpArrow: | 34 case kScrollbarUpArrow: |
| 98 width = scrollbar_width; | 35 width = scrollbar_width; |
| 99 height = rb.GetBitmapNamed(IDR_SCROLL_ARROW_UP)->height(); | 36 height = rb.GetBitmapNamed(IDR_SCROLL_ARROW_UP)->height(); |
| 100 break; | 37 break; |
| 101 case kScrollbarDownArrow: | 38 case kScrollbarDownArrow: |
| 102 width = scrollbar_width; | 39 width = scrollbar_width; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 117 case kScrollbarVerticalTrack: | 54 case kScrollbarVerticalTrack: |
| 118 width = scrollbar_width; | 55 width = scrollbar_width; |
| 119 height = 0; | 56 height = 0; |
| 120 break; | 57 break; |
| 121 case kScrollbarHorizontalThumb: | 58 case kScrollbarHorizontalThumb: |
| 122 case kScrollbarVerticalThumb: | 59 case kScrollbarVerticalThumb: |
| 123 // allow thumb to be square but no shorter. | 60 // allow thumb to be square but no shorter. |
| 124 width = scrollbar_width; | 61 width = scrollbar_width; |
| 125 height = scrollbar_width; | 62 height = scrollbar_width; |
| 126 break; | 63 break; |
| 64 default: |
| 65 return NativeThemeLinux::GetPartSize(part); |
| 127 } | 66 } |
| 128 return gfx::Size(width, height); | 67 return gfx::Size(width, height); |
| 129 } | 68 } |
| 130 | 69 |
| 131 void NativeThemeChromeos::PaintTrack(skia::PlatformCanvas* canvas, | 70 void NativeThemeChromeos::PaintScrollbarTrack(skia::PlatformCanvas* canvas, |
| 132 Part part, State state, | 71 Part part, State state, |
| 133 const ScrollbarTrackExtraParams& extra_params, const gfx::Rect& rect) { | 72 const ScrollbarTrackExtraParams& extra_params, const gfx::Rect& rect) { |
| 134 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 73 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 135 if (part == kScrollbarVerticalTrack) { | 74 if (part == kScrollbarVerticalTrack) { |
| 136 SkBitmap* background = | 75 SkBitmap* background = |
| 137 rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND); | 76 rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND); |
| 138 SkBitmap* border_up = | 77 SkBitmap* border_up = |
| 139 rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_UP); | 78 rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_UP); |
| 140 SkBitmap* border_down = | 79 SkBitmap* border_down = |
| 141 rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_DOWN); | 80 rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_DOWN); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 167 // Draw left button right border. | 106 // Draw left button right border. |
| 168 canvas->drawBitmap(*border_left,extra_params.track_x, extra_params.track_y); | 107 canvas->drawBitmap(*border_left,extra_params.track_x, extra_params.track_y); |
| 169 // Draw right button left border. | 108 // Draw right button left border. |
| 170 canvas->drawBitmap( | 109 canvas->drawBitmap( |
| 171 *border_right, | 110 *border_right, |
| 172 extra_params.track_x + extra_params.track_width - border_right->width(), | 111 extra_params.track_x + extra_params.track_width - border_right->width(), |
| 173 extra_params.track_y); | 112 extra_params.track_y); |
| 174 } | 113 } |
| 175 } | 114 } |
| 176 | 115 |
| 177 void NativeThemeChromeos::PaintThumb(skia::PlatformCanvas* canvas, | 116 void NativeThemeChromeos::PaintScrollbarThumb(skia::PlatformCanvas* canvas, |
| 178 Part part, State state, const gfx::Rect& rect) { | 117 Part part, State state, const gfx::Rect& rect) { |
| 179 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 118 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 180 int resource_id = IDR_SCROLL_THUMB; | 119 int resource_id = IDR_SCROLL_THUMB; |
| 181 if (state == kHover) | 120 if (state == kHovered) |
| 182 resource_id++; | 121 resource_id++; |
| 183 else if (state == kPressed) | 122 else if (state == kPressed) |
| 184 resource_id += 2; | 123 resource_id += 2; |
| 185 if (part == kScrollbarVerticalThumb) { | 124 if (part == kScrollbarVerticalThumb) { |
| 186 SkBitmap* bitmap = rb.GetBitmapNamed(resource_id); | 125 SkBitmap* bitmap = rb.GetBitmapNamed(resource_id); |
| 187 // Top | 126 // Top |
| 188 DrawBitmapInt( | 127 DrawBitmapInt( |
| 189 canvas, *bitmap, | 128 canvas, *bitmap, |
| 190 0, 1, bitmap->width(), 5, | 129 0, 1, bitmap->width(), 5, |
| 191 rect.x(), rect.y(), rect.width(), 5); | 130 rect.x(), rect.y(), rect.width(), 5); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 218 rect.x() + rect.width() - 5, rect.y(), 5, rect.height()); | 157 rect.x() + rect.width() - 5, rect.y(), 5, rect.height()); |
| 219 } | 158 } |
| 220 } | 159 } |
| 221 | 160 |
| 222 void NativeThemeChromeos::PaintArrowButton(skia::PlatformCanvas* canvas, | 161 void NativeThemeChromeos::PaintArrowButton(skia::PlatformCanvas* canvas, |
| 223 const gfx::Rect& rect, Part part, State state) { | 162 const gfx::Rect& rect, Part part, State state) { |
| 224 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 163 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 225 int resource_id = | 164 int resource_id = |
| 226 (part == kScrollbarUpArrow || part == kScrollbarLeftArrow) ? | 165 (part == kScrollbarUpArrow || part == kScrollbarLeftArrow) ? |
| 227 IDR_SCROLL_ARROW_UP : IDR_SCROLL_ARROW_DOWN; | 166 IDR_SCROLL_ARROW_UP : IDR_SCROLL_ARROW_DOWN; |
| 228 if (state == kHover) | 167 if (state == kHovered) |
| 229 resource_id++; | 168 resource_id++; |
| 230 else if (state == kPressed) | 169 else if (state == kPressed) |
| 231 resource_id += 2; | 170 resource_id += 2; |
| 232 SkBitmap* bitmap; | 171 SkBitmap* bitmap; |
| 233 if (part == kScrollbarUpArrow || part == kScrollbarDownArrow) | 172 if (part == kScrollbarUpArrow || part == kScrollbarDownArrow) |
| 234 bitmap = rb.GetBitmapNamed(resource_id); | 173 bitmap = rb.GetBitmapNamed(resource_id); |
| 235 else | 174 else |
| 236 bitmap = GetHorizontalBitmapNamed(resource_id); | 175 bitmap = GetHorizontalBitmapNamed(resource_id); |
| 237 canvas->drawBitmap(*bitmap, rect.x(), rect.y()); | 176 canvas->drawBitmap(*bitmap, rect.x(), rect.y()); |
| 238 } | 177 } |
| 239 | 178 |
| 240 SkBitmap* NativeThemeChromeos::GetHorizontalBitmapNamed(int resource_id) { | 179 SkBitmap* NativeThemeChromeos::GetHorizontalBitmapNamed(int resource_id) { |
| 241 SkImageMap::const_iterator found = horizontal_bitmaps_.find(resource_id); | 180 SkImageMap::const_iterator found = horizontal_bitmaps_.find(resource_id); |
| 242 if (found != horizontal_bitmaps_.end()) | 181 if (found != horizontal_bitmaps_.end()) |
| 243 return found->second; | 182 return found->second; |
| 244 | 183 |
| 245 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 184 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 246 SkBitmap* vertical_bitmap = rb.GetBitmapNamed(resource_id); | 185 SkBitmap* vertical_bitmap = rb.GetBitmapNamed(resource_id); |
| 247 | 186 |
| 248 if (vertical_bitmap) { | 187 if (vertical_bitmap) { |
| 249 SkBitmap transposed_bitmap = | 188 SkBitmap transposed_bitmap = |
| 250 SkBitmapOperations::CreateTransposedBtmap(*vertical_bitmap); | 189 SkBitmapOperations::CreateTransposedBtmap(*vertical_bitmap); |
| 251 SkBitmap* horizontal_bitmap = new SkBitmap(transposed_bitmap); | 190 SkBitmap* horizontal_bitmap = new SkBitmap(transposed_bitmap); |
| 252 | 191 |
| 253 horizontal_bitmaps_[resource_id] = horizontal_bitmap; | 192 horizontal_bitmaps_[resource_id] = horizontal_bitmap; |
| 254 return horizontal_bitmap; | 193 return horizontal_bitmap; |
| 255 } | 194 } |
| 256 return NULL; | 195 return NULL; |
| 257 } | 196 } |
| 258 | |
| OLD | NEW |