Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix pattern and icon rendering when pattern resolution does not match devicePixelRatio #1919

Merged
merged 1 commit into from
Jan 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion js/data/symbol_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ SymbolBucket.prototype.addFeatures = function(collisionTile, stacks, icons) {
this.tilePixelRatio = tileExtent / tileSize;
this.compareText = {};
this.symbolInstances = [];
this.iconsNeedLinear = false;

var layout = this.layoutProperties;
var features = this.features;
Expand Down Expand Up @@ -200,6 +201,9 @@ SymbolBucket.prototype.addFeatures = function(collisionTile, stacks, icons) {
} else if (this.sdfIcons !== image.sdf) {
console.warn('Style sheet warning: Cannot mix SDF and non-SDF icons in one buffer');
}
if (image.pixelRatio !== 1) {
this.iconsNeedLinear = true;
}
}
} else {
shapedIcon = null;
Expand Down Expand Up @@ -307,7 +311,8 @@ SymbolBucket.prototype.placeFeatures = function(collisionTile, buffers, collisio
var elementGroups = this.elementGroups = {
glyph: new ElementGroups(buffers.glyphVertex, buffers.glyphElement),
icon: new ElementGroups(buffers.iconVertex, buffers.iconElement),
sdfIcons: this.sdfIcons
sdfIcons: this.sdfIcons,
iconsNeedLinear: this.iconsNeedLinear
};

var layout = this.layoutProperties;
Expand Down
8 changes: 4 additions & 4 deletions js/render/draw_symbol.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function drawSymbols(painter, source, layer, coords) {

posMatrix = painter.calculatePosMatrix(coords[i], source.maxzoom);
painter.enableTileClippingMask(coords[i]);
drawSymbol(painter, layer, posMatrix, tile, elementGroups.icon, 'icon', elementGroups.sdfIcons);
drawSymbol(painter, layer, posMatrix, tile, elementGroups.icon, 'icon', elementGroups.sdfIcons, elementGroups.iconsNeedLinear);
}

for (var j = 0; j < coords.length; j++) {
Expand All @@ -53,7 +53,7 @@ function drawSymbols(painter, source, layer, coords) {

posMatrix = painter.calculatePosMatrix(coords[j], source.maxzoom);
painter.enableTileClippingMask(coords[j]);
drawSymbol(painter, layer, posMatrix, tile, elementGroups.glyph, 'text', true);
drawSymbol(painter, layer, posMatrix, tile, elementGroups.glyph, 'text', true, false);
}

for (var k = 0; k < coords.length; k++) {
Expand All @@ -73,7 +73,7 @@ var defaultSizes = {
text: 24
};

function drawSymbol(painter, layer, posMatrix, tile, elementGroups, prefix, sdf) {
function drawSymbol(painter, layer, posMatrix, tile, elementGroups, prefix, sdf, iconsNeedLinear) {
var gl = painter.gl;

posMatrix = painter.translatePosMatrix(posMatrix, tile, layer.paint[prefix + '-translate'], layer.paint[prefix + '-translate-anchor']);
Expand Down Expand Up @@ -125,7 +125,7 @@ function drawSymbol(painter, layer, posMatrix, tile, elementGroups, prefix, sdf)
texsize = [painter.glyphAtlas.width / 4, painter.glyphAtlas.height / 4];
} else {
var mapMoving = painter.options.rotating || painter.options.zooming;
var iconScaled = fontScale !== 1 || browser.devicePixelRatio !== painter.spriteAtlas.pixelRatio;
var iconScaled = fontScale !== 1 || browser.devicePixelRatio !== painter.spriteAtlas.pixelRatio || iconsNeedLinear;
var iconTransformed = alignedWithMap || painter.transform.pitch;
painter.spriteAtlas.bind(gl, sdf || mapMoving || iconScaled || iconTransformed);
vertex = tile.buffers.iconVertex;
Expand Down
1 change: 0 additions & 1 deletion js/style/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ function Style(stylesheet, animationLoop) {
this.dispatcher = new Dispatcher(Math.max(browser.hardwareConcurrency - 1, 1), this);
this.glyphAtlas = new GlyphAtlas(1024, 1024);
this.spriteAtlas = new SpriteAtlas(512, 512);
this.spriteAtlas.resize(browser.devicePixelRatio);
this.lineAtlas = new LineAtlas(256, 512);

this._layers = {};
Expand Down
4 changes: 2 additions & 2 deletions js/symbol/quads.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ function getIconQuads(anchor, shapedIcon, boxScale, line, layout, alongLine) {

var border = 1;
var left = shapedIcon.left - border;
var right = left + rect.w;
var right = left + rect.w / shapedIcon.image.pixelRatio;
var top = shapedIcon.top - border;
var bottom = top + rect.h;
var bottom = top + rect.h / shapedIcon.image.pixelRatio;
var tl = new Point(left, top);
var tr = new Point(right, top);
var br = new Point(right, bottom);
Expand Down
79 changes: 20 additions & 59 deletions js/symbol/sprite_atlas.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

var BinPack = require('./bin_pack');
var browser = require('../util/browser');

module.exports = SpriteAtlas;
function SpriteAtlas(width, height) {
Expand Down Expand Up @@ -37,51 +38,6 @@ SpriteAtlas.prototype = {
}
};

SpriteAtlas.prototype.resize = function(newRatio) {
newRatio = newRatio > 1 ? 2 : 1;

if (this.pixelRatio === newRatio) return false;

var oldRatio = this.pixelRatio;
this.pixelRatio = newRatio;

if (this.canvas) {
this.canvas.width = this.width * this.pixelRatio;
this.canvas.height = this.height * this.pixelRatio;
}

if (this.data) {
var oldData = this.data;

this.data = false;
this.allocate();
this.texture = false;

var oldWidth = this.width * oldRatio;
var oldHeight = this.height * oldRatio;
var newWidth = this.width * newRatio;
var newHeight = this.height * newRatio;

// Basic image scaling. TODO: Replace this with better image scaling.
var newImage = this.data;
var oldImage = oldData;

for (var y = 0; y < newHeight; y++) {
var oldYOffset = Math.floor((y * oldHeight) / newHeight) * oldWidth;
var newYOffset = y * newWidth;
for (var x = 0; x < newWidth; x++) {
var oldX = Math.floor((x * oldWidth) / newWidth);
newImage[newYOffset + x] = oldImage[oldYOffset + oldX];
}
}

oldData = null;
this.dirty = true;
}

return this.dirty;
};

function copyBitmap(src, srcStride, srcX, srcY, dst, dstStride, dstX, dstY, width, height, wrap) {
var srcI = srcY * srcStride + srcX;
var dstI = dstY * dstStride + dstX;
Expand All @@ -107,6 +63,9 @@ function copyBitmap(src, srcStride, srcX, srcY, dst, dstStride, dstX, dstY, widt

SpriteAtlas.prototype.allocateImage = function(pixelWidth, pixelHeight) {

pixelWidth = pixelWidth / this.pixelRatio;
pixelHeight = pixelHeight / this.pixelRatio;

// Increase to next number divisible by 4, but at least 1.
// This is so we can scale down the texture coordinates and pack them
// into 2 bytes rather than 4 bytes.
Expand All @@ -123,9 +82,6 @@ SpriteAtlas.prototype.allocateImage = function(pixelWidth, pixelHeight) {
return rect;
}

rect.originalWidth = pixelWidth;
rect.originalHeight = pixelHeight;

return rect;
};

Expand All @@ -143,14 +99,12 @@ SpriteAtlas.prototype.getImage = function(name, wrap) {
return null;
}

var width = pos.width / pos.pixelRatio;
var height = pos.height / pos.pixelRatio;
var rect = this.allocateImage(width, height);
var rect = this.allocateImage(pos.width, pos.height);
if (rect.x < 0) {
return rect;
}

var image = new AtlasImage(rect, width, height, pos.sdf);
var image = new AtlasImage(rect, pos.width / pos.pixelRatio, pos.height / pos.pixelRatio, pos.sdf, pos.pixelRatio / this.pixelRatio);
this.images[name] = image;

this.copy(rect, pos, wrap);
Expand All @@ -159,6 +113,7 @@ SpriteAtlas.prototype.getImage = function(name, wrap) {
};


// Return position of a repeating fill pattern.
SpriteAtlas.prototype.getPosition = function(name, repeating) {
var image = this.getImage(name, repeating);
var rect = image && image.rect;
Expand All @@ -167,14 +122,12 @@ SpriteAtlas.prototype.getPosition = function(name, repeating) {
return null;
}

// When the image is repeating, get the correct position of the image, rather than the
// one rounded up to 4 pixels.
var width = repeating ? image.width : rect.w;
var height = repeating ? image.height : rect.h;
var width = image.width * image.pixelRatio;
var height = image.height * image.pixelRatio;
var padding = 1;

return {
size: [width, height],
size: [image.width, image.height],
tl: [(rect.x + padding) / this.width, (rect.y + padding) / this.height],
br: [(rect.x + padding + width) / this.width, (rect.y + padding + height) / this.height]
};
Expand All @@ -194,7 +147,6 @@ SpriteAtlas.prototype.allocate = function() {


SpriteAtlas.prototype.copy = function(dst, src, wrap) {
// if (!sprite->raster) return;
if (!this.sprite.img.data) return;
var srcImg = new Uint32Array(this.sprite.img.data.buffer);

Expand All @@ -221,6 +173,14 @@ SpriteAtlas.prototype.copy = function(dst, src, wrap) {
};

SpriteAtlas.prototype.setSprite = function(sprite) {
if (sprite) {
this.pixelRatio = browser.devicePixelRatio > 1 ? 2 : 1;

if (this.canvas) {
this.canvas.width = this.width * this.pixelRatio;
this.canvas.height = this.height * this.pixelRatio;
}
}
this.sprite = sprite;
};

Expand Down Expand Up @@ -298,9 +258,10 @@ SpriteAtlas.prototype.bind = function(gl, linear) {
}
};

function AtlasImage(rect, width, height, sdf) {
function AtlasImage(rect, width, height, sdf, pixelRatio) {
this.rect = rect;
this.width = width;
this.height = height;
this.sdf = sdf;
this.pixelRatio = pixelRatio;
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"eslint": "^1.5.0",
"eslint-config-mourner": "^1.0.0",
"istanbul": "^0.4.1",
"mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#46c907f48d2b3b8ae6531963cdc40cb07958fd01",
"mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#a6fe23c8cccda72a0afde9a87f8c6aabd4dcccba",
"prova": "^2.1.2",
"sinon": "^1.15.4",
"st": "^1.0.0",
Expand Down
1 change: 1 addition & 0 deletions test/js/symbol/quads.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ test('getIconQuads', function(t) {
left: -7,
right: 8,
image: {
pixelRatio: 1,
rect: { w: 15, h: 11}
}
};
Expand Down