10 #include "flutter/fml/logging.h"
27 skyline_.push_back(SkylineSegment{0, 0,
width()});
37 struct SkylineSegment {
43 std::vector<SkylineSegment> skyline_;
51 bool RectangleFits(
size_t skyline_index,
int width,
int height,
int* y)
const;
54 void AddSkylineLevel(
size_t skylineIndex,
62 if ((
unsigned)p_width > (
unsigned)
width() ||
63 (
unsigned)p_height > (
unsigned)
height()) {
68 int bestWidth =
width() + 1;
72 for (
auto i = 0u; i < skyline_.size(); ++i) {
74 if (RectangleFits(i, p_width, p_height, &y)) {
76 if (y < bestY || (y == bestY && skyline_[i].width_ < bestWidth)) {
78 bestWidth = skyline_[i].width_;
79 bestX = skyline_[i].x_;
86 if (-1 != bestIndex) {
87 AddSkylineLevel(bestIndex, bestX, bestY, p_width, p_height);
91 area_so_far_ += p_width * p_height;
100 bool SkylineRectanglePacker::RectangleFits(
size_t skyline_index,
104 int x = skyline_[skyline_index].x_;
105 if (x + p_width >
width()) {
109 int widthLeft = p_width;
110 size_t i = skyline_index;
111 int y = skyline_[skyline_index].y_;
112 while (widthLeft > 0) {
113 y = std::max(y, skyline_[i].y_);
114 if (y + p_height >
height()) {
117 widthLeft -= skyline_[i].width_;
119 FML_CHECK(i < skyline_.size() || widthLeft <= 0);
126 void SkylineRectanglePacker::AddSkylineLevel(
size_t skyline_index,
131 SkylineSegment newSegment;
133 newSegment.y_ = y + p_height;
134 newSegment.width_ = p_width;
135 skyline_.insert(skyline_.begin() + skyline_index, newSegment);
137 FML_DCHECK(newSegment.x_ + newSegment.width_ <=
width());
138 FML_DCHECK(newSegment.y_ <=
height());
141 for (
auto i = skyline_index + 1; i < skyline_.size(); ++i) {
143 FML_DCHECK(skyline_[i - 1].x_ <= skyline_[i].x_);
145 if (skyline_[i].x_ < skyline_[i - 1].x_ + skyline_[i - 1].width_) {
146 int shrink = skyline_[i - 1].x_ + skyline_[i - 1].width_ - skyline_[i].x_;
148 skyline_[i].x_ += shrink;
149 skyline_[i].width_ -= shrink;
151 if (skyline_[i].width_ <= 0) {
153 skyline_.erase(skyline_.begin() + i);
165 for (
auto i = 0u; i < skyline_.size() - 1; ++i) {
166 if (skyline_[i].y_ == skyline_[i + 1].y_) {
167 skyline_[i].width_ += skyline_[i + 1].width_;
168 skyline_.erase(skyline_.begin() + i + 1);
176 return std::make_shared<SkylineRectanglePacker>(
width,
height);