OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "ui/base/cursor/cursor_loader_x11.h" | 5 #include "ui/base/cursor/cursor_loader_x11.h" |
6 | 6 |
7 #include <float.h> | 7 #include <float.h> |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 #include <X11/cursorfont.h> | 9 #include <X11/cursorfont.h> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "skia/ext/image_operations.h" | 12 #include "skia/ext/image_operations.h" |
13 #include "ui/base/cursor/cursor.h" | 13 #include "ui/base/cursor/cursor.h" |
14 #include "ui/base/cursor/cursor_util.h" | 14 #include "ui/base/cursor/cursor_util.h" |
15 #include "ui/base/resource/resource_bundle.h" | |
16 #include "ui/base/x/x11_util.h" | 15 #include "ui/base/x/x11_util.h" |
17 #include "ui/gfx/image/image.h" | 16 #include "ui/gfx/image/image.h" |
18 #include "ui/gfx/image/image_skia.h" | |
19 #include "ui/gfx/point_conversions.h" | 17 #include "ui/gfx/point_conversions.h" |
20 #include "ui/gfx/size_conversions.h" | 18 #include "ui/gfx/size_conversions.h" |
21 #include "ui/gfx/skbitmap_operations.h" | 19 #include "ui/gfx/skbitmap_operations.h" |
22 #include "ui/gfx/skia_util.h" | 20 #include "ui/gfx/skia_util.h" |
23 | 21 |
24 namespace { | 22 namespace { |
25 | 23 |
26 // Returns X font cursor shape from an Aura cursor. | 24 // Returns X font cursor shape from an Aura cursor. |
27 int CursorShapeFromNative(const gfx::NativeCursor& native_cursor) { | 25 int CursorShapeFromNative(const gfx::NativeCursor& native_cursor) { |
28 switch (native_cursor.native_type()) { | 26 switch (native_cursor.native_type()) { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 : invisible_cursor_(CreateInvisibleCursor(), gfx::GetXDisplay()) { | 147 : invisible_cursor_(CreateInvisibleCursor(), gfx::GetXDisplay()) { |
150 } | 148 } |
151 | 149 |
152 CursorLoaderX11::~CursorLoaderX11() { | 150 CursorLoaderX11::~CursorLoaderX11() { |
153 UnloadAll(); | 151 UnloadAll(); |
154 } | 152 } |
155 | 153 |
156 void CursorLoaderX11::LoadImageCursor(int id, | 154 void CursorLoaderX11::LoadImageCursor(int id, |
157 int resource_id, | 155 int resource_id, |
158 const gfx::Point& hot) { | 156 const gfx::Point& hot) { |
159 const gfx::ImageSkia* image = | 157 SkBitmap bitmap; |
160 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id); | 158 gfx::Point hotspot = hot; |
161 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(scale()); | |
162 SkBitmap bitmap = image_rep.sk_bitmap(); | |
163 gfx::Point hotpoint = hot; | |
164 // TODO(oshima): The cursor should use resource scale factor when | |
165 // fractional scale factor is enabled. crbug.com/372212 | |
166 ScaleAndRotateCursorBitmapAndHotpoint( | |
167 scale() / image_rep.scale(), rotation(), &bitmap, &hotpoint); | |
168 | 159 |
169 XcursorImage* x_image = SkBitmapToXcursorImage(&bitmap, hotpoint); | 160 GetImageCursorBitmap(resource_id, scale(), rotation(), &hotspot, &bitmap); |
| 161 XcursorImage* x_image = SkBitmapToXcursorImage(&bitmap, hotspot); |
170 cursors_[id] = CreateReffedCustomXCursor(x_image); | 162 cursors_[id] = CreateReffedCustomXCursor(x_image); |
171 // |image_rep| is owned by the resource bundle. So we do not need to free it. | |
172 } | 163 } |
173 | 164 |
174 void CursorLoaderX11::LoadAnimatedCursor(int id, | 165 void CursorLoaderX11::LoadAnimatedCursor(int id, |
175 int resource_id, | 166 int resource_id, |
176 const gfx::Point& hot, | 167 const gfx::Point& hot, |
177 int frame_delay_ms) { | 168 int frame_delay_ms) { |
178 // TODO(oshima|tdanderson): Support rotation and fractional scale factor. | 169 std::vector<SkBitmap> bitmaps; |
179 const gfx::ImageSkia* image = | 170 gfx::Point hotspot = hot; |
180 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id); | |
181 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(scale()); | |
182 SkBitmap bitmap = image_rep.sk_bitmap(); | |
183 int frame_width = bitmap.height(); | |
184 int frame_height = frame_width; | |
185 int total_width = bitmap.width(); | |
186 DCHECK_EQ(total_width % frame_width, 0); | |
187 int frame_count = total_width / frame_width; | |
188 DCHECK_GT(frame_count, 0); | |
189 XcursorImages* x_images = XcursorImagesCreate(frame_count); | |
190 x_images->nimage = frame_count; | |
191 | 171 |
192 for (int frame = 0; frame < frame_count; ++frame) { | 172 GetAnimatedCursorBitmaps( |
193 gfx::Point hotpoint = hot; | 173 resource_id, scale(), rotation(), &hotspot, &bitmaps); |
194 int x_offset = frame_width * frame; | |
195 DCHECK_LE(x_offset + frame_width, total_width); | |
196 | 174 |
197 SkBitmap cropped = SkBitmapOperations::CreateTiledBitmap( | 175 XcursorImages* x_images = XcursorImagesCreate(bitmaps.size()); |
198 bitmap, x_offset, 0, frame_width, frame_height); | 176 x_images->nimage = bitmaps.size(); |
199 DCHECK_EQ(frame_width, cropped.width()); | |
200 DCHECK_EQ(frame_height, cropped.height()); | |
201 | 177 |
202 XcursorImage* x_image = SkBitmapToXcursorImage(&cropped, hotpoint); | 178 for (unsigned int frame = 0; frame < bitmaps.size(); ++frame) { |
203 | 179 XcursorImage* x_image = SkBitmapToXcursorImage(&bitmaps[frame], hotspot); |
204 x_image->delay = frame_delay_ms; | 180 x_image->delay = frame_delay_ms; |
205 x_images->images[frame] = x_image; | 181 x_images->images[frame] = x_image; |
206 } | 182 } |
207 | 183 |
208 animated_cursors_[id] = std::make_pair( | 184 animated_cursors_[id] = std::make_pair( |
209 XcursorImagesLoadCursor(gfx::GetXDisplay(), x_images), x_images); | 185 XcursorImagesLoadCursor(gfx::GetXDisplay(), x_images), x_images); |
210 // |bitmap| is owned by the resource bundle. So we do not need to free it. | |
211 } | 186 } |
212 | 187 |
213 void CursorLoaderX11::UnloadAll() { | 188 void CursorLoaderX11::UnloadAll() { |
214 for (ImageCursorMap::const_iterator it = cursors_.begin(); | 189 for (ImageCursorMap::const_iterator it = cursors_.begin(); |
215 it != cursors_.end(); ++it) | 190 it != cursors_.end(); ++it) |
216 UnrefCustomXCursor(it->second); | 191 UnrefCustomXCursor(it->second); |
217 | 192 |
218 // Free animated cursors and images. | 193 // Free animated cursors and images. |
219 for (AnimatedCursorMap::iterator it = animated_cursors_.begin(); | 194 for (AnimatedCursorMap::iterator it = animated_cursors_.begin(); |
220 it != animated_cursors_.end(); ++it) { | 195 it != animated_cursors_.end(); ++it) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 if (animated_cursors_.count(type)) | 232 if (animated_cursors_.count(type)) |
258 return animated_cursors_[type].first; | 233 return animated_cursors_[type].first; |
259 | 234 |
260 ImageCursorMap::iterator find = cursors_.find(type); | 235 ImageCursorMap::iterator find = cursors_.find(type); |
261 if (find != cursors_.end()) | 236 if (find != cursors_.end()) |
262 return cursors_[type]; | 237 return cursors_[type]; |
263 return GetXCursor(CursorShapeFromNative(native_cursor)); | 238 return GetXCursor(CursorShapeFromNative(native_cursor)); |
264 } | 239 } |
265 | 240 |
266 } // namespace ui | 241 } // namespace ui |
OLD | NEW |