mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
common: spec out Scene Clipper
Scene Clipper is an unusual feature that is too unstable and ambiguous in ThorVG. Users can achieve the same functionality with multiple composed shapes instead of scene clipping. size: -2.5kb issues: - https://github.com/thorvg/thorvg/issues/1548 - https://github.com/thorvg/thorvg/issues/1549 - https://github.com/thorvg/thorvg/issues/1573
This commit is contained in:
parent
e50bf002de
commit
407fc84796
16 changed files with 15 additions and 281 deletions
|
@ -1,91 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2023 - 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
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Example.h"
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* ThorVG Drawing Contents */
|
|
||||||
/************************************************************************/
|
|
||||||
|
|
||||||
struct UserExample : tvgexam::Example
|
|
||||||
{
|
|
||||||
bool content(tvg::Canvas* canvas, uint32_t w, uint32_t h) override
|
|
||||||
{
|
|
||||||
if (!canvas) return false;
|
|
||||||
|
|
||||||
/* Using a single shape is sufficient to clip multiple regions.
|
|
||||||
The disabled code below performs the same function. Please try it. */
|
|
||||||
#if 1
|
|
||||||
//A scene clipper
|
|
||||||
auto clipper = tvg::Scene::gen();
|
|
||||||
|
|
||||||
auto shape1 = tvg::Shape::gen();
|
|
||||||
shape1->appendCircle(200, 200, 100, 100);
|
|
||||||
clipper->push(std::move(shape1));
|
|
||||||
|
|
||||||
auto shape2 = tvg::Shape::gen();
|
|
||||||
shape2->appendCircle(400, 400, 150, 150);
|
|
||||||
clipper->push(std::move(shape2));
|
|
||||||
|
|
||||||
auto shape3 = tvg::Shape::gen();
|
|
||||||
shape3->appendCircle(150, 300, 60, 60);
|
|
||||||
clipper->push(std::move(shape3));
|
|
||||||
|
|
||||||
auto shape4 = tvg::Shape::gen();
|
|
||||||
shape4->appendCircle(400, 100, 125, 125);
|
|
||||||
clipper->push(std::move(shape4));
|
|
||||||
|
|
||||||
auto shape5 = tvg::Shape::gen();
|
|
||||||
shape5->appendCircle(150, 500, 100, 100);
|
|
||||||
clipper->push(std::move(shape5));
|
|
||||||
#else
|
|
||||||
//A single clipper with multiple regions
|
|
||||||
auto clipper = tvg::Shape::gen();
|
|
||||||
clipper->appendCircle(200, 200, 100, 100);
|
|
||||||
clipper->appendCircle(400, 400, 150, 150);
|
|
||||||
clipper->appendCircle(150, 300, 60, 60);
|
|
||||||
clipper->appendCircle(400, 100, 125, 125);
|
|
||||||
clipper->appendCircle(150, 500, 100, 100);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//Source
|
|
||||||
auto shape = tvg::Shape::gen();
|
|
||||||
shape->appendRect(100, 100, 400, 400, 50, 50);
|
|
||||||
shape->strokeFill(0, 0, 255);
|
|
||||||
shape->strokeWidth(10);
|
|
||||||
shape->fill(255, 255, 255);
|
|
||||||
shape->composite(std::move(clipper), tvg::CompositeMethod::ClipPath);
|
|
||||||
canvas->push(std::move(shape));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
/* Entry Point */
|
|
||||||
/************************************************************************/
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
return tvgexam::main(new UserExample, argc, argv);
|
|
||||||
}
|
|
|
@ -59,7 +59,6 @@ source_file = [
|
||||||
'Retaining.cpp',
|
'Retaining.cpp',
|
||||||
'Scene.cpp',
|
'Scene.cpp',
|
||||||
'SceneBlending.cpp',
|
'SceneBlending.cpp',
|
||||||
'SceneClipper.cpp',
|
|
||||||
'SceneTransform.cpp',
|
'SceneTransform.cpp',
|
||||||
'Shape.cpp',
|
'Shape.cpp',
|
||||||
'Stroke.cpp',
|
'Stroke.cpp',
|
||||||
|
|
|
@ -157,7 +157,7 @@ enum class FillRule : uint8_t
|
||||||
enum class CompositeMethod : uint8_t
|
enum class CompositeMethod : uint8_t
|
||||||
{
|
{
|
||||||
None = 0, ///< No composition is applied.
|
None = 0, ///< No composition is applied.
|
||||||
ClipPath, ///< The intersection of the source and the target is determined and only the resulting pixels from the source are rendered.
|
ClipPath, ///< The intersection of the source and the target is determined and only the resulting pixels from the source are rendered. Note that ClipPath only supports the Shape type.
|
||||||
AlphaMask, ///< Alpha Masking using the compositing target's pixels as an alpha value.
|
AlphaMask, ///< Alpha Masking using the compositing target's pixels as an alpha value.
|
||||||
InvAlphaMask, ///< Alpha Masking using the complement to the compositing target's pixels as an alpha value.
|
InvAlphaMask, ///< Alpha Masking using the complement to the compositing target's pixels as an alpha value.
|
||||||
LumaMask, ///< Alpha Masking using the grayscale (0.2125R + 0.7154G + 0.0721*B) of the compositing target's pixels. @since 0.9
|
LumaMask, ///< Alpha Masking using the grayscale (0.2125R + 0.7154G + 0.0721*B) of the compositing target's pixels. @since 0.9
|
||||||
|
|
|
@ -138,7 +138,7 @@ typedef enum {
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TVG_COMPOSITE_METHOD_NONE = 0, ///< No composition is applied.
|
TVG_COMPOSITE_METHOD_NONE = 0, ///< No composition is applied.
|
||||||
TVG_COMPOSITE_METHOD_CLIP_PATH, ///< The intersection of the source and the target is determined and only the resulting pixels from the source are rendered.
|
TVG_COMPOSITE_METHOD_CLIP_PATH, ///< The intersection of the source and the target is determined and only the resulting pixels from the source are rendered. Note that ClipPath only supports the Shape type.
|
||||||
TVG_COMPOSITE_METHOD_ALPHA_MASK, ///< The pixels of the source and the target are alpha blended. As a result, only the part of the source, which intersects with the target is visible.
|
TVG_COMPOSITE_METHOD_ALPHA_MASK, ///< The pixels of the source and the target are alpha blended. As a result, only the part of the source, which intersects with the target is visible.
|
||||||
TVG_COMPOSITE_METHOD_INVERSE_ALPHA_MASK, ///< The pixels of the source and the complement to the target's pixels are alpha blended. As a result, only the part of the source which is not covered by the target is visible.
|
TVG_COMPOSITE_METHOD_INVERSE_ALPHA_MASK, ///< The pixels of the source and the complement to the target's pixels are alpha blended. As a result, only the part of the source which is not covered by the target is visible.
|
||||||
TVG_COMPOSITE_METHOD_LUMA_MASK, ///< The source pixels are converted to grayscale (luma value) and alpha blended with the target. As a result, only the part of the source which intersects with the target is visible. \since 0.9
|
TVG_COMPOSITE_METHOD_LUMA_MASK, ///< The source pixels are converted to grayscale (luma value) and alpha blended with the target. As a result, only the part of the source which intersects with the target is visible. \since 0.9
|
||||||
|
|
|
@ -1131,13 +1131,6 @@ RenderData GlRenderer::prepare(Surface* image, const RenderMesh* mesh, RenderDat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RenderData GlRenderer::prepare(TVG_UNUSED const Array<RenderData>& scene, TVG_UNUSED RenderData data, TVG_UNUSED const Matrix& transform, TVG_UNUSED Array<RenderData>& clips, TVG_UNUSED uint8_t opacity, TVG_UNUSED RenderUpdateFlag flags)
|
|
||||||
{
|
|
||||||
//TODO:
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper)
|
RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper)
|
||||||
{
|
{
|
||||||
// If prepare for clip, only path is meaningful.
|
// If prepare for clip, only path is meaningful.
|
||||||
|
|
|
@ -54,7 +54,6 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override;
|
RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override;
|
||||||
RenderData prepare(const Array<RenderData>& scene, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
|
|
||||||
RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
|
RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
|
||||||
bool preRender() override;
|
bool preRender() override;
|
||||||
bool renderShape(RenderData data) override;
|
bool renderShape(RenderData data) override;
|
||||||
|
|
|
@ -199,59 +199,6 @@ struct SwShapeTask : SwTask
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct SwSceneTask : SwTask
|
|
||||||
{
|
|
||||||
Array<RenderData> scene; //list of paints render data (SwTask)
|
|
||||||
SwRle* sceneRle = nullptr;
|
|
||||||
|
|
||||||
bool clip(SwRle* target) override
|
|
||||||
{
|
|
||||||
//Only one shape
|
|
||||||
if (scene.count == 1) {
|
|
||||||
return static_cast<SwTask*>(*scene.data)->clip(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
//More than one shapes
|
|
||||||
if (sceneRle) rleClipPath(target, sceneRle);
|
|
||||||
else TVGLOG("SW_ENGINE", "No clippers in a scene?");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
SwRle* rle() override
|
|
||||||
{
|
|
||||||
return sceneRle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void run(unsigned tid) override
|
|
||||||
{
|
|
||||||
//TODO: Skip the run if the scene hasn't changed.
|
|
||||||
if (!sceneRle) sceneRle = static_cast<SwRle*>(calloc(1, sizeof(SwRle)));
|
|
||||||
else rleReset(sceneRle);
|
|
||||||
|
|
||||||
//Merge shapes if it has more than one shapes
|
|
||||||
if (scene.count > 1) {
|
|
||||||
//Merge first two clippers
|
|
||||||
auto clipper1 = static_cast<SwTask*>(*scene.data);
|
|
||||||
auto clipper2 = static_cast<SwTask*>(*(scene.data + 1));
|
|
||||||
|
|
||||||
rleMerge(sceneRle, clipper1->rle(), clipper2->rle());
|
|
||||||
|
|
||||||
//Unify the remained clippers
|
|
||||||
for (auto rd = scene.begin() + 2; rd < scene.end(); ++rd) {
|
|
||||||
auto clipper = static_cast<SwTask*>(*rd);
|
|
||||||
rleMerge(sceneRle, sceneRle, clipper->rle());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dispose() override
|
|
||||||
{
|
|
||||||
rleFree(sceneRle);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct SwImageTask : SwTask
|
struct SwImageTask : SwTask
|
||||||
{
|
{
|
||||||
SwImage image;
|
SwImage image;
|
||||||
|
@ -759,26 +706,6 @@ RenderData SwRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RenderData SwRenderer::prepare(const Array<RenderData>& scene, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags)
|
|
||||||
{
|
|
||||||
//prepare task
|
|
||||||
auto task = static_cast<SwSceneTask*>(data);
|
|
||||||
if (!task) task = new SwSceneTask;
|
|
||||||
else task->done();
|
|
||||||
|
|
||||||
task->scene = scene;
|
|
||||||
|
|
||||||
//TODO: Failed threading them. It would be better if it's possible.
|
|
||||||
//See: https://github.com/thorvg/thorvg/issues/1409
|
|
||||||
//Guarantee composition targets get ready.
|
|
||||||
for (auto task = scene.begin(); task < scene.end(); ++task) {
|
|
||||||
static_cast<SwTask*>(*task)->done();
|
|
||||||
}
|
|
||||||
|
|
||||||
return prepareCommon(task, transform, clips, opacity, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RenderData SwRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper)
|
RenderData SwRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper)
|
||||||
{
|
{
|
||||||
//prepare task
|
//prepare task
|
||||||
|
|
|
@ -37,7 +37,6 @@ class SwRenderer : public RenderMethod
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override;
|
RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override;
|
||||||
RenderData prepare(const Array<RenderData>& scene, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
|
|
||||||
RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
|
RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
|
||||||
bool preRender() override;
|
bool preRender() override;
|
||||||
bool renderShape(RenderData data) override;
|
bool renderShape(RenderData data) override;
|
||||||
|
|
|
@ -822,46 +822,6 @@ static SwSpan* _intersectSpansRect(const SwBBox *bbox, const SwRle *targetRle, S
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SwSpan* _mergeSpansRegion(const SwRle *clip1, const SwRle *clip2, SwSpan *outSpans)
|
|
||||||
{
|
|
||||||
auto out = outSpans;
|
|
||||||
auto spans1 = clip1->spans;
|
|
||||||
auto end1 = clip1->spans + clip1->size;
|
|
||||||
auto spans2 = clip2->spans;
|
|
||||||
auto end2 = clip2->spans + clip2->size;
|
|
||||||
|
|
||||||
//list two spans up in y order
|
|
||||||
//TODO: Remove duplicated regions?
|
|
||||||
while (spans1 < end1 && spans2 < end2) {
|
|
||||||
while (spans1 < end1 && spans1->y <= spans2->y) {
|
|
||||||
*out = *spans1;
|
|
||||||
++spans1;
|
|
||||||
++out;
|
|
||||||
}
|
|
||||||
if (spans1 >= end1) break;
|
|
||||||
while (spans2 < end2 && spans2->y <= spans1->y) {
|
|
||||||
*out = *spans2;
|
|
||||||
++spans2;
|
|
||||||
++out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Leftovers
|
|
||||||
while (spans1 < end1) {
|
|
||||||
*out = *spans1;
|
|
||||||
++spans1;
|
|
||||||
++out;
|
|
||||||
}
|
|
||||||
while (spans2 < end2) {
|
|
||||||
*out = *spans2;
|
|
||||||
++spans2;
|
|
||||||
++out;
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void _replaceClipSpan(SwRle *rle, SwSpan* clippedSpans, uint32_t size)
|
void _replaceClipSpan(SwRle *rle, SwSpan* clippedSpans, uint32_t size)
|
||||||
{
|
{
|
||||||
free(rle->spans);
|
free(rle->spans);
|
||||||
|
@ -1030,45 +990,6 @@ void rleFree(SwRle* rle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void rleMerge(SwRle* rle, SwRle* clip1, SwRle* clip2)
|
|
||||||
{
|
|
||||||
if (!rle || (!clip1 && !clip2)) return;
|
|
||||||
if (clip1 && clip1->size == 0 && clip2 && clip2->size == 0) return;
|
|
||||||
|
|
||||||
TVGLOG("SW_ENGINE", "Unifying Rle!");
|
|
||||||
|
|
||||||
//clip1 is empty, just copy clip2
|
|
||||||
if (!clip1 || clip1->size == 0) {
|
|
||||||
if (clip2) {
|
|
||||||
auto spans = static_cast<SwSpan*>(malloc(sizeof(SwSpan) * (clip2->size)));
|
|
||||||
memcpy(spans, clip2->spans, clip2->size);
|
|
||||||
_replaceClipSpan(rle, spans, clip2->size);
|
|
||||||
} else {
|
|
||||||
_replaceClipSpan(rle, nullptr, 0);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//clip2 is empty, just copy clip1
|
|
||||||
if (!clip2 || clip2->size == 0) {
|
|
||||||
if (clip1) {
|
|
||||||
auto spans = static_cast<SwSpan*>(malloc(sizeof(SwSpan) * (clip1->size)));
|
|
||||||
memcpy(spans, clip1->spans, clip1->size);
|
|
||||||
_replaceClipSpan(rle, spans, clip1->size);
|
|
||||||
} else {
|
|
||||||
_replaceClipSpan(rle, nullptr, 0);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto spanCnt = clip1->size + clip2->size;
|
|
||||||
auto spans = static_cast<SwSpan*>(malloc(sizeof(SwSpan) * spanCnt));
|
|
||||||
auto spansEnd = _mergeSpansRegion(clip1, clip2, spans);
|
|
||||||
|
|
||||||
_replaceClipSpan(rle, spans, spansEnd - spans);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void rleClipPath(SwRle *rle, const SwRle *clip)
|
void rleClipPath(SwRle *rle, const SwRle *clip)
|
||||||
{
|
{
|
||||||
if (rle->size == 0 || clip->size == 0) return;
|
if (rle->size == 0 || clip->size == 0) return;
|
||||||
|
|
|
@ -435,6 +435,11 @@ Paint* Paint::duplicate() const noexcept
|
||||||
|
|
||||||
Result Paint::composite(std::unique_ptr<Paint> target, CompositeMethod method) noexcept
|
Result Paint::composite(std::unique_ptr<Paint> target, CompositeMethod method) noexcept
|
||||||
{
|
{
|
||||||
|
if (method == CompositeMethod::ClipPath && target && target->type() != Type::Shape) {
|
||||||
|
TVGERR("RENDERER", "ClipPath only allows the Shape!");
|
||||||
|
return Result::NonSupport;
|
||||||
|
}
|
||||||
|
|
||||||
auto p = target.release();
|
auto p = target.release();
|
||||||
if (pImpl->composite(this, p, method)) return Result::Success;
|
if (pImpl->composite(this, p, method)) return Result::Success;
|
||||||
delete(p);
|
delete(p);
|
||||||
|
|
|
@ -89,7 +89,7 @@ struct Picture::Impl
|
||||||
delete(paint);
|
delete(paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderData update(RenderMethod* renderer, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper)
|
RenderData update(RenderMethod* renderer, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, TVG_UNUSED bool clipper)
|
||||||
{
|
{
|
||||||
auto flag = static_cast<RenderUpdateFlag>(pFlag | load());
|
auto flag = static_cast<RenderUpdateFlag>(pFlag | load());
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ struct Picture::Impl
|
||||||
resizing = false;
|
resizing = false;
|
||||||
}
|
}
|
||||||
needComp = needComposition(opacity) ? true : false;
|
needComp = needComposition(opacity) ? true : false;
|
||||||
rd = paint->pImpl->update(renderer, transform, clips, opacity, flag, clipper);
|
rd = paint->pImpl->update(renderer, transform, clips, opacity, flag, false);
|
||||||
}
|
}
|
||||||
return rd;
|
return rd;
|
||||||
}
|
}
|
||||||
|
|
|
@ -285,7 +285,6 @@ public:
|
||||||
|
|
||||||
virtual ~RenderMethod() {}
|
virtual ~RenderMethod() {}
|
||||||
virtual RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) = 0;
|
virtual RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) = 0;
|
||||||
virtual RenderData prepare(const Array<RenderData>& scene, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) = 0;
|
|
||||||
virtual RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) = 0;
|
virtual RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) = 0;
|
||||||
virtual bool preRender() = 0;
|
virtual bool preRender() = 0;
|
||||||
virtual bool renderShape(RenderData data) = 0;
|
virtual bool renderShape(RenderData data) = 0;
|
||||||
|
|
|
@ -101,7 +101,7 @@ struct Scene::Impl
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderData update(RenderMethod* renderer, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flag, bool clipper)
|
RenderData update(RenderMethod* renderer, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flag, TVG_UNUSED bool clipper)
|
||||||
{
|
{
|
||||||
if ((needComp = needComposition(opacity))) {
|
if ((needComp = needComposition(opacity))) {
|
||||||
/* Overriding opacity value. If this scene is half-translucent,
|
/* Overriding opacity value. If this scene is half-translucent,
|
||||||
|
@ -109,21 +109,11 @@ struct Scene::Impl
|
||||||
this->opacity = opacity;
|
this->opacity = opacity;
|
||||||
opacity = 255;
|
opacity = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clipper) {
|
|
||||||
Array<RenderData> rds(paints.size());
|
|
||||||
for (auto paint : paints) {
|
|
||||||
rds.push(paint->pImpl->update(renderer, transform, clips, opacity, flag, true));
|
|
||||||
}
|
|
||||||
rd = renderer->prepare(rds, rd, transform, clips, opacity, flag);
|
|
||||||
return rd;
|
|
||||||
} else {
|
|
||||||
for (auto paint : paints) {
|
for (auto paint : paints) {
|
||||||
paint->pImpl->update(renderer, transform, clips, opacity, flag, false);
|
paint->pImpl->update(renderer, transform, clips, opacity, flag, false);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool render(RenderMethod* renderer)
|
bool render(RenderMethod* renderer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -120,7 +120,7 @@ struct Text::Impl
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderData update(RenderMethod* renderer, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper)
|
RenderData update(RenderMethod* renderer, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, TVG_UNUSED bool clipper)
|
||||||
{
|
{
|
||||||
if (!load()) return nullptr;
|
if (!load()) return nullptr;
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ struct Text::Impl
|
||||||
P(static_cast<RadialGradient*>(fill))->fr *= scale;
|
P(static_cast<RadialGradient*>(fill))->fr *= scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PP(paint)->update(renderer, transform, clips, opacity, pFlag, clipper);
|
return PP(paint)->update(renderer, transform, clips, opacity, pFlag, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bounds(float* x, float* y, float* w, float* h, TVG_UNUSED bool stroking)
|
bool bounds(float* x, float* y, float* w, float* h, TVG_UNUSED bool stroking)
|
||||||
|
|
|
@ -111,12 +111,6 @@ RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RenderData WgRenderer::prepare(TVG_UNUSED const Array<RenderData>& scene, TVG_UNUSED RenderData data, TVG_UNUSED const Matrix& transform, TVG_UNUSED Array<RenderData>& clips, TVG_UNUSED uint8_t opacity, TVG_UNUSED RenderUpdateFlag flags)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RenderData WgRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags)
|
RenderData WgRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags)
|
||||||
{
|
{
|
||||||
// get or create render data shape
|
// get or create render data shape
|
||||||
|
|
|
@ -29,7 +29,6 @@ class WgRenderer : public RenderMethod
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override;
|
RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override;
|
||||||
RenderData prepare(const Array<RenderData>& scene, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
|
|
||||||
RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
|
RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
|
||||||
bool preRender() override;
|
bool preRender() override;
|
||||||
bool renderShape(RenderData data) override;
|
bool renderShape(RenderData data) override;
|
||||||
|
|
Loading…
Add table
Reference in a new issue