From e77ef6c82a336e3dee4c557f37a03a05b0ad423e Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 22 May 2017 12:52:43 -0700 Subject: [PATCH 1/4] Remove destructuring assignment, per CONTRIBUTING.md --- test/unit/ui/camera.test.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/unit/ui/camera.test.js b/test/unit/ui/camera.test.js index b1483723949..28cedb4fe4a 100644 --- a/test/unit/ui/camera.test.js +++ b/test/unit/ui/camera.test.js @@ -1156,9 +1156,9 @@ test('camera', (t) => { camera.on('moveend', () => { t.equalWithPrecision(camera.getZoom(), 10, 1e-10); - const { lng, lat } = camera.getCenter(); - t.equalWithPrecision(lng, 12, 1e-10); - t.equalWithPrecision(lat, 34, 1e-10); + const center = camera.getCenter(); + t.equalWithPrecision(center.lng, 12, 1e-10); + t.equalWithPrecision(center.lat, 34, 1e-10); t.end(); }); @@ -1176,9 +1176,9 @@ test('camera', (t) => { camera.on('moveend', () => { t.equalWithPrecision(camera.getZoom(), 2, 1e-10); - const { lng, lat } = camera.getCenter(); - t.equalWithPrecision(lng, 12, 1e-10); - t.equalWithPrecision(lat, 34, 1e-10); + const center = camera.getCenter(); + t.equalWithPrecision(center.lng, 12, 1e-10); + t.equalWithPrecision(center.lat, 34, 1e-10); t.end(); }); From 333168db945e09e1fda53e8d27b2332691e94b7c Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Fri, 19 May 2017 16:42:47 -0700 Subject: [PATCH 2/4] Simplify and fix sprite atlas coordinate calculations * Always return image metrics exclusive of padding * Work with integer coordinates whenever possible * Eliminate redundant SpriteAtlasElement members * Fix asymmetric re-padding in getIconQuad when pixelRatio != 1 * Add explanatory comments --- src/data/bucket/symbol_bucket.js | 7 +- src/render/draw_line.js | 10 +- src/render/draw_symbol.js | 5 +- src/render/pattern.js | 14 +- src/symbol/quads.js | 24 +++- src/symbol/shaping.js | 10 +- src/symbol/sprite_atlas.js | 134 ++++++++++-------- .../image-add-1x-image-2x-screen/expected.png | Bin 4709 -> 4700 bytes .../image-add-2x-image-1x-screen/expected.png | Bin 1420 -> 1346 bytes .../image-add-2x-image-2x-screen/expected.png | Bin 2603 -> 2956 bytes .../sprites/1x-screen-2x-icon/expected.png | Bin 1424 -> 1346 bytes .../sprites/2x-screen-1x-icon/expected.png | Bin 4703 -> 4700 bytes .../sprites/2x-screen-2x-icon/expected.png | Bin 2971 -> 2956 bytes test/unit/data/symbol_bucket.test.js | 2 +- test/unit/symbol/quads.test.js | 74 +++++----- 15 files changed, 155 insertions(+), 125 deletions(-) diff --git a/src/data/bucket/symbol_bucket.js b/src/data/bucket/symbol_bucket.js index 3659f171ee0..f0f561da8c0 100644 --- a/src/data/bucket/symbol_bucket.js +++ b/src/data/bucket/symbol_bucket.js @@ -373,16 +373,15 @@ class SymbolBucket { let shapedIcon; if (feature.icon) { const image = icons[feature.icon]; - const iconOffset = this.layers[0].getLayoutValue('icon-offset', {zoom: this.zoom}, feature.properties); - shapedIcon = shapeIcon(image, iconOffset); - if (image) { + shapedIcon = shapeIcon(image, + this.layers[0].getLayoutValue('icon-offset', {zoom: this.zoom}, feature.properties)); if (this.sdfIcons === undefined) { this.sdfIcons = image.sdf; } else if (this.sdfIcons !== image.sdf) { util.warnOnce('Style sheet warning: Cannot mix SDF and non-SDF icons in one buffer'); } - if (image.pixelRatio !== 1) { + if (!image.isNativePixelRatio) { this.iconsNeedLinear = true; } else if (layout['icon-rotate'] !== 0 || !this.layers[0].isLayoutValueFeatureConstant('icon-rotate')) { this.iconsNeedLinear = true; diff --git a/src/render/draw_line.js b/src/render/draw_line.js index 656b93ca60f..5274ab04b0a 100644 --- a/src/render/draw_line.js +++ b/src/render/draw_line.js @@ -73,13 +73,13 @@ function drawLineTile(program, painter, tile, buffers, layer, coord, layerData, gl.uniform1f(program.u_sdfgamma, painter.lineAtlas.width / (Math.min(widthA, widthB) * 256 * browser.devicePixelRatio) / 2); } else if (image) { - imagePosA = painter.spriteAtlas.getPosition(image.from, true); - imagePosB = painter.spriteAtlas.getPosition(image.to, true); + imagePosA = painter.spriteAtlas.getPattern(image.from); + imagePosB = painter.spriteAtlas.getPattern(image.to); if (!imagePosA || !imagePosB) return; - gl.uniform2f(program.u_pattern_size_a, imagePosA.size[0] * image.fromScale / tileRatio, imagePosB.size[1]); - gl.uniform2f(program.u_pattern_size_b, imagePosB.size[0] * image.toScale / tileRatio, imagePosB.size[1]); - gl.uniform2f(program.u_texsize, painter.spriteAtlas.width, painter.spriteAtlas.height); + gl.uniform2f(program.u_pattern_size_a, imagePosA.displaySize[0] * image.fromScale / tileRatio, imagePosB.displaySize[1]); + gl.uniform2f(program.u_pattern_size_b, imagePosB.displaySize[0] * image.toScale / tileRatio, imagePosB.displaySize[1]); + gl.uniform2fv(program.u_texsize, painter.spriteAtlas.getPixelSize()); } gl.uniform2f(program.u_gl_units_to_pixels, 1 / painter.transform.pixelsToGLUnits[0], 1 / painter.transform.pixelsToGLUnits[1]); diff --git a/src/render/draw_symbol.js b/src/render/draw_symbol.js index 764e18acd9b..042db5c4701 100644 --- a/src/render/draw_symbol.js +++ b/src/render/draw_symbol.js @@ -2,7 +2,6 @@ const assert = require('assert'); const util = require('../util/util'); -const browser = require('../util/browser'); const drawCollisionDebug = require('./draw_collision_debug'); const pixelsToTileUnits = require('../source/pixels_to_tile_units'); const interpolationFactor = require('../style-spec/function').interpolationFactor; @@ -136,10 +135,10 @@ function setSymbolDrawState(program, painter, layer, tileZoom, isText, isSDF, ro const iconSizeScaled = !layer.isLayoutValueFeatureConstant('icon-size') || !layer.isLayoutValueZoomConstant('icon-size') || layer.getLayoutValue('icon-size', { zoom: tr.zoom }) !== 1; - const iconScaled = iconSizeScaled || browser.devicePixelRatio !== painter.spriteAtlas.pixelRatio || iconsNeedLinear; + const iconScaled = iconSizeScaled || iconsNeedLinear; const iconTransformed = pitchWithMap || tr.pitch; painter.spriteAtlas.bind(gl, isSDF || mapMoving || iconScaled || iconTransformed); - gl.uniform2f(program.u_texsize, painter.spriteAtlas.width, painter.spriteAtlas.height); + gl.uniform2fv(program.u_texsize, painter.spriteAtlas.getPixelSize()); } gl.activeTexture(gl.TEXTURE1); diff --git a/src/render/pattern.js b/src/render/pattern.js index 5a0dfcc1169..851d4834415 100644 --- a/src/render/pattern.js +++ b/src/render/pattern.js @@ -11,16 +11,16 @@ const pixelsToTileUnits = require('../source/pixels_to_tile_units'); */ exports.isPatternMissing = function(image, painter) { if (!image) return false; - const imagePosA = painter.spriteAtlas.getPosition(image.from, true); - const imagePosB = painter.spriteAtlas.getPosition(image.to, true); + const imagePosA = painter.spriteAtlas.getPattern(image.from); + const imagePosB = painter.spriteAtlas.getPattern(image.to); return !imagePosA || !imagePosB; }; exports.prepare = function (image, painter, program) { const gl = painter.gl; - const imagePosA = painter.spriteAtlas.getPosition(image.from, true); - const imagePosB = painter.spriteAtlas.getPosition(image.to, true); + const imagePosA = painter.spriteAtlas.getPattern(image.from); + const imagePosB = painter.spriteAtlas.getPattern(image.to); assert(imagePosA && imagePosB); gl.uniform1i(program.u_image, 0); @@ -28,10 +28,10 @@ exports.prepare = function (image, painter, program) { gl.uniform2fv(program.u_pattern_br_a, imagePosA.br); gl.uniform2fv(program.u_pattern_tl_b, imagePosB.tl); gl.uniform2fv(program.u_pattern_br_b, imagePosB.br); - gl.uniform2f(program.u_texsize, painter.spriteAtlas.width, painter.spriteAtlas.height); + gl.uniform2fv(program.u_texsize, painter.spriteAtlas.getPixelSize()); gl.uniform1f(program.u_mix, image.t); - gl.uniform2fv(program.u_pattern_size_a, imagePosA.size); - gl.uniform2fv(program.u_pattern_size_b, imagePosB.size); + gl.uniform2fv(program.u_pattern_size_a, imagePosA.displaySize); + gl.uniform2fv(program.u_pattern_size_b, imagePosB.displaySize); gl.uniform1f(program.u_scale_a, image.fromScale); gl.uniform1f(program.u_scale_b, image.toScale); diff --git a/src/symbol/quads.js b/src/symbol/quads.js index 16ce489db34..8b745b6c146 100644 --- a/src/symbol/quads.js +++ b/src/symbol/quads.js @@ -59,14 +59,18 @@ function SymbolQuad(anchorPoint, tl, tr, bl, br, tex, anchorAngle, glyphAngle, m * @private */ function getIconQuads(anchor, shapedIcon, boxScale, line, layer, alongLine, shapedText, globalProperties, featureProperties) { - const rect = shapedIcon.image.rect; + const image = shapedIcon.image; const layout = layer.layout; + // 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 = 1; - const left = shapedIcon.left - border; - const right = left + rect.w / shapedIcon.image.pixelRatio; - const top = shapedIcon.top - border; - const bottom = top + rect.h / shapedIcon.image.pixelRatio; + + const top = shapedIcon.top - border / image.pixelRatio; + const left = shapedIcon.left - border / image.pixelRatio; + const bottom = shapedIcon.bottom + border / image.pixelRatio; + const right = shapedIcon.right + border / image.pixelRatio; let tl, tr, br, bl; // text-fit mode @@ -122,7 +126,15 @@ function getIconQuads(anchor, shapedIcon, boxScale, line, layer, alongLine, shap br = br.matMult(matrix); } - return [new SymbolQuad(new Point(anchor.x, anchor.y), tl, tr, bl, br, shapedIcon.image.rect, 0, 0, minScale, Infinity)]; + // Icon quad is padded, so texture coordinates also need to be padded. + const textureRect = { + x: image.textureRect.x - border, + y: image.textureRect.y - border, + w: image.textureRect.w + border * 2, + h: image.textureRect.h + border * 2 + }; + + return [new SymbolQuad(new Point(anchor.x, anchor.y), tl, tr, bl, br, textureRect, 0, 0, minScale, Infinity)]; } /** diff --git a/src/symbol/shaping.js b/src/symbol/shaping.js index e2446b0a0ed..20076ea44bc 100644 --- a/src/symbol/shaping.js +++ b/src/symbol/shaping.js @@ -310,14 +310,12 @@ function align(positionedGlyphs, justify, horizontalAlign, verticalAlign, maxLin } function shapeIcon(image, iconOffset) { - if (!image || !image.rect) return null; - const dx = iconOffset[0]; const dy = iconOffset[1]; - const x1 = dx - image.width / 2; - const x2 = x1 + image.width; - const y1 = dy - image.height / 2; - const y2 = y1 + image.height; + const x1 = dx - image.displaySize[0] / 2; + const x2 = x1 + image.displaySize[0]; + const y1 = dy - image.displaySize[1] / 2; + const y2 = y1 + image.displaySize[1]; return new PositionedIcon(image, y1, y2, x1, x2); } diff --git a/src/symbol/sprite_atlas.js b/src/symbol/sprite_atlas.js index e39f310499b..5239941eb41 100644 --- a/src/symbol/sprite_atlas.js +++ b/src/symbol/sprite_atlas.js @@ -7,28 +7,62 @@ const window = require('../util/window'); const Evented = require('../util/evented'); const padding = 1; +// This wants to be a class, but is sent to workers, so must be a plain JSON blob. +function spriteAtlasElement(image) { + const textureRect = { + x: image.rect.x + padding, + y: image.rect.y + padding, + w: image.rect.w - padding * 2, + h: image.rect.h - padding * 2 + }; + return { + sdf: image.sdf, + pixelRatio: image.pixelRatio, + isNativePixelRatio: image.pixelRatio === browser.devicePixelRatio, + textureRect: textureRect, + + // Redundant calculated members. + tl: [ + textureRect.x, + textureRect.y + ], + br: [ + textureRect.x + textureRect.w, + textureRect.y + textureRect.h + ], + displaySize: [ + textureRect.w / image.pixelRatio, + textureRect.h / image.pixelRatio + ] + }; +} + // The SpriteAtlas class is responsible for turning a sprite and assorted // other images added at runtime into a texture that can be consumed by WebGL. class SpriteAtlas extends Evented { constructor(width, height) { super(); - - this.width = width; - this.height = height; - - this.shelfPack = new ShelfPack(width, height); this.images = {}; this.data = false; this.texture = 0; // WebGL ID this.filter = 0; // WebGL ID - this.pixelRatio = browser.devicePixelRatio > 1 ? 2 : 1; + this.width = width * browser.devicePixelRatio; + this.height = height * browser.devicePixelRatio; + this.shelfPack = new ShelfPack(this.width, this.height); this.dirty = true; } + getPixelSize() { + return [ + this.width, + this.height + ]; + } + allocateImage(pixelWidth, pixelHeight) { - const width = pixelWidth / this.pixelRatio + 2 * padding; - const height = pixelHeight / this.pixelRatio + 2 * padding; + const width = pixelWidth + 2 * padding; + const height = pixelHeight + 2 * padding; const rect = this.shelfPack.packOne(width, height); if (!rect) { @@ -69,16 +103,15 @@ class SpriteAtlas extends Evented { return this.fire('error', {error: new Error('There is not enough space to add this image.')}); } - const image = { + this.images[name] = { rect, - width: width / pixelRatio, - height: height / pixelRatio, - sdf: false, - pixelRatio: pixelRatio / this.pixelRatio + width, + height, + pixelRatio, + sdf: false }; - this.images[name] = image; - this.copy(pixels, width, rect, {pixelRatio, x: 0, y: 0, width, height}, false); + this.copy(pixels, width, rect, {x: 0, y: 0, width, height}, false); this.fire('data', {dataType: 'style'}); } @@ -95,9 +128,19 @@ class SpriteAtlas extends Evented { this.fire('data', {dataType: 'style'}); } - getImage(name, wrap) { + // Return metrics for an icon image. + getIcon(name) { + return this._getImage(name, false); + } + + // Return metrics for repeating pattern image. + getPattern(name) { + return this._getImage(name, true); + } + + _getImage(name, wrap) { if (this.images[name]) { - return this.images[name]; + return spriteAtlasElement(this.images[name]); } if (!this.sprite) { @@ -116,10 +159,10 @@ class SpriteAtlas extends Evented { const image = { rect, - width: pos.width / pos.pixelRatio, - height: pos.height / pos.pixelRatio, + width: pos.width, + height: pos.height, sdf: pos.sdf, - pixelRatio: pos.pixelRatio / this.pixelRatio + pixelRatio: pos.pixelRatio }; this.images[name] = image; @@ -127,33 +170,12 @@ class SpriteAtlas extends Evented { const srcImg = new Uint32Array(this.sprite.imgData.buffer); this.copy(srcImg, this.sprite.width, rect, pos, wrap); - return image; - } - - // Return position of a repeating fill pattern. - getPosition(name, repeating) { - const image = this.getImage(name, repeating); - const rect = image && image.rect; - - if (!rect) { - return null; - } - - const width = image.width * image.pixelRatio; - const height = image.height * image.pixelRatio; - - return { - size: [image.width, image.height], - tl: [(rect.x + padding), (rect.y + padding)], - br: [(rect.x + padding + width), (rect.y + padding + height)] - }; + return spriteAtlasElement(image); } allocate() { if (!this.data) { - const w = Math.floor(this.width * this.pixelRatio); - const h = Math.floor(this.height * this.pixelRatio); - this.data = new Uint32Array(w * h); + this.data = new Uint32Array(this.width * this.height); for (let i = 0; i < this.data.length; i++) { this.data[i] = 0; } @@ -171,9 +193,9 @@ class SpriteAtlas extends Evented { /* source x */ srcPos.x, /* source y */ srcPos.y, /* dest buffer */ dstImg, - /* dest stride */ this.width * this.pixelRatio, - /* dest x */ (dstPos.x + padding) * this.pixelRatio, - /* dest y */ (dstPos.y + padding) * this.pixelRatio, + /* dest stride */ this.getPixelSize()[0], + /* dest x */ dstPos.x + padding, + /* dest y */ dstPos.y + padding, /* icon dimension */ srcPos.width, /* icon dimension */ srcPos.height, /* wrap */ wrap @@ -186,18 +208,18 @@ class SpriteAtlas extends Evented { setSprite(sprite) { if (sprite && this.canvas) { - this.canvas.width = this.width * this.pixelRatio; - this.canvas.height = this.height * this.pixelRatio; + this.canvas.width = this.width; + this.canvas.height = this.height; } this.sprite = sprite; } addIcons(icons, callback) { - for (let i = 0; i < icons.length; i++) { - this.getImage(icons[i]); + const result = {}; + for (const icon of icons) { + result[icon] = this.getIcon(icon); } - - callback(null, this.images); + callback(null, result); } bind(gl, linear) { @@ -228,8 +250,8 @@ class SpriteAtlas extends Evented { gl.TEXTURE_2D, // enum target 0, // ind level gl.RGBA, // ind internalformat - this.width * this.pixelRatio, // GLsizei width - this.height * this.pixelRatio, // GLsizei height + this.width, // GLsizei width + this.height, // GLsizei height 0, // ind border gl.RGBA, // enum format gl.UNSIGNED_BYTE, // enum type @@ -241,8 +263,8 @@ class SpriteAtlas extends Evented { 0, // int level 0, // int xoffset 0, // int yoffset - this.width * this.pixelRatio, // long width - this.height * this.pixelRatio, // long height + this.width, // long width + this.height, // long height gl.RGBA, // enum format gl.UNSIGNED_BYTE, // enum type new Uint8Array(this.data.buffer) // Object pixels diff --git a/test/integration/render-tests/runtime-styling/image-add-1x-image-2x-screen/expected.png b/test/integration/render-tests/runtime-styling/image-add-1x-image-2x-screen/expected.png index 309f787dcc179ea0e8a14cc5b3c4054e03d83e9b..2f9d0663ec3730ce55ec78e7d6087219e26b53bf 100644 GIT binary patch literal 4700 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 literal 4709 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%0DtAtFuXdR6t)cy0%f1mKbn$@{D3FwU zY1cFu82Iw$tNO;CI877xS4!DI$9h!dfcykdt^QJ(hVI!o{;Cgyvn(}sJ zODVL}nAfgcMl%8Ezb~tWmE|!@^W^)*QfIY0Pt~*ER}fsJH6(s&WGZzQZQXjs+1~>y z;2E1fBYiZS=MsSOz&|u!4Mw>*@@2#R^W=a~XN=Qnw$G6FEKt(bO5lZ}$ys8NWa^oV z`p&PKeK99i5mELpR@>bL_#+UZLh0jyNM7Rv`0lgCod$EaS4ph-+s=Kfh~?Hf++*s+$rQcrzJfKe3y%=dLIG^hHuBFI1mBfW6Lixqg*Ec^&9k@jX$ zKR+)opu$kIdSk;hL@#D|wI=<|53O z;(gJ_tq49E+!i{Xx59Gf9Pfs@n@h?)EE@Nyp37Iwe8C)?Ug4gM-cu}$-hA#SA|3aI zFYa@o6!Fza@ZefDQxX2zs<)U%fTp(p%QmKTkkXKLSXv|VMXTS+d@HSSQ+vf^-*i&f z_IPnSB@N)acb?t3UzB~l+pnwR+x713F6UB2{RQg; zbqk4*JYm-Sp0AtCiRZy#-v_Unya^59xsktPYDUWHzAvg>`02|Pbug#l7J<;gU|3wH zOj+28yL8t9d5;FO`#6R8aQP(xiElU(kPSpRF;#~rsSlr@pBG~5R5F$JVSnyJb#x

{#S#`FKg<%FBI>IHg(2gn_Jzp_l|^57D+`UWWfHbS>wAZLZ5u-uyHDev`~!na z;WYHv0&a-V$j#05(a)oF*PVc5gB8ZWB`~p*2W|*Iva+1rDX|IB zY1c|aDzTuY2-g{$=Sa=*^2^&Zt5wmCnB;Yg$z9Kd*5tCtDovjgW{zh;+~FrBA?yZQ z)}XlQ7ifW&C0k*_-e>V#c26ZRzhr-U(bBpGhovS?;{zB^ zY5%w}zus)w8^G>*RY$GMuQm==t`{h=qKIBySU>AadkG-E3X&uQSN4dOGg$LTHue(= zPym^k;axXH9pVwBb2SBt-H;O#n{muAEPnL&ciGu#`Odadg`!VyiizQOn4E_|~cw=R^3dh34uDpE*h- zenStaXlum*4^XqpjM=u$bKRvIDuuRgXmwUd-GFve-Ra)lR@##V?9S|m>SP--cKIfc zC>_*9(u*Q>n@NN<>{lfs`bBlL3n@WNa@~G*P-B1Py3=*o!6?x2<{}iA*h$iopnmH5 zg~{xf?=Gfp2`1@ZMQkLIi3}MFFt6BCp?F-s*cWc2G4Qy^ZJ(}o$Y_b}II@EY|P&Q=+7!FJszBdU0x?BOV|Ty(p{A z{c~X6J085HBs%F|hYqqa=h;&Ga27Pa^EZlz>q}8O?E{B7SmQTXa}i+?*QDh^LkpaB zK!1(+j>Siyz+fSd%_y^{ye#@N&Q4{J9|nVneaeOkwvr0dtLF82|A~-sKtnF!tb@CG zab$iW4-hvL1sd-?^%PJxg%n&aBC8EAJbERJom2F+d_Fw}q7KFhbt4gMP_B3O(D3jo zmO?zqtpy03JI*PMBt1hCo*^x|Mu!rUbPC(!lOW75Uk`rx85S@v@c8-D0^uvE$) zk=Crw;aNrT2Lr-3?a?lt*Y_TawQ7Uj3$h_2xS(_ppC$<$>s0VBAfD$zM@_$^i~a8| j%m3}U{6EY%Yti7$3fxd%g6=TTHv(Cj+nAM`di?cY6yy~* diff --git a/test/integration/render-tests/runtime-styling/image-add-2x-image-1x-screen/expected.png b/test/integration/render-tests/runtime-styling/image-add-2x-image-1x-screen/expected.png index 07895f2b64a2f98eeb88437c99553a521614e1ba..44770e5ecdfdb0eb7a8dcd038c6c8c26fb087e84 100644 GIT binary patch delta 1314 zcmV+-1>O3L3&IMJF@FU6NklPj&{hkQqZbJt^j5GQgd#-|Zz3_E9z2OPHih)V;s-^AAT?>iHjQbzO`5G6HnU&t z>`rF(%^Qe&~6@TT~R!ZBkp&&$hiSx;6 z#~GV(oN*4Uqd^E7q%ROS`dTFNNl!G|-mPia)!dAhPzak!mW9>3cX1<|#eA`t{-#`h zYqnY)M*|Qvz>!esgCi|1?>yhtg{N9u@lRF?1^lwOh_j{Ahi5J81SDgSY%mmhe<&7v z_i$ey;yZTWL4R68A#}C1LA`hHpu@Sc!1>RRh(V%mMS1Cs*48fv`}z=8Rcu#)F+3fQ zgA@ucT(|AZc_Ee{357&Mk;upaT}MP!QO^|u*-8c3N(HVEs25RH9ME+PMIs}Rh(VIx zKw$9ISnTcR_U=W!8N>fA<0fkdzykl)XJ@| zBi7rCsDG}bUR2i+>+MBueI2!$fh!hOY5 z3KPS_7|=8@N>OXgG;!N?uRsz7lFU`B7ngInmw!9san$NhBml#}*M|-v*4v9s`D79U znuh*F0`-=2Im}h77a@rPNv0iVY|$`2KA`K0swk+{pGcrL7DLW7u_@lu14b$8IhTt1`q36CWA@S9KYkbS0NFFWM?Xs<5Mdu z+_Y_MmucIWT3O*|DwX4qj6t%B=j8)HSmXTQ-nKSu$K{0uoX+PznyOY$Lo$j6IA>WW zr*pZbo7puy$j$5;rgOQabCz`y4ZzR<0)OCX&SyI8_1C*J4Ju>UO4)I6>H2kyluEA{ zLM);I7#bumL|O&3sBQ1>(ll)4r}=q&S15e;t8I@05NH4f`6y#-cOVehvna%D2j?%g zG8W(2+>BbY=`?=KWEQ@%?e{2S2>^=cc_si45;4dX*zgRcGzx%tfVbefzjstBhku`J zX$dq1gV^*}se~VH+^BqNS#Op-uLyupN_S97qe6%x00BuDBvKTmlTzA*8WqpGyDG#j z%`^|`ZEdK!F20|e!{_Dli6z&aMGZnofDobzAqtR$K_W#__5dKLlNDk~xGsy7%L6IH zz*wpD#c$Q>x7Y$9BgIr=m4glQ{20*Yq!gbv&=lm7`7ZMRPjzTGo zQc7D0At6G@6R6>Np6z*_C4?vmA&LMvd_JGg=kxh|KA+F$^Z9%}pU>y>`5SybpYK2N YH#r3*jM!2L`4pTR)Rx9?b1-Sm1BpEy6|6Gak?L%-b=GL{w{WN>cIm!h9cz#Q(PxJytS|Tq&LY27hoAZ~+fkDM!(pWhuAm zu@pV>E!&=)w(TElsnmBq*VktaI1Z++6SmuI`92%1mWcQEF3bhNPcH_+GCh)_2hOzM6g%U(=f2q2_mgiv{QvZ-35*;U7>$M}d-ISku|;Z@xY; zVVZ`)ehbwqe~)7xedZY+o0&lyALp+N3k0neqq!XW^=GqGHa5Ocj-qp0aV$~5K!H*^ z{Y1fWa=A=~{cia_*A0X3zV;e+vBnX-0^)X&1Q8j2wp}Z4MoaQigFY^zp%Q>XR)xlN;!(2FH0#< zNJF8yAb7FTY<{@jXz(D`8x1PW=7)1Z@FI$7C{&hGl%wdmw^nY@j$`geJC1p4S@{oL)_r;ZE^Xm&bHeP@R^mY3TXve_T58^#)+$hfZCCxqCPQlg5E zBDq|yXxny?E?b&bbK32eymRL(M}GLhf{97jTXZ}-KN*M|vc2Gn|5zDd; z*|zO+fR%K5abS0Mu=??>$tCtK{63rgHTNKd*bzc(qlkez5uai%oBhS{FkE`iG%xV! zA{5e5CvaW2A4qcmnM&<_Y#2*2mD=Opf<~jUCZ$9b9Yv&+2q7A->)Jqu2W8i)R4O-w z5N#An(F6S*`F#E`-~uV`Z4dD3_4@5b2R)FYhb+s|Ez8OQ7NGHo7!V!XLWnkrL?V$$ uBoc{4B9TZW5{X12kw_#Gi9{mtKlV@45GhPK94#vV0000g| diff --git a/test/integration/render-tests/runtime-styling/image-add-2x-image-2x-screen/expected.png b/test/integration/render-tests/runtime-styling/image-add-2x-image-2x-screen/expected.png index efe3e87dd4e2dc82adba1e31b391d0c3dbb5036b..e7135300c68ec13285c6fbe3b41426219d37b329 100644 GIT binary patch literal 2956 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 OK(>~S7R_e}ss92UVA{R_ diff --git a/test/integration/render-tests/sprites/1x-screen-2x-icon/expected.png b/test/integration/render-tests/sprites/1x-screen-2x-icon/expected.png index 3be50e4ff30ea501afcd18b65d602c3ef7038e60..44770e5ecdfdb0eb7a8dcd038c6c8c26fb087e84 100644 GIT binary patch delta 1314 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 HH=_Rs{^qoI diff --git a/test/integration/render-tests/sprites/2x-screen-2x-icon/expected.png b/test/integration/render-tests/sprites/2x-screen-2x-icon/expected.png index d0455e1c98bcd6b40f5b8f874f2e3f09ec201bcd..e7135300c68ec13285c6fbe3b41426219d37b329 100644 GIT binary patch literal 2956 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 diff --git a/test/unit/data/symbol_bucket.test.js b/test/unit/data/symbol_bucket.test.js index bd8a29ebacb..13f2a84a70c 100644 --- a/test/unit/data/symbol_bucket.test.js +++ b/test/unit/data/symbol_bucket.test.js @@ -131,7 +131,7 @@ test('SymbolBucket#getPaintPropertyStatistics()', (t) => { bucket.populate([feature], options); bucket.prepare(stacks, { - dot: { width: 10, height: 10, pixelRatio: 1, rect: { w: 10, h: 10 } } + dot: { displaySize: () => [10, 10], textureRect: { x: 0, y: 0, w: 10, h: 10 }, pixelRatio: 1 } }); bucket.place(collision); diff --git a/test/unit/symbol/quads.test.js b/test/unit/symbol/quads.test.js index a4e158bcbb4..5f43884af65 100644 --- a/test/unit/symbol/quads.test.js +++ b/test/unit/symbol/quads.test.js @@ -23,7 +23,7 @@ function createShapedIcon() { right: 8, image: { pixelRatio: 1, - rect: { w: 15, h: 11} + textureRect: { x: 1, y: 1, w: 15, h: 11} } }; } @@ -39,10 +39,10 @@ test('getIconQuads', (t) => { { anchorPoint: { x: 2, y: 3 }, tl: { x: -8, y: -6 }, - tr: { x: 7, y: -6 }, - bl: { x: -8, y: 5 }, - br: { x: 7, y: 5 }, - tex: { w: 15, h: 11 }, + tr: { x: 9, y: -6 }, + bl: { x: -8, y: 7 }, + br: { x: 9, y: 7 }, + tex: { x: 0, y: 0, w: 17, h: 13 }, anchorAngle: 0, glyphAngle: 0, minScale: 0.5, @@ -61,10 +61,10 @@ test('getIconQuads', (t) => { { anchorPoint: { x: 2, y: 3}, tl: { x: -8, y: -6 }, - tr: { x: 7, y: -6 }, - bl: { x: -8, y: 5 }, - br: { x: 7, y: 5 }, - tex: { w: 15, h: 11 }, + tr: { x: 9, y: -6 }, + bl: { x: -8, y: 7 }, + br: { x: 9, y: 7 }, + tex: { x: 0, y: 0, w: 17, h: 13 }, anchorAngle: 0, glyphAngle: 0, minScale: 0.5, @@ -86,7 +86,7 @@ test('getIconQuads text-fit', (t) => { right: 10, image: { pixelRatio: 1, - rect: { w: 20, h: 20 } + textureRect: { x: 1, y: 1, w: 20, h: 20 } } }; } @@ -107,9 +107,9 @@ test('getIconQuads text-fit', (t) => { } }), false, createshapedText()); t.deepEqual(quads[0].tl, { x: -11, y: -11 }); - t.deepEqual(quads[0].tr, { x: 9, y: -11 }); - t.deepEqual(quads[0].bl, { x: -11, y: 9 }); - t.deepEqual(quads[0].br, { x: 9, y: 9 }); + t.deepEqual(quads[0].tr, { x: 11, y: -11 }); + t.deepEqual(quads[0].bl, { x: -11, y: 11 }); + t.deepEqual(quads[0].br, { x: 11, y: 11 }); t.deepEqual(quads, getIconQuads(anchor, createShapedIcon(), 2, [], createLayer({ layout: { @@ -131,10 +131,10 @@ test('getIconQuads text-fit', (t) => { 'icon-text-fit-padding': [ 0, 0, 0, 0 ] } }), false, createshapedText()); - t.deepEqual(quads[0].tl, { x: -60, y: 0 }); - t.deepEqual(quads[0].tr, { x: 20, y: 0 }); - t.deepEqual(quads[0].bl, { x: -60, y: 20 }); - t.deepEqual(quads[0].br, { x: 20, y: 20 }); + t.deepEqual(quads[0].tl, { x: -60, y: -1 }); + t.deepEqual(quads[0].tr, { x: 20, y: -1 }); + t.deepEqual(quads[0].bl, { x: -60, y: 21 }); + t.deepEqual(quads[0].br, { x: 20, y: 21 }); t.end(); }); @@ -148,10 +148,10 @@ test('getIconQuads text-fit', (t) => { 'icon-text-fit-padding': [ 0, 0, 0, 0 ] } }), false, createshapedText()); - t.deepEqual(quads[0].tl, { x: -30, y: -5 }); - t.deepEqual(quads[0].tr, { x: 10, y: -5 }); - t.deepEqual(quads[0].bl, { x: -30, y: 15 }); - t.deepEqual(quads[0].br, { x: 10, y: 15 }); + t.deepEqual(quads[0].tl, { x: -30, y: -6 }); + t.deepEqual(quads[0].tr, { x: 10, y: -6 }); + t.deepEqual(quads[0].bl, { x: -30, y: 16 }); + t.deepEqual(quads[0].br, { x: 10, y: 16 }); t.end(); }); @@ -166,10 +166,10 @@ test('getIconQuads text-fit', (t) => { 'icon-text-fit-padding': [ 5, 10, 5, 10 ] } }), false, createshapedText()); - t.deepEqual(quads[0].tl, { x: -40, y: -10 }); - t.deepEqual(quads[0].tr, { x: 20, y: -10 }); - t.deepEqual(quads[0].bl, { x: -40, y: 20 }); - t.deepEqual(quads[0].br, { x: 20, y: 20 }); + t.deepEqual(quads[0].tl, { x: -40, y: -11 }); + t.deepEqual(quads[0].tr, { x: 20, y: -11 }); + t.deepEqual(quads[0].bl, { x: -40, y: 21 }); + t.deepEqual(quads[0].br, { x: 20, y: 21 }); t.end(); }); @@ -183,10 +183,10 @@ test('getIconQuads text-fit', (t) => { 'icon-text-fit-padding': [ 0, 0, 0, 0 ] } }), false, createshapedText()); - t.deepEqual(quads[0].tl, { x: -30, y: -10 }); - t.deepEqual(quads[0].tr, { x: -10, y: -10 }); - t.deepEqual(quads[0].bl, { x: -30, y: 30 }); - t.deepEqual(quads[0].br, { x: -10, y: 30 }); + t.deepEqual(quads[0].tl, { x: -31, y: -10 }); + t.deepEqual(quads[0].tr, { x: -9, y: -10 }); + t.deepEqual(quads[0].bl, { x: -31, y: 30 }); + t.deepEqual(quads[0].br, { x: -9, y: 30 }); t.end(); }); @@ -200,10 +200,10 @@ test('getIconQuads text-fit', (t) => { 'icon-text-fit-padding': [ 0, 0, 0, 0 ] } }), false, createshapedText()); - t.deepEqual(quads[0].tl, { x: -20, y: -5 }); - t.deepEqual(quads[0].tr, { x: 0, y: -5 }); - t.deepEqual(quads[0].bl, { x: -20, y: 15 }); - t.deepEqual(quads[0].br, { x: 0, y: 15 }); + t.deepEqual(quads[0].tl, { x: -21, y: -5 }); + t.deepEqual(quads[0].tr, { x: 1, y: -5 }); + t.deepEqual(quads[0].bl, { x: -21, y: 15 }); + t.deepEqual(quads[0].br, { x: 1, y: 15 }); t.end(); }); @@ -218,10 +218,10 @@ test('getIconQuads text-fit', (t) => { 'icon-text-fit-padding': [ 5, 10, 5, 10 ] } }), false, createshapedText()); - t.deepEqual(quads[0].tl, { x: -30, y: -10 }); - t.deepEqual(quads[0].tr, { x: 10, y: -10 }); - t.deepEqual(quads[0].bl, { x: -30, y: 20 }); - t.deepEqual(quads[0].br, { x: 10, y: 20 }); + t.deepEqual(quads[0].tl, { x: -31, y: -10 }); + t.deepEqual(quads[0].tr, { x: 11, y: -10 }); + t.deepEqual(quads[0].bl, { x: -31, y: 20 }); + t.deepEqual(quads[0].br, { x: 11, y: 20 }); t.end(); }); From e869abb19382bb82cb3893df45ec8eba198e8948 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Fri, 19 May 2017 17:02:44 -0700 Subject: [PATCH 3/4] Add tests for 1.5x image --- .../expected.png | Bin 0 -> 1616 bytes .../image-add-1.5x-image-1x-screen/style.json | 42 ++++++++++++++++++ .../expected.png | Bin 0 -> 4864 bytes .../image-add-1.5x-image-2x-screen/style.json | 42 ++++++++++++++++++ test/integration/sprites/1.5x.png | Bin 0 -> 3377 bytes 5 files changed, 84 insertions(+) create mode 100644 test/integration/render-tests/runtime-styling/image-add-1.5x-image-1x-screen/expected.png create mode 100644 test/integration/render-tests/runtime-styling/image-add-1.5x-image-1x-screen/style.json create mode 100644 test/integration/render-tests/runtime-styling/image-add-1.5x-image-2x-screen/expected.png create mode 100644 test/integration/render-tests/runtime-styling/image-add-1.5x-image-2x-screen/style.json create mode 100644 test/integration/sprites/1.5x.png diff --git a/test/integration/render-tests/runtime-styling/image-add-1.5x-image-1x-screen/expected.png b/test/integration/render-tests/runtime-styling/image-add-1.5x-image-1x-screen/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..d1074ed8bbd1bd24cd8934abbd6df770789556b7 GIT binary patch literal 1616 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 literal 0 HcmV?d00001 diff --git a/test/integration/render-tests/runtime-styling/image-add-1.5x-image-2x-screen/style.json b/test/integration/render-tests/runtime-styling/image-add-1.5x-image-2x-screen/style.json new file mode 100644 index 00000000000..5b974e9c878 --- /dev/null +++ b/test/integration/render-tests/runtime-styling/image-add-1.5x-image-2x-screen/style.json @@ -0,0 +1,42 @@ +{ + "version": 8, + "metadata": { + "test": { + "width": 64, + "height": 64, + "pixelRatio": 2, + "operations": [ + [ + "addImage", + "marker", + "./sprites/1.5x.png", + 1.5 + ], + [ + "addLayer", + { + "id": "geometry", + "type": "symbol", + "source": "geometry", + "layout": { + "icon-image": "marker" + } + } + ], + [ + "wait" + ] + ] + } + }, + "sources": { + "geometry": { + "type": "geojson", + "data": { + "type": "Point", + "coordinates": [0, 0] + } + } + }, + "layers": [] +} diff --git a/test/integration/sprites/1.5x.png b/test/integration/sprites/1.5x.png new file mode 100644 index 0000000000000000000000000000000000000000..75607750d6caa532afd25b93c4c54910973e767c GIT binary patch literal 3377 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 K^vZRdBmNCzFfDNa literal 0 HcmV?d00001 From 7478d792ce20367a94bfd6af43795a9de7535fa9 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 22 May 2017 11:53:38 -0700 Subject: [PATCH 4/4] Enable passing test in gl-native --- .../render-tests/icon-pixelratio-mismatch/default/style.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/integration/render-tests/icon-pixelratio-mismatch/default/style.json b/test/integration/render-tests/icon-pixelratio-mismatch/default/style.json index e3de2b695a5..f918c923c17 100644 --- a/test/integration/render-tests/icon-pixelratio-mismatch/default/style.json +++ b/test/integration/render-tests/icon-pixelratio-mismatch/default/style.json @@ -2,9 +2,6 @@ "version": 8, "metadata": { "test": { - "ignored": { - "native": "https://github.com/mapbox/mapbox-gl-native/issues/3164" - }, "pixelRatio": 0.5, "height": 256 } @@ -53,4 +50,4 @@ } } ] -} \ No newline at end of file +}