Cocoa: fix the Drawing issue #36714, Merge branch 'cocoa/cgcontext'

This commit is contained in:
rich2014 2024-06-06 11:27:01 +08:00
parent 0c1f7c3b17
commit 2099ac1c1f
3 changed files with 55 additions and 76 deletions

View File

@ -374,8 +374,6 @@ type
protected
function SaveDCData: TCocoaDCData; virtual;
procedure RestoreDCData(const AData: TCocoaDCData); virtual;
procedure SetCGFillping(Ctx: CGContextRef; Width, Height: CGFloat);
procedure RestoreCGFillping(Ctx: CGContextRef; Width, Height: CGFloat);
procedure ApplyTransform(Trans: CGAffineTransform);
procedure ClearClipping;
procedure AttachedBitmap_SetModified(); virtual;
@ -1510,8 +1508,11 @@ begin
FSize.cx := width;
FSize.cy := height;
CGContextTranslateCTM(cg, 0, height);
CGContextScaleCTM(cg, 1, -1);
if NOT ctx.isFlipped then begin
CGContextTranslateCTM(cg, 0, height);
CGContextScaleCTM(cg, 1, -1);
end;
FPenPos.x := 0;
FPenPos.y := 0;
end;
@ -2102,36 +2103,6 @@ begin
AttachedBitmap_SetModified();
end;
procedure TCocoaContext.SetCGFillping(Ctx: CGContextRef; Width, Height: CGFloat);
begin
if Width < 0 then
begin
CGContextTranslateCTM(Ctx, -Width, 0);
CGContextScaleCTM(Ctx, -1, 1);
end;
if Height < 0 then
begin
CGContextTranslateCTM(Ctx, 0, -Height);
CGContextScaleCTM(Ctx, 1, -1);
end;
end;
procedure TCocoaContext.RestoreCGFillping(Ctx: CGContextRef; Width, Height: CGFloat);
begin
if Height < 0 then
begin
CGContextTranslateCTM(Ctx, 0, Height);
CGContextScaleCTM(Ctx, 1, -1);
end;
if Width < 0 then
begin
CGContextScaleCTM(Ctx, -1, 1);
CGContextTranslateCTM(Ctx, Width, 0);
end;
end;
procedure TCocoaContext.ApplyTransform(Trans: CGAffineTransform);
var
T2: CGAffineTransform;
@ -2193,13 +2164,19 @@ function TCocoaContext.StretchDraw(X, Y, Width, Height: Integer;
Msk: TCocoaBitmap; XMsk, YMsk: Integer; Rop: DWORD): Boolean;
var
Bmp: TCocoaBitmap;
MskImage: CGImageRef;
MskImage: CGImageRef = nil;
ImgRect: CGRect;
dcWidth: Integer;
dcHeight: Integer;
begin
Bmp := SrcDC.Bitmap;
if not Assigned(Bmp) then
Exit(False);
dcWidth:= Max(Width,FSize.Width);
dcHeight:= Max(Height,FSize.Height);
// Make sure that bitmap is the most up-to-date
Bmp.ReCreateHandle_IfModified(); // Fix for bug 28102
@ -2208,29 +2185,31 @@ begin
inc(XSrc, -SrcDC.WindowOfs.X);
inc(YSrc, -SrcDC.WindowOfs.Y);
CGContextSaveGState(CGContext);
//apply window offset
if (Msk <> nil) and (Msk.Image <> nil) then
begin
if (Msk <> nil) and (Msk.Image <> nil) then begin
MskImage := Msk.CreateMaskImage(Bounds(XMsk, YMsk, SrcWidth, SrcHeight));
ImgRect := CGRectMake(x, -y, SrcWidth, SrcHeight);
CGContextSaveGState(CGContext);
CGContextScaleCTM(CGContext, 1, -1);
CGContextTranslateCTM(CGContext, 0, -SrcHeight);
CGContextClipToMask(CGContext, ImgRect, MskImage );
NSGraphicsContext.setCurrentContext(ctx);
Result := bmp.ImageRep.drawInRect_fromRect_operation_fraction_respectFlipped_hints(
GetNSRect(X, -Y, Width, Height), GetNSRect(XSrc, YSrc, SrcWidth, SrcHeight), NSCompositeSourceOver, 1.0, True, nil );
CGImageRelease(MskImage);
CGContextRestoreGState(CGContext);
end
else
begin
// convert Y coordinate of the source bitmap
YSrc := Bmp.Height - (SrcHeight + YSrc);
Result := DrawImageRep(GetNSRect(X, Y, Width, Height),GetNSRect(XSrc, YSrc, SrcWidth, SrcHeight), bmp.ImageRep);
ImgRect := CGRectMake(x, y, dcWidth, dcHeight);
CGContextClipToMask(CGContext, ImgRect, MskImage);
end;
if NOT ctx.isFlipped then begin
CGContextScaleCTM(CGContext, 1, -1);
CGContextTranslateCTM(CGContext, 0, -dcHeight);
Y:= dcHeight - (Height + Y);
end;
if NOT SrcDC.ctx.isFlipped then begin
YSrc := Bmp.Height - (SrcHeight + YSrc);
end;
Result := bmp.ImageRep.drawInRect_fromRect_operation_fraction_respectFlipped_hints(
GetNSRect(X, Y, Width, Height), GetNSRect(XSrc, YSrc, SrcWidth, SrcHeight), NSCompositeSourceOver, 1.0, True, nil );
if Assigned(MskImage) then
CGImageRelease(MskImage);
CGContextRestoreGState(CGContext);
AttachedBitmap_SetModified();
end;

View File

@ -521,6 +521,7 @@ begin
inherited;
if not Assigned(callback) then Exit;
ctx := TCocoaContext.Create(NSGraphicsContext.currentContext);
ctx.InitDraw(round(clipRect.size.width), round(clipRect.size.height));
try
ItemState := [];
if isRowSelected(row) then Include(ItemState, odSelected);

View File

@ -36,9 +36,9 @@ type
function SetButtonCellType(btn: NSButtonCell; Details: TThemedElementDetails): Boolean;
procedure SetButtonCellToDetails(btn: NSButtonCell; Details: TThemedElementDetails);
procedure CellDrawStart(dst: TCocoaContext; const r: Trect; out cur: NSGraphicsContext; out dstRect: NSRect);
procedure CellDrawStart(dst: TCocoaContext; const r: Trect; out dstRect: NSRect);
procedure CellDrawFrame(cell: NSCell; const dst: NSRect);
procedure CellDrawEnd(dst: TCocoaContext; cur: NSGraphicsContext);
procedure CellDrawEnd(dst: TCocoaContext);
function InitThemes: Boolean; override;
function UseThemes: Boolean; override;
@ -197,7 +197,6 @@ var
lState: TCDControlState = [];
lDrawer: TCDDrawer;
lPt: TPoint;
cur : NSGraphicsContext;
nsr : NSRect;
b : NSButtonCell;
begin
@ -207,9 +206,9 @@ begin
if SetButtonCellType(b, Details) then
begin
SetButtonCellToDetails(b, Details);
CellDrawStart(DC, R, cur, nsr);
CellDrawStart(DC, R, nsr);
CellDrawFrame(b, nsr);
CellDrawEnd(DC, cur);
CellDrawEnd(DC);
Exit;
end;
finally
@ -261,14 +260,13 @@ end;
function TCocoaThemeServices.DrawHeaderElement(DC: TCocoaContext;
Details: TThemedElementDetails; R: TRect; ClipRect: PRect): TRect;
var
cur : NSGraphicsContext;
nsr : NSRect;
begin
if (HdrCell=nil) then
begin
hdrCell := NSTableHeaderCell.alloc.initTextCell(NSSTR_EMPTY);
end;
CellDrawStart(DC, R, cur, nsr);
CellDrawStart(DC, R, nsr);
// this draws a header background
hdrCell.setDrawsBackground(true);
@ -279,7 +277,7 @@ begin
hdrCell.setDrawsBackground(false);
CellDrawFrame(hdrCell, nsr);
CellDrawEnd(DC, cur);
CellDrawEnd(DC);
Result := R;
end;
@ -346,7 +344,6 @@ var
lCDToolbarItem: TCDToolBarItem;
lCDToolbar: TCDToolBarStateEx;
lDrawer: TCDDrawer;
cur : NSGraphicsContext;
nsr : NSRect;
begin
if Details.Part = TP_BUTTON then
@ -354,9 +351,9 @@ begin
//BtnCell.setBezeled(true);
SetButtonCellType(BtnCell, Details);
SetButtonCellToDetails(BtnCell, Details);
CellDrawStart(DC, R, cur, nsr);
CellDrawStart(DC, R, nsr);
CellDrawFrame(btnCell, nsr);
CellDrawEnd(DC, cur);
CellDrawEnd(DC);
Result := R;
end
else
@ -941,15 +938,20 @@ begin
btn.setIntValue(0);
end;
procedure TCocoaThemeServices.CellDrawStart(dst: TCocoaContext; const r: Trect; out cur: NSGraphicsContext; out dstRect: NSRect);
procedure TCocoaThemeServices.CellDrawStart(dst: TCocoaContext; const r: Trect; out dstRect: NSRect);
var
acc : TCocoaContextAccess absolute dst;
begin
cur := NSGraphicsContext.currentContext;
NSGraphicsContext.setCurrentContext( acc.ctx );
NSGraphicsContext.classSaveGraphicsState;
NSGraphicsContext.setCurrentContext(acc.ctx);
acc.SetCGFillping(acc.CGContext, 0, -acc.Size.cy);
LCLToNSRect( R, acc.size.cy, dstRect);
if NOT acc.ctx.isFlipped then begin
CGContextTranslateCTM(acc.ctx.CGContext, 0, acc.Size.cy);
CGContextScaleCTM(acc.ctx.CGContext, 1, -1);
LCLToNSRect(R, acc.size.cy, dstRect);
end else begin
dstRect:= RectTONSRect(R);
end;
end;
procedure TCocoaThemeServices.CellDrawFrame(cell: NSCell; const dst: NSRect);
@ -957,12 +959,9 @@ begin
cell.drawWithFrame_inView(dst, nil);
end;
procedure TCocoaThemeServices.CellDrawEnd(dst: TCocoaContext; cur: NSGraphicsContext);
var
acc : TCocoaContextAccess absolute dst;
procedure TCocoaThemeServices.CellDrawEnd(dst: TCocoaContext);
begin
acc.SetCGFillping(acc.CGContext, 0, -acc.Size.cy);
NSGraphicsContext.setCurrentContext( cur );
NSGraphicsContext.classRestoreGraphicsState;
end;
{ TCocoaThemeCallback }