Mercurial > hg > orthanc-stone
annotate Framework/Toolbox/ViewportGeometry.cpp @ 45:ecd96e563929 wasm
new wasm branch
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 19 Apr 2017 10:28:08 +0200 |
parents | 7207a407bcd8 |
children | 28956ed68280 |
rev | line source |
---|---|
0 | 1 /** |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
40
7207a407bcd8
shared copyright with osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
5 * Copyright (C) 2017 Osimis, Belgium |
0 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU General Public License as | |
9 * published by the Free Software Foundation, either version 3 of the | |
10 * License, or (at your option) any later version. | |
11 * | |
12 * In addition, as a special exception, the copyright holders of this | |
13 * program give permission to link the code of its release with the | |
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it | |
15 * that use the same license as the "OpenSSL" library), and distribute | |
16 * the linked executables. You must obey the GNU General Public License | |
17 * in all respects for all of the code used other than "OpenSSL". If you | |
18 * modify file(s) with this exception, you may extend this exception to | |
19 * your version of the file(s), but you are not obligated to do so. If | |
20 * you do not wish to do so, delete this exception statement from your | |
21 * version. If you delete this exception statement from all source files | |
22 * in the program, then also delete it here. | |
23 * | |
24 * This program is distributed in the hope that it will be useful, but | |
25 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
27 * General Public License for more details. | |
28 * | |
29 * You should have received a copy of the GNU General Public License | |
30 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
31 **/ | |
32 | |
33 | |
34 #include "ViewportGeometry.h" | |
35 | |
16 | 36 #include "../../Resources/Orthanc/Core/Logging.h" |
37 #include "../../Resources/Orthanc/Core/OrthancException.h" | |
0 | 38 |
39 #include <boost/math/special_functions/round.hpp> | |
40 | |
41 namespace OrthancStone | |
42 { | |
43 void ViewportGeometry::ComputeTransform() | |
44 { | |
45 // The following lines must be read in reverse order! | |
46 cairo_matrix_t tmp; | |
47 | |
48 // Bring the center of the scene to the center of the view | |
49 cairo_matrix_init_translate(&transform_, | |
50 panX_ + static_cast<double>(width_) / 2.0, | |
51 panY_ + static_cast<double>(height_) / 2.0); | |
52 | |
53 // Apply the zoom around (0,0) | |
54 cairo_matrix_init_scale(&tmp, zoom_, zoom_); | |
55 cairo_matrix_multiply(&transform_, &tmp, &transform_); | |
56 | |
57 // Bring the center of the scene to (0,0) | |
58 cairo_matrix_init_translate(&tmp, -(x1_ + x2_) / 2.0, -(y1_ + y2_) / 2.0); | |
59 cairo_matrix_multiply(&transform_, &tmp, &transform_); | |
60 } | |
61 | |
62 | |
63 ViewportGeometry::ViewportGeometry() | |
64 { | |
65 x1_ = 0; | |
66 y1_ = 0; | |
67 x2_ = 0; | |
68 y2_ = 0; | |
69 | |
70 width_ = 0; | |
71 height_ = 0; | |
72 | |
73 zoom_ = 1; | |
74 panX_ = 0; | |
75 panY_ = 0; | |
76 | |
77 ComputeTransform(); | |
78 } | |
79 | |
80 | |
81 void ViewportGeometry::SetDisplaySize(unsigned int width, | |
82 unsigned int height) | |
83 { | |
84 if (width_ != width || | |
85 height_ != height) | |
86 { | |
87 LOG(INFO) << "New display size: " << width << "x" << height; | |
88 | |
89 width_ = width; | |
90 height_ = height; | |
91 | |
92 ComputeTransform(); | |
93 } | |
94 } | |
95 | |
96 | |
97 void ViewportGeometry::SetSceneExtent(double x1, | |
98 double y1, | |
99 double x2, | |
100 double y2) | |
101 { | |
102 if (x1 == x1_ && | |
103 y1 == y1_ && | |
104 x2 == x2_ && | |
105 y2 == y2_) | |
106 { | |
107 return; | |
108 } | |
109 else if (x1 > x2 || | |
110 y1 > y2) | |
111 { | |
112 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
113 } | |
114 else | |
115 { | |
116 LOG(INFO) << "New scene extent: (" << x1 << "," << y1 << ") => (" << x2 << "," << y2 << ")"; | |
117 | |
118 x1_ = x1; | |
119 y1_ = y1; | |
120 x2_ = x2; | |
121 y2_ = y2; | |
122 | |
123 ComputeTransform(); | |
124 } | |
125 } | |
126 | |
127 | |
128 void ViewportGeometry::GetSceneExtent(double& x1, | |
129 double& y1, | |
130 double& x2, | |
131 double& y2) const | |
132 { | |
133 x1 = x1_; | |
134 y1 = y1_; | |
135 x2 = x2_; | |
136 y2 = y2_; | |
137 } | |
138 | |
139 | |
140 void ViewportGeometry::MapDisplayToScene(double& sceneX /* out */, | |
141 double& sceneY /* out */, | |
142 double x, | |
143 double y) const | |
144 { | |
145 cairo_matrix_t transform = transform_; | |
146 | |
147 if (cairo_matrix_invert(&transform) != CAIRO_STATUS_SUCCESS) | |
148 { | |
149 LOG(ERROR) << "Cannot invert singular matrix"; | |
150 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
151 } | |
152 | |
153 sceneX = x; | |
154 sceneY = y; | |
155 cairo_matrix_transform_point(&transform, &sceneX, &sceneY); | |
156 } | |
157 | |
158 | |
159 void ViewportGeometry::MapSceneToDisplay(int& displayX /* out */, | |
160 int& displayY /* out */, | |
161 double x, | |
162 double y) const | |
163 { | |
164 cairo_matrix_transform_point(&transform_, &x, &y); | |
165 | |
166 displayX = static_cast<int>(boost::math::iround(x)); | |
167 displayY = static_cast<int>(boost::math::iround(y)); | |
168 } | |
169 | |
170 | |
171 void ViewportGeometry::SetDefaultView() | |
172 { | |
173 if (width_ > 0 && | |
174 height_ > 0 && | |
175 x2_ > x1_ + 10 * std::numeric_limits<double>::epsilon() && | |
176 y2_ > y1_ + 10 * std::numeric_limits<double>::epsilon()) | |
177 { | |
178 double zoomX = static_cast<double>(width_) / (x2_ - x1_); | |
179 double zoomY = static_cast<double>(height_) / (y2_ - y1_); | |
180 zoom_ = zoomX < zoomY ? zoomX : zoomY; | |
181 | |
182 panX_ = 0; | |
183 panY_ = 0; | |
184 | |
185 ComputeTransform(); | |
186 } | |
187 } | |
188 | |
189 | |
190 void ViewportGeometry::ApplyTransform(CairoContext& context) const | |
191 { | |
192 cairo_set_matrix(context.GetObject(), &transform_); | |
193 } | |
194 | |
195 | |
196 void ViewportGeometry::GetPan(double& x, | |
197 double& y) const | |
198 { | |
199 x = panX_; | |
200 y = panY_; | |
201 } | |
202 | |
203 | |
204 void ViewportGeometry::SetPan(double x, | |
205 double y) | |
206 { | |
207 panX_ = x; | |
208 panY_ = y; | |
209 ComputeTransform(); | |
210 } | |
211 | |
212 | |
213 void ViewportGeometry::SetZoom(double zoom) | |
214 { | |
215 zoom_ = zoom; | |
216 ComputeTransform(); | |
217 } | |
218 } |