mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-14 12:04:29 +00:00
parent
5b2d10d97a
commit
21f8828890
3 changed files with 40 additions and 67 deletions
|
@ -22,11 +22,7 @@
|
||||||
#ifndef _TVG_BINARY_DESC_H_
|
#ifndef _TVG_BINARY_DESC_H_
|
||||||
#define _TVG_BINARY_DESC_H_
|
#define _TVG_BINARY_DESC_H_
|
||||||
|
|
||||||
// now only little endian
|
using TvgBinByte = uint8_t;
|
||||||
#define _read_tvg_ui16(dst, src) memcpy(dst, (src), sizeof(uint16_t))
|
|
||||||
#define _read_tvg_ui32(dst, src) memcpy(dst, (src), sizeof(uint32_t))
|
|
||||||
#define _read_tvg_float(dst, src) memcpy(dst, (src), sizeof(float))
|
|
||||||
|
|
||||||
using TvgIndicator = uint8_t;
|
using TvgIndicator = uint8_t;
|
||||||
using ByteCounter = uint32_t;
|
using ByteCounter = uint32_t;
|
||||||
using TvgFlag = uint8_t;
|
using TvgFlag = uint8_t;
|
||||||
|
@ -35,15 +31,6 @@ using TvgFlag = uint8_t;
|
||||||
#define BYTE_COUNTER_SIZE sizeof(ByteCounter)
|
#define BYTE_COUNTER_SIZE sizeof(ByteCounter)
|
||||||
#define TVG_FLAG_SIZE sizeof(TvgFlag)
|
#define TVG_FLAG_SIZE sizeof(TvgFlag)
|
||||||
|
|
||||||
struct tvgBlock
|
|
||||||
{
|
|
||||||
TvgIndicator type;
|
|
||||||
ByteCounter length;
|
|
||||||
const char* data;
|
|
||||||
const char* end;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// HEADER
|
// HEADER
|
||||||
#define TVG_BIN_HEADER_SIGNATURE "ThorVG"
|
#define TVG_BIN_HEADER_SIGNATURE "ThorVG"
|
||||||
#define TVG_BIN_HEADER_SIGNATURE_LENGTH 6
|
#define TVG_BIN_HEADER_SIGNATURE_LENGTH 6
|
||||||
|
|
|
@ -22,16 +22,17 @@
|
||||||
#ifndef _TVG_SAVER_IMPL_H_
|
#ifndef _TVG_SAVER_IMPL_H_
|
||||||
#define _TVG_SAVER_IMPL_H_
|
#define _TVG_SAVER_IMPL_H_
|
||||||
|
|
||||||
#include "tvgPaint.h"
|
|
||||||
#include "tvgBinaryDesc.h"
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "tvgPaint.h"
|
||||||
|
#include "tvgBinaryDesc.h"
|
||||||
|
|
||||||
|
|
||||||
struct Saver::Impl
|
struct Saver::Impl
|
||||||
{
|
{
|
||||||
Paint* paint = nullptr; //TODO: replace with Array
|
Paint* paint = nullptr; //TODO: replace with Array
|
||||||
Array<char> buffer;
|
Array<TvgBinByte> buffer;
|
||||||
|
|
||||||
~Impl()
|
~Impl()
|
||||||
{
|
{
|
||||||
|
@ -132,12 +133,12 @@ struct Saver::Impl
|
||||||
{
|
{
|
||||||
ByteCounter paintDataByteCnt = 0;
|
ByteCounter paintDataByteCnt = 0;
|
||||||
|
|
||||||
uint8_t opacity = paint->opacity();
|
auto opacity = paint->opacity();
|
||||||
if (opacity < 255) {
|
if (opacity < 255) {
|
||||||
paintDataByteCnt += writeMember(TVG_PAINT_OPACITY_INDICATOR, sizeof(opacity), &opacity);
|
paintDataByteCnt += writeMember(TVG_PAINT_OPACITY_INDICATOR, sizeof(opacity), &opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix m = const_cast<Paint*>(paint)->transform();
|
auto m = const_cast<Paint*>(paint)->transform();
|
||||||
if (fabs(m.e11 - 1) > FLT_EPSILON || fabs(m.e12) > FLT_EPSILON || fabs(m.e13) > FLT_EPSILON ||
|
if (fabs(m.e11 - 1) > FLT_EPSILON || fabs(m.e12) > FLT_EPSILON || fabs(m.e13) > FLT_EPSILON ||
|
||||||
fabs(m.e21) > FLT_EPSILON || fabs(m.e22 - 1) > FLT_EPSILON || fabs(m.e23) > FLT_EPSILON ||
|
fabs(m.e21) > FLT_EPSILON || fabs(m.e22 - 1) > FLT_EPSILON || fabs(m.e23) > FLT_EPSILON ||
|
||||||
fabs(m.e31) > FLT_EPSILON || fabs(m.e32) > FLT_EPSILON || fabs(m.e33 - 1) > FLT_EPSILON) {
|
fabs(m.e31) > FLT_EPSILON || fabs(m.e32) > FLT_EPSILON || fabs(m.e33 - 1) > FLT_EPSILON) {
|
||||||
|
@ -153,17 +154,12 @@ struct Saver::Impl
|
||||||
return paintDataByteCnt;
|
return paintDataByteCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteCounter serializeScene(const Paint* paint)
|
ByteCounter serializeScene(const Scene* scene)
|
||||||
{
|
{
|
||||||
auto scene = static_cast<const Scene*>(paint);
|
|
||||||
if (!scene) return 0;
|
|
||||||
|
|
||||||
ByteCounter sceneDataByteCnt = 0;
|
|
||||||
|
|
||||||
writeMemberIndicator(TVG_SCENE_BEGIN_INDICATOR);
|
writeMemberIndicator(TVG_SCENE_BEGIN_INDICATOR);
|
||||||
skipInBufferMemberDataSize();
|
skipInBufferMemberDataSize();
|
||||||
|
|
||||||
sceneDataByteCnt += serializeChildren(paint);
|
auto sceneDataByteCnt = serializeChildren(scene);
|
||||||
sceneDataByteCnt += serializePaint(scene);
|
sceneDataByteCnt += serializePaint(scene);
|
||||||
|
|
||||||
writeMemberDataSizeAt(sceneDataByteCnt);
|
writeMemberDataSizeAt(sceneDataByteCnt);
|
||||||
|
@ -270,22 +266,15 @@ struct Saver::Impl
|
||||||
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + pathDataByteCnt;
|
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + pathDataByteCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteCounter serializeShape(const Paint* paint)
|
ByteCounter serializeShape(const Shape* shape)
|
||||||
{
|
{
|
||||||
auto shape = static_cast<const Shape*>(paint);
|
|
||||||
if (!shape) return 0;
|
|
||||||
|
|
||||||
ByteCounter shapeDataByteCnt = 0;
|
|
||||||
|
|
||||||
writeMemberIndicator(TVG_SHAPE_BEGIN_INDICATOR);
|
writeMemberIndicator(TVG_SHAPE_BEGIN_INDICATOR);
|
||||||
skipInBufferMemberDataSize();
|
skipInBufferMemberDataSize();
|
||||||
|
|
||||||
TvgFlag ruleTvgFlag = (shape->fillRule() == FillRule::EvenOdd) ? TVG_SHAPE_FILLRULE_EVENODD_FLAG : TVG_SHAPE_FILLRULE_WINDING_FLAG;
|
auto ruleTvgFlag = (shape->fillRule() == FillRule::EvenOdd) ? TVG_SHAPE_FILLRULE_EVENODD_FLAG : TVG_SHAPE_FILLRULE_WINDING_FLAG;
|
||||||
shapeDataByteCnt += writeMember(TVG_SHAPE_FILLRULE_INDICATOR, TVG_FLAG_SIZE, &ruleTvgFlag);
|
auto shapeDataByteCnt = writeMember(TVG_SHAPE_FILLRULE_INDICATOR, TVG_FLAG_SIZE, &ruleTvgFlag);
|
||||||
|
|
||||||
if (shape->strokeWidth() > 0) {
|
if (shape->strokeWidth() > 0) shapeDataByteCnt += serializeShapeStroke(shape);
|
||||||
shapeDataByteCnt += serializeShapeStroke(shape);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auto fill = shape->fill()) {
|
if (auto fill = shape->fill()) {
|
||||||
shapeDataByteCnt += serializeShapeFill(fill, TVG_SHAPE_FILL_INDICATOR);
|
shapeDataByteCnt += serializeShapeFill(fill, TVG_SHAPE_FILL_INDICATOR);
|
||||||
|
@ -296,8 +285,6 @@ struct Saver::Impl
|
||||||
}
|
}
|
||||||
|
|
||||||
shapeDataByteCnt += serializeShapePath(shape);
|
shapeDataByteCnt += serializeShapePath(shape);
|
||||||
|
|
||||||
shapeDataByteCnt += serializeChildren(paint);
|
|
||||||
shapeDataByteCnt += serializePaint(shape);
|
shapeDataByteCnt += serializePaint(shape);
|
||||||
|
|
||||||
writeMemberDataSizeAt(shapeDataByteCnt);
|
writeMemberDataSizeAt(shapeDataByteCnt);
|
||||||
|
@ -305,10 +292,8 @@ struct Saver::Impl
|
||||||
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + shapeDataByteCnt;
|
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + shapeDataByteCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteCounter serializePicture(const Paint* paint)
|
ByteCounter serializePicture(const Picture* picture)
|
||||||
{
|
{
|
||||||
auto picture = static_cast<const Picture*>(paint);
|
|
||||||
if (!picture) return 0;
|
|
||||||
auto pixels = picture->data();
|
auto pixels = picture->data();
|
||||||
|
|
||||||
ByteCounter pictureDataByteCnt = 0;
|
ByteCounter pictureDataByteCnt = 0;
|
||||||
|
@ -333,7 +318,7 @@ struct Saver::Impl
|
||||||
pictureDataByteCnt += writeMemberData(pixels, pixelsByteCnt);
|
pictureDataByteCnt += writeMemberData(pixels, pixelsByteCnt);
|
||||||
pictureDataByteCnt += TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE;
|
pictureDataByteCnt += TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE;
|
||||||
} else {
|
} else {
|
||||||
pictureDataByteCnt += serializeChildren(paint);
|
pictureDataByteCnt += serializeChildren(picture);
|
||||||
}
|
}
|
||||||
|
|
||||||
pictureDataByteCnt += serializePaint(picture);
|
pictureDataByteCnt += serializePaint(picture);
|
||||||
|
@ -375,24 +360,14 @@ struct Saver::Impl
|
||||||
ByteCounter serialize(const Paint* paint)
|
ByteCounter serialize(const Paint* paint)
|
||||||
{
|
{
|
||||||
if (!paint) return 0;
|
if (!paint) return 0;
|
||||||
ByteCounter dataByteCnt = 0;
|
|
||||||
|
|
||||||
switch (paint->id()) {
|
switch (paint->id()) {
|
||||||
case TVG_CLASS_ID_SHAPE: {
|
case TVG_CLASS_ID_SHAPE: return serializeShape(static_cast<const Shape*>(paint));
|
||||||
dataByteCnt += serializeShape(paint);
|
case TVG_CLASS_ID_SCENE: return serializeScene(static_cast<const Scene*>(paint));
|
||||||
break;
|
case TVG_CLASS_ID_PICTURE: return serializePicture(static_cast<const Picture*>(paint));
|
||||||
}
|
|
||||||
case TVG_CLASS_ID_SCENE: {
|
|
||||||
dataByteCnt += serializeScene(paint);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TVG_CLASS_ID_PICTURE: {
|
|
||||||
dataByteCnt += serializePicture(paint);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dataByteCnt;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool save(Paint* paint, const std::string& path)
|
bool save(Paint* paint, const std::string& path)
|
||||||
|
|
|
@ -28,12 +28,23 @@
|
||||||
/* Internal Class Implementation */
|
/* Internal Class Implementation */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
|
struct TvgBinBlock
|
||||||
|
{
|
||||||
|
TvgIndicator type;
|
||||||
|
ByteCounter length;
|
||||||
|
const char* data;
|
||||||
|
const char* end;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define _read_tvg_ui32(dst, src) memcpy(dst, (src), sizeof(uint32_t))
|
||||||
|
#define _read_tvg_float(dst, src) memcpy(dst, (src), sizeof(float))
|
||||||
|
|
||||||
enum class LoaderResult { Success = 0, InvalidType, SizeCorruption, MemoryCorruption, LogicalCorruption };
|
enum class LoaderResult { Success = 0, InvalidType, SizeCorruption, MemoryCorruption, LogicalCorruption };
|
||||||
|
|
||||||
static Paint* _parsePaint(tvgBlock block);
|
static Paint* _parsePaint(TvgBinBlock block);
|
||||||
|
|
||||||
|
|
||||||
static bool _paintProperty(tvgBlock block)
|
static bool _paintProperty(TvgBinBlock block)
|
||||||
{
|
{
|
||||||
switch (block.type) {
|
switch (block.type) {
|
||||||
case TVG_PAINT_OPACITY_INDICATOR:
|
case TVG_PAINT_OPACITY_INDICATOR:
|
||||||
|
@ -45,9 +56,9 @@ static bool _paintProperty(tvgBlock block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static tvgBlock _readBlock(const char *ptr)
|
static TvgBinBlock _readBlock(const char *ptr)
|
||||||
{
|
{
|
||||||
tvgBlock block;
|
TvgBinBlock block;
|
||||||
block.type = *ptr;
|
block.type = *ptr;
|
||||||
_read_tvg_ui32(&block.length, ptr + TVG_INDICATOR_SIZE);
|
_read_tvg_ui32(&block.length, ptr + TVG_INDICATOR_SIZE);
|
||||||
block.data = ptr + TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE;
|
block.data = ptr + TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE;
|
||||||
|
@ -108,7 +119,7 @@ static LoaderResult _parseCmpTarget(const char *ptr, const char *end, Paint *pai
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static LoaderResult _parsePaintProperty(tvgBlock block, Paint *paint)
|
static LoaderResult _parsePaintProperty(TvgBinBlock block, Paint *paint)
|
||||||
{
|
{
|
||||||
switch (block.type) {
|
switch (block.type) {
|
||||||
case TVG_PAINT_OPACITY_INDICATOR: {
|
case TVG_PAINT_OPACITY_INDICATOR: {
|
||||||
|
@ -132,7 +143,7 @@ static LoaderResult _parsePaintProperty(tvgBlock block, Paint *paint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static LoaderResult _parseScene(tvgBlock block, Paint *paint)
|
static LoaderResult _parseScene(TvgBinBlock block, Paint *paint)
|
||||||
{
|
{
|
||||||
auto scene = static_cast<Scene*>(paint);
|
auto scene = static_cast<Scene*>(paint);
|
||||||
|
|
||||||
|
@ -350,7 +361,7 @@ static LoaderResult _parseShapeStroke(const char *ptr, const char *end, Shape *s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static LoaderResult _parseShape(tvgBlock block, Paint* paint)
|
static LoaderResult _parseShape(TvgBinBlock block, Paint* paint)
|
||||||
{
|
{
|
||||||
auto shape = static_cast<Shape*>(paint);
|
auto shape = static_cast<Shape*>(paint);
|
||||||
|
|
||||||
|
@ -395,7 +406,7 @@ static LoaderResult _parseShape(tvgBlock block, Paint* paint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static LoaderResult _parsePicture(tvgBlock block, Paint* paint)
|
static LoaderResult _parsePicture(TvgBinBlock block, Paint* paint)
|
||||||
{
|
{
|
||||||
auto picture = static_cast<Picture*>(paint);
|
auto picture = static_cast<Picture*>(paint);
|
||||||
|
|
||||||
|
@ -431,9 +442,9 @@ static LoaderResult _parsePicture(tvgBlock block, Paint* paint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Paint* _parsePaint(tvgBlock baseBlock)
|
static Paint* _parsePaint(TvgBinBlock baseBlock)
|
||||||
{
|
{
|
||||||
LoaderResult (*parser)(tvgBlock, Paint*);
|
LoaderResult (*parser)(TvgBinBlock, Paint*);
|
||||||
Paint *paint = nullptr;
|
Paint *paint = nullptr;
|
||||||
|
|
||||||
switch (baseBlock.type) {
|
switch (baseBlock.type) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue