Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ DerivedData/
.netrc
.claude/
.rb_template/
.augment/
2 changes: 1 addition & 1 deletion Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 34 additions & 6 deletions Sources/OpenRenderBox/Path/ORBPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include <OpenRenderBox/ORBPath.h>
#include <OpenRenderBox/ORBPathCallbacks.h>
#include <OpenRenderBoxCxx/Path/PathStorage.hpp>
#include <OpenRenderBoxCxx/Util/assert.hpp>

// Empty path callbacks (all null) - C++ internal linkage
static const ORBPathCallbacks empty_path_callbacks = {
Expand Down Expand Up @@ -53,6 +55,21 @@ void ORBPathRelease(ORBPath path) {

// MARK: - Path Creation

namespace {
ORBPath make_rect(CGRect rect, const CGAffineTransform *transform, ORBPathElement element) {
if (CGRectIsNull(rect)) {
return ORBPathNull;
}
if (transform == nullptr || CGAffineTransformIsIdentity(*transform)) {
// TODO
return ORBPathNull;
} else {
// TODO
return ORBPathNull;
}
}
} /* anonymous namespace */

// TODO: TO be implemented natively

ORBPath ORBPathMakeWithCGPath(CGPathRef cgPath) {
Expand All @@ -67,12 +84,7 @@ ORBPath ORBPathMakeWithCGPath(CGPathRef cgPath) {
}

ORBPath ORBPathMakeRect(CGRect rect, const CGAffineTransform *transform) {
CGPathRef cgPath = CGPathCreateWithRect(rect, transform);
ORBPath path = {
reinterpret_cast<ORBPathStorage *>(const_cast<CGPath *>(cgPath)),
&ORBPathCGPathCallbacks,
};
return path;
return make_rect(rect, transform, ORBPathElementRect);
}

ORBPath ORBPathMakeEllipse(CGRect rect, const CGAffineTransform *transform) {
Expand Down Expand Up @@ -146,3 +158,19 @@ bool ORBPathContainsPoints(ORBPath path, uint64_t count, const CGPoint *points,
}

#endif /* ORB_TARGET_OS_DARWIN */

bool ORBPathApplyElements(ORBPath path, void *info, ORBPathApplyCallback callback) {
auto apply = path.callbacks->apply;
bool flag = false; // TODO: calllbacks's flag to indicate whether it supports extra features
if (flag) {
if (callback == nullptr) {
return true;
}
return apply(path.storage, info, callback/*, path.callbacks*/);
} else {
if (callback == nullptr) {
return true;
}
return apply(path.storage, info, callback);
}
}
26 changes: 19 additions & 7 deletions Sources/OpenRenderBox/Path/ORBPathStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@

using namespace ORB;

namespace ORB {
namespace Path {
namespace {
bool append_element_callback(void * info, ORBPathElement element, const CGFloat *points, const void * _Nullable userInfo) {
reinterpret_cast<Storage *>(info)->append_element(element, points, userInfo);
return true;
}
} /* anonymous namespace */
} /* Path */
} /* ORB */

void ORBPathStorageInit(ORBPathStorageRef dst, uint32_t capacity, ORBPathStorageRef source) {
if (source != nullptr) {
dst->storage = ORB::Path::Storage(capacity, source->storage);
Expand All @@ -24,16 +35,16 @@ void ORBPathStorageClear(ORBPathStorageRef storage) {
storage->storage.clear();
}

bool ORBPathStorageAppendElement(ORBPathStorageRef storage, ORBPathElement element, double const * points, const void * userInfo) {
precondition_failure("TODO");
bool ORBPathStorageAppendElement(ORBPathStorageRef storage, ORBPathElement element, const CGFloat * points, const void * userInfo) {
return storage->storage.append_element(element, points, userInfo);
}

void ORBPathStorageAppendPath(ORBPathStorageRef storage, ORBPath path) {
precondition_failure("TODO");
bool ORBPathStorageAppendPath(ORBPathStorageRef storage, ORBPath path) {
return ORBPathApplyElements(path, storage, ORB::Path::append_element_callback);
}

bool ORBPathStorageApplyElements(ORBPathStorageRef, void *info, ORBPathApplyCallback callback) {
precondition_failure("TODO");
bool ORBPathStorageApplyElements(ORBPathStorageRef storage, void *info, ORBPathApplyCallback callback) {
return storage->storage.apply_elements(info, callback);
}

bool ORBPathStorageIsEmpty(ORBPathStorageRef storage) {
Expand All @@ -59,6 +70,7 @@ CGRect ORBPathStorageGetBoundingRect(ORBPathStorageRef storage) {
}

CGPathRef ORBPathStorageGetCGPath(ORBPathStorageRef storage) {
precondition_failure("TODO");
// FIXME
return storage->storage.cgpath();
}
#endif
80 changes: 73 additions & 7 deletions Sources/OpenRenderBox/Path/PathStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// PathStorage.cpp
// OpenRenderBox

#include <OpenRenderBox/ORBPath.h>
#include <OpenRenderBox/ORBPathCallbacks.h>
#include <OpenRenderBoxCxx/Path/PathStorage.hpp>
#include <OpenRenderBoxCxx/Util/assert.hpp>

Expand All @@ -11,7 +13,7 @@

namespace ORB {
namespace Path {
atomic_long Storage::_last_identifier;
atomic_uint Storage::_last_identifier;

Storage::Storage(uint32_t capacity) {
_unknown = nullptr;
Expand Down Expand Up @@ -59,9 +61,21 @@ Storage::Storage(uint32_t capacity, const Storage &storage): Storage(capacity) {

Storage::~Storage() {
if (_unknown != nullptr) {
auto oldValue = _unknown;
_unknown = nullptr;
// TODO
}
// TODO: MapCache
if (flags().isExternal()) {
#if ORB_TARGET_OS_DARWIN
if (cachedCGPath() != nullptr) {
auto oldCache = cachedCGPath();
_cached_cgPath = nullptr;
CFRelease(oldCache);
}
#endif
free((void *)external_storage());
}
}

bool Storage::operator==(const Storage &other) const ORB_NOEXCEPT {
Expand All @@ -73,16 +87,68 @@ void Storage::clear() {
// TODO
}

void * Storage::cgpath() const ORB_NOEXCEPT {
if (_flags.isInline()) {
bool Storage::append_element(ORBPathElement element, const CGFloat *points, const void *info) {
if (element >= ORBPathElementInvalid) {
precondition_failure("invalid path element: %d", element);
}
// TODO: Implement element appending
precondition_failure("TODO");
}

bool Storage::apply_elements(void *info, ORBPathApplyCallback callback) const ORB_NOEXCEPT {
// TODO: Add fast-path checks for special callbacks:
// - append_element_callback → append_storage(info, this)
// - NestedCallbacks::apply_elements_callback → apply_elements_fast
// - NestedCallbacks::single_element_callback → single_element_fast
// - Mapper::apply_callback with flags check → MapCache::apply
return apply_elements_(info, callback);
}

bool Storage::apply_elements_(void *info, ORBPathApplyCallback callback) const ORB_NOEXCEPT {
// TODO: Implement actual element iteration over storage
return true;
}

#if ORB_TARGET_OS_DARWIN
CGPathRef Storage::cgpath() const ORB_NOEXCEPT {
if (flags().isInline()) {
return nullptr;
}
if (_cached_cgPath != nullptr) {
return _cached_cgPath;
CGPathRef cached = __atomic_load_n(&_cached_cgPath, __ATOMIC_SEQ_CST);
if (cached != nullptr) {
return cached;
}
static const ORBPathCallbacks callbacks = {
nullptr,
nullptr,
nullptr,
+[](const void *object, void *info, ORBPathApplyCallback callback) -> bool {
auto storage = reinterpret_cast<const ORB::Path::Storage *>(object);
return storage->apply_elements(info, callback);
},
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
};
ORBPath path = {
const_cast<ORBPathStorage *>(reinterpret_cast<const ORBPathStorage *>(this)),
&callbacks
};
CGPathRef new_path = ORBPathCopyCGPath(path);
CGPathRef expected = nullptr;
if (__atomic_compare_exchange_n(&_cached_cgPath, &expected, new_path,
false, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) {
return new_path;
} else {
CGPathRelease(new_path);
return expected;
}
// TODO: Create CGPath via RBPathCopyCGPath
return nullptr;
}
#endif

} /* Path */
} /* ORB */
2 changes: 1 addition & 1 deletion Sources/OpenRenderBox/include/OpenRenderBox/ORBBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@

#if !ORB_TRRET_OS_DARWIN
#include "CFCGTypes.h"
#endif
#endif
16 changes: 11 additions & 5 deletions Sources/OpenRenderBox/include/OpenRenderBox/ORBPath.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ typedef ORB_ENUM(int32_t, ORBPathElement) {
ORBPathElementAddQuadCurveToPoint = 2,
ORBPathElementAddCurveToPoint = 3,
ORBPathElementCloseSubpath = 4,

ORBPathElementRect = 5,
ORBPathElementRoundedRect = 6,
ORBPathElementFixedRoundedRectCircular = 8,
ORBPathElementFixedRoundedRectContinuous = 9,
};

ORBPathElementInvalid = 25,
} ORB_SWIFT_NAME(ORBPath.Element);

/// Defines the shape of a rounded rectangle's corners.
typedef ORB_ENUM(int32_t, ORBPathRoundedCornerStyle) {
Expand All @@ -37,7 +40,7 @@ typedef ORB_ENUM(int32_t, ORBPathRoundedCornerStyle) {
/// Returns true to stop enumeration, false to continue
typedef bool (*ORBPathApplyCallback)(void * info, ORBPathElement element, const CGFloat *points, const void * _Nullable userInfo);

typedef struct ORBPathCallbacks ORBPathCallbacks;
typedef struct ORBPathCallbacks ORBPathCallbacks ORB_SWIFT_NAME(ORBPath.ApplyCallback);

typedef struct ORBPathStorage * ORBPathStorageRef ORB_SWIFT_STRUCT ORB_SWIFT_NAME(ORBPath.Storage);

Expand All @@ -55,11 +58,9 @@ ORB_EXPORT
const ORBPath ORBPathNull ORB_SWIFT_NAME(ORBPath.null);

ORB_EXPORT
ORB_REFINED_FOR_SWIFT
void ORBPathRetain(ORBPath path) ORB_SWIFT_NAME(ORBPath.retain(self:));

ORB_EXPORT
ORB_REFINED_FOR_SWIFT
void ORBPathRelease(ORBPath path) ORB_SWIFT_NAME(ORBPath.release(self:));

#if ORB_TARGET_OS_DARWIN
Expand Down Expand Up @@ -95,6 +96,11 @@ ORB_EXPORT
bool ORBPathContainsPoints(ORBPath path, uint64_t count, const CGPoint *points, bool eoFill, const CGAffineTransform * _Nullable transform) ORB_SWIFT_NAME(ORBPath.containsPoints(self:count:points:eoFill:transform:));
#endif

// MARK: - Apply Callback

ORB_EXPORT
bool ORBPathApplyElements(ORBPath path, void * info, _Nullable ORBPathApplyCallback callback) ORB_SWIFT_NAME(ORBPath.apply(self:info:callback:));

ORB_EXTERN_C_END

ORB_ASSUME_NONNULL_END
17 changes: 3 additions & 14 deletions Sources/OpenRenderBox/include/OpenRenderBox/ORBPathStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,53 +18,42 @@ ORB_ASSUME_NONNULL_BEGIN
ORB_EXTERN_C_BEGIN

ORB_EXPORT
ORB_REFINED_FOR_SWIFT
void ORBPathStorageInit(ORBPathStorageRef dst, uint32_t capacity, ORBPathStorageRef _Nullable source) ORB_SWIFT_NAME(ORBPathStorageRef.initialize(self:capacity:source:));

ORB_EXPORT
ORB_REFINED_FOR_SWIFT
void ORBPathStorageDestroy(ORBPathStorageRef storage) ORB_SWIFT_NAME(ORBPathStorageRef.destroy(self:));

ORB_EXPORT
ORB_REFINED_FOR_SWIFT
void ORBPathStorageClear(ORBPathStorageRef storage) ORB_SWIFT_NAME(ORBPathStorageRef.clear(self:));

ORB_EXPORT
ORB_REFINED_FOR_SWIFT
bool ORBPathStorageAppendElement(ORBPathStorageRef storage, ORBPathElement element, CGFloat const * points, const void * _Nullable userInfo) ORB_SWIFT_NAME(ORBPathStorageRef.append(self:element:points:userInfo:));

ORB_EXPORT
ORB_REFINED_FOR_SWIFT
void ORBPathStorageAppendPath(ORBPathStorageRef, ORBPath) ORB_SWIFT_NAME(ORBPathStorageRef.append(self:path:));
bool ORBPathStorageAppendPath(ORBPathStorageRef, ORBPath) ORB_SWIFT_NAME(ORBPathStorageRef.append(self:path:));

ORB_EXPORT
ORB_REFINED_FOR_SWIFT
bool ORBPathStorageApplyElements(ORBPathStorageRef, void *info, ORBPathApplyCallback _Nullable callback) ORB_SWIFT_NAME(ORBPathStorageRef.apply(self:info:callback:));

ORB_EXPORT
ORB_REFINED_FOR_SWIFT
bool ORBPathStorageIsEmpty(ORBPathStorageRef storage) ORB_SWIFT_NAME(getter:ORBPathStorageRef.isEmpty(self:));

ORB_EXPORT
ORB_REFINED_FOR_SWIFT
bool ORBPathStorageEqualToStorage(ORBPathStorageRef lhs, ORBPathStorageRef rhs) ORB_SWIFT_NAME(ORBPathStorageRef.isEqual(self:to:));

ORB_EXPORT
ORB_REFINED_FOR_SWIFT
bool ORBPathStorageIsSingleElement(ORBPathStorageRef storage) ORB_SWIFT_NAME(getter:ORBPathStorageRef.isSingleElement(self:));

ORB_EXPORT
ORB_REFINED_FOR_SWIFT
uint32_t ORBPathStorageGetBezierOrder(ORBPathStorageRef storage) ORB_SWIFT_NAME(getter:ORBPathStorageRef.bezierOrder(self:));

#if ORB_TARGET_OS_DARWIN
ORB_EXPORT
ORB_REFINED_FOR_SWIFT
CGRect ORBPathStorageGetBoundingRect(ORBPathStorageRef storage) ORB_SWIFT_NAME(getter:ORBPathStorageRef.boundingRect(self:));

ORB_EXPORT
ORB_REFINED_FOR_SWIFT
CGPathRef RBPathStorageGetCGPath(ORBPathStorageRef storage) ORB_SWIFT_NAME(getter:ORBPathStorageRef.cgPath(self:));
CF_RETURNS_NOT_RETAINED
__nullable CGPathRef ORBPathStorageGetCGPath(ORBPathStorageRef storage) ORB_SWIFT_NAME(getter:ORBPathStorageRef.cgPath(self:));
#endif

ORB_EXTERN_C_END
Expand Down
2 changes: 0 additions & 2 deletions Sources/OpenRenderBox/include/OpenRenderBox/ORBUUID.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@ ORB_EXTERN_C_BEGIN

#if ORB_TARGET_OS_DARWIN && __OBJC__
ORB_EXPORT
ORB_REFINED_FOR_SWIFT
ORBUUID ORBUUIDInitFromNSUUID(NSUUID *uuid) ORB_SWIFT_NAME(ORBUUID.init(uuid:));
#endif

ORB_EXPORT
ORB_REFINED_FOR_SWIFT
ORBUUID ORBUUIDInitFromHash(uint64_t words0, uint64_t words1, uint32_t words2) ORB_SWIFT_NAME(ORBUUID.init(_:_:_:));

ORB_EXTERN_C_END
Expand Down
Loading