Split this partition at the given x coordinate, returning the right half and keeping the left half in this.
| 829 | // Split this partition at the given x coordinate, returning the right |
| 830 | // half and keeping the left half in this. |
| 831 | ColPartition* ColPartition::SplitAt(int split_x) { |
| 832 | if (split_x <= bounding_box_.left() || split_x >= bounding_box_.right()) |
| 833 | return NULL; // There will be no change. |
| 834 | ColPartition* split_part = ShallowCopy(); |
| 835 | split_part->set_owns_blobs(owns_blobs()); |
| 836 | BLOBNBOX_C_IT it(&boxes_); |
| 837 | for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) { |
| 838 | BLOBNBOX* bbox = it.data(); |
| 839 | ColPartition* prev_owner = bbox->owner(); |
| 840 | ASSERT_HOST(!owns_blobs() || prev_owner == this || prev_owner == NULL); |
| 841 | const TBOX& box = bbox->bounding_box(); |
| 842 | if (box.left() >= split_x) { |
| 843 | split_part->AddBox(it.extract()); |
| 844 | if (owns_blobs() && prev_owner != NULL) |
| 845 | bbox->set_owner(split_part); |
| 846 | } |
| 847 | } |
| 848 | if (it.empty()) { |
| 849 | // Possible if split-x passes through the first blob. |
| 850 | it.add_list_after(&split_part->boxes_); |
| 851 | } |
| 852 | ASSERT_HOST(!it.empty()); |
| 853 | if (split_part->IsEmpty()) { |
| 854 | // Split part ended up with nothing. Possible if split_x passes |
| 855 | // through the last blob. |
| 856 | delete split_part; |
| 857 | return NULL; |
| 858 | } |
| 859 | right_key_tab_ = false; |
| 860 | split_part->left_key_tab_ = false; |
| 861 | right_margin_ = split_x; |
| 862 | split_part->left_margin_ = split_x; |
| 863 | ComputeLimits(); |
| 864 | split_part->ComputeLimits(); |
| 865 | return split_part; |
| 866 | } |
| 867 | |
| 868 | // Recalculates all the coordinate limits of the partition. |
| 869 | void ColPartition::ComputeLimits() { |
no test coverage detected