From 5e2b9fb629af6d949268e01e72f871d70d4f8997 Mon Sep 17 00:00:00 2001 From: Luis Camacho Date: Fri, 8 Apr 2022 15:53:34 +0100 Subject: [PATCH 1/3] fix to text width calculation now considers new lines to match rendering --- src/ol/render/canvas.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ol/render/canvas.js b/src/ol/render/canvas.js index 46af528f7c..8aff0d75b8 100644 --- a/src/ol/render/canvas.js +++ b/src/ol/render/canvas.js @@ -362,7 +362,9 @@ export function measureAndCacheTextWidth(font, text, cache) { if (text in cache) { return cache[text]; } - const width = measureTextWidth(font, text); + const width = text + .split('\n') + .reduce((prev, curr) => Math.max(prev, measureTextWidth(font, curr)), 0); cache[text] = width; return width; } From 94c890088355ac3ea71b4e23f0a1616ee690c7fa Mon Sep 17 00:00:00 2001 From: Luis Camacho Date: Sun, 22 May 2022 17:41:52 +0100 Subject: [PATCH 2/3] ensure single-line label when rendering across segments --- src/ol/geom/flat/textpath.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ol/geom/flat/textpath.js b/src/ol/geom/flat/textpath.js index 18eff716a4..4124320b3d 100644 --- a/src/ol/geom/flat/textpath.js +++ b/src/ol/geom/flat/textpath.js @@ -104,6 +104,9 @@ export function drawTextOnPath( return result; } + // rendering across line segments + text = text.replace(/\n/g, ' '); // ensure rendering in single-line as all calculations below don't handle multi-lines + for (let i = 0, ii = text.length; i < ii; ) { advance(); let angle = Math.atan2(y2 - y1, x2 - x1); From 4773595748fe47138a14617cd35ac1f53b9b7d47 Mon Sep 17 00:00:00 2001 From: Luis Camacho Date: Wed, 25 May 2022 14:33:29 +0100 Subject: [PATCH 3/3] added tests for drawTextOnPath multi-line text handling --- test/node/ol/geom/flat/textpath.test.js | 55 +++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/test/node/ol/geom/flat/textpath.test.js b/test/node/ol/geom/flat/textpath.test.js index af5b0da8bb..f88b569b06 100644 --- a/test/node/ol/geom/flat/textpath.test.js +++ b/test/node/ol/geom/flat/textpath.test.js @@ -242,4 +242,59 @@ describe('ol/geom/flat/drawTextOnPath.js', function () { expect(instructions[0][3]).to.be((45 * Math.PI) / 180); expect(instructions.length).to.be(1); }); + + it('renders multi-line in one segment', function () { + const foo = 'foo'; + const bar = 'bar'; + const text = foo + '\n' + bar; + const pathLength = lineStringLength(angled, 2, angled.length, 2); + const textLength = measureAndCacheTextWidth('', bar); + const textAlign = 0.5; + const startM = (pathLength - textLength) * textAlign; + const instructions = drawTextOnPath( + angled, + 0, + angled.length, + 2, + text, + startM, + Infinity, + 1, + measureAndCacheTextWidth, + '', + {} + ); + expect(instructions[0][3]).to.be((45 * Math.PI) / 180); + expect(instructions[0][4]).to.be(text); + expect(instructions.length).to.be(1); + }); + + it('renders multi-line as single-line across segments', function () { + const foo = 'foo-foo-foo'; + const bar = 'bar-bar-bar-bar-bar-bar-bar'; + const text = foo + '\n' + bar; + const pathLength = lineStringLength(angled, 2, angled.length, 2); + const textLength = measureAndCacheTextWidth('', bar); + const textAlign = 0.5; + const startM = (pathLength - textLength) * textAlign; + + const instructions = drawTextOnPath( + angled, + 0, + angled.length, + 2, + text, + startM, + Infinity, + 1, + measureAndCacheTextWidth, + '', + {} + ); + expect(instructions[0][3]).to.be((45 * Math.PI) / 180); + expect(instructions[0][4]).to.be('foo-foo-foo bar-bar-b'); + expect(instructions.length).to.be(2); + expect(instructions[1][3]).to.be((-45 * Math.PI) / 180); + expect(instructions[1][4]).to.be('ar-bar-bar-bar-bar'); + }); });