Skip to content

Commit

Permalink
Merge pull request openlayers#1070 from tschaub/text-stroke
Browse files Browse the repository at this point in the history
Add stroke support to text symbolizers.
  • Loading branch information
tschaub committed Oct 8, 2013
2 parents 2f10e62 + 539ecbd commit 2f3cd43
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 3 deletions.
10 changes: 7 additions & 3 deletions examples/vector-layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var vector = new ol.layer.Vector({
new ol.style.Rule({
symbolizers: [
new ol.style.Fill({
color: '#ffffff',
color: 'white',
opacity: 0.6
}),
new ol.style.Stroke({
Expand All @@ -40,10 +40,14 @@ var vector = new ol.layer.Vector({
maxResolution: 5000,
symbolizers: [
new ol.style.Text({
color: '#000000',
color: 'black',
text: ol.expr.parse('name'),
fontFamily: 'Calibri,sans-serif',
fontSize: 12
fontSize: 12,
stroke: new ol.style.Stroke({
color: 'white',
width: 3
})
})
]
})
Expand Down
1 change: 1 addition & 0 deletions src/objectliterals.jsdoc
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,7 @@
* @property {number|ol.expr.Expression|undefined} fontSize Font size in pixels.
* @property {string|ol.expr.Expression} text Text for the label.
* @property {number|ol.expr.Expression|undefined} opacity Opacity (0-1).
* @property {ol.style.Stroke|undefined} stroke Stroke symbolizer for text.
* @property {number|ol.expr.Expression|undefined} zIndex Stack order.
*/

Expand Down
19 changes: 19 additions & 0 deletions src/ol/renderer/canvas/canvasvectorrenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,15 @@ ol.renderer.canvas.Vector.prototype.renderText_ =
context.textAlign = 'center';
context.textBaseline = 'middle';

var stroke = false;
if (goog.isDef(text.strokeColor)) {
stroke = true;
goog.asserts.assertString(text.strokeColor);
context.strokeStyle = text.strokeColor;
goog.asserts.assertNumber(text.strokeWidth);
context.lineWidth = text.strokeWidth;
}

for (var i = 0, ii = features.length; i < ii; ++i) {
feature = features[i];
if (feature.renderIntent === ol.layer.VectorLayerRenderIntent.HIDDEN) {
Expand All @@ -303,6 +312,16 @@ ol.renderer.canvas.Vector.prototype.renderText_ =
for (var j = 0, jj = vecs.length; j < jj; ++j) {
vec = vecs[j];
goog.vec.Mat4.multVec3(this.transform_, vec, vec);
if (stroke) {
if (text.strokeOpacity !== text.opacity) {
goog.asserts.assertNumber(text.strokeOpacity);
context.globalAlpha = text.strokeOpacity;
}
context.strokeText(texts[i], vec[0], vec[1]);
if (text.strokeOpacity !== text.opacity) {
context.globalAlpha = text.opacity;
}
}
context.fillText(texts[i], vec[0], vec[1]);
}
}
Expand Down
37 changes: 37 additions & 0 deletions src/ol/style/textliteral.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ goog.require('ol.style.Literal');
* fontSize: number,
* text: string,
* opacity: number,
* strokeColor: (string|undefined),
* strokeOpacity: (number|undefined),
* strokeWidth: (number|undefined),
* zIndex: number}}
*/
ol.style.TextLiteralOptions;
Expand Down Expand Up @@ -43,6 +46,37 @@ ol.style.TextLiteral = function(options) {
/** @type {number} */
this.opacity = options.opacity;

/** @type {string|undefined} */
this.strokeColor = options.strokeColor;
if (goog.isDef(this.strokeColor)) {
goog.asserts.assertString(
this.strokeColor, 'strokeColor must be a string');
}

/** @type {number|undefined} */
this.strokeOpacity = options.strokeOpacity;
if (goog.isDef(this.strokeOpacity)) {
goog.asserts.assertNumber(
this.strokeOpacity, 'strokeOpacity must be a number');
}

/** @type {number|undefined} */
this.strokeWidth = options.strokeWidth;
if (goog.isDef(this.strokeWidth)) {
goog.asserts.assertNumber(
this.strokeWidth, 'strokeWidth must be a number');
}

// if any stroke property is defined, all must be defined
var strokeDef = goog.isDef(this.strokeColor) &&
goog.isDef(this.strokeOpacity) &&
goog.isDef(this.strokeWidth);
var strokeUndef = !goog.isDef(this.strokeColor) &&
!goog.isDef(this.strokeOpacity) &&
!goog.isDef(this.strokeWidth);
goog.asserts.assert(strokeDef || strokeUndef,
'If any stroke property is defined, all must be defined');

goog.asserts.assertNumber(options.zIndex, 'zIndex must be a number');
/** @type {number} */
this.zIndex = options.zIndex;
Expand All @@ -59,5 +93,8 @@ ol.style.TextLiteral.prototype.equals = function(other) {
this.fontFamily == other.fontFamily &&
this.fontSize == other.fontSize &&
this.opacity == other.opacity &&
this.strokeColor == other.strokeColor &&
this.strokeOpacity == other.strokeOpacity &&
this.strokeWidth == other.strokeWidth &&
this.zIndex == other.zIndex;
};
23 changes: 23 additions & 0 deletions src/ol/style/textsymbolizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ ol.style.Text = function(options) {
(options.opacity instanceof ol.expr.Expression) ?
options.opacity : new ol.expr.Literal(options.opacity);

/**
* @type {ol.style.Stroke}
* @private
*/
this.stroke_ = goog.isDefAndNotNull(options.stroke) ? options.stroke : null;

/**
* @type {ol.expr.Expression}
* @private
Expand Down Expand Up @@ -102,6 +108,20 @@ ol.style.Text.prototype.createLiteral = function(featureOrType) {
var opacity = Number(ol.expr.evaluateFeature(this.opacity_, feature));
goog.asserts.assert(!isNaN(opacity), 'opacity must be a number');

var strokeColor, strokeOpacity, strokeWidth;
if (!goog.isNull(this.stroke_)) {
strokeColor = ol.expr.evaluateFeature(this.stroke_.getColor(), feature);
goog.asserts.assertString(
strokeColor, 'strokeColor must be a string');
strokeOpacity = Number(ol.expr.evaluateFeature(
this.stroke_.getOpacity(), feature));
goog.asserts.assert(!isNaN(strokeOpacity),
'strokeOpacity must be a number');
strokeWidth = Number(ol.expr.evaluateFeature(
this.stroke_.getWidth(), feature));
goog.asserts.assert(!isNaN(strokeWidth), 'strokeWidth must be a number');
}

var zIndex = Number(ol.expr.evaluateFeature(this.zIndex_, feature));
goog.asserts.assert(!isNaN(zIndex), 'zIndex must be a number');

Expand All @@ -111,6 +131,9 @@ ol.style.Text.prototype.createLiteral = function(featureOrType) {
fontSize: fontSize,
text: text,
opacity: opacity,
strokeColor: strokeColor,
strokeOpacity: strokeOpacity,
strokeWidth: strokeWidth,
zIndex: zIndex
});
};
Expand Down
50 changes: 50 additions & 0 deletions test/spec/ol/style/textliteral.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,54 @@ goog.provide('ol.test.style.TextLiteral');

describe('ol.style.TextLiteral', function() {

describe('constructor', function() {

it('creates a new literal', function() {
var literal = new ol.style.TextLiteral({
color: '#ff0000',
fontFamily: 'Arial',
fontSize: 11,
text: 'Test',
opacity: 0.5,
zIndex: 0
});
expect(literal).to.be.a(ol.style.Literal);
expect(literal).to.be.a(ol.style.TextLiteral);
});

it('accepts stroke properties', function() {
var literal = new ol.style.TextLiteral({
color: '#ff0000',
fontFamily: 'Arial',
fontSize: 11,
text: 'Test',
opacity: 0.5,
strokeColor: '#ff0000',
strokeWidth: 2,
strokeOpacity: 0.5,
zIndex: 0
});
expect(literal).to.be.a(ol.style.TextLiteral);
});

it('throws with incomplete stroke properties', function() {
expect(function() {
new ol.style.TextLiteral({
color: '#ff0000',
fontFamily: 'Arial',
fontSize: 11,
text: 'Test',
opacity: 0.5,
strokeColor: '#ff0000',
zIndex: 0
});
}).throwException(function(err) {
expect(err).to.be.a(goog.asserts.AssertionError);
});
});

});

describe('#equals()', function() {

it('identifies equal literals', function() {
Expand Down Expand Up @@ -82,4 +130,6 @@ describe('ol.style.TextLiteral', function() {

});

goog.require('goog.asserts.AssertionError');
goog.require('ol.style.Literal');
goog.require('ol.style.TextLiteral');
44 changes: 44 additions & 0 deletions test/spec/ol/style/textsymbolizer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ describe('ol.style.Text', function() {
expect(symbolizer).to.be.a(ol.style.Text);
});

it('accepts stroke', function() {
var symbolizer = new ol.style.Text({
color: '#000000',
text: 'Test',
stroke: new ol.style.Stroke({
color: '#ff0000',
width: 2,
opacity: 0.5
})
});
expect(symbolizer).to.be.a(ol.style.Text);
});

});

describe('#createLiteral()', function() {
Expand Down Expand Up @@ -128,6 +141,36 @@ describe('ol.style.Text', function() {
expect(literal.opacity).to.be(0.42);
});

it('evaluates stroke expressions', function() {
var symbolizer = new ol.style.Text({
text: 'test',
stroke: new ol.style.Stroke({
width: ol.expr.parse('strokeWidth')
})
});

var feature = new ol.Feature({
strokeWidth: '4.2'
});

var literal = symbolizer.createLiteral(feature);
expect(literal.strokeWidth).to.be(4.2);
});

it('applies stroke defaults', function() {
var symbolizer = new ol.style.Text({
text: 'test',
stroke: new ol.style.Stroke({
width: 2
})
});

var literal = symbolizer.createLiteral();
expect(literal.strokeWidth).to.be(2);
expect(literal.strokeColor).to.be('#696969');
expect(literal.strokeOpacity).to.be(0.75);
});

});

describe('#getColor()', function() {
Expand Down Expand Up @@ -338,5 +381,6 @@ goog.require('ol.expr');
goog.require('ol.expr.Literal');
goog.require('ol.expr.Literal');
goog.require('ol.geom.GeometryType');
goog.require('ol.style.Stroke');
goog.require('ol.style.Text');
goog.require('ol.style.TextLiteral');

0 comments on commit 2f3cd43

Please sign in to comment.