| // Copyright 2010 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CC_BASE_TILING_DATA_H_ |
| #define CC_BASE_TILING_DATA_H_ |
| |
| #include <utility> |
| |
| #include "base/logging.h" |
| #include "cc/base/cc_export.h" |
| #include "ui/gfx/geometry/rect.h" |
| #include "ui/gfx/geometry/size.h" |
| |
| namespace gfx { |
| class Vector2d; |
| } |
| |
| namespace cc { |
| |
| class CC_EXPORT TilingData { |
| public: |
| TilingData(); |
| TilingData(const gfx::Size& max_texture_size, |
| const gfx::Size& tiling_size, |
| bool has_border_texels); |
| TilingData(const gfx::Size& max_texture_size, |
| const gfx::Size& tiling_size, |
| int border_texels); |
| |
| gfx::Size tiling_size() const { return tiling_size_; } |
| void SetTilingSize(const gfx::Size& tiling_size); |
| |
| gfx::Size max_texture_size() const { return max_texture_size_; } |
| void SetMaxTextureSize(const gfx::Size& max_texture_size); |
| |
| int border_texels() const { return border_texels_; } |
| void SetHasBorderTexels(bool has_border_texels); |
| void SetBorderTexels(int border_texels); |
| |
| bool has_empty_bounds() const { return !num_tiles_x_ || !num_tiles_y_; } |
| int num_tiles_x() const { return num_tiles_x_; } |
| int num_tiles_y() const { return num_tiles_y_; } |
| // Return the tile index whose non-border texels include src_position. |
| int TileXIndexFromSrcCoord(int src_position) const; |
| int TileYIndexFromSrcCoord(int src_position) const; |
| // Return the lowest tile index whose border texels include src_position. |
| int FirstBorderTileXIndexFromSrcCoord(int src_position) const; |
| int FirstBorderTileYIndexFromSrcCoord(int src_position) const; |
| // Return the highest tile index whose border texels include src_position. |
| int LastBorderTileXIndexFromSrcCoord(int src_position) const; |
| int LastBorderTileYIndexFromSrcCoord(int src_position) const; |
| |
| gfx::Rect ExpandRectIgnoringBordersToTileBounds(const gfx::Rect& rect) const; |
| gfx::Rect ExpandRectToTileBounds(const gfx::Rect& rect) const; |
| |
| gfx::Rect TileBounds(int i, int j) const; |
| gfx::Rect TileBoundsWithBorder(int i, int j) const; |
| int TilePositionX(int x_index) const; |
| int TilePositionY(int y_index) const; |
| int TileSizeX(int x_index) const; |
| int TileSizeY(int y_index) const; |
| |
| // Difference between TileBound's and TileBoundWithBorder's origin(). |
| gfx::Vector2d TextureOffset(int x_index, int y_index) const; |
| |
| class CC_EXPORT BaseIterator { |
| public: |
| operator bool() const { return index_x_ != -1 && index_y_ != -1; } |
| |
| int index_x() const { return index_x_; } |
| int index_y() const { return index_y_; } |
| std::pair<int, int> index() const { |
| return std::make_pair(index_x_, index_y_); |
| } |
| |
| protected: |
| BaseIterator(); |
| void done() { |
| index_x_ = -1; |
| index_y_ = -1; |
| } |
| |
| int index_x_; |
| int index_y_; |
| }; |
| |
| // Iterate through tiles whose bounds + optional border intersect with |rect|. |
| class CC_EXPORT Iterator : public BaseIterator { |
| public: |
| Iterator(); |
| Iterator(const TilingData* tiling_data, |
| const gfx::Rect& consider_rect, |
| bool include_borders); |
| Iterator& operator++(); |
| |
| private: |
| int left_; |
| int right_; |
| int bottom_; |
| }; |
| |
| class CC_EXPORT BaseDifferenceIterator : public BaseIterator { |
| protected: |
| BaseDifferenceIterator(); |
| BaseDifferenceIterator(const TilingData* tiling_data, |
| const gfx::Rect& consider_rect, |
| const gfx::Rect& ignore_rect); |
| |
| bool HasConsiderRect() const; |
| bool in_consider_rect() const { |
| return index_x_ >= consider_left_ && index_x_ <= consider_right_ && |
| index_y_ >= consider_top_ && index_y_ <= consider_bottom_; |
| } |
| bool in_ignore_rect() const { |
| return index_x_ >= ignore_left_ && index_x_ <= ignore_right_ && |
| index_y_ >= ignore_top_ && index_y_ <= ignore_bottom_; |
| } |
| |
| int consider_left_; |
| int consider_top_; |
| int consider_right_; |
| int consider_bottom_; |
| int ignore_left_; |
| int ignore_top_; |
| int ignore_right_; |
| int ignore_bottom_; |
| }; |
| |
| // Iterate through all indices whose bounds (not including borders) intersect |
| // with |consider| but which also do not intersect with |ignore|. |
| class CC_EXPORT DifferenceIterator : public BaseDifferenceIterator { |
| public: |
| DifferenceIterator(); |
| DifferenceIterator(const TilingData* tiling_data, |
| const gfx::Rect& consider_rect, |
| const gfx::Rect& ignore_rect); |
| DifferenceIterator& operator++(); |
| }; |
| |
| // Iterate through all indices whose bounds + border intersect with |
| // |consider| but which also do not intersect with |ignore|. The iterator |
| // order is a counterclockwise spiral around the given center. |
| class CC_EXPORT SpiralDifferenceIterator : public BaseDifferenceIterator { |
| public: |
| SpiralDifferenceIterator(); |
| SpiralDifferenceIterator(const TilingData* tiling_data, |
| const gfx::Rect& consider_rect, |
| const gfx::Rect& ignore_rect, |
| const gfx::Rect& center_rect); |
| SpiralDifferenceIterator& operator++(); |
| |
| private: |
| bool valid_column() const { |
| return index_x_ >= consider_left_ && index_x_ <= consider_right_; |
| } |
| bool valid_row() const { |
| return index_y_ >= consider_top_ && index_y_ <= consider_bottom_; |
| } |
| |
| int current_step_count() const { |
| return (direction_ == UP || direction_ == DOWN) ? vertical_step_count_ |
| : horizontal_step_count_; |
| } |
| |
| bool needs_direction_switch() const; |
| void switch_direction(); |
| |
| enum Direction { UP, LEFT, DOWN, RIGHT }; |
| |
| Direction direction_; |
| int delta_x_; |
| int delta_y_; |
| int current_step_; |
| int horizontal_step_count_; |
| int vertical_step_count_; |
| }; |
| |
| class CC_EXPORT ReverseSpiralDifferenceIterator |
| : public BaseDifferenceIterator { |
| public: |
| ReverseSpiralDifferenceIterator(); |
| ReverseSpiralDifferenceIterator(const TilingData* tiling_data, |
| const gfx::Rect& consider_rect, |
| const gfx::Rect& ignore_rect, |
| const gfx::Rect& center_rect); |
| ReverseSpiralDifferenceIterator& operator++(); |
| |
| private: |
| bool in_around_rect() const { |
| return index_x_ >= around_left_ && index_x_ <= around_right_ && |
| index_y_ >= around_top_ && index_y_ <= around_bottom_; |
| } |
| bool valid_column() const { |
| return index_x_ >= consider_left_ && index_x_ <= consider_right_; |
| } |
| bool valid_row() const { |
| return index_y_ >= consider_top_ && index_y_ <= consider_bottom_; |
| } |
| |
| int current_step_count() const { |
| return (direction_ == UP || direction_ == DOWN) ? vertical_step_count_ |
| : horizontal_step_count_; |
| } |
| |
| bool needs_direction_switch() const; |
| void switch_direction(); |
| |
| int around_left_; |
| int around_top_; |
| int around_right_; |
| int around_bottom_; |
| |
| enum Direction { LEFT, UP, RIGHT, DOWN }; |
| |
| Direction direction_; |
| int delta_x_; |
| int delta_y_; |
| int current_step_; |
| int horizontal_step_count_; |
| int vertical_step_count_; |
| }; |
| |
| private: |
| void AssertTile(int i, int j) const { |
| DCHECK_GE(i, 0); |
| DCHECK_LT(i, num_tiles_x_); |
| DCHECK_GE(j, 0); |
| DCHECK_LT(j, num_tiles_y_); |
| } |
| |
| void RecomputeNumTiles(); |
| |
| gfx::Size max_texture_size_; |
| gfx::Size tiling_size_; |
| int border_texels_; |
| |
| // These are computed values. |
| int num_tiles_x_; |
| int num_tiles_y_; |
| }; |
| |
| } // namespace cc |
| |
| #endif // CC_BASE_TILING_DATA_H_ |