1
0
mirror of synced 2024-11-24 02:43:51 +00:00

Added: support for custom drawing procedures

This commit is contained in:
Mark van Renswoude 2008-06-09 08:44:30 +00:00
parent 18b17e3487
commit 2ac4754fa6

View File

@ -24,6 +24,7 @@ uses
{$IFDEF VER150} {$IFDEF VER150}
{$WARN UNSAFE_CODE OFF} {$WARN UNSAFE_CODE OFF}
{$WARN UNSAFE_CAST OFF} {$WARN UNSAFE_CAST OFF}
{$WARN UNSAFE_TYPE OFF}
{$ENDIF} {$ENDIF}
@ -32,6 +33,13 @@ type
TX2GraphicList = class; TX2GraphicList = class;
TX2GraphicContainer = class; TX2GraphicContainer = class;
TX2GLCustomDrawImageProc = function(ACanvas: TCanvas;
AGraphicList: TX2GraphicList;
AIndex: Integer;
AX, AY: Integer;
AEnabled: Boolean): Boolean;
{ {
:$ Holds a single graphic. :$ Holds a single graphic.
} }
@ -190,6 +198,11 @@ type
property StretchMode: TX2GLStretchMode read FStretchMode write SetStretchMode default smCrop; property StretchMode: TX2GLStretchMode read FStretchMode write SetStretchMode default smCrop;
end; end;
procedure X2GLRegisterCustomDrawImageProc(ACustomDrawImageProc: TX2GLCustomDrawImageProc);
procedure X2GLUnregisterCustomDrawImageProc(ACustomDrawImageProc: TX2GLCustomDrawImageProc);
implementation implementation
uses uses
Forms, Forms,
@ -197,6 +210,10 @@ uses
SysUtils; SysUtils;
var
CustomDrawImageProcs: TList;
type type
PClass = ^TClass; PClass = ^TClass;
@ -223,6 +240,47 @@ type
procedure X2GLRegisterCustomDrawImageProc(ACustomDrawImageProc: TX2GLCustomDrawImageProc);
var
procPointer: Pointer absolute ACustomDrawImageProc;
begin
if CustomDrawImageProcs.IndexOf(procPointer) = -1 then
CustomDrawImageProcs.Add(procPointer);
end;
procedure X2GLUnregisterCustomDrawImageProc(ACustomDrawImageProc: TX2GLCustomDrawImageProc);
var
procPointer: Pointer absolute ACustomDrawImageProc;
begin
CustomDrawImageProcs.Remove(procPointer);
end;
function CustomDrawImage(ACanvas: TCanvas; AGraphicList: TX2GraphicList;
AIndex: Integer; AX, AY: Integer; AEnabled: Boolean): Boolean;
var
customProcIndex: Integer;
customProc: TX2GLCustomDrawImageProc;
begin
Result := False;
for customProcIndex := Pred(CustomDrawImageProcs.Count) downto 0 do
begin
customProc := TX2GLCustomDrawImageProc(CustomDrawImageProcs[customProcIndex]);
if customProc(ACanvas, AGraphicList, AIndex, AX, AY, AEnabled) then
begin
Result := True;
Break;
end;
end;
end;
{================ TX2GraphicContainerItem {================ TX2GraphicContainerItem
Initialization Initialization
========================================} ========================================}
@ -900,55 +958,59 @@ begin
(FContainer.Graphics[AIndex].Picture.Graphic.Empty) then (FContainer.Graphics[AIndex].Picture.Graphic.Empty) then
exit; exit;
if AEnabled then { First see if any custom draw handlers want to draw the image }
// Enabled, simply draw the graphic if not CustomDrawImage(ACanvas, Self, AIndex, AX, AY, AEnabled) then
InternalDrawGraphic(ACanvas, AX, AY)
else
begin begin
// Disabled, need to draw the image using 50% transparency. There's only if AEnabled then
// one problem; not all TGraphic's support that, and neither is there a { Enabled, simply draw the graphic }
// generic way of determining a pixel's transparency. So instead, we InternalDrawGraphic(ACanvas, AX, AY)
// blend the background with a copy of the background with the graphic else
// painted on it... begin
bmpBackground := TBitmap.Create(); { Disabled, need to draw the image using 50% transparency. There's only
bmpBlend := TBitmap.Create(); one problem; not all TGraphic's support that, and neither is there a
try generic way of determining a pixel's transparency. So instead, we
// Get background from canvas blend the background with a copy of the background with the graphic
with bmpBackground do painted on it... }
begin bmpBackground := TBitmap.Create();
Width := Self.Width; bmpBlend := TBitmap.Create();
Height := Self.Height; try
PixelFormat := pf24bit; { Get background from canvas }
Canvas.CopyRect(Rect(0, 0, Width, Height), ACanvas, with bmpBackground do
Rect(AX, AY, AX + Width, AY + Height)); begin
Width := Self.Width;
Height := Self.Height;
PixelFormat := pf24bit;
Canvas.CopyRect(Rect(0, 0, Width, Height), ACanvas,
Rect(AX, AY, AX + Width, AY + Height));
end;
bmpBlend.Assign(bmpBackground);
InternalDrawGraphic(bmpBlend.Canvas, 0, 0);
{ Blend graphic with background at 50% }
for iY := 0 to bmpBackground.Height - 1 do
begin
pBackground := bmpBackground.ScanLine[iY];
pBlend := bmpBlend.ScanLine[iY];
for iX := 0 to bmpBackground.Width - 1 do
with pBlend^[iX] do
begin
rgbtBlue := ((pBackground^[iX].rgbtBlue shl 7) +
(rgbtBlue shl 7)) shr 8;
rgbtGreen := ((pBackground^[iX].rgbtGreen shl 7) +
(rgbtGreen shl 7)) shr 8;
rgbtRed := ((pBackground^[iX].rgbtRed shl 7) +
(rgbtRed shl 7)) shr 8;
end;
end;
{ Copy blended graphic back }
ACanvas.Draw(AX, AY, bmpBlend);
finally
FreeAndNil(bmpBlend);
FreeAndNil(bmpBackground);
end; end;
bmpBlend.Assign(bmpBackground);
InternalDrawGraphic(bmpBlend.Canvas, 0, 0);
// Blend graphic with background at 50%
for iY := 0 to bmpBackground.Height - 1 do
begin
pBackground := bmpBackground.ScanLine[iY];
pBlend := bmpBlend.ScanLine[iY];
for iX := 0 to bmpBackground.Width - 1 do
with pBlend^[iX] do
begin
rgbtBlue := ((pBackground^[iX].rgbtBlue shl 7) +
(rgbtBlue shl 7)) shr 8;
rgbtGreen := ((pBackground^[iX].rgbtGreen shl 7) +
(rgbtGreen shl 7)) shr 8;
rgbtRed := ((pBackground^[iX].rgbtRed shl 7) +
(rgbtRed shl 7)) shr 8;
end;
end;
// Copy blended graphic back
ACanvas.Draw(AX, AY, bmpBlend);
finally
FreeAndNil(bmpBlend);
FreeAndNil(bmpBackground);
end; end;
end; end;
@ -1338,5 +1400,9 @@ end;
initialization initialization
RegisterClass(TX2GraphicContainerItem); RegisterClass(TX2GraphicContainerItem);
CustomDrawImageProcs := TList.Create;
finalization
FreeAndNil(CustomDrawImageProcs);
end. end.