blob: 021f84ba9979bd3b823b82a6d47680c3ab82d37a [file] [log] [blame]
#include "rive/math/hit_test.hpp"
#include "rive/shapes/image.hpp"
#include "rive/backboard.hpp"
#include "rive/importers/backboard_importer.hpp"
#include "rive/assets/file_asset.hpp"
#include "rive/assets/image_asset.hpp"
#include "rive/shapes/mesh.hpp"
#include "rive/artboard.hpp"
#include "rive/clip_result.hpp"
using namespace rive;
void Image::draw(Renderer* renderer)
{
rive::ImageAsset* asset = this->imageAsset();
if (asset == nullptr || renderOpacity() == 0.0f)
{
return;
}
rive::RenderImage* renderImage = asset->renderImage();
if (renderImage == nullptr)
{
return;
}
ClipResult clipResult = clip(renderer);
if (clipResult == ClipResult::noClip)
{
// We didn't clip, so make sure to save as we'll be doing some
// transformations.
renderer->save();
}
if (clipResult != ClipResult::emptyClip)
{
auto width = renderImage->width();
auto height = renderImage->height();
if (m_Mesh != nullptr)
{
m_Mesh->draw(renderer, renderImage, blendMode(), renderOpacity());
}
else
{
renderer->transform(worldTransform());
renderer->translate(-width * originX(), -height * originY());
renderer->drawImage(renderImage, blendMode(), renderOpacity());
}
}
renderer->restore();
}
Core* Image::hitTest(HitInfo* hinfo, const Mat2D& xform)
{
// TODO: handle clip?
auto renderImage = imageAsset()->renderImage();
int width = renderImage->width();
int height = renderImage->height();
if (m_Mesh)
{
printf("Missing mesh\n");
// TODO: hittest mesh
}
else
{
auto mx = xform * worldTransform() *
Mat2D::fromTranslate(-width * originX(), -height * originY());
HitTester tester(hinfo->area);
tester.addRect(AABB(0, 0, (float)width, (float)height), mx);
if (tester.test())
{
return this;
}
}
return nullptr;
}
StatusCode Image::import(ImportStack& importStack)
{
auto result = registerReferencer(importStack);
if (result != StatusCode::Ok)
{
return result;
}
return Super::import(importStack);
}
// Question: thoughts on this? it looks a bit odd to me,
// maybe there's a trick i'm missing here .. (could also implement getAssetId...)
uint32_t Image::assetId() { return ImageBase::assetId(); }
void Image::setAsset(FileAsset* asset)
{
if (asset->is<ImageAsset>())
{
FileAssetReferencer::setAsset(asset);
// If we have a mesh and we're in the source artboard, let's initialize
// the mesh buffers.
if (m_Mesh != nullptr && !artboard()->isInstance())
{
m_Mesh->initializeSharedBuffers(imageAsset()->renderImage());
}
}
}
Core* Image::clone() const
{
Image* twin = ImageBase::clone()->as<Image>();
if (m_fileAsset != nullptr)
{
twin->setAsset(m_fileAsset);
}
return twin;
}
void Image::setMesh(Mesh* mesh) { m_Mesh = mesh; }
Mesh* Image::mesh() const { return m_Mesh; }