api: revise the apis for v1.0

replaced std::string with char* in API parameters.

API Modification:
- Result Picture::load(const std::string& path) -> Result Picture::load(const char* filename)
- Result Picture::load(const char* data, uint32_t size, const std::string& mimeType, const std::string& rpath = "", bool copy = false) -> Result Picture::load(const char* data, uint32_t size, const char* mimeType, const char* rpath = "", bool copy = false)
- Result Text::load(const std::string& path) -> Result Text::load(const char* filename)
- Result Text::load(const char* name, const char* data, uint32_t size, const std::string& mimeType = "ttf", bool copy = false) -> Result Text::load(const char* name, const char* data, uint32_t size, const char* mimeType = "ttf", bool copy = false)
- Result Text::unload(const std::string& path) -> Result Text::unload(const char* filename)
- Result Saver::save(std::unique_ptr<Paint> paint, const std::string& path, uint32_t quality = 100) -> Result Saver::save(std::unique_ptr<Paint> paint, const char* filename, uint32_t quality = 100)
- Result Saver::save(std::unique_ptr<Animation> animation, const std::string& path, uint32_t quality = 100, uint32_t fps = 0) -> Result Saver::save(std::unique_ptr<Animation> animation, const char* filename, uint32_t quality = 100, uint32_t fps = 0)

issue: https://github.com/thorvg/thorvg/issues/1372
This commit is contained in:
Hermet Park 2024-11-06 19:12:51 +09:00 committed by Hermet Park
parent 50a7f3957b
commit 9a134fcb90
14 changed files with 104 additions and 84 deletions

View file

@ -73,7 +73,7 @@ struct UserExample : tvgexam::Example
//blueprint
{
// Load png file from path.
string path = EXAMPLE_DIR"/image/stroke-miterlimit.png";
const char* path = EXAMPLE_DIR"/image/stroke-miterlimit.png";
auto picture = tvg::Picture::gen();
if (!tvgexam::verify(picture->load(path))) return false;

View file

@ -3,7 +3,6 @@
#include <functional>
#include <memory>
#include <string>
#include <list>
#ifdef TVG_API
@ -1233,7 +1232,7 @@ public:
* This means that loading the same file again will not result in duplicate operations;
* instead, ThorVG will reuse the previously loaded picture data.
*
* @param[in] path A path to the picture file.
* @param[in] filename A file name, including the path, for the picture file.
*
* @retval Result::InvalidArguments In case the @p path is invalid.
* @retval Result::NonSupport When trying to load a file with an unknown extension.
@ -1241,7 +1240,7 @@ public:
* @note The Load behavior can be asynchronous if the assigned thread number is greater than zero.
* @see Initializer::init()
*/
Result load(const std::string& path) noexcept;
Result load(const char* filename) noexcept;
/**
* @brief Loads a picture data from a memory block of a given size.
@ -1264,7 +1263,7 @@ public:
* @note If you are unsure about the MIME type, you can provide an empty value like @c "", and thorvg will attempt to figure it out.
* @since 0.5
*/
Result load(const char* data, uint32_t size, const std::string& mimeType, const std::string& rpath = "", bool copy = false) noexcept;
Result load(const char* data, uint32_t size, const char* mimeType, const char* rpath = "", bool copy = false) noexcept;
/**
* @brief Resizes the picture content to the given width and height.
@ -1510,16 +1509,16 @@ public:
* This means that loading the same file again will not result in duplicate operations;
* instead, ThorVG will reuse the previously loaded font data.
*
* @param[in] path The path to the font file.
* @param[in] filename A file name, including the path, for the font file.
*
* @retval Result::InvalidArguments In case the @p path is invalid.
* @retval Result::NonSupport When trying to load a file with an unknown extension.
*
* @see Text::unload(const std::string& path)
* @see Text::unload(const char* filename)
*
* @since 0.15
*/
static Result load(const std::string& path) noexcept;
static Result load(const char* filename) noexcept;
/**
* @brief Loads a scalable font data (ttf) from a memory block of a given size.
@ -1546,23 +1545,23 @@ public:
*
* @note 0.15
*/
static Result load(const char* name, const char* data, uint32_t size, const std::string& mimeType = "ttf", bool copy = false) noexcept;
static Result load(const char* name, const char* data, uint32_t size, const char* mimeType = "ttf", bool copy = false) noexcept;
/**
* @brief Unloads the specified scalable font data (TTF) that was previously loaded.
*
* This function is used to release resources associated with a font file that has been loaded into memory.
*
* @param[in] path The file path of the loaded font.
* @param[in] filename The file name of the loaded font, including the path.
*
* @retval Result::InsufficientCondition Fails if the loader is not initialized.
*
* @note If the font data is currently in use, it will not be immediately unloaded.
* @see Text::load(const std::string& path)
* @see Text::load(const char* filename)
*
* @since 0.15
*/
static Result unload(const std::string& path) noexcept;
static Result unload(const char* filename) noexcept;
/**
* @brief Creates a new Text object.
@ -1979,7 +1978,7 @@ public:
* if you wish to optimize for speed.
*
* @param[in] paint The paint to be saved with all its associated properties.
* @param[in] path A path to the file, in which the paint data is to be saved.
* @param[in] filename A file name, including the path, where the paint data will be saved.
* @param[in] quality The encoded quality level. @c 0 is the minimum, @c 100 is the maximum value(recommended).
*
* @retval Result::InsufficientCondition If currently saving other resources.
@ -1991,7 +1990,7 @@ public:
*
* @since 0.5
*/
Result save(std::unique_ptr<Paint> paint, const std::string& path, uint32_t quality = 100) noexcept;
Result save(std::unique_ptr<Paint> paint, const char* filename, uint32_t quality = 100) noexcept;
/**
* @brief Export the provided animation data to the specified file path.
@ -1999,7 +1998,7 @@ public:
* This function exports the given animation data to the provided file path. You can also specify the desired frame rate in frames per second (FPS) by providing the fps parameter.
*
* @param[in] animation The animation to be saved, including all associated properties.
* @param[in] path The path to the file where the animation will be saved.
* @param[in] filename A file name, including the path, where the animation will be saved.
* @param[in] quality The encoded quality level. @c 0 is the minimum, @c 100 is the maximum value(recommended).
* @param[in] fps The desired frames per second (FPS). For example, to encode data at 60 FPS, pass 60. Pass 0 to keep the original frame data.
*
@ -2014,7 +2013,7 @@ public:
*
* @note Experimental API
*/
Result save(std::unique_ptr<Animation> animation, const std::string& path, uint32_t quality = 100, uint32_t fps = 0) noexcept;
Result save(std::unique_ptr<Animation> animation, const char* filename, uint32_t quality = 100, uint32_t fps = 0) noexcept;
/**
* @brief Guarantees that the saving task is finished.

View file

@ -228,6 +228,7 @@ public:
return false;
}
//FIXME: remove this copy, save with a file passing.
this->data = data; //back up for saving
canvas->clear(true);
@ -239,7 +240,7 @@ public:
filetype = "lottie";
}
if (animation->picture()->load(data.c_str(), data.size(), filetype, rpath, false) != Result::Success) {
if (animation->picture()->load(data.c_str(), data.size(), filetype.c_str(), rpath.c_str(), false) != Result::Success) {
errorMsg = "load() fail";
return false;
}

View file

@ -237,4 +237,16 @@ char* strDirname(const char* path)
return strDuplicate(path, len);
}
const char* strExtension(const char* filename)
{
auto ext = filename;
while (ext) {
auto p = strchr(ext, '.');
if (!p) break;
ext = p + 1;
}
return ext;
}
}

View file

@ -28,10 +28,11 @@
namespace tvg
{
float strToFloat(const char *nPtr, char **endPtr); //convert to float
char* strDuplicate(const char *str, size_t n); //copy the string
float strToFloat(const char *nPtr, char **endPtr); //convert to float
char* strDuplicate(const char *str, size_t n); //copy the string
char* strAppend(char* lhs, const char* rhs, size_t n); //append the rhs to the lhs
char* strDirname(const char* path); //return the full directory name
char* strDirname(const char* path); //return the full directory name
const char* strExtension(const char* filename); //return the file extension name
}
#endif //_TVG_STR_H_

View file

@ -564,7 +564,7 @@ static Paint* _imageBuildHelper(SvgLoaderData& loaderData, SvgNode* node, const
auto last = svgPath.find_last_of("/");
imagePath = svgPath.substr(0, (last == string::npos ? 0 : last + 1)) + imagePath;
}
if (picture->load(imagePath) != Result::Success) {
if (picture->load(imagePath.c_str()) != Result::Success) {
TaskScheduler::async(true);
return nullptr;
}

View file

@ -23,6 +23,7 @@
#ifndef _TVG_COMMON_H_
#define _TVG_COMMON_H_
#include <string>
#include "config.h"
#include "thorvg.h"

View file

@ -23,6 +23,7 @@
#include <string.h>
#include "tvgInlist.h"
#include "tvgStr.h"
#include "tvgLoader.h"
#include "tvgLock.h"
@ -158,51 +159,55 @@ static LoadModule* _find(FileType type)
}
static LoadModule* _findByPath(const string& path)
static LoadModule* _findByPath(const char* filename)
{
auto ext = path.substr(path.find_last_of(".") + 1);
if (!ext.compare("svg")) return _find(FileType::Svg);
if (!ext.compare("json")) return _find(FileType::Lottie);
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);
auto ext = strExtension(filename);
if (!ext) return nullptr;
if (!strcmp(ext, "svg")) return _find(FileType::Svg);
if (!strcmp(ext, "json")) return _find(FileType::Lottie);
if (!strcmp(ext, "png")) return _find(FileType::Png);
if (!strcmp(ext, "jpg")) return _find(FileType::Jpg);
if (!strcmp(ext, "webp")) return _find(FileType::Webp);
if (!strcmp(ext, "ttf") || !strcmp(ext, "ttc")) return _find(FileType::Ttf);
if (!strcmp(ext, "otf") || !strcmp(ext, "otc")) return _find(FileType::Ttf);
return nullptr;
}
static FileType _convert(const string& mimeType)
static FileType _convert(const char* mimeType)
{
if (!mimeType) return FileType::Unknown;
auto type = FileType::Unknown;
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());
if (!strcmp(mimeType, "svg") || !strcmp(mimeType, "svg+xml")) type = FileType::Svg;
else if (!strcmp(mimeType, "ttf") || !strcmp(mimeType, "otf")) type = FileType::Ttf;
else if (!strcmp(mimeType, "lottie")) type = FileType::Lottie;
else if (!strcmp(mimeType, "raw")) type = FileType::Raw;
else if (!strcmp(mimeType, "png")) type = FileType::Png;
else if (!strcmp(mimeType, "jpg") || !strcmp(mimeType, "jpeg")) type = FileType::Jpg;
else if (!strcmp(mimeType, "webp")) type = FileType::Webp;
else TVGLOG("RENDERER", "Given mimetype is unknown = \"%s\".", mimeType);
return type;
}
static LoadModule* _findByType(const string& mimeType)
static LoadModule* _findByType(const char* mimeType)
{
return _find(_convert(mimeType));
}
static LoadModule* _findFromCache(const string& path)
static LoadModule* _findFromCache(const char* filename)
{
ScopedLock lock(key);
auto loader = _activeLoaders.head;
while (loader) {
if (loader->pathcache && !strcmp(loader->hashpath, path.c_str())) {
if (loader->pathcache && !strcmp(loader->hashpath, filename)) {
++loader->sharing;
return loader;
}
@ -212,7 +217,7 @@ static LoadModule* _findFromCache(const string& path)
}
static LoadModule* _findFromCache(const char* data, uint32_t size, const string& mimeType)
static LoadModule* _findFromCache(const char* data, uint32_t size, const char* mimeType)
{
auto type = _convert(mimeType);
if (type == FileType::Unknown) return nullptr;
@ -274,23 +279,23 @@ bool LoaderMgr::retrieve(LoadModule* loader)
}
LoadModule* LoaderMgr::loader(const string& path, bool* invalid)
LoadModule* LoaderMgr::loader(const char* filename, bool* invalid)
{
*invalid = false;
//TODO: svg & lottie is not sharable.
auto allowCache = true;
auto ext = path.substr(path.find_last_of(".") + 1);
if (!ext.compare("svg") || !ext.compare("json")) allowCache = false;
auto ext = strExtension(filename);
if (ext && (!strcmp(ext, "svg") || !strcmp(ext, "json"))) allowCache = false;
if (allowCache) {
if (auto loader = _findFromCache(path)) return loader;
if (auto loader = _findFromCache(filename)) return loader;
}
if (auto loader = _findByPath(path)) {
if (loader->open(path)) {
if (auto loader = _findByPath(filename)) {
if (loader->open(filename)) {
if (allowCache) {
loader->hashpath = strdup(path.c_str());
loader->hashpath = strdup(filename);
loader->pathcache = true;
{
ScopedLock lock(key);
@ -304,9 +309,9 @@ LoadModule* LoaderMgr::loader(const string& path, bool* invalid)
//Unknown MimeType. Try with the candidates in the order
for (int i = 0; i < static_cast<int>(FileType::Raw); i++) {
if (auto loader = _find(static_cast<FileType>(i))) {
if (loader->open(path)) {
if (loader->open(filename)) {
if (allowCache) {
loader->hashpath = strdup(path.c_str());
loader->hashpath = strdup(filename);
loader->pathcache = true;
{
ScopedLock lock(key);
@ -323,9 +328,9 @@ LoadModule* LoaderMgr::loader(const string& path, bool* invalid)
}
bool LoaderMgr::retrieve(const string& path)
bool LoaderMgr::retrieve(const char* filename)
{
return retrieve(_findFromCache(path));
return retrieve(_findFromCache(filename));
}
@ -344,7 +349,7 @@ LoadModule* LoaderMgr::loader(const char* key)
}
LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mimeType, const string& rpath, bool copy)
LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const char* mimeType, const char* rpath, bool copy)
{
//Note that users could use the same data pointer with the different content.
//Thus caching is only valid for shareable.
@ -361,7 +366,7 @@ LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mim
}
//Try with the given MimeType
if (!mimeType.empty()) {
if (!mimeType) {
if (auto loader = _findByType(mimeType)) {
if (loader->open(data, size, rpath, copy)) {
if (allowCache) {
@ -371,7 +376,7 @@ LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mim
}
return loader;
} else {
TVGLOG("LOADER", "Given mimetype \"%s\" seems incorrect or not supported.", mimeType.c_str());
TVGLOG("LOADER", "Given mimetype \"%s\" seems incorrect or not supported.", mimeType);
delete(loader);
}
}
@ -420,7 +425,7 @@ LoadModule* LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, Colo
//loads fonts from memory - loader is cached (regardless of copy value) in order to access it while setting font
LoadModule* LoaderMgr::loader(const char* name, const char* data, uint32_t size, TVG_UNUSED const string& mimeType, bool copy)
LoadModule* LoaderMgr::loader(const char* name, const char* data, uint32_t size, TVG_UNUSED const char* mimeType, bool copy)
{
#ifdef THORVG_TTF_LOADER_SUPPORT
//TODO: add check for mimetype ?

View file

@ -29,12 +29,12 @@ struct LoaderMgr
{
static bool init();
static bool term();
static LoadModule* loader(const string& path, bool* invalid);
static LoadModule* loader(const char* data, uint32_t size, const string& mimeType, const string& rpath, bool copy);
static LoadModule* loader(const char* filename, bool* invalid);
static LoadModule* loader(const char* data, uint32_t size, const char* mimeType, const char* rpath, bool copy);
static LoadModule* loader(const uint32_t* data, uint32_t w, uint32_t h, ColorSpace cs, bool copy);
static LoadModule* loader(const char* name, const char* data, uint32_t size, const string& mimeType, bool copy);
static LoadModule* loader(const char* name, const char* data, uint32_t size, const char* mimeType, bool copy);
static LoadModule* loader(const char* key);
static bool retrieve(const string& path);
static bool retrieve(const char* filename);
static bool retrieve(LoadModule* loader);
};

View file

@ -154,15 +154,15 @@ Type Picture::type() const noexcept
}
Result Picture::load(const std::string& path) noexcept
Result Picture::load(const char* filename) noexcept
{
if (path.empty()) return Result::InvalidArguments;
if (!filename) return Result::InvalidArguments;
return pImpl->load(path);
return pImpl->load(filename);
}
Result Picture::load(const char* data, uint32_t size, const string& mimeType, const string& rpath, bool copy) noexcept
Result Picture::load(const char* data, uint32_t size, const char* mimeType, const char* rpath, bool copy) noexcept
{
if (!data || size <= 0) return Result::InvalidArguments;

View file

@ -122,12 +122,12 @@ struct Picture::Impl
return true;
}
Result load(const string& path)
Result load(const char* filename)
{
if (paint || surface) return Result::InsufficientCondition;
bool invalid; //Invalid Path
auto loader = static_cast<ImageLoader*>(LoaderMgr::loader(path, &invalid));
auto loader = static_cast<ImageLoader*>(LoaderMgr::loader(filename, &invalid));
if (!loader) {
if (invalid) return Result::InvalidArguments;
return Result::NonSupport;
@ -135,7 +135,7 @@ struct Picture::Impl
return load(loader);
}
Result load(const char* data, uint32_t size, const string& mimeType, const string& rpath, bool copy)
Result load(const char* data, uint32_t size, const char* mimeType, const char* rpath, bool copy)
{
if (paint || surface) return Result::InsufficientCondition;
auto loader = static_cast<ImageLoader*>(LoaderMgr::loader(data, size, mimeType, rpath, copy));

View file

@ -21,6 +21,7 @@
*/
#include "tvgCommon.h"
#include "tvgStr.h"
#include "tvgSaveModule.h"
#include "tvgPaint.h"
@ -77,10 +78,10 @@ static SaveModule* _find(FileType type)
}
static SaveModule* _find(const string& path)
static SaveModule* _find(const char* filename)
{
auto ext = path.substr(path.find_last_of(".") + 1);
if (!ext.compare("gif")) return _find(FileType::Gif);
auto ext = strExtension(filename);
if (ext && !strcmp(ext, "gif")) return _find(FileType::Gif);
return nullptr;
}
@ -100,7 +101,7 @@ Saver::~Saver()
}
Result Saver::save(unique_ptr<Paint> paint, const string& path, uint32_t quality) noexcept
Result Saver::save(unique_ptr<Paint> paint, const char* filename, uint32_t quality) noexcept
{
auto p = paint.release();
if (!p) return Result::MemoryCorruption;
@ -111,8 +112,8 @@ Result Saver::save(unique_ptr<Paint> paint, const string& path, uint32_t quality
return Result::InsufficientCondition;
}
if (auto saveModule = _find(path)) {
if (saveModule->save(p, pImpl->bg, path, quality)) {
if (auto saveModule = _find(filename)) {
if (saveModule->save(p, pImpl->bg, filename, quality)) {
pImpl->saveModule = saveModule;
return Result::Success;
} else {
@ -135,7 +136,7 @@ Result Saver::background(unique_ptr<Paint> paint) noexcept
}
Result Saver::save(unique_ptr<Animation> animation, const string& path, uint32_t quality, uint32_t fps) noexcept
Result Saver::save(unique_ptr<Animation> animation, const char* filename, uint32_t quality, uint32_t fps) noexcept
{
auto a = animation.release();
if (!a) return Result::MemoryCorruption;
@ -154,8 +155,8 @@ Result Saver::save(unique_ptr<Animation> animation, const string& path, uint32_t
return Result::InsufficientCondition;
}
if (auto saveModule = _find(path)) {
if (saveModule->save(a, pImpl->bg, path, quality, fps)) {
if (auto saveModule = _find(filename)) {
if (saveModule->save(a, pImpl->bg, filename, quality, fps)) {
pImpl->saveModule = saveModule;
return Result::Success;
} else {

View file

@ -58,7 +58,7 @@ Result Text::font(const char* name, float size, const char* style) noexcept
}
Result Text::load(const std::string& path) noexcept
Result Text::load(const char* path) noexcept
{
bool invalid; //invalid path
if (!LoaderMgr::loader(path, &invalid)) {
@ -70,7 +70,7 @@ Result Text::load(const std::string& path) noexcept
}
Result Text::load(const char* name, const char* data, uint32_t size, const string& mimeType, bool copy) noexcept
Result Text::load(const char* name, const char* data, uint32_t size, const char* mimeType, bool copy) noexcept
{
if (!name || (size == 0 && data)) return Result::InvalidArguments;
@ -85,9 +85,9 @@ Result Text::load(const char* name, const char* data, uint32_t size, const strin
}
Result Text::unload(const std::string& path) noexcept
Result Text::unload(const char* filename) noexcept
{
if (LoaderMgr::retrieve(path)) return Result::Success;
if (LoaderMgr::retrieve(filename)) return Result::Success;
return Result::InsufficientCondition;
}

View file

@ -73,7 +73,7 @@ private:
auto animation = Animation::gen();
auto picture = animation->picture();
if (picture->load(in) != Result::Success) return false;
if (picture->load(in.c_str()) != Result::Success) return false;
float width, height;
picture->size(&width, &height);
@ -89,7 +89,7 @@ private:
bg->appendRect(0, 0, width * scale, height * scale);
saver->background(std::move(bg));
}
if (saver->save(std::move(animation), out, 100, fps) != Result::Success) return false;
if (saver->save(std::move(animation), out.c_str(), 100, fps) != Result::Success) return false;
if (saver->sync() != Result::Success) return false;
if (Initializer::term() != Result::Success) return false;