ultimatepp/uppsrc/CtrlCore/CocoDraw.mm
2026-04-29 11:48:46 +02:00

183 lines
No EOL
3.5 KiB
Text

#include "CocoMM.h"
#ifdef GUI_COCOA
namespace Upp {
void SystemDraw::Init(void *cgContext, void *view)
{
handle = cgContext;
nsview = view;
Push();
CGContextSetBlendMode(cgHandle, kCGBlendModeNormal);
CGContextSetTextPosition(cgHandle, 0, 0);
CGContextSetTextDrawingMode(cgHandle, kCGTextFill);
double sc = Ctrl::GetDisplayUnScale();
if(sc != 1)
CGContextScaleCTM(cgHandle, sc, sc);
}
SystemDraw::SystemDraw(void *cgContext, void *nsview)
{
Init(cgContext, nsview);
}
SystemDraw::~SystemDraw()
{
Pop();
}
void SystemDraw::Set(Color c)
{
if(c != fill) {
fill = c;
CGContextSetRGBFillColor(cgHandle, c.GetR() / 255.0, c.GetG() / 255.0, c.GetB() / 255.0, 1.0);
}
}
void SystemDraw::SetStroke(Color c)
{
CGContextSetRGBStrokeColor(cgHandle, c.GetR() / 255.0, c.GetG() / 255.0, c.GetB() / 255.0, 1.0);
}
dword SystemDraw::GetInfo() const
{
return DRAWTEXTLINES;
}
void SystemDraw::Push()
{
CGContextSaveGState(cgHandle);
offset.Add(GetOffset());
clip.Add(GetClip());
}
void SystemDraw::Pop()
{
if(offset.GetCount())
offset.Drop();
if(clip.GetCount())
clip.Drop();
if(cgHandle)
CGContextRestoreGState(cgHandle);
fill = Null;
}
void SystemDraw::BeginOp()
{
Push();
}
void SystemDraw::EndOp()
{
Pop();
}
void SystemDraw::OffsetOp(Point p)
{
Push();
offset.Top() += p;
}
PointCG SystemDraw::Convert(int x, int y)
{
Point p = GetOffset(); // TODO: Optimize
x += p.x;
y += p.y;
return PointCG(x, y);
}
RectCG SystemDraw::Convert(int x, int y, int cx, int cy)
{
Point p = GetOffset(); // TODO: Optimize
x += p.x;
y += p.y;
return RectCG(x, y, cx, cy);
}
RectCG SystemDraw::Convert(const Rect& r)
{
return Convert(r.left, r.top, r.GetWidth(), r.GetHeight());
}
RectCG SystemDraw::MakeRectCG(const Rect& r) const
{
Size sz = r.GetSize();
return RectCG(r.left, r.top, sz.cx, sz.cy);
}
void SystemDraw::ClipCG(const Rect& r)
{
CGContextClipToRect(cgHandle, MakeRectCG(r));
}
bool SystemDraw::ClipOp(const Rect& r)
{
Push();
clip.Top() &= r.Offseted(GetOffset());
ClipCG(clip.Top());
return true;
}
bool SystemDraw::ClipoffOp(const Rect& r)
{
Push();
clip.Top() &= r.Offseted(GetOffset());
offset.Top() += r.TopLeft();
ClipCG(clip.Top());
return true;
}
bool SystemDraw::ExcludeClipOp(const Rect& r_)
{
CGRect cgr[4];
Rect r = r_.Offseted(GetOffset());
cgr[0] = MakeRectCG(Rect(0, 0, 9999, r.top));
cgr[1] = MakeRectCG(Rect(0, r.bottom, 9999, 9999));
cgr[2] = MakeRectCG(Rect(0, 0, r.left, 9999));
cgr[3] = MakeRectCG(Rect(r.right, 0, 9999, 9999));
CGContextClipToRects(cgHandle, cgr, 4);
return true;
}
bool SystemDraw::IntersectClipOp(const Rect& r)
{
ClipCG(r.Offseted(GetOffset()));
return true;
}
bool SystemDraw::IsPaintingOp(const Rect& r) const
{
Rect cr = r.Offseted(GetOffset());
cr.Intersect(GetClip());
if(cr.IsEmpty())
return false;
return true;
// return nsview ? [(NSView *)nsview needsToDrawRect:MakeRectCG(1.0 / DPI(1) * cr)] : true;
}
Rect SystemDraw::GetPaintRect() const
{
return Rect(0, 0, INT_MAX, INT_MAX);
}
void SystemDraw::DrawRectOp(int x, int y, int cx, int cy, Color color)
{
if(IsNull(color))
return;
CGRect cgr = Convert(x, y, cx, cy);
if(color == InvertColor()) {
Set(White());
CGContextSetBlendMode(cgHandle, kCGBlendModeExclusion);
CGContextFillRect(cgHandle, cgr);
CGContextSetBlendMode(cgHandle, kCGBlendModeNormal);
}
else {
Set(color);
CGContextFillRect(cgHandle, cgr);
}
}
};
#endif