blob: 6dcd9c6b927da77a373bbcb6420d5218eee61896 [file]
#ifndef _RIVE_NESTED_ARTBOARD_MESH_HOST_HPP_
#define _RIVE_NESTED_ARTBOARD_MESH_HOST_HPP_
#include "rive/shapes/mesh_host.hpp"
#ifdef RIVE_CANVAS
#include "rive/offscreen_raster.hpp"
#endif
namespace rive
{
class Artboard;
class ArtboardInstance;
class NestedArtboard;
class Renderer;
// Mesh state of a Node-mode NestedArtboard, which owns it.
class NestedArtboardMeshHost final : public MeshHost
{
public:
explicit NestedArtboardMeshHost(NestedArtboard* owner) : m_owner(owner) {}
void setMesh(MeshDrawable* mesh) override;
MeshDrawable* hostedMesh() const override { return m_mesh; }
float meshHostWidth() const override;
float meshHostHeight() const override;
Vec2D meshHostOrigin() const override;
float meshHostScaleX() const override;
float meshHostScaleY() const override;
Mat2D meshHostWorldTransform() const override;
bool meshHostReady() const override;
Mat2D meshHostUVTransform() const override;
#ifdef WITH_RIVE_EDITOR
void setMeshForEditor(MeshDrawable* mesh) override { setMesh(mesh); }
void clearMeshIfForEditor(MeshDrawable* expected) override
{
if (m_mesh == expected)
{
setMesh(nullptr);
}
}
#endif
// The artboard's Bitmap Cache resolution, else 1.
float meshRasterResolution() const;
void resetRaster();
// Whether pointers follow the mesh: it drew the last frame, rather than
// the artboard falling back to its undeformed vectors.
bool pointersFollowMesh() const;
// Maps a host-space point into the artboard (the space
// NestedArtboard::worldToLocal returns) through the mesh. `offMesh` is
// true past the mesh's edge, where the mapping extends the nearest
// triangle. False when pointers don't follow the mesh, or it has no
// triangles to map through. `toLocal`, when given, is set to the affine
// map through the triangle used.
bool localThroughMesh(
Vec2D world,
Vec2D* local,
bool* offMesh,
Mat2D* toLocal = nullptr);
// Where a point in the artboard's content space is drawn, in host space.
bool worldThroughMesh(Vec2D content, Vec2D* world) const;
#ifdef RIVE_CANVAS
// False when no raster could be made; the caller draws vectors.
bool draw(Renderer* renderer);
bool compositeDropsClip() const;
// Whether the last draw went through the mesh, so pointers follow it.
void drewThroughMesh(bool value) { m_drewThroughMesh = value; }
#endif
#ifdef TESTING
bool rasterHeld() const
{
#ifdef RIVE_CANVAS
return m_raster.canvas != nullptr;
#else
return false;
#endif
}
#endif
private:
ArtboardInstance* instance() const;
const Artboard* sizeSource() const;
#ifdef RIVE_CANVAS
bool underClip() const;
#endif
NestedArtboard* m_owner;
MeshDrawable* m_mesh = nullptr;
#ifdef RIVE_CANVAS
offscreen::CachedRaster m_raster;
// A data-bound swap or resize rebuilds the raster and UVs.
const Artboard* m_rasterSource = nullptr;
Mat2D m_uvTransform;
bool m_uvValid = false;
// Until a draw says otherwise, pointers follow the mesh.
bool m_drewThroughMesh = true;
// The last pointer localThroughMesh mapped, where it was and where it
// landed in content space (see worldThroughMesh).
Vec2D m_pointerWorld;
Vec2D m_pointerContent;
bool m_hasPointer = false;
#endif
};
} // namespace rive
#endif