aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-10-20 17:04:27 +0800
committercrupest <crupest@outlook.com>2021-10-20 17:04:27 +0800
commit152133978872f6d6476c3fc7e0e3a5a6cc23b119 (patch)
tree374a793cb56ef5c8d1e413f4b781fec087e28678 /src
parent398aadcddb8b6ed20b17f6c56cd7b49947b72136 (diff)
downloadcru-152133978872f6d6476c3fc7e0e3a5a6cc23b119.tar.gz
cru-152133978872f6d6476c3fc7e0e3a5a6cc23b119.tar.bz2
cru-152133978872f6d6476c3fc7e0e3a5a6cc23b119.zip
...
Diffstat (limited to 'src')
-rw-r--r--src/osx/graphics/quartz/Font.cpp1
-rw-r--r--src/osx/graphics/quartz/Painter.cpp29
-rw-r--r--src/osx/graphics/quartz/TextLayout.cpp105
3 files changed, 108 insertions, 27 deletions
diff --git a/src/osx/graphics/quartz/Font.cpp b/src/osx/graphics/quartz/Font.cpp
index 596489e4..72d6d56d 100644
--- a/src/osx/graphics/quartz/Font.cpp
+++ b/src/osx/graphics/quartz/Font.cpp
@@ -13,6 +13,7 @@ OsxCTFont::OsxCTFont(IGraphicsFactory* graphics_factory, const String& name,
CFStringRef n = Convert(name);
ct_font_ = CTFontCreateWithName(n, size, nullptr);
+ Ensures(ct_font_);
CFRelease(n);
}
diff --git a/src/osx/graphics/quartz/Painter.cpp b/src/osx/graphics/quartz/Painter.cpp
index 0dc9e786..3f859571 100644
--- a/src/osx/graphics/quartz/Painter.cpp
+++ b/src/osx/graphics/quartz/Painter.cpp
@@ -6,6 +6,7 @@
#include "cru/osx/graphics/quartz/Geometry.hpp"
#include "cru/osx/graphics/quartz/TextLayout.hpp"
#include "cru/platform/Check.hpp"
+#include "cru/platform/Color.hpp"
#include "cru/platform/Exception.hpp"
#include "cru/platform/graphics/util/Painter.hpp"
@@ -118,20 +119,38 @@ void QuartzCGContextPainter::DrawText(const Point& offset,
Validate();
auto tl = CheckPlatform<OsxCTTextLayout>(text_layout, GetPlatformId());
- auto b = CheckPlatform<QuartzBrush>(brush, GetPlatformId());
+
+ Color color;
+
+ if (auto b = dynamic_cast<QuartzSolidColorBrush*>(brush)) {
+ color = b->GetColor();
+ } else {
+ color = colors::black;
+ }
util::WithTransform(this, Matrix::Translation(offset),
- [this, tl, b](IPainter*) {
- CTFrameDraw(tl->GetCTFrameRef(), cg_context_);
+ [this, tl, color](IPainter*) {
+ auto frame = tl->CreateFrameWithColor(color);
+ Ensures(frame);
+ CTFrameDraw(frame, cg_context_);
+ CFRelease(frame);
});
}
void QuartzCGContextPainter::PushLayer(const Rect& bounds) {
- // TODO: Implement this.
+ Validate();
+ clip_stack_.push_back(bounds);
+ CGContextClipToRect(cg_context_, Convert(bounds));
}
void QuartzCGContextPainter::PopLayer() {
- // TODO: Implement this.
+ Validate();
+ clip_stack_.pop_back();
+ if (clip_stack_.empty()) {
+ CGContextResetClip(cg_context_);
+ } else {
+ CGContextClipToRect(cg_context_, Convert(clip_stack_.back()));
+ }
}
void QuartzCGContextPainter::EndDraw() { DoEndDraw(); }
diff --git a/src/osx/graphics/quartz/TextLayout.cpp b/src/osx/graphics/quartz/TextLayout.cpp
index 6c6644e5..d96cf025 100644
--- a/src/osx/graphics/quartz/TextLayout.cpp
+++ b/src/osx/graphics/quartz/TextLayout.cpp
@@ -18,40 +18,62 @@ OsxCTTextLayout::OsxCTTextLayout(IGraphicsFactory* graphics_factory,
max_height_(0.f),
font_(std::move(font)),
text_(str) {
- cf_text_ = Convert(str);
+ Expects(font_);
+
+ CFStringRef s = Convert(text_);
+ CFDictionaryRef attributes =
+ CFDictionaryCreateMutable(nullptr, 0, nullptr, nullptr);
+
+ Ensures(s);
+ Ensures(attributes);
+
+ cf_attributed_text_ = CFAttributedStringCreate(nullptr, s, attributes);
+ Ensures(cf_attributed_text_);
+
+ CFRelease(attributes);
+ CFRelease(s);
RecreateFrame();
}
-OsxCTTextLayout::~OsxCTTextLayout() {}
+OsxCTTextLayout::~OsxCTTextLayout() {
+ ReleaseResource();
+ CFRelease(cf_attributed_text_);
+}
void OsxCTTextLayout::SetFont(std::shared_ptr<IFont> font) {
font_ = CheckPlatform<OsxCTFont>(font, GetPlatformId());
- CFRelease(ct_framesetter_);
- CFRelease(ct_frame_);
RecreateFrame();
}
void OsxCTTextLayout::SetText(String new_text) {
text_ = std::move(new_text);
- CFRelease(cf_text_);
- cf_text_ = Convert(text_);
- CFRelease(ct_framesetter_);
- CFRelease(ct_frame_);
+
+ CFRelease(cf_attributed_text_);
+
+ CFStringRef s = Convert(text_);
+ CFDictionaryRef attributes =
+ CFDictionaryCreateMutable(nullptr, 0, nullptr, nullptr);
+
+ Ensures(s);
+ Ensures(attributes);
+
+ cf_attributed_text_ = CFAttributedStringCreate(nullptr, s, attributes);
+ Ensures(cf_attributed_text_);
+
+ CFRelease(attributes);
+ CFRelease(s);
+
RecreateFrame();
}
void OsxCTTextLayout::SetMaxWidth(float max_width) {
max_width_ = max_width;
- CFRelease(ct_framesetter_);
- CFRelease(ct_frame_);
RecreateFrame();
}
void OsxCTTextLayout::SetMaxHeight(float max_height) {
max_height_ = max_height;
- CFRelease(ct_framesetter_);
- CFRelease(ct_frame_);
RecreateFrame();
}
@@ -147,24 +169,38 @@ TextHitTestResult OsxCTTextLayout::HitTest(const Point& point) {
return TextHitTestResult{0, false, false};
}
+void OsxCTTextLayout::ReleaseResource() {
+ line_count_ = 0;
+ line_origins_.clear();
+ lines_.clear();
+ if (ct_framesetter_) CFRelease(ct_framesetter_);
+ if (ct_frame_) CFRelease(ct_frame_);
+}
+
void OsxCTTextLayout::RecreateFrame() {
- auto attributed_string = CFAttributedStringCreateMutable(nullptr, 0);
- CFAttributedStringReplaceString(attributed_string, CFRangeMake(0, 0),
- cf_text_);
- CFAttributedStringSetAttribute(attributed_string,
- CFRangeMake(0, CFStringGetLength(cf_text_)),
- kCTFontAttributeName, font_->GetCTFont());
- ct_framesetter_ = CTFramesetterCreateWithAttributedString(attributed_string);
+ ReleaseResource();
+
+ ct_framesetter_ =
+ CTFramesetterCreateWithAttributedString(cf_attributed_text_);
+ Ensures(ct_framesetter_);
auto path = CGPathCreateMutable();
+ Ensures(path);
CGPathAddRect(path, nullptr, CGRectMake(0, 0, max_width_, max_height_));
+ CFMutableDictionaryRef dictionary =
+ CFDictionaryCreateMutable(nullptr, 0, &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ CFDictionaryAddValue(dictionary, kCTFontAttributeName, font_->GetCTFont());
+
ct_frame_ = CTFramesetterCreateFrame(
- ct_framesetter_, CFRangeMake(0, CFStringGetLength(cf_text_)), path,
- nullptr);
+ ct_framesetter_,
+ CFRangeMake(0, CFAttributedStringGetLength(cf_attributed_text_)), path,
+ dictionary);
+ Ensures(ct_frame_);
- CFRelease(attributed_string);
CGPathRelease(path);
+ CFRelease(dictionary);
const auto lines = CTFrameGetLines(ct_frame_);
line_count_ = CFArrayGetCount(lines);
@@ -176,4 +212,29 @@ void OsxCTTextLayout::RecreateFrame() {
}
}
+CTFrameRef OsxCTTextLayout::CreateFrameWithColor(const Color& color) {
+ auto path = CGPathCreateMutable();
+ CGPathAddRect(path, nullptr, CGRectMake(0, 0, max_width_, max_height_));
+
+ CFMutableDictionaryRef dictionary =
+ CFDictionaryCreateMutable(nullptr, 0, &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ CFDictionaryAddValue(dictionary, kCTFontAttributeName, font_->GetCTFont());
+
+ CGColorRef cg_color =
+ CGColorCreateGenericRGB(color.GetFloatRed(), color.GetFloatGreen(),
+ color.GetFloatBlue(), color.GetFloatAlpha());
+ CFDictionaryAddValue(dictionary, kCTForegroundColorAttributeName, cg_color);
+
+ auto frame = CTFramesetterCreateFrame(
+ ct_framesetter_,
+ CFRangeMake(0, CFAttributedStringGetLength(cf_attributed_text_)), path,
+ dictionary);
+ Ensures(frame);
+
+ CGPathRelease(path);
+ CFRelease(dictionary);
+
+ return frame;
+}
} // namespace cru::platform::graphics::osx::quartz