// 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/basictypes.h"
#include "base/logging.h"
#include "cc/base/cc_export.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
namespace gfx {
class Vector2d;
}
namespace cc {
class CC_EXPORT TilingData {
public:
TilingData();
TilingData(const gfx::Size& max_texture_size,
const gfx::Rect& tiling_rect,
bool has_border_texels);
TilingData(const gfx::Size& max_texture_size,
const gfx::Rect& tiling_rect,
int border_texels);
gfx::Rect tiling_rect() const { return tiling_rect_; }
void SetTilingRect(const gfx::Rect& tiling_rect);
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 ExpandRectToTileBoundsWithBorders(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:
explicit BaseIterator(const TilingData* tiling_data);
void done() {
index_x_ = -1;
index_y_ = -1;
}
const TilingData* tiling_data_;
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& tiling_rect,
bool include_borders);
Iterator& operator++();
private:
int left_;
int right_;
int bottom_;
};
// Iterate through all indices whose bounds + border intersect with
// |consider| but which also do not intersect with |ignore|.
class CC_EXPORT DifferenceIterator : public BaseIterator {
public:
DifferenceIterator(
const TilingData* tiling_data,
const gfx::Rect& consider_rect,
const gfx::Rect& ignore_rect);
DifferenceIterator& operator++();
private:
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 + 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 BaseIterator {
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 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_;
}
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 consider_left_;
int consider_top_;
int consider_right_;
int consider_bottom_;
int ignore_left_;
int ignore_top_;
int ignore_right_;
int ignore_bottom_;
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_;
};
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::Rect tiling_rect_;
int border_texels_;
// These are computed values.
int num_tiles_x_;
int num_tiles_y_;
};
} // namespace cc
#endif // CC_BASE_TILING_DATA_H_