| 116 | } |
| 117 | |
| 118 | float BoxSplitter::canBreak(stack<Position>& s, const sptr<HorizontalBox>& hbox, const float width) { |
| 119 | const vector<sptr<Box>>& children = hbox->_children; |
| 120 | const int count = children.size(); |
| 121 | // Cumulative width |
| 122 | float* cumWidth = new float[count + 1](); |
| 123 | cumWidth[0] = 0; |
| 124 | for (int i = 0; i < count; i++) { |
| 125 | auto box = children[i]; |
| 126 | cumWidth[i + 1] = cumWidth[i] + box->_width; |
| 127 | if (cumWidth[i + 1] <= width) continue; |
| 128 | int pos = getBreakPosition(hbox, i); |
| 129 | auto h = dynamic_pointer_cast<HorizontalBox>(box); |
| 130 | if (h != nullptr) { |
| 131 | stack<Position> sub; |
| 132 | float w = canBreak(sub, h, width - cumWidth[i]); |
| 133 | if (w != box->_width && (cumWidth[i] + w <= width || pos == -1)) { |
| 134 | s.push(Position(i - 1, hbox)); |
| 135 | // add to stack |
| 136 | vector<Position> p; |
| 137 | while (!sub.empty()) { |
| 138 | p.push_back(sub.top()); |
| 139 | sub.pop(); |
| 140 | } |
| 141 | for (auto it = p.rbegin(); it != p.rend(); it++) s.push(*it); |
| 142 | // release cum-width |
| 143 | float x = cumWidth[i] + w; |
| 144 | delete[] cumWidth; |
| 145 | return x; |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | if (pos != -1) { |
| 150 | s.push(Position(pos, hbox)); |
| 151 | float x = cumWidth[pos]; |
| 152 | delete[] cumWidth; |
| 153 | return x; |
| 154 | } |
| 155 | } |
| 156 | |
| 157 | delete[] cumWidth; |
| 158 | return hbox->_width; |
| 159 | } |
| 160 | |
| 161 | int BoxSplitter::getBreakPosition(const sptr<HorizontalBox>& hb, int i) { |
| 162 | if (hb->_breakPositions.empty()) return -1; |