mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-28 22:20:25 +02:00
cocoa: fix some legacy transparent icon format issues #41131
there are two transparent formats: 1. the one with alpha channel like modern graphic formats (supported previously) 2. the other historical legacy with extra 1bit/pixel MaskBitmap (fixed this time), scaled mask supported also.
This commit is contained in:
parent
f8cb933df5
commit
e5159ea7a2
@ -281,6 +281,7 @@ type
|
|||||||
procedure ReCreateHandle_IfModified();
|
procedure ReCreateHandle_IfModified();
|
||||||
procedure SetModified();
|
procedure SetModified();
|
||||||
function CreateSubImage(const ARect: TRect): CGImageRef;
|
function CreateSubImage(const ARect: TRect): CGImageRef;
|
||||||
|
function CreateMaskImage(const ARect: TRect): CGImageRef;
|
||||||
procedure PreMultiplyAlpha();
|
procedure PreMultiplyAlpha();
|
||||||
function GetNonPreMultipliedData(): PByte;
|
function GetNonPreMultipliedData(): PByte;
|
||||||
public
|
public
|
||||||
@ -1080,6 +1081,22 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TCocoaBitmap.CreateMaskImage(const ARect: TRect): CGImageRef;
|
||||||
|
var
|
||||||
|
CGDataProvider: CGDataProviderRef;
|
||||||
|
Mask: CGImageRef;
|
||||||
|
begin
|
||||||
|
CGDataProvider := CGDataProviderCreateWithData(nil, FData, FDataSize, nil);
|
||||||
|
try
|
||||||
|
Mask := CGImageMaskCreate(FWidth, FHeight, FBitsPerPixel,
|
||||||
|
FBitsPerPixel, FBytesPerRow, CGDataProvider, nil, 0);
|
||||||
|
Result := CGImageCreateWithImageInRect(Mask, RectToCGRect(ARect));
|
||||||
|
finally
|
||||||
|
CGDataProviderRelease(CGDataProvider);
|
||||||
|
CGImageRelease(Mask);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TCocoaBitmap.GetColorSpace: NSString;
|
function TCocoaBitmap.GetColorSpace: NSString;
|
||||||
begin
|
begin
|
||||||
if FType in [cbtMono, cbtGray] then
|
if FType in [cbtMono, cbtGray] then
|
||||||
@ -2148,36 +2165,43 @@ function TCocoaContext.StretchDraw(X, Y, Width, Height: Integer;
|
|||||||
SrcDC: TCocoaBitmapContext; XSrc, YSrc, SrcWidth, SrcHeight: Integer;
|
SrcDC: TCocoaBitmapContext; XSrc, YSrc, SrcWidth, SrcHeight: Integer;
|
||||||
Msk: TCocoaBitmap; XMsk, YMsk: Integer; Rop: DWORD): Boolean;
|
Msk: TCocoaBitmap; XMsk, YMsk: Integer; Rop: DWORD): Boolean;
|
||||||
var
|
var
|
||||||
Bmp: TCocoaBitmap;
|
dcBitmap: TCocoaBitmap;
|
||||||
ImgRect: CGRect;
|
maskImage: CGImageRef = nil;
|
||||||
|
cgImage: CGImageRef;
|
||||||
dcWidth: Integer;
|
imageRep: NSBitmapImageRep;
|
||||||
dcHeight: Integer;
|
|
||||||
begin
|
begin
|
||||||
Bmp := SrcDC.Bitmap;
|
dcBitmap := SrcDC.Bitmap;
|
||||||
if not Assigned(Bmp) then
|
if not Assigned(dcBitmap) then
|
||||||
Exit(False);
|
Exit(False);
|
||||||
|
|
||||||
dcWidth:= Max(Width,FSize.Width);
|
|
||||||
dcHeight:= Max(Height,FSize.Height);
|
|
||||||
|
|
||||||
// Make sure that bitmap is the most up-to-date
|
// Make sure that bitmap is the most up-to-date
|
||||||
Bmp.ReCreateHandle_IfModified(); // Fix for bug 28102
|
dcBitmap.ReCreateHandle_IfModified(); // Fix for bug 28102
|
||||||
|
|
||||||
// see https://bugs.freepascal.org/view.php?id=34197
|
// see https://bugs.freepascal.org/view.php?id=34197
|
||||||
// Bitmap context windowsofs should be used when rendering a bitmap
|
// Bitmap context windowsofs should be used when rendering a bitmap
|
||||||
inc(XSrc, -SrcDC.WindowOfs.X);
|
inc(XSrc, -SrcDC.WindowOfs.X);
|
||||||
inc(YSrc, -SrcDC.WindowOfs.Y);
|
inc(YSrc, -SrcDC.WindowOfs.Y);
|
||||||
|
|
||||||
CGContextSaveGState(CGContext);
|
|
||||||
|
|
||||||
if NOT SrcDC.ctx.isFlipped then begin
|
if NOT SrcDC.ctx.isFlipped then begin
|
||||||
YSrc := Bmp.Height - (SrcHeight + YSrc);
|
YSrc := dcBitmap.Height - (SrcHeight + YSrc);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Result := DrawImageRep(GetNSRect(X, Y, Width, Height),GetNSRect(XSrc, YSrc, SrcWidth, SrcHeight), bmp.ImageRep);
|
imageRep:= dcBitmap.ImageRep;
|
||||||
|
if (Msk <> nil) and (Msk.Image <> nil) then begin
|
||||||
|
maskImage := Msk.CreateMaskImage(Bounds(XMsk, YMsk, SrcWidth, SrcHeight));
|
||||||
|
cgImage:= CGImageCreateWithMask(imageRep.CGImage, maskImage);
|
||||||
|
imageRep:= NSBitmapImageRep.alloc.initWithCGImage(cgImage);
|
||||||
|
end;
|
||||||
|
|
||||||
CGContextRestoreGState(CGContext);
|
Result := DrawImageRep( GetNSRect(X, Y, Width, Height),
|
||||||
|
GetNSRect(XSrc, YSrc, SrcWidth, SrcHeight),
|
||||||
|
imageRep );
|
||||||
|
|
||||||
|
if Assigned(maskImage) then begin
|
||||||
|
imageRep.release;
|
||||||
|
CGImageRelease(cgImage);
|
||||||
|
CGImageRelease(maskImage);
|
||||||
|
end;
|
||||||
|
|
||||||
AttachedBitmap_SetModified();
|
AttachedBitmap_SetModified();
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user