Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2010 The Chromium Authors. All rights reserved. | 1 // Copyright 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/base/tiling_data.h" | 5 #include "cc/base/tiling_data.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "ui/gfx/rect.h" | 9 #include "ui/gfx/rect.h" |
| 10 #include "ui/gfx/vector2d.h" | 10 #include "ui/gfx/vector2d.h" |
| (...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 658 | 658 |
| 659 current_step_ = 0; | 659 current_step_ = 0; |
| 660 direction_ = static_cast<Direction>((direction_ + 1) % 4); | 660 direction_ = static_cast<Direction>((direction_ + 1) % 4); |
| 661 | 661 |
| 662 if (direction_ == RIGHT || direction_ == LEFT) { | 662 if (direction_ == RIGHT || direction_ == LEFT) { |
| 663 ++vertical_step_count_; | 663 ++vertical_step_count_; |
| 664 ++horizontal_step_count_; | 664 ++horizontal_step_count_; |
| 665 } | 665 } |
| 666 } | 666 } |
| 667 | 667 |
| 668 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() | |
| 669 : BaseIterator(nullptr) { | |
| 670 done(); | |
| 671 } | |
| 672 | |
| 673 TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator( | |
| 674 const TilingData* tiling_data, | |
| 675 const gfx::Rect& consider_rect, | |
| 676 const gfx::Rect& ignore_rect, | |
| 677 const gfx::Rect& center_rect) | |
| 678 : BaseIterator(tiling_data), | |
| 679 consider_left_(-1), | |
| 680 consider_top_(-1), | |
| 681 consider_right_(-1), | |
| 682 consider_bottom_(-1), | |
| 683 around_left_(-1), | |
| 684 around_top_(-1), | |
| 685 around_right_(-1), | |
| 686 around_bottom_(-1), | |
| 687 ignore_left_(-1), | |
| 688 ignore_top_(-1), | |
| 689 ignore_right_(-1), | |
| 690 ignore_bottom_(-1), | |
| 691 direction_(LEFT), | |
| 692 delta_x_(-1), | |
| 693 delta_y_(0), | |
| 694 current_step_(0), | |
| 695 horizontal_step_count_(0), | |
| 696 vertical_step_count_(0) { | |
| 697 if (tiling_data_->num_tiles_x() <= 0 || tiling_data_->num_tiles_y() <= 0) { | |
| 698 done(); | |
| 699 return; | |
| 700 } | |
| 701 | |
| 702 gfx::Rect tiling_bounds_rect(tiling_data_->tiling_size()); | |
| 703 gfx::Rect consider(consider_rect); | |
| 704 gfx::Rect ignore(ignore_rect); | |
| 705 gfx::Rect center(center_rect); | |
| 706 consider.Intersect(tiling_bounds_rect); | |
| 707 ignore.Intersect(tiling_bounds_rect); | |
| 708 if (consider.IsEmpty()) { | |
| 709 done(); | |
| 710 return; | |
| 711 } | |
| 712 | |
| 713 consider_left_ = tiling_data_->TileXIndexFromSrcCoord(consider.x()); | |
| 714 consider_top_ = tiling_data_->TileYIndexFromSrcCoord(consider.y()); | |
| 715 consider_right_ = tiling_data_->TileXIndexFromSrcCoord(consider.right() - 1); | |
| 716 consider_bottom_ = | |
| 717 tiling_data_->TileYIndexFromSrcCoord(consider.bottom() - 1); | |
| 718 | |
| 719 if (!ignore.IsEmpty()) { | |
| 720 ignore_left_ = tiling_data_->TileXIndexFromSrcCoord(ignore.x()); | |
| 721 ignore_top_ = tiling_data_->TileYIndexFromSrcCoord(ignore.y()); | |
| 722 ignore_right_ = tiling_data_->TileXIndexFromSrcCoord(ignore.right() - 1); | |
| 723 ignore_bottom_ = tiling_data_->TileYIndexFromSrcCoord(ignore.bottom() - 1); | |
| 724 | |
| 725 // Clamp ignore indices to consider indices. | |
| 726 ignore_left_ = std::max(ignore_left_, consider_left_); | |
| 727 ignore_top_ = std::max(ignore_top_, consider_top_); | |
| 728 ignore_right_ = std::min(ignore_right_, consider_right_); | |
| 729 ignore_bottom_ = std::min(ignore_bottom_, consider_bottom_); | |
| 730 } | |
| 731 | |
| 732 if (ignore_left_ == consider_left_ && ignore_right_ == consider_right_ && | |
| 733 ignore_top_ == consider_top_ && ignore_bottom_ == consider_bottom_) { | |
| 734 done(); | |
| 735 return; | |
| 736 } | |
| 737 | |
| 738 // Determine around left, such that it is between -1 and num_tiles_x. | |
| 739 if (center.x() < 0 || center.IsEmpty()) | |
| 740 around_left_ = -1; | |
| 741 else if (center.x() > tiling_data->tiling_size().width()) | |
|
danakj
2014/10/11 01:35:24
u mean >= width()?
vmpstr
2014/10/11 02:17:44
I think I do?
| |
| 742 around_left_ = tiling_data->num_tiles_x(); | |
| 743 else | |
| 744 around_left_ = tiling_data->TileXIndexFromSrcCoord(center.x()); | |
| 745 | |
| 746 // Determine around top, such that it is between -1 and num_tiles_y. | |
| 747 if (center.y() < 0 || center.IsEmpty()) | |
| 748 around_top_ = -1; | |
| 749 else if (center.y() > tiling_data->tiling_size().height()) | |
|
danakj
2014/10/11 01:35:24
you mean >= height()?
vmpstr
2014/10/11 02:17:44
Done.
| |
| 750 around_top_ = tiling_data->num_tiles_y(); | |
| 751 else | |
| 752 around_top_ = tiling_data->TileYIndexFromSrcCoord(center.y()); | |
| 753 | |
| 754 // Determine around right, such that it is between -1 and num_tiles_x. | |
| 755 int right_src_coord = center.right() - 1; | |
| 756 if (right_src_coord < 0 || center.IsEmpty()) { | |
| 757 around_right_ = -1; | |
| 758 } else if (right_src_coord > tiling_data->tiling_size().width()) { | |
|
danakj
2014/10/11 01:35:24
you mean >= width()?
vmpstr
2014/10/11 02:17:44
Done.
| |
| 759 around_right_ = tiling_data->num_tiles_x(); | |
| 760 } else { | |
| 761 around_right_ = tiling_data->TileXIndexFromSrcCoord(right_src_coord); | |
| 762 } | |
| 763 | |
| 764 // Determine around bottom, such that it is between -1 and num_tiles_y. | |
| 765 int bottom_src_coord = center.bottom() - 1; | |
| 766 if (bottom_src_coord < 0 || center.IsEmpty()) { | |
| 767 around_bottom_ = -1; | |
| 768 } else if (bottom_src_coord > tiling_data->tiling_size().height()) { | |
|
danakj
2014/10/11 01:35:24
and >= height()?
vmpstr
2014/10/11 02:17:44
Done.
| |
| 769 around_bottom_ = tiling_data->num_tiles_y(); | |
| 770 } else { | |
| 771 around_bottom_ = tiling_data->TileYIndexFromSrcCoord(bottom_src_coord); | |
| 772 } | |
| 773 | |
| 774 // Figure out the maximum distance from the around edge to consider edge. | |
| 775 int max_distance = 0; | |
|
danakj
2014/10/11 01:35:24
what if max_distance comes out negative?
vmpstr
2014/10/11 02:17:44
That can only be if |consider| is contained in |ar
| |
| 776 max_distance = std::max(max_distance, around_top_ - consider_top_); | |
| 777 max_distance = std::max(max_distance, around_left_ - consider_left_); | |
| 778 max_distance = std::max(max_distance, consider_bottom_ - around_bottom_); | |
| 779 max_distance = std::max(max_distance, consider_right_ - around_right_); | |
| 780 | |
| 781 // The step count is the length of the edge (around_right_ - around_left_ + 1) | |
| 782 // plus twice the max distance to pad (to the right and to the left). This way | |
| 783 // the initial rect is the size proportional to the center, but big enough | |
| 784 // to cover the consider rect. | |
| 785 // | |
| 786 // C = consider rect | |
| 787 // A = around rect | |
| 788 // . = area of the padded around rect | |
| 789 // md = max distance | |
| 790 // I = initial starting position | |
| 791 // | |
| 792 // |md| |md| | |
| 793 // -.......... | |
| 794 // m.......... | |
| 795 // d.......... | |
| 796 // -CCCCCCC... | |
| 797 // CCCCAAC... | |
| 798 // CCCCAAC... | |
| 799 // -.......... | |
| 800 // m.......... | |
| 801 // d.......... | |
| 802 // -..........I | |
| 803 vertical_step_count_ = around_bottom_ - around_top_ + 1 + 2 * max_distance; | |
| 804 horizontal_step_count_ = around_right_ - around_left_ + 1 + 2 * max_distance; | |
| 805 | |
| 806 // Start with one to the right of the padded around rect. | |
| 807 index_x_ = around_right_ + max_distance + 1; | |
| 808 index_y_ = around_bottom_ + max_distance; | |
| 809 | |
| 810 // The current index is outside a valid tile, so advance immediately. | |
| 811 ++(*this); | |
| 812 } | |
| 813 | |
| 814 TilingData::ReverseSpiralDifferenceIterator& | |
| 815 TilingData::ReverseSpiralDifferenceIterator:: | |
| 816 operator++() { | |
| 817 while (!in_around_rect()) { | |
|
danakj
2014/10/11 01:35:24
you could avoid nesting by recursing instead. it'd
vmpstr
2014/10/11 02:17:44
Ehh.. I'm kind of weary of recursion in this funct
| |
| 818 if (needs_direction_switch()) | |
| 819 switch_direction(); | |
| 820 | |
| 821 index_x_ += delta_x_; | |
| 822 index_y_ += delta_y_; | |
| 823 ++current_step_; | |
| 824 | |
| 825 if (in_around_rect()) { | |
| 826 break; | |
| 827 } else if (in_consider_rect()) { | |
| 828 // If the tile is in the consider rect but not in ignore rect, then it's a | |
| 829 // valid tile to visit. | |
| 830 if (!in_ignore_rect()) | |
| 831 break; | |
| 832 | |
| 833 // Steps needed to reach the very edge of the ignore rect, while remaining | |
| 834 // inside it (so that the continue would take us outside). | |
| 835 int steps_to_edge = 0; | |
| 836 switch (direction_) { | |
| 837 case UP: | |
| 838 steps_to_edge = index_y_ - ignore_top_; | |
| 839 break; | |
| 840 case LEFT: | |
| 841 steps_to_edge = index_x_ - ignore_left_; | |
| 842 break; | |
| 843 case DOWN: | |
| 844 steps_to_edge = ignore_bottom_ - index_y_; | |
| 845 break; | |
| 846 case RIGHT: | |
| 847 steps_to_edge = ignore_right_ - index_x_; | |
| 848 break; | |
| 849 } | |
| 850 | |
| 851 // We need to switch directions in |max_steps|. | |
| 852 int max_steps = current_step_count() - current_step_; | |
| 853 | |
| 854 int steps_to_take = std::min(steps_to_edge, max_steps); | |
| 855 DCHECK_GE(steps_to_take, 0); | |
| 856 | |
| 857 index_x_ += steps_to_take * delta_x_; | |
| 858 index_y_ += steps_to_take * delta_y_; | |
| 859 current_step_ += steps_to_take; | |
| 860 } else { | |
| 861 // We're not in the consider rect. | |
| 862 | |
| 863 int max_steps = current_step_count() - current_step_; | |
| 864 int steps_to_take = max_steps; | |
| 865 | |
| 866 // We might hit the consider rect before needing to switch directions: | |
| 867 // update steps to take. | |
| 868 switch (direction_) { | |
| 869 case UP: | |
| 870 if (valid_column() && consider_bottom_ < index_y_) | |
| 871 steps_to_take = index_y_ - consider_bottom_ - 1; | |
| 872 break; | |
| 873 case LEFT: | |
| 874 if (valid_row() && consider_right_ < index_x_) | |
| 875 steps_to_take = index_x_ - consider_right_ - 1; | |
| 876 break; | |
| 877 case DOWN: | |
| 878 if (valid_column() && consider_top_ > index_y_) | |
| 879 steps_to_take = consider_top_ - index_y_ - 1; | |
| 880 break; | |
| 881 case RIGHT: | |
| 882 if (valid_row() && consider_left_ > index_x_) | |
| 883 steps_to_take = consider_left_ - index_x_ - 1; | |
| 884 break; | |
| 885 } | |
| 886 steps_to_take = std::min(steps_to_take, max_steps); | |
| 887 DCHECK_GE(steps_to_take, 0); | |
| 888 | |
| 889 index_x_ += steps_to_take * delta_x_; | |
| 890 index_y_ += steps_to_take * delta_y_; | |
| 891 current_step_ += steps_to_take; | |
| 892 } | |
| 893 } | |
| 894 | |
| 895 // Once we enter the around rect, we're done. | |
| 896 if (in_around_rect()) | |
| 897 done(); | |
| 898 return *this; | |
| 899 } | |
| 900 | |
| 901 bool TilingData::ReverseSpiralDifferenceIterator::needs_direction_switch() | |
| 902 const { | |
| 903 return current_step_ >= current_step_count(); | |
| 904 } | |
| 905 | |
| 906 void TilingData::ReverseSpiralDifferenceIterator::switch_direction() { | |
| 907 int new_delta_y_ = delta_x_; | |
| 908 delta_x_ = -delta_y_; | |
| 909 delta_y_ = new_delta_y_; | |
| 910 | |
| 911 current_step_ = 0; | |
| 912 direction_ = static_cast<Direction>((direction_ + 1) % 4); | |
| 913 | |
| 914 if (direction_ == UP || direction_ == DOWN) { | |
| 915 --vertical_step_count_; | |
| 916 --horizontal_step_count_; | |
| 917 | |
| 918 // We should always end up in an around rect at some point. | |
| 919 // Since the direction is now vertical, we have to ensure that we will | |
| 920 // advance. | |
| 921 DCHECK_GE(horizontal_step_count_, 1); | |
| 922 DCHECK_GE(vertical_step_count_, 1); | |
| 923 } | |
| 924 } | |
| 925 | |
| 668 } // namespace cc | 926 } // namespace cc |
| OLD | NEW |