Home | History | Annotate | Download | only in base
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef CC_BASE_TILING_DATA_H_
      6 #define CC_BASE_TILING_DATA_H_
      7 
      8 #include <utility>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/logging.h"
     12 #include "cc/base/cc_export.h"
     13 #include "ui/gfx/rect.h"
     14 #include "ui/gfx/size.h"
     15 
     16 namespace gfx {
     17 class Vector2d;
     18 }
     19 
     20 namespace cc {
     21 
     22 class CC_EXPORT TilingData {
     23  public:
     24   TilingData();
     25   TilingData(const gfx::Size& max_texture_size,
     26              const gfx::Size& tiling_size,
     27              bool has_border_texels);
     28   TilingData(const gfx::Size& max_texture_size,
     29              const gfx::Size& tiling_size,
     30              int border_texels);
     31 
     32   gfx::Size tiling_size() const { return tiling_size_; }
     33   void SetTilingSize(const gfx::Size& tiling_size);
     34 
     35   gfx::Size max_texture_size() const { return max_texture_size_; }
     36   void SetMaxTextureSize(const gfx::Size& max_texture_size);
     37 
     38   int border_texels() const { return border_texels_; }
     39   void SetHasBorderTexels(bool has_border_texels);
     40   void SetBorderTexels(int border_texels);
     41 
     42   bool has_empty_bounds() const { return !num_tiles_x_ || !num_tiles_y_; }
     43   int num_tiles_x() const { return num_tiles_x_; }
     44   int num_tiles_y() const { return num_tiles_y_; }
     45   // Return the tile index whose non-border texels include src_position.
     46   int TileXIndexFromSrcCoord(int src_position) const;
     47   int TileYIndexFromSrcCoord(int src_position) const;
     48   // Return the lowest tile index whose border texels include src_position.
     49   int FirstBorderTileXIndexFromSrcCoord(int src_position) const;
     50   int FirstBorderTileYIndexFromSrcCoord(int src_position) const;
     51   // Return the highest tile index whose border texels include src_position.
     52   int LastBorderTileXIndexFromSrcCoord(int src_position) const;
     53   int LastBorderTileYIndexFromSrcCoord(int src_position) const;
     54 
     55   gfx::Rect ExpandRectIgnoringBordersToTileBounds(const gfx::Rect& rect) const;
     56   gfx::Rect ExpandRectToTileBounds(const gfx::Rect& rect) const;
     57 
     58   gfx::Rect TileBounds(int i, int j) const;
     59   gfx::Rect TileBoundsWithBorder(int i, int j) const;
     60   int TilePositionX(int x_index) const;
     61   int TilePositionY(int y_index) const;
     62   int TileSizeX(int x_index) const;
     63   int TileSizeY(int y_index) const;
     64 
     65   // Difference between TileBound's and TileBoundWithBorder's origin().
     66   gfx::Vector2d TextureOffset(int x_index, int y_index) const;
     67 
     68   class CC_EXPORT BaseIterator {
     69    public:
     70     operator bool() const { return index_x_ != -1 && index_y_ != -1; }
     71 
     72     int index_x() const { return index_x_; }
     73     int index_y() const { return index_y_; }
     74     std::pair<int, int> index() const {
     75      return std::make_pair(index_x_, index_y_);
     76     }
     77 
     78    protected:
     79     explicit BaseIterator(const TilingData* tiling_data);
     80     void done() {
     81       index_x_ = -1;
     82       index_y_ = -1;
     83     }
     84 
     85     const TilingData* tiling_data_;
     86     int index_x_;
     87     int index_y_;
     88   };
     89 
     90   // Iterate through tiles whose bounds + optional border intersect with |rect|.
     91   class CC_EXPORT Iterator : public BaseIterator {
     92    public:
     93     Iterator();
     94     Iterator(const TilingData* tiling_data,
     95              const gfx::Rect& consider_rect,
     96              bool include_borders);
     97     Iterator& operator++();
     98 
     99    private:
    100     int left_;
    101     int right_;
    102     int bottom_;
    103   };
    104 
    105   // Iterate through all indices whose bounds (not including borders) intersect
    106   // with |consider| but which also do not intersect with |ignore|.
    107   class CC_EXPORT DifferenceIterator : public BaseIterator {
    108    public:
    109     DifferenceIterator(const TilingData* tiling_data,
    110                        const gfx::Rect& consider_rect,
    111                        const gfx::Rect& ignore_rect);
    112     DifferenceIterator& operator++();
    113 
    114    private:
    115     bool in_ignore_rect() const {
    116      return index_x_ >= ignore_left_ && index_x_ <= ignore_right_ &&
    117        index_y_ >= ignore_top_ && index_y_ <= ignore_bottom_;
    118     }
    119 
    120     int consider_left_;
    121     int consider_top_;
    122     int consider_right_;
    123     int consider_bottom_;
    124     int ignore_left_;
    125     int ignore_top_;
    126     int ignore_right_;
    127     int ignore_bottom_;
    128   };
    129 
    130   // Iterate through all indices whose bounds + border intersect with
    131   // |consider| but which also do not intersect with |ignore|. The iterator
    132   // order is a counterclockwise spiral around the given center.
    133   class CC_EXPORT SpiralDifferenceIterator : public BaseIterator {
    134    public:
    135     SpiralDifferenceIterator();
    136     SpiralDifferenceIterator(const TilingData* tiling_data,
    137                              const gfx::Rect& consider_rect,
    138                              const gfx::Rect& ignore_rect,
    139                              const gfx::Rect& center_rect);
    140     SpiralDifferenceIterator& operator++();
    141 
    142    private:
    143     bool in_consider_rect() const {
    144       return index_x_ >= consider_left_ && index_x_ <= consider_right_ &&
    145              index_y_ >= consider_top_ && index_y_ <= consider_bottom_;
    146     }
    147     bool in_ignore_rect() const {
    148       return index_x_ >= ignore_left_ && index_x_ <= ignore_right_ &&
    149              index_y_ >= ignore_top_ && index_y_ <= ignore_bottom_;
    150     }
    151     bool valid_column() const {
    152       return index_x_ >= consider_left_ && index_x_ <= consider_right_;
    153     }
    154     bool valid_row() const {
    155       return index_y_ >= consider_top_ && index_y_ <= consider_bottom_;
    156     }
    157 
    158     int current_step_count() const {
    159       return (direction_ == UP || direction_ == DOWN) ? vertical_step_count_
    160                                                       : horizontal_step_count_;
    161     }
    162 
    163     bool needs_direction_switch() const;
    164     void switch_direction();
    165 
    166     int consider_left_;
    167     int consider_top_;
    168     int consider_right_;
    169     int consider_bottom_;
    170     int ignore_left_;
    171     int ignore_top_;
    172     int ignore_right_;
    173     int ignore_bottom_;
    174 
    175     enum Direction { UP, LEFT, DOWN, RIGHT };
    176 
    177     Direction direction_;
    178     int delta_x_;
    179     int delta_y_;
    180     int current_step_;
    181     int horizontal_step_count_;
    182     int vertical_step_count_;
    183   };
    184 
    185  private:
    186   void AssertTile(int i, int j) const {
    187     DCHECK_GE(i,  0);
    188     DCHECK_LT(i, num_tiles_x_);
    189     DCHECK_GE(j, 0);
    190     DCHECK_LT(j, num_tiles_y_);
    191   }
    192 
    193   void RecomputeNumTiles();
    194 
    195   gfx::Size max_texture_size_;
    196   gfx::Size tiling_size_;
    197   int border_texels_;
    198 
    199   // These are computed values.
    200   int num_tiles_x_;
    201   int num_tiles_y_;
    202 };
    203 
    204 }  // namespace cc
    205 
    206 #endif  // CC_BASE_TILING_DATA_H_
    207