| /* | |
| * Copyright 2026 Rive | |
| */ | |
| #ifndef _RIVE_SERIALIZE_OPS_HPP_ | |
| #define _RIVE_SERIALIZE_OPS_HPP_ | |
| #include "rive/core/binary_reader.hpp" | |
| #include "rive/core/binary_writer.hpp" | |
| #include "rive/math/raw_path.hpp" | |
| #include <vector> | |
| namespace rive | |
| { | |
| // Wire opcodes shared by SerializingFactory and replaySerializedCommands so | |
| // the two ends of the .sriv format cannot drift apart. | |
| enum class SerializeOp : uint32_t | |
| { | |
| makeRenderBuffer = 0, | |
| makeLinearGradient = 1, | |
| makeRadialGradient = 2, | |
| makeRenderPath = 3, | |
| makeRenderPaint = 5, | |
| decodeImage = 6, | |
| save = 7, | |
| restore = 8, | |
| transform = 9, | |
| drawPath = 10, | |
| clipPath = 11, | |
| drawImage = 12, | |
| drawImageMesh = 13, | |
| // RenderBuffer | |
| setVertexBufferData = 14, | |
| setIndexBufferData = 15, | |
| // RenderPath | |
| addRawPath = 16, | |
| rewind = 17, | |
| fillRule = 18, | |
| // RenderPaint | |
| style = 20, | |
| color = 21, | |
| thickness = 22, | |
| join = 23, | |
| cap = 24, | |
| feather = 25, | |
| blendMode = 26, | |
| shader = 27, | |
| frame = 28, | |
| frameSize = 29, | |
| modulateOpacity = 30, | |
| }; | |
| inline void serializeRawPath(BinaryWriter* writer, const RawPath& path) | |
| { | |
| auto verbs = path.verbs(); | |
| auto points = path.points(); | |
| writer->writeVarUint((uint64_t)verbs.size()); | |
| for (auto verb : verbs) | |
| { | |
| writer->writeVarUint((uint64_t)verb); | |
| } | |
| writer->writeVarUint((uint64_t)points.size()); | |
| for (auto point : points) | |
| { | |
| writer->writeFloat(point.x); | |
| writer->writeFloat(point.y); | |
| } | |
| } | |
| inline RawPath deserializeRawPath(BinaryReader& reader) | |
| { | |
| RawPath path; | |
| size_t verbCount = static_cast<size_t>(reader.readVarUint64()); | |
| std::vector<PathVerb> verbs(verbCount); | |
| for (size_t i = 0; i < verbCount; ++i) | |
| verbs[i] = static_cast<PathVerb>(reader.readVarUint64()); | |
| size_t pointCount = static_cast<size_t>(reader.readVarUint64()); | |
| std::vector<Vec2D> pts(pointCount); | |
| for (size_t i = 0; i < pointCount; ++i) | |
| { | |
| pts[i].x = reader.readFloat32(); | |
| pts[i].y = reader.readFloat32(); | |
| } | |
| size_t p = 0; | |
| // A truncated stream can promise more points than it delivers. | |
| auto have = [&](size_t n) { return p + n <= pts.size(); }; | |
| for (PathVerb v : verbs) | |
| { | |
| switch (v) | |
| { | |
| case PathVerb::move: | |
| if (!have(1)) | |
| return path; | |
| path.move(pts[p++]); | |
| break; | |
| case PathVerb::line: | |
| if (!have(1)) | |
| return path; | |
| path.line(pts[p++]); | |
| break; | |
| case PathVerb::quad: | |
| if (!have(2)) | |
| return path; | |
| path.quad(pts[p], pts[p + 1]); | |
| p += 2; | |
| break; | |
| case PathVerb::cubic: | |
| if (!have(3)) | |
| return path; | |
| path.cubic(pts[p], pts[p + 1], pts[p + 2]); | |
| p += 3; | |
| break; | |
| case PathVerb::close: | |
| path.close(); | |
| break; | |
| } | |
| } | |
| return path; | |
| } | |
| } // namespace rive | |
| #endif |