Merge pull request #7201 from ahocevar/text-renderer
Prerender text to images
This commit is contained in:
@@ -11,11 +11,12 @@ goog.require('ol.render.canvas.Replay');
|
|||||||
* @param {number} tolerance Tolerance.
|
* @param {number} tolerance Tolerance.
|
||||||
* @param {ol.Extent} maxExtent Maximum extent.
|
* @param {ol.Extent} maxExtent Maximum extent.
|
||||||
* @param {number} resolution Resolution.
|
* @param {number} resolution Resolution.
|
||||||
|
* @param {number} pixelRatio Pixel ratio.
|
||||||
* @param {boolean} overlaps The replay can have overlapping geometries.
|
* @param {boolean} overlaps The replay can have overlapping geometries.
|
||||||
* @struct
|
* @struct
|
||||||
*/
|
*/
|
||||||
ol.render.canvas.ImageReplay = function(tolerance, maxExtent, resolution, overlaps) {
|
ol.render.canvas.ImageReplay = function(tolerance, maxExtent, resolution, pixelRatio, overlaps) {
|
||||||
ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps);
|
ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, pixelRatio, overlaps);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@@ -131,7 +132,7 @@ ol.render.canvas.ImageReplay.prototype.drawPoint = function(pointGeometry, featu
|
|||||||
// Remaining arguments to DRAW_IMAGE are in alphabetical order
|
// Remaining arguments to DRAW_IMAGE are in alphabetical order
|
||||||
this.anchorX_, this.anchorY_, this.height_, this.opacity_,
|
this.anchorX_, this.anchorY_, this.height_, this.opacity_,
|
||||||
this.originX_, this.originY_, this.rotateWithView_, this.rotation_,
|
this.originX_, this.originY_, this.rotateWithView_, this.rotation_,
|
||||||
this.scale_, this.snapToPixel_, this.width_
|
this.scale_ * this.pixelRatio, this.snapToPixel_, this.width_
|
||||||
]);
|
]);
|
||||||
this.hitDetectionInstructions.push([
|
this.hitDetectionInstructions.push([
|
||||||
ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd,
|
ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd,
|
||||||
|
|||||||
@@ -10,12 +10,10 @@ ol.render.canvas.Instruction = {
|
|||||||
CLOSE_PATH: 3,
|
CLOSE_PATH: 3,
|
||||||
CUSTOM: 4,
|
CUSTOM: 4,
|
||||||
DRAW_IMAGE: 5,
|
DRAW_IMAGE: 5,
|
||||||
DRAW_TEXT: 6,
|
END_GEOMETRY: 6,
|
||||||
END_GEOMETRY: 7,
|
FILL: 7,
|
||||||
FILL: 8,
|
MOVE_TO_LINE_TO: 8,
|
||||||
MOVE_TO_LINE_TO: 9,
|
SET_FILL_STYLE: 9,
|
||||||
SET_FILL_STYLE: 10,
|
SET_STROKE_STYLE: 10,
|
||||||
SET_STROKE_STYLE: 11,
|
STROKE: 11
|
||||||
SET_TEXT_STYLE: 12,
|
|
||||||
STROKE: 13
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,12 +15,13 @@ goog.require('ol.render.canvas.Replay');
|
|||||||
* @param {number} tolerance Tolerance.
|
* @param {number} tolerance Tolerance.
|
||||||
* @param {ol.Extent} maxExtent Maximum extent.
|
* @param {ol.Extent} maxExtent Maximum extent.
|
||||||
* @param {number} resolution Resolution.
|
* @param {number} resolution Resolution.
|
||||||
|
* @param {number} pixelRatio Pixel ratio.
|
||||||
* @param {boolean} overlaps The replay can have overlapping geometries.
|
* @param {boolean} overlaps The replay can have overlapping geometries.
|
||||||
* @struct
|
* @struct
|
||||||
*/
|
*/
|
||||||
ol.render.canvas.LineStringReplay = function(tolerance, maxExtent, resolution, overlaps) {
|
ol.render.canvas.LineStringReplay = function(tolerance, maxExtent, resolution, pixelRatio, overlaps) {
|
||||||
|
|
||||||
ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps);
|
ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, pixelRatio, overlaps);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@@ -129,7 +130,8 @@ ol.render.canvas.LineStringReplay.prototype.setStrokeStyle_ = function() {
|
|||||||
state.lastStroke = 0;
|
state.lastStroke = 0;
|
||||||
this.instructions.push([
|
this.instructions.push([
|
||||||
ol.render.canvas.Instruction.SET_STROKE_STYLE,
|
ol.render.canvas.Instruction.SET_STROKE_STYLE,
|
||||||
strokeStyle, lineWidth, lineCap, lineJoin, miterLimit, lineDash, lineDashOffset, true, 1
|
strokeStyle, lineWidth * this.pixelRatio, lineCap, lineJoin, miterLimit,
|
||||||
|
this.applyPixelRatio(lineDash), lineDashOffset * this.pixelRatio
|
||||||
], [
|
], [
|
||||||
ol.render.canvas.Instruction.BEGIN_PATH
|
ol.render.canvas.Instruction.BEGIN_PATH
|
||||||
]);
|
]);
|
||||||
@@ -159,7 +161,7 @@ ol.render.canvas.LineStringReplay.prototype.drawLineString = function(lineString
|
|||||||
this.hitDetectionInstructions.push([
|
this.hitDetectionInstructions.push([
|
||||||
ol.render.canvas.Instruction.SET_STROKE_STYLE,
|
ol.render.canvas.Instruction.SET_STROKE_STYLE,
|
||||||
state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
|
state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
|
||||||
state.miterLimit, state.lineDash, state.lineDashOffset, true, 1
|
state.miterLimit, state.lineDash, state.lineDashOffset
|
||||||
], [
|
], [
|
||||||
ol.render.canvas.Instruction.BEGIN_PATH
|
ol.render.canvas.Instruction.BEGIN_PATH
|
||||||
]);
|
]);
|
||||||
@@ -186,7 +188,7 @@ ol.render.canvas.LineStringReplay.prototype.drawMultiLineString = function(multi
|
|||||||
this.hitDetectionInstructions.push([
|
this.hitDetectionInstructions.push([
|
||||||
ol.render.canvas.Instruction.SET_STROKE_STYLE,
|
ol.render.canvas.Instruction.SET_STROKE_STYLE,
|
||||||
state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
|
state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
|
||||||
state.miterLimit, state.lineDash, state.lineDashOffset, true, 1
|
state.miterLimit, state.lineDash, state.lineDashOffset
|
||||||
], [
|
], [
|
||||||
ol.render.canvas.Instruction.BEGIN_PATH
|
ol.render.canvas.Instruction.BEGIN_PATH
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -17,12 +17,13 @@ goog.require('ol.render.canvas.Replay');
|
|||||||
* @param {number} tolerance Tolerance.
|
* @param {number} tolerance Tolerance.
|
||||||
* @param {ol.Extent} maxExtent Maximum extent.
|
* @param {ol.Extent} maxExtent Maximum extent.
|
||||||
* @param {number} resolution Resolution.
|
* @param {number} resolution Resolution.
|
||||||
|
* @param {number} pixelRatio Pixel ratio.
|
||||||
* @param {boolean} overlaps The replay can have overlapping geometries.
|
* @param {boolean} overlaps The replay can have overlapping geometries.
|
||||||
* @struct
|
* @struct
|
||||||
*/
|
*/
|
||||||
ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution, overlaps) {
|
ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution, pixelRatio, overlaps) {
|
||||||
|
|
||||||
ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps);
|
ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, pixelRatio, overlaps);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@@ -141,7 +142,7 @@ ol.render.canvas.PolygonReplay.prototype.drawCircle = function(circleGeometry, f
|
|||||||
this.hitDetectionInstructions.push([
|
this.hitDetectionInstructions.push([
|
||||||
ol.render.canvas.Instruction.SET_STROKE_STYLE,
|
ol.render.canvas.Instruction.SET_STROKE_STYLE,
|
||||||
state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
|
state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
|
||||||
state.miterLimit, state.lineDash, state.lineDashOffset, true, 1
|
state.miterLimit, state.lineDash, state.lineDashOffset
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
var flatCoordinates = circleGeometry.getFlatCoordinates();
|
var flatCoordinates = circleGeometry.getFlatCoordinates();
|
||||||
@@ -183,7 +184,7 @@ ol.render.canvas.PolygonReplay.prototype.drawPolygon = function(polygonGeometry,
|
|||||||
this.hitDetectionInstructions.push([
|
this.hitDetectionInstructions.push([
|
||||||
ol.render.canvas.Instruction.SET_STROKE_STYLE,
|
ol.render.canvas.Instruction.SET_STROKE_STYLE,
|
||||||
state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
|
state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
|
||||||
state.miterLimit, state.lineDash, state.lineDashOffset, true, 1
|
state.miterLimit, state.lineDash, state.lineDashOffset
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
var ends = polygonGeometry.getEnds();
|
var ends = polygonGeometry.getEnds();
|
||||||
@@ -215,7 +216,7 @@ ol.render.canvas.PolygonReplay.prototype.drawMultiPolygon = function(multiPolygo
|
|||||||
this.hitDetectionInstructions.push([
|
this.hitDetectionInstructions.push([
|
||||||
ol.render.canvas.Instruction.SET_STROKE_STYLE,
|
ol.render.canvas.Instruction.SET_STROKE_STYLE,
|
||||||
state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
|
state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
|
||||||
state.miterLimit, state.lineDash, state.lineDashOffset, true, 1
|
state.miterLimit, state.lineDash, state.lineDashOffset
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
var endss = multiPolygonGeometry.getEndss();
|
var endss = multiPolygonGeometry.getEndss();
|
||||||
@@ -352,7 +353,8 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function(geometr
|
|||||||
state.currentMiterLimit != miterLimit) {
|
state.currentMiterLimit != miterLimit) {
|
||||||
this.instructions.push([
|
this.instructions.push([
|
||||||
ol.render.canvas.Instruction.SET_STROKE_STYLE,
|
ol.render.canvas.Instruction.SET_STROKE_STYLE,
|
||||||
strokeStyle, lineWidth, lineCap, lineJoin, miterLimit, lineDash, lineDashOffset, true, 1
|
strokeStyle, lineWidth * this.pixelRatio, lineCap, lineJoin, miterLimit,
|
||||||
|
this.applyPixelRatio(lineDash), lineDashOffset * this.pixelRatio
|
||||||
]);
|
]);
|
||||||
state.currentStrokeStyle = strokeStyle;
|
state.currentStrokeStyle = strokeStyle;
|
||||||
state.currentLineCap = lineCap;
|
state.currentLineCap = lineCap;
|
||||||
|
|||||||
@@ -20,10 +20,11 @@ goog.require('ol.transform');
|
|||||||
* @param {number} tolerance Tolerance.
|
* @param {number} tolerance Tolerance.
|
||||||
* @param {ol.Extent} maxExtent Maximum extent.
|
* @param {ol.Extent} maxExtent Maximum extent.
|
||||||
* @param {number} resolution Resolution.
|
* @param {number} resolution Resolution.
|
||||||
|
* @param {number} pixelRatio Pixel ratio.
|
||||||
* @param {boolean} overlaps The replay can have overlapping geometries.
|
* @param {boolean} overlaps The replay can have overlapping geometries.
|
||||||
* @struct
|
* @struct
|
||||||
*/
|
*/
|
||||||
ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, overlaps) {
|
ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, pixelRatio, overlaps) {
|
||||||
ol.render.VectorContext.call(this);
|
ol.render.VectorContext.call(this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,6 +46,12 @@ ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, overlaps) {
|
|||||||
*/
|
*/
|
||||||
this.overlaps = overlaps;
|
this.overlaps = overlaps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
this.pixelRatio = pixelRatio;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @protected
|
* @protected
|
||||||
* @type {number}
|
* @type {number}
|
||||||
@@ -127,6 +134,19 @@ ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, overlaps) {
|
|||||||
ol.inherits(ol.render.canvas.Replay, ol.render.VectorContext);
|
ol.inherits(ol.render.canvas.Replay, ol.render.VectorContext);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @param {Array.<number>} dashArray Dash array.
|
||||||
|
* @return {Array.<number>} Dash array with pixel ratio applied
|
||||||
|
*/
|
||||||
|
ol.render.canvas.Replay.prototype.applyPixelRatio = function(dashArray) {
|
||||||
|
var pixelRatio = this.pixelRatio;
|
||||||
|
return pixelRatio == 1 ? dashArray : dashArray.map(function(dash) {
|
||||||
|
return dash * pixelRatio;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||||
* @param {number} offset Offset.
|
* @param {number} offset Offset.
|
||||||
@@ -287,7 +307,6 @@ ol.render.canvas.Replay.prototype.fill_ = function(context, rotation) {
|
|||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {CanvasRenderingContext2D} context Context.
|
* @param {CanvasRenderingContext2D} context Context.
|
||||||
* @param {number} pixelRatio Pixel ratio.
|
|
||||||
* @param {ol.Transform} transform Transform.
|
* @param {ol.Transform} transform Transform.
|
||||||
* @param {number} viewRotation View rotation.
|
* @param {number} viewRotation View rotation.
|
||||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||||
@@ -301,7 +320,7 @@ ol.render.canvas.Replay.prototype.fill_ = function(context, rotation) {
|
|||||||
* @template T
|
* @template T
|
||||||
*/
|
*/
|
||||||
ol.render.canvas.Replay.prototype.replay_ = function(
|
ol.render.canvas.Replay.prototype.replay_ = function(
|
||||||
context, pixelRatio, transform, viewRotation, skippedFeaturesHash,
|
context, transform, viewRotation, skippedFeaturesHash,
|
||||||
instructions, featureCallback, opt_hitExtent) {
|
instructions, featureCallback, opt_hitExtent) {
|
||||||
/** @type {Array.<number>} */
|
/** @type {Array.<number>} */
|
||||||
var pixelCoordinates;
|
var pixelCoordinates;
|
||||||
@@ -330,7 +349,7 @@ ol.render.canvas.Replay.prototype.replay_ = function(
|
|||||||
|
|
||||||
var state = /** @type {olx.render.State} */ ({
|
var state = /** @type {olx.render.State} */ ({
|
||||||
context: context,
|
context: context,
|
||||||
pixelRatio: pixelRatio,
|
pixelRatio: this.pixelRatio,
|
||||||
resolution: this.resolution,
|
resolution: this.resolution,
|
||||||
rotation: viewRotation
|
rotation: viewRotation
|
||||||
});
|
});
|
||||||
@@ -342,7 +361,7 @@ ol.render.canvas.Replay.prototype.replay_ = function(
|
|||||||
while (i < ii) {
|
while (i < ii) {
|
||||||
var instruction = instructions[i];
|
var instruction = instructions[i];
|
||||||
var type = /** @type {ol.render.canvas.Instruction} */ (instruction[0]);
|
var type = /** @type {ol.render.canvas.Instruction} */ (instruction[0]);
|
||||||
var /** @type {ol.Feature|ol.render.Feature} */ feature, fill, stroke, text, x, y;
|
var /** @type {ol.Feature|ol.render.Feature} */ feature, x, y;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ol.render.canvas.Instruction.BEGIN_GEOMETRY:
|
case ol.render.canvas.Instruction.BEGIN_GEOMETRY:
|
||||||
feature = /** @type {ol.Feature|ol.render.Feature} */ (instruction[1]);
|
feature = /** @type {ol.Feature|ol.render.Feature} */ (instruction[1]);
|
||||||
@@ -416,16 +435,16 @@ ol.render.canvas.Replay.prototype.replay_ = function(
|
|||||||
dd = /** @type {number} */ (instruction[2]);
|
dd = /** @type {number} */ (instruction[2]);
|
||||||
var image = /** @type {HTMLCanvasElement|HTMLVideoElement|Image} */
|
var image = /** @type {HTMLCanvasElement|HTMLVideoElement|Image} */
|
||||||
(instruction[3]);
|
(instruction[3]);
|
||||||
|
var scale = /** @type {number} */ (instruction[12]);
|
||||||
// Remaining arguments in DRAW_IMAGE are in alphabetical order
|
// Remaining arguments in DRAW_IMAGE are in alphabetical order
|
||||||
var anchorX = /** @type {number} */ (instruction[4]) * pixelRatio;
|
var anchorX = /** @type {number} */ (instruction[4]) * scale;
|
||||||
var anchorY = /** @type {number} */ (instruction[5]) * pixelRatio;
|
var anchorY = /** @type {number} */ (instruction[5]) * scale;
|
||||||
var height = /** @type {number} */ (instruction[6]);
|
var height = /** @type {number} */ (instruction[6]);
|
||||||
var opacity = /** @type {number} */ (instruction[7]);
|
var opacity = /** @type {number} */ (instruction[7]);
|
||||||
var originX = /** @type {number} */ (instruction[8]);
|
var originX = /** @type {number} */ (instruction[8]);
|
||||||
var originY = /** @type {number} */ (instruction[9]);
|
var originY = /** @type {number} */ (instruction[9]);
|
||||||
var rotateWithView = /** @type {boolean} */ (instruction[10]);
|
var rotateWithView = /** @type {boolean} */ (instruction[10]);
|
||||||
var rotation = /** @type {number} */ (instruction[11]);
|
var rotation = /** @type {number} */ (instruction[11]);
|
||||||
var scale = /** @type {number} */ (instruction[12]);
|
|
||||||
var snapToPixel = /** @type {boolean} */ (instruction[13]);
|
var snapToPixel = /** @type {boolean} */ (instruction[13]);
|
||||||
var width = /** @type {number} */ (instruction[14]);
|
var width = /** @type {number} */ (instruction[14]);
|
||||||
if (rotateWithView) {
|
if (rotateWithView) {
|
||||||
@@ -438,11 +457,11 @@ ol.render.canvas.Replay.prototype.replay_ = function(
|
|||||||
x = Math.round(x);
|
x = Math.round(x);
|
||||||
y = Math.round(y);
|
y = Math.round(y);
|
||||||
}
|
}
|
||||||
if (scale != 1 || rotation !== 0) {
|
if (rotation !== 0) {
|
||||||
var centerX = x + anchorX;
|
var centerX = x + anchorX;
|
||||||
var centerY = y + anchorY;
|
var centerY = y + anchorY;
|
||||||
ol.transform.compose(localTransform,
|
ol.transform.compose(localTransform,
|
||||||
centerX, centerY, scale, scale, rotation, -centerX, -centerY);
|
centerX, centerY, 1, 1, rotation, -centerX, -centerY);
|
||||||
context.setTransform.apply(context, localTransform);
|
context.setTransform.apply(context, localTransform);
|
||||||
}
|
}
|
||||||
var alpha = context.globalAlpha;
|
var alpha = context.globalAlpha;
|
||||||
@@ -454,67 +473,12 @@ ol.render.canvas.Replay.prototype.replay_ = function(
|
|||||||
var h = (height + originY > image.height) ? image.height - originY : height;
|
var h = (height + originY > image.height) ? image.height - originY : height;
|
||||||
|
|
||||||
context.drawImage(image, originX, originY, w, h,
|
context.drawImage(image, originX, originY, w, h,
|
||||||
x, y, w * pixelRatio, h * pixelRatio);
|
x, y, w * scale, h * scale);
|
||||||
|
|
||||||
if (opacity != 1) {
|
if (opacity != 1) {
|
||||||
context.globalAlpha = alpha;
|
context.globalAlpha = alpha;
|
||||||
}
|
}
|
||||||
if (scale != 1 || rotation !== 0) {
|
if (rotation !== 0) {
|
||||||
context.setTransform.apply(context, resetTransform);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
break;
|
|
||||||
case ol.render.canvas.Instruction.DRAW_TEXT:
|
|
||||||
d = /** @type {number} */ (instruction[1]);
|
|
||||||
dd = /** @type {number} */ (instruction[2]);
|
|
||||||
text = /** @type {string} */ (instruction[3]);
|
|
||||||
var offsetX = /** @type {number} */ (instruction[4]) * pixelRatio;
|
|
||||||
var offsetY = /** @type {number} */ (instruction[5]) * pixelRatio;
|
|
||||||
rotation = /** @type {number} */ (instruction[6]);
|
|
||||||
scale = /** @type {number} */ (instruction[7]) * pixelRatio;
|
|
||||||
fill = /** @type {boolean} */ (instruction[8]);
|
|
||||||
stroke = /** @type {boolean} */ (instruction[9]);
|
|
||||||
rotateWithView = /** @type {boolean} */ (instruction[10]);
|
|
||||||
if (rotateWithView) {
|
|
||||||
rotation += viewRotation;
|
|
||||||
}
|
|
||||||
for (; d < dd; d += 2) {
|
|
||||||
x = pixelCoordinates[d] + offsetX;
|
|
||||||
y = pixelCoordinates[d + 1] + offsetY;
|
|
||||||
if (scale != 1 || rotation !== 0) {
|
|
||||||
ol.transform.compose(localTransform, x, y, scale, scale, rotation, -x, -y);
|
|
||||||
context.setTransform.apply(context, localTransform);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Support multiple lines separated by \n
|
|
||||||
var lines = text.split('\n');
|
|
||||||
var numLines = lines.length;
|
|
||||||
var fontSize, lineY;
|
|
||||||
if (numLines > 1) {
|
|
||||||
// Estimate line height using width of capital M, and add padding
|
|
||||||
fontSize = Math.round(context.measureText('M').width * 1.5);
|
|
||||||
lineY = y - (((numLines - 1) / 2) * fontSize);
|
|
||||||
} else {
|
|
||||||
// No need to calculate line height/offset for a single line
|
|
||||||
fontSize = 0;
|
|
||||||
lineY = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var lineIndex = 0; lineIndex < numLines; lineIndex++) {
|
|
||||||
var line = lines[lineIndex];
|
|
||||||
if (stroke) {
|
|
||||||
context.strokeText(line, x, lineY);
|
|
||||||
}
|
|
||||||
if (fill) {
|
|
||||||
context.fillText(line, x, lineY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move next line down by fontSize px
|
|
||||||
lineY = lineY + fontSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scale != 1 || rotation !== 0) {
|
|
||||||
context.setTransform.apply(context, resetTransform);
|
context.setTransform.apply(context, resetTransform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -579,43 +543,21 @@ ol.render.canvas.Replay.prototype.replay_ = function(
|
|||||||
++i;
|
++i;
|
||||||
break;
|
break;
|
||||||
case ol.render.canvas.Instruction.SET_STROKE_STYLE:
|
case ol.render.canvas.Instruction.SET_STROKE_STYLE:
|
||||||
var usePixelRatio = instruction[8] !== undefined ?
|
|
||||||
instruction[8] : true;
|
|
||||||
var renderedPixelRatio = instruction[9];
|
|
||||||
|
|
||||||
var lineWidth = /** @type {number} */ (instruction[2]);
|
|
||||||
if (pendingStroke) {
|
if (pendingStroke) {
|
||||||
context.stroke();
|
context.stroke();
|
||||||
pendingStroke = 0;
|
pendingStroke = 0;
|
||||||
}
|
}
|
||||||
context.strokeStyle = /** @type {ol.ColorLike} */ (instruction[1]);
|
context.strokeStyle = /** @type {ol.ColorLike} */ (instruction[1]);
|
||||||
context.lineWidth = usePixelRatio ? lineWidth * pixelRatio : lineWidth;
|
context.lineWidth = /** @type {number} */ (instruction[2]);
|
||||||
context.lineCap = /** @type {string} */ (instruction[3]);
|
context.lineCap = /** @type {string} */ (instruction[3]);
|
||||||
context.lineJoin = /** @type {string} */ (instruction[4]);
|
context.lineJoin = /** @type {string} */ (instruction[4]);
|
||||||
context.miterLimit = /** @type {number} */ (instruction[5]);
|
context.miterLimit = /** @type {number} */ (instruction[5]);
|
||||||
if (ol.has.CANVAS_LINE_DASH) {
|
if (ol.has.CANVAS_LINE_DASH) {
|
||||||
var lineDash = /** @type {Array.<number>} */ (instruction[6]);
|
context.lineDashOffset = /** @type {number} */ (instruction[7]);
|
||||||
var lineDashOffset = /** @type {number} */ (instruction[7]);
|
context.setLineDash(/** @type {Array.<number>} */ (instruction[6]));
|
||||||
if (usePixelRatio && pixelRatio !== renderedPixelRatio) {
|
|
||||||
lineDash = lineDash.map(function(dash) {
|
|
||||||
return dash * pixelRatio / renderedPixelRatio;
|
|
||||||
});
|
|
||||||
lineDashOffset *= pixelRatio / renderedPixelRatio;
|
|
||||||
instruction[6] = lineDash;
|
|
||||||
instruction[7] = lineDashOffset;
|
|
||||||
instruction[9] = pixelRatio;
|
|
||||||
}
|
|
||||||
context.lineDashOffset = lineDashOffset;
|
|
||||||
context.setLineDash(lineDash);
|
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
break;
|
break;
|
||||||
case ol.render.canvas.Instruction.SET_TEXT_STYLE:
|
|
||||||
context.font = /** @type {string} */ (instruction[1]);
|
|
||||||
context.textAlign = /** @type {string} */ (instruction[2]);
|
|
||||||
context.textBaseline = /** @type {string} */ (instruction[3]);
|
|
||||||
++i;
|
|
||||||
break;
|
|
||||||
case ol.render.canvas.Instruction.STROKE:
|
case ol.render.canvas.Instruction.STROKE:
|
||||||
if (batchSize) {
|
if (batchSize) {
|
||||||
pendingStroke++;
|
pendingStroke++;
|
||||||
@@ -641,16 +583,15 @@ ol.render.canvas.Replay.prototype.replay_ = function(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {CanvasRenderingContext2D} context Context.
|
* @param {CanvasRenderingContext2D} context Context.
|
||||||
* @param {number} pixelRatio Pixel ratio.
|
|
||||||
* @param {ol.Transform} transform Transform.
|
* @param {ol.Transform} transform Transform.
|
||||||
* @param {number} viewRotation View rotation.
|
* @param {number} viewRotation View rotation.
|
||||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||||
* to skip.
|
* to skip.
|
||||||
*/
|
*/
|
||||||
ol.render.canvas.Replay.prototype.replay = function(
|
ol.render.canvas.Replay.prototype.replay = function(
|
||||||
context, pixelRatio, transform, viewRotation, skippedFeaturesHash) {
|
context, transform, viewRotation, skippedFeaturesHash) {
|
||||||
var instructions = this.instructions;
|
var instructions = this.instructions;
|
||||||
this.replay_(context, pixelRatio, transform, viewRotation,
|
this.replay_(context, transform, viewRotation,
|
||||||
skippedFeaturesHash, instructions, undefined, undefined);
|
skippedFeaturesHash, instructions, undefined, undefined);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -672,7 +613,7 @@ ol.render.canvas.Replay.prototype.replayHitDetection = function(
|
|||||||
context, transform, viewRotation, skippedFeaturesHash,
|
context, transform, viewRotation, skippedFeaturesHash,
|
||||||
opt_featureCallback, opt_hitExtent) {
|
opt_featureCallback, opt_hitExtent) {
|
||||||
var instructions = this.hitDetectionInstructions;
|
var instructions = this.hitDetectionInstructions;
|
||||||
return this.replay_(context, 1, transform, viewRotation,
|
return this.replay_(context, transform, viewRotation,
|
||||||
skippedFeaturesHash, instructions, opt_featureCallback, opt_hitExtent);
|
skippedFeaturesHash, instructions, opt_featureCallback, opt_hitExtent);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -22,12 +22,13 @@ goog.require('ol.transform');
|
|||||||
* @param {number} tolerance Tolerance.
|
* @param {number} tolerance Tolerance.
|
||||||
* @param {ol.Extent} maxExtent Max extent.
|
* @param {ol.Extent} maxExtent Max extent.
|
||||||
* @param {number} resolution Resolution.
|
* @param {number} resolution Resolution.
|
||||||
|
* @param {number} pixelRatio Pixel ratio.
|
||||||
* @param {boolean} overlaps The replay group can have overlapping geometries.
|
* @param {boolean} overlaps The replay group can have overlapping geometries.
|
||||||
* @param {number=} opt_renderBuffer Optional rendering buffer.
|
* @param {number=} opt_renderBuffer Optional rendering buffer.
|
||||||
* @struct
|
* @struct
|
||||||
*/
|
*/
|
||||||
ol.render.canvas.ReplayGroup = function(
|
ol.render.canvas.ReplayGroup = function(
|
||||||
tolerance, maxExtent, resolution, overlaps, opt_renderBuffer) {
|
tolerance, maxExtent, resolution, pixelRatio, overlaps, opt_renderBuffer) {
|
||||||
ol.render.ReplayGroup.call(this);
|
ol.render.ReplayGroup.call(this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,6 +49,12 @@ ol.render.canvas.ReplayGroup = function(
|
|||||||
*/
|
*/
|
||||||
this.overlaps_ = overlaps;
|
this.overlaps_ = overlaps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
this.pixelRatio_ = pixelRatio;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {number}
|
* @type {number}
|
||||||
@@ -296,7 +303,7 @@ ol.render.canvas.ReplayGroup.prototype.getReplay = function(zIndex, replayType)
|
|||||||
if (replay === undefined) {
|
if (replay === undefined) {
|
||||||
var Constructor = ol.render.canvas.ReplayGroup.BATCH_CONSTRUCTORS_[replayType];
|
var Constructor = ol.render.canvas.ReplayGroup.BATCH_CONSTRUCTORS_[replayType];
|
||||||
replay = new Constructor(this.tolerance_, this.maxExtent_,
|
replay = new Constructor(this.tolerance_, this.maxExtent_,
|
||||||
this.resolution_, this.overlaps_);
|
this.resolution_, this.pixelRatio_, this.overlaps_);
|
||||||
replays[replayType] = replay;
|
replays[replayType] = replay;
|
||||||
}
|
}
|
||||||
return replay;
|
return replay;
|
||||||
@@ -313,7 +320,6 @@ ol.render.canvas.ReplayGroup.prototype.isEmpty = function() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {CanvasRenderingContext2D} context Context.
|
* @param {CanvasRenderingContext2D} context Context.
|
||||||
* @param {number} pixelRatio Pixel ratio.
|
|
||||||
* @param {ol.Transform} transform Transform.
|
* @param {ol.Transform} transform Transform.
|
||||||
* @param {number} viewRotation View rotation.
|
* @param {number} viewRotation View rotation.
|
||||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||||
@@ -321,7 +327,7 @@ ol.render.canvas.ReplayGroup.prototype.isEmpty = function() {
|
|||||||
* @param {Array.<ol.render.ReplayType>=} opt_replayTypes Ordered replay types
|
* @param {Array.<ol.render.ReplayType>=} opt_replayTypes Ordered replay types
|
||||||
* to replay. Default is {@link ol.render.replay.ORDER}
|
* to replay. Default is {@link ol.render.replay.ORDER}
|
||||||
*/
|
*/
|
||||||
ol.render.canvas.ReplayGroup.prototype.replay = function(context, pixelRatio,
|
ol.render.canvas.ReplayGroup.prototype.replay = function(context,
|
||||||
transform, viewRotation, skippedFeaturesHash, opt_replayTypes) {
|
transform, viewRotation, skippedFeaturesHash, opt_replayTypes) {
|
||||||
|
|
||||||
/** @type {Array.<number>} */
|
/** @type {Array.<number>} */
|
||||||
@@ -346,8 +352,7 @@ ol.render.canvas.ReplayGroup.prototype.replay = function(context, pixelRatio,
|
|||||||
for (j = 0, jj = replayTypes.length; j < jj; ++j) {
|
for (j = 0, jj = replayTypes.length; j < jj; ++j) {
|
||||||
replay = replays[replayTypes[j]];
|
replay = replays[replayTypes[j]];
|
||||||
if (replay !== undefined) {
|
if (replay !== undefined) {
|
||||||
replay.replay(context, pixelRatio, transform, viewRotation,
|
replay.replay(context, transform, viewRotation, skippedFeaturesHash);
|
||||||
skippedFeaturesHash);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -402,7 +407,7 @@ ol.render.canvas.ReplayGroup.prototype.replayHitDetection_ = function(
|
|||||||
* @private
|
* @private
|
||||||
* @type {Object.<ol.render.ReplayType,
|
* @type {Object.<ol.render.ReplayType,
|
||||||
* function(new: ol.render.canvas.Replay, number, ol.Extent,
|
* function(new: ol.render.canvas.Replay, number, ol.Extent,
|
||||||
* number, boolean)>}
|
* number, number, boolean)>}
|
||||||
*/
|
*/
|
||||||
ol.render.canvas.ReplayGroup.BATCH_CONSTRUCTORS_ = {
|
ol.render.canvas.ReplayGroup.BATCH_CONSTRUCTORS_ = {
|
||||||
'Circle': ol.render.canvas.PolygonReplay,
|
'Circle': ol.render.canvas.PolygonReplay,
|
||||||
|
|||||||
+137
-136
@@ -2,9 +2,12 @@ goog.provide('ol.render.canvas.TextReplay');
|
|||||||
|
|
||||||
goog.require('ol');
|
goog.require('ol');
|
||||||
goog.require('ol.colorlike');
|
goog.require('ol.colorlike');
|
||||||
|
goog.require('ol.has');
|
||||||
goog.require('ol.render.canvas');
|
goog.require('ol.render.canvas');
|
||||||
goog.require('ol.render.canvas.Instruction');
|
goog.require('ol.render.canvas.Instruction');
|
||||||
goog.require('ol.render.canvas.Replay');
|
goog.require('ol.render.canvas.Replay');
|
||||||
|
goog.require('ol.render.replay');
|
||||||
|
goog.require('ol.structs.LRUCache');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -13,30 +16,13 @@ goog.require('ol.render.canvas.Replay');
|
|||||||
* @param {number} tolerance Tolerance.
|
* @param {number} tolerance Tolerance.
|
||||||
* @param {ol.Extent} maxExtent Maximum extent.
|
* @param {ol.Extent} maxExtent Maximum extent.
|
||||||
* @param {number} resolution Resolution.
|
* @param {number} resolution Resolution.
|
||||||
|
* @param {number} pixelRatio Pixel ratio.
|
||||||
* @param {boolean} overlaps The replay can have overlapping geometries.
|
* @param {boolean} overlaps The replay can have overlapping geometries.
|
||||||
* @struct
|
* @struct
|
||||||
*/
|
*/
|
||||||
ol.render.canvas.TextReplay = function(tolerance, maxExtent, resolution, overlaps) {
|
ol.render.canvas.TextReplay = function(tolerance, maxExtent, resolution, pixelRatio, overlaps) {
|
||||||
|
|
||||||
ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, overlaps);
|
ol.render.canvas.Replay.call(this, tolerance, maxExtent, resolution, pixelRatio, overlaps);
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {?ol.CanvasFillState}
|
|
||||||
*/
|
|
||||||
this.replayFillState_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {?ol.CanvasStrokeState}
|
|
||||||
*/
|
|
||||||
this.replayStrokeState_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {?ol.CanvasTextState}
|
|
||||||
*/
|
|
||||||
this.replayTextState_ = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@@ -92,140 +78,155 @@ ol.render.canvas.TextReplay = function(tolerance, maxExtent, resolution, overlap
|
|||||||
*/
|
*/
|
||||||
this.textState_ = null;
|
this.textState_ = null;
|
||||||
|
|
||||||
|
while (ol.render.canvas.TextReplay.labelCache_.canExpireCache()) {
|
||||||
|
ol.render.canvas.TextReplay.labelCache_.pop();
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
ol.inherits(ol.render.canvas.TextReplay, ol.render.canvas.Replay);
|
ol.inherits(ol.render.canvas.TextReplay, ol.render.canvas.Replay);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {ol.structs.LRUCache.<HTMLCanvasElement>}
|
||||||
|
*/
|
||||||
|
ol.render.canvas.TextReplay.labelCache_ = new ol.structs.LRUCache();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} font Font to use for measuring.
|
||||||
|
* @param {Array.<string>} lines Lines to measure.
|
||||||
|
* @param {Array.<number>} widths Array will be populated with the widths of
|
||||||
|
* each line.
|
||||||
|
* @return {ol.Size} Measuremnt.
|
||||||
|
*/
|
||||||
|
ol.render.canvas.TextReplay.measureText = (function() {
|
||||||
|
var textContainer;
|
||||||
|
return function(font, lines, widths) {
|
||||||
|
if (!textContainer) {
|
||||||
|
textContainer = document.createElement('span');
|
||||||
|
textContainer.style.visibility = 'hidden';
|
||||||
|
textContainer.style.whiteSpace = 'nowrap';
|
||||||
|
}
|
||||||
|
textContainer.style.font = font;
|
||||||
|
document.body.appendChild(textContainer);
|
||||||
|
var numLines = lines.length;
|
||||||
|
var width = 0;
|
||||||
|
var currentWidth, i;
|
||||||
|
for (i = 0; i < numLines; ++i) {
|
||||||
|
textContainer.textContent = lines[i];
|
||||||
|
currentWidth = textContainer.offsetWidth;
|
||||||
|
width = Math.max(width, currentWidth);
|
||||||
|
widths.push(currentWidth);
|
||||||
|
}
|
||||||
|
var measurement = [width, textContainer.offsetHeight * numLines];
|
||||||
|
document.body.removeChild(textContainer);
|
||||||
|
return measurement;
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.render.canvas.TextReplay.prototype.drawText = function(flatCoordinates, offset, end, stride, geometry, feature) {
|
ol.render.canvas.TextReplay.prototype.drawText = function(flatCoordinates, offset, end, stride, geometry, feature) {
|
||||||
if (this.text_ === '' || !this.textState_ ||
|
var fillState = this.textFillState_;
|
||||||
(!this.textFillState_ && !this.textStrokeState_)) {
|
var strokeState = this.textStrokeState_;
|
||||||
|
var textState = this.textState_;
|
||||||
|
if (this.text_ === '' || !textState || (!fillState && !strokeState)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.textFillState_) {
|
|
||||||
this.setReplayFillState_(this.textFillState_);
|
|
||||||
}
|
|
||||||
if (this.textStrokeState_) {
|
|
||||||
this.setReplayStrokeState_(this.textStrokeState_);
|
|
||||||
}
|
|
||||||
this.setReplayTextState_(this.textState_);
|
|
||||||
this.beginGeometry(geometry, feature);
|
this.beginGeometry(geometry, feature);
|
||||||
|
|
||||||
var myBegin = this.coordinates.length;
|
var myBegin = this.coordinates.length;
|
||||||
var myEnd =
|
var myEnd =
|
||||||
this.appendFlatCoordinates(flatCoordinates, offset, end, stride, false, false);
|
this.appendFlatCoordinates(flatCoordinates, offset, end, stride, false, false);
|
||||||
var fill = !!this.textFillState_;
|
var fill = !!fillState;
|
||||||
var stroke = !!this.textStrokeState_;
|
var stroke = !!strokeState;
|
||||||
var drawTextInstruction = [
|
var pixelRatio = this.pixelRatio;
|
||||||
ol.render.canvas.Instruction.DRAW_TEXT, myBegin, myEnd, this.text_,
|
var textAlign = textState.textAlign;
|
||||||
this.textOffsetX_, this.textOffsetY_, this.textRotation_, this.textScale_,
|
var align = ol.render.replay.TEXT_ALIGN[textAlign];
|
||||||
fill, stroke, this.textRotateWithView_];
|
var textBaseline = textState.textBaseline;
|
||||||
this.instructions.push(drawTextInstruction);
|
var baseline = ol.render.replay.TEXT_ALIGN[textBaseline];
|
||||||
this.hitDetectionInstructions.push(drawTextInstruction);
|
var strokeWidth = stroke && strokeState.lineWidth ? strokeState.lineWidth : 0;
|
||||||
|
|
||||||
|
var label;
|
||||||
|
var text = this.text_;
|
||||||
|
var key =
|
||||||
|
(stroke ?
|
||||||
|
(typeof strokeState.strokeStyle == 'string' ? strokeState.strokeStyle : ol.getUid(strokeState.strokeStyle)) +
|
||||||
|
strokeState.lineCap + strokeState.lineDashOffset + '|' + strokeWidth +
|
||||||
|
strokeState.lineJoin + strokeState.miterLimit +
|
||||||
|
'[' + strokeState.lineDash.join() + ']' : '') +
|
||||||
|
textState.font + textAlign + text +
|
||||||
|
(fill ?
|
||||||
|
(typeof fillState.fillStyle == 'string' ? fillState.fillStyle : ('|' + ol.getUid(fillState.fillStyle))) : '');
|
||||||
|
|
||||||
|
var lines = text.split('\n');
|
||||||
|
var numLines = lines.length;
|
||||||
|
|
||||||
|
if (!ol.render.canvas.TextReplay.labelCache_.containsKey(key)) {
|
||||||
|
label = /** @type {HTMLCanvasElement} */ (document.createElement('canvas'));
|
||||||
|
ol.render.canvas.TextReplay.labelCache_.set(key, label);
|
||||||
|
var context = label.getContext('2d');
|
||||||
|
var widths = [];
|
||||||
|
var metrics = ol.render.canvas.TextReplay.measureText(textState.font, lines, widths);
|
||||||
|
var lineHeight = metrics[1] / numLines;
|
||||||
|
label.width = Math.ceil(metrics[0] + 2 * strokeWidth) * pixelRatio;
|
||||||
|
label.height = Math.ceil(metrics[1] + 2 * strokeWidth) * pixelRatio;
|
||||||
|
context.scale(pixelRatio, pixelRatio);
|
||||||
|
context.font = textState.font;
|
||||||
|
if (stroke) {
|
||||||
|
context.strokeStyle = strokeState.strokeStyle;
|
||||||
|
context.lineWidth = strokeState.lineWidth;
|
||||||
|
context.lineCap = strokeState.lineCap;
|
||||||
|
context.lineJoin = strokeState.lineJoin;
|
||||||
|
context.miterLimit = strokeState.miterLimit;
|
||||||
|
if (ol.has.CANVAS_LINE_DASH) {
|
||||||
|
context.setLineDash(strokeState.lineDash);
|
||||||
|
context.lineDashOffset = strokeState.lineDashOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fill) {
|
||||||
|
context.fillStyle = fillState.fillStyle;
|
||||||
|
}
|
||||||
|
context.textBaseline = 'top';
|
||||||
|
context.textAlign = 'left';
|
||||||
|
var x = align * label.width / pixelRatio + 2 * (0.5 - align) * strokeWidth;
|
||||||
|
var i;
|
||||||
|
if (stroke) {
|
||||||
|
for (i = 0; i < numLines; ++i) {
|
||||||
|
context.strokeText(lines[i], x - align * widths[i], strokeWidth + i * lineHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fill) {
|
||||||
|
for (i = 0; i < numLines; ++i) {
|
||||||
|
context.fillText(lines[i], x - align * widths[i], strokeWidth + i * lineHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label = ol.render.canvas.TextReplay.labelCache_.get(key);
|
||||||
|
|
||||||
|
var anchorX = align * label.width / pixelRatio + 2 * (0.5 - align) * strokeWidth;
|
||||||
|
var anchorY = baseline * label.height / pixelRatio + 2 * (0.5 - baseline) * strokeWidth;
|
||||||
|
|
||||||
|
this.instructions.push([
|
||||||
|
ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd, label,
|
||||||
|
(anchorX - this.textOffsetX_) * pixelRatio, (anchorY - this.textOffsetY_) * pixelRatio,
|
||||||
|
label.height, 1, 0, 0, this.textRotateWithView_, this.textRotation_,
|
||||||
|
this.textScale_, true, label.width
|
||||||
|
]);
|
||||||
|
this.hitDetectionInstructions.push([
|
||||||
|
ol.render.canvas.Instruction.DRAW_IMAGE, myBegin, myEnd, label,
|
||||||
|
(anchorX - this.textOffsetX_) * pixelRatio, (anchorY - this.textOffsetY_) * pixelRatio,
|
||||||
|
label.height, 1, 0, 0, this.textRotateWithView_, this.textRotation_,
|
||||||
|
this.textScale_ / pixelRatio, true, label.width
|
||||||
|
]);
|
||||||
|
|
||||||
this.endGeometry(geometry, feature);
|
this.endGeometry(geometry, feature);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.CanvasFillState} fillState Fill state.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.render.canvas.TextReplay.prototype.setReplayFillState_ = function(fillState) {
|
|
||||||
var replayFillState = this.replayFillState_;
|
|
||||||
if (replayFillState &&
|
|
||||||
replayFillState.fillStyle == fillState.fillStyle) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var setFillStyleInstruction =
|
|
||||||
[ol.render.canvas.Instruction.SET_FILL_STYLE, fillState.fillStyle];
|
|
||||||
this.instructions.push(setFillStyleInstruction);
|
|
||||||
this.hitDetectionInstructions.push(setFillStyleInstruction);
|
|
||||||
if (!replayFillState) {
|
|
||||||
this.replayFillState_ = {
|
|
||||||
fillStyle: fillState.fillStyle
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
replayFillState.fillStyle = fillState.fillStyle;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.CanvasStrokeState} strokeState Stroke state.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.render.canvas.TextReplay.prototype.setReplayStrokeState_ = function(strokeState) {
|
|
||||||
var replayStrokeState = this.replayStrokeState_;
|
|
||||||
if (replayStrokeState &&
|
|
||||||
replayStrokeState.lineCap == strokeState.lineCap &&
|
|
||||||
replayStrokeState.lineDash == strokeState.lineDash &&
|
|
||||||
replayStrokeState.lineDashOffset == strokeState.lineDashOffset &&
|
|
||||||
replayStrokeState.lineJoin == strokeState.lineJoin &&
|
|
||||||
replayStrokeState.lineWidth == strokeState.lineWidth &&
|
|
||||||
replayStrokeState.miterLimit == strokeState.miterLimit &&
|
|
||||||
replayStrokeState.strokeStyle == strokeState.strokeStyle) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var setStrokeStyleInstruction = [
|
|
||||||
ol.render.canvas.Instruction.SET_STROKE_STYLE, strokeState.strokeStyle,
|
|
||||||
strokeState.lineWidth, strokeState.lineCap, strokeState.lineJoin,
|
|
||||||
strokeState.miterLimit, strokeState.lineDash, strokeState.lineDashOffset, false, 1
|
|
||||||
];
|
|
||||||
this.instructions.push(setStrokeStyleInstruction);
|
|
||||||
this.hitDetectionInstructions.push(setStrokeStyleInstruction);
|
|
||||||
if (!replayStrokeState) {
|
|
||||||
this.replayStrokeState_ = {
|
|
||||||
lineCap: strokeState.lineCap,
|
|
||||||
lineDash: strokeState.lineDash,
|
|
||||||
lineDashOffset: strokeState.lineDashOffset,
|
|
||||||
lineJoin: strokeState.lineJoin,
|
|
||||||
lineWidth: strokeState.lineWidth,
|
|
||||||
miterLimit: strokeState.miterLimit,
|
|
||||||
strokeStyle: strokeState.strokeStyle
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
replayStrokeState.lineCap = strokeState.lineCap;
|
|
||||||
replayStrokeState.lineDash = strokeState.lineDash;
|
|
||||||
replayStrokeState.lineDashOffset = strokeState.lineDashOffset;
|
|
||||||
replayStrokeState.lineJoin = strokeState.lineJoin;
|
|
||||||
replayStrokeState.lineWidth = strokeState.lineWidth;
|
|
||||||
replayStrokeState.miterLimit = strokeState.miterLimit;
|
|
||||||
replayStrokeState.strokeStyle = strokeState.strokeStyle;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.CanvasTextState} textState Text state.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.render.canvas.TextReplay.prototype.setReplayTextState_ = function(textState) {
|
|
||||||
var replayTextState = this.replayTextState_;
|
|
||||||
if (replayTextState &&
|
|
||||||
replayTextState.font == textState.font &&
|
|
||||||
replayTextState.textAlign == textState.textAlign &&
|
|
||||||
replayTextState.textBaseline == textState.textBaseline) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var setTextStyleInstruction = [ol.render.canvas.Instruction.SET_TEXT_STYLE,
|
|
||||||
textState.font, textState.textAlign, textState.textBaseline];
|
|
||||||
this.instructions.push(setTextStyleInstruction);
|
|
||||||
this.hitDetectionInstructions.push(setTextStyleInstruction);
|
|
||||||
if (!replayTextState) {
|
|
||||||
this.replayTextState_ = {
|
|
||||||
font: textState.font,
|
|
||||||
textAlign: textState.textAlign,
|
|
||||||
textBaseline: textState.textBaseline
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
replayTextState.font = textState.font;
|
|
||||||
replayTextState.textAlign = textState.textAlign;
|
|
||||||
replayTextState.textBaseline = textState.textBaseline;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -15,3 +15,20 @@ ol.render.replay.ORDER = [
|
|||||||
ol.render.ReplayType.TEXT,
|
ol.render.ReplayType.TEXT,
|
||||||
ol.render.ReplayType.DEFAULT
|
ol.render.ReplayType.DEFAULT
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {number}
|
||||||
|
*/
|
||||||
|
ol.render.replay.TEXT_ALIGN = {};
|
||||||
|
ol.render.replay.TEXT_ALIGN['left'] = 0;
|
||||||
|
ol.render.replay.TEXT_ALIGN['end'] = 0;
|
||||||
|
ol.render.replay.TEXT_ALIGN['center'] = 0.5;
|
||||||
|
ol.render.replay.TEXT_ALIGN['right'] = 1;
|
||||||
|
ol.render.replay.TEXT_ALIGN['start'] = 1;
|
||||||
|
ol.render.replay.TEXT_ALIGN['top'] = 0;
|
||||||
|
ol.render.replay.TEXT_ALIGN['middle'] = 0.5;
|
||||||
|
ol.render.replay.TEXT_ALIGN['hanging'] = 0.2;
|
||||||
|
ol.render.replay.TEXT_ALIGN['alphabetic'] = 0.8;
|
||||||
|
ol.render.replay.TEXT_ALIGN['ideographic'] = 0.8;
|
||||||
|
ol.render.replay.TEXT_ALIGN['bottom'] = 1;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ goog.require('ol');
|
|||||||
goog.require('ol.colorlike');
|
goog.require('ol.colorlike');
|
||||||
goog.require('ol.dom');
|
goog.require('ol.dom');
|
||||||
goog.require('ol.has');
|
goog.require('ol.has');
|
||||||
|
goog.require('ol.render.replay');
|
||||||
goog.require('ol.render.webgl');
|
goog.require('ol.render.webgl');
|
||||||
goog.require('ol.render.webgl.TextureReplay');
|
goog.require('ol.render.webgl.TextureReplay');
|
||||||
goog.require('ol.style.AtlasManager');
|
goog.require('ol.style.AtlasManager');
|
||||||
@@ -348,8 +349,8 @@ ol.render.webgl.TextReplay.prototype.setTextStyle = function(textStyle) {
|
|||||||
state.font = textStyle.getFont() || ol.render.webgl.defaultFont;
|
state.font = textStyle.getFont() || ol.render.webgl.defaultFont;
|
||||||
state.scale = textStyle.getScale() || 1;
|
state.scale = textStyle.getScale() || 1;
|
||||||
this.text_ = /** @type {string} */ (textStyle.getText());
|
this.text_ = /** @type {string} */ (textStyle.getText());
|
||||||
var textAlign = ol.render.webgl.TextReplay.Align_[textStyle.getTextAlign()];
|
var textAlign = ol.render.replay.TEXT_ALIGN[textStyle.getTextAlign()];
|
||||||
var textBaseline = ol.render.webgl.TextReplay.Align_[textStyle.getTextBaseline()];
|
var textBaseline = ol.render.replay.TEXT_ALIGN[textStyle.getTextBaseline()];
|
||||||
this.textAlign_ = textAlign === undefined ?
|
this.textAlign_ = textAlign === undefined ?
|
||||||
ol.render.webgl.defaultTextAlign : textAlign;
|
ol.render.webgl.defaultTextAlign : textAlign;
|
||||||
this.textBaseline_ = textBaseline === undefined ?
|
this.textBaseline_ = textBaseline === undefined ?
|
||||||
@@ -430,22 +431,3 @@ ol.render.webgl.TextReplay.prototype.getTextures = function(opt_all) {
|
|||||||
ol.render.webgl.TextReplay.prototype.getHitDetectionTextures = function() {
|
ol.render.webgl.TextReplay.prototype.getHitDetectionTextures = function() {
|
||||||
return this.textures_;
|
return this.textures_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @enum {number}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.render.webgl.TextReplay.Align_ = {
|
|
||||||
left: 0,
|
|
||||||
end: 0,
|
|
||||||
center: 0.5,
|
|
||||||
right: 1,
|
|
||||||
start: 1,
|
|
||||||
top: 0,
|
|
||||||
middle: 0.5,
|
|
||||||
hanging: 0.2,
|
|
||||||
alphabetic: 0.8,
|
|
||||||
ideographic: 0.8,
|
|
||||||
bottom: 1
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -157,8 +157,7 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay
|
|||||||
var height = frameState.size[1] * pixelRatio;
|
var height = frameState.size[1] * pixelRatio;
|
||||||
ol.render.canvas.rotateAtOffset(replayContext, -rotation,
|
ol.render.canvas.rotateAtOffset(replayContext, -rotation,
|
||||||
width / 2, height / 2);
|
width / 2, height / 2);
|
||||||
replayGroup.replay(replayContext, pixelRatio, transform, rotation,
|
replayGroup.replay(replayContext, transform, rotation, skippedFeatureUids);
|
||||||
skippedFeatureUids);
|
|
||||||
if (vectorSource.getWrapX() && projection.canWrapX() &&
|
if (vectorSource.getWrapX() && projection.canWrapX() &&
|
||||||
!ol.extent.containsExtent(projectionExtent, extent)) {
|
!ol.extent.containsExtent(projectionExtent, extent)) {
|
||||||
var startX = extent[0];
|
var startX = extent[0];
|
||||||
@@ -169,8 +168,7 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay
|
|||||||
--world;
|
--world;
|
||||||
offsetX = worldWidth * world;
|
offsetX = worldWidth * world;
|
||||||
transform = this.getTransform(frameState, offsetX);
|
transform = this.getTransform(frameState, offsetX);
|
||||||
replayGroup.replay(replayContext, pixelRatio, transform, rotation,
|
replayGroup.replay(replayContext, transform, rotation, skippedFeatureUids);
|
||||||
skippedFeatureUids);
|
|
||||||
startX += worldWidth;
|
startX += worldWidth;
|
||||||
}
|
}
|
||||||
world = 0;
|
world = 0;
|
||||||
@@ -179,8 +177,7 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay
|
|||||||
++world;
|
++world;
|
||||||
offsetX = worldWidth * world;
|
offsetX = worldWidth * world;
|
||||||
transform = this.getTransform(frameState, offsetX);
|
transform = this.getTransform(frameState, offsetX);
|
||||||
replayGroup.replay(replayContext, pixelRatio, transform, rotation,
|
replayGroup.replay(replayContext, transform, rotation, skippedFeatureUids);
|
||||||
skippedFeatureUids);
|
|
||||||
startX -= worldWidth;
|
startX -= worldWidth;
|
||||||
}
|
}
|
||||||
// restore original transform for render and compose events
|
// restore original transform for render and compose events
|
||||||
@@ -321,8 +318,8 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame = function(frameState, lay
|
|||||||
this.dirty_ = false;
|
this.dirty_ = false;
|
||||||
|
|
||||||
var replayGroup = new ol.render.canvas.ReplayGroup(
|
var replayGroup = new ol.render.canvas.ReplayGroup(
|
||||||
ol.renderer.vector.getTolerance(resolution, pixelRatio), extent,
|
ol.renderer.vector.getTolerance(resolution, pixelRatio), extent, resolution,
|
||||||
resolution, vectorSource.getOverlaps(), vectorLayer.getRenderBuffer());
|
pixelRatio, vectorSource.getOverlaps(), vectorLayer.getRenderBuffer());
|
||||||
vectorSource.loadFeatures(extent, resolution, projection);
|
vectorSource.loadFeatures(extent, resolution, projection);
|
||||||
/**
|
/**
|
||||||
* @param {ol.Feature} feature Feature.
|
* @param {ol.Feature} feature Feature.
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(
|
|||||||
}
|
}
|
||||||
replayState.dirty = false;
|
replayState.dirty = false;
|
||||||
var replayGroup = new ol.render.canvas.ReplayGroup(0, sharedExtent,
|
var replayGroup = new ol.render.canvas.ReplayGroup(0, sharedExtent,
|
||||||
resolution, source.getOverlaps(), layer.getRenderBuffer());
|
resolution, pixelRatio, source.getOverlaps(), layer.getRenderBuffer());
|
||||||
var squaredTolerance = ol.renderer.vector.getSquaredTolerance(
|
var squaredTolerance = ol.renderer.vector.getSquaredTolerance(
|
||||||
resolution, pixelRatio);
|
resolution, pixelRatio);
|
||||||
|
|
||||||
@@ -187,9 +187,6 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (styles) {
|
if (styles) {
|
||||||
if (!Array.isArray(styles)) {
|
|
||||||
styles = [styles];
|
|
||||||
}
|
|
||||||
var dirty = this.renderFeature(feature, squaredTolerance, styles,
|
var dirty = this.renderFeature(feature, squaredTolerance, styles,
|
||||||
replayGroup);
|
replayGroup);
|
||||||
this.dirty_ = this.dirty_ || dirty;
|
this.dirty_ = this.dirty_ || dirty;
|
||||||
@@ -388,7 +385,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.postCompose = function(context, fra
|
|||||||
context.clip();
|
context.clip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
replayGroup.replay(context, pixelRatio, transform, rotation, {}, replays);
|
replayGroup.replay(context, transform, rotation, {}, replays);
|
||||||
context.restore();
|
context.restore();
|
||||||
clips.push(currentClip);
|
clips.push(currentClip);
|
||||||
zs.push(currentZ);
|
zs.push(currentZ);
|
||||||
@@ -461,7 +458,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.renderTileImage_ = function(
|
|||||||
ol.transform.scale(transform, pixelScale, -pixelScale);
|
ol.transform.scale(transform, pixelScale, -pixelScale);
|
||||||
ol.transform.translate(transform, -tileExtent[0], -tileExtent[3]);
|
ol.transform.translate(transform, -tileExtent[0], -tileExtent[3]);
|
||||||
var replayGroup = sourceTile.getReplayGroup(layer, tile.tileCoord.toString());
|
var replayGroup = sourceTile.getReplayGroup(layer, tile.tileCoord.toString());
|
||||||
replayGroup.replay(context, pixelRatio, transform, 0, {}, replays, true);
|
replayGroup.replay(context, transform, 0, {}, replays, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ ol.source.ImageVector.prototype.canvasFunctionInternal_ = function(extent, resol
|
|||||||
|
|
||||||
var replayGroup = new ol.render.canvas.ReplayGroup(
|
var replayGroup = new ol.render.canvas.ReplayGroup(
|
||||||
ol.renderer.vector.getTolerance(resolution, pixelRatio), extent,
|
ol.renderer.vector.getTolerance(resolution, pixelRatio), extent,
|
||||||
resolution, this.source_.getOverlaps(), this.renderBuffer_);
|
resolution, pixelRatio, this.source_.getOverlaps(), this.renderBuffer_);
|
||||||
|
|
||||||
this.source_.loadFeatures(extent, resolution, projection);
|
this.source_.loadFeatures(extent, resolution, projection);
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ ol.source.ImageVector.prototype.canvasFunctionInternal_ = function(extent, resol
|
|||||||
|
|
||||||
var transform = this.getTransform_(ol.extent.getCenter(extent),
|
var transform = this.getTransform_(ol.extent.getCenter(extent),
|
||||||
resolution, pixelRatio, size);
|
resolution, pixelRatio, size);
|
||||||
replayGroup.replay(this.canvasContext_, pixelRatio, transform, 0, {});
|
replayGroup.replay(this.canvasContext_, transform, 0, {});
|
||||||
|
|
||||||
this.replayGroup_ = replayGroup;
|
this.replayGroup_ = replayGroup;
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,14 @@ goog.require('ol.asserts');
|
|||||||
* @constructor
|
* @constructor
|
||||||
* @struct
|
* @struct
|
||||||
* @template T
|
* @template T
|
||||||
|
* @param {number=} opt_highWaterMark High water mark.
|
||||||
*/
|
*/
|
||||||
ol.structs.LRUCache = function() {
|
ol.structs.LRUCache = function(opt_highWaterMark) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
this.highWaterMark = opt_highWaterMark !== undefined ? opt_highWaterMark : 2048;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@@ -40,6 +46,14 @@ ol.structs.LRUCache = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {boolean} Can expire cache.
|
||||||
|
*/
|
||||||
|
ol.structs.LRUCache.prototype.canExpireCache = function() {
|
||||||
|
return this.getCount() > this.highWaterMark;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIXME empty description for jsdoc
|
* FIXME empty description for jsdoc
|
||||||
*/
|
*/
|
||||||
|
|||||||
+1
-14
@@ -12,25 +12,12 @@ goog.require('ol.structs.LRUCache');
|
|||||||
*/
|
*/
|
||||||
ol.TileCache = function(opt_highWaterMark) {
|
ol.TileCache = function(opt_highWaterMark) {
|
||||||
|
|
||||||
ol.structs.LRUCache.call(this);
|
ol.structs.LRUCache.call(this, opt_highWaterMark);
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.highWaterMark = opt_highWaterMark !== undefined ? opt_highWaterMark : 2048;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
ol.inherits(ol.TileCache, ol.structs.LRUCache);
|
ol.inherits(ol.TileCache, ol.structs.LRUCache);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {boolean} Can expire cache.
|
|
||||||
*/
|
|
||||||
ol.TileCache.prototype.canExpireCache = function() {
|
|
||||||
return this.getCount() > this.highWaterMark;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object.<string, ol.TileRange>} usedTiles Used tiles.
|
* @param {Object.<string, ol.TileRange>} usedTiles Used tiles.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 8.1 KiB |
@@ -103,6 +103,94 @@ describe('ol.rendering.style.Text', function() {
|
|||||||
expectResemble(map, 'rendering/ol/style/expected/text-rotated-canvas.png', IMAGE_TOLERANCE, done);
|
expectResemble(map, 'rendering/ol/style/expected/text-rotated-canvas.png', IMAGE_TOLERANCE, done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('renders multiline text with alignment options', function(done) {
|
||||||
|
createMap('canvas');
|
||||||
|
var feature;
|
||||||
|
feature = new ol.Feature(new ol.geom.Point([25, 0]));
|
||||||
|
feature.setStyle(new ol.style.Style({
|
||||||
|
text: new ol.style.Text({
|
||||||
|
text: 'Hello world\nleft',
|
||||||
|
font: 'bold 14px sans-serif',
|
||||||
|
textAlign: 'left'
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
vectorSource.addFeature(feature);
|
||||||
|
feature = new ol.Feature(new ol.geom.Point([-25, 0]));
|
||||||
|
feature.setStyle(new ol.style.Style({
|
||||||
|
text: new ol.style.Text({
|
||||||
|
text: 'Hello world\nright',
|
||||||
|
font: 'bold 14px sans-serif',
|
||||||
|
textAlign: 'right'
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
vectorSource.addFeature(feature);
|
||||||
|
feature = new ol.Feature(new ol.geom.Point([0, 25]));
|
||||||
|
feature.setStyle(new ol.style.Style({
|
||||||
|
text: new ol.style.Text({
|
||||||
|
text: 'Hello world\nbottom',
|
||||||
|
font: 'bold 14px sans-serif',
|
||||||
|
textBaseline: 'bottom'
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
vectorSource.addFeature(feature);
|
||||||
|
feature = new ol.Feature(new ol.geom.Point([0, -25]));
|
||||||
|
feature.setStyle(new ol.style.Style({
|
||||||
|
text: new ol.style.Text({
|
||||||
|
text: 'top\nHello world',
|
||||||
|
font: 'bold 14px sans-serif',
|
||||||
|
textBaseline: 'top'
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
vectorSource.addFeature(feature);
|
||||||
|
expectResemble(map, 'rendering/ol/style/expected/text-align-offset-canvas.png', 5, done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders multiline text with positioning options', function(done) {
|
||||||
|
createMap('canvas');
|
||||||
|
var feature;
|
||||||
|
feature = new ol.Feature(new ol.geom.Point([0, 0]));
|
||||||
|
feature.setStyle(new ol.style.Style({
|
||||||
|
text: new ol.style.Text({
|
||||||
|
text: 'Hello world\nleft',
|
||||||
|
font: 'bold 14px sans-serif',
|
||||||
|
textAlign: 'left',
|
||||||
|
offsetX: 25
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
vectorSource.addFeature(feature);
|
||||||
|
feature = new ol.Feature(new ol.geom.Point([0, 0]));
|
||||||
|
feature.setStyle(new ol.style.Style({
|
||||||
|
text: new ol.style.Text({
|
||||||
|
text: 'Hello world\nright',
|
||||||
|
font: 'bold 14px sans-serif',
|
||||||
|
textAlign: 'right',
|
||||||
|
offsetX: -25
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
vectorSource.addFeature(feature);
|
||||||
|
feature = new ol.Feature(new ol.geom.Point([0, 0]));
|
||||||
|
feature.setStyle(new ol.style.Style({
|
||||||
|
text: new ol.style.Text({
|
||||||
|
text: 'Hello world\nbottom',
|
||||||
|
font: 'bold 14px sans-serif',
|
||||||
|
textBaseline: 'bottom',
|
||||||
|
offsetY: -25
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
vectorSource.addFeature(feature);
|
||||||
|
feature = new ol.Feature(new ol.geom.Point([0, 0]));
|
||||||
|
feature.setStyle(new ol.style.Style({
|
||||||
|
text: new ol.style.Text({
|
||||||
|
text: 'top\nHello world',
|
||||||
|
font: 'bold 14px sans-serif',
|
||||||
|
textBaseline: 'top',
|
||||||
|
offsetY: 25
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
vectorSource.addFeature(feature);
|
||||||
|
expectResemble(map, 'rendering/ol/style/expected/text-align-offset-canvas.png', 5, done);
|
||||||
|
});
|
||||||
|
|
||||||
where('WebGL').it('tests the webgl renderer without rotation', function(done) {
|
where('WebGL').it('tests the webgl renderer without rotation', function(done) {
|
||||||
createMap('webgl');
|
createMap('webgl');
|
||||||
createFeatures();
|
createFeatures();
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ describe('ol.render.canvas.ReplayGroup', function() {
|
|||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
transform = ol.transform.create();
|
transform = ol.transform.create();
|
||||||
replay = new ol.render.canvas.ReplayGroup(1, [-180, -90, 180, 90], 1, false);
|
replay = new ol.render.canvas.ReplayGroup(1, [-180, -90, 180, 90], 1, 1, false);
|
||||||
feature0 = new ol.Feature(new ol.geom.Polygon(
|
feature0 = new ol.Feature(new ol.geom.Polygon(
|
||||||
[[[-90, 0], [-45, 45], [0, 0], [1, 1], [0, -45], [-90, 0]]]));
|
[[[-90, 0], [-45, 45], [0, 0], [1, 1], [0, -45], [-90, 0]]]));
|
||||||
feature1 = new ol.Feature(new ol.geom.Polygon(
|
feature1 = new ol.Feature(new ol.geom.Polygon(
|
||||||
@@ -91,18 +91,18 @@ describe('ol.render.canvas.ReplayGroup', function() {
|
|||||||
|
|
||||||
it('omits lineTo for repeated coordinates', function() {
|
it('omits lineTo for repeated coordinates', function() {
|
||||||
ol.renderer.vector.renderFeature(replay, feature0, fill0, 1);
|
ol.renderer.vector.renderFeature(replay, feature0, fill0, 1);
|
||||||
replay.replay(context, 1, transform, 0, {});
|
replay.replay(context, transform, 0, {});
|
||||||
expect(lineToCount).to.be(4);
|
expect(lineToCount).to.be(4);
|
||||||
lineToCount = 0;
|
lineToCount = 0;
|
||||||
ol.transform.scale(transform, 0.25, 0.25);
|
ol.transform.scale(transform, 0.25, 0.25);
|
||||||
replay.replay(context, 1, transform, 0, {});
|
replay.replay(context, transform, 0, {});
|
||||||
expect(lineToCount).to.be(3);
|
expect(lineToCount).to.be(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not omit moveTo for repeated coordinates', function() {
|
it('does not omit moveTo for repeated coordinates', function() {
|
||||||
ol.renderer.vector.renderFeature(replay, feature0, fill0, 1);
|
ol.renderer.vector.renderFeature(replay, feature0, fill0, 1);
|
||||||
ol.renderer.vector.renderFeature(replay, feature1, fill1, 1);
|
ol.renderer.vector.renderFeature(replay, feature1, fill1, 1);
|
||||||
replay.replay(context, 1, transform, 0, {});
|
replay.replay(context, transform, 0, {});
|
||||||
expect(moveToCount).to.be(2);
|
expect(moveToCount).to.be(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ describe('ol.render.canvas.ReplayGroup', function() {
|
|||||||
ol.renderer.vector.renderFeature(replay, feature1, style1, 1);
|
ol.renderer.vector.renderFeature(replay, feature1, style1, 1);
|
||||||
ol.renderer.vector.renderFeature(replay, feature2, style1, 1);
|
ol.renderer.vector.renderFeature(replay, feature2, style1, 1);
|
||||||
ol.renderer.vector.renderFeature(replay, feature3, style1, 1);
|
ol.renderer.vector.renderFeature(replay, feature3, style1, 1);
|
||||||
replay.replay(context, 1, transform, 0, {});
|
replay.replay(context, transform, 0, {});
|
||||||
expect(fillCount).to.be(1);
|
expect(fillCount).to.be(1);
|
||||||
expect(strokeCount).to.be(1);
|
expect(strokeCount).to.be(1);
|
||||||
expect(beginPathCount).to.be(1);
|
expect(beginPathCount).to.be(1);
|
||||||
@@ -120,7 +120,7 @@ describe('ol.render.canvas.ReplayGroup', function() {
|
|||||||
ol.renderer.vector.renderFeature(replay, feature1, style1, 1);
|
ol.renderer.vector.renderFeature(replay, feature1, style1, 1);
|
||||||
ol.renderer.vector.renderFeature(replay, feature2, style1, 1);
|
ol.renderer.vector.renderFeature(replay, feature2, style1, 1);
|
||||||
ol.renderer.vector.renderFeature(replay, feature3, style2, 1);
|
ol.renderer.vector.renderFeature(replay, feature3, style2, 1);
|
||||||
replay.replay(context, 1, transform, 0, {});
|
replay.replay(context, transform, 0, {});
|
||||||
expect(fillCount).to.be(2);
|
expect(fillCount).to.be(2);
|
||||||
expect(strokeCount).to.be(2);
|
expect(strokeCount).to.be(2);
|
||||||
expect(beginPathCount).to.be(2);
|
expect(beginPathCount).to.be(2);
|
||||||
@@ -130,7 +130,7 @@ describe('ol.render.canvas.ReplayGroup', function() {
|
|||||||
ol.renderer.vector.renderFeature(replay, feature1, style1, 1);
|
ol.renderer.vector.renderFeature(replay, feature1, style1, 1);
|
||||||
ol.renderer.vector.renderFeature(replay, feature2, style2, 1);
|
ol.renderer.vector.renderFeature(replay, feature2, style2, 1);
|
||||||
ol.renderer.vector.renderFeature(replay, feature3, style1, 1);
|
ol.renderer.vector.renderFeature(replay, feature3, style1, 1);
|
||||||
replay.replay(context, 1, transform, 0, {});
|
replay.replay(context, transform, 0, {});
|
||||||
expect(fillCount).to.be(3);
|
expect(fillCount).to.be(3);
|
||||||
expect(strokeCount).to.be(3);
|
expect(strokeCount).to.be(3);
|
||||||
expect(beginPathCount).to.be(3);
|
expect(beginPathCount).to.be(3);
|
||||||
@@ -142,7 +142,7 @@ describe('ol.render.canvas.ReplayGroup', function() {
|
|||||||
ol.renderer.vector.renderFeature(replay, feature3, style2, 1);
|
ol.renderer.vector.renderFeature(replay, feature3, style2, 1);
|
||||||
var skippedUids = {};
|
var skippedUids = {};
|
||||||
skippedUids[ol.getUid(feature1)] = true;
|
skippedUids[ol.getUid(feature1)] = true;
|
||||||
replay.replay(context, 1, transform, 0, skippedUids);
|
replay.replay(context, transform, 0, skippedUids);
|
||||||
expect(fillCount).to.be(1);
|
expect(fillCount).to.be(1);
|
||||||
expect(strokeCount).to.be(1);
|
expect(strokeCount).to.be(1);
|
||||||
expect(beginPathCount).to.be(1);
|
expect(beginPathCount).to.be(1);
|
||||||
@@ -154,7 +154,7 @@ describe('ol.render.canvas.ReplayGroup', function() {
|
|||||||
ol.renderer.vector.renderFeature(replay, feature3, style2, 1);
|
ol.renderer.vector.renderFeature(replay, feature3, style2, 1);
|
||||||
var skippedUids = {};
|
var skippedUids = {};
|
||||||
skippedUids[ol.getUid(feature3)] = true;
|
skippedUids[ol.getUid(feature3)] = true;
|
||||||
replay.replay(context, 1, transform, 0, skippedUids);
|
replay.replay(context, transform, 0, skippedUids);
|
||||||
expect(fillCount).to.be(1);
|
expect(fillCount).to.be(1);
|
||||||
expect(strokeCount).to.be(1);
|
expect(strokeCount).to.be(1);
|
||||||
expect(beginPathCount).to.be(1);
|
expect(beginPathCount).to.be(1);
|
||||||
@@ -167,24 +167,27 @@ describe('ol.render.canvas.ReplayGroup', function() {
|
|||||||
var skippedUids = {};
|
var skippedUids = {};
|
||||||
skippedUids[ol.getUid(feature1)] = true;
|
skippedUids[ol.getUid(feature1)] = true;
|
||||||
skippedUids[ol.getUid(feature2)] = true;
|
skippedUids[ol.getUid(feature2)] = true;
|
||||||
replay.replay(context, 1, transform, 0, skippedUids);
|
replay.replay(context, transform, 0, skippedUids);
|
||||||
expect(fillCount).to.be(1);
|
expect(fillCount).to.be(1);
|
||||||
expect(strokeCount).to.be(1);
|
expect(strokeCount).to.be(1);
|
||||||
expect(beginPathCount).to.be(1);
|
expect(beginPathCount).to.be(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not batch when overlaps is set to true', function() {
|
it('does not batch when overlaps is set to true', function() {
|
||||||
replay = new ol.render.canvas.ReplayGroup(1, [-180, -90, 180, 90], 1, true);
|
replay = new ol.render.canvas.ReplayGroup(1, [-180, -90, 180, 90], 1, 1, true);
|
||||||
ol.renderer.vector.renderFeature(replay, feature1, style1, 1);
|
ol.renderer.vector.renderFeature(replay, feature1, style1, 1);
|
||||||
ol.renderer.vector.renderFeature(replay, feature2, style1, 1);
|
ol.renderer.vector.renderFeature(replay, feature2, style1, 1);
|
||||||
ol.renderer.vector.renderFeature(replay, feature3, style1, 1);
|
ol.renderer.vector.renderFeature(replay, feature3, style1, 1);
|
||||||
replay.replay(context, 1, transform, 0, {});
|
replay.replay(context, transform, 0, {});
|
||||||
expect(fillCount).to.be(3);
|
expect(fillCount).to.be(3);
|
||||||
expect(strokeCount).to.be(3);
|
expect(strokeCount).to.be(3);
|
||||||
expect(beginPathCount).to.be(3);
|
expect(beginPathCount).to.be(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('applies the pixelRatio to the linedash array and offset', function() {
|
it('applies the pixelRatio to the linedash array and offset', function() {
|
||||||
|
// replay with a pixelRatio of 2
|
||||||
|
replay = new ol.render.canvas.ReplayGroup(1, [-180, -90, 180, 90], 1, 2, true);
|
||||||
|
|
||||||
var lineDash, lineDashCount = 0,
|
var lineDash, lineDashCount = 0,
|
||||||
lineDashOffset, lineDashOffsetCount = 0;
|
lineDashOffset, lineDashOffsetCount = 0;
|
||||||
|
|
||||||
@@ -202,7 +205,7 @@ describe('ol.render.canvas.ReplayGroup', function() {
|
|||||||
|
|
||||||
ol.renderer.vector.renderFeature(replay, feature1, style2, 1);
|
ol.renderer.vector.renderFeature(replay, feature1, style2, 1);
|
||||||
ol.renderer.vector.renderFeature(replay, feature2, style2, 1);
|
ol.renderer.vector.renderFeature(replay, feature2, style2, 1);
|
||||||
replay.replay(context, 2, transform, 0, {});
|
replay.replay(context, transform, 0, {});
|
||||||
|
|
||||||
expect(lineDashCount).to.be(1);
|
expect(lineDashCount).to.be(1);
|
||||||
expect(style2.getStroke().getLineDash()).to.eql([3, 6]);
|
expect(style2.getStroke().getLineDash()).to.eql([3, 6]);
|
||||||
@@ -240,7 +243,7 @@ describe('ol.render.canvas.ReplayGroup', function() {
|
|||||||
[polygon.getGeometry().getCoordinates(), polygon.getGeometry().getCoordinates()]));
|
[polygon.getGeometry().getCoordinates(), polygon.getGeometry().getCoordinates()]));
|
||||||
var geometrycollection = new ol.Feature(new ol.geom.GeometryCollection(
|
var geometrycollection = new ol.Feature(new ol.geom.GeometryCollection(
|
||||||
[point.getGeometry(), linestring.getGeometry(), polygon.getGeometry()]));
|
[point.getGeometry(), linestring.getGeometry(), polygon.getGeometry()]));
|
||||||
replay = new ol.render.canvas.ReplayGroup(1, [-180, -90, 180, 90], 1, true);
|
replay = new ol.render.canvas.ReplayGroup(1, [-180, -90, 180, 90], 1, 1, true);
|
||||||
ol.renderer.vector.renderFeature(replay, point, style, 1);
|
ol.renderer.vector.renderFeature(replay, point, style, 1);
|
||||||
ol.renderer.vector.renderFeature(replay, multipoint, style, 1);
|
ol.renderer.vector.renderFeature(replay, multipoint, style, 1);
|
||||||
ol.renderer.vector.renderFeature(replay, linestring, style, 1);
|
ol.renderer.vector.renderFeature(replay, linestring, style, 1);
|
||||||
@@ -249,7 +252,7 @@ describe('ol.render.canvas.ReplayGroup', function() {
|
|||||||
ol.renderer.vector.renderFeature(replay, multipolygon, style, 1);
|
ol.renderer.vector.renderFeature(replay, multipolygon, style, 1);
|
||||||
ol.renderer.vector.renderFeature(replay, geometrycollection, style, 1);
|
ol.renderer.vector.renderFeature(replay, geometrycollection, style, 1);
|
||||||
ol.transform.scale(transform, 0.1, 0.1);
|
ol.transform.scale(transform, 0.1, 0.1);
|
||||||
replay.replay(context, 1, transform, 0, {});
|
replay.replay(context, transform, 0, {});
|
||||||
expect(calls.length).to.be(9);
|
expect(calls.length).to.be(9);
|
||||||
expect(calls[0].geometry).to.be(point.getGeometry());
|
expect(calls[0].geometry).to.be(point.getGeometry());
|
||||||
expect(calls[0].feature).to.be(point);
|
expect(calls[0].feature).to.be(point);
|
||||||
@@ -284,7 +287,7 @@ describe('ol.render.canvas.Replay', function() {
|
|||||||
it('creates a new replay batch', function() {
|
it('creates a new replay batch', function() {
|
||||||
var tolerance = 10;
|
var tolerance = 10;
|
||||||
var extent = [-180, -90, 180, 90];
|
var extent = [-180, -90, 180, 90];
|
||||||
var replay = new ol.render.canvas.Replay(tolerance, extent, 1, true);
|
var replay = new ol.render.canvas.Replay(tolerance, extent, 1, 1, true);
|
||||||
expect(replay).to.be.a(ol.render.canvas.Replay);
|
expect(replay).to.be.a(ol.render.canvas.Replay);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -294,7 +297,7 @@ describe('ol.render.canvas.Replay', function() {
|
|||||||
|
|
||||||
var replay;
|
var replay;
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
replay = new ol.render.canvas.Replay(1, [-180, -90, 180, 90], 1, true);
|
replay = new ol.render.canvas.Replay(1, [-180, -90, 180, 90], 1, 1, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('appends coordinates that are within the max extent', function() {
|
it('appends coordinates that are within the max extent', function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user