From 2ee776d9f6a5358ecc5deb13cce247ae600dbf1f Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 9 Oct 2013 11:52:00 -0600 Subject: [PATCH] Support fontWeight in text symbolizer --- src/objectliterals.jsdoc | 1 + .../renderer/canvas/canvasvectorrenderer.js | 8 +++- src/ol/style/textliteral.js | 6 +++ src/ol/style/textsymbolizer.js | 34 +++++++++++++++ test/spec/ol/style/style.test.js | 1 + test/spec/ol/style/textliteral.test.js | 21 ++++++++++ test/spec/ol/style/textsymbolizer.test.js | 42 +++++++++++++++++++ 7 files changed, 112 insertions(+), 1 deletion(-) diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index dd79015e38..1385e200a3 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -760,6 +760,7 @@ * @property {string|ol.expr.Expression|undefined} color Color. * @property {string|ol.expr.Expression|undefined} fontFamily Font family. * @property {number|ol.expr.Expression|undefined} fontSize Font size in pixels. + * @property {string|ol.expr.Expression|undefined} fontWeight Font weight. * @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. diff --git a/src/ol/renderer/canvas/canvasvectorrenderer.js b/src/ol/renderer/canvas/canvasvectorrenderer.js index 7232ad8865..c6b0d87f0c 100644 --- a/src/ol/renderer/canvas/canvasvectorrenderer.js +++ b/src/ol/renderer/canvas/canvasvectorrenderer.js @@ -286,7 +286,13 @@ ol.renderer.canvas.Vector.prototype.renderText_ = if (context.fillStyle !== text.color) { context.fillStyle = text.color; } - context.font = text.fontSize + 'px ' + text.fontFamily; + + // font shorthand values must be given in the correct order + // see http://www.w3.org/TR/CSS21/fonts.html#font-shorthand + context.font = text.fontWeight + ' ' + + text.fontSize + 'px ' + + text.fontFamily; + context.globalAlpha = text.opacity; // TODO: make alignments configurable diff --git a/src/ol/style/textliteral.js b/src/ol/style/textliteral.js index 23e06cad90..9f6026c080 100644 --- a/src/ol/style/textliteral.js +++ b/src/ol/style/textliteral.js @@ -8,6 +8,7 @@ goog.require('ol.style.Literal'); * @typedef {{color: string, * fontFamily: string, * fontSize: number, + * fontWeight: string, * text: string, * opacity: number, * strokeColor: (string|undefined), @@ -38,6 +39,10 @@ ol.style.TextLiteral = function(options) { /** @type {number} */ this.fontSize = options.fontSize; + goog.asserts.assertString(options.fontWeight, 'fontWeight must be a string'); + /** @type {string} */ + this.fontWeight = options.fontWeight; + goog.asserts.assertString(options.text, 'text must be a string'); /** @type {string} */ this.text = options.text; @@ -92,6 +97,7 @@ ol.style.TextLiteral.prototype.equals = function(other) { return this.color == other.color && this.fontFamily == other.fontFamily && this.fontSize == other.fontSize && + this.fontWeight == other.fontWeight && this.opacity == other.opacity && this.strokeColor == other.strokeColor && this.strokeOpacity == other.strokeOpacity && diff --git a/src/ol/style/textsymbolizer.js b/src/ol/style/textsymbolizer.js index a597fe27c2..bc3e1d3ec7 100644 --- a/src/ol/style/textsymbolizer.js +++ b/src/ol/style/textsymbolizer.js @@ -44,6 +44,15 @@ ol.style.Text = function(options) { (options.fontSize instanceof ol.expr.Expression) ? options.fontSize : new ol.expr.Literal(options.fontSize); + /** + * @type {ol.expr.Expression} + * @private + */ + this.fontWeight_ = !goog.isDef(options.fontWeight) ? + new ol.expr.Literal(ol.style.TextDefaults.fontWeight) : + (options.fontWeight instanceof ol.expr.Expression) ? + options.fontWeight : new ol.expr.Literal(options.fontWeight); + /** * @type {ol.expr.Expression} * @private @@ -102,6 +111,9 @@ ol.style.Text.prototype.createLiteral = function(featureOrType) { var fontSize = Number(ol.expr.evaluateFeature(this.fontSize_, feature)); goog.asserts.assert(!isNaN(fontSize), 'fontSize must be a number'); + var fontWeight = ol.expr.evaluateFeature(this.fontWeight_, feature); + goog.asserts.assertString(fontWeight, 'fontWeight must be a string'); + var text = ol.expr.evaluateFeature(this.text_, feature); goog.asserts.assertString(text, 'text must be a string'); @@ -129,6 +141,7 @@ ol.style.Text.prototype.createLiteral = function(featureOrType) { color: color, fontFamily: fontFamily, fontSize: fontSize, + fontWeight: fontWeight, text: text, opacity: opacity, strokeColor: strokeColor, @@ -166,6 +179,15 @@ ol.style.Text.prototype.getFontSize = function() { }; +/** + * Get the font weight. + * @return {ol.expr.Expression} Font weight. + */ +ol.style.Text.prototype.getFontWeight = function() { + return this.fontWeight_; +}; + + /** * Get the opacity. * @return {ol.expr.Expression} Opacity. @@ -223,6 +245,16 @@ ol.style.Text.prototype.setFontSize = function(fontSize) { }; +/** + * Set the font weight. + * @param {ol.expr.Expression} fontWeight Font weight. + */ +ol.style.Text.prototype.setFontWeight = function(fontWeight) { + goog.asserts.assertInstanceof(fontWeight, ol.expr.Expression); + this.fontWeight_ = fontWeight; +}; + + /** * Set the opacity. * @param {ol.expr.Expression} opacity Opacity. @@ -257,6 +289,7 @@ ol.style.Text.prototype.setZIndex = function(zIndex) { * @typedef {{color: string, * fontFamily: string, * fontSize: number, + * fontWeight: string, * opacity: number, * zIndex: number}} */ @@ -264,6 +297,7 @@ ol.style.TextDefaults = { color: '#000', fontFamily: 'sans-serif', fontSize: 10, + fontWeight: 'normal', opacity: 1, zIndex: 0 }; diff --git a/test/spec/ol/style/style.test.js b/test/spec/ol/style/style.test.js index 5bc1314f36..d282a06dcd 100644 --- a/test/spec/ol/style/style.test.js +++ b/test/spec/ol/style/style.test.js @@ -269,6 +269,7 @@ describe('ol.style.Style', function() { color: '#ffffff', fontFamily: 'Arial', fontSize: 11, + fontWeight: 'normal', text: 'Test', opacity: 0.5, zIndex: 0 diff --git a/test/spec/ol/style/textliteral.test.js b/test/spec/ol/style/textliteral.test.js index 0ad48b7835..2e5e8c5b96 100644 --- a/test/spec/ol/style/textliteral.test.js +++ b/test/spec/ol/style/textliteral.test.js @@ -9,6 +9,7 @@ describe('ol.style.TextLiteral', function() { color: '#ff0000', fontFamily: 'Arial', fontSize: 11, + fontWeight: 'normal', text: 'Test', opacity: 0.5, zIndex: 0 @@ -22,6 +23,7 @@ describe('ol.style.TextLiteral', function() { color: '#ff0000', fontFamily: 'Arial', fontSize: 11, + fontWeight: 'normal', text: 'Test', opacity: 0.5, strokeColor: '#ff0000', @@ -38,6 +40,7 @@ describe('ol.style.TextLiteral', function() { color: '#ff0000', fontFamily: 'Arial', fontSize: 11, + fontWeight: 'normal', text: 'Test', opacity: 0.5, strokeColor: '#ff0000', @@ -57,6 +60,7 @@ describe('ol.style.TextLiteral', function() { color: '#ff0000', fontFamily: 'Arial', fontSize: 11, + fontWeight: 'normal', text: 'Test', opacity: 0.5, zIndex: 0 @@ -65,6 +69,7 @@ describe('ol.style.TextLiteral', function() { color: '#ff0000', fontFamily: 'Arial', fontSize: 11, + fontWeight: 'normal', text: 'Test', opacity: 0.5, zIndex: 0 @@ -73,6 +78,7 @@ describe('ol.style.TextLiteral', function() { color: '#0000ff', fontFamily: 'Arial', fontSize: 11, + fontWeight: 'normal', text: 'Test', opacity: 0.5, zIndex: 0 @@ -81,6 +87,7 @@ describe('ol.style.TextLiteral', function() { color: '#ff0000', fontFamily: 'Dingbats', fontSize: 11, + fontWeight: 'normal', text: 'Test', opacity: 0.5, zIndex: 0 @@ -89,6 +96,16 @@ describe('ol.style.TextLiteral', function() { color: '#ff0000', fontFamily: 'Arial', fontSize: 12, + fontWeight: 'normal', + text: 'Test', + opacity: 0.5, + zIndex: 0 + }); + var differentFontWeight = new ol.style.TextLiteral({ + color: '#ff0000', + fontFamily: 'Arial', + fontSize: 11, + fontWeight: 'bold', text: 'Test', opacity: 0.5, zIndex: 0 @@ -97,6 +114,7 @@ describe('ol.style.TextLiteral', function() { color: '#ff0000', fontFamily: 'Arial', fontSize: 11, + fontWeight: 'normal', text: 'Test', opacity: 0.6, zIndex: 0 @@ -105,6 +123,7 @@ describe('ol.style.TextLiteral', function() { color: '#ff0000', fontFamily: 'Arial', fontSize: 11, + fontWeight: 'normal', text: 'Text is not compared for equality', opacity: 0.5, zIndex: 0 @@ -113,6 +132,7 @@ describe('ol.style.TextLiteral', function() { color: '#ff0000', fontFamily: 'Arial', fontSize: 11, + fontWeight: 'normal', text: 'Test', opacity: 0.5, zIndex: 3 @@ -121,6 +141,7 @@ describe('ol.style.TextLiteral', function() { expect(literal.equals(differentColor)).to.be(false); expect(literal.equals(differentFontFamily)).to.be(false); expect(literal.equals(differentFontSize)).to.be(false); + expect(literal.equals(differentFontWeight)).to.be(false); expect(literal.equals(differentOpacity)).to.be(false); expect(literal.equals(equalLiteral2)).to.be(true); expect(literal.equals(differentZIndex)).to.be(false); diff --git a/test/spec/ol/style/textsymbolizer.test.js b/test/spec/ol/style/textsymbolizer.test.js index 11ad31e8b8..bd43dafd6b 100644 --- a/test/spec/ol/style/textsymbolizer.test.js +++ b/test/spec/ol/style/textsymbolizer.test.js @@ -109,6 +109,7 @@ describe('ol.style.Text', function() { expect(literal.color).to.be('#000'); expect(literal.fontFamily).to.be('sans-serif'); expect(literal.fontSize).to.be(10); + expect(literal.fontWeight).to.be('normal'); expect(literal.text).to.be('Test'); expect(literal.opacity).to.be(1); }); @@ -216,6 +217,20 @@ describe('ol.style.Text', function() { }); + describe('#getFontWeight()', function() { + + it('returns the font size', function() { + var symbolizer = new ol.style.Text({ + fontWeight: 'bold' + }); + + var fontWeight = symbolizer.getFontWeight(); + expect(fontWeight).to.be.a(ol.expr.Literal); + expect(fontWeight.getValue()).to.be('bold'); + }); + + }); + describe('#getOpacity()', function() { it('returns the opacity', function() { @@ -314,6 +329,33 @@ describe('ol.style.Text', function() { }); + describe('#setFontWeight()', function() { + + it('sets the font size', function() { + var symbolizer = new ol.style.Text({ + fontWeight: 'bold' + }); + symbolizer.setFontWeight(new ol.expr.Literal('900')); + + var fontWeight = symbolizer.getFontWeight(); + expect(fontWeight).to.be.a(ol.expr.Literal); + expect(fontWeight.getValue()).to.be('900'); + }); + + it('throws when not provided an expression', function() { + var symbolizer = new ol.style.Text({ + fontWeight: 'lighter' + }); + + expect(function() { + symbolizer.setFontWeight('bolder'); + }).throwException(function(err) { + expect(err).to.be.a(goog.asserts.AssertionError); + }); + }); + + }); + describe('#setOpacity()', function() { it('sets the opacity', function() {