forked from hertog/godot-module-template
feat: modules moved and engine moved to submodule
This commit is contained in:
parent
dfb5e645cd
commit
c33d2130cc
5136 changed files with 225275 additions and 64485 deletions
|
|
@ -448,9 +448,9 @@ static inline uint32_t opBlendColorDodge(uint32_t s, uint32_t d, TVG_UNUSED uint
|
|||
{
|
||||
// d / (1 - s)
|
||||
s = 0xffffffff - s;
|
||||
auto c1 = (C1(s) == 0) ? C1(d) : std::min(C1(d) * 255 / C1(s), 255);
|
||||
auto c2 = (C2(s) == 0) ? C2(d) : std::min(C2(d) * 255 / C2(s), 255);
|
||||
auto c3 = (C3(s) == 0) ? C3(d) : std::min(C3(d) * 255 / C3(s), 255);
|
||||
auto c1 = C1(d) == 0 ? 0 : (C1(s) == 0 ? 255 : std::min(C1(d) * 255 / C1(s), 255));
|
||||
auto c2 = C2(d) == 0 ? 0 : (C2(s) == 0 ? 255 : std::min(C2(d) * 255 / C2(s), 255));
|
||||
auto c3 = C3(d) == 0 ? 0 : (C3(s) == 0 ? 255 : std::min(C3(d) * 255 / C3(s), 255));
|
||||
return JOIN(255, c1, c2, c3);
|
||||
}
|
||||
|
||||
|
|
@ -458,9 +458,9 @@ static inline uint32_t opBlendColorBurn(uint32_t s, uint32_t d, TVG_UNUSED uint8
|
|||
{
|
||||
// 1 - (1 - d) / s
|
||||
auto id = 0xffffffff - d;
|
||||
auto c1 = (C1(s) == 0) ? C1(d) : 255 - std::min(C1(id) * 255 / C1(s), 255);
|
||||
auto c2 = (C2(s) == 0) ? C2(d) : 255 - std::min(C2(id) * 255 / C2(s), 255);
|
||||
auto c3 = (C3(s) == 0) ? C3(d) : 255 - std::min(C3(id) * 255 / C3(s), 255);
|
||||
auto c1 = C1(d) == 255 ? 255 : (C1(s) == 0 ? 0 : 255 - std::min(C1(id) * 255 / C1(s), 255));
|
||||
auto c2 = C2(d) == 255 ? 255 : (C2(s) == 0 ? 0 : 255 - std::min(C2(id) * 255 / C2(s), 255));
|
||||
auto c3 = C3(d) == 255 ? 255 : (C3(s) == 0 ? 0 : 255 - std::min(C3(id) * 255 / C3(s), 255));
|
||||
|
||||
return JOIN(255, c1, c2, c3);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -314,10 +314,10 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S
|
|||
}
|
||||
|
||||
if (fastTrack) {
|
||||
renderRegion.min.x = static_cast<SwCoord>(nearbyint(xMin / 64.0f));
|
||||
renderRegion.max.x = static_cast<SwCoord>(nearbyint(xMax / 64.0f));
|
||||
renderRegion.min.y = static_cast<SwCoord>(nearbyint(yMin / 64.0f));
|
||||
renderRegion.max.y = static_cast<SwCoord>(nearbyint(yMax / 64.0f));
|
||||
renderRegion.min.x = static_cast<SwCoord>(round(xMin / 64.0f));
|
||||
renderRegion.max.x = static_cast<SwCoord>(round(xMax / 64.0f));
|
||||
renderRegion.min.y = static_cast<SwCoord>(round(yMin / 64.0f));
|
||||
renderRegion.max.y = static_cast<SwCoord>(round(yMax / 64.0f));
|
||||
} else {
|
||||
renderRegion.min.x = xMin >> 6;
|
||||
renderRegion.max.x = (xMax + 63) >> 6;
|
||||
|
|
|
|||
|
|
@ -266,10 +266,10 @@ static void _dropShadowFilter(uint32_t* dst, uint32_t* src, int stride, int w, i
|
|||
}
|
||||
|
||||
|
||||
static void _dropShadowShift(uint32_t* dst, uint32_t* src, int stride, SwBBox& region, SwPoint& offset, uint8_t opacity, bool direct)
|
||||
static void _dropShadowShift(uint32_t* dst, uint32_t* src, int dstride, int sstride, SwBBox& region, SwPoint& offset, uint8_t opacity, bool direct)
|
||||
{
|
||||
src += (region.min.y * stride + region.min.x);
|
||||
dst += (region.min.y * stride + region.min.x);
|
||||
src += (region.min.y * sstride + region.min.x);
|
||||
dst += (region.min.y * dstride + region.min.x);
|
||||
|
||||
auto w = region.max.x - region.min.x;
|
||||
auto h = region.max.y - region.min.y;
|
||||
|
|
@ -279,14 +279,14 @@ static void _dropShadowShift(uint32_t* dst, uint32_t* src, int stride, SwBBox& r
|
|||
if (region.min.x + offset.x < 0) src -= offset.x;
|
||||
else dst += offset.x;
|
||||
|
||||
if (region.min.y + offset.y < 0) src -= (offset.y * stride);
|
||||
else dst += (offset.y * stride);
|
||||
if (region.min.y + offset.y < 0) src -= (offset.y * sstride);
|
||||
else dst += (offset.y * dstride);
|
||||
|
||||
for (auto y = 0; y < h; ++y) {
|
||||
if (translucent) rasterTranslucentPixel32(dst, src, w, opacity);
|
||||
else rasterPixel32(dst, src, w, opacity);
|
||||
src += stride;
|
||||
dst += stride;
|
||||
src += sstride;
|
||||
dst += dstride;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -389,14 +389,14 @@ bool effectDropShadow(SwCompositor* cmp, SwSurface* surface[2], const RenderEffe
|
|||
|
||||
//draw to the main surface directly
|
||||
if (direct) {
|
||||
_dropShadowShift(cmp->recoverSfc->buf32, cmp->image.buf32, stride, bbox, data->offset, opacity, direct);
|
||||
_dropShadowShift(cmp->recoverSfc->buf32, cmp->image.buf32, cmp->recoverSfc->stride, stride, bbox, data->offset, opacity, direct);
|
||||
std::swap(cmp->image.buf32, buffer[0]->buf32);
|
||||
return true;
|
||||
}
|
||||
|
||||
//draw to the intermediate surface
|
||||
rasterClear(surface[1], bbox.min.x, bbox.min.y, w, h);
|
||||
_dropShadowShift(buffer[1]->buf32, cmp->image.buf32, stride, bbox, data->offset, opacity, direct);
|
||||
_dropShadowShift(buffer[1]->buf32, cmp->image.buf32, stride, stride, bbox, data->offset, opacity, direct);
|
||||
std::swap(cmp->image.buf32, buffer[1]->buf32);
|
||||
|
||||
//compositing shadow and body
|
||||
|
|
|
|||
|
|
@ -1813,7 +1813,7 @@ bool rasterConvertCS(RenderSurface* surface, ColorSpace to)
|
|||
//TODO: SIMD OPTIMIZATION?
|
||||
void rasterXYFlip(uint32_t* src, uint32_t* dst, int32_t stride, int32_t w, int32_t h, const SwBBox& bbox, bool flipped)
|
||||
{
|
||||
constexpr int BLOCK = 8; //experimental decision
|
||||
constexpr int32_t BLOCK = 8; //experimental decision
|
||||
|
||||
if (flipped) {
|
||||
src += ((bbox.min.x * stride) + bbox.min.y);
|
||||
|
|
@ -1824,16 +1824,16 @@ void rasterXYFlip(uint32_t* src, uint32_t* dst, int32_t stride, int32_t w, int32
|
|||
}
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int x = 0; x < w; x += BLOCK) {
|
||||
for (int32_t x = 0; x < w; x += BLOCK) {
|
||||
auto bx = std::min(w, x + BLOCK) - x;
|
||||
auto in = &src[x];
|
||||
auto out = &dst[x * stride];
|
||||
for (int y = 0; y < h; y += BLOCK) {
|
||||
for (int32_t y = 0; y < h; y += BLOCK) {
|
||||
auto p = &in[y * stride];
|
||||
auto q = &out[y];
|
||||
auto by = std::min(h, y + BLOCK) - y;
|
||||
for (int xx = 0; xx < bx; ++xx) {
|
||||
for (int yy = 0; yy < by; ++yy) {
|
||||
for (int32_t xx = 0; xx < bx; ++xx) {
|
||||
for (int32_t yy = 0; yy < by; ++yy) {
|
||||
*q = *p;
|
||||
p += stride;
|
||||
++q;
|
||||
|
|
|
|||
|
|
@ -121,8 +121,7 @@ struct SwShapeTask : SwTask
|
|||
auto visibleFill = false;
|
||||
|
||||
//This checks also for the case, if the invisible shape turned to visible by alpha.
|
||||
auto prepareShape = false;
|
||||
if (!shapePrepared(&shape) && (flags & RenderUpdateFlag::Color)) prepareShape = true;
|
||||
auto prepareShape = !shapePrepared(&shape) && flags & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient);
|
||||
|
||||
//Shape
|
||||
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform) || prepareShape) {
|
||||
|
|
@ -186,6 +185,7 @@ struct SwShapeTask : SwTask
|
|||
err:
|
||||
bbox.reset();
|
||||
shapeReset(&shape);
|
||||
rleReset(shape.strokeRle);
|
||||
shapeDelOutline(&shape, mpool, tid);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -482,7 +482,7 @@ static bool _setCell(RleWorker& rw, SwPoint pos)
|
|||
static bool _startCell(RleWorker& rw, SwPoint pos)
|
||||
{
|
||||
if (pos.x > rw.cellMax.x) pos.x = rw.cellMax.x;
|
||||
if (pos.x < rw.cellMin.x) pos.x = rw.cellMin.x;
|
||||
if (pos.x < rw.cellMin.x) pos.x = rw.cellMin.x - 1;
|
||||
|
||||
rw.area = 0;
|
||||
rw.cover = 0;
|
||||
|
|
@ -866,6 +866,8 @@ void _replaceClipSpan(SwRle *rle, SwSpan* clippedSpans, uint32_t size)
|
|||
|
||||
SwRle* rleRender(SwRle* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias)
|
||||
{
|
||||
if (!outline) return nullptr;
|
||||
|
||||
constexpr auto RENDER_POOL_SIZE = 16384L;
|
||||
constexpr auto BAND_SIZE = 40;
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,6 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix& trans
|
|||
{
|
||||
Line cur = {dash.ptCur, *to};
|
||||
auto len = cur.length();
|
||||
|
||||
if (tvg::zero(len)) {
|
||||
_outlineMoveTo(*dash.outline, &dash.ptCur, transform);
|
||||
//draw the current line fully
|
||||
|
|
@ -117,7 +116,7 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix& trans
|
|||
}
|
||||
//draw the current line partially
|
||||
} else {
|
||||
while (len - dash.curLen > 0.0001f) {
|
||||
while (len - dash.curLen > DASH_PATTERN_THRESHOLD) {
|
||||
Line left, right;
|
||||
if (dash.curLen > 0) {
|
||||
len -= dash.curLen;
|
||||
|
|
@ -178,7 +177,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct
|
|||
}
|
||||
//draw the current line partially
|
||||
} else {
|
||||
while ((len - dash.curLen) > 0.0001f) {
|
||||
while ((len - dash.curLen) > DASH_PATTERN_THRESHOLD) {
|
||||
Bezier left, right;
|
||||
if (dash.curLen > 0) {
|
||||
len -= dash.curLen;
|
||||
|
|
@ -543,7 +542,6 @@ void shapeDelOutline(SwShape* shape, SwMpool* mpool, uint32_t tid)
|
|||
void shapeReset(SwShape* shape)
|
||||
{
|
||||
rleReset(shape->rle);
|
||||
rleReset(shape->strokeRle);
|
||||
shape->fastTrack = false;
|
||||
shape->bbox.reset();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#ifndef _TVG_LOAD_MODULE_H_
|
||||
#define _TVG_LOAD_MODULE_H_
|
||||
|
||||
#include <atomic>
|
||||
#include "tvgCommon.h"
|
||||
#include "tvgRender.h"
|
||||
#include "tvgInlist.h"
|
||||
|
||||
|
|
@ -38,7 +40,7 @@ struct LoadModule
|
|||
};
|
||||
|
||||
FileType type; //current loader file type
|
||||
uint16_t sharing = 0; //reference count
|
||||
atomic<uint16_t> sharing{}; //reference count
|
||||
bool readied = false; //read done already.
|
||||
bool pathcache = false; //cached by path
|
||||
|
||||
|
|
@ -77,7 +79,7 @@ struct LoadModule
|
|||
|
||||
struct ImageLoader : LoadModule
|
||||
{
|
||||
static ColorSpace cs; //desired value
|
||||
static atomic<ColorSpace> cs; //desired value
|
||||
|
||||
float w = 0, h = 0; //default image size
|
||||
RenderSurface surface;
|
||||
|
|
@ -95,14 +97,21 @@ struct ImageLoader : LoadModule
|
|||
};
|
||||
|
||||
|
||||
struct FontMetrics
|
||||
{
|
||||
//TODO: add necessary metrics
|
||||
float minw;
|
||||
};
|
||||
|
||||
|
||||
struct FontLoader : LoadModule
|
||||
{
|
||||
float scale = 1.0f;
|
||||
|
||||
FontLoader(FileType type) : LoadModule(type) {}
|
||||
|
||||
virtual bool request(Shape* shape, char* text) = 0;
|
||||
virtual bool transform(Paint* paint, float fontSize, bool italic) = 0;
|
||||
using LoadModule::read;
|
||||
|
||||
virtual bool read(Shape* shape, char* text, FontMetrics& out) = 0;
|
||||
virtual float transform(Paint* paint, FontMetrics& mertrics, float fontSize, bool italic) = 0;
|
||||
};
|
||||
|
||||
#endif //_TVG_LOAD_MODULE_H_
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include <atomic>
|
||||
#include "tvgInlist.h"
|
||||
#include "tvgLoader.h"
|
||||
#include "tvgLock.h"
|
||||
|
|
@ -66,9 +67,10 @@ uintptr_t HASH_KEY(const char* data)
|
|||
/* Internal Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
ColorSpace ImageLoader::cs = ColorSpace::ARGB8888;
|
||||
//TODO: remove it.
|
||||
atomic<ColorSpace> ImageLoader::cs{ColorSpace::ARGB8888};
|
||||
|
||||
static Key key;
|
||||
static Key _key;
|
||||
static Inlist<LoadModule> _activeLoaders;
|
||||
|
||||
|
||||
|
|
@ -215,7 +217,7 @@ static LoadModule* _findByType(const string& mimeType)
|
|||
|
||||
static LoadModule* _findFromCache(const string& path)
|
||||
{
|
||||
ScopedLock lock(key);
|
||||
ScopedLock lock(_key);
|
||||
|
||||
auto loader = _activeLoaders.head;
|
||||
|
||||
|
|
@ -235,11 +237,10 @@ static LoadModule* _findFromCache(const char* data, uint32_t size, const string&
|
|||
auto type = _convert(mimeType);
|
||||
if (type == FileType::Unknown) return nullptr;
|
||||
|
||||
ScopedLock lock(key);
|
||||
auto loader = _activeLoaders.head;
|
||||
|
||||
auto key = HASH_KEY(data);
|
||||
ScopedLock lock(_key);
|
||||
|
||||
auto loader = _activeLoaders.head;
|
||||
while (loader) {
|
||||
if (loader->type == type && loader->hashkey == key) {
|
||||
++loader->sharing;
|
||||
|
|
@ -267,7 +268,11 @@ bool LoaderMgr::term()
|
|||
auto loader = _activeLoaders.head;
|
||||
|
||||
//clean up the remained font loaders which is globally used.
|
||||
while (loader && loader->type == FileType::Ttf) {
|
||||
while (loader) {
|
||||
if (loader->type != FileType::Ttf) {
|
||||
loader = loader->next;
|
||||
continue;
|
||||
}
|
||||
auto ret = loader->close();
|
||||
auto tmp = loader;
|
||||
loader = loader->next;
|
||||
|
|
@ -281,9 +286,9 @@ bool LoaderMgr::term()
|
|||
bool LoaderMgr::retrieve(LoadModule* loader)
|
||||
{
|
||||
if (!loader) return false;
|
||||
|
||||
if (loader->close()) {
|
||||
if (loader->cached()) {
|
||||
ScopedLock lock(key);
|
||||
_activeLoaders.remove(loader);
|
||||
}
|
||||
delete(loader);
|
||||
|
|
@ -312,7 +317,7 @@ LoadModule* LoaderMgr::loader(const string& path, bool* invalid)
|
|||
loader->hashpath = strdup(path.c_str());
|
||||
loader->pathcache = true;
|
||||
{
|
||||
ScopedLock lock(key);
|
||||
ScopedLock lock(_key);
|
||||
_activeLoaders.back(loader);
|
||||
}
|
||||
}
|
||||
|
|
@ -328,7 +333,7 @@ LoadModule* LoaderMgr::loader(const string& path, bool* invalid)
|
|||
loader->hashpath = strdup(path.c_str());
|
||||
loader->pathcache = true;
|
||||
{
|
||||
ScopedLock lock(key);
|
||||
ScopedLock lock(_key);
|
||||
_activeLoaders.back(loader);
|
||||
}
|
||||
}
|
||||
|
|
@ -386,7 +391,7 @@ LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mim
|
|||
if (loader->open(data, size, copy)) {
|
||||
if (allowCache) {
|
||||
loader->hashkey = HASH_KEY(data);
|
||||
ScopedLock lock(key);
|
||||
ScopedLock lock(_key);
|
||||
_activeLoaders.back(loader);
|
||||
}
|
||||
return loader;
|
||||
|
|
@ -403,7 +408,7 @@ LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mim
|
|||
if (loader->open(data, size, copy)) {
|
||||
if (allowCache) {
|
||||
loader->hashkey = HASH_KEY(data);
|
||||
ScopedLock lock(key);
|
||||
ScopedLock lock(_key);
|
||||
_activeLoaders.back(loader);
|
||||
}
|
||||
return loader;
|
||||
|
|
@ -429,7 +434,7 @@ LoadModule* LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool
|
|||
if (loader->open(data, w, h, copy)) {
|
||||
if (!copy) {
|
||||
loader->hashkey = HASH_KEY((const char*)data);
|
||||
ScopedLock lock(key);
|
||||
ScopedLock lock(_key);
|
||||
_activeLoaders.back(loader);
|
||||
}
|
||||
return loader;
|
||||
|
|
@ -451,7 +456,7 @@ LoadModule* LoaderMgr::loader(const char* name, const char* data, uint32_t size,
|
|||
if (loader->open(data, size, copy)) {
|
||||
loader->hashpath = strdup(name);
|
||||
loader->pathcache = true;
|
||||
ScopedLock lock(key);
|
||||
ScopedLock lock(_key);
|
||||
_activeLoaders.back(loader);
|
||||
return loader;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ namespace tvg
|
|||
using RenderData = void*;
|
||||
using pixel_t = uint32_t;
|
||||
|
||||
#define DASH_PATTERN_THRESHOLD 0.001f
|
||||
|
||||
enum RenderUpdateFlag : uint8_t {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, Blend = 128, All = 255};
|
||||
enum CompositionFlag : uint8_t {Invalid = 0, Opacity = 1, Blending = 2, Masking = 4, PostProcessing = 8}; //Composition Purpose
|
||||
|
||||
|
|
|
|||
|
|
@ -40,8 +40,6 @@ static TaskSchedulerImpl* inst = nullptr;
|
|||
|
||||
#ifdef THORVG_THREAD_SUPPORT
|
||||
|
||||
static thread_local bool _async = true;
|
||||
|
||||
struct TaskQueue {
|
||||
Inlist<Task> taskDeque;
|
||||
mutex mtx;
|
||||
|
|
@ -157,7 +155,7 @@ struct TaskSchedulerImpl
|
|||
void request(Task* task)
|
||||
{
|
||||
//Async
|
||||
if (threads.count > 0 && _async) {
|
||||
if (threads.count > 0) {
|
||||
task->prepare();
|
||||
auto i = idx++;
|
||||
for (uint32_t n = 0; n < threads.count; ++n) {
|
||||
|
|
@ -178,8 +176,6 @@ struct TaskSchedulerImpl
|
|||
|
||||
#else //THORVG_THREAD_SUPPORT
|
||||
|
||||
static bool _async = true;
|
||||
|
||||
struct TaskSchedulerImpl
|
||||
{
|
||||
TaskSchedulerImpl(TVG_UNUSED uint32_t threadCnt) {}
|
||||
|
|
@ -220,10 +216,3 @@ uint32_t TaskScheduler::threads()
|
|||
if (inst) return inst->threadCnt();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void TaskScheduler::async(bool on)
|
||||
{
|
||||
//toggle async tasking for each thread on/off
|
||||
_async = on;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,6 @@ struct TaskScheduler
|
|||
static void init(uint32_t threads);
|
||||
static void term();
|
||||
static void request(Task* task);
|
||||
static void async(bool on);
|
||||
};
|
||||
|
||||
} //namespace
|
||||
|
|
|
|||
|
|
@ -62,7 +62,11 @@ Result Text::load(const std::string& path) noexcept
|
|||
{
|
||||
#ifdef THORVG_FILE_IO_SUPPORT
|
||||
bool invalid; //invalid path
|
||||
if (!LoaderMgr::loader(path, &invalid)) {
|
||||
auto loader = LoaderMgr::loader(path, &invalid);
|
||||
if (loader) {
|
||||
if (loader->sharing > 0) --loader->sharing; //font loading doesn't mean sharing.
|
||||
return Result::Success;
|
||||
} else {
|
||||
if (invalid) return Result::InvalidArguments;
|
||||
else return Result::NonSupport;
|
||||
}
|
||||
|
|
|
|||
18
engine/thirdparty/thorvg/src/renderer/tvgText.h
vendored
18
engine/thirdparty/thorvg/src/renderer/tvgText.h
vendored
|
|
@ -24,6 +24,7 @@
|
|||
#define _TVG_TEXT_H
|
||||
|
||||
#include <cstring>
|
||||
#include "tvgMath.h"
|
||||
#include "tvgShape.h"
|
||||
#include "tvgFill.h"
|
||||
#include "tvgLoader.h"
|
||||
|
|
@ -33,6 +34,7 @@ struct Text::Impl
|
|||
FontLoader* loader = nullptr;
|
||||
Text* paint;
|
||||
Shape* shape;
|
||||
FontMetrics metrics;
|
||||
char* utf8 = nullptr;
|
||||
float fontSize;
|
||||
bool italic = false;
|
||||
|
|
@ -40,6 +42,7 @@ struct Text::Impl
|
|||
|
||||
Impl(Text* p) : paint(p), shape(Shape::gen().release())
|
||||
{
|
||||
shape->fill(FillRule::EvenOdd);
|
||||
}
|
||||
|
||||
~Impl()
|
||||
|
|
@ -94,27 +97,26 @@ struct Text::Impl
|
|||
return PP(shape)->render(renderer);
|
||||
}
|
||||
|
||||
bool load()
|
||||
float load()
|
||||
{
|
||||
if (!loader) return false;
|
||||
if (!loader) return 0.0f;
|
||||
|
||||
loader->request(shape, utf8);
|
||||
//reload
|
||||
if (changed) {
|
||||
loader->read();
|
||||
loader->read(shape, utf8, metrics);
|
||||
changed = false;
|
||||
}
|
||||
return loader->transform(shape, fontSize, italic);
|
||||
return loader->transform(shape, metrics, fontSize, italic);
|
||||
}
|
||||
|
||||
RenderData update(RenderMethod* renderer, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, TVG_UNUSED bool clipper)
|
||||
{
|
||||
if (!load()) return nullptr;
|
||||
auto scale = 1.0f / load();
|
||||
if (tvg::zero(scale)) return nullptr;
|
||||
|
||||
//transform the gradient coordinates based on the final scaled font.
|
||||
auto fill = P(shape)->rs.fill;
|
||||
if (fill && P(shape)->rFlag & RenderUpdateFlag::Gradient) {
|
||||
auto scale = 1.0f / loader->scale;
|
||||
if (fill->type() == Type::LinearGradient) {
|
||||
P(static_cast<LinearGradient*>(fill))->x1 *= scale;
|
||||
P(static_cast<LinearGradient*>(fill))->y1 *= scale;
|
||||
|
|
@ -134,7 +136,7 @@ struct Text::Impl
|
|||
|
||||
bool bounds(float* x, float* y, float* w, float* h, TVG_UNUSED bool stroking)
|
||||
{
|
||||
if (!load()) return false;
|
||||
if (load() == 0.0f) return false;
|
||||
PP(shape)->bounds(x, y, w, h, true, true, false);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue