Merge pull request #9536 from ahocevar/font-cache-hits

More font cache hits
This commit is contained in:
Andreas Hocevar
2019-05-15 12:13:40 +02:00
committed by GitHub
2 changed files with 14 additions and 30 deletions
+10 -28
View File
@@ -16,8 +16,8 @@ import {lerp} from '../../math.js';
* @param {function(string, string, Object<string, number>):number} measureAndCacheTextWidth Measure and cache text width. * @param {function(string, string, Object<string, number>):number} measureAndCacheTextWidth Measure and cache text width.
* @param {string} font The font. * @param {string} font The font.
* @param {Object<string, number>} cache A cache of measured widths. * @param {Object<string, number>} cache A cache of measured widths.
* @return {Array<Array<*>>} The result array of null if `maxAngle` was * @return {Array<Array<*>>} The result array (or null if `maxAngle` was
* exceeded. Entries of the array are x, y, anchorX, angle, chunk. * exceeded). Entries of the array are x, y, anchorX, angle, chunk.
*/ */
export function drawTextOnPath( export function drawTextOnPath(
flatCoordinates, offset, end, stride, text, startM, maxAngle, scale, measureAndCacheTextWidth, font, cache) { flatCoordinates, offset, end, stride, text, startM, maxAngle, scale, measureAndCacheTextWidth, font, cache) {
@@ -35,16 +35,13 @@ export function drawTextOnPath(
let y2 = flatCoordinates[offset + 1]; let y2 = flatCoordinates[offset + 1];
let segmentM = 0; let segmentM = 0;
let segmentLength = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); let segmentLength = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
let angleChanged = false;
let chunk = ''; let index, previousAngle;
let chunkLength = 0;
let data, index, previousAngle;
for (let i = 0; i < numChars; ++i) { for (let i = 0; i < numChars; ++i) {
index = reverse ? numChars - i - 1 : i; index = reverse ? numChars - i - 1 : i;
const char = text.charAt(index); const char = text[index];
chunk = reverse ? char + chunk : chunk + char; const charLength = scale * measureAndCacheTextWidth(font, char, cache);
const charLength = scale * measureAndCacheTextWidth(font, chunk, cache) - chunkLength;
chunkLength += charLength;
const charM = startM + charLength / 2; const charM = startM + charLength / 2;
while (offset < end - stride && segmentM + segmentLength < charM) { while (offset < end - stride && segmentM + segmentLength < charM) {
x1 = x2; x1 = x2;
@@ -62,33 +59,18 @@ export function drawTextOnPath(
} }
if (previousAngle !== undefined) { if (previousAngle !== undefined) {
let delta = angle - previousAngle; let delta = angle - previousAngle;
angleChanged = angleChanged || delta !== 0;
delta += (delta > Math.PI) ? -2 * Math.PI : (delta < -Math.PI) ? 2 * Math.PI : 0; delta += (delta > Math.PI) ? -2 * Math.PI : (delta < -Math.PI) ? 2 * Math.PI : 0;
if (Math.abs(delta) > maxAngle) { if (Math.abs(delta) > maxAngle) {
return null; return null;
} }
} }
previousAngle = angle;
const interpolate = segmentPos / segmentLength; const interpolate = segmentPos / segmentLength;
const x = lerp(x1, x2, interpolate); const x = lerp(x1, x2, interpolate);
const y = lerp(y1, y2, interpolate); const y = lerp(y1, y2, interpolate);
if (previousAngle == angle) { result[index] = [x, y, charLength / 2, angle, char];
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;
}
startM += charLength; startM += charLength;
} }
return result; return angleChanged ? result : [[result[0][0], result[0][1], result[0][2], result[0][3], text]];
} }
+4 -2
View File
@@ -72,9 +72,11 @@ describe('ol.geom.flat.drawTextOnPath', function() {
const instructions = drawTextOnPath( const instructions = drawTextOnPath(
angled, 0, angled.length, 2, 'foo', startM, Infinity, 1, measureAndCacheTextWidth, '', {}); angled, 0, angled.length, 2, 'foo', startM, Infinity, 1, measureAndCacheTextWidth, '', {});
expect(instructions[0][3]).to.eql(45 * Math.PI / 180); expect(instructions[0][3]).to.eql(45 * Math.PI / 180);
expect(instructions[0][4]).to.be('fo'); expect(instructions[0][4]).to.be('f');
expect(instructions[1][3]).to.eql(-45 * Math.PI / 180); expect(instructions[1][3]).to.eql(45 * Math.PI / 180);
expect(instructions[1][4]).to.be('o'); 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() { it('respects maxAngle', function() {