GR32_Backends_LCL_CustomDrawn.pas 8.9 KB

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