Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(733)

Side by Side Diff: cc/quads/nine_patch_generator.cc

Issue 2591863003: Use nine-patch resource for drawing Aura overlay scrollbar thumb. (Closed)
Patch Set: Rename to painted_overlay_scrollbar_layer + rudimentary tests Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 "cc/quads/nine_patch_generator.h"
6
7 #include "base/values.h"
8 #include "cc/base/math_util.h"
9 #include "cc/layers/append_quads_data.h"
10 #include "cc/layers/draw_properties.h"
11 #include "cc/quads/render_pass.h"
12 #include "cc/quads/shared_quad_state.h"
13 #include "cc/quads/texture_draw_quad.h"
aelias_OOO_until_Jul13 2017/02/28 23:23:51 Some of these includes aren't used (unless you mov
bokan 2017/03/01 00:44:21 Done and pared this down to what's needed.
14 #include "cc/resources/resource_provider.h"
15 #include "cc/trees/layer_tree_impl.h"
16 #include "cc/trees/occlusion.h"
17 #include "ui/gfx/geometry/rect_f.h"
18
19 namespace cc {
20
21 namespace {
22
23 // Maximum number of patches that can be produced for one NinePatchLayer.
24 const int kMaxOcclusionPatches = 12;
25 const int kMaxPatches = 9;
26
27 gfx::RectF BoundsToRect(int x1, int y1, int x2, int y2) {
28 return gfx::RectF(x1, y1, x2 - x1, y2 - y1);
29 }
30
31 gfx::RectF NormalizedRect(const gfx::RectF& rect,
32 float total_width,
33 float total_height) {
34 return gfx::RectF(rect.x() / total_width, rect.y() / total_height,
35 rect.width() / total_width, rect.height() / total_height);
36 }
37
38 } // namespace
39
40 NinePatchGenerator::Patch::Patch(const gfx::RectF& image_rect,
41 const gfx::Size& total_image_bounds,
42 const gfx::RectF& output_rect)
43 : image_rect(image_rect),
44 normalized_image_rect(NormalizedRect(image_rect,
45 total_image_bounds.width(),
46 total_image_bounds.height())),
47 output_rect(output_rect) {}
48
49 NinePatchGenerator::NinePatchGenerator() : fill_center_(false) {}
50
51 bool NinePatchGenerator::SetLayout(const gfx::Size& image_bounds,
52 const gfx::Size& output_bounds,
53 const gfx::Rect& aperture,
54 const gfx::Rect& border,
55 const gfx::Rect& output_occlusion,
56 bool fill_center) {
57 if (image_bounds_ == image_bounds && output_bounds_ == output_bounds &&
58 image_aperture_ == aperture && border_ == border &&
59 fill_center_ == fill_center && output_occlusion_ == output_occlusion)
60 return false;
61
62 image_bounds_ = image_bounds;
63 output_bounds_ = output_bounds;
64 image_aperture_ = aperture;
65 border_ = border;
66 fill_center_ = fill_center;
67 output_occlusion_ = output_occlusion;
68
69 CheckGeometryLimitations();
70
71 return true;
72 }
73
74 void NinePatchGenerator::CheckGeometryLimitations() {
75 // |border| is in layer space. It cannot exceed the bounds of the layer.
76 DCHECK_GE(output_bounds_.width(), border_.width());
77 DCHECK_GE(output_bounds_.height(), border_.height());
78
79 // Sanity Check on |border|
80 DCHECK_LE(border_.x(), border_.width());
81 DCHECK_LE(border_.y(), border_.height());
82 DCHECK_GE(border_.x(), 0);
83 DCHECK_GE(border_.y(), 0);
84
85 // |aperture| is in image space. It cannot exceed the bounds of the bitmap.
86 DCHECK(!image_aperture_.size().IsEmpty());
87 DCHECK(gfx::Rect(image_bounds_).Contains(image_aperture_))
88 << "image_bounds_ " << gfx::Rect(image_bounds_).ToString()
89 << " image_aperture_ " << image_aperture_.ToString();
90
91 // Sanity check on |output_occlusion_|. It should always be within the
92 // border.
93 gfx::Rect border_rect(border_.x(), border_.y(),
94 output_bounds_.width() - border_.width(),
95 output_bounds_.height() - border_.height());
96 DCHECK(output_occlusion_.IsEmpty() || output_occlusion_.Contains(border_rect))
97 << "border_rect " << border_rect.ToString() << " output_occlusion_ "
98 << output_occlusion_.ToString();
99 }
100
101 std::vector<NinePatchGenerator::Patch>
102 NinePatchGenerator::ComputeQuadsWithoutOcclusion() const {
103 float image_width = image_bounds_.width();
104 float image_height = image_bounds_.height();
105 float output_width = output_bounds_.width();
106 float output_height = output_bounds_.height();
107 gfx::RectF output_aperture(border_.x(), border_.y(),
108 output_width - border_.width(),
109 output_height - border_.height());
110
111 std::vector<Patch> patches;
112 patches.reserve(kMaxPatches);
113
114 // Top-left.
115 patches.push_back(
116 Patch(BoundsToRect(0, 0, image_aperture_.x(), image_aperture_.y()),
117 image_bounds_,
118 BoundsToRect(0, 0, output_aperture.x(), output_aperture.y())));
119
120 // Top-right.
121 patches.push_back(Patch(BoundsToRect(image_aperture_.right(), 0, image_width,
122 image_aperture_.y()),
123 image_bounds_,
124 BoundsToRect(output_aperture.right(), 0, output_width,
125 output_aperture.y())));
126
127 // Bottom-left.
128 patches.push_back(Patch(BoundsToRect(0, image_aperture_.bottom(),
129 image_aperture_.x(), image_height),
130 image_bounds_,
131 BoundsToRect(0, output_aperture.bottom(),
132 output_aperture.x(), output_height)));
133
134 // Bottom-right.
135 patches.push_back(
136 Patch(BoundsToRect(image_aperture_.right(), image_aperture_.bottom(),
137 image_width, image_height),
138 image_bounds_,
139 BoundsToRect(output_aperture.right(), output_aperture.bottom(),
140 output_width, output_height)));
141
142 // Top.
143 patches.push_back(
144 Patch(BoundsToRect(image_aperture_.x(), 0, image_aperture_.right(),
145 image_aperture_.y()),
146 image_bounds_,
147 BoundsToRect(output_aperture.x(), 0, output_aperture.right(),
148 output_aperture.y())));
149
150 // Left.
151 patches.push_back(
152 Patch(BoundsToRect(0, image_aperture_.y(), image_aperture_.x(),
153 image_aperture_.bottom()),
154 image_bounds_,
155 BoundsToRect(0, output_aperture.y(), output_aperture.x(),
156 output_aperture.bottom())));
157
158 // Right.
159 patches.push_back(
160 Patch(BoundsToRect(image_aperture_.right(), image_aperture_.y(),
161 image_width, image_aperture_.bottom()),
162 image_bounds_,
163 BoundsToRect(output_aperture.right(), output_aperture.y(),
164 output_width, output_aperture.bottom())));
165
166 // Bottom.
167 patches.push_back(
168 Patch(BoundsToRect(image_aperture_.x(), image_aperture_.bottom(),
169 image_aperture_.right(), image_height),
170 image_bounds_,
171 BoundsToRect(output_aperture.x(), output_aperture.bottom(),
172 output_aperture.right(), output_height)));
173
174 // Center.
175 if (fill_center_) {
176 patches.push_back(
177 Patch(BoundsToRect(image_aperture_.x(), image_aperture_.y(),
178 image_aperture_.right(), image_aperture_.bottom()),
179 image_bounds_,
180 BoundsToRect(output_aperture.x(), output_aperture.y(),
181 output_aperture.right(), output_aperture.bottom())));
182 }
183
184 return patches;
185 }
186
187 std::vector<NinePatchGenerator::Patch>
188 NinePatchGenerator::ComputeQuadsWithOcclusion() const {
189 float image_width = image_bounds_.width();
190 float image_height = image_bounds_.height();
191
192 float output_width = output_bounds_.width();
193 float output_height = output_bounds_.height();
194
195 float layer_border_right = border_.width() - border_.x();
196 float layer_border_bottom = border_.height() - border_.y();
197
198 float image_aperture_right = image_width - image_aperture_.right();
199 float image_aperture_bottom = image_height - image_aperture_.bottom();
200
201 float output_occlusion_right = output_width - output_occlusion_.right();
202 float output_occlusion_bottom = output_height - output_occlusion_.bottom();
203
204 gfx::RectF image_occlusion(BoundsToRect(
205 border_.x() == 0
206 ? 0
207 : (output_occlusion_.x() * image_aperture_.x() / border_.x()),
208 border_.y() == 0
209 ? 0
210 : (output_occlusion_.y() * image_aperture_.y() / border_.y()),
211 image_width - (layer_border_right == 0
212 ? 0
213 : output_occlusion_right * image_aperture_right /
214 layer_border_right),
215 image_height - (layer_border_bottom == 0
216 ? 0
217 : output_occlusion_bottom * image_aperture_bottom /
218 layer_border_bottom)));
219 gfx::RectF output_aperture(border_.x(), border_.y(),
220 output_width - border_.width(),
221 output_height - border_.height());
222
223 std::vector<Patch> patches;
224 patches.reserve(kMaxOcclusionPatches);
225
226 // Top-left-left.
227 patches.push_back(
228 Patch(BoundsToRect(0, 0, image_occlusion.x(), image_aperture_.y()),
229 image_bounds_,
230 BoundsToRect(0, 0, output_occlusion_.x(), output_aperture.y())));
231
232 // Top-left-right.
233 patches.push_back(
234 Patch(BoundsToRect(image_occlusion.x(), 0, image_aperture_.x(),
235 image_occlusion.y()),
236 image_bounds_,
237 BoundsToRect(output_occlusion_.x(), 0, output_aperture.x(),
238 output_occlusion_.y())));
239
240 // Top-center.
241 patches.push_back(
242 Patch(BoundsToRect(image_aperture_.x(), 0, image_aperture_.right(),
243 image_occlusion.y()),
244 image_bounds_,
245 BoundsToRect(output_aperture.x(), 0, output_aperture.right(),
246 output_occlusion_.y())));
247
248 // Top-right-left.
249 patches.push_back(
250 Patch(BoundsToRect(image_aperture_.right(), 0, image_occlusion.right(),
251 image_occlusion.y()),
252 image_bounds_,
253 BoundsToRect(output_aperture.right(), 0, output_occlusion_.right(),
254 output_occlusion_.y())));
255
256 // Top-right-right.
257 patches.push_back(Patch(BoundsToRect(image_occlusion.right(), 0, image_width,
258 image_aperture_.y()),
259 image_bounds_,
260 BoundsToRect(output_occlusion_.right(), 0,
261 output_width, output_aperture.y())));
262
263 // Left-center.
264 patches.push_back(
265 Patch(BoundsToRect(0, image_aperture_.y(), image_occlusion.x(),
266 image_aperture_.bottom()),
267 image_bounds_,
268 BoundsToRect(0, output_aperture.y(), output_occlusion_.x(),
269 output_aperture.bottom())));
270
271 // Right-center.
272 patches.push_back(
273 Patch(BoundsToRect(image_occlusion.right(), image_aperture_.y(),
274 image_width, image_aperture_.bottom()),
275 image_bounds_,
276 BoundsToRect(output_occlusion_.right(), output_aperture.y(),
277 output_width, output_aperture.bottom())));
278
279 // Bottom-left-left.
280 patches.push_back(Patch(BoundsToRect(0, image_aperture_.bottom(),
281 image_occlusion.x(), image_height),
282 image_bounds_,
283 BoundsToRect(0, output_aperture.bottom(),
284 output_occlusion_.x(), output_height)));
285
286 // Bottom-left-right.
287 patches.push_back(
288 Patch(BoundsToRect(image_occlusion.x(), image_occlusion.bottom(),
289 image_aperture_.x(), image_height),
290 image_bounds_,
291 BoundsToRect(output_occlusion_.x(), output_occlusion_.bottom(),
292 output_aperture.x(), output_height)));
293
294 // Bottom-center.
295 patches.push_back(
296 Patch(BoundsToRect(image_aperture_.x(), image_occlusion.bottom(),
297 image_aperture_.right(), image_height),
298 image_bounds_,
299 BoundsToRect(output_aperture.x(), output_occlusion_.bottom(),
300 output_aperture.right(), output_height)));
301
302 // Bottom-right-left.
303 patches.push_back(
304 Patch(BoundsToRect(image_aperture_.right(), image_occlusion.bottom(),
305 image_occlusion.right(), image_height),
306 image_bounds_,
307 BoundsToRect(output_aperture.right(), output_occlusion_.bottom(),
308 output_occlusion_.right(), output_height)));
309
310 // Bottom-right-right.
311 patches.push_back(
312 Patch(BoundsToRect(image_occlusion.right(), image_aperture_.bottom(),
313 image_width, image_height),
314 image_bounds_,
315 BoundsToRect(output_occlusion_.right(), output_aperture.bottom(),
316 output_width, output_height)));
317
318 return patches;
319 }
320
321 std::vector<NinePatchGenerator::Patch> NinePatchGenerator::GeneratePatches()
322 const {
323 DCHECK(!output_bounds_.IsEmpty());
324
325 std::vector<Patch> patches;
326
327 if (output_occlusion_.IsEmpty() || fill_center_)
328 patches = ComputeQuadsWithoutOcclusion();
329 else
330 patches = ComputeQuadsWithOcclusion();
331
332 return patches;
333 }
334
335 void NinePatchGenerator::AsJson(base::DictionaryValue* dictionary) const {
336 base::ListValue* list = new base::ListValue;
337 list->AppendInteger(image_aperture_.origin().x());
338 list->AppendInteger(image_aperture_.origin().y());
339 list->AppendInteger(image_aperture_.size().width());
340 list->AppendInteger(image_aperture_.size().height());
341 dictionary->Set("ImageAperture", list);
342
343 list = new base::ListValue;
344 list->AppendInteger(image_bounds_.width());
345 list->AppendInteger(image_bounds_.height());
346 dictionary->Set("ImageBounds", list);
347
348 dictionary->Set("Border", MathUtil::AsValue(border_).release());
349
350 dictionary->SetBoolean("FillCenter", fill_center_);
351
352 list = new base::ListValue;
353 list->AppendInteger(output_occlusion_.x());
354 list->AppendInteger(output_occlusion_.y());
355 list->AppendInteger(output_occlusion_.width());
356 list->AppendInteger(output_occlusion_.height());
357 dictionary->Set("OutputOcclusion", list);
358 }
359
360 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698