Skip to content

Commit

Permalink
Cache for UILabel
Browse files Browse the repository at this point in the history
  • Loading branch information
XITRIX committed Dec 17, 2024
1 parent 74d7068 commit 123bf32
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 17 deletions.
33 changes: 22 additions & 11 deletions Submodules/UIKit/include/UILabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,37 @@ class UILabel: public UIView {
public:
UILabel();

void setText(std::string text) { _textLayer()->setText(text); }
[[nodiscard]] std::string text() const { return _textLayer()->text(); }
void draw() override;

void setTextColor(UIColor textColor) { _textLayer()->setTextColor(textColor); }
[[nodiscard]] UIColor textColor() const { return _textLayer()->textColor(); }
void setText(std::string text);
[[nodiscard]] std::string text() const { return _text; }

void setFontSize(NXFloat fontSize) { _textLayer()->setFontSize(fontSize); }
[[nodiscard]] NXFloat fontSize() const { return _textLayer()->fontSize(); }
void setTextColor(UIColor textColor);
[[nodiscard]] UIColor textColor() const { return _textColor; }

void setTextAlignment(NSTextAlignment textAlignment) { _textLayer()->setTextAlignment(textAlignment); }
[[nodiscard]] NSTextAlignment textAlignment() const { return _textLayer()->textAlignment(); }
void setFontSize(NXFloat fontSize);
[[nodiscard]] NXFloat fontSize() const { return _fontSize; }

void setFontWeight(NXFloat fontWeight) { _textLayer()->setFontWeight(fontWeight); }
[[nodiscard]] NXFloat fontWeight() const { return _textLayer()->fontWeight(); }
void setTextAlignment(NSTextAlignment textAlignment);
[[nodiscard]] NSTextAlignment textAlignment() const { return _textAlignment; }

void setFontWeight(NXFloat fontWeight);
[[nodiscard]] NXFloat fontWeight() const { return _fontWeight; }

NXSize sizeThatFits(NXSize size) override;

private:
int _numberOfLines = 1;
std::shared_ptr<CATextLayer> _textLayer() const;
NXFloat _fontSize = 17;
NXFloat _fontWeight = SkFontStyle::kNormal_Weight;
NSTextAlignment _textAlignment = NSTextAlignment::left;
std::string _text = "Furthermore, العربية نص جميل. द क्विक ब्राउन फ़ॉक्स jumps over the lazy 🐕.";
UIColor _textColor = UIColor::black;

sk_sp<SkUnicode> unicode;
std::unique_ptr<skia::textlayout::Paragraph> paragraph;

void updateParagraph();
};

}
3 changes: 1 addition & 2 deletions Submodules/UIKit/include/UIView.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ class UIWindow;
class UIViewController;
class UIView: public CALayerDelegate, public enable_shared_from_this<UIView> {
public:
UIView(): UIView(NXRect()) {}
UIView(NXRect frame, std::shared_ptr<CALayer> layer = new_shared<CALayer>());
UIView(NXRect frame = NXRect(), std::shared_ptr<CALayer> layer = new_shared<CALayer>());

void setFrame(NXRect frame);
[[nodiscard]] NXRect frame() const { return _layer->getFrame(); }
Expand Down
105 changes: 101 additions & 4 deletions Submodules/UIKit/lib/UILabel.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,110 @@
#include <UILabel.h>
#include <include/core/SkBitmap.h>
#include <modules/skunicode/include/SkUnicode_icu.h>

using namespace NXKit;
using namespace skia::textlayout;

UILabel::UILabel(): UIView(NXRect(), new_shared<CATextLayer>()) {}
UILabel::UILabel(): UIView() {
unicode = SkUnicodes::ICU::Make();
}

void UILabel::setText(std::string text) {
if (_text == text) return;
_text = text;
setNeedsLayout();
}

std::shared_ptr<CATextLayer> UILabel::_textLayer() const {
return std::static_pointer_cast<CATextLayer>(layer());
void UILabel::setTextColor(UIColor textColor) {
if (_textColor == textColor) return;
_textColor = textColor;
setNeedsLayout();
}

void UILabel::setFontSize(NXFloat fontSize) {
if (_fontSize == fontSize) return;
_fontSize = fontSize;
setNeedsLayout();
}

void UILabel::setTextAlignment(NSTextAlignment textAlignment) {
if (_textAlignment == textAlignment) return;
_textAlignment = textAlignment;
setNeedsLayout();
}

void UILabel::setFontWeight(NXFloat fontWeight) {
if (_fontWeight == fontWeight) return;
_fontWeight = fontWeight;
setNeedsLayout();
}

NXSize UILabel::sizeThatFits(NXSize size) {
return _textLayer()->sizeThatFits(size);
updateParagraph();
paragraph->layout(size.width);
auto height = paragraph->getHeight();
auto width = paragraph->getMaxIntrinsicWidth();
auto rWidth = std::ceil(width);
return { rWidth, height };
}

void UILabel::draw() {
updateParagraph();

SkBitmap bitmap;
auto scale = SkiaCtx::main()->getScaleFactor();
auto size = layer()->presentationOrSelf()->bounds().size;
auto bitmapSize = size * scale;
bitmap.allocPixels(SkImageInfo::MakeN32Premul(bitmapSize.width, bitmapSize.height));
SkCanvas canvas(bitmap);

canvas.scale(scale, scale);
paragraph->layout(size.width);
paragraph->paint(&canvas, 0, 0);

layer()->setContents(new_shared<CGImage>(bitmap.asImage()));
}

void UILabel::updateParagraph() {
SkFontStyle fontStyle;
auto typeface = SkiaCtx::main()->getFontMgr()->matchFamilyStyle(nullptr, fontStyle);

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

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

skia::textlayout::TextStyle style;
style.setForegroundColor(paint);
style.setTypeface(typeface);
style.setFontSize(_fontSize);
style.setFontStyle(SkFontStyle(_fontWeight, SkFontStyle::kNormal_Width,
SkFontStyle::kUpright_Slant));

ParagraphStyle paraStyle;
paraStyle.setTextStyle(style);
switch (_textAlignment) {
case NSTextAlignment::left:
paraStyle.setTextAlign(TextAlign::kLeft);
break;
case NSTextAlignment::right:
paraStyle.setTextAlign(TextAlign::kRight);
break;
case NSTextAlignment::center:
paraStyle.setTextAlign(TextAlign::kCenter);
break;
case NSTextAlignment::justified:
paraStyle.setTextAlign(TextAlign::kJustify);
break;
case NSTextAlignment::natural:
paraStyle.setTextAlign(TextAlign::kStart);
break;
}

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

paragraphBuilder->addText(_text.c_str());
paragraph = paragraphBuilder->Build();
}
8 changes: 8 additions & 0 deletions Submodules/UIKit/lib/UIView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ void UIView::drawAndLayoutTreeIfNeeded() {

if (visibleLayer->isHidden() || visibleLayer->opacity() < 0.01f) { return; }

if (_contentMode == UIViewContentMode::redraw) {
if (visibleLayer->contents() && visibleLayer->contents()->size() != visibleLayer->bounds().size) {
setNeedsDisplay();
}
}

if (visibleLayer->_needsDisplay) {
visibleLayer->display();
visibleLayer->_needsDisplay = false;
Expand Down Expand Up @@ -149,6 +155,8 @@ void UIView::setMask(std::shared_ptr<UIView> mask) {
}

void UIView::setContentMode(UIViewContentMode mode) {
if (_contentMode == mode) return;
_contentMode = mode;
switch (mode) {
case UIViewContentMode::scaleToFill:
_layer->setContentsGravity(CALayerContentsGravity::resize);
Expand Down
1 change: 1 addition & 0 deletions app/Screens/TestViewController/TestViewController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ void TestViewController::loadView() {
label->setText("Привет\nебать,\nэто\nкириллица,\nнахуй!!!!");
label->setTextAlignment(NSTextAlignment::center);
label->setBackgroundColor(UIColor::red);
label->setContentMode(NXKit::UIViewContentMode::redraw);
rootView->addSubview(label);

auto blur = new_shared<UIBlurView>();
Expand Down

0 comments on commit 123bf32

Please sign in to comment.