1 // Copyright 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.
7 #include "cc/nine_patch_layer_impl.h"
9 #include "cc/append_quads_data.h"
10 #include "cc/single_thread_proxy.h"
11 #include "cc/test/fake_impl_proxy.h"
12 #include "cc/test/fake_layer_tree_host_impl.h"
13 #include "cc/test/geometry_test_utils.h"
14 #include "cc/test/layer_test_common.h"
15 #include "cc/test/mock_quad_culler.h"
16 #include "cc/texture_draw_quad.h"
17 #include "ui/gfx/rect_conversions.h"
18 #include "ui/gfx/safe_integer_conversions.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "ui/gfx/transform.h"
26 gfx::Rect
ToRoundedIntRect(gfx::RectF rect_f
) {
27 return gfx::Rect(gfx::ToRoundedInt(rect_f
.x()), gfx::ToRoundedInt(rect_f
.y()), gfx::ToRoundedInt(rect_f
.width()), gfx::ToRoundedInt(rect_f
.height()));
30 TEST(NinePatchLayerImplTest
, verifyDrawQuads
)
32 // Input is a 100x100 bitmap with a 40x50 aperture at x=20, y=30.
33 // The bounds of the layer are set to 400x400, so the draw quads
34 // generated should leave the border width (40) intact.
35 MockQuadCuller quadCuller
;
36 gfx::Size
bitmapSize(100, 100);
37 gfx::Size
layerSize(400, 400);
38 gfx::Rect
visibleContentRect(gfx::Point(), layerSize
);
39 gfx::Rect
apertureRect(20, 30, 40, 50);
40 gfx::Rect
scaledApertureNonUniform(20, 30, 340, 350);
43 FakeLayerTreeHostImpl
hostImpl(&proxy
);
44 scoped_ptr
<NinePatchLayerImpl
> layer
= NinePatchLayerImpl::create(hostImpl
.activeTree(), 1);
45 layer
->drawProperties().visible_content_rect
= visibleContentRect
;
46 layer
->setBounds(layerSize
);
47 layer
->setContentBounds(layerSize
);
48 layer
->createRenderSurface();
49 layer
->drawProperties().render_target
= layer
.get();
50 layer
->setLayout(bitmapSize
, apertureRect
);
51 layer
->setResourceId(1);
53 // This scale should not affect the generated quad geometry, but only
54 // the shared draw transform.
55 gfx::Transform transform
;
56 transform
.Scale(10, 10);
57 layer
->drawProperties().target_space_transform
= transform
;
60 layer
->appendQuads(quadCuller
, data
);
63 const QuadList
& quads
= quadCuller
.quadList();
64 EXPECT_EQ(8, quads
.size());
65 Region
remaining(visibleContentRect
);
66 for (size_t i
= 0; i
< quads
.size(); ++i
) {
67 DrawQuad
* quad
= quads
[i
];
68 gfx::Rect quadRect
= quad
->rect
;
70 EXPECT_TRUE(visibleContentRect
.Contains(quadRect
)) << i
;
71 EXPECT_TRUE(remaining
.Contains(quadRect
)) << i
;
72 EXPECT_EQ(transform
, quad
->quadTransform());
73 remaining
.Subtract(Region(quadRect
));
75 EXPECT_RECT_EQ(scaledApertureNonUniform
, remaining
.bounds());
76 Region
scaledApertureRegion(scaledApertureNonUniform
);
77 EXPECT_EQ(scaledApertureRegion
, remaining
);
80 gfx::Rect
bitmapRect(gfx::Point(), bitmapSize
);
81 Region
texRemaining(bitmapRect
);
82 for (size_t i
= 0; i
< quads
.size(); ++i
) {
83 DrawQuad
* quad
= quads
[i
];
84 const TextureDrawQuad
* texQuad
= TextureDrawQuad::MaterialCast(quad
);
85 gfx::RectF texRect
= gfx::BoundingRect(texQuad
->uv_top_left
, texQuad
->uv_bottom_right
);
86 texRect
.Scale(bitmapSize
.width(), bitmapSize
.height());
87 texRemaining
.Subtract(Region(ToRoundedIntRect(texRect
)));
89 EXPECT_RECT_EQ(apertureRect
, texRemaining
.bounds());
90 Region
apertureRegion(apertureRect
);
91 EXPECT_EQ(apertureRegion
, texRemaining
);
94 TEST(NinePatchLayerImplTest
, verifyDrawQuadsForSqueezedLayer
)
96 // Test with a layer much smaller than the bitmap.
97 MockQuadCuller quadCuller
;
98 gfx::Size
bitmapSize(101, 101);
99 gfx::Size
layerSize(51, 51);
100 gfx::Rect
visibleContentRect(gfx::Point(), layerSize
);
101 gfx::Rect
apertureRect(20, 30, 40, 45); // rightWidth: 40, botHeight: 25
104 FakeLayerTreeHostImpl
hostImpl(&proxy
);
105 scoped_ptr
<NinePatchLayerImpl
> layer
= NinePatchLayerImpl::create(hostImpl
.activeTree(), 1);
106 layer
->drawProperties().visible_content_rect
= visibleContentRect
;
107 layer
->setBounds(layerSize
);
108 layer
->setContentBounds(layerSize
);
109 layer
->createRenderSurface();
110 layer
->drawProperties().render_target
= layer
.get();
111 layer
->setLayout(bitmapSize
, apertureRect
);
112 layer
->setResourceId(1);
114 AppendQuadsData data
;
115 layer
->appendQuads(quadCuller
, data
);
117 // Verify corner rects fill the layer and don't overlap
118 const QuadList
& quads
= quadCuller
.quadList();
119 EXPECT_EQ(4, quads
.size());
121 for (size_t i
= 0; i
< quads
.size(); ++i
) {
122 DrawQuad
* quad
= quads
[i
];
123 gfx::Rect quadRect
= quad
->rect
;
125 EXPECT_FALSE(filled
.Intersects(quadRect
));
126 filled
.Union(quadRect
);
128 Region
expectedFull(visibleContentRect
);
129 EXPECT_EQ(expectedFull
, filled
);
131 // Verify UV rects cover the corners of the bitmap and the crop is weighted
132 // proportionately to the relative corner sizes (for uneven apertures).
133 gfx::Rect
bitmapRect(gfx::Point(), bitmapSize
);
134 Region
texRemaining(bitmapRect
);
135 for (size_t i
= 0; i
< quads
.size(); ++i
) {
136 DrawQuad
* quad
= quads
[i
];
137 const TextureDrawQuad
* texQuad
= TextureDrawQuad::MaterialCast(quad
);
138 gfx::RectF texRect
= gfx::BoundingRect(texQuad
->uv_top_left
, texQuad
->uv_bottom_right
);
139 texRect
.Scale(bitmapSize
.width(), bitmapSize
.height());
140 texRemaining
.Subtract(Region(ToRoundedIntRect(texRect
)));
142 Region expectedRemainingRegion
= Region(gfx::Rect(bitmapSize
));
143 expectedRemainingRegion
.Subtract(gfx::Rect(0, 0, 17, 28));
144 expectedRemainingRegion
.Subtract(gfx::Rect(67, 0, 34, 28));
145 expectedRemainingRegion
.Subtract(gfx::Rect(0, 78, 17, 23));
146 expectedRemainingRegion
.Subtract(gfx::Rect(67, 78, 34, 23));
147 EXPECT_EQ(expectedRemainingRegion
, texRemaining
);