Mercurial > hg > orthanc-stone
annotate Applications/Samples/SingleFrameEditorApplication.h @ 360:8262e4e9826d am-2
export to png
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 30 Oct 2018 10:47:13 +0100 |
parents | 100df90bf0ea |
children | f559ac66ef55 |
rev | line source |
---|---|
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1 /** |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2 * Stone of Orthanc |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
4 * Department, University Hospital of Liege, Belgium |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
6 * |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
7 * This program is free software: you can redistribute it and/or |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
8 * modify it under the terms of the GNU Affero General Public License |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
9 * as published by the Free Software Foundation, either version 3 of |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
10 * the License, or (at your option) any later version. |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
11 * |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
12 * This program is distributed in the hope that it will be useful, but |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
13 * WITHOUT ANY WARRANTY; without even the implied warranty of |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
15 * Affero General Public License for more details. |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
16 * |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
17 * You should have received a copy of the GNU Affero General Public License |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
19 **/ |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
20 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
21 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
22 #pragma once |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
23 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
24 #include "SampleApplicationBase.h" |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
25 |
339 | 26 #include "../../Framework/Toolbox/ImageGeometry.h" |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
27 #include "../../Framework/Toolbox/OrthancApiClient.h" |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
28 #include "../../Framework/Toolbox/DicomFrameConverter.h" |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
29 |
343 | 30 #include <Core/Images/FontRegistry.h> |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
31 #include <Core/Images/Image.h> |
339 | 32 #include <Core/Images/ImageProcessing.h> |
338 | 33 #include <Core/Images/PamReader.h> |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
34 #include <Core/Logging.h> |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
35 #include <Plugins/Samples/Common/DicomDatasetReader.h> |
338 | 36 #include <Plugins/Samples/Common/FullOrthancDataset.h> |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
37 |
360 | 38 #include <Core/Images/PngWriter.h> |
39 | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
40 |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
41 #include <boost/math/constants/constants.hpp> |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
42 |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
43 namespace OrthancStone |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
44 { |
338 | 45 class BitmapStack : |
337 | 46 public IObserver, |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
47 public IObservable |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
48 { |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
49 public: |
338 | 50 typedef OriginMessage<MessageType_Widget_GeometryChanged, BitmapStack> GeometryChangedMessage; |
51 typedef OriginMessage<MessageType_Widget_ContentChanged, BitmapStack> ContentChangedMessage; | |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
52 |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
53 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
54 enum Corner |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
55 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
56 Corner_TopLeft, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
57 Corner_TopRight, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
58 Corner_BottomLeft, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
59 Corner_BottomRight |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
60 }; |
354 | 61 |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
62 |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
63 |
338 | 64 class Bitmap : public boost::noncopyable |
65 { | |
66 private: | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
67 size_t index_; |
343 | 68 bool hasSize_; |
69 unsigned int width_; | |
70 unsigned int height_; | |
71 bool hasCrop_; | |
72 unsigned int cropX_; | |
73 unsigned int cropY_; | |
74 unsigned int cropWidth_; | |
75 unsigned int cropHeight_; | |
76 Matrix transform_; | |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
77 Matrix transformInverse_; |
343 | 78 double pixelSpacingX_; |
79 double pixelSpacingY_; | |
80 double panX_; | |
81 double panY_; | |
346 | 82 double angle_; |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
83 bool resizeable_; |
338 | 84 |
342 | 85 |
348 | 86 protected: |
346 | 87 static Matrix CreateOffsetMatrix(double dx, |
88 double dy) | |
342 | 89 { |
346 | 90 Matrix m = LinearAlgebra::IdentityMatrix(3); |
91 m(0, 2) = dx; | |
92 m(1, 2) = dy; | |
93 return m; | |
94 } | |
95 | |
342 | 96 |
346 | 97 static Matrix CreateScalingMatrix(double sx, |
98 double sy) | |
99 { | |
100 Matrix m = LinearAlgebra::IdentityMatrix(3); | |
101 m(0, 0) = sx; | |
102 m(1, 1) = sy; | |
103 return m; | |
104 } | |
105 | |
106 | |
107 static Matrix CreateRotationMatrix(double angle) | |
108 { | |
342 | 109 Matrix m; |
346 | 110 const double v[] = { cos(angle), -sin(angle), 0, |
111 sin(angle), cos(angle), 0, | |
342 | 112 0, 0, 1 }; |
113 LinearAlgebra::FillMatrix(m, 3, 3, v); | |
346 | 114 return m; |
342 | 115 } |
346 | 116 |
345 | 117 |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
118 const Matrix& GetTransform() const |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
119 { |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
120 return transform_; |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
121 } |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
122 |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
123 |
348 | 124 private: |
346 | 125 static void ApplyTransform(double& x /* inout */, |
126 double& y /* inout */, | |
127 const Matrix& transform) | |
339 | 128 { |
129 Vector p; | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
130 LinearAlgebra::AssignVector(p, x, y, 1); |
339 | 131 |
346 | 132 Vector q = LinearAlgebra::Product(transform, p); |
339 | 133 |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
134 if (!LinearAlgebra::IsNear(q[2], 1.0)) |
339 | 135 { |
136 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
137 } | |
138 else | |
139 { | |
345 | 140 x = q[0]; |
141 y = q[1]; | |
339 | 142 } |
143 } | |
144 | |
345 | 145 |
346 | 146 void UpdateTransform() |
147 { | |
148 transform_ = CreateScalingMatrix(pixelSpacingX_, pixelSpacingY_); | |
149 | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
150 double centerX, centerY; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
151 GetCenter(centerX, centerY); |
346 | 152 |
153 transform_ = LinearAlgebra::Product( | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
154 CreateOffsetMatrix(panX_ + centerX, panY_ + centerY), |
346 | 155 CreateRotationMatrix(angle_), |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
156 CreateOffsetMatrix(-centerX, -centerY), |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
157 transform_); |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
158 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
159 LinearAlgebra::InvertMatrix(transformInverse_, transform_); |
346 | 160 } |
161 | |
162 | |
345 | 163 void AddToExtent(Extent2D& extent, |
164 double x, | |
165 double y) const | |
166 { | |
346 | 167 ApplyTransform(x, y, transform_); |
345 | 168 extent.AddPoint(x, y); |
169 } | |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
170 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
171 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
172 void GetCornerInternal(double& x, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
173 double& y, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
174 Corner corner, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
175 unsigned int cropX, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
176 unsigned int cropY, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
177 unsigned int cropWidth, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
178 unsigned int cropHeight) const |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
179 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
180 double dx = static_cast<double>(cropX); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
181 double dy = static_cast<double>(cropY); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
182 double dwidth = static_cast<double>(cropWidth); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
183 double dheight = static_cast<double>(cropHeight); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
184 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
185 switch (corner) |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
186 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
187 case Corner_TopLeft: |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
188 x = dx; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
189 y = dy; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
190 break; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
191 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
192 case Corner_TopRight: |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
193 x = dx + dwidth; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
194 y = dy; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
195 break; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
196 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
197 case Corner_BottomLeft: |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
198 x = dx; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
199 y = dy + dheight; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
200 break; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
201 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
202 case Corner_BottomRight: |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
203 x = dx + dwidth; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
204 y = dy + dheight; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
205 break; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
206 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
207 default: |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
208 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
209 } |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
210 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
211 ApplyTransform(x, y, transform_); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
212 } |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
213 |
339 | 214 |
338 | 215 public: |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
216 Bitmap(size_t index) : |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
217 index_(index), |
343 | 218 hasSize_(false), |
339 | 219 width_(0), |
220 height_(0), | |
221 hasCrop_(false), | |
342 | 222 pixelSpacingX_(1), |
223 pixelSpacingY_(1), | |
224 panX_(0), | |
346 | 225 panY_(0), |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
226 angle_(0), |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
227 resizeable_(false) |
339 | 228 { |
342 | 229 UpdateTransform(); |
339 | 230 } |
231 | |
343 | 232 virtual ~Bitmap() |
233 { | |
234 } | |
235 | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
236 size_t GetIndex() const |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
237 { |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
238 return index_; |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
239 } |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
240 |
339 | 241 void ResetCrop() |
242 { | |
243 hasCrop_ = false; | |
244 } | |
245 | |
348 | 246 void SetCrop(unsigned int x, |
247 unsigned int y, | |
248 unsigned int width, | |
249 unsigned int height) | |
339 | 250 { |
348 | 251 if (!hasSize_) |
252 { | |
253 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
254 } | |
255 | |
256 if (x + width > width_ || | |
257 y + height > height_) | |
258 { | |
259 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
260 } | |
261 | |
339 | 262 hasCrop_ = true; |
263 cropX_ = x; | |
264 cropY_ = y; | |
265 cropWidth_ = width; | |
266 cropHeight_ = height; | |
348 | 267 |
268 UpdateTransform(); | |
339 | 269 } |
270 | |
271 void GetCrop(unsigned int& x, | |
272 unsigned int& y, | |
273 unsigned int& width, | |
274 unsigned int& height) const | |
338 | 275 { |
339 | 276 if (hasCrop_) |
277 { | |
278 x = cropX_; | |
279 y = cropY_; | |
280 width = cropWidth_; | |
281 height = cropHeight_; | |
282 } | |
283 else | |
284 { | |
285 x = 0; | |
286 y = 0; | |
287 width = width_; | |
288 height = height_; | |
289 } | |
290 } | |
291 | |
346 | 292 void SetAngle(double angle) |
293 { | |
294 angle_ = angle; | |
295 UpdateTransform(); | |
296 } | |
297 | |
298 double GetAngle() const | |
299 { | |
300 return angle_; | |
301 } | |
302 | |
343 | 303 void SetSize(unsigned int width, |
304 unsigned int height) | |
338 | 305 { |
343 | 306 if (hasSize_ && |
307 (width != width_ || | |
308 height != height_)) | |
339 | 309 { |
343 | 310 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize); |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
311 } |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
312 |
343 | 313 hasSize_ = true; |
314 width_ = width; | |
315 height_ = height; | |
346 | 316 |
317 UpdateTransform(); | |
338 | 318 } |
319 | |
343 | 320 |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
321 unsigned int GetWidth() const |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
322 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
323 return width_; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
324 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
325 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
326 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
327 unsigned int GetHeight() const |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
328 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
329 return height_; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
330 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
331 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
332 |
343 | 333 void CheckSize(unsigned int width, |
334 unsigned int height) | |
338 | 335 { |
343 | 336 if (hasSize_ && |
337 (width != width_ || | |
338 height != height_)) | |
338 | 339 { |
343 | 340 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize); |
339 | 341 } |
342 } | |
343 | 343 |
339 | 344 |
345 Extent2D GetExtent() const | |
346 { | |
347 Extent2D extent; | |
348 | |
349 unsigned int x, y, width, height; | |
350 GetCrop(x, y, width, height); | |
351 | |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
352 double dx = static_cast<double>(x); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
353 double dy = static_cast<double>(y); |
339 | 354 double dwidth = static_cast<double>(width); |
355 double dheight = static_cast<double>(height); | |
342 | 356 |
339 | 357 AddToExtent(extent, dx, dy); |
358 AddToExtent(extent, dx + dwidth, dy); | |
359 AddToExtent(extent, dx, dy + dheight); | |
360 AddToExtent(extent, dx + dwidth, dy + dheight); | |
361 | |
362 return extent; | |
363 } | |
364 | |
365 | |
341 | 366 bool Contains(double x, |
367 double y) const | |
368 { | |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
369 ApplyTransform(x, y, transformInverse_); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
370 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
371 unsigned int cropX, cropY, cropWidth, cropHeight; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
372 GetCrop(cropX, cropY, cropWidth, cropHeight); |
341 | 373 |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
374 return (x >= cropX && x <= cropX + cropWidth && |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
375 y >= cropY && y <= cropY + cropHeight); |
341 | 376 } |
342 | 377 |
378 | |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
379 bool GetPixel(unsigned int& imageX, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
380 unsigned int& imageY, |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
381 double sceneX, |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
382 double sceneY) const |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
383 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
384 if (width_ == 0 || |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
385 height_ == 0) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
386 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
387 return false; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
388 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
389 else |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
390 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
391 ApplyTransform(sceneX, sceneY, transformInverse_); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
392 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
393 int x = static_cast<int>(std::floor(sceneX)); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
394 int y = static_cast<int>(std::floor(sceneY)); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
395 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
396 if (x < 0) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
397 { |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
398 imageX = 0; |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
399 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
400 else if (x >= static_cast<int>(width_)) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
401 { |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
402 imageX = width_; |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
403 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
404 else |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
405 { |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
406 imageX = static_cast<unsigned int>(x); |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
407 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
408 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
409 if (y < 0) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
410 { |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
411 imageY = 0; |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
412 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
413 else if (y >= static_cast<int>(height_)) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
414 { |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
415 imageY = height_; |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
416 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
417 else |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
418 { |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
419 imageY = static_cast<unsigned int>(y); |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
420 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
421 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
422 return true; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
423 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
424 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
425 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
426 |
342 | 427 void SetPan(double x, |
428 double y) | |
429 { | |
430 panX_ = x; | |
431 panY_ = y; | |
432 UpdateTransform(); | |
433 } | |
434 | |
435 | |
343 | 436 void SetPixelSpacing(double x, |
437 double y) | |
438 { | |
439 pixelSpacingX_ = x; | |
440 pixelSpacingY_ = y; | |
441 UpdateTransform(); | |
442 } | |
443 | |
345 | 444 double GetPixelSpacingX() const |
445 { | |
446 return pixelSpacingX_; | |
447 } | |
448 | |
449 double GetPixelSpacingY() const | |
450 { | |
451 return pixelSpacingY_; | |
452 } | |
343 | 453 |
342 | 454 double GetPanX() const |
455 { | |
456 return panX_; | |
457 } | |
458 | |
459 double GetPanY() const | |
460 { | |
461 return panY_; | |
462 } | |
343 | 463 |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
464 void GetCenter(double& centerX, |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
465 double& centerY) const |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
466 { |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
467 centerX = static_cast<double>(width_) / 2.0; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
468 centerY = static_cast<double>(height_) / 2.0; |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
469 ApplyTransform(centerX, centerY, transform_); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
470 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
471 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
472 |
345 | 473 void DrawBorders(CairoContext& context, |
474 double zoom) | |
475 { | |
476 unsigned int cx, cy, width, height; | |
477 GetCrop(cx, cy, width, height); | |
478 | |
479 double dx = static_cast<double>(cx); | |
480 double dy = static_cast<double>(cy); | |
481 double dwidth = static_cast<double>(width); | |
482 double dheight = static_cast<double>(height); | |
483 | |
484 cairo_t* cr = context.GetObject(); | |
485 cairo_set_line_width(cr, 2.0 / zoom); | |
486 | |
487 double x, y; | |
488 x = dx; | |
489 y = dy; | |
346 | 490 ApplyTransform(x, y, transform_); |
345 | 491 cairo_move_to(cr, x, y); |
492 | |
493 x = dx + dwidth; | |
494 y = dy; | |
346 | 495 ApplyTransform(x, y, transform_); |
345 | 496 cairo_line_to(cr, x, y); |
497 | |
498 x = dx + dwidth; | |
499 y = dy + dheight; | |
346 | 500 ApplyTransform(x, y, transform_); |
345 | 501 cairo_line_to(cr, x, y); |
502 | |
503 x = dx; | |
504 y = dy + dheight; | |
346 | 505 ApplyTransform(x, y, transform_); |
345 | 506 cairo_line_to(cr, x, y); |
507 | |
508 x = dx; | |
509 y = dy; | |
346 | 510 ApplyTransform(x, y, transform_); |
345 | 511 cairo_line_to(cr, x, y); |
512 | |
513 cairo_stroke(cr); | |
514 } | |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
515 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
516 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
517 static double Square(double x) |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
518 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
519 return x * x; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
520 } |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
521 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
522 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
523 void GetCorner(double& x /* out */, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
524 double& y /* out */, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
525 Corner corner) const |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
526 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
527 unsigned int cropX, cropY, cropWidth, cropHeight; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
528 GetCrop(cropX, cropY, cropWidth, cropHeight); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
529 GetCornerInternal(x, y, corner, cropX, cropY, cropWidth, cropHeight); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
530 } |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
531 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
532 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
533 bool LookupCorner(Corner& corner /* out */, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
534 double x, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
535 double y, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
536 double zoom, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
537 double viewportDistance) const |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
538 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
539 static const Corner CORNERS[] = { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
540 Corner_TopLeft, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
541 Corner_TopRight, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
542 Corner_BottomLeft, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
543 Corner_BottomRight |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
544 }; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
545 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
546 unsigned int cropX, cropY, cropWidth, cropHeight; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
547 GetCrop(cropX, cropY, cropWidth, cropHeight); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
548 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
549 double threshold = Square(viewportDistance / zoom); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
550 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
551 for (size_t i = 0; i < 4; i++) |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
552 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
553 double cx, cy; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
554 GetCornerInternal(cx, cy, CORNERS[i], cropX, cropY, cropWidth, cropHeight); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
555 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
556 double d = Square(cx - x) + Square(cy - y); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
557 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
558 if (d <= threshold) |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
559 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
560 corner = CORNERS[i]; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
561 return true; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
562 } |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
563 } |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
564 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
565 return false; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
566 } |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
567 |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
568 bool IsResizeable() const |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
569 { |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
570 return resizeable_; |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
571 } |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
572 |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
573 void SetResizeable(bool resizeable) |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
574 { |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
575 resizeable_ = resizeable; |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
576 } |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
577 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
578 virtual bool GetDefaultWindowing(float& center, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
579 float& width) const |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
580 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
581 return false; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
582 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
583 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
584 virtual void Render(Orthanc::ImageAccessor& buffer, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
585 const ViewportGeometry& view, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
586 ImageInterpolation interpolation) const = 0; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
587 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
588 virtual bool GetRange(float& minValue, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
589 float& maxValue) const = 0; |
338 | 590 }; |
591 | |
592 | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
593 class BitmapAccessor : public boost::noncopyable |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
594 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
595 private: |
354 | 596 BitmapStack& stack_; |
597 size_t index_; | |
598 Bitmap* bitmap_; | |
343 | 599 |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
600 public: |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
601 BitmapAccessor(BitmapStack& stack, |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
602 size_t index) : |
354 | 603 stack_(stack), |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
604 index_(index) |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
605 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
606 Bitmaps::iterator bitmap = stack.bitmaps_.find(index); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
607 if (bitmap == stack.bitmaps_.end()) |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
608 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
609 bitmap_ = NULL; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
610 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
611 else |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
612 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
613 assert(bitmap->second != NULL); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
614 bitmap_ = bitmap->second; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
615 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
616 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
617 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
618 BitmapAccessor(BitmapStack& stack, |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
619 double x, |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
620 double y) : |
354 | 621 stack_(stack), |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
622 index_(0) // Dummy initialization |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
623 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
624 if (stack.LookupBitmap(index_, x, y)) |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
625 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
626 Bitmaps::iterator bitmap = stack.bitmaps_.find(index_); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
627 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
628 if (bitmap == stack.bitmaps_.end()) |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
629 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
630 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
631 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
632 else |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
633 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
634 assert(bitmap->second != NULL); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
635 bitmap_ = bitmap->second; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
636 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
637 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
638 else |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
639 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
640 bitmap_ = NULL; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
641 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
642 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
643 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
644 void Invalidate() |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
645 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
646 bitmap_ = NULL; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
647 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
648 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
649 bool IsValid() const |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
650 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
651 return bitmap_ != NULL; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
652 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
653 |
354 | 654 BitmapStack& GetStack() const |
655 { | |
656 if (IsValid()) | |
657 { | |
658 return stack_; | |
659 } | |
660 else | |
661 { | |
662 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
663 } | |
664 } | |
665 | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
666 size_t GetIndex() const |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
667 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
668 if (IsValid()) |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
669 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
670 return index_; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
671 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
672 else |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
673 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
674 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
675 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
676 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
677 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
678 Bitmap& GetBitmap() const |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
679 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
680 if (IsValid()) |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
681 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
682 return *bitmap_; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
683 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
684 else |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
685 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
686 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
687 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
688 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
689 }; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
690 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
691 |
354 | 692 class AlphaBitmap : public Bitmap |
693 { | |
694 private: | |
695 const BitmapStack& stack_; | |
696 std::auto_ptr<Orthanc::ImageAccessor> alpha_; // Grayscale8 | |
697 bool useWindowing_; | |
698 float foreground_; | |
699 | |
700 public: | |
701 AlphaBitmap(size_t index, | |
702 const BitmapStack& stack) : | |
703 Bitmap(index), | |
704 stack_(stack), | |
705 useWindowing_(true), | |
706 foreground_(0) | |
707 { | |
708 } | |
709 | |
710 | |
711 void SetForegroundValue(float foreground) | |
712 { | |
713 useWindowing_ = false; | |
714 foreground_ = foreground; | |
715 } | |
716 | |
717 | |
718 void SetAlpha(Orthanc::ImageAccessor* image) | |
719 { | |
720 std::auto_ptr<Orthanc::ImageAccessor> raii(image); | |
721 | |
722 if (image == NULL) | |
723 { | |
724 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
725 } | |
726 | |
727 if (image->GetFormat() != Orthanc::PixelFormat_Grayscale8) | |
728 { | |
729 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); | |
730 } | |
731 | |
732 SetSize(image->GetWidth(), image->GetHeight()); | |
733 alpha_ = raii; | |
734 } | |
735 | |
736 | |
737 void LoadText(const Orthanc::Font& font, | |
738 const std::string& utf8) | |
739 { | |
740 SetAlpha(font.RenderAlpha(utf8)); | |
741 } | |
742 | |
743 | |
744 virtual void Render(Orthanc::ImageAccessor& buffer, | |
745 const ViewportGeometry& view, | |
746 ImageInterpolation interpolation) const | |
747 { | |
748 if (buffer.GetFormat() != Orthanc::PixelFormat_Float32) | |
749 { | |
750 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); | |
751 } | |
752 | |
753 unsigned int cropX, cropY, cropWidth, cropHeight; | |
754 GetCrop(cropX, cropY, cropWidth, cropHeight); | |
755 | |
756 Matrix m = LinearAlgebra::Product(view.GetMatrix(), | |
757 GetTransform(), | |
758 CreateOffsetMatrix(cropX, cropY)); | |
759 | |
760 Orthanc::ImageAccessor cropped; | |
761 alpha_->GetRegion(cropped, cropX, cropY, cropWidth, cropHeight); | |
762 | |
763 Orthanc::Image tmp(Orthanc::PixelFormat_Grayscale8, buffer.GetWidth(), buffer.GetHeight(), false); | |
764 ApplyProjectiveTransform(tmp, cropped, m, interpolation, true /* clear */); | |
765 | |
766 // Blit | |
767 const unsigned int width = buffer.GetWidth(); | |
768 const unsigned int height = buffer.GetHeight(); | |
769 | |
770 float value = foreground_; | |
771 | |
772 if (useWindowing_) | |
773 { | |
774 float center, width; | |
775 if (stack_.GetWindowing(center, width)) | |
776 { | |
777 value = center + width / 2.0f; | |
778 } | |
779 } | |
780 | |
781 for (unsigned int y = 0; y < height; y++) | |
782 { | |
783 float *q = reinterpret_cast<float*>(buffer.GetRow(y)); | |
784 const uint8_t *p = reinterpret_cast<uint8_t*>(tmp.GetRow(y)); | |
785 | |
786 for (unsigned int x = 0; x < width; x++, p++, q++) | |
787 { | |
788 float a = static_cast<float>(*p) / 255.0f; | |
789 | |
790 *q = (a * value + (1.0f - a) * (*q)); | |
791 } | |
792 } | |
793 } | |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
794 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
795 virtual bool GetRange(float& minValue, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
796 float& maxValue) const |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
797 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
798 if (useWindowing_) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
799 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
800 return false; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
801 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
802 else |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
803 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
804 minValue = 0; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
805 maxValue = 0; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
806 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
807 if (foreground_ < 0) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
808 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
809 minValue = foreground_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
810 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
811 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
812 if (foreground_ > 0) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
813 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
814 maxValue = foreground_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
815 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
816 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
817 return true; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
818 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
819 } |
354 | 820 }; |
821 | |
822 | |
823 | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
824 private: |
343 | 825 class DicomBitmap : public Bitmap |
826 { | |
827 private: | |
828 std::auto_ptr<Orthanc::ImageAccessor> source_; // Content of PixelData | |
829 std::auto_ptr<DicomFrameConverter> converter_; | |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
830 std::auto_ptr<Orthanc::ImageAccessor> converted_; // Float32 |
343 | 831 |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
832 static OrthancPlugins::DicomTag ConvertTag(const Orthanc::DicomTag& tag) |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
833 { |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
834 return OrthancPlugins::DicomTag(tag.GetGroup(), tag.GetElement()); |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
835 } |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
836 |
343 | 837 |
838 void ApplyConverter() | |
839 { | |
840 if (source_.get() != NULL && | |
841 converter_.get() != NULL) | |
842 { | |
843 converted_.reset(converter_->ConvertFrame(*source_)); | |
844 } | |
845 } | |
846 | |
847 public: | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
848 DicomBitmap(size_t index) : |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
849 Bitmap(index) |
343 | 850 { |
851 } | |
852 | |
853 void SetDicomTags(const OrthancPlugins::FullOrthancDataset& dataset) | |
854 { | |
855 converter_.reset(new DicomFrameConverter); | |
856 converter_->ReadParameters(dataset); | |
857 ApplyConverter(); | |
858 | |
859 std::string tmp; | |
860 Vector pixelSpacing; | |
861 | |
862 if (dataset.GetStringValue(tmp, ConvertTag(Orthanc::DICOM_TAG_PIXEL_SPACING)) && | |
863 LinearAlgebra::ParseVector(pixelSpacing, tmp) && | |
864 pixelSpacing.size() == 2) | |
865 { | |
866 SetPixelSpacing(pixelSpacing[0], pixelSpacing[1]); | |
867 } | |
868 | |
348 | 869 //SetPan(-0.5 * GetPixelSpacingX(), -0.5 * GetPixelSpacingY()); |
345 | 870 |
343 | 871 OrthancPlugins::DicomDatasetReader reader(dataset); |
872 | |
873 unsigned int width, height; | |
874 if (!reader.GetUnsignedIntegerValue(width, ConvertTag(Orthanc::DICOM_TAG_COLUMNS)) || | |
875 !reader.GetUnsignedIntegerValue(height, ConvertTag(Orthanc::DICOM_TAG_ROWS))) | |
876 { | |
877 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | |
878 } | |
879 else | |
880 { | |
881 SetSize(width, height); | |
882 } | |
883 } | |
884 | |
885 | |
886 void SetSourceImage(Orthanc::ImageAccessor* image) // Takes ownership | |
887 { | |
888 std::auto_ptr<Orthanc::ImageAccessor> raii(image); | |
889 | |
890 if (image == NULL) | |
891 { | |
892 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
893 } | |
894 | |
895 SetSize(image->GetWidth(), image->GetHeight()); | |
896 | |
897 source_ = raii; | |
898 ApplyConverter(); | |
899 } | |
900 | |
901 | |
902 virtual void Render(Orthanc::ImageAccessor& buffer, | |
345 | 903 const ViewportGeometry& view, |
904 ImageInterpolation interpolation) const | |
343 | 905 { |
906 if (converted_.get() != NULL) | |
907 { | |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
908 if (converted_->GetFormat() != Orthanc::PixelFormat_Float32) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
909 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
910 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
911 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
912 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
913 unsigned int cropX, cropY, cropWidth, cropHeight; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
914 GetCrop(cropX, cropY, cropWidth, cropHeight); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
915 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
916 Matrix m = LinearAlgebra::Product(view.GetMatrix(), |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
917 GetTransform(), |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
918 CreateOffsetMatrix(cropX, cropY)); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
919 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
920 Orthanc::ImageAccessor cropped; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
921 converted_->GetRegion(cropped, cropX, cropY, cropWidth, cropHeight); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
922 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
923 ApplyProjectiveTransform(buffer, cropped, m, interpolation, false); |
343 | 924 } |
925 } | |
926 | |
927 | |
928 virtual bool GetDefaultWindowing(float& center, | |
929 float& width) const | |
930 { | |
931 if (converter_.get() != NULL && | |
932 converter_->HasDefaultWindow()) | |
933 { | |
934 center = static_cast<float>(converter_->GetDefaultWindowCenter()); | |
935 width = static_cast<float>(converter_->GetDefaultWindowWidth()); | |
936 return true; | |
937 } | |
938 else | |
939 { | |
940 return false; | |
941 } | |
942 } | |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
943 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
944 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
945 virtual bool GetRange(float& minValue, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
946 float& maxValue) const |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
947 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
948 if (converted_.get() != NULL) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
949 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
950 if (converted_->GetFormat() != Orthanc::PixelFormat_Float32) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
951 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
952 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
953 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
954 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
955 Orthanc::ImageProcessing::GetMinMaxFloatValue(minValue, maxValue, *converted_); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
956 return true; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
957 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
958 else |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
959 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
960 return false; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
961 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
962 } |
343 | 963 }; |
964 | |
965 | |
966 | |
967 | |
341 | 968 typedef std::map<size_t, Bitmap*> Bitmaps; |
338 | 969 |
341 | 970 OrthancApiClient& orthanc_; |
971 size_t countBitmaps_; | |
972 bool hasWindowing_; | |
973 float windowingCenter_; | |
974 float windowingWidth_; | |
975 Bitmaps bitmaps_; | |
345 | 976 bool hasSelection_; |
977 size_t selectedBitmap_; | |
338 | 978 |
979 public: | |
980 BitmapStack(MessageBroker& broker, | |
981 OrthancApiClient& orthanc) : | |
982 IObserver(broker), | |
983 IObservable(broker), | |
984 orthanc_(orthanc), | |
341 | 985 countBitmaps_(0), |
338 | 986 hasWindowing_(false), |
987 windowingCenter_(0), // Dummy initialization | |
345 | 988 windowingWidth_(0), // Dummy initialization |
989 hasSelection_(false), | |
990 selectedBitmap_(0) // Dummy initialization | |
338 | 991 { |
992 } | |
993 | |
345 | 994 |
995 void Unselect() | |
996 { | |
997 hasSelection_ = false; | |
998 } | |
999 | |
1000 | |
1001 void Select(size_t bitmap) | |
1002 { | |
1003 hasSelection_ = true; | |
1004 selectedBitmap_ = bitmap; | |
1005 } | |
346 | 1006 |
1007 | |
1008 bool GetSelectedBitmap(size_t& bitmap) const | |
1009 { | |
1010 if (hasSelection_) | |
1011 { | |
1012 bitmap = selectedBitmap_; | |
1013 return true; | |
1014 } | |
1015 else | |
1016 { | |
1017 return false; | |
1018 } | |
1019 } | |
345 | 1020 |
338 | 1021 |
1022 virtual ~BitmapStack() | |
1023 { | |
1024 for (Bitmaps::iterator it = bitmaps_.begin(); it != bitmaps_.end(); it++) | |
1025 { | |
1026 assert(it->second != NULL); | |
1027 delete it->second; | |
1028 } | |
1029 } | |
339 | 1030 |
1031 | |
343 | 1032 bool GetWindowing(float& center, |
1033 float& width) const | |
339 | 1034 { |
1035 if (hasWindowing_) | |
1036 { | |
1037 center = windowingCenter_; | |
1038 width = windowingWidth_; | |
343 | 1039 return true; |
339 | 1040 } |
1041 else | |
1042 { | |
343 | 1043 return false; |
339 | 1044 } |
1045 } | |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1046 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1047 |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1048 void GetWindowingWithDefault(float& center, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1049 float& width) const |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1050 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1051 if (!GetWindowing(center, width)) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1052 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1053 center = 128; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1054 width = 256; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1055 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1056 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1057 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1058 |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1059 void SetWindowing(float center, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1060 float width) |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1061 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1062 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1063 hasWindowing_ = true; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1064 windowingCenter_ = center; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1065 windowingWidth_ = width; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1066 |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1067 //EmitMessage(ContentChangedMessage(*this)); |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1068 } |
338 | 1069 |
1070 | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1071 Bitmap& LoadText(const Orthanc::Font& font, |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1072 const std::string& utf8) |
343 | 1073 { |
348 | 1074 size_t bitmap = countBitmaps_++; |
1075 | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1076 std::auto_ptr<AlphaBitmap> alpha(new AlphaBitmap(bitmap, *this)); |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1077 alpha->LoadText(font, utf8); |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1078 |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1079 AlphaBitmap* ptr = alpha.get(); |
348 | 1080 bitmaps_[bitmap] = alpha.release(); |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1081 |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1082 return *ptr; |
348 | 1083 } |
1084 | |
1085 | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1086 Bitmap& LoadTestBlock(unsigned int width, |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1087 unsigned int height) |
348 | 1088 { |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1089 size_t bitmap = countBitmaps_++; |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1090 |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1091 std::auto_ptr<AlphaBitmap> alpha(new AlphaBitmap(bitmap, *this)); |
348 | 1092 |
1093 std::auto_ptr<Orthanc::Image> block(new Orthanc::Image(Orthanc::PixelFormat_Grayscale8, width, height, false)); | |
1094 | |
1095 for (unsigned int padding = 0; | |
1096 (width > 2 * padding) && (height > 2 * padding); | |
1097 padding++) | |
1098 { | |
1099 uint8_t color; | |
1100 if (255 > 10 * padding) | |
1101 { | |
1102 color = 255 - 10 * padding; | |
1103 } | |
1104 else | |
1105 { | |
1106 color = 0; | |
1107 } | |
1108 | |
1109 Orthanc::ImageAccessor region; | |
1110 block->GetRegion(region, padding, padding, width - 2 * padding, height - 2 * padding); | |
1111 Orthanc::ImageProcessing::Set(region, color); | |
1112 } | |
1113 | |
1114 alpha->SetAlpha(block.release()); | |
343 | 1115 |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1116 AlphaBitmap* ptr = alpha.get(); |
343 | 1117 bitmaps_[bitmap] = alpha.release(); |
1118 | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1119 return *ptr; |
343 | 1120 } |
1121 | |
1122 | |
354 | 1123 Bitmap& LoadFrame(const std::string& instance, |
341 | 1124 unsigned int frame, |
1125 bool httpCompression) | |
338 | 1126 { |
341 | 1127 size_t bitmap = countBitmaps_++; |
338 | 1128 |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1129 bitmaps_[bitmap] = new DicomBitmap(bitmap); |
338 | 1130 |
1131 { | |
1132 IWebService::Headers headers; | |
1133 std::string uri = "/instances/" + instance + "/tags"; | |
1134 orthanc_.GetBinaryAsync(uri, headers, | |
1135 new Callable<BitmapStack, OrthancApiClient::BinaryResponseReadyMessage> | |
1136 (*this, &BitmapStack::OnTagsReceived), NULL, | |
341 | 1137 new Orthanc::SingleValueObject<size_t>(bitmap)); |
338 | 1138 } |
1139 | |
1140 { | |
1141 IWebService::Headers headers; | |
1142 headers["Accept"] = "image/x-portable-arbitrarymap"; | |
1143 | |
1144 if (httpCompression) | |
1145 { | |
1146 headers["Accept-Encoding"] = "gzip"; | |
1147 } | |
1148 | |
1149 std::string uri = "/instances/" + instance + "/frames/" + boost::lexical_cast<std::string>(frame) + "/image-uint16"; | |
1150 orthanc_.GetBinaryAsync(uri, headers, | |
1151 new Callable<BitmapStack, OrthancApiClient::BinaryResponseReadyMessage> | |
1152 (*this, &BitmapStack::OnFrameReceived), NULL, | |
341 | 1153 new Orthanc::SingleValueObject<size_t>(bitmap)); |
338 | 1154 } |
1155 | |
354 | 1156 return *bitmaps_[bitmap]; |
338 | 1157 } |
1158 | |
1159 | |
1160 void OnTagsReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) | |
1161 { | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
1162 size_t index = dynamic_cast<Orthanc::SingleValueObject<size_t>*>(message.Payload.get())->GetValue(); |
358 | 1163 |
1164 LOG(INFO) << "JSON received: " << message.Uri.c_str() | |
1165 << " (" << message.AnswerSize << " bytes) for bitmap " << index; | |
338 | 1166 |
341 | 1167 Bitmaps::iterator bitmap = bitmaps_.find(index); |
338 | 1168 if (bitmap != bitmaps_.end()) |
1169 { | |
1170 assert(bitmap->second != NULL); | |
1171 | |
1172 OrthancPlugins::FullOrthancDataset dicom(message.Answer, message.AnswerSize); | |
343 | 1173 dynamic_cast<DicomBitmap*>(bitmap->second)->SetDicomTags(dicom); |
338 | 1174 |
1175 float c, w; | |
1176 if (!hasWindowing_ && | |
1177 bitmap->second->GetDefaultWindowing(c, w)) | |
1178 { | |
1179 hasWindowing_ = true; | |
1180 windowingCenter_ = c; | |
1181 windowingWidth_ = w; | |
1182 } | |
1183 | |
1184 EmitMessage(GeometryChangedMessage(*this)); | |
1185 } | |
1186 } | |
1187 | |
1188 | |
1189 void OnFrameReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) | |
1190 { | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
1191 size_t index = dynamic_cast<Orthanc::SingleValueObject<size_t>*>(message.Payload.get())->GetValue(); |
338 | 1192 |
358 | 1193 LOG(INFO) << "DICOM frame received: " << message.Uri.c_str() |
1194 << " (" << message.AnswerSize << " bytes) for bitmap " << index; | |
341 | 1195 |
1196 Bitmaps::iterator bitmap = bitmaps_.find(index); | |
338 | 1197 if (bitmap != bitmaps_.end()) |
1198 { | |
1199 assert(bitmap->second != NULL); | |
1200 | |
1201 std::string content; | |
1202 if (message.AnswerSize > 0) | |
1203 { | |
1204 content.assign(reinterpret_cast<const char*>(message.Answer), message.AnswerSize); | |
1205 } | |
1206 | |
1207 std::auto_ptr<Orthanc::PamReader> reader(new Orthanc::PamReader); | |
1208 reader->ReadFromMemory(content); | |
343 | 1209 dynamic_cast<DicomBitmap*>(bitmap->second)->SetSourceImage(reader.release()); |
338 | 1210 |
1211 EmitMessage(ContentChangedMessage(*this)); | |
1212 } | |
1213 } | |
339 | 1214 |
1215 | |
1216 Extent2D GetSceneExtent() const | |
1217 { | |
1218 Extent2D extent; | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1219 |
339 | 1220 for (Bitmaps::const_iterator it = bitmaps_.begin(); |
1221 it != bitmaps_.end(); ++it) | |
1222 { | |
1223 assert(it->second != NULL); | |
1224 extent.Union(it->second->GetExtent()); | |
1225 } | |
1226 | |
1227 return extent; | |
1228 } | |
1229 | |
1230 | |
1231 void Render(Orthanc::ImageAccessor& buffer, | |
345 | 1232 const ViewportGeometry& view, |
1233 ImageInterpolation interpolation) const | |
339 | 1234 { |
1235 Orthanc::ImageProcessing::Set(buffer, 0); | |
1236 | |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1237 // Render layers in the background-to-foreground order |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1238 for (size_t index = 0; index < countBitmaps_; index++) |
339 | 1239 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1240 Bitmaps::const_iterator it = bitmaps_.find(index); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1241 if (it != bitmaps_.end()) |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1242 { |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1243 assert(it->second != NULL); |
345 | 1244 it->second->Render(buffer, view, interpolation); |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1245 } |
339 | 1246 } |
1247 } | |
342 | 1248 |
1249 | |
1250 bool LookupBitmap(size_t& index /* out */, | |
1251 double x, | |
1252 double y) const | |
1253 { | |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1254 // Render layers in the foreground-to-background order |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1255 for (size_t i = countBitmaps_; i > 0; i--) |
342 | 1256 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1257 index = i - 1; |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1258 Bitmaps::const_iterator it = bitmaps_.find(index); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1259 if (it != bitmaps_.end()) |
342 | 1260 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1261 assert(it->second != NULL); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1262 if (it->second->Contains(x, y)) |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1263 { |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1264 return true; |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1265 } |
342 | 1266 } |
1267 } | |
1268 | |
1269 return false; | |
1270 } | |
1271 | |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
1272 void DrawControls(CairoContext& context, |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
1273 double zoom) |
345 | 1274 { |
1275 if (hasSelection_) | |
1276 { | |
1277 Bitmaps::const_iterator bitmap = bitmaps_.find(selectedBitmap_); | |
1278 | |
1279 if (bitmap != bitmaps_.end()) | |
1280 { | |
1281 context.SetSourceColor(255, 0, 0); | |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
1282 //view.ApplyTransform(context); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
1283 bitmap->second->DrawBorders(context, zoom); |
345 | 1284 } |
1285 } | |
1286 } | |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1287 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1288 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1289 void GetRange(float& minValue, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1290 float& maxValue) const |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1291 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1292 bool first = true; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1293 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1294 for (Bitmaps::const_iterator it = bitmaps_.begin(); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1295 it != bitmaps_.end(); it++) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1296 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1297 assert(it->second != NULL); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1298 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1299 float a, b; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1300 if (it->second->GetRange(a, b)) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1301 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1302 if (first) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1303 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1304 minValue = a; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1305 maxValue = b; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1306 first = false; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1307 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1308 else |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1309 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1310 minValue = std::min(a, minValue); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1311 maxValue = std::max(b, maxValue); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1312 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1313 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1314 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1315 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1316 if (first) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1317 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1318 minValue = 0; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1319 maxValue = 0; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1320 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
1321 } |
338 | 1322 }; |
1323 | |
341 | 1324 |
354 | 1325 class UndoRedoStack : public boost::noncopyable |
1326 { | |
1327 public: | |
1328 class ICommand : public boost::noncopyable | |
1329 { | |
1330 public: | |
1331 virtual ~ICommand() | |
1332 { | |
1333 } | |
1334 | |
1335 virtual void Undo() const = 0; | |
1336 | |
1337 virtual void Redo() const = 0; | |
1338 }; | |
1339 | |
1340 private: | |
1341 typedef std::list<ICommand*> Stack; | |
1342 | |
1343 Stack stack_; | |
1344 Stack::iterator current_; | |
1345 | |
1346 void Clear(Stack::iterator from) | |
1347 { | |
1348 for (Stack::iterator it = from; it != stack_.end(); ++it) | |
1349 { | |
1350 assert(*it != NULL); | |
1351 delete *it; | |
1352 } | |
1353 | |
1354 stack_.erase(from, stack_.end()); | |
1355 } | |
1356 | |
1357 public: | |
1358 UndoRedoStack() : | |
1359 current_(stack_.end()) | |
1360 { | |
1361 } | |
1362 | |
1363 ~UndoRedoStack() | |
1364 { | |
1365 Clear(stack_.begin()); | |
1366 } | |
1367 | |
1368 void Add(ICommand* command) | |
1369 { | |
1370 if (command == NULL) | |
1371 { | |
1372 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
1373 } | |
1374 | |
1375 Clear(current_); | |
1376 | |
1377 stack_.push_back(command); | |
1378 current_ = stack_.end(); | |
1379 } | |
1380 | |
1381 void Undo() | |
1382 { | |
1383 if (current_ != stack_.begin()) | |
1384 { | |
1385 --current_; | |
1386 | |
1387 assert(*current_ != NULL); | |
1388 (*current_)->Undo(); | |
1389 } | |
1390 } | |
1391 | |
1392 void Redo() | |
1393 { | |
1394 if (current_ != stack_.end()) | |
1395 { | |
1396 assert(*current_ != NULL); | |
1397 (*current_)->Redo(); | |
1398 | |
1399 ++current_; | |
1400 } | |
1401 } | |
1402 }; | |
1403 | |
1404 | |
1405 class BitmapCommandBase : public UndoRedoStack::ICommand | |
1406 { | |
1407 private: | |
1408 BitmapStack& stack_; | |
1409 size_t bitmap_; | |
1410 | |
1411 protected: | |
1412 virtual void UndoInternal(BitmapStack::Bitmap& bitmap) const = 0; | |
1413 | |
1414 virtual void RedoInternal(BitmapStack::Bitmap& bitmap) const = 0; | |
1415 | |
1416 public: | |
1417 BitmapCommandBase(BitmapStack& stack, | |
1418 size_t bitmap) : | |
1419 stack_(stack), | |
1420 bitmap_(bitmap) | |
1421 { | |
1422 } | |
1423 | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1424 BitmapCommandBase(const BitmapStack::BitmapAccessor& accessor) : |
354 | 1425 stack_(accessor.GetStack()), |
1426 bitmap_(accessor.GetIndex()) | |
1427 { | |
1428 } | |
1429 | |
1430 virtual void Undo() const | |
1431 { | |
1432 BitmapStack::BitmapAccessor accessor(stack_, bitmap_); | |
1433 | |
1434 if (accessor.IsValid()) | |
1435 { | |
1436 UndoInternal(accessor.GetBitmap()); | |
1437 } | |
1438 } | |
1439 | |
1440 virtual void Redo() const | |
1441 { | |
1442 BitmapStack::BitmapAccessor accessor(stack_, bitmap_); | |
1443 | |
1444 if (accessor.IsValid()) | |
1445 { | |
1446 RedoInternal(accessor.GetBitmap()); | |
1447 } | |
1448 } | |
1449 }; | |
1450 | |
1451 | |
1452 class RotateBitmapTracker : public IWorldSceneMouseTracker | |
1453 { | |
1454 private: | |
1455 UndoRedoStack& undoRedoStack_; | |
1456 BitmapStack::BitmapAccessor accessor_; | |
1457 double centerX_; | |
1458 double centerY_; | |
1459 double originalAngle_; | |
1460 double clickAngle_; | |
1461 bool roundAngles_; | |
1462 | |
1463 bool ComputeAngle(double& angle /* out */, | |
1464 double sceneX, | |
1465 double sceneY) const | |
1466 { | |
1467 Vector u; | |
1468 LinearAlgebra::AssignVector(u, sceneX - centerX_, sceneY - centerY_); | |
1469 | |
1470 double nu = boost::numeric::ublas::norm_2(u); | |
1471 | |
1472 if (!LinearAlgebra::IsCloseToZero(nu)) | |
1473 { | |
1474 u /= nu; | |
1475 angle = atan2(u[1], u[0]); | |
1476 return true; | |
1477 } | |
1478 else | |
1479 { | |
1480 return false; | |
1481 } | |
1482 } | |
1483 | |
1484 | |
1485 class UndoRedoCommand : public BitmapCommandBase | |
1486 { | |
1487 private: | |
1488 double sourceAngle_; | |
1489 double targetAngle_; | |
1490 | |
1491 static int ToDegrees(double angle) | |
1492 { | |
1493 return static_cast<int>(round(angle * 180.0 / boost::math::constants::pi<double>())); | |
1494 } | |
1495 | |
1496 protected: | |
1497 virtual void UndoInternal(BitmapStack::Bitmap& bitmap) const | |
1498 { | |
1499 LOG(INFO) << "Undo - Set angle to " << ToDegrees(sourceAngle_) << " degrees"; | |
1500 bitmap.SetAngle(sourceAngle_); | |
1501 } | |
1502 | |
1503 virtual void RedoInternal(BitmapStack::Bitmap& bitmap) const | |
1504 { | |
1505 LOG(INFO) << "Redo - Set angle to " << ToDegrees(sourceAngle_) << " degrees"; | |
1506 bitmap.SetAngle(targetAngle_); | |
1507 } | |
1508 | |
1509 public: | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1510 UndoRedoCommand(const RotateBitmapTracker& tracker) : |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1511 BitmapCommandBase(tracker.accessor_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1512 sourceAngle_(tracker.originalAngle_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1513 targetAngle_(tracker.accessor_.GetBitmap().GetAngle()) |
354 | 1514 { |
1515 } | |
1516 }; | |
1517 | |
1518 | |
1519 public: | |
1520 RotateBitmapTracker(UndoRedoStack& undoRedoStack, | |
1521 BitmapStack& stack, | |
1522 const ViewportGeometry& view, | |
1523 size_t bitmap, | |
1524 double x, | |
1525 double y, | |
1526 bool roundAngles) : | |
1527 undoRedoStack_(undoRedoStack), | |
1528 accessor_(stack, bitmap), | |
1529 roundAngles_(roundAngles) | |
1530 { | |
1531 if (accessor_.IsValid()) | |
1532 { | |
1533 accessor_.GetBitmap().GetCenter(centerX_, centerY_); | |
1534 originalAngle_ = accessor_.GetBitmap().GetAngle(); | |
1535 | |
1536 double sceneX, sceneY; | |
1537 view.MapDisplayToScene(sceneX, sceneY, x, y); | |
1538 | |
1539 if (!ComputeAngle(clickAngle_, x, y)) | |
1540 { | |
1541 accessor_.Invalidate(); | |
1542 } | |
1543 } | |
1544 } | |
1545 | |
1546 virtual bool HasRender() const | |
1547 { | |
1548 return false; | |
1549 } | |
1550 | |
1551 virtual void Render(CairoContext& context, | |
1552 double zoom) | |
1553 { | |
1554 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
1555 } | |
1556 | |
1557 virtual void MouseUp() | |
1558 { | |
1559 if (accessor_.IsValid()) | |
1560 { | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1561 undoRedoStack_.Add(new UndoRedoCommand(*this)); |
354 | 1562 } |
1563 } | |
1564 | |
1565 virtual void MouseMove(int displayX, | |
1566 int displayY, | |
1567 double sceneX, | |
1568 double sceneY) | |
1569 { | |
1570 static const double ROUND_ANGLE = 15.0 / 180.0 * boost::math::constants::pi<double>(); | |
1571 | |
1572 double angle; | |
1573 | |
1574 if (accessor_.IsValid() && | |
1575 ComputeAngle(angle, sceneX, sceneY)) | |
1576 { | |
1577 angle = angle - clickAngle_ + originalAngle_; | |
1578 | |
1579 if (roundAngles_) | |
1580 { | |
1581 angle = round(angle / ROUND_ANGLE) * ROUND_ANGLE; | |
1582 } | |
1583 | |
1584 accessor_.GetBitmap().SetAngle(angle); | |
1585 } | |
1586 } | |
1587 }; | |
1588 | |
1589 | |
1590 class MoveBitmapTracker : public IWorldSceneMouseTracker | |
1591 { | |
1592 private: | |
1593 UndoRedoStack& undoRedoStack_; | |
1594 BitmapStack::BitmapAccessor accessor_; | |
1595 double clickX_; | |
1596 double clickY_; | |
1597 double panX_; | |
1598 double panY_; | |
1599 bool oneAxis_; | |
1600 | |
1601 class UndoRedoCommand : public BitmapCommandBase | |
1602 { | |
1603 private: | |
1604 double sourceX_; | |
1605 double sourceY_; | |
1606 double targetX_; | |
1607 double targetY_; | |
1608 | |
1609 protected: | |
1610 virtual void UndoInternal(BitmapStack::Bitmap& bitmap) const | |
1611 { | |
1612 bitmap.SetPan(sourceX_, sourceY_); | |
1613 } | |
1614 | |
1615 virtual void RedoInternal(BitmapStack::Bitmap& bitmap) const | |
1616 { | |
1617 bitmap.SetPan(targetX_, targetY_); | |
1618 } | |
1619 | |
1620 public: | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1621 UndoRedoCommand(const MoveBitmapTracker& tracker) : |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1622 BitmapCommandBase(tracker.accessor_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1623 sourceX_(tracker.panX_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1624 sourceY_(tracker.panY_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1625 targetX_(tracker.accessor_.GetBitmap().GetPanX()), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1626 targetY_(tracker.accessor_.GetBitmap().GetPanY()) |
354 | 1627 { |
1628 } | |
1629 }; | |
1630 | |
1631 | |
1632 public: | |
1633 MoveBitmapTracker(UndoRedoStack& undoRedoStack, | |
1634 BitmapStack& stack, | |
1635 size_t bitmap, | |
1636 double x, | |
1637 double y, | |
1638 bool oneAxis) : | |
1639 undoRedoStack_(undoRedoStack), | |
1640 accessor_(stack, bitmap), | |
1641 clickX_(x), | |
1642 clickY_(y), | |
1643 oneAxis_(oneAxis) | |
1644 { | |
1645 if (accessor_.IsValid()) | |
1646 { | |
1647 panX_ = accessor_.GetBitmap().GetPanX(); | |
1648 panY_ = accessor_.GetBitmap().GetPanY(); | |
1649 } | |
1650 } | |
1651 | |
1652 virtual bool HasRender() const | |
1653 { | |
1654 return false; | |
1655 } | |
1656 | |
1657 virtual void Render(CairoContext& context, | |
1658 double zoom) | |
1659 { | |
1660 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
1661 } | |
1662 | |
1663 virtual void MouseUp() | |
1664 { | |
1665 if (accessor_.IsValid()) | |
1666 { | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1667 undoRedoStack_.Add(new UndoRedoCommand(*this)); |
354 | 1668 } |
1669 } | |
1670 | |
1671 virtual void MouseMove(int displayX, | |
1672 int displayY, | |
1673 double sceneX, | |
1674 double sceneY) | |
1675 { | |
1676 if (accessor_.IsValid()) | |
1677 { | |
1678 double dx = sceneX - clickX_; | |
1679 double dy = sceneY - clickY_; | |
1680 | |
1681 if (oneAxis_) | |
1682 { | |
1683 if (fabs(dx) > fabs(dy)) | |
1684 { | |
1685 accessor_.GetBitmap().SetPan(dx + panX_, panY_); | |
1686 } | |
1687 else | |
1688 { | |
1689 accessor_.GetBitmap().SetPan(panX_, dy + panY_); | |
1690 } | |
1691 } | |
1692 else | |
1693 { | |
1694 accessor_.GetBitmap().SetPan(dx + panX_, dy + panY_); | |
1695 } | |
1696 } | |
1697 } | |
1698 }; | |
1699 | |
1700 | |
1701 class CropBitmapTracker : public IWorldSceneMouseTracker | |
1702 { | |
1703 private: | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1704 UndoRedoStack& undoRedoStack_; |
354 | 1705 BitmapStack::BitmapAccessor accessor_; |
1706 BitmapStack::Corner corner_; | |
1707 unsigned int cropX_; | |
1708 unsigned int cropY_; | |
1709 unsigned int cropWidth_; | |
1710 unsigned int cropHeight_; | |
1711 | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1712 class UndoRedoCommand : public BitmapCommandBase |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1713 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1714 private: |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1715 unsigned int sourceCropX_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1716 unsigned int sourceCropY_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1717 unsigned int sourceCropWidth_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1718 unsigned int sourceCropHeight_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1719 unsigned int targetCropX_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1720 unsigned int targetCropY_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1721 unsigned int targetCropWidth_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1722 unsigned int targetCropHeight_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1723 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1724 protected: |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1725 virtual void UndoInternal(BitmapStack::Bitmap& bitmap) const |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1726 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1727 bitmap.SetCrop(sourceCropX_, sourceCropY_, sourceCropWidth_, sourceCropHeight_); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1728 } |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1729 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1730 virtual void RedoInternal(BitmapStack::Bitmap& bitmap) const |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1731 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1732 bitmap.SetCrop(targetCropX_, targetCropY_, targetCropWidth_, targetCropHeight_); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1733 } |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1734 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1735 public: |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1736 UndoRedoCommand(const CropBitmapTracker& tracker) : |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1737 BitmapCommandBase(tracker.accessor_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1738 sourceCropX_(tracker.cropX_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1739 sourceCropY_(tracker.cropY_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1740 sourceCropWidth_(tracker.cropWidth_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1741 sourceCropHeight_(tracker.cropHeight_) |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1742 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1743 tracker.accessor_.GetBitmap().GetCrop(targetCropX_, targetCropY_, |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1744 targetCropWidth_, targetCropHeight_); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1745 } |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1746 }; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1747 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1748 |
354 | 1749 public: |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1750 CropBitmapTracker(UndoRedoStack& undoRedoStack, |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1751 BitmapStack& stack, |
354 | 1752 const ViewportGeometry& view, |
1753 size_t bitmap, | |
1754 double x, | |
1755 double y, | |
1756 BitmapStack::Corner corner) : | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1757 undoRedoStack_(undoRedoStack), |
354 | 1758 accessor_(stack, bitmap), |
1759 corner_(corner) | |
1760 { | |
1761 if (accessor_.IsValid()) | |
1762 { | |
1763 accessor_.GetBitmap().GetCrop(cropX_, cropY_, cropWidth_, cropHeight_); | |
1764 } | |
1765 } | |
1766 | |
1767 virtual bool HasRender() const | |
1768 { | |
1769 return false; | |
1770 } | |
1771 | |
1772 virtual void Render(CairoContext& context, | |
1773 double zoom) | |
1774 { | |
1775 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
1776 } | |
1777 | |
1778 virtual void MouseUp() | |
1779 { | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1780 if (accessor_.IsValid()) |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1781 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1782 undoRedoStack_.Add(new UndoRedoCommand(*this)); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1783 } |
354 | 1784 } |
1785 | |
1786 virtual void MouseMove(int displayX, | |
1787 int displayY, | |
1788 double sceneX, | |
1789 double sceneY) | |
1790 { | |
1791 if (accessor_.IsValid()) | |
1792 { | |
1793 unsigned int x, y; | |
1794 | |
1795 BitmapStack::Bitmap& bitmap = accessor_.GetBitmap(); | |
1796 if (bitmap.GetPixel(x, y, sceneX, sceneY)) | |
1797 { | |
1798 unsigned int targetX, targetWidth; | |
1799 | |
1800 if (corner_ == BitmapStack::Corner_TopLeft || | |
1801 corner_ == BitmapStack::Corner_BottomLeft) | |
1802 { | |
1803 targetX = std::min(x, cropX_ + cropWidth_); | |
1804 targetWidth = cropX_ + cropWidth_ - targetX; | |
1805 } | |
1806 else | |
1807 { | |
1808 targetX = cropX_; | |
1809 targetWidth = std::max(x, cropX_) - cropX_; | |
1810 } | |
1811 | |
1812 unsigned int targetY, targetHeight; | |
1813 | |
1814 if (corner_ == BitmapStack::Corner_TopLeft || | |
1815 corner_ == BitmapStack::Corner_TopRight) | |
1816 { | |
1817 targetY = std::min(y, cropY_ + cropHeight_); | |
1818 targetHeight = cropY_ + cropHeight_ - targetY; | |
1819 } | |
1820 else | |
1821 { | |
1822 targetY = cropY_; | |
1823 targetHeight = std::max(y, cropY_) - cropY_; | |
1824 } | |
1825 | |
1826 bitmap.SetCrop(targetX, targetY, targetWidth, targetHeight); | |
1827 } | |
1828 } | |
1829 } | |
1830 }; | |
1831 | |
1832 | |
1833 class ResizeBitmapTracker : public IWorldSceneMouseTracker | |
1834 { | |
1835 private: | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1836 UndoRedoStack& undoRedoStack_; |
354 | 1837 BitmapStack::BitmapAccessor accessor_; |
1838 bool roundScaling_; | |
1839 double originalSpacingX_; | |
1840 double originalSpacingY_; | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1841 double originalPanX_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1842 double originalPanY_; |
354 | 1843 BitmapStack::Corner oppositeCorner_; |
1844 double oppositeX_; | |
1845 double oppositeY_; | |
1846 double baseScaling_; | |
1847 | |
1848 static double ComputeDistance(double x1, | |
1849 double y1, | |
1850 double x2, | |
1851 double y2) | |
1852 { | |
1853 double dx = x1 - x2; | |
1854 double dy = y1 - y2; | |
1855 return sqrt(dx * dx + dy * dy); | |
1856 } | |
1857 | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1858 class UndoRedoCommand : public BitmapCommandBase |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1859 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1860 private: |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1861 double sourceSpacingX_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1862 double sourceSpacingY_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1863 double sourcePanX_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1864 double sourcePanY_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1865 double targetSpacingX_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1866 double targetSpacingY_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1867 double targetPanX_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1868 double targetPanY_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1869 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1870 protected: |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1871 virtual void UndoInternal(BitmapStack::Bitmap& bitmap) const |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1872 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1873 bitmap.SetPixelSpacing(sourceSpacingX_, sourceSpacingY_); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1874 bitmap.SetPan(sourcePanX_, sourcePanY_); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1875 } |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1876 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1877 virtual void RedoInternal(BitmapStack::Bitmap& bitmap) const |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1878 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1879 bitmap.SetPixelSpacing(targetSpacingX_, targetSpacingY_); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1880 bitmap.SetPan(targetPanX_, targetPanY_); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1881 } |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1882 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1883 public: |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1884 UndoRedoCommand(const ResizeBitmapTracker& tracker) : |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1885 BitmapCommandBase(tracker.accessor_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1886 sourceSpacingX_(tracker.originalSpacingX_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1887 sourceSpacingY_(tracker.originalSpacingY_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1888 sourcePanX_(tracker.originalPanX_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1889 sourcePanY_(tracker.originalPanY_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1890 targetSpacingX_(tracker.accessor_.GetBitmap().GetPixelSpacingX()), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1891 targetSpacingY_(tracker.accessor_.GetBitmap().GetPixelSpacingY()), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1892 targetPanX_(tracker.accessor_.GetBitmap().GetPanX()), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1893 targetPanY_(tracker.accessor_.GetBitmap().GetPanY()) |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1894 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1895 } |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1896 }; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1897 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1898 |
354 | 1899 public: |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1900 ResizeBitmapTracker(UndoRedoStack& undoRedoStack, |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1901 BitmapStack& stack, |
354 | 1902 size_t bitmap, |
1903 double x, | |
1904 double y, | |
1905 BitmapStack::Corner corner, | |
1906 bool roundScaling) : | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1907 undoRedoStack_(undoRedoStack), |
354 | 1908 accessor_(stack, bitmap), |
1909 roundScaling_(roundScaling) | |
1910 { | |
1911 if (accessor_.IsValid() && | |
1912 accessor_.GetBitmap().IsResizeable()) | |
1913 { | |
1914 originalSpacingX_ = accessor_.GetBitmap().GetPixelSpacingX(); | |
1915 originalSpacingY_ = accessor_.GetBitmap().GetPixelSpacingY(); | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1916 originalPanX_ = accessor_.GetBitmap().GetPanX(); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1917 originalPanY_ = accessor_.GetBitmap().GetPanY(); |
354 | 1918 |
1919 switch (corner) | |
1920 { | |
1921 case BitmapStack::Corner_TopLeft: | |
1922 oppositeCorner_ = BitmapStack::Corner_BottomRight; | |
1923 break; | |
1924 | |
1925 case BitmapStack::Corner_TopRight: | |
1926 oppositeCorner_ = BitmapStack::Corner_BottomLeft; | |
1927 break; | |
1928 | |
1929 case BitmapStack::Corner_BottomLeft: | |
1930 oppositeCorner_ = BitmapStack::Corner_TopRight; | |
1931 break; | |
1932 | |
1933 case BitmapStack::Corner_BottomRight: | |
1934 oppositeCorner_ = BitmapStack::Corner_TopLeft; | |
1935 break; | |
1936 | |
1937 default: | |
1938 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
1939 } | |
1940 | |
1941 accessor_.GetBitmap().GetCorner(oppositeX_, oppositeY_, oppositeCorner_); | |
1942 | |
1943 double d = ComputeDistance(x, y, oppositeX_, oppositeY_); | |
1944 if (d >= std::numeric_limits<float>::epsilon()) | |
1945 { | |
1946 baseScaling_ = 1.0 / d; | |
1947 } | |
1948 else | |
1949 { | |
1950 // Avoid division by zero in extreme cases | |
1951 accessor_.Invalidate(); | |
1952 } | |
1953 } | |
1954 } | |
1955 | |
1956 virtual bool HasRender() const | |
1957 { | |
1958 return false; | |
1959 } | |
1960 | |
1961 virtual void Render(CairoContext& context, | |
1962 double zoom) | |
1963 { | |
1964 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
1965 } | |
1966 | |
1967 virtual void MouseUp() | |
1968 { | |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
1969 if (accessor_.IsValid() && |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
1970 accessor_.GetBitmap().IsResizeable()) |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1971 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1972 undoRedoStack_.Add(new UndoRedoCommand(*this)); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1973 } |
354 | 1974 } |
1975 | |
1976 virtual void MouseMove(int displayX, | |
1977 int displayY, | |
1978 double sceneX, | |
1979 double sceneY) | |
1980 { | |
1981 static const double ROUND_SCALING = 0.1; | |
1982 | |
1983 if (accessor_.IsValid() && | |
1984 accessor_.GetBitmap().IsResizeable()) | |
1985 { | |
1986 double scaling = ComputeDistance(oppositeX_, oppositeY_, sceneX, sceneY) * baseScaling_; | |
1987 | |
1988 if (roundScaling_) | |
1989 { | |
1990 scaling = round(scaling / ROUND_SCALING) * ROUND_SCALING; | |
1991 } | |
1992 | |
1993 BitmapStack::Bitmap& bitmap = accessor_.GetBitmap(); | |
1994 bitmap.SetPixelSpacing(scaling * originalSpacingX_, | |
1995 scaling * originalSpacingY_); | |
1996 | |
1997 // Keep the opposite corner at a fixed location | |
1998 double ox, oy; | |
1999 bitmap.GetCorner(ox, oy, oppositeCorner_); | |
2000 bitmap.SetPan(bitmap.GetPanX() + oppositeX_ - ox, | |
2001 bitmap.GetPanY() + oppositeY_ - oy); | |
2002 } | |
2003 } | |
2004 }; | |
2005 | |
2006 | |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2007 class WindowingTracker : public IWorldSceneMouseTracker |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2008 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2009 public: |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2010 enum Action |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2011 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2012 Action_IncreaseWidth, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2013 Action_DecreaseWidth, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2014 Action_IncreaseCenter, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2015 Action_DecreaseCenter |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2016 }; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2017 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2018 private: |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2019 UndoRedoStack& undoRedoStack_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2020 BitmapStack& stack_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2021 int clickX_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2022 int clickY_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2023 Action leftAction_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2024 Action rightAction_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2025 Action upAction_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2026 Action downAction_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2027 float strength_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2028 float sourceCenter_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2029 float sourceWidth_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2030 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2031 static void ComputeAxisEffect(int& deltaCenter, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2032 int& deltaWidth, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2033 int delta, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2034 Action actionNegative, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2035 Action actionPositive) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2036 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2037 if (delta < 0) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2038 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2039 switch (actionNegative) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2040 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2041 case Action_IncreaseWidth: |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2042 deltaWidth = -delta; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2043 break; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2044 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2045 case Action_DecreaseWidth: |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2046 deltaWidth = delta; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2047 break; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2048 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2049 case Action_IncreaseCenter: |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2050 deltaCenter = -delta; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2051 break; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2052 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2053 case Action_DecreaseCenter: |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2054 deltaCenter = delta; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2055 break; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2056 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2057 default: |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2058 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2059 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2060 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2061 else if (delta > 0) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2062 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2063 switch (actionPositive) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2064 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2065 case Action_IncreaseWidth: |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2066 deltaWidth = delta; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2067 break; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2068 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2069 case Action_DecreaseWidth: |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2070 deltaWidth = -delta; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2071 break; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2072 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2073 case Action_IncreaseCenter: |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2074 deltaCenter = delta; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2075 break; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2076 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2077 case Action_DecreaseCenter: |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2078 deltaCenter = -delta; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2079 break; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2080 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2081 default: |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2082 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2083 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2084 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2085 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2086 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2087 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2088 class UndoRedoCommand : public UndoRedoStack::ICommand |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2089 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2090 private: |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2091 BitmapStack& stack_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2092 float sourceCenter_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2093 float sourceWidth_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2094 float targetCenter_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2095 float targetWidth_; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2096 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2097 public: |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2098 UndoRedoCommand(const WindowingTracker& tracker) : |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2099 stack_(tracker.stack_), |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2100 sourceCenter_(tracker.sourceCenter_), |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2101 sourceWidth_(tracker.sourceWidth_) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2102 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2103 stack_.GetWindowingWithDefault(targetCenter_, targetWidth_); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2104 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2105 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2106 virtual void Undo() const |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2107 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2108 stack_.SetWindowing(sourceCenter_, sourceWidth_); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2109 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2110 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2111 virtual void Redo() const |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2112 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2113 stack_.SetWindowing(targetCenter_, targetWidth_); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2114 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2115 }; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2116 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2117 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2118 public: |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2119 WindowingTracker(UndoRedoStack& undoRedoStack, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2120 BitmapStack& stack, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2121 int x, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2122 int y, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2123 Action leftAction, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2124 Action rightAction, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2125 Action upAction, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2126 Action downAction) : |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2127 undoRedoStack_(undoRedoStack), |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2128 stack_(stack), |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2129 clickX_(x), |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2130 clickY_(y), |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2131 leftAction_(leftAction), |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2132 rightAction_(rightAction), |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2133 upAction_(upAction), |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2134 downAction_(downAction) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2135 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2136 stack_.GetWindowingWithDefault(sourceCenter_, sourceWidth_); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2137 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2138 float minValue, maxValue; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2139 stack.GetRange(minValue, maxValue); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2140 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2141 assert(minValue <= maxValue); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2142 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2143 float tmp; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2144 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2145 float delta = (maxValue - minValue); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2146 if (delta <= 1) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2147 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2148 tmp = 0; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2149 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2150 else |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2151 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2152 tmp = log2(delta); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2153 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2154 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2155 strength_ = tmp - 7; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2156 if (strength_ < 1) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2157 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2158 strength_ = 1; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2159 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2160 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2161 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2162 virtual bool HasRender() const |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2163 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2164 return false; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2165 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2166 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2167 virtual void Render(CairoContext& context, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2168 double zoom) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2169 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2170 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2171 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2172 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2173 virtual void MouseUp() |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2174 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2175 undoRedoStack_.Add(new UndoRedoCommand(*this)); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2176 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2177 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2178 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2179 virtual void MouseMove(int displayX, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2180 int displayY, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2181 double sceneX, |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2182 double sceneY) |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2183 { |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2184 // https://bitbucket.org/osimis/osimis-webviewer-plugin/src/master/frontend/src/app/viewport/image-plugins/windowing-viewport-tool.class.js |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2185 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2186 static const float SCALE = 1.0; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2187 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2188 int deltaCenter = 0; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2189 int deltaWidth = 0; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2190 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2191 ComputeAxisEffect(deltaCenter, deltaWidth, displayX - clickX_, leftAction_, rightAction_); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2192 ComputeAxisEffect(deltaCenter, deltaWidth, displayY - clickY_, upAction_, downAction_); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2193 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2194 float newCenter = sourceCenter_ + (deltaCenter / SCALE * strength_); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2195 float newWidth = sourceWidth_ + (deltaWidth / SCALE * strength_); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2196 stack_.SetWindowing(newCenter, newWidth); |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2197 } |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2198 }; |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2199 |
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2200 |
338 | 2201 class BitmapStackWidget : |
2202 public WorldSceneWidget, | |
2203 public IObservable, | |
2204 public IObserver | |
2205 { | |
2206 private: | |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2207 BitmapStack& stack_; |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2208 std::auto_ptr<Orthanc::Image> floatBuffer_; |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2209 std::auto_ptr<CairoSurface> cairoBuffer_; |
358 | 2210 bool invert_; |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2211 ImageInterpolation interpolation_; |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2212 |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2213 virtual bool RenderInternal(unsigned int width, |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2214 unsigned int height, |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2215 ImageInterpolation interpolation) |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2216 { |
339 | 2217 float windowCenter, windowWidth; |
356
885f0a5eaa49
mouse tracker to set windowing
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
355
diff
changeset
|
2218 stack_.GetWindowingWithDefault(windowCenter, windowWidth); |
339 | 2219 |
2220 float x0 = windowCenter - windowWidth / 2.0f; | |
2221 float x1 = windowCenter + windowWidth / 2.0f; | |
2222 | |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2223 if (windowWidth <= 0.001f) // Avoid division by zero at (*) |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2224 { |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2225 return false; |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2226 } |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2227 else |
339 | 2228 { |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2229 if (floatBuffer_.get() == NULL || |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2230 floatBuffer_->GetWidth() != width || |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2231 floatBuffer_->GetHeight() != height) |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2232 { |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2233 floatBuffer_.reset(new Orthanc::Image(Orthanc::PixelFormat_Float32, width, height, false)); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2234 } |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2235 |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2236 if (cairoBuffer_.get() == NULL || |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2237 cairoBuffer_->GetWidth() != width || |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2238 cairoBuffer_->GetHeight() != height) |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2239 { |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2240 cairoBuffer_.reset(new CairoSurface(width, height)); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2241 } |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2242 |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2243 stack_.Render(*floatBuffer_, GetView(), interpolation); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2244 |
360 | 2245 // Conversion from Float32 to BGRA32 (cairo). Very similar to |
2246 // GrayscaleFrameRenderer => TODO MERGE? | |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2247 |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2248 Orthanc::ImageAccessor target; |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2249 cairoBuffer_->GetAccessor(target); |
360 | 2250 |
2251 float scaling = 255.0f / (x1 - x0); | |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2252 |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2253 for (unsigned int y = 0; y < height; y++) |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2254 { |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2255 const float* p = reinterpret_cast<const float*>(floatBuffer_->GetConstRow(y)); |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2256 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); |
339 | 2257 |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2258 for (unsigned int x = 0; x < width; x++, p++, q += 4) |
339 | 2259 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2260 uint8_t v = 0; |
339 | 2261 if (*p >= x1) |
2262 { | |
2263 v = 255; | |
2264 } | |
2265 else if (*p <= x0) | |
2266 { | |
2267 v = 0; | |
2268 } | |
2269 else | |
2270 { | |
2271 // https://en.wikipedia.org/wiki/Linear_interpolation | |
360 | 2272 v = static_cast<uint8_t>(scaling * (*p - x0)); // (*) |
339 | 2273 } |
2274 | |
358 | 2275 if (invert_) |
2276 { | |
339 | 2277 v = 255 - v; |
358 | 2278 } |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2279 |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2280 q[0] = v; |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2281 q[1] = v; |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2282 q[2] = v; |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2283 q[3] = 255; |
339 | 2284 } |
2285 } | |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2286 |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2287 return true; |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2288 } |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2289 } |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2290 |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2291 |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2292 protected: |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2293 virtual Extent2D GetSceneExtent() |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2294 { |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2295 return stack_.GetSceneExtent(); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2296 } |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2297 |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2298 virtual bool RenderScene(CairoContext& context, |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2299 const ViewportGeometry& view) |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2300 { |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2301 cairo_t* cr = context.GetObject(); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2302 |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2303 if (RenderInternal(context.GetWidth(), context.GetHeight(), interpolation_)) |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2304 { |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2305 // https://www.cairographics.org/FAQ/#paint_from_a_surface |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2306 cairo_save(cr); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2307 cairo_identity_matrix(cr); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2308 cairo_set_source_surface(cr, cairoBuffer_->GetObject(), 0, 0); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2309 cairo_paint(cr); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2310 cairo_restore(cr); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2311 } |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2312 else |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2313 { |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2314 // https://www.cairographics.org/FAQ/#clear_a_surface |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2315 context.SetSourceColor(0, 0, 0); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2316 cairo_paint(cr); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2317 } |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2318 |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2319 stack_.DrawControls(context, view.GetZoom()); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2320 |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2321 return true; |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2322 } |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2323 |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2324 public: |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2325 BitmapStackWidget(MessageBroker& broker, |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2326 BitmapStack& stack, |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2327 const std::string& name) : |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2328 WorldSceneWidget(name), |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2329 IObservable(broker), |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2330 IObserver(broker), |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2331 stack_(stack), |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2332 invert_(false), |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2333 interpolation_(ImageInterpolation_Nearest) |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2334 { |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2335 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::GeometryChangedMessage>(*this, &BitmapStackWidget::OnGeometryChanged)); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2336 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::ContentChangedMessage>(*this, &BitmapStackWidget::OnContentChanged)); |
358 | 2337 } |
2338 | |
2339 BitmapStack& GetStack() const | |
2340 { | |
2341 return stack_; | |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2342 } |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2343 |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2344 void OnGeometryChanged(const BitmapStack::GeometryChangedMessage& message) |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2345 { |
358 | 2346 LOG(INFO) << "Geometry has changed"; |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2347 FitContent(); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2348 } |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2349 |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2350 void OnContentChanged(const BitmapStack::ContentChangedMessage& message) |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2351 { |
358 | 2352 LOG(INFO) << "Content has changed"; |
2353 NotifyContentChanged(); | |
2354 } | |
2355 | |
2356 void SetInvert(bool invert) | |
2357 { | |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2358 if (invert_ != invert) |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2359 { |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2360 invert_ = invert; |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2361 NotifyContentChanged(); |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2362 } |
358 | 2363 } |
2364 | |
2365 void SwitchInvert() | |
2366 { | |
2367 invert_ = !invert_; | |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2368 NotifyContentChanged(); |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2369 } |
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2370 |
358 | 2371 bool IsInvert() const |
2372 { | |
2373 return invert_; | |
2374 } | |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2375 |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2376 void SetInterpolation(ImageInterpolation interpolation) |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2377 { |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2378 if (interpolation_ != interpolation) |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2379 { |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2380 interpolation_ = interpolation; |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2381 NotifyContentChanged(); |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2382 } |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2383 } |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2384 |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2385 ImageInterpolation GetInterpolation() const |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2386 { |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2387 return interpolation_; |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2388 } |
358 | 2389 }; |
2390 | |
2391 | |
2392 class BitmapStackInteractor : public IWorldSceneInteractor | |
2393 { | |
2394 private: | |
2395 enum Tool | |
2396 { | |
2397 Tool_Move, | |
2398 Tool_Rotate, | |
2399 Tool_Crop, | |
2400 Tool_Resize, | |
2401 Tool_Windowing | |
2402 }; | |
2403 | |
2404 | |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2405 UndoRedoStack undoRedoStack_; |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2406 Tool tool_; |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2407 OrthancApiClient *orthanc_; |
358 | 2408 |
2409 | |
2410 static double GetHandleSize() | |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2411 { |
358 | 2412 return 10.0; |
2413 } | |
2414 | |
2415 | |
2416 static BitmapStackWidget& GetWidget(WorldSceneWidget& widget) | |
2417 { | |
2418 return dynamic_cast<BitmapStackWidget&>(widget); | |
2419 } | |
2420 | |
2421 | |
2422 static BitmapStack& GetStack(WorldSceneWidget& widget) | |
2423 { | |
2424 return GetWidget(widget).GetStack(); | |
2425 } | |
2426 | |
2427 | |
2428 public: | |
2429 BitmapStackInteractor() : | |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2430 tool_(Tool_Move), |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2431 orthanc_(NULL) |
358 | 2432 { |
2433 } | |
2434 | |
2435 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, | |
2436 const ViewportGeometry& view, | |
2437 MouseButton button, | |
2438 KeyboardModifiers modifiers, | |
2439 int viewportX, | |
2440 int viewportY, | |
2441 double x, | |
2442 double y, | |
2443 IStatusBar* statusBar) | |
2444 { | |
2445 if (button == MouseButton_Left) | |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2446 { |
358 | 2447 size_t selected; |
2448 | |
2449 if (tool_ == Tool_Windowing) | |
2450 { | |
2451 return new WindowingTracker(undoRedoStack_, GetStack(widget), | |
2452 viewportX, viewportY, | |
2453 WindowingTracker::Action_DecreaseWidth, | |
2454 WindowingTracker::Action_IncreaseWidth, | |
2455 WindowingTracker::Action_DecreaseCenter, | |
2456 WindowingTracker::Action_IncreaseCenter); | |
2457 } | |
2458 else if (!GetStack(widget).GetSelectedBitmap(selected)) | |
2459 { | |
2460 size_t bitmap; | |
2461 if (GetStack(widget).LookupBitmap(bitmap, x, y)) | |
2462 { | |
2463 LOG(INFO) << "Click on bitmap " << bitmap; | |
2464 GetStack(widget).Select(bitmap); | |
2465 } | |
2466 | |
2467 return NULL; | |
2468 } | |
2469 else if (tool_ == Tool_Crop || | |
2470 tool_ == Tool_Resize) | |
2471 { | |
2472 BitmapStack::BitmapAccessor accessor(GetStack(widget), selected); | |
2473 BitmapStack::Corner corner; | |
2474 if (accessor.GetBitmap().LookupCorner(corner, x, y, view.GetZoom(), GetHandleSize())) | |
2475 { | |
2476 switch (tool_) | |
2477 { | |
2478 case Tool_Crop: | |
2479 return new CropBitmapTracker(undoRedoStack_, GetStack(widget), view, selected, x, y, corner); | |
2480 | |
2481 case Tool_Resize: | |
2482 return new ResizeBitmapTracker(undoRedoStack_, GetStack(widget), selected, x, y, corner, | |
2483 (modifiers & KeyboardModifiers_Shift)); | |
2484 | |
2485 default: | |
2486 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
2487 } | |
2488 } | |
2489 else | |
2490 { | |
2491 size_t bitmap; | |
2492 | |
2493 if (!GetStack(widget).LookupBitmap(bitmap, x, y) || | |
2494 bitmap != selected) | |
2495 { | |
2496 GetStack(widget).Unselect(); | |
2497 } | |
2498 | |
2499 return NULL; | |
2500 } | |
2501 } | |
2502 else | |
2503 { | |
2504 size_t bitmap; | |
2505 | |
2506 if (GetStack(widget).LookupBitmap(bitmap, x, y) && | |
2507 bitmap == selected) | |
2508 { | |
2509 switch (tool_) | |
2510 { | |
2511 case Tool_Move: | |
2512 return new MoveBitmapTracker(undoRedoStack_, GetStack(widget), bitmap, x, y, | |
2513 (modifiers & KeyboardModifiers_Shift)); | |
2514 | |
2515 case Tool_Rotate: | |
2516 return new RotateBitmapTracker(undoRedoStack_, GetStack(widget), view, bitmap, x, y, | |
2517 (modifiers & KeyboardModifiers_Shift)); | |
2518 | |
2519 default: | |
2520 break; | |
2521 } | |
2522 | |
2523 return NULL; | |
2524 } | |
2525 else | |
2526 { | |
2527 LOG(INFO) << "Click out of any bitmap"; | |
2528 GetStack(widget).Unselect(); | |
2529 return NULL; | |
2530 } | |
2531 } | |
339 | 2532 } |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2533 else |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2534 { |
358 | 2535 return NULL; |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2536 } |
358 | 2537 } |
2538 | |
2539 virtual void MouseOver(CairoContext& context, | |
2540 WorldSceneWidget& widget, | |
2541 const ViewportGeometry& view, | |
2542 double x, | |
2543 double y, | |
2544 IStatusBar* statusBar) | |
2545 { | |
2546 #if 0 | |
2547 if (statusBar != NULL) | |
2548 { | |
2549 char buf[64]; | |
2550 sprintf(buf, "X = %.02f Y = %.02f (in cm)", x / 10.0, y / 10.0); | |
2551 statusBar->SetMessage(buf); | |
2552 } | |
2553 #endif | |
2554 | |
2555 size_t selected; | |
2556 if (GetStack(widget).GetSelectedBitmap(selected) && | |
2557 (tool_ == Tool_Crop || | |
2558 tool_ == Tool_Resize)) | |
345 | 2559 { |
358 | 2560 BitmapStack::BitmapAccessor accessor(GetStack(widget), selected); |
2561 | |
2562 BitmapStack::Corner corner; | |
2563 if (accessor.GetBitmap().LookupCorner(corner, x, y, view.GetZoom(), GetHandleSize())) | |
2564 { | |
2565 accessor.GetBitmap().GetCorner(x, y, corner); | |
2566 | |
2567 double z = 1.0 / view.GetZoom(); | |
2568 | |
2569 context.SetSourceColor(255, 0, 0); | |
2570 cairo_t* cr = context.GetObject(); | |
2571 cairo_set_line_width(cr, 2.0 * z); | |
2572 cairo_move_to(cr, x - GetHandleSize() * z, y - GetHandleSize() * z); | |
2573 cairo_line_to(cr, x + GetHandleSize() * z, y - GetHandleSize() * z); | |
2574 cairo_line_to(cr, x + GetHandleSize() * z, y + GetHandleSize() * z); | |
2575 cairo_line_to(cr, x - GetHandleSize() * z, y + GetHandleSize() * z); | |
2576 cairo_line_to(cr, x - GetHandleSize() * z, y - GetHandleSize() * z); | |
2577 cairo_stroke(cr); | |
2578 } | |
345 | 2579 } |
358 | 2580 } |
2581 | |
2582 virtual void MouseWheel(WorldSceneWidget& widget, | |
2583 MouseWheelDirection direction, | |
2584 KeyboardModifiers modifiers, | |
2585 IStatusBar* statusBar) | |
2586 { | |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2587 } |
358 | 2588 |
2589 virtual void KeyPressed(WorldSceneWidget& widget, | |
2590 KeyboardKeys key, | |
2591 char keyChar, | |
2592 KeyboardModifiers modifiers, | |
2593 IStatusBar* statusBar) | |
2594 { | |
2595 switch (keyChar) | |
2596 { | |
2597 case 'a': | |
2598 widget.FitContent(); | |
2599 break; | |
2600 | |
2601 case 'c': | |
2602 tool_ = Tool_Crop; | |
2603 break; | |
2604 | |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2605 case 'e': |
360 | 2606 Export(GetStack(widget), 0.1, 0.1, GetWidget(widget).GetInterpolation()); |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2607 break; |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2608 |
358 | 2609 case 'i': |
360 | 2610 GetWidget(widget).SwitchInvert(); |
358 | 2611 break; |
2612 | |
2613 case 'm': | |
2614 tool_ = Tool_Move; | |
2615 break; | |
2616 | |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2617 case 'n': |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2618 { |
360 | 2619 switch (GetWidget(widget).GetInterpolation()) |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2620 { |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2621 case ImageInterpolation_Nearest: |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2622 LOG(INFO) << "Switching to bilinear interpolation"; |
360 | 2623 GetWidget(widget).SetInterpolation(ImageInterpolation_Bilinear); |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2624 break; |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2625 |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2626 case ImageInterpolation_Bilinear: |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2627 LOG(INFO) << "Switching to nearest neighbor interpolation"; |
360 | 2628 GetWidget(widget).SetInterpolation(ImageInterpolation_Nearest); |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2629 break; |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2630 |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2631 default: |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2632 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2633 } |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2634 |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2635 break; |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2636 } |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2637 |
358 | 2638 case 'r': |
2639 tool_ = Tool_Rotate; | |
2640 break; | |
2641 | |
2642 case 's': | |
2643 tool_ = Tool_Resize; | |
2644 break; | |
2645 | |
2646 case 'w': | |
2647 tool_ = Tool_Windowing; | |
2648 break; | |
2649 | |
2650 case 'y': | |
2651 if (modifiers & KeyboardModifiers_Control) | |
2652 { | |
2653 undoRedoStack_.Redo(); | |
2654 widget.NotifyContentChanged(); | |
2655 } | |
2656 break; | |
2657 | |
2658 case 'z': | |
2659 if (modifiers & KeyboardModifiers_Control) | |
2660 { | |
2661 undoRedoStack_.Undo(); | |
2662 widget.NotifyContentChanged(); | |
2663 } | |
2664 break; | |
2665 | |
2666 default: | |
2667 break; | |
2668 } | |
2669 } | |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2670 |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2671 |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2672 void SetOrthanc(OrthancApiClient& orthanc) |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2673 { |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2674 orthanc_ = &orthanc; |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2675 } |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2676 |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2677 |
360 | 2678 void Export(const BitmapStack& stack, |
2679 double pixelSpacingX, | |
2680 double pixelSpacingY, | |
2681 ImageInterpolation interpolation) | |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2682 { |
360 | 2683 if (pixelSpacingX <= 0 || |
2684 pixelSpacingY <= 0) | |
2685 { | |
2686 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
2687 } | |
2688 | |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2689 if (orthanc_ == NULL) |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2690 { |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2691 return; |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2692 } |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2693 |
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2694 LOG(WARNING) << "Exporting DICOM"; |
360 | 2695 |
2696 Extent2D extent = stack.GetSceneExtent(); | |
2697 | |
2698 int w = std::ceil(extent.GetWidth() / pixelSpacingX); | |
2699 int h = std::ceil(extent.GetHeight() / pixelSpacingY); | |
2700 | |
2701 if (w < 0 || h < 0) | |
2702 { | |
2703 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
2704 } | |
2705 | |
2706 Orthanc::Image layers(Orthanc::PixelFormat_Float32, | |
2707 static_cast<unsigned int>(w), | |
2708 static_cast<unsigned int>(h), false); | |
2709 | |
2710 ViewportGeometry view; | |
2711 view.SetDisplaySize(layers.GetWidth(), layers.GetHeight()); | |
2712 view.SetSceneExtent(extent); | |
2713 view.FitContent(); | |
2714 | |
2715 stack.Render(layers, view, interpolation); | |
2716 | |
2717 Orthanc::Image rendered(Orthanc::PixelFormat_Grayscale16, | |
2718 layers.GetWidth(), layers.GetHeight(), false); | |
2719 Orthanc::ImageProcessing::Convert(rendered, layers); | |
2720 | |
2721 Orthanc::PngWriter png; | |
2722 png.WriteToFile("/tmp/a.png", rendered); | |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2723 } |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2724 }; |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2725 |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2726 |
358 | 2727 |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2728 namespace Samples |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2729 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2730 class SingleFrameEditorApplication : |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2731 public SampleSingleCanvasApplicationBase, |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2732 public IObserver |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2733 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2734 private: |
334
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
2735 std::auto_ptr<OrthancApiClient> orthancApiClient_; |
338 | 2736 std::auto_ptr<BitmapStack> stack_; |
358 | 2737 BitmapStackInteractor interactor_; |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2738 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2739 public: |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2740 SingleFrameEditorApplication(MessageBroker& broker) : |
358 | 2741 IObserver(broker) |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2742 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2743 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2744 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2745 virtual void DeclareStartupOptions(boost::program_options::options_description& options) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2746 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2747 boost::program_options::options_description generic("Sample options"); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2748 generic.add_options() |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2749 ("instance", boost::program_options::value<std::string>(), |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2750 "Orthanc ID of the instance") |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2751 ("frame", boost::program_options::value<unsigned int>()->default_value(0), |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2752 "Number of the frame, for multi-frame DICOM instances") |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2753 ; |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2754 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2755 options.add(generic); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2756 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2757 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2758 virtual void Initialize(StoneApplicationContext* context, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2759 IStatusBar& statusBar, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2760 const boost::program_options::variables_map& parameters) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2761 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2762 using namespace OrthancStone; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2763 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2764 context_ = context; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2765 |
358 | 2766 statusBar.SetMessage("Use the key \"a\" to reinitialize the layout"); |
2767 statusBar.SetMessage("Use the key \"c\" to crop"); | |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2768 statusBar.SetMessage("Use the key \"e\" to export DICOM to the Orthanc server"); |
358 | 2769 statusBar.SetMessage("Use the key \"f\" to switch full screen"); |
2770 statusBar.SetMessage("Use the key \"i\" to invert contrast"); | |
2771 statusBar.SetMessage("Use the key \"m\" to move objects"); | |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2772 statusBar.SetMessage("Use the key \"n\" to switch between nearest neighbor and bilinear interpolation"); |
358 | 2773 statusBar.SetMessage("Use the key \"r\" to rotate objects"); |
2774 statusBar.SetMessage("Use the key \"s\" to resize objects (not applicable to DICOM bitmaps)"); | |
2775 statusBar.SetMessage("Use the key \"w\" to change windowing"); | |
2776 | |
2777 statusBar.SetMessage("Use the key \"ctrl-z\" to undo action"); | |
2778 statusBar.SetMessage("Use the key \"ctrl-y\" to redo action"); | |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2779 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2780 if (parameters.count("instance") != 1) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2781 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2782 LOG(ERROR) << "The instance ID is missing"; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2783 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2784 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2785 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2786 std::string instance = parameters["instance"].as<std::string>(); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2787 int frame = parameters["frame"].as<unsigned int>(); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2788 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2789 orthancApiClient_.reset(new OrthancApiClient(IObserver::broker_, context_->GetWebService())); |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2790 interactor_.SetOrthanc(*orthancApiClient_); |
337 | 2791 |
343 | 2792 Orthanc::FontRegistry fonts; |
2793 fonts.AddFromResource(Orthanc::EmbeddedResources::FONT_UBUNTU_MONO_BOLD_16); | |
2794 | |
338 | 2795 stack_.reset(new BitmapStack(IObserver::broker_, *orthancApiClient_)); |
358 | 2796 stack_->LoadFrame(instance, frame, false).SetPan(200, 0); |
2797 //stack_->LoadFrame("61f3143e-96f34791-ad6bbb8d-62559e75-45943e1b", 0, false); | |
354 | 2798 |
2799 { | |
359
100df90bf0ea
preparing to implement Export
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
358
diff
changeset
|
2800 BitmapStack::Bitmap& bitmap = stack_->LoadText(fonts.GetFont(0), "Hello\nworld"); |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2801 //dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetForegroundValue(256); |
354 | 2802 dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetResizeable(true); |
2803 } | |
2804 | |
2805 { | |
2806 BitmapStack::Bitmap& bitmap = stack_->LoadTestBlock(100, 50); | |
357
ec4ad6c5eb99
avoid breaking class hierarchy
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
356
diff
changeset
|
2807 //dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetForegroundValue(256); |
354 | 2808 dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetResizeable(true); |
358 | 2809 dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetPan(0, 200); |
354 | 2810 } |
2811 | |
337 | 2812 |
338 | 2813 mainWidget_ = new BitmapStackWidget(IObserver::broker_, *stack_, "main-widget"); |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2814 mainWidget_->SetTransmitMouseOver(true); |
358 | 2815 mainWidget_->SetInteractor(interactor_); |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2816 |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2817 //stack_->SetWindowing(128, 256); |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2818 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2819 }; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2820 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2821 } |