'-DTEST_DIR="@0@/test/images"'.format(meson.current_source_dir()),
language : 'cpp')
+config_h.set_quoted('THORVG_VERSION_STRING', meson.project_version())
+
if get_option('engines').contains('sw') == true
config_h.set10('THORVG_SW_RASTER_SUPPORT', true)
endif
#define TVGLOG(...)
#endif
+uint16_t THORVG_VERSION_NUMBER();
+
#endif //_TVG_COMMON_H_
/************************************************************************/
static int _initCnt = 0;
+static uint16_t _version = 0;
+
+
+static bool _buildVersionInfo()
+{
+ auto SRC = THORVG_VERSION_STRING; //ex) 0.3.99
+ auto p = SRC;
+ const char* x;
+
+ char major[3];
+ x = strchr(p, '.');
+ if (!x) return false;
+ strncpy(major, p, x - p);
+ p = x + 1;
+
+ char minor[3];
+ x = strchr(p, '.');
+ if (!x) return false;
+ strncpy(minor, p, x - p);
+ p = x + 1;
+
+ char micro[3];
+ x = SRC + strlen(THORVG_VERSION_STRING);
+ if (!x) return false;
+ strncpy(micro, p, x - p);
+
+ char sum[7];
+ snprintf(sum, sizeof(sum), "%s%s%s", major, minor, micro);
+
+ _version = atoi(sum);
+
+ return true;
+}
/************************************************************************/
if (_initCnt++ > 0) return Result::Success;
+ if (!_buildVersionInfo()) return Result::Unknown;
+
if (!LoaderMgr::init()) return Result::Unknown;
TaskScheduler::init(threads);
return Result::Success;
}
+
+
+uint16_t THORVG_VERSION_NUMBER()
+{
+ return _version;
+}
/* Internal Class Implementation */
/************************************************************************/
-#define SIZE(A) sizeof(A)
-#define READ_UI32(dst, src) memcpy(dst, (src), sizeof(uint32_t))
-#define READ_FLOAT(dst, src) memcpy(dst, (src), sizeof(float))
-
struct TvgBinBlock
{
TvgBinTag type;
return block;
}
-static bool _readTvgHeader(const char **ptr, float* w, float* h)
-{
- if (!*ptr) return false;
-
- //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_HEADER_VERSION
- if (memcmp(*ptr, TVG_HEADER_VERSION, TVG_HEADER_VERSION_LENGTH)) return false;
- *ptr += TVG_HEADER_VERSION_LENGTH;
-
- //View width
- if (w) READ_FLOAT(w, *ptr);
- *ptr += SIZE(float);
-
- //View height
- if (h) READ_FLOAT(h, *ptr);
- *ptr += SIZE(float);
-
- return true;
-}
-
static bool _parseCmpTarget(const char *ptr, const char *end, Paint *paint)
{
/* External Class Implementation */
/************************************************************************/
-bool tvgValidateData(const char *ptr, uint32_t size, float* w, float* h)
-{
- auto end = ptr + size;
- if (!_readTvgHeader(&ptr, w, h) || ptr >= end) return false;
- return true;
-}
-
-unique_ptr<Scene> tvgLoadData(const char *ptr, uint32_t size)
+unique_ptr<Scene> tvgLoadData(const char *ptr, const char* end)
{
- auto end = ptr + size;
-
- if (!_readTvgHeader(&ptr, nullptr, nullptr) || ptr >= end) {
- TVGLOG("TVG", "Invalid TVG Data!");
- return nullptr;
- }
-
auto scene = Scene::gen();
if (!scene) return nullptr;
}
return move(scene);
-}
+}
\ No newline at end of file
#include "tvgCommon.h"
#include "tvgBinaryDesc.h"
-bool tvgValidateData(const char *ptr, uint32_t size, float* w, float* h);
-unique_ptr<Scene> tvgLoadData(const char *ptr, uint32_t size);
+#define SIZE(A) sizeof(A)
+#define READ_UI32(dst, src) memcpy(dst, (src), sizeof(uint32_t))
+#define READ_FLOAT(dst, src) memcpy(dst, (src), sizeof(float))
+
+unique_ptr<Scene> tvgLoadData(const char* ptr, const char* end);
#endif //_TVG_TVG_LOAD_PARSER_H_
void TvgLoader::clear()
{
if (copy) free((char*)data);
- data = nullptr;
- pointer = nullptr;
+ ptr = data = nullptr;
size = 0;
copy = false;
}
+/* WARNING: Header format shall not change! */
+bool TvgLoader::readHeader()
+{
+ if (!ptr) return false;
+
+ //1. Signature
+ if (memcmp(ptr, TVG_HEADER_SIGNATURE, TVG_HEADER_SIGNATURE_LENGTH)) return false;
+ ptr += TVG_HEADER_SIGNATURE_LENGTH;
+
+ //2. Version
+ char version[TVG_HEADER_VERSION_LENGTH];
+ memcpy(version, ptr, TVG_HEADER_VERSION_LENGTH);
+ ptr += TVG_HEADER_VERSION_LENGTH;
+ this->version = atoi(version);
+ if (this->version > THORVG_VERSION_NUMBER()) {
+ TVGLOG("TVG", "This TVG file expects a higher version(%d) of ThorVG symbol!, Current ThorVG(%d)", this->version, THORVG_VERSION_NUMBER());
+ }
+
+ //3. View Size
+ READ_FLOAT(&w, ptr);
+ ptr += SIZE(float);
+ READ_FLOAT(&h, ptr);
+ ptr += SIZE(float);
+
+ return true;
+}
+
+
/************************************************************************/
/* External Class Implementation */
/************************************************************************/
f.close();
- pointer = data;
+ ptr = data;
- return tvgValidateData(pointer, size, &w, &h);
+ return readHeader();
}
memcpy((char*)this->data, data, size);
} else this->data = data;
- this->pointer = this->data;
+ this->ptr = this->data;
this->size = size;
this->copy = copy;
- return tvgValidateData(pointer, size, &w, &h);
+ return readHeader();
}
bool TvgLoader::read()
{
- if (!pointer || size == 0) return false;
+ if (!ptr || size == 0) return false;
TaskScheduler::request(this);
void TvgLoader::run(unsigned tid)
{
if (root) root.reset();
- root = tvgLoadData(pointer, size);
+ root = tvgLoadData(ptr, data + size);
if (!root) clear();
}
this->done();
if (root) return move(root);
return nullptr;
-}
\ No newline at end of file
+}
{
public:
const char* data = nullptr;
- const char* pointer = nullptr;
+ const char* ptr = nullptr;
uint32_t size = 0;
+ uint16_t version = 0;
unique_ptr<Scene> root = nullptr;
bool copy = false;
unique_ptr<Paint> paint() override;
private:
+ bool readHeader();
void run(unsigned tid) override;
void clear();
};
}
+/* WARNING: Header format shall not changed! */
bool TvgSaver::writeHeader()
{
buffer.grow(TVG_HEADER_SIGNATURE_LENGTH + TVG_HEADER_VERSION_LENGTH);
+ //1. Signature
auto ptr = buffer.ptr();
memcpy(ptr, TVG_HEADER_SIGNATURE, TVG_HEADER_SIGNATURE_LENGTH);
ptr += TVG_HEADER_SIGNATURE_LENGTH;
+
+ //2. Version
memcpy(ptr, TVG_HEADER_VERSION, TVG_HEADER_VERSION_LENGTH);
ptr += TVG_HEADER_VERSION_LENGTH;
buffer.count += (TVG_HEADER_SIGNATURE_LENGTH + TVG_HEADER_VERSION_LENGTH);
- return true;
-}
-
-
-bool TvgSaver::writeViewSize()
-{
+ //3. View Size
float var[2];
paint->bounds(nullptr, nullptr, &var[0], &var[1]);
-
- if (var[0] <= 0.0f || var[1] <= 0.0f) return false;
-
+ if (var[0] <= FLT_EPSILON || var[1] <= FLT_EPSILON) return false;
writeData(var, SIZE(var));
return true;
void TvgSaver::run(unsigned tid)
{
if (!writeHeader()) return;
- if (!writeViewSize()) return;
if (serialize(paint) == 0) return;
if (!flushTo(path)) return;
}