mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-13 19:44:28 +00:00
ttf_loader: support loading from memory
New text API for loading fonts from memory is introduced. This is necessary to enable embedded fonts support.
This commit is contained in:
parent
f8626d13d1
commit
d8a720fb7e
6 changed files with 95 additions and 3 deletions
30
inc/thorvg.h
30
inc/thorvg.h
|
@ -1552,7 +1552,7 @@ public:
|
|||
Result fill(std::unique_ptr<Fill> f) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Loads a scalable font data(ttf) from a file.
|
||||
* @brief Loads a scalable font data (ttf) from a file.
|
||||
*
|
||||
* ThorVG efficiently caches the loaded data using the specified @p path as a key.
|
||||
* This means that loading the same file again will not result in duplicate operations;
|
||||
|
@ -1571,6 +1571,34 @@ public:
|
|||
*/
|
||||
static Result load(const std::string& path) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Loads a scalable font data (ttf) from a memory block of a given size.
|
||||
*
|
||||
* ThorVG efficiently caches the loaded font data using the specified @p name as a key.
|
||||
* This means that loading the same fonts again will not result in duplicate operations.
|
||||
* Instead, ThorVG will reuse the previously loaded font data.
|
||||
*
|
||||
* @param[in] name The name under which the font will be stored and accessible (e.x. in a @p font() API).
|
||||
* @param[in] data A pointer to a memory location where the content of the font data is stored.
|
||||
* @param[in] size The size in bytes of the memory occupied by the @p data.
|
||||
* @param[in] mimeType Mimetype or extension of font data. In case an empty string is provided the loader will be determined automatically.
|
||||
* @param[in] copy If @c true the data are copied into the engine local buffer, otherwise they are not (default).
|
||||
*
|
||||
* @retval Result::Success When succeed.
|
||||
* @retval Result::InvalidArguments If no name is provided or if @p size is zero while @p data points to a valid memory location.
|
||||
* @retval Result::NonSupport When trying to load a file with an unsupported extension.
|
||||
* @retval Result::Unknown If an error occurs at a later stage.
|
||||
*
|
||||
* @warning: It's the user responsibility to release the @p data memory.
|
||||
*
|
||||
* @note To unload the font data loaded using this API, pass the proper @p name and @c nullptr as @p data.
|
||||
* @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.
|
||||
* @note Experimental API
|
||||
*
|
||||
* @see Text::font(const char* name, float size, const char* style)
|
||||
*/
|
||||
static Result load(const char* name, const char* data, uint32_t size, const std::string& mimeType = "ttf", bool copy = false) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Unloads the specified scalable font data (TTF) that was previously loaded.
|
||||
*
|
||||
|
|
|
@ -193,7 +193,13 @@ static uint32_t* _codepoints(const char* text, size_t n)
|
|||
|
||||
void TtfLoader::clear()
|
||||
{
|
||||
_unmap(this);
|
||||
if (nomap) {
|
||||
if (freeData) free(reader.data);
|
||||
reader.data = nullptr;
|
||||
reader.size = 0;
|
||||
freeData = false;
|
||||
nomap = false;
|
||||
} else _unmap(this);
|
||||
shape = nullptr;
|
||||
}
|
||||
|
||||
|
@ -236,6 +242,22 @@ bool TtfLoader::open(const string& path)
|
|||
}
|
||||
|
||||
|
||||
bool TtfLoader::open(const char* data, uint32_t size, TVG_UNUSED const string& rpath, bool copy)
|
||||
{
|
||||
reader.size = size;
|
||||
nomap = true;
|
||||
|
||||
if (copy) {
|
||||
reader.data = (uint8_t*)malloc(size);
|
||||
if (!reader.data) return false;
|
||||
memcpy((char*)reader.data, data, reader.size);
|
||||
freeData = true;
|
||||
} else reader.data = (uint8_t*)data;
|
||||
|
||||
return reader.header();
|
||||
}
|
||||
|
||||
|
||||
bool TtfLoader::request(Shape* shape, char* text, bool italic)
|
||||
{
|
||||
this->shape = shape;
|
||||
|
@ -279,4 +301,4 @@ bool TtfLoader::read()
|
|||
free(code);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -37,12 +37,15 @@ struct TtfLoader : public FontLoader
|
|||
char* text = nullptr;
|
||||
Shape* shape = nullptr;
|
||||
bool italic = false;
|
||||
bool nomap = false;
|
||||
bool freeData = false;
|
||||
|
||||
TtfLoader();
|
||||
~TtfLoader();
|
||||
|
||||
using FontLoader::open;
|
||||
bool open(const string& path) override;
|
||||
bool open(const char *data, uint32_t size, const string& rpath, bool copy) override;
|
||||
bool resize(Paint* paint, float w, float h) override;
|
||||
bool request(Shape* shape, char* text, bool italic = false) override;
|
||||
bool read() override;
|
||||
|
|
|
@ -431,5 +431,28 @@ LoadModule* LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool
|
|||
return loader;
|
||||
}
|
||||
delete(loader);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
//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, const string& mimeType, bool copy)
|
||||
{
|
||||
//TODO: add check for mimetype ?
|
||||
if (auto loader = _findFromCache(name)) return loader;
|
||||
|
||||
if (auto loader = _findByType(mimeType)) {
|
||||
if (loader->open(data, size, "", copy)) {
|
||||
loader->hashpath = strdup(name);
|
||||
loader->pathcache = true;
|
||||
ScopedLock lock(key);
|
||||
_activeLoaders.back(loader);
|
||||
return loader;
|
||||
} else {
|
||||
TVGLOG("LOADER", "The font data \"%s\" could not be loaded.", name);
|
||||
delete(loader);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
|
@ -32,6 +32,7 @@ struct LoaderMgr
|
|||
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 uint32_t* data, uint32_t w, uint32_t h, bool premultiplied, bool copy);
|
||||
static LoadModule* loader(const char* name, const char* data, uint32_t size, const string& mimeType, bool copy);
|
||||
static LoadModule* loader(const char* key);
|
||||
static bool retrieve(const string& path);
|
||||
static bool retrieve(LoadModule* loader);
|
||||
|
|
|
@ -71,6 +71,21 @@ 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
|
||||
{
|
||||
if (!name || (size == 0 && data)) return Result::InvalidArguments;
|
||||
|
||||
//unload font
|
||||
if (!data) {
|
||||
if (LoaderMgr::retrieve(name)) return Result::Success;
|
||||
return Result::InvalidArguments;
|
||||
}
|
||||
|
||||
if (!LoaderMgr::loader(name, data, size, mimeType, copy)) return Result::NonSupport;
|
||||
return Result::Success;
|
||||
}
|
||||
|
||||
|
||||
Result Text::unload(const std::string& path) noexcept
|
||||
{
|
||||
if (LoaderMgr::retrieve(path)) return Result::Success;
|
||||
|
|
Loading…
Add table
Reference in a new issue