123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- unit GR32.ImageFormats.TPicture;
- (* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1 or LGPL 2.1 with linking exception
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * Alternatively, the contents of this file may be used under the terms of the
- * Free Pascal modified version of the GNU Lesser General Public License
- * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
- * of this license are applicable instead of those above.
- * Please see the file LICENSE.txt for additional information concerning this
- * license.
- *
- * The Original Code is image format support for Graphics32
- *
- * The Initial Developer of the Original Code is
- * Anders Melander <[email protected]>
- *
- * Portions created by the Initial Developer are Copyright (C) 2008-2022
- * the Initial Developer. All Rights Reserved.
- *
- * ***** END LICENSE BLOCK ***** *)
- interface
- {$include GR32.inc}
- implementation
- uses
- Classes,
- {$ifdef FPC}
- LCLType, // LCLType must be after Classes so we get the correct THandle
- {$endif FPC}
- Graphics,
- Clipbrd,
- GR32,
- GR32.ImageFormats;
- //------------------------------------------------------------------------------
- //
- // TImageFormatAdapterTPicture
- //
- //------------------------------------------------------------------------------
- // Implements IImageFormatAdapter for the TPicture class.
- //------------------------------------------------------------------------------
- type
- TImageFormatAdapterTPicture = class(TCustomImageFormatAdapter,
- IImageFormatAdapter)
- strict protected
- // IImageFormatAdapter
- function CanAssignFrom(Source: TPersistent): boolean; override;
- function AssignFrom(Dest: TCustomBitmap32; Source: TPersistent): boolean; override;
- function CanAssignTo(Dest: TPersistent): boolean; override;
- function AssignTo(Source: TCustomBitmap32; Dest: TPersistent): boolean; override;
- end;
- //------------------------------------------------------------------------------
- // IImageFormatAdapter
- //------------------------------------------------------------------------------
- function TImageFormatAdapterTPicture.CanAssignFrom(Source: TPersistent): boolean;
- begin
- Result := (Source is TPicture) and (TPicture(Source).Graphic <> nil) and
- ImageFormatManager.Adapters.CanAssignFrom(TPicture(Source).Graphic);
- end;
- function TImageFormatAdapterTPicture.AssignFrom(Dest: TCustomBitmap32; Source: TPersistent): boolean;
- begin
- Result := (Source is TPicture) and (TPicture(Source).Graphic <> nil) and
- // Recurse and try to assign from the TGraphic
- ImageFormatManager.Adapters.AssignFrom(Dest, TPicture(Source).Graphic);
- end;
- //------------------------------------------------------------------------------
- function TImageFormatAdapterTPicture.CanAssignTo(Dest: TPersistent): boolean;
- begin
- if (Dest is TPicture) then
- begin
- // Try to assign to TPicture.Graphic, fallback to TBitmap
- Result := ((TPicture(Dest).Graphic <> nil) and ImageFormatManager.Adapters.CanAssignTo(TPicture(Dest).Graphic)) or
- ImageFormatManager.Adapters.CanAssignTo(TPicture(Dest).Bitmap); // Note: This potentially modifies the TPicture
- end else
- Result := False;
- end;
- function TImageFormatAdapterTPicture.AssignTo(Source: TCustomBitmap32; Dest: TPersistent): boolean;
- begin
- if (Dest is TPicture) then
- begin
- // Try to assign to TPicture.Graphic, fallback to TBitmap
- Result := (TPicture(Dest).Graphic <> nil) and
- // Recurse and try to assign to the TGraphic
- ImageFormatManager.Adapters.AssignTo(Source, TPicture(Dest).Graphic);
- if (not Result) then
- // Recurse and try to assign to TBitmap
- Result := ImageFormatManager.Adapters.AssignTo(Source, TPicture(Dest).Bitmap);
- end else
- Result := False;
- end;
- //------------------------------------------------------------------------------
- //
- // TImageFormatReaderTPicture
- //
- //------------------------------------------------------------------------------
- // Implements IImageFormatReader for the TPicture class.
- // Basically this reader will support all TGraphic implementations that can
- // read from a stream.
- // Additionally IImageFormatFileReader is implemented to allow TPicture to
- // determine the image format based on the file type.
- //------------------------------------------------------------------------------
- type
- TImageFormatReaderTPicture = class(TCustomImageFormat,
- IImageFormatReader,
- IImageFormatFileReader,
- IImageFormatClipboardFormat)
- strict private
- // IImageFormatReader
- function CanLoadFromStream(AStream: TStream): boolean;
- function LoadFromStream(ADest: TCustomBitmap32; AStream: TStream): boolean;
- strict private
- // IImageFormatFileReader
- function LoadFromFile(ADest: TCustomBitmap32; const AFilename: string): boolean;
- strict private
- // IImageFormatClipboardFormat
- function SupportsClipboardFormat(AFormat: TClipboardFormat): Boolean;
- function PasteFromClipboard(ADest: TCustomBitmap32): boolean;
- function LoadFromClipboardFormat(ADest: TCustomBitmap32; AFormat: TClipboardFormat; AData: THandle; APalette: THandle): boolean;
- end;
- //------------------------------------------------------------------------------
- // IImageFormatReader
- //------------------------------------------------------------------------------
- function TImageFormatReaderTPicture.CanLoadFromStream(AStream: TStream): boolean;
- begin
- // TPicture does not have a CanLoadFromStream so this is a last-ditch effort.
- Result := True;
- end;
- function TImageFormatReaderTPicture.LoadFromStream(ADest: TCustomBitmap32; AStream: TStream): boolean;
- {$ifdef LOADFROMSTREAM}
- var
- Picture: TPicture;
- {$endif LOADFROMSTREAM}
- begin
- {$ifdef LOADFROMSTREAM}
- // TPicture.LoadFromStream requires TGraphic.CanLoadFromStream.
- // Introduced in Delphi 10.2 and present in FPC as well
- // See issue #145
- Picture := TPicture.Create;
- try
- try
- Picture.LoadFromStream(AStream);
- except
- on E: EInvalidGraphic do
- Exit(False);
- end;
- ADest.Assign(Picture.Graphic);
- finally
- Picture.Free;
- end;
- Result := True;
- {$else LOADFROMSTREAM}
- Result := False;
- {$endif LOADFROMSTREAM}
- end;
- //------------------------------------------------------------------------------
- // IImageFormatFileReader
- //------------------------------------------------------------------------------
- function TImageFormatReaderTPicture.LoadFromFile(ADest: TCustomBitmap32; const AFilename: string): boolean;
- var
- Picture: TPicture;
- begin
- Picture := TPicture.Create;
- try
- try
- Picture.LoadFromFile(AFilename);
- except
- on E: EInvalidGraphic do
- Exit(False);
- end;
- ADest.Assign(Picture.Graphic);
- finally
- Picture.Free;
- end;
- Result := True;
- end;
- //------------------------------------------------------------------------------
- // IImageFormatClipboard
- //------------------------------------------------------------------------------
- function TImageFormatReaderTPicture.SupportsClipboardFormat(AFormat: TClipboardFormat): Boolean;
- begin
- Result := TPicture.SupportsClipboardFormat(AFormat);
- end;
- function TImageFormatReaderTPicture.PasteFromClipboard(ADest: TCustomBitmap32): boolean;
- var
- Picture: TPicture;
- begin
- Picture := TPicture.Create;
- try
- Picture.Assign(Clipboard);
- ADest.Assign(Picture.Graphic);
- finally
- Picture.Free;
- end;
- Result := True;
- end;
- function TImageFormatReaderTPicture.LoadFromClipboardFormat(ADest: TCustomBitmap32; AFormat: TClipboardFormat; AData: THandle; APalette: THandle): boolean;
- var
- Picture: TPicture;
- begin
- Picture := TPicture.Create;
- try
- {$ifdef FPC}
- Picture.LoadFromClipboardFormat(AFormat);
- {$else FPC}
- Picture.LoadFromClipboardFormat(AFormat, AData, APalette);
- {$endif FPC}
- ADest.Assign(Picture.Graphic);
- finally
- Picture.Free;
- end;
- Result := True;
- end;
- //------------------------------------------------------------------------------
- //------------------------------------------------------------------------------
- //------------------------------------------------------------------------------
- var
- ImageFormatAdapterHandle: integer = 0;
- ImageFormatReaderHandle: integer = 0;
- initialization
- ImageFormatAdapterHandle := ImageFormatManager.RegisterImageFormat(TImageFormatAdapterTPicture.Create, ImageFormatPriorityNormal);
- {$ifdef LOADFROMSTREAM}
- ImageFormatReaderHandle := ImageFormatManager.RegisterImageFormat(TImageFormatReaderTPicture.Create, ImageFormatPriorityWorst);
- {$endif LOADFROMSTREAM}
- finalization
- ImageFormatManager.UnregisterImageFormat(ImageFormatAdapterHandle);
- ImageFormatManager.UnregisterImageFormat(ImageFormatReaderHandle);
- end.
|