summaryrefslogtreecommitdiffstats
path: root/thirdparty/thorvg/src/renderer/tvgLoader.cpp
diff options
context:
space:
mode:
authorMartin Capitanio <capnm@capitanio.org>2024-01-05 18:01:00 +0100
committerMartin Capitanio <capnm@capitanio.org>2024-01-08 09:59:43 +0100
commite090b112efe049233ea4b36e83f901ca507ac14e (patch)
treec5220f7ef3b069b01a51c27a949f3f6d858ea60b /thirdparty/thorvg/src/renderer/tvgLoader.cpp
parentc8c483cf57a768110fce57e509f9b855e69d34b7 (diff)
downloadredot-engine-e090b112efe049233ea4b36e83f901ca507ac14e.tar.gz
ThorVG: update from v0.11.6 to v0.12.0
https://github.com/thorvg/thorvg/releases/tag/v0.12.0 Godot-related SVG bug fixes: + [SwEngine] Fixed a linear filling scaling issue. thorvg/thorvg#1834 + [SwEngine] Path data not invalid even though it doesn't start with MoveTo. thorvg/thorvg#1848 Fixes #86128 Gradient issue.
Diffstat (limited to 'thirdparty/thorvg/src/renderer/tvgLoader.cpp')
-rw-r--r--thirdparty/thorvg/src/renderer/tvgLoader.cpp184
1 files changed, 162 insertions, 22 deletions
diff --git a/thirdparty/thorvg/src/renderer/tvgLoader.cpp b/thirdparty/thorvg/src/renderer/tvgLoader.cpp
index 65330e9e77..628b0fa17f 100644
--- a/thirdparty/thorvg/src/renderer/tvgLoader.cpp
+++ b/thirdparty/thorvg/src/renderer/tvgLoader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 - 2023 the ThorVG project. All rights reserved.
+ * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -20,6 +20,9 @@
* SOFTWARE.
*/
+#include <string.h>
+
+#include "tvgInlist.h"
#include "tvgLoader.h"
#ifdef THORVG_SVG_LOADER_SUPPORT
@@ -42,16 +45,30 @@
#include "tvgWebpLoader.h"
#endif
+#ifdef THORVG_TTF_LOADER_SUPPORT
+ #include "tvgTtfLoader.h"
+#endif
+
#ifdef THORVG_LOTTIE_LOADER_SUPPORT
#include "tvgLottieLoader.h"
#endif
#include "tvgRawLoader.h"
+
+uint64_t HASH_KEY(const char* data, uint64_t size)
+{
+ return (((uint64_t) data) << 32) | size;
+}
+
/************************************************************************/
/* Internal Class Implementation */
/************************************************************************/
+static mutex mtx;
+static Inlist<LoadModule> _activeLoaders;
+
+
static LoadModule* _find(FileType type)
{
switch(type) {
@@ -67,6 +84,12 @@ static LoadModule* _find(FileType type)
#endif
break;
}
+ case FileType::Ttf: {
+#ifdef THORVG_TTF_LOADER_SUPPORT
+ return new TtfLoader;
+#endif
+ break;
+ }
case FileType::Lottie: {
#ifdef THORVG_LOTTIE_LOADER_SUPPORT
return new LottieLoader;
@@ -111,6 +134,10 @@ static LoadModule* _find(FileType type)
format = "SVG";
break;
}
+ case FileType::Ttf: {
+ format = "TTF";
+ break;
+ }
case FileType::Lottie: {
format = "lottie(json)";
break;
@@ -152,29 +179,71 @@ static LoadModule* _findByPath(const string& path)
if (!ext.compare("png")) return _find(FileType::Png);
if (!ext.compare("jpg")) return _find(FileType::Jpg);
if (!ext.compare("webp")) return _find(FileType::Webp);
+ if (!ext.compare("ttf") || !ext.compare("ttc")) return _find(FileType::Ttf);
+ if (!ext.compare("otf") || !ext.compare("otc")) return _find(FileType::Ttf);
return nullptr;
}
-static LoadModule* _findByType(const string& mimeType)
+static FileType _convert(const string& mimeType)
{
- if (mimeType.empty()) return nullptr;
-
auto type = FileType::Unknown;
if (mimeType == "tvg") type = FileType::Tvg;
else if (mimeType == "svg" || mimeType == "svg+xml") type = FileType::Svg;
+ else if (mimeType == "ttf" || mimeType == "otf") type = FileType::Ttf;
else if (mimeType == "lottie") type = FileType::Lottie;
else if (mimeType == "raw") type = FileType::Raw;
else if (mimeType == "png") type = FileType::Png;
else if (mimeType == "jpg" || mimeType == "jpeg") type = FileType::Jpg;
else if (mimeType == "webp") type = FileType::Webp;
- else {
- TVGLOG("RENDERER", "Given mimetype is unknown = \"%s\".", mimeType.c_str());
- return nullptr;
+ else TVGLOG("RENDERER", "Given mimetype is unknown = \"%s\".", mimeType.c_str());
+
+ return type;
+}
+
+
+static LoadModule* _findByType(const string& mimeType)
+{
+ return _find(_convert(mimeType));
+}
+
+
+static LoadModule* _findFromCache(const string& path)
+{
+ unique_lock<mutex> lock{mtx};
+
+ auto loader = _activeLoaders.head;
+
+ while (loader) {
+ if (loader->hashpath && !strcmp(loader->hashpath, path.c_str())) {
+ ++loader->sharing;
+ return loader;
+ }
+ loader = loader->next;
}
+ return nullptr;
+}
+
+
+static LoadModule* _findFromCache(const char* data, uint32_t size, const string& mimeType)
+{
+ auto type = _convert(mimeType);
+ if (type == FileType::Unknown) return nullptr;
- return _find(type);
+ unique_lock<mutex> lock{mtx};
+ auto loader = _activeLoaders.head;
+
+ auto key = HASH_KEY(data, size);
+
+ while (loader) {
+ if (loader->type == type && loader->hashkey == key) {
+ ++loader->sharing;
+ return loader;
+ }
+ loader = loader->next;
+ }
+ return nullptr;
}
@@ -185,40 +254,95 @@ static LoadModule* _findByType(const string& mimeType)
bool LoaderMgr::init()
{
- //TODO:
-
return true;
}
bool LoaderMgr::term()
{
- //TODO:
+ auto loader = _activeLoaders.head;
+
+ //clean up the remained font loaders which is globally used.
+ while (loader && loader->type == FileType::Ttf) {
+ auto ret = loader->close();
+ auto tmp = loader;
+ loader = loader->next;
+ _activeLoaders.remove(tmp);
+ if (ret) delete(loader);
+ }
+ return true;
+}
+
+bool LoaderMgr::retrieve(LoadModule* loader)
+{
+ if (!loader) return false;
+ if (loader->close()) {
+ {
+ unique_lock<mutex> lock{mtx};
+ _activeLoaders.remove(loader);
+ }
+ delete(loader);
+ }
return true;
}
-shared_ptr<LoadModule> LoaderMgr::loader(const string& path, bool* invalid)
+LoadModule* LoaderMgr::loader(const string& path, bool* invalid)
{
*invalid = false;
+ if (auto loader = _findFromCache(path)) return loader;
+
if (auto loader = _findByPath(path)) {
- if (loader->open(path)) return shared_ptr<LoadModule>(loader);
- else delete(loader);
+ if (loader->open(path)) {
+ loader->hashpath = strdup(path.c_str());
+ {
+ unique_lock<mutex> lock{mtx};
+ _activeLoaders.back(loader);
+ }
+ return loader;
+ }
+ delete(loader);
*invalid = true;
}
return nullptr;
}
-shared_ptr<LoadModule> LoaderMgr::loader(const char* data, uint32_t size, const string& mimeType, bool copy)
+bool LoaderMgr::retrieve(const string& path)
+{
+ return retrieve(_findFromCache(path));
+}
+
+
+LoadModule* LoaderMgr::loader(const char* key)
+{
+ auto loader = _activeLoaders.head;
+
+ while (loader) {
+ if (loader->hashpath && strstr(loader->hashpath, key)) {
+ ++loader->sharing;
+ return loader;
+ }
+ loader = loader->next;
+ }
+ return nullptr;
+}
+
+
+LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mimeType, bool copy)
{
+ if (auto loader = _findFromCache(data, size, mimeType)) return loader;
+
//Try with the given MimeType
if (!mimeType.empty()) {
if (auto loader = _findByType(mimeType)) {
if (loader->open(data, size, copy)) {
- return shared_ptr<LoadModule>(loader);
+ loader->hashkey = HASH_KEY(data, size);
+ unique_lock<mutex> lock{mtx};
+ _activeLoaders.back(loader);
+ return loader;
} else {
TVGLOG("LOADER", "Given mimetype \"%s\" seems incorrect or not supported.", mimeType.c_str());
delete(loader);
@@ -229,8 +353,15 @@ shared_ptr<LoadModule> LoaderMgr::loader(const char* data, uint32_t size, const
for (int i = 0; i < static_cast<int>(FileType::Unknown); i++) {
auto loader = _find(static_cast<FileType>(i));
if (loader) {
- if (loader->open(data, size, copy)) return shared_ptr<LoadModule>(loader);
- else delete(loader);
+ if (loader->open(data, size, copy)) {
+ loader->hashkey = HASH_KEY(data, size);
+ {
+ unique_lock<mutex> lock{mtx};
+ _activeLoaders.back(loader);
+ }
+ return loader;
+ }
+ delete(loader);
}
}
}
@@ -238,12 +369,21 @@ shared_ptr<LoadModule> LoaderMgr::loader(const char* data, uint32_t size, const
}
-shared_ptr<LoadModule> LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy)
+LoadModule* LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy)
{
+ //TODO: should we check premultiplied??
+ if (auto loader = _findFromCache((const char*)(data), w * h, "raw")) return loader;
+
//function is dedicated for raw images only
auto loader = new RawLoader;
- if (loader->open(data, w, h, copy)) return shared_ptr<LoadModule>(loader);
- else delete(loader);
-
+ if (loader->open(data, w, h, copy)) {
+ loader->hashkey = HASH_KEY((const char*)data, w * h);
+ {
+ unique_lock<mutex> lock{mtx};
+ _activeLoaders.back(loader);
+ }
+ return loader;
+ }
+ delete(loader);
return nullptr;
}