diff --git a/src/ol/geom/flat/textpath.js b/src/ol/geom/flat/textpath.js index a4941a8467..2714e5f14b 100644 --- a/src/ol/geom/flat/textpath.js +++ b/src/ol/geom/flat/textpath.js @@ -16,8 +16,8 @@ import {lerp} from '../../math.js'; * @param {function(string, string, Object):number} measureAndCacheTextWidth Measure and cache text width. * @param {string} font The font. * @param {Object} cache A cache of measured widths. - * @return {Array>} The result array of null if `maxAngle` was - * exceeded. Entries of the array are x, y, anchorX, angle, chunk. + * @return {Array>} The result array (or null if `maxAngle` was + * exceeded). Entries of the array are x, y, anchorX, angle, chunk. */ export function drawTextOnPath( flatCoordinates, offset, end, stride, text, startM, maxAngle, scale, measureAndCacheTextWidth, font, cache) { @@ -35,16 +35,13 @@ export function drawTextOnPath( let y2 = flatCoordinates[offset + 1]; let segmentM = 0; let segmentLength = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); + let angleChanged = false; - let chunk = ''; - let chunkLength = 0; - let data, index, previousAngle; + let index, previousAngle; for (let i = 0; i < numChars; ++i) { index = reverse ? numChars - i - 1 : i; - const char = text.charAt(index); - chunk = reverse ? char + chunk : chunk + char; - const charLength = scale * measureAndCacheTextWidth(font, chunk, cache) - chunkLength; - chunkLength += charLength; + const char = text[index]; + const charLength = scale * measureAndCacheTextWidth(font, char, cache); const charM = startM + charLength / 2; while (offset < end - stride && segmentM + segmentLength < charM) { x1 = x2; @@ -62,33 +59,18 @@ export function drawTextOnPath( } if (previousAngle !== undefined) { let delta = angle - previousAngle; + angleChanged = angleChanged || delta !== 0; delta += (delta > Math.PI) ? -2 * Math.PI : (delta < -Math.PI) ? 2 * Math.PI : 0; if (Math.abs(delta) > maxAngle) { return null; } } + previousAngle = angle; const interpolate = segmentPos / segmentLength; const x = lerp(x1, x2, interpolate); const y = lerp(y1, y2, interpolate); - if (previousAngle == angle) { - if (reverse) { - data[0] = x; - data[1] = y; - data[2] = charLength / 2; - } - data[4] = chunk; - } else { - chunk = char; - chunkLength = charLength; - data = [x, y, charLength / 2, angle, chunk]; - if (reverse) { - result.unshift(data); - } else { - result.push(data); - } - previousAngle = angle; - } + result[index] = [x, y, charLength / 2, angle, char]; startM += charLength; } - return result; + return angleChanged ? result : [[result[0][0], result[0][1], result[0][2], result[0][3], text]]; } diff --git a/test/spec/ol/geom/flat/textpath.test.js b/test/spec/ol/geom/flat/textpath.test.js index 8755bfe680..285d7e0cec 100644 --- a/test/spec/ol/geom/flat/textpath.test.js +++ b/test/spec/ol/geom/flat/textpath.test.js @@ -72,9 +72,11 @@ describe('ol.geom.flat.drawTextOnPath', function() { const instructions = drawTextOnPath( angled, 0, angled.length, 2, 'foo', startM, Infinity, 1, measureAndCacheTextWidth, '', {}); expect(instructions[0][3]).to.eql(45 * Math.PI / 180); - expect(instructions[0][4]).to.be('fo'); - expect(instructions[1][3]).to.eql(-45 * Math.PI / 180); + expect(instructions[0][4]).to.be('f'); + expect(instructions[1][3]).to.eql(45 * Math.PI / 180); expect(instructions[1][4]).to.be('o'); + expect(instructions[2][3]).to.eql(-45 * Math.PI / 180); + expect(instructions[2][4]).to.be('o'); }); it('respects maxAngle', function() {