[OpenLayers-Commits] r11838 - in trunk/openlayers: examples
lib/OpenLayers/Renderer
commits-20090109 at openlayers.org
commits-20090109 at openlayers.org
Thu Mar 31 07:58:33 EDT 2011
Author: ahocevar
Date: 2011-03-31 04:58:28 -0700 (Thu, 31 Mar 2011)
New Revision: 11838
Modified:
trunk/openlayers/examples/vector-features-with-text.html
trunk/openlayers/lib/OpenLayers/Renderer/Canvas.js
trunk/openlayers/lib/OpenLayers/Renderer/SVG.js
trunk/openlayers/lib/OpenLayers/Renderer/SVG2.js
Log:
adding support for line breaks to SVG, SVG2 and Canvas renderers. Also adds vertical alignment support to Canvas. p=vog,fredj,me r=me (closes #2193)
Modified: trunk/openlayers/examples/vector-features-with-text.html
===================================================================
--- trunk/openlayers/examples/vector-features-with-text.html 2011-03-31 11:53:46 UTC (rev 11837)
+++ trunk/openlayers/examples/vector-features-with-text.html 2011-03-31 11:58:28 UTC (rev 11838)
@@ -29,7 +29,8 @@
fillOpacity: 0.5,
pointRadius: 6,
pointerEvents: "visiblePainted",
- label : "name: ${name}, age: ${age}",
+ // label with \n linebreaks
+ label : "name: ${name}\n\nage: ${age}",
fontColor: "${favColor}",
fontSize: "12px",
@@ -113,7 +114,7 @@
map.addLayer(vectorLayer);
vectorLayer.drawFeature(multiFeature);
- map.setCenter(new OpenLayers.LonLat(point.x, point.y), 3);
+ map.setCenter(new OpenLayers.LonLat(-109.370078125, 43.39484375), 4);
vectorLayer.addFeatures([pointFeature, polygonFeature, multiFeature, labelOffsetFeature, nullFeature ]);
}
</script>
Modified: trunk/openlayers/lib/OpenLayers/Renderer/Canvas.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Renderer/Canvas.js 2011-03-31 11:53:46 UTC (rev 11837)
+++ trunk/openlayers/lib/OpenLayers/Renderer/Canvas.js 2011-03-31 11:58:28 UTC (rev 11838)
@@ -9,7 +9,7 @@
/**
* Class: OpenLayers.Renderer.Canvas
- * A renderer based on the 2D 'canvas' drawing element.element
+ * A renderer based on the 2D 'canvas' drawing element.
*
* Inherits:
* - <OpenLayers.Renderer>
@@ -329,42 +329,61 @@
labelAlign: "cm"
}, style);
var pt = this.getLocalXY(location);
-
+
this.setCanvasStyle("reset");
this.canvas.fillStyle = style.fontColor;
this.canvas.globalAlpha = style.fontOpacity || 1.0;
var fontStyle = [style.fontStyle ? style.fontStyle : "normal",
"normal", // "font-variant" not supported
style.fontWeight ? style.fontWeight : "normal",
- style.fontSize ? style.fontSize : "10px",
+ style.fontSize ? style.fontSize : "1em",
style.fontFamily ? style.fontFamily : "sans-serif"].join(" ");
+ var labelRows = style.label.split('\n');
+ var numRows = labelRows.length;
if (this.canvas.fillText) {
// HTML5
- var labelAlign =
+ this.canvas.font = fontStyle;
+ this.canvas.textAlign =
OpenLayers.Renderer.Canvas.LABEL_ALIGN[style.labelAlign[0]] ||
"center";
- this.canvas.font = fontStyle;
- this.canvas.textAlign = labelAlign;
- this.canvas.fillText(style.label, pt[0], pt[1]);
+ this.canvas.textBaseline =
+ OpenLayers.Renderer.Canvas.LABEL_ALIGN[style.labelAlign[1]] ||
+ "middle";
+ var vfactor =
+ OpenLayers.Renderer.Canvas.LABEL_FACTOR[style.labelAlign[1]];
+ if (vfactor == null) {
+ vfactor = -.5;
+ }
+ var lineHeight =
+ this.canvas.measureText('Mg').height ||
+ this.canvas.measureText('xx').width;
+ pt[1] += lineHeight*vfactor*(numRows-1);
+ for (var i = 0; i < numRows; i++) {
+ this.canvas.fillText(labelRows[i], pt[0], pt[1] + (lineHeight*i));
+ }
} else if (this.canvas.mozDrawText) {
// Mozilla pre-Gecko1.9.1 (<FF3.1)
this.canvas.mozTextStyle = fontStyle;
// No built-in text alignment, so we measure and adjust the position
- var len = this.canvas.mozMeasureText(style.label);
- switch(style.labelAlign[0]) {
- case "l":
- break;
- case "r":
- pt[0] -= len;
- break;
- case "c":
- default:
- pt[0] -= len / 2;
+ var hfactor =
+ OpenLayers.Renderer.Canvas.LABEL_FACTOR[style.labelAlign[0]];
+ if (hfactor == null) {
+ hfactor = -.5;
}
- this.canvas.translate(pt[0], pt[1]);
-
- this.canvas.mozDrawText(style.label);
- this.canvas.translate(-1*pt[0], -1*pt[1]);
+ var vfactor =
+ OpenLayers.Renderer.Canvas.LABEL_FACTOR[style.labelAlign[1]];
+ if (vfactor == null) {
+ vfactor = -.5;
+ }
+ var lineHeight = this.canvas.mozMeasureText('xx');
+ pt[1] += lineHeight*(1 + (vfactor*numRows));
+ for (var i = 0; i < numRows; i++) {
+ var x = pt[0] + (hfactor*this.canvas.mozMeasureText(labelRows[i]));
+ var y = pt[1] + (i*lineHeight);
+ this.canvas.translate(x, y);
+ this.canvas.mozDrawText(labelRows[i]);
+ this.canvas.translate(-x, -y);
+ }
}
this.setCanvasStyle("reset");
},
@@ -478,5 +497,18 @@
*/
OpenLayers.Renderer.Canvas.LABEL_ALIGN = {
"l": "left",
- "r": "right"
+ "r": "right",
+ "t": "top",
+ "b": "bottom"
};
+
+/**
+ * Constant: OpenLayers.Renderer.Canvas.LABEL_FACTOR
+ * {Object}
+ */
+OpenLayers.Renderer.Canvas.LABEL_FACTOR = {
+ "l": 0,
+ "r": -1,
+ "t": 0,
+ "b": -1
+};
Modified: trunk/openlayers/lib/OpenLayers/Renderer/SVG.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Renderer/SVG.js 2011-03-31 11:53:46 UTC (rev 11837)
+++ trunk/openlayers/lib/OpenLayers/Renderer/SVG.js 2011-03-31 11:58:28 UTC (rev 11838)
@@ -679,24 +679,23 @@
/**
* Method: drawText
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* featureId - {String}
* style -
* location - {<OpenLayers.Geometry.Point>}
*/
drawText: function(featureId, style, location) {
var resolution = this.getResolution();
-
+
var x = (location.x / resolution + this.left);
var y = (location.y / resolution - this.top);
-
+
var label = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX, "text");
- var tspan = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX + "_tspan", "tspan");
label.setAttributeNS(null, "x", x);
label.setAttributeNS(null, "y", -y);
-
+
if (style.fontColor) {
label.setAttributeNS(null, "fill", style.fontColor);
}
@@ -715,12 +714,9 @@
if (style.fontStyle) {
label.setAttributeNS(null, "font-style", style.fontStyle);
}
- if(style.labelSelect === true) {
+ if (style.labelSelect === true) {
label.setAttributeNS(null, "pointer-events", "visible");
label._featureId = featureId;
- tspan._featureId = featureId;
- tspan._geometry = location;
- tspan._geometryClass = location.CLASS_NAME;
} else {
label.setAttributeNS(null, "pointer-events", "none");
}
@@ -731,17 +727,43 @@
if (OpenLayers.IS_GECKO === true) {
label.setAttributeNS(null, "dominant-baseline",
OpenLayers.Renderer.SVG.LABEL_ALIGN[align[1]] || "central");
- } else {
- tspan.setAttributeNS(null, "baseline-shift",
- OpenLayers.Renderer.SVG.LABEL_VSHIFT[align[1]] || "-35%");
}
- tspan.textContent = style.label;
-
- if(!label.parentNode) {
- label.appendChild(tspan);
+ var labelRows = style.label.split('\n');
+ var numRows = labelRows.length;
+ while (label.childNodes.length > numRows) {
+ label.removeChild(label.lastChild);
+ }
+ for (var i = 0; i < numRows; i++) {
+ var tspan = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX + "_tspan_" + i, "tspan");
+ if (style.labelSelect === true) {
+ tspan._featureId = featureId;
+ tspan._geometry = location;
+ tspan._geometryClass = location.CLASS_NAME;
+ }
+ if (OpenLayers.IS_GECKO === false) {
+ tspan.setAttributeNS(null, "baseline-shift",
+ OpenLayers.Renderer.SVG.LABEL_VSHIFT[align[1]] || "-35%");
+ }
+ tspan.setAttribute("x", x);
+ if (i == 0) {
+ var vfactor = OpenLayers.Renderer.SVG.LABEL_VFACTOR[align[1]];
+ if (vfactor == null) {
+ vfactor = -.5;
+ }
+ tspan.setAttribute("dy", (vfactor*(numRows-1)) + "em");
+ } else {
+ tspan.setAttribute("dy", "1em");
+ }
+ tspan.textContent = (labelRows[i] === '') ? ' ' : labelRows[i];
+ if (!tspan.parentNode) {
+ label.appendChild(tspan);
+ }
+ }
+
+ if (!label.parentNode) {
this.textRoot.appendChild(label);
- }
+ }
},
/**
@@ -989,6 +1011,15 @@
};
/**
+ * Constant: OpenLayers.Renderer.SVG.LABEL_VFACTOR
+ * {Object}
+ */
+OpenLayers.Renderer.SVG.LABEL_VFACTOR = {
+ "t": 0,
+ "b": -1
+};
+
+/**
* Function: OpenLayers.Renderer.SVG.preventDefault
* Used to prevent default events (especially opening images in a new tab on
* ctrl-click) from being executed for externalGraphic symbols
Modified: trunk/openlayers/lib/OpenLayers/Renderer/SVG2.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Renderer/SVG2.js 2011-03-31 11:53:46 UTC (rev 11837)
+++ trunk/openlayers/lib/OpenLayers/Renderer/SVG2.js 2011-03-31 11:58:28 UTC (rev 11838)
@@ -570,8 +570,8 @@
* Method: drawText
* Function for drawing text labels.
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* featureId - {String|DOMElement}
* style - {Object}
* location - {<OpenLayers.Geometry.Point>}, will be modified inline
@@ -583,14 +583,12 @@
var g = OpenLayers.Renderer.NG.prototype.drawText.apply(this, arguments);
var text = g.firstChild ||
this.nodeFactory(featureId + this.LABEL_ID_SUFFIX + "_text", "text");
- var tspan = text.firstChild ||
- this.nodeFactory(featureId + this.LABEL_ID_SUFFIX + "_tspan", "tspan");
var res = this.getResolution();
text.setAttributeNS(null, "x", location.x / res);
text.setAttributeNS(null, "y", - location.y / res);
g.setAttributeNS(null, "transform", "scale(" + res + ")");
-
+
if (style.fontColor) {
text.setAttributeNS(null, "fill", style.fontColor);
}
@@ -609,10 +607,9 @@
if (style.fontStyle) {
text.setAttributeNS(null, "font-style", style.fontStyle);
}
- if(style.labelSelect === true) {
+ if (style.labelSelect === true) {
text.setAttributeNS(null, "pointer-events", "visible");
text._featureId = featureId;
- tspan._featureId = featureId;
} else {
text.setAttributeNS(null, "pointer-events", "none");
}
@@ -623,18 +620,43 @@
if (OpenLayers.IS_GECKO === true) {
text.setAttributeNS(null, "dominant-baseline",
OpenLayers.Renderer.SVG2.LABEL_ALIGN[align[1]] || "central");
- } else {
- tspan.setAttributeNS(null, "baseline-shift",
- OpenLayers.Renderer.SVG2.LABEL_VSHIFT[align[1]] || "-35%");
}
- tspan.textContent = style.label;
-
- if(!text.parentNode) {
- text.appendChild(tspan);
+ var labelRows = style.label.split('\n');
+ var numRows = labelRows.length;
+ while (text.childNodes.length > numRows) {
+ text.removeChild(text.lastChild);
+ }
+ for (var i = 0; i < numRows; i++) {
+ var tspan = text.childNodes[i] ||
+ this.nodeFactory(featureId + this.LABEL_ID_SUFFIX + "_tspan_" + i, "tspan");
+ if (style.labelSelect === true) {
+ tspan._featureId = featureId;
+ }
+ if (OpenLayers.IS_GECKO === false) {
+ tspan.setAttributeNS(null, "baseline-shift",
+ OpenLayers.Renderer.SVG2.LABEL_VSHIFT[align[1]] || "-35%");
+ }
+ tspan.setAttribute("x", location.x / res);
+ if (i == 0) {
+ var vfactor = OpenLayers.Renderer.SVG2.LABEL_VFACTOR[align[1]];
+ if (vfactor == null) {
+ vfactor = -.5;
+ }
+ tspan.setAttribute("dy", (vfactor*(numRows-1)) + "em");
+ } else {
+ tspan.setAttribute("dy", "1em");
+ }
+ tspan.textContent = (labelRows[i] === '') ? ' ' : labelRows[i];
+ if (!tspan.parentNode) {
+ text.appendChild(tspan);
+ }
+ }
+
+ if (!text.parentNode) {
g.appendChild(text);
}
-
+
return g;
},
@@ -786,6 +808,15 @@
"b": "0"
};
+/**
+ * Constant: OpenLayers.Renderer.SVG2.LABEL_VFACTOR
+ * {Object}
+ */
+OpenLayers.Renderer.SVG2.LABEL_VFACTOR = {
+ "t": 0,
+ "b": -1
+};
+
/**
* Function: OpenLayers.Renderer.SVG2.preventDefault
* Used to prevent default events (especially opening images in a new tab on
More information about the Commits
mailing list