Skip to content

Commit b001bcd

Browse files
committed
preserve pdf pages when setting width and height
Fixes #2538
1 parent 33bcb56 commit b001bcd

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ project adheres to [Semantic Versioning](http://semver.org/).
1111
### Added
1212
### Fixed
1313
* Fix dangling env pointer in image MIME data cleanup (#2550)
14+
* Preserve rest of PDF pages when changing width and height (#2538)
1415

1516
3.2.1
1617
==================

src/Canvas.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,10 @@ Canvas::resurface(Napi::Object This) {
923923
Napi::HandleScope scope(env);
924924
Napi::Value context;
925925

926-
if (This.Get("context").UnwrapTo(&context) && context.IsObject()) {
926+
if (type == CANVAS_TYPE_PDF) {
927+
ensureSurface();
928+
cairo_pdf_surface_set_size(_surface, width, height);
929+
} else if (This.Get("context").UnwrapTo(&context) && context.IsObject()) {
927930
destroySurface();
928931
ensureSurface();
929932
// Reset context

test/canvas.test.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2148,6 +2148,53 @@ describe('Canvas', function () {
21482148
})
21492149
})
21502150

2151+
it('PDF does not lose page content when setting width/height after addPage (#2538)', function () {
2152+
const zlib = require('zlib')
2153+
const canvas = createCanvas(100, 100, 'pdf')
2154+
const ctx = canvas.getContext('2d')
2155+
2156+
ctx.fillStyle = 'rgb(85, 85, 85)'
2157+
ctx.fillRect(10, 10, 30, 30)
2158+
2159+
// Should lock in page 1
2160+
ctx.addPage(200, 200)
2161+
2162+
ctx.fillStyle = 'rgb(170, 170, 170)'
2163+
ctx.fillRect(10, 10, 30, 30)
2164+
2165+
// Should not erase rgb(85, 85, 85)
2166+
// SHOULD erase rgb(170, 170, 170)
2167+
canvas.width = 200
2168+
canvas.height = 200
2169+
2170+
// Draw on page 2
2171+
ctx.fillStyle = 'rgb(250, 250, 250)'
2172+
ctx.fillRect(50, 50, 40, 40)
2173+
2174+
const pdf = canvas.toBuffer()
2175+
2176+
// Parse PDF streams to verify page 1 content is preserved
2177+
const pdfStr = pdf.toString('latin1')
2178+
const streamRegex = /stream\r?\n([\s\S]*?)\r?\nendstream/g
2179+
let match
2180+
let allContent = ''
2181+
while ((match = streamRegex.exec(pdfStr)) !== null) {
2182+
try {
2183+
const compressed = Buffer.from(match[1], 'latin1')
2184+
allContent += zlib.inflateSync(compressed).toString()
2185+
} catch (e) {
2186+
// Some streams may not be zlib-compressed
2187+
}
2188+
}
2189+
2190+
// 85/255 ≈ 0.333333 - page 1 fill color
2191+
// 170/255 ≈ 0.666667 - page 2 fill color, erased
2192+
// 250/255 ≈ 0.980392 - page 2 fill color
2193+
assert(allContent.includes('0.333333 0.333333 0.333333'), 'Page 1 content should be preserved')
2194+
assert(!allContent.includes('0.666667 0.666667 0.666667'), 'Page 2 content should exist')
2195+
assert(allContent.includes('0.980392 0.980392 0.980392'), 'Page 2 content should\'ve been erased')
2196+
})
2197+
21512198
it('Canvas#createJPEGStream()', function (done) {
21522199
const canvas = createCanvas(640, 480)
21532200
const stream = canvas.createJPEGStream()

0 commit comments

Comments
 (0)