mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-27 00:26:51 +00:00
tvg format: code refactoring #3
use the Array function instead of own implementation.
This commit is contained in:
parent
8059a23f7c
commit
2eb920beaf
2 changed files with 44 additions and 96 deletions
|
@ -53,6 +53,16 @@ struct Array
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool grow(uint32_t size)
|
||||||
|
{
|
||||||
|
return reserve(count + size);
|
||||||
|
}
|
||||||
|
|
||||||
|
T* ptr()
|
||||||
|
{
|
||||||
|
return data + count;
|
||||||
|
}
|
||||||
|
|
||||||
void pop()
|
void pop()
|
||||||
{
|
{
|
||||||
if (count > 0) --count;
|
if (count > 0) --count;
|
||||||
|
|
|
@ -32,10 +32,7 @@ struct Saver::Impl
|
||||||
{
|
{
|
||||||
Saver* saver;
|
Saver* saver;
|
||||||
Paint* paint = nullptr; //TODO: replace with Array
|
Paint* paint = nullptr; //TODO: replace with Array
|
||||||
char* buffer = nullptr;
|
Array<char> buffer;
|
||||||
char* pointer = nullptr;
|
|
||||||
uint32_t size = 0;
|
|
||||||
uint32_t reserved = 0;
|
|
||||||
|
|
||||||
Impl(Saver* s) : saver(s)
|
Impl(Saver* s) : saver(s)
|
||||||
{
|
{
|
||||||
|
@ -50,48 +47,17 @@ struct Saver::Impl
|
||||||
{
|
{
|
||||||
if (paint) delete(paint);
|
if (paint) delete(paint);
|
||||||
|
|
||||||
clearBuffer();
|
buffer.reset();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void resizeBuffer(uint32_t newSize)
|
|
||||||
{
|
|
||||||
//OPTIMIZE ME: find more optimal alg ? "*2" is not opt when raw/png is used
|
|
||||||
reserved += 100;
|
|
||||||
if (newSize > reserved) reserved = newSize + 100;
|
|
||||||
|
|
||||||
auto bufferOld = buffer;
|
|
||||||
|
|
||||||
buffer = static_cast<char*>(realloc(buffer, reserved));
|
|
||||||
|
|
||||||
if (buffer != bufferOld)
|
|
||||||
pointer = buffer + (pointer - bufferOld);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rewindBuffer(ByteCounter bytesNum)
|
|
||||||
{
|
|
||||||
if (pointer - bytesNum < buffer) return;
|
|
||||||
|
|
||||||
pointer -= bytesNum;
|
|
||||||
size -= bytesNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearBuffer()
|
|
||||||
{
|
|
||||||
if (buffer) free(buffer);
|
|
||||||
buffer = nullptr;
|
|
||||||
pointer = nullptr;
|
|
||||||
size = 0;
|
|
||||||
reserved = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveBufferToFile(const std::string& path)
|
bool saveBufferToFile(const std::string& path)
|
||||||
{
|
{
|
||||||
ofstream outFile;
|
ofstream outFile;
|
||||||
outFile.open(path, ios::out | ios::trunc | ios::binary);
|
outFile.open(path, ios::out | ios::trunc | ios::binary);
|
||||||
if (!outFile.is_open()) return false;
|
if (!outFile.is_open()) return false;
|
||||||
outFile.write(buffer, size);
|
outFile.write(buffer.data, buffer.count);
|
||||||
outFile.close();
|
outFile.close();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -99,84 +65,73 @@ struct Saver::Impl
|
||||||
|
|
||||||
bool writeHeader()
|
bool writeHeader()
|
||||||
{
|
{
|
||||||
reserved = TVG_BIN_HEADER_SIGNATURE_LENGTH + TVG_BIN_HEADER_VERSION_LENGTH;
|
buffer.grow(TVG_BIN_HEADER_SIGNATURE_LENGTH + TVG_BIN_HEADER_VERSION_LENGTH);
|
||||||
|
|
||||||
buffer = static_cast<char*>(malloc(reserved));
|
auto ptr = buffer.ptr();
|
||||||
if (!buffer) return false;
|
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;
|
||||||
|
|
||||||
pointer = buffer;
|
buffer.count += (TVG_BIN_HEADER_SIGNATURE_LENGTH + TVG_BIN_HEADER_VERSION_LENGTH);
|
||||||
|
|
||||||
memcpy(pointer, TVG_BIN_HEADER_SIGNATURE, TVG_BIN_HEADER_SIGNATURE_LENGTH);
|
|
||||||
pointer += TVG_BIN_HEADER_SIGNATURE_LENGTH;
|
|
||||||
memcpy(pointer, TVG_BIN_HEADER_VERSION, TVG_BIN_HEADER_VERSION_LENGTH);
|
|
||||||
pointer += TVG_BIN_HEADER_VERSION_LENGTH;
|
|
||||||
|
|
||||||
size += (TVG_BIN_HEADER_SIGNATURE_LENGTH + TVG_BIN_HEADER_VERSION_LENGTH);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeMemberIndicator(TvgIndicator ind)
|
void writeMemberIndicator(TvgIndicator ind)
|
||||||
{
|
{
|
||||||
if (size + TVG_INDICATOR_SIZE > reserved) resizeBuffer(size + TVG_INDICATOR_SIZE);
|
buffer.grow(TVG_INDICATOR_SIZE);
|
||||||
|
memcpy(buffer.ptr(), &ind, TVG_INDICATOR_SIZE);
|
||||||
memcpy(pointer, &ind, TVG_INDICATOR_SIZE);
|
buffer.count += TVG_INDICATOR_SIZE;
|
||||||
pointer += TVG_INDICATOR_SIZE;
|
|
||||||
size += TVG_INDICATOR_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeMemberDataSize(ByteCounter byteCnt)
|
void writeMemberDataSize(ByteCounter byteCnt)
|
||||||
{
|
{
|
||||||
if (size + BYTE_COUNTER_SIZE > reserved) resizeBuffer(size + BYTE_COUNTER_SIZE);
|
buffer.grow(BYTE_COUNTER_SIZE);
|
||||||
|
memcpy(buffer.ptr(), &byteCnt, BYTE_COUNTER_SIZE);
|
||||||
memcpy(pointer, &byteCnt, BYTE_COUNTER_SIZE);
|
buffer.count += BYTE_COUNTER_SIZE;
|
||||||
pointer += BYTE_COUNTER_SIZE;
|
|
||||||
size += BYTE_COUNTER_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeMemberDataSizeAt(ByteCounter byteCnt)
|
void writeMemberDataSizeAt(ByteCounter byteCnt)
|
||||||
{
|
{
|
||||||
memcpy(pointer - byteCnt - BYTE_COUNTER_SIZE, &byteCnt, BYTE_COUNTER_SIZE);
|
memcpy(buffer.ptr() - byteCnt - BYTE_COUNTER_SIZE, &byteCnt, BYTE_COUNTER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void skipInBufferMemberDataSize()
|
void skipInBufferMemberDataSize()
|
||||||
{
|
{
|
||||||
if (size + BYTE_COUNTER_SIZE > reserved) resizeBuffer(size + BYTE_COUNTER_SIZE);
|
buffer.grow(BYTE_COUNTER_SIZE);
|
||||||
pointer += BYTE_COUNTER_SIZE;
|
buffer.count += BYTE_COUNTER_SIZE;
|
||||||
size += BYTE_COUNTER_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteCounter writeMemberData(const void* data, ByteCounter byteCnt)
|
ByteCounter writeMemberData(const void* data, ByteCounter byteCnt)
|
||||||
{
|
{
|
||||||
if (size + byteCnt > reserved) resizeBuffer(size + byteCnt);
|
buffer.grow(byteCnt);
|
||||||
|
memcpy(buffer.ptr(), data, byteCnt);
|
||||||
memcpy(pointer, data, byteCnt);
|
buffer.count += byteCnt;
|
||||||
pointer += byteCnt;
|
|
||||||
size += byteCnt;
|
|
||||||
|
|
||||||
return byteCnt;
|
return byteCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ByteCounter writeMember(TvgIndicator ind, ByteCounter byteCnt, const void* data)
|
ByteCounter writeMember(TvgIndicator ind, ByteCounter byteCnt, const void* data)
|
||||||
{
|
{
|
||||||
ByteCounter blockByteCnt = TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + byteCnt;
|
ByteCounter blockByteCnt = TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + byteCnt;
|
||||||
|
|
||||||
if (size + blockByteCnt > reserved) resizeBuffer(size + blockByteCnt);
|
buffer.grow(blockByteCnt);
|
||||||
|
|
||||||
memcpy(pointer, &ind, TVG_INDICATOR_SIZE);
|
auto ptr = buffer.ptr();
|
||||||
pointer += TVG_INDICATOR_SIZE;
|
|
||||||
memcpy(pointer, &byteCnt, BYTE_COUNTER_SIZE);
|
|
||||||
pointer += BYTE_COUNTER_SIZE;
|
|
||||||
memcpy(pointer, data, byteCnt);
|
|
||||||
pointer += byteCnt;
|
|
||||||
|
|
||||||
size += blockByteCnt;
|
memcpy(ptr, &ind, TVG_INDICATOR_SIZE);
|
||||||
|
ptr += TVG_INDICATOR_SIZE;
|
||||||
|
memcpy(ptr, &byteCnt, BYTE_COUNTER_SIZE);
|
||||||
|
ptr += BYTE_COUNTER_SIZE;
|
||||||
|
memcpy(ptr, data, byteCnt);
|
||||||
|
ptr += byteCnt;
|
||||||
|
|
||||||
|
buffer.count += blockByteCnt;
|
||||||
|
|
||||||
return blockByteCnt;
|
return blockByteCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ByteCounter serializePaint(const Paint* paint)
|
ByteCounter serializePaint(const Paint* paint)
|
||||||
{
|
{
|
||||||
ByteCounter paintDataByteCnt = 0;
|
ByteCounter paintDataByteCnt = 0;
|
||||||
|
@ -202,7 +157,6 @@ struct Saver::Impl
|
||||||
return paintDataByteCnt;
|
return paintDataByteCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ByteCounter serializeScene(const Paint* paint)
|
ByteCounter serializeScene(const Paint* paint)
|
||||||
{
|
{
|
||||||
auto scene = static_cast<const Scene*>(paint);
|
auto scene = static_cast<const Scene*>(paint);
|
||||||
|
@ -221,7 +175,6 @@ struct Saver::Impl
|
||||||
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + sceneDataByteCnt;
|
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + sceneDataByteCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ByteCounter serializeShapeFill(const Fill* f, TvgIndicator fillTvgFlag)
|
ByteCounter serializeShapeFill(const Fill* f, TvgIndicator fillTvgFlag)
|
||||||
{
|
{
|
||||||
ByteCounter fillDataByteCnt = 0;
|
ByteCounter fillDataByteCnt = 0;
|
||||||
|
@ -235,25 +188,18 @@ struct Saver::Impl
|
||||||
if (f->id() == TVG_CLASS_ID_RADIAL) {
|
if (f->id() == TVG_CLASS_ID_RADIAL) {
|
||||||
float argRadial[3];
|
float argRadial[3];
|
||||||
auto radGrad = static_cast<const RadialGradient*>(f);
|
auto radGrad = static_cast<const RadialGradient*>(f);
|
||||||
if (radGrad->radial(argRadial, argRadial + 1,argRadial + 2) != Result::Success) {
|
radGrad->radial(argRadial, argRadial + 1,argRadial + 2);
|
||||||
rewindBuffer(TVG_FLAG_SIZE + BYTE_COUNTER_SIZE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
fillDataByteCnt += writeMember(TVG_FILL_RADIAL_GRADIENT_INDICATOR, sizeof(argRadial), argRadial);
|
fillDataByteCnt += writeMember(TVG_FILL_RADIAL_GRADIENT_INDICATOR, sizeof(argRadial), argRadial);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float argLinear[4];
|
float argLinear[4];
|
||||||
auto linGrad = static_cast<const LinearGradient*>(f);
|
auto linGrad = static_cast<const LinearGradient*>(f);
|
||||||
if (linGrad->linear(argLinear, argLinear + 1, argLinear + 2, argLinear + 3) != Result::Success) {
|
linGrad->linear(argLinear, argLinear + 1, argLinear + 2, argLinear + 3);
|
||||||
rewindBuffer(TVG_FLAG_SIZE + BYTE_COUNTER_SIZE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
fillDataByteCnt += writeMember(TVG_FILL_LINEAR_GRADIENT_INDICATOR, sizeof(argLinear), argLinear);
|
fillDataByteCnt += writeMember(TVG_FILL_LINEAR_GRADIENT_INDICATOR, sizeof(argLinear), argLinear);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto flag = static_cast<TvgFlag>(f->spread());
|
auto flag = static_cast<TvgFlag>(f->spread());
|
||||||
fillDataByteCnt += writeMember(TVG_FILL_FILLSPREAD_INDICATOR, TVG_FLAG_SIZE, &flag);
|
fillDataByteCnt += writeMember(TVG_FILL_FILLSPREAD_INDICATOR, TVG_FLAG_SIZE, &flag);
|
||||||
|
|
||||||
fillDataByteCnt += writeMember(TVG_FILL_COLORSTOPS_INDICATOR, stopsCnt * sizeof(stops), stops);
|
fillDataByteCnt += writeMember(TVG_FILL_COLORSTOPS_INDICATOR, stopsCnt * sizeof(stops), stops);
|
||||||
|
|
||||||
writeMemberDataSizeAt(fillDataByteCnt);
|
writeMemberDataSizeAt(fillDataByteCnt);
|
||||||
|
@ -261,7 +207,6 @@ struct Saver::Impl
|
||||||
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + fillDataByteCnt;
|
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + fillDataByteCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ByteCounter serializeShapeStroke(const Shape* shape)
|
ByteCounter serializeShapeStroke(const Shape* shape)
|
||||||
{
|
{
|
||||||
ByteCounter strokeDataByteCnt = 0;
|
ByteCounter strokeDataByteCnt = 0;
|
||||||
|
@ -305,7 +250,6 @@ struct Saver::Impl
|
||||||
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + strokeDataByteCnt;
|
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + strokeDataByteCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ByteCounter serializeShapePath(const Shape* shape)
|
ByteCounter serializeShapePath(const Shape* shape)
|
||||||
{
|
{
|
||||||
const PathCommand* cmds = nullptr;
|
const PathCommand* cmds = nullptr;
|
||||||
|
@ -330,7 +274,6 @@ 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 Paint* paint)
|
||||||
{
|
{
|
||||||
auto shape = static_cast<const Shape*>(paint);
|
auto shape = static_cast<const Shape*>(paint);
|
||||||
|
@ -366,7 +309,6 @@ 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 Paint* paint)
|
||||||
{
|
{
|
||||||
auto picture = static_cast<const Picture*>(paint);
|
auto picture = static_cast<const Picture*>(paint);
|
||||||
|
@ -405,7 +347,6 @@ struct Saver::Impl
|
||||||
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + pictureDataByteCnt;
|
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + pictureDataByteCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ByteCounter serializeComposite(const Paint* cmpTarget, CompositeMethod cmpMethod)
|
ByteCounter serializeComposite(const Paint* cmpTarget, CompositeMethod cmpMethod)
|
||||||
{
|
{
|
||||||
ByteCounter cmpDataByteCnt = 0;
|
ByteCounter cmpDataByteCnt = 0;
|
||||||
|
@ -423,7 +364,6 @@ struct Saver::Impl
|
||||||
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + cmpDataByteCnt;
|
return TVG_INDICATOR_SIZE + BYTE_COUNTER_SIZE + cmpDataByteCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ByteCounter serializeChildren(const Paint* paint)
|
ByteCounter serializeChildren(const Paint* paint)
|
||||||
{
|
{
|
||||||
if (!paint) return 0;
|
if (!paint) return 0;
|
||||||
|
@ -436,7 +376,6 @@ struct Saver::Impl
|
||||||
return dataByteCnt;
|
return dataByteCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ByteCounter serialize(const Paint* paint)
|
ByteCounter serialize(const Paint* paint)
|
||||||
{
|
{
|
||||||
if (!paint) return 0;
|
if (!paint) return 0;
|
||||||
|
@ -460,7 +399,6 @@ struct Saver::Impl
|
||||||
return dataByteCnt;
|
return dataByteCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool save(Paint* paint, const std::string& path)
|
bool save(Paint* paint, const std::string& path)
|
||||||
{
|
{
|
||||||
//FIXME: use Array and remove sync() here
|
//FIXME: use Array and remove sync() here
|
||||||
|
|
Loading…
Add table
Reference in a new issue