1 // Copyright 2014 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 <algorithm>
6
7 #include "base/macros.h"
8 #include "base/strings/stringprintf.h"
9 #include "ui/gfx/geometry/point_conversions.h"
10 #include "ui/gfx/geometry/rect.h"
11 #include "ui/gfx/geometry/rect_f.h"
12 #include "ui/gfx/selection_bound.h"
13
14 namespace gfx {
15
SelectionBound()16 SelectionBound::SelectionBound() : type_(EMPTY), visible_(false) {}
17
18 SelectionBound::SelectionBound(const SelectionBound& other) = default;
19
~SelectionBound()20 SelectionBound::~SelectionBound() {}
21
SetEdgeStart(const gfx::PointF & value)22 void SelectionBound::SetEdgeStart(const gfx::PointF& value) {
23 edge_start_ = value;
24 edge_start_rounded_ = gfx::ToRoundedPoint(value);
25 }
26
SetVisibleEdgeStart(const gfx::PointF & value)27 void SelectionBound::SetVisibleEdgeStart(const gfx::PointF& value) {
28 visible_edge_start_ = value;
29 }
30
SetEdgeEnd(const gfx::PointF & value)31 void SelectionBound::SetEdgeEnd(const gfx::PointF& value) {
32 edge_end_ = value;
33 edge_end_rounded_ = gfx::ToRoundedPoint(value);
34 }
35
SetVisibleEdgeEnd(const gfx::PointF & value)36 void SelectionBound::SetVisibleEdgeEnd(const gfx::PointF& value) {
37 visible_edge_end_ = value;
38 }
39
SetEdge(const gfx::PointF & start,const gfx::PointF & end)40 void SelectionBound::SetEdge(const gfx::PointF& start, const gfx::PointF& end) {
41 SetEdgeStart(start);
42 SetEdgeEnd(end);
43 }
44
SetVisibleEdge(const gfx::PointF & start,const gfx::PointF & end)45 void SelectionBound::SetVisibleEdge(const gfx::PointF& start,
46 const gfx::PointF& end) {
47 SetVisibleEdgeStart(start);
48 SetVisibleEdgeEnd(end);
49 }
50
GetHeight() const51 int SelectionBound::GetHeight() const {
52 return edge_end_rounded_.y() - edge_start_rounded_.y();
53 }
54
ToString() const55 std::string SelectionBound::ToString() const {
56 return base::StringPrintf(
57 "SelectionBound(%s, %s, %s, %s, %d)", edge_start_.ToString().c_str(),
58 edge_end_.ToString().c_str(), edge_start_rounded_.ToString().c_str(),
59 edge_end_rounded_.ToString().c_str(), visible_);
60 }
61
operator ==(const SelectionBound & lhs,const SelectionBound & rhs)62 bool operator==(const SelectionBound& lhs, const SelectionBound& rhs) {
63 return lhs.type() == rhs.type() && lhs.visible() == rhs.visible() &&
64 lhs.edge_start() == rhs.edge_start() &&
65 lhs.edge_end() == rhs.edge_end() &&
66 lhs.visible_edge_start() == rhs.visible_edge_start() &&
67 lhs.visible_edge_end() == rhs.visible_edge_end();
68 }
69
operator !=(const SelectionBound & lhs,const SelectionBound & rhs)70 bool operator!=(const SelectionBound& lhs, const SelectionBound& rhs) {
71 return !(lhs == rhs);
72 }
73
RectBetweenSelectionBounds(const SelectionBound & b1,const SelectionBound & b2)74 gfx::Rect RectBetweenSelectionBounds(const SelectionBound& b1,
75 const SelectionBound& b2) {
76 gfx::Point top_left(b1.edge_start_rounded());
77 top_left.SetToMin(b1.edge_end_rounded());
78 top_left.SetToMin(b2.edge_start_rounded());
79 top_left.SetToMin(b2.edge_end_rounded());
80
81 gfx::Point bottom_right(b1.edge_start_rounded());
82 bottom_right.SetToMax(b1.edge_end_rounded());
83 bottom_right.SetToMax(b2.edge_start_rounded());
84 bottom_right.SetToMax(b2.edge_end_rounded());
85
86 gfx::Vector2d diff = bottom_right - top_left;
87 return gfx::Rect(top_left, gfx::Size(diff.x(), diff.y()));
88 }
89
RectFBetweenSelectionBounds(const SelectionBound & b1,const SelectionBound & b2)90 gfx::RectF RectFBetweenSelectionBounds(const SelectionBound& b1,
91 const SelectionBound& b2) {
92 gfx::PointF top_left(b1.edge_start());
93 top_left.SetToMin(b1.edge_end());
94 top_left.SetToMin(b2.edge_start());
95 top_left.SetToMin(b2.edge_end());
96
97 gfx::PointF bottom_right(b1.edge_start());
98 bottom_right.SetToMax(b1.edge_end());
99 bottom_right.SetToMax(b2.edge_start());
100 bottom_right.SetToMax(b2.edge_end());
101
102 gfx::Vector2dF diff = bottom_right - top_left;
103 return gfx::RectF(top_left, gfx::SizeF(diff.x(), diff.y()));
104 }
105
RectFBetweenVisibleSelectionBounds(const SelectionBound & b1,const SelectionBound & b2)106 gfx::RectF RectFBetweenVisibleSelectionBounds(const SelectionBound& b1,
107 const SelectionBound& b2) {
108 // The selection bound is determined by the |start| and |end| points. For the
109 // writing-mode is vertical-*, the bounds are horizontal, the |end| might
110 // be on the left side of the |start|.
111 gfx::PointF top_left(b1.visible_edge_start());
112 top_left.SetToMin(b1.visible_edge_end());
113 top_left.SetToMin(b2.visible_edge_start());
114 top_left.SetToMin(b2.visible_edge_end());
115
116 gfx::PointF bottom_right(b1.visible_edge_start());
117 bottom_right.SetToMax(b1.visible_edge_end());
118 bottom_right.SetToMax(b2.visible_edge_start());
119 bottom_right.SetToMax(b2.visible_edge_end());
120
121 gfx::Vector2dF diff = bottom_right - top_left;
122 return gfx::RectF(top_left, gfx::SizeF(diff.x(), diff.y()));
123 }
124
125 } // namespace gfx
126