clang-format the universe

find . -name '*.c' -o -name '*.cpp' -o -name '*.cc'-o \
       -name '*.h' -o -name '*.hpp' \
  | xargs clang-format --style=file -i

Diffs=
c885b0ffd clang-format the universe
This commit is contained in:
csmartdalton
2022-07-08 17:01:01 +00:00
parent cc2c765a22
commit 4d41d33e3b
74 changed files with 800 additions and 787 deletions

View File

@@ -1 +1 @@
3f2972fe3f004c4afe35960517d701d100a6a406
c885b0ffdf19f2d4b90ed6538ac8463842d24e0d

View File

@@ -25,8 +25,7 @@ namespace rive {
BlendStateAnimationInstance(const T* blendAnimation, ArtboardInstance* instance) :
m_BlendAnimation(blendAnimation),
m_AnimationInstance(blendAnimation->animation(), instance)
{}
m_AnimationInstance(blendAnimation->animation(), instance) {}
void mix(float value) { m_Mix = value; }
};
@@ -37,9 +36,10 @@ namespace rive {
bool m_KeepGoing = true;
public:
BlendStateInstance(const K* blendState, ArtboardInstance* instance) : StateInstance(blendState) {
BlendStateInstance(const K* blendState, ArtboardInstance* instance) :
StateInstance(blendState) {
m_AnimationInstances.reserve(blendState->animations().size());
for (auto blendAnimation : blendState->animations()) {
m_AnimationInstances.emplace_back(
BlendStateAnimationInstance<T>(static_cast<T*>(blendAnimation), instance));

View File

@@ -9,7 +9,7 @@ namespace rive {
class LinearAnimation : public LinearAnimationBase {
private:
std::vector< std::unique_ptr<KeyedObject> > m_KeyedObjects;
std::vector<std::unique_ptr<KeyedObject>> m_KeyedObjects;
friend class Artboard;

View File

@@ -26,7 +26,7 @@ namespace rive {
// Advance the animation by the specified time. Returns true if the
// animation will continue to animate after this advance.
bool advance(float seconds);
// Returns a pointer to the instance's animation
const LinearAnimation* animation() const { return m_Animation; }
@@ -53,9 +53,7 @@ namespace rive {
// Applies the animation instance to its artboard instance. The mix (a value
// between 0 and 1) is the strength at which the animation is mixed with
// other animations applied to the artboard.
void apply(float mix = 1.0f) const {
m_Animation->apply(m_ArtboardInstance, m_Time, mix);
}
void apply(float mix = 1.0f) const { m_Animation->apply(m_ArtboardInstance, m_Time, mix); }
// Set when the animation is advanced, true if the animation has stopped
// (oneShot), reached the end (loop), or changed direction (pingPong)
@@ -71,7 +69,7 @@ namespace rive {
uint32_t duration() const;
float speed() const;
float startSeconds() const;
// Returns either the animation's default or overridden loop values
Loop loop() const override { return (Loop)loopValue(); }
int loopValue() const;

View File

@@ -34,9 +34,7 @@ namespace rive {
void move(Vec2D v) { this->moveTo(v.x, v.y); }
void line(Vec2D v) { this->lineTo(v.x, v.y); }
void cubic(Vec2D a, Vec2D b, Vec2D c) {
this->cubicTo(a.x, a.y, b.x, b.y, c.x, c.y);
}
void cubic(Vec2D a, Vec2D b, Vec2D c) { this->cubicTo(a.x, a.y, b.x, b.y, c.x, c.y); }
};
} // namespace rive
#endif

View File

@@ -33,7 +33,7 @@ namespace rive {
uint8_t readByte();
uint32_t readUint32();
uint64_t readVarUint64(); // Reads a LEB128 encoded uint64_t
// This will cast the uint read to the requested size, but if the
// raw value was out-of-range, instead returns 0 and sets the IntRangeError.
template <typename T> T readVarUintAs() {

View File

@@ -10,17 +10,16 @@
namespace rive {
template <typename T> bool fitsIn(intmax_t x) {
return x >= std::numeric_limits<T>::min() &&
x <= std::numeric_limits<T>::max();
}
template <typename T> bool fitsIn(intmax_t x) {
return x >= std::numeric_limits<T>::min() && x <= std::numeric_limits<T>::max();
}
template <typename T> T castTo(intmax_t x) {
assert(sizeof(T) <= 4); // don't cast to 64bit types
assert(fitsIn<T>(x));
return static_cast<T>(x);
}
template <typename T> T castTo(intmax_t x) {
assert(sizeof(T) <= 4); // don't cast to 64bit types
assert(fitsIn<T>(x));
return static_cast<T>(x);
}
} // namespace
} // namespace rive
#endif

View File

@@ -27,25 +27,28 @@ namespace rive {
virtual rcp<RenderBuffer> makeBufferU32(Span<const uint32_t>) = 0;
virtual rcp<RenderBuffer> makeBufferF32(Span<const float>) = 0;
virtual rcp<RenderShader> makeLinearGradient(float sx, float sy,
float ex, float ey,
const ColorInt colors[], // [count]
const float stops[], // [count]
virtual rcp<RenderShader> makeLinearGradient(float sx,
float sy,
float ex,
float ey,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode,
const Mat2D* localMatrix = nullptr) = 0;
virtual rcp<RenderShader> makeRadialGradient(float cx, float cy, float radius,
const ColorInt colors[], // [count]
const float stops[], // [count]
virtual rcp<RenderShader> makeRadialGradient(float cx,
float cy,
float radius,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode,
const Mat2D* localMatrix = nullptr) = 0;
// Returns a full-formed RenderPath -- can be treated as immutable
virtual std::unique_ptr<RenderPath> makeRenderPath(Span<const Vec2D> points,
Span<const uint8_t> verbs,
FillRule) = 0;
virtual std::unique_ptr<RenderPath>
makeRenderPath(Span<const Vec2D> points, Span<const uint8_t> verbs, FillRule) = 0;
virtual std::unique_ptr<RenderPath> makeEmptyRenderPath() = 0;

View File

@@ -69,7 +69,7 @@ namespace rive {
/// @returns a pointer to the file, or null on failure.
static std::unique_ptr<File> import(Span<const uint8_t> data,
Factory*,
ImportResult* result = nullptr,
ImportResult* result = nullptr,
FileAssetResolver* assetResolver = nullptr);
/// @returns the file's backboard. All files have exactly one backboard.

View File

@@ -41,7 +41,7 @@ namespace rive {
(void)invert(&inverse); // inverse is unchanged if invert() fails
return inverse;
}
TransformComponents decompose() const;
static Mat2D compose(const TransformComponents&);
Mat2D scale(Vec2D) const;

View File

@@ -10,10 +10,10 @@
namespace rive {
namespace math {
constexpr float PI = 3.14159265f;
}
namespace math {
constexpr float PI = 3.14159265f;
}
}
} // namespace rive
#endif

View File

@@ -24,12 +24,12 @@ namespace rive {
enum class PathVerb : uint8_t {
// These deliberately match Skia's values
move = 0,
line = 1,
quad = 2,
move = 0,
line = 1,
quad = 2,
// conic
cubic = 4,
close = 5,
cubic = 4,
close = 5,
};
int path_verb_to_point_count(PathVerb);

View File

@@ -37,9 +37,7 @@ namespace rive {
RawPath transform(const Mat2D&) const;
void transformInPlace(const Mat2D&);
RawPath operator*(const Mat2D& mat) const {
return this->transform(mat);
}
RawPath operator*(const Mat2D& mat) const { return this->transform(mat); }
Span<const Vec2D> points() const { return toSpan(m_Points); }
Span<Vec2D> points() { return toSpan(m_Points); }
@@ -73,21 +71,21 @@ namespace rive {
const PathVerb* m_stopVerb; // 1 past last verb
public:
Iter(const RawPath& path) {
m_currPts = path.m_Points.data();
m_currPts = path.m_Points.data();
m_currVerb = path.m_Verbs.data();
m_stopVerb = path.m_Verbs.data() + path.m_Verbs.size();
}
struct Rec {
const Vec2D* pts;
int count;
PathVerb verb;
operator bool() const { return pts != nullptr; }
};
Rec next();
};
template <typename Handler> RawPath morph(Handler proc) const {
RawPath dst;
// todo: dst.reserve(src.ptCount, src.verbCount);
@@ -98,16 +96,25 @@ namespace rive {
pts[i] = proc(rec.pts[i]);
}
switch (rec.verb) {
case PathVerb::move: dst.move(pts[0]); break;
case PathVerb::line: dst.line(pts[0]); break;
case PathVerb::quad: dst.quad(pts[0], pts[1]); break;
case PathVerb::cubic: dst.cubic(pts[0], pts[1], pts[2]); break;
case PathVerb::close: dst.close(); break;
case PathVerb::move:
dst.move(pts[0]);
break;
case PathVerb::line:
dst.line(pts[0]);
break;
case PathVerb::quad:
dst.quad(pts[0], pts[1]);
break;
case PathVerb::cubic:
dst.cubic(pts[0], pts[1], pts[2]);
break;
case PathVerb::close:
dst.close();
break;
}
}
return dst;
}
};
} // namespace rive

View File

@@ -79,9 +79,7 @@ namespace rive {
inline bool operator==(const Vec2D& a, const Vec2D& b) { return a.x == b.x && a.y == b.y; }
inline bool operator!=(const Vec2D& a, const Vec2D& b) { return a.x != b.x || a.y != b.y; }
Vec2D Vec2D::lerp(Vec2D a, Vec2D b, float t) {
return a + (b - a) * t;
}
Vec2D Vec2D::lerp(Vec2D a, Vec2D b, float t) { return a + (b - a) * t; }
} // namespace rive
#endif

View File

@@ -5,20 +5,20 @@
namespace rive {
enum class PointerEventType {
down, // The button has gone from up to down
move, // The pointer's position has changed
up, // The button has gone from down to up
};
enum class PointerEventType {
down, // The button has gone from up to down
move, // The pointer's position has changed
up, // The button has gone from down to up
};
struct PointerEvent {
PointerEventType m_Type;
Vec2D m_Position;
int m_PointerIndex;
struct PointerEvent {
PointerEventType m_Type;
Vec2D m_Position;
int m_PointerIndex;
// add more fields as needed
};
// add more fields as needed
};
} // namespace rive
#endif

View File

@@ -18,9 +18,7 @@ namespace rive {
Factory* m_Factory;
public:
RelativeLocalAssetResolver(std::string filename, Factory* factory)
: m_Factory(factory)
{
RelativeLocalAssetResolver(std::string filename, Factory* factory) : m_Factory(factory) {
std::size_t finalSlash = filename.rfind('/');
if (finalSlash != std::string::npos) {

View File

@@ -11,88 +11,88 @@
namespace rive {
using Unichar = int32_t;
using GlyphID = uint16_t;
using Unichar = int32_t;
using GlyphID = uint16_t;
struct RenderTextRun;
struct RenderGlyphRun;
struct RenderTextRun;
struct RenderGlyphRun;
class RenderFont : public RefCnt {
public:
struct LineMetrics {
float ascent,
descent;
class RenderFont : public RefCnt {
public:
struct LineMetrics {
float ascent, descent;
};
const LineMetrics& lineMetrics() const { return m_LineMetrics; }
// This is experimental
// -- may only be needed by Editor
// -- so it may be removed from here later
//
struct Axis {
uint32_t tag;
float min;
float def; // default value
float max;
};
// Returns the canonical set of Axes for this font. Use this to know
// what variations are possible. If you want to know the specific
// coordinate within that variations space for *this* font, call
// getCoords().
//
virtual std::vector<Axis> getAxes() const = 0;
struct Coord {
uint32_t axis;
float value;
};
// Returns the specific coords in variation space for this font.
// If you want to have a description of the entire variation space,
// call getAxes().
//
virtual std::vector<Coord> getCoords() const = 0;
virtual rcp<RenderFont> makeAtCoords(Span<const Coord>) const = 0;
rcp<RenderFont> makeAtCoord(Coord c) {
return this->makeAtCoords(Span<const Coord>(&c, 1));
}
// Returns a 1-point path for this glyph. It will be positioned
// relative to (0,0) with the typographic baseline at y = 0.
//
virtual RawPath getPath(GlyphID) const = 0;
std::vector<RenderGlyphRun> shapeText(rive::Span<const rive::Unichar> text,
rive::Span<const rive::RenderTextRun> runs) const;
protected:
RenderFont(const LineMetrics& lm) : m_LineMetrics(lm) {}
virtual std::vector<RenderGlyphRun>
onShapeText(rive::Span<const rive::Unichar> text,
rive::Span<const rive::RenderTextRun> runs) const = 0;
private:
const LineMetrics m_LineMetrics;
};
const LineMetrics& lineMetrics() const { return m_LineMetrics; }
// This is experimental
// -- may only be needed by Editor
// -- so it may be removed from here later
//
struct Axis {
uint32_t tag;
float min;
float def; // default value
float max;
struct RenderTextRun {
rcp<RenderFont> font;
float size;
uint32_t unicharCount;
};
// Returns the canonical set of Axes for this font. Use this to know
// what variations are possible. If you want to know the specific
// coordinate within that variations space for *this* font, call
// getCoords().
//
virtual std::vector<Axis> getAxes() const = 0;
struct RenderGlyphRun {
rcp<RenderFont> font;
float size;
struct Coord {
uint32_t axis;
float value;
std::vector<GlyphID> glyphs; // [#glyphs]
std::vector<uint32_t> textOffsets; // [#glyphs]
std::vector<float> xpos; // [#glyphs + 1]
};
// Returns the specific coords in variation space for this font.
// If you want to have a description of the entire variation space,
// call getAxes().
//
virtual std::vector<Coord> getCoords() const = 0;
virtual rcp<RenderFont> makeAtCoords(Span<const Coord>) const = 0;
rcp<RenderFont> makeAtCoord(Coord c) {
return this->makeAtCoords(Span<const Coord>(&c, 1));
}
// Returns a 1-point path for this glyph. It will be positioned
// relative to (0,0) with the typographic baseline at y = 0.
//
virtual RawPath getPath(GlyphID) const = 0;
std::vector<RenderGlyphRun> shapeText(rive::Span<const rive::Unichar> text,
rive::Span<const rive::RenderTextRun> runs) const;
protected:
RenderFont(const LineMetrics& lm) : m_LineMetrics(lm) {}
virtual std::vector<RenderGlyphRun> onShapeText(rive::Span<const rive::Unichar> text,
rive::Span<const rive::RenderTextRun> runs) const = 0;
private:
const LineMetrics m_LineMetrics;
};
struct RenderTextRun {
rcp<RenderFont> font;
float size;
uint32_t unicharCount;
};
struct RenderGlyphRun {
rcp<RenderFont> font;
float size;
std::vector<GlyphID> glyphs; // [#glyphs]
std::vector<uint32_t> textOffsets; // [#glyphs]
std::vector<float> xpos; // [#glyphs + 1]
};
} // namespace rive
#endif

View File

@@ -64,7 +64,7 @@ namespace rive {
public:
RenderPaint();
virtual ~RenderPaint();
virtual void style(RenderPaintStyle style) = 0;
virtual void color(ColorInt value) = 0;
virtual void thickness(float value) = 0;

View File

@@ -9,32 +9,32 @@
namespace rive {
struct Counter {
enum Type {
kFile,
kArtboardInstance,
kLinearAnimationInstance,
kStateMachineInstance,
struct Counter {
enum Type {
kFile,
kArtboardInstance,
kLinearAnimationInstance,
kStateMachineInstance,
kBuffer,
kPath,
kPaint,
kShader,
kImage,
kBuffer,
kPath,
kPaint,
kShader,
kImage,
kLastType = kImage,
kLastType = kImage,
};
static constexpr int kNumTypes = Type::kLastType + 1;
static int counts[kNumTypes];
static void update(Type ct, int delta) {
assert(delta == 1 || delta == -1);
counts[ct] += delta;
assert(counts[ct] >= 0);
}
};
static constexpr int kNumTypes = Type::kLastType + 1;
static int counts[kNumTypes];
static void update(Type ct, int delta) {
assert(delta == 1 || delta == -1);
counts[ct] += delta;
assert(counts[ct] >= 0);
}
};
} // namespace rive
#endif

View File

@@ -36,14 +36,14 @@
#ifdef __APPLE__
#define RIVE_BUILD_FOR_APPLE
#include <TargetConditionals.h>
#define RIVE_BUILD_FOR_APPLE
#include <TargetConditionals.h>
#if TARGET_OS_IPHONE
#define RIVE_BUILD_FOR_IOS
#elif TARGET_OS_MAC
#define RIVE_BUILD_FOR_OSX
#endif
#if TARGET_OS_IPHONE
#define RIVE_BUILD_FOR_IOS
#elif TARGET_OS_MAC
#define RIVE_BUILD_FOR_OSX
#endif
#endif

View File

@@ -15,7 +15,7 @@ namespace rive {
class SMINumber;
class SMITrigger;
class Scene {
class Scene {
protected:
ArtboardInstance* m_ArtboardInstance;
@@ -23,7 +23,7 @@ namespace rive {
public:
virtual ~Scene() {}
Scene(Scene const& lhs) : m_ArtboardInstance(lhs.m_ArtboardInstance) {}
float width() const;
@@ -38,7 +38,7 @@ namespace rive {
virtual bool isTranslucent() const = 0;
// returns -1 for continuous
virtual float durationSeconds() const = 0;
// returns true if draw() should be called
virtual bool advanceAndApply(float elapsedSeconds) = 0;

View File

@@ -31,7 +31,7 @@ namespace rive {
virtual void draw(Renderer* renderer, CommandPath* path) = 0;
RenderPaint* renderPaint() { return m_RenderPaint.get(); }
/// Get the component that represents the ShapePaintMutator for this
/// ShapePaint. It'll be one of SolidColor, LinearGradient, or
/// RadialGradient.

View File

@@ -18,7 +18,7 @@ namespace rive {
// Need this to access our artboard. We are treated as a mixin, either
// as a Shape or Artboard, so both of those will override this.
virtual Artboard* getArtboard() = 0;
PathSpace m_DefaultPathSpace = PathSpace::Neither;
std::vector<ShapePaint*> m_ShapePaints;
void addPaint(ShapePaint* paint);

View File

@@ -55,9 +55,7 @@ public:
printf("%c\n", c);
}
void add(const char key[], int value) {
this->add(key, std::to_string(value).c_str());
}
void add(const char key[], int value) { this->add(key, std::to_string(value).c_str()); }
};
//////////////////////////////////////////////////

View File

@@ -8,10 +8,9 @@
#include "skia_factory.hpp"
namespace rive {
struct CGSkiaFactory : public SkiaFactory {
std::vector<uint8_t> platformDecode(Span<const uint8_t>,
SkiaFactory::ImageInfo*) override;
};
} // namespace
struct CGSkiaFactory : public SkiaFactory {
std::vector<uint8_t> platformDecode(Span<const uint8_t>, SkiaFactory::ImageInfo*) override;
};
} // namespace rive
#endif // _RIVE_CGSkiaFactory_HPP_

View File

@@ -9,40 +9,38 @@
namespace rive {
struct RenderGlyphLine {
int startRun;
int startIndex;
int endRun;
int endIndex;
int wsRun;
int wsIndex;
float startX;
float top = 0, baseline = 0, bottom = 0;
struct RenderGlyphLine {
int startRun;
int startIndex;
int endRun;
int endIndex;
int wsRun;
int wsIndex;
float startX;
float top = 0, baseline = 0, bottom = 0;
RenderGlyphLine(int startRun,
int startIndex,
int endRun,
int endIndex,
int wsRun,
int wsIndex,
float startX) :
startRun(startRun),
startIndex(startIndex),
endRun(endRun),
endIndex(endIndex),
wsRun(wsRun),
wsIndex(wsIndex),
startX(startX)
{}
RenderGlyphLine(int startRun,
int startIndex,
int endRun,
int endIndex,
int wsRun,
int wsIndex,
float startX) :
startRun(startRun),
startIndex(startIndex),
endRun(endRun),
endIndex(endIndex),
wsRun(wsRun),
wsIndex(wsIndex),
startX(startX) {}
static std::vector<RenderGlyphLine> BreakLines(Span<const RenderGlyphRun> runs,
Span<const int> breaks,
float width);
// Compute vaues for top/baseline/bottom per line
static void ComputeLineSpacing(rive::Span<RenderGlyphLine>,
rive::Span<const RenderGlyphRun>);
};
static std::vector<RenderGlyphLine>
BreakLines(Span<const RenderGlyphRun> runs, Span<const int> breaks, float width);
// Compute vaues for top/baseline/bottom per line
static void ComputeLineSpacing(rive::Span<RenderGlyphLine>,
rive::Span<const RenderGlyphRun>);
};
} // namespace
} // namespace rive
#endif

View File

@@ -5,9 +5,9 @@
#include <string>
#if defined(RIVE_BUILD_FOR_OSX)
#include <ApplicationServices/ApplicationServices.h>
#include <ApplicationServices/ApplicationServices.h>
#elif defined(RIVE_BUILD_FOR_IOS)
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CoreFoundation.h>
#endif
template <size_t N, typename T> class AutoSTArray {
@@ -44,16 +44,20 @@ static inline std::string tag2str(uint32_t tag) {
std::string str = "abcd";
str[0] = (tag >> 24) & 0xFF;
str[1] = (tag >> 16) & 0xFF;
str[2] = (tag >> 8) & 0xFF;
str[3] = (tag >> 0) & 0xFF;
str[2] = (tag >> 8) & 0xFF;
str[3] = (tag >> 0) & 0xFF;
return str;
}
template <typename T> class AutoCF {
T m_Obj;
public:
AutoCF(T obj) : m_Obj(obj) {}
~AutoCF() { if (m_Obj) CFRelease(m_Obj); }
~AutoCF() {
if (m_Obj)
CFRelease(m_Obj);
}
operator T() const { return m_Obj; }
operator bool() const { return m_Obj != nullptr; }

View File

@@ -46,8 +46,8 @@ static inline std::string tag2str(uint32_t tag) {
std::string str = "abcd";
str[0] = (tag >> 24) & 0xFF;
str[1] = (tag >> 16) & 0xFF;
str[2] = (tag >> 8) & 0xFF;
str[3] = (tag >> 0) & 0xFF;
str[2] = (tag >> 8) & 0xFF;
str[3] = (tag >> 0) & 0xFF;
return str;
}

View File

@@ -9,9 +9,9 @@
#include "rive/render_text.hpp"
#if defined(RIVE_BUILD_FOR_OSX)
#include <ApplicationServices/ApplicationServices.h>
#include <ApplicationServices/ApplicationServices.h>
#elif defined(RIVE_BUILD_FOR_IOS)
#include <CoreText/CoreText.h>
#include <CoreText/CoreText.h>
#endif
class CoreTextRenderFont : public rive::RenderFont {
@@ -28,8 +28,9 @@ public:
std::vector<Coord> getCoords() const override { return m_coords; }
rive::rcp<rive::RenderFont> makeAtCoords(rive::Span<const Coord>) const override;
rive::RawPath getPath(rive::GlyphID) const override;
std::vector<rive::RenderGlyphRun> onShapeText(rive::Span<const rive::Unichar>,
rive::Span<const rive::RenderTextRun>) const override;
std::vector<rive::RenderGlyphRun>
onShapeText(rive::Span<const rive::Unichar>,
rive::Span<const rive::RenderTextRun>) const override;
static rive::rcp<rive::RenderFont> Decode(rive::Span<const uint8_t>);
};

View File

@@ -25,8 +25,9 @@ public:
std::vector<Coord> getCoords() const override;
rive::rcp<rive::RenderFont> makeAtCoords(rive::Span<const Coord>) const override;
rive::RawPath getPath(rive::GlyphID) const override;
std::vector<rive::RenderGlyphRun> onShapeText(rive::Span<const rive::Unichar>,
rive::Span<const rive::RenderTextRun>) const override;
std::vector<rive::RenderGlyphRun>
onShapeText(rive::Span<const rive::Unichar>,
rive::Span<const rive::RenderTextRun>) const override;
static rive::rcp<rive::RenderFont> Decode(rive::Span<const uint8_t>);
};

View File

@@ -18,8 +18,9 @@ public:
std::vector<Coord> getCoords() const override;
rive::rcp<rive::RenderFont> makeAtCoords(rive::Span<const Coord>) const override;
rive::RawPath getPath(rive::GlyphID) const override;
std::vector<rive::RenderGlyphRun> onShapeText(rive::Span<const rive::Unichar>,
rive::Span<const rive::RenderTextRun>) const override;
std::vector<rive::RenderGlyphRun>
onShapeText(rive::Span<const rive::Unichar>,
rive::Span<const rive::RenderTextRun>) const override;
static rive::rcp<rive::RenderFont> Decode(rive::Span<const uint8_t>);
};

View File

@@ -10,64 +10,67 @@
namespace rive {
class SkiaFactory : public Factory {
public:
rcp<RenderBuffer> makeBufferU16(Span<const uint16_t>) override;
rcp<RenderBuffer> makeBufferU32(Span<const uint32_t>) override;
rcp<RenderBuffer> makeBufferF32(Span<const float>) override;
class SkiaFactory : public Factory {
public:
rcp<RenderBuffer> makeBufferU16(Span<const uint16_t>) override;
rcp<RenderBuffer> makeBufferU32(Span<const uint32_t>) override;
rcp<RenderBuffer> makeBufferF32(Span<const float>) override;
rcp<RenderShader> makeLinearGradient(float sx, float sy,
float ex, float ey,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode,
const Mat2D* localMatrix = nullptr) override;
rcp<RenderShader> makeLinearGradient(float sx,
float sy,
float ex,
float ey,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode,
const Mat2D* localMatrix = nullptr) override;
rcp<RenderShader> makeRadialGradient(float cx, float cy, float radius,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode,
const Mat2D* localMatrix = nullptr) override;
rcp<RenderShader> makeRadialGradient(float cx,
float cy,
float radius,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode,
const Mat2D* localMatrix = nullptr) override;
std::unique_ptr<RenderPath> makeRenderPath(Span<const Vec2D> points,
Span<const uint8_t> verbs,
FillRule) override;
std::unique_ptr<RenderPath>
makeRenderPath(Span<const Vec2D> points, Span<const uint8_t> verbs, FillRule) override;
std::unique_ptr<RenderPath> makeEmptyRenderPath() override;
std::unique_ptr<RenderPath> makeEmptyRenderPath() override;
std::unique_ptr<RenderPaint> makeRenderPaint() override;
std::unique_ptr<RenderPaint> makeRenderPaint() override;
std::unique_ptr<RenderImage> decodeImage(Span<const uint8_t>) override;
std::unique_ptr<RenderImage> decodeImage(Span<const uint8_t>) override;
//
// New virtual for access the platform's codecs
//
//
// New virtual for access the platform's codecs
//
enum class ColorType {
rgba,
bgra,
enum class ColorType {
rgba,
bgra,
};
enum class AlphaType {
premul,
opaque,
};
struct ImageInfo {
size_t rowBytes; // number of bytes between rows
uint32_t width; // logical width in pixels
uint32_t height; // logical height in pixels
ColorType colorType;
AlphaType alphaType;
};
// Clients can override this to provide access to the platform's decoders, rather
// than solely relying on the codecs built into Skia. This allows for the Skia impl
// to not have to duplicate the code for codecs that the platform may already have.
virtual std::vector<uint8_t> platformDecode(Span<const uint8_t>, ImageInfo* info) {
return std::vector<uint8_t>(); // empty vector means decode failed
}
};
enum class AlphaType {
premul,
opaque,
};
struct ImageInfo {
size_t rowBytes; // number of bytes between rows
uint32_t width; // logical width in pixels
uint32_t height; // logical height in pixels
ColorType colorType;
AlphaType alphaType;
};
// Clients can override this to provide access to the platform's decoders, rather
// than solely relying on the codecs built into Skia. This allows for the Skia impl
// to not have to duplicate the code for codecs that the platform may already have.
virtual std::vector<uint8_t> platformDecode(Span<const uint8_t>, ImageInfo* info) {
return std::vector<uint8_t>(); // empty vector means decode failed
}
};
} // namespace rive
#endif

View File

@@ -26,9 +26,7 @@ namespace rive {
return SkMatrix::MakeAll(m[0], m[2], m[4], m[1], m[3], m[5], 0, 0, 1);
}
static SkPoint convert(rive::Vec2D point) {
return SkPoint::Make(point.x, point.y);
}
static SkPoint convert(rive::Vec2D point) { return SkPoint::Make(point.x, point.y); }
// clang-format off
static SkTileMode convert(RenderTileMode rtm) {

View File

@@ -11,10 +11,10 @@
#include "mac_utils.hpp"
#if defined(RIVE_BUILD_FOR_OSX)
#include <ApplicationServices/ApplicationServices.h>
#include <ApplicationServices/ApplicationServices.h>
#elif defined(RIVE_BUILD_FOR_IOS)
#include <CoreGraphics/CoreGraphics.h>
#include <ImageIO/ImageIO.h>
#include <CoreGraphics/CoreGraphics.h>
#include <ImageIO/ImageIO.h>
#endif
using namespace rive;
@@ -52,7 +52,7 @@ std::vector<uint8_t> CGSkiaFactory::platformDecode(Span<const uint8_t> span,
// Now create a drawing context to produce RGBA pixels
const size_t bitsPerComponent = 8;
CGBitmapInfo cgInfo = kCGBitmapByteOrder32Big; // rgba
CGBitmapInfo cgInfo = kCGBitmapByteOrder32Big; // rgba
if (isOpaque) {
cgInfo |= kCGImageAlphaNoneSkipLast;
} else {
@@ -60,13 +60,14 @@ std::vector<uint8_t> CGSkiaFactory::platformDecode(Span<const uint8_t> span,
}
const size_t width = CGImageGetWidth(image);
const size_t height = CGImageGetHeight(image);
const size_t rowBytes = width * 4; // 4 bytes per pixel
const size_t rowBytes = width * 4; // 4 bytes per pixel
const size_t size = rowBytes * height;
pixels.resize(size);
AutoCF cs = CGColorSpaceCreateDeviceRGB();
AutoCF cg = CGBitmapContextCreate(pixels.data(), width, height, bitsPerComponent, rowBytes, cs, cgInfo);
AutoCF cg =
CGBitmapContextCreate(pixels.data(), width, height, bitsPerComponent, rowBytes, cs, cgInfo);
if (!cg) {
pixels.clear();
return pixels;
@@ -83,4 +84,4 @@ std::vector<uint8_t> CGSkiaFactory::platformDecode(Span<const uint8_t> span,
return pixels;
};
#endif // RIVE_BUILD_FOR_APPLE
#endif // RIVE_BUILD_FOR_APPLE

View File

@@ -19,21 +19,20 @@ static int _offsetToRunIndex(Span<const RenderGlyphRun> runs, size_t textOffset)
static int textOffsetToGlyphIndex(const RenderGlyphRun& run, size_t textOffset) {
assert(textOffset >= run.textOffsets.front());
// assert(textOffset <= run.textOffsets.back()); // not true for last run
// assert(textOffset <= run.textOffsets.back()); // not true for last run
// todo: bsearch?
auto begin = run.textOffsets.begin();
auto end = run.textOffsets.end();
auto iter = std::find(begin, end, textOffset);
if (iter == end) { // end of run
return run.glyphs.size() - 1;
if (iter == end) { // end of run
return run.glyphs.size() - 1;
}
return iter - begin;
}
std::vector<RenderGlyphLine> RenderGlyphLine::BreakLines(Span<const RenderGlyphRun> runs,
Span<const int> breaks,
float width) {
std::vector<RenderGlyphLine>
RenderGlyphLine::BreakLines(Span<const RenderGlyphRun> runs, Span<const int> breaks, float width) {
assert(breaks.size() >= 2);
std::vector<RenderGlyphLine> lines;
@@ -50,99 +49,96 @@ std::vector<RenderGlyphLine> RenderGlyphLine::BreakLines(Span<const RenderGlyphR
int lineStartTextOffset = wordStart;
for (;;) {
assert(wordStart <= wordEnd); // == means trailing spaces?
assert(wordStart <= wordEnd); // == means trailing spaces?
int endRun = _offsetToRunIndex(runs, wordEnd);
int endIndex = textOffsetToGlyphIndex(runs[endRun], wordEnd);
float pos = runs[endRun].xpos[endIndex];
bool bumpBreakIndex = true;
if (pos > xlimit) {
int wsRun = _offsetToRunIndex(runs, wordStart);
int wsIndex = textOffsetToGlyphIndex(runs[wsRun], wordStart);
int endRun = _offsetToRunIndex(runs, wordEnd);
int endIndex = textOffsetToGlyphIndex(runs[endRun], wordEnd);
float pos = runs[endRun].xpos[endIndex];
bool bumpBreakIndex = true;
if (pos > xlimit) {
int wsRun = _offsetToRunIndex(runs, wordStart);
int wsIndex = textOffsetToGlyphIndex(runs[wsRun], wordStart);
bumpBreakIndex = false;
// does just one word not fit?
if (lineStartTextOffset == wordStart) {
// walk backwards a letter at a time until we fit, stopping at
// 1 letter.
int wend = wordEnd;
while (pos > xlimit && wend - 1 > wordStart) {
wend -= 1;
prevRun = _offsetToRunIndex(runs, wend);
prevIndex = textOffsetToGlyphIndex(runs[prevRun], wend);
pos = runs[prevRun].xpos[prevIndex];
}
assert(wend < wordEnd || wend == wordEnd && wordStart + 1 == wordEnd);
if (wend == wordEnd) {
bumpBreakIndex = true;
}
bumpBreakIndex = false;
// does just one word not fit?
if (lineStartTextOffset == wordStart) {
// walk backwards a letter at a time until we fit, stopping at
// 1 letter.
int wend = wordEnd;
while (pos > xlimit && wend - 1 > wordStart) {
wend -= 1;
prevRun = _offsetToRunIndex(runs, wend);
prevIndex = textOffsetToGlyphIndex(runs[prevRun], wend);
pos = runs[prevRun].xpos[prevIndex];
}
assert(wend < wordEnd || wend == wordEnd && wordStart + 1 == wordEnd);
if (wend == wordEnd) {
bumpBreakIndex = true;
}
// now reset our "whitespace" marker to just be prev, since
// by defintion we have no extra whitespace on this line
wsRun = prevRun;
wsIndex = prevIndex;
wordStart = wend;
}
// now reset our "whitespace" marker to just be prev, since
// by defintion we have no extra whitespace on this line
wsRun = prevRun;
wsIndex = prevIndex;
wordStart = wend;
}
// bulid the line
const auto lineStartX = runs[startRun].xpos[startIndex];
lines.push_back(RenderGlyphLine(
startRun, startIndex, prevRun, prevIndex, wsRun, wsIndex, lineStartX
));
// bulid the line
const auto lineStartX = runs[startRun].xpos[startIndex];
lines.push_back(RenderGlyphLine(
startRun, startIndex, prevRun, prevIndex, wsRun, wsIndex, lineStartX));
// update for the next line
xlimit = runs[wsRun].xpos[wsIndex] + width;
startRun = prevRun = wsRun;
startIndex = prevIndex = wsIndex;
lineStartTextOffset = wordStart;
} else {
// we didn't go too far, so remember this word-end boundary
prevRun = endRun;
prevIndex = endIndex;
}
if (bumpBreakIndex) {
if (nextBreakIndex < breaks.size()) {
wordStart = breaks[nextBreakIndex++];
wordEnd = breaks[nextBreakIndex++];
// update for the next line
xlimit = runs[wsRun].xpos[wsIndex] + width;
startRun = prevRun = wsRun;
startIndex = prevIndex = wsIndex;
lineStartTextOffset = wordStart;
} else {
break; // bust out of the loop
// we didn't go too far, so remember this word-end boundary
prevRun = endRun;
prevIndex = endIndex;
}
if (bumpBreakIndex) {
if (nextBreakIndex < breaks.size()) {
wordStart = breaks[nextBreakIndex++];
wordEnd = breaks[nextBreakIndex++];
} else {
break; // bust out of the loop
}
}
}
}
// scoop up the last line (if present)
const int tailRun = runs.size() - 1;
const int tailIndex = runs[tailRun].glyphs.size();
if (startRun != tailRun || startIndex != tailIndex) {
const auto startX = runs[startRun].xpos[startIndex];
lines.push_back(RenderGlyphLine(
startRun, startIndex, tailRun, tailIndex, tailRun, tailIndex, startX
));
const auto startX = runs[startRun].xpos[startIndex];
lines.push_back(
RenderGlyphLine(startRun, startIndex, tailRun, tailIndex, tailRun, tailIndex, startX));
}
ComputeLineSpacing(toSpan(lines), runs);
return lines;
}
}
void RenderGlyphLine::ComputeLineSpacing(Span<RenderGlyphLine> lines,
Span<const RenderGlyphRun> runs) {
float Y = 0; // top of our frame
float Y = 0; // top of our frame
for (auto& line : lines) {
float asc = 0;
float des = 0;
for (int i = line.startRun; i <= line.wsRun; ++i) {
const auto& run = runs[i];
float asc = 0;
float des = 0;
for (int i = line.startRun; i <= line.wsRun; ++i) {
const auto& run = runs[i];
asc = std::min(asc, run.font->lineMetrics().ascent * run.size);
des = std::max(des, run.font->lineMetrics().descent * run.size);
}
line.top = Y;
Y -= asc;
line.baseline = Y;
Y += des;
line.bottom = Y;
asc = std::min(asc, run.font->lineMetrics().ascent * run.size);
des = std::max(des, run.font->lineMetrics().descent * run.size);
}
line.top = Y;
Y -= asc;
line.baseline = Y;
Y += des;
line.bottom = Y;
}
// TODO: good place to perform left/center/right alignment
}

View File

@@ -12,12 +12,12 @@
#ifdef RIVE_BUILD_FOR_APPLE
#if defined(RIVE_BUILD_FOR_OSX)
#include <ApplicationServices/ApplicationServices.h>
#include <ApplicationServices/ApplicationServices.h>
#elif defined(RIVE_BUILD_FOR_IOS)
#include <CoreText/CoreText.h>
#include <CoreText/CTFontManager.h>
#include <CoreGraphics/CoreGraphics.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreText/CoreText.h>
#include <CoreText/CTFontManager.h>
#include <CoreGraphics/CoreGraphics.h>
#include <CoreFoundation/CoreFoundation.h>
#endif
constexpr int kStdScale = 2048;
@@ -37,7 +37,7 @@ static std::vector<rive::RenderFont::Axis> compute_axes(CTFontRef font) {
auto min = find_float(axis, kCTFontVariationAxisMinimumValueKey);
auto def = find_float(axis, kCTFontVariationAxisDefaultValueKey);
auto max = find_float(axis, kCTFontVariationAxisMaximumValueKey);
// printf("%08X %g %g %g\n", tag, min, def, max);
// printf("%08X %g %g %g\n", tag, min, def, max);
axes.push_back({tag, min, def, max});
}
@@ -60,7 +60,7 @@ static std::vector<rive::RenderFont::Coord> compute_coords(CTFontRef font) {
for (int i = 0; i < count; ++i) {
uint32_t tag = number_as_u32((CFNumberRef)keys[i]);
float value = number_as_float((CFNumberRef)values[i]);
// printf("[%d] %08X %s %g\n", i, tag, tag2str(tag).c_str(), value);
// printf("[%d] %08X %s %g\n", i, tag, tag2str(tag).c_str(), value);
coords[i] = {tag, value};
}
}
@@ -69,7 +69,7 @@ static std::vector<rive::RenderFont::Coord> compute_coords(CTFontRef font) {
}
rive::rcp<rive::RenderFont> CoreTextRenderFont::Decode(rive::Span<const uint8_t> span) {
AutoCF data = CFDataCreate(nullptr, span.data(), span.size()); // makes a copy
AutoCF data = CFDataCreate(nullptr, span.data(), span.size()); // makes a copy
if (!data) {
assert(false);
return nullptr;
@@ -111,26 +111,23 @@ rive::rcp<rive::RenderFont> CoreTextRenderFont::Decode(rive::Span<const uint8_t>
static rive::RenderFont::LineMetrics make_lmx(CTFontRef font) {
return {
(float) -CTFontGetAscent(font) * gInvScale,
(float) CTFontGetDescent(font) * gInvScale,
(float)-CTFontGetAscent(font) * gInvScale,
(float)CTFontGetDescent(font) * gInvScale,
};
}
CoreTextRenderFont::CoreTextRenderFont(CTFontRef font,
std::vector<rive::RenderFont::Axis> axes) :
CoreTextRenderFont::CoreTextRenderFont(CTFontRef font, std::vector<rive::RenderFont::Axis> axes) :
rive::RenderFont(make_lmx(font)),
m_font(font), // we take ownership of font
m_font(font), // we take ownership of font
m_axes(std::move(axes)),
m_coords(compute_coords(font))
{}
m_coords(compute_coords(font)) {}
CoreTextRenderFont::~CoreTextRenderFont() {
CFRelease(m_font);
}
CoreTextRenderFont::~CoreTextRenderFont() { CFRelease(m_font); }
rive::rcp<rive::RenderFont> CoreTextRenderFont::makeAtCoords(rive::Span<const Coord> coords) const {
AutoCF vars = CFDictionaryCreateMutable(kCFAllocatorDefault, coords.size(),
&kCFTypeDictionaryKeyCallBacks,
AutoCF vars = CFDictionaryCreateMutable(kCFAllocatorDefault,
coords.size(),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
for (const auto& c : coords) {
AutoCF tagNum = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &c.axis);
@@ -138,11 +135,10 @@ rive::rcp<rive::RenderFont> CoreTextRenderFont::makeAtCoords(rive::Span<const Co
CFDictionaryAddValue(vars.get(), tagNum.get(), valueNum.get());
}
AutoCF attrs = CFDictionaryCreateMutable(kCFAllocatorDefault, 1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
AutoCF attrs = CFDictionaryCreateMutable(
kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(attrs.get(), kCTFontVariationAttribute, vars.get());
AutoCF desc = (CTFontDescriptorRef)CTFontDescriptorCreateWithAttributes(attrs.get());
auto font = CTFontCreateCopyWithAttributes(m_font, 0, nullptr, desc.get());
@@ -150,7 +146,7 @@ rive::rcp<rive::RenderFont> CoreTextRenderFont::makeAtCoords(rive::Span<const Co
return rive::rcp<rive::RenderFont>(new CoreTextRenderFont(font, compute_axes(font)));
}
static void apply_element(void *ctx, const CGPathElement *element) {
static void apply_element(void* ctx, const CGPathElement* element) {
auto path = (rive::RawPath*)ctx;
const CGPoint* points = element->points;
@@ -164,14 +160,12 @@ static void apply_element(void *ctx, const CGPathElement *element) {
break;
case kCGPathElementAddQuadCurveToPoint:
path->quadTo(points[0].x, points[0].y,
points[1].x, points[1].y);
path->quadTo(points[0].x, points[0].y, points[1].x, points[1].y);
break;
case kCGPathElementAddCurveToPoint:
path->cubicTo(points[0].x, points[0].y,
points[1].x, points[1].y,
points[2].x, points[2].y);
path->cubicTo(
points[0].x, points[0].y, points[1].x, points[1].y, points[2].x, points[2].y);
break;
case kCGPathElementCloseSubpath:
@@ -209,8 +203,8 @@ struct AutoUTF16 {
}
};
static float add_run(rive::RenderGlyphRun* gr, CTRunRef run,
uint32_t textStart, float textSize, float startX) {
static float
add_run(rive::RenderGlyphRun* gr, CTRunRef run, uint32_t textStart, float textSize, float startX) {
if (auto count = CTRunGetGlyphCount(run)) {
const float scale = textSize * gInvScale;
@@ -250,12 +244,13 @@ CoreTextRenderFont::onShapeText(rive::Span<const rive::Unichar> text,
CTFontRef font = ((CoreTextRenderFont*)tr.font.get())->m_font;
AutoUTF16 utf16(&text[unicharIndex], tr.unicharCount);
AutoCF string = CFStringCreateWithCharactersNoCopy(nullptr, utf16.array.data(),
tr.unicharCount, kCFAllocatorNull);
AutoCF string = CFStringCreateWithCharactersNoCopy(
nullptr, utf16.array.data(), tr.unicharCount, kCFAllocatorNull);
AutoCF attr = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
AutoCF attr = CFDictionaryCreateMutable(kCFAllocatorDefault,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(attr.get(), kCTFontAttributeName, font);
AutoCF attrString = CFAttributedStringCreate(kCFAllocatorDefault, string.get(), attr.get());
@@ -268,8 +263,11 @@ CoreTextRenderFont::onShapeText(rive::Span<const rive::Unichar> text,
CFIndex runCount = CFArrayGetCount(run_array);
for (CFIndex i = 0; i < runCount; ++i) {
rive::RenderGlyphRun grun;
startX = add_run(&grun, (CTRunRef)CFArrayGetValueAtIndex(run_array, i),
unicharIndex, tr.size, startX);
startX = add_run(&grun,
(CTRunRef)CFArrayGetValueAtIndex(run_array, i),
unicharIndex,
tr.size,
startX);
if (grun.glyphs.size() > 0) {
grun.font = tr.font;
grun.size = tr.size;

View File

@@ -12,10 +12,13 @@
#include "hb-ot.h"
rive::rcp<rive::RenderFont> HBRenderFont::Decode(rive::Span<const uint8_t> span) {
auto blob = hb_blob_create_or_fail((const char*)span.data(), (unsigned)span.size(),
HB_MEMORY_MODE_DUPLICATE, nullptr, nullptr);
auto blob = hb_blob_create_or_fail((const char*)span.data(),
(unsigned)span.size(),
HB_MEMORY_MODE_DUPLICATE,
nullptr,
nullptr);
if (blob) {
auto face = hb_face_create(blob, 0);
auto face = hb_face_create(blob, 0);
hb_blob_destroy(blob);
if (face) {
auto font = hb_font_create(face);
@@ -40,15 +43,34 @@ void rpath_move_to(hb_draw_funcs_t*, void* rpath, hb_draw_state_t*, float x, flo
void rpath_line_to(hb_draw_funcs_t*, void* rpath, hb_draw_state_t*, float x1, float y1, void*) {
((rive::RawPath*)rpath)->lineTo(x1 * gInvScale, -y1 * gInvScale);
}
void rpath_quad_to(hb_draw_funcs_t*, void* rpath, hb_draw_state_t*, float x1, float y1, float x2, float y2, void*) {
((rive::RawPath*)rpath)->quadTo(x1 * gInvScale, -y1 * gInvScale,
x2 * gInvScale, -y2 * gInvScale);
void rpath_quad_to(hb_draw_funcs_t*,
void* rpath,
hb_draw_state_t*,
float x1,
float y1,
float x2,
float y2,
void*) {
((rive::RawPath*)rpath)
->quadTo(x1 * gInvScale, -y1 * gInvScale, x2 * gInvScale, -y2 * gInvScale);
}
void rpath_cubic_to(hb_draw_funcs_t*, void* rpath, hb_draw_state_t*,
float x1, float y1, float x2, float y2, float x3, float y3, void*) {
((rive::RawPath*)rpath)->cubicTo(x1 * gInvScale, -y1 * gInvScale,
x2 * gInvScale, -y2 * gInvScale,
x3 * gInvScale, -y3 * gInvScale);
void rpath_cubic_to(hb_draw_funcs_t*,
void* rpath,
hb_draw_state_t*,
float x1,
float y1,
float x2,
float y2,
float x3,
float y3,
void*) {
((rive::RawPath*)rpath)
->cubicTo(x1 * gInvScale,
-y1 * gInvScale,
x2 * gInvScale,
-y2 * gInvScale,
x3 * gInvScale,
-y3 * gInvScale);
}
void rpath_close(hb_draw_funcs_t*, void* rpath, hb_draw_state_t*, void*) {
((rive::RawPath*)rpath)->close();
@@ -67,7 +89,7 @@ static rive::RenderFont::LineMetrics make_lmx(hb_font_t* font) {
HBRenderFont::HBRenderFont(hb_font_t* font) :
RenderFont(make_lmx(font)),
m_Font(font) // we just take ownership, no need to call reference()
m_Font(font) // we just take ownership, no need to call reference()
{
m_DrawFuncs = hb_draw_funcs_create();
hb_draw_funcs_set_move_to_func(m_DrawFuncs, rpath_move_to, nullptr, nullptr);
@@ -96,8 +118,9 @@ std::vector<rive::RenderFont::Axis> HBRenderFont::getAxes() const {
unsigned n = 1;
hb_ot_var_get_axis_infos(face, i, &n, &info);
assert(n == 1);
axes[i] = { info.tag, info.min_value, info.default_value, info.max_value };
// printf("[%d] %08X %g %g %g\n", i, info.tag, info.min_value, info.default_value, info.max_value);
axes[i] = {info.tag, info.min_value, info.default_value, info.max_value};
// printf("[%d] %08X %g %g %g\n", i, info.tag, info.min_value, info.default_value,
// info.max_value);
}
}
return axes;
@@ -105,14 +128,14 @@ std::vector<rive::RenderFont::Axis> HBRenderFont::getAxes() const {
std::vector<rive::RenderFont::Coord> HBRenderFont::getCoords() const {
auto axes = this->getAxes();
// const int count = (int)axes.size();
// const int count = (int)axes.size();
unsigned length;
const float* values = hb_font_get_var_coords_design(m_Font, &length);
std::vector<rive::RenderFont::Coord> coords(length);
for (unsigned i = 0; i < length; ++i) {
coords[i] = { axes[i].tag, values[i] };
coords[i] = {axes[i].tag, values[i]};
}
return coords;
}
@@ -144,28 +167,29 @@ HBRenderFont::onShapeText(rive::Span<const rive::Unichar> text,
/////////////////
const hb_feature_t features[] = {
{ 'liga', 1, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END },
{ 'dlig', 1, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END },
{ 'kern', 1, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END },
{'liga', 1, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END},
{'dlig', 1, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END},
{'kern', 1, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END},
};
constexpr int numFeatures = sizeof(features) / sizeof(features[0]);
uint32_t unicharIndex = 0;
rive::Vec2D origin = {0, 0};
for (const auto& tr : truns) {
hb_buffer_t *buf = hb_buffer_create();
hb_buffer_add_utf32(buf, (const uint32_t*)&text[unicharIndex], tr.unicharCount, 0, tr.unicharCount);
hb_buffer_t* buf = hb_buffer_create();
hb_buffer_add_utf32(
buf, (const uint32_t*)&text[unicharIndex], tr.unicharCount, 0, tr.unicharCount);
hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
hb_buffer_set_script(buf, HB_SCRIPT_LATIN);
hb_buffer_set_language(buf, hb_language_from_string("en", -1));
auto hbfont = (HBRenderFont*)tr.font.get();
hb_shape(hbfont->m_Font, buf, features, numFeatures);
unsigned int glyph_count;
hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(buf, &glyph_count);
hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count);
hb_glyph_info_t* glyph_info = hb_buffer_get_glyph_infos(buf, &glyph_count);
hb_glyph_position_t* glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count);
// todo: check for missing glyphs, and perform font-substitution
@@ -179,8 +203,8 @@ HBRenderFont::onShapeText(rive::Span<const rive::Unichar> text,
const float scale = tr.size / kStdScale;
for (unsigned int i = 0; i < glyph_count; i++) {
// hb_position_t x_offset = glyph_pos[i].x_offset;
// hb_position_t y_offset = glyph_pos[i].y_offset;
// hb_position_t x_offset = glyph_pos[i].x_offset;
// hb_position_t y_offset = glyph_pos[i].y_offset;
gr.glyphs[i] = (uint16_t)glyph_info[i].codepoint;
gr.textOffsets[i] = unicharIndex + glyph_info[i].cluster;

View File

@@ -27,13 +27,10 @@ static rive::RenderFont::LineMetrics make_lmx(sk_sp<SkTypeface> tf) {
}
SkiaRenderFont::SkiaRenderFont(sk_sp<SkTypeface> tf) :
RenderFont(make_lmx(tf)),
m_Typeface(std::move(tf))
{}
RenderFont(make_lmx(tf)), m_Typeface(std::move(tf)) {}
rive::rcp<rive::RenderFont> SkiaRenderFont::Decode(rive::Span<const uint8_t> span) {
auto tf = SkTypeface::MakeFromData(SkData::MakeWithCopy(span.data(),
span.size()));
auto tf = SkTypeface::MakeFromData(SkData::MakeWithCopy(span.data(), span.size()));
return tf ? rive::rcp<rive::RenderFont>(new SkiaRenderFont(std::move(tf))) : nullptr;
}
@@ -45,7 +42,7 @@ std::vector<rive::RenderFont::Axis> SkiaRenderFont::getAxes() const {
(void)m_Typeface->getVariationDesignParameters(src.data(), count);
axes.resize(count);
for (int i = 0; i < count; ++i) {
axes[i] = { src[i].tag, src[i].min, src[i].def, src[i].max };
axes[i] = {src[i].tag, src[i].min, src[i].def, src[i].max};
}
}
return axes;
@@ -58,7 +55,7 @@ std::vector<rive::RenderFont::Coord> SkiaRenderFont::getCoords() const {
std::vector<rive::RenderFont::Coord> coords(count);
for (int i = 0; i < count; ++i) {
coords[i] = { skcoord[i].axis, skcoord[i].value };
coords[i] = {skcoord[i].axis, skcoord[i].value};
}
return coords;
}
@@ -98,13 +95,27 @@ rive::RawPath SkiaRenderFont::getPath(rive::GlyphID glyph) const {
bool done = false;
while (!done) {
switch (iter.next(pts)) {
case SkPath::kMove_Verb: rpath.move (rv(pts[0])); break;
case SkPath::kLine_Verb: rpath.line (rv(pts[1])); break;
case SkPath::kQuad_Verb: rpath.quad (rv(pts[1]), rv(pts[2])); break;
case SkPath::kConic_Verb: rpath.quad (rv(pts[1]), rv(pts[2])); break; // TODO: convert
case SkPath::kCubic_Verb: rpath.cubic(rv(pts[1]), rv(pts[2]), rv(pts[3])); break;
case SkPath::kClose_Verb: rpath.close(); break;
case SkPath::kDone_Verb: done = true; break;
case SkPath::kMove_Verb:
rpath.move(rv(pts[0]));
break;
case SkPath::kLine_Verb:
rpath.line(rv(pts[1]));
break;
case SkPath::kQuad_Verb:
rpath.quad(rv(pts[1]), rv(pts[2]));
break;
case SkPath::kConic_Verb:
rpath.quad(rv(pts[1]), rv(pts[2]));
break; // TODO: convert
case SkPath::kCubic_Verb:
rpath.cubic(rv(pts[1]), rv(pts[2]), rv(pts[3]));
break;
case SkPath::kClose_Verb:
rpath.close();
break;
case SkPath::kDone_Verb:
done = true;
break;
}
}
return rpath;
@@ -112,9 +123,12 @@ rive::RawPath SkiaRenderFont::getPath(rive::GlyphID glyph) const {
///////////////////////////////////////////////////////////
static float shapeRun(rive::RenderGlyphRun* grun, const rive::RenderTextRun& trun,
const rive::Unichar text[], size_t textOffset, float origin) {
const int glyphCount = SkToInt(trun.unicharCount); // simple shaper, no ligatures
static float shapeRun(rive::RenderGlyphRun* grun,
const rive::RenderTextRun& trun,
const rive::Unichar text[],
size_t textOffset,
float origin) {
const int glyphCount = SkToInt(trun.unicharCount); // simple shaper, no ligatures
grun->font = trun.font;
grun->size = trun.size;

View File

@@ -256,17 +256,17 @@ rcp<RenderBuffer> SkiaFactory::makeBufferU32(Span<const uint32_t> data) {
return make_buffer(data);
}
rcp<RenderBuffer> SkiaFactory::makeBufferF32(Span<const float> data) {
return make_buffer(data);
}
rcp<RenderBuffer> SkiaFactory::makeBufferF32(Span<const float> data) { return make_buffer(data); }
rcp<RenderShader> SkiaFactory::makeLinearGradient(float sx, float sy,
float ex, float ey,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode mode,
const Mat2D* localMatrix) {
rcp<RenderShader> SkiaFactory::makeLinearGradient(float sx,
float sy,
float ex,
float ey,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode mode,
const Mat2D* localMatrix) {
const SkPoint pts[] = {{sx, sy}, {ex, ey}};
const SkMatrix lm = localMatrix ? ToSkia::convert(*localMatrix) : SkMatrix();
auto sh = SkGradientShader::MakeLinear(
@@ -274,12 +274,14 @@ rcp<RenderShader> SkiaFactory::makeLinearGradient(float sx, float sy,
return rcp<RenderShader>(new SkiaRenderShader(std::move(sh)));
}
rcp<RenderShader> SkiaFactory::makeRadialGradient(float cx, float cy, float radius,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode mode,
const Mat2D* localMatrix) {
rcp<RenderShader> SkiaFactory::makeRadialGradient(float cx,
float cy,
float radius,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode mode,
const Mat2D* localMatrix) {
const SkMatrix lm = localMatrix ? ToSkia::convert(*localMatrix) : SkMatrix();
auto sh = SkGradientShader::MakeRadial(
{cx, cy}, radius, (const SkColor*)colors, stops, count, ToSkia::convert(mode), 0, &lm);
@@ -289,17 +291,18 @@ rcp<RenderShader> SkiaFactory::makeRadialGradient(float cx, float cy, float radi
std::unique_ptr<RenderPath> SkiaFactory::makeRenderPath(Span<const Vec2D> points,
Span<const uint8_t> verbs,
FillRule fillRule) {
const bool isVolatile = false; // ???
const bool isVolatile = false; // ???
const SkScalar* conicWeights = nullptr;
const int conicWeightCount = 0;
return std::make_unique<SkiaRenderPath>(SkPath::Make(reinterpret_cast<const SkPoint*>(points.data()),
points.count(),
verbs.data(),
verbs.count(),
conicWeights,
conicWeightCount,
ToSkia::convert(fillRule),
isVolatile));
return std::make_unique<SkiaRenderPath>(
SkPath::Make(reinterpret_cast<const SkPoint*>(points.data()),
points.count(),
verbs.data(),
verbs.count(),
conicWeights,
conicWeightCount,
ToSkia::convert(fillRule),
isVolatile));
}
std::unique_ptr<RenderPath> SkiaFactory::makeEmptyRenderPath() {
@@ -323,10 +326,10 @@ std::unique_ptr<RenderImage> SkiaFactory::decodeImage(Span<const uint8_t> encode
ImageInfo info;
auto pixels = this->platformDecode(encoded, &info);
if (pixels.size() > 0) {
auto ct = info.colorType == ColorType::rgba ? kRGBA_8888_SkColorType
: kBGRA_8888_SkColorType;
auto at = info.alphaType == AlphaType::premul ? kPremul_SkAlphaType
: kOpaque_SkAlphaType;
auto ct =
info.colorType == ColorType::rgba ? kRGBA_8888_SkColorType : kBGRA_8888_SkColorType;
auto at =
info.alphaType == AlphaType::premul ? kPremul_SkAlphaType : kOpaque_SkAlphaType;
auto skinfo = SkImageInfo::Make(info.width, info.height, ct, at);
image = SkImage::MakeRasterCopy({skinfo, pixels.data(), info.rowBytes});
}

View File

@@ -7,45 +7,44 @@
namespace rive {
ContourMeasure::ContourMeasure(const RawPath& path) {
auto skpath = ToSkia::convert(path);
m_meas = SkContourMeasureIter(skpath, false).next().release();
}
ContourMeasure::~ContourMeasure() {
m_meas->unref();
}
float ContourMeasure::length() const { return m_meas->length(); }
bool ContourMeasure::computePosTan(float distance, Vec2D* pos, Vec2D* tan) const {
return m_meas->getPosTan(distance, (SkPoint*)pos, (SkPoint*)tan);
}
RawPath ContourMeasure::warp(const RawPath& src) const {
RawPath dst;
RawPath::Iter iter(src);
while (auto rec = iter.next()) {
switch (rec.verb) {
case PathVerb::move:
dst.move(this->warp(rec.pts[0]));
break;
case PathVerb::line:
dst.line(this->warp(rec.pts[0]));
break;
case PathVerb::quad:
dst.quad(this->warp(rec.pts[0]), this->warp(rec.pts[1]));
break;
case PathVerb::cubic:
dst.cubic(this->warp(rec.pts[0]), this->warp(rec.pts[1]), this->warp(rec.pts[2]));
break;
case PathVerb::close:
dst.close();
break;
}
ContourMeasure::ContourMeasure(const RawPath& path) {
auto skpath = ToSkia::convert(path);
m_meas = SkContourMeasureIter(skpath, false).next().release();
}
return dst;
}
}
ContourMeasure::~ContourMeasure() { m_meas->unref(); }
float ContourMeasure::length() const { return m_meas->length(); }
bool ContourMeasure::computePosTan(float distance, Vec2D* pos, Vec2D* tan) const {
return m_meas->getPosTan(distance, (SkPoint*)pos, (SkPoint*)tan);
}
RawPath ContourMeasure::warp(const RawPath& src) const {
RawPath dst;
RawPath::Iter iter(src);
while (auto rec = iter.next()) {
switch (rec.verb) {
case PathVerb::move:
dst.move(this->warp(rec.pts[0]));
break;
case PathVerb::line:
dst.line(this->warp(rec.pts[0]));
break;
case PathVerb::quad:
dst.quad(this->warp(rec.pts[0]), this->warp(rec.pts[1]));
break;
case PathVerb::cubic:
dst.cubic(
this->warp(rec.pts[0]), this->warp(rec.pts[1]), this->warp(rec.pts[2]));
break;
case PathVerb::close:
dst.close();
break;
}
}
return dst;
}
} // namespace rive

View File

@@ -11,6 +11,7 @@ namespace rive {
class ContourMeasure {
SkContourMeasure* m_meas;
public:
ContourMeasure(const RawPath& path);
~ContourMeasure();
@@ -38,6 +39,6 @@ namespace rive {
RawPath warp(const RawPath&) const;
};
}
} // namespace rive
#endif

View File

@@ -9,12 +9,11 @@
class ImageContent : public ViewerContent {
sk_sp<SkImage> m_image;
public:
ImageContent(sk_sp<SkImage> image) : m_image(std::move(image)) {}
void handleDraw(SkCanvas* canvas, double) override {
canvas->drawImage(m_image, 0, 0);
}
void handleDraw(SkCanvas* canvas, double) override { canvas->drawImage(m_image, 0, 0); }
void handleResize(int width, int height) override {}
void handleImgui() override {}

View File

@@ -178,7 +178,7 @@ int main() {
ImGui::NewFrame();
if (gContent) {
gContent->handleImgui();
gContent->handleImgui();
}
ImGui::Render();
@@ -188,7 +188,7 @@ int main() {
glfwPollEvents();
}
gContent = nullptr; // force delete now, so we can clean up
gContent = nullptr; // force delete now, so we can clean up
// Cleanup Skia.
surface = nullptr;

View File

@@ -17,7 +17,6 @@
#include "skia_renderer.hpp"
#include "viewer_content.hpp"
// ImGui wants raw pointers to names, but our public API returns
// names as strings (by value), so we cache these names each time we
// load a file
@@ -40,11 +39,9 @@ double GetSecondsToday() {
hours -= 12;
}
auto secs = (double)hours * 60 * 60 +
(double)tstruct.tm_min * 60 +
(double)tstruct.tm_sec;
// printf("%d %d %d\n", tstruct.tm_sec, tstruct.tm_min, hours);
// printf("%g %g %g\n", secs, secs/60, secs/60/60);
auto secs = (double)hours * 60 * 60 + (double)tstruct.tm_min * 60 + (double)tstruct.tm_sec;
// printf("%d %d %d\n", tstruct.tm_sec, tstruct.tm_min, hours);
// printf("%g %g %g\n", secs, secs/60, secs/60/60);
return secs;
}
@@ -53,7 +50,6 @@ double GetSecondsToday() {
// it.
std::vector<uint8_t> fileBytes;
static void loadNames(const rive::Artboard* ab) {
animationNames.clear();
stateMachineNames.clear();
@@ -70,12 +66,12 @@ static void loadNames(const rive::Artboard* ab) {
class SceneContent : public ViewerContent {
std::string m_filename;
std::unique_ptr<rive::File> m_file;
std::unique_ptr<rive::ArtboardInstance> m_artboardInstance;
std::unique_ptr<rive::Scene> m_currentScene;
int m_animationIndex = 0;
int m_stateMachineIndex = -1;
int m_width = 0, m_height = 0;
rive::Vec2D m_lastPointer;
rive::Mat2D m_inverseViewTransform;
@@ -135,9 +131,7 @@ class SceneContent : public ViewerContent {
public:
SceneContent(const char filename[], std::unique_ptr<rive::File> file) :
m_filename(filename),
m_file(std::move(file))
{
m_filename(filename), m_file(std::move(file)) {
initStateMachine(REQUEST_DEFAULT_SCENE);
}
@@ -168,7 +162,7 @@ public:
if (m_currentScene) {
// See if we can "set the time" e.g. clock statemachine
if (auto num = m_currentScene->getNumber("isTime")) {
num->value(GetSecondsToday()/60/60);
num->value(GetSecondsToday() / 60 / 60);
}
m_currentScene->advanceAndApply(elapsed);

View File

@@ -15,32 +15,34 @@ using RenderFontTextRuns = std::vector<rive::RenderTextRun>;
using RenderFontGlyphRuns = std::vector<rive::RenderGlyphRun>;
using RenderFontFactory = rive::rcp<rive::RenderFont> (*)(const rive::Span<const uint8_t>);
static bool ws(rive::Unichar c) {
return c <= ' ';
}
static bool ws(rive::Unichar c) { return c <= ' '; }
std::vector<int> compute_word_breaks(rive::Span<rive::Unichar> chars) {
std::vector<int> breaks;
const unsigned len = chars.size();
for (unsigned i = 0; i < len;) {
// skip ws
while (i < len && ws(chars[i])) {
++i;
}
breaks.push_back(i); // word start
// skip non-ws
while (i < len && !ws(chars[i])) {
++i;
}
breaks.push_back(i); // word end
// skip ws
while (i < len && ws(chars[i])) {
++i;
}
breaks.push_back(i); // word start
// skip non-ws
while (i < len && !ws(chars[i])) {
++i;
}
breaks.push_back(i); // word end
}
assert(breaks[breaks.size()-1] == len);
assert(breaks[breaks.size() - 1] == len);
return breaks;
}
static void drawrun(rive::Factory* factory, rive::Renderer* renderer,
const rive::RenderGlyphRun& run, unsigned startIndex, unsigned endIndex, rive::Vec2D origin) {
static void drawrun(rive::Factory* factory,
rive::Renderer* renderer,
const rive::RenderGlyphRun& run,
unsigned startIndex,
unsigned endIndex,
rive::Vec2D origin) {
auto font = run.font.get();
const auto scale = rive::Mat2D::fromScale(run.size, run.size);
auto paint = factory->makeRenderPaint();
@@ -51,12 +53,14 @@ static void drawrun(rive::Factory* factory, rive::Renderer* renderer,
auto trans = rive::Mat2D::fromTranslate(origin.x + run.xpos[i], origin.y);
auto rawpath = font->getPath(run.glyphs[i]);
rawpath.transformInPlace(trans * scale);
auto path = factory->makeRenderPath(rawpath.points(), rawpath.verbsU8(), rive::FillRule::nonZero);
auto path =
factory->makeRenderPath(rawpath.points(), rawpath.verbsU8(), rive::FillRule::nonZero);
renderer->drawPath(path.get(), paint.get());
}
}
static void drawpara(rive::Factory* factory, rive::Renderer* renderer,
static void drawpara(rive::Factory* factory,
rive::Renderer* renderer,
rive::Span<const rive::RenderGlyphLine> lines,
rive::Span<const rive::RenderGlyphRun> runs,
rive::Vec2D origin) {
@@ -66,7 +70,11 @@ static void drawpara(rive::Factory* factory, rive::Renderer* renderer,
for (int runIndex = line.startRun; runIndex <= line.endRun; ++runIndex) {
const auto& run = runs[runIndex];
int endGIndex = runIndex == line.endRun ? line.endIndex : run.glyphs.size();
drawrun(factory, renderer, run, startGIndex, endGIndex,
drawrun(factory,
renderer,
run,
startGIndex,
endGIndex,
{origin.x - x0, origin.y + line.baseline});
startGIndex = 0;
}
@@ -96,13 +104,14 @@ static rive::SkiaFactory skiaFactory;
static rive::RenderTextRun append(std::vector<rive::Unichar>* unichars,
rive::rcp<rive::RenderFont> font,
float size, const char text[]) {
float size,
const char text[]) {
uint32_t n = 0;
while (text[n]) {
unichars->push_back(text[n]); // todo: utf8 -> unichar
unichars->push_back(text[n]); // todo: utf8 -> unichar
n += 1;
}
return { std::move(font), size, n };
return {std::move(font), size, n};
}
class TextContent : public ViewerContent {
@@ -133,8 +142,7 @@ class TextContent : public ViewerContent {
assert(font0);
assert(font1);
rive::RenderFont::Coord c1 = {'wght', 100.f},
c2 = {'wght', 800.f};
rive::RenderFont::Coord c1 = {'wght', 100.f}, c2 = {'wght', 800.f};
RenderFontTextRuns truns;
@@ -157,19 +165,19 @@ public:
};
for (auto f : factory) {
auto truns = this->make_truns(f);
m_gruns.push_back(truns[0].font->shapeText(rive::toSpan(m_unichars),
rive::toSpan(truns)));
m_gruns.push_back(
truns[0].font->shapeText(rive::toSpan(m_unichars), rive::toSpan(truns)));
}
m_xform = rive::Mat2D::fromTranslate(10, 0)
* rive::Mat2D::fromScale(3, 3);
m_xform = rive::Mat2D::fromTranslate(10, 0) * rive::Mat2D::fromScale(3, 3);
}
void draw(rive::Renderer* renderer, float width, const RenderFontGlyphRuns& gruns) {
renderer->save();
renderer->transform(m_xform);
auto lines = rive::RenderGlyphLine::BreakLines(rive::toSpan(gruns), rive::toSpan(m_breaks), width);
auto lines =
rive::RenderGlyphLine::BreakLines(rive::toSpan(gruns), rive::toSpan(m_breaks), width);
drawpara(&skiaFactory, renderer, rive::toSpan(lines), rive::toSpan(gruns), {0, 0});
draw_line(&skiaFactory, renderer, width);
@@ -184,13 +192,12 @@ public:
this->draw(&renderer, m_width, grun);
renderer.translate(1200, 0);
}
}
void handleResize(int width, int height) override {}
void handleImgui() override {
ImGui::Begin("text", nullptr);
ImGui::SliderFloat("Alignment", &m_width, 10, 400);
ImGui::SliderFloat("Alignment", &m_width, 10, 400);
ImGui::End();
}
};

View File

@@ -24,17 +24,15 @@ void visit(const std::vector<RenderGlyphRun>& gruns, Vec2D origin, Handler proc)
for (const auto& gr : gruns) {
for (size_t i = 0; i < gr.glyphs.size(); ++i) {
auto path = gr.font->getPath(gr.glyphs[i]);
auto mx = Mat2D::fromTranslate(origin.x + gr.xpos[i], origin.y)
* Mat2D::fromScale(gr.size, gr.size);
auto mx = Mat2D::fromTranslate(origin.x + gr.xpos[i], origin.y) *
Mat2D::fromScale(gr.size, gr.size);
path.transformInPlace(mx);
proc(path);
}
}
}
static Vec2D ave(Vec2D a, Vec2D b) {
return (a + b) * 0.5f;
}
static Vec2D ave(Vec2D a, Vec2D b) { return (a + b) * 0.5f; }
static RawPath make_quad_path(Span<const Vec2D> pts) {
const int N = pts.size();
@@ -47,9 +45,9 @@ static RawPath make_quad_path(Span<const Vec2D> pts) {
path.quad(pts[1], pts[2]);
} else {
for (int i = 1; i < N - 2; ++i) {
path.quad(pts[i], ave(pts[i], pts[i+1]));
path.quad(pts[i], ave(pts[i], pts[i + 1]));
}
path.quad(pts[N-2], pts[N-1]);
path.quad(pts[N - 2], pts[N - 1]);
}
}
return path;
@@ -96,14 +94,14 @@ static void fill_point(Renderer* renderer, Vec2D p, float r, RenderPaint* paint)
typedef rcp<RenderFont> (*RenderFontFactory)(Span<const uint8_t>);
static RenderTextRun append(std::vector<Unichar>* unichars, rcp<RenderFont> font,
float size, const char text[]) {
static RenderTextRun
append(std::vector<Unichar>* unichars, rcp<RenderFont> font, float size, const char text[]) {
uint32_t n = 0;
while (text[n]) {
unichars->push_back(text[n]); // todo: utf8 -> unichar
unichars->push_back(text[n]); // todo: utf8 -> unichar
n += 1;
}
return { std::move(font), size, n };
return {std::move(font), size, n};
}
class TextPathContent : public ViewerContent {
@@ -113,7 +111,7 @@ class TextPathContent : public ViewerContent {
AABB m_gbounds;
std::vector<Vec2D> m_pathpts;
Vec2D m_lastPt = {0,0};
Vec2D m_lastPt = {0, 0};
int m_trackingIndex = -1;
Mat2D m_trans;
@@ -121,11 +119,9 @@ class TextPathContent : public ViewerContent {
bool m_trackingOneLine = false;
float m_oneLineX = 0;
float m_alignment = 0,
m_scaleY = 1,
m_offsetY = 0,
m_windowWidth = 1, // %
m_windowOffset = 0; // %
float m_alignment = 0, m_scaleY = 1, m_offsetY = 0,
m_windowWidth = 1, // %
m_windowOffset = 0; // %
RenderFontTextRuns make_truns(RenderFontFactory fact) {
auto loader = [fact](const char filename[]) -> rcp<RenderFont> {
@@ -147,8 +143,7 @@ class TextPathContent : public ViewerContent {
assert(font0);
assert(font1);
RenderFont::Coord c1 = {'wght', 100.f},
c2 = {'wght', 800.f};
RenderFont::Coord c1 = {'wght', 100.f}, c2 = {'wght', 800.f};
RenderFontTextRuns truns;
@@ -185,7 +180,7 @@ public:
m_paint = skiaFactory.makeRenderPaint();
m_paint->color(0xFFFFFFFF);
m_pathpts.push_back({ 20, 300});
m_pathpts.push_back({20, 300});
m_pathpts.push_back({220, 100});
m_pathpts.push_back({420, 500});
m_pathpts.push_back({620, 100});
@@ -213,15 +208,13 @@ public:
return n;
}
void modify(float amount) {
m_paint->color(0xFFFFFFFF);
}
void modify(float amount) { m_paint->color(0xFFFFFFFF); }
void draw(Renderer* renderer, const RenderFontGlyphRuns& gruns) {
auto get_path = [this](const RenderGlyphRun& run, int index, float dx) {
auto path = run.font->getPath(run.glyphs[index]);
path.transformInPlace(Mat2D::fromTranslate(run.xpos[index] + dx, m_offsetY)
* Mat2D::fromScale(run.size, run.size * m_scaleY));
path.transformInPlace(Mat2D::fromTranslate(run.xpos[index] + dx, m_offsetY) *
Mat2D::fromScale(run.size, run.size * m_scaleY));
return path;
};
@@ -268,10 +261,16 @@ public:
const float radius = 50;
if (m_trackingOneLine) {
float mx = m_oneLineX / m_gbounds.width();
const ColorInt colors[] = { 0xFF88FFFF, 0xFF88FFFF, 0xFFFFFFFF, 0xFF88FFFF, 0xFF88FFFF };
const float stops[] = { 0, mx / 2, mx, (1 + mx) / 2, 1 };
paint->shader(skiaFactory.makeLinearGradient(m_gbounds.left(), 0, m_gbounds.right(), 0,
colors, stops, 5, RenderTileMode::clamp));
const ColorInt colors[] = {0xFF88FFFF, 0xFF88FFFF, 0xFFFFFFFF, 0xFF88FFFF, 0xFF88FFFF};
const float stops[] = {0, mx / 2, mx, (1 + mx) / 2, 1};
paint->shader(skiaFactory.makeLinearGradient(m_gbounds.left(),
0,
m_gbounds.right(),
0,
colors,
stops,
5,
RenderTileMode::clamp));
}
auto wrap_path = [](const RawPath& src, float x, float rad) {
@@ -333,9 +332,7 @@ public:
}
}
void handlePointerDown() override {
auto close_to = [](Vec2D a, Vec2D b) {
return Vec2D::distance(a, b) <= 10;
};
auto close_to = [](Vec2D a, Vec2D b) { return Vec2D::distance(a, b) <= 10; };
for (size_t i = 0; i < m_pathpts.size(); ++i) {
if (close_to(m_lastPt, m_pathpts[i])) {
m_trackingIndex = i;
@@ -344,19 +341,17 @@ public:
}
}
void handlePointerUp() override {
m_trackingIndex = -1;
}
void handlePointerUp() override { m_trackingIndex = -1; }
void handleResize(int width, int height) override {}
void handleImgui() override {
ImGui::Begin("path", nullptr);
ImGui::SliderFloat("Alignment", &m_alignment, -3, 4);
ImGui::SliderFloat("Scale Y", &m_scaleY, 0.25f, 3.0f);
ImGui::SliderFloat("Offset Y", &m_offsetY, -100, 100);
ImGui::SliderFloat("Window Offset", &m_windowOffset, -1.1f, 1.1f);
ImGui::SliderFloat("Window Width", &m_windowWidth, 0, 1.2f);
ImGui::SliderFloat("Alignment", &m_alignment, -3, 4);
ImGui::SliderFloat("Scale Y", &m_scaleY, 0.25f, 3.0f);
ImGui::SliderFloat("Offset Y", &m_offsetY, -100, 100);
ImGui::SliderFloat("Window Offset", &m_windowOffset, -1.1f, 1.1f);
ImGui::SliderFloat("Window Width", &m_windowWidth, 0, 1.2f);
ImGui::End();
}
};

View File

@@ -5,17 +5,22 @@
#include "viewer_content.hpp"
#include "rive/rive_counter.hpp"
ViewerContent::~ViewerContent() {
DumpCounters("After deleting content");
}
ViewerContent::~ViewerContent() { DumpCounters("After deleting content"); }
const char* gCounterNames[] = {
"file", "artboard", "animation", "machine",
"buffer", "path", "paint", "shader", "image",
"file",
"artboard",
"animation",
"machine",
"buffer",
"path",
"paint",
"shader",
"image",
};
void ViewerContent::DumpCounters(const char label[]) {
assert(sizeof(gCounterNames)/sizeof(gCounterNames[0]) == rive::Counter::kLastType + 1);
assert(sizeof(gCounterNames) / sizeof(gCounterNames[0]) == rive::Counter::kLastType + 1);
if (label == nullptr) {
label = "Counters";

View File

@@ -27,7 +27,7 @@ public:
// Searches all handlers and returns a content if it is found.
static std::unique_ptr<ViewerContent> FindHandler(const char filename[]) {
Factory factories[] = { Scene, Image, Text, TextPath };
Factory factories[] = {Scene, Image, Text, TextPath};
for (auto f : factories) {
if (auto content = f(filename)) {
return content;

View File

@@ -3,7 +3,8 @@
using namespace rive;
BlendState1DInstance::BlendState1DInstance(const BlendState1D* blendState, ArtboardInstance* instance) :
BlendState1DInstance::BlendState1DInstance(const BlendState1D* blendState,
ArtboardInstance* instance) :
BlendStateInstance<BlendState1D, BlendAnimation1D>(blendState, instance) {}
int BlendState1DInstance::animationIndex(float value) {

View File

@@ -3,7 +3,8 @@
using namespace rive;
BlendStateDirectInstance::BlendStateDirectInstance(const BlendStateDirect* blendState, ArtboardInstance* instance) :
BlendStateDirectInstance::BlendStateDirectInstance(const BlendStateDirect* blendState,
ArtboardInstance* instance) :
BlendStateInstance<BlendStateDirect, BlendAnimationDirect>(blendState, instance) {}
void BlendStateDirectInstance::advance(float seconds, Span<SMIInput*> inputs) {

View File

@@ -14,8 +14,7 @@ LinearAnimationInstance::LinearAnimationInstance(const LinearAnimation* animatio
m_TotalTime(0.0f),
m_LastTotalTime(0.0f),
m_SpilledTime(0.0f),
m_Direction(1)
{
m_Direction(1) {
Counter::update(Counter::kLinearAnimationInstance, +1);
}
@@ -28,8 +27,7 @@ LinearAnimationInstance::LinearAnimationInstance(LinearAnimationInstance const&
m_SpilledTime(lhs.m_SpilledTime),
m_Direction(lhs.m_Direction),
m_DidLoop(lhs.m_DidLoop),
m_LoopValue(lhs.m_LoopValue)
{
m_LoopValue(lhs.m_LoopValue) {
Counter::update(Counter::kLinearAnimationInstance, +1);
}
@@ -151,9 +149,7 @@ float LinearAnimationInstance::speed() const { return m_Animation->speed(); }
float LinearAnimationInstance::startSeconds() const { return m_Animation->startSeconds(); }
std::string LinearAnimationInstance::name() const {
return m_Animation->name();
}
std::string LinearAnimationInstance::name() const { return m_Animation->name(); }
bool LinearAnimationInstance::isTranslucent() const {
return m_ArtboardInstance->isTranslucent(this);

View File

@@ -7,6 +7,6 @@ NestedLinearAnimation::NestedLinearAnimation() {}
NestedLinearAnimation::~NestedLinearAnimation() {}
void NestedLinearAnimation::initializeAnimation(ArtboardInstance* artboard) {
m_AnimationInstance = std::make_unique<LinearAnimationInstance>(artboard->animation(animationId()),
artboard);
m_AnimationInstance =
std::make_unique<LinearAnimationInstance>(artboard->animation(animationId()), artboard);
}

View File

@@ -326,8 +326,7 @@ void StateMachineInstance::pointerUp(Vec2D position) {
StateMachineInstance::StateMachineInstance(const StateMachine* machine,
ArtboardInstance* instance) :
Scene(instance), m_Machine(machine)
{
Scene(instance), m_Machine(machine) {
Counter::update(Counter::kStateMachineInstance, +1);
const auto count = machine->inputCount();

View File

@@ -101,8 +101,9 @@ const LinearAnimation* StateTransition::exitTimeAnimation(const LayerState* from
: nullptr;
}
AllowTransition
StateTransition::allowed(StateInstance* stateFrom, Span<SMIInput*> inputs, bool ignoreTriggers) const {
AllowTransition StateTransition::allowed(StateInstance* stateFrom,
Span<SMIInput*> inputs,
bool ignoreTriggers) const {
if (isDisabled()) {
return AllowTransition::no;
}

View File

@@ -585,13 +585,9 @@ StatusCode Artboard::import(ImportStack& importStack) {
#include "rive/animation/linear_animation_instance.hpp"
#include "rive/animation/state_machine_instance.hpp"
ArtboardInstance::ArtboardInstance() {
Counter::update(Counter::kArtboardInstance, +1);
}
ArtboardInstance::ArtboardInstance() { Counter::update(Counter::kArtboardInstance, +1); }
ArtboardInstance::~ArtboardInstance() {
Counter::update(Counter::kArtboardInstance, -1);
}
ArtboardInstance::~ArtboardInstance() { Counter::update(Counter::kArtboardInstance, -1); }
std::unique_ptr<LinearAnimationInstance> ArtboardInstance::animationAt(size_t index) {
auto la = this->animation(index);

View File

@@ -25,9 +25,7 @@ float Bone::x() const { return parent()->as<Bone>()->length(); }
float Bone::y() const { return 0.0f; }
Vec2D Bone::tipWorldTranslation() const {
return worldTransform() * Vec2D(length(), 0);
}
Vec2D Bone::tipWorldTranslation() const { return worldTransform() * Vec2D(length(), 0); }
void Bone::addPeerConstraint(Constraint* peer) {
assert(std::find(m_PeerConstraints.begin(), m_PeerConstraints.end(), peer) ==

View File

@@ -23,10 +23,10 @@ static int encodedWeightValue(unsigned int index, unsigned int data) {
}
Vec2D Weight::deform(Vec2D inPoint,
unsigned int indices,
unsigned int weights,
const Mat2D& world,
const float* boneTransforms) {
unsigned int indices,
unsigned int weights,
const Mat2D& world,
const float* boneTransforms) {
float xx = 0, xy = 0, yx = 0, yy = 0, tx = 0, ty = 0;
for (int i = 0; i < 4; i++) {
int weight = encodedWeightValue(i, weights);

View File

@@ -14,7 +14,7 @@ void DistanceConstraint::constrain(TransformComponent* component) {
const Vec2D targetTranslation = m_Target->worldTranslation();
const Vec2D ourTranslation = component->worldTranslation();
Vec2D toTarget = ourTranslation - targetTranslation;
float currentDistance = toTarget.length();

View File

@@ -6,9 +6,7 @@
using namespace rive;
static float atan2(Vec2D v) {
return std::atan2(v.y, v.x);
}
static float atan2(Vec2D v) { return std::atan2(v.y, v.x); }
void IKConstraint::buildDependencies() {
Super::buildDependencies();

View File

@@ -109,16 +109,13 @@ static Core* readRuntimeObject(BinaryReader& reader, const RuntimeHeader& header
}
File::File(Factory* factory, FileAssetResolver* assetResolver) :
m_Factory(factory), m_AssetResolver(assetResolver)
{
m_Factory(factory), m_AssetResolver(assetResolver) {
Counter::update(Counter::kFile, +1);
assert(factory);
}
File::~File() {
Counter::update(Counter::kFile, -1);
}
File::~File() { Counter::update(Counter::kFile, -1); }
std::unique_ptr<File> File::import(Span<const uint8_t> bytes,
Factory* factory,

View File

@@ -7,11 +7,10 @@
using namespace rive;
FileAssetImporter::FileAssetImporter(FileAsset* fileAsset, FileAssetResolver* assetResolver, Factory* factory) :
m_FileAsset(fileAsset),
m_FileAssetResolver(assetResolver),
m_Factory(factory)
{}
FileAssetImporter::FileAssetImporter(FileAsset* fileAsset,
FileAssetResolver* assetResolver,
Factory* factory) :
m_FileAsset(fileAsset), m_FileAssetResolver(assetResolver), m_Factory(factory) {}
void FileAssetImporter::loadContents(const FileAssetContents& contents) {
auto data = contents.bytes();

View File

@@ -316,9 +316,7 @@ bool HitTester::test(FillRule rule) {
/////////////////////////
static bool cross_lt(Vec2D a, Vec2D b) {
return a.x * b.y < a.y * b.x;
}
static bool cross_lt(Vec2D a, Vec2D b) { return a.x * b.y < a.y * b.x; }
bool HitTester::testMesh(Vec2D pt, Span<Vec2D> verts, Span<uint16_t> indices) {
if (verts.size() < 3) {
@@ -330,8 +328,8 @@ bool HitTester::testMesh(Vec2D pt, Span<Vec2D> verts, Span<uint16_t> indices) {
if (CULL_BOUNDS) {
const auto bounds = AABB(verts);
if (bounds.bottom() < pt.y || pt.y < bounds.top() ||
bounds.right() < pt.x || pt.x < bounds.left()) {
if (bounds.bottom() < pt.y || pt.y < bounds.top() || bounds.right() < pt.x ||
pt.x < bounds.left()) {
return false;
}
}
@@ -344,7 +342,7 @@ bool HitTester::testMesh(Vec2D pt, Span<Vec2D> verts, Span<uint16_t> indices) {
auto pa = a - pt;
auto pb = b - pt;
auto pc = c - pt;
auto ab = cross_lt(pa, pb);
auto bc = cross_lt(pb, pc);
auto ca = cross_lt(pc, pa);
@@ -382,12 +380,12 @@ bool HitTester::testMesh(const IAABB& area, Span<Vec2D> verts, Span<uint16_t> in
std::vector<int> windings(area.width() * area.height());
const auto offset = Vec2D((float)area.left, (float)area.top);
int* deltas = windings.data();
for (size_t i = 0; i < indices.size(); i += 3) {
const auto a = verts[indices[i + 0]] - offset;
const auto b = verts[indices[i + 1]] - offset;
const auto c = verts[indices[i + 2]] - offset;
clip_line(area.height(), a, b, deltas, area.width());
clip_line(area.height(), b, c, deltas, area.width());
clip_line(area.height(), c, a, deltas, area.width());

View File

@@ -26,8 +26,8 @@ Mat2D Mat2D::scale(Vec2D vec) const {
}
Mat2D Mat2D::multiply(const Mat2D& a, const Mat2D& b) {
float a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5];
float a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], b0 = b[0], b1 = b[1],
b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5];
return {
a0 * b0 + a2 * b1,
a1 * b0 + a3 * b1,
@@ -39,8 +39,8 @@ Mat2D Mat2D::multiply(const Mat2D& a, const Mat2D& b) {
}
bool Mat2D::invert(Mat2D* result) const {
float aa = m_Buffer[0], ab = m_Buffer[1], ac = m_Buffer[2],
ad = m_Buffer[3], atx = m_Buffer[4], aty = m_Buffer[5];
float aa = m_Buffer[0], ab = m_Buffer[1], ac = m_Buffer[2], ad = m_Buffer[3], atx = m_Buffer[4],
aty = m_Buffer[5];
float det = aa * ad - ab * ac;
if (det == 0.0f) {
@@ -49,10 +49,10 @@ bool Mat2D::invert(Mat2D* result) const {
det = 1.0f / det;
*result = {
ad * det,
ad * det,
-ab * det,
-ac * det,
aa * det,
aa * det,
(ac * aty - ad * atx) * det,
(ab * atx - aa * aty) * det,
};
@@ -60,8 +60,7 @@ bool Mat2D::invert(Mat2D* result) const {
}
TransformComponents Mat2D::decompose() const {
float m0 = m_Buffer[0], m1 = m_Buffer[1],
m2 = m_Buffer[2], m3 = m_Buffer[3];
float m0 = m_Buffer[0], m1 = m_Buffer[1], m2 = m_Buffer[2], m3 = m_Buffer[3];
float rotation = (float)std::atan2(m1, m0);
float denom = m0 * m0 + m1 * m1;

View File

@@ -169,20 +169,20 @@ void RawPath::addPoly(Span<const Vec2D> span, bool isClosed) {
//////////////////////////////////////////////////////////////////////////
namespace rive {
int path_verb_to_point_count(PathVerb v) {
static uint8_t ptCounts[] = {
1, // move
1, // line
2, // quad
2, // conic (unused)
3, // cubic
0, // close
};
size_t index = (size_t)v;
assert(index < sizeof(ptCounts));
return ptCounts[index];
}
}
int path_verb_to_point_count(PathVerb v) {
static uint8_t ptCounts[] = {
1, // move
1, // line
2, // quad
2, // conic (unused)
3, // cubic
0, // close
};
size_t index = (size_t)v;
assert(index < sizeof(ptCounts));
return ptCounts[index];
}
} // namespace rive
RawPath::Iter::Rec RawPath::Iter::next() {
// initialize with "false"

View File

@@ -69,13 +69,9 @@ void Renderer::rotate(float radians) {
this->transform(Mat2D(c, s, -s, c, 0, 0));
}
RenderBuffer::RenderBuffer(size_t count) : m_Count(count) {
Counter::update(Counter::kBuffer, 1);
}
RenderBuffer::RenderBuffer(size_t count) : m_Count(count) { Counter::update(Counter::kBuffer, 1); }
RenderBuffer::~RenderBuffer() {
Counter::update(Counter::kBuffer, -1);
}
RenderBuffer::~RenderBuffer() { Counter::update(Counter::kBuffer, -1); }
RenderShader::RenderShader() { Counter::update(Counter::kShader, 1); }
RenderShader::~RenderShader() { Counter::update(Counter::kShader, -1); }
@@ -91,8 +87,9 @@ RenderPath::~RenderPath() { Counter::update(Counter::kPath, -1); }
#include "rive/render_text.hpp"
std::vector<RenderGlyphRun> RenderFont::shapeText(rive::Span<const rive::Unichar> text,
rive::Span<const rive::RenderTextRun> runs) const {
std::vector<RenderGlyphRun>
RenderFont::shapeText(rive::Span<const rive::Unichar> text,
rive::Span<const rive::RenderTextRun> runs) const {
#ifdef DEBUG
size_t count = 0;
for (const auto& tr : runs) {

View File

@@ -7,17 +7,11 @@ Scene::Scene(ArtboardInstance* abi) : m_ArtboardInstance(abi) {
assert(m_ArtboardInstance->isInstance());
}
float Scene::width() const {
return m_ArtboardInstance->width();
}
float Scene::width() const { return m_ArtboardInstance->width(); }
float Scene::height() const {
return m_ArtboardInstance->height();
}
float Scene::height() const { return m_ArtboardInstance->height(); }
void Scene::draw(Renderer* renderer) {
m_ArtboardInstance->draw(renderer);
}
void Scene::draw(Renderer* renderer) { m_ArtboardInstance->draw(renderer); }
void Scene::pointerDown(Vec2D) {}
void Scene::pointerMove(Vec2D) {}

View File

@@ -4,14 +4,10 @@
using namespace rive;
static float clamp(float v, float lo, float hi) {
return std::min(std::max(v, lo), hi);
}
static float clamp(float v, float lo, float hi) { return std::min(std::max(v, lo), hi); }
// Less exact, but faster, than std::lerp
static float lerp(float from, float to, float f) {
return from + f * (to - from);
}
static float lerp(float from, float to, float f) { return from + f * (to - from); }
void MetricsPath::reset() {
m_ComputedLength = 0.0f;
@@ -349,9 +345,8 @@ void MetricsPath::extractSubPart(
}
}
RenderMetricsPath::RenderMetricsPath(std::unique_ptr<RenderPath> path)
: m_RenderPath(std::move(path))
{}
RenderMetricsPath::RenderMetricsPath(std::unique_ptr<RenderPath> path) :
m_RenderPath(std::move(path)) {}
void RenderMetricsPath::addPath(CommandPath* path, const Mat2D& transform) {
MetricsPath::addPath(path, transform);

View File

@@ -13,9 +13,6 @@ void Vertex::xChanged() { markGeometryDirty(); }
void Vertex::yChanged() { markGeometryDirty(); }
void Vertex::deform(const Mat2D& worldTransform, const float* boneTransforms) {
m_Weight->translation() = Weight::deform(Vec2D(x(), y()),
m_Weight->indices(),
m_Weight->values(),
worldTransform,
boneTransforms);
m_Weight->translation() = Weight::deform(
Vec2D(x(), y()), m_Weight->indices(), m_Weight->values(), worldTransform, boneTransforms);
}

View File

@@ -4,10 +4,10 @@
template <typename T> void checkFits() {
int64_t min = std::numeric_limits<T>::min();
int64_t max = std::numeric_limits<T>::max();
REQUIRE( rive::fitsIn<T>(max+0));
REQUIRE( rive::fitsIn<T>(min-0));
REQUIRE(!rive::fitsIn<T>(max+1));
REQUIRE(!rive::fitsIn<T>(min-1));
REQUIRE(rive::fitsIn<T>(max + 0));
REQUIRE(rive::fitsIn<T>(min - 0));
REQUIRE(!rive::fitsIn<T>(max + 1));
REQUIRE(!rive::fitsIn<T>(min - 1));
}
TEST_CASE("fitsIn checks", "[type_conversions]") {
@@ -36,9 +36,9 @@ template <typename T> bool checkAs(uint64_t value) {
p = packvarint(storage, value);
rive::BinaryReader reader(rive::Span(storage, p - storage));
auto newValue = reader.readVarUintAs<T>();
if (reader.hasError()) {
REQUIRE(newValue == 0);
}
@@ -47,15 +47,15 @@ template <typename T> bool checkAs(uint64_t value) {
}
TEST_CASE("range checks", "[binary_reader]") {
REQUIRE( checkAs<uint8_t>(100));
REQUIRE( checkAs<uint16_t>(100));
REQUIRE( checkAs<uint32_t>(100));
REQUIRE(checkAs<uint8_t>(100));
REQUIRE(checkAs<uint16_t>(100));
REQUIRE(checkAs<uint32_t>(100));
REQUIRE(!checkAs<uint8_t>(1000));
REQUIRE( checkAs<uint16_t>(1000));
REQUIRE( checkAs<uint32_t>(1000));
REQUIRE(checkAs<uint16_t>(1000));
REQUIRE(checkAs<uint32_t>(1000));
REQUIRE(!checkAs<uint8_t>(100000));
REQUIRE(!checkAs<uint16_t>(100000));
REQUIRE( checkAs<uint32_t>(100000));
REQUIRE(checkAs<uint32_t>(100000));
}

View File

@@ -45,7 +45,7 @@ TEST_CASE("image assets loads correctly", "[assets]") {
TEST_CASE("out of band image assets loads correctly", "[assets]") {
RenderObjectLeakChecker checker;
rive::NoOpFactory gEmptyFactory;
std::string filename = "../../test/assets/out_of_band/walle.riv";
rive::RelativeLocalAssetResolver resolver(filename, &gEmptyFactory);

View File

@@ -9,24 +9,31 @@ rcp<RenderBuffer> NoOpFactory::makeBufferU16(Span<const uint16_t>) { return null
rcp<RenderBuffer> NoOpFactory::makeBufferU32(Span<const uint32_t>) { return nullptr; }
rcp<RenderBuffer> NoOpFactory::makeBufferF32(Span<const float>) { return nullptr; }
rcp<RenderShader> NoOpFactory::makeLinearGradient(float sx, float sy,
float ex, float ey,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode,
const Mat2D* localMatrix) { return nullptr; }
rcp<RenderShader> NoOpFactory::makeLinearGradient(float sx,
float sy,
float ex,
float ey,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode,
const Mat2D* localMatrix) {
return nullptr;
}
rcp<RenderShader> NoOpFactory::makeRadialGradient(float cx, float cy, float radius,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode,
const Mat2D* localMatrix) { return nullptr; }
rcp<RenderShader> NoOpFactory::makeRadialGradient(float cx,
float cy,
float radius,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode,
const Mat2D* localMatrix) {
return nullptr;
}
std::unique_ptr<RenderPath> NoOpFactory::makeRenderPath(Span<const Vec2D> points,
Span<const uint8_t> verbs,
FillRule) {
std::unique_ptr<RenderPath>
NoOpFactory::makeRenderPath(Span<const Vec2D> points, Span<const uint8_t> verbs, FillRule) {
return std::make_unique<NoOpRenderPath>();
}

View File

@@ -11,24 +11,27 @@ namespace rive {
rcp<RenderBuffer> makeBufferU32(Span<const uint32_t>) override;
rcp<RenderBuffer> makeBufferF32(Span<const float>) override;
rcp<RenderShader> makeLinearGradient(float sx, float sy,
float ex, float ey,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode,
const Mat2D* localMatrix = nullptr) override;
rcp<RenderShader> makeLinearGradient(float sx,
float sy,
float ex,
float ey,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode,
const Mat2D* localMatrix = nullptr) override;
rcp<RenderShader> makeRadialGradient(float cx, float cy, float radius,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode,
const Mat2D* localMatrix = nullptr) override;
rcp<RenderShader> makeRadialGradient(float cx,
float cy,
float radius,
const ColorInt colors[], // [count]
const float stops[], // [count]
size_t count,
RenderTileMode,
const Mat2D* localMatrix = nullptr) override;
std::unique_ptr<RenderPath> makeRenderPath(Span<const Vec2D> points,
Span<const uint8_t> verbs,
FillRule) override;
std::unique_ptr<RenderPath>
makeRenderPath(Span<const Vec2D> points, Span<const uint8_t> verbs, FillRule) override;
std::unique_ptr<RenderPath> makeEmptyRenderPath() override;

View File

@@ -125,7 +125,7 @@ TEST_CASE("rawpath-iter", "[rawpath]") {
RawPath rp;
RawPath::Iter iter(rp);
REQUIRE(iter.next() == false);
REQUIRE(iter.next() == false); // should be safe to call again
REQUIRE(iter.next() == false); // should be safe to call again
}
{
RawPath rp;
@@ -136,20 +136,18 @@ TEST_CASE("rawpath-iter", "[rawpath]") {
rp.close();
RawPath::Iter iter(rp);
auto rec = iter.next();
REQUIRE((rec && is_move(rec) && eq(rec.pts[0], 1,2)));
REQUIRE((rec && is_move(rec) && eq(rec.pts[0], 1, 2)));
rec = iter.next();
REQUIRE((rec && is_line(rec) && eq(rec.pts[0], 3,4)));
REQUIRE((rec && is_line(rec) && eq(rec.pts[0], 3, 4)));
rec = iter.next();
REQUIRE((rec && is_quad(rec) && eq(rec.pts[0], 5,6)
&& eq(rec.pts[1], 7,8)));
REQUIRE((rec && is_quad(rec) && eq(rec.pts[0], 5, 6) && eq(rec.pts[1], 7, 8)));
rec = iter.next();
REQUIRE((rec && is_cubic(rec) && eq(rec.pts[0], 9,10)
&& eq(rec.pts[1], 11,12)
&& eq(rec.pts[2], 13,14)));
REQUIRE((rec && is_cubic(rec) && eq(rec.pts[0], 9, 10) && eq(rec.pts[1], 11, 12) &&
eq(rec.pts[2], 13, 14)));
rec = iter.next();
REQUIRE((rec && is_close(rec)));
rec = iter.next();
REQUIRE(rec == false);
REQUIRE(iter.next() == false); // should be safe to call again
REQUIRE(iter.next() == false); // should be safe to call again
}
}

View File

@@ -39,9 +39,8 @@ class RenderObjectLeakChecker {
public:
RenderObjectLeakChecker() {
std::copy(rive::Counter::counts,
rive::Counter::counts + rive::Counter::kNumTypes,
m_before);
std::copy(
rive::Counter::counts, rive::Counter::counts + rive::Counter::kNumTypes, m_before);
}
~RenderObjectLeakChecker() {
const int* after = rive::Counter::counts;