1 // Copyright 2014 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.
5 #include "ui/base/cursor/cursor_util.h"
7 #include "base/logging.h"
8 #include "skia/ext/image_operations.h"
9 #include "ui/base/resource/resource_bundle.h"
10 #include "ui/gfx/geometry/point_conversions.h"
11 #include "ui/gfx/geometry/size_conversions.h"
12 #include "ui/gfx/image/image_skia.h"
13 #include "ui/gfx/skbitmap_operations.h"
14 #include "ui/gfx/skia_util.h"
18 void ScaleAndRotateCursorBitmapAndHotpoint(float scale
,
19 gfx::Display::Rotation rotation
,
21 gfx::Point
* hotpoint
) {
23 case gfx::Display::ROTATE_0
:
25 case gfx::Display::ROTATE_90
:
26 hotpoint
->SetPoint(bitmap
->height() - hotpoint
->y(), hotpoint
->x());
27 *bitmap
= SkBitmapOperations::Rotate(
28 *bitmap
, SkBitmapOperations::ROTATION_90_CW
);
30 case gfx::Display::ROTATE_180
:
32 bitmap
->width() - hotpoint
->x(), bitmap
->height() - hotpoint
->y());
33 *bitmap
= SkBitmapOperations::Rotate(
34 *bitmap
, SkBitmapOperations::ROTATION_180_CW
);
36 case gfx::Display::ROTATE_270
:
37 hotpoint
->SetPoint(hotpoint
->y(), bitmap
->width() - hotpoint
->x());
38 *bitmap
= SkBitmapOperations::Rotate(
39 *bitmap
, SkBitmapOperations::ROTATION_270_CW
);
43 if (scale
< FLT_EPSILON
) {
44 NOTREACHED() << "Scale must be larger than 0.";
51 gfx::Size scaled_size
= gfx::ToFlooredSize(
52 gfx::ScaleSize(gfx::Size(bitmap
->width(), bitmap
->height()), scale
));
54 *bitmap
= skia::ImageOperations::Resize(
56 skia::ImageOperations::RESIZE_BETTER
,
58 scaled_size
.height());
59 *hotpoint
= gfx::ToFlooredPoint(gfx::ScalePoint(*hotpoint
, scale
));
62 void GetImageCursorBitmap(int resource_id
,
64 gfx::Display::Rotation rotation
,
67 const gfx::ImageSkia
* image
=
68 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id
);
69 const gfx::ImageSkiaRep
& image_rep
= image
->GetRepresentation(scale
);
70 // TODO(oshima): The cursor should use resource scale factor when
71 // fractional scale factor is enabled. crbug.com/372212
72 (*bitmap
) = image_rep
.sk_bitmap();
73 ScaleAndRotateCursorBitmapAndHotpoint(
74 scale
/ image_rep
.scale(), rotation
, bitmap
, hotspot
);
75 // |image_rep| is owned by the resource bundle. So we do not need to free it.
78 void GetAnimatedCursorBitmaps(int resource_id
,
80 gfx::Display::Rotation rotation
,
82 std::vector
<SkBitmap
>* bitmaps
) {
83 // TODO(oshima|tdanderson): Support rotation and fractional scale factor.
84 const gfx::ImageSkia
* image
=
85 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id
);
86 const gfx::ImageSkiaRep
& image_rep
= image
->GetRepresentation(scale
);
87 SkBitmap bitmap
= image_rep
.sk_bitmap();
88 int frame_width
= bitmap
.height();
89 int frame_height
= frame_width
;
90 int total_width
= bitmap
.width();
91 DCHECK_EQ(total_width
% frame_width
, 0);
92 int frame_count
= total_width
/ frame_width
;
93 DCHECK_GT(frame_count
, 0);
95 bitmaps
->resize(frame_count
);
97 for (int frame
= 0; frame
< frame_count
; ++frame
) {
98 int x_offset
= frame_width
* frame
;
99 DCHECK_LE(x_offset
+ frame_width
, total_width
);
101 SkBitmap cropped
= SkBitmapOperations::CreateTiledBitmap(
102 bitmap
, x_offset
, 0, frame_width
, frame_height
);
103 DCHECK_EQ(frame_width
, cropped
.width());
104 DCHECK_EQ(frame_height
, cropped
.height());
106 (*bitmaps
)[frame
] = cropped
;