GR32.ImageFormats.SVG.pas 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. unit GR32.ImageFormats.SVG;
  2. (* ***** BEGIN LICENSE BLOCK *****
  3. * Version: MPL 1.1 or LGPL 2.1 with linking exception
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. * http://www.mozilla.org/MPL/
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. *
  15. * Alternatively, the contents of this file may be used under the terms of the
  16. * Free Pascal modified version of the GNU Lesser General Public License
  17. * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
  18. * of this license are applicable instead of those above.
  19. * Please see the file LICENSE.txt for additional information concerning this
  20. * license.
  21. *
  22. * The Original Code is SVG Image Format support for Graphics32
  23. *
  24. * The Initial Developer of the Original Code is
  25. * Anders Melander <[email protected]>
  26. *
  27. * Portions created by the Initial Developer are Copyright (C) 2008-2022
  28. * the Initial Developer. All Rights Reserved.
  29. *
  30. * Contributor(s):
  31. *
  32. * ***** END LICENSE BLOCK ***** *)
  33. interface
  34. {$include GR32.inc}
  35. implementation
  36. uses
  37. Classes,
  38. Graphics,
  39. // Image32 must be in your library search path
  40. Img32,
  41. Img32.Fmt.SVG,
  42. GR32,
  43. GR32.ImageFormats;
  44. resourcestring
  45. sImageFormatSVGName = 'SVG images';
  46. //------------------------------------------------------------------------------
  47. //
  48. // TImage32Backend
  49. //
  50. //------------------------------------------------------------------------------
  51. // Minimal TBitmap32 backend using a TImage32 as storage.
  52. //------------------------------------------------------------------------------
  53. type
  54. TImage32Backend = class(TCustomBackend)
  55. private
  56. FImage32: TImage32;
  57. private
  58. procedure Image32Changed(Sender: TObject);
  59. public
  60. constructor Create(AOwner: TCustomBitmap32; AImage32: TImage32);
  61. destructor Destroy; override;
  62. function Empty: Boolean; override;
  63. property Image32: TImage32 read FImage32;
  64. end;
  65. constructor TImage32Backend.Create(AOwner: TCustomBitmap32; AImage32: TImage32);
  66. begin
  67. inherited Create(AOwner);
  68. FImage32 := AImage32;
  69. FImage32.OnChange := Image32Changed;
  70. end;
  71. destructor TImage32Backend.Destroy;
  72. begin
  73. FImage32.OnChange := nil;
  74. inherited;
  75. end;
  76. procedure TImage32Backend.Image32Changed(Sender: TObject);
  77. begin
  78. BeginUpdate;
  79. try
  80. FBits := pointer(FImage32.PixelBase);
  81. // TImage32 doesn't fire OnResized when being resized from within SVG.LoadFromStream
  82. // so we have to handle the resize manually.
  83. FOwner.SetSize(FImage32.Width, FImage32.Height);
  84. Changed;
  85. finally
  86. EndUpdate;
  87. end;
  88. end;
  89. function TImage32Backend.Empty: Boolean;
  90. begin
  91. Result := FImage32.IsEmpty;
  92. end;
  93. //------------------------------------------------------------------------------
  94. //
  95. // TImageFormatAdapterSVG
  96. //
  97. //------------------------------------------------------------------------------
  98. // Implements IImageFormatReader for the SVG image format using the Image32
  99. // library's SVG reading and rendering capabilities.
  100. //------------------------------------------------------------------------------
  101. type
  102. TImageFormatAdapterSVG = class(TCustomImageFormat,
  103. IImageFormatFileInfo,
  104. IImageFormatReader)
  105. private
  106. // IImageFormatFileInfo
  107. function ImageFormatDescription: string;
  108. function ImageFormatFileTypes: TFileTypes;
  109. private
  110. // IImageFormatReader
  111. function CanLoadFromStream(AStream: TStream): boolean;
  112. function LoadFromStream(ADest: TCustomBitmap32; AStream: TStream): boolean;
  113. end;
  114. //------------------------------------------------------------------------------
  115. // IImageFormatFileInfo
  116. //------------------------------------------------------------------------------
  117. function TImageFormatAdapterSVG.ImageFormatFileTypes: TFileTypes;
  118. begin
  119. Result := ['svg'];
  120. end;
  121. function TImageFormatAdapterSVG.ImageFormatDescription: string;
  122. begin
  123. Result := sImageFormatSVGName;
  124. end;
  125. //------------------------------------------------------------------------------
  126. // IImageFormatReader
  127. //------------------------------------------------------------------------------
  128. function TImageFormatAdapterSVG.CanLoadFromStream(AStream: TStream): boolean;
  129. begin
  130. Result := TImageFormat_SVG.IsValidImageStream(AStream);
  131. end;
  132. function TImageFormatAdapterSVG.LoadFromStream(ADest: TCustomBitmap32; AStream: TStream): boolean;
  133. var
  134. SVG: TImageFormat_SVG;
  135. Bitmap: TBitmap32;
  136. Image32: TImage32;
  137. begin
  138. if (not TImageFormat_SVG.IsValidImageStream(AStream)) then
  139. Exit(False);
  140. Image32 := TImage32.Create;
  141. try
  142. Bitmap := TBitmap32.Create;
  143. try
  144. TImage32Backend.Create(Bitmap, Image32); // Bitmap now owns the backend
  145. SVG := TImageFormat_SVG.Create;
  146. try
  147. SVG.LoadFromStream(AStream, Image32);
  148. finally
  149. SVG.Free;
  150. end;
  151. ADest.Assign(Bitmap);
  152. finally
  153. Bitmap.Free;
  154. end;
  155. finally
  156. Image32.Free;
  157. end;
  158. Result := True;
  159. end;
  160. //------------------------------------------------------------------------------
  161. //------------------------------------------------------------------------------
  162. //------------------------------------------------------------------------------
  163. var
  164. ImageFormatHandle: integer = 0;
  165. initialization
  166. ImageFormatHandle := ImageFormatManager.RegisterImageFormat(TImageFormatAdapterSVG.Create, ImageFormatPriorityBetter);
  167. finalization
  168. ImageFormatManager.UnregisterImageFormat(ImageFormatHandle);
  169. end.