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.
5 #include "base/pickle.h"
6 #include "content/common/cursors/webcursor.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "third_party/WebKit/public/platform/WebCursorInfo.h"
10 using blink::WebCursorInfo
;
14 TEST(WebCursorTest
, OKCursorSerialization
) {
15 WebCursor custom_cursor
;
16 // This is a valid custom cursor.
17 base::Pickle ok_custom_pickle
;
19 ok_custom_pickle
.WriteInt(WebCursorInfo::TypeCustom
);
20 ok_custom_pickle
.WriteInt(0);
21 ok_custom_pickle
.WriteInt(0);
23 ok_custom_pickle
.WriteInt(1);
24 ok_custom_pickle
.WriteInt(1);
26 ok_custom_pickle
.WriteFloat(1.0);
27 // Data len including enough data for a 1x1 image.
28 ok_custom_pickle
.WriteInt(4);
29 ok_custom_pickle
.WriteUInt32(0);
30 // Custom Windows message.
31 ok_custom_pickle
.WriteUInt32(0);
32 base::PickleIterator
iter(ok_custom_pickle
);
33 EXPECT_TRUE(custom_cursor
.Deserialize(&iter
));
36 TEST(WebCursorTest
, BrokenCursorSerialization
) {
37 WebCursor custom_cursor
;
38 // This custom cursor has not been send with enough data.
39 base::Pickle short_custom_pickle
;
41 short_custom_pickle
.WriteInt(WebCursorInfo::TypeCustom
);
42 short_custom_pickle
.WriteInt(0);
43 short_custom_pickle
.WriteInt(0);
45 short_custom_pickle
.WriteInt(1);
46 short_custom_pickle
.WriteInt(1);
48 short_custom_pickle
.WriteFloat(1.0);
49 // Data len not including enough data for a 1x1 image.
50 short_custom_pickle
.WriteInt(3);
51 short_custom_pickle
.WriteUInt32(0);
52 base::PickleIterator
iter(short_custom_pickle
);
53 EXPECT_FALSE(custom_cursor
.Deserialize(&iter
));
55 // This custom cursor has enough data but is too big.
56 base::Pickle large_custom_pickle
;
58 large_custom_pickle
.WriteInt(WebCursorInfo::TypeCustom
);
59 large_custom_pickle
.WriteInt(0);
60 large_custom_pickle
.WriteInt(0);
62 static const int kTooBigSize
= 4096 + 1;
63 large_custom_pickle
.WriteInt(kTooBigSize
);
64 large_custom_pickle
.WriteInt(1);
66 large_custom_pickle
.WriteFloat(1.0);
67 // Data len including enough data for a 4097x1 image.
68 large_custom_pickle
.WriteInt(kTooBigSize
* 4);
69 for (int i
= 0; i
< kTooBigSize
; ++i
)
70 large_custom_pickle
.WriteUInt32(0);
71 iter
= base::PickleIterator(large_custom_pickle
);
72 EXPECT_FALSE(custom_cursor
.Deserialize(&iter
));
74 // This custom cursor uses negative lengths.
75 base::Pickle neg_custom_pickle
;
77 neg_custom_pickle
.WriteInt(WebCursorInfo::TypeCustom
);
78 neg_custom_pickle
.WriteInt(0);
79 neg_custom_pickle
.WriteInt(0);
81 neg_custom_pickle
.WriteInt(-1);
82 neg_custom_pickle
.WriteInt(-1);
84 neg_custom_pickle
.WriteFloat(1.0);
85 // Data len including enough data for a 1x1 image.
86 neg_custom_pickle
.WriteInt(4);
87 neg_custom_pickle
.WriteUInt32(0);
88 // Custom Windows message.
89 neg_custom_pickle
.WriteUInt32(0);
90 iter
= base::PickleIterator(neg_custom_pickle
);
91 EXPECT_FALSE(custom_cursor
.Deserialize(&iter
));
93 // This custom cursor uses zero scale.
94 base::Pickle scale_zero_custom_pickle
;
96 scale_zero_custom_pickle
.WriteInt(WebCursorInfo::TypeCustom
);
97 scale_zero_custom_pickle
.WriteInt(0);
98 scale_zero_custom_pickle
.WriteInt(0);
100 scale_zero_custom_pickle
.WriteInt(1);
101 scale_zero_custom_pickle
.WriteInt(1);
103 scale_zero_custom_pickle
.WriteFloat(0);
104 // Data len including enough data for a 1x1 image.
105 scale_zero_custom_pickle
.WriteInt(4);
106 scale_zero_custom_pickle
.WriteUInt32(0);
107 // Custom Windows message.
108 scale_zero_custom_pickle
.WriteUInt32(0);
109 iter
= base::PickleIterator(scale_zero_custom_pickle
);
110 EXPECT_FALSE(custom_cursor
.Deserialize(&iter
));
112 // This custom cursor uses tiny scale.
113 base::Pickle scale_tiny_custom_pickle
;
114 // Type and hotspots.
115 scale_tiny_custom_pickle
.WriteInt(WebCursorInfo::TypeCustom
);
116 scale_tiny_custom_pickle
.WriteInt(0);
117 scale_tiny_custom_pickle
.WriteInt(0);
119 scale_tiny_custom_pickle
.WriteInt(1);
120 scale_tiny_custom_pickle
.WriteInt(1);
122 scale_tiny_custom_pickle
.WriteFloat(0.001f
);
123 // Data len including enough data for a 1x1 image.
124 scale_tiny_custom_pickle
.WriteInt(4);
125 scale_tiny_custom_pickle
.WriteUInt32(0);
126 // Custom Windows message.
127 scale_tiny_custom_pickle
.WriteUInt32(0);
128 iter
= base::PickleIterator(scale_tiny_custom_pickle
);
129 EXPECT_FALSE(custom_cursor
.Deserialize(&iter
));
132 TEST(WebCursorTest
, ClampHotspot
) {
133 WebCursor custom_cursor
;
134 // This is a valid custom cursor.
135 base::Pickle ok_custom_pickle
;
136 // Type and hotspots.
137 ok_custom_pickle
.WriteInt(WebCursorInfo::TypeCustom
);
138 // Hotspot is invalid --- outside the bounds of the image.
139 ok_custom_pickle
.WriteInt(5);
140 ok_custom_pickle
.WriteInt(5);
142 ok_custom_pickle
.WriteInt(2);
143 ok_custom_pickle
.WriteInt(2);
145 ok_custom_pickle
.WriteFloat(1.0);
146 // Data len including enough data for a 2x2 image.
147 ok_custom_pickle
.WriteInt(4 * 4);
148 for (size_t i
= 0; i
< 4; i
++)
149 ok_custom_pickle
.WriteUInt32(0);
150 // Custom Windows message.
151 ok_custom_pickle
.WriteUInt32(0);
152 base::PickleIterator
iter(ok_custom_pickle
);
153 EXPECT_TRUE(custom_cursor
.Deserialize(&iter
));
155 // Convert to WebCursorInfo, make sure the hotspot got clamped.
156 WebCursor::CursorInfo info
;
157 custom_cursor
.GetCursorInfo(&info
);
158 EXPECT_EQ(gfx::Point(1, 1), info
.hotspot
);
160 // Set hotspot to an invalid point again, pipe back through WebCursor,
161 // and make sure the hotspot got clamped again.
162 info
.hotspot
= gfx::Point(-1, -1);
163 custom_cursor
.InitFromCursorInfo(info
);
164 custom_cursor
.GetCursorInfo(&info
);
165 EXPECT_EQ(gfx::Point(0, 0), info
.hotspot
);
168 TEST(WebCursorTest
, EmptyImage
) {
169 WebCursor custom_cursor
;
170 base::Pickle broken_cursor_pickle
;
171 broken_cursor_pickle
.WriteInt(WebCursorInfo::TypeCustom
);
172 // Hotspot is at origin
173 broken_cursor_pickle
.WriteInt(0);
174 broken_cursor_pickle
.WriteInt(0);
176 broken_cursor_pickle
.WriteInt(0);
177 broken_cursor_pickle
.WriteInt(0);
179 broken_cursor_pickle
.WriteFloat(1.0);
180 // No data for the image since the size is 0.
181 broken_cursor_pickle
.WriteInt(0);
182 // Custom Windows message.
183 broken_cursor_pickle
.WriteInt(0);
185 // Make sure we can read this on all platforms; it is technicaally a valid
187 base::PickleIterator
iter(broken_cursor_pickle
);
188 EXPECT_TRUE(custom_cursor
.Deserialize(&iter
));
191 TEST(WebCursorTest
, Scale2
) {
192 WebCursor custom_cursor
;
193 // This is a valid custom cursor.
194 base::Pickle ok_custom_pickle
;
195 // Type and hotspots.
196 ok_custom_pickle
.WriteInt(WebCursorInfo::TypeCustom
);
197 ok_custom_pickle
.WriteInt(0);
198 ok_custom_pickle
.WriteInt(0);
200 ok_custom_pickle
.WriteInt(1);
201 ok_custom_pickle
.WriteInt(1);
202 // Scale - 2 image pixels per UI pixel.
203 ok_custom_pickle
.WriteFloat(2.0);
204 // Data len including enough data for a 1x1 image.
205 ok_custom_pickle
.WriteInt(4);
206 ok_custom_pickle
.WriteUInt32(0);
207 // Custom Windows message.
208 ok_custom_pickle
.WriteUInt32(0);
209 base::PickleIterator
iter(ok_custom_pickle
);
210 EXPECT_TRUE(custom_cursor
.Deserialize(&iter
));
213 TEST(WebCursorTest
, AlphaConversion
) {
215 SkPMColor testColor
= SkPreMultiplyARGB(10, 255, 255, 255);
216 bitmap
.allocN32Pixels(1,1);
217 SkAutoLockPixels
bitmap_lock(bitmap
);
218 *bitmap
.getAddr32(0, 0) = testColor
;
219 WebCursor::CursorInfo cursor_info
;
220 cursor_info
.type
= WebCursorInfo::TypeCustom
;
221 cursor_info
.custom_image
= bitmap
;
222 cursor_info
.image_scale_factor
= 1;
223 WebCursor custom_cursor
;
225 // This round trip will convert the cursor to unpremultiplied form
226 custom_cursor
.InitFromCursorInfo(cursor_info
);
227 custom_cursor
.GetCursorInfo(&cursor_info
);
229 SkAutoLockPixels
lock(cursor_info
.custom_image
);
230 EXPECT_EQ(kUnpremul_SkAlphaType
, cursor_info
.custom_image
.alphaType());
232 SkPreMultiplyColor(*cursor_info
.custom_image
.getAddr32(0,0)));
235 // Second round trip should not do any conversion because data is alread
237 custom_cursor
.InitFromCursorInfo(cursor_info
);
238 custom_cursor
.GetCursorInfo(&cursor_info
);
240 SkAutoLockPixels
lock(cursor_info
.custom_image
);
241 EXPECT_EQ(kUnpremul_SkAlphaType
, cursor_info
.custom_image
.alphaType());
243 SkPreMultiplyColor(*cursor_info
.custom_image
.getAddr32(0,0)));
247 } // namespace content