1// Copyright (c) 2012 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#include "cc/base/region.h"
6
7#include "base/debug/trace_event_argument.h"
8#include "base/values.h"
9#include "cc/base/simple_enclosed_region.h"
10
11namespace cc {
12
13Region::Region() {
14}
15
16Region::Region(const Region& region)
17    : skregion_(region.skregion_) {
18}
19
20Region::Region(const gfx::Rect& rect)
21    : skregion_(gfx::RectToSkIRect(rect)) {
22}
23
24Region::~Region() {
25}
26
27const Region& Region::operator=(const gfx::Rect& rect) {
28  skregion_ = SkRegion(gfx::RectToSkIRect(rect));
29  return *this;
30}
31
32const Region& Region::operator=(const Region& region) {
33  skregion_ = region.skregion_;
34  return *this;
35}
36
37void Region::Swap(Region* region) {
38  region->skregion_.swap(skregion_);
39}
40
41void Region::Clear() {
42  skregion_.setEmpty();
43}
44
45bool Region::IsEmpty() const {
46  return skregion_.isEmpty();
47}
48
49int Region::GetRegionComplexity() const {
50  return skregion_.computeRegionComplexity();
51}
52
53bool Region::Contains(const gfx::Point& point) const {
54  return skregion_.contains(point.x(), point.y());
55}
56
57bool Region::Contains(const gfx::Rect& rect) const {
58  if (rect.IsEmpty())
59    return true;
60  return skregion_.contains(gfx::RectToSkIRect(rect));
61}
62
63bool Region::Contains(const Region& region) const {
64  if (region.IsEmpty())
65    return true;
66  return skregion_.contains(region.skregion_);
67}
68
69bool Region::Intersects(const gfx::Rect& rect) const {
70  return skregion_.intersects(gfx::RectToSkIRect(rect));
71}
72
73bool Region::Intersects(const Region& region) const {
74  return skregion_.intersects(region.skregion_);
75}
76
77void Region::Subtract(const gfx::Rect& rect) {
78  skregion_.op(gfx::RectToSkIRect(rect), SkRegion::kDifference_Op);
79}
80
81void Region::Subtract(const Region& region) {
82  skregion_.op(region.skregion_, SkRegion::kDifference_Op);
83}
84
85void Region::Subtract(const SimpleEnclosedRegion& region) {
86  for (size_t i = 0; i < region.GetRegionComplexity(); ++i) {
87    skregion_.op(gfx::RectToSkIRect(region.GetRect(i)),
88                 SkRegion::kDifference_Op);
89  }
90}
91
92void Region::Union(const gfx::Rect& rect) {
93  skregion_.op(gfx::RectToSkIRect(rect), SkRegion::kUnion_Op);
94}
95
96void Region::Union(const Region& region) {
97  skregion_.op(region.skregion_, SkRegion::kUnion_Op);
98}
99
100void Region::Intersect(const gfx::Rect& rect) {
101  skregion_.op(gfx::RectToSkIRect(rect), SkRegion::kIntersect_Op);
102}
103
104void Region::Intersect(const Region& region) {
105  skregion_.op(region.skregion_, SkRegion::kIntersect_Op);
106}
107
108std::string Region::ToString() const {
109  if (IsEmpty())
110    return gfx::Rect().ToString();
111
112  std::string result;
113  for (Iterator it(*this); it.has_rect(); it.next()) {
114    if (!result.empty())
115      result += " | ";
116    result += it.rect().ToString();
117  }
118  return result;
119}
120
121scoped_ptr<base::Value> Region::AsValue() const {
122  scoped_ptr<base::ListValue> result(new base::ListValue());
123  for (Iterator it(*this); it.has_rect(); it.next()) {
124    gfx::Rect rect(it.rect());
125    result->AppendInteger(rect.x());
126    result->AppendInteger(rect.y());
127    result->AppendInteger(rect.width());
128    result->AppendInteger(rect.height());
129  }
130  return result.PassAs<base::Value>();
131}
132
133void Region::AsValueInto(base::debug::TracedValue* result) const {
134  for (Iterator it(*this); it.has_rect(); it.next()) {
135    gfx::Rect rect(it.rect());
136    result->AppendInteger(rect.x());
137    result->AppendInteger(rect.y());
138    result->AppendInteger(rect.width());
139    result->AppendInteger(rect.height());
140  }
141}
142
143Region::Iterator::Iterator() {
144}
145
146Region::Iterator::Iterator(const Region& region)
147    : it_(region.skregion_) {
148}
149
150Region::Iterator::~Iterator() {
151}
152
153}  // namespace cc
154