1<!DOCTYPE html>
2<!--
3Copyright (c) 2014 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7<link rel="import" href="/tracing/base/base.html">
8<link rel="import" href="/tracing/base/math.html">
9<link rel="import" href="/tracing/base/rect.html">
10
11<script>
12'use strict';
13
14/**
15 * @fileoverview 2D bounding box computations.
16 */
17tr.exportTo('tr.b', function() {
18
19  /**
20   * Tracks a 2D bounding box.
21   * @constructor
22   */
23  function BBox2() {
24    this.isEmpty_ = true;
25    this.min_ = undefined;
26    this.max_ = undefined;
27  };
28
29  BBox2.prototype = {
30    __proto__: Object.prototype,
31
32    reset: function() {
33      this.isEmpty_ = true;
34      this.min_ = undefined;
35      this.max_ = undefined;
36    },
37
38    get isEmpty() {
39      return this.isEmpty_;
40    },
41
42    addBBox2: function(bbox2) {
43      if (bbox2.isEmpty)
44        return;
45      this.addVec2(bbox2.min_);
46      this.addVec2(bbox2.max_);
47    },
48
49    clone: function() {
50      var bbox = new BBox2();
51      bbox.addBBox2(this);
52      return bbox;
53    },
54
55    /**
56     * Adds x, y to the range.
57     */
58    addXY: function(x, y) {
59      if (this.isEmpty_) {
60        this.max_ = vec2.create();
61        this.min_ = vec2.create();
62        vec2.set(this.max_, x, y);
63        vec2.set(this.min_, x, y);
64        this.isEmpty_ = false;
65        return;
66      }
67      this.max_[0] = Math.max(this.max_[0], x);
68      this.max_[1] = Math.max(this.max_[1], y);
69      this.min_[0] = Math.min(this.min_[0], x);
70      this.min_[1] = Math.min(this.min_[1], y);
71    },
72
73    /**
74     * Adds value_x, value_y in the form [value_x,value_y] to the range.
75     */
76    addVec2: function(value) {
77      if (this.isEmpty_) {
78        this.max_ = vec2.create();
79        this.min_ = vec2.create();
80        vec2.set(this.max_, value[0], value[1]);
81        vec2.set(this.min_, value[0], value[1]);
82        this.isEmpty_ = false;
83        return;
84      }
85      this.max_[0] = Math.max(this.max_[0], value[0]);
86      this.max_[1] = Math.max(this.max_[1], value[1]);
87      this.min_[0] = Math.min(this.min_[0], value[0]);
88      this.min_[1] = Math.min(this.min_[1], value[1]);
89    },
90
91    addQuad: function(quad) {
92      this.addVec2(quad.p1);
93      this.addVec2(quad.p2);
94      this.addVec2(quad.p3);
95      this.addVec2(quad.p4);
96    },
97
98    get minVec2() {
99      if (this.isEmpty_)
100        return undefined;
101      return this.min_;
102    },
103
104    get maxVec2() {
105      if (this.isEmpty_)
106        return undefined;
107      return this.max_;
108    },
109
110    get sizeAsVec2() {
111      if (this.isEmpty_)
112        throw new Error('Empty BBox2 has no size');
113      var size = vec2.create();
114      vec2.subtract(size, this.max_, this.min_);
115      return size;
116    },
117
118    get size() {
119      if (this.isEmpty_)
120        throw new Error('Empty BBox2 has no size');
121      return {width: this.max_[0] - this.min_[0],
122        height: this.max_[1] - this.min_[1]};
123    },
124
125    get width() {
126      if (this.isEmpty_)
127        throw new Error('Empty BBox2 has no width');
128      return this.max_[0] - this.min_[0];
129    },
130
131    get height() {
132      if (this.isEmpty_)
133        throw new Error('Empty BBox2 has no width');
134      return this.max_[1] - this.min_[1];
135    },
136
137    toString: function() {
138      if (this.isEmpty_)
139        return 'empty';
140      return 'min=(' + this.min_[0] + ',' + this.min_[1] + ') ' +
141          'max=(' + this.max_[0] + ',' + this.max_[1] + ')';
142    },
143
144    asRect: function() {
145      return tr.b.Rect.fromXYWH(
146          this.min_[0],
147          this.min_[1],
148          this.max_[0] - this.min_[0],
149          this.max_[1] - this.min_[1]);
150    }
151  };
152
153  return {
154    BBox2: BBox2
155  };
156
157});
158</script>
159