blob: 73217ebca4061fe6fa1dc15b41f54b2f316117f9 [file] [log] [blame] [edit]
/*
* Copyright 2022 Rive
*/
#ifndef _RIVE_GM_UTILS_HPP_
#define _RIVE_GM_UTILS_HPP_
#include "rive/math/aabb.hpp"
#include "rive/renderer.hpp"
#include "rive/factory.hpp"
#include "rive/refcnt.hpp"
#include "common/testing_window.hpp"
#include <utility>
#include <vector>
namespace rivegm
{
double GetCurrSeconds();
class AutoRestore
{
rive::Renderer* m_Ren;
public:
AutoRestore(rive::Renderer* ren, bool doSave = false) : m_Ren(ren)
{
if (doSave)
{
m_Ren->save();
}
}
~AutoRestore() { m_Ren->restore(); }
};
rive::rcp<rive::RenderImage> LoadImage(rive::Span<uint8_t>);
class Paint
{
rive::rcp<rive::RenderPaint> m_Paint;
public:
Paint() : m_Paint(TestingWindow::Get()->factory()->makeRenderPaint()) {}
Paint(rive::ColorInt c) :
m_Paint(TestingWindow::Get()->factory()->makeRenderPaint())
{
m_Paint->color(c);
}
rive::RenderPaint* get() const { return m_Paint.get(); }
rive::RenderPaint* operator->() const { return m_Paint.get(); }
operator rive::RenderPaint*() const { return m_Paint.get(); }
};
class Path
{
rive::rcp<rive::RenderPath> m_Path;
public:
Path() : m_Path(TestingWindow::Get()->factory()->makeEmptyRenderPath()) {}
Path(rive::FillRule rule) : Path() { m_Path->fillRule(rule); }
Path(Path&& path) : m_Path(std::move(path.m_Path)) {}
Path(const Path&) = delete;
Path& operator=(Path&& path)
{
m_Path = std::move(path.m_Path);
return *this;
}
Path& operator=(const Path&) = delete;
rive::RenderPath* get() const { return m_Path.get(); }
rive::RenderPath* operator->() const { return m_Path.get(); }
operator rive::RenderPath*() const { return m_Path.get(); }
};
enum class PathDirection
{
clockwise,
counterclockwise,
cw = clockwise,
ccw = counterclockwise,
};
void path_addOval(rive::RenderPath*,
rive::AABB bounds,
PathDirection = PathDirection::cw);
void draw_rect(rive::Renderer* r, rive::AABB rect, rive::RenderPaint*);
void draw_oval(rive::Renderer* r, rive::AABB rect, rive::RenderPaint*);
void draw_image(rive::Renderer*, rive::RenderImage*, rive::AABB);
void draw_image(rive::Renderer* ren,
rive::RenderImage* img,
const rive::ImageSampler& options,
rive::AABB dst);
rive::rcp<rive::RenderPath> renderPathFromRawPath(
rive::RawPath& path,
const rive::FillRule fillRule = rive::FillRule::nonZero);
class PathBuilder
{
public:
static Path Rect(rive::AABB rect, PathDirection dir = PathDirection::cw)
{
return PathBuilder().addRect(rect, dir).detach();
}
static Path Oval(rive::AABB bounds, PathDirection dir = PathDirection::cw)
{
return PathBuilder().addOval(bounds, dir).detach();
}
static Path Circle(float x,
float y,
float r,
PathDirection dir = PathDirection::cw)
{
return PathBuilder().addCircle(x, y, r, dir).detach();
}
static Path RRect(rive::AABB rect, float radX, float radY)
{
return PathBuilder().addRRect(rect, radX, radY).detach();
}
static Path Polygon(const std::vector<rive::Vec2D>& pts,
bool doClose,
rive::FillRule fillRule = rive::FillRule::nonZero)
{
return PathBuilder()
.addPolygon(pts, doClose)
.fillRule(fillRule)
.detach();
}
PathBuilder& fillRule(rive::FillRule f);
PathBuilder& moveTo(float x, float y);
PathBuilder& lineTo(float x, float y);
PathBuilder& quadTo(float ox, float oy, float x, float y);
PathBuilder& cubicTo(float ox,
float oy,
float ix,
float iy,
float x,
float y);
PathBuilder& close();
PathBuilder& addRect(rive::AABB rect, PathDirection = PathDirection::cw);
PathBuilder& addOval(rive::AABB rect, PathDirection = PathDirection::cw);
PathBuilder& addCircle(float x,
float y,
float r,
PathDirection = PathDirection::cw);
PathBuilder& addRRect(rive::AABB rect, float radX, float radY);
PathBuilder& addPolygon(const std::vector<rive::Vec2D>&, bool doClose);
PathBuilder& polylineTo(const std::vector<rive::Vec2D>&);
Path detach() { return std::exchange(m_Path, Path()); }
private:
Path m_Path;
float m_FirstX = 0;
float m_FirstY = 0;
float m_LastX = 0;
float m_LastY = 0;
};
void path_add_star(Path& path, int count, float anglePhase, float dir);
} // namespace rivegm
#endif