Mercurial > hg > orthanc-stone
changeset 1575:e4a52cbbdd70
working on print
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 23 Sep 2020 17:25:25 +0200 |
parents | fb5e620430ae |
children | 92fca2b3ba3d |
files | Applications/StoneWebViewer/Resources/Graveyard/print.js Applications/StoneWebViewer/WebApplication/index.html Applications/StoneWebViewer/WebApplication/print.js Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp OrthancStone/Sources/OpenGL/WebAssemblyOpenGLContext.cpp OrthancStone/Sources/Viewport/WebAssemblyViewport.cpp OrthancStone/Sources/Viewport/WebAssemblyViewport.h |
diffstat | 7 files changed, 262 insertions(+), 127 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Applications/StoneWebViewer/Resources/Graveyard/print.js Wed Sep 23 17:25:25 2020 +0200 @@ -0,0 +1,178 @@ +function beforePrint(event){ + console.log('beforePrint'); + var $body = $('body'); + $body.addClass('print'); + + // because firefox does not support/executes codes after the cloned document as been rendered + // https://bugzilla.mozilla.org/show_bug.cgi?format=default&id=1048317 + // we cannot calculate using the good body size for the clone document + // so we have to hardcode the body width (meaning we can only renders in A4 in firefox); + var uaParser = new UAParser(); + var isFirefox = (uaParser.getBrowser().name === 'Firefox'); + var isIE = (uaParser.getBrowser().name === 'IE'); + var isEdge = (uaParser.getBrowser().name === 'Edge'); + console.log('ua parser', uaParser.getBrowser()); + if(isFirefox || isIE || isEdge){ + if (0) { + // This is Letter + $body.css('width', '8.5in'); + $body.css('height', '11in'); + } else { + // This is A4 + //$body.css('width', '210mm'); + //$body.css('height', '297mm'); + $body.css('width', '210mm'); + $body.css('height', '297mm'); // Setting "297mm" makes Firefox create 2 pages + } + + // console.log('html size', $html.width(), $html.height()); + } + + if(isIE){ + window.alert('GENERAL_PARAGRAPHS.INCOMPATIBLE_PRINT_BROWSER'); + } + + console.log('body size', $body.width(), $body.height()); + + var $splitpane = $('#viewport'); + var splitpaneSize = {width: $splitpane.width(), height: $splitpane.height()}; + console.log(splitpaneSize); + var panesCount = { + x: app.layoutCountX, + y: app.layoutCountY + } + + var panes = []; + $('#viewport canvas').each(function(key, value) { + if ($(value).is(':visible')) { + console.log(value); + panes.push(value); + } + }); + + console.log(panesCount); + + if (0){ + for(var i = 0; i < panes.length; i++){ + var canvas = panes[i]; + var paneSize = { + originalWidth: $(canvas).width(), //canvas.getBoundingClientRect().width, + originalHeight: $(canvas).height(), //canvas.getBoundingClientRect().height, + originalRatio: 0, + paneFinalWidth: splitpaneSize.width / panesCount.x, + paneFinalHeight: splitpaneSize.height / panesCount.y, + paneFinalRatio: 0, + canvasFinalWidth: 0, + canvasFinalHeight: 0, + canvasFinalRatio: 0 + }; + paneSize.originalRatio = paneSize.originalWidth / paneSize.originalHeight; + paneSize.paneFinalRatio = paneSize.paneFinalWidth / paneSize.paneFinalHeight; + + if(paneSize.paneFinalRatio > 1){ + // If pane width ratio means it's width is larger than it's height + if(paneSize.paneFinalRatio > paneSize.originalRatio){ + // the final pane is larger than the original + // So we should fit on the height to recalc the ratio + console.log('case 1'); + paneSize.canvasFinalHeight = paneSize.paneFinalHeight; + paneSize.canvasFinalWidth = paneSize.canvasFinalHeight * paneSize.originalRatio; // Then we calc the width according the ratio + } else { + // the final pane is higher than or equal to the original + // So we should fit on the width + console.log('case 2'); + paneSize.canvasFinalWidth = paneSize.paneFinalWidth; + paneSize.canvasFinalHeight = paneSize.canvasFinalWidth / paneSize.originalRatio; // Then we calc the width according the ratio + + } + } else { + // If pane width ratio means it's height is higher than it's height + if(paneSize.paneFinalRatio > paneSize.originalRatio){ + // the final pane is larger than the original + // So we should fit on the height to recalc the ratio + console.log('case 3'); + paneSize.canvasFinalHeight = paneSize.paneFinalHeight; + paneSize.canvasFinalWidth = paneSize.canvasFinalHeight * paneSize.originalRatio; // Then we calc the width according the ratio + } else { + // the final pane is higher than or equal to the original + // So we should fit on the width + console.log('case 4'); + paneSize.canvasFinalWidth = paneSize.paneFinalWidth; + paneSize.canvasFinalHeight = paneSize.canvasFinalWidth / paneSize.originalRatio; // Then we calc the width according the ratio + + } + } + + paneSize.canvasFinalRatio = paneSize.canvasFinalWidth / paneSize.canvasFinalHeight; + console.log('paneSizes:', paneSize, 'splitpaneSize:', splitpaneSize, 'panesCount:', panesCount); + //canvas.resizeCanvas(paneSize.canvasFinalWidth, paneSize.canvasFinalHeight); + //canvas.draw(); + + console.log(paneSize.canvasFinalWidth + ' ' + paneSize.canvasFinalHeight); + /*canvas.width = Math.round(paneSize.canvasFinalWidth); + canvas.height = Math.round(paneSize.canvasFinalHeight);*/ + + $(canvas).width(paneSize.canvasFinalWidth); + $(canvas).height(paneSize.canvasFinalHeight); + + + /* + https://stackoverflow.com/questions/27863783/javascript-canvas-disappears-after-changing-width + + var buffer = document.getElementById('buffer'); + var context = canvas.getContext('2d'); + console.log(context); + var bufferContext = buffer.getContext('2d'); + console.log(bufferContext); + + bufferContext.drawImage(canvas, 0, 0); //Make a copy of the canvas to hidden buffer + canvas.width = Math.round(paneSize.canvasFinalWidth); + canvas.height = Math.round(paneSize.canvasFinalHeight); + context.drawImage(buffer, 0, 0); */ + } + } + else { + for(var i = 0; i < panes.length; i++){ + var canvas = panes[i]; + $(canvas).width($(canvas).parent().width()); + $(canvas).height($(canvas).parent().height()); + } + } + + stone.AllViewportsUpdateSize(false); + $(window).trigger('resize'); // to force screen and canvas recalculation +}; + +function afterPrint(){ + console.log('afterprint'); + var $body = $('body'); + // var $html = $('html'); + $body.removeClass('print'); + $body.css('width', '100%'); + $body.css('height', '100%'); + $('#viewport canvas').css('width', '100%'); + $('#viewport canvas').css('height', '100%'); + stone.AllViewportsUpdateSize(false); + $(window).trigger('resize'); // to force screen and canvas recalculation +} + +window.addEventListener('beforeprint', function(event){ + beforePrint(event); +}); + +var printMedia = window.matchMedia('print'); +printMedia.addListener(function(mql) { + if(mql.matches) { + console.log('webkit equivalent of onbeforeprint'); + beforePrint(); + } +}); + +window.addEventListener('afterprint', function(){ + afterPrint(); +});$ + +/*vm.cancelPrintMode = function(){ + afterPrint(); +} +*/
--- a/Applications/StoneWebViewer/WebApplication/index.html Mon Sep 21 18:29:53 2020 +0200 +++ b/Applications/StoneWebViewer/WebApplication/index.html Wed Sep 23 17:25:25 2020 +0200 @@ -537,9 +537,9 @@ <div class="wvSplitpane__cell" v-on:click="MakeActive()"> <div v-show="status == 'ready'" - style="position:absolute; left:0; top:0; width:100%; height:100%"> + style="position:absolute; left:0; top:0; width:100%; height:100%;"> <!--div style="width: 100%; height: 100%; background-color: red"></div--> - <canvas v-bind:id="canvasId" class="wvPrintViewer" + <canvas v-bind:id="canvasId" style="position:absolute; left:0; top:0; width:100%; height:100%" oncontextmenu="return false"></canvas>
--- a/Applications/StoneWebViewer/WebApplication/print.js Mon Sep 21 18:29:53 2020 +0200 +++ b/Applications/StoneWebViewer/WebApplication/print.js Wed Sep 23 17:25:25 2020 +0200 @@ -1,7 +1,6 @@ -function beforePrint(event){ - console.log('beforePrint'); - var $body = $('body'); - $body.addClass('print'); +function beforePrint(event) { + var body = $('body'); + body.addClass('print'); // because firefox does not support/executes codes after the cloned document as been rendered // https://bugzilla.mozilla.org/show_bug.cgi?format=default&id=1048317 @@ -11,148 +10,63 @@ var isFirefox = (uaParser.getBrowser().name === 'Firefox'); var isIE = (uaParser.getBrowser().name === 'IE'); var isEdge = (uaParser.getBrowser().name === 'Edge'); - console.log('ua parser', uaParser.getBrowser()); - if(isFirefox || isIE || isEdge){ - $body.css('width', '8.5in'); - $body.css('height', '11in'); - // console.log('html size', $html.width(), $html.height()); - } - - if(isIE){ - window.alert('GENERAL_PARAGRAPHS.INCOMPATIBLE_PRINT_BROWSER'); + //console.log('ua parser', uaParser.getBrowser()); + + if (isFirefox || isIE || isEdge) { + if (0) { + // This is Letter + body.css('width', '8.5in'); + body.css('height', '11in'); + } else { + // This is A4 + body.css('width', '210mm'); + body.css('height', '296mm'); // If using "297mm", Firefox creates a second blank page + } } - console.log('body size', $body.width(), $body.height()); - - var $splitpane = $('#viewport'); - var splitpaneSize = {width: $splitpane.width(), height: $splitpane.height()}; - console.log(splitpaneSize); - var panesCount = { - x: app.layoutCountX, - y: app.layoutCountY - } - - var panes = []; - $('#viewport canvas').each(function(key, value) { - if ($(value).is(':visible')) { - console.log(value); - panes.push(value); + $('#viewport canvas').each(function(key, canvas) { + if ($(canvas).is(':visible')) { + $(canvas).width($(canvas).parent().width()); + $(canvas).height($(canvas).parent().height()); } }); - - console.log(panesCount); - - for(var i = 0; i < panes.length; i++){ - var canvas = panes[i]; - var paneSize = { - originalWidth: canvas.getBoundingClientRect().width, - originalHeight: canvas.getBoundingClientRect().height, - originalRatio: 0, - paneFinalWidth: splitpaneSize.width / panesCount.x, - paneFinalHeight: splitpaneSize.height / panesCount.y, - paneFinalRatio: 0, - canvasFinalWidth: 0, - canvasFinalHeight: 0, - canvasFinalRatio: 0 - }; - paneSize.originalRatio = paneSize.originalWidth / paneSize.originalHeight; - paneSize.paneFinalRatio = paneSize.paneFinalWidth / paneSize.paneFinalHeight; - if(paneSize.paneFinalRatio > 1){ - // If pane width ratio means it's width is larger than it's height - if(paneSize.paneFinalRatio > paneSize.originalRatio){ - // the final pane is larger than the original - // So we should fit on the height to recalc the ratio - console.log('case 1'); - paneSize.canvasFinalHeight = paneSize.paneFinalHeight; - paneSize.canvasFinalWidth = paneSize.canvasFinalHeight * paneSize.originalRatio; // Then we calc the width according the ratio - } else { - // the final pane is higher than or equal to the original - // So we should fit on the width - console.log('case 2'); - paneSize.canvasFinalWidth = paneSize.paneFinalWidth; - paneSize.canvasFinalHeight = paneSize.canvasFinalWidth / paneSize.originalRatio; // Then we calc the width according the ratio - - } - } else { - // If pane width ratio means it's height is higher than it's height - if(paneSize.paneFinalRatio > paneSize.originalRatio){ - // the final pane is larger than the original - // So we should fit on the height to recalc the ratio - console.log('case 3'); - paneSize.canvasFinalHeight = paneSize.paneFinalHeight; - paneSize.canvasFinalWidth = paneSize.canvasFinalHeight * paneSize.originalRatio; // Then we calc the width according the ratio - } else { - // the final pane is higher than or equal to the original - // So we should fit on the width - console.log('case 4'); - paneSize.canvasFinalWidth = paneSize.paneFinalWidth; - paneSize.canvasFinalHeight = paneSize.canvasFinalWidth / paneSize.originalRatio; // Then we calc the width according the ratio - - } - } - - paneSize.canvasFinalRatio = paneSize.canvasFinalWidth / paneSize.canvasFinalHeight; - console.log('paneSizes:', paneSize, 'splitpaneSize:', splitpaneSize, 'panesCount:', panesCount); - //canvas.resizeCanvas(paneSize.canvasFinalWidth, paneSize.canvasFinalHeight); - //canvas.draw(); - - console.log(paneSize.canvasFinalWidth + ' ' + paneSize.canvasFinalHeight); - canvas.width = Math.round(paneSize.canvasFinalWidth); - canvas.height = Math.round(paneSize.canvasFinalHeight); + stone.FitForPrint(); +}; - /* - https://stackoverflow.com/questions/27863783/javascript-canvas-disappears-after-changing-width - - var buffer = document.getElementById('buffer'); - var context = canvas.getContext('2d'); - console.log(context); - var bufferContext = buffer.getContext('2d'); - console.log(bufferContext); - - bufferContext.drawImage(canvas, 0, 0); //Make a copy of the canvas to hidden buffer - canvas.width = Math.round(paneSize.canvasFinalWidth); - canvas.height = Math.round(paneSize.canvasFinalHeight); - context.drawImage(buffer, 0, 0); */ - } - - stone.AllViewportsUpdateSize(false); - $(window).trigger('resize'); // to force screen and canvas recalculation -}; - -function afterPrint(){ - console.log('afterprint'); - var $body = $('body'); - // var $html = $('html'); - $body.removeClass('print'); - $body.css('width', '100%'); - $body.css('height', '100%'); - // $html.css('width', '100%'); - // $html.css('height', '100%'); +function afterPrint() { + var body = $('body'); + body.removeClass('print'); + body.css('width', '100%'); + body.css('height', '100%'); $('#viewport canvas').css('width', '100%'); $('#viewport canvas').css('height', '100%'); - stone.AllViewportsUpdateSize(0); - $(window).trigger('resize'); // to force screen and canvas recalculation + + stone.FitForPrint(); } -window.addEventListener('beforeprint', function(event){ - beforePrint(event) + +window.addEventListener('beforeprint', function(event) { + beforePrint(event); }); + var printMedia = window.matchMedia('print'); printMedia.addListener(function(mql) { - if(mql.matches) { - console.log('webkit equivalent of onbeforeprint'); + if (mql.matches) { + // webkit equivalent of onbeforeprint beforePrint(); } }); -window.addEventListener('afterprint', function(){ + +window.addEventListener('afterprint', function() { afterPrint(); -});$ +}); -/*vm.cancelPrintMode = function(){ + +/*vm.cancelPrintMode = function() { afterPrint(); } */
--- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Mon Sep 21 18:29:53 2020 +0200 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Wed Sep 23 17:25:25 2020 +0200 @@ -1906,6 +1906,13 @@ assert(viewport_ != NULL); viewport_->AcquireInteractor(interactor.release()); } + + + + void FitForPrint() // TODO - REMOVE + { + viewport_->FitForPrint(); + } }; @@ -2458,4 +2465,19 @@ } EXTERN_CATCH_EXCEPTIONS; } + + + EMSCRIPTEN_KEEPALIVE + void FitForPrint() // TODO - REMOVE + { + try + { + for (Viewports::iterator it = allViewports_.begin(); it != allViewports_.end(); ++it) + { + assert(it->second != NULL); + it->second->FitForPrint(); + } + } + EXTERN_CATCH_EXCEPTIONS; + } }
--- a/OrthancStone/Sources/OpenGL/WebAssemblyOpenGLContext.cpp Mon Sep 21 18:29:53 2020 +0200 +++ b/OrthancStone/Sources/OpenGL/WebAssemblyOpenGLContext.cpp Wed Sep 23 17:25:25 2020 +0200 @@ -52,6 +52,14 @@ EmscriptenWebGLContextAttributes attr; emscripten_webgl_init_context_attributes(&attr); +#if 0 + // The next line might be necessary to print on Firefox 71 + // using WebGL. Sometimes, if set to "false" (the default + // value), the canvas was rendered as a fully white or black + // area. UNCONFIRMED, so disabled. + attr.preserveDrawingBuffer = true; +#endif + context_ = emscripten_webgl_create_context(canvasSelector.c_str(), &attr); if (context_ == 0) {
--- a/OrthancStone/Sources/Viewport/WebAssemblyViewport.cpp Mon Sep 21 18:29:53 2020 +0200 +++ b/OrthancStone/Sources/Viewport/WebAssemblyViewport.cpp Wed Sep 23 17:25:25 2020 +0200 @@ -210,6 +210,17 @@ emscripten_request_animation_frame(OnRequestAnimationFrame, reinterpret_cast<void*>(this)); } + void WebAssemblyViewport::FitForPrint() + { + if (compositor_.get() != NULL && + controller_ /* should always be true */) + { + UpdateSize(*compositor_); + compositor_->FitContent(controller_->GetScene()); + OnRequestAnimationFrame(0, reinterpret_cast<void*>(this)); + } + } + void WebAssemblyViewport::AcquireCompositor(ICompositor* compositor /* takes ownership */) { if (compositor == NULL)