mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 23:39:40 +02:00
* Fixed loading of old graphic streams
* Added TIcon.AssignImage, so one image of an icon can be changed git-svn-id: trunk@15775 -
This commit is contained in:
parent
a5f211b8cc
commit
19919c7035
@ -391,10 +391,13 @@ const
|
|||||||
|
|
||||||
type
|
type
|
||||||
TCanvas = class;
|
TCanvas = class;
|
||||||
|
|
||||||
// standard LCL graphic formats
|
// base class
|
||||||
TCustomBitmap = class; // base class
|
TRasterImage = class;
|
||||||
|
TRasterImageClass = class of TRasterImage;
|
||||||
|
TCustomBitmap = class;
|
||||||
TCustomBitmapClass = class of TCustomBitmap;
|
TCustomBitmapClass = class of TCustomBitmap;
|
||||||
|
// standard LCL graphic formats
|
||||||
TBitmap = class; // bmp
|
TBitmap = class; // bmp
|
||||||
TPixmap = class; // xpm
|
TPixmap = class; // xpm
|
||||||
TIcon = class; // ico
|
TIcon = class; // ico
|
||||||
@ -1481,6 +1484,7 @@ type
|
|||||||
|
|
||||||
procedure Add(AFormat: TPixelFormat; AHeight, AWidth: Word);
|
procedure Add(AFormat: TPixelFormat; AHeight, AWidth: Word);
|
||||||
procedure Assign(Source: TPersistent); override;
|
procedure Assign(Source: TPersistent); override;
|
||||||
|
procedure AssignImage(ASource: TRasterImage); virtual;
|
||||||
procedure Clear; override;
|
procedure Clear; override;
|
||||||
procedure Delete(Aindex: Integer);
|
procedure Delete(Aindex: Integer);
|
||||||
procedure Remove(AFormat: TPixelFormat; AHeight, AWidth: Word);
|
procedure Remove(AFormat: TPixelFormat; AHeight, AWidth: Word);
|
||||||
@ -1779,6 +1783,7 @@ begin
|
|||||||
Result:='['+Result+']';
|
Result:='['+Result+']';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function LoadCursorFromLazarusResource(ACursorName: String): HCursor;
|
function LoadCursorFromLazarusResource(ACursorName: String): HCursor;
|
||||||
var
|
var
|
||||||
CursorImage: TCursorImage;
|
CursorImage: TCursorImage;
|
||||||
|
@ -270,12 +270,85 @@ end;
|
|||||||
|
|
||||||
procedure TCustomIcon.Assign(Source: TPersistent);
|
procedure TCustomIcon.Assign(Source: TPersistent);
|
||||||
begin
|
begin
|
||||||
if Source is TCustomIcon then
|
if Source is TCustomIcon
|
||||||
|
then begin
|
||||||
FCurrent := TCustomIcon(Source).Current;
|
FCurrent := TCustomIcon(Source).Current;
|
||||||
|
end
|
||||||
|
else if Source is TRasterImage
|
||||||
|
then begin
|
||||||
|
Clear;
|
||||||
|
|
||||||
|
with TRasterImage(Source) do
|
||||||
|
Self.Add(PixelFormat, Height, Width);
|
||||||
|
|
||||||
|
AssignImage(TRasterImage(Source));
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
inherited Assign(Source);
|
inherited Assign(Source);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomIcon.AssignImage(ASource: TRasterImage);
|
||||||
|
var
|
||||||
|
Image, NewImage: TIconImage;
|
||||||
|
RawImage: PRawImage;
|
||||||
|
begin
|
||||||
|
if FCurrent = -1
|
||||||
|
then raise EInvalidGraphicOperation.Create(rsIconNoCurrent);
|
||||||
|
|
||||||
|
if ASource = nil
|
||||||
|
then raise EInvalidGraphicOperation.Create(rsIconImageEmpty);
|
||||||
|
|
||||||
|
Image := TIconImage(TSharedIcon(FSharedImage).FImages[FCurrent]);
|
||||||
|
|
||||||
|
if (Image.Width <> ASource.Width)
|
||||||
|
or (Image.Height <> ASource.Height)
|
||||||
|
then raise EInvalidGraphicOperation.Create(rsIconImageSize);
|
||||||
|
|
||||||
|
if Image.PixelFormat <> ASource.PixelFormat
|
||||||
|
then raise EInvalidGraphicOperation.Create(rsIconImageFormat);
|
||||||
|
|
||||||
|
UnshareImage(True);
|
||||||
|
FreeCanvasContext;
|
||||||
|
|
||||||
|
RawImage := ASource.GetRawImage;
|
||||||
|
NewImage := TIconImage.Create(Image.PixelFormat, Image.Height, Image.Width);
|
||||||
|
try
|
||||||
|
NewImage.FImage.Description := RawImage^.Description;
|
||||||
|
|
||||||
|
NewImage.FImage.DataSize := RawImage^.DataSize;
|
||||||
|
if NewImage.FImage.DataSize > 0
|
||||||
|
then begin
|
||||||
|
NewImage.FImage.Data := GetMem(NewImage.FImage.DataSize);
|
||||||
|
Move(RawImage^.Data^, NewImage.FImage.Data^, NewImage.FImage.DataSize);
|
||||||
|
end;
|
||||||
|
NewImage.FImage.MaskSize := RawImage^.MaskSize;
|
||||||
|
if NewImage.FImage.MaskSize > 0
|
||||||
|
then begin
|
||||||
|
NewImage.FImage.Mask := GetMem(NewImage.FImage.MaskSize);
|
||||||
|
Move(RawImage^.Mask^, NewImage.FImage.Mask^, NewImage.FImage.MaskSize);
|
||||||
|
end;
|
||||||
|
NewImage.FImage.PaletteSize := RawImage^.PaletteSize;
|
||||||
|
if NewImage.FImage.PaletteSize > 0
|
||||||
|
then begin
|
||||||
|
NewImage.FImage.Palette := GetMem(NewImage.FImage.PaletteSize);
|
||||||
|
Move(RawImage^.Palette^, NewImage.FImage.Palette^, NewImage.FImage.PaletteSize);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// this cannot be shcanged without adjusting data
|
||||||
|
// NewImage.FImage.Description.MaskBitsPerPixel := 1;
|
||||||
|
|
||||||
|
TSharedIcon(FSharedImage).FImages[FCurrent] := NewImage;
|
||||||
|
NewImage := nil;
|
||||||
|
Image.Free;
|
||||||
|
|
||||||
|
finally
|
||||||
|
NewImage.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Changed(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCustomIcon.Clear;
|
procedure TCustomIcon.Clear;
|
||||||
begin
|
begin
|
||||||
if not Empty then
|
if not Empty then
|
||||||
@ -475,14 +548,15 @@ begin
|
|||||||
|
|
||||||
Position := Stream.Position;
|
Position := Stream.Position;
|
||||||
Stream.Read(Signature, SizeOf(Signature));
|
Stream.Read(Signature, SizeOf(Signature));
|
||||||
|
Stream.Position := Position;
|
||||||
if Cardinal(Signature) = Cardinal(IconSignature)
|
if Cardinal(Signature) = Cardinal(IconSignature)
|
||||||
then begin
|
then begin
|
||||||
// Assume Icon - stream without explicit size
|
// Assume Icon - stream without explicit size
|
||||||
Stream.Position := Position;
|
|
||||||
LoadFromStream(Stream);
|
LoadFromStream(Stream);
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
LoadFromStream(Stream, LEtoN(Size));
|
// use inherited to read, so "old" streams are converted
|
||||||
|
inherited;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -731,7 +805,7 @@ var
|
|||||||
NewIcon, OldIcon: TSharedIcon;
|
NewIcon, OldIcon: TSharedIcon;
|
||||||
n: Integer;
|
n: Integer;
|
||||||
OldImage, NewImage: TIconImage;
|
OldImage, NewImage: TIconImage;
|
||||||
OldBitmap: TSharedCustomBitmap;
|
// OldBitmap: TSharedCustomBitmap;
|
||||||
OldSharedImage: TSharedImage;
|
OldSharedImage: TSharedImage;
|
||||||
begin
|
begin
|
||||||
if FSharedImage.RefCount <= 1 then Exit;
|
if FSharedImage.RefCount <= 1 then Exit;
|
||||||
@ -741,8 +815,12 @@ begin
|
|||||||
NewIcon.Reference;
|
NewIcon.Reference;
|
||||||
if CopyContent
|
if CopyContent
|
||||||
then begin
|
then begin
|
||||||
|
// in theory we should have a compatible shared image
|
||||||
|
// if not, something internal is wrong
|
||||||
|
(*
|
||||||
if FSharedImage is TSharedIcon then
|
if FSharedImage is TSharedIcon then
|
||||||
begin
|
begin
|
||||||
|
*)
|
||||||
OldIcon := FSharedImage as TSharedIcon;
|
OldIcon := FSharedImage as TSharedIcon;
|
||||||
for n := 0 to OldIcon.FImages.Count -1 do
|
for n := 0 to OldIcon.FImages.Count -1 do
|
||||||
begin
|
begin
|
||||||
@ -769,6 +847,7 @@ begin
|
|||||||
Move(OldImage.FImage.Palette^, NewImage.FImage.Palette^, NewImage.FImage.PaletteSize);
|
Move(OldImage.FImage.Palette^, NewImage.FImage.Palette^, NewImage.FImage.PaletteSize);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
(*
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if FSharedImage is TSharedCustomBitmap then
|
if FSharedImage is TSharedCustomBitmap then
|
||||||
@ -797,6 +876,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
NewImage.FImage.Description.MaskBitsPerPixel := 1;
|
NewImage.FImage.Description.MaskBitsPerPixel := 1;
|
||||||
end;
|
end;
|
||||||
|
*)
|
||||||
end;
|
end;
|
||||||
FreeCanvasContext;
|
FreeCanvasContext;
|
||||||
OldSharedImage := FSharedImage;
|
OldSharedImage := FSharedImage;
|
||||||
|
@ -649,12 +649,56 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TRasterImage.ReadData(Stream: TStream);
|
procedure TRasterImage.ReadData(Stream: TStream);
|
||||||
|
function GetImageClass: TRasterImageClass;
|
||||||
|
const
|
||||||
|
// need to repeat here since they aren't defined yet
|
||||||
|
IconSignature: array [0..3] of char = #0#0#1#0;
|
||||||
|
CursorSignature: array [0..3] of char = #0#0#2#0;
|
||||||
|
var
|
||||||
|
Sig: array[0..7] of Char;
|
||||||
|
Position: Int64;
|
||||||
|
begin
|
||||||
|
Position := Stream.Position;
|
||||||
|
Stream.Read(Sig[0], SizeOf(Sig));
|
||||||
|
Stream.Position := Position;
|
||||||
|
|
||||||
|
if (Sig[0] = 'B') and (Sig[1] = 'M') then Exit(TBitmap);
|
||||||
|
if CompareMem(@Sig[0], @PNGcomn.Signature[0], 8) then Exit(TPortableNetworkGraphic);
|
||||||
|
if CompareMem(@Sig[0], @IconSignature[0], 4) then Exit(TIcon);
|
||||||
|
if CompareMem(@Sig[0], @CursorSignature[0], 4) then Exit(TCursorImage);
|
||||||
|
if TestStreamIsXPM(Stream) then Exit(TPixmap);
|
||||||
|
|
||||||
|
Result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
Size: Longint;
|
Size: Longint;
|
||||||
|
ImageClass: TRasterImageClass;
|
||||||
|
Image: TRasterImage;
|
||||||
begin
|
begin
|
||||||
Stream.Read(Size, SizeOf(Size));
|
Stream.Read(Size, SizeOf(Size));
|
||||||
Size := LEtoN(Size);
|
Size := LEtoN(Size);
|
||||||
LoadFromStream(Stream, Size);
|
|
||||||
|
// pre laz 0.9.26 there was no strict relation between graphic format and
|
||||||
|
// classtype, so we need to check if we need some conversion
|
||||||
|
if Size >= 8
|
||||||
|
then ImageClass := GetImageClass
|
||||||
|
else ImageClass := nil;
|
||||||
|
|
||||||
|
if (ImageClass = nil) or ClassType.InheritsFrom(ImageClass)
|
||||||
|
then begin
|
||||||
|
// no conversion needed, or it wasn't a known "old" format
|
||||||
|
LoadFromStream(Stream, Size);
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Image := ImageClass.Create;
|
||||||
|
Image.LoadFromStream(Stream, Size);
|
||||||
|
try
|
||||||
|
Assign(Image);
|
||||||
|
finally
|
||||||
|
Image.Free;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TRasterImage.WriteData(Stream: TStream);
|
procedure TRasterImage.WriteData(Stream: TStream);
|
||||||
|
@ -196,6 +196,10 @@ ResourceString
|
|||||||
rsUnsupportedBitmapFormat = 'Unsupported bitmap format.';
|
rsUnsupportedBitmapFormat = 'Unsupported bitmap format.';
|
||||||
rsErrorWhileSavingBitmap = 'Error while saving bitmap.';
|
rsErrorWhileSavingBitmap = 'Error while saving bitmap.';
|
||||||
rsDuplicateIconFormat = 'Duplicate icon format.';
|
rsDuplicateIconFormat = 'Duplicate icon format.';
|
||||||
|
rsIconImageEmpty = 'Icon image cannot be empty';
|
||||||
|
rsIconImageSize = 'Icon image must have the same size';
|
||||||
|
rsIconNoCurrent = 'Icon has no current image';
|
||||||
|
rsIconImageFormat = 'Icon image must have the same format';
|
||||||
rsNoWidgetSet = 'No widgetset object. '
|
rsNoWidgetSet = 'No widgetset object. '
|
||||||
+'Please check if the unit "interfaces" was added to the programs uses clause.';
|
+'Please check if the unit "interfaces" was added to the programs uses clause.';
|
||||||
rsPressOkToIgnoreAndRiskDataCorruptionPressCancelToK = '%s%sPress Ok to '
|
rsPressOkToIgnoreAndRiskDataCorruptionPressCancelToK = '%s%sPress Ok to '
|
||||||
|
Loading…
Reference in New Issue
Block a user