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 |