mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-26 12:23:51 +02:00
cocoa: cocoa does not support BGR(A) bitmaps
git-svn-id: trunk@38807 -
This commit is contained in:
parent
bc0f56fefe
commit
05b660c8dc
lcl/interfaces/cocoa
@ -27,9 +27,7 @@ type
|
||||
cbtGray, // grayscale bitmap
|
||||
cbtRGB, // color bitmap 8-8-8 R-G-B
|
||||
cbtARGB, // color bitmap with alpha channel first 8-8-8-8 A-R-G-B
|
||||
cbtRGBA, // color bitmap with alpha channel last 8-8-8-8 R-G-B-A
|
||||
cbtBGR, // color bitmap 8-8-8 B-G-R (windows compatible)
|
||||
cbtBGRA // color bitmap with alpha channel 8-8-8-8 B-G-R-A (windows compatible)
|
||||
cbtRGBA // color bitmap with alpha channel last 8-8-8-8 R-G-B-A
|
||||
);
|
||||
|
||||
const
|
||||
@ -728,15 +726,14 @@ begin
|
||||
FFreeData := False;
|
||||
end;
|
||||
|
||||
HasAlpha := AType in [cbtARGB, cbtRGBA, cbtBGRA];
|
||||
BitmapFormat := NSAlphaNonpremultipliedBitmapFormat;
|
||||
if AType = cbtARGB then
|
||||
HasAlpha := AType in [cbtARGB, cbtRGBA];
|
||||
if HasAlpha then
|
||||
BitmapFormat := NSAlphaNonpremultipliedBitmapFormat
|
||||
else
|
||||
BitmapFormat := 0;
|
||||
if AType in [cbtARGB, cbtRGB] then
|
||||
BitmapFormat := BitmapFormat or NSAlphaFirstBitmapFormat;
|
||||
|
||||
{$ifdef VerboseBitmaps}
|
||||
DebugLn(Format('[TCocoaBitmap.Create] NSBitmapImageRep.alloc HasAlpha=%d',
|
||||
[Integer(HasAlpha)]));
|
||||
{$endif}
|
||||
// Create the associated NSImageRep
|
||||
FImagerep := NSBitmapImageRep(NSBitmapImageRep.alloc.initWithBitmapDataPlanes_pixelsWide_pixelsHigh__colorSpaceName_bitmapFormat_bytesPerRow_bitsPerPixel(
|
||||
@FData, // planes, BitmapDataPlanes
|
||||
@ -820,7 +817,7 @@ begin
|
||||
32:
|
||||
begin
|
||||
FBitsPerSample := 8;
|
||||
if AType in [cbtRGB, cbtBGR] then
|
||||
if AType = cbtRGB then
|
||||
FSamplesPerPixel := 3
|
||||
else
|
||||
FSamplesPerPixel := 4;
|
||||
@ -2484,7 +2481,6 @@ end;
|
||||
|
||||
procedure TCocoaBrush.SetImage(AImage: NSImage);
|
||||
var
|
||||
AWidth, AHeight: Single;
|
||||
ACallBacks: CGPatternCallbacks;
|
||||
Rect: CGRect;
|
||||
begin
|
||||
|
@ -125,7 +125,7 @@ type
|
||||
function RawImage_DescriptionFromCocoaBitmap(out ADesc: TRawImageDescription; ABitmap: TCocoaBitmap): Boolean;
|
||||
function RawImage_FromCocoaBitmap(out ARawImage: TRawImage; ABitmap, AMask: TCocoaBitmap; ARect: PRect = nil): Boolean;
|
||||
function RawImage_DescriptionToBitmapType(ADesc: TRawImageDescription; out bmpType: TCocoaBitmapType): Boolean;
|
||||
// function GetImagePixelData(AImage: CGImageRef; var bitmapByteCount: PtrUInt): Pointer;
|
||||
function GetImagePixelData(AImage: CGImageRef; out bitmapByteCount: PtrUInt): Pointer;
|
||||
property NSApp: NSApplication read FNSApp;
|
||||
// the winapi compatibility methods
|
||||
{$I cocoawinapih.inc}
|
||||
|
@ -433,7 +433,84 @@ begin
|
||||
then Result := RawImage_FromCocoaBitmap(ARawImage, TCocoaBitmap(ABitmap), TCocoaBitmap(AMask), ARect)
|
||||
else Result := False;
|
||||
end;
|
||||
(*
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
Method: TCocoaWidgetSet.GetImagePixelData
|
||||
|
||||
Used by RawImage_FromDevice. Copies the data from a CGImageRef into a local
|
||||
buffer.
|
||||
|
||||
The buffer is created using GetMem, and the caller is responsible for using
|
||||
FreeMem to free the returned pointer.
|
||||
|
||||
This function throws exceptions in case of errors and may return a nil pointer.
|
||||
------------------------------------------------------------------------------}
|
||||
function TCocoaWidgetSet.GetImagePixelData(AImage: CGImageRef; out bitmapByteCount: PtrUInt): Pointer;
|
||||
var
|
||||
bitmapData: Pointer;
|
||||
context: CGContextRef = nil;
|
||||
colorSpace: CGColorSpaceRef;
|
||||
bitmapBytesPerRow, pixelsWide, pixelsHigh: PtrUInt;
|
||||
imageRect: CGRect;
|
||||
begin
|
||||
Result := nil;
|
||||
|
||||
// Get image width, height. The entire image is used.
|
||||
pixelsWide := CGImageGetWidth(AImage);
|
||||
pixelsHigh := CGImageGetHeight(AImage);
|
||||
imageRect.origin.x := 0.0;
|
||||
imageRect.origin.y := 0.0;
|
||||
imageRect.size.width := pixelsWide;
|
||||
imageRect.size.height := pixelsHigh;
|
||||
|
||||
// The target format is fixed in ARGB, DQWord alignment, with 32-bits depth and
|
||||
// 8-bits per channel, the default image format on the LCL
|
||||
bitmapBytesPerRow := ((pixelsWide * 4) + $F) and not PtrUInt($F);
|
||||
bitmapByteCount := (bitmapBytesPerRow * pixelsHigh);
|
||||
|
||||
// Use the generic RGB color space.
|
||||
colorSpace := CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
||||
if (colorSpace = nil) then
|
||||
raise Exception.Create('Unable to create CGColorSpaceRef');
|
||||
|
||||
// Allocate memory for image data. This is the destination in memory
|
||||
// where any drawing to the bitmap context will be rendered.
|
||||
bitmapData := System.GetMem( bitmapByteCount );
|
||||
if (bitmapData = nil) then
|
||||
raise Exception.Create('Unable to allocate memory');
|
||||
|
||||
{ Creates the bitmap context.
|
||||
|
||||
Regardless of what the source image format is, it will be converted
|
||||
over to the format specified here by CGBitmapContextCreate. }
|
||||
context := CGBitmapContextCreate(bitmapData,
|
||||
pixelsWide,
|
||||
pixelsHigh,
|
||||
8, // bits per component
|
||||
bitmapBytesPerRow,
|
||||
colorSpace,
|
||||
kCGImageAlphaNoneSkipFirst); // The function fails with kCGImageAlphaFirst
|
||||
if (context = nil) then
|
||||
begin
|
||||
System.FreeMem(bitmapData);
|
||||
raise Exception.Create('Unable to create CGContextRef');
|
||||
end;
|
||||
|
||||
// Draw the image to the bitmap context. Once we draw, the memory
|
||||
// allocated for the context for rendering will then contain the
|
||||
// raw image data in the specified color space.
|
||||
CGContextDrawImage(context, imageRect, AImage);
|
||||
|
||||
// Now we can get a pointer to the image data associated with the context.
|
||||
// ToDo: Verify if we should copy this data to a new buffer
|
||||
Result := CGBitmapContextGetData(context);
|
||||
|
||||
{ Clean-up }
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
CGContextRelease(context);
|
||||
end;
|
||||
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
Function: RawImage_FromDevice
|
||||
Params: ARawImage: Image to create
|
||||
@ -458,9 +535,9 @@ end;
|
||||
|
||||
http://developer.apple.com/qa/qa2007/qa1509.html
|
||||
------------------------------------------------------------------------------}
|
||||
function TCarbonWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
|
||||
function TCocoaWidgetSet.RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean;
|
||||
var
|
||||
CBC: TCarbonBitmapContext absolute ADC;
|
||||
CBC: TCocoaBitmapContext absolute ADC;
|
||||
Desc: TRawImageDescription absolute ARawImage.Description;
|
||||
displayID: CGDirectDisplayID;
|
||||
ScreenImage: CGImageRef;
|
||||
@ -469,9 +546,9 @@ begin
|
||||
|
||||
// Verifies if we are getting the rawimage from a normal DC as opposed to a
|
||||
// desktop DC
|
||||
if CheckDC(ADC, 'RawImage_FromDevice') and (CBC is TCarbonBitmapContext) then
|
||||
if CheckDC(ADC, 'RawImage_FromDevice') and (CBC is TCocoaBitmapContext) then
|
||||
begin
|
||||
Result := RawImage_FromCarbonBitmap(ARawImage, CBC.Bitmap, nil, @ARect);
|
||||
Result := RawImage_FromCocoaBitmap(ARawImage, CBC.Bitmap, nil, @ARect);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
@ -479,8 +556,7 @@ begin
|
||||
|
||||
{ Get's a screenshot }
|
||||
displayID := CGMainDisplayID();
|
||||
ScreenImage := grabViaOpenGL(displayID, CGDisplayBounds(displayID));
|
||||
//dataProvider := CGImageGetDataProvider(ScreenImage);
|
||||
ScreenImage := CGDisplayCreateImage(displayID);
|
||||
|
||||
{ Fills the image description }
|
||||
ARawImage.Init;
|
||||
@ -509,7 +585,7 @@ end;
|
||||
//begin
|
||||
// // override only when queried formats are different from screen description
|
||||
//end;
|
||||
|
||||
(*
|
||||
{------------------------------------------------------------------------------
|
||||
Method: ReleaseDesignerDC
|
||||
Params: Window - handle of window
|
||||
|
@ -52,9 +52,9 @@ function RawImage_CreateBitmaps(const ARawImage: TRawImage; out ABitmap, AMask:
|
||||
function RawImage_DescriptionFromBitmap(ABitmap: HBITMAP; out ADesc: TRawImageDescription): Boolean; override;
|
||||
function RawImage_DescriptionFromDevice(ADC: HDC; out ADesc: TRawImageDescription): Boolean; override;
|
||||
function RawImage_FromBitmap(out ARawImage: TRawImage; ABitmap, AMask: HBITMAP; ARect: PRect = nil): Boolean; override;
|
||||
{function RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean; override;
|
||||
function RawImage_FromDevice(out ARawImage: TRawImage; ADC: HDC; const ARect: TRect): Boolean; override;
|
||||
// override only when queried formats are different from screen description
|
||||
//function RawImage_QueryDescription(AFlags: TRawImageQueryFlags; var ADesc: TRawImageDescription): Boolean; override;
|
||||
|
||||
function ReleaseDesignerDC(Window: HWND; DC: HDC): Integer; override;}
|
||||
{function ReleaseDesignerDC(Window: HWND; DC: HDC): Integer; override;}
|
||||
|
||||
|
@ -527,7 +527,7 @@ begin
|
||||
if ADesc.Format = ricfGray then Exit;
|
||||
|
||||
// alpha
|
||||
if ABitmap.BitmapType in [cbtARGB, cbtRGBA, cbtBGRA] then
|
||||
if ABitmap.BitmapType in [cbtARGB, cbtRGBA] then
|
||||
ADesc.AlphaPrec := Prec;
|
||||
|
||||
case ABitmap.BitmapType of
|
||||
@ -539,14 +539,6 @@ begin
|
||||
Dec(Shift, Prec);
|
||||
ADesc.BlueShift := Shift;
|
||||
end;
|
||||
cbtBGR: begin
|
||||
Shift := 32 - Prec;
|
||||
ADesc.BlueShift := Shift;
|
||||
Dec(Shift, Prec);
|
||||
ADesc.GreenShift := Shift;
|
||||
Dec(Shift, Prec);
|
||||
ADesc.RedShift := Shift;
|
||||
end;
|
||||
cbtARGB: begin
|
||||
Shift := 32 - Prec;
|
||||
ADesc.AlphaShift := Shift;
|
||||
@ -567,16 +559,6 @@ begin
|
||||
Dec(Shift, Prec);
|
||||
ADesc.AlphaShift := Shift;
|
||||
end;
|
||||
cbtBGRA: begin
|
||||
Shift := 32 - Prec;
|
||||
ADesc.BlueShift := Shift;
|
||||
Dec(Shift, Prec);
|
||||
ADesc.GreenShift := Shift;
|
||||
Dec(Shift, Prec);
|
||||
ADesc.RedShift := Shift;
|
||||
Dec(Shift, Prec);
|
||||
ADesc.AlphaShift := Shift;
|
||||
end;
|
||||
end;
|
||||
|
||||
Result := True;
|
||||
@ -646,21 +628,9 @@ begin
|
||||
and (ADesc.GreenShift = 16 )
|
||||
and (ADesc.BlueShift = 8 )
|
||||
then bmpType := cbtRGBA
|
||||
else
|
||||
if (ADesc.AlphaShift = 0 )
|
||||
and (ADesc.RedShift = 8 )
|
||||
and (ADesc.GreenShift = 16)
|
||||
and (ADesc.BlueShift = 24)
|
||||
then bmpType := cbtBGRA
|
||||
else Exit;
|
||||
end
|
||||
else begin
|
||||
if (ADesc.AlphaShift = 24)
|
||||
and (ADesc.RedShift = 16)
|
||||
and (ADesc.GreenShift = 8 )
|
||||
and (ADesc.BlueShift = 0 )
|
||||
then bmpType := cbtBGRA
|
||||
else
|
||||
if (ADesc.AlphaShift = 0 )
|
||||
and (ADesc.RedShift = 8 )
|
||||
and (ADesc.GreenShift = 16)
|
||||
|
Loading…
Reference in New Issue
Block a user