File indexing completed on 2025-01-05 04:01:18

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #include "rive_serializer.hpp"
0008 #include <QColor>
0009 
0010 glaxnimate::io::rive::RiveSerializer::RiveSerializer(QIODevice* file)
0011     : stream(file)
0012 {
0013 }
0014 
0015 void glaxnimate::io::rive::RiveSerializer::write_header(int vmaj, int vmin, glaxnimate::io::rive::Identifier file_id)
0016 {
0017     stream.write("RIVE");
0018     stream.write_uint_leb128(vmaj);
0019     stream.write_uint_leb128(vmin);
0020     stream.write_uint_leb128(file_id);
0021 }
0022 
0023 void glaxnimate::io::rive::RiveSerializer::write_property_table(const glaxnimate::io::rive::PropertyTable& properties)
0024 {
0025     for ( const auto& p: properties )
0026         stream.write_uint_leb128(p.first);
0027 
0028     stream.write_byte(0);
0029 
0030     quint32 current_int = 0;
0031     quint32 bit = 0;
0032     for ( const auto& p: properties )
0033     {
0034         int type = 0;
0035         switch ( p.second )
0036         {
0037             case PropertyType::VarUint:
0038             case PropertyType::Bool:
0039                 type = 0;
0040                 break;
0041             case PropertyType::Bytes:
0042             case PropertyType::String:
0043                 type = 1;
0044                 break;
0045             case PropertyType::Float:
0046                 type = 2;
0047                 break;
0048             case PropertyType::Color:
0049                 type = 3;
0050                 break;
0051         }
0052 
0053         current_int <<= 2;
0054         current_int |= type;
0055         bit += 2;
0056         if ( bit == 8 )
0057         {
0058             stream.write_uint32_le(current_int);
0059             bit = 0;
0060             current_int = 0;
0061         }
0062     }
0063     if ( bit != 0 )
0064         stream.write_uint32_le(current_int);
0065 }
0066 
0067 void glaxnimate::io::rive::RiveSerializer::write_object(const glaxnimate::io::rive::Object& output)
0068 {
0069     stream.write_uint_leb128(VarUint(output.type().id));
0070     for ( const auto& p : output.properties() )
0071     {
0072         if ( !p.second.isValid() || (p.second.userType() == QMetaType::QString && p.second.toString().isEmpty()) )
0073             continue;
0074         stream.write_uint_leb128(p.first->id);
0075         write_property_value(p.first->type, p.second);
0076     }
0077     stream.write_byte(0);
0078 }
0079 
0080 void glaxnimate::io::rive::RiveSerializer::write_property_value(glaxnimate::io::rive::PropertyType id, const QVariant& value)
0081 {
0082     switch ( id )
0083     {
0084         case PropertyType::Bool:
0085             stream.write_byte(value.toBool());
0086             return;
0087         case PropertyType::VarUint:
0088             stream.write_uint_leb128(value.value<VarUint>());
0089             return;
0090         case PropertyType::Color:
0091             stream.write_uint32_le(value.value<QColor>().rgba());
0092             return;
0093         case PropertyType::Bytes:
0094         {
0095             auto data = value.toByteArray();
0096             stream.write_uint_leb128(data.size());
0097             stream.write(data);
0098             return;
0099         }
0100         case PropertyType::String:
0101         {
0102             auto data = value.toString().toUtf8();
0103             stream.write_uint_leb128(data.size());
0104             stream.write(data);
0105             return;
0106         }
0107         case PropertyType::Float:
0108             stream.write_float32_le(value.toFloat());
0109     }
0110 }