GR32_Backends_LCL_CustomDrawn.pas 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. unit GR32_Backends_LCL_CustomDrawn;
  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. * Mattias Andersson <[email protected]>
  26. *
  27. * Portions created by the Initial Developer are Copyright (C) 2007-2009
  28. * the Initial Developer. All Rights Reserved.
  29. *
  30. * Contributor(s):
  31. *
  32. * ***** END LICENSE BLOCK ***** *)
  33. interface
  34. {$include GR32.inc}
  35. uses
  36. { RTL and LCL }
  37. LCLIntf, LCLType, types, Controls, SysUtils, Classes, Graphics,
  38. { CustomDrawn bindings }
  39. GraphType, FPImage, IntfGraphics, LCLProc, CustomDrawnProc,
  40. { Graphics 32 }
  41. GR32,
  42. GR32_Backends,
  43. GR32_Containers;
  44. type
  45. { TLCLBackend }
  46. TLCLBackend = class(
  47. TCustomBackend,
  48. IPaintSupport,
  49. ITextSupport,
  50. IFontSupport,
  51. IDeviceContextSupport,
  52. IInteroperabilitySupport,
  53. ICanvasSupport
  54. )
  55. private
  56. FFont: TFont;
  57. FCanvas: TCanvas;
  58. FCanvasHandle: HDC;
  59. FOnFontChange: TNotifyEvent;
  60. FOnCanvasChange: TNotifyEvent;
  61. FWidth, FHeight: Cardinal;
  62. FRawImage: TRawImage;
  63. FBitmap: TBitmap;
  64. procedure CanvasChangedHandler(Sender: TObject);
  65. protected
  66. { BITS_GETTER }
  67. function GetBits: PColor32Array; override;
  68. procedure InitializeSurface(NewWidth, NewHeight: Integer; ClearBuffer: Boolean); override;
  69. procedure FinalizeSurface; override;
  70. public
  71. constructor Create; override;
  72. destructor Destroy; override;
  73. procedure Changed; override;
  74. function Empty: Boolean; override;
  75. public
  76. { IPaintSupport }
  77. procedure ImageNeeded;
  78. procedure CheckPixmap;
  79. procedure DoPaint(ABuffer: TBitmap32; AInvalidRects: TRectList; ACanvas: TCanvas); overload;
  80. procedure DoPaint(ABuffer: TBitmap32; const AInvalidRect: TRect; ACanvas: TCanvas); overload;
  81. { IDeviceContextSupport }
  82. function GetHandle: HDC;
  83. procedure Draw(const DstRect, SrcRect: TRect; hSrc: HDC); overload;
  84. procedure DrawTo(hDst: HDC; DstX, DstY: Integer); overload;
  85. procedure DrawTo(hDst: HDC; const DstRect, SrcRect: TRect); overload;
  86. property Handle: HDC read GetHandle;
  87. { ITextSupport }
  88. procedure Textout(X, Y: Integer; const Text: string); overload;
  89. procedure Textout(X, Y: Integer; const ClipRect: TRect; const Text: string); overload;
  90. procedure Textout(var DstRect: TRect; const Flags: Cardinal; const Text: string); overload;
  91. function TextExtent(const Text: string): TSize;
  92. { IFontSupport }
  93. function GetOnFontChange: TNotifyEvent;
  94. procedure SetOnFontChange(Handler: TNotifyEvent);
  95. function GetFont: TFont;
  96. procedure SetFont(const Font: TFont);
  97. procedure UpdateFont;
  98. property Font: TFont read GetFont write SetFont;
  99. property OnFontChange: TNotifyEvent read FOnFontChange write FOnFontChange;
  100. { IInteroperabilitySupport }
  101. function CopyFrom(Graphic: TGraphic): Boolean; overload;
  102. { ICanvasSupport }
  103. function GetCanvasChange: TNotifyEvent;
  104. procedure SetCanvasChange(Handler: TNotifyEvent);
  105. function GetCanvas: TCanvas;
  106. procedure DeleteCanvas;
  107. function CanvasAllocated: Boolean;
  108. property Canvas: TCanvas read GetCanvas;
  109. property OnCanvasChange: TNotifyEvent read GetCanvasChange write SetCanvasChange;
  110. end;
  111. implementation
  112. uses
  113. GR32_LowLevel;
  114. { TLCLBackend }
  115. constructor TLCLBackend.Create;
  116. begin
  117. inherited;
  118. FBitmap := TBitmap.Create;
  119. FBitmap.Canvas.OnChange := CanvasChangedHandler;
  120. FFont := TFont.Create;
  121. end;
  122. destructor TLCLBackend.Destroy;
  123. begin
  124. inherited;
  125. FFont.Free;
  126. FBitmap.Free;
  127. end;
  128. procedure TLCLBackend.CanvasChangedHandler(Sender: TObject);
  129. begin
  130. if Assigned(FOnCanvasChange) then
  131. FOnCanvasChange(Sender);
  132. end;
  133. function TLCLBackend.GetBits: PColor32Array;
  134. begin
  135. Result := FBits;
  136. end;
  137. procedure TLCLBackend.InitializeSurface(NewWidth, NewHeight: Integer; ClearBuffer: Boolean);
  138. var
  139. CDBitmap: TCDBitmap;
  140. LazImage: TLazIntfImage;
  141. begin
  142. { We allocate our own memory for the image }
  143. FRawImage.Description.Init_BPP32_B8G8R8A8_BIO_TTB(NewWidth, NewHeight);
  144. FRawImage.CreateData(ClearBuffer);
  145. FBits := PColor32Array(FRawImage.Data);
  146. if FBits = nil then
  147. raise Exception.Create('[TLCLBackend.InitializeSurface] ERROR FBits = nil');
  148. LazImage := TLazIntfImage.Create(FRawImage, False);
  149. CDBitmap := TCDBitmap.Create;
  150. CDBitmap.Image := LazImage;
  151. FBitmap.Handle := HBITMAP(CDBitmap);
  152. FWidth := NewWidth;
  153. FHeight := NewHeight;
  154. end;
  155. procedure TLCLBackend.FinalizeSurface;
  156. begin
  157. if Assigned(FBits) then
  158. begin
  159. FRawImage.FreeData;
  160. FBits := nil;
  161. FBitmap.Handle := HBITMAP(0);
  162. end;
  163. FBits := nil;
  164. end;
  165. procedure TLCLBackend.Changed;
  166. begin
  167. inherited;
  168. end;
  169. function TLCLBackend.Empty: Boolean;
  170. begin
  171. Result := FBits = nil;
  172. end;
  173. { IPaintSupport }
  174. procedure TLCLBackend.ImageNeeded;
  175. begin
  176. end;
  177. procedure TLCLBackend.CheckPixmap;
  178. begin
  179. end;
  180. procedure TLCLBackend.DoPaint(ABuffer: TBitmap32; AInvalidRects: TRectList; ACanvas: TCanvas);
  181. begin
  182. ACanvas.Draw(0, 0, FBitmap);
  183. end;
  184. procedure TLCLBackend.DoPaint(ABuffer: TBitmap32; const AInvalidRect: TRect; ACanvas: TCanvas);
  185. begin
  186. ACanvas.Draw(0, 0, FBitmap);
  187. end;
  188. { IDeviceContextSupport }
  189. function TLCLBackend.GetHandle: HDC;
  190. begin
  191. Result := Canvas.Handle;
  192. end;
  193. procedure TLCLBackend.Draw(const DstRect, SrcRect: TRect; hSrc: HDC);
  194. begin
  195. StretchMaskBlt(
  196. Canvas.Handle,
  197. DstRect.Left,
  198. DstRect.Top,
  199. DstRect.Right - DstRect.Left,
  200. DstRect.Bottom - DstRect.Top,
  201. hSrc,
  202. SrcRect.Left,
  203. SrcRect.Top,
  204. SrcRect.Right - SrcRect.Left,
  205. SrcRect.Bottom - SrcRect.Top,
  206. 0,
  207. 0,
  208. 0,
  209. Canvas.CopyMode
  210. );
  211. end;
  212. procedure TLCLBackend.DrawTo(hDst: HDC; DstX, DstY: Integer);
  213. begin
  214. StretchMaskBlt(
  215. hDst,
  216. DstX,
  217. DstY,
  218. FWidth,
  219. FHeight,
  220. Canvas.Handle,
  221. 0,
  222. 0,
  223. FWidth,
  224. FHeight,
  225. 0,
  226. 0,
  227. 0,
  228. Canvas.CopyMode
  229. );
  230. end;
  231. procedure TLCLBackend.DrawTo(hDst: HDC; const DstRect, SrcRect: TRect);
  232. begin
  233. StretchMaskBlt(
  234. hDst,
  235. DstRect.Left,
  236. DstRect.Top,
  237. DstRect.Right - DstRect.Left,
  238. DstRect.Bottom - DstRect.Top,
  239. Canvas.Handle,
  240. SrcRect.Left,
  241. SrcRect.Top,
  242. SrcRect.Right - SrcRect.Left,
  243. SrcRect.Bottom - SrcRect.Top,
  244. 0,
  245. 0,
  246. 0,
  247. Canvas.CopyMode
  248. );
  249. end;
  250. { ITextSupport }
  251. procedure TLCLBackend.Textout(X, Y: Integer; const Text: string);
  252. begin
  253. if not Assigned(FCanvas) then GetCanvas;
  254. UpdateFont;
  255. if not FOwner.MeasuringMode then
  256. FCanvas.TextOut(X, Y, Text);
  257. // FOwner.Changed(DstRect);
  258. end;
  259. procedure TLCLBackend.Textout(X, Y: Integer; const ClipRect: TRect; const Text: string);
  260. begin
  261. if not Assigned(FCanvas) then GetCanvas;
  262. UpdateFont;
  263. LCLIntf.ExtTextOut(FCanvas.Handle, X, Y, ETO_CLIPPED, @ClipRect, PChar(Text), Length(Text), nil);
  264. end;
  265. procedure TLCLBackend.Textout(var DstRect: TRect; const Flags: Cardinal; const Text: string);
  266. begin
  267. UpdateFont;
  268. LCLIntf.DrawText(FCanvas.Handle, PChar(Text), Length(Text), DstRect, Flags);
  269. end;
  270. function TLCLBackend.TextExtent(const Text: string): TSize;
  271. begin
  272. if not Assigned(FCanvas) then GetCanvas;
  273. UpdateFont;
  274. Result := FCanvas.TextExtent(Text);
  275. end;
  276. { IFontSupport }
  277. function TLCLBackend.GetOnFontChange: TNotifyEvent;
  278. begin
  279. Result := FFont.OnChange;
  280. end;
  281. procedure TLCLBackend.SetOnFontChange(Handler: TNotifyEvent);
  282. begin
  283. FFont.OnChange := Handler;
  284. end;
  285. function TLCLBackend.GetFont: TFont;
  286. begin
  287. Result := FFont;
  288. end;
  289. procedure TLCLBackend.SetFont(const Font: TFont);
  290. begin
  291. FFont.Assign(Font);
  292. end;
  293. procedure TLCLBackend.UpdateFont;
  294. begin
  295. FFont.OnChange := FOnFontChange;
  296. if Assigned(FCanvas) then FCanvas.Font := FFont;
  297. end;
  298. { IInteroperabilitySupport }
  299. type
  300. TGraphicAccess = class(TGraphic);
  301. function TLCLBackend.CopyFrom(Graphic: TGraphic): Boolean;
  302. begin
  303. TGraphicAccess(Graphic).Draw(Canvas, MakeRect(0, 0, Canvas.Width, Canvas.Height));
  304. end;
  305. { ICanvasSupport }
  306. function TLCLBackend.GetCanvasChange: TNotifyEvent;
  307. begin
  308. Result := FOnCanvasChange;
  309. end;
  310. procedure TLCLBackend.SetCanvasChange(Handler: TNotifyEvent);
  311. begin
  312. FOnCanvasChange := Handler;
  313. end;
  314. function TLCLBackend.GetCanvas: TCanvas;
  315. begin
  316. Result := FBitmap.Canvas;
  317. end;
  318. procedure TLCLBackend.DeleteCanvas;
  319. begin
  320. end;
  321. function TLCLBackend.CanvasAllocated: Boolean;
  322. begin
  323. Result := (Canvas <> nil);
  324. end;
  325. end.