OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/gfx/nine_image_painter.h" | 5 #include "ui/gfx/nine_image_painter.h" |
6 | 6 |
| 7 #include "base/base64.h" |
7 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
8 #include "ui/gfx/canvas.h" | 9 #include "ui/gfx/canvas.h" |
| 10 #include "ui/gfx/codec/png_codec.h" |
9 #include "ui/gfx/geometry/insets.h" | 11 #include "ui/gfx/geometry/insets.h" |
10 #include "ui/gfx/geometry/rect.h" | 12 #include "ui/gfx/geometry/rect.h" |
| 13 #include "ui/gfx/geometry/vector2d.h" |
| 14 #include "ui/gfx/geometry/vector2d_conversions.h" |
11 #include "ui/gfx/image/image_skia.h" | 15 #include "ui/gfx/image/image_skia.h" |
12 | 16 |
13 namespace gfx { | 17 namespace gfx { |
14 | 18 |
| 19 static std::string GetPNGDataUrl(const SkBitmap& bitmap) { |
| 20 std::vector<unsigned char> png_data; |
| 21 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &png_data); |
| 22 std::string data_url; |
| 23 data_url.insert(data_url.end(), png_data.begin(), png_data.end()); |
| 24 base::Base64Encode(data_url, &data_url); |
| 25 data_url.insert(0, "data:image/png;base64,"); |
| 26 |
| 27 return data_url; |
| 28 } |
| 29 |
| 30 void ExpectRedWithGreenRect(const SkBitmap& bitmap, |
| 31 const Rect& outer_rect, |
| 32 const Rect& green_rect) { |
| 33 for (int y = outer_rect.y(); y < outer_rect.bottom(); y++) { |
| 34 SCOPED_TRACE(y); |
| 35 for (int x = outer_rect.x(); x < outer_rect.right(); x++) { |
| 36 SCOPED_TRACE(x); |
| 37 if (green_rect.Contains(x, y)) { |
| 38 ASSERT_EQ(SK_ColorGREEN, bitmap.getColor(x, y)) |
| 39 << "Output image:\n" << GetPNGDataUrl(bitmap); |
| 40 } else { |
| 41 ASSERT_EQ(SK_ColorRED, bitmap.getColor(x, y)) << "Output image:\n" |
| 42 << GetPNGDataUrl(bitmap); |
| 43 } |
| 44 } |
| 45 } |
| 46 } |
| 47 |
15 TEST(NineImagePainterTest, GetSubsetRegions) { | 48 TEST(NineImagePainterTest, GetSubsetRegions) { |
16 SkBitmap src; | 49 SkBitmap src; |
17 src.allocN32Pixels(40, 50); | 50 src.allocN32Pixels(40, 50); |
18 const ImageSkia image_skia(ImageSkiaRep(src, 1.0)); | 51 const ImageSkia image_skia(ImageSkiaRep(src, 1.0)); |
19 const Insets insets(1, 2, 3, 4); | 52 const Insets insets(1, 2, 3, 4); |
20 std::vector<Rect> rects; | 53 std::vector<Rect> rects; |
21 NineImagePainter::GetSubsetRegions(image_skia, insets, &rects); | 54 NineImagePainter::GetSubsetRegions(image_skia, insets, &rects); |
22 ASSERT_EQ(9u, rects.size()); | 55 ASSERT_EQ(9u, rects.size()); |
23 EXPECT_EQ(gfx::Rect(0, 0, 2, 1), rects[0]); | 56 EXPECT_EQ(gfx::Rect(0, 0, 2, 1), rects[0]); |
24 EXPECT_EQ(gfx::Rect(2, 0, 34, 1), rects[1]); | 57 EXPECT_EQ(gfx::Rect(2, 0, 34, 1), rects[1]); |
25 EXPECT_EQ(gfx::Rect(36, 0, 4, 1), rects[2]); | 58 EXPECT_EQ(gfx::Rect(36, 0, 4, 1), rects[2]); |
26 EXPECT_EQ(gfx::Rect(0, 1, 2, 46), rects[3]); | 59 EXPECT_EQ(gfx::Rect(0, 1, 2, 46), rects[3]); |
27 EXPECT_EQ(gfx::Rect(2, 1, 34, 46), rects[4]); | 60 EXPECT_EQ(gfx::Rect(2, 1, 34, 46), rects[4]); |
28 EXPECT_EQ(gfx::Rect(36, 1, 4, 46), rects[5]); | 61 EXPECT_EQ(gfx::Rect(36, 1, 4, 46), rects[5]); |
29 EXPECT_EQ(gfx::Rect(0, 47, 2, 3), rects[6]); | 62 EXPECT_EQ(gfx::Rect(0, 47, 2, 3), rects[6]); |
30 EXPECT_EQ(gfx::Rect(2, 47, 34, 3), rects[7]); | 63 EXPECT_EQ(gfx::Rect(2, 47, 34, 3), rects[7]); |
31 EXPECT_EQ(gfx::Rect(36, 47, 4, 3), rects[8]); | 64 EXPECT_EQ(gfx::Rect(36, 47, 4, 3), rects[8]); |
32 } | 65 } |
33 | 66 |
34 TEST(NineImagePainterTest, PaintScale) { | 67 TEST(NineImagePainterTest, PaintHighDPI) { |
35 SkBitmap src; | 68 SkBitmap src; |
36 src.allocN32Pixels(100, 100); | 69 src.allocN32Pixels(100, 100); |
37 src.eraseColor(SK_ColorRED); | 70 src.eraseColor(SK_ColorRED); |
38 src.eraseArea(SkIRect::MakeXYWH(10, 10, 80, 80), SK_ColorGREEN); | 71 src.eraseArea(SkIRect::MakeXYWH(10, 10, 80, 80), SK_ColorGREEN); |
39 | 72 |
40 gfx::ImageSkia image(gfx::ImageSkiaRep(src, 0.0f)); | 73 float image_scale = 2.f; |
| 74 |
| 75 gfx::ImageSkia image(gfx::ImageSkiaRep(src, image_scale)); |
41 gfx::Insets insets(10, 10, 10, 10); | 76 gfx::Insets insets(10, 10, 10, 10); |
42 gfx::NineImagePainter painter(image, insets); | 77 gfx::NineImagePainter painter(image, insets); |
43 | 78 |
44 int image_scale = 2; | |
45 bool is_opaque = true; | 79 bool is_opaque = true; |
46 gfx::Canvas canvas(gfx::Size(400, 400), image_scale, is_opaque); | 80 gfx::Canvas canvas(gfx::Size(100, 100), image_scale, is_opaque); |
47 canvas.Scale(2, 1); | |
48 | 81 |
49 gfx::Rect bounds(0, 0, 100, 100); | 82 gfx::Vector2d offset(20, 10); |
| 83 canvas.Translate(offset); |
| 84 |
| 85 gfx::Rect bounds(0, 0, 50, 50); |
50 painter.Paint(&canvas, bounds); | 86 painter.Paint(&canvas, bounds); |
51 | 87 |
52 SkBitmap result; | 88 SkBitmap result; |
53 const SkISize size = canvas.sk_canvas()->getDeviceSize(); | 89 const SkISize size = canvas.sk_canvas()->getDeviceSize(); |
54 result.allocN32Pixels(size.width(), size.height()); | 90 result.allocN32Pixels(size.width(), size.height()); |
55 canvas.sk_canvas()->readPixels(&result, 0, 0); | 91 canvas.sk_canvas()->readPixels(&result, 0, 0); |
56 | 92 |
57 SkIRect green_rect = SkIRect::MakeLTRB(40, 20, 360, 180); | 93 gfx::Vector2d paint_offset = |
58 for (int y = 0; y < 200; y++) { | 94 gfx::ToFlooredVector2d(gfx::ScaleVector2d(offset, image_scale)); |
59 for (int x = 0; x < 400; x++) { | 95 gfx::Rect green_rect = gfx::Rect(10, 10, 80, 80) + paint_offset; |
60 if (green_rect.contains(x, y)) { | 96 gfx::Rect outer_rect = gfx::Rect(100, 100) + paint_offset; |
61 ASSERT_EQ(SK_ColorGREEN, result.getColor(x, y)); | 97 ExpectRedWithGreenRect(result, outer_rect, green_rect); |
62 } else { | |
63 ASSERT_EQ(SK_ColorRED, result.getColor(x, y)); | |
64 } | |
65 } | |
66 } | |
67 } | 98 } |
68 | 99 |
69 TEST(NineImagePainterTest, PaintStaysInBounds) { | 100 TEST(NineImagePainterTest, PaintStaysInBounds) { |
70 // In this test the bounds rect is 1x1 but each image is 2x2. | 101 // In this test the bounds rect is 1x1 but each image is 2x2. |
71 // The NineImagePainter should not paint outside the bounds. | 102 // The NineImagePainter should not paint outside the bounds. |
72 | 103 |
73 SkBitmap src; | 104 SkBitmap src; |
74 src.allocN32Pixels(6, 6); | 105 src.allocN32Pixels(6, 6); |
75 src.eraseColor(SK_ColorRED); | 106 src.eraseColor(SK_ColorRED); |
76 | 107 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 for (int x = 1; x < 10; x++) { | 160 for (int x = 1; x < 10; x++) { |
130 if (green_rect.contains(x, y)) { | 161 if (green_rect.contains(x, y)) { |
131 ASSERT_EQ(SK_ColorGREEN, result.getColor(x, y)); | 162 ASSERT_EQ(SK_ColorGREEN, result.getColor(x, y)); |
132 } else { | 163 } else { |
133 ASSERT_EQ(SK_ColorRED, result.getColor(x, y)); | 164 ASSERT_EQ(SK_ColorRED, result.getColor(x, y)); |
134 } | 165 } |
135 } | 166 } |
136 } | 167 } |
137 } | 168 } |
138 | 169 |
139 TEST(NineImagePainterTest, PaintWithNagativeScale) { | 170 TEST(NineImagePainterTest, PaintWithScale) { |
140 SkBitmap src; | 171 SkBitmap src; |
141 src.allocN32Pixels(100, 100); | 172 src.allocN32Pixels(100, 100); |
142 src.eraseColor(SK_ColorRED); | 173 src.eraseColor(SK_ColorRED); |
143 src.eraseArea(SkIRect::MakeXYWH(10, 10, 80, 80), SK_ColorGREEN); | 174 src.eraseArea(SkIRect::MakeXYWH(10, 10, 80, 80), SK_ColorGREEN); |
144 | 175 |
145 gfx::ImageSkia image(gfx::ImageSkiaRep(src, 0.0f)); | 176 float image_scale = 2.f; |
| 177 |
| 178 gfx::ImageSkia image(gfx::ImageSkiaRep(src, image_scale)); |
146 gfx::Insets insets(10, 10, 10, 10); | 179 gfx::Insets insets(10, 10, 10, 10); |
147 gfx::NineImagePainter painter(image, insets); | 180 gfx::NineImagePainter painter(image, insets); |
148 | 181 |
149 int image_scale = 2; | |
150 bool is_opaque = true; | 182 bool is_opaque = true; |
151 gfx::Canvas canvas(gfx::Size(400, 400), image_scale, is_opaque); | 183 gfx::Canvas canvas(gfx::Size(400, 400), image_scale, is_opaque); |
152 canvas.Translate(gfx::Vector2d(200, 200)); | |
153 canvas.Scale(-2, -1); | |
154 | 184 |
155 gfx::Rect bounds(0, 0, 100, 100); | 185 gfx::Vector2d offset(20, 10); |
| 186 canvas.Translate(offset); |
| 187 canvas.Scale(2, 1); |
| 188 |
| 189 gfx::Rect bounds(0, 0, 50, 50); |
156 painter.Paint(&canvas, bounds); | 190 painter.Paint(&canvas, bounds); |
157 | 191 |
158 SkBitmap result; | 192 SkBitmap result; |
159 const SkISize size = canvas.sk_canvas()->getDeviceSize(); | 193 const SkISize size = canvas.sk_canvas()->getDeviceSize(); |
160 result.allocN32Pixels(size.width(), size.height()); | 194 result.allocN32Pixels(size.width(), size.height()); |
161 canvas.sk_canvas()->readPixels(&result, 0, 0); | 195 canvas.sk_canvas()->readPixels(&result, 0, 0); |
162 | 196 |
163 SkIRect green_rect = SkIRect::MakeLTRB(40, 220, 360, 380); | 197 gfx::Vector2d paint_offset = |
164 for (int y = 200; y < 400; y++) { | 198 gfx::ToFlooredVector2d(gfx::ScaleVector2d(offset, image_scale)); |
165 for (int x = 0; x < 400; x++) { | 199 gfx::Rect green_rect = gfx::Rect(20, 10, 160, 80) + paint_offset; |
166 if (green_rect.contains(x, y)) { | 200 gfx::Rect outer_rect = gfx::Rect(200, 100) + paint_offset; |
167 ASSERT_EQ(SK_ColorGREEN, result.getColor(x, y)); | 201 ExpectRedWithGreenRect(result, outer_rect, green_rect); |
168 } else { | 202 } |
169 ASSERT_EQ(SK_ColorRED, result.getColor(x, y)); | 203 |
170 } | 204 TEST(NineImagePainterTest, PaintWithNegativeScale) { |
171 } | 205 SkBitmap src; |
172 } | 206 src.allocN32Pixels(100, 100); |
| 207 src.eraseColor(SK_ColorRED); |
| 208 src.eraseArea(SkIRect::MakeXYWH(10, 10, 80, 80), SK_ColorGREEN); |
| 209 |
| 210 float image_scale = 2.f; |
| 211 |
| 212 gfx::ImageSkia image(gfx::ImageSkiaRep(src, image_scale)); |
| 213 gfx::Insets insets(10, 10, 10, 10); |
| 214 gfx::NineImagePainter painter(image, insets); |
| 215 |
| 216 bool is_opaque = true; |
| 217 gfx::Canvas canvas(gfx::Size(400, 400), image_scale, is_opaque); |
| 218 canvas.Translate(gfx::Vector2d(70, 60)); |
| 219 canvas.Scale(-1, -1); |
| 220 |
| 221 gfx::Rect bounds(0, 0, 50, 50); |
| 222 painter.Paint(&canvas, bounds); |
| 223 |
| 224 SkBitmap result; |
| 225 const SkISize size = canvas.sk_canvas()->getDeviceSize(); |
| 226 result.allocN32Pixels(size.width(), size.height()); |
| 227 canvas.sk_canvas()->readPixels(&result, 0, 0); |
| 228 |
| 229 // The painting space is 50x50 and the scale of -1,-1 means an offset of 50,50 |
| 230 // would put the output in the top left corner. Since the offset is 70,60 it |
| 231 // moves by 20,10. Since the output is 2x DPI it will become offset by 40,20. |
| 232 gfx::Vector2d paint_offset(40, 20); |
| 233 gfx::Rect green_rect = gfx::Rect(10, 10, 80, 80) + paint_offset; |
| 234 gfx::Rect outer_rect = gfx::Rect(100, 100) + paint_offset; |
| 235 ExpectRedWithGreenRect(result, outer_rect, green_rect); |
173 } | 236 } |
174 | 237 |
175 } // namespace gfx | 238 } // namespace gfx |
OLD | NEW |