mirror of https://github.com/aseprite/aseprite.git
Move code related to UserData::Variants to doc/user_data.cpp
Only code that is related to <iostream> IO is in _io.cpp files.
This commit is contained in:
parent
a7b5ab24bb
commit
70a388177d
|
|
@ -1,5 +1,5 @@
|
||||||
# Aseprite Document Library
|
# Aseprite Document Library
|
||||||
# Copyright (C) 2019-2022 Igara Studio S.A.
|
# Copyright (C) 2019-2023 Igara Studio S.A.
|
||||||
# Copyright (C) 2001-2018 David Capello
|
# Copyright (C) 2001-2018 David Capello
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|
@ -74,6 +74,7 @@ add_library(doc-lib
|
||||||
tileset.cpp
|
tileset.cpp
|
||||||
tileset_io.cpp
|
tileset_io.cpp
|
||||||
tilesets.cpp
|
tilesets.cpp
|
||||||
|
user_data.cpp
|
||||||
user_data_io.cpp
|
user_data_io.cpp
|
||||||
util.cpp)
|
util.cpp)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,218 @@
|
||||||
|
// Aseprite Document Library
|
||||||
|
// Copyright (c) 2023 Igara Studio S.A.
|
||||||
|
//
|
||||||
|
// This file is released under the terms of the MIT license.
|
||||||
|
// Read LICENSE.txt for more information.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "doc/user_data.h"
|
||||||
|
|
||||||
|
namespace doc {
|
||||||
|
|
||||||
|
size_t count_nonempty_properties_maps(const UserData::PropertiesMaps& propertiesMaps)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
for (const auto& it : propertiesMaps)
|
||||||
|
if (!it.second.empty())
|
||||||
|
++i;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_negative(const UserData::Variant& value)
|
||||||
|
{
|
||||||
|
switch (value.type()) {
|
||||||
|
case USER_DATA_PROPERTY_TYPE_INT8: {
|
||||||
|
auto v = get_value<int8_t>(value);
|
||||||
|
return v < 0;
|
||||||
|
}
|
||||||
|
case USER_DATA_PROPERTY_TYPE_INT16: {
|
||||||
|
auto v = get_value<int16_t>(value);
|
||||||
|
return v < 0;
|
||||||
|
}
|
||||||
|
case USER_DATA_PROPERTY_TYPE_INT32: {
|
||||||
|
auto v = get_value<int32_t>(value);
|
||||||
|
return v < 0;
|
||||||
|
}
|
||||||
|
case USER_DATA_PROPERTY_TYPE_INT64: {
|
||||||
|
auto v = get_value<int64_t>(value);
|
||||||
|
return v < 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t all_elements_of_same_type(const UserData::Vector& vector)
|
||||||
|
{
|
||||||
|
uint16_t type = vector.empty() ? 0 : vector.front().type();
|
||||||
|
uint16_t commonReducedType = 0;
|
||||||
|
bool hasNegativeNumbers = false;
|
||||||
|
for (auto value : vector) {
|
||||||
|
if (type != value.type()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (IS_REDUCIBLE_INT(value.type())) {
|
||||||
|
auto t = reduce_int_type_size(value).type();
|
||||||
|
hasNegativeNumbers |= is_negative(value);
|
||||||
|
if (t > commonReducedType) {
|
||||||
|
commonReducedType = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: The following check probably is not useful right now, I believe this could
|
||||||
|
// become useful if at some point we want to try to find a common integer type for vectors
|
||||||
|
// that contains elements of different integer types only.
|
||||||
|
|
||||||
|
// If our common reduced type is unsigned and we have negative numbers
|
||||||
|
// in our vector we should select the next signed type that includes it.
|
||||||
|
if (commonReducedType != 0 &&
|
||||||
|
(commonReducedType & 1) &&
|
||||||
|
hasNegativeNumbers) {
|
||||||
|
commonReducedType++;
|
||||||
|
// We couldn't find one type that satisfies all the integers. This shouldn't ever happen.
|
||||||
|
if (commonReducedType >= USER_DATA_PROPERTY_TYPE_UINT64) commonReducedType = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return commonReducedType ? commonReducedType : type;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserData::Variant cast_to_smaller_int_type(const UserData::Variant& value, uint16_t type)
|
||||||
|
{
|
||||||
|
ASSERT(type < value.type());
|
||||||
|
switch (value.type()) {
|
||||||
|
case USER_DATA_PROPERTY_TYPE_INT16: {
|
||||||
|
auto v = get_value<int16_t>(value);
|
||||||
|
if (type == USER_DATA_PROPERTY_TYPE_INT8)
|
||||||
|
return static_cast<int8_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_UINT8)
|
||||||
|
return static_cast<uint8_t>(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USER_DATA_PROPERTY_TYPE_UINT16: {
|
||||||
|
auto v = get_value<uint16_t>(value);
|
||||||
|
if (type == USER_DATA_PROPERTY_TYPE_INT8)
|
||||||
|
return static_cast<int8_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_UINT8)
|
||||||
|
return static_cast<uint8_t>(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USER_DATA_PROPERTY_TYPE_INT32: {
|
||||||
|
auto v = get_value<int32_t>(value);
|
||||||
|
if (type == USER_DATA_PROPERTY_TYPE_INT8)
|
||||||
|
return static_cast<int8_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_UINT8)
|
||||||
|
return static_cast<uint8_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_INT16)
|
||||||
|
return static_cast<int16_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_UINT16)
|
||||||
|
return static_cast<uint16_t>(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USER_DATA_PROPERTY_TYPE_UINT32: {
|
||||||
|
auto v = get_value<uint32_t>(value);
|
||||||
|
if (type == USER_DATA_PROPERTY_TYPE_INT8)
|
||||||
|
return static_cast<int8_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_UINT8)
|
||||||
|
return static_cast<uint8_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_INT16)
|
||||||
|
return static_cast<int16_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_UINT16)
|
||||||
|
return static_cast<uint16_t>(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USER_DATA_PROPERTY_TYPE_INT64: {
|
||||||
|
auto v = get_value<int64_t>(value);
|
||||||
|
if (type == USER_DATA_PROPERTY_TYPE_INT8)
|
||||||
|
return static_cast<int8_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_UINT8)
|
||||||
|
return static_cast<uint8_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_INT16)
|
||||||
|
return static_cast<int16_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_UINT16)
|
||||||
|
return static_cast<uint16_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_INT32)
|
||||||
|
return static_cast<int32_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_UINT32)
|
||||||
|
return static_cast<uint32_t>(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USER_DATA_PROPERTY_TYPE_UINT64: {
|
||||||
|
auto v = get_value<uint64_t>(value);
|
||||||
|
if (type == USER_DATA_PROPERTY_TYPE_INT8)
|
||||||
|
return static_cast<int8_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_UINT8)
|
||||||
|
return static_cast<uint8_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_INT16)
|
||||||
|
return static_cast<int16_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_UINT16)
|
||||||
|
return static_cast<uint16_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_INT32)
|
||||||
|
return static_cast<int32_t>(v);
|
||||||
|
else if (type == USER_DATA_PROPERTY_TYPE_UINT32)
|
||||||
|
return static_cast<uint32_t>(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserData::Variant reduce_int_type_size(const UserData::Variant& value)
|
||||||
|
{
|
||||||
|
switch (value.type()) {
|
||||||
|
case USER_DATA_PROPERTY_TYPE_INT16: {
|
||||||
|
auto v = get_value<int16_t>(value);
|
||||||
|
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
||||||
|
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
case USER_DATA_PROPERTY_TYPE_UINT16: {
|
||||||
|
auto v = get_value<uint16_t>(value);
|
||||||
|
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
||||||
|
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
case USER_DATA_PROPERTY_TYPE_INT32: {
|
||||||
|
auto v = get_value<int32_t>(value);
|
||||||
|
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
||||||
|
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
||||||
|
else if (INT16_COMPATIBLE(v)) return static_cast<int16_t>(v);
|
||||||
|
else if (UINT16_COMPATIBLE(v)) return static_cast<uint16_t>(v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
case USER_DATA_PROPERTY_TYPE_UINT32: {
|
||||||
|
auto v = get_value<uint32_t>(value);
|
||||||
|
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
||||||
|
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
||||||
|
else if (INT16_COMPATIBLE(v)) return static_cast<int16_t>(v);
|
||||||
|
else if (UINT16_COMPATIBLE(v)) return static_cast<uint16_t>(v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
case USER_DATA_PROPERTY_TYPE_INT64: {
|
||||||
|
auto v = get_value<int64_t>(value);
|
||||||
|
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
||||||
|
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
||||||
|
else if (INT16_COMPATIBLE(v)) return static_cast<int16_t>(v);
|
||||||
|
else if (UINT16_COMPATIBLE(v)) return static_cast<uint16_t>(v);
|
||||||
|
else if (INT32_COMPATIBLE(v)) return static_cast<int32_t>(v);
|
||||||
|
else if (UINT32_COMPATIBLE(v)) return static_cast<uint32_t>(v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
case USER_DATA_PROPERTY_TYPE_UINT64: {
|
||||||
|
auto v = get_value<uint64_t>(value);
|
||||||
|
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
||||||
|
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
||||||
|
else if (INT16_COMPATIBLE(v)) return static_cast<int16_t>(v);
|
||||||
|
else if (UINT16_COMPATIBLE(v)) return static_cast<uint16_t>(v);
|
||||||
|
else if (INT32_COMPATIBLE(v)) return static_cast<int32_t>(v);
|
||||||
|
else if (UINT32_COMPATIBLE(v)) return static_cast<uint32_t>(v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -160,13 +160,13 @@ namespace doc {
|
||||||
|
|
||||||
size_t count_nonempty_properties_maps(const UserData::PropertiesMaps& propertiesMaps);
|
size_t count_nonempty_properties_maps(const UserData::PropertiesMaps& propertiesMaps);
|
||||||
|
|
||||||
// If all the vector elements are of the same type returns such type.
|
// If all the elements of vector have the same type, returns that type, also
|
||||||
// Otherwise it returns -1.
|
// if this type is an integer, it tries to reduce it to the minimum int type
|
||||||
|
// capable of storing all the vector values.
|
||||||
|
// If all the elements of vector doesn't have the same type, returns 0.
|
||||||
uint16_t all_elements_of_same_type(const UserData::Vector& vector);
|
uint16_t all_elements_of_same_type(const UserData::Vector& vector);
|
||||||
|
|
||||||
UserData::Variant reduce_int_type_size(const UserData::Variant& value);
|
|
||||||
|
|
||||||
UserData::Variant cast_to_smaller_int_type(const UserData::Variant& value, uint16_t type);
|
UserData::Variant cast_to_smaller_int_type(const UserData::Variant& value, uint16_t type);
|
||||||
|
UserData::Variant reduce_int_type_size(const UserData::Variant& value);
|
||||||
|
|
||||||
} // namespace doc
|
} // namespace doc
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
// Aseprite Document Library
|
// Aseprite Document Library
|
||||||
|
// Copyright (c) 2023 Igara Studio S.A.
|
||||||
// Copyright (c) 2001-2015 David Capello
|
// Copyright (c) 2001-2015 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
|
|
@ -21,253 +22,19 @@ namespace doc {
|
||||||
using namespace base::serialization;
|
using namespace base::serialization;
|
||||||
using namespace base::serialization::little_endian;
|
using namespace base::serialization::little_endian;
|
||||||
|
|
||||||
void write_properties_maps(std::ostream& os, const UserData::PropertiesMaps& propertiesMaps);
|
static void write_point(std::ostream& os, const gfx::Point& point)
|
||||||
UserData::PropertiesMaps read_properties_maps(std::istream& is);
|
|
||||||
|
|
||||||
void write_user_data(std::ostream& os, const UserData& userData)
|
|
||||||
{
|
|
||||||
write_string(os, userData.text());
|
|
||||||
write32(os, userData.color());
|
|
||||||
write_properties_maps(os, userData.propertiesMaps());
|
|
||||||
}
|
|
||||||
|
|
||||||
UserData read_user_data(std::istream& is)
|
|
||||||
{
|
|
||||||
UserData userData;
|
|
||||||
userData.setText(read_string(is));
|
|
||||||
// This check is here because we've been restoring sprites from
|
|
||||||
// old sessions where the color is restored incorrectly if we
|
|
||||||
// don't check if there is enough space to read from the file
|
|
||||||
// (e.g. reading a random color or just white, maybe -1 which is
|
|
||||||
// 0xffffffff in 32-bit).
|
|
||||||
if (!is.eof()) {
|
|
||||||
userData.setColor(read32(is));
|
|
||||||
userData.propertiesMaps() = read_properties_maps(is);
|
|
||||||
}
|
|
||||||
return userData;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t count_nonempty_properties_maps(const UserData::PropertiesMaps& propertiesMaps)
|
|
||||||
{
|
|
||||||
size_t i = 0;
|
|
||||||
for (const auto& it : propertiesMaps)
|
|
||||||
if (!it.second.empty())
|
|
||||||
++i;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_negative(const UserData::Variant& value)
|
|
||||||
{
|
|
||||||
switch (value.type()) {
|
|
||||||
case USER_DATA_PROPERTY_TYPE_INT8: {
|
|
||||||
auto v = get_value<int8_t>(value);
|
|
||||||
return v < 0;
|
|
||||||
}
|
|
||||||
case USER_DATA_PROPERTY_TYPE_INT16: {
|
|
||||||
auto v = get_value<int16_t>(value);
|
|
||||||
return v < 0;
|
|
||||||
}
|
|
||||||
case USER_DATA_PROPERTY_TYPE_INT32: {
|
|
||||||
auto v = get_value<int32_t>(value);
|
|
||||||
return v < 0;
|
|
||||||
}
|
|
||||||
case USER_DATA_PROPERTY_TYPE_INT64: {
|
|
||||||
auto v = get_value<int64_t>(value);
|
|
||||||
return v < 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// If all the elements of vector have the same type, returns that type, also
|
|
||||||
// if this type is an integer, it tries to reduce it to the minimum int type
|
|
||||||
// capable of storing all the vector values.
|
|
||||||
// If all the elements of vector doesn't have the same type, returns 0.
|
|
||||||
uint16_t all_elements_of_same_type(const UserData::Vector& vector)
|
|
||||||
{
|
|
||||||
uint16_t type = vector.empty() ? 0 : vector.front().type();
|
|
||||||
uint16_t commonReducedType = 0;
|
|
||||||
bool hasNegativeNumbers = false;
|
|
||||||
for (auto value : vector) {
|
|
||||||
if (type != value.type()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (IS_REDUCIBLE_INT(value.type())) {
|
|
||||||
auto t = reduce_int_type_size(value).type();
|
|
||||||
hasNegativeNumbers |= is_negative(value);
|
|
||||||
if (t > commonReducedType) {
|
|
||||||
commonReducedType = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: The following check probably is not useful right now, I believe this could
|
|
||||||
// become useful if at some point we want to try to find a common integer type for vectors
|
|
||||||
// that contains elements of different integer types only.
|
|
||||||
|
|
||||||
// If our common reduced type is unsigned and we have negative numbers
|
|
||||||
// in our vector we should select the next signed type that includes it.
|
|
||||||
if (commonReducedType != 0 &&
|
|
||||||
(commonReducedType & 1) &&
|
|
||||||
hasNegativeNumbers) {
|
|
||||||
commonReducedType++;
|
|
||||||
// We couldn't find one type that satisfies all the integers. This shouldn't ever happen.
|
|
||||||
if (commonReducedType >= USER_DATA_PROPERTY_TYPE_UINT64) commonReducedType = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return commonReducedType ? commonReducedType : type;
|
|
||||||
}
|
|
||||||
|
|
||||||
UserData::Variant cast_to_smaller_int_type(const UserData::Variant& value, uint16_t type)
|
|
||||||
{
|
|
||||||
ASSERT(type < value.type());
|
|
||||||
switch (value.type()) {
|
|
||||||
case USER_DATA_PROPERTY_TYPE_INT16: {
|
|
||||||
auto v = get_value<int16_t>(value);
|
|
||||||
if (type == USER_DATA_PROPERTY_TYPE_INT8)
|
|
||||||
return static_cast<int8_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_UINT8)
|
|
||||||
return static_cast<uint8_t>(v);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case USER_DATA_PROPERTY_TYPE_UINT16: {
|
|
||||||
auto v = get_value<uint16_t>(value);
|
|
||||||
if (type == USER_DATA_PROPERTY_TYPE_INT8)
|
|
||||||
return static_cast<int8_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_UINT8)
|
|
||||||
return static_cast<uint8_t>(v);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case USER_DATA_PROPERTY_TYPE_INT32: {
|
|
||||||
auto v = get_value<int32_t>(value);
|
|
||||||
if (type == USER_DATA_PROPERTY_TYPE_INT8)
|
|
||||||
return static_cast<int8_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_UINT8)
|
|
||||||
return static_cast<uint8_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_INT16)
|
|
||||||
return static_cast<int16_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_UINT16)
|
|
||||||
return static_cast<uint16_t>(v);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case USER_DATA_PROPERTY_TYPE_UINT32: {
|
|
||||||
auto v = get_value<uint32_t>(value);
|
|
||||||
if (type == USER_DATA_PROPERTY_TYPE_INT8)
|
|
||||||
return static_cast<int8_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_UINT8)
|
|
||||||
return static_cast<uint8_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_INT16)
|
|
||||||
return static_cast<int16_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_UINT16)
|
|
||||||
return static_cast<uint16_t>(v);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case USER_DATA_PROPERTY_TYPE_INT64: {
|
|
||||||
auto v = get_value<int64_t>(value);
|
|
||||||
if (type == USER_DATA_PROPERTY_TYPE_INT8)
|
|
||||||
return static_cast<int8_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_UINT8)
|
|
||||||
return static_cast<uint8_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_INT16)
|
|
||||||
return static_cast<int16_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_UINT16)
|
|
||||||
return static_cast<uint16_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_INT32)
|
|
||||||
return static_cast<int32_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_UINT32)
|
|
||||||
return static_cast<uint32_t>(v);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case USER_DATA_PROPERTY_TYPE_UINT64: {
|
|
||||||
auto v = get_value<uint64_t>(value);
|
|
||||||
if (type == USER_DATA_PROPERTY_TYPE_INT8)
|
|
||||||
return static_cast<int8_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_UINT8)
|
|
||||||
return static_cast<uint8_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_INT16)
|
|
||||||
return static_cast<int16_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_UINT16)
|
|
||||||
return static_cast<uint16_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_INT32)
|
|
||||||
return static_cast<int32_t>(v);
|
|
||||||
else if (type == USER_DATA_PROPERTY_TYPE_UINT32)
|
|
||||||
return static_cast<uint32_t>(v);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
UserData::Variant reduce_int_type_size(const UserData::Variant& value)
|
|
||||||
{
|
|
||||||
switch (value.type()) {
|
|
||||||
case USER_DATA_PROPERTY_TYPE_INT16: {
|
|
||||||
auto v = get_value<int16_t>(value);
|
|
||||||
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
|
||||||
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
case USER_DATA_PROPERTY_TYPE_UINT16: {
|
|
||||||
auto v = get_value<uint16_t>(value);
|
|
||||||
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
|
||||||
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
case USER_DATA_PROPERTY_TYPE_INT32: {
|
|
||||||
auto v = get_value<int32_t>(value);
|
|
||||||
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
|
||||||
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
|
||||||
else if (INT16_COMPATIBLE(v)) return static_cast<int16_t>(v);
|
|
||||||
else if (UINT16_COMPATIBLE(v)) return static_cast<uint16_t>(v);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
case USER_DATA_PROPERTY_TYPE_UINT32: {
|
|
||||||
auto v = get_value<uint32_t>(value);
|
|
||||||
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
|
||||||
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
|
||||||
else if (INT16_COMPATIBLE(v)) return static_cast<int16_t>(v);
|
|
||||||
else if (UINT16_COMPATIBLE(v)) return static_cast<uint16_t>(v);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
case USER_DATA_PROPERTY_TYPE_INT64: {
|
|
||||||
auto v = get_value<int64_t>(value);
|
|
||||||
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
|
||||||
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
|
||||||
else if (INT16_COMPATIBLE(v)) return static_cast<int16_t>(v);
|
|
||||||
else if (UINT16_COMPATIBLE(v)) return static_cast<uint16_t>(v);
|
|
||||||
else if (INT32_COMPATIBLE(v)) return static_cast<int32_t>(v);
|
|
||||||
else if (UINT32_COMPATIBLE(v)) return static_cast<uint32_t>(v);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
case USER_DATA_PROPERTY_TYPE_UINT64: {
|
|
||||||
auto v = get_value<uint64_t>(value);
|
|
||||||
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
|
||||||
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
|
||||||
else if (INT16_COMPATIBLE(v)) return static_cast<int16_t>(v);
|
|
||||||
else if (UINT16_COMPATIBLE(v)) return static_cast<uint16_t>(v);
|
|
||||||
else if (INT32_COMPATIBLE(v)) return static_cast<int32_t>(v);
|
|
||||||
else if (UINT32_COMPATIBLE(v)) return static_cast<uint32_t>(v);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void write_point(std::ostream& os, const gfx::Point& point)
|
|
||||||
{
|
{
|
||||||
write32(os, point.x);
|
write32(os, point.x);
|
||||||
write32(os, point.y);
|
write32(os, point.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_size(std::ostream& os, const gfx::Size& size)
|
static void write_size(std::ostream& os, const gfx::Size& size)
|
||||||
{
|
{
|
||||||
write32(os, size.w);
|
write32(os, size.w);
|
||||||
write32(os, size.h);
|
write32(os, size.h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_property_value(std::ostream& os, const UserData::Variant& variant)
|
static void write_property_value(std::ostream& os, const UserData::Variant& variant)
|
||||||
{
|
{
|
||||||
switch (variant.type())
|
switch (variant.type())
|
||||||
{
|
{
|
||||||
|
|
@ -348,7 +115,7 @@ void write_property_value(std::ostream& os, const UserData::Variant& variant)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_properties_maps(std::ostream& os, const UserData::PropertiesMaps& propertiesMaps)
|
static void write_properties_maps(std::ostream& os, const UserData::PropertiesMaps& propertiesMaps)
|
||||||
{
|
{
|
||||||
write32(os, propertiesMaps.size());
|
write32(os, propertiesMaps.size());
|
||||||
for (auto propertiesMap : propertiesMaps) {
|
for (auto propertiesMap : propertiesMaps) {
|
||||||
|
|
@ -359,7 +126,14 @@ void write_properties_maps(std::ostream& os, const UserData::PropertiesMaps& pro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UserData::Variant read_property_value(std::istream& is, uint16_t type)
|
void write_user_data(std::ostream& os, const UserData& userData)
|
||||||
|
{
|
||||||
|
write_string(os, userData.text());
|
||||||
|
write32(os, userData.color());
|
||||||
|
write_properties_maps(os, userData.propertiesMaps());
|
||||||
|
}
|
||||||
|
|
||||||
|
static UserData::Variant read_property_value(std::istream& is, uint16_t type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case USER_DATA_PROPERTY_TYPE_NULLPTR: {
|
case USER_DATA_PROPERTY_TYPE_NULLPTR: {
|
||||||
|
|
@ -458,7 +232,7 @@ UserData::Variant read_property_value(std::istream& is, uint16_t type)
|
||||||
return doc::UserData::Variant{};
|
return doc::UserData::Variant{};
|
||||||
}
|
}
|
||||||
|
|
||||||
UserData::PropertiesMaps read_properties_maps(std::istream& is)
|
static UserData::PropertiesMaps read_properties_maps(std::istream& is)
|
||||||
{
|
{
|
||||||
doc::UserData::PropertiesMaps propertiesMaps;
|
doc::UserData::PropertiesMaps propertiesMaps;
|
||||||
size_t nmaps = read32(is);
|
size_t nmaps = read32(is);
|
||||||
|
|
@ -470,4 +244,20 @@ UserData::PropertiesMaps read_properties_maps(std::istream& is)
|
||||||
return propertiesMaps;
|
return propertiesMaps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UserData read_user_data(std::istream& is)
|
||||||
|
{
|
||||||
|
UserData userData;
|
||||||
|
userData.setText(read_string(is));
|
||||||
|
// This check is here because we've been restoring sprites from
|
||||||
|
// old sessions where the color is restored incorrectly if we
|
||||||
|
// don't check if there is enough space to read from the file
|
||||||
|
// (e.g. reading a random color or just white, maybe -1 which is
|
||||||
|
// 0xffffffff in 32-bit).
|
||||||
|
if (!is.eof()) {
|
||||||
|
userData.setColor(read32(is));
|
||||||
|
userData.propertiesMaps() = read_properties_maps(is);
|
||||||
|
}
|
||||||
|
return userData;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue