blob: ca9e13a2bca5ec3dd8bec291b9de27b35ffa6283 [file] [log] [blame]
alex-ac2cb37ad82014-11-13 18:03:291// 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.
4
5#include "ui/gfx/path_win.h"
6
avic89eb8d42015-12-23 08:08:187#include <stddef.h>
8
alex-ac2cb37ad82014-11-13 18:03:299#include <algorithm>
10#include <vector>
11
avic89eb8d42015-12-23 08:08:1812#include "base/macros.h"
alex-ac2cb37ad82014-11-13 18:03:2913#include "base/win/scoped_gdi_object.h"
14#include "skia/ext/skia_utils_win.h"
15#include "testing/gtest/include/gtest/gtest.h"
16#include "third_party/skia/include/core/SkRRect.h"
17#include "ui/gfx/path.h"
18
19namespace gfx {
20
21namespace {
22
23// Get rectangles from the |region| and convert them to SkIRect.
24std::vector<SkIRect> GetRectsFromHRGN(HRGN region) {
25 // Determine the size of output buffer required to receive the region.
26 DWORD bytes_size = GetRegionData(region, 0, NULL);
27 CHECK_NE((DWORD)0, bytes_size);
28
29 // Fetch the Windows RECTs that comprise the region.
30 std::vector<char> buffer(bytes_size);
31 LPRGNDATA region_data = reinterpret_cast<LPRGNDATA>(buffer.data());
32 DWORD result = GetRegionData(region, bytes_size, region_data);
33 CHECK_EQ(bytes_size, result);
34
35 // Pull out the rectangles into a SkIRect vector to return to caller.
36 const LPRECT rects = reinterpret_cast<LPRECT>(&region_data->Buffer[0]);
37 std::vector<SkIRect> sk_rects(region_data->rdh.nCount);
38 std::transform(rects, rects + region_data->rdh.nCount,
39 sk_rects.begin(), skia::RECTToSkIRect);
40
41 return sk_rects;
42}
43
44} // namespace
45
46// Test that rectangle with round corners stil has round corners after
47// converting from SkPath to the HRGN.
fmalita22146632015-02-16 21:00:4148// FIXME: this test is fragile (it depends on rrect rasterization impl)
alex-ac2cb37ad82014-11-13 18:03:2949TEST(CreateHRGNFromSkPathTest, RoundCornerTest) {
50 const SkIRect rects[] = {
fmalita22146632015-02-16 21:00:4151 { 16, 0, 34, 1 },
52 { 12, 1, 38, 2 },
53 { 10, 2, 40, 3 },
54 { 9, 3, 41, 4 },
55 { 7, 4, 43, 5 },
56 { 6, 5, 44, 6 },
57 { 5, 6, 45, 7 },
58 { 4, 7, 45, 8 },
59 { 4, 8, 46, 9 },
60 { 3, 9, 47, 10 },
61 { 2, 10, 47, 11 },
62 { 2, 11, 48, 12 },
63 { 1, 12, 49, 16 },
64 { 0, 16, 50, 34 },
65 { 1, 34, 49, 38 },
66 { 2, 38, 48, 39 },
67 { 2, 39, 47, 40 },
68 { 3, 40, 47, 41 },
69 { 4, 41, 46, 42 },
70 { 4, 42, 45, 43 },
71 { 5, 43, 45, 44 },
72 { 6, 44, 44, 45 },
73 { 8, 45, 42, 46 },
74 { 9, 46, 41, 47 },
75 { 11, 47, 39, 48 },
76 { 12, 48, 38, 49 },
77 { 16, 49, 34, 50 },
alex-ac2cb37ad82014-11-13 18:03:2978 };
79
80 Path path;
81 SkRRect rrect;
82 rrect.setRectXY(SkRect::MakeWH(50, 50), 20, 20);
83 path.addRRect(rrect);
84 base::win::ScopedRegion region(CreateHRGNFromSkPath(path));
anpol280746c2015-12-18 08:39:0385 const std::vector<SkIRect>& region_rects = GetRectsFromHRGN(region.get());
alex-ac2cb37ad82014-11-13 18:03:2986 EXPECT_EQ(arraysize(rects), region_rects.size());
87 for (size_t i = 0; i < arraysize(rects) && i < region_rects.size(); ++i)
88 EXPECT_EQ(rects[i], region_rects[i]);
89}
90
91// Check that a path enclosing two non-adjacent areas is correctly translated
92// to a non-contiguous region.
93TEST(CreateHRGNFromSkPathTest, NonContiguousPath) {
94 const SkIRect rects[] = {
95 { 0, 0, 50, 50},
96 { 100, 100, 150, 150},
97 };
98
99 Path path;
100 for (const SkIRect& rect : rects) {
101 path.addRect(SkRect::Make(rect));
102 }
103 base::win::ScopedRegion region(CreateHRGNFromSkPath(path));
anpol280746c2015-12-18 08:39:03104 const std::vector<SkIRect>& region_rects = GetRectsFromHRGN(region.get());
alex-ac2cb37ad82014-11-13 18:03:29105 ASSERT_EQ(arraysize(rects), region_rects.size());
106 for (size_t i = 0; i < arraysize(rects); ++i)
107 EXPECT_EQ(rects[i], region_rects[i]);
108}
109
110// Check that empty region is returned for empty path.
111TEST(CreateHRGNFromSkPathTest, EmptyPath) {
112 Path path;
113 base::win::ScopedRegion empty_region(::CreateRectRgn(0, 0, 0, 0));
114 base::win::ScopedRegion region(CreateHRGNFromSkPath(path));
anpol280746c2015-12-18 08:39:03115 EXPECT_TRUE(::EqualRgn(empty_region.get(), region.get()));
alex-ac2cb37ad82014-11-13 18:03:29116}
117
118} // namespace gfx
119