diff options
author | crupest <crupest@outlook.com> | 2021-10-20 17:04:27 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-10-20 17:04:27 +0800 |
commit | 152133978872f6d6476c3fc7e0e3a5a6cc23b119 (patch) | |
tree | 374a793cb56ef5c8d1e413f4b781fec087e28678 /src | |
parent | 398aadcddb8b6ed20b17f6c56cd7b49947b72136 (diff) | |
download | cru-152133978872f6d6476c3fc7e0e3a5a6cc23b119.tar.gz cru-152133978872f6d6476c3fc7e0e3a5a6cc23b119.tar.bz2 cru-152133978872f6d6476c3fc7e0e3a5a6cc23b119.zip |
...
Diffstat (limited to 'src')
-rw-r--r-- | src/osx/graphics/quartz/Font.cpp | 1 | ||||
-rw-r--r-- | src/osx/graphics/quartz/Painter.cpp | 29 | ||||
-rw-r--r-- | src/osx/graphics/quartz/TextLayout.cpp | 105 |
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 |