From 530af8e689f7f71548a4f85910530d3e3a2c3b4b Mon Sep 17 00:00:00 2001 From: Daniel Bretzigheimer Date: Thu, 11 Aug 2022 19:21:20 +0200 Subject: [PATCH] fix pattern position and scaling (#212) --- src/nodes/pattern.ts | 34 +++++++++++++++--------- test/common/tests.js | 2 ++ test/specs/pattern-offset/reference.pdf | Bin 0 -> 4459 bytes test/specs/pattern-offset/spec.svg | 8 ++++++ test/specs/pattern-scale/spec.svg | 8 ++++++ test/unit/all.spec.js | 3 ++- 6 files changed, 41 insertions(+), 14 deletions(-) create mode 100644 test/specs/pattern-offset/reference.pdf create mode 100644 test/specs/pattern-offset/spec.svg create mode 100644 test/specs/pattern-scale/spec.svg diff --git a/src/nodes/pattern.ts b/src/nodes/pattern.ts index fcd65384..7a3dcdca 100644 --- a/src/nodes/pattern.ts +++ b/src/nodes/pattern.ts @@ -12,27 +12,35 @@ export class Pattern extends NonRenderedNode { return } + const scaleFactor = context.pdf.internal.scaleFactor + // the transformations directly at the node are written to the pattern transformation matrix - const bBox = this.getBoundingBox(context) + const x = context.svg2pdfParameters.x ?? 0 + const y = context.svg2pdfParameters.y ?? 0 + const [patternX, patternY, width, height] = this.getBoundingBox(context) + const startX = (patternX + x) * scaleFactor + const startY = (patternY + y) * scaleFactor + const endX = startX + width * scaleFactor + const endY = startY + height * scaleFactor const pattern = new TilingPattern( - [bBox[0], bBox[1], bBox[0] + bBox[2], bBox[1] + bBox[3]], - bBox[2], - bBox[3] + [startX, startY, endX, endY], + width * scaleFactor, + height * scaleFactor ) context.pdf.beginTilingPattern(pattern) // continue without transformation for (const child of this.children) { - await child.render( - new Context(context.pdf, { - attributeState: context.attributeState, - refsHandler: context.refsHandler, - styleSheets: context.styleSheets, - viewport: context.viewport, - svg2pdfParameters: context.svg2pdfParameters - }) - ) + const childContext = new Context(context.pdf, { + attributeState: context.attributeState, + refsHandler: context.refsHandler, + styleSheets: context.styleSheets, + viewport: context.viewport, + svg2pdfParameters: context.svg2pdfParameters, + transform: context.pdf.Matrix(scaleFactor, 0, 0, scaleFactor, startX, startY) + }) + await child.render(childContext) } context.pdf.endTilingPattern(id, pattern) } diff --git a/test/common/tests.js b/test/common/tests.js index d505b8b1..8c2670b1 100644 --- a/test/common/tests.js +++ b/test/common/tests.js @@ -37,6 +37,8 @@ window.tests = [ 'nested-tspans', 'opacity-and-rgba', 'path-arc-support', + ['pattern-offset', undefined, { x: 10, y: 10 }], + ['pattern-scale', [400, 300, 'mm'], {}], 'pattern-units', 'patterns', 'polyline', diff --git a/test/specs/pattern-offset/reference.pdf b/test/specs/pattern-offset/reference.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d5d334ac5c43efe47b95e35426f0841696d4c461 GIT binary patch literal 4459 zcmd^C?{3>R5dY4nxG%w446#JY@}I#7P}}uttc5*0K)VI~Aj`C^K&BFj-jY32pP(-m?|%I8Y&smB^M=RHKL7dYFXn*@$>N&zdd}tjjRa>J ztR=($R4NS|TW8Ff$t>BWq0B(!f_HKm1^wg>u3Qud*KL@;kIWe)N@LFqnnv^Df=RU` z160oqG3TvRYrO#>nhX^(oyuU#+y;*03Lk!FF8s)D8E*iNiw{nhUdBwgEw^9;#}@iw z1JS>WJ`PL^#3#;6rW#YLEp2cBbeYyNRS;%a z7LbLCt=P|{FFL|5)w+bdTk}2k{wZ2!a78;a1LM*iZ3Vf?cJ%ihnccM!x}7=wAd^%A z=Z%bilR63m=FE2sZFZLSmow+J3X^4|*5JI4)GL)mg@8GuD9!X>6Qtk?+@-))gzuM( zx1MhNyr0C&=bu6QD`qfR#L?{zBl@}B(D{lYAbSIo{9tS9Y%omr@R%Yk3WE-dx1Vb6&zZ?v?{nLN~ zKMsny`LPb-C_KUXj|1aj{U@8maculGxLFMm{}+MAv!)7*PdWnlaqyepZx>1YFUJ>k zT(PI?{+KlZhNsyyh?FiWmr;xhD{6g1Py`;+^lSR&hv(^sxt2E|{04J=ITQ~ZhZCYA z>#;1Q-6@fjTgwTMC8X;EL&0icr$ie_gip+hHp3aH60?mV2Q^9{>R|F8u3T8Y_b$+B zgye3|g-Q$z9r%AZ#%xM~vePsP=TgI!gJc$*OL>QsXS_w`+PCk4eUEXvh7t98Sl~b) zfm=HgK-o$q4=81*)C3A^D*0eTVAMj2XN7Grrwz4tz<@p#yTA=m!y;<(ob_Uvg8?K` zL0w*0LuFprLuHdlGm0-~z6lH~!--P0V3W4`VY0ZEp@zJAV1j1HzD>6{Q;tbzHisPc zsE1JFn|BahNDQ>(vG%C1$`k^VY`F_%3NNlRN;BSY8}3WI;o)sfM~NB+TEdIr54_uH zbAdM@^ZDL&zr*Kc>B1oD#9$EMA)Kr!%-49Uw6HU|k?K`QV;8p{ypiZPpmuSLc}%)* zgZpHM$v#nXki@&KD%rV9v^LPu6)&2G&uZ{a1os@JZs zgLgW$@q|kd_t1vm1aB2tyNR(>k%_vWJ(t3=qStKIWVp01$hrvFMPHo;QH+-y0{VIM zhom@gW=W#K#2*6jSgjHe7OlraxPqSP{SSW^Pf__uF_`Hf)g}VHjw{&N+3U&ZZ-slA A + + + + + + + \ No newline at end of file diff --git a/test/specs/pattern-scale/spec.svg b/test/specs/pattern-scale/spec.svg new file mode 100644 index 00000000..7bac89f9 --- /dev/null +++ b/test/specs/pattern-scale/spec.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/test/unit/all.spec.js b/test/unit/all.spec.js index 89acf1e9..c6e0c419 100644 --- a/test/unit/all.spec.js +++ b/test/unit/all.spec.js @@ -22,7 +22,8 @@ for (const test of window.tests) { it(`testing ${name}`, async function() { const width = jsPDFOptions ? jsPDFOptions[0] : svgElement.width.baseVal.value const height = jsPDFOptions ? jsPDFOptions[1] : svgElement.height.baseVal.value - const pdf = new jsPDF(width > height ? 'l' : 'p', 'pt', [width, height]) + const unit = jsPDFOptions ? jsPDFOptions[2] || 'pt' : 'pt' + const pdf = new jsPDF(width > height ? 'l' : 'p', unit, [width, height]) if (name === 'custom-fonts') { const filename = '/base/test/specs/custom-fonts/Batang.ttf'