@@ -1042,9 +1042,8 @@ function copyCtxState(sourceCtx, destCtx) {
1042
1042
}
1043
1043
}
1044
1044
1045
- function resetCtxToDefault ( ctx ) {
1046
- ctx . strokeStyle = "#000000" ;
1047
- ctx . fillStyle = "#000000" ;
1045
+ function resetCtxToDefault ( ctx , foregroundColor ) {
1046
+ ctx . strokeStyle = ctx . fillStyle = foregroundColor || "#000000" ;
1048
1047
ctx . fillRule = "nonzero" ;
1049
1048
ctx . globalAlpha = 1 ;
1050
1049
ctx . lineWidth = 1 ;
@@ -1212,7 +1211,8 @@ class CanvasGraphics {
1212
1211
canvasFactory ,
1213
1212
imageLayer ,
1214
1213
optionalContentConfig ,
1215
- annotationCanvasMap
1214
+ annotationCanvasMap ,
1215
+ pageColors
1216
1216
) {
1217
1217
this . ctx = canvasCtx ;
1218
1218
this . current = new CanvasExtraState (
@@ -1248,6 +1248,8 @@ class CanvasGraphics {
1248
1248
this . viewportScale = 1 ;
1249
1249
this . outputScaleX = 1 ;
1250
1250
this . outputScaleY = 1 ;
1251
+ this . foregroundColor = pageColors ?. foreground || null ;
1252
+ this . backgroundColor = pageColors ?. background || null ;
1251
1253
if ( canvasCtx ) {
1252
1254
// NOTE: if mozCurrentTransform is polyfilled, then the current state of
1253
1255
// the transformation must already be set in canvasCtx._transformMatrix.
@@ -1280,9 +1282,47 @@ class CanvasGraphics {
1280
1282
// transparent canvas when we have blend modes.
1281
1283
const width = this . ctx . canvas . width ;
1282
1284
const height = this . ctx . canvas . height ;
1283
-
1285
+ this . defaultBackgroundColor = background || "#ffffff" ;
1284
1286
this . ctx . save ( ) ;
1285
- this . ctx . fillStyle = background || "rgb(255, 255, 255)" ;
1287
+
1288
+ if ( this . foregroundColor && this . backgroundColor ) {
1289
+ this . ctx . fillStyle = this . foregroundColor ;
1290
+ const fg = ( this . foregroundColor = this . ctx . fillStyle ) ;
1291
+ this . ctx . fillStyle = this . backgroundColor ;
1292
+ const bg = ( this . backgroundColor = this . ctx . fillStyle ) ;
1293
+
1294
+ if ( fg === "#000000" && bg === "#ffffff" ) {
1295
+ this . foregroundColor = this . backgroundColor = null ;
1296
+ } else {
1297
+ // https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_Colors_and_Luminance
1298
+ //
1299
+ // Relative luminance:
1300
+ // https://www.w3.org/TR/WCAG20/#relativeluminancedef
1301
+ //
1302
+ // We compute the rounded luminance of the default background color.
1303
+ // Then for every color in the pdf, if its rounded luminance is the
1304
+ // same as the background one then it's replaced by the new
1305
+ // background color else by the foreground one.
1306
+ const cB = parseInt ( this . defaultBackgroundColor . slice ( 1 ) , 16 ) ;
1307
+ const rB = ( cB && 0xff0000 ) >> 16 ;
1308
+ const gB = ( cB && 0x00ff00 ) >> 8 ;
1309
+ const bB = cB && 0x0000ff ;
1310
+ const newComp = x => {
1311
+ x /= 255 ;
1312
+ return x <= 0.03928 ? x / 12.92 : ( ( x + 0.055 ) / 1.055 ) ** 2.4 ;
1313
+ } ;
1314
+ const lB = Math . round (
1315
+ 0.2126 * newComp ( rB ) + 0.7152 * newComp ( gB ) + 0.0722 * newComp ( bB )
1316
+ ) ;
1317
+ this . selectColor = ( r , g , b ) => {
1318
+ const lC =
1319
+ 0.2126 * newComp ( r ) + 0.7152 * newComp ( g ) + 0.0722 * newComp ( b ) ;
1320
+ return Math . round ( lC ) === lB ? bg : fg ;
1321
+ } ;
1322
+ }
1323
+ }
1324
+
1325
+ this . ctx . fillStyle = this . backgroundColor || this . defaultBackgroundColor ;
1286
1326
this . ctx . fillRect ( 0 , 0 , width , height ) ;
1287
1327
this . ctx . restore ( ) ;
1288
1328
@@ -1303,7 +1343,7 @@ class CanvasGraphics {
1303
1343
}
1304
1344
1305
1345
this . ctx . save ( ) ;
1306
- resetCtxToDefault ( this . ctx ) ;
1346
+ resetCtxToDefault ( this . ctx , this . foregroundColor ) ;
1307
1347
if ( transform ) {
1308
1348
this . ctx . transform . apply ( this . ctx , transform ) ;
1309
1349
this . outputScaleX = transform [ 0 ] ;
@@ -2636,13 +2676,13 @@ class CanvasGraphics {
2636
2676
}
2637
2677
2638
2678
setStrokeRGBColor ( r , g , b ) {
2639
- const color = Util . makeHexColor ( r , g , b ) ;
2679
+ const color = this . selectColor ?. ( r , g , b ) || Util . makeHexColor ( r , g , b ) ;
2640
2680
this . ctx . strokeStyle = color ;
2641
2681
this . current . strokeColor = color ;
2642
2682
}
2643
2683
2644
2684
setFillRGBColor ( r , g , b ) {
2645
- const color = Util . makeHexColor ( r , g , b ) ;
2685
+ const color = this . selectColor ?. ( r , g , b ) || Util . makeHexColor ( r , g , b ) ;
2646
2686
this . ctx . fillStyle = color ;
2647
2687
this . current . fillColor = color ;
2648
2688
this . current . patternFill = false ;
@@ -2964,9 +3004,9 @@ class CanvasGraphics {
2964
3004
this . ctx . setTransform ( scaleX , 0 , 0 , - scaleY , 0 , height * scaleY ) ;
2965
3005
addContextCurrentTransform ( this . ctx ) ;
2966
3006
2967
- resetCtxToDefault ( this . ctx ) ;
3007
+ resetCtxToDefault ( this . ctx , this . foregroundColor ) ;
2968
3008
} else {
2969
- resetCtxToDefault ( this . ctx ) ;
3009
+ resetCtxToDefault ( this . ctx , this . foregroundColor ) ;
2970
3010
2971
3011
this . ctx . rect ( rect [ 0 ] , rect [ 1 ] , width , height ) ;
2972
3012
this . ctx . clip ( ) ;
0 commit comments