Merge pull request #7287 from ahocevar/text-line-baseline
Fix vertical stroke/fill alignment for text along lines
@@ -527,10 +527,9 @@ ol.render.canvas.Replay.prototype.replay_ = function(
|
|||||||
var maxAngle = /** @type {number} */ (instruction[6]);
|
var maxAngle = /** @type {number} */ (instruction[6]);
|
||||||
var measure = /** @type {function(string):number} */ (instruction[7]);
|
var measure = /** @type {function(string):number} */ (instruction[7]);
|
||||||
var offsetY = /** @type {number} */ (instruction[8]);
|
var offsetY = /** @type {number} */ (instruction[8]);
|
||||||
var strokeWidth = /** @type {number} */ (instruction[9]);
|
var text = /** @type {string} */ (instruction[9]);
|
||||||
var text = /** @type {string} */ (instruction[10]);
|
var align = /** @type {number} */ (instruction[10]);
|
||||||
var align = /** @type {number} */ (instruction[11]);
|
var textScale = /** @type {number} */ (instruction[11]);
|
||||||
var textScale = /** @type {number} */ (instruction[12]);
|
|
||||||
|
|
||||||
var pathLength = ol.geom.flat.length.lineString(pixelCoordinates, begin, end, 2);
|
var pathLength = ol.geom.flat.length.lineString(pixelCoordinates, begin, end, 2);
|
||||||
var textLength = measure(text);
|
var textLength = measure(text);
|
||||||
@@ -540,11 +539,12 @@ ol.render.canvas.Replay.prototype.replay_ = function(
|
|||||||
pixelCoordinates, begin, end, 2, text, measure, startM, maxAngle, this.chars_);
|
pixelCoordinates, begin, end, 2, text, measure, startM, maxAngle, this.chars_);
|
||||||
var numChars = text.length;
|
var numChars = text.length;
|
||||||
if (chars) {
|
if (chars) {
|
||||||
|
var fillHeight = images[images.length - 1].height;
|
||||||
for (var c = 0, cc = images.length; c < cc; ++c) {
|
for (var c = 0, cc = images.length; c < cc; ++c) {
|
||||||
var char = chars[c % numChars]; // x, y, rotation
|
var char = chars[c % numChars]; // x, y, rotation
|
||||||
var label = images[c];
|
var label = images[c];
|
||||||
anchorX = label.width / 2;
|
anchorX = label.width / 2;
|
||||||
anchorY = baseline * label.height + 2 * (0.5 - baseline) * strokeWidth - offsetY;
|
anchorY = baseline * label.height + (0.5 - baseline) * (label.height - fillHeight) - offsetY;
|
||||||
this.replayImage_(context, char[0], char[1], label, anchorX, anchorY,
|
this.replayImage_(context, char[0], char[1], label, anchorX, anchorY,
|
||||||
label.height, 1, 0, 0, char[2], textScale, false, label.width);
|
label.height, 1, 0, 0, char[2], textScale, false, label.width);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -383,7 +383,6 @@ ol.render.canvas.TextReplay.prototype.drawChars_ = function(begin, end) {
|
|||||||
var stroke = !!strokeState;
|
var stroke = !!strokeState;
|
||||||
var textState = this.textState_;
|
var textState = this.textState_;
|
||||||
var baseline = ol.render.replay.TEXT_ALIGN[textState.textBaseline];
|
var baseline = ol.render.replay.TEXT_ALIGN[textState.textBaseline];
|
||||||
var strokeWidth = stroke && strokeState.lineWidth ? strokeState.lineWidth * pixelRatio : 0;
|
|
||||||
|
|
||||||
var labels = [];
|
var labels = [];
|
||||||
var text = this.text_;
|
var text = this.text_;
|
||||||
@@ -409,13 +408,13 @@ ol.render.canvas.TextReplay.prototype.drawChars_ = function(begin, end) {
|
|||||||
begin, end, labels, baseline,
|
begin, end, labels, baseline,
|
||||||
textState.exceedLength, textState.maxAngle,
|
textState.exceedLength, textState.maxAngle,
|
||||||
ol.render.canvas.TextReplay.getTextWidth.bind(widths, context, pixelRatio),
|
ol.render.canvas.TextReplay.getTextWidth.bind(widths, context, pixelRatio),
|
||||||
offsetY, strokeWidth, this.text_, align, this.textScale_
|
offsetY, this.text_, align, this.textScale_
|
||||||
]);
|
]);
|
||||||
this.hitDetectionInstructions.push([ol.render.canvas.Instruction.DRAW_CHARS,
|
this.hitDetectionInstructions.push([ol.render.canvas.Instruction.DRAW_CHARS,
|
||||||
begin, end, labels, baseline,
|
begin, end, labels, baseline,
|
||||||
textState.exceedLength, textState.maxAngle,
|
textState.exceedLength, textState.maxAngle,
|
||||||
ol.render.canvas.TextReplay.getTextWidth.bind(widths, context, 1),
|
ol.render.canvas.TextReplay.getTextWidth.bind(widths, context, 1),
|
||||||
offsetY, strokeWidth, this.text_, align, this.textScale_ / pixelRatio
|
offsetY, this.text_, align, this.textScale_ / pixelRatio
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.6 KiB |
@@ -99,7 +99,7 @@ describe('ol.rendering.style.Text', function() {
|
|||||||
var uglyPath = [163, 22, 159, 30, 150, 30, 143, 24, 151, 17];
|
var uglyPath = [163, 22, 159, 30, 150, 30, 143, 24, 151, 17];
|
||||||
var polygon = [151, 17, 163, 22, 159, 30, 150, 30, 143, 24, 151, 17];
|
var polygon = [151, 17, 163, 22, 159, 30, 150, 30, 143, 24, 151, 17];
|
||||||
|
|
||||||
function createLineString(coords, textAlign, maxAngle) {
|
function createLineString(coords, textAlign, maxAngle, strokeColor, strokeWidth) {
|
||||||
var geom = new ol.geom.LineString();
|
var geom = new ol.geom.LineString();
|
||||||
geom.setFlatCoordinates('XY', coords);
|
geom.setFlatCoordinates('XY', coords);
|
||||||
var style = new ol.style.Style({
|
var style = new ol.style.Style({
|
||||||
@@ -113,7 +113,8 @@ describe('ol.rendering.style.Text', function() {
|
|||||||
maxAngle: maxAngle,
|
maxAngle: maxAngle,
|
||||||
placement: 'line',
|
placement: 'line',
|
||||||
stroke: new ol.style.Stroke({
|
stroke: new ol.style.Stroke({
|
||||||
color: 'white'
|
color: strokeColor || 'white',
|
||||||
|
width: strokeWidth
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@@ -282,13 +283,20 @@ describe('ol.rendering.style.Text', function() {
|
|||||||
it('renders text along a linestring', function(done) {
|
it('renders text along a linestring', function(done) {
|
||||||
createMap('canvas');
|
createMap('canvas');
|
||||||
createLineString(nicePath);
|
createLineString(nicePath);
|
||||||
expectResemble(map, 'rendering/ol/style/expected/text-linestring-nice.png', 2.5, done);
|
expectResemble(map, 'rendering/ol/style/expected/text-linestring-nice.png', 2.8, done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('aligns text along a linestring correctly with `textBaseline` option', function(done) {
|
||||||
|
createMap('canvas');
|
||||||
|
createLineString(nicePath, undefined, undefined, 'cyan', 3);
|
||||||
|
map.getView().setResolution(0.25);
|
||||||
|
expectResemble(map, 'rendering/ol/style/expected/text-linestring-nice-baseline.png', 6.2, done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders text along a linestring with `textAlign: \'left\'`', function(done) {
|
it('renders text along a linestring with `textAlign: \'left\'`', function(done) {
|
||||||
createMap('canvas');
|
createMap('canvas');
|
||||||
createLineString(nicePath, 'left');
|
createLineString(nicePath, 'left');
|
||||||
expectResemble(map, 'rendering/ol/style/expected/text-linestring-left-nice.png', 2.5, done);
|
expectResemble(map, 'rendering/ol/style/expected/text-linestring-left-nice.png', 2.8, done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders text along a rotated linestring', function(done) {
|
it('renders text along a rotated linestring', function(done) {
|
||||||
|
|||||||