mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-27 00:26:51 +00:00
tvg format: code refactoring #10
keep neat & clean code, revise to tvg style naming convention.
This commit is contained in:
parent
c2ec997db5
commit
87d00b4121
3 changed files with 167 additions and 150 deletions
Binary file not shown.
|
@ -22,14 +22,17 @@
|
||||||
#ifndef _TVG_BINARY_DESC_H_
|
#ifndef _TVG_BINARY_DESC_H_
|
||||||
#define _TVG_BINARY_DESC_H_
|
#define _TVG_BINARY_DESC_H_
|
||||||
|
|
||||||
//TODO: Need to consider whether uin8_t is enough size for extension...
|
/* TODO: Need to consider whether uin8_t is enough size for extension...
|
||||||
|
Rather than optimal data, we can use enough size and data compress? */
|
||||||
|
|
||||||
/* Data types, do not change data types once Tvg Format is officially released,
|
/* Data types, do not change data types once Tvg Format is officially released,
|
||||||
That would occur the abi break. */
|
That would occur the abi break. */
|
||||||
|
|
||||||
using TvgBinByte = uint8_t;
|
using TvgBinByte = uint8_t;
|
||||||
using TvgBinTag = uint8_t;
|
|
||||||
using TvgBinCounter = uint32_t;
|
using TvgBinCounter = uint32_t;
|
||||||
using TvgBinFlag = uint8_t;
|
using TvgBinTag = TvgBinByte;
|
||||||
|
using TvgBinFlag = TvgBinByte;
|
||||||
|
|
||||||
|
|
||||||
//Header
|
//Header
|
||||||
#define TVG_HEADER_SIGNATURE "ThorVG"
|
#define TVG_HEADER_SIGNATURE "ThorVG"
|
||||||
|
|
|
@ -30,6 +30,14 @@
|
||||||
|
|
||||||
#define SIZE(A) sizeof(A)
|
#define SIZE(A) sizeof(A)
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/* Internal Class Implementation */
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
static inline TvgBinCounter SERIAL_DONE(TvgBinCounter cnt)
|
||||||
|
{
|
||||||
|
return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + cnt;
|
||||||
|
}
|
||||||
|
|
||||||
struct Saver::Impl
|
struct Saver::Impl
|
||||||
{
|
{
|
||||||
|
@ -50,7 +58,7 @@ struct Saver::Impl
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bufferToFile(const std::string& path)
|
bool flushTo(const std::string& path)
|
||||||
{
|
{
|
||||||
FILE* fp = fopen(path.c_str(), "w+");
|
FILE* fp = fopen(path.c_str(), "w+");
|
||||||
if (!fp) return false;
|
if (!fp) return false;
|
||||||
|
@ -77,289 +85,295 @@ struct Saver::Impl
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeMemberIndicator(TvgBinTag ind)
|
void writeTag(TvgBinTag tag)
|
||||||
{
|
{
|
||||||
buffer.grow(SIZE(TvgBinTag));
|
buffer.grow(SIZE(TvgBinTag));
|
||||||
memcpy(buffer.ptr(), &ind, SIZE(TvgBinTag));
|
memcpy(buffer.ptr(), &tag, SIZE(TvgBinTag));
|
||||||
buffer.count += SIZE(TvgBinTag);
|
buffer.count += SIZE(TvgBinTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeMemberDataSize(TvgBinCounter byteCnt)
|
void writeCount(TvgBinCounter cnt)
|
||||||
{
|
{
|
||||||
buffer.grow(SIZE(TvgBinCounter));
|
buffer.grow(SIZE(TvgBinCounter));
|
||||||
memcpy(buffer.ptr(), &byteCnt, SIZE(TvgBinCounter));
|
memcpy(buffer.ptr(), &cnt, SIZE(TvgBinCounter));
|
||||||
buffer.count += SIZE(TvgBinCounter);
|
buffer.count += SIZE(TvgBinCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeMemberDataSizeAt(TvgBinCounter byteCnt)
|
void writeReservedCount(TvgBinCounter cnt)
|
||||||
{
|
{
|
||||||
memcpy(buffer.ptr() - byteCnt - SIZE(TvgBinCounter), &byteCnt, SIZE(TvgBinCounter));
|
memcpy(buffer.ptr() - cnt - SIZE(TvgBinCounter), &cnt, SIZE(TvgBinCounter));
|
||||||
}
|
}
|
||||||
|
|
||||||
void skipInBufferMemberDataSize()
|
void reserveCount()
|
||||||
{
|
{
|
||||||
buffer.grow(SIZE(TvgBinCounter));
|
buffer.grow(SIZE(TvgBinCounter));
|
||||||
buffer.count += SIZE(TvgBinCounter);
|
buffer.count += SIZE(TvgBinCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
TvgBinCounter writeMemberData(const void* data, TvgBinCounter byteCnt)
|
TvgBinCounter writeData(const void* data, TvgBinCounter cnt)
|
||||||
{
|
{
|
||||||
buffer.grow(byteCnt);
|
buffer.grow(cnt);
|
||||||
memcpy(buffer.ptr(), data, byteCnt);
|
memcpy(buffer.ptr(), data, cnt);
|
||||||
buffer.count += byteCnt;
|
buffer.count += cnt;
|
||||||
|
|
||||||
return byteCnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
TvgBinCounter writeMember(TvgBinTag ind, TvgBinCounter byteCnt, const void* data)
|
TvgBinCounter writeTagProperty(TvgBinTag tag, TvgBinCounter cnt, const void* data)
|
||||||
{
|
{
|
||||||
TvgBinCounter blockByteCnt = SIZE(TvgBinTag) + SIZE(TvgBinCounter) + byteCnt;
|
TvgBinCounter growCnt = SERIAL_DONE(cnt);
|
||||||
|
|
||||||
buffer.grow(blockByteCnt);
|
buffer.grow(growCnt);
|
||||||
|
|
||||||
auto ptr = buffer.ptr();
|
auto ptr = buffer.ptr();
|
||||||
|
|
||||||
memcpy(ptr, &ind, SIZE(TvgBinTag));
|
*ptr = tag;
|
||||||
ptr += SIZE(TvgBinTag);
|
++ptr;
|
||||||
memcpy(ptr, &byteCnt, SIZE(TvgBinCounter));
|
|
||||||
|
memcpy(ptr, &cnt, SIZE(TvgBinCounter));
|
||||||
ptr += SIZE(TvgBinCounter);
|
ptr += SIZE(TvgBinCounter);
|
||||||
memcpy(ptr, data, byteCnt);
|
|
||||||
ptr += byteCnt;
|
|
||||||
|
|
||||||
buffer.count += blockByteCnt;
|
memcpy(ptr, data, cnt);
|
||||||
|
ptr += cnt;
|
||||||
|
|
||||||
return blockByteCnt;
|
buffer.count += growCnt;
|
||||||
|
|
||||||
|
return growCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
TvgBinCounter serializePaint(const Paint* paint)
|
TvgBinCounter serializePaint(const Paint* paint)
|
||||||
{
|
{
|
||||||
TvgBinCounter paintDataByteCnt = 0;
|
TvgBinCounter cnt = 0;
|
||||||
|
|
||||||
|
//opacity
|
||||||
auto opacity = paint->opacity();
|
auto opacity = paint->opacity();
|
||||||
if (opacity < 255) {
|
if (opacity < 255) {
|
||||||
paintDataByteCnt += writeMember(TVG_TAG_PAINT_OPACITY, sizeof(opacity), &opacity);
|
cnt += writeTagProperty(TVG_TAG_PAINT_OPACITY, sizeof(opacity), &opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//transform
|
||||||
auto 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) {
|
||||||
paintDataByteCnt += writeMember(TVG_TAG_PAINT_TRANSFORM, sizeof(m), &m);
|
cnt += writeTagProperty(TVG_TAG_PAINT_TRANSFORM, sizeof(m), &m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//composite
|
||||||
const Paint* cmpTarget = nullptr;
|
const Paint* cmpTarget = nullptr;
|
||||||
auto cmpMethod = paint->composite(&cmpTarget);
|
auto cmpMethod = paint->composite(&cmpTarget);
|
||||||
if (cmpMethod != CompositeMethod::None && cmpTarget) {
|
if (cmpMethod != CompositeMethod::None && cmpTarget) {
|
||||||
paintDataByteCnt += serializeComposite(cmpTarget, cmpMethod);
|
cnt += serializeComposite(cmpTarget, cmpMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
return paintDataByteCnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
TvgBinCounter serialize(const Scene* scene)
|
TvgBinCounter serializeScene(const Scene* scene)
|
||||||
{
|
{
|
||||||
writeMemberIndicator(TVG_TAG_CLASS_SCENE);
|
writeTag(TVG_TAG_CLASS_SCENE);
|
||||||
skipInBufferMemberDataSize();
|
reserveCount();
|
||||||
|
|
||||||
auto sceneDataByteCnt = serializeChildren(scene);
|
auto cnt = serializeChildren(scene) + serializePaint(scene);
|
||||||
sceneDataByteCnt += serializePaint(scene);
|
|
||||||
|
|
||||||
writeMemberDataSizeAt(sceneDataByteCnt);
|
writeReservedCount(cnt);
|
||||||
|
|
||||||
return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + sceneDataByteCnt;
|
return SERIAL_DONE(cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
TvgBinCounter serializeShapeFill(const Fill* f, TvgBinTag fillTvgBinFlag)
|
TvgBinCounter serializeFill(const Fill* fill, TvgBinTag tag)
|
||||||
{
|
{
|
||||||
TvgBinCounter fillDataByteCnt = 0;
|
|
||||||
const Fill::ColorStop* stops = nullptr;
|
const Fill::ColorStop* stops = nullptr;
|
||||||
auto stopsCnt = f->colorStops(&stops);
|
auto stopsCnt = fill->colorStops(&stops);
|
||||||
if (!stops || stopsCnt == 0) return 0;
|
if (!stops || stopsCnt == 0) return 0;
|
||||||
|
|
||||||
writeMemberIndicator(fillTvgBinFlag);
|
writeTag(tag);
|
||||||
skipInBufferMemberDataSize();
|
reserveCount();
|
||||||
|
|
||||||
if (f->id() == TVG_CLASS_ID_RADIAL) {
|
TvgBinCounter cnt = 0;
|
||||||
float argRadial[3];
|
|
||||||
auto radGrad = static_cast<const RadialGradient*>(f);
|
//radial fill
|
||||||
radGrad->radial(argRadial, argRadial + 1,argRadial + 2);
|
if (fill->id() == TVG_CLASS_ID_RADIAL) {
|
||||||
fillDataByteCnt += writeMember(TVG_TAG_FILL_RADIAL_GRADIENT, sizeof(argRadial), argRadial);
|
float args[3];
|
||||||
}
|
static_cast<const RadialGradient*>(fill)->radial(args, args + 1,args + 2);
|
||||||
else {
|
cnt += writeTagProperty(TVG_TAG_FILL_RADIAL_GRADIENT, sizeof(args), args);
|
||||||
float argLinear[4];
|
//linear fill
|
||||||
auto linGrad = static_cast<const LinearGradient*>(f);
|
} else {
|
||||||
linGrad->linear(argLinear, argLinear + 1, argLinear + 2, argLinear + 3);
|
float args[4];
|
||||||
fillDataByteCnt += writeMember(TVG_TAG_FILL_LINEAR_GRADIENT, sizeof(argLinear), argLinear);
|
static_cast<const LinearGradient*>(fill)->linear(args, args + 1, args + 2, args + 3);
|
||||||
|
cnt += writeTagProperty(TVG_TAG_FILL_LINEAR_GRADIENT, sizeof(args), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto flag = static_cast<TvgBinFlag>(f->spread());
|
auto flag = static_cast<TvgBinFlag>(fill->spread());
|
||||||
fillDataByteCnt += writeMember(TVG_TAG_FILL_FILLSPREAD, SIZE(TvgBinFlag), &flag);
|
cnt += writeTagProperty(TVG_TAG_FILL_FILLSPREAD, SIZE(TvgBinFlag), &flag);
|
||||||
fillDataByteCnt += writeMember(TVG_TAG_FILL_COLORSTOPS, stopsCnt * sizeof(stops), stops);
|
cnt += writeTagProperty(TVG_TAG_FILL_COLORSTOPS, stopsCnt * sizeof(stops), stops);
|
||||||
|
|
||||||
writeMemberDataSizeAt(fillDataByteCnt);
|
writeReservedCount(cnt);
|
||||||
|
|
||||||
return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + fillDataByteCnt;
|
return SERIAL_DONE(cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
TvgBinCounter serializeShapeStroke(const Shape* shape)
|
TvgBinCounter serializeStroke(const Shape* shape)
|
||||||
{
|
{
|
||||||
TvgBinCounter strokeDataByteCnt = 0;
|
writeTag(TVG_TAG_SHAPE_STROKE);
|
||||||
TvgBinFlag flag;
|
reserveCount();
|
||||||
|
|
||||||
writeMemberIndicator(TVG_TAG_SHAPE_STROKE);
|
//cap
|
||||||
skipInBufferMemberDataSize();
|
auto flag = static_cast<TvgBinFlag>(shape->strokeCap());
|
||||||
|
auto cnt = writeTagProperty(TVG_TAG_SHAPE_STROKE_CAP, SIZE(TvgBinFlag), &flag);
|
||||||
flag = static_cast<TvgBinFlag>(shape->strokeCap());
|
|
||||||
strokeDataByteCnt += writeMember(TVG_TAG_SHAPE_STROKE_CAP, SIZE(TvgBinFlag), &flag);
|
|
||||||
|
|
||||||
|
//join
|
||||||
flag = static_cast<TvgBinFlag>(shape->strokeJoin());
|
flag = static_cast<TvgBinFlag>(shape->strokeJoin());
|
||||||
strokeDataByteCnt += writeMember(TVG_TAG_SHAPE_STROKE_JOIN, SIZE(TvgBinFlag), &flag);
|
cnt += writeTagProperty(TVG_TAG_SHAPE_STROKE_JOIN, SIZE(TvgBinFlag), &flag);
|
||||||
|
|
||||||
float width = shape->strokeWidth();
|
//width
|
||||||
strokeDataByteCnt += writeMember(TVG_TAG_SHAPE_STROKE_WIDTH, sizeof(width), &width);
|
auto width = shape->strokeWidth();
|
||||||
|
cnt += writeTagProperty(TVG_TAG_SHAPE_STROKE_WIDTH, sizeof(width), &width);
|
||||||
|
|
||||||
|
//fill
|
||||||
if (auto fill = shape->strokeFill()) {
|
if (auto fill = shape->strokeFill()) {
|
||||||
strokeDataByteCnt += serializeShapeFill(fill, TVG_TAG_SHAPE_STROKE_FILL);
|
cnt += serializeFill(fill, TVG_TAG_SHAPE_STROKE_FILL);
|
||||||
} else {
|
} else {
|
||||||
uint8_t color[4] = {0, 0, 0, 0};
|
uint8_t color[4] = {0, 0, 0, 0};
|
||||||
shape->strokeColor(color, color + 1, color + 2, color + 3);
|
shape->strokeColor(color, color + 1, color + 2, color + 3);
|
||||||
strokeDataByteCnt += writeMember(TVG_TAG_SHAPE_STROKE_COLOR, sizeof(color), &color);
|
cnt += writeTagProperty(TVG_TAG_SHAPE_STROKE_COLOR, sizeof(color), &color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//dash
|
||||||
const float* dashPattern = nullptr;
|
const float* dashPattern = nullptr;
|
||||||
uint32_t dashCnt = shape->strokeDash(&dashPattern);
|
auto dashCnt = shape->strokeDash(&dashPattern);
|
||||||
if (dashPattern && dashCnt > 0) {
|
if (dashPattern && dashCnt > 0) {
|
||||||
TvgBinCounter dashCntByteCnt = sizeof(dashCnt);
|
TvgBinCounter dashCntSize = sizeof(dashCnt);
|
||||||
TvgBinCounter dashPtrnByteCnt = dashCnt * sizeof(dashPattern[0]);
|
TvgBinCounter dashPtrnSize = dashCnt * sizeof(dashPattern[0]);
|
||||||
|
|
||||||
writeMemberIndicator(TVG_TAG_SHAPE_STROKE_DASHPTRN);
|
writeTag(TVG_TAG_SHAPE_STROKE_DASHPTRN);
|
||||||
writeMemberDataSize(dashCntByteCnt + dashPtrnByteCnt);
|
writeCount(dashCntSize + dashPtrnSize);
|
||||||
strokeDataByteCnt += writeMemberData(&dashCnt, dashCntByteCnt);
|
cnt += writeData(&dashCnt, dashCntSize);
|
||||||
strokeDataByteCnt += writeMemberData(dashPattern, dashPtrnByteCnt);
|
cnt += writeData(dashPattern, dashPtrnSize);
|
||||||
strokeDataByteCnt += SIZE(TvgBinTag) + SIZE(TvgBinCounter);
|
cnt += SIZE(TvgBinTag) + SIZE(TvgBinCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
writeMemberDataSizeAt(strokeDataByteCnt);
|
writeReservedCount(cnt);
|
||||||
|
|
||||||
return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + strokeDataByteCnt;
|
return SERIAL_DONE(cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
TvgBinCounter serializeShapePath(const Shape* shape)
|
TvgBinCounter serializePath(const Shape* shape)
|
||||||
{
|
{
|
||||||
const PathCommand* cmds = nullptr;
|
const PathCommand* cmds = nullptr;
|
||||||
uint32_t cmdCnt = shape->pathCommands(&cmds);
|
auto cmdCnt = shape->pathCommands(&cmds);
|
||||||
const Point* pts = nullptr;
|
const Point* pts = nullptr;
|
||||||
uint32_t ptsCnt = shape->pathCoords(&pts);
|
auto ptsCnt = shape->pathCoords(&pts);
|
||||||
|
|
||||||
if (!cmds || !pts || !cmdCnt || !ptsCnt) return 0;
|
if (!cmds || !pts || cmdCnt == 0 || ptsCnt == 0) return 0;
|
||||||
|
|
||||||
TvgBinCounter pathDataByteCnt = 0;
|
writeTag(TVG_TAG_SHAPE_PATH);
|
||||||
|
reserveCount();
|
||||||
|
|
||||||
writeMemberIndicator(TVG_TAG_SHAPE_PATH);
|
auto cnt = writeData(&cmdCnt, sizeof(cmdCnt));
|
||||||
skipInBufferMemberDataSize();
|
cnt += writeData(&ptsCnt, sizeof(ptsCnt));
|
||||||
|
cnt += writeData(cmds, cmdCnt * sizeof(cmds[0]));
|
||||||
|
cnt += writeData(pts, ptsCnt * sizeof(pts[0]));
|
||||||
|
|
||||||
pathDataByteCnt += writeMemberData(&cmdCnt, sizeof(cmdCnt));
|
writeReservedCount(cnt);
|
||||||
pathDataByteCnt += writeMemberData(&ptsCnt, sizeof(ptsCnt));
|
|
||||||
pathDataByteCnt += writeMemberData(cmds, cmdCnt * sizeof(cmds[0]));
|
|
||||||
pathDataByteCnt += writeMemberData(pts, ptsCnt * sizeof(pts[0]));
|
|
||||||
|
|
||||||
writeMemberDataSizeAt(pathDataByteCnt);
|
return SERIAL_DONE(cnt);
|
||||||
|
|
||||||
return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + pathDataByteCnt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TvgBinCounter serialize(const Shape* shape)
|
TvgBinCounter serializeShape(const Shape* shape)
|
||||||
{
|
{
|
||||||
writeMemberIndicator(TVG_TAG_CLASS_SHAPE);
|
writeTag(TVG_TAG_CLASS_SHAPE);
|
||||||
skipInBufferMemberDataSize();
|
reserveCount();
|
||||||
|
|
||||||
auto ruleTvgBinFlag = (shape->fillRule() == FillRule::EvenOdd) ? TVG_FLAG_SHAPE_FILLRULE_EVENODD : TVG_FLAG_SHAPE_FILLRULE_WINDING;
|
//fill rule
|
||||||
auto shapeDataByteCnt = writeMember(TVG_TAG_SHAPE_FILLRULE, SIZE(TvgBinFlag), &ruleTvgBinFlag);
|
auto flag = (shape->fillRule() == FillRule::EvenOdd) ? TVG_FLAG_SHAPE_FILLRULE_EVENODD : TVG_FLAG_SHAPE_FILLRULE_WINDING;
|
||||||
|
auto cnt = writeTagProperty(TVG_TAG_SHAPE_FILLRULE, SIZE(TvgBinFlag), &flag);
|
||||||
|
|
||||||
if (shape->strokeWidth() > 0) shapeDataByteCnt += serializeShapeStroke(shape);
|
//stroke
|
||||||
|
if (shape->strokeWidth() > 0) cnt += serializeStroke(shape);
|
||||||
|
|
||||||
|
//fill
|
||||||
if (auto fill = shape->fill()) {
|
if (auto fill = shape->fill()) {
|
||||||
shapeDataByteCnt += serializeShapeFill(fill, TVG_TAG_SHAPE_FILL);
|
cnt += serializeFill(fill, TVG_TAG_SHAPE_FILL);
|
||||||
} else {
|
} else {
|
||||||
uint8_t color[4] = {0, 0, 0, 0};
|
uint8_t color[4] = {0, 0, 0, 0};
|
||||||
shape->fillColor(color, color + 1, color + 2, color + 3);
|
shape->fillColor(color, color + 1, color + 2, color + 3);
|
||||||
shapeDataByteCnt += writeMember(TVG_TAG_SHAPE_COLOR, sizeof(color), color);
|
cnt += writeTagProperty(TVG_TAG_SHAPE_COLOR, sizeof(color), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
shapeDataByteCnt += serializeShapePath(shape);
|
cnt += serializePath(shape);
|
||||||
shapeDataByteCnt += serializePaint(shape);
|
cnt += serializePaint(shape);
|
||||||
|
|
||||||
writeMemberDataSizeAt(shapeDataByteCnt);
|
writeReservedCount(cnt);
|
||||||
|
|
||||||
return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + shapeDataByteCnt;
|
return SERIAL_DONE(cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
TvgBinCounter serialize(const Picture* picture)
|
TvgBinCounter serializePicture(const Picture* picture)
|
||||||
{
|
{
|
||||||
auto pixels = picture->data();
|
writeTag(TVG_TAG_CLASS_PICTURE);
|
||||||
|
reserveCount();
|
||||||
|
|
||||||
TvgBinCounter pictureDataByteCnt = 0;
|
TvgBinCounter cnt = 0;
|
||||||
|
|
||||||
writeMemberIndicator(TVG_TAG_CLASS_PICTURE);
|
//Bitmap Image
|
||||||
skipInBufferMemberDataSize();
|
if (auto pixels = picture->data()) {
|
||||||
|
//TODO: Loader expects uints
|
||||||
|
float fw, fh;
|
||||||
|
picture->size(&fw, &fh);
|
||||||
|
|
||||||
if (pixels) {
|
auto w = static_cast<uint32_t>(fw);
|
||||||
//TODO - loader expects uints
|
auto h = static_cast<uint32_t>(fh);
|
||||||
float vw, vh;
|
TvgBinCounter sizeCnt = sizeof(w);
|
||||||
picture->viewbox(nullptr, nullptr, &vw, &vh);
|
TvgBinCounter imgSize = w * h * sizeof(pixels[0]);
|
||||||
|
|
||||||
uint32_t w = static_cast<uint32_t>(vw);
|
writeTag(TVG_TAG_PICTURE_RAW_IMAGE);
|
||||||
uint32_t h = static_cast<uint32_t>(vh);
|
writeCount(2 * sizeCnt + imgSize);
|
||||||
TvgBinCounter wByteCnt = sizeof(w); // same as h size
|
|
||||||
TvgBinCounter pixelsByteCnt = w * h * sizeof(pixels[0]);
|
|
||||||
|
|
||||||
writeMemberIndicator(TVG_TAG_PICTURE_RAW_IMAGE);
|
cnt += writeData(&w, sizeCnt);
|
||||||
writeMemberDataSize(2 * wByteCnt + pixelsByteCnt);
|
cnt += writeData(&h, sizeCnt);
|
||||||
pictureDataByteCnt += writeMemberData(&w, wByteCnt);
|
cnt += writeData(pixels, imgSize);
|
||||||
pictureDataByteCnt += writeMemberData(&h, wByteCnt);
|
cnt += SIZE(TvgBinTag) + SIZE(TvgBinCounter);
|
||||||
pictureDataByteCnt += writeMemberData(pixels, pixelsByteCnt);
|
//Vector Image
|
||||||
pictureDataByteCnt += SIZE(TvgBinTag) + SIZE(TvgBinCounter);
|
|
||||||
} else {
|
} else {
|
||||||
pictureDataByteCnt += serializeChildren(picture);
|
cnt += serializeChildren(picture);
|
||||||
}
|
}
|
||||||
|
|
||||||
pictureDataByteCnt += serializePaint(picture);
|
cnt += serializePaint(picture);
|
||||||
|
|
||||||
writeMemberDataSizeAt(pictureDataByteCnt);
|
writeReservedCount(cnt);
|
||||||
|
|
||||||
return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + pictureDataByteCnt;
|
return SERIAL_DONE(cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
TvgBinCounter serializeComposite(const Paint* cmpTarget, CompositeMethod cmpMethod)
|
TvgBinCounter serializeComposite(const Paint* cmpTarget, CompositeMethod cmpMethod)
|
||||||
{
|
{
|
||||||
TvgBinCounter cmpDataByteCnt = 0;
|
writeTag(TVG_TAG_PAINT_CMP_TARGET);
|
||||||
|
reserveCount();
|
||||||
|
|
||||||
writeMemberIndicator(TVG_TAG_PAINT_CMP_TARGET);
|
auto flag = static_cast<TvgBinFlag>(cmpMethod);
|
||||||
skipInBufferMemberDataSize();
|
auto cnt = writeTagProperty(TVG_TAG_PAINT_CMP_METHOD, SIZE(TvgBinFlag), &flag);
|
||||||
|
|
||||||
auto cmpMethodTvgBinFlag = static_cast<TvgBinFlag>(cmpMethod);
|
cnt += serialize(cmpTarget);
|
||||||
cmpDataByteCnt += writeMember(TVG_TAG_PAINT_CMP_METHOD, SIZE(TvgBinFlag), &cmpMethodTvgBinFlag);
|
|
||||||
|
|
||||||
cmpDataByteCnt += serialize(cmpTarget);
|
writeReservedCount(cnt);
|
||||||
|
|
||||||
writeMemberDataSizeAt(cmpDataByteCnt);
|
return SERIAL_DONE(cnt);
|
||||||
|
|
||||||
return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + cmpDataByteCnt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TvgBinCounter serializeChildren(const Paint* paint)
|
TvgBinCounter serializeChildren(const Paint* paint)
|
||||||
{
|
{
|
||||||
TvgBinCounter dataByteCnt = 0;
|
|
||||||
|
|
||||||
auto it = paint->pImpl->iterator();
|
auto it = paint->pImpl->iterator();
|
||||||
|
if (!it) return 0;
|
||||||
|
|
||||||
while (auto p = it->next()) {
|
TvgBinCounter cnt = 0;
|
||||||
dataByteCnt += serialize(p);
|
|
||||||
}
|
while (auto p = it->next())
|
||||||
|
cnt += serialize(p);
|
||||||
|
|
||||||
delete(it);
|
delete(it);
|
||||||
|
|
||||||
return dataByteCnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
TvgBinCounter serialize(const Paint* paint)
|
TvgBinCounter serialize(const Paint* paint)
|
||||||
|
@ -367,9 +381,9 @@ struct Saver::Impl
|
||||||
if (!paint) return 0;
|
if (!paint) return 0;
|
||||||
|
|
||||||
switch (paint->id()) {
|
switch (paint->id()) {
|
||||||
case TVG_CLASS_ID_SHAPE: return serialize(static_cast<const Shape*>(paint));
|
case TVG_CLASS_ID_SHAPE: return serializeShape(static_cast<const Shape*>(paint));
|
||||||
case TVG_CLASS_ID_SCENE: return serialize(static_cast<const Scene*>(paint));
|
case TVG_CLASS_ID_SCENE: return serializeScene(static_cast<const Scene*>(paint));
|
||||||
case TVG_CLASS_ID_PICTURE: return serialize(static_cast<const Picture*>(paint));
|
case TVG_CLASS_ID_PICTURE: return serializePicture(static_cast<const Picture*>(paint));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -386,7 +400,7 @@ struct Saver::Impl
|
||||||
|
|
||||||
if (!writeHeader()) return false;
|
if (!writeHeader()) return false;
|
||||||
if (serialize(paint) == 0) return false;
|
if (serialize(paint) == 0) return false;
|
||||||
if (!bufferToFile(path)) return false;
|
if (!flushTo(path)) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue