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); 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; } 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'); + }); });