diff --git a/src/pipeline.cc b/src/pipeline.cc index 4837a939..285cbfe2 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -602,8 +602,13 @@ class PipelineWorker : public Napi::AsyncWorker { int top; if (composite->hasOffset) { // Composite image at given offsets - std::tie(left, top) = sharp::CalculateCrop(image.width(), image.height(), - compositeImage.width(), compositeImage.height(), composite->left, composite->top); + if (composite->tile) { + std::tie(left, top) = sharp::CalculateCrop(image.width(), image.height(), + compositeImage.width(), compositeImage.height(), composite->left, composite->top); + } else { + left = composite->left; + top = composite->top; + } } else { // Composite image with given gravity std::tie(left, top) = sharp::CalculateCrop(image.width(), image.height(), diff --git a/test/unit/composite.js b/test/unit/composite.js index 069d807f..389e6e62 100644 --- a/test/unit/composite.js +++ b/test/unit/composite.js @@ -408,4 +408,20 @@ describe('composite', () => { }, /Expected valid gravity for gravity but received invalid of type string/); }); }); + + it('Allow offset beyond bottom/right edge', async () => { + const red = { r: 255, g: 0, b: 0 }; + const blue = { r: 0, g: 0, b: 255 }; + + const [r, g, b] = await sharp({ create: { width: 2, height: 2, channels: 4, background: red } }) + .composite([{ + input: { create: { width: 2, height: 2, channels: 4, background: blue } }, + top: 1, + left: 1 + }]) + .raw() + .toBuffer(); + + assert.deepStrictEqual(red, { r, g, b }); + }); });