* When saving icon, use maskhandle when set

* Update custombitmap pixelformat when rawimage is changed

git-svn-id: trunk@16395 -
This commit is contained in:
marc 2008-09-04 00:09:45 +00:00
parent 68a2e1b6d1
commit 848eeac586
6 changed files with 74 additions and 23 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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));

View File

@ -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;

View File

@ -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);