Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 | |
| OLD | NEW |