Merge pull request #12106 from IQGeo/issue-12101
improve text width calculation
This commit is contained in:
@@ -104,6 +104,9 @@ export function drawTextOnPath(
|
|||||||
return result;
|
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; ) {
|
for (let i = 0, ii = text.length; i < ii; ) {
|
||||||
advance();
|
advance();
|
||||||
let angle = Math.atan2(y2 - y1, x2 - x1);
|
let angle = Math.atan2(y2 - y1, x2 - x1);
|
||||||
|
|||||||
@@ -362,7 +362,9 @@ export function measureAndCacheTextWidth(font, text, cache) {
|
|||||||
if (text in cache) {
|
if (text in cache) {
|
||||||
return cache[text];
|
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;
|
cache[text] = width;
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -242,4 +242,59 @@ describe('ol/geom/flat/drawTextOnPath.js', function () {
|
|||||||
expect(instructions[0][3]).to.be((45 * Math.PI) / 180);
|
expect(instructions[0][3]).to.be((45 * Math.PI) / 180);
|
||||||
expect(instructions.length).to.be(1);
|
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');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user