comparison Applications/Samples/SingleFrameEditorApplication.h @ 345:55438b1ca317 am-2

drawing borders
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 22 Oct 2018 17:02:34 +0200
parents fdec8e6893cb
children c2e040ea8fbe
comparison
equal deleted inserted replaced
344:fdec8e6893cb 345:55438b1ca317
76 transform_(0, 0) = pixelSpacingX_; 76 transform_(0, 0) = pixelSpacingX_;
77 transform_(1, 1) = pixelSpacingY_; 77 transform_(1, 1) = pixelSpacingY_;
78 transform_(0, 2) = panX_; 78 transform_(0, 2) = panX_;
79 transform_(1, 2) = panY_; 79 transform_(1, 2) = panY_;
80 80
81
82 #if 0 81 #if 0
83 double a = 10.0 / 180.0 * boost::math::constants::pi<double>(); 82 double a = 10.0 / 180.0 * boost::math::constants::pi<double>();
84 Matrix m; 83 Matrix m;
85 const double v[] = { cos(a), -sin(a), 0, 84 const double v[] = { cos(a), -sin(a), 0,
86 sin(a), cos(a), 0, 85 sin(a), cos(a), 0,
87 0, 0, 1 }; 86 0, 0, 1 };
88 LinearAlgebra::FillMatrix(m, 3, 3, v); 87 LinearAlgebra::FillMatrix(m, 3, 3, v);
89 transform_ = LinearAlgebra::Product(m, transform_); 88 transform_ = LinearAlgebra::Product(m, transform_);
90 #endif 89 #endif
91 } 90 }
91
92
93 void MapImageToScene(double& x,
94 double& y) const
95 {
96 Vector p;
97 LinearAlgebra::AssignVector(p, x, y, 1);
98
99 Vector q = LinearAlgebra::Product(transform_, p);
100
101 if (!LinearAlgebra::IsNear(q[2], 1.0))
102 {
103 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
104 }
105 else
106 {
107 x = q[0];
108 y = q[1];
109 }
110 }
92 111
93 112
94 void AddToExtent(Extent2D& extent, 113 void AddToExtent(Extent2D& extent,
95 double x, 114 double x,
96 double y) const 115 double y) const
97 { 116 {
98 Vector p; 117 MapImageToScene(x, y);
99 LinearAlgebra::AssignVector(p, x, y, 1); 118 extent.AddPoint(x, y);
100
101 Vector q = LinearAlgebra::Product(transform_, p);
102
103 if (!LinearAlgebra::IsNear(q[2], 1.0))
104 {
105 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
106 }
107 else
108 {
109 extent.AddPoint(q[0], q[1]);
110 }
111 } 119 }
112 120
113 121
114 public: 122 public:
115 Bitmap() : 123 Bitmap() :
227 return extent; 235 return extent;
228 } 236 }
229 237
230 238
231 virtual void Render(Orthanc::ImageAccessor& buffer, 239 virtual void Render(Orthanc::ImageAccessor& buffer,
232 const ViewportGeometry& view) const = 0; 240 const ViewportGeometry& view,
241 ImageInterpolation interpolation) const = 0;
233 242
234 243
235 bool Contains(double x, 244 bool Contains(double x,
236 double y) const 245 double y) const
237 { 246 {
273 pixelSpacingX_ = x; 282 pixelSpacingX_ = x;
274 pixelSpacingY_ = y; 283 pixelSpacingY_ = y;
275 UpdateTransform(); 284 UpdateTransform();
276 } 285 }
277 286
287 double GetPixelSpacingX() const
288 {
289 return pixelSpacingX_;
290 }
291
292 double GetPixelSpacingY() const
293 {
294 return pixelSpacingY_;
295 }
278 296
279 double GetPanX() const 297 double GetPanX() const
280 { 298 {
281 return panX_; 299 return panX_;
282 } 300 }
283 301
284
285 double GetPanY() const 302 double GetPanY() const
286 { 303 {
287 return panY_; 304 return panY_;
288 } 305 }
289
290 306
291 virtual bool GetDefaultWindowing(float& center, 307 virtual bool GetDefaultWindowing(float& center,
292 float& width) const 308 float& width) const
293 { 309 {
294 return false; 310 return false;
295 } 311 }
296 312
297
298 const Matrix& GetTransform() const 313 const Matrix& GetTransform() const
299 { 314 {
300 return transform_; 315 return transform_;
316 }
317
318
319 void DrawBorders(CairoContext& context,
320 double zoom)
321 {
322 unsigned int cx, cy, width, height;
323 GetCrop(cx, cy, width, height);
324
325 double dx = static_cast<double>(cx);
326 double dy = static_cast<double>(cy);
327 double dwidth = static_cast<double>(width);
328 double dheight = static_cast<double>(height);
329
330 cairo_t* cr = context.GetObject();
331 cairo_set_line_width(cr, 2.0 / zoom);
332
333 double x, y;
334 x = dx;
335 y = dy;
336 MapImageToScene(x, y);
337 cairo_move_to(cr, x, y);
338
339 x = dx + dwidth;
340 y = dy;
341 MapImageToScene(x, y);
342 cairo_line_to(cr, x, y);
343
344 x = dx + dwidth;
345 y = dy + dheight;
346 MapImageToScene(x, y);
347 cairo_line_to(cr, x, y);
348
349 x = dx;
350 y = dy + dheight;
351 MapImageToScene(x, y);
352 cairo_line_to(cr, x, y);
353
354 x = dx;
355 y = dy;
356 MapImageToScene(x, y);
357 cairo_line_to(cr, x, y);
358
359 cairo_stroke(cr);
301 } 360 }
302 }; 361 };
303 362
304 363
305 364
340 pixelSpacing.size() == 2) 399 pixelSpacing.size() == 2)
341 { 400 {
342 SetPixelSpacing(pixelSpacing[0], pixelSpacing[1]); 401 SetPixelSpacing(pixelSpacing[0], pixelSpacing[1]);
343 } 402 }
344 403
404 SetPan(-0.5 * GetPixelSpacingX(), -0.5 * GetPixelSpacingY());
405
345 static unsigned int c = 0; 406 static unsigned int c = 0;
346 if (c == 0) 407 if (c == 0)
347 { 408 {
348 SetPan(400, 0); 409 SetPan(400, 0);
349 c ++; 410 c ++;
379 ApplyConverter(); 440 ApplyConverter();
380 } 441 }
381 442
382 443
383 virtual void Render(Orthanc::ImageAccessor& buffer, 444 virtual void Render(Orthanc::ImageAccessor& buffer,
384 const ViewportGeometry& view) const 445 const ViewportGeometry& view,
446 ImageInterpolation interpolation) const
385 { 447 {
386 if (converted_.get() != NULL) 448 if (converted_.get() != NULL)
387 { 449 {
388 Matrix m = LinearAlgebra::Product(view.GetMatrix(), GetTransform()); 450 Matrix m = LinearAlgebra::Product(view.GetMatrix(), GetTransform());
389 //ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Bilinear, false); 451 ApplyProjectiveTransform(buffer, *converted_, m, interpolation, false);
390 ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Nearest, false);
391 } 452 }
392 } 453 }
393 454
394 455
395 virtual bool GetDefaultWindowing(float& center, 456 virtual bool GetDefaultWindowing(float& center,
461 SetAlpha(font.RenderAlpha(utf8)); 522 SetAlpha(font.RenderAlpha(utf8));
462 } 523 }
463 524
464 525
465 virtual void Render(Orthanc::ImageAccessor& buffer, 526 virtual void Render(Orthanc::ImageAccessor& buffer,
466 const ViewportGeometry& view) const 527 const ViewportGeometry& view,
528 ImageInterpolation interpolation) const
467 { 529 {
468 if (buffer.GetFormat() != Orthanc::PixelFormat_Float32) 530 if (buffer.GetFormat() != Orthanc::PixelFormat_Float32)
469 { 531 {
470 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); 532 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat);
471 } 533 }
472 534
473 Matrix m = LinearAlgebra::Product(view.GetMatrix(), GetTransform()); 535 Matrix m = LinearAlgebra::Product(view.GetMatrix(), GetTransform());
474 536
475 Orthanc::Image tmp(Orthanc::PixelFormat_Grayscale8, buffer.GetWidth(), buffer.GetHeight(), false); 537 Orthanc::Image tmp(Orthanc::PixelFormat_Grayscale8, buffer.GetWidth(), buffer.GetHeight(), false);
476 ApplyProjectiveTransform(tmp, *alpha_, m, ImageInterpolation_Nearest, true /* clear */); 538 ApplyProjectiveTransform(tmp, *alpha_, m, interpolation, true /* clear */);
477 539
478 // Blit 540 // Blit
479 const unsigned int width = buffer.GetWidth(); 541 const unsigned int width = buffer.GetWidth();
480 const unsigned int height = buffer.GetHeight(); 542 const unsigned int height = buffer.GetHeight();
481 543
513 size_t countBitmaps_; 575 size_t countBitmaps_;
514 bool hasWindowing_; 576 bool hasWindowing_;
515 float windowingCenter_; 577 float windowingCenter_;
516 float windowingWidth_; 578 float windowingWidth_;
517 Bitmaps bitmaps_; 579 Bitmaps bitmaps_;
580 bool hasSelection_;
581 size_t selectedBitmap_;
518 582
519 public: 583 public:
520 BitmapStack(MessageBroker& broker, 584 BitmapStack(MessageBroker& broker,
521 OrthancApiClient& orthanc) : 585 OrthancApiClient& orthanc) :
522 IObserver(broker), 586 IObserver(broker),
523 IObservable(broker), 587 IObservable(broker),
524 orthanc_(orthanc), 588 orthanc_(orthanc),
525 countBitmaps_(0), 589 countBitmaps_(0),
526 hasWindowing_(false), 590 hasWindowing_(false),
527 windowingCenter_(0), // Dummy initialization 591 windowingCenter_(0), // Dummy initialization
528 windowingWidth_(0) // Dummy initialization 592 windowingWidth_(0), // Dummy initialization
529 { 593 hasSelection_(false),
530 } 594 selectedBitmap_(0) // Dummy initialization
531 595 {
596 }
597
598
599 void Unselect()
600 {
601 hasSelection_ = false;
602 }
603
604
605 void Select(size_t bitmap)
606 {
607 hasSelection_ = true;
608 selectedBitmap_ = bitmap;
609 }
610
532 611
533 virtual ~BitmapStack() 612 virtual ~BitmapStack()
534 { 613 {
535 for (Bitmaps::iterator it = bitmaps_.begin(); it != bitmaps_.end(); it++) 614 for (Bitmaps::iterator it = bitmaps_.begin(); it != bitmaps_.end(); it++)
536 { 615 {
680 return extent; 759 return extent;
681 } 760 }
682 761
683 762
684 void Render(Orthanc::ImageAccessor& buffer, 763 void Render(Orthanc::ImageAccessor& buffer,
685 const ViewportGeometry& view) const 764 const ViewportGeometry& view,
765 ImageInterpolation interpolation) const
686 { 766 {
687 Orthanc::ImageProcessing::Set(buffer, 0); 767 Orthanc::ImageProcessing::Set(buffer, 0);
688 768
689 // Render layers in the background-to-foreground order 769 // Render layers in the background-to-foreground order
690 for (size_t index = 0; index < countBitmaps_; index++) 770 for (size_t index = 0; index < countBitmaps_; index++)
691 { 771 {
692 Bitmaps::const_iterator it = bitmaps_.find(index); 772 Bitmaps::const_iterator it = bitmaps_.find(index);
693 if (it != bitmaps_.end()) 773 if (it != bitmaps_.end())
694 { 774 {
695 assert(it->second != NULL); 775 assert(it->second != NULL);
696 it->second->Render(buffer, view); 776 it->second->Render(buffer, view, interpolation);
697 } 777 }
698 } 778 }
699 } 779 }
700 780
701 781
748 } 828 }
749 else 829 else
750 { 830 {
751 panX = 0; 831 panX = 0;
752 panY = 0; 832 panY = 0;
833 }
834 }
835
836
837 void DrawControls(CairoSurface& surface,
838 const ViewportGeometry& view)
839 {
840 if (hasSelection_)
841 {
842 Bitmaps::const_iterator bitmap = bitmaps_.find(selectedBitmap_);
843
844 if (bitmap != bitmaps_.end())
845 {
846 CairoContext context(surface);
847
848 context.SetSourceColor(255, 0, 0);
849 view.ApplyTransform(context);
850 bitmap->second->DrawBorders(context, view.GetZoom());
851 }
753 } 852 }
754 } 853 }
755 }; 854 };
756 855
757 856
816 { 915 {
817 stack_.SetPan(bitmap_, dx + panX_, panY_); 916 stack_.SetPan(bitmap_, dx + panX_, panY_);
818 } 917 }
819 else 918 else
820 { 919 {
821 stack_.SetPan(bitmap_, panX_, dy + panY_); 920 stack_.SetPan(bitmap_, panX_, dy + panY_);
822 } 921 }
823 } 922 }
824 else 923 else
825 { 924 {
826 stack_.SetPan(bitmap_, dx + panX_, dy + panY_); 925 stack_.SetPan(bitmap_, dx + panX_, dy + panY_);
847 { 946 {
848 size_t bitmap; 947 size_t bitmap;
849 if (stack_.LookupBitmap(bitmap, x, y)) 948 if (stack_.LookupBitmap(bitmap, x, y))
850 { 949 {
851 printf("CLICK on bitmap %ld\n", bitmap); 950 printf("CLICK on bitmap %ld\n", bitmap);
951 stack_.Select(bitmap);
852 return new MoveBitmapTracker(stack_, bitmap, x, y, 952 return new MoveBitmapTracker(stack_, bitmap, x, y,
853 (modifiers & KeyboardModifiers_Shift)); 953 (modifiers & KeyboardModifiers_Shift));
854 } 954 }
855 else 955 else
856 { 956 {
857 printf("CLICK outside\n"); 957 printf("CLICK outside\n");
958 stack_.Unselect();
858 return NULL; 959 return NULL;
859 } 960 }
860 } 961 }
861 else 962 else
862 { 963 {
945 1046
946 virtual bool Render(Orthanc::ImageAccessor& target) 1047 virtual bool Render(Orthanc::ImageAccessor& target)
947 { 1048 {
948 Orthanc::Image buffer(Orthanc::PixelFormat_Float32, target.GetWidth(), 1049 Orthanc::Image buffer(Orthanc::PixelFormat_Float32, target.GetWidth(),
949 target.GetHeight(), false); 1050 target.GetHeight(), false);
950 stack_.Render(buffer, GetView()); 1051
1052 // TODO => rendering quality
1053 //stack_.Render(buffer, GetView(), ImageInterpolation_Nearest);
1054 stack_.Render(buffer, GetView(), ImageInterpolation_Bilinear);
951 1055
952 // As in GrayscaleFrameRenderer => TODO MERGE? 1056 // As in GrayscaleFrameRenderer => TODO MERGE?
953 1057
954 float windowCenter, windowWidth; 1058 float windowCenter, windowWidth;
955 if (!stack_.GetWindowing(windowCenter, windowWidth)) 1059 if (!stack_.GetWindowing(windowCenter, windowWidth))
1002 } 1106 }
1003 } 1107 }
1004 else 1108 else
1005 { 1109 {
1006 Orthanc::ImageProcessing::Set(target, 0, 0, 0, 255); 1110 Orthanc::ImageProcessing::Set(target, 0, 0, 0, 255);
1111 }
1112
1113 {
1114 // TODO => REFACTOR
1115 CairoSurface surface(target);
1116 stack_.DrawControls(surface, GetView());
1007 } 1117 }
1008 1118
1009 return true; 1119 return true;
1010 } 1120 }
1011 1121