diff options
Diffstat (limited to 'include/cru/platform/graphics/quartz')
-rw-r--r-- | include/cru/platform/graphics/quartz/Brush.h | 47 | ||||
-rw-r--r-- | include/cru/platform/graphics/quartz/Convert.h | 24 | ||||
-rw-r--r-- | include/cru/platform/graphics/quartz/Factory.h | 35 | ||||
-rw-r--r-- | include/cru/platform/graphics/quartz/Font.h | 27 | ||||
-rw-r--r-- | include/cru/platform/graphics/quartz/Geometry.h | 57 | ||||
-rw-r--r-- | include/cru/platform/graphics/quartz/Image.h | 37 | ||||
-rw-r--r-- | include/cru/platform/graphics/quartz/ImageFactory.h | 22 | ||||
-rw-r--r-- | include/cru/platform/graphics/quartz/Painter.h | 82 | ||||
-rw-r--r-- | include/cru/platform/graphics/quartz/Resource.h | 25 | ||||
-rw-r--r-- | include/cru/platform/graphics/quartz/TextLayout.h | 95 |
10 files changed, 451 insertions, 0 deletions
diff --git a/include/cru/platform/graphics/quartz/Brush.h b/include/cru/platform/graphics/quartz/Brush.h new file mode 100644 index 00000000..f3579771 --- /dev/null +++ b/include/cru/platform/graphics/quartz/Brush.h @@ -0,0 +1,47 @@ +#pragma once +#include "Resource.h" +#include "cru/common/Base.h" +#include "cru/platform/graphics/Base.h" +#include "cru/platform/graphics/Brush.h" + +#include <CoreGraphics/CoreGraphics.h> + +#include <functional> + +namespace cru::platform::graphics::quartz { +class QuartzBrush : public OsxQuartzResource, public virtual IBrush { + public: + QuartzBrush(IGraphicsFactory* graphics_factory) + : OsxQuartzResource(graphics_factory) {} + CRU_DELETE_COPY(QuartzBrush) + CRU_DELETE_MOVE(QuartzBrush) + ~QuartzBrush() override = default; + + public: + virtual void Select(CGContextRef context) = 0; +}; + +class QuartzSolidColorBrush : public QuartzBrush, + public virtual ISolidColorBrush { + public: + QuartzSolidColorBrush(IGraphicsFactory* graphics_factory, const Color& color); + + CRU_DELETE_COPY(QuartzSolidColorBrush) + CRU_DELETE_MOVE(QuartzSolidColorBrush) + + ~QuartzSolidColorBrush() override; + + Color GetColor() override { return color_; } + void SetColor(const Color& color) override; + + CGColorRef GetCGColorRef() const { return cg_color_; } + + void Select(CGContextRef context) override; + + String GetDebugString() override; + + private: + Color color_; + CGColorRef cg_color_; +}; +} // namespace cru::platform::graphics::quartz diff --git a/include/cru/platform/graphics/quartz/Convert.h b/include/cru/platform/graphics/quartz/Convert.h new file mode 100644 index 00000000..c7dab7c9 --- /dev/null +++ b/include/cru/platform/graphics/quartz/Convert.h @@ -0,0 +1,24 @@ +#pragma once +#include "cru/common/Range.h" +#include "cru/common/String.h" +#include "cru/common/io/Stream.h" +#include "cru/platform/Matrix.h" + +#include <CoreGraphics/CoreGraphics.h> + +namespace cru::platform::graphics::quartz { +CGAffineTransform Convert(const Matrix& matrix); +Matrix Convert(const CGAffineTransform& matrix); + +CGPoint Convert(const Point& point); +Point Convert(const CGPoint& point); + +CGSize Convert(const Size& size); +Size Convert(const CGSize& size); + +CGRect Convert(const Rect& rect); +Rect Convert(const CGRect& rect); + +CGDataProviderRef ConvertStreamToCGDataProvider(io::Stream* stream); +CGDataConsumerRef ConvertStreamToCGDataConsumer(io::Stream* stream); +} // namespace cru::platform::graphics::quartz diff --git a/include/cru/platform/graphics/quartz/Factory.h b/include/cru/platform/graphics/quartz/Factory.h new file mode 100644 index 00000000..57992d87 --- /dev/null +++ b/include/cru/platform/graphics/quartz/Factory.h @@ -0,0 +1,35 @@ +#pragma once +#include "Resource.h" +#include "cru/common/Base.h" +#include "cru/platform/graphics/quartz/ImageFactory.h" +#include "cru/platform/graphics/Factory.h" +#include "cru/platform/graphics/ImageFactory.h" + +namespace cru::platform::graphics::quartz { +class QuartzGraphicsFactory : public OsxQuartzResource, + public virtual IGraphicsFactory { + public: + QuartzGraphicsFactory(); + + CRU_DELETE_COPY(QuartzGraphicsFactory) + CRU_DELETE_MOVE(QuartzGraphicsFactory) + + ~QuartzGraphicsFactory() override; + + public: + std::unique_ptr<ISolidColorBrush> CreateSolidColorBrush() override; + + std::unique_ptr<IGeometryBuilder> CreateGeometryBuilder() override; + + std::unique_ptr<IFont> CreateFont(String font_family, + float font_size) override; + + std::unique_ptr<ITextLayout> CreateTextLayout(std::shared_ptr<IFont> font, + String text) override; + + IImageFactory* GetImageFactory() override; + + private: + std::unique_ptr<QuartzImageFactory> image_factory_; +}; +} // namespace cru::platform::graphics::quartz diff --git a/include/cru/platform/graphics/quartz/Font.h b/include/cru/platform/graphics/quartz/Font.h new file mode 100644 index 00000000..36dba31a --- /dev/null +++ b/include/cru/platform/graphics/quartz/Font.h @@ -0,0 +1,27 @@ +#pragma once +#include "Resource.h" +#include "cru/common/Base.h" +#include "cru/platform/graphics/Font.h" + +#include <CoreText/CoreText.h> + +namespace cru::platform::graphics::quartz { +class OsxCTFont : public OsxQuartzResource, public virtual IFont { + public: + OsxCTFont(IGraphicsFactory* graphics_factory, const String& name, float size); + + CRU_DELETE_COPY(OsxCTFont) + CRU_DELETE_MOVE(OsxCTFont) + + ~OsxCTFont() override; + + CTFontRef GetCTFont() const { return ct_font_; } + + String GetFontName() override; + float GetFontSize() override; + + private: + String name_; + CTFontRef ct_font_; +}; +} // namespace cru::platform::graphics::quartz diff --git a/include/cru/platform/graphics/quartz/Geometry.h b/include/cru/platform/graphics/quartz/Geometry.h new file mode 100644 index 00000000..18e2e25e --- /dev/null +++ b/include/cru/platform/graphics/quartz/Geometry.h @@ -0,0 +1,57 @@ +#pragma once +#include "Resource.h" +#include "cru/platform/graphics/Geometry.h" + +#include <memory> + +#include <CoreGraphics/CoreGraphics.h> + +namespace cru::platform::graphics::quartz { +class QuartzGeometry : public OsxQuartzResource, public virtual IGeometry { + public: + QuartzGeometry(IGraphicsFactory *graphics_factory, CGPathRef cg_path); + + CRU_DELETE_COPY(QuartzGeometry) + CRU_DELETE_MOVE(QuartzGeometry) + + ~QuartzGeometry() override; + + CGPathRef GetCGPath() const { return cg_path_; } + + bool FillContains(const Point &point) override; + Rect GetBounds() override; + + std::unique_ptr<IGeometry> Transform(const Matrix &matrix) override; + std::unique_ptr<IGeometry> CreateStrokeGeometry(float width) override; + + private: + CGPathRef cg_path_; +}; + +class QuartzGeometryBuilder : public OsxQuartzResource, + public virtual IGeometryBuilder { + public: + explicit QuartzGeometryBuilder(IGraphicsFactory *graphics_factory); + + CRU_DELETE_COPY(QuartzGeometryBuilder) + CRU_DELETE_MOVE(QuartzGeometryBuilder) + + ~QuartzGeometryBuilder() override; + + Point GetCurrentPosition() override; + + void MoveTo(const Point &point) override; + void LineTo(const Point &point) override; + void CubicBezierTo(const Point &start_control_point, + const Point &end_control_point, + const Point &end_point) override; + void QuadraticBezierTo(const Point &control_point, + const Point &end_point) override; + void CloseFigure(bool close) override; + + std::unique_ptr<IGeometry> Build() override; + + private: + CGMutablePathRef cg_mutable_path_; +}; +} // namespace cru::platform::graphics::quartz diff --git a/include/cru/platform/graphics/quartz/Image.h b/include/cru/platform/graphics/quartz/Image.h new file mode 100644 index 00000000..1dd8f0a6 --- /dev/null +++ b/include/cru/platform/graphics/quartz/Image.h @@ -0,0 +1,37 @@ +#pragma once +#include "Resource.h" +#include "cru/platform/graphics/Image.h" +#include "cru/platform/graphics/ImageFactory.h" + +#include <CoreGraphics/CoreGraphics.h> + +namespace cru::platform::graphics::quartz { +class QuartzImage : public OsxQuartzResource, public virtual IImage { + public: + QuartzImage(IGraphicsFactory* graphics_factory, IImageFactory* image_factory, + CGImageRef image, bool auto_release, + unsigned char* buffer = nullptr); + + CRU_DELETE_COPY(QuartzImage) + CRU_DELETE_MOVE(QuartzImage) + + ~QuartzImage() override; + + public: + float GetWidth() override; + float GetHeight() override; + + std::unique_ptr<IImage> CreateWithRect(const Rect& rect) override; + + std::unique_ptr<IPainter> CreatePainter() override; + + CGImageRef GetCGImage() const { return image_; } + + private: + IImageFactory* image_factory_; + CGImageRef image_; + bool auto_release_ = false; + + unsigned char* buffer_; +}; +} // namespace cru::platform::graphics::quartz diff --git a/include/cru/platform/graphics/quartz/ImageFactory.h b/include/cru/platform/graphics/quartz/ImageFactory.h new file mode 100644 index 00000000..bd2a929f --- /dev/null +++ b/include/cru/platform/graphics/quartz/ImageFactory.h @@ -0,0 +1,22 @@ +#pragma once +#include "Resource.h" +#include "cru/platform/graphics/ImageFactory.h" + +namespace cru::platform::graphics::quartz { +class QuartzImageFactory : public OsxQuartzResource, + public virtual IImageFactory { + public: + explicit QuartzImageFactory(IGraphicsFactory* graphics_factory); + + CRU_DELETE_COPY(QuartzImageFactory) + CRU_DELETE_MOVE(QuartzImageFactory) + + ~QuartzImageFactory() override; + + public: + std::unique_ptr<IImage> DecodeFromStream(io::Stream* stream) override; + void EncodeToStream(IImage* image, io::Stream* stream, ImageFormat format, + float quality) override; + std::unique_ptr<IImage> CreateBitmap(int width, int height) override; +}; +} // namespace cru::platform::graphics::quartz diff --git a/include/cru/platform/graphics/quartz/Painter.h b/include/cru/platform/graphics/quartz/Painter.h new file mode 100644 index 00000000..eba66a56 --- /dev/null +++ b/include/cru/platform/graphics/quartz/Painter.h @@ -0,0 +1,82 @@ +#pragma once +#include "Resource.h" +#include "cru/common/Base.h" +#include "cru/platform/graphics/Base.h" +#include "cru/platform/graphics/Painter.h" + +#include <CoreGraphics/CoreGraphics.h> + +#include <functional> + +namespace cru::platform::graphics::quartz { +class QuartzCGContextPainter : public OsxQuartzResource, + public virtual IPainter { + CRU_DEFINE_CLASS_LOG_TAG(u"QuartzCGContextPainter") + + public: + explicit QuartzCGContextPainter( + IGraphicsFactory* graphics_factory, CGContextRef cg_context, + bool auto_release, const Size& size, + std::function<void(QuartzCGContextPainter*)> on_end_draw); + + CRU_DELETE_COPY(QuartzCGContextPainter) + CRU_DELETE_MOVE(QuartzCGContextPainter) + + ~QuartzCGContextPainter() override; + + public: + Matrix GetTransform() override; + void SetTransform(const Matrix& matrix) override; + + void ConcatTransform(const Matrix& matrix) override; + + void Clear(const Color& color) override; + + void DrawLine(const Point& start, const Point& end, IBrush* brush, + float width) override; + void StrokeRectangle(const Rect& rectangle, IBrush* brush, + float width) override; + void FillRectangle(const Rect& rectangle, IBrush* brush) override; + void StrokeEllipse(const Rect& outline_rect, IBrush* brush, + float width) override; + void FillEllipse(const Rect& outline_rect, IBrush* brush) override; + + void StrokeGeometry(IGeometry* geometry, IBrush* brush, float width) override; + void FillGeometry(IGeometry* geometry, IBrush* brush) override; + + void DrawText(const Point& offset, ITextLayout* text_layout, + IBrush* brush) override; + + void DrawImage(const Point& offset, IImage* image) override; + + void PushLayer(const Rect& bounds) override; + + void PopLayer() override; + + void EndDraw() override; + + void PushState() override; + + void PopState() override; + + private: + void SetLineWidth(float width); + + void DoEndDraw(); + + void Validate(); + + private: + CGContextRef cg_context_; + + bool auto_release_; + + Size size_; + + Matrix transform_; + + std::function<void(QuartzCGContextPainter*)> on_end_draw_; + + std::vector<Rect> clip_stack_; +}; +} // namespace cru::platform::graphics::quartz diff --git a/include/cru/platform/graphics/quartz/Resource.h b/include/cru/platform/graphics/quartz/Resource.h new file mode 100644 index 00000000..d28e4055 --- /dev/null +++ b/include/cru/platform/graphics/quartz/Resource.h @@ -0,0 +1,25 @@ +#pragma once +#include "cru/platform/osx/Resource.h" +#include "cru/platform/graphics/Base.h" +#include "cru/platform/graphics/Resource.h" + +namespace cru::platform::graphics::quartz { +class OsxQuartzResource : public platform::osx::OsxResource, + public virtual IGraphicsResource { + public: + explicit OsxQuartzResource(IGraphicsFactory* graphics_factory) + : graphics_factory_(graphics_factory) {} + + CRU_DELETE_COPY(OsxQuartzResource) + CRU_DELETE_MOVE(OsxQuartzResource) + ~OsxQuartzResource() override = default; + + public: + String GetPlatformId() const override { return u"OSX Quartz"; } + + IGraphicsFactory* GetGraphicsFactory() override { return graphics_factory_; } + + private: + IGraphicsFactory* graphics_factory_; +}; +} // namespace cru::platform::graphics::quartz diff --git a/include/cru/platform/graphics/quartz/TextLayout.h b/include/cru/platform/graphics/quartz/TextLayout.h new file mode 100644 index 00000000..0d23360d --- /dev/null +++ b/include/cru/platform/graphics/quartz/TextLayout.h @@ -0,0 +1,95 @@ +#pragma once +#include "Resource.h" + +#include "Font.h" +#include "cru/common/Base.h" +#include "cru/platform/graphics/TextLayout.h" + +#include <memory> + +namespace cru::platform::graphics::quartz { +class OsxCTTextLayout : public OsxQuartzResource, public virtual ITextLayout { + public: + OsxCTTextLayout(IGraphicsFactory* graphics_factory, + std::shared_ptr<OsxCTFont> font, const String& str); + + CRU_DELETE_COPY(OsxCTTextLayout) + CRU_DELETE_MOVE(OsxCTTextLayout) + + ~OsxCTTextLayout() override; + + public: + String GetText() override { return text_; } + void SetText(String new_text) override; + + std::shared_ptr<IFont> GetFont() override { return font_; } + void SetFont(std::shared_ptr<IFont> font) override; + + void SetMaxWidth(float max_width) override; + void SetMaxHeight(float max_height) override; + + bool IsEditMode() override; + void SetEditMode(bool enable) override; + + Index GetLineIndexFromCharIndex(Index char_index) override; + Index GetLineCount() override; + float GetLineHeight(Index line_index) override; + + Rect GetTextBounds(bool includingTrailingSpace = false) override; + std::vector<Rect> TextRangeRect(const TextRange& text_range) override; + Rect TextSinglePoint(Index position, bool trailing) override; + TextHitTestResult HitTest(const Point& point) override; + + CTFrameRef GetCTFrameRef() const { return ct_frame_; } + + CTFrameRef CreateFrameWithColor(const Color& color); + + Matrix GetTransform() { return transform_; } + + String GetDebugString() override; + + private: + void DoSetText(String text); + + void ReleaseResource(); + void RecreateFrame(); + + CGRect DoGetTextBounds(bool includingTrailingSpace = false); + CGRect DoGetTextBoundsIncludingEmptyLines( + bool includingTrailingSpace = false); + std::vector<CGRect> DoTextRangeRect(const TextRange& text_range); + CGRect DoTextSinglePoint(Index position, bool trailing); + + private: + float max_width_; + float max_height_; + + bool edit_mode_; + + std::shared_ptr<OsxCTFont> font_; + + String text_; + String actual_text_; + CFMutableAttributedStringRef cf_attributed_text_; + + CTFramesetterRef ct_framesetter_ = nullptr; + float suggest_height_; + CTFrameRef ct_frame_ = nullptr; + int line_count_; + std::vector<CGPoint> line_origins_; + std::vector<CTLineRef> lines_; + std::vector<float> line_ascents_; + std::vector<float> line_descents_; + std::vector<float> line_heights_; + // The empty line count in the front of the lines. + int head_empty_line_count_; + // The trailing empty line count in the back of the lines. + int tail_empty_line_count_; + + // Just for cache. + CGRect text_bounds_without_trailing_space_; + CGRect text_bounds_with_trailing_space_; + + Matrix transform_; +}; +} // namespace cru::platform::graphics::quartz |