diff --git a/src/data/bucket/symbol_bucket.js b/src/data/bucket/symbol_bucket.js index 2b7b751389e..2369e6029c5 100644 --- a/src/data/bucket/symbol_bucket.js +++ b/src/data/bucket/symbol_bucket.js @@ -839,22 +839,13 @@ class SymbolBucket implements Bucket { return this.iconCollisionCircle.segments.get().length > 0; } - addIndicesForPlacedTextSymbol(placedTextSymbolIndex: number) { - const placedSymbol = this.text.placedSymbolArray.get(placedTextSymbolIndex); + addIndicesForPlacedSymbol(iconOrText: SymbolBuffers, placedSymbolIndex: number) { + const placedSymbol = iconOrText.placedSymbolArray.get(placedSymbolIndex); const endIndex = placedSymbol.vertexStartIndex + placedSymbol.numGlyphs * 4; for (let vertexIndex = placedSymbol.vertexStartIndex; vertexIndex < endIndex; vertexIndex += 4) { - this.text.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2); - this.text.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3); - } - } - - addIndicesForPlacedIconSymbol(placedIconSymbolIndex: number) { - const placedIcon = this.icon.placedSymbolArray.get(placedIconSymbolIndex); - if (placedIcon.numGlyphs) { - const vertexIndex = placedIcon.vertexStartIndex; - this.icon.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2); - this.icon.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3); + iconOrText.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2); + iconOrText.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3); } } @@ -917,20 +908,20 @@ class SymbolBucket implements Bucket { // to avoid duplicate opacity entries when multiple justifications // share the same glyphs. if (index >= 0 && array.indexOf(index) === i) { - this.addIndicesForPlacedTextSymbol(index); + this.addIndicesForPlacedSymbol(this.text, index); } }); if (symbolInstance.verticalPlacedTextSymbolIndex >= 0) { - this.addIndicesForPlacedTextSymbol(symbolInstance.verticalPlacedTextSymbolIndex); + this.addIndicesForPlacedSymbol(this.text, symbolInstance.verticalPlacedTextSymbolIndex); } if (symbolInstance.placedIconSymbolIndex >= 0) { - this.addIndicesForPlacedIconSymbol(symbolInstance.placedIconSymbolIndex); + this.addIndicesForPlacedSymbol(this.icon, symbolInstance.placedIconSymbolIndex); } if (symbolInstance.verticalPlacedIconSymbolIndex >= 0) { - this.addIndicesForPlacedIconSymbol(symbolInstance.verticalPlacedIconSymbolIndex); + this.addIndicesForPlacedSymbol(this.icon, symbolInstance.verticalPlacedIconSymbolIndex); } } diff --git a/src/symbol/quads.js b/src/symbol/quads.js index 2c3d6423167..fd5f629ea1a 100644 --- a/src/symbol/quads.js +++ b/src/symbol/quads.js @@ -59,7 +59,8 @@ const border = IMAGE_PADDING; export function getIconQuads( shapedIcon: PositionedIcon, iconRotate: number, - isSDFIcon: boolean): Array { + isSDFIcon: boolean, + hasIconTextFit: boolean): Array { const quads = []; const image = shapedIcon.image; @@ -88,7 +89,7 @@ export function getIconQuads( let fixedOffsetY = 0; let fixedContentHeight = fixedHeight; - if (image.content) { + if (image.content && hasIconTextFit) { const content = image.content; stretchOffsetX = sumWithinRange(stretchX, 0, content[0]); stretchOffsetY = sumWithinRange(stretchY, 0, content[1]); @@ -153,7 +154,7 @@ export function getIconQuads( return {tl, tr, bl, br, tex: subRect, writingMode: undefined, glyphOffset: [0, 0], sectionIndex: 0, pixelOffsetTL, pixelOffsetBR, minFontScaleX, minFontScaleY, isSDF: isSDFIcon}; }; - if (!image.stretchX && !image.stretchY) { + if (!hasIconTextFit || (!image.stretchX && !image.stretchY)) { quads.push(makeBox( {fixed: 0, stretch: -1}, {fixed: 0, stretch: -1}, diff --git a/src/symbol/symbol_layout.js b/src/symbol/symbol_layout.js index 28c182ba5c8..a79902e9bcf 100644 --- a/src/symbol/symbol_layout.js +++ b/src/symbol/symbol_layout.js @@ -608,8 +608,9 @@ function addSymbol(bucket: SymbolBucket, // For more info check `updateVariableAnchors` in `draw_symbol.js` . if (shapedIcon) { const iconRotate = layer.layout.get('icon-rotate').evaluate(feature, {}); - const iconQuads = getIconQuads(shapedIcon, iconRotate, isSDFIcon); - const verticalIconQuads = verticallyShapedIcon ? getIconQuads(verticallyShapedIcon, iconRotate, isSDFIcon) : undefined; + const hasIconTextFit = layer.layout.get('icon-text-fit') !== 'none'; + const iconQuads = getIconQuads(shapedIcon, iconRotate, isSDFIcon, hasIconTextFit); + const verticalIconQuads = verticallyShapedIcon ? getIconQuads(verticallyShapedIcon, iconRotate, isSDFIcon, hasIconTextFit) : undefined; iconCollisionFeature = new CollisionFeature(collisionBoxArray, line, anchor, featureIndex, sourceLayerIndex, bucketIndex, shapedIcon, iconBoxScale, iconPadding, /*align boxes to line*/false, bucket.overscaling, iconRotate); numIconVertices = iconQuads.length * 4; diff --git a/test/integration/render-tests/icon-image/stretchable-content/expected.png b/test/integration/render-tests/icon-image/stretchable-content/expected.png new file mode 100644 index 00000000000..04453e4b961 Binary files /dev/null and b/test/integration/render-tests/icon-image/stretchable-content/expected.png differ diff --git a/test/integration/render-tests/icon-image/stretchable-content/style.json b/test/integration/render-tests/icon-image/stretchable-content/style.json new file mode 100644 index 00000000000..b4914406fd6 --- /dev/null +++ b/test/integration/render-tests/icon-image/stretchable-content/style.json @@ -0,0 +1,41 @@ +{ + "version": 8, + "metadata": { + "test": { + "width": 200, + "height": 150 + } + }, + "zoom": 0.5, + "sources": { + "geojson": { + "type": "geojson", + "data": "local://geojson/anchors.json" + } + }, + "sprite": "local://sprites/stretch", + "glyphs": "local://glyphs/{fontstack}/{range}.pbf", + "layers": [ + { + "id": "anchor-left", + "type": "symbol", + "source": "geojson", + "layout": { + "icon-image": "nine-part", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchors", + "type": "circle", + "source": "geojson", + "paint": { + "circle-radius": 2, + "circle-color": "green", + "circle-stroke-color": "white", + "circle-stroke-width": 1 + } + } + ] +} diff --git a/test/integration/render-tests/icon-image/stretchable/expected.png b/test/integration/render-tests/icon-image/stretchable/expected.png new file mode 100644 index 00000000000..5a8e5d5b41a Binary files /dev/null and b/test/integration/render-tests/icon-image/stretchable/expected.png differ diff --git a/test/integration/render-tests/icon-image/stretchable/style.json b/test/integration/render-tests/icon-image/stretchable/style.json new file mode 100644 index 00000000000..56edb0c4305 --- /dev/null +++ b/test/integration/render-tests/icon-image/stretchable/style.json @@ -0,0 +1,41 @@ +{ + "version": 8, + "metadata": { + "test": { + "width": 200, + "height": 150 + } + }, + "zoom": 0.5, + "sources": { + "geojson": { + "type": "geojson", + "data": "local://geojson/anchors.json" + } + }, + "sprite": "local://sprites/stretch", + "glyphs": "local://glyphs/{fontstack}/{range}.pbf", + "layers": [ + { + "id": "anchor-left", + "type": "symbol", + "source": "geojson", + "layout": { + "icon-image": "nine-part-content", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchors", + "type": "circle", + "source": "geojson", + "paint": { + "circle-radius": 2, + "circle-color": "green", + "circle-stroke-color": "white", + "circle-stroke-width": 1 + } + } + ] +} diff --git a/test/integration/render-tests/icon-text-fit/stretch-nine-part-just-height/expected.png b/test/integration/render-tests/icon-text-fit/stretch-nine-part-just-height/expected.png new file mode 100644 index 00000000000..cedb6506279 Binary files /dev/null and b/test/integration/render-tests/icon-text-fit/stretch-nine-part-just-height/expected.png differ diff --git a/test/integration/render-tests/icon-text-fit/stretch-nine-part-just-height/style.json b/test/integration/render-tests/icon-text-fit/stretch-nine-part-just-height/style.json new file mode 100644 index 00000000000..650f9a9e169 --- /dev/null +++ b/test/integration/render-tests/icon-text-fit/stretch-nine-part-just-height/style.json @@ -0,0 +1,192 @@ +{ + "version": 8, + "metadata": { + "test": { + "width": 200, + "height": 150 + } + }, + "sources": { + "geojson": { + "type": "geojson", + "data": "local://geojson/anchors.json" + } + }, + "sprite": "local://sprites/stretch", + "glyphs": "local://glyphs/{fontstack}/{range}.pbf", + "layers": [ + { + "id": "anchor-center", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "center"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "center", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "height", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "left"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "height", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-left"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "top-left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "height", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "top", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "height", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-right"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "top-right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "height", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "right"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "height", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-left"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "bottom-left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "height", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "bottom", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "height", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-right"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "bottom-right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "height", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchors", + "type": "circle", + "source": "geojson", + "paint": { + "circle-radius": 2, + "circle-color": "green", + "circle-stroke-color": "white", + "circle-stroke-width": 1 + } + } + ] +} diff --git a/test/integration/render-tests/icon-text-fit/stretch-nine-part-just-width/expected.png b/test/integration/render-tests/icon-text-fit/stretch-nine-part-just-width/expected.png new file mode 100644 index 00000000000..0d59496c399 Binary files /dev/null and b/test/integration/render-tests/icon-text-fit/stretch-nine-part-just-width/expected.png differ diff --git a/test/integration/render-tests/icon-text-fit/stretch-nine-part-just-width/style.json b/test/integration/render-tests/icon-text-fit/stretch-nine-part-just-width/style.json new file mode 100644 index 00000000000..9776d8cc4dd --- /dev/null +++ b/test/integration/render-tests/icon-text-fit/stretch-nine-part-just-width/style.json @@ -0,0 +1,192 @@ +{ + "version": 8, + "metadata": { + "test": { + "width": 200, + "height": 150 + } + }, + "sources": { + "geojson": { + "type": "geojson", + "data": "local://geojson/anchors.json" + } + }, + "sprite": "local://sprites/stretch", + "glyphs": "local://glyphs/{fontstack}/{range}.pbf", + "layers": [ + { + "id": "anchor-center", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "center"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "center", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "width", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "left"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "width", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-left"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "top-left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "width", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "top", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "width", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-right"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "top-right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "width", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "right"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "width", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-left"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "bottom-left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "width", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "bottom", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "width", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-right"], + "layout": { + "text-field": "ASDFASDF", + "text-size": 10, + "text-anchor": "bottom-right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part", + "icon-text-fit": "width", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchors", + "type": "circle", + "source": "geojson", + "paint": { + "circle-radius": 2, + "circle-color": "green", + "circle-stroke-color": "white", + "circle-stroke-width": 1 + } + } + ] +}