Skip to content

Commit

Permalink
WIP: UILabel
Browse files Browse the repository at this point in the history
  • Loading branch information
XITRIX committed Dec 15, 2024
1 parent 1962ae7 commit 36554a5
Show file tree
Hide file tree
Showing 13 changed files with 265 additions and 37 deletions.
3 changes: 3 additions & 0 deletions Submodules/BuildSkia.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh
bin/gn gen out/ios-arm64-angle --args='is_official_build=false target_cpu="arm64" skia_use_gl=true skia_use_metal=false is_trivial_abi=true target_os="ios"'
bin/gn gen out/mac-arm64-angle --args='is_official_build=false target_cpu="arm64" skia_use_gl=true skia_use_metal=false is_trivial_abi=true skia_use_angle=true'
6 changes: 6 additions & 0 deletions Submodules/UIKit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ add_library(UIKit
lib/CASpringAnimation.cpp
lib/CASpringAnimationPrototype.cpp
lib/CAMediaTimingFunction.cpp
lib/CATextLayer.cpp
lib/CATransaction.cpp
lib/ContentsGravityTransformation.cpp
lib/platforms/SkiaCtx.cpp
Expand Down Expand Up @@ -50,6 +51,11 @@ if (APPLE)
SDL2-static SDL2main
${EXTERN_PATH}/skia/out/mac-arm64-angle/libskia.a
${EXTERN_PATH}/skia/out/mac-arm64-angle/libwindow.a
${EXTERN_PATH}/skia/out/mac-arm64-angle/libicu.a
${EXTERN_PATH}/skia/out/mac-arm64-angle/libskshaper.a
${EXTERN_PATH}/skia/out/mac-arm64-angle/libskunicode_core.a
${EXTERN_PATH}/skia/out/mac-arm64-angle/libskunicode_icu.a
${EXTERN_PATH}/skia/out/mac-arm64-angle/libskparagraph.a
)

target_sources(UIKit PRIVATE
Expand Down
11 changes: 9 additions & 2 deletions Submodules/UIKit/include/CALayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class CALayer: public enable_shared_from_this<CALayer> {
public:
CALayer();
CALayer(CALayer* layer);
~CALayer() {}
virtual ~CALayer() {}

std::weak_ptr<CALayerDelegate> delegate;

Expand Down Expand Up @@ -80,6 +80,8 @@ class CALayer: public enable_shared_from_this<CALayer> {
NXRect getFrame();
void setFrame(NXRect frame);

virtual void draw(SkCanvas* context);

// Layers
[[nodiscard]] std::vector<std::shared_ptr<CALayer>> sublayers() { return _sublayers; }

Expand All @@ -90,7 +92,7 @@ class CALayer: public enable_shared_from_this<CALayer> {

void removeFromSuperlayer();

CALayer* copy();
virtual std::shared_ptr<CALayer> copy();

std::shared_ptr<CAAction> actionForKey(std::string event);
static std::shared_ptr<CABasicAnimation> defaultActionForKey(std::string event);
Expand All @@ -100,6 +102,10 @@ class CALayer: public enable_shared_from_this<CALayer> {
std::shared_ptr<CALayer> presentation() { return _presentation; }
std::shared_ptr<CALayer> presentationOrSelf();

bool needsDisplay() { return _needsDisplay; }
void setNeedsDisplay() { _needsDisplay = true; }
void display();

// Animations
void add(std::shared_ptr<CABasicAnimation> animation, std::string keyPath);
void removeAnimation(std::string forKey);
Expand All @@ -124,6 +130,7 @@ class CALayer: public enable_shared_from_this<CALayer> {
std::shared_ptr<CALayer> _mask;

bool _isHidden = false;
bool _needsDisplay = true;

std::shared_ptr<CGImage> _contents;
bool _masksToBounds = false;
Expand Down
41 changes: 41 additions & 0 deletions Submodules/UIKit/include/CATextLayer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include <CALayer.h>
#include <SkiaCtx.h>
#include <include/core/SkFont.h>
#include <include/core/SkTypeface.h>
#include <modules/skparagraph/include/Paragraph.h>
#include <modules/skparagraph/include/ParagraphBuilder.h>

namespace NXKit {

class CATextLayer: public CALayer {
public:
CATextLayer();
CATextLayer(CATextLayer* layer);
virtual ~CATextLayer() = default;

void draw(SkCanvas* context) override;
std::shared_ptr<CALayer> copy() override;

void setText(std::string text);
[[nodiscard]] std::string text() const { return _text; }

void setTextColor(UIColor textColor);
[[nodiscard]] UIColor textColor() const { return _textColor; }
private:
std::string _text = "Furthermore, العربية نص جميل. द क्विक ब्राउन फ़ॉक्स jumps over the lazy 🐕.";
UIColor _textColor = UIColor::black;

// Skia
sk_sp<SkTypeface> typeface;
skia::textlayout::ParagraphStyle paraStyle;
sk_sp<skia::textlayout::FontCollection> fontCollection;
sk_sp<SkUnicode> unicode;
std::unique_ptr<skia::textlayout::ParagraphBuilder> paragraphBuilder;
std::unique_ptr<skia::textlayout::Paragraph> paragraph;

void updateParagraph();
};

}
4 changes: 3 additions & 1 deletion Submodules/UIKit/include/UIColor.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <Geometry.h>
#include <stdint.h>

namespace NXKit {

Expand All @@ -18,6 +19,7 @@ class UIColor {
bool operator==(const UIColor& rhs) const;

UIColor interpolationTo(UIColor endResult, NXFloat progress);
uint32_t raw() const { return color; }

static UIColor clear;
static UIColor red;
Expand All @@ -37,7 +39,7 @@ class UIColor {

private:
friend class CALayer;
int color;
uint32_t color;
};

}
4 changes: 3 additions & 1 deletion Submodules/UIKit/include/UILabel.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
#pragma once

#include <UIView.h>
#include <include/core/SkTypeface.h>

namespace NXKit {

class UILabel: public UIView {
public:
UILabel();
private:
int _numberOfLines = 1;
std::string _text;
UIColor _textColor = UIColor::black;
};

}
}
27 changes: 22 additions & 5 deletions Submodules/UIKit/include/UIView.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace NXKit {
class UIView: public CALayerDelegate, public enable_shared_from_this<UIView> {
public:
UIView(): UIView(NXRect()) {}
UIView(NXRect frame);
UIView(NXRect frame, std::shared_ptr<CALayer> layer = new_shared<CALayer>());

void setFrame(NXRect frame);
[[nodiscard]] NXRect frame() const { return _layer->getFrame(); }
Expand Down Expand Up @@ -41,6 +41,9 @@ class UIView: public CALayerDelegate, public enable_shared_from_this<UIView> {
void setContentMode(UIViewContentMode mode);
[[nodiscard]] UIViewContentMode contentMode() const { return _contentMode; }

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

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 @@ -51,9 +54,19 @@ class UIView: public CALayerDelegate, public enable_shared_from_this<UIView> {
const std::vector<std::shared_ptr<UIView>>& subviews() const { return _subviews; }
std::weak_ptr<UIView> superview() const { return _superview; }

virtual std::shared_ptr<CALayer> initLayer();
std::shared_ptr<CALayer> layer() const { return _layer; };

// Layout
void setNeedsDisplay() { _needsDisplay = true; }
void setNeedsLayout();// { setNeedsDisplay(); _needsLayout = true; }
//
// void layoutIfNeeded();
// virtual void layoutSubviews();
//
// virtual Size sizeThatFits(Size size);
// virtual void sizeToFit();

void drawAndLayoutTreeIfNeeded();

// Animations
static std::set<std::shared_ptr<CALayer>> layersWithAnimations;
Expand All @@ -66,7 +79,8 @@ class UIView: public CALayerDelegate, public enable_shared_from_this<UIView> {
std::function<void(bool)> completion = [](bool res){});

static void animate(double duration,
std::function<void()> animations = [](){});
std::function<void()> animations,
std::function<void(bool)> completion = [](bool res){});

static void animate(double duration,
double delay,
Expand All @@ -80,16 +94,19 @@ class UIView: public CALayerDelegate, public enable_shared_from_this<UIView> {
static void completePendingAnimations();

std::shared_ptr<CABasicAnimation> actionForKey(std::string event) override;
// virtual void draw() {}
virtual void draw() {}
virtual void display(std::shared_ptr<CALayer> layer) override;
private:
std::vector<std::shared_ptr<UIView>> _subviews;
std::weak_ptr<UIView> _superview;
std::shared_ptr<CALayer> _layer;
std::shared_ptr<UIView> _mask;
UIViewContentMode _contentMode;

bool _isUserInteractionEnabled = true;

bool _needsLayout = true;
bool _needsDisplay = true;

void setSuperview(std::shared_ptr<UIView> superview);
bool anyCurrentlyRunningAnimationsAllowUserInteraction();
};
Expand Down
18 changes: 13 additions & 5 deletions Submodules/UIKit/lib/CALayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ void CALayer::removeFromSuperlayer() {
CALayer::layerTreeIsDirty = true;
}

void CALayer::draw(SkCanvas* context) {}

void CALayer::skiaRender(SkCanvas* canvas) {
// Do not render is hidden
if (_isHidden || _opacity < 0.001f) return;
Expand Down Expand Up @@ -239,6 +241,8 @@ void CALayer::skiaRender(SkCanvas* canvas) {
canvas->restore();
}

draw(canvas);

// Reset Anchor to Origin matrix
// Origin matrix save 2 // restore
canvas->restore();
Expand Down Expand Up @@ -286,8 +290,8 @@ void CALayer::setFrame(NXRect frame) {
setBounds(bounds);
}

CALayer* CALayer::copy() {
return new CALayer(this);
std::shared_ptr<CALayer> CALayer::copy() {
return new_shared<CALayer>(this);
}

std::shared_ptr<CAAction> CALayer::actionForKey(std::string event) {
Expand All @@ -302,9 +306,13 @@ std::shared_ptr<CABasicAnimation> CALayer::defaultActionForKey(std::string event
}

std::shared_ptr<CALayer> CALayer::createPresentation() {
auto copy = new_shared<CALayer>(this);
copy->isPresentationForAnotherLayer = true;
return copy;
auto _copy = copy();
_copy->isPresentationForAnotherLayer = true;
return _copy;
}

void CALayer::display() {
if (!delegate.expired()) delegate.lock()->display(shared_from_this());
}

// MARK: - Animations
Expand Down
71 changes: 71 additions & 0 deletions Submodules/UIKit/lib/CATextLayer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <CATextLayer.h>
#include <modules/skunicode/include/SkUnicode_icu.h>

using namespace NXKit;
using namespace skia::textlayout;

CATextLayer::CATextLayer(): CALayer() {
auto fontMgr = SkiaCtx::main()->getFontMgr();

SkFontStyle fontStyle;
typeface = SkiaCtx::main()->getFontMgr()->matchFamilyStyle(nullptr, fontStyle);

fontCollection = sk_make_sp<FontCollection>();
fontCollection->setDefaultFontManager(SkiaCtx::main()->getFontMgr());

unicode = SkUnicodes::ICU::Make();

paragraphBuilder = ParagraphBuilder::make(paraStyle, fontCollection, unicode);
updateParagraph();
}

CATextLayer::CATextLayer(CATextLayer* layer): CALayer(layer) {
typeface = layer->typeface;
paraStyle = layer->paraStyle;
fontCollection = layer->fontCollection;
unicode = layer->unicode;

paragraphBuilder = ParagraphBuilder::make(paraStyle, fontCollection, unicode);
updateParagraph();
}

std::shared_ptr<CALayer> CATextLayer::copy() {
return new_shared<CATextLayer>(this);
}

void CATextLayer::draw(SkCanvas* context) {
paragraph->layout(bounds().size.width);
paragraph->paint(context, 0, 0);
}

void CATextLayer::setText(std::string text) {
if (_text == text) return;
_text = text;
updateParagraph();
}

void CATextLayer::setTextColor(UIColor textColor) {
if (_textColor == textColor) return;
_textColor = textColor;
updateParagraph();
}

void CATextLayer::updateParagraph() {
paragraphBuilder->Reset();

SkPaint paint;
paint.setAntiAlias(true);
paint.setColor(_textColor.raw());

skia::textlayout::TextStyle style;
style.setForegroundColor(paint);
style.setTypeface(typeface);
style.setFontSize(17);

paraStyle.setTextStyle(style);
paraStyle.setTextAlign(TextAlign::kRight);

paragraphBuilder->addText(_text.c_str());

paragraph = paragraphBuilder->Build();
}
7 changes: 4 additions & 3 deletions Submodules/UIKit/lib/UIApplicationMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ bool applicationRunLoop() {
// UIRenderer::main()->render(UIApplication::shared->keyWindow.lock(), currentTime);


UIView::animateIfNeeded(currentTime);
// Move to UIRenderer
auto keyWindow = UIApplication::shared->keyWindow.lock();

UIView::animateIfNeeded(currentTime);
keyWindow->drawAndLayoutTreeIfNeeded();

// Move to UIRenderer
auto surface = SkiaCtx::_main->getBackbufferSurface();
if (!surface) return true;

Expand All @@ -28,7 +30,6 @@ bool applicationRunLoop() {
canvas->save();
auto scale = SkiaCtx::_main->getScaleFactor();
canvas->scale(scale, scale);
auto keyWindow = UIApplication::shared->keyWindow.lock();

keyWindow->layer()->setBounds({ NXPoint::zero, SkiaCtx::_main->getSize() } );
keyWindow->layer()->presentationOrSelf()->skiaRender(canvas);
Expand Down
8 changes: 8 additions & 0 deletions Submodules/UIKit/lib/UILabel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include <UILabel.h>
#include <CATextLayer.h>

using namespace NXKit;

UILabel::UILabel(): UIView(NXRect(), new_shared<CATextLayer>()) {

}
Loading

0 comments on commit 36554a5

Please sign in to comment.