@@ -59,7 +59,7 @@ function loadStyles(styles) {
59
59
return Promise . all ( promises ) ;
60
60
}
61
61
62
- function writeSVG ( svgElement , ctx ) {
62
+ function writeSVG ( svgElement , ctx , outputScale ) {
63
63
// We need to have UTF-8 encoded XML.
64
64
const svg_xml = unescape (
65
65
encodeURIComponent ( new XMLSerializer ( ) . serializeToString ( svgElement ) )
@@ -102,15 +102,18 @@ function inlineImages(images) {
102
102
return Promise . all ( imagePromises ) ;
103
103
}
104
104
105
- async function convertCanvasesToImages ( annotationCanvasMap ) {
105
+ async function convertCanvasesToImages ( annotationCanvasMap , outputScale ) {
106
106
const results = new Map ( ) ;
107
107
const promises = [ ] ;
108
108
for ( const [ key , canvas ] of annotationCanvasMap ) {
109
109
promises . push (
110
110
new Promise ( resolve => {
111
111
canvas . toBlob ( blob => {
112
112
const image = document . createElement ( "img" ) ;
113
- image . onload = resolve ;
113
+ image . onload = function ( ) {
114
+ image . style . width = Math . floor ( image . width / outputScale ) + "px" ;
115
+ resolve ( ) ;
116
+ } ;
114
117
results . set ( key , image ) ;
115
118
image . src = URL . createObjectURL ( blob ) ;
116
119
} ) ;
@@ -198,6 +201,7 @@ class Rasterize {
198
201
static async annotationLayer (
199
202
ctx ,
200
203
viewport ,
204
+ outputScale ,
201
205
annotations ,
202
206
annotationCanvasMap ,
203
207
page ,
@@ -213,7 +217,8 @@ class Rasterize {
213
217
214
218
const annotationViewport = viewport . clone ( { dontFlip : true } ) ;
215
219
const annotationImageMap = await convertCanvasesToImages (
216
- annotationCanvasMap
220
+ annotationCanvasMap ,
221
+ outputScale
217
222
) ;
218
223
219
224
// Rendering annotation layer as HTML.
@@ -600,13 +605,38 @@ class Driver {
600
605
ctx = this . canvas . getContext ( "2d" , { alpha : false } ) ;
601
606
task . pdfDoc . getPage ( task . pageNum ) . then (
602
607
page => {
603
- const viewport = page . getViewport ( {
608
+ // Default to creating the test images at the devices pixel ratio,
609
+ // unless the test explicitly specifies an output scale.
610
+ const outputScale = task . outputScale || window . devicePixelRatio ;
611
+ let viewport = page . getViewport ( {
604
612
scale : PixelsPerInch . PDF_TO_CSS_UNITS ,
605
613
} ) ;
606
- this . canvas . width = viewport . width ;
607
- this . canvas . height = viewport . height ;
614
+ // Restrict the test from creating a canvas that is too big.
615
+ const MAX_CANVAS_PIXEL_DIMENSION = 4096 ;
616
+ const largestDimension = Math . max ( viewport . width , viewport . height ) ;
617
+ if (
618
+ Math . floor ( largestDimension * outputScale ) >
619
+ MAX_CANVAS_PIXEL_DIMENSION
620
+ ) {
621
+ const rescale = MAX_CANVAS_PIXEL_DIMENSION / largestDimension ;
622
+ viewport = viewport . clone ( {
623
+ scale : PixelsPerInch . PDF_TO_CSS_UNITS * rescale ,
624
+ } ) ;
625
+ }
626
+ const pixelWidth = Math . floor ( viewport . width * outputScale ) ;
627
+ const pixelHeight = Math . floor ( viewport . height * outputScale ) ;
628
+ task . viewportWidth = Math . floor ( viewport . width ) ;
629
+ task . viewportHeight = Math . floor ( viewport . height ) ;
630
+ task . outputScale = outputScale ;
631
+ this . canvas . width = pixelWidth ;
632
+ this . canvas . height = pixelHeight ;
633
+ this . canvas . style . width = Math . floor ( viewport . width ) + "px" ;
634
+ this . canvas . style . height = Math . floor ( viewport . height ) + "px" ;
608
635
this . _clearCanvas ( ) ;
609
636
637
+ const transform =
638
+ outputScale !== 1 ? [ outputScale , 0 , 0 , outputScale , 0 , 0 ] : null ;
639
+
610
640
// Initialize various `eq` test subtypes, see comment below.
611
641
let renderAnnotations = false ,
612
642
renderForms = false ,
@@ -631,15 +661,16 @@ class Driver {
631
661
textLayerCanvas = document . createElement ( "canvas" ) ;
632
662
this . textLayerCanvas = textLayerCanvas ;
633
663
}
634
- textLayerCanvas . width = viewport . width ;
635
- textLayerCanvas . height = viewport . height ;
664
+ textLayerCanvas . width = pixelWidth ;
665
+ textLayerCanvas . height = pixelHeight ;
636
666
const textLayerContext = textLayerCanvas . getContext ( "2d" ) ;
637
667
textLayerContext . clearRect (
638
668
0 ,
639
669
0 ,
640
670
textLayerCanvas . width ,
641
671
textLayerCanvas . height
642
672
) ;
673
+ textLayerContext . scale ( outputScale , outputScale ) ;
643
674
const enhanceText = ! ! task . enhance ;
644
675
// The text builder will draw its content on the test canvas
645
676
initPromise = page
@@ -672,15 +703,16 @@ class Driver {
672
703
annotationLayerCanvas = document . createElement ( "canvas" ) ;
673
704
this . annotationLayerCanvas = annotationLayerCanvas ;
674
705
}
675
- annotationLayerCanvas . width = viewport . width ;
676
- annotationLayerCanvas . height = viewport . height ;
706
+ annotationLayerCanvas . width = pixelWidth ;
707
+ annotationLayerCanvas . height = pixelHeight ;
677
708
annotationLayerContext = annotationLayerCanvas . getContext ( "2d" ) ;
678
709
annotationLayerContext . clearRect (
679
710
0 ,
680
711
0 ,
681
712
annotationLayerCanvas . width ,
682
713
annotationLayerCanvas . height
683
714
) ;
715
+ annotationLayerContext . scale ( outputScale , outputScale ) ;
684
716
685
717
if ( ! renderXfa ) {
686
718
// The annotation builder will draw its content
@@ -709,6 +741,7 @@ class Driver {
709
741
viewport,
710
742
optionalContentConfigPromise : task . optionalContentConfigPromise ,
711
743
annotationCanvasMap,
744
+ transform,
712
745
} ;
713
746
if ( renderForms ) {
714
747
renderContext . annotationMode = AnnotationMode . ENABLE_FORMS ;
@@ -725,7 +758,7 @@ class Driver {
725
758
ctx . save ( ) ;
726
759
ctx . globalCompositeOperation = "screen" ;
727
760
ctx . fillStyle = "rgb(128, 255, 128)" ; // making it green
728
- ctx . fillRect ( 0 , 0 , viewport . width , viewport . height ) ;
761
+ ctx . fillRect ( 0 , 0 , pixelWidth , pixelHeight ) ;
729
762
ctx . restore ( ) ;
730
763
ctx . drawImage ( textLayerCanvas , 0 , 0 ) ;
731
764
}
@@ -755,6 +788,7 @@ class Driver {
755
788
Rasterize . annotationLayer (
756
789
annotationLayerContext ,
757
790
viewport ,
791
+ outputScale ,
758
792
data ,
759
793
annotationCanvasMap ,
760
794
page ,
@@ -864,6 +898,9 @@ class Driver {
864
898
page : task . pageNum ,
865
899
snapshot,
866
900
stats : task . stats . times ,
901
+ viewportWidth : task . viewportWidth ,
902
+ viewportHeight : task . viewportHeight ,
903
+ outputScale : task . outputScale ,
867
904
} ) ;
868
905
this . _send ( "/submit_task_results" , result , callback ) ;
869
906
}
0 commit comments