mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 20:59:06 +02:00
made TIcon more independent of TBitmap from Colin
git-svn-id: trunk@5404 -
This commit is contained in:
parent
723d653f98
commit
eaf26981f3
@ -38,7 +38,7 @@ interface
|
|||||||
|
|
||||||
|
|
||||||
uses
|
uses
|
||||||
SysUtils, Classes, FPCAdds,
|
SysUtils, Classes, Contnrs, FPCAdds,
|
||||||
{$IFNDEF DisableFPImage}
|
{$IFNDEF DisableFPImage}
|
||||||
FPImage, FPReadPNG, FPWritePNG, FPReadBMP, FPWriteBMP, IntfGraphics,
|
FPImage, FPReadPNG, FPWritePNG, FPReadBMP, FPWriteBMP, IntfGraphics,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
@ -998,9 +998,6 @@ type
|
|||||||
procedure WriteData(Stream: TStream); override;
|
procedure WriteData(Stream: TStream); override;
|
||||||
procedure StoreOriginalStream(Stream: TStream; Size: integer); virtual;
|
procedure StoreOriginalStream(Stream: TStream; Size: integer); virtual;
|
||||||
{$IFNDEF DisableFPImage}
|
{$IFNDEF DisableFPImage}
|
||||||
procedure ReadStreamWithFPImage(Stream: TStream; UseSize: boolean;
|
|
||||||
Size: Longint;
|
|
||||||
ReaderClass: TFPCustomImageReaderClass); virtual;
|
|
||||||
procedure WriteStreamWithFPImage(Stream: TStream; WriteSize: boolean;
|
procedure WriteStreamWithFPImage(Stream: TStream; WriteSize: boolean;
|
||||||
WriterClass: TFPCustomImageWriterClass); virtual;
|
WriterClass: TFPCustomImageWriterClass); virtual;
|
||||||
procedure InitFPImageReader(ImgReader: TFPCustomImageReader); virtual;
|
procedure InitFPImageReader(ImgReader: TFPCustomImageReader); virtual;
|
||||||
@ -1041,6 +1038,9 @@ type
|
|||||||
const FileExtension: string): TFPCustomImageWriterClass; override;
|
const FileExtension: string): TFPCustomImageWriterClass; override;
|
||||||
class function GetDefaultFPReader: TFPCustomImageReaderClass; override;
|
class function GetDefaultFPReader: TFPCustomImageReaderClass; override;
|
||||||
class function GetDefaultFPWriter: TFPCustomImageWriterClass; override;
|
class function GetDefaultFPWriter: TFPCustomImageWriterClass; override;
|
||||||
|
procedure ReadStreamWithFPImage(Stream: TStream; UseSize: boolean;
|
||||||
|
Size: Longint;
|
||||||
|
ReaderClass: TFPCustomImageReaderClass); virtual;
|
||||||
procedure WriteNativeStream(Stream: TStream; WriteSize: Boolean;
|
procedure WriteNativeStream(Stream: TStream; WriteSize: Boolean;
|
||||||
SaveStreamType: TBitmapNativeType); virtual;
|
SaveStreamType: TBitmapNativeType); virtual;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
@ -1110,11 +1110,25 @@ type
|
|||||||
{ TIcon }
|
{ TIcon }
|
||||||
{
|
{
|
||||||
TIcon reads and writes .ICO file format.
|
TIcon reads and writes .ICO file format.
|
||||||
! Currently it is almost a TBitmap !
|
A .ico file typically contains several versions of the same image. When loading,
|
||||||
|
the largest/most colourful image is loaded as the TBitmap and so can be handled
|
||||||
|
as any other bitmap. Any other versions of the images are available via the
|
||||||
|
Bitmaps property
|
||||||
|
Writing is not (yet) implemented.
|
||||||
}
|
}
|
||||||
TIcon = class(TBitmap)
|
TIcon = class(TBitmap)
|
||||||
|
{$IFNDEF DisableFPImage}
|
||||||
|
private
|
||||||
|
FBitmaps: TObjectList;
|
||||||
protected
|
protected
|
||||||
procedure ReadData(Stream: TStream); override;
|
procedure ReadData(Stream: TStream); override;
|
||||||
|
procedure InitFPImageReader(ImgReader: TFPCustomImageReader); override;
|
||||||
|
public
|
||||||
|
class function GetFileExtensions: string; override;
|
||||||
|
property Bitmaps: TObjectList read FBitmaps;
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure AddBitmap(Bitmap: TBitmap); { Note that Ownership passes to TIcon }
|
||||||
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1588,6 +1602,11 @@ end;
|
|||||||
|
|
||||||
{ TIcon }
|
{ TIcon }
|
||||||
|
|
||||||
|
{$IFNDEF DisableFPImage}
|
||||||
|
|
||||||
|
const
|
||||||
|
IconSignature: array [0..3] of char = #0#0#1#0;
|
||||||
|
|
||||||
function TestStreamIsIcon(const AStream: TStream): boolean;
|
function TestStreamIsIcon(const AStream: TStream): boolean;
|
||||||
var
|
var
|
||||||
Signature: array[0..3] of char;
|
Signature: array[0..3] of char;
|
||||||
@ -1596,7 +1615,7 @@ var
|
|||||||
begin
|
begin
|
||||||
OldPosition:=AStream.Position;
|
OldPosition:=AStream.Position;
|
||||||
ReadSize:=AStream.Read(Signature, SizeOf(Signature));
|
ReadSize:=AStream.Read(Signature, SizeOf(Signature));
|
||||||
Result:=(ReadSize=SizeOf(Signature)) and (Signature=#0#0#1#0);
|
Result:=(ReadSize=SizeOf(Signature)) and CompareMem(@Signature,@IconSignature,4);
|
||||||
AStream.Position:=OldPosition;
|
AStream.Position:=OldPosition;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1606,8 +1625,8 @@ var
|
|||||||
Position: TStreamSeekType;
|
Position: TStreamSeekType;
|
||||||
begin
|
begin
|
||||||
Position := Stream.Position;
|
Position := Stream.Position;
|
||||||
Stream.Read(Size, SizeOf(Size));
|
Stream.Read(Size, 4); // Beware BigEndian and LowEndian sytems
|
||||||
if Size = $10000 then begin // Icon starts 00 00 01 00
|
if CompareMem(@Size,@IconSignature,4) then begin
|
||||||
// Assume Icon - stream without explicit size
|
// Assume Icon - stream without explicit size
|
||||||
Stream.Position := Position;
|
Stream.Position := Position;
|
||||||
ReadStream(Stream, false, Size);
|
ReadStream(Stream, false, Size);
|
||||||
@ -1615,6 +1634,32 @@ begin
|
|||||||
ReadStream(Stream, true, Size);
|
ReadStream(Stream, true, Size);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TIcon.InitFPImageReader(ImgReader: TFPCustomImageReader);
|
||||||
|
begin
|
||||||
|
inherited InitFPImageReader(ImgReader);
|
||||||
|
if ImgReader is TLazReaderIcon then
|
||||||
|
TLazReaderIcon(ImgReader).Icon := self;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TIcon.GetFileExtensions: string;
|
||||||
|
begin
|
||||||
|
Result:='ico';
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TIcon.Destroy;
|
||||||
|
begin
|
||||||
|
inherited Destroy;
|
||||||
|
FreeAndNil(FBitmaps);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIcon.AddBitmap(Bitmap: TBitmap);
|
||||||
|
begin
|
||||||
|
if not Assigned(FBitmaps) then
|
||||||
|
FBitmaps := TObjectList.create(True);
|
||||||
|
FBitmaps.Add(Bitmap);
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
PicClipboardFormats:=nil;
|
PicClipboardFormats:=nil;
|
||||||
PicFileFormats:=nil;
|
PicFileFormats:=nil;
|
||||||
@ -1636,6 +1681,9 @@ end.
|
|||||||
{ =============================================================================
|
{ =============================================================================
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.134 2004/04/12 22:36:29 mattias
|
||||||
|
made TIcon more independent of TBitmap from Colin
|
||||||
|
|
||||||
Revision 1.133 2004/04/10 14:20:20 mattias
|
Revision 1.133 2004/04/10 14:20:20 mattias
|
||||||
fixed saving findtext from vincent
|
fixed saving findtext from vincent
|
||||||
|
|
||||||
|
@ -50,9 +50,7 @@ begin
|
|||||||
{$IFNDEF DisableFPImage}
|
{$IFNDEF DisableFPImage}
|
||||||
Add('png', 'Portable Network Graphic', TPortableNetworkGraphic);
|
Add('png', 'Portable Network Graphic', TPortableNetworkGraphic);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
{$IFDEF HasIconGraphic}
|
|
||||||
Add('ico', 'Icon', TIcon);
|
Add('ico', 'Icon', TIcon);
|
||||||
{$ENDIF}
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPicFileFormatsList.Clear;
|
procedure TPicFileFormatsList.Clear;
|
||||||
|
@ -3105,9 +3105,8 @@ var
|
|||||||
UnRef : Boolean;
|
UnRef : Boolean;
|
||||||
DCOrigin: TPoint;
|
DCOrigin: TPoint;
|
||||||
UnderLine: boolean;
|
UnderLine: boolean;
|
||||||
|
buffer: PGdkDrawable;
|
||||||
buffer : PGdkPixmap;
|
buffered: Boolean;
|
||||||
buffered : boolean;
|
|
||||||
|
|
||||||
procedure DrawTextLine;
|
procedure DrawTextLine;
|
||||||
var
|
var
|
||||||
@ -3202,25 +3201,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
//If we don't have double buffering, try and buffer each block of text,
|
|
||||||
//otherwise most text "flashes" by disapearing and then redrawing on account
|
|
||||||
//of the two passes, first one to draw bg and then another to draw fg.
|
|
||||||
|
|
||||||
//By doing it this way the "constant" flashing is replaced by more occasional
|
|
||||||
//flashing, and is primarily restricted to the larger blocks of text. Far
|
|
||||||
//more pleasant to work with, especially in the Lazarus Source Editor where
|
|
||||||
//each keyword, string, etc is its own block drawn individually, thus is
|
|
||||||
//constantly flashing during code changes, resizing, scrolling, etc.
|
|
||||||
if ((Options and ETO_OPAQUE) <> 0) then
|
if ((Options and ETO_OPAQUE) <> 0) then
|
||||||
begin
|
begin
|
||||||
Width := Rect^.Right - Rect^.Left;
|
Width := Rect^.Right - Rect^.Left;
|
||||||
Height := Rect^.Bottom - Rect^.Top;
|
Height := Rect^.Bottom - Rect^.Top;
|
||||||
SelectedColors := dcscCustom;
|
SelectedColors := dcscCustom;
|
||||||
EnsureGCColor(DC, dccCurrentBackColor, True, False);
|
EnsureGCColor(DC, dccCurrentBackColor, True, False);
|
||||||
{$IFDEF EnableDoubleBuf}
|
|
||||||
buffered := True;
|
|
||||||
buffer := gdk_pixmap_new(Drawable, Width, Height, -1);
|
|
||||||
{$ENDIF}
|
|
||||||
if buffered then begin
|
if buffered then begin
|
||||||
Left:=0;
|
Left:=0;
|
||||||
Top:=0;
|
Top:=0;
|
||||||
@ -3285,13 +3271,6 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if buffered then begin
|
|
||||||
BeginGDKErrorTrap;
|
|
||||||
gdk_draw_pixmap(drawable, gc, buffer, 0,0, Rect^.Left+DCOrigin.X,
|
|
||||||
Rect^.Top+DCOrigin.Y, Width, Height);
|
|
||||||
gdk_pixmap_unref(buffer);
|
|
||||||
EndGDKErrorTrap;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
Assert(False, Format('trace:< [TGtkWidgetSet.ExtTextOut] DC:0x%x, X:%d, Y:%d, Options:%d, Str:''%s'', Count: %d', [DC, X, Y, Options, Str, Count]));
|
Assert(False, Format('trace:< [TGtkWidgetSet.ExtTextOut] DC:0x%x, X:%d, Y:%d, Options:%d, Str:''%s'', Count: %d', [DC, X, Y, Options, Str, Count]));
|
||||||
@ -8715,6 +8694,9 @@ end;
|
|||||||
{ =============================================================================
|
{ =============================================================================
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.346 2004/04/12 22:36:29 mattias
|
||||||
|
made TIcon more independent of TBitmap from Colin
|
||||||
|
|
||||||
Revision 1.345 2004/04/03 16:47:46 mattias
|
Revision 1.345 2004/04/03 16:47:46 mattias
|
||||||
implemented converting gdkbitmap to RawImage mask
|
implemented converting gdkbitmap to RawImage mask
|
||||||
|
|
||||||
|
@ -128,6 +128,7 @@ type
|
|||||||
FAlphaReadRawImageBits: TOnReadRawImageBits;
|
FAlphaReadRawImageBits: TOnReadRawImageBits;
|
||||||
FAlphaWriteRawImageBits: TOnWriteRawImageBits;
|
FAlphaWriteRawImageBits: TOnWriteRawImageBits;
|
||||||
procedure SetAutoCreateMask(const AValue: boolean);
|
procedure SetAutoCreateMask(const AValue: boolean);
|
||||||
|
procedure SetUsePalette (Value:boolean);override;
|
||||||
protected
|
protected
|
||||||
OnGetInternalColor: TOnGetLazIntfImagePixel;
|
OnGetInternalColor: TOnGetLazIntfImagePixel;
|
||||||
OnSetInternalColor: TOnSetLazIntfImagePixel;
|
OnSetInternalColor: TOnSetLazIntfImagePixel;
|
||||||
@ -334,6 +335,7 @@ type
|
|||||||
ReadPalette: Boolean); virtual;
|
ReadPalette: Boolean); virtual;
|
||||||
procedure ReadScanLine(Row: Integer; Stream: TStream); virtual;
|
procedure ReadScanLine(Row: Integer; Stream: TStream); virtual;
|
||||||
procedure WriteScanLine(Row: Integer; Img: TFPCustomImage); virtual;
|
procedure WriteScanLine(Row: Integer; Img: TFPCustomImage); virtual;
|
||||||
|
function BmpRGBAToFPColor(Const RGBA: TColorRGBA): TFPcolor; virtual;
|
||||||
// required by TFPCustomImageReader
|
// required by TFPCustomImageReader
|
||||||
procedure InternalRead(Stream: TStream; Img: TFPCustomImage); override;
|
procedure InternalRead(Stream: TStream; Img: TFPCustomImage); override;
|
||||||
procedure InternalReadBody(Stream: TStream; Img: TFPCustomImage);
|
procedure InternalReadBody(Stream: TStream; Img: TFPCustomImage);
|
||||||
@ -343,16 +345,30 @@ type
|
|||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TLazReaderIcon }
|
{ TLazReaderPartIcon }
|
||||||
{ This is a FPImage writer for icon images. }
|
{ This is a FPImage writer for a single icon from an icon file }
|
||||||
TLazReaderIcon = class (TLazReaderBMP)
|
TLazReaderPartIcon = class (TLazReaderBMP)
|
||||||
private
|
|
||||||
FnIcons: Integer;
|
|
||||||
FnStartPos: TStreamSeekType;
|
|
||||||
protected
|
protected
|
||||||
// required by TFPCustomImageReader
|
// required by TFPCustomImageReader
|
||||||
procedure InternalRead(Stream: TStream; Img: TFPCustomImage); override;
|
procedure InternalRead(Stream: TStream; Img: TFPCustomImage); override;
|
||||||
function InternalCheck(Stream: TStream) : boolean; override;
|
function InternalCheck(Stream: TStream) : boolean; override;
|
||||||
|
function BmpRGBAToFPColor(Const RGBA: TColorRGBA): TFPcolor; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TLazReaderIcon }
|
||||||
|
{ This is a FPImage writer for icon images. }
|
||||||
|
TLazReaderIcon = class (TLazReaderPartIcon)
|
||||||
|
private
|
||||||
|
FIcon: TObject; { Actually TIcon, but this would give rise to a circular reference }
|
||||||
|
FnIcons: Integer;
|
||||||
|
FnStartPos: TStreamSeekType;
|
||||||
|
procedure SetIcon(const AValue: TObject);
|
||||||
|
protected
|
||||||
|
// required by TFPCustomImageReader
|
||||||
|
procedure InternalRead(Stream: TStream; Img: TFPCustomImage); override;
|
||||||
|
function InternalCheck(Stream: TStream) : boolean; override;
|
||||||
|
public
|
||||||
|
property Icon: TObject read FIcon write SetIcon;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ReadCompleteStreamToString(Str: TStream; StartSize: integer): string;
|
function ReadCompleteStreamToString(Str: TStream; StartSize: integer): string;
|
||||||
@ -361,6 +377,8 @@ procedure ReadCompleteStreamToStream(SrcStream, DestStream: TStream;
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
uses Graphics;
|
||||||
|
|
||||||
var
|
var
|
||||||
IsSpaceChar, IsNumberChar, IsHexNumberChar: array[char] of Boolean;
|
IsSpaceChar, IsNumberChar, IsHexNumberChar: array[char] of Boolean;
|
||||||
|
|
||||||
@ -1374,6 +1392,11 @@ begin
|
|||||||
FreeMaskData;
|
FreeMaskData;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TLazIntfImage.SetUsePalette(Value: boolean);
|
||||||
|
begin
|
||||||
|
inherited SetUsePalette(False); // Can't handle palettes at the moment
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TLazIntfImage.SetInternalColor(x, y: integer; const Value: TFPColor);
|
procedure TLazIntfImage.SetInternalColor(x, y: integer; const Value: TFPColor);
|
||||||
begin
|
begin
|
||||||
{if (x=0) and (y=0) then begin
|
{if (x=0) and (y=0) then begin
|
||||||
@ -2870,34 +2893,19 @@ end;
|
|||||||
|
|
||||||
{ TLazReaderBMP }
|
{ TLazReaderBMP }
|
||||||
|
|
||||||
type
|
function TLazReaderBMP.BmpRGBAToFPColor(Const RGBA: TColorRGBA): TFPcolor;
|
||||||
TColorBmpRGB=packed record
|
|
||||||
B,G,R: Byte;
|
|
||||||
end;
|
|
||||||
PColorBmpRGB = ^TColorBmpRGB;
|
|
||||||
|
|
||||||
TColorBmpRGBA=packed record
|
|
||||||
case Boolean of
|
|
||||||
False:(B,G,R,A: Byte);
|
|
||||||
True:(RGB: TColorBmpRGB);
|
|
||||||
end;
|
|
||||||
PColorBmpRGBA = ^TColorBmpRGBA;
|
|
||||||
|
|
||||||
function BmpRGBAToFPColor(Const RGBA: TColorBmpRGBA): TFPcolor;
|
|
||||||
var
|
|
||||||
NewAlpha: Byte;
|
|
||||||
begin
|
begin
|
||||||
with Result, RGBA do
|
with Result, RGBA do
|
||||||
begin
|
begin
|
||||||
Red :=(R shl 8) or R;
|
Red :=(R shl 8) or R;
|
||||||
Green :=(G shl 8) or G;
|
Green :=(G shl 8) or G;
|
||||||
Blue :=(B shl 8) or B;
|
Blue :=(B shl 8) or B;
|
||||||
NewAlpha:=255-A;
|
// Specification for bitmap files has these bits always zero - unused
|
||||||
alpha :=(NewAlpha shl 8) or NewAlpha;
|
alpha := alphaOpaque;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Function BmpRGBToFPColor(Const RGB: TColorBmpRGB) : TFPColor;
|
Function BmpRGBToFPColor(Const RGB: TColorRGB) : TFPColor;
|
||||||
begin
|
begin
|
||||||
with Result,RGB do
|
with Result,RGB do
|
||||||
begin
|
begin
|
||||||
@ -2941,48 +2949,55 @@ procedure TLazReaderBMP.SetupRead(nPalette, nRowBits: Integer; Stream: TStream;
|
|||||||
ReadPalette: Boolean);
|
ReadPalette: Boolean);
|
||||||
{$ifdef VER1_0}
|
{$ifdef VER1_0}
|
||||||
type
|
type
|
||||||
tcolinfo = ARRAY [0..0] OF TColorBmpRGBA;
|
tcolinfo = ARRAY [0..0] OF TColorRGBA;
|
||||||
pcolinfo = ^tcolinfo;
|
pcolinfo = ^tcolinfo;
|
||||||
var
|
var
|
||||||
ColInfo: pcolinfo;
|
ColInfo: pcolinfo;
|
||||||
{$else}
|
{$else}
|
||||||
var
|
var
|
||||||
ColInfo: ARRAY OF TColorBmpRGBA;
|
ColInfo: ARRAY OF TColorRGBA;
|
||||||
{$endif}
|
{$endif}
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
FPcolor: TFPcolor;
|
||||||
begin
|
begin
|
||||||
if nPalette>0 then
|
if nPalette>0 then
|
||||||
begin
|
begin
|
||||||
GetMem(FPalette, nPalette*SizeOf(TFPColor));
|
GetMem(FPalette, nPalette*SizeOf(TFPColor));
|
||||||
{$ifdef VER1_0}
|
{$ifdef VER1_0}
|
||||||
GetMem(ColInfo, nPalette*Sizeof(TColorBmpRGBA));
|
GetMem(ColInfo, nPalette*Sizeof(TColorRGBA));
|
||||||
if ReadPalette then begin
|
if ReadPalette then begin
|
||||||
if BFI.biClrUsed>0 then
|
if BFI.biClrUsed>0 then
|
||||||
Stream.Read(ColInfo^[0],BFI.biClrUsed*SizeOf(TColorBmpRGBA))
|
Stream.Read(ColInfo^[0],BFI.biClrUsed*SizeOf(TColorRGBA))
|
||||||
else // Seems to me that this is dangerous.
|
else // Seems to me that this is dangerous.
|
||||||
Stream.Read(ColInfo^[0],nPalette*SizeOf(TColorBmpRGBA));
|
Stream.Read(ColInfo^[0],nPalette*SizeOf(TColorRGBA));
|
||||||
for i := 0 to nPalette-1 do
|
for i := 0 to nPalette-1 do begin
|
||||||
FPalette[i] := BmpRGBAToFPColor(ColInfo^[i]);
|
FPcolor := BmpRGBAToFPColor(ColInfo^[i]);
|
||||||
|
FPcolor.alpha := alphaOpaque; { No transparency info in palette }
|
||||||
|
FPalette[i] := FPcolor;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
{$else}
|
{$else}
|
||||||
SetLength(ColInfo, nPalette);
|
SetLength(ColInfo, nPalette);
|
||||||
if ReadPalette then begin
|
if ReadPalette then begin
|
||||||
if BFI.biClrUsed>0 then
|
if BFI.biClrUsed>0 then
|
||||||
Stream.Read(ColInfo[0],BFI.biClrUsed*SizeOf(TColorBmpRGBA))
|
Stream.Read(ColInfo[0],BFI.biClrUsed*SizeOf(TColorRGBA))
|
||||||
else // Seems to me that this is dangerous.
|
else // Seems to me that this is dangerous.
|
||||||
Stream.Read(ColInfo[0],nPalette*SizeOf(TColorBmpRGBA));
|
Stream.Read(ColInfo[0],nPalette*SizeOf(TColorRGBA));
|
||||||
for i := 0 to High(ColInfo) do
|
for i := 0 to nPalette-1 do begin
|
||||||
FPalette[i] := BmpRGBAToFPColor(ColInfo[i]);
|
FPcolor := BmpRGBAToFPColor(ColInfo[i]);
|
||||||
|
FPcolor.alpha := alphaOpaque; { No transparency info in palette }
|
||||||
|
FPalette[i] := FPcolor;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
{$endif}
|
{$endif}
|
||||||
end
|
end
|
||||||
else if BFI.biClrUsed>0 then { Skip palette }
|
else if BFI.biClrUsed>0 then { Skip palette }
|
||||||
Stream.Position := Stream.Position
|
Stream.Position := Stream.Position
|
||||||
+ TStreamSeekType(BFI.biClrUsed*SizeOf(TColorBmpRGBA));
|
+ TStreamSeekType(BFI.biClrUsed*SizeOf(TColorRGBA));
|
||||||
ReadSize:=((nRowBits + 31) div 32) shl 2;
|
ReadSize:=((nRowBits + 31) div 32) shl 2;
|
||||||
GetMem(LineBuf,ReadSize);
|
GetMem(LineBuf,ReadSize);
|
||||||
{$ifdef VER1_0}
|
{$ifdef VER1_0}
|
||||||
FreeMem(ColInfo, nPalette*Sizeof(TColorBmpRGBA));
|
FreeMem(ColInfo, nPalette*Sizeof(TColorRGBA));
|
||||||
{$endif}
|
{$endif}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3016,10 +3031,10 @@ begin
|
|||||||
img.colors[Column,Row]:=Bmp16BitToFPColor(PWord(LineBuf)[Column]);
|
img.colors[Column,Row]:=Bmp16BitToFPColor(PWord(LineBuf)[Column]);
|
||||||
24 :
|
24 :
|
||||||
for Column:=0 to img.Width-1 do
|
for Column:=0 to img.Width-1 do
|
||||||
img.colors[Column,Row]:=BmpRGBToFPColor(PColorBmpRGB(LineBuf)[Column]);
|
img.colors[Column,Row]:=BmpRGBToFPColor(PColorRGB(LineBuf)[Column]);
|
||||||
32 :
|
32 :
|
||||||
for Column:=0 to img.Width-1 do
|
for Column:=0 to img.Width-1 do
|
||||||
img.colors[Column,Row]:=BmpRGBAToFPColor(PColorBmpRGBA(LineBuf)[Column]);
|
img.colors[Column,Row]:=BmpRGBAToFPColor(PColorRGBA(LineBuf)[Column]);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3034,7 +3049,7 @@ Var
|
|||||||
Row : Integer;
|
Row : Integer;
|
||||||
begin
|
begin
|
||||||
{ This will move past any junk after the BFI header }
|
{ This will move past any junk after the BFI header }
|
||||||
Stream.Position:=Stream.Position-TStreamSeekType(SizeOf(BFI)-BFI.biSize);
|
Stream.Position:=Stream.Position+TStreamSeekType(BFI.biSize-SizeOf(BFI));
|
||||||
with BFI do
|
with BFI do
|
||||||
begin
|
begin
|
||||||
if (biCompression<>0) then
|
if (biCompression<>0) then
|
||||||
@ -3138,6 +3153,43 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TLazReaderPartIcon }
|
||||||
|
|
||||||
|
procedure TLazReaderPartIcon.InternalRead(Stream: TStream; Img: TFPCustomImage);
|
||||||
|
var
|
||||||
|
Row, Column: Integer;
|
||||||
|
begin
|
||||||
|
Stream.Read(BFI,SizeOf(BFI));
|
||||||
|
BFI.biHeight := BFI.biHeight div 2; { Height field is doubled, to (sort of) accomodate mask }
|
||||||
|
InternalReadBody(Stream, Img); { Now read standard bitmap }
|
||||||
|
{ Mask immediately follows unless bitmap was 32 bit - monchrome bitmap with no header }
|
||||||
|
if BFI.biBitCount < 32 then begin
|
||||||
|
ReadSize:=((Img.Width + 31) div 32) shl 2;
|
||||||
|
SetupRead(2,Img.Width,Stream,False);
|
||||||
|
try
|
||||||
|
for Row:=Img.Height-1 downto 0 do begin
|
||||||
|
ReadScanLine(Row,Stream); // Scanline in LineBuf with Size ReadSize.
|
||||||
|
for Column:=0 to Img.Width-1 do
|
||||||
|
if ((LineBuf[Column div 8] shr (7-(Column and 7)) ) and 1) <> 0 then
|
||||||
|
img.colors[Column,Row]:=colTransparent
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FreeBufs;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLazReaderPartIcon.InternalCheck(Stream: TStream): boolean;
|
||||||
|
begin
|
||||||
|
Result:=True; { Assumes stream in the correct place }
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLazReaderPartIcon.BmpRGBAToFPColor(const RGBA: TColorRGBA): TFPcolor;
|
||||||
|
begin
|
||||||
|
Result:=inherited BmpRGBAToFPColor(RGBA);
|
||||||
|
Result.alpha := (RGBA.A shl 8) or RGBA.A; { For icon files (only) upper byte is used for transparency }
|
||||||
|
end;
|
||||||
|
|
||||||
{ TLazReaderIcon }
|
{ TLazReaderIcon }
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -3159,44 +3211,62 @@ type
|
|||||||
dwImageOffset: Longint; {pos of image as offset from the beginning of file}
|
dwImageOffset: Longint; {pos of image as offset from the beginning of file}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
PIconDirEntry = ^TIconDirEntry;
|
||||||
|
|
||||||
|
procedure TLazReaderIcon.SetIcon(const AValue: TObject);
|
||||||
|
begin
|
||||||
|
if AValue is TIcon then
|
||||||
|
FIcon:=AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TLazReaderIcon.InternalRead(Stream: TStream; Img: TFPCustomImage);
|
procedure TLazReaderIcon.InternalRead(Stream: TStream; Img: TFPCustomImage);
|
||||||
var
|
var
|
||||||
CurrentDirEntry, BestDirEntry: TIconDirEntry;
|
CurrentDirEntry, BestDirEntry, IconDir: PIconDirEntry;
|
||||||
Row, Column, i: Integer;
|
i: Integer;
|
||||||
|
Bitmap: TBitmap;
|
||||||
begin
|
begin
|
||||||
{ For the time being, read the largest and/or most colourful icon }
|
GetMem(IconDir, FnIcons*Sizeof(TIconDirEntry));
|
||||||
Stream.Read(BestDirEntry, Sizeof(BestDirEntry));
|
|
||||||
CurrentDirEntry := BestDirEntry;
|
|
||||||
for i := 2 to FnIcons do begin
|
|
||||||
Stream.Read(CurrentDirEntry, Sizeof(CurrentDirEntry));
|
|
||||||
if ((CurrentDirEntry.bWidth > BestDirEntry.bWidth)
|
|
||||||
and (CurrentDirEntry.bHeight > BestDirEntry.bHeight))
|
|
||||||
or ((CurrentDirEntry.bWidth = BestDirEntry.bWidth)
|
|
||||||
and (CurrentDirEntry.bHeight = BestDirEntry.bHeight)
|
|
||||||
and (CurrentDirEntry.dwBytesInRes > BestDirEntry.dwBytesInRes)) then
|
|
||||||
BestDirEntry := CurrentDirEntry;
|
|
||||||
end;
|
|
||||||
Stream.Position := FnStartPos + BestDirEntry.dwImageOffset;
|
|
||||||
Stream.Read(BFI,SizeOf(BFI));
|
|
||||||
BFI.biHeight := BFI.biHeight div 2; { Height field is doubled, to (sort of) accomodate mask }
|
|
||||||
InternalReadBody(Stream, Img); { Now read standard bitmap }
|
|
||||||
{ Mask immediately follows unless bitmap was 32 bit - monchrome bitmap with no header }
|
|
||||||
if BFI.biBitCount < 32 then begin
|
|
||||||
ReadSize:=((Img.Width + 31) div 32) shl 2;
|
|
||||||
SetupRead(2,Img.Width,Stream,False);
|
|
||||||
try
|
try
|
||||||
for Row:=Img.Height-1 downto 0 do begin
|
Stream.Read(IconDir^, FnIcons*Sizeof(TIconDirEntry));
|
||||||
ReadScanLine(Row,Stream); // Scanline in LineBuf with Size ReadSize.
|
BestDirEntry := IconDir;
|
||||||
for Column:=0 to Img.Width-1 do
|
CurrentDirEntry := IconDir+1;
|
||||||
if ((LineBuf[Column div 8] shr (7-(Column and 7)) ) and 1) <> 0 then
|
{ First locate largest and/or most colourful icon as the default image }
|
||||||
img.colors[Column,Row]:=colTransparent
|
for i := 2 to FnIcons do begin
|
||||||
|
if ((CurrentDirEntry^.bWidth > BestDirEntry^.bWidth)
|
||||||
|
and (CurrentDirEntry^.bHeight > BestDirEntry^.bHeight))
|
||||||
|
or ((CurrentDirEntry^.bWidth = BestDirEntry^.bWidth)
|
||||||
|
and (CurrentDirEntry^.bHeight = BestDirEntry^.bHeight)
|
||||||
|
and (CurrentDirEntry^.dwBytesInRes > BestDirEntry^.dwBytesInRes)) then
|
||||||
|
BestDirEntry := CurrentDirEntry;
|
||||||
|
Inc(CurrentDirEntry);
|
||||||
|
end;
|
||||||
|
if Assigned(Icon) then begin
|
||||||
|
CurrentDirEntry := IconDir;
|
||||||
|
for i := 1 to FnIcons do begin
|
||||||
|
Stream.Position := FnStartPos + CurrentDirEntry^.dwImageOffset;
|
||||||
|
if CurrentDirEntry = BestDirEntry then
|
||||||
|
inherited InternalRead(Stream, Img)
|
||||||
|
else begin
|
||||||
|
Bitmap := TBitmap.Create;
|
||||||
|
try
|
||||||
|
Bitmap.ReadStreamWithFPImage(Stream, False, 0, TLazReaderPartIcon);
|
||||||
|
except
|
||||||
|
Bitmap.Free;
|
||||||
|
raise;
|
||||||
|
end;
|
||||||
|
TIcon(Icon).AddBitmap(Bitmap);
|
||||||
|
end;
|
||||||
|
Inc(CurrentDirEntry);
|
||||||
|
end;
|
||||||
|
end else begin
|
||||||
|
Stream.Position := FnStartPos + BestDirEntry^.dwImageOffset;
|
||||||
|
inherited InternalRead(Stream, Img);
|
||||||
|
{ Finally skip remaining icons }
|
||||||
|
Stream.Position := FnStartPos + CurrentDirEntry^.dwImageOffset + CurrentDirEntry^.dwBytesInRes;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
FreeBufs;
|
FreeMem(IconDir);
|
||||||
end;
|
end;
|
||||||
end;
|
|
||||||
{ Finally skip remaining icons }
|
|
||||||
Stream.Position := FnStartPos + BestDirEntry.dwImageOffset + BestDirEntry.dwBytesInRes;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TLazReaderIcon.InternalCheck(Stream: TStream): boolean;
|
function TLazReaderIcon.InternalCheck(Stream: TStream): boolean;
|
||||||
|
Loading…
Reference in New Issue
Block a user