[core] parse stretchX, stretchX, and content from sprite JSON files
This commit is contained in:
committed by
Alexander Shalamov
parent
62b0f4cde2
commit
47dc5727ab
@@ -1,6 +1,7 @@
|
||||
#include <mbgl/sprite/sprite_parser.hpp>
|
||||
#include <mbgl/style/image.hpp>
|
||||
|
||||
#include <mbgl/util/exception.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <mbgl/util/image.hpp>
|
||||
@@ -19,16 +20,24 @@ std::unique_ptr<style::Image> createStyleImage(const std::string& id,
|
||||
const uint32_t width,
|
||||
const uint32_t height,
|
||||
const double ratio,
|
||||
const bool sdf) {
|
||||
const bool sdf,
|
||||
style::ImageStretches&& stretchX,
|
||||
style::ImageStretches&& stretchY,
|
||||
optional<style::ImageContent> content) {
|
||||
// Disallow invalid parameter configurations.
|
||||
if (width <= 0 || height <= 0 || width > 1024 || height > 1024 ||
|
||||
ratio <= 0 || ratio > 10 ||
|
||||
srcX >= image.size.width || srcY >= image.size.height ||
|
||||
srcX + width > image.size.width || srcY + height > image.size.height) {
|
||||
Log::Error(Event::Sprite, "Can't create image with invalid metrics: %ux%u@%u,%u in %ux%u@%sx sprite",
|
||||
width, height, srcX, srcY,
|
||||
image.size.width, image.size.height,
|
||||
util::toString(ratio).c_str());
|
||||
Log::Error(Event::Sprite,
|
||||
"Can't create image with invalid metrics: %ux%u@%u,%u in %ux%u@%sx sprite",
|
||||
width,
|
||||
height,
|
||||
srcX,
|
||||
srcY,
|
||||
image.size.width,
|
||||
image.size.height,
|
||||
util::toString(ratio).c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -37,51 +46,107 @@ std::unique_ptr<style::Image> createStyleImage(const std::string& id,
|
||||
// Copy from the source image into our individual sprite image
|
||||
PremultipliedImage::copy(image, dstImage, { srcX, srcY }, { 0, 0 }, { width, height });
|
||||
|
||||
return std::make_unique<style::Image>(id, std::move(dstImage), ratio, sdf);
|
||||
try {
|
||||
return std::make_unique<style::Image>(
|
||||
id, std::move(dstImage), ratio, sdf, std::move(stretchX), std::move(stretchY), std::move(content));
|
||||
} catch (const util::StyleImageException& ex) {
|
||||
Log::Error(Event::Sprite, "Can't create image with invalid metadata: %s", ex.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
uint16_t getUInt16(const JSValue& value, const char* name, const uint16_t def = 0) {
|
||||
if (value.HasMember(name)) {
|
||||
auto& v = value[name];
|
||||
uint16_t getUInt16(const JSValue& value, const char* property, const char* name, const uint16_t def = 0) {
|
||||
if (value.HasMember(property)) {
|
||||
auto& v = value[property];
|
||||
if (v.IsUint() && v.GetUint() <= std::numeric_limits<uint16_t>::max()) {
|
||||
return v.GetUint();
|
||||
} else {
|
||||
Log::Warning(Event::Sprite, "Value of '%s' must be an integer between 0 and 65535",
|
||||
name);
|
||||
Log::Warning(Event::Sprite,
|
||||
"Invalid sprite image '%s': value of '%s' must be an integer between 0 and 65535",
|
||||
name,
|
||||
property);
|
||||
}
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
double getDouble(const JSValue& value, const char* name, const double def = 0) {
|
||||
if (value.HasMember(name)) {
|
||||
auto& v = value[name];
|
||||
double getDouble(const JSValue& value, const char* property, const char* name, const double def = 0) {
|
||||
if (value.HasMember(property)) {
|
||||
auto& v = value[property];
|
||||
if (v.IsNumber()) {
|
||||
return v.GetDouble();
|
||||
} else {
|
||||
Log::Warning(Event::Sprite, "Value of '%s' must be a number", name);
|
||||
Log::Warning(Event::Sprite, "Invalid sprite image '%s': value of '%s' must be a number", name, property);
|
||||
}
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
bool getBoolean(const JSValue& value, const char* name, const bool def = false) {
|
||||
if (value.HasMember(name)) {
|
||||
auto& v = value[name];
|
||||
bool getBoolean(const JSValue& value, const char* property, const char* name, const bool def = false) {
|
||||
if (value.HasMember(property)) {
|
||||
auto& v = value[property];
|
||||
if (v.IsBool()) {
|
||||
return v.GetBool();
|
||||
} else {
|
||||
Log::Warning(Event::Sprite, "Value of '%s' must be a boolean", name);
|
||||
Log::Warning(Event::Sprite, "Invalid sprite image '%s': value of '%s' must be a boolean", name, property);
|
||||
}
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
style::ImageStretches getStretches(const JSValue& value, const char* property, const char* name) {
|
||||
style::ImageStretches stretches;
|
||||
|
||||
if (value.HasMember(property)) {
|
||||
auto& v = value[property];
|
||||
if (v.IsArray()) {
|
||||
for (rapidjson::SizeType i = 0; i < v.Size(); ++i) {
|
||||
const JSValue& stretch = v[i];
|
||||
if (stretch.IsArray() && stretch.Size() == 2 && stretch[rapidjson::SizeType(0)].IsNumber() &&
|
||||
stretch[rapidjson::SizeType(1)].IsNumber()) {
|
||||
stretches.emplace_back(style::ImageStretch{stretch[rapidjson::SizeType(0)].GetFloat(),
|
||||
stretch[rapidjson::SizeType(1)].GetFloat()});
|
||||
} else {
|
||||
Log::Warning(Event::Sprite,
|
||||
"Invalid sprite image '%s': members of '%s' must be an array of two numbers",
|
||||
name,
|
||||
property);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log::Warning(Event::Sprite, "Invalid sprite image '%s': value of '%s' must be an array", name, property);
|
||||
}
|
||||
}
|
||||
|
||||
return stretches;
|
||||
}
|
||||
|
||||
optional<style::ImageContent> getContent(const JSValue& value, const char* property, const char* name) {
|
||||
if (value.HasMember(property)) {
|
||||
auto& content = value[property];
|
||||
if (content.IsArray() && content.Size() == 4 && content[rapidjson::SizeType(0)].IsNumber() &&
|
||||
content[rapidjson::SizeType(1)].IsNumber() && content[rapidjson::SizeType(2)].IsNumber() &&
|
||||
content[rapidjson::SizeType(3)].IsNumber()) {
|
||||
return style::ImageContent{content[rapidjson::SizeType(0)].GetFloat(),
|
||||
content[rapidjson::SizeType(1)].GetFloat(),
|
||||
content[rapidjson::SizeType(2)].GetFloat(),
|
||||
content[rapidjson::SizeType(3)].GetFloat()};
|
||||
} else {
|
||||
Log::Warning(Event::Sprite,
|
||||
"Invalid sprite image '%s': value of '%s' must be an array of four numbers",
|
||||
name,
|
||||
property);
|
||||
}
|
||||
}
|
||||
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::vector<std::unique_ptr<style::Image>> parseSprite(const std::string& encodedImage, const std::string& json) {
|
||||
@@ -100,14 +165,27 @@ std::vector<std::unique_ptr<style::Image>> parseSprite(const std::string& encode
|
||||
const JSValue& value = property.value;
|
||||
|
||||
if (value.IsObject()) {
|
||||
const uint16_t x = getUInt16(value, "x", 0);
|
||||
const uint16_t y = getUInt16(value, "y", 0);
|
||||
const uint16_t width = getUInt16(value, "width", 0);
|
||||
const uint16_t height = getUInt16(value, "height", 0);
|
||||
const double pixelRatio = getDouble(value, "pixelRatio", 1);
|
||||
const bool sdf = getBoolean(value, "sdf", false);
|
||||
const uint16_t x = getUInt16(value, "x", name.c_str(), 0);
|
||||
const uint16_t y = getUInt16(value, "y", name.c_str(), 0);
|
||||
const uint16_t width = getUInt16(value, "width", name.c_str(), 0);
|
||||
const uint16_t height = getUInt16(value, "height", name.c_str(), 0);
|
||||
const double pixelRatio = getDouble(value, "pixelRatio", name.c_str(), 1);
|
||||
const bool sdf = getBoolean(value, "sdf", name.c_str(), false);
|
||||
style::ImageStretches stretchX = getStretches(value, "stretchX", name.c_str());
|
||||
style::ImageStretches stretchY = getStretches(value, "stretchY", name.c_str());
|
||||
optional<style::ImageContent> content = getContent(value, "content", name.c_str());
|
||||
|
||||
auto image = createStyleImage(name, raster, x, y, width, height, pixelRatio, sdf);
|
||||
auto image = createStyleImage(name,
|
||||
raster,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
pixelRatio,
|
||||
sdf,
|
||||
std::move(stretchX),
|
||||
std::move(stretchY),
|
||||
std::move(content));
|
||||
if (image) {
|
||||
images.push_back(std::move(image));
|
||||
}
|
||||
|
||||
@@ -1,17 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/image.hpp>
|
||||
#include <mbgl/style/image.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace style {
|
||||
class Image;
|
||||
} // namespace style
|
||||
|
||||
// Extracts an individual image from a spritesheet from the given location.
|
||||
std::unique_ptr<style::Image> createStyleImage(const std::string& id,
|
||||
const PremultipliedImage&,
|
||||
@@ -20,7 +14,10 @@ std::unique_ptr<style::Image> createStyleImage(const std::string& id,
|
||||
uint32_t srcWidth,
|
||||
uint32_t srcHeight,
|
||||
double ratio,
|
||||
bool sdf);
|
||||
bool sdf,
|
||||
style::ImageStretches&& stretchX = {},
|
||||
style::ImageStretches&& stretchY = {},
|
||||
optional<style::ImageContent> content = nullopt);
|
||||
|
||||
// Parses an image and an associated JSON file and returns the sprite objects.
|
||||
std::vector<std::unique_ptr<style::Image>> parseSprite(const std::string& image, const std::string& json);
|
||||
|
||||
@@ -27,111 +27,160 @@ TEST(Sprite, SpriteImageCreationInvalid) {
|
||||
ASSERT_EQ(200u, image_1x.size.width);
|
||||
ASSERT_EQ(299u, image_1x.size.height);
|
||||
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 0, 16, 1, false)); // width == 0
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 16, 0, 1, false)); // height == 0
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, -1, 16, 1, false)); // width < 0
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 16, -1, 1, false)); // height < 0
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 1, 1, 0, false)); // ratio == 0
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 1, 1, -1, false)); // ratio < 0
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 1, 1, 23, false)); // ratio too large
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 0, 16, 1, false)); // width == 0
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 0x16@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 16, 0, 1, false)); // height == 0
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 16x0@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, -1, 16, 1, false)); // width < 0
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 4294967295x16@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 16, -1, 1, false)); // height < 0
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 16x4294967295@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 1, 1, 0, false)); // ratio == 0
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 1x1@0,0 in 200x299@0x sprite",
|
||||
}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 1, 1, -1, false)); // ratio < 0
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 1x1@0,0 in 200x299@-1x sprite",
|
||||
}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 1, 1, 23, false)); // ratio too large
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 1x1@0,0 in 200x299@23x sprite",
|
||||
}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 2048, 16, 1, false)); // too wide
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 2048x16@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 16, 1025, 1, false)); // too tall
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, -1, 0, 16, 16, 1, false)); // srcX < 0
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, -1, 16, 16, 1, false)); // srcY < 0
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, image_1x.size.width + 1, 16, 1, false)); // right edge out of bounds
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 16, image_1x.size.height + 1, 1, false)); // bottom edge out of bounds
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 16x1025@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 0x16@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, -1, 0, 16, 16, 1, false)); // srcX < 0
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 16x16@4294967295,0 in 200x299@1x sprite",
|
||||
}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 16x0@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, -1, 16, 16, 1, false)); // srcY < 0
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 16x16@0,4294967295 in 200x299@1x sprite",
|
||||
}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 4294967295x16@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
ASSERT_EQ(
|
||||
nullptr,
|
||||
createStyleImage("test", image_1x, 0, 0, image_1x.size.width + 1, 16, 1, false)); // right edge out of bounds
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 201x16@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 16x4294967295@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
ASSERT_EQ(
|
||||
nullptr,
|
||||
createStyleImage("test", image_1x, 0, 0, 16, image_1x.size.height + 1, 1, false)); // bottom edge out of bounds
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 16x300@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 1x1@0,0 in 200x299@0x sprite",
|
||||
}));
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 1x1@0,0 in 200x299@-1x sprite",
|
||||
}));
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 1x1@0,0 in 200x299@23x sprite",
|
||||
}));
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 2048x16@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 16x1025@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 16x16@4294967295,0 in 200x299@1x sprite",
|
||||
}));
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 16x16@0,4294967295 in 200x299@1x sprite",
|
||||
}));
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 201x16@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 16x300@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
ASSERT_EQ(nullptr, createStyleImage("test", image_1x, 0, 0, 16, 16, 1, false, {{-1, 3}}));
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metadata: stretchX is out of bounds or overlapping",
|
||||
}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
ASSERT_EQ(nullptr,
|
||||
createStyleImage("test", image_1x, 0, 0, 16, 16, 1, false, {}, {}, style::ImageContent{14, 14, 12, 10}));
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metadata: content area is invalid",
|
||||
}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
}
|
||||
|
||||
TEST(Sprite, SpriteImageCreation1x) {
|
||||
@@ -294,6 +343,129 @@ TEST(Sprite, SpriteParsingInvalidJSON) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Sprite, SpriteParsingInvalidStretches) {
|
||||
FixtureLog log;
|
||||
|
||||
const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
|
||||
|
||||
parseSprite(image_1x, R"JSON({
|
||||
"interstate_1": {
|
||||
"width": 40,
|
||||
"height": 42,
|
||||
"x": 100,
|
||||
"y": 44,
|
||||
"pixelRatio": 1,
|
||||
"stretchX": {}
|
||||
}
|
||||
})JSON");
|
||||
EXPECT_EQ(1u,
|
||||
log.count({EventSeverity::Warning,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Invalid sprite image 'interstate_1': value of 'stretchX' must be an array"}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
parseSprite(image_1x, R"JSON({
|
||||
"interstate_1": {
|
||||
"width": 40,
|
||||
"height": 42,
|
||||
"x": 100,
|
||||
"y": 44,
|
||||
"pixelRatio": 1,
|
||||
"stretchX": [[[]]]
|
||||
}
|
||||
})JSON");
|
||||
EXPECT_EQ(
|
||||
1u,
|
||||
log.count({EventSeverity::Warning,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Invalid sprite image 'interstate_1': members of 'stretchX' must be an array of two numbers"}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
parseSprite(image_1x, R"JSON({
|
||||
"interstate_1": {
|
||||
"width": 40,
|
||||
"height": 42,
|
||||
"x": 100,
|
||||
"y": 44,
|
||||
"pixelRatio": 1,
|
||||
"stretchX": [[4, false]]
|
||||
}
|
||||
})JSON");
|
||||
EXPECT_EQ(
|
||||
1u,
|
||||
log.count({EventSeverity::Warning,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Invalid sprite image 'interstate_1': members of 'stretchX' must be an array of two numbers"}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
}
|
||||
|
||||
TEST(Sprite, SpriteParsingInvalidContent) {
|
||||
FixtureLog log;
|
||||
|
||||
const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
|
||||
|
||||
parseSprite(image_1x, R"JSON({
|
||||
"interstate_1": {
|
||||
"width": 40,
|
||||
"height": 42,
|
||||
"x": 100,
|
||||
"y": 44,
|
||||
"pixelRatio": 1,
|
||||
"content": []
|
||||
}
|
||||
})JSON");
|
||||
EXPECT_EQ(1u,
|
||||
log.count({EventSeverity::Warning,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Invalid sprite image 'interstate_1': value of 'content' must be an array of four numbers"}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
|
||||
parseSprite(image_1x, R"JSON({
|
||||
"interstate_1": {
|
||||
"width": 40,
|
||||
"height": 42,
|
||||
"x": 100,
|
||||
"y": 44,
|
||||
"pixelRatio": 1,
|
||||
"content": [4, 4, 4, true]
|
||||
}
|
||||
})JSON");
|
||||
EXPECT_EQ(1u,
|
||||
log.count({EventSeverity::Warning,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Invalid sprite image 'interstate_1': value of 'content' must be an array of four numbers"}));
|
||||
EXPECT_EQ(0u, log.uncheckedCount());
|
||||
}
|
||||
|
||||
TEST(Sprite, SpriteParsingStretchAndContent) {
|
||||
FixtureLog log;
|
||||
|
||||
const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
|
||||
|
||||
const auto images = parseSprite(image_1x, R"JSON({
|
||||
"image": {
|
||||
"width": 16,
|
||||
"height": 16,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"pixelRatio": 1,
|
||||
"stretchX": [[2, 14]],
|
||||
"stretchY": [[0, 4], [12, 16]],
|
||||
"content": [2, 2, 14, 14]
|
||||
}
|
||||
})JSON");
|
||||
EXPECT_EQ(1u, images.size());
|
||||
EXPECT_EQ("image", images[0]->getID());
|
||||
EXPECT_EQ((style::ImageStretches{{2, 14}}), images[0]->getStretchX());
|
||||
EXPECT_EQ((style::ImageStretches{{0, 4}, {12, 16}}), images[0]->getStretchY());
|
||||
EXPECT_EQ((style::ImageContent{2, 2, 14, 14}), images[0]->getContent());
|
||||
}
|
||||
|
||||
TEST(Sprite, SpriteParsingEmptyImage) {
|
||||
FixtureLog log;
|
||||
|
||||
@@ -303,12 +475,13 @@ TEST(Sprite, SpriteParsingEmptyImage) {
|
||||
const auto images = parseSprite(image_1x, json_1x);
|
||||
EXPECT_EQ(0u, images.size());
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 0x0@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 0x0@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
}
|
||||
|
||||
TEST(Sprite, SpriteParsingSimpleWidthHeight) {
|
||||
@@ -330,18 +503,20 @@ TEST(Sprite, SpriteParsingWidthTooBig) {
|
||||
const auto images = parseSprite(image_1x, json_1x);
|
||||
EXPECT_EQ(0u, images.size());
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Warning,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Value of 'width' must be an integer between 0 and 65535",
|
||||
}));
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 0x32@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Warning,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Invalid sprite image 'image': value of 'width' must be an integer between 0 and 65535",
|
||||
}));
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 0x32@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
}
|
||||
|
||||
TEST(Sprite, SpriteParsingNegativeWidth) {
|
||||
@@ -353,18 +528,20 @@ TEST(Sprite, SpriteParsingNegativeWidth) {
|
||||
const auto images = parseSprite(image_1x, json_1x);
|
||||
EXPECT_EQ(0u, images.size());
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Warning,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Value of 'width' must be an integer between 0 and 65535",
|
||||
}));
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 0x32@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Warning,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Invalid sprite image 'image': value of 'width' must be an integer between 0 and 65535",
|
||||
}));
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 0x32@0,0 in 200x299@1x sprite",
|
||||
}));
|
||||
}
|
||||
|
||||
TEST(Sprite, SpriteParsingNullRatio) {
|
||||
@@ -376,10 +553,11 @@ TEST(Sprite, SpriteParsingNullRatio) {
|
||||
const auto images = parseSprite(image_1x, json_1x);
|
||||
EXPECT_EQ(0u, images.size());
|
||||
|
||||
EXPECT_EQ(1u, log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 32x32@0,0 in 200x299@0x sprite",
|
||||
}));
|
||||
EXPECT_EQ(1u,
|
||||
log.count({
|
||||
EventSeverity::Error,
|
||||
Event::Sprite,
|
||||
int64_t(-1),
|
||||
"Can't create image with invalid metrics: 32x32@0,0 in 200x299@0x sprite",
|
||||
}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user