comparison Applications/Samples/SingleFrameEditorApplication.h @ 343:712acc87fa2e am-2

text layer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 22 Oct 2018 14:20:39 +0200
parents 4297d6c5eef9
children fdec8e6893cb
comparison
equal deleted inserted replaced
342:4297d6c5eef9 343:712acc87fa2e
26 #include "../../Framework/Toolbox/GeometryToolbox.h" 26 #include "../../Framework/Toolbox/GeometryToolbox.h"
27 #include "../../Framework/Toolbox/ImageGeometry.h" 27 #include "../../Framework/Toolbox/ImageGeometry.h"
28 #include "../../Framework/Layers/OrthancFrameLayerSource.h" 28 #include "../../Framework/Layers/OrthancFrameLayerSource.h"
29 29
30 #include <Core/DicomFormat/DicomArray.h> 30 #include <Core/DicomFormat/DicomArray.h>
31 #include <Core/Images/FontRegistry.h>
31 #include <Core/Images/ImageProcessing.h> 32 #include <Core/Images/ImageProcessing.h>
32 #include <Core/Images/PamReader.h> 33 #include <Core/Images/PamReader.h>
34 #include <Core/Images/PngWriter.h> //TODO
33 #include <Core/Logging.h> 35 #include <Core/Logging.h>
34 #include <Plugins/Samples/Common/FullOrthancDataset.h> 36 #include <Plugins/Samples/Common/FullOrthancDataset.h>
35 #include <Plugins/Samples/Common/DicomDatasetReader.h> 37 #include <Plugins/Samples/Common/DicomDatasetReader.h>
36 38
37 39
49 51
50 private: 52 private:
51 class Bitmap : public boost::noncopyable 53 class Bitmap : public boost::noncopyable
52 { 54 {
53 private: 55 private:
54 bool visible_; 56 bool visible_;
55 std::auto_ptr<Orthanc::ImageAccessor> source_; 57 bool hasSize_;
56 std::auto_ptr<Orthanc::ImageAccessor> converted_; // Float32 or RGB24 58 unsigned int width_;
57 std::auto_ptr<Orthanc::Image> alpha_; // Grayscale8 (if any) 59 unsigned int height_;
58 std::auto_ptr<DicomFrameConverter> converter_; 60 bool hasCrop_;
59 unsigned int width_; 61 unsigned int cropX_;
60 unsigned int height_; 62 unsigned int cropY_;
61 bool hasCrop_; 63 unsigned int cropWidth_;
62 unsigned int cropX_; 64 unsigned int cropHeight_;
63 unsigned int cropY_; 65 Matrix transform_;
64 unsigned int cropWidth_; 66 double pixelSpacingX_;
65 unsigned int cropHeight_; 67 double pixelSpacingY_;
66 Matrix transform_; 68 double panX_;
67 double pixelSpacingX_; 69 double panY_;
68 double pixelSpacingY_;
69 double panX_;
70 double panY_;
71 70
72 71
73 void UpdateTransform() 72 void UpdateTransform()
74 { 73 {
75 transform_ = LinearAlgebra::IdentityMatrix(3); 74 transform_ = LinearAlgebra::IdentityMatrix(3);
90 transform_ = LinearAlgebra::Product(m, transform_); 89 transform_ = LinearAlgebra::Product(m, transform_);
91 #endif 90 #endif
92 } 91 }
93 92
94 93
95 void ApplyConverter()
96 {
97 if (source_.get() != NULL &&
98 converter_.get() != NULL)
99 {
100 if (width_ != source_->GetWidth() ||
101 height_ != source_->GetHeight())
102 {
103 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
104 }
105
106 printf("CONVERTED! %dx%d\n", width_, height_);
107 converted_.reset(converter_->ConvertFrame(*source_));
108 }
109 }
110
111 void AddToExtent(Extent2D& extent, 94 void AddToExtent(Extent2D& extent,
112 double x, 95 double x,
113 double y) const 96 double y) const
114 { 97 {
115 Vector p; 98 Vector p;
129 112
130 113
131 public: 114 public:
132 Bitmap() : 115 Bitmap() :
133 visible_(true), 116 visible_(true),
117 hasSize_(false),
134 width_(0), 118 width_(0),
135 height_(0), 119 height_(0),
136 hasCrop_(false), 120 hasCrop_(false),
137 pixelSpacingX_(1), 121 pixelSpacingX_(1),
138 pixelSpacingY_(1), 122 pixelSpacingY_(1),
140 panY_(0) 124 panY_(0)
141 { 125 {
142 UpdateTransform(); 126 UpdateTransform();
143 } 127 }
144 128
129 virtual ~Bitmap()
130 {
131 }
132
145 void ResetCrop() 133 void ResetCrop()
146 { 134 {
147 hasCrop_ = false; 135 hasCrop_ = false;
148 } 136 }
149 137
189 { 177 {
190 visible_ = visible; 178 visible_ = visible;
191 } 179 }
192 180
193 181
194 static OrthancPlugins::DicomTag ConvertTag(const Orthanc::DicomTag& tag) 182 void SetSize(unsigned int width,
195 { 183 unsigned int height)
196 return OrthancPlugins::DicomTag(tag.GetGroup(), tag.GetElement()); 184 {
197 } 185 if (hasSize_ &&
198 186 (width != width_ ||
199 void SetDicomTags(const OrthancPlugins::FullOrthancDataset& dataset) 187 height != height_))
200 { 188 {
201 converter_.reset(new DicomFrameConverter); 189 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize);
202 converter_->ReadParameters(dataset); 190 }
203 ApplyConverter(); 191
204 192 hasSize_ = true;
205 transform_ = LinearAlgebra::IdentityMatrix(3); 193 width_ = width;
206 194 height_ = height;
207 std::string tmp; 195 }
208 Vector pixelSpacing; 196
209 197
210 if (dataset.GetStringValue(tmp, ConvertTag(Orthanc::DICOM_TAG_PIXEL_SPACING)) && 198 void CheckSize(unsigned int width,
211 LinearAlgebra::ParseVector(pixelSpacing, tmp) && 199 unsigned int height)
212 pixelSpacing.size() == 2) 200 {
213 { 201 if (hasSize_ &&
214 pixelSpacingX_ = pixelSpacing[0]; 202 (width != width_ ||
215 pixelSpacingY_ = pixelSpacing[1]; 203 height != height_))
216 } 204 {
217 205 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize);
218 static unsigned int c = 0; 206 }
219 if (c == 0) 207 }
220 { 208
221 panX_ = 400;
222 c ++;
223 }
224
225 OrthancPlugins::DicomDatasetReader reader(dataset);
226
227 if (!reader.GetUnsignedIntegerValue(width_, ConvertTag(Orthanc::DICOM_TAG_COLUMNS)) ||
228 !reader.GetUnsignedIntegerValue(height_, ConvertTag(Orthanc::DICOM_TAG_ROWS)))
229 {
230 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
231 }
232
233 UpdateTransform();
234 }
235
236
237 void SetSourceImage(Orthanc::ImageAccessor* image) // Takes ownership
238 {
239 source_.reset(image);
240 ApplyConverter();
241 }
242
243
244 bool GetDefaultWindowing(float& center,
245 float& width) const
246 {
247 if (converter_.get() != NULL &&
248 converter_->HasDefaultWindow())
249 {
250 center = static_cast<float>(converter_->GetDefaultWindowCenter());
251 width = static_cast<float>(converter_->GetDefaultWindowWidth());
252 return true;
253 }
254 else
255 {
256 return false;
257 }
258 }
259
260 209
261 Extent2D GetExtent() const 210 Extent2D GetExtent() const
262 { 211 {
263 Extent2D extent; 212 Extent2D extent;
264 213
268 double dx = static_cast<double>(x) - 0.5; 217 double dx = static_cast<double>(x) - 0.5;
269 double dy = static_cast<double>(y) - 0.5; 218 double dy = static_cast<double>(y) - 0.5;
270 double dwidth = static_cast<double>(width); 219 double dwidth = static_cast<double>(width);
271 double dheight = static_cast<double>(height); 220 double dheight = static_cast<double>(height);
272 221
273 LinearAlgebra::Print(transform_);
274
275 AddToExtent(extent, dx, dy); 222 AddToExtent(extent, dx, dy);
276 AddToExtent(extent, dx + dwidth, dy); 223 AddToExtent(extent, dx + dwidth, dy);
277 AddToExtent(extent, dx, dy + dheight); 224 AddToExtent(extent, dx, dy + dheight);
278 AddToExtent(extent, dx + dwidth, dy + dheight); 225 AddToExtent(extent, dx + dwidth, dy + dheight);
279 226
280 return extent; 227 return extent;
281 } 228 }
282 229
283 230
284 void Render(Orthanc::ImageAccessor& buffer, 231 virtual void Render(Orthanc::ImageAccessor& buffer,
285 const ViewportGeometry& view) const 232 const ViewportGeometry& view) const = 0;
286 {
287 if (converted_.get() != NULL)
288 {
289 Matrix m = LinearAlgebra::Product(view.GetMatrix(), transform_);
290 //ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Bilinear, false);
291 ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Nearest, false);
292 }
293 }
294 233
295 234
296 bool Contains(double x, 235 bool Contains(double x,
297 double y) const 236 double y) const
298 { 237 {
326 panY_ = y; 265 panY_ = y;
327 UpdateTransform(); 266 UpdateTransform();
328 } 267 }
329 268
330 269
270 void SetPixelSpacing(double x,
271 double y)
272 {
273 pixelSpacingX_ = x;
274 pixelSpacingY_ = y;
275 UpdateTransform();
276 }
277
278
331 double GetPanX() const 279 double GetPanX() const
332 { 280 {
333 return panX_; 281 return panX_;
334 } 282 }
335 283
336 284
337 double GetPanY() const 285 double GetPanY() const
338 { 286 {
339 return panY_; 287 return panY_;
340 } 288 }
289
290
291 virtual bool GetDefaultWindowing(float& center,
292 float& width) const
293 {
294 return false;
295 }
296
297
298 const Matrix& GetTransform() const
299 {
300 return transform_;
301 }
341 }; 302 };
342 303
304
305
306 class DicomBitmap : public Bitmap
307 {
308 private:
309 std::auto_ptr<Orthanc::ImageAccessor> source_; // Content of PixelData
310 std::auto_ptr<DicomFrameConverter> converter_;
311 std::auto_ptr<Orthanc::ImageAccessor> converted_; // Float32 or RGB24
312
313
314 void ApplyConverter()
315 {
316 if (source_.get() != NULL &&
317 converter_.get() != NULL)
318 {
319 converted_.reset(converter_->ConvertFrame(*source_));
320 }
321 }
322
323 public:
324 static OrthancPlugins::DicomTag ConvertTag(const Orthanc::DicomTag& tag)
325 {
326 return OrthancPlugins::DicomTag(tag.GetGroup(), tag.GetElement());
327 }
328
329 void SetDicomTags(const OrthancPlugins::FullOrthancDataset& dataset)
330 {
331 converter_.reset(new DicomFrameConverter);
332 converter_->ReadParameters(dataset);
333 ApplyConverter();
334
335 std::string tmp;
336 Vector pixelSpacing;
337
338 if (dataset.GetStringValue(tmp, ConvertTag(Orthanc::DICOM_TAG_PIXEL_SPACING)) &&
339 LinearAlgebra::ParseVector(pixelSpacing, tmp) &&
340 pixelSpacing.size() == 2)
341 {
342 SetPixelSpacing(pixelSpacing[0], pixelSpacing[1]);
343 }
344
345 static unsigned int c = 0;
346 if (c == 0)
347 {
348 SetPan(400, 0);
349 c ++;
350 }
351
352 OrthancPlugins::DicomDatasetReader reader(dataset);
353
354 unsigned int width, height;
355 if (!reader.GetUnsignedIntegerValue(width, ConvertTag(Orthanc::DICOM_TAG_COLUMNS)) ||
356 !reader.GetUnsignedIntegerValue(height, ConvertTag(Orthanc::DICOM_TAG_ROWS)))
357 {
358 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
359 }
360 else
361 {
362 SetSize(width, height);
363 }
364 }
365
366
367 void SetSourceImage(Orthanc::ImageAccessor* image) // Takes ownership
368 {
369 std::auto_ptr<Orthanc::ImageAccessor> raii(image);
370
371 if (image == NULL)
372 {
373 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
374 }
375
376 SetSize(image->GetWidth(), image->GetHeight());
377
378 source_ = raii;
379 ApplyConverter();
380 }
381
382
383 virtual void Render(Orthanc::ImageAccessor& buffer,
384 const ViewportGeometry& view) const
385 {
386 if (converted_.get() != NULL)
387 {
388 Matrix m = LinearAlgebra::Product(view.GetMatrix(), GetTransform());
389 //ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Bilinear, false);
390 ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Nearest, false);
391 }
392 }
393
394
395 virtual bool GetDefaultWindowing(float& center,
396 float& width) const
397 {
398 if (converter_.get() != NULL &&
399 converter_->HasDefaultWindow())
400 {
401 center = static_cast<float>(converter_->GetDefaultWindowCenter());
402 width = static_cast<float>(converter_->GetDefaultWindowWidth());
403 return true;
404 }
405 else
406 {
407 return false;
408 }
409 }
410 };
411
412
413
414
415 class AlphaBitmap : public Bitmap
416 {
417 private:
418 const BitmapStack& stack_;
419 std::auto_ptr<Orthanc::ImageAccessor> alpha_; // Grayscale8
420 bool useWindowing_;
421 float foreground_;
422
423 public:
424 AlphaBitmap(const BitmapStack& stack) :
425 stack_(stack),
426 useWindowing_(true),
427 foreground_(0)
428 {
429 }
430
431
432 void SetForegroundValue(float foreground)
433 {
434 useWindowing_ = false;
435 foreground_ = foreground;
436 }
437
438
439 void SetAlpha(Orthanc::ImageAccessor* image)
440 {
441 std::auto_ptr<Orthanc::ImageAccessor> raii(image);
442
443 if (image == NULL)
444 {
445 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
446 }
447
448 if (image->GetFormat() != Orthanc::PixelFormat_Grayscale8)
449 {
450 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat);
451 }
452
453 SetSize(image->GetWidth(), image->GetHeight());
454 alpha_ = raii;
455 }
456
457
458 void LoadText(const Orthanc::Font& font,
459 const std::string& utf8)
460 {
461 SetAlpha(font.RenderAlpha(utf8));
462 }
463
464
465 virtual void Render(Orthanc::ImageAccessor& buffer,
466 const ViewportGeometry& view) const
467 {
468 if (buffer.GetFormat() != Orthanc::PixelFormat_Float32)
469 {
470 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat);
471 }
472
473 Matrix m = LinearAlgebra::Product(view.GetMatrix(), GetTransform());
474
475 Orthanc::Image tmp(Orthanc::PixelFormat_Grayscale8, buffer.GetWidth(), buffer.GetHeight(), false);
476 ApplyProjectiveTransform(tmp, *alpha_, m, ImageInterpolation_Nearest, true /* clear */);
477
478 // Blit
479 const unsigned int width = buffer.GetWidth();
480 const unsigned int height = buffer.GetHeight();
481
482 float value = foreground_;
483
484 if (useWindowing_)
485 {
486 float center, width;
487 if (stack_.GetWindowing(center, width))
488 {
489 value = center + width / 2.0f;
490 }
491 }
492
493 for (unsigned int y = 0; y < height; y++)
494 {
495 float *q = reinterpret_cast<float*>(buffer.GetRow(y));
496 const uint8_t *p = reinterpret_cast<uint8_t*>(tmp.GetRow(y));
497
498 for (unsigned int x = 0; x < width; x++, p++, q++)
499 {
500 float a = static_cast<float>(*p) / 255.0f;
501
502 *q = (a * value + (1.0f - a) * (*q));
503 }
504 }
505 }
506 };
507
508
343 509
344 typedef std::map<size_t, Bitmap*> Bitmaps; 510 typedef std::map<size_t, Bitmap*> Bitmaps;
345 511
346 OrthancApiClient& orthanc_; 512 OrthancApiClient& orthanc_;
347 size_t countBitmaps_; 513 size_t countBitmaps_;
372 delete it->second; 538 delete it->second;
373 } 539 }
374 } 540 }
375 541
376 542
377 void GetWindowing(float& center, 543 bool GetWindowing(float& center,
378 float& width) 544 float& width) const
379 { 545 {
380 if (hasWindowing_) 546 if (hasWindowing_)
381 { 547 {
382 center = windowingCenter_; 548 center = windowingCenter_;
383 width = windowingWidth_; 549 width = windowingWidth_;
550 return true;
384 } 551 }
385 else 552 else
386 { 553 {
387 center = 128; 554 return false;
388 width = 256;
389 } 555 }
390 } 556 }
391 557
392 558
559 size_t LoadText(const Orthanc::Font& font,
560 const std::string& utf8,
561 double x,
562 double y)
563 {
564 std::auto_ptr<AlphaBitmap> alpha(new AlphaBitmap(*this));
565 alpha->LoadText(font, utf8);
566
567 size_t bitmap = countBitmaps_++;
568
569 bitmaps_[bitmap] = alpha.release();
570
571 return bitmap;
572 }
573
574
393 size_t LoadFrame(const std::string& instance, 575 size_t LoadFrame(const std::string& instance,
394 unsigned int frame, 576 unsigned int frame,
395 bool httpCompression) 577 bool httpCompression)
396 { 578 {
397 size_t bitmap = countBitmaps_++; 579 size_t bitmap = countBitmaps_++;
398 580
399 bitmaps_[bitmap] = new Bitmap; 581 bitmaps_[bitmap] = new DicomBitmap;
400 582
401 583
402 { 584 {
403 IWebService::Headers headers; 585 IWebService::Headers headers;
404 std::string uri = "/instances/" + instance + "/tags"; 586 std::string uri = "/instances/" + instance + "/tags";
439 if (bitmap != bitmaps_.end()) 621 if (bitmap != bitmaps_.end())
440 { 622 {
441 assert(bitmap->second != NULL); 623 assert(bitmap->second != NULL);
442 624
443 OrthancPlugins::FullOrthancDataset dicom(message.Answer, message.AnswerSize); 625 OrthancPlugins::FullOrthancDataset dicom(message.Answer, message.AnswerSize);
444 bitmap->second->SetDicomTags(dicom); 626 dynamic_cast<DicomBitmap*>(bitmap->second)->SetDicomTags(dicom);
445 627
446 float c, w; 628 float c, w;
447 if (!hasWindowing_ && 629 if (!hasWindowing_ &&
448 bitmap->second->GetDefaultWindowing(c, w)) 630 bitmap->second->GetDefaultWindowing(c, w))
449 { 631 {
475 content.assign(reinterpret_cast<const char*>(message.Answer), message.AnswerSize); 657 content.assign(reinterpret_cast<const char*>(message.Answer), message.AnswerSize);
476 } 658 }
477 659
478 std::auto_ptr<Orthanc::PamReader> reader(new Orthanc::PamReader); 660 std::auto_ptr<Orthanc::PamReader> reader(new Orthanc::PamReader);
479 reader->ReadFromMemory(content); 661 reader->ReadFromMemory(content);
480 bitmap->second->SetSourceImage(reader.release()); 662 dynamic_cast<DicomBitmap*>(bitmap->second)->SetSourceImage(reader.release());
481 663
482 EmitMessage(ContentChangedMessage(*this)); 664 EmitMessage(ContentChangedMessage(*this));
483 } 665 }
484 } 666 }
485 667
572 754
573 755
574 class MoveBitmapTracker : public IWorldSceneMouseTracker 756 class MoveBitmapTracker : public IWorldSceneMouseTracker
575 { 757 {
576 private: 758 private:
577 WorldSceneWidget& widget_;
578 BitmapStack& stack_; 759 BitmapStack& stack_;
579 size_t bitmap_; 760 size_t bitmap_;
580 double clickX_; 761 double clickX_;
581 double clickY_; 762 double clickY_;
763 double panX_;
764 double panY_;
765 bool oneAxis_;
582 766
583 public: 767 public:
584 MoveBitmapTracker(WorldSceneWidget& widget, 768 MoveBitmapTracker(BitmapStack& stack,
585 BitmapStack& stack,
586 size_t bitmap, 769 size_t bitmap,
587 double x, 770 double x,
588 double y) : 771 double y,
589 widget_(widget), 772 bool oneAxis) :
590 stack_(stack), 773 stack_(stack),
591 bitmap_(bitmap), 774 bitmap_(bitmap),
592 clickX_(x), 775 clickX_(x),
593 clickY_(y) 776 clickY_(y),
594 { 777 oneAxis_(oneAxis)
595 double panX, panY; 778 {
596 stack.GetPan(panX, panY, bitmap_); 779 stack.GetPan(panX_, panY_, bitmap_);
597 clickX_ -= panX;
598 clickY_ -= panY;
599 } 780 }
600 781
601 virtual bool HasRender() const 782 virtual bool HasRender() const
602 { 783 {
603 return false; 784 return false;
616 virtual void MouseMove(int displayX, 797 virtual void MouseMove(int displayX,
617 int displayY, 798 int displayY,
618 double sceneX, 799 double sceneX,
619 double sceneY) 800 double sceneY)
620 { 801 {
621 stack_.SetPan(bitmap_, sceneX - clickX_, sceneY - clickY_); 802 double dx = sceneX - clickX_;
803 double dy = sceneY - clickY_;
804
805 if (oneAxis_)
806 {
807 if (fabs(dx) > fabs(dy))
808 {
809 stack_.SetPan(bitmap_, dx + panX_, panY_);
810 }
811 else
812 {
813 stack_.SetPan(bitmap_, panX_, dy + panY_);
814 }
815 }
816 else
817 {
818 stack_.SetPan(bitmap_, dx + panX_, dy + panY_);
819 }
622 } 820 }
623 }; 821 };
624 822
625 823
626 public: 824 public:
641 { 839 {
642 size_t bitmap; 840 size_t bitmap;
643 if (stack_.LookupBitmap(bitmap, x, y)) 841 if (stack_.LookupBitmap(bitmap, x, y))
644 { 842 {
645 printf("CLICK on bitmap %d\n", bitmap); 843 printf("CLICK on bitmap %d\n", bitmap);
646 return new MoveBitmapTracker(widget, stack_, bitmap, x, y); 844 return new MoveBitmapTracker(stack_, bitmap, x, y,
845 (modifiers & KeyboardModifiers_Shift));
647 } 846 }
648 else 847 else
649 { 848 {
650 printf("CLICK outside\n"); 849 printf("CLICK outside\n");
651 return NULL; 850 return NULL;
743 stack_.Render(buffer, GetView()); 942 stack_.Render(buffer, GetView());
744 943
745 // As in GrayscaleFrameRenderer => TODO MERGE 944 // As in GrayscaleFrameRenderer => TODO MERGE
746 945
747 float windowCenter, windowWidth; 946 float windowCenter, windowWidth;
748 stack_.GetWindowing(windowCenter, windowWidth); 947 if (!stack_.GetWindowing(windowCenter, windowWidth))
948 {
949 windowCenter = 128;
950 windowWidth = 256;
951 }
749 952
750 float x0 = windowCenter - windowWidth / 2.0f; 953 float x0 = windowCenter - windowWidth / 2.0f;
751 float x1 = windowCenter + windowWidth / 2.0f; 954 float x1 = windowCenter + windowWidth / 2.0f;
752 955
753 const unsigned int width = target.GetWidth(); 956 const unsigned int width = target.GetWidth();
963 std::string instance = parameters["instance"].as<std::string>(); 1166 std::string instance = parameters["instance"].as<std::string>();
964 int frame = parameters["frame"].as<unsigned int>(); 1167 int frame = parameters["frame"].as<unsigned int>();
965 1168
966 orthancApiClient_.reset(new OrthancApiClient(IObserver::broker_, context_->GetWebService())); 1169 orthancApiClient_.reset(new OrthancApiClient(IObserver::broker_, context_->GetWebService()));
967 1170
1171 Orthanc::FontRegistry fonts;
1172 fonts.AddFromResource(Orthanc::EmbeddedResources::FONT_UBUNTU_MONO_BOLD_16);
1173
968 stack_.reset(new BitmapStack(IObserver::broker_, *orthancApiClient_)); 1174 stack_.reset(new BitmapStack(IObserver::broker_, *orthancApiClient_));
969 stack_->LoadFrame(instance, frame, false); 1175 stack_->LoadFrame(instance, frame, false);
970 stack_->LoadFrame("61f3143e-96f34791-ad6bbb8d-62559e75-45943e1b", frame, false); 1176 stack_->LoadFrame("61f3143e-96f34791-ad6bbb8d-62559e75-45943e1b", frame, false);
1177 stack_->LoadText(fonts.GetFont(0), "Hello\nworld\nBonjour, Alain", 0, -50);
971 1178
972 mainWidget_ = new BitmapStackWidget(IObserver::broker_, *stack_, "main-widget"); 1179 mainWidget_ = new BitmapStackWidget(IObserver::broker_, *stack_, "main-widget");
973 mainWidget_->SetTransmitMouseOver(true); 1180 mainWidget_->SetTransmitMouseOver(true);
974 1181
975 mainWidgetInteractor_.reset(new Interactor(*this)); 1182 mainWidgetInteractor_.reset(new Interactor(*this));