From 9f01202e2c56f4131c0af66a4f773594d5078ece Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Thu, 7 Nov 2019 13:13:11 -0500 Subject: [PATCH] implement stretchable icons --- debug/stretchable.html | 129 ++++++++++++ src/data/array_types.js | 23 +- src/data/bucket/symbol_attributes.js | 5 +- src/data/bucket/symbol_bucket.js | 22 +- src/render/image_atlas.js | 8 +- src/render/image_manager.js | 3 + src/shaders/symbol_icon.vertex.glsl | 6 +- src/shaders/symbol_sdf.vertex.glsl | 5 +- src/style/load_sprite.js | 4 +- src/style/style_image.js | 3 + src/symbol/quads.js | 197 ++++++++++++++---- src/ui/map.js | 7 +- .../stretch-fifteen-part/expected.png | Bin 0 -> 16247 bytes .../stretch-fifteen-part/style.json | 192 +++++++++++++++++ .../stretch-nine-part-@2x/expected.png | Bin 0 -> 16173 bytes .../stretch-nine-part-@2x/style.json | 192 +++++++++++++++++ .../stretch-nine-part-content/expected.png | Bin 0 -> 14999 bytes .../stretch-nine-part-content/style.json | 192 +++++++++++++++++ .../stretch-nine-part/expected.png | Bin 0 -> 15797 bytes .../stretch-nine-part/style.json | 192 +++++++++++++++++ .../stretch-three-part/expected.png | Bin 0 -> 15617 bytes .../stretch-three-part/style.json | 192 +++++++++++++++++ .../stretch-two-part/expected.png | Bin 0 -> 15115 bytes .../icon-text-fit/stretch-two-part/style.json | 192 +++++++++++++++++ .../stretch-underscale/expected.png | Bin 0 -> 6089 bytes .../stretch-underscale/style.json | 192 +++++++++++++++++ test/integration/sprites/stretch.json | 61 ++++++ test/integration/sprites/stretch.png | Bin 0 -> 437 bytes test/unit/symbol/quads.test.js | 60 +++++- test/unit/symbol/shaping.test.js | 3 + 30 files changed, 1814 insertions(+), 66 deletions(-) create mode 100644 debug/stretchable.html create mode 100644 test/integration/render-tests/icon-text-fit/stretch-fifteen-part/expected.png create mode 100644 test/integration/render-tests/icon-text-fit/stretch-fifteen-part/style.json create mode 100644 test/integration/render-tests/icon-text-fit/stretch-nine-part-@2x/expected.png create mode 100644 test/integration/render-tests/icon-text-fit/stretch-nine-part-@2x/style.json create mode 100644 test/integration/render-tests/icon-text-fit/stretch-nine-part-content/expected.png create mode 100644 test/integration/render-tests/icon-text-fit/stretch-nine-part-content/style.json create mode 100644 test/integration/render-tests/icon-text-fit/stretch-nine-part/expected.png create mode 100644 test/integration/render-tests/icon-text-fit/stretch-nine-part/style.json create mode 100644 test/integration/render-tests/icon-text-fit/stretch-three-part/expected.png create mode 100644 test/integration/render-tests/icon-text-fit/stretch-three-part/style.json create mode 100644 test/integration/render-tests/icon-text-fit/stretch-two-part/expected.png create mode 100644 test/integration/render-tests/icon-text-fit/stretch-two-part/style.json create mode 100644 test/integration/render-tests/icon-text-fit/stretch-underscale/expected.png create mode 100644 test/integration/render-tests/icon-text-fit/stretch-underscale/style.json create mode 100644 test/integration/sprites/stretch.json create mode 100644 test/integration/sprites/stretch.png diff --git a/debug/stretchable.html b/debug/stretchable.html new file mode 100644 index 00000000000..fb1cbf8d124 --- /dev/null +++ b/debug/stretchable.html @@ -0,0 +1,129 @@ + + + + Mapbox GL JS debug page + + + + + + + +
+ + + + + + diff --git a/src/data/array_types.js b/src/data/array_types.js index ffc8bf7f62c..a62f059d8a3 100644 --- a/src/data/array_types.js +++ b/src/data/array_types.js @@ -189,10 +189,11 @@ register('StructArrayLayout8ui16', StructArrayLayout8ui16); * Implementation of the StructArray layout: * [0]: Int16[4] * [8]: Uint16[4] + * [16]: Int16[4] * * @private */ -class StructArrayLayout4i4ui16 extends StructArray { +class StructArrayLayout4i4ui4i24 extends StructArray { uint8: Uint8Array; int16: Int16Array; uint16: Uint16Array; @@ -203,14 +204,14 @@ class StructArrayLayout4i4ui16 extends StructArray { this.uint16 = new Uint16Array(this.arrayBuffer); } - emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number) { + emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number, v10: number, v11: number) { const i = this.length; this.resize(i + 1); - return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7); + return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); } - emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number) { - const o2 = i * 8; + emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number, v10: number, v11: number) { + const o2 = i * 12; this.int16[o2 + 0] = v0; this.int16[o2 + 1] = v1; this.int16[o2 + 2] = v2; @@ -219,12 +220,16 @@ class StructArrayLayout4i4ui16 extends StructArray { this.uint16[o2 + 5] = v5; this.uint16[o2 + 6] = v6; this.uint16[o2 + 7] = v7; + this.int16[o2 + 8] = v8; + this.int16[o2 + 9] = v9; + this.int16[o2 + 10] = v10; + this.int16[o2 + 11] = v11; return i; } } -StructArrayLayout4i4ui16.prototype.bytesPerElement = 16; -register('StructArrayLayout4i4ui16', StructArrayLayout4i4ui16); +StructArrayLayout4i4ui4i24.prototype.bytesPerElement = 24; +register('StructArrayLayout4i4ui4i24', StructArrayLayout4i4ui4i24); /** * Implementation of the StructArray layout: @@ -1143,7 +1148,7 @@ export { StructArrayLayout2i4i12, StructArrayLayout2i4ub8, StructArrayLayout8ui16, - StructArrayLayout4i4ui16, + StructArrayLayout4i4ui4i24, StructArrayLayout3f12, StructArrayLayout1ul4, StructArrayLayout6i1ul2ui2i24, @@ -1167,7 +1172,7 @@ export { StructArrayLayout2i4 as HeatmapLayoutArray, StructArrayLayout2i4ub8 as LineLayoutArray, StructArrayLayout8ui16 as PatternLayoutArray, - StructArrayLayout4i4ui16 as SymbolLayoutArray, + StructArrayLayout4i4ui4i24 as SymbolLayoutArray, StructArrayLayout3f12 as SymbolDynamicLayoutArray, StructArrayLayout1ul4 as SymbolOpacityArray, StructArrayLayout2i2i2i12 as CollisionBoxLayoutArray, diff --git a/src/data/bucket/symbol_attributes.js b/src/data/bucket/symbol_attributes.js index bc8bb06e0bf..014d922e595 100644 --- a/src/data/bucket/symbol_attributes.js +++ b/src/data/bucket/symbol_attributes.js @@ -4,8 +4,9 @@ import {createLayout} from '../../util/struct_array'; export const symbolLayoutAttributes = createLayout([ {name: 'a_pos_offset', components: 4, type: 'Int16'}, - {name: 'a_data', components: 4, type: 'Uint16'} -]); + {name: 'a_data', components: 4, type: 'Uint16'}, + {name: 'a_pixeloffset', components: 4, type: 'Int16'} +], 4); export const dynamicLayoutAttributes = createLayout([ {name: 'a_projected_pos', components: 3, type: 'Float32'} diff --git a/src/data/bucket/symbol_bucket.js b/src/data/bucket/symbol_bucket.js index 925e8e70499..2b7b751389e 100644 --- a/src/data/bucket/symbol_bucket.js +++ b/src/data/bucket/symbol_bucket.js @@ -102,7 +102,7 @@ const shaderOpacityAttributes = [ {name: 'a_fade_opacity', components: 1, type: 'Uint8', offset: 0} ]; -function addVertex(array, anchorX, anchorY, ox, oy, tx, ty, sizeVertex, isSDF: boolean) { +function addVertex(array, anchorX, anchorY, ox, oy, tx, ty, sizeVertex, isSDF: boolean, pixelOffsetX, pixelOffsetY, minFontScaleX, minFontScaleY) { const aSizeX = sizeVertex ? Math.min(MAX_PACKED_SIZE, Math.round(sizeVertex[0])) : 0; const aSizeY = sizeVertex ? Math.min(MAX_PACKED_SIZE, Math.round(sizeVertex[1])) : 0; array.emplaceBack( @@ -116,7 +116,11 @@ function addVertex(array, anchorX, anchorY, ox, oy, tx, ty, sizeVertex, isSDF: b tx, // x coordinate of symbol on glyph atlas texture ty, // y coordinate of symbol on glyph atlas texture (aSizeX << 1) + (isSDF ? 1 : 0), - aSizeY + aSizeY, + pixelOffsetX * 16, + pixelOffsetY * 16, + minFontScaleX * 256, + minFontScaleY * 256 ); } @@ -593,15 +597,19 @@ class SymbolBucket implements Bucket { tr = symbol.tr, bl = symbol.bl, br = symbol.br, - tex = symbol.tex; + tex = symbol.tex, + pixelOffsetTL = symbol.pixelOffsetTL, + pixelOffsetBR = symbol.pixelOffsetBR, + mfsx = symbol.minFontScaleX, + mfsy = symbol.minFontScaleY; const index = segment.vertexLength; const y = symbol.glyphOffset[1]; - addVertex(layoutVertexArray, labelAnchor.x, labelAnchor.y, tl.x, y + tl.y, tex.x, tex.y, sizeVertex, symbol.isSDF); - addVertex(layoutVertexArray, labelAnchor.x, labelAnchor.y, tr.x, y + tr.y, tex.x + tex.w, tex.y, sizeVertex, symbol.isSDF); - addVertex(layoutVertexArray, labelAnchor.x, labelAnchor.y, bl.x, y + bl.y, tex.x, tex.y + tex.h, sizeVertex, symbol.isSDF); - addVertex(layoutVertexArray, labelAnchor.x, labelAnchor.y, br.x, y + br.y, tex.x + tex.w, tex.y + tex.h, sizeVertex, symbol.isSDF); + addVertex(layoutVertexArray, labelAnchor.x, labelAnchor.y, tl.x, y + tl.y, tex.x, tex.y, sizeVertex, symbol.isSDF, pixelOffsetTL.x, pixelOffsetTL.y, mfsx, mfsy); + addVertex(layoutVertexArray, labelAnchor.x, labelAnchor.y, tr.x, y + tr.y, tex.x + tex.w, tex.y, sizeVertex, symbol.isSDF, pixelOffsetBR.x, pixelOffsetTL.y, mfsx, mfsy); + addVertex(layoutVertexArray, labelAnchor.x, labelAnchor.y, bl.x, y + bl.y, tex.x, tex.y + tex.h, sizeVertex, symbol.isSDF, pixelOffsetTL.x, pixelOffsetBR.y, mfsx, mfsy); + addVertex(layoutVertexArray, labelAnchor.x, labelAnchor.y, br.x, y + br.y, tex.x + tex.w, tex.y + tex.h, sizeVertex, symbol.isSDF, pixelOffsetBR.x, pixelOffsetBR.y, mfsx, mfsy); addDynamicAttributes(dynamicLayoutVertexArray, labelAnchor, angle); diff --git a/src/render/image_atlas.js b/src/render/image_atlas.js index ebf78823be9..e3083183ac5 100644 --- a/src/render/image_atlas.js +++ b/src/render/image_atlas.js @@ -22,10 +22,16 @@ export class ImagePosition { paddedRect: Rect; pixelRatio: number; version: number; + stretchY: Array> | void; + stretchX: Array> | void; + content: Array | void; - constructor(paddedRect: Rect, {pixelRatio, version}: StyleImage) { + constructor(paddedRect: Rect, {pixelRatio, version, stretchX, stretchY, content}: StyleImage) { this.paddedRect = paddedRect; this.pixelRatio = pixelRatio; + this.stretchX = stretchX; + this.stretchY = stretchY; + this.content = content; this.version = version; } diff --git a/src/render/image_manager.js b/src/render/image_manager.js index e3b53bfa911..40b9666595a 100644 --- a/src/render/image_manager.js +++ b/src/render/image_manager.js @@ -150,6 +150,9 @@ class ImageManager extends Evented { pixelRatio: image.pixelRatio, sdf: image.sdf, version: image.version, + stretchX: image.stretchX, + stretchY: image.stretchY, + content: image.content, hasRenderCallback: Boolean(image.userImage && image.userImage.render) }; } else { diff --git a/src/shaders/symbol_icon.vertex.glsl b/src/shaders/symbol_icon.vertex.glsl index 056ce24e4d2..16ab111429c 100644 --- a/src/shaders/symbol_icon.vertex.glsl +++ b/src/shaders/symbol_icon.vertex.glsl @@ -2,6 +2,7 @@ const float PI = 3.141592653589793; attribute vec4 a_pos_offset; attribute vec4 a_data; +attribute vec4 a_pixeloffset; attribute vec3 a_projected_pos; attribute float a_fade_opacity; @@ -39,6 +40,9 @@ void main() { vec2 a_size = a_data.zw; float a_size_min = floor(a_size[0] * 0.5); + vec2 a_pxoffset = a_pixeloffset.xy; + vec2 a_minFontScale = a_pixeloffset.zw / 256.0; + highp float segment_angle = -a_projected_pos[2]; float size; @@ -81,7 +85,7 @@ void main() { mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0); - gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale), 0.0, 1.0); + gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * max(a_minFontScale, fontScale) + a_pxoffset / 16.0), 0.0, 1.0); v_tex = a_tex / u_texsize; vec2 fade_opacity = unpack_opacity(a_fade_opacity); diff --git a/src/shaders/symbol_sdf.vertex.glsl b/src/shaders/symbol_sdf.vertex.glsl index 6c9ef11f833..71ccf3c81d7 100644 --- a/src/shaders/symbol_sdf.vertex.glsl +++ b/src/shaders/symbol_sdf.vertex.glsl @@ -2,6 +2,7 @@ const float PI = 3.141592653589793; attribute vec4 a_pos_offset; attribute vec4 a_data; +attribute vec4 a_pixeloffset; attribute vec3 a_projected_pos; attribute float a_fade_opacity; @@ -51,6 +52,8 @@ void main() { vec2 a_size = a_data.zw; float a_size_min = floor(a_size[0] * 0.5); + vec2 a_pxoffset = a_pixeloffset.xy; + highp float segment_angle = -a_projected_pos[2]; float size; @@ -100,7 +103,7 @@ void main() { mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos); vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0); - gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale), 0.0, 1.0); + gl_Position = u_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 32.0 * fontScale + a_pxoffset), 0.0, 1.0); float gamma_scale = gl_Position.w; vec2 fade_opacity = unpack_opacity(a_fade_opacity); diff --git a/src/style/load_sprite.js b/src/style/load_sprite.js index 11f5eb2e25e..6e8a65443fb 100644 --- a/src/style/load_sprite.js +++ b/src/style/load_sprite.js @@ -42,10 +42,10 @@ export default function(baseURL: string, const result = {}; for (const id in json) { - const {width, height, x, y, sdf, pixelRatio} = json[id]; + const {width, height, x, y, sdf, pixelRatio, stretchX, stretchY, content} = json[id]; const data = new RGBAImage({width, height}); RGBAImage.copy(imageData, data, {x, y}, {x: 0, y: 0}, {width, height}); - result[id] = {data, pixelRatio, sdf}; + result[id] = {data, pixelRatio, sdf, stretchX, stretchY, content}; } callback(null, result); diff --git a/src/style/style_image.js b/src/style/style_image.js index fdb62515301..77d1d3303a1 100644 --- a/src/style/style_image.js +++ b/src/style/style_image.js @@ -8,6 +8,9 @@ export type StyleImage = { data: RGBAImage, pixelRatio: number, sdf: boolean, + stretchX: any, + stretchY: any, + content: any, version: number, hasRenderCallback?: boolean, userImage?: StyleImageInterface diff --git a/src/symbol/quads.js b/src/symbol/quads.js index c30ea9a931f..2c3d6423167 100644 --- a/src/symbol/quads.js +++ b/src/symbol/quads.js @@ -37,12 +37,21 @@ export type SymbolQuad = { w: number, h: number }, + pixelOffsetTL: Point, + pixelOffsetBR: Point, writingMode: any | void, glyphOffset: [number, number], sectionIndex: number, - isSDF: boolean + isSDF: boolean, + minFontScaleX: number, + minFontScaleY: number }; +// If you have a 10px icon that isn't perfectly aligned to the pixel grid it will cover 11 actual +// pixels. The quad needs to be padded to account for this, otherwise they'll look slightly clipped +// on one edge in some cases. +const border = IMAGE_PADDING; + /** * Create the quads used for rendering an icon. * @private @@ -51,46 +60,158 @@ export function getIconQuads( shapedIcon: PositionedIcon, iconRotate: number, isSDFIcon: boolean): Array { - const image = shapedIcon.image; + const quads = []; - // If you have a 10px icon that isn't perfectly aligned to the pixel grid it will cover 11 actual - // pixels. The quad needs to be padded to account for this, otherwise they'll look slightly clipped - // on one edge in some cases. - const border = IMAGE_PADDING; + const image = shapedIcon.image; + const pixelRatio = image.pixelRatio; + const imageWidth = image.paddedRect.w - 2 * border; + const imageHeight = image.paddedRect.h - 2 * border; - // Expand the box to respect the 1 pixel border in the atlas image. We're using `image.paddedRect - border` - // instead of image.displaySize because we only pad with one pixel for retina images as well, and the - // displaySize uses the logical dimensions, not the physical pixel dimensions. const iconWidth = shapedIcon.right - shapedIcon.left; - const expandX = (iconWidth * image.paddedRect.w / (image.paddedRect.w - 2 * border) - iconWidth) / 2; - const left = shapedIcon.left - expandX; - const right = shapedIcon.right + expandX; - const iconHeight = shapedIcon.bottom - shapedIcon.top; - const expandY = (iconHeight * image.paddedRect.h / (image.paddedRect.h - 2 * border) - iconHeight) / 2; - const top = shapedIcon.top - expandY; - const bottom = shapedIcon.bottom + expandY; - - const tl = new Point(left, top); - const tr = new Point(right, top); - const br = new Point(right, bottom); - const bl = new Point(left, bottom); - - const angle = iconRotate * Math.PI / 180; - - if (angle) { - const sin = Math.sin(angle), - cos = Math.cos(angle), - matrix = [cos, -sin, sin, cos]; - - tl._matMult(matrix); - tr._matMult(matrix); - bl._matMult(matrix); - br._matMult(matrix); + + const stretchX = image.stretchX || [[0, imageWidth]]; + const stretchY = image.stretchY || [[0, imageHeight]]; + + const reduceRanges = (sum, range) => sum + range[1] - range[0]; + const stretchWidth = stretchX.reduce(reduceRanges, 0); + const stretchHeight = stretchY.reduce(reduceRanges, 0); + const fixedWidth = imageWidth - stretchWidth; + const fixedHeight = imageHeight - stretchHeight; + + let stretchOffsetX = 0; + let stretchContentWidth = stretchWidth; + let stretchOffsetY = 0; + let stretchContentHeight = stretchHeight; + let fixedOffsetX = 0; + let fixedContentWidth = fixedWidth; + let fixedOffsetY = 0; + let fixedContentHeight = fixedHeight; + + if (image.content) { + const content = image.content; + stretchOffsetX = sumWithinRange(stretchX, 0, content[0]); + stretchOffsetY = sumWithinRange(stretchY, 0, content[1]); + stretchContentWidth = sumWithinRange(stretchX, content[0], content[2]); + stretchContentHeight = sumWithinRange(stretchY, content[1], content[3]); + fixedOffsetX = content[0] - stretchOffsetX; + fixedOffsetY = content[1] - stretchOffsetY; + fixedContentWidth = content[2] - content[0] - stretchContentWidth; + fixedContentHeight = content[3] - content[1] - stretchContentHeight; + } + + const makeBox = (left, top, right, bottom) => { + + const leftEm = getEmOffset(left.stretch - stretchOffsetX, stretchContentWidth, iconWidth, shapedIcon.left); + const leftPx = getPxOffset(left.fixed - fixedOffsetX, fixedContentWidth, left.stretch, stretchWidth); + + const topEm = getEmOffset(top.stretch - stretchOffsetY, stretchContentHeight, iconHeight, shapedIcon.top); + const topPx = getPxOffset(top.fixed - fixedOffsetY, fixedContentHeight, top.stretch, stretchHeight); + + const rightEm = getEmOffset(right.stretch - stretchOffsetX, stretchContentWidth, iconWidth, shapedIcon.left); + const rightPx = getPxOffset(right.fixed - fixedOffsetX, fixedContentWidth, right.stretch, stretchWidth); + + const bottomEm = getEmOffset(bottom.stretch - stretchOffsetY, stretchContentHeight, iconHeight, shapedIcon.top); + const bottomPx = getPxOffset(bottom.fixed - fixedOffsetY, fixedContentHeight, bottom.stretch, stretchHeight); + + const tl = new Point(leftEm, topEm); + const tr = new Point(rightEm, topEm); + const br = new Point(rightEm, bottomEm); + const bl = new Point(leftEm, bottomEm); + const pixelOffsetTL = new Point(leftPx / pixelRatio, topPx / pixelRatio); + const pixelOffsetBR = new Point(rightPx / pixelRatio, bottomPx / pixelRatio); + + const angle = iconRotate * Math.PI / 180; + + if (angle) { + const sin = Math.sin(angle), + cos = Math.cos(angle), + matrix = [cos, -sin, sin, cos]; + + tl._matMult(matrix); + tr._matMult(matrix); + bl._matMult(matrix); + br._matMult(matrix); + } + + const x1 = left.stretch + left.fixed; + const x2 = right.stretch + right.fixed; + const y1 = top.stretch + top.fixed; + const y2 = bottom.stretch + bottom.fixed; + + const subRect = { + x: image.paddedRect.x + border + x1, + y: image.paddedRect.y + border + y1, + w: x2 - x1, + h: y2 - y1 + }; + + const minFontScaleX = fixedContentWidth / pixelRatio / iconWidth; + const minFontScaleY = fixedContentHeight / pixelRatio / iconHeight; + + // Icon quad is padded, so texture coordinates also need to be padded. + 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) { + quads.push(makeBox( + {fixed: 0, stretch: -1}, + {fixed: 0, stretch: -1}, + {fixed: 0, stretch: imageWidth + 1}, + {fixed: 0, stretch: imageHeight + 1})); + } else { + const xCuts = stretchZonesToCuts(stretchX, fixedWidth, stretchWidth); + const yCuts = stretchZonesToCuts(stretchY, fixedHeight, stretchHeight); + + for (let xi = 0; xi < xCuts.length - 1; xi++) { + const x1 = xCuts[xi]; + const x2 = xCuts[xi + 1]; + for (let yi = 0; yi < yCuts.length - 1; yi++) { + const y1 = yCuts[yi]; + const y2 = yCuts[yi + 1]; + quads.push(makeBox(x1, y1, x2, y2)); + } + } + } + + return quads; +} + +function sumWithinRange(ranges, min, max) { + let sum = 0; + for (const range of ranges) { + sum += Math.max(min, Math.min(max, range[1])) - Math.max(min, Math.min(max, range[0])); + } + return sum; +} + +function stretchZonesToCuts(stretchZones, fixedSize, stretchSize) { + const cuts = [{fixed: -border, stretch: 0}]; + + for (const [c1, c2] of stretchZones) { + const last = cuts[cuts.length - 1]; + cuts.push({ + fixed: c1 - last.stretch, + stretch: last.stretch + }); + cuts.push({ + fixed: c1 - last.stretch, + stretch: last.stretch + (c2 - c1) + }); } + cuts.push({ + fixed: fixedSize + border, + stretch: stretchSize + }); + return cuts; +} + +function getEmOffset(stretchOffset, stretchSize, iconSize, iconOffset) { + return stretchOffset / stretchSize * iconSize + iconOffset; +} - // Icon quad is padded, so texture coordinates also need to be padded. - return [{tl, tr, bl, br, tex: image.paddedRect, writingMode: undefined, glyphOffset: [0, 0], sectionIndex: 0, isSDF: isSDFIcon}]; +function getPxOffset(fixedOffset, fixedSize, stretchOffset, stretchSize) { + return fixedOffset - fixedSize * stretchOffset / stretchSize; } /** @@ -200,7 +321,11 @@ export function getGlyphQuads(anchor: Anchor, br._matMult(matrix); } - quads.push({tl, tr, bl, br, tex: textureRect, writingMode: shaping.writingMode, glyphOffset, sectionIndex: positionedGlyph.sectionIndex, isSDF}); + const pixelOffsetTL = new Point(0, 0); + const pixelOffsetBR = new Point(0, 0); + const minFontScaleX = 0; + const minFontScaleY = 0; + quads.push({tl, tr, bl, br, tex: textureRect, writingMode: shaping.writingMode, glyphOffset, sectionIndex: positionedGlyph.sectionIndex, isSDF, pixelOffsetTL, pixelOffsetBR, minFontScaleX, minFontScaleY}); } } diff --git a/src/ui/map.js b/src/ui/map.js index 8bd87bb11da..ea4a8573e86 100755 --- a/src/ui/map.js +++ b/src/ui/map.js @@ -1409,13 +1409,13 @@ class Map extends Camera { */ addImage(id: string, image: HTMLImageElement | ImageData | {width: number, height: number, data: Uint8Array | Uint8ClampedArray} | StyleImageInterface, - {pixelRatio = 1, sdf = false}: {pixelRatio?: number, sdf?: boolean} = {}) { + {pixelRatio = 1, sdf = false, stretchX, stretchY, content}: {pixelRatio?: number, sdf?: boolean, stretchX?: Array>, stretchY?: Array>, content?: Array} = {}) { const version = 0; if (image instanceof HTMLImageElement) { const {width, height, data} = browser.getImageData(image); - this.style.addImage(id, {data: new RGBAImage({width, height}, data), pixelRatio, sdf, version}); + this.style.addImage(id, {data: new RGBAImage({width, height}, data), pixelRatio, stretchX, stretchY, content, sdf, version}); } else if (image.width === undefined || image.height === undefined) { return this.fire(new ErrorEvent(new Error( 'Invalid arguments to map.addImage(). The second argument must be an `HTMLImageElement`, `ImageData`, ' + @@ -1427,6 +1427,9 @@ class Map extends Camera { this.style.addImage(id, { data: new RGBAImage({width, height}, new Uint8Array(data)), pixelRatio, + stretchX, + stretchY, + content, sdf, version, userImage diff --git a/test/integration/render-tests/icon-text-fit/stretch-fifteen-part/expected.png b/test/integration/render-tests/icon-text-fit/stretch-fifteen-part/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..e9a97643789b56ebed6bb2203666a93d7a9bc166 GIT binary patch literal 16247 zcmb8Wbx<5pyY(9afguEUx53@r273_Tj$jM z?)l@?t%8QB>7jSa-p_h|YZ0cbD24o<;QgC7Z;)lAB~*c*1HgAO2p-sGEcN5Rc_Sh$ zBO#{l33Jqi;QQxl{q|+{;qq>2XxTjU2od@V{WnQap7tNj@&>nDX>U?$u-e4m*t^52HCJA&ZuwV3d&!ByM-3| z>l_yoHtAF|#FT54-UCAEQ2$=bsz+i>sbw)y^HCgklE-&stQi!1beVg5|8CvX^=VjU z`fe<#U6#+RAT!)pwWcqaR_UY(Y#8KlxpmV!m%=c6P~>lrIVsh}nv{k6UlLLl>&}hJ zdOyF;tC74F*ez`t%NH20JCmN9o;m z01lq|dT_m;1R9rYpZBi*aGezYG$z$(&?V2l9CP=c*Etr&36k0=aGr&FzEu=xmk(T= z4(}zBayVzB9L%^i^rhT!3sP)ox?A_*YV#@z&ao{wHHlBMrqhIcoS#Y++#xyoYxY~1 zAfyI$blZO2wKoF~S(9CD*N9WQ)JAaNoZ}@hER*I|1QMu&{?CG~f09&&7D_2 z|ETo1D0i`+p9_R==sYuKK3OeJQ1t)kc?9JWbBkJ;;=%w_PJ<)L=&n!& zb|NWh9WIh0Nx8E8q#Em7Uf^YiP%axWD}l2-zlh?KSFB@K7BWDE3AgS1j@LEr1raS< z{>F$1DJ3vYktRQi$KnrH<|1XmVv(G-;a!~XUUrzF9F~0RD@;>XG<|&V+vj`i;*s?~ z_f=)bqT!{M7kutx@6?TCly*JN1aqzDxWMHVQkWNoO8)46V%^(P!IYJi$`Ud%f#0M0 zRZ?_E^W)^>E}ec7i}l*h%ia~}VIXo4ziA{K_&2uCFfu}QOXq|eS zs+Ct=Q-f);3rnxSWd|RVqx44hHBkxa`4Ll-?ECE#b3>6*N7+&pRP;tJ5V*2n1{!yr z*g~Qy;3-zK`+I>4fcGs3JKhM54ys=lAI@`j-y#!EI*way7_poViH%kSmWXGMW3Egq z=lX`Sh(oEK@B3tk%w%xV@sL19d@+!>8W&4$8NUzh+$TBl#u#!3P%D^O ziNV}*mC9(VhVWaR<%F*0fnHJJ+?>v)k(-RbIr{qm{y!ssuo%=5DtmOW^!%fQiUYa_ zr)EI|vKcXq_@J4;Dr5WMjdK$#GEy-^Vbr+gatnMjM}78*clHJt9MiT?WRj2?IaQ6; zsJ`S)+VC`Vo!Keek8Jg}5}X1yL=`NjX6|3JQeqm!35V>l$t?zgDS@JpW=8 zMgB@z$vmMp&=0BF6AGE5+CQkG;(7RV^cO20gL)#z zCiG+daYZmFSVA)~j0UHu{?~$-h9#=MMn9RHXC)F|wi~jkiv#&@3@K&35l83xYAUOy zI>HEwIDGT1a4f>h`XlfsiL9q z?_72MCaRKVKLRc2PfzK;WS;X3`J6Lk=$c>9bEHho*$z`PndqAcXNtR%NV7}>Yz+jR zAVaUe6wvRDgQh3OQ+ut5LyhC2AZB`+O<8AloV-Ia=vw#Z(~5#NZ_2VAN+G_OL~^yg z2$ZApLklH49wufH0l#-W5*BgnX79t!H_;#zo%^5jD!eJvcWBnUT#%@B&`eeENNlKS z7NBUpfo0x&8tnuftKx=c^8-d|O(S~Qnm@6g5`o8BzE7I52v2fLPs+jPu;s4HhwDgW zSK=(7P4Fui%OtO^+3DN`jG6|wMm91tTB72rHGLTfH&`E%e>T9e|#8$jgb z(4Mq1kG;LJw*t7gn_blY9^cW)*A|Q?<)tHy5-v3fbQLF-+`~aGL}D#flbdd6u^E0$ z92FUR=Qipd-h6-7wnjOKZAA{(c9EuThZ4!*_FJN-mm`bHKa6Te4q8zr_7cgN4m%+P zORuv}P4a2{B$&V#*+5FvtSqjxKq8L*T;sB`4o@RcPAvV_-^GoZCnlOo)cp~rV^yKC zJZ^7*(R)~?BmNNQIXdU#IA!N#{>3L5LXqW9{n-ol{y&<(YB>-@kJ6&kQ#rk#9eKe< z-{BQT%%_1g&-FbP?_kzkRaHi2^QNdtH60C=^GxlRP%&Ba13QHe&nkavAW`KTFF&Z@ zTaGrIZZ`E53}|5{%x8=x?hu{jS`c9P7DgiL@b??}NX9j5#~>qRXZ1djy<@Gf53xgv zdu&HTGP;umj@d_yA*-4=o^wL8qOqbzeT0Bgj&E4Z`9H5!fg_r*Y7a`MeYEso;@Wjr zQ+?7t$&L-I>i*@RS=Zi{&?vju z>?Ti?i`5%Bk2U%qtqH5#DJl)O*YbRZDRA?c`C_RwO5*Ri+a_h-A}2WX@E#8o7SjzV z&ONIFnq72jxlKUAWYYR!zkDG6hymxR5j94FErStBY|=%G6a? z9mJqoQPISo5U+`9Zbt$<31RPa;-K+h{9u!vgzu~aK$(JjYH31mEY7-1bAPrRIn~bp zae4d+wf*3&L9}iJco6Q-;f#cYZ-~1kE^3nE+Sg10HvG}81Sto8M^U;$xKtz02%zXy zg9R06?c8}vA39|9#i;@+NJF?^LV?{vYtxrSf41e2E?Stx!u`T_)M-1Ls0j6MZ}`jr zgF5Q{?dDgfd91@YWyz1xZjRmXuvo5VpQFW|kF=S*jMIObqG-IIB^3LlgGL7LN}_ac zpYRDOP8Y$bGBi1Y_ZRWaAsT`DKhBsA*$rfFnQ)~8C)J)s=lfFT^;j+=&!x5&FX!xz zcRu>2DmTx1^QawbdNUX~(&a7-eCiAkB7N%Tb~IW^vPJ8Js) zNTekyGcpctbX<2RZ2FjN%wam5h~@zh%cVbJ|$?+ozKeJ299vI`H5hc z$Y24GZQ<;LAGkw?w~T@lgc_ECnt@{>g~7`Bccg+-;Bbha*VP2KyRHxI-#pdLcWZ)H zlr}k;J9NbqQu7-$4pe#BwG|n}RO~Q0<9bPqwSA{ettTk|=0VeB?iTZ3ccjf zZ3^fd!pIip#;mJm%8yMow<;2XD4jTvHa}y!n|T%ye{F(!L)bwqFRLTIT9OX>R6@KbpQBR<%U|*ZfTeSA47eGYUsBv&CU{ zBd_;o)P91++rImHqR)=!i&SaaA249IZyrFg=I>R}F)!4)~gu$I3xlB7br`KOPB`%N86Z)NRy2@DoMBV+waQq}VgLhWBivxjR z-r#sGMy@_J&cgKjqd#d&RdB4b8SF1UKZ0;DXlCb{V-5>mCpRCYq=dkdnTE(&(^`~q zXkbG=ux(GZW_yhPmFS*&*g3yB5Lx?!RDZGK?zIiyrwjIRV(VP4XB9xVpib~@cA#qy ztE{?V@jpX^y`UF1{Np^?e%s)a+1LNO;P(7|BI=o`&tULAD`=L5)BA&1}_?NKMd^w zC6D-p{~UAvd~l<@SQA5MdTL4*&Dk=iwy4mV`9UCl4FZWp<9RPL@JQqA^@&fdIr_~< zHq!`ciUF${^tCIu`sT8T`Ya(c$+SHtpk@A>c)D>ZFyFRY%=v?;d*A-Iy~4VQZ`oKz z;W1ofWFss4*vKcIT|{!xS?O=YquWJ}_*f~GlG7SrEf_aAw4O;4x)fu}?s!!nF*4kr zQr*mnGmnqRIff(*M|SW=imYDy8nOc-1Cmv*X!~l}@a4`rbT+8|p6#)F`X?o0Wkz5B z{Z$#cOi4gRs~sZ#t!n+sADZG;nC0tsfOh{nZ0T7p?`hX4<+7^FP;mv@N@p^pE+$hG zHad(KX5bmomBQC>6L`~=y3T`1$d$MviTo?OI~2*v^ zwtitv#NeN{a8L1eD!yn^SJ(30E&;0Q!R5rh%Dmy}R!BY*QHh5Mm$YwyBs(B=q536F zzR2Gb()dG{Ds0do)QLvDTuVw(~dA6oSB+;kPF#%WxiaZN^v**QT(d=yZ@GqWuFyY86X z{W;81d&lHH9!(&=8Q&dP8|urNq8REa?#`1x$%jkSjfxhi6b+ZF&N#6^q_->#hkliV9g^BJXOQ>E>%8{|n}xEOcvg0On!eMdmgGN6q@d&Y1H_a9;S*4)Y4 zeX)d=MLasH-(v8;h}DvzJ<`xuuRxd6gL;XEYa)C9S^5`cd8N4%Wce#{H#eKh6D^Lp zt1NEkx6~t$cUp{s0TEtmdP>7!MJt|!149x@*{ z06~)lg#mp)laQTs{1>I5-)k4EE&nvy{At3?whWtnAc8zm;a#+H+Q=BM?V4$0jC%~J z25dcr=NDoCb})mRtOtkx-4en1t^UNzXEf%Leq@NS6d5~W@DBuIL1S-~INg?DBMF@t z(yL6^dM9$!TjO{f279XyB{Hz#CXO|%9q-R>UBQS3f4Gesz!QtN=!QlT*KSrVIf18( zIFv|VX2{6pf}R0=;|PLhK{6%6-zMb=^9&R$BQ*_{mMZc=crf{8wWkI!)x)P}pp#bp-?jG?rZpzq-U7#a1C}AXoqavh zZocYmZ03o@%E|@uLTi~cK6_f>Wk4{P?%&Ryir1YdL%C9;+VXsGfAuEU7&)8q+is3( zi=}V6h-VMW6^qw)pBBf_ekkxMB+5_=Ec7hN3q;gW*5aFcFV<|5A7r3RbjDIwoioe8@uOu$Cojdm< z8iTJ>-F3doq}i9NAMPKbWNOp@EB32fs$K-Ooa)OKdBVVGdvYA#FvzhbW3J}u!Il3r zXpTNdGMQ`v%mL`I#|mj2vw5~bj9m56;g(9&sVPl}p?neTN(!>NGx~c{RqJhmOnUv0 zqH@lLY%{$RCbPm(%0#W1y9EJ_Hs?HSh0t5jyI`=DwTQUiB|1>qSvgJ7(UUy|SD1m; zXmUm83)n1DlF*L#{FcjGJq!DRAT`Ni7ic6?Q>D$9|O^izTb}pef2SvHxpJPFvPs=vsxA}piF@VC9 zE!411F$2fQcy;ax0PcXecT{F^k?I4e1(_1}n4H#?5;H)gLpozYu>OLaKZ)|IoJ15V zi}A9(xaw?w?|)u*-PUaqItF+?cQC0wLZe}K@qwVmpH2-v6~Pv=C>a@aIImyJ>VNGE z3oGHs!5?JdfK!~o7=PIKBFhX}7oTv;0v-@ikZP!WVf!733fpE-HbbhUQC7h7N}aF; zC1ylsy`IvvmHq&cxZ6MIqn^Q+ZtY+NGDb zq8w%JURytYcAy+(CXH~(yHzy6;G3k*whu_|OEyi^a-g6wMc>_jRC6`MnPs|VGK}y8 zH5%qujCPl8xN~c`$9EJ)yT=S+B2CA^y~HR6P8w~yXmxz+#gL+np!>RU!Q%@5W&AX+ z$rc%y@=d9F1nDtAZ=MaEi-X<+cZoaE!$cG8-%b`qC7yqqaCrK|P1EtGJ;He{Wvn@- zSb7l!v}eX8dn@ipB=0jnvLfl?82@d5DfbH9;rFWHVTK&yp;R~|v6dnXR=?k~_+0LK=CQ8JJ`(`$#5r)L z5mcCW2lD_Mfsv z!91wNTAgtgC1T@CV>$2Nt&K4KUC;Bcxljy1aSMb4!}up=`36fE3JiPCor_)YkieO} zs-VpR6M3|swt58)G1HQ32+sAogtv{p7AFMNMlwALp_uBtb1?}3Lq_T8Z}S;*Kl=mp|DIx) z)r5=PEvyfoJ5U`+R+p+2iWc5BmE z5R-`@l=rQ`f~Q^0mI_=fuFY+M20BFX_YyawUP`!7#&DI=TE0YRCAWzw-^^iZd-&y~ zGb1z}%Np$`HO8g!X9A8*rOL&*$D}AOf!t`!W#AJ_Tl^VkZcFhW^oGrHSNDeV(CfQL z2MZDaDb(xz)-n2d?sajT!Fzg*ebh)V*s{62jXLUU)m(Kb2Sp>i1^tJ(Jj-KdXX6x6 z>)suoovNixbU(uSFJy3ELT{AJ3b!%7_a7D@kM1tTRSJ45Z>v9Q$m5Fu-q9_M&KJ^- z{-J~bN~5P_shW?^L7aEIB6Z{INl-(lFK`1yS6Jq)f6ojOqAZU?wi5bXb}atBnN$^8 ztw2$Z}whM0GP_&FkMUrZb$-2?&Z5-55UFZ^Tt$DGNSj6 zMTrT0*>C@{+PgbhbnB&1mW!NaGoo~%@o@Q1v$K;{FVAl`^Qhbf!&F5(lQ?9V)&;Pb zvKQ3GTd}j`?W(Bg$fE++=S_8ZFTGdh?>*c}mwMt7d{Wu{QNp@gwPVetlHpP)_}QaV z2YC5g7pxAg@*3?dTRpEGIpAfCzSTI1|Ai|OvY;|@8~lv26tKqA2@-|}+A(h@0QJz* zypNz@V;}pSXvT1=;qG*Ht5`SXjEDwtJPy(=tzsz7ZT`C2@#yl^BDzm#XwXusFSc&) zvO@5V=frE1B&hu&soK%#O7=b>GgU0Gdp>M>o9xg07>NOkHO&+)=4Zf`i|KN(5abCC z-bJ|>*pYI4o*Rs&j^eN*smoUwk!i%Vj&HX2`OctQHL9C?dD<6PD_F3V}s&b3QEf6FI_H8UA+K}m9H~${~Gm1 zrgI~cmRsG`dGA)SO854iJT($bcYXgwrBA?E%V@x6XDxAJj!-Yp*l$A=p35U`nu0!O zx)0%B-YBT4Xo%!;5|b<`N3B5^Qp`E zyeKmrreC2>v`)HJ&2 zK>_s3t)YH5r<=E;%%oHzVe#bjqCrcwXwn)y_o#ggf|J3 zL4#KCEW7yTuN|;5SgfR0oZ=SG*JWJD=dVcfgG?2HH}*oBc$;5dbYK|@OUx;MC>XA+ zYC8Y(UgvZE;_GDuXiQl7&Pq=tT?C(}Edq`EV{+bt{j+5NB}#Q)PW7-P#)ofJz|bZda|#T-T8U>d92;ZmwGQVm9gIUQ>?m1*oC; zXGYcar?>WzbK<%AL>iYWl?I4MV5dC~{A?}2b_8j+zL$&)4n1wo6P>-%f}(BvN&udw z;EH0lh!AQ?|MBeY)4IJ`F4~%w5ZvvfaLctwubp_^?Hf#1gp;sR{pOp!#Ab}?k9*8_&f&{!8vHvDh$v0AR32QG;mNi}V#OQ##r zh|^?B8bPtQw7~kzsX%yrmKo{*l%4yF$K9N~?tF|h19KjM&wS&XR~U{(o`lni0a3=a z7Q#k&kGy5?Urwav0*+AIRFAp^cTmAp@&$ul;Us?4Wh>pQOG=ljmmYg|fIVujgGDkwe7K3oWkuB{manx0W-Ij`>S5T$Y!C>((&pjSU8U)l}+%mNAuUTR@)34dK^dUD)vhiRp0~3Q2Yr z#IG?X6Au&TBSqrya?toGxYI0h%OqXj|Jk!9%o3Fc)A8Zf^J`yfXBW+e`aHe*jGW>< zq{{Fg4c5GTNzvbgw#NgB&#i40EQecFi07RAPX%+xP*n{U;BLSGok6_v-e`3TqN-cg zXp;V;ryP@FPTx0P4nrc`ewxCc#w>182&}X?JGGgMhv+6Y$ZF#U32+MA8hF$m$->km~pf><^t|+cMLWq1B(I zE!B<~UY7r&C#9f;ig2i(Y3rVQ_$pWZSvk^_WTmvQH5wK{czpl7fpd32tj$l&Kp$M- zIIa+0R`iAb#%w*n$FVW_R2C&s4pXeP9aV?Gt8$MDMT;bGrvySCWx3n5t*B4okW0P= zp;vS@A224<+OOnY5Z8}W#3A^1gr*RHjes#sXZ#kQu6}PAFg$rRFDOC}^lb$W*KmCf zfbMU{d|@z(%TyKolSi;?awBEJHL0RNr+`X%l7o}CB`o}%vfk_%Dp2vj07J<-cU@{PJJpV`NdV*k*niw~ubB08n~H;JMwa%AXgomH&_VDz zzE{o51My#$Dhlziko*Q^3rJ!3s@6?tr8p3xo#L;b{(5782quG zr2D%z2< zYg}X^{#F4?o=Bb9S}wlK(fE%9Oj8RLcQD8F@hgeg_?LTtW|v$VVeI+xuSO})-$*oHQHupZoKbJAj@76xBlFlh>gaaZMoT)%&=t`D#vN^cewHMl z0h8?2^)#A7dqvTn2^j#QRS1>s#vPE(?y9Mv(w1j~>y_B4G4h64u7ZENgZ~oAhzNiH z$=(e79K0{fw9^^AMBO8Ut3~c zUYun^t5x9}$-eMoP8i$AY#$R{;-trsbXrL<{fbsLaZY%jM{7|O?GyOj_kkZ?lGW)C zu`kj8$Si(P?s_l7`sS4ziefpkVWjB(zh1MV{r79VNZ@_oH7U*io^=!k7$s~CV(L3A zSR^PKlW+K53kj+%j3i8J;716E)EHM8bU0j;WA`w>^!qquN%;A?766T2pn-Y1!5GB!%qZUAbtj^X1Xgi^?dl6-aL=_$?e|K`rrM641wSb&w z9G(bDFoxK~yo-Q}28-CKPD>2|6=0#7N#Fw{zx~J0oZR}>Lwr_ob&U}dcGmf3cO*|$1@lEp+hY+ zCGkV22%w)T8jZyIv$q96^hC%2;q>Gd2AN5!_7lb{+Cdtsn~%bfGI zD0m1K2(^6eiP~PcV*urhaI6=n`8@i6h`W-XyP zgjn#7$S39z6(T)Qhxmm|Iv!b`#1Ho+?3%>yD-ehX1IVA<@7X5z=j#2@>ix&Mk}o2p zpYw7TL(7759KH`&0GZ3an6@adX%gx+Ag|C?f4u1Fw@e!z(pbO@CTEonl1>-_WP7`y z7bqW-5n5(9*PkABGkIJgrNRh;%RTyuwStT2$|jA)Twm5=_lJj6Y*wR19~sC!BmwvW zdQr+RvY^*}NOcUXCjk7Csl%U};Y$MQ{13NeN~nBnnfLi?mPa!_RGtF3j)18Qi?wO{tG3>&{VcAi476wx)o<)$^arYs{@TioN~i1ZcPjPQ^0^{F8oz% zro_dQ&hAoqVQ2k#3I&M3b^-n5YXnw*xuK*ir2r~}hl~!b(^a#wEijyw3TqVYIa-&(BZ?9hMj>st4t?ebkI%C6S#-SPtRhA49vU~pG*zK>eas@M4*t56UqG!` z$P>YrOy!cZla^VXd&m#;6M#r0S=1SCZ?SK0tW6)GrBsWrgtF7(RAruX)J^TW!07Kv zpGVNYriBjn_~oo;1OPfY@@L-FZB}K~H+5>rEq1^Q$e-DFNG8fy*ncGs27}NbfV9aH4)CMY$GPN4m-R6CK?46QFoh^3y z2@R7qLEKMHfJZw4NxVI+K(xn%#p>y;f89}YXbz)+VL-t2 zve2>r0El6p$6tv<(f>)xbof$dDA(Ec*oH$e*m2Q5@P`bS0O>gtOIYBd;U_o4RgcTq z`Jwl2+e}=Fo&~5L!Bc#|$P%I_91_6CcM!wywYrg)UsDQAr?a`Nsj3Jr?9RV?Lw>6? zyI+!SSz=)8*V!7uCpjXvrqo|r#rf7kFUL4YGL@xIXuT@7@aDW zdLTUyXwlW|)-EoLM%<#M=VWXPq}nuK%ErOH`@jsuUCa_PfN)&i2)ov{1bN^jB2H1^ z!kp$z?|OpIfHbjWAQ)`laxLuLMuL(x*Lwm>$meK_fG{29>ve$!c)Y=AA5ziYwlbx^ zY3v7mPNq!|8yA* z(q$!(hZ{-trK&teZo67x0IG;SZ>n0(^8t3fA z;<%0moP0*~gTHLG|B38e#k;rsqE}O^7=QqFzV+p8S}I=G-!kUt%%xGTONTxyPRv-e zl#$ufN4n7HQ=`ih9=b}wuCEu0KeOG=vi4=L#*{uL!@(9>)5FBaqC+SWQGgDB5^lFw z2P<7qm>E}pwit%tRs{7u`Lz>1v7KveaTTEqsLoWLlix4ZJj|>WCPSsDDmR=1yB}Y` zgdPS060YBqizMWWVrpGAd#Sa{w6@z^XX3K0*xO38sl&r}u=viY@J=5ACLTPg>lA^Y zv+=e8g)mrQogG*x{$^X#tO3{Yrd{KU=yzBRVj;L!8k9DK8A;5R1gLSN`+^YpEY=vz zVpK0U1$&ks} zSocASak;M?SDEz;q#0){06(Dyj^V#Vb$*Jzugae|$GsS&`~w8Ixsr-OO~UP8SsHv} zAX4ZbS59G+rpvZe5^G3g2A~UTYkn9hU0F&e-toxWgdk7n*@Q>OYt&OX67$zV?47%x z`wp6XkA9PaBlZ#ZB?gB4aj!+PchIA$?tn2&6PA?B$jg99?T7Er(}2vzamlmbzL~ko zL87ZRxTP@hnBCd2hR3`+YREo+o70cTz;zY=RjhI4y*Z@@7an?~I55&-L5fURj%B5YAoQISU{ zD5@p!dRQ(*KOh8XyU7Zby3D7IK>ub_r^yUp&B{nDEubixU^sT7Td=ZY#8ZJ?wZGdm ze3J1wEuWpfvc)>~eAl-Vv${Ji5cLt=_o_&hJCUz>#WnlOL!;g1MR3aCx0sZ(2M+4f zq^fpqc@71)yUGgdM{wC^DlM5w1kjCd+^)Cy8LW)v!%^T;eYPrIYXRJx}^jzi4ZXvO3L7_1{iryW1o}5**HSav9s9(Zo zg1KoCbFM7N4NQzhoHfb14ElnrxEuRbboQmL)80UwSwDZQc(c9~E}u>@>V!H;QCZ_> z7+2Iyo$_ff<>T$yvLFL|YFJ@vs*=fD|JFXsS%kU9=FGzx)DD}CbNGSOG;Xizk&)<$ z=@&+P1-F~;Wtun`ko9~8;p{_Xr+*tCI`&b|qcHO$N2#<=rb}IQWr`FGNEU~V9?dha z-|$p_lL)VE28aC!D+0MQ@_7DZDWmn!ZO*pR)0JIaLtmLF{{Jf4^`zaIe zgr4BD?!ay|fACcyN|7lYe?O&dsk@6U>j>dGoOmuTh;h7J9g``gakqdsT0I8T0rN~S=82q&a_;Sw0mbE45Ku@WmTKII|9 zn9v+oh)L*I1+{@)@kZY$LahKCjamxmP*Qkb5OkM07lhr>NJ5Tvkrocd|InKjR*V;( z-LqNNxmhL(3aRikNxmC^(}69;)70p))?jr_@&%qmT0yu}#=g&P^%Dz44<&RRQR@6( z#?_>RhyD2NZn)8u($oq0H8ohV!d=*~DC4E`X@j~qtiyegOTt6+Y_wLS-0mz?_j&OR zold&)K)&wC;#z~nWww|BzYYVW!Mjcia-JeqdZz9fq^+al0&KSQUlpi^tLQ42oMI2H zn!cLucnuASDu{GLEN3g1B&4}DAZWr_E$25DAfU7Ng8&g$R^`}cJ!}sX(zdW1w z%?3gNvA9Zt@`8N*CS}9++X`=4?*bqto+d3_Uu8g|;H+!bb7plTDRx7Ed8E8rWW zAYOXdZ8@9;g1rZQK013o$0_qSi{u-02?X7;&5N>z1?l@~ z5t$ulAIb@YB{k`jjO_g*KU5dvh-Z*z%W|+1=er0(bUkAAql8K34F;Wa6gBy?$atrf zzOGk6R5+dah+$UDD6r+lTj+&g$JsapAeZ6#kqYkYtQS7iLHcX!cGHtsBHnI6oH_ZH1?BqRhZ=0bB9oftniyjGoZQpJBnpWN+Oe}^?kewMDP@!FPBhD4 zSSOG^nG-XY%QCl~Y;H1%*0)cl}6LVy)P!$ulSS zsO3QT=j>_jD7Z(m}fkj^)_aS{7g&AI|Wmw z+oUlcoSOs&)Ux1xW)TL=r;)>bqj-;D3d-}Hq8fy&K<_7H$+6x~0-LJ8a}o%_4sFnG zO$oozP$z!bz4o&Y`hKBd_8hg=@9|0Wdn?Q3CF3)RBWhal;X=@9w=g<)?Lm$;rtv9K z7S@L-&Mz%*kPvf~zy0mU7K8aj2ZfLWo8MQW;-BI}mof$x0xY0r&e4@g^sAMAfs=V~ zG%vAaSc0P+Bfb$c3Owh@Z#XONP+fo4*Ux19nlHpg;y^lK5}tb zFaFZ6T~cuOCX#4tt03#e@yA8%To0=4<_{PH^F)?Ifl_x}of2$oI?e(H_8jTyzd})E zpcDJEy!T>-{X@rGB-sa<8-M0aE9_gsDq@z-t@~)C_@=#rcB6%R<%$i~^sx0m}jQ&U#bT3d5QsV{z_VtX z$h71B18jH4=HjlVbMrGkRQXQam-LLbyOhgU=#c`oTz3##u8419S)ng#g-@7te*Aep zAv5~<%`H*5L9f-QTvL|$7Jux9!h6+q&H}1K!bh&$GcxY-F5(Q*u46{ZVesfcp&F6E z6)lS%$jP4q;!>N{i+A$*Gs90-)<=OIO3VUPC(h9^fxFWxGMcXz=xtzcL z_r{r;aaPa01L0gW(a+T`t%X)cPrC~byw4d6X8EvQM_<9$1tO=t z;8N9U$nrh0{^wlc5?^W+Z#C63p#cwJgBN#F4{01J-bK94Xx{$XQCxdsUkA<0E9LGq z+fo$}V~aop8R?e>cYNA61=gZolqfw2?VO!3)=aplSc^As78TYlF;g22+DwW|W9%2! zI>u-9Ldbh%Mrt7u#KS^u?EF$Mu9=?nQB`!Ae^8a1kAeZE(#&1?BJg?0f$~r-I-s+P zF0qvfs5~w7+9L;Fg*=70zzJ-w%fYT!z*hRp#KB)2Pzl< literal 0 HcmV?d00001 diff --git a/test/integration/render-tests/icon-text-fit/stretch-fifteen-part/style.json b/test/integration/render-tests/icon-text-fit/stretch-fifteen-part/style.json new file mode 100644 index 00000000000..f06d1490eeb --- /dev/null +++ b/test/integration/render-tests/icon-text-fit/stretch-fifteen-part/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": "ASDF", + "text-size": 20, + "text-anchor": "center", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "fifteen-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "left"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "fifteen-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-left"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "top-left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "fifteen-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "top", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "fifteen-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-right"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "top-right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "fifteen-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "right"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "fifteen-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-left"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "bottom-left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "fifteen-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "bottom", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "fifteen-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-right"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "bottom-right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "fifteen-part", + "icon-text-fit": "both", + "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-@2x/expected.png b/test/integration/render-tests/icon-text-fit/stretch-nine-part-@2x/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..fe56e368c016a06324a62f90b7bed3c029d413ee GIT binary patch literal 16173 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 literal 0 HcmV?d00001 diff --git a/test/integration/render-tests/icon-text-fit/stretch-nine-part-@2x/style.json b/test/integration/render-tests/icon-text-fit/stretch-nine-part-@2x/style.json new file mode 100644 index 00000000000..d7ebfbd8afc --- /dev/null +++ b/test/integration/render-tests/icon-text-fit/stretch-nine-part-@2x/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": "ASDF", + "text-size": 20, + "text-anchor": "center", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part-@2x", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "left"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part-@2x", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-left"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "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-@2x", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "top", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part-@2x", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-right"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "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-@2x", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "right"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part-@2x", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-left"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "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-@2x", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "bottom", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part-@2x", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-right"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "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-@2x", + "icon-text-fit": "both", + "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-content/expected.png b/test/integration/render-tests/icon-text-fit/stretch-nine-part-content/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..87b0ca1431c5d43a0e61a72ba964e499184174ab GIT binary patch literal 14999 zcmZ|01yq%7*e+<$A>ANImq>TRrbALfkOmd$6r{UD+6@8{(xEicB`pd_HzI-{Dj_lV z{^rcAf99;SmWaY;zx6!VeHGF7wUqI3sBx}cyN0i-qNod>2jL?f3j_YnSs0+Yc1_$| zRZ&jg=lYK>On+p!<+r^niLvRW9+PyNp}O=<7GLd}uFNb#totfhnl~Rev#1U{SRpxSmv#_rQFCuSDYDZc9m~`Fwo>WH{I4;#8tG76{bgLLgSW| znb*B1-+PNpEG^2~7;)Dh>AjrE-B`&r<;%I@Lu1fa*_5mp{q%3Z?bOM*sZARj|Ddw7 zdN|2n^BI9^Cc5O&hmRfl*&=<{zB*4$e+lZN?d)$u+PvAypP`}5p)6?Fk?ab#RE!Mk zrVXG^j$1}NF!a08IN#T@@XX_{;N;Sjik=_Yu3JOx%azwI4bLQHjZ~Opg*WzBT4gT8 z>yM`1c}%BJ=0$9!S&vUl8zc@ntX7QÙ}`H0sX*~ubY^jD83hfd7&;kEkHd3~=% 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 literal 0 HcmV?d00001 diff --git a/test/integration/render-tests/icon-text-fit/stretch-nine-part-content/style.json b/test/integration/render-tests/icon-text-fit/stretch-nine-part-content/style.json new file mode 100644 index 00000000000..f0babee1c58 --- /dev/null +++ b/test/integration/render-tests/icon-text-fit/stretch-nine-part-content/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": "ABC", + "text-size": 20, + "text-anchor": "center", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part-content", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "left"], + "layout": { + "text-field": "ABC", + "text-size": 20, + "text-anchor": "left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part-content", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-left"], + "layout": { + "text-field": "ABC", + "text-size": 20, + "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-content", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top"], + "layout": { + "text-field": "ABC", + "text-size": 20, + "text-anchor": "top", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part-content", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-right"], + "layout": { + "text-field": "ABC", + "text-size": 20, + "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-content", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "right"], + "layout": { + "text-field": "ABC", + "text-size": 20, + "text-anchor": "right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part-content", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-left"], + "layout": { + "text-field": "ABC", + "text-size": 20, + "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-content", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom"], + "layout": { + "text-field": "ABC", + "text-size": 20, + "text-anchor": "bottom", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "nine-part-content", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-right"], + "layout": { + "text-field": "ABC", + "text-size": 20, + "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-content", + "icon-text-fit": "both", + "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/expected.png b/test/integration/render-tests/icon-text-fit/stretch-nine-part/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..8a035589456cbb3067ac13a7abe685deb44d205c GIT binary patch literal 15797 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 Vq@;a2z@IkXLddJjq2Vur{|`^R`S<_; literal 0 HcmV?d00001 diff --git a/test/integration/render-tests/icon-text-fit/stretch-three-part/style.json b/test/integration/render-tests/icon-text-fit/stretch-three-part/style.json new file mode 100644 index 00000000000..30cebd99ce9 --- /dev/null +++ b/test/integration/render-tests/icon-text-fit/stretch-three-part/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": "ASDF", + "text-size": 20, + "text-anchor": "center", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "left"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-left"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "top-left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "top", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-right"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "top-right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "right"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-left"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "bottom-left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "bottom", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-right"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "bottom-right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "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-two-part/expected.png b/test/integration/render-tests/icon-text-fit/stretch-two-part/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..f218020df93878ec6629cdf4402fddf1c953b0a8 GIT binary patch literal 15115 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 literal 0 HcmV?d00001 diff --git a/test/integration/render-tests/icon-text-fit/stretch-two-part/style.json b/test/integration/render-tests/icon-text-fit/stretch-two-part/style.json new file mode 100644 index 00000000000..5c45313726d --- /dev/null +++ b/test/integration/render-tests/icon-text-fit/stretch-two-part/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": "ASDF", + "text-size": 20, + "text-anchor": "center", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "two-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "left"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "two-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-left"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "top-left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "two-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "top", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "two-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-right"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "top-right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "two-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "right"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "two-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-left"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "bottom-left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "two-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "bottom", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "two-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-right"], + "layout": { + "text-field": "ASDF", + "text-size": 20, + "text-anchor": "bottom-right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "two-part", + "icon-text-fit": "both", + "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-underscale/expected.png b/test/integration/render-tests/icon-text-fit/stretch-underscale/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..f6e32fca763a0fd5364577aa6152c122b02bb243 GIT binary patch literal 6089 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 literal 0 HcmV?d00001 diff --git a/test/integration/render-tests/icon-text-fit/stretch-underscale/style.json b/test/integration/render-tests/icon-text-fit/stretch-underscale/style.json new file mode 100644 index 00000000000..a658c727bc6 --- /dev/null +++ b/test/integration/render-tests/icon-text-fit/stretch-underscale/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": "A", + "text-size": 20, + "text-anchor": "center", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "left"], + "layout": { + "text-field": "A", + "text-size": 20, + "text-anchor": "left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-left"], + "layout": { + "text-field": "A", + "text-size": 20, + "text-anchor": "top-left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top"], + "layout": { + "text-field": "A", + "text-size": 20, + "text-anchor": "top", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-top-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "top-right"], + "layout": { + "text-field": "A", + "text-size": 20, + "text-anchor": "top-right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "right"], + "layout": { + "text-field": "A", + "text-size": 20, + "text-anchor": "right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-left", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-left"], + "layout": { + "text-field": "A", + "text-size": 20, + "text-anchor": "bottom-left", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom"], + "layout": { + "text-field": "A", + "text-size": 20, + "text-anchor": "bottom", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "icon-allow-overlap": true, + "icon-ignore-placement": true + } + }, + { + "id": "anchor-bottom-right", + "type": "symbol", + "source": "geojson", + "filter": ["==", "anchor", "bottom-right"], + "layout": { + "text-field": "A", + "text-size": 20, + "text-anchor": "bottom-right", + "text-font": [ "Open Sans Semibold", "Arial Unicode MS Bold" ], + "text-allow-overlap": true, + "text-ignore-placement": true, + "icon-image": "three-part", + "icon-text-fit": "both", + "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/sprites/stretch.json b/test/integration/sprites/stretch.json new file mode 100644 index 00000000000..35b03bec863 --- /dev/null +++ b/test/integration/sprites/stretch.json @@ -0,0 +1,61 @@ +{ + "nine-part": { + "x": 0, + "y": 0, + "width": 40, + "height": 40, + "pixelRatio": 1, + "stretchX": [[10, 30]], + "stretchY": [[10, 30]], + "sdf": false + }, + "nine-part-content": { + "x": 0, + "y": 0, + "width": 40, + "height": 40, + "pixelRatio": 2, + "stretchX": [[10, 30]], + "stretchY": [[10, 30]], + "sdf": false, + "content": [10, 10, 30, 30] + }, + "fifteen-part": { + "x": 50, + "y": 0, + "width": 70, + "height": 40, + "pixelRatio": 1, + "stretchX": [[10, 30], [40, 60]], + "stretchY": [[10, 30]], + "sdf": false + }, + "three-part": { + "x": 150, + "y": 0, + "width": 60, + "height": 10, + "pixelRatio": 1, + "stretchX": [[20, 40]], + "sdf": false + }, + "two-part": { + "x": 250, + "y": 0, + "width": 30, + "height": 10, + "pixelRatio": 1, + "stretchX": [[10, 20]], + "sdf": false + }, + "nine-part-@2x": { + "x": 300, + "y": 0, + "width": 80, + "height": 80, + "pixelRatio": 2, + "stretchX": [[20, 60]], + "stretchY": [[20, 60]], + "sdf": false + } +} diff --git a/test/integration/sprites/stretch.png b/test/integration/sprites/stretch.png new file mode 100644 index 0000000000000000000000000000000000000000..36685591c28f2dac8fad792c8512a0ee1e0c3cd0 GIT binary patch literal 437 zcmeAS@N?(olHy`uVBq!ia0y~yU=jkdqnMb1nlEI^7S-O<;Pfnj4m_n$;oAYUQb zBgmJ5p-PQ`p`nF=;TKS-;RORjsR0ASs{{rHs~HRo;stYd1=;{5cmjMvT$>91{jW9q z|NsBeNk@2!wIhMzj7i?^E=+0MH7P(2dx@v7EBj+^VJ;Tq{lVHAK%r%xE{-7?_uk$x z6d`YxwPBZNDRx7ern==FwxAeQ$k&8qfM$IUOC&t1Mlg>~Yyrdh1$M zR`M04KFfYL`-|plOYhq)J7V>qblL(SxG`O6Y4OUP+dQXFxwR`NTX-Qza7Or--KS@L z%v=s+|1duqUB6!h1pK>JR%^gP-TEI7u1;-&fk(eVT5rsJ#8&b^n(UO_QmvAUQh^kMk%6J5uA!l>p=F4nsg;3=m8qew0gz#^Yhrs2iiX_$l+3hB+!{`w SvA+P+z~JfX=d#Wzp$P!yWtz_b literal 0 HcmV?d00001 diff --git a/test/unit/symbol/quads.test.js b/test/unit/symbol/quads.test.js index f97a7959fd6..3c3135e7b63 100644 --- a/test/unit/symbol/quads.test.js +++ b/test/unit/symbol/quads.test.js @@ -24,7 +24,17 @@ test('getIconQuads', (t) => { writingMode: null, glyphOffset: [0, 0], isSDF: true, - sectionIndex: 0 + sectionIndex: 0, + minFontScaleX: 0, + minFontScaleY: 0, + pixelOffsetBR: { + x: 0, + y: 0 + }, + pixelOffsetTL: { + x: 0, + y: 0 + } }], 'icon-anchor: center'); t.deepEqual(getIconQuads({ @@ -42,7 +52,17 @@ test('getIconQuads', (t) => { writingMode: null, glyphOffset: [0, 0], isSDF: false, - sectionIndex: 0 + sectionIndex: 0, + minFontScaleX: 0, + minFontScaleY: 0, + pixelOffsetBR: { + x: 0, + y: 0 + }, + pixelOffsetTL: { + x: 0, + y: 0 + } }], 'icon-anchor: center icon, icon-scale: 2'); t.deepEqual(getIconQuads({ @@ -60,7 +80,17 @@ test('getIconQuads', (t) => { writingMode: null, glyphOffset: [0, 0], isSDF: false, - sectionIndex: 0 + sectionIndex: 0, + minFontScaleX: 0, + minFontScaleY: 0, + pixelOffsetBR: { + x: 0, + y: 0 + }, + pixelOffsetTL: { + x: 0, + y: 0 + } }], 'icon-anchor: top-right'); t.deepEqual(getIconQuads({ @@ -78,7 +108,17 @@ test('getIconQuads', (t) => { writingMode: null, glyphOffset: [0, 0], isSDF: false, - sectionIndex: 0 + sectionIndex: 0, + minFontScaleX: 0, + minFontScaleY: 0, + pixelOffsetBR: { + x: 0, + y: 0 + }, + pixelOffsetTL: { + x: 0, + y: 0 + } }], 'icon-text-fit: both'); t.end(); @@ -100,7 +140,17 @@ test('getIconQuads', (t) => { writingMode: null, glyphOffset: [0, 0], isSDF: false, - sectionIndex: 0 + sectionIndex: 0, + minFontScaleX: 0, + minFontScaleY: 0, + pixelOffsetBR: { + x: 0, + y: 0 + }, + pixelOffsetTL: { + x: 0, + y: 0 + } }]); t.end(); }); diff --git a/test/unit/symbol/shaping.test.js b/test/unit/symbol/shaping.test.js index 33278229af2..6dce3ef180e 100644 --- a/test/unit/symbol/shaping.test.js +++ b/test/unit/symbol/shaping.test.js @@ -141,6 +141,9 @@ test('shaping', (t) => { test('shapeIcon', (t) => { const imagePosition = new ImagePosition({x: 0, y: 0, w: 22, h: 22}, {pixelRatio: 1, version: 1}); const image = Object.freeze({ + content: null, + stretchX: null, + stretchY: null, paddedRect: Object.freeze({x: 0, y: 0, w: 22, h: 22}), pixelRatio: 1, version: 1