tvg format: code refactoring #9

revise format of the macro names, no logical changes.
++ comments for maintenence.
This commit is contained in:
Hermet Park 2021-07-21 11:14:11 +09:00 committed by Hermet Park
parent e0667ca7f1
commit 02b3d7dd20
3 changed files with 211 additions and 198 deletions

View file

@ -22,72 +22,80 @@
#ifndef _TVG_BINARY_DESC_H_
#define _TVG_BINARY_DESC_H_
//TODO: Need to consider whether uin8_t is enough size for extension...
/* Data types, do not change data types once Tvg Format is officially released,
That would occur the abi break. */
using TvgBinByte = uint8_t;
using TvgIndicator = uint8_t;
using ByteCounter = uint32_t;
using TvgFlag = uint8_t;
using TvgBinTag = uint8_t;
using TvgBinCounter = uint32_t;
using TvgBinFlag = uint8_t;
#define TVG_INDICATOR_SIZE sizeof(TvgIndicator)
#define BYTE_COUNTER_SIZE sizeof(ByteCounter)
#define TVG_FLAG_SIZE sizeof(TvgFlag)
//Header
#define TVG_HEADER_SIGNATURE "ThorVG"
#define TVG_HEADER_SIGNATURE_LENGTH 6
#define TVG_HEADER_VERSION "000400" //Major 00, Minor 04, Micro 00
#define TVG_HEADER_VERSION_LENGTH 6
// HEADER
#define TVG_BIN_HEADER_SIGNATURE "ThorVG"
#define TVG_BIN_HEADER_SIGNATURE_LENGTH 6
#define TVG_BIN_HEADER_VERSION "000200"
#define TVG_BIN_HEADER_VERSION_LENGTH 6
#define TVG_PICTURE_BEGIN_INDICATOR (TvgIndicator)0xfc
#define TVG_SHAPE_BEGIN_INDICATOR (TvgIndicator)0xfd
#define TVG_SCENE_BEGIN_INDICATOR (TvgIndicator)0xfe
//Paint Type
#define TVG_TAG_CLASS_PICTURE (TvgBinTag)0xfc
#define TVG_TAG_CLASS_SHAPE (TvgBinTag)0xfd
#define TVG_TAG_CLASS_SCENE (TvgBinTag)0xfe
//Paint
#define TVG_PAINT_OPACITY_INDICATOR (TvgIndicator)0x10
#define TVG_PAINT_TRANSFORM_MATRIX_INDICATOR (TvgIndicator)0x11
#define TVG_PAINT_CMP_TARGET_INDICATOR (TvgIndicator)0x1
#define TVG_TAG_PAINT_OPACITY (TvgBinTag)0x10
#define TVG_TAG_PAINT_TRANSFORM (TvgBinTag)0x11
#define TVG_TAG_PAINT_CMP_TARGET (TvgBinTag)0x01
//Composition
#define TVG_TAG_PAINT_CMP_METHOD (TvgBinTag)0x20
#define TVG_FLAG_PAINT_CMP_METHOD_CLIPPATH (TvgBinFlag)0x01
#define TVG_FLAG_PAINT_CMP_METHOD_ALPHAMASK (TvgBinFlag)0x02
#define TVG_FLAG_PAINT_CMP_METHOD_IALPHAMASK (TvgBinFlag)0x03
#define TVG_PAINT_CMP_METHOD_INDICATOR (TvgIndicator)0x20
#define TVG_PAINT_CMP_METHOD_CLIPPATH_FLAG (TvgFlag)0x01
#define TVG_PAINT_CMP_METHOD_ALPHAMASK_FLAG (TvgFlag)0x02
#define TVG_PAINT_CMP_METHOD_INV_ALPHAMASK_FLAG (TvgFlag)0x03
//Scene
#define TVG_SCENE_FLAG_RESERVEDCNT (TvgIndicator)0x30
#define TVG_FLAG_SCENE_RESERVEDCNT (TvgBinTag)0x30
//Shape
#define TVG_SHAPE_PATH_INDICATOR (TvgIndicator)0x40
#define TVG_SHAPE_STROKE_INDICATOR (TvgIndicator)0x41
#define TVG_SHAPE_FILL_INDICATOR (TvgIndicator)0x42
#define TVG_SHAPE_COLOR_INDICATOR (TvgIndicator)0x43
#define TVG_TAG_SHAPE_PATH (TvgBinTag)0x40
#define TVG_TAG_SHAPE_STROKE (TvgBinTag)0x41
#define TVG_TAG_SHAPE_FILL (TvgBinTag)0x42
#define TVG_TAG_SHAPE_COLOR (TvgBinTag)0x43
//Fill Rule
#define TVG_TAG_SHAPE_FILLRULE (TvgBinTag)0x44
#define TVG_FLAG_SHAPE_FILLRULE_WINDING (TvgBinFlag)0x00
#define TVG_FLAG_SHAPE_FILLRULE_EVENODD (TvgBinFlag)0x01
//Stroke Cap
#define TVG_TAG_SHAPE_STROKE_CAP (TvgBinTag)0x50
#define TVG_FLAG_SHAPE_STROKE_CAP_SQUARE (TvgBinFlag)0x00
#define TVG_FLAG_SHAPE_STROKE_CAP_ROUND (TvgBinFlag)0x01
#define TVG_FLAG_SHAPE_STROKE_CAP_BUTT (TvgBinFlag)0x02
//Stroke Join
#define TVG_TAG_SHAPE_STROKE_JOIN (TvgBinTag)0x51
#define TVG_FLAG_SHAPE_STROKE_JOIN_BEVEL (TvgBinFlag)0x00
#define TVG_FLAG_SHAPE_STROKE_JOIN_ROUND (TvgBinFlag)0x01
#define TVG_FLAG_SHAPE_STROKE_JOIN_MITER (TvgBinFlag)0x02
//Stroke
#define TVG_TAG_SHAPE_STROKE_WIDTH (TvgBinTag)0x52
#define TVG_TAG_SHAPE_STROKE_COLOR (TvgBinTag)0x53
#define TVG_TAG_SHAPE_STROKE_FILL (TvgBinTag)0x54
#define TVG_TAG_SHAPE_STROKE_DASHPTRN (TvgBinTag)0x55
#define TVG_SHAPE_FILLRULE_INDICATOR (TvgIndicator)0x44
#define TVG_SHAPE_FILLRULE_WINDING_FLAG (TvgFlag)0x00
#define TVG_SHAPE_FILLRULE_EVENODD_FLAG (TvgFlag)0x01
#define TVG_SHAPE_STROKE_CAP_INDICATOR (TvgIndicator)0x50
#define TVG_SHAPE_STROKE_CAP_SQUARE_FLAG (TvgFlag)0x00
#define TVG_SHAPE_STROKE_CAP_ROUND_FLAG (TvgFlag)0x01
#define TVG_SHAPE_STROKE_CAP_BUTT_FLAG (TvgFlag)0x02
//Fill
#define TVG_TAG_FILL_LINEAR_GRADIENT (TvgBinTag)0x60
#define TVG_TAG_FILL_RADIAL_GRADIENT (TvgBinTag)0x61
#define TVG_TAG_FILL_COLORSTOPS (TvgBinTag)0x62
#define TVG_TAG_FILL_FILLSPREAD (TvgBinTag)0x63
#define TVG_FLAG_FILL_FILLSPREAD_PAD (TvgBinFlag)0x00
#define TVG_FLAG_FILL_FILLSPREAD_REFLECT (TvgBinFlag)0x01
#define TVG_FLAG_FILL_FILLSPREAD_REPEAT (TvgBinFlag)0x02
#define TVG_SHAPE_STROKE_JOIN_INDICATOR (TvgIndicator)0x51
#define TVG_SHAPE_STROKE_JOIN_BEVEL_FLAG (TvgFlag)0x00
#define TVG_SHAPE_STROKE_JOIN_ROUND_FLAG (TvgFlag)0x01
#define TVG_SHAPE_STROKE_JOIN_MITER_FLAG (TvgFlag)0x02
#define TVG_SHAPE_STROKE_WIDTH_INDICATOR (TvgIndicator)0x52
#define TVG_SHAPE_STROKE_COLOR_INDICATOR (TvgIndicator)0x53
#define TVG_SHAPE_STROKE_FILL_INDICATOR (TvgIndicator)0x54
#define TVG_SHAPE_STROKE_DASHPTRN_INDICATOR (TvgIndicator)0x55
#define TVG_FILL_LINEAR_GRADIENT_INDICATOR (TvgIndicator)0x60
#define TVG_FILL_RADIAL_GRADIENT_INDICATOR (TvgIndicator)0x61
#define TVG_FILL_COLORSTOPS_INDICATOR (TvgIndicator)0x62
#define TVG_FILL_FILLSPREAD_INDICATOR (TvgIndicator)0x63
#define TVG_FILL_FILLSPREAD_PAD_FLAG (TvgFlag)0x00
#define TVG_FILL_FILLSPREAD_REFLECT_FLAG (TvgFlag)0x01
#define TVG_FILL_FILLSPREAD_REPEAT_FLAG (TvgFlag)0x02
//Picture
#define TVG_RAW_IMAGE_BEGIN_INDICATOR (TvgIndicator)0x70
#define TVG_TAG_PICTURE_RAW_IMAGE (TvgBinTag)0x70
#endif //_TVG_BINARY_DESC_H_

View file

@ -28,6 +28,8 @@
#include "tvgPaint.h"
#include "tvgBinaryDesc.h"
#define SIZE(A) sizeof(A)
struct Saver::Impl
{
@ -62,45 +64,45 @@ struct Saver::Impl
bool writeHeader()
{
buffer.grow(TVG_BIN_HEADER_SIGNATURE_LENGTH + TVG_BIN_HEADER_VERSION_LENGTH);
buffer.grow(TVG_HEADER_SIGNATURE_LENGTH + TVG_HEADER_VERSION_LENGTH);
auto ptr = buffer.ptr();
memcpy(ptr, TVG_BIN_HEADER_SIGNATURE, TVG_BIN_HEADER_SIGNATURE_LENGTH);
ptr += TVG_BIN_HEADER_SIGNATURE_LENGTH;
memcpy(ptr, TVG_BIN_HEADER_VERSION, TVG_BIN_HEADER_VERSION_LENGTH);
ptr += TVG_BIN_HEADER_VERSION_LENGTH;
memcpy(ptr, TVG_HEADER_SIGNATURE, TVG_HEADER_SIGNATURE_LENGTH);
ptr += TVG_HEADER_SIGNATURE_LENGTH;
memcpy(ptr, TVG_HEADER_VERSION, TVG_HEADER_VERSION_LENGTH);
ptr += TVG_HEADER_VERSION_LENGTH;
buffer.count += (TVG_BIN_HEADER_SIGNATURE_LENGTH + TVG_BIN_HEADER_VERSION_LENGTH);
buffer.count += (TVG_HEADER_SIGNATURE_LENGTH + TVG_HEADER_VERSION_LENGTH);
return true;
}
void writeMemberIndicator(TvgIndicator ind)
void writeMemberIndicator(TvgBinTag ind)
{
buffer.grow(TVG_INDICATOR_SIZE);
memcpy(buffer.ptr(), &ind, TVG_INDICATOR_SIZE);
buffer.count += TVG_INDICATOR_SIZE;
buffer.grow(SIZE(TvgBinTag));
memcpy(buffer.ptr(), &ind, SIZE(TvgBinTag));
buffer.count += SIZE(TvgBinTag);
}
void writeMemberDataSize(ByteCounter byteCnt)
void writeMemberDataSize(TvgBinCounter byteCnt)
{
buffer.grow(BYTE_COUNTER_SIZE);
memcpy(buffer.ptr(), &byteCnt, BYTE_COUNTER_SIZE);
buffer.count += BYTE_COUNTER_SIZE;
buffer.grow(SIZE(TvgBinCounter));
memcpy(buffer.ptr(), &byteCnt, SIZE(TvgBinCounter));
buffer.count += SIZE(TvgBinCounter);
}
void writeMemberDataSizeAt(ByteCounter byteCnt)
void writeMemberDataSizeAt(TvgBinCounter byteCnt)
{
memcpy(buffer.ptr() - byteCnt - BYTE_COUNTER_SIZE, &byteCnt, BYTE_COUNTER_SIZE);
memcpy(buffer.ptr() - byteCnt - SIZE(TvgBinCounter), &byteCnt, SIZE(TvgBinCounter));
}
void skipInBufferMemberDataSize()
{
buffer.grow(BYTE_COUNTER_SIZE);
buffer.count += BYTE_COUNTER_SIZE;
buffer.grow(SIZE(TvgBinCounter));
buffer.count += SIZE(TvgBinCounter);
}
ByteCounter writeMemberData(const void* data, ByteCounter byteCnt)
TvgBinCounter writeMemberData(const void* data, TvgBinCounter byteCnt)
{
buffer.grow(byteCnt);
memcpy(buffer.ptr(), data, byteCnt);
@ -109,18 +111,18 @@ struct Saver::Impl
return byteCnt;
}
ByteCounter writeMember(TvgIndicator ind, ByteCounter byteCnt, const void* data)
TvgBinCounter writeMember(TvgBinTag ind, TvgBinCounter byteCnt, const void* data)
{
ByteCounter blockByteCnt = TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + byteCnt;
TvgBinCounter blockByteCnt = SIZE(TvgBinTag) + SIZE(TvgBinCounter) + byteCnt;
buffer.grow(blockByteCnt);
auto ptr = buffer.ptr();
memcpy(ptr, &ind, TVG_INDICATOR_SIZE);
ptr += TVG_INDICATOR_SIZE;
memcpy(ptr, &byteCnt, BYTE_COUNTER_SIZE);
ptr += BYTE_COUNTER_SIZE;
memcpy(ptr, &ind, SIZE(TvgBinTag));
ptr += SIZE(TvgBinTag);
memcpy(ptr, &byteCnt, SIZE(TvgBinCounter));
ptr += SIZE(TvgBinCounter);
memcpy(ptr, data, byteCnt);
ptr += byteCnt;
@ -129,20 +131,20 @@ struct Saver::Impl
return blockByteCnt;
}
ByteCounter serializePaint(const Paint* paint)
TvgBinCounter serializePaint(const Paint* paint)
{
ByteCounter paintDataByteCnt = 0;
TvgBinCounter paintDataByteCnt = 0;
auto opacity = paint->opacity();
if (opacity < 255) {
paintDataByteCnt += writeMember(TVG_PAINT_OPACITY_INDICATOR, sizeof(opacity), &opacity);
paintDataByteCnt += writeMember(TVG_TAG_PAINT_OPACITY, sizeof(opacity), &opacity);
}
auto m = const_cast<Paint*>(paint)->transform();
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.e31) > FLT_EPSILON || fabs(m.e32) > FLT_EPSILON || fabs(m.e33 - 1) > FLT_EPSILON) {
paintDataByteCnt += writeMember(TVG_PAINT_TRANSFORM_MATRIX_INDICATOR, sizeof(m), &m);
paintDataByteCnt += writeMember(TVG_TAG_PAINT_TRANSFORM, sizeof(m), &m);
}
const Paint* cmpTarget = nullptr;
@ -154,9 +156,9 @@ struct Saver::Impl
return paintDataByteCnt;
}
ByteCounter serializeScene(const Scene* scene)
TvgBinCounter serialize(const Scene* scene)
{
writeMemberIndicator(TVG_SCENE_BEGIN_INDICATOR);
writeMemberIndicator(TVG_TAG_CLASS_SCENE);
skipInBufferMemberDataSize();
auto sceneDataByteCnt = serializeChildren(scene);
@ -164,85 +166,85 @@ struct Saver::Impl
writeMemberDataSizeAt(sceneDataByteCnt);
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + sceneDataByteCnt;
return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + sceneDataByteCnt;
}
ByteCounter serializeShapeFill(const Fill* f, TvgIndicator fillTvgFlag)
TvgBinCounter serializeShapeFill(const Fill* f, TvgBinTag fillTvgBinFlag)
{
ByteCounter fillDataByteCnt = 0;
TvgBinCounter fillDataByteCnt = 0;
const Fill::ColorStop* stops = nullptr;
auto stopsCnt = f->colorStops(&stops);
if (!stops || stopsCnt == 0) return 0;
writeMemberIndicator(fillTvgFlag);
writeMemberIndicator(fillTvgBinFlag);
skipInBufferMemberDataSize();
if (f->id() == TVG_CLASS_ID_RADIAL) {
float argRadial[3];
auto radGrad = static_cast<const RadialGradient*>(f);
radGrad->radial(argRadial, argRadial + 1,argRadial + 2);
fillDataByteCnt += writeMember(TVG_FILL_RADIAL_GRADIENT_INDICATOR, sizeof(argRadial), argRadial);
fillDataByteCnt += writeMember(TVG_TAG_FILL_RADIAL_GRADIENT, sizeof(argRadial), argRadial);
}
else {
float argLinear[4];
auto linGrad = static_cast<const LinearGradient*>(f);
linGrad->linear(argLinear, argLinear + 1, argLinear + 2, argLinear + 3);
fillDataByteCnt += writeMember(TVG_FILL_LINEAR_GRADIENT_INDICATOR, sizeof(argLinear), argLinear);
fillDataByteCnt += writeMember(TVG_TAG_FILL_LINEAR_GRADIENT, sizeof(argLinear), argLinear);
}
auto flag = static_cast<TvgFlag>(f->spread());
fillDataByteCnt += writeMember(TVG_FILL_FILLSPREAD_INDICATOR, TVG_FLAG_SIZE, &flag);
fillDataByteCnt += writeMember(TVG_FILL_COLORSTOPS_INDICATOR, stopsCnt * sizeof(stops), stops);
auto flag = static_cast<TvgBinFlag>(f->spread());
fillDataByteCnt += writeMember(TVG_TAG_FILL_FILLSPREAD, SIZE(TvgBinFlag), &flag);
fillDataByteCnt += writeMember(TVG_TAG_FILL_COLORSTOPS, stopsCnt * sizeof(stops), stops);
writeMemberDataSizeAt(fillDataByteCnt);
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + fillDataByteCnt;
return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + fillDataByteCnt;
}
ByteCounter serializeShapeStroke(const Shape* shape)
TvgBinCounter serializeShapeStroke(const Shape* shape)
{
ByteCounter strokeDataByteCnt = 0;
TvgFlag flag;
TvgBinCounter strokeDataByteCnt = 0;
TvgBinFlag flag;
writeMemberIndicator(TVG_SHAPE_STROKE_INDICATOR);
writeMemberIndicator(TVG_TAG_SHAPE_STROKE);
skipInBufferMemberDataSize();
flag = static_cast<TvgFlag>(shape->strokeCap());
strokeDataByteCnt += writeMember(TVG_SHAPE_STROKE_CAP_INDICATOR, TVG_FLAG_SIZE, &flag);
flag = static_cast<TvgBinFlag>(shape->strokeCap());
strokeDataByteCnt += writeMember(TVG_TAG_SHAPE_STROKE_CAP, SIZE(TvgBinFlag), &flag);
flag = static_cast<TvgFlag>(shape->strokeJoin());
strokeDataByteCnt += writeMember(TVG_SHAPE_STROKE_JOIN_INDICATOR, TVG_FLAG_SIZE, &flag);
flag = static_cast<TvgBinFlag>(shape->strokeJoin());
strokeDataByteCnt += writeMember(TVG_TAG_SHAPE_STROKE_JOIN, SIZE(TvgBinFlag), &flag);
float width = shape->strokeWidth();
strokeDataByteCnt += writeMember(TVG_SHAPE_STROKE_WIDTH_INDICATOR, sizeof(width), &width);
strokeDataByteCnt += writeMember(TVG_TAG_SHAPE_STROKE_WIDTH, sizeof(width), &width);
if (auto fill = shape->strokeFill()) {
strokeDataByteCnt += serializeShapeFill(fill, TVG_SHAPE_STROKE_FILL_INDICATOR);
strokeDataByteCnt += serializeShapeFill(fill, TVG_TAG_SHAPE_STROKE_FILL);
} else {
uint8_t color[4] = {0, 0, 0, 0};
shape->strokeColor(color, color + 1, color + 2, color + 3);
strokeDataByteCnt += writeMember(TVG_SHAPE_STROKE_COLOR_INDICATOR, sizeof(color), &color);
strokeDataByteCnt += writeMember(TVG_TAG_SHAPE_STROKE_COLOR, sizeof(color), &color);
}
const float* dashPattern = nullptr;
uint32_t dashCnt = shape->strokeDash(&dashPattern);
if (dashPattern && dashCnt > 0) {
ByteCounter dashCntByteCnt = sizeof(dashCnt);
ByteCounter dashPtrnByteCnt = dashCnt * sizeof(dashPattern[0]);
TvgBinCounter dashCntByteCnt = sizeof(dashCnt);
TvgBinCounter dashPtrnByteCnt = dashCnt * sizeof(dashPattern[0]);
writeMemberIndicator(TVG_SHAPE_STROKE_DASHPTRN_INDICATOR);
writeMemberIndicator(TVG_TAG_SHAPE_STROKE_DASHPTRN);
writeMemberDataSize(dashCntByteCnt + dashPtrnByteCnt);
strokeDataByteCnt += writeMemberData(&dashCnt, dashCntByteCnt);
strokeDataByteCnt += writeMemberData(dashPattern, dashPtrnByteCnt);
strokeDataByteCnt += TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE;
strokeDataByteCnt += SIZE(TvgBinTag) + SIZE(TvgBinCounter);
}
writeMemberDataSizeAt(strokeDataByteCnt);
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + strokeDataByteCnt;
return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + strokeDataByteCnt;
}
ByteCounter serializeShapePath(const Shape* shape)
TvgBinCounter serializeShapePath(const Shape* shape)
{
const PathCommand* cmds = nullptr;
uint32_t cmdCnt = shape->pathCommands(&cmds);
@ -251,9 +253,9 @@ struct Saver::Impl
if (!cmds || !pts || !cmdCnt || !ptsCnt) return 0;
ByteCounter pathDataByteCnt = 0;
TvgBinCounter pathDataByteCnt = 0;
writeMemberIndicator(TVG_SHAPE_PATH_INDICATOR);
writeMemberIndicator(TVG_TAG_SHAPE_PATH);
skipInBufferMemberDataSize();
pathDataByteCnt += writeMemberData(&cmdCnt, sizeof(cmdCnt));
@ -263,25 +265,25 @@ struct Saver::Impl
writeMemberDataSizeAt(pathDataByteCnt);
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + pathDataByteCnt;
return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + pathDataByteCnt;
}
ByteCounter serializeShape(const Shape* shape)
TvgBinCounter serialize(const Shape* shape)
{
writeMemberIndicator(TVG_SHAPE_BEGIN_INDICATOR);
writeMemberIndicator(TVG_TAG_CLASS_SHAPE);
skipInBufferMemberDataSize();
auto ruleTvgFlag = (shape->fillRule() == FillRule::EvenOdd) ? TVG_SHAPE_FILLRULE_EVENODD_FLAG : TVG_SHAPE_FILLRULE_WINDING_FLAG;
auto shapeDataByteCnt = writeMember(TVG_SHAPE_FILLRULE_INDICATOR, TVG_FLAG_SIZE, &ruleTvgFlag);
auto ruleTvgBinFlag = (shape->fillRule() == FillRule::EvenOdd) ? TVG_FLAG_SHAPE_FILLRULE_EVENODD : TVG_FLAG_SHAPE_FILLRULE_WINDING;
auto shapeDataByteCnt = writeMember(TVG_TAG_SHAPE_FILLRULE, SIZE(TvgBinFlag), &ruleTvgBinFlag);
if (shape->strokeWidth() > 0) shapeDataByteCnt += serializeShapeStroke(shape);
if (auto fill = shape->fill()) {
shapeDataByteCnt += serializeShapeFill(fill, TVG_SHAPE_FILL_INDICATOR);
shapeDataByteCnt += serializeShapeFill(fill, TVG_TAG_SHAPE_FILL);
} else {
uint8_t color[4] = {0, 0, 0, 0};
shape->fillColor(color, color + 1, color + 2, color + 3);
shapeDataByteCnt += writeMember(TVG_SHAPE_COLOR_INDICATOR, sizeof(color), color);
shapeDataByteCnt += writeMember(TVG_TAG_SHAPE_COLOR, sizeof(color), color);
}
shapeDataByteCnt += serializeShapePath(shape);
@ -289,16 +291,16 @@ struct Saver::Impl
writeMemberDataSizeAt(shapeDataByteCnt);
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + shapeDataByteCnt;
return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + shapeDataByteCnt;
}
ByteCounter serializePicture(const Picture* picture)
TvgBinCounter serialize(const Picture* picture)
{
auto pixels = picture->data();
ByteCounter pictureDataByteCnt = 0;
TvgBinCounter pictureDataByteCnt = 0;
writeMemberIndicator(TVG_PICTURE_BEGIN_INDICATOR);
writeMemberIndicator(TVG_TAG_CLASS_PICTURE);
skipInBufferMemberDataSize();
if (pixels) {
@ -308,15 +310,15 @@ struct Saver::Impl
uint32_t w = static_cast<uint32_t>(vw);
uint32_t h = static_cast<uint32_t>(vh);
ByteCounter wByteCnt = sizeof(w); // same as h size
ByteCounter pixelsByteCnt = w * h * sizeof(pixels[0]);
TvgBinCounter wByteCnt = sizeof(w); // same as h size
TvgBinCounter pixelsByteCnt = w * h * sizeof(pixels[0]);
writeMemberIndicator(TVG_RAW_IMAGE_BEGIN_INDICATOR);
writeMemberIndicator(TVG_TAG_PICTURE_RAW_IMAGE);
writeMemberDataSize(2 * wByteCnt + pixelsByteCnt);
pictureDataByteCnt += writeMemberData(&w, wByteCnt);
pictureDataByteCnt += writeMemberData(&h, wByteCnt);
pictureDataByteCnt += writeMemberData(pixels, pixelsByteCnt);
pictureDataByteCnt += TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE;
pictureDataByteCnt += SIZE(TvgBinTag) + SIZE(TvgBinCounter);
} else {
pictureDataByteCnt += serializeChildren(picture);
}
@ -325,29 +327,29 @@ struct Saver::Impl
writeMemberDataSizeAt(pictureDataByteCnt);
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + pictureDataByteCnt;
return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + pictureDataByteCnt;
}
ByteCounter serializeComposite(const Paint* cmpTarget, CompositeMethod cmpMethod)
TvgBinCounter serializeComposite(const Paint* cmpTarget, CompositeMethod cmpMethod)
{
ByteCounter cmpDataByteCnt = 0;
TvgBinCounter cmpDataByteCnt = 0;
writeMemberIndicator(TVG_PAINT_CMP_TARGET_INDICATOR);
writeMemberIndicator(TVG_TAG_PAINT_CMP_TARGET);
skipInBufferMemberDataSize();
auto cmpMethodTvgFlag = static_cast<TvgFlag>(cmpMethod);
cmpDataByteCnt += writeMember(TVG_PAINT_CMP_METHOD_INDICATOR, TVG_FLAG_SIZE, &cmpMethodTvgFlag);
auto cmpMethodTvgBinFlag = static_cast<TvgBinFlag>(cmpMethod);
cmpDataByteCnt += writeMember(TVG_TAG_PAINT_CMP_METHOD, SIZE(TvgBinFlag), &cmpMethodTvgBinFlag);
cmpDataByteCnt += serialize(cmpTarget);
writeMemberDataSizeAt(cmpDataByteCnt);
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + cmpDataByteCnt;
return SIZE(TvgBinTag) + SIZE(TvgBinCounter) + cmpDataByteCnt;
}
ByteCounter serializeChildren(const Paint* paint)
TvgBinCounter serializeChildren(const Paint* paint)
{
ByteCounter dataByteCnt = 0;
TvgBinCounter dataByteCnt = 0;
auto it = paint->pImpl->iterator();
@ -360,14 +362,14 @@ struct Saver::Impl
return dataByteCnt;
}
ByteCounter serialize(const Paint* paint)
TvgBinCounter serialize(const Paint* paint)
{
if (!paint) return 0;
switch (paint->id()) {
case TVG_CLASS_ID_SHAPE: return serializeShape(static_cast<const Shape*>(paint));
case TVG_CLASS_ID_SCENE: return serializeScene(static_cast<const Scene*>(paint));
case TVG_CLASS_ID_PICTURE: return serializePicture(static_cast<const Picture*>(paint));
case TVG_CLASS_ID_SHAPE: return serialize(static_cast<const Shape*>(paint));
case TVG_CLASS_ID_SCENE: return serialize(static_cast<const Scene*>(paint));
case TVG_CLASS_ID_PICTURE: return serialize(static_cast<const Picture*>(paint));
}
return 0;

View file

@ -28,10 +28,13 @@
/* Internal Class Implementation */
/************************************************************************/
#define SIZE(A) sizeof(A)
struct TvgBinBlock
{
TvgIndicator type;
ByteCounter length;
TvgBinTag type;
TvgBinCounter length;
const char* data;
const char* end;
};
@ -44,9 +47,9 @@ static Paint* _parsePaint(TvgBinBlock block);
static bool _paintProperty(TvgBinBlock block)
{
switch (block.type) {
case TVG_PAINT_OPACITY_INDICATOR:
case TVG_PAINT_TRANSFORM_MATRIX_INDICATOR:
case TVG_PAINT_CMP_TARGET_INDICATOR:
case TVG_TAG_PAINT_OPACITY:
case TVG_TAG_PAINT_TRANSFORM:
case TVG_TAG_PAINT_CMP_TARGET:
return true;
}
return false;
@ -57,8 +60,8 @@ static TvgBinBlock _readBlock(const char *ptr)
{
TvgBinBlock block;
block.type = *ptr;
_read_tvg_ui32(&block.length, ptr + TVG_INDICATOR_SIZE);
block.data = ptr + TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE;
_read_tvg_ui32(&block.length, ptr + SIZE(TvgBinTag));
block.data = ptr + SIZE(TvgBinTag) + SIZE(TvgBinCounter);
block.end = block.data + block.length;
return block;
}
@ -67,13 +70,13 @@ static bool _readTvgHeader(const char **ptr)
{
if (!*ptr) return false;
//Sign phase, always TVG_BIN_HEADER_SIGNATURE is declared
if (memcmp(*ptr, TVG_BIN_HEADER_SIGNATURE, TVG_BIN_HEADER_SIGNATURE_LENGTH)) return false;
*ptr += TVG_BIN_HEADER_SIGNATURE_LENGTH;
//Sign phase, always TVG_HEADER_SIGNATURE is declared
if (memcmp(*ptr, TVG_HEADER_SIGNATURE, TVG_HEADER_SIGNATURE_LENGTH)) return false;
*ptr += TVG_HEADER_SIGNATURE_LENGTH;
//Version number, declared in TVG_BIN_HEADER_VERSION
if (memcmp(*ptr, TVG_BIN_HEADER_VERSION, TVG_BIN_HEADER_VERSION_LENGTH)) return false;
*ptr += TVG_BIN_HEADER_VERSION_LENGTH;
//Version number, declared in TVG_HEADER_VERSION
if (memcmp(*ptr, TVG_HEADER_VERSION, TVG_HEADER_VERSION_LENGTH)) return false;
*ptr += TVG_HEADER_VERSION_LENGTH;
return true;
}
@ -84,21 +87,21 @@ static bool _parseCmpTarget(const char *ptr, const char *end, Paint *paint)
auto block = _readBlock(ptr);
if (block.end > end) return false;
if (block.type != TVG_PAINT_CMP_METHOD_INDICATOR) return false;
if (block.length != sizeof(TvgFlag)) return false;
if (block.type != TVG_TAG_PAINT_CMP_METHOD) return false;
if (block.length != sizeof(TvgBinFlag)) return false;
CompositeMethod cmpMethod;
switch (*block.data) {
case TVG_PAINT_CMP_METHOD_CLIPPATH_FLAG: {
case TVG_FLAG_PAINT_CMP_METHOD_CLIPPATH: {
cmpMethod = CompositeMethod::ClipPath;
break;
}
case TVG_PAINT_CMP_METHOD_ALPHAMASK_FLAG: {
case TVG_FLAG_PAINT_CMP_METHOD_ALPHAMASK: {
cmpMethod = CompositeMethod::AlphaMask;
break;
}
case TVG_PAINT_CMP_METHOD_INV_ALPHAMASK_FLAG: {
case TVG_FLAG_PAINT_CMP_METHOD_IALPHAMASK: {
cmpMethod = CompositeMethod::InvAlphaMask;
break;
}
@ -119,20 +122,20 @@ static bool _parseCmpTarget(const char *ptr, const char *end, Paint *paint)
static bool _parsePaintProperty(TvgBinBlock block, Paint *paint)
{
switch (block.type) {
case TVG_PAINT_OPACITY_INDICATOR: {
case TVG_TAG_PAINT_OPACITY: {
if (block.length != sizeof(uint8_t)) return false;
paint->opacity(*block.data);
return true;
}
case TVG_PAINT_TRANSFORM_MATRIX_INDICATOR: {
case TVG_TAG_PAINT_TRANSFORM: {
if (block.length != sizeof(Matrix)) return false;
Matrix matrix;
memcpy(&matrix, block.data, sizeof(Matrix));
if (paint->transform(matrix) != Result::Success) return false;
return true;
}
case TVG_PAINT_CMP_TARGET_INDICATOR: {
if (block.length < TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE) return false;
case TVG_TAG_PAINT_CMP_TARGET: {
if (block.length < SIZE(TvgBinTag) + SIZE(TvgBinCounter)) return false;
return _parseCmpTarget(block.data, block.end, paint);
}
}
@ -145,7 +148,7 @@ static bool _parseScene(TvgBinBlock block, Paint *paint)
auto scene = static_cast<Scene*>(paint);
switch (block.type) {
case TVG_SCENE_FLAG_RESERVEDCNT: {
case TVG_FLAG_SCENE_RESERVEDCNT: {
if (block.length != sizeof(uint32_t)) return false;
uint32_t reservedCnt;
_read_tvg_ui32(&reservedCnt, block.data);
@ -195,7 +198,7 @@ static bool _parseShapeFill(const char *ptr, const char *end, Fill **fillOutside
if (block.end > end) return false;
switch (block.type) {
case TVG_FILL_RADIAL_GRADIENT_INDICATOR: {
case TVG_TAG_FILL_RADIAL_GRADIENT: {
if (block.length != 3 * sizeof(float)) return false;
auto ptr = block.data;
@ -212,7 +215,7 @@ static bool _parseShapeFill(const char *ptr, const char *end, Fill **fillOutside
fillGrad = move(fillGradRadial);
break;
}
case TVG_FILL_LINEAR_GRADIENT_INDICATOR: {
case TVG_TAG_FILL_LINEAR_GRADIENT: {
if (block.length != 4 * sizeof(float)) return false;
auto ptr = block.data;
@ -231,26 +234,26 @@ static bool _parseShapeFill(const char *ptr, const char *end, Fill **fillOutside
fillGrad = move(fillGradLinear);
break;
}
case TVG_FILL_FILLSPREAD_INDICATOR: {
case TVG_TAG_FILL_FILLSPREAD: {
if (!fillGrad) return false;
if (block.length != sizeof(TvgFlag)) return false;
if (block.length != sizeof(TvgBinFlag)) return false;
switch (*block.data) {
case TVG_FILL_FILLSPREAD_PAD_FLAG: {
case TVG_FLAG_FILL_FILLSPREAD_PAD: {
fillGrad->spread(FillSpread::Pad);
break;
}
case TVG_FILL_FILLSPREAD_REFLECT_FLAG: {
case TVG_FLAG_FILL_FILLSPREAD_REFLECT: {
fillGrad->spread(FillSpread::Reflect);
break;
}
case TVG_FILL_FILLSPREAD_REPEAT_FLAG: {
case TVG_FLAG_FILL_FILLSPREAD_REPEAT: {
fillGrad->spread(FillSpread::Repeat);
break;
}
}
break;
}
case TVG_FILL_COLORSTOPS_INDICATOR: {
case TVG_TAG_FILL_COLORSTOPS: {
if (!fillGrad) return false;
if (block.length == 0 || block.length & 0x07) return false;
uint32_t stopsCnt = block.length >> 3; // 8 bytes per ColorStop
@ -297,55 +300,55 @@ static bool _parseShapeStroke(const char *ptr, const char *end, Shape *shape)
if (block.end > end) return false;
switch (block.type) {
case TVG_SHAPE_STROKE_CAP_INDICATOR: {
if (block.length != sizeof(TvgFlag)) return false;
case TVG_TAG_SHAPE_STROKE_CAP: {
if (block.length != sizeof(TvgBinFlag)) return false;
switch (*block.data) {
case TVG_SHAPE_STROKE_CAP_SQUARE_FLAG:
case TVG_FLAG_SHAPE_STROKE_CAP_SQUARE:
shape->stroke(StrokeCap::Square);
break;
case TVG_SHAPE_STROKE_CAP_ROUND_FLAG:
case TVG_FLAG_SHAPE_STROKE_CAP_ROUND:
shape->stroke(StrokeCap::Round);
break;
case TVG_SHAPE_STROKE_CAP_BUTT_FLAG:
case TVG_FLAG_SHAPE_STROKE_CAP_BUTT:
shape->stroke(StrokeCap::Butt);
break;
}
break;
}
case TVG_SHAPE_STROKE_JOIN_INDICATOR: {
if (block.length != sizeof(TvgFlag)) return false;
case TVG_TAG_SHAPE_STROKE_JOIN: {
if (block.length != sizeof(TvgBinFlag)) return false;
switch (*block.data) {
case TVG_SHAPE_STROKE_JOIN_BEVEL_FLAG:
case TVG_FLAG_SHAPE_STROKE_JOIN_BEVEL:
shape->stroke(StrokeJoin::Bevel);
break;
case TVG_SHAPE_STROKE_JOIN_ROUND_FLAG:
case TVG_FLAG_SHAPE_STROKE_JOIN_ROUND:
shape->stroke(StrokeJoin::Round);
break;
case TVG_SHAPE_STROKE_JOIN_MITER_FLAG:
case TVG_FLAG_SHAPE_STROKE_JOIN_MITER:
shape->stroke(StrokeJoin::Miter);
break;
}
break;
}
case TVG_SHAPE_STROKE_WIDTH_INDICATOR: {
case TVG_TAG_SHAPE_STROKE_WIDTH: {
if (block.length != sizeof(float)) return false;
float width;
_read_tvg_float(&width, block.data);
shape->stroke(width);
break;
}
case TVG_SHAPE_STROKE_COLOR_INDICATOR: {
case TVG_TAG_SHAPE_STROKE_COLOR: {
if (block.length != 4) return false;
shape->stroke(block.data[0], block.data[1], block.data[2], block.data[3]);
break;
}
case TVG_SHAPE_STROKE_FILL_INDICATOR: {
case TVG_TAG_SHAPE_STROKE_FILL: {
Fill* fill;
if (!_parseShapeFill(block.data, block.end, &fill)) return false;
shape->stroke(unique_ptr < Fill > (fill));
break;
}
case TVG_SHAPE_STROKE_DASHPTRN_INDICATOR: {
case TVG_TAG_SHAPE_STROKE_DASHPTRN: {
if (!_parseShapeStrokeDashPattern(block.data, block.end, shape)) return false;
break;
}
@ -361,32 +364,32 @@ static bool _parseShape(TvgBinBlock block, Paint* paint)
auto shape = static_cast<Shape*>(paint);
switch (block.type) {
case TVG_SHAPE_PATH_INDICATOR: {
case TVG_TAG_SHAPE_PATH: {
if (!_parseShapePath(block.data, block.end, shape)) return false;
break;
}
case TVG_SHAPE_STROKE_INDICATOR: {
case TVG_TAG_SHAPE_STROKE: {
if (!_parseShapeStroke(block.data, block.end, shape)) return false;
break;
}
case TVG_SHAPE_FILL_INDICATOR: {
case TVG_TAG_SHAPE_FILL: {
Fill* fill;
if (!_parseShapeFill(block.data, block.end, &fill)) return false;
shape->fill(unique_ptr < Fill > (fill));
break;
}
case TVG_SHAPE_COLOR_INDICATOR: {
case TVG_TAG_SHAPE_COLOR: {
if (block.length != 4) return false;
shape->fill(block.data[0], block.data[1], block.data[2], block.data[3]);
break;
}
case TVG_SHAPE_FILLRULE_INDICATOR: {
if (block.length != sizeof(TvgFlag)) return false;
case TVG_TAG_SHAPE_FILLRULE: {
if (block.length != sizeof(TvgBinFlag)) return false;
switch (*block.data) {
case TVG_SHAPE_FILLRULE_WINDING_FLAG:
case TVG_FLAG_SHAPE_FILLRULE_WINDING:
shape->fill(FillRule::Winding);
break;
case TVG_SHAPE_FILLRULE_EVENODD_FLAG:
case TVG_FLAG_SHAPE_FILLRULE_EVENODD:
shape->fill(FillRule::EvenOdd);
break;
}
@ -403,7 +406,7 @@ static bool _parsePicture(TvgBinBlock block, Paint* paint)
auto picture = static_cast<Picture*>(paint);
switch (block.type) {
case TVG_RAW_IMAGE_BEGIN_INDICATOR: {
case TVG_TAG_PICTURE_RAW_IMAGE: {
if (block.length < 2 * sizeof(uint32_t)) return false;
auto ptr = block.data;
@ -439,17 +442,17 @@ static Paint* _parsePaint(TvgBinBlock baseBlock)
Paint *paint = nullptr;
switch (baseBlock.type) {
case TVG_SCENE_BEGIN_INDICATOR: {
case TVG_TAG_CLASS_SCENE: {
paint = Scene::gen().release();
parser = _parseScene;
break;
}
case TVG_SHAPE_BEGIN_INDICATOR: {
case TVG_TAG_CLASS_SHAPE: {
paint = Shape::gen().release();
parser = _parseShape;
break;
}
case TVG_PICTURE_BEGIN_INDICATOR: {
case TVG_TAG_CLASS_PICTURE: {
paint = Picture::gen().release();
parser = _parsePicture;
break;