port sprite atlas pollution fix
fixes #1398 js: 212760981493460b438f1cc117001825773fad91 https://github.com/mapbox/mapbox-gl-js/pull/1195 The sprite atlas already had two empty pixels between each each icon. But the icon's real boundary isn't used for drawing. Drawing uses an icon's box rounded up to the nearest multiple of four. Sometimes this rounded boundary was directly on the edge of another icon. When the icon was sampled with linear interpolation it's edge would get polluted with values from the other icon. This commit shifts all icons and glyphs by 1px so that there is padding on all sides of the box being drawn. The quads used for drawing are shifted in the opposite direction by 1px to compensate for this.
This commit is contained in:
committed by
John Firebaugh
parent
d7bd429619
commit
03d5e2da80
@@ -69,8 +69,9 @@ Rect<uint16_t> GlyphAtlas::addGlyph(uintptr_t tileUID,
|
||||
uint16_t buffered_height = glyph.metrics.height + buffer * 2;
|
||||
|
||||
// Add a 1px border around every image.
|
||||
uint16_t pack_width = buffered_width;
|
||||
uint16_t pack_height = buffered_height;
|
||||
const uint16_t padding = 1;
|
||||
uint16_t pack_width = buffered_width + 2 * padding;
|
||||
uint16_t pack_height = buffered_height + 2 * padding;
|
||||
|
||||
// Increase to next number divisible by 4, but at least 1.
|
||||
// This is so we can scale down the texture coordinates and pack them
|
||||
@@ -92,7 +93,7 @@ Rect<uint16_t> GlyphAtlas::addGlyph(uintptr_t tileUID,
|
||||
// Copy the bitmap
|
||||
const uint8_t* source = reinterpret_cast<const uint8_t*>(glyph.bitmap.data());
|
||||
for (uint32_t y = 0; y < buffered_height; y++) {
|
||||
uint32_t y1 = width * (rect.y + y) + rect.x;
|
||||
uint32_t y1 = width * (rect.y + y + padding) + rect.x + padding;
|
||||
uint32_t y2 = buffered_width * y;
|
||||
for (uint32_t x = 0; x < buffered_width; x++) {
|
||||
data[y1 + x] = source[y2 + x];
|
||||
|
||||
@@ -127,10 +127,12 @@ SpriteAtlasPosition SpriteAtlas::getPosition(const std::string& name, bool repea
|
||||
rect.h = pos.height / pos.pixelRatio;
|
||||
}
|
||||
|
||||
const float padding = 1;
|
||||
|
||||
return SpriteAtlasPosition {
|
||||
{{ float(rect.w), float(rect.h) }},
|
||||
{{ float(rect.x) / width, float(rect.y) / height }},
|
||||
{{ float(rect.x + rect.w) / width, float(rect.y + rect.h) / height }}
|
||||
{{ float(rect.x + padding) / width, float(rect.y + padding) / height }},
|
||||
{{ float(rect.x + padding + rect.w) / width, float(rect.y + padding + rect.h) / height }}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -151,12 +153,14 @@ void SpriteAtlas::copy(const Rect<dimension>& dst, const SpritePosition& src, co
|
||||
const vec2<uint32_t> srcSize { sprite->raster->getWidth(), sprite->raster->getHeight() };
|
||||
const Rect<uint32_t> srcPos { src.x, src.y, src.width, src.height };
|
||||
|
||||
const int offset = 1;
|
||||
|
||||
allocate();
|
||||
uint32_t *const dstData = data.get();
|
||||
const vec2<uint32_t> dstSize { static_cast<unsigned int>(width * pixelRatio),
|
||||
static_cast<unsigned int>(height * pixelRatio) };
|
||||
const Rect<uint32_t> dstPos { static_cast<uint32_t>(dst.x * pixelRatio),
|
||||
static_cast<uint32_t>(dst.y * pixelRatio),
|
||||
const Rect<uint32_t> dstPos { static_cast<uint32_t>((offset + dst.x) * pixelRatio),
|
||||
static_cast<uint32_t>((offset + dst.y) * pixelRatio),
|
||||
static_cast<uint32_t>(dst.originalW * pixelRatio),
|
||||
static_cast<uint32_t>(dst.originalH * pixelRatio) };
|
||||
|
||||
|
||||
@@ -135,11 +135,12 @@ GlyphBox getMergedBoxes(const GlyphBoxes &glyphs, const Anchor &anchor) {
|
||||
Placement Placement::getIcon(Anchor &anchor, const Rect<uint16_t> &image, float boxScale,
|
||||
const std::vector<Coordinate> &line, const StyleLayoutSymbol &layout) {
|
||||
|
||||
const float padding = 1.0f;
|
||||
const float dx = layout.icon.offset[0];
|
||||
const float dy = layout.icon.offset[1];
|
||||
float x1 = dx - image.originalW / 2.0f;
|
||||
float x1 = dx - image.originalW / 2.0f - padding;
|
||||
float x2 = x1 + image.w;
|
||||
float y1 = dy - image.originalH / 2.0f;
|
||||
float y1 = dy - image.originalH / 2.0f - padding;
|
||||
float y2 = y1 + image.h;
|
||||
|
||||
vec2<float> tl{x1, y1};
|
||||
@@ -212,7 +213,8 @@ Placement Placement::getGlyphs(Anchor &anchor, const vec2<float> &origin, const
|
||||
|
||||
Placement placement;
|
||||
|
||||
const uint32_t buffer = 3;
|
||||
const uint32_t glyphPadding = 1;
|
||||
const uint32_t buffer = 3 + glyphPadding;
|
||||
|
||||
for (const auto& shape : shaping) {
|
||||
auto face_it = face.find(shape.glyph);
|
||||
|
||||
Reference in New Issue
Block a user