123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- unit GR32_ExtImage;
- (* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1 or LGPL 2.1 with linking exception
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * Alternatively, the contents of this file may be used under the terms of the
- * Free Pascal modified version of the GNU Lesser General Public License
- * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
- * of this license are applicable instead of those above.
- * Please see the file LICENSE.txt for additional information concerning this
- * license.
- *
- * The Original Code is Extended Image components for Graphics32
- *
- * The Initial Developer of the Original Code is
- * Mattias Andersson <[email protected]>
- *
- * Portions created by the Initial Developer are Copyright (C) 2005-2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** *)
- interface
- {$include GR32.inc}
- uses
- {$IFDEF FPC}
- LCLIntf, LCLType, LMessages,
- {$ELSE}
- Windows, Messages,
- {$ENDIF}
- GR32, GR32_Image, GR32_Rasterizers, Classes, Controls;
- type
- TRenderThread = class;
- TRenderMode = (rnmFull, rnmConstrained);
- { TSyntheticImage32 }
- TSyntheticImage32 = class(TPaintBox32)
- private
- FRasterizer: TRasterizer;
- FAutoRasterize: Boolean;
- FDefaultProc: TWndMethod;
- FResized: Boolean;
- FRenderThread: TRenderThread;
- FOldAreaChanged: TAreaChangedEvent;
- FDstRect: TRect;
- FRenderMode: TRenderMode;
- FClearBuffer: Boolean;
- procedure SetRasterizer(const Value: TRasterizer);
- procedure StopRenderThread;
- procedure SetDstRect(const Value: TRect);
- procedure SetRenderMode(const Value: TRenderMode);
- protected
- procedure RasterizerChanged(Sender: TObject);
- procedure SetParent(AParent: TWinControl); override;
- {$IFDEF FPC}
- procedure FormWindowProc(var Message: TLMessage);
- {$ELSE}
- procedure FormWindowProc(var Message: TMessage);
- {$ENDIF}
- procedure DoRasterize;
- property RepaintMode;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure Resize; override;
- procedure Rasterize;
- property DstRect: TRect read FDstRect write SetDstRect;
- published
- property AutoRasterize: Boolean read FAutoRasterize write FAutoRasterize;
- property Rasterizer: TRasterizer read FRasterizer write SetRasterizer;
- property ClearBuffer: Boolean read FClearBuffer write FClearBuffer;
- property RenderMode: TRenderMode read FRenderMode write SetRenderMode;
- property Color;
- end;
- { TRenderThread }
- TRenderThread = class(TThread)
- private
- FDest: TBitmap32;
- FRasterizer: TRasterizer;
- FOldAreaChanged: TAreaChangedEvent;
- FArea: TRect;
- FDstRect: TRect;
- procedure SynchronizedAreaChanged;
- procedure AreaChanged(Sender: TObject; const Area: TRect; const Hint: Cardinal);
- protected
- procedure Execute; override;
- procedure Rasterize;
- public
- constructor Create(Rasterizer: TRasterizer; Dst: TBitmap32; DstRect: TRect;
- Suspended: Boolean);
- end;
- procedure Rasterize(Rasterizer: TRasterizer; Dst: TBitmap32; DstRect: TRect);
- implementation
- uses
- Forms, SysUtils, Graphics;
- procedure Rasterize(Rasterizer: TRasterizer; Dst: TBitmap32; DstRect: TRect);
- var
- R: TRenderThread;
- begin
- R := TRenderThread.Create(Rasterizer, Dst, DstRect, True);
- R.FreeOnTerminate := True;
- {$IFDEF USETHREADRESUME}
- R.Resume;
- {$ELSE}
- R.Start;
- {$ENDIF}
- end;
- { TSyntheticImage32 }
- constructor TSyntheticImage32.Create(AOwner: TComponent);
- begin
- inherited;
- FRasterizer := TRegularRasterizer.Create;
- FRasterizer.Sampler := Buffer.Resampler;
- FAutoRasterize := True;
- FResized := False;
- RepaintMode := rmDirect;
- RenderMode := rnmFull;
- BufferOversize := 0;
- end;
- destructor TSyntheticImage32.Destroy;
- var
- ParentForm: TCustomForm;
- begin
- StopRenderThread;
- if Assigned(FRenderThread) then FRenderThread.Free;
- if Assigned(FDefaultProc) then
- begin
- ParentForm := GetParentForm(Self);
- if ParentForm <> nil then
- ParentForm.WindowProc := FDefaultProc;
- end;
- FRasterizer.Free;
- inherited;
- end;
- procedure TSyntheticImage32.DoRasterize;
- begin
- if FAutoRasterize then Rasterize;
- end;
- {$IFDEF FPC}
- procedure TSyntheticImage32.FormWindowProc(var Message: TLMessage);
- var
- CmdType: Integer;
- begin
- FDefaultProc(Message);
- case Message.Msg of
- 534: FResized := False;
- 562:
- begin
- if FResized then DoRasterize;
- FResized := True;
- end;
- 274:
- begin
- CmdType := Message.WParam and $FFF0;
- if (CmdType = SC_MAXIMIZE) or (CmdType = SC_RESTORE) then
- DoRasterize;
- end;
- end;
- end;
- {$ELSE}
- procedure TSyntheticImage32.FormWindowProc(var Message: TMessage);
- var
- CmdType: Integer;
- begin
- FDefaultProc(Message);
- case Message.Msg of
- WM_MOVING: FResized := False;
- WM_EXITSIZEMOVE:
- begin
- if FResized then DoRasterize;
- FResized := True;
- end;
- WM_SYSCOMMAND:
- begin
- CmdType := Message.WParam and $FFF0;
- if (CmdType = SC_MAXIMIZE) or (CmdType = SC_RESTORE) then
- DoRasterize;
- end;
- end;
- end;
- {$ENDIF}
- procedure TSyntheticImage32.Rasterize;
- var
- BackgroundColor: TColor;
- R: TRect;
- begin
- { Clear buffer before rasterization }
- if FClearBuffer then
- begin
- BackgroundColor := Color;
- {$ifdef FPC}
- if (BackgroundColor = clDefault) then
- BackgroundColor := GetDefaultColor(dctBrush);
- {$endif}
- Buffer.Clear(Color32(BackgroundColor));
- Invalidate;
- end;
- { Create rendering thread }
- StopRenderThread;
- FOldAreaChanged := Buffer.OnAreaChanged;
- if FRenderMode = rnmFull then
- R := Rect(0, 0, Buffer.Width, Buffer.Height)
- else
- R := FDstRect;
- FRenderThread := TRenderThread.Create(FRasterizer, Buffer, R, False);
- FResized := True;
- end;
- procedure TSyntheticImage32.RasterizerChanged(Sender: TObject);
- begin
- DoRasterize;
- end;
- procedure TSyntheticImage32.Resize;
- begin
- if not FResized then StopRenderThread;
- inherited;
- end;
- procedure TSyntheticImage32.SetDstRect(const Value: TRect);
- begin
- FDstRect := Value;
- end;
- procedure TSyntheticImage32.SetParent(AParent: TWinControl);
- var
- ParentForm: TCustomForm;
- begin
- ParentForm := GetParentForm(Self);
- if ParentForm = AParent then Exit;
- if ParentForm <> nil then
- if Assigned(FDefaultProc) then
- ParentForm.WindowProc := FDefaultProc;
- inherited;
- if AParent <> nil then
- begin
- ParentForm := GetParentForm(Self);
- if ParentForm <> nil then
- begin
- FDefaultProc := ParentForm.WindowProc;
- ParentForm.WindowProc := FormWindowProc;
- end;
- end;
- end;
- procedure TSyntheticImage32.SetRasterizer(const Value: TRasterizer);
- begin
- if Value <> FRasterizer then
- begin
- StopRenderThread;
- if Assigned(FRasterizer) then FRasterizer.Free;
- FRasterizer := Value;
- FRasterizer.OnChange := RasterizerChanged;
- DoRasterize;
- Changed;
- end;
- end;
- procedure TSyntheticImage32.SetRenderMode(const Value: TRenderMode);
- begin
- FRenderMode := Value;
- end;
- procedure TSyntheticImage32.StopRenderThread;
- begin
- if Assigned(FRenderThread) and (not FRenderThread.Terminated) then
- begin
- FRenderThread.Synchronize(FRenderThread.Terminate);
- FRenderThread.WaitFor;
- FreeAndNil(FRenderThread);
- end;
- end;
- { TRenderThread }
- constructor TRenderThread.Create(Rasterizer: TRasterizer; Dst: TBitmap32;
- DstRect: TRect; Suspended: Boolean);
- begin
- {$IFDEF USETHREADRESUME}
- inherited Create(True);
- {$ELSE}
- inherited Create(Suspended);
- {$ENDIF}
- FRasterizer := Rasterizer;
- FDest := Dst;
- FDstRect := DstRect;
- {$IFDEF USETHREADRESUME}
- if not Suspended then Resume;
- {$ENDIF}
- end;
- procedure TRenderThread.Execute;
- begin
- Rasterize;
- end;
- procedure TRenderThread.Rasterize;
- begin
- FRasterizer.Lock;
- { Save current AreaChanged handler }
- FOldAreaChanged := FDest.OnAreaChanged;
- FDest.OnAreaChanged := AreaChanged;
- try
- FRasterizer.Rasterize(FDest, FDstRect);
- except
- on EAbort do;
- end;
- { Reset old AreaChanged handler }
- FDest.OnAreaChanged := FOldAreaChanged;
- Synchronize(FRasterizer.Unlock);
- end;
- procedure TRenderThread.AreaChanged(Sender: TObject; const Area: TRect;
- const Hint: Cardinal);
- begin
- if Terminated then Abort else
- begin
- FArea := Area;
- Synchronize(SynchronizedAreaChanged);
- end;
- end;
- procedure TRenderThread.SynchronizedAreaChanged;
- begin
- if Assigned(FOldAreaChanged) then
- FOldAreaChanged(FDest, FArea, AREAINFO_RECT);
- end;
- end.
|