Skip to content

Commit

Permalink
WIP: CGImage
Browse files Browse the repository at this point in the history
  • Loading branch information
XITRIX committed Dec 14, 2024
1 parent 2781952 commit bc48a8f
Show file tree
Hide file tree
Showing 13 changed files with 283 additions and 115 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ set(PROJECT_ICON ${CMAKE_CURRENT_SOURCE_DIR}/resources/img/moonlight_icon.jpg)
set(PROJECT_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/resources)
set(CMAKE_CXX_STANDARD 17)

add_libromfs(${PROJECT_NAME} ${PROJECT_RESOURCES})

add_executable(${PROJECT_NAME}
app/main.cpp
app/AppDelegate.cpp
)

setup_project()

target_link_libraries(${PROJECT_NAME} PRIVATE
target_link_libraries(${PROJECT_NAME}
UIKit
)

Expand Down
12 changes: 12 additions & 0 deletions Submodules/UIKit/include/CALayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,21 @@ class CALayer: public enable_shared_from_this<CALayer> {
void setTransform(NXTransform3D transform);
[[nodiscard]] NXTransform3D transform() const { return _transform; }

void setAffineTransform(NXAffineTransform transform);
[[nodiscard]] NXAffineTransform affineTransform();

void setMask(std::shared_ptr<CALayer> mask);
[[nodiscard]] std::shared_ptr<CALayer> mask() const { return _mask; }

void setMasksToBounds(bool newValue) { _masksToBounds = newValue; }
[[nodiscard]] bool masksToBounds() { return _masksToBounds; }

void setContents(std::shared_ptr<CGImage> contents);
[[nodiscard]] std::shared_ptr<CGImage> contents() { return _contents; }

void setHidden(bool hidden);
[[nodiscard]] bool isHidden() const { return _isHidden; }

NXRect getFrame();
void setFrame(NXRect frame);

Expand Down Expand Up @@ -84,7 +93,10 @@ class CALayer: public enable_shared_from_this<CALayer> {
std::vector<std::shared_ptr<CALayer>> _sublayers;
std::shared_ptr<CALayer> _mask;

bool _isHidden = false;

std::shared_ptr<CGImage> _contents;
bool _masksToBounds = false;

// Animatable
NXPoint _anchorPoint = NXPoint(0.5, 0.5);
Expand Down
8 changes: 4 additions & 4 deletions Submodules/UIKit/include/CGImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ class CGImage {
sk_sp<SkImage> pointee;

// CGImage(NXSize size);
CGImage(const NXData& sourceData);
CGImage(std::shared_ptr<NXData> sourceData);
// CGImage(SDL_Surface* surface);
CGImage(sk_sp<SkImage> image, std::optional<NXData> sourceData);
CGImage(sk_sp<SkImage> image): CGImage(image, std::nullopt) {}
CGImage(sk_sp<SkImage> image, std::shared_ptr<NXData> sourceData);
CGImage(sk_sp<SkImage> image): CGImage(image, nullptr) {}
~CGImage();

[[nodiscard]] NXSize size() const;
private:
std::optional<NXData> sourceData;
std::shared_ptr<NXData> sourceData;
};
}
48 changes: 31 additions & 17 deletions Submodules/UIKit/include/Geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct NXSize {
NXSize(NXFloat width, NXFloat height);

bool operator==(const NXSize &rhs) const;
bool operator!=(const NXSize &rhs) const;

NXSize operator+(const NXSize &first) const;
NXSize operator-(const NXSize &first) const;
Expand All @@ -57,33 +58,46 @@ struct NXRect {

NXRect();
NXRect(NXPoint origin, NXSize size);
NXRect(NXFloat x, NXFloat y, NXFloat width, NXFloat height);
NXRect(float x, float y, float width, float height);

NXFloat width() const;
NXFloat height() const;
float width() const;
float height() const;

NXFloat minX() const;
NXFloat midX() const;
NXFloat maxX() const;
float minX() const;
float midX() const;
float maxX() const;

NXFloat minY() const;
NXFloat midY() const;
NXFloat maxY() const;
float minY() const;
float midY() const;
float maxY() const;

void setWidth(float newValue);
void setHeight(float newValue);

void setMinX(float newValue);
void setMidX(float newValue);
void setMaxX(float newValue);

void setMinY(float newValue);
void setMidY(float newValue);
void setMaxY(float newValue);

bool contains(NXPoint point);
bool intersects(const NXRect& other) const;
NXRect intersection(const NXRect& other) const;
NXRect& offsetBy(const NXPoint& offset);
NXRect& offsetBy(const NXFloat& offsetX, const NXFloat& offsetY);
// NXRect& insetBy(const UIEdgeInsets& insets);
NXRect applying(const NXAffineTransform& t) const;
NXRect applying(const NXTransform3D& t) const;
NXRect& offsetBy(const float& offsetX, const float& offsetY);

bool operator==(const NXRect& rhs);
bool operator==(const NXRect& rhs) const;
NXRect operator+(const NXRect& rhs) const;
NXRect operator-(const NXRect& rhs) const;
NXRect operator*(const float& rhs) const;

bool valid();
NXRect applying(NXAffineTransform transform);
NXRect applying(NXTransform3D transform);

NXRect intersection(NXRect other) const;

static NXRect zero;
bool isNull() const;
static NXRect null;
};

Expand Down
8 changes: 4 additions & 4 deletions Submodules/UIKit/include/NXData.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ namespace NXKit {

class NXData {
public:
int count() const;
uint8_t* data() const;
std::size_t count() const;
const std::byte* data() const;

NXData(uint8_t* bytes, int count, bool freeSource = false);
NXData(const std::byte* bytes, std::size_t count, bool freeSource = false);
~NXData();

static std::optional<NXData> fromPath(const std::string& path);
private:
std::vector<uint8_t> _data;
std::vector<std::byte> _data;
};

}
26 changes: 25 additions & 1 deletion Submodules/UIKit/include/UIView.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,30 @@ class UIView: public enable_shared_from_this<UIView> {
public:
UIView();

void setFrame(NXRect frame);
NXRect frame() const { return _layer->getFrame(); }

void setBounds(NXRect bounds);
NXRect bounds() const { return _layer->bounds(); }

void setCenter(NXPoint position);
NXPoint center() const;

void setAlpha(NXFloat alpha) { _layer->setOpacity(alpha); }
NXFloat alpha() const { return _layer->opacity(); }

void setHidden(bool hidden) { _layer->setHidden(hidden); }
bool isHidden() const { return _layer->isHidden(); }

void setClipsToBounds(bool clipsToBounds) { _layer->setMasksToBounds(clipsToBounds); }
bool clipsToBounds() const { return _layer->masksToBounds(); }

void setTransform(NXAffineTransform transform) { _layer->setAffineTransform(transform); }
NXAffineTransform transform() const { return _layer->affineTransform(); }

void setBackgroundColor(std::optional<UIColor> backbroundColor) { _layer->setBackgroundColor(backbroundColor); }
std::optional<UIColor> backgroundColor() const { return _layer->backgroundColor(); }

virtual void addSubview(std::shared_ptr<UIView> view);
void insertSubviewAt(std::shared_ptr<UIView> view, int index);
void insertSubviewBelow(std::shared_ptr<UIView> view, std::shared_ptr<UIView> belowSubview);
Expand All @@ -27,4 +51,4 @@ class UIView: public enable_shared_from_this<UIView> {
void setSuperview(std::shared_ptr<UIView> superview);
};

}
}
76 changes: 62 additions & 14 deletions Submodules/UIKit/lib/CALayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#include "CALayer.h"
#include "include/core/SkRRect.h"

#include "include/effects/SkGradientShader.h"
#include "include/effects/SkImageFilters.h"

using namespace NXKit;

bool CALayer::layerTreeIsDirty = true;
Expand Down Expand Up @@ -59,6 +62,19 @@ void CALayer::setTransform(NXTransform3D transform) {
_transform = transform;
}

void CALayer::setAffineTransform(NXAffineTransform transform) {
this->setTransform(NXTransform3DMakeAffineTransform(transform));
}

NXAffineTransform CALayer::affineTransform() {
return NXTransform3DGetAffineTransform(_transform);
}

void CALayer::setHidden(bool hidden) {
_isHidden = hidden;
CALayer::layerTreeIsDirty = true;
}

void CALayer::setContents(std::shared_ptr<CGImage> contents) {
_contents = contents;
CALayer::layerTreeIsDirty = true;
Expand Down Expand Up @@ -133,6 +149,11 @@ void CALayer::skiaRender(SkCanvas* canvas) {
paint.setAntiAlias(true);
SkRect rect = SkRect::MakeXYWH(0, 0, _bounds.width(), _bounds.height());

// Opacity enable
if (_opacity < 1) {
canvas->saveLayerAlphaf(nullptr, _opacity);
}

// Background color
if (_backgroundColor.has_value()) {
paint.setColor(_backgroundColor->color);
Expand All @@ -147,27 +168,33 @@ void CALayer::skiaRender(SkCanvas* canvas) {
// Content
if (_contents) {
auto contentsGravity = ContentsGravityTransformation(this);
canvas->drawImageRect(_contents.get()->pointee, rect, SkSamplingOptions());
// GPU_SetAnchor(_contents->pointee, _anchorPoint.x, _anchorPoint.y);
// GPU_SetRGBA(_contents->pointee, 255, 255, 255, _opacity * 255);
//
// GPU_BlitTransform(
// _contents->pointee,
// NULL,
// renderer,
// contentsGravity.offset.x,
// contentsGravity.offset.y,
// 0, // rotation in degrees
// contentsGravity.scale.width / contentsScale,
// contentsGravity.scale.height / contentsScale
// );
auto width = _contents->size().width * contentsGravity.scale.width / _contentsScale;
auto height = _contents->size().height * contentsGravity.scale.height / _contentsScale;
auto x = (_bounds.size.width - width) / 2.0 + contentsGravity.offset.x;
auto y = (_bounds.size.height - height) / 2.0 + contentsGravity.offset.y;

canvas->save();
canvas->translate(x, y);

canvas->drawImageRect(_contents.get()->pointee, {
float(0),
float(0),
float(width),
float(height)
}, SkSamplingOptions(), nullptr);

canvas->restore();
}

// Reset Anchor to Origin matrix
canvas->restore();
for (const auto& sublayer: _sublayers) {
sublayer->skiaRender(canvas);
}
// Opacity disable
if (_opacity < 1) {
canvas->restore();
}

canvas->restore();
}
Expand All @@ -187,6 +214,27 @@ NXRect CALayer::getFrame() {
transformedBounds.height());
}

void CALayer::setFrame(NXRect frame) {
setPosition(NXPoint(frame.origin.x + (frame.width() * _anchorPoint.x),
frame.origin.y + (frame.height() * _anchorPoint.y)));

auto inverseTransformOpt = affineTransform().inverted();
if (!inverseTransformOpt.has_value()) {
// assertionFailure("You tried to set the frame of a CALayer whose transform cannot be inverted. This is undefined behaviour.");
return;
}
auto inverseTransform = inverseTransformOpt.value();


// If we are shrinking the view with a transform and then setting a
// new frame, the layer's actual `bounds` is bigger (and vice-versa):
auto nonTransformedBoundSize = frame.applying(inverseTransform).size;

auto bounds = _bounds;
bounds.size = nonTransformedBoundSize;
setBounds(bounds);
}

void CALayer::onWillSet(std::string keyPath) {
CALayer::layerTreeIsDirty = true;
auto animationKey = keyPath;
Expand Down
16 changes: 9 additions & 7 deletions Submodules/UIKit/lib/CGImage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,23 @@ using namespace NXKit;
//// GPU_SetBlendMode(pointee, GPU_BLEND_NORMAL_FACTOR_ALPHA);
//}

CGImage::CGImage(sk_sp<SkImage> image, std::optional<NXData> sourceData) {
this->sourceData = std::move(sourceData);
CGImage::CGImage(sk_sp<SkImage> image, std::shared_ptr<NXData> sourceData) {
this->sourceData = sourceData;
pointee = image;

// GPU_SetSnapMode(pointee, GPU_SNAP_POSITION_AND_DIMENSIONS);
// GPU_SetBlendMode(pointee, GPU_BLEND_NORMAL_FACTOR_ALPHA);
// GPU_SetImageFilter(pointee, GPU_FILTER_LINEAR);
}

CGImage::CGImage(const NXData& sourceData) {
auto data = sourceData;
auto dataCount = data.count();
CGImage::CGImage(std::shared_ptr<NXData> sourceData) {
auto data = sourceData->data();
auto dataCount = sourceData->count();

auto skData = SkData::MakeFromMalloc(data.data(), data.count());
auto skData = SkData::MakeWithoutCopy(data, dataCount);
auto image = SkImages::DeferredFromEncodedData(skData);

new (this) CGImage(image, data);
new (this) CGImage(image, sourceData);
}

//CGImage::CGImage(SDL_Surface* surface) {
Expand All @@ -39,6 +39,8 @@ CGImage::CGImage(const NXData& sourceData) {
//}

CGImage::~CGImage() {
sourceData = nullptr;
pointee = nullptr;
// GPU_FreeTarget(pointee->target);
// GPU_FreeImage(pointee);
}
Expand Down
Loading

0 comments on commit bc48a8f

Please sign in to comment.