221 lines
5.5 KiB
ObjectPascal

unit ubgralape;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, BGRABitmap, BGRABitmapTypes, lptypes, lpcompiler;
function RegisterBitmap(ABitmap: TBGRABitmap): integer;
procedure UnregisterBitmap(AIndex: integer);
procedure EnsureInvalidate(AIndex: integer);
procedure SetTargetBitmap(AIndex: integer);
procedure AddScriptSystemTypes(Compiler: TLapeCompiler);
procedure AddScriptSystemFunctions(Compiler: TLapeCompiler);
procedure FreeBitmaps;
implementation
uses FileUtil, Graphics, GraphType, BGRAPolygon, BGRAFillInfo;
var
bitmaps: array of record
Bitmap: TBGRABitmap;
Registered: boolean;
Invalidated: boolean;
LockedCount: Int32or64;
end;
target: TBGRABitmap;
targetIndex: integer;
function NewBitmapEntry: integer;
var i: integer;
begin
for i:= 0 to high(bitmaps) do
if bitmaps[i].Bitmap = nil then
begin
result := i;
bitmaps[i].LockedCount:= 0;
exit;
end;
result := length(bitmaps);
setlength(bitmaps,length(bitmaps)*2+1);
bitmaps[result].LockedCount:= 0;
end;
procedure FreeBitmap(AIndex: integer);
begin
if (AIndex >= 0) and (AIndex < length(bitmaps)) then
if not bitmaps[AIndex].Registered then
begin
if bitmaps[AIndex].LockedCount > 0 then
raise exception.Create('Bitmap is locked');
FreeAndNil(bitmaps[AIndex].Bitmap);
bitmaps[AIndex].Invalidated:= false;
end;
end;
function RegisterBitmap(ABitmap: TBGRABitmap): integer;
begin
result := NewBitmapEntry;
bitmaps[result].Bitmap := ABitmap;
bitmaps[result].Invalidated := false;
bitmaps[result].Registered := true;
end;
procedure UnregisterBitmap(AIndex: integer);
begin
if (AIndex >= 0) and (AIndex < length(bitmaps)) then
begin
EnsureInvalidate(AIndex);
if not bitmaps[AIndex].Registered then
raise Exception.Create('This bitmap has not been registered');
if target = bitmaps[AIndex].Bitmap then
begin
target := nil;
targetIndex := -1;
end;
bitmaps[AIndex].Bitmap := nil;
bitmaps[AIndex].Registered := false;
end;
end;
procedure EnsureInvalidate(AIndex: integer);
begin
if (AIndex >= 0) and (AIndex < length(bitmaps)) then
begin
if bitmaps[AIndex].Invalidated then
begin
bitmaps[AIndex].Bitmap.InvalidateBitmap;
bitmaps[AIndex].Invalidated := false;
end;
end;
end;
procedure WillInvalidateBitmap(AIndex: integer);
begin
if (AIndex >= 0) and (AIndex < length(bitmaps)) then
Bitmaps[AIndex].Invalidated := true;
end;
procedure SetTargetBitmap(AIndex: integer);
begin
if (AIndex < 0) or (AIndex >= length(bitmaps)) or (bitmaps[AIndex].Bitmap = nil) then
raise exception.create('Bitmap does not exist');
target := bitmaps[AIndex].Bitmap;
targetIndex := AIndex;
end;
function GetBitmap(AIndex: integer): TBGRABitmap;
begin
if (AIndex < 0) or (AIndex >= length(bitmaps)) or (Bitmaps[AIndex].Bitmap = nil) then
raise exception.Create('Bitmap does not exist');
result := Bitmaps[AIndex].Bitmap;
end;
function GetScriptSystemInlineFunctions: string; forward;
///////////////////////////// Function implementation ///////////////////////////
{$I basic_functions.inc}
{$I basic_geometry_functions.inc}
{$I extended_geometry_functions.inc}
{$I text_functions.inc}
{$I color_functions.inc}
/////////////////////////// Function list /////////////////////////////////////////////
procedure AddScriptSystemFunctions(Compiler: TLapeCompiler);
begin
RegisterBasicFunctions(Compiler);
RegisterBasicGeometryFunctions(Compiler);
RegisterExtendedGeometryFunctions(Compiler);
RegisterTextFunctions(Compiler);
RegisterColorFunctions(Compiler);
Compiler.addDelayedCode(GetScriptSystemInlineFunctions, '',false,true);
end;
procedure FreeBitmaps;
var i: integer;
begin
for i := 0 to High(bitmaps) do
if (bitmaps[i].Bitmap <> nil) and not bitmaps[i].Registered then
begin
bitmaps[i].LockedCount := 0;
FreeBitmap(i);
end;
end;
////////////////////////////// Load script system //////////////////////////////
var
scriptSystemFunctions,scriptSystemTypes: TStringList;
function GetScriptSystemInlineFunctions: string;
var i: integer;
begin
result := LineEnding;
for i := 0 to scriptSystemFunctions.Count-1 do
result += scriptSystemFunctions[i]+LineEnding;
textAlignment:= taLeftJustify;
end;
procedure AddScriptSystemTypes(Compiler: TLapeCompiler);
var line: string;
i,idxEq: integer;
begin
for i := 0 to scriptSystemTypes.Count-1 do
begin
line := scriptSystemTypes[i];
idxEq := pos('=',line);
if idxEq <> 0 then
Compiler.addGlobalType(trim(copy(line,idxEq+1,length(line)-idxEq)),trim(copy(line,1,idxEq-1)));
end;
end;
procedure LoadScriptSystem;
var
scriptSystem: TStringList;
i: integer;
dest: TStringList;
begin
scriptSystemFunctions := TStringList.Create;
scriptSystemTypes := TStringList.Create;
dest := nil;
scriptSystem := TStringList.Create;
scriptSystem.LoadFromFile('bgralapesys.pas');
for i := 0 to scriptSystem.Count-1 do
begin
if CompareText(Trim(scriptSystem[i]),'implementation') = 0 then
dest := scriptSystemFunctions else
if CompareText(Trim(scriptSystem[i]),'type') = 0 then
dest := scriptSystemTypes else
if CompareText(Trim(scriptSystem[i]),'end.') = 0 then break
else
if Assigned(dest) then dest.Add(scriptSystem[i]);
end;
scriptSystem.Free;
end;
procedure FreeScriptSystem;
begin
scriptSystemTypes.Free;
scriptSystemFunctions.Free;
end;
initialization
LoadScriptSystem;
Randomize;
finalization
FreeScriptSystem;
end.