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)
--- a/OrthancStone/Sources/Viewport/WebAssemblyViewport.h	Mon Sep 21 18:29:53 2020 +0200
+++ b/OrthancStone/Sources/Viewport/WebAssemblyViewport.h	Wed Sep 23 17:25:25 2020 +0200
@@ -123,5 +123,7 @@
     {
       return canvasCssSelector_;
     }
+
+    void FitForPrint();  // TODO - REMOVE
   };
 }