mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2026-01-04 15:10:37 +01:00
* When saving icon, use maskhandle when set
* Update custombitmap pixelformat when rawimage is changed git-svn-id: trunk@16395 -
This commit is contained in:
parent
68a2e1b6d1
commit
848eeac586
@ -1251,6 +1251,7 @@ type
|
||||
TCustomBitmap = class(TRasterImage)
|
||||
private
|
||||
FPixelFormat: TPixelFormat;
|
||||
FPixelFormatNeedsUpdate: Boolean;
|
||||
FMaskHandle: HBITMAP; // mask is not part of the image, so not shared
|
||||
function GetHandleType: TBitmapHandleType;
|
||||
function GetMonochrome: Boolean;
|
||||
@ -1284,6 +1285,7 @@ type
|
||||
constructor Create; override;
|
||||
destructor Destroy; override;
|
||||
|
||||
procedure Clear; override;
|
||||
function GetResourceType: TResourceType; override;
|
||||
function LazarusResourceTypeValid(const ResourceType: string): Boolean; override;
|
||||
function BitmapHandleAllocated: boolean; override;
|
||||
|
||||
@ -39,6 +39,12 @@ begin
|
||||
inherited Changed(Sender);
|
||||
end;
|
||||
|
||||
procedure TCustomBitmap.Clear;
|
||||
begin
|
||||
FPixelFormat := pfDevice;
|
||||
inherited Clear;
|
||||
end;
|
||||
|
||||
constructor TCustomBitmap.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
@ -126,7 +132,7 @@ begin
|
||||
if ImagePtr^.IsMasked(False)
|
||||
then begin
|
||||
// move mask to image data, so we only have to create one handle
|
||||
// (and don't have to think about imahehandle format)
|
||||
// (and don't have to think about imagehandle format)
|
||||
|
||||
MaskImage.Init;
|
||||
MaskImage.Description := ImagePtr^.Description.GetDescriptionFromMask;
|
||||
@ -182,6 +188,7 @@ begin
|
||||
if ADescOnly
|
||||
or not RawImage_FromBitmap(ImagePtr^, FSharedImage.FHandle, FMaskHandle)
|
||||
then ImagePtr^.Description := GetDescriptionFromBitmap(FSharedImage.FHandle);
|
||||
FPixelFormatNeedsUpdate := True;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
@ -189,7 +196,8 @@ begin
|
||||
// ImagePtr^.Description := GetDescriptionFromDevice(0, ImagePtr^.Description.Width, ImagePtr^.Description.Height);
|
||||
// use query to get a default description without alpha, since alpha drawing
|
||||
// is not yet supported (unless asked for)
|
||||
case PixelFormat of
|
||||
// use var and not pixelformat property since it requires a rawimagedescription (which we are creating)
|
||||
case FPixelFormat of
|
||||
pf1bit: Flags := [riqfMono, riqfMask];
|
||||
pf4bit,
|
||||
pf8bit: Flags := [riqfRGB, riqfMask, riqfPalette];
|
||||
@ -198,6 +206,8 @@ begin
|
||||
Flags := [riqfRGB, riqfMask];
|
||||
end;
|
||||
ImagePtr^.Description := QueryDescription(Flags, ImagePtr^.Description.Width, ImagePtr^.Description.Height);
|
||||
// atleast for now let pixelformat reflect the created description
|
||||
FPixelFormatNeedsUpdate := True;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
@ -206,6 +216,7 @@ begin
|
||||
try
|
||||
OnChange := nil;
|
||||
LoadFromStream(FSharedImage.FSaveStream);
|
||||
FPixelFormatNeedsUpdate := True;
|
||||
finally
|
||||
OnChange := OldChangeEvent;
|
||||
end;
|
||||
@ -333,7 +344,9 @@ end;
|
||||
|
||||
procedure TCustomBitmap.UpdatePixelFormat;
|
||||
begin
|
||||
RawimageNeeded(True);
|
||||
FPixelFormat := TSharedCustomBitmap(FSharedImage).GetPixelFormat;
|
||||
FPixelFormatNeedsUpdate := False;
|
||||
end;
|
||||
|
||||
function TCustomBitmap.GetMonochrome: Boolean;
|
||||
@ -413,7 +426,10 @@ begin
|
||||
end;
|
||||
|
||||
if UpdateHandles(ABitmap, AMask)
|
||||
then Changed(Self);
|
||||
then begin
|
||||
FPixelFormatNeedsUpdate := True;
|
||||
Changed(Self);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCustomBitmap.SetHandle(AValue: THandle);
|
||||
@ -446,6 +462,8 @@ end;
|
||||
|
||||
function TCustomBitmap.GetPixelFormat: TPixelFormat;
|
||||
begin
|
||||
if FPixelFormatNeedsUpdate
|
||||
then UpdatePixelFormat;
|
||||
Result := FPixelFormat;
|
||||
end;
|
||||
|
||||
|
||||
@ -129,6 +129,7 @@ begin
|
||||
SCB.FHasMask := IntfImg.HasMask;
|
||||
if not SCB.FHasMask
|
||||
then SCB.FImage.Description.MaskBitsPerPixel := 0;
|
||||
FPixelFormatNeedsUpdate := True;
|
||||
finally
|
||||
LazReader := nil;
|
||||
IntfImg.Free;
|
||||
|
||||
@ -332,6 +332,7 @@ procedure TCustomIcon.AssignImage(ASource: TRasterImage);
|
||||
var
|
||||
Image, NewImage: TIconImage;
|
||||
RawImg: PRawImage;
|
||||
RawMsk: TRawImage;
|
||||
begin
|
||||
if FCurrent = -1
|
||||
then raise EInvalidGraphicOperation.Create(rsIconNoCurrent);
|
||||
@ -356,18 +357,43 @@ begin
|
||||
try
|
||||
NewImage.FImage.Description := RawImg^.Description;
|
||||
|
||||
// image
|
||||
NewImage.FImage.DataSize := RawImg^.DataSize;
|
||||
if NewImage.FImage.DataSize > 0
|
||||
then begin
|
||||
NewImage.FImage.Data := GetMem(NewImage.FImage.DataSize);
|
||||
Move(RawImg^.Data^, NewImage.FImage.Data^, NewImage.FImage.DataSize);
|
||||
end;
|
||||
NewImage.FImage.MaskSize := RawImg^.MaskSize;
|
||||
if NewImage.FImage.MaskSize > 0
|
||||
|
||||
// mask
|
||||
// in theory, it should not matter if a HBITMAP was created as bitmap or as mask
|
||||
// since there is a description problem in gtk, create both (we cannot create mask only)
|
||||
// todo: fix gtk
|
||||
if ASource.MaskHandleAllocated
|
||||
and RawImage_FromBitmap(RawMsk, ASource.MaskHandle, ASource.MaskHandle)
|
||||
then begin
|
||||
NewImage.FImage.Mask := GetMem(NewImage.FImage.MaskSize);
|
||||
Move(RawImg^.Mask^, NewImage.FImage.Mask^, NewImage.FImage.MaskSize);
|
||||
NewImage.FImage.MaskSize := RawMsk.MaskSize;
|
||||
if NewImage.FImage.MaskSize > 0
|
||||
then begin
|
||||
NewImage.FImage.Mask := GetMem(NewImage.FImage.MaskSize);
|
||||
Move(RawMsk.Mask^, NewImage.FImage.Mask^, NewImage.FImage.MaskSize);
|
||||
|
||||
// prevent cleanup
|
||||
RawMsk.MaskSize := 0;
|
||||
RawMsk.Mask := nil;
|
||||
end;
|
||||
RawMsk.FreeData;
|
||||
end
|
||||
else begin
|
||||
NewImage.FImage.MaskSize := RawImg^.MaskSize;
|
||||
if NewImage.FImage.MaskSize > 0
|
||||
then begin
|
||||
NewImage.FImage.Mask := GetMem(NewImage.FImage.MaskSize);
|
||||
Move(RawImg^.Mask^, NewImage.FImage.Mask^, NewImage.FImage.MaskSize);
|
||||
end;
|
||||
end;
|
||||
|
||||
// palette
|
||||
NewImage.FImage.PaletteSize := RawImg^.PaletteSize;
|
||||
if NewImage.FImage.PaletteSize > 0
|
||||
then begin
|
||||
@ -948,26 +974,29 @@ begin
|
||||
end;
|
||||
|
||||
procedure TCustomIcon.WriteStream(AStream: TMemoryStream);
|
||||
procedure GetMaskData(ARawImg: TRawImage; AMskPtr: Pointer; AMskSize, AWidth, AHeight: Cardinal);
|
||||
procedure GetMaskData(ARawImg: TRawImage; AIconImage: TIconImage; AMskPtr: Pointer; AMskSize: Cardinal);
|
||||
var
|
||||
SrcRawImg, DstRawImg: TRawImage;
|
||||
SrcDesc: TRawImageDescription absolute SrcRawImg.Description;
|
||||
DstDesc: TRawImageDescription absolute DstRawImg.Description;
|
||||
SrcImage, DstImage: TLazIntfImage;
|
||||
begin
|
||||
|
||||
SrcRawImg.Init;
|
||||
SrcRawImg.Description := ARawImg.Description.GetDescriptionFromMask;
|
||||
SrcRawImg.Data := ARawImg.Mask;
|
||||
SrcRawImg.DataSize := ARawImg.MaskSize;
|
||||
if (AIconImage.MaskHandle = 0)
|
||||
or not RawImage_FromBitmap(SrcRawImg, AIconImage.MaskHandle, 0)
|
||||
then begin
|
||||
SrcRawImg.Init;
|
||||
SrcRawImg.Description := ARawImg.Description.GetDescriptionFromMask;
|
||||
SrcRawImg.Data := ARawImg.Mask;
|
||||
SrcRawImg.DataSize := ARawImg.MaskSize;
|
||||
end;
|
||||
|
||||
DstRawImg.Init;
|
||||
DstRawImg.Data := AMskPtr;
|
||||
DstRawImg.DataSize := AMskSize;
|
||||
|
||||
DstDesc.Format := ricfGray;
|
||||
DstDesc.Width := AWidth;
|
||||
DstDesc.Height := AHeight;
|
||||
DstDesc.Width := AIconImage.Width;
|
||||
DstDesc.Height := AIconImage.Height;
|
||||
DstDesc.Depth := 1;
|
||||
DstDesc.BitOrder := riboReversedBits;
|
||||
DstDesc.ByteOrder := riboLSBFirst;
|
||||
@ -1111,7 +1140,7 @@ begin
|
||||
if (RawImg.Mask = nil)
|
||||
or (RawImg.MaskSize = 0)
|
||||
then FillChar(MskPtr^, MskSize, 0)
|
||||
else GetMaskData(RawImg, MskPtr, MskSize, IconImage.Width, IconImage.Height);
|
||||
else GetMaskData(RawImg, IconImage, MskPtr, MskSize);
|
||||
|
||||
// write
|
||||
AStream.WriteBuffer(BmpPtr^, MemStream.Position - SizeOf(TBitMapFileHeader));
|
||||
|
||||
@ -157,13 +157,12 @@ end;
|
||||
|
||||
procedure TRasterImage.Clear;
|
||||
begin
|
||||
if not Empty then
|
||||
begin
|
||||
FreeSaveStream;
|
||||
SetSize(0, 0);
|
||||
if FUpdateCount = 0
|
||||
then Changed(Self);
|
||||
end;
|
||||
if Empty then Exit;
|
||||
|
||||
FreeSaveStream;
|
||||
SetSize(0, 0);
|
||||
if FUpdateCount = 0
|
||||
then Changed(Self);
|
||||
end;
|
||||
|
||||
procedure TRasterImage.BitmapHandleNeeded;
|
||||
|
||||
@ -75,6 +75,8 @@ end;
|
||||
|
||||
function TSharedCustomBitmap.GetPixelFormat: TPixelFormat;
|
||||
begin
|
||||
if FImage.Description.Format = ricfNone then Exit(pfDevice);
|
||||
|
||||
case FImage.Description.Depth of
|
||||
1: Exit(pf1Bit);
|
||||
4: Exit(pf4Bit);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user