comparison Applications/Platforms/WebAssembly/WebAssemblyCairoViewport.cpp @ 1591:5887a4f8594b

moving platform-specific files out of the "OrthancStone" folder
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 23 Oct 2020 13:15:03 +0200
parents OrthancStone/Sources/Viewport/WebAssemblyCairoViewport.cpp@92fca2b3ba3d
children 228a41233540
comparison
equal deleted inserted replaced
1590:7b963bccafef 1591:5887a4f8594b
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21
22 #if defined(ORTHANC_BUILDING_STONE_LIBRARY) && ORTHANC_BUILDING_STONE_LIBRARY == 1
23 # include "WebAssemblyCairoViewport.h"
24 # include "../../../OrthancStone/Sources/Scene2D/CairoCompositor.h"
25 # include "../../../OrthancStone/Sources/Scene2DViewport/ViewportController.h"
26 #else
27 // This is the case when using the WebAssembly side module, and this
28 // source file must be compiled within the WebAssembly main module
29 # include <Viewport/WebAssemblyCairoViewport.h>
30 # include <Scene2D/CairoCompositor.h>
31 # include <Scene2DViewport/ViewportController.h>
32 #endif
33
34
35 #include <Images/Image.h>
36
37 namespace OrthancStone
38 {
39 void WebAssemblyCairoViewport::Paint(ICompositor& compositor,
40 ViewportController& controller)
41 {
42 compositor.Refresh(controller.GetScene());
43
44 // Create a temporary memory buffer for the canvas in JavaScript
45 Orthanc::ImageAccessor cairo;
46 dynamic_cast<CairoCompositor&>(compositor).GetCanvas().GetReadOnlyAccessor(cairo);
47
48 const unsigned int width = cairo.GetWidth();
49 const unsigned int height = cairo.GetHeight();
50
51 if (javascript_.get() == NULL ||
52 javascript_->GetWidth() != width ||
53 javascript_->GetHeight() != height)
54 {
55 javascript_.reset(new Orthanc::Image(Orthanc::PixelFormat_RGBA32, width, height,
56 true /* force minimal pitch */));
57 }
58
59 // Convert from BGRA32 memory layout (only color mode supported
60 // by Cairo, which corresponds to CAIRO_FORMAT_ARGB32) to RGBA32
61 // (as expected by HTML5 canvas). This simply amounts to
62 // swapping the B and R channels. Alpha channel is also set to
63 // full opacity (255).
64 uint8_t* q = reinterpret_cast<uint8_t*>(javascript_->GetBuffer());
65 for (unsigned int y = 0; y < height; y++)
66 {
67 const uint8_t* p = reinterpret_cast<const uint8_t*>(cairo.GetConstRow(y));
68 for (unsigned int x = 0; x < width; x++)
69 {
70 q[0] = p[2]; // R
71 q[1] = p[1]; // G
72 q[2] = p[0]; // B
73 q[3] = 255; // A
74
75 p += 4;
76 q += 4;
77 }
78 }
79
80 // Execute JavaScript commands to blit the image buffer onto the
81 // 2D drawing context of the HTML5 canvas
82 EM_ASM({
83 const data = new Uint8ClampedArray(Module.HEAP8.buffer, $1, 4 * $2 * $3);
84 const img = new ImageData(data, $2, $3);
85 const ctx = document.getElementById(UTF8ToString($0)).getContext('2d');
86 ctx.putImageData(img, 0, 0);
87 },
88 GetCanvasId().c_str(), // $0
89 javascript_->GetBuffer(), // $1
90 javascript_->GetWidth(), // $2
91 javascript_->GetHeight()); // $3
92 }
93
94
95 WebAssemblyCairoViewport::WebAssemblyCairoViewport(const std::string& canvasId,
96 bool enableEmscriptenMouseEvents) :
97 WebAssemblyViewport(canvasId,enableEmscriptenMouseEvents)
98 {
99 RefreshCanvasSize();
100 AcquireCompositor(new CairoCompositor(GetCanvasWidth(), GetCanvasHeight()));
101 }
102
103
104 boost::shared_ptr<WebAssemblyCairoViewport> WebAssemblyCairoViewport::Create(
105 const std::string& canvasId, bool enableEmscriptenMouseEvents)
106 {
107 boost::shared_ptr<WebAssemblyCairoViewport> that = boost::shared_ptr<WebAssemblyCairoViewport>(
108 new WebAssemblyCairoViewport(canvasId, enableEmscriptenMouseEvents));
109
110 that->WebAssemblyViewport::PostConstructor();
111 return that;
112 }
113 }