Skip to content

Commit

Permalink
Add copy of CGSkiaFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
mikerreed committed Jun 30, 2022
1 parent 88a8e60 commit b4e54e2
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 2 deletions.
8 changes: 8 additions & 0 deletions RiveRuntime.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
04BE5430264D1F4100427B39 /* LayerState.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BE542F264D1F4100427B39 /* LayerState.h */; settings = {ATTRIBUTES = (Public, ); }; };
04BE5434264D267900427B39 /* LayerState.mm in Sources */ = {isa = PBXBuildFile; fileRef = 04BE5431264D243D00427B39 /* LayerState.mm */; };
04BE5436264D2A7500427B39 /* RivePrivateHeaders.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BE5435264D2A7500427B39 /* RivePrivateHeaders.h */; };
274175FD286DB9CE000A60D1 /* cg_skia_factory.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 274175FB286DB9CE000A60D1 /* cg_skia_factory.hpp */; };
274175FE286DB9CE000A60D1 /* cg_skia_factory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 274175FC286DB9CE000A60D1 /* cg_skia_factory.cpp */; };
2A7079352726277C00C035A1 /* rive_renderer_view.hh in Headers */ = {isa = PBXBuildFile; fileRef = 2A7079342726277C00C035A1 /* rive_renderer_view.hh */; settings = {ATTRIBUTES = (Public, ); }; };
2A707937272628AD00C035A1 /* rive_renderer_view.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2A707936272628AD00C035A1 /* rive_renderer_view.mm */; };
C34609FC27FF9114002DBCB7 /* RiveFile+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C34609FB27FF9114002DBCB7 /* RiveFile+Extensions.swift */; };
Expand Down Expand Up @@ -105,6 +107,8 @@
04BE542F264D1F4100427B39 /* LayerState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayerState.h; sourceTree = "<group>"; };
04BE5431264D243D00427B39 /* LayerState.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = LayerState.mm; sourceTree = "<group>"; };
04BE5435264D2A7500427B39 /* RivePrivateHeaders.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RivePrivateHeaders.h; sourceTree = "<group>"; };
274175FB286DB9CE000A60D1 /* cg_skia_factory.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = cg_skia_factory.hpp; sourceTree = "<group>"; };
274175FC286DB9CE000A60D1 /* cg_skia_factory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cg_skia_factory.cpp; sourceTree = "<group>"; };
2A7079342726277C00C035A1 /* rive_renderer_view.hh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = rive_renderer_view.hh; sourceTree = "<group>"; };
2A707936272628AD00C035A1 /* rive_renderer_view.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = rive_renderer_view.mm; sourceTree = "<group>"; };
C34609FB27FF9114002DBCB7 /* RiveFile+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveFile+Extensions.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -147,6 +151,7 @@
046FB801264EB632000129B1 /* include */ = {
isa = PBXGroup;
children = (
274175FB286DB9CE000A60D1 /* cg_skia_factory.hpp */,
046FB7EC264EAA60000129B1 /* RiveArtboard.h */,
046FB7E7264EAA5F000129B1 /* RiveFile.h */,
046FB7E1264EAA5E000129B1 /* RiveLinearAnimationInstance.h */,
Expand Down Expand Up @@ -202,6 +207,7 @@
C9BD3927263B64B100696C37 /* Renderer */ = {
isa = PBXGroup;
children = (
274175FC286DB9CE000A60D1 /* cg_skia_factory.cpp */,
046FB801264EB632000129B1 /* include */,
046FB7E2264EAA5E000129B1 /* RiveArtboard.mm */,
046FB7EF264EAA60000129B1 /* RiveFile.mm */,
Expand Down Expand Up @@ -293,6 +299,7 @@
046FB7F7264EAA60000129B1 /* RiveFile.h in Headers */,
046FB7FC264EAA61000129B1 /* RiveArtboard.h in Headers */,
2A7079352726277C00C035A1 /* rive_renderer_view.hh in Headers */,
274175FD286DB9CE000A60D1 /* cg_skia_factory.hpp in Headers */,
046FB800264EAA61000129B1 /* RiveStateMachineInstance.h in Headers */,
046FB7FB264EAA61000129B1 /* RiveSMIInput.h in Headers */,
046FB7F1264EAA60000129B1 /* RiveLinearAnimationInstance.h in Headers */,
Expand Down Expand Up @@ -428,6 +435,7 @@
C9C741F524FC510200EF9516 /* Rive.mm in Sources */,
046FB7F8264EAA60000129B1 /* RiveStateMachineInstance.mm in Sources */,
C3468E5C27ED4C41008652FD /* RiveModel.swift in Sources */,
274175FE286DB9CE000A60D1 /* cg_skia_factory.cpp in Sources */,
046FB7FF264EAA61000129B1 /* RiveFile.mm in Sources */,
046FB7F2264EAA60000129B1 /* RiveArtboard.mm in Sources */,
046FB7F4264EAA60000129B1 /* RiveLinearAnimationInstance.mm in Sources */,
Expand Down
4 changes: 2 additions & 2 deletions Source/Renderer/RiveFile.mm
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

#import <Rive.h>
#import <RivePrivateHeaders.h>
#include "skia_factory.hpp"
#import <cg_skia_factory.hpp>

static rive::SkiaFactory gFactory;
static rive::CGSkiaFactory gFactory;

/*
* RiveFile
Expand Down
96 changes: 96 additions & 0 deletions Source/Renderer/cg_skia_factory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Copyright 2022 Rive
*/

#include "cg_skia_factory.hpp"
#include "rive/core/type_conversions.hpp"
#include <vector>

#ifdef RIVE_BUILD_FOR_APPLE

#if defined(RIVE_BUILD_FOR_OSX)
#include <ApplicationServices/ApplicationServices.h>
#elif defined(RIVE_BUILD_FOR_IOS)
#include <CoreGraphics/CoreGraphics.h>
#include <ImageIO/ImageIO.h>
#endif

// Helper that remembers to call CFRelease when an object goes out of scope.
template <typename T> class AutoCF {
T m_Obj;
public:
AutoCF(T obj) : m_Obj(obj) {}
~AutoCF() { if (m_Obj) CFRelease(m_Obj); }

operator T() const { return m_Obj; }
operator bool() const { return m_Obj != nullptr; }
T get() const { return m_Obj; }
};

using namespace rive;

std::vector<uint8_t> CGSkiaFactory::platformDecode(Span<const uint8_t> span,
SkiaFactory::ImageInfo* info) {
std::vector<uint8_t> pixels;

AutoCF data = CFDataCreateWithBytesNoCopy(nullptr, span.data(), span.size(), nullptr);
if (!data) {
return pixels;
}

AutoCF source = CGImageSourceCreateWithData(data, nullptr);
if (!source) {
return pixels;
}

AutoCF image = CGImageSourceCreateImageAtIndex(source, 0, nullptr);
if (!image) {
return pixels;
}

bool isOpaque = false;
switch (CGImageGetAlphaInfo(image.get())) {
case kCGImageAlphaNone:
case kCGImageAlphaNoneSkipFirst:
case kCGImageAlphaNoneSkipLast:
isOpaque = true;
break;
default:
break;
}

// Now create a drawing context to produce RGBA pixels

const size_t bitsPerComponent = 8;
CGBitmapInfo cgInfo = kCGBitmapByteOrder32Big; // rgba
if (isOpaque) {
cgInfo |= kCGImageAlphaNoneSkipLast;
} else {
cgInfo |= kCGImageAlphaPremultipliedLast; // premul
}
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 size = rowBytes * height;

pixels.resize(size);

AutoCF cs = CGColorSpaceCreateDeviceRGB();
AutoCF cg = CGBitmapContextCreate(pixels.data(), width, height, bitsPerComponent, rowBytes, cs, cgInfo);
if (!cg) {
pixels.clear();
return pixels;
}

CGContextSetBlendMode(cg, kCGBlendModeCopy);
CGContextDrawImage(cg, CGRectMake(0, 0, width, height), image);

info->alphaType = isOpaque ? AlphaType::opaque : AlphaType::premul;
info->colorType = ColorType::rgba;
info->width = castTo<uint32_t>(width);
info->height = castTo<uint32_t>(height);
info->rowBytes = rowBytes;
return pixels;
};

#endif // RIVE_BUILD_FOR_APPLE
17 changes: 17 additions & 0 deletions Source/Renderer/include/cg_skia_factory.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2022 Rive
*/

#ifndef _RIVE_CGSkiaFactory_HPP_
#define _RIVE_CGSkiaFactory_HPP_

#include "skia_factory.hpp"

namespace rive {
struct CGSkiaFactory : public SkiaFactory {
std::vector<uint8_t> platformDecode(Span<const uint8_t>,
SkiaFactory::ImageInfo*) override;
};
} // namespace

#endif // _RIVE_CGSkiaFactory_HPP_

0 comments on commit b4e54e2

Please sign in to comment.