// 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. #include "cc/tiling_data.h" #include #include "ui/gfx/rect.h" #include "ui/gfx/vector2d.h" namespace cc { static int ComputeNumTiles(int max_texture_size, int total_size, int border_texels) { if (max_texture_size - 2 * border_texels <= 0) return total_size > 0 && max_texture_size >= total_size ? 1 : 0; int num_tiles = std::max(1, 1 + (total_size - 1 - 2 * border_texels) / (max_texture_size - 2 * border_texels)); return total_size > 0 ? num_tiles : 0; } TilingData::TilingData(gfx::Size max_texture_size, gfx::Size total_size, bool hasBorderTexels) : max_texture_size_(max_texture_size), total_size_(total_size), border_texels_(hasBorderTexels ? 1 : 0) { RecomputeNumTiles(); } TilingData::~TilingData() { } void TilingData::SetTotalSize(gfx::Size total_size) { total_size_ = total_size; RecomputeNumTiles(); } void TilingData::SetMaxTextureSize(gfx::Size max_texture_size) { max_texture_size_ = max_texture_size; RecomputeNumTiles(); } void TilingData::SetHasBorderTexels(bool has_border_texels) { border_texels_ = has_border_texels ? 1 : 0; RecomputeNumTiles(); } int TilingData::TileXIndexFromSrcCoord(int src_position) const { if (num_tiles_x_ <= 1) return 0; DCHECK(max_texture_size_.width() - 2 * border_texels_); int x = (src_position - border_texels_) / (max_texture_size_.width() - 2 * border_texels_); return std::min(std::max(x, 0), num_tiles_x_ - 1); } int TilingData::TileYIndexFromSrcCoord(int src_position) const { if (num_tiles_y_ <= 1) return 0; DCHECK(max_texture_size_.height() - 2 * border_texels_); int y = (src_position - border_texels_) / (max_texture_size_.height() - 2 * border_texels_); return std::min(std::max(y, 0), num_tiles_y_ - 1); } gfx::Rect TilingData::TileBounds(int i, int j) const { AssertTile(i, j); int x = TilePositionX(i); int y = TilePositionY(j); int width = TileSizeX(i); int height = TileSizeY(j); DCHECK_GE(x, 0); DCHECK_GE(y, 0); DCHECK_GE(width, 0); DCHECK_GE(height, 0); DCHECK_LE(x, total_size_.width()); DCHECK_LE(y, total_size_.height()); return gfx::Rect(x, y, width, height); } gfx::Rect TilingData::TileBoundsWithBorder(int i, int j) const { gfx::Rect bounds = TileBounds(i, j); if (border_texels_) { int x1 = bounds.x(); int x2 = bounds.right(); int y1 = bounds.y(); int y2 = bounds.bottom(); if (i > 0) x1--; if (i < (num_tiles_x_ - 1)) x2++; if (j > 0) y1--; if (j < (num_tiles_y_ - 1)) y2++; bounds = gfx::Rect(x1, y1, x2 - x1, y2 - y1); } return bounds; } int TilingData::TilePositionX(int x_index) const { DCHECK_GE(x_index, 0); DCHECK_LT(x_index, num_tiles_x_); int pos = 0; for (int i = 0; i < x_index; i++) pos += TileSizeX(i); return pos; } int TilingData::TilePositionY(int y_index) const { DCHECK_GE(y_index, 0); DCHECK_LT(y_index, num_tiles_y_); int pos = 0; for (int i = 0; i < y_index; i++) pos += TileSizeY(i); return pos; } int TilingData::TileSizeX(int x_index) const { DCHECK_GE(x_index, 0); DCHECK_LT(x_index, num_tiles_x_); if (!x_index && num_tiles_x_ == 1) return total_size_.width(); if (!x_index && num_tiles_x_ > 1) return max_texture_size_.width() - border_texels_; if (x_index < num_tiles_x_ - 1) return max_texture_size_.width() - 2 * border_texels_; if (x_index == num_tiles_x_ - 1) return total_size_.width() - TilePositionX(x_index); NOTREACHED(); return 0; } int TilingData::TileSizeY(int y_index) const { DCHECK_GE(y_index, 0); DCHECK_LT(y_index, num_tiles_y_); if (!y_index && num_tiles_y_ == 1) return total_size_.height(); if (!y_index && num_tiles_y_ > 1) return max_texture_size_.height() - border_texels_; if (y_index < num_tiles_y_ - 1) return max_texture_size_.height() - 2 * border_texels_; if (y_index == num_tiles_y_ - 1) return total_size_.height() - TilePositionY(y_index); NOTREACHED(); return 0; } gfx::Vector2d TilingData::TextureOffset(int x_index, int y_index) const { int left = (!x_index || num_tiles_x_ == 1) ? 0 : border_texels_; int top = (!y_index || num_tiles_y_ == 1) ? 0 : border_texels_; return gfx::Vector2d(left, top); } void TilingData::RecomputeNumTiles() { num_tiles_x_ = ComputeNumTiles(max_texture_size_.width(), total_size_.width(), border_texels_); num_tiles_y_ = ComputeNumTiles(max_texture_size_.height(), total_size_.height(), border_texels_); } } // namespace cc