source: trunk/Packages/Graphics32/GR32_Backends_LCL_Win.pas

Last change on this file was 2, checked in by chronos, 5 years ago
File size: 23.2 KB
Line 
1unit GR32_Backends_LCL_Win;
2
3(* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1 or LGPL 2.1 with linking exception
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * Alternatively, the contents of this file may be used under the terms of the
17 * Free Pascal modified version of the GNU Lesser General Public License
18 * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
19 * of this license are applicable instead of those above.
20 * Please see the file LICENSE.txt for additional information concerning this
21 * license.
22 *
23 * The Original Code is Backend Extension for Graphics32
24 *
25 * The Initial Developer of the Original Code is
26 * Andre Beckedorf - metaException
27 * Andre@metaException.de
28 *
29 * Portions created by the Initial Developer are Copyright (C) 2007-2012
30 * the Initial Developer. All Rights Reserved.
31 *
32 * Contributor(s):
33 * Christian Budde
34 *
35 * ***** END LICENSE BLOCK ***** *)
36
37interface
38
39{$I GR32.inc}
40
41uses
42 {$IFDEF LCLWin32} Windows, {$ENDIF} LCLIntf, LCLType, Types, Controls,
43 SysUtils, Classes, Graphics, GR32, GR32_Backends, GR32_Backends_Generic,
44 GR32_Containers, GR32_Image, GR32_Paths;
45
46type
47 { TLCLBackend }
48 { This backend uses the LCL to manage and provide the buffer and additional
49 graphics sub system features. The backing buffer is kept in memory. }
50
51 TLCLBackend = class(TCustomBackend, IPaintSupport,
52 IBitmapContextSupport, IDeviceContextSupport,
53 ITextSupport, IFontSupport, ITextToPathSupport, ICanvasSupport)
54 private
55 procedure FontChangedHandler(Sender: TObject);
56 procedure CanvasChangedHandler(Sender: TObject);
57 procedure CanvasChanged;
58 procedure FontChanged;
59 protected
60 FBitmapInfo: TBitmapInfo;
61 FBitmapHandle: HBITMAP;
62 FHDC: HDC;
63 FFont: TFont;
64 FCanvas: TCanvas;
65 FFontHandle: HFont;
66 FMapHandle: THandle;
67
68 FOnFontChange: TNotifyEvent;
69 FOnCanvasChange: TNotifyEvent;
70
71 procedure InitializeSurface(NewWidth, NewHeight: Integer; ClearBuffer: Boolean); override;
72 procedure FinalizeSurface; override;
73
74 procedure PrepareFileMapping(NewWidth, NewHeight: Integer); virtual;
75 public
76 constructor Create; override;
77 destructor Destroy; override;
78
79 procedure Changed; override;
80
81 function Empty: Boolean; override;
82 public
83 { IPaintSupport }
84 procedure ImageNeeded;
85 procedure CheckPixmap;
86 procedure DoPaint(ABuffer: TBitmap32; AInvalidRects: TRectList;
87 ACanvas: TCanvas; APaintBox: TCustomPaintBox32);
88
89 { IBitmapContextSupport }
90 function GetBitmapInfo: TBitmapInfo;
91 function GetBitmapHandle: THandle;
92
93 property BitmapInfo: TBitmapInfo read GetBitmapInfo;
94 property BitmapHandle: THandle read GetBitmapHandle;
95
96 { IDeviceContextSupport }
97 function GetHandle: HDC;
98
99 procedure Draw(const DstRect, SrcRect: TRect; hSrc: HDC); overload;
100 procedure DrawTo(hDst: HDC; DstX, DstY: Integer); overload;
101 procedure DrawTo(hDst: HDC; const DstRect, SrcRect: TRect); overload;
102
103 property Handle: HDC read GetHandle;
104
105 { ITextSupport }
106 procedure Textout(X, Y: Integer; const Text: string); overload;
107 procedure Textout(X, Y: Integer; const ClipRect: TRect; const Text: string); overload;
108 procedure Textout(var DstRect: TRect; const Flags: Cardinal; const Text: string); overload;
109 function TextExtent(const Text: string): TSize;
110
111 procedure TextoutW(X, Y: Integer; const Text: Widestring); overload;
112 procedure TextoutW(X, Y: Integer; const ClipRect: TRect; const Text: Widestring); overload;
113 procedure TextoutW(var DstRect: TRect; const Flags: Cardinal; const Text: Widestring); overload;
114 function TextExtentW(const Text: Widestring): TSize;
115
116 { IFontSupport }
117 function GetOnFontChange: TNotifyEvent;
118 procedure SetOnFontChange(Handler: TNotifyEvent);
119 function GetFont: TFont;
120 procedure SetFont(const Font: TFont);
121
122 procedure UpdateFont;
123 property Font: TFont read GetFont write SetFont;
124 property OnFontChange: TNotifyEvent read FOnFontChange write FOnFontChange;
125
126 { ITextToPathSupport }
127 procedure TextToPath(Path: TCustomPath; const X, Y: TFloat; const Text: WideString); overload;
128 procedure TextToPath(Path: TCustomPath; const DstRect: TFloatRect; const Text: WideString; Flags: Cardinal); overload;
129 function MeasureText(const DstRect: TFloatRect; const Text: WideString; Flags: Cardinal): TFloatRect;
130
131 { ICanvasSupport }
132 function GetCanvasChange: TNotifyEvent;
133 procedure SetCanvasChange(Handler: TNotifyEvent);
134 function GetCanvas: TCanvas;
135
136 procedure DeleteCanvas;
137 function CanvasAllocated: Boolean;
138
139 property Canvas: TCanvas read GetCanvas;
140 property OnCanvasChange: TNotifyEvent read GetCanvasChange write SetCanvasChange;
141 end;
142
143 { TLCLGDIMMFBackend }
144 { Same as TGDIBackend but relies on memory mapped files or mapped swap space
145 for the backing buffer. }
146
147 TLCLMMFBackend = class(TLCLBackend)
148 private
149 FMapFileHandle: THandle;
150 FMapIsTemporary: Boolean;
151 FMapFileName: string;
152 protected
153 procedure PrepareFileMapping(NewWidth, NewHeight: Integer); override;
154 public
155 constructor Create(Owner: TBitmap32; IsTemporary: Boolean = True; const MapFileName: string = ''); virtual;
156 destructor Destroy; override;
157 end;
158
159 { TGDIMemoryBackend }
160 { A backend that keeps the backing buffer entirely in memory and offers
161 IPaintSupport without allocating a GDI handle }
162
163 TLCLMemoryBackend = class(TMemoryBackend, IPaintSupport, IDeviceContextSupport)
164 private
165 procedure DoPaintRect(ABuffer: TBitmap32; ARect: TRect; ACanvas: TCanvas);
166
167 function GetHandle: HDC; // Dummy
168 protected
169 FBitmapInfo: TBitmapInfo;
170
171 procedure InitializeSurface(NewWidth: Integer; NewHeight: Integer;
172 ClearBuffer: Boolean); override;
173 public
174 constructor Create; override;
175
176 { IPaintSupport }
177 procedure ImageNeeded;
178 procedure CheckPixmap;
179 procedure DoPaint(ABuffer: TBitmap32; AInvalidRects: TRectList; ACanvas: TCanvas; APaintBox: TCustomPaintBox32);
180
181 { IDeviceContextSupport }
182 procedure Draw(const DstRect, SrcRect: TRect; hSrc: HDC); overload;
183 procedure DrawTo(hDst: HDC; DstX, DstY: Integer); overload;
184 procedure DrawTo(hDst: HDC; const DstRect, SrcRect: TRect); overload;
185 end;
186
187implementation
188
189uses
190 GR32_Text_LCL_Win;
191
192var
193 StockFont: HFONT;
194
195{ TLCLBackend }
196
197constructor TLCLBackend.Create;
198begin
199 inherited;
200
201 FillChar(FBitmapInfo, SizeOf(TBitmapInfo), 0);
202 with FBitmapInfo.bmiHeader do
203 begin
204 biSize := SizeOf(TBitmapInfoHeader);
205 biPlanes := 1;
206 biBitCount := 32;
207 biCompression := BI_RGB;
208 end;
209
210 FMapHandle := 0;
211
212 FFont := TFont.Create;
213 FFont.OnChange := FontChangedHandler;
214end;
215
216destructor TLCLBackend.Destroy;
217begin
218 DeleteCanvas;
219 FFont.Free;
220
221 inherited;
222end;
223
224procedure TLCLBackend.InitializeSurface(NewWidth, NewHeight: Integer; ClearBuffer: Boolean);
225begin
226 with FBitmapInfo.bmiHeader do
227 begin
228 biWidth := NewWidth;
229 biHeight := -NewHeight;
230 biSizeImage := NewWidth * NewHeight * 4;
231 end;
232
233 PrepareFileMapping(NewWidth, NewHeight);
234
235 FBitmapHandle := LCLIntf.CreateDIBSection(0, FBitmapInfo, DIB_RGB_COLORS, Pointer(FBits), FMapHandle, 0);
236
237 if FBits = nil then
238 raise Exception.Create(RCStrCannotAllocateDIBHandle);
239
240 FHDC := CreateCompatibleDC(0);
241 if FHDC = 0 then
242 begin
243 DeleteObject(FBitmapHandle);
244 FBitmapHandle := 0;
245 FBits := nil;
246 raise Exception.Create(RCStrCannotCreateCompatibleDC);
247 end;
248
249 if SelectObject(FHDC, FBitmapHandle) = 0 then
250 begin
251 DeleteDC(FHDC);
252 DeleteObject(FBitmapHandle);
253 FHDC := 0;
254 FBitmapHandle := 0;
255 FBits := nil;
256 raise Exception.Create(RCStrCannotSelectAnObjectIntoDC);
257 end;
258end;
259
260procedure TLCLBackend.FinalizeSurface;
261begin
262 if FHDC <> 0 then DeleteDC(FHDC);
263 FHDC := 0;
264 if FBitmapHandle <> 0 then DeleteObject(FBitmapHandle);
265 FBitmapHandle := 0;
266
267 FBits := nil;
268end;
269
270procedure TLCLBackend.DeleteCanvas;
271begin
272 if Assigned(FCanvas) then
273 begin
274 FCanvas.Handle := 0;
275 FCanvas.Free;
276 FCanvas := nil;
277 end;
278end;
279
280procedure TLCLBackend.PrepareFileMapping(NewWidth, NewHeight: Integer);
281begin
282 // to be implemented by descendants
283end;
284
285procedure TLCLBackend.Changed;
286begin
287 if FCanvas <> nil then FCanvas.Handle := Self.Handle;
288 inherited;
289end;
290
291procedure TLCLBackend.CanvasChanged;
292begin
293 if Assigned(FOnCanvasChange) then
294 FOnCanvasChange(Self);
295end;
296
297procedure TLCLBackend.FontChanged;
298begin
299 if Assigned(FOnFontChange) then
300 FOnFontChange(Self);
301end;
302
303function TLCLBackend.TextExtent(const Text: string): TSize;
304var
305 DC: HDC;
306 OldFont: HGDIOBJ;
307begin
308 UpdateFont;
309 Result.cX := 0;
310 Result.cY := 0;
311 if Handle <> 0 then
312 GetTextExtentPoint32(Handle, PChar(Text), Length(Text), Result)
313 else
314 begin
315 StockBitmap.Canvas.Lock;
316 try
317 DC := StockBitmap.Canvas.Handle;
318 OldFont := SelectObject(DC, Font.Handle);
319 GetTextExtentPoint32(DC, PChar(Text), Length(Text), Result);
320 SelectObject(DC, OldFont);
321 finally
322 StockBitmap.Canvas.Unlock;
323 end;
324 end;
325end;
326
327function TLCLBackend.TextExtentW(const Text: Widestring): TSize;
328var
329 DC: HDC;
330 OldFont: HGDIOBJ;
331begin
332 UpdateFont;
333 Result.cX := 0;
334 Result.cY := 0;
335
336 if Handle <> 0 then
337 GetTextExtentPoint32W(Handle, PWideChar(Text), Length(Text), Result)
338 else
339 begin
340 StockBitmap.Canvas.Lock;
341 try
342 DC := StockBitmap.Canvas.Handle;
343 OldFont := SelectObject(DC, Font.Handle);
344 GetTextExtentPoint32W(DC, PWideChar(Text), Length(Text), Result);
345 SelectObject(DC, OldFont);
346 finally
347 StockBitmap.Canvas.Unlock;
348 end;
349 end;
350end;
351
352procedure TLCLBackend.Textout(X, Y: Integer; const Text: string);
353var
354 Extent: TSize;
355begin
356 UpdateFont;
357
358 if not FOwner.MeasuringMode then
359 begin
360 if FOwner.Clipping then
361 ExtTextout(Handle, X, Y, ETO_CLIPPED, @FOwner.ClipRect, PChar(Text), Length(Text), nil)
362 else
363 ExtTextout(Handle, X, Y, 0, nil, PChar(Text), Length(Text), nil);
364 end;
365
366 Extent := TextExtent(Text);
367 FOwner.Changed(MakeRect(X, Y, X + Extent.cx + 1, Y + Extent.cy + 1));
368end;
369
370procedure TLCLBackend.TextoutW(X, Y: Integer; const Text: Widestring);
371var
372 Extent: TSize;
373begin
374 UpdateFont;
375
376 if not FOwner.MeasuringMode then
377 begin
378 if FOwner.Clipping then
379 ExtTextoutW(Handle, X, Y, ETO_CLIPPED, @FOwner.ClipRect, PWideChar(Text), Length(Text), nil)
380 else
381 ExtTextoutW(Handle, X, Y, 0, nil, PWideChar(Text), Length(Text), nil);
382 end;
383
384 Extent := TextExtentW(Text);
385 FOwner.Changed(MakeRect(X, Y, X + Extent.cx + 1, Y + Extent.cy + 1));
386end;
387
388procedure TLCLBackend.TextoutW(X, Y: Integer; const ClipRect: TRect; const Text: Widestring);
389var
390 Extent: TSize;
391begin
392 UpdateFont;
393
394 if not FOwner.MeasuringMode then
395 ExtTextoutW(Handle, X, Y, ETO_CLIPPED, @ClipRect, PWideChar(Text), Length(Text), nil);
396
397 Extent := TextExtentW(Text);
398 FOwner.Changed(MakeRect(X, Y, X + Extent.cx + 1, Y + Extent.cy + 1));
399end;
400
401procedure TLCLBackend.Textout(X, Y: Integer; const ClipRect: TRect; const Text: string);
402var
403 Extent: TSize;
404begin
405 UpdateFont;
406
407 if not FOwner.MeasuringMode then
408 ExtTextout(Handle, X, Y, ETO_CLIPPED, @ClipRect, PChar(Text), Length(Text), nil);
409
410 Extent := TextExtent(Text);
411 FOwner.Changed(MakeRect(X, Y, X + Extent.cx + 1, Y + Extent.cy + 1));
412end;
413
414procedure TLCLBackend.TextoutW(var DstRect: TRect; const Flags: Cardinal; const Text: Widestring);
415begin
416 UpdateFont;
417
418 if not FOwner.MeasuringMode then
419 DrawTextW(Handle, PWideChar(Text), Length(Text), DstRect, Flags);
420
421 FOwner.Changed(DstRect);
422end;
423
424procedure TLCLBackend.UpdateFont;
425begin
426 if (FFontHandle = 0) and (Handle <> 0) then
427 begin
428 SelectObject(Handle, Font.Handle);
429 SetTextColor(Handle, ColorToRGB(Font.Color));
430 SetBkMode(Handle, TRANSPARENT);
431 FFontHandle := Font.Handle;
432 end
433 else
434 begin
435 SelectObject(Handle, FFontHandle);
436 SetTextColor(Handle, ColorToRGB(Font.Color));
437 SetBkMode(Handle, TRANSPARENT);
438 end;
439end;
440
441procedure TLCLBackend.TextToPath(Path: TCustomPath; const X, Y: TFloat;
442 const Text: WideString);
443var
444 R: TFloatRect;
445begin
446 R := FloatRect(X, Y, X, Y);
447 GR32_Text_LCL_Win.TextToPath(Font.Handle, Path, R, Text, 0);
448end;
449
450procedure TLCLBackend.TextToPath(Path: TCustomPath; const DstRect: TFloatRect;
451 const Text: WideString; Flags: Cardinal);
452begin
453 GR32_Text_LCL_Win.TextToPath(Font.Handle, Path, DstRect, Text, Flags);
454end;
455
456function TLCLBackend.MeasureText(const DstRect: TFloatRect;
457 const Text: WideString; Flags: Cardinal): TFloatRect;
458begin
459 Result := GR32_Text_LCL_Win.MeasureText(Font.Handle, DstRect, Text, Flags);
460end;
461
462procedure TLCLBackend.Textout(var DstRect: TRect; const Flags: Cardinal; const Text: string);
463begin
464 UpdateFont;
465
466 if not FOwner.MeasuringMode then
467 DrawText(Handle, PChar(Text), Length(Text), DstRect, Flags);
468
469 FOwner.Changed(DstRect);
470end;
471
472procedure TLCLBackend.DrawTo(hDst: HDC; DstX, DstY: Integer);
473begin
474 Windows.BitBlt(hDst, DstX, DstY, FOwner.Width, FOwner.Height, Handle, 0, 0,
475 SRCCOPY);
476(*
477StretchDIBits(
478 hDst, DstX, DstY, FOwner.Width, FOwner.Height,
479 0, 0, FOwner.Width, FOwner.Height, Bits, FBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
480*)
481end;
482
483procedure TLCLBackend.DrawTo(hDst: HDC; const DstRect, SrcRect: TRect);
484begin
485 Windows.StretchBlt(hDst,
486 DstRect.Left, DstRect.Top, DstRect.Right - DstRect.Left, DstRect.Bottom - DstRect.Top, Handle,
487 SrcRect.Left, SrcRect.Top, SrcRect.Right - SrcRect.Left, SrcRect.Bottom - SrcRect.Top, SRCCOPY);
488end;
489
490function TLCLBackend.GetBitmapHandle: THandle;
491begin
492 Result := FBitmapHandle;
493end;
494
495function TLCLBackend.GetBitmapInfo: TBitmapInfo;
496begin
497 Result := FBitmapInfo;
498end;
499
500function TLCLBackend.GetCanvas: TCanvas;
501begin
502 if not Assigned(FCanvas) then
503 begin
504 FCanvas := TCanvas.Create;
505 FCanvas.Handle := Handle;
506 FCanvas.OnChange := CanvasChangedHandler;
507 end;
508 Result := FCanvas;
509end;
510
511function TLCLBackend.GetCanvasChange: TNotifyEvent;
512begin
513 Result := FOnCanvasChange;
514end;
515
516function TLCLBackend.GetFont: TFont;
517begin
518 Result := FFont;
519end;
520
521function TLCLBackend.GetHandle: HDC;
522begin
523 Result := FHDC;
524end;
525
526function TLCLBackend.GetOnFontChange: TNotifyEvent;
527begin
528 Result := FOnFontChange;
529end;
530
531procedure TLCLBackend.SetCanvasChange(Handler: TNotifyEvent);
532begin
533 FOnCanvasChange := Handler;
534end;
535
536procedure TLCLBackend.SetFont(const Font: TFont);
537begin
538 FFont.Assign(Font);
539 FontChanged;
540end;
541
542procedure TLCLBackend.SetOnFontChange(Handler: TNotifyEvent);
543begin
544 FOnFontChange := Handler;
545end;
546
547procedure TLCLBackend.Draw(const DstRect, SrcRect: TRect; hSrc: HDC);
548begin
549 if FOwner.Empty then Exit;
550
551 if not FOwner.MeasuringMode then
552 Windows.StretchBlt(Handle, DstRect.Left, DstRect.Top, DstRect.Right - DstRect.Left,
553 DstRect.Bottom - DstRect.Top, hSrc, SrcRect.Left, SrcRect.Top,
554 SrcRect.Right - SrcRect.Left, SrcRect.Bottom - SrcRect.Top, SRCCOPY);
555
556 FOwner.Changed(DstRect);
557end;
558
559function TLCLBackend.CanvasAllocated: Boolean;
560begin
561 Result := Assigned(FCanvas);
562end;
563
564function TLCLBackend.Empty: Boolean;
565begin
566 Result := FBitmapHandle = 0;
567end;
568
569procedure TLCLBackend.FontChangedHandler(Sender: TObject);
570begin
571 if FFontHandle <> 0 then
572 begin
573 if Handle <> 0 then SelectObject(Handle, StockFont);
574 FFontHandle := 0;
575 end;
576
577 FontChanged;
578end;
579
580procedure TLCLBackend.CanvasChangedHandler(Sender: TObject);
581begin
582 CanvasChanged;
583end;
584
585{ IPaintSupport }
586
587procedure TLCLBackend.ImageNeeded;
588begin
589
590end;
591
592procedure TLCLBackend.CheckPixmap;
593begin
594
595end;
596
597procedure TLCLBackend.DoPaint(ABuffer: TBitmap32; AInvalidRects: TRectList;
598 ACanvas: TCanvas; APaintBox: TCustomPaintBox32);
599var
600 i: Integer;
601begin
602 if AInvalidRects.Count > 0 then
603 for i := 0 to AInvalidRects.Count - 1 do
604 with AInvalidRects[i]^ do
605 Windows.BitBlt(ACanvas.Handle, Left, Top, Right - Left, Bottom - Top, ABuffer.Handle, Left, Top, SRCCOPY)
606 else
607 with APaintBox.GetViewportRect do
608 Windows.BitBlt(ACanvas.Handle, Left, Top, Right - Left, Bottom - Top, ABuffer.Handle, Left, Top, SRCCOPY);
609end;
610
611
612{ TLCLMMFBackend }
613
614constructor TLCLMMFBackend.Create(Owner: TBitmap32; IsTemporary: Boolean = True; const MapFileName: string = '');
615begin
616 FMapFileName := MapFileName;
617 FMapIsTemporary := IsTemporary;
618 TMMFBackend.InitializeFileMapping(FMapHandle, FMapFileHandle, FMapFileName);
619 inherited Create(Owner);
620end;
621
622destructor TLCLMMFBackend.Destroy;
623begin
624 TMMFBackend.DeinitializeFileMapping(FMapHandle, FMapFileHandle, FMapFileName);
625 inherited;
626end;
627
628procedure TLCLMMFBackend.PrepareFileMapping(NewWidth, NewHeight: Integer);
629begin
630 TMMFBackend.CreateFileMapping(FMapHandle, FMapFileHandle, FMapFileName, FMapIsTemporary, NewWidth, NewHeight);
631end;
632
633
634{ TLCLMemoryBackend }
635
636constructor TLCLMemoryBackend.Create;
637begin
638 inherited;
639 FillChar(FBitmapInfo, SizeOf(TBitmapInfo), 0);
640 with FBitmapInfo.bmiHeader do
641 begin
642 biSize := SizeOf(TBitmapInfoHeader);
643 biPlanes := 1;
644 biBitCount := 32;
645 biCompression := BI_RGB;
646 biXPelsPerMeter := 96;
647 biYPelsPerMeter := 96;
648 biClrUsed := 0;
649 end;
650end;
651
652procedure TLCLMemoryBackend.InitializeSurface(NewWidth, NewHeight: Integer;
653 ClearBuffer: Boolean);
654begin
655 inherited;
656 with FBitmapInfo.bmiHeader do
657 begin
658 biWidth := NewWidth;
659 biHeight := -NewHeight;
660 end;
661end;
662
663procedure TLCLMemoryBackend.ImageNeeded;
664begin
665
666end;
667
668procedure TLCLMemoryBackend.CheckPixmap;
669begin
670
671end;
672
673procedure TLCLMemoryBackend.DoPaintRect(ABuffer: TBitmap32;
674 ARect: TRect; ACanvas: TCanvas);
675var
676 Bitmap : HBITMAP;
677 DeviceContext : HDC;
678 Buffer : Pointer;
679 OldObject : HGDIOBJ;
680begin
681 {$IFDEF LCLWin32}
682 if SetDIBitsToDevice(ACanvas.Handle, ARect.Left, ARect.Top, ARect.Right -
683 ARect.Left, ARect.Bottom - ARect.Top, ARect.Left, ARect.Top, 0,
684 ARect.Bottom - ARect.Top, ABuffer.Bits, Windows.BITMAPINFO(FBitmapInfo), DIB_RGB_COLORS) = 0 then
685 begin
686 // create compatible device context
687 DeviceContext := CreateCompatibleDC(ACanvas.Handle);
688 if DeviceContext <> 0 then
689 try
690 Bitmap := CreateDIBSection(DeviceContext, FBitmapInfo, DIB_RGB_COLORS,
691 Buffer, 0, 0);
692
693 if Bitmap <> 0 then
694 begin
695 OldObject := SelectObject(DeviceContext, Bitmap);
696 try
697 Move(ABuffer.Bits^, Buffer^, FBitmapInfo.bmiHeader.biWidth *
698 FBitmapInfo.bmiHeader.biHeight * SizeOf(Cardinal));
699 Windows.BitBlt(ACanvas.Handle, ARect.Left, ARect.Top, ARect.Right -
700 ARect.Left, ARect.Bottom - ARect.Top, DeviceContext, 0, 0, SRCCOPY);
701 finally
702 if OldObject <> 0 then
703 SelectObject(DeviceContext, OldObject);
704 DeleteObject(Bitmap);
705 end;
706 end else
707 raise Exception.Create(RCStrCannotCreateCompatibleDC);
708 finally
709 DeleteDC(DeviceContext);
710 end;
711 end;
712 {$ELSE}
713 raise Exception.Create('"SetDIBitsToDevice" is only included in windows unit!')
714 {$ENDIF}
715end;
716
717procedure TLCLMemoryBackend.Draw(const DstRect, SrcRect: TRect; hSrc: HDC);
718begin
719 if FOwner.Empty then Exit;
720
721 if not FOwner.MeasuringMode then
722 raise Exception.Create('Not yet supported!');
723
724 FOwner.Changed(DstRect);
725end;
726
727procedure TLCLMemoryBackend.DrawTo(hDst: HDC; DstX, DstY: Integer);
728var
729 Bitmap: HBITMAP;
730 DeviceContext: HDC;
731 Buffer: Pointer;
732 OldObject: HGDIOBJ;
733begin
734 {$IFDEF LCLWin32}
735 if SetDIBitsToDevice(hDst, DstX, DstY,
736 FOwner.Width, FOwner.Height, 0, 0, 0, FOwner.Height, FBits,
737 Windows.BITMAPINFO(FBitmapInfo), DIB_RGB_COLORS) = 0 then
738 begin
739 // create compatible device context
740 DeviceContext := CreateCompatibleDC(hDst);
741 if DeviceContext <> 0 then
742 try
743 Bitmap := CreateDIBSection(DeviceContext, FBitmapInfo, DIB_RGB_COLORS,
744 Buffer, 0, 0);
745
746 if Bitmap <> 0 then
747 begin
748 OldObject := SelectObject(DeviceContext, Bitmap);
749 try
750 Move(FBits^, Buffer^, FBitmapInfo.bmiHeader.biWidth *
751 FBitmapInfo.bmiHeader.biHeight * SizeOf(Cardinal));
752 Windows.BitBlt(hDst, DstX, DstY, FOwner.Width, FOwner.Height, DeviceContext,
753 0, 0, SRCCOPY);
754 finally
755 if OldObject <> 0 then
756 SelectObject(DeviceContext, OldObject);
757 DeleteObject(Bitmap);
758 end;
759 end else
760 raise Exception.Create('Can''t create compatible DC''');
761 finally
762 DeleteDC(DeviceContext);
763 end;
764 end;
765 {$ELSE}
766 raise Exception.Create('"SetDIBitsToDevice" is only included in windows unit!')
767 {$ENDIF}
768end;
769
770procedure TLCLMemoryBackend.DrawTo(hDst: HDC; const DstRect, SrcRect: TRect);
771var
772 Bitmap: HBITMAP;
773 DeviceContext: HDC;
774 Buffer: Pointer;
775 OldObject: HGDIOBJ;
776begin
777 {$IFDEF LCLWin32}
778 if SetDIBitsToDevice(hDst, DstRect.Left, DstRect.Top,
779 DstRect.Right - DstRect.Left, DstRect.Bottom - DstRect.Top, SrcRect.Left,
780 SrcRect.Top, 0, SrcRect.Bottom - SrcRect.Top, FBits,
781 Windows.BITMAPINFO(FBitmapInfo), DIB_RGB_COLORS) = 0 then
782 begin
783 // create compatible device context
784 DeviceContext := CreateCompatibleDC(hDst);
785 if DeviceContext <> 0 then
786 try
787 Buffer := nil;
788 Bitmap := CreateDIBSection(DeviceContext, FBitmapInfo, DIB_RGB_COLORS,
789 Buffer, 0, 0);
790
791 if Bitmap <> 0 then
792 begin
793 OldObject := SelectObject(DeviceContext, Bitmap);
794 try
795 Move(FBits^, Buffer^, FBitmapInfo.bmiHeader.biWidth *
796 FBitmapInfo.bmiHeader.biHeight * SizeOf(Cardinal));
797 Windows.BitBlt(hDst, DstRect.Left, DstRect.Top, DstRect.Right -
798 DstRect.Left, DstRect.Bottom - DstRect.Top, DeviceContext, 0, 0, SRCCOPY);
799 finally
800 if OldObject <> 0 then
801 SelectObject(DeviceContext, OldObject);
802 DeleteObject(Bitmap);
803 end;
804 end else
805 raise Exception.Create('Can''t create compatible DC''');
806 finally
807 DeleteDC(DeviceContext);
808 end;
809 end;
810 {$ELSE}
811 raise Exception.Create('"SetDIBitsToDevice" is only included in windows unit!')
812 {$ENDIF}
813end;
814
815function TLCLMemoryBackend.GetHandle: HDC;
816begin
817 Result := 0;
818end;
819
820procedure TLCLMemoryBackend.DoPaint(ABuffer: TBitmap32;
821 AInvalidRects: TRectList; ACanvas: TCanvas; APaintBox: TCustomPaintBox32);
822var
823 i : Integer;
824begin
825 if AInvalidRects.Count > 0 then
826 for i := 0 to AInvalidRects.Count - 1 do
827 DoPaintRect(ABuffer, AInvalidRects[i]^, ACanvas)
828 else
829 DoPaintRect(ABuffer, APaintBox.GetViewportRect, ACanvas);
830end;
831
832initialization
833 StockFont := GetStockObject(SYSTEM_FONT);
834
835finalization
836
837end.
Note: See TracBrowser for help on using the repository browser.