diff --git a/src/geo/transform.js b/src/geo/transform.js index 0e9c1eb713e..9452ceae304 100644 --- a/src/geo/transform.js +++ b/src/geo/transform.js @@ -4,7 +4,7 @@ const LngLat = require('./lng_lat'), Point = require('point-geometry'), Coordinate = require('./coordinate'), util = require('../util/util'), - interp = require('../util/interpolate'), + interp = require('../style-spec/util/interpolate'), TileCoord = require('../source/tile_coord'), EXTENT = require('../data/extent'), glmatrix = require('@mapbox/gl-matrix'); diff --git a/src/style-spec/function/index.js b/src/style-spec/function/index.js index 27921543886..072b80187c6 100644 --- a/src/style-spec/function/index.js +++ b/src/style-spec/function/index.js @@ -4,6 +4,7 @@ const colorSpaces = require('./color_spaces'); const parseColor = require('../util/parse_color'); const extend = require('../util/extend'); const getType = require('../util/get_type'); +const interpolate = require('../util/interpolate'); function identityFunction(x) { return x; @@ -184,15 +185,28 @@ function evaluateExponentialFunction(parameters, propertySpec, input) { if (input >= parameters.stops[n - 1][0]) return parameters.stops[n - 1][1]; const index = findStopLessThanOrEqualTo(parameters.stops, input); + const t = interpolationFactor( + input, base, + parameters.stops[index][0], + parameters.stops[index + 1][0]); - return interpolate( - input, - base, - parameters.stops[index][0], - parameters.stops[index + 1][0], - parameters.stops[index][1], - parameters.stops[index + 1][1] - ); + const outputLower = parameters.stops[index][1]; + const outputUpper = parameters.stops[index + 1][1]; + const interp = interpolate[propertySpec.type] || identityFunction; + + if (typeof outputLower === 'function') { + return function() { + const evaluatedLower = outputLower.apply(undefined, arguments); + const evaluatedUpper = outputUpper.apply(undefined, arguments); + // Special case for fill-outline-color, which has no spec default. + if (evaluatedLower === undefined || evaluatedUpper === undefined) { + return undefined; + } + return interp(evaluatedLower, evaluatedUpper, t); + }; + } + + return interp(outputLower, outputUpper, t); } function evaluateIdentityFunction(parameters, propertySpec, input) { @@ -232,37 +246,6 @@ function findStopLessThanOrEqualTo(stops, input) { return Math.max(currentIndex - 1, 0); } -function interpolate(input, base, inputLower, inputUpper, outputLower, outputUpper) { - if (typeof outputLower === 'function') { - return function() { - const evaluatedLower = outputLower.apply(undefined, arguments); - const evaluatedUpper = outputUpper.apply(undefined, arguments); - // Special case for fill-outline-color, which has no spec default. - if (evaluatedLower === undefined || evaluatedUpper === undefined) { - return undefined; - } - return interpolate(input, base, inputLower, inputUpper, evaluatedLower, evaluatedUpper); - }; - } else if (outputLower.length) { - return interpolateArray(input, base, inputLower, inputUpper, outputLower, outputUpper); - } else { - return interpolateNumber(input, base, inputLower, inputUpper, outputLower, outputUpper); - } -} - -function interpolateNumber(input, base, inputLower, inputUpper, outputLower, outputUpper) { - const ratio = interpolationFactor(input, base, inputLower, inputUpper); - return outputLower + ratio * (outputUpper - outputLower); -} - -function interpolateArray(input, base, inputLower, inputUpper, outputLower, outputUpper) { - const output = []; - for (let i = 0; i < outputLower.length; i++) { - output[i] = interpolateNumber(input, base, inputLower, inputUpper, outputLower[i], outputUpper[i]); - } - return output; -} - function isFunctionDefinition(value) { return typeof value === 'object' && (value.stops || value.type === 'identity'); } diff --git a/src/util/interpolate.js b/src/style-spec/util/interpolate.js similarity index 100% rename from src/util/interpolate.js rename to src/style-spec/util/interpolate.js diff --git a/src/style/style_transition.js b/src/style/style_transition.js index b664adbbc74..8ded3e56fd9 100644 --- a/src/style/style_transition.js +++ b/src/style/style_transition.js @@ -1,7 +1,7 @@ 'use strict'; const util = require('../util/util'); -const interpolate = require('../util/interpolate'); +const interpolate = require('../style-spec/util/interpolate'); const fakeZoomHistory = { lastIntegerZoom: 0, lastIntegerZoomTime: 0, lastZoom: 0 }; diff --git a/src/symbol/get_anchors.js b/src/symbol/get_anchors.js index db1bd776f14..0be6ed3ae0b 100644 --- a/src/symbol/get_anchors.js +++ b/src/symbol/get_anchors.js @@ -1,6 +1,6 @@ 'use strict'; -const interpolate = require('../util/interpolate'); +const interpolate = require('../style-spec/util/interpolate'); const Anchor = require('../symbol/anchor'); const checkMaxAngle = require('./check_max_angle'); diff --git a/src/ui/camera.js b/src/ui/camera.js index 716d1b62fdf..2119dcb048d 100644 --- a/src/ui/camera.js +++ b/src/ui/camera.js @@ -1,7 +1,7 @@ 'use strict'; const util = require('../util/util'); -const interpolate = require('../util/interpolate'); +const interpolate = require('../style-spec/util/interpolate'); const browser = require('../util/browser'); const LngLat = require('../geo/lng_lat'); const LngLatBounds = require('../geo/lng_lat_bounds'); diff --git a/test/integration/render-tests/regressions/mapbox-gl-js#4605/expected.png b/test/integration/render-tests/regressions/mapbox-gl-js#4605/expected.png new file mode 100644 index 00000000000..02e48470928 Binary files /dev/null and b/test/integration/render-tests/regressions/mapbox-gl-js#4605/expected.png differ diff --git a/test/integration/render-tests/regressions/mapbox-gl-js#4605/style.json b/test/integration/render-tests/regressions/mapbox-gl-js#4605/style.json new file mode 100644 index 00000000000..b39b68e2657 --- /dev/null +++ b/test/integration/render-tests/regressions/mapbox-gl-js#4605/style.json @@ -0,0 +1,53 @@ +{ + "version": 8, + "metadata": { + "test": { + "height": 64, + "width": 64 + } + }, + "zoom": 1, + "sources": { + "point": { + "type": "geojson", + "data": { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "foo": "bar" + }, + "geometry": { + "type": "Point", + "coordinates": [ 0, 0 ] + } + } + ] + } + } + }, + "glyphs": "local://glyphs/{fontstack}/{range}.pbf", + "layers": [ + { + "id": "text", + "type": "symbol", + "source": "point", + "layout": { + "text-field": { + "type": "categorical", + "property": "foo", + "stops": [ + [{ "value": "bar", "zoom": 0 }, "xxx"], + [{ "value": "bar", "zoom": 2 }, "XXX"] + ] + + }, + "text-font": [ + "Open Sans Semibold", + "Arial Unicode MS Bold" + ] + } + } + ] +} diff --git a/test/unit/util/interpolate.test.js b/test/unit/style-spec/interpolate.test.js similarity index 90% rename from test/unit/util/interpolate.test.js rename to test/unit/style-spec/interpolate.test.js index d4d8e11c74b..85dd80b3533 100644 --- a/test/unit/util/interpolate.test.js +++ b/test/unit/style-spec/interpolate.test.js @@ -1,7 +1,7 @@ 'use strict'; const test = require('mapbox-gl-js-test').test; -const interpolate = require('../../../src/util/interpolate'); +const interpolate = require('../../../src/style-spec/util/interpolate'); test('interpolate.number', (t) => { t.equal(interpolate(0, 1, 0.5), 0.5);