Added: support for custom drawing procedures
This commit is contained in:
parent
18b17e3487
commit
2ac4754fa6
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user