1// SuperTux
2// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17#include "math/anchor_point.hpp"
18
19#include <config.h>
20
21#include <stdexcept>
22#include <sstream>
23
24#include "math/rectf.hpp"
25#include "util/log.hpp"
26
27std::string anchor_point_to_string(AnchorPoint point)
28{
29 switch (point) {
30 case ANCHOR_TOP_LEFT:
31 return "topleft";
32 case ANCHOR_TOP:
33 return "top";
34 case ANCHOR_TOP_RIGHT:
35 return "topright";
36 case ANCHOR_LEFT:
37 return "left";
38 case ANCHOR_MIDDLE:
39 return "middle";
40 case ANCHOR_RIGHT:
41 return "right";
42 case ANCHOR_BOTTOM_LEFT:
43 return "bottomleft";
44 case ANCHOR_BOTTOM:
45 return "bottom";
46 case ANCHOR_BOTTOM_RIGHT:
47 return "bottomright";
48 default:
49 throw std::runtime_error("Invalid anchor point");
50 }
51}
52
53AnchorPoint string_to_anchor_point(const std::string& str)
54{
55 if (str == "topleft")
56 return ANCHOR_TOP_LEFT;
57 else if (str == "top")
58 return ANCHOR_TOP;
59 else if (str == "topright")
60 return ANCHOR_TOP_RIGHT;
61 else if (str == "left")
62 return ANCHOR_LEFT;
63 else if (str == "middle")
64 return ANCHOR_MIDDLE;
65 else if (str == "right")
66 return ANCHOR_RIGHT;
67 else if (str == "bottomleft")
68 return ANCHOR_BOTTOM_LEFT;
69 else if (str == "bottom")
70 return ANCHOR_BOTTOM;
71 else if (str == "bottomright")
72 return ANCHOR_BOTTOM_RIGHT;
73
74 std::ostringstream msg;
75 msg << "Unknown anchor '" << str << "'";
76 throw std::runtime_error(msg.str());
77}
78
79Vector get_anchor_pos(const Rectf& rect, AnchorPoint point)
80{
81 Vector result;
82
83 switch (point & ANCHOR_V_MASK) {
84 case ANCHOR_LEFT:
85 result.x = rect.get_left();
86 break;
87 case ANCHOR_MIDDLE:
88 result.x = rect.get_left() + (rect.get_right() - rect.get_left()) / 2.0f;
89 break;
90 case ANCHOR_RIGHT:
91 result.x = rect.get_right();
92 break;
93 default:
94 log_warning << "Invalid anchor point found" << std::endl;
95 result.x = rect.get_left();
96 break;
97 }
98
99 switch (point & ANCHOR_H_MASK) {
100 case ANCHOR_TOP:
101 result.y = rect.get_top();
102 break;
103 case ANCHOR_MIDDLE:
104 result.y = rect.get_top() + (rect.get_bottom() - rect.get_top()) / 2.0f;
105 break;
106 case ANCHOR_BOTTOM:
107 result.y = rect.get_bottom();
108 break;
109 default:
110 log_warning << "Invalid anchor point found" << std::endl;
111 result.y = rect.get_top();
112 break;
113 }
114
115 return result;
116}
117
118Vector get_anchor_pos(const Rectf& destrect, float width, float height,
119 AnchorPoint point)
120{
121 Vector result;
122
123 switch (point & ANCHOR_V_MASK) {
124 case ANCHOR_LEFT:
125 result.x = destrect.get_left();
126 break;
127 case ANCHOR_MIDDLE:
128 result.x = destrect.get_middle().x - width / 2.0f;
129 break;
130 case ANCHOR_RIGHT:
131 result.x = destrect.get_right() - width;
132 break;
133 default:
134 log_warning << "Invalid anchor point found" << std::endl;
135 result.x = destrect.get_left();
136 break;
137 }
138
139 switch (point & ANCHOR_H_MASK) {
140 case ANCHOR_TOP:
141 result.y = destrect.get_top();
142 break;
143 case ANCHOR_MIDDLE:
144 result.y = destrect.get_middle().y - height / 2.0f;
145 break;
146 case ANCHOR_BOTTOM:
147 result.y = destrect.get_bottom() - height;
148 break;
149 default:
150 log_warning << "Invalid anchor point found" << std::endl;
151 result.y = destrect.get_top();
152 break;
153 }
154
155 return result;
156}
157
158/* EOF */
159