2
0

GR32_Backends.pas 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. unit GR32_Backends;
  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 Backend Extension for Graphics32
  23. *
  24. * The Initial Developer of the Original Code is
  25. * Andre Beckedorf - metaException
  26. * [email protected]
  27. *
  28. * Portions created by the Initial Developer are Copyright (C) 2007-2009
  29. * the Initial Developer. All Rights Reserved.
  30. *
  31. * Contributor(s):
  32. *
  33. * ***** END LICENSE BLOCK ***** *)
  34. interface
  35. {$include GR32.inc}
  36. uses
  37. {$if defined(FRAMEWORK_VCL)}
  38. WinApi.Windows,
  39. WinApi.Messages,
  40. Vcl.Controls,
  41. Vcl.Graphics,
  42. {$elseif defined(FRAMEWORK_FMX)}
  43. WinApi.Windows,
  44. WinApi.Messages,
  45. FMX.Controls,
  46. FMX.Graphics,
  47. {$elseif defined(FRAMEWORK_LCL)}
  48. LCLIntf, LCLType,
  49. Types,
  50. Controls,
  51. Graphics,
  52. {$ifend}
  53. Classes,
  54. SysUtils,
  55. GR32,
  56. GR32.Text.Types,
  57. GR32_Containers,
  58. GR32_Paths;
  59. type
  60. EBackend = class(Exception);
  61. ITextSupport = interface(IUnknown)
  62. ['{225997CC-958A-423E-8B60-9EDE0D3B53B5}']
  63. procedure Textout(X, Y: Integer; const Text: String); overload;
  64. procedure Textout(X, Y: Integer; const ClipRect: TRect; const Text: String); overload;
  65. procedure Textout(var DstRect: TRect; const Flags: Cardinal; const Text: String); overload;
  66. function TextExtent(const Text: String): TSize;
  67. end;
  68. IFontSupport = interface(IUnknown)
  69. ['{67C73044-1EFF-4FDE-AEA2-56BFADA50A48}']
  70. function GetOnFontChange: TNotifyEvent;
  71. procedure SetOnFontChange(Handler: TNotifyEvent);
  72. function GetFont: TFont;
  73. procedure SetFont(const Font: TFont);
  74. procedure UpdateFont;
  75. property Font: TFont read GetFont write SetFont;
  76. property OnFontChange: TNotifyEvent read GetOnFontChange write SetOnFontChange;
  77. end;
  78. ITextToPathSupport = interface(IUnknown)
  79. ['{6C4037E4-FF4D-4EE2-9C20-B9DB9C64B42D}']
  80. procedure TextToPath(Path: TCustomPath; const X, Y: TFloat; const Text: string); overload;
  81. procedure TextToPath(Path: TCustomPath; const DstRect: TFloatRect; const Text: string; Flags: Cardinal = 0); overload;
  82. function MeasureText(const DstRect: TFloatRect; const Text: string; Flags: Cardinal = 0): TFloatRect;
  83. end;
  84. ICanvasSupport = interface(IUnknown)
  85. ['{5ACFEEC7-0123-4AD8-8AE6-145718438E01}']
  86. function GetCanvasChange: TNotifyEvent;
  87. procedure SetCanvasChange(Handler: TNotifyEvent);
  88. function GetCanvas: TCanvas;
  89. procedure DeleteCanvas;
  90. function CanvasAllocated: Boolean;
  91. property Canvas: TCanvas read GetCanvas;
  92. property OnCanvasChange: TNotifyEvent read GetCanvasChange write SetCanvasChange;
  93. end;
  94. IInteroperabilitySupport = interface(IUnknown)
  95. ['{B86229E8-228F-4FDA-A47D-2E9BD9F78D1E}']
  96. function CopyFrom(Graphic: TGraphic): Boolean; overload;
  97. end;
  98. IDeviceContextSupport = interface(IUnknown)
  99. ['{DD1109DA-4019-4A5C-A450-3631A73CF288}']
  100. function GetHandle: HDC;
  101. procedure Draw(const DstRect, SrcRect: TRect; hSrc: HDC);
  102. procedure DrawTo(hDst: HDC; DstX, DstY: Integer); overload;
  103. procedure DrawTo(hDst: HDC; const DstRect, SrcRect: TRect); overload;
  104. property Handle: HDC read GetHandle;
  105. end;
  106. IBitmapContextSupport = interface(IUnknown)
  107. ['{DF0F9475-BA13-4C6B-81C3-D138624C4D08}']
  108. function GetBitmapInfo: TBitmapInfo;
  109. function GetBitmapHandle: THandle;
  110. property BitmapInfo: TBitmapInfo read GetBitmapInfo;
  111. property BitmapHandle: THandle read GetBitmapHandle;
  112. end;
  113. IPaintSupport = interface(IUnknown)
  114. ['{CE64DBEE-C4A9-4E8E-ABCA-1B1FD6F45924}']
  115. procedure ImageNeeded;
  116. procedure CheckPixmap;
  117. procedure DoPaint(ABuffer: TBitmap32; AInvalidRects: TRectList; ACanvas: TCanvas); overload;
  118. procedure DoPaint(ABuffer: TBitmap32; const AInvalidRect: TRect; ACanvas: TCanvas); overload;
  119. end;
  120. IUpdateRectSupport = interface(IUnknown)
  121. ['{BC19CD02-0ACB-4545-A65A-1317C8E9E7F5}']
  122. procedure InvalidateRect(AControl: TWinControl; const ARect: TRect);
  123. procedure GetUpdateRects(AControl: TWinControl; AUpdateRects: TRectList; AReservedCapacity: integer; var AFullUpdate: boolean);
  124. end;
  125. TRequireOperatorMode = (romAnd, romOr);
  126. type
  127. IFontHintingSupport = interface(IUnknown)
  128. ['{42D96689-8627-472E-A93B-A39971A1F603}']
  129. function GetHinting: TTextHinting;
  130. procedure SetHinting(Value: TTextHinting);
  131. property Hinting: TTextHinting read GetHinting write SetHinting;
  132. end;
  133. // Helper functions to temporarily switch the back-end depending on the required interfaces
  134. procedure RequireBackendSupport(TargetBitmap: TCustomBitmap32;
  135. RequiredInterfaces: array of TGUID;
  136. Mode: TRequireOperatorMode; UseOptimizedDestructiveSwitchMethod: Boolean;
  137. out ReleasedBackend: TCustomBackend);
  138. procedure RestoreBackend(TargetBitmap: TCustomBitmap32; const SavedBackend: TCustomBackend);
  139. resourcestring
  140. RCStrCannotAllocateDIBHandle = 'Can''t allocate the DIB handle';
  141. RCStrCannotCreateCompatibleDC = 'Can''t create compatible DC';
  142. RCStrCannotSelectAnObjectIntoDC = 'Can''t select an object into DC';
  143. implementation
  144. procedure RequireBackendSupport(TargetBitmap: TCustomBitmap32;
  145. RequiredInterfaces: array of TGUID;
  146. Mode: TRequireOperatorMode; UseOptimizedDestructiveSwitchMethod: Boolean;
  147. out ReleasedBackend: TCustomBackend);
  148. var
  149. I: Integer;
  150. Supported: Boolean;
  151. begin
  152. Supported := False;
  153. for I := Low(RequiredInterfaces) to High(RequiredInterfaces) do
  154. begin
  155. Supported := Supports(TargetBitmap.Backend, RequiredInterfaces[I]);
  156. if ((Mode = romAnd) and not Supported) or
  157. ((Mode = romOr) and Supported) then
  158. Break;
  159. end;
  160. if not Supported then
  161. begin
  162. if UseOptimizedDestructiveSwitchMethod then
  163. TargetBitmap.SetSize(0, 0); // Reset size so we avoid the buffer copy during back-end switch
  164. ReleasedBackend := TargetBitmap.ReleaseBackend;
  165. // TODO: Try to find a back-end that supports the required interfaces
  166. // instead of resorting to the default platform back-end class...
  167. TargetBitmap.Backend := TargetBitmap.GetPlatformBackendClass.Create;
  168. end
  169. else
  170. ReleasedBackend := nil;
  171. end;
  172. procedure RestoreBackend(TargetBitmap: TCustomBitmap32; const SavedBackend: TCustomBackend);
  173. begin
  174. if (SavedBackend <> nil) then
  175. TargetBitmap.Backend := SavedBackend;
  176. end;
  177. end.