mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-10 21:44:22 +00:00
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
|
||||
# Copyright (C) 2019-2022 Igara Studio S.A.
|
||||
# Copyright (C) 2019-2023 Igara Studio S.A.
|
||||
# Copyright (C) 2001-2018 David Capello
|
||||
|
||||
if(WIN32)
|
||||
@ -74,6 +74,7 @@ add_library(doc-lib
|
||||
tileset.cpp
|
||||
tileset_io.cpp
|
||||
tilesets.cpp
|
||||
user_data.cpp
|
||||
user_data_io.cpp
|
||||
util.cpp)
|
||||
|
||||
|
218
src/doc/user_data.cpp
Normal file
218
src/doc/user_data.cpp
Normal file
@ -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);
|
||||
|
||||
// If all the vector elements are of the same type returns such type.
|
||||
// Otherwise it returns -1.
|
||||
// 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);
|
||||
|
||||
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 reduce_int_type_size(const UserData::Variant& value);
|
||||
|
||||
} // namespace doc
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (c) 2023 Igara Studio S.A.
|
||||
// Copyright (c) 2001-2015 David Capello
|
||||
//
|
||||
// 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::little_endian;
|
||||
|
||||
void write_properties_maps(std::ostream& os, const UserData::PropertiesMaps& propertiesMaps);
|
||||
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)
|
||||
static void write_point(std::ostream& os, const gfx::Point& point)
|
||||
{
|
||||
write32(os, point.x);
|
||||
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.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())
|
||||
{
|
||||
@ -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());
|
||||
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) {
|
||||
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{};
|
||||
}
|
||||
|
||||
UserData::PropertiesMaps read_properties_maps(std::istream& is)
|
||||
static UserData::PropertiesMaps read_properties_maps(std::istream& is)
|
||||
{
|
||||
doc::UserData::PropertiesMaps propertiesMaps;
|
||||
size_t nmaps = read32(is);
|
||||
@ -470,4 +244,20 @@ UserData::PropertiesMaps read_properties_maps(std::istream& is)
|
||||
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…
x
Reference in New Issue
Block a user