Getting in-band assets to render with the viewer renderer.
diff --git a/include/rive/assets/file_asset.hpp b/include/rive/assets/file_asset.hpp index 5826e3a..dcc91e5 100644 --- a/include/rive/assets/file_asset.hpp +++ b/include/rive/assets/file_asset.hpp
@@ -7,7 +7,7 @@ class FileAsset : public FileAssetBase { public: - virtual void decode(const uint8_t* bytes) = 0; + virtual void decode(const uint8_t* bytes, std::size_t size) = 0; StatusCode import(ImportStack& importStack) override; }; } // namespace rive
diff --git a/include/rive/assets/file_asset_contents.hpp b/include/rive/assets/file_asset_contents.hpp index d035621..5b3e961 100644 --- a/include/rive/assets/file_asset_contents.hpp +++ b/include/rive/assets/file_asset_contents.hpp
@@ -1,12 +1,13 @@ #ifndef _RIVE_FILE_ASSET_CONTENTS_HPP_ #define _RIVE_FILE_ASSET_CONTENTS_HPP_ #include "rive/generated/assets/file_asset_contents_base.hpp" -#include <stdio.h> + namespace rive { class FileAssetContents : public FileAssetContentsBase { public: + StatusCode import(ImportStack& importStack) override; }; } // namespace rive
diff --git a/include/rive/assets/image_asset.hpp b/include/rive/assets/image_asset.hpp index 152ff58..30777ce 100644 --- a/include/rive/assets/image_asset.hpp +++ b/include/rive/assets/image_asset.hpp
@@ -14,7 +14,7 @@ ImageAsset(); ~ImageAsset(); - void decode(const uint8_t* bytes) override; + void decode(const uint8_t* bytes, std::size_t size) override; RenderImage* renderImage() const { return m_RenderImage; } }; } // namespace rive
diff --git a/include/rive/importers/file_asset_importer.hpp b/include/rive/importers/file_asset_importer.hpp new file mode 100644 index 0000000..57626c3 --- /dev/null +++ b/include/rive/importers/file_asset_importer.hpp
@@ -0,0 +1,23 @@ +#ifndef _RIVE_FILE_ASSET_IMPORTER_HPP_ +#define _RIVE_FILE_ASSET_IMPORTER_HPP_ + +#include "rive/importers/import_stack.hpp" +#include <unordered_map> +#include <vector> + +namespace rive +{ + class FileAsset; + class FileAssetContents; + class FileAssetImporter : public ImportStackObject + { + private: + FileAsset* m_FileAsset; + + public: + FileAssetImporter(FileAsset* fileAsset); + void loadContents(const FileAssetContents& contents); + StatusCode resolve() override; + }; +} // namespace rive +#endif
diff --git a/include/rive/renderer.hpp b/include/rive/renderer.hpp index de385b8..3b4bce5 100644 --- a/include/rive/renderer.hpp +++ b/include/rive/renderer.hpp
@@ -47,7 +47,7 @@ public: virtual ~RenderImage() {} - virtual bool decode(const uint8_t* bytes) = 0; + virtual bool decode(const uint8_t* bytes, std::size_t size) = 0; int width() const { return m_Width; } int height() const { return m_Height; } };
diff --git a/include/rive/shapes/image.hpp b/include/rive/shapes/image.hpp index d36fcbd..190d261 100644 --- a/include/rive/shapes/image.hpp +++ b/include/rive/shapes/image.hpp
@@ -15,6 +15,7 @@ void draw(Renderer* renderer) override; StatusCode import(ImportStack& importStack) override; void assets(const std::vector<FileAsset*>& assets) override; + Core* clone() const override; }; } // namespace rive
diff --git a/skia/dependencies/make_glfw.sh b/skia/dependencies/make_glfw.sh index 71c7a9c..62620a7 100755 --- a/skia/dependencies/make_glfw.sh +++ b/skia/dependencies/make_glfw.sh
@@ -19,7 +19,7 @@ cd .. fi -mkdir glfw_build +mkdir -p glfw_build cd glfw_build cmake ../glfw -DBUILD_SHARED_LIBS=OFF make \ No newline at end of file
diff --git a/skia/renderer/include/skia_renderer.hpp b/skia/renderer/include/skia_renderer.hpp index 96d9ba4..8239567 100644 --- a/skia/renderer/include/skia_renderer.hpp +++ b/skia/renderer/include/skia_renderer.hpp
@@ -4,6 +4,7 @@ #include "SkCanvas.h" #include "SkPaint.h" #include "SkPath.h" +#include "SkImage.h" #include "rive/renderer.hpp" #include <vector> @@ -91,6 +92,16 @@ void completeGradient() override; }; + class SkiaRenderImage : public RenderImage + { + private: + sk_sp<SkImage> m_SkImage; + + public: + sk_sp<SkImage> skImage() const { return m_SkImage; }; + bool decode(const uint8_t* bytes, std::size_t size) override; + }; + class SkiaRenderer : public Renderer { protected: @@ -102,6 +113,8 @@ void restore() override; void transform(const Mat2D& transform) override; void drawPath(RenderPath* path, RenderPaint* paint) override; + void + drawImage(RenderImage* image, BlendMode value, float opacity) override; void clipPath(RenderPath* path) override; }; } // namespace rive
diff --git a/skia/renderer/src/skia_renderer.cpp b/skia/renderer/src/skia_renderer.cpp index 4d05007..cb170b6 100644 --- a/skia/renderer/src/skia_renderer.cpp +++ b/skia/renderer/src/skia_renderer.cpp
@@ -143,8 +143,34 @@ m_Canvas->clipPath(reinterpret_cast<SkiaRenderPath*>(path)->path(), true); } +void SkiaRenderer::drawImage(RenderImage* image, + BlendMode blendMode, + float opacity) +{ + SkPaint paint; + paint.setAlphaf(opacity); + paint.setBlendMode(ToSkia::convert(blendMode)); + auto skiaImage = reinterpret_cast<SkiaRenderImage*>(image); + SkSamplingOptions samplingOptions(SkFilterMode::kLinear, + SkMipmapMode::kNone); + m_Canvas->drawImage( + skiaImage->skImage(), 0.0f, 0.0f, samplingOptions, &paint); +} + +bool SkiaRenderImage::decode(const uint8_t* bytes, std::size_t size) +{ + + sk_sp<SkData> data = SkData::MakeWithoutCopy(bytes, size); + m_SkImage = SkImage::MakeFromEncoded(data); + m_Width = m_SkImage->width(); + m_Height = m_SkImage->height(); + printf("DECODING IMAGE! %i %i\n", m_Width, m_Height); + return true; +} + namespace rive { RenderPath* makeRenderPath() { return new SkiaRenderPath(); } RenderPaint* makeRenderPaint() { return new SkiaRenderPaint(); } + RenderImage* makeRenderImage() { return new SkiaRenderImage(); } } // namespace rive \ No newline at end of file
diff --git a/skia/viewer/build/premake5.lua b/skia/viewer/build/premake5.lua index 16eb857..acc6885 100644 --- a/skia/viewer/build/premake5.lua +++ b/skia/viewer/build/premake5.lua
@@ -32,7 +32,6 @@ "../../dependencies/imgui/imgui_draw.cpp"} buildoptions {"-Wall", "-fno-exceptions", "-fno-rtti", "-flto=full"} --- linkoptions {"-Oz", "-flto=full"} filter "configurations:debug" defines {"DEBUG"} symbols "On"
diff --git a/src/assets/file_asset_contents.cpp b/src/assets/file_asset_contents.cpp new file mode 100644 index 0000000..0b6ad54 --- /dev/null +++ b/src/assets/file_asset_contents.cpp
@@ -0,0 +1,18 @@ +#include "rive/assets/file_asset_contents.hpp" +#include "rive/assets/file_asset.hpp" +#include "rive/importers/file_asset_importer.hpp" + +using namespace rive; + +StatusCode FileAssetContents::import(ImportStack& importStack) +{ + auto fileAssetImporter = + importStack.latest<FileAssetImporter>(FileAsset::typeKey); + if (fileAssetImporter == nullptr) + { + return StatusCode::MissingObject; + } + fileAssetImporter->loadContents(*this); + + return Super::import(importStack); +} \ No newline at end of file
diff --git a/src/assets/image_asset.cpp b/src/assets/image_asset.cpp index 22ae470..1ff6d33 100644 --- a/src/assets/image_asset.cpp +++ b/src/assets/image_asset.cpp
@@ -6,4 +6,7 @@ ImageAsset::ImageAsset() : m_RenderImage(makeRenderImage()) {} ImageAsset::~ImageAsset() { delete m_RenderImage; } -void ImageAsset::decode(const uint8_t* bytes) { m_RenderImage->decode(bytes); } \ No newline at end of file +void ImageAsset::decode(const uint8_t* bytes, std::size_t size) +{ + m_RenderImage->decode(bytes, size); +} \ No newline at end of file
diff --git a/src/file.cpp b/src/file.cpp index 9a88194..a7eb452 100644 --- a/src/file.cpp +++ b/src/file.cpp
@@ -7,6 +7,7 @@ #include "rive/generated/core_registry.hpp" #include "rive/importers/artboard_importer.hpp" #include "rive/importers/backboard_importer.hpp" +#include "rive/importers/file_asset_importer.hpp" #include "rive/importers/import_stack.hpp" #include "rive/importers/keyed_object_importer.hpp" #include "rive/importers/keyed_property_importer.hpp" @@ -251,6 +252,10 @@ new StateTransitionImporter(object->as<StateTransition>()); stackType = StateTransition::typeKey; break; + case ImageAsset::typeKey: + stackObject = new FileAssetImporter(object->as<FileAsset>()); + stackType = FileAsset::typeKey; + break; } if (importStack.makeLatest(stackType, stackObject) != StatusCode::Ok) {
diff --git a/src/importers/file_asset_importer.cpp b/src/importers/file_asset_importer.cpp new file mode 100644 index 0000000..9e62fe3 --- /dev/null +++ b/src/importers/file_asset_importer.cpp
@@ -0,0 +1,21 @@ +#include "rive/importers/file_asset_importer.hpp" +#include "rive/assets/file_asset_contents.hpp" +#include "rive/assets/file_asset.hpp" + +using namespace rive; + +FileAssetImporter::FileAssetImporter(FileAsset* fileAsset) : + m_FileAsset(fileAsset) +{ +} +void FileAssetImporter::loadContents(const FileAssetContents& contents) +{ + const std::vector<uint8_t>& data = contents.bytes(); + m_FileAsset->decode(&data[0], data.size()); +} + +StatusCode FileAssetImporter::resolve() +{ + // TODO: find data if the bytes weren't in band. + return StatusCode::Ok; +} \ No newline at end of file
diff --git a/src/shapes/image.cpp b/src/shapes/image.cpp index 2256a1a..9eb58e7 100644 --- a/src/shapes/image.cpp +++ b/src/shapes/image.cpp
@@ -8,12 +8,25 @@ void Image::draw(Renderer* renderer) { - if (renderOpacity() == 0.0f) + if (m_ImageAsset == nullptr || renderOpacity() == 0.0f) { return; } - renderer->drawImage( - m_ImageAsset->renderImage(), blendMode(), renderOpacity()); + renderer->save(); + + auto renderImage = m_ImageAsset->renderImage(); + auto width = renderImage->width(); + auto height = renderImage->height(); + + const Mat2D& transform = worldTransform(); + renderer->transform(transform); + + Mat2D originTranslation( + 1.0f, 0.0f, 0.0f, 1.0f, -width / 2.0f, -height / 2.0f); + renderer->transform(originTranslation); + + renderer->drawImage(renderImage, blendMode(), renderOpacity()); + renderer->restore(); } StatusCode Image::import(ImportStack& importStack) @@ -40,4 +53,11 @@ { m_ImageAsset = asset->as<ImageAsset>(); } +} + +Core* Image::clone() const +{ + Image* twin = ImageBase::clone()->as<Image>(); + twin->m_ImageAsset = m_ImageAsset; + return twin; } \ No newline at end of file