comparison Framework/Deprecated/Toolbox/ViewportGeometry.cpp @ 732:c35e98d22764

move Deprecated classes to a separate folder
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 21 May 2019 14:27:35 +0200
parents Framework/Toolbox/ViewportGeometry.cpp@4f2416d519b4
children d33ae2b0db9d
comparison
equal deleted inserted replaced
729:529189f399ec 732:c35e98d22764
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2019 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21
22 #include "ViewportGeometry.h"
23
24 #include <Core/Logging.h>
25 #include <Core/OrthancException.h>
26
27 #include <boost/math/special_functions/round.hpp>
28
29 namespace Deprecated
30 {
31 void ViewportGeometry::ComputeTransform()
32 {
33 // The following lines must be read in reverse order!
34 cairo_matrix_t tmp;
35
36 // Bring the center of the scene to the center of the view
37 cairo_matrix_init_translate(&transform_,
38 panX_ + static_cast<double>(width_) / 2.0,
39 panY_ + static_cast<double>(height_) / 2.0);
40
41 // Apply the zoom around (0,0)
42 cairo_matrix_init_scale(&tmp, zoom_, zoom_);
43 cairo_matrix_multiply(&transform_, &tmp, &transform_);
44
45 // Bring the center of the scene to (0,0)
46 cairo_matrix_init_translate(&tmp,
47 -(sceneExtent_.GetX1() + sceneExtent_.GetX2()) / 2.0,
48 -(sceneExtent_.GetY1() + sceneExtent_.GetY2()) / 2.0);
49 cairo_matrix_multiply(&transform_, &tmp, &transform_);
50 }
51
52
53 ViewportGeometry::ViewportGeometry()
54 {
55 width_ = 0;
56 height_ = 0;
57
58 zoom_ = 1;
59 panX_ = 0;
60 panY_ = 0;
61
62 ComputeTransform();
63 }
64
65
66 void ViewportGeometry::SetDisplaySize(unsigned int width,
67 unsigned int height)
68 {
69 if (width_ != width ||
70 height_ != height)
71 {
72 LOG(INFO) << "New display size: " << width << "x" << height;
73
74 width_ = width;
75 height_ = height;
76
77 ComputeTransform();
78 }
79 }
80
81
82 void ViewportGeometry::SetSceneExtent(const OrthancStone::Extent2D& extent)
83 {
84 LOG(INFO) << "New scene extent: ("
85 << extent.GetX1() << "," << extent.GetY1() << ") => ("
86 << extent.GetX2() << "," << extent.GetY2() << ")";
87
88 sceneExtent_ = extent;
89 ComputeTransform();
90 }
91
92
93 void ViewportGeometry::MapDisplayToScene(double& sceneX /* out */,
94 double& sceneY /* out */,
95 double x,
96 double y) const
97 {
98 cairo_matrix_t transform = transform_;
99
100 if (cairo_matrix_invert(&transform) != CAIRO_STATUS_SUCCESS)
101 {
102 LOG(ERROR) << "Cannot invert singular matrix";
103 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
104 }
105
106 sceneX = x;
107 sceneY = y;
108 cairo_matrix_transform_point(&transform, &sceneX, &sceneY);
109 }
110
111
112 void ViewportGeometry::MapSceneToDisplay(int& displayX /* out */,
113 int& displayY /* out */,
114 double x,
115 double y) const
116 {
117 cairo_matrix_transform_point(&transform_, &x, &y);
118
119 displayX = static_cast<int>(boost::math::iround(x));
120 displayY = static_cast<int>(boost::math::iround(y));
121 }
122
123
124 void ViewportGeometry::MapPixelCenterToScene(std::vector<Touch>& sceneTouches /* out */,
125 const std::vector<Touch>& displayTouches) const
126 {
127 double sceneX, sceneY;
128 sceneTouches.clear();
129 for (size_t t = 0; t < displayTouches.size(); t++)
130 {
131 MapPixelCenterToScene(
132 sceneX,
133 sceneY,
134 static_cast<int>(displayTouches[t].x),
135 static_cast<int>(displayTouches[t].y));
136
137 sceneTouches.push_back(Touch((float)sceneX, (float)sceneY));
138 }
139 }
140
141 void ViewportGeometry::MapPixelCenterToScene(double& sceneX,
142 double& sceneY,
143 int x,
144 int y) const
145 {
146 // Take the center of the pixel
147 MapDisplayToScene(sceneX, sceneY,
148 static_cast<double>(x) + 0.5,
149 static_cast<double>(y) + 0.5);
150 }
151
152
153 void ViewportGeometry::FitContent()
154 {
155 if (width_ > 0 &&
156 height_ > 0 &&
157 !sceneExtent_.IsEmpty())
158 {
159 double zoomX = static_cast<double>(width_) / (sceneExtent_.GetX2() - sceneExtent_.GetX1());
160 double zoomY = static_cast<double>(height_) / (sceneExtent_.GetY2() - sceneExtent_.GetY1());
161 zoom_ = zoomX < zoomY ? zoomX : zoomY;
162
163 panX_ = 0;
164 panY_ = 0;
165
166 ComputeTransform();
167 }
168 }
169
170
171 void ViewportGeometry::ApplyTransform(OrthancStone::CairoContext& context) const
172 {
173 cairo_set_matrix(context.GetObject(), &transform_);
174 }
175
176
177 void ViewportGeometry::GetPan(double& x,
178 double& y) const
179 {
180 x = panX_;
181 y = panY_;
182 }
183
184
185 void ViewportGeometry::SetPan(double x,
186 double y)
187 {
188 panX_ = x;
189 panY_ = y;
190 ComputeTransform();
191 }
192
193
194 void ViewportGeometry::SetZoom(double zoom)
195 {
196 zoom_ = zoom;
197 ComputeTransform();
198 }
199
200
201 OrthancStone::Matrix ViewportGeometry::GetMatrix() const
202 {
203 OrthancStone::Matrix m(3, 3);
204
205 m(0, 0) = transform_.xx;
206 m(0, 1) = transform_.xy;
207 m(0, 2) = transform_.x0;
208 m(1, 0) = transform_.yx;
209 m(1, 1) = transform_.yy;
210 m(1, 2) = transform_.y0;
211 m(2, 0) = 0;
212 m(2, 1) = 0;
213 m(2, 2) = 1;
214
215 return m;
216 }
217 }