fpc/packages/extra/hermes/clear.inc
daniel 4b074a0e5c + Add PTCpas package
git-svn-id: trunk@1944 -
2005-12-13 21:13:29 +00:00

224 lines
6.2 KiB
PHP

{
Free Pascal port of the Hermes C library.
Copyright (C) 2001-2003 Nikolay Nikolov (nickysn@users.sourceforge.net)
Original C version by Christian Nentwich (c.nentwich@cs.ucl.ac.uk)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
}
{Function Hermes_ClearerInstance : THermesHandle;
Procedure Hermes_ClearerReturn(handle : THermesHandle);
Function Hermes_ClearerRequest(handle : THermesHandle; format : PHermesFormat) : Boolean;
Function Hermes_ClearerClear(handle : THermesHandle; pixels : Pointer;
x1, y1, width, height, pitch : Integer;
r, g, b : int32; index : char8) : Boolean;}
Type
PClearerInstance = ^TClearerInstance;
TClearerInstance = Record
format : PHermesFormat;
func : THermesClearPtr;
End;
Const
{ClearerList is a list of TClearerInstance}
ClearerList : PHermesList = Nil;
CLEARrefcount : Integer = 0;
ClearCurrenthandle : THermesHandle = 0;
Function Hermes_ClearerInstance : THermesHandle;
Var
element : PHermesListElement;
newinstance : PClearerInstance;
Begin
If CLEARrefcount = 0 Then
Begin
ClearerList := Hermes_ListNew;
If ClearerList = Nil Then
Begin
Hermes_ClearerInstance := 0;
Exit;
End;
End;
element := Hermes_ListElementNew(ClearCurrenthandle + 1);
If element = Nil Then
Begin
Hermes_ClearerInstance := 0;
Exit;
End;
newinstance := malloc(SizeOf(TClearerInstance));
If newinstance = Nil Then
Begin
Hermes_ClearerInstance := 0;
Exit;
End;
newinstance^.func := Nil;
newinstance^.format := Hermes_FormatNewEmpty;
If newinstance^.format = Nil Then
Begin
Hermes_ClearerInstance := 0;
Exit;
End;
element^.data := newinstance;
Hermes_ListAdd(ClearerList, element);
Inc(CLEARrefcount);
Inc(ClearCurrenthandle);
Hermes_ClearerInstance := ClearCurrenthandle;
End;
Procedure Hermes_ClearerFreeHandleCallback(q : Pointer);
Begin
free(PClearerInstance(q)^.format);
End;
Procedure Hermes_ClearerReturn(handle : THermesHandle);
Var
element : PHermesListElement;
instance : PClearerInstance;
Begin
Dec(CLEARrefcount);
If Hermes_ListDeleteElement(ClearerList, handle, @Hermes_ClearerFreeHandleCallback) = False Then
Exit;
If CLEARrefcount = 0 Then
Begin
{ Dirty fix: Free the format pointers in all the clearer instances }
{ The list functions need updating to allow member deletion! }
element := ClearerList^.first;
While element <> Nil Do
Begin
instance := element^.data;
free(instance^.format);
element := element^.next;
End;
Hermes_ListDestroy(ClearerList);
End;
End;
Function Hermes_ClearerRequest(handle : THermesHandle; format : PHermesFormat) : Boolean;
Var
element : PHermesListElement;
clr : PClearerInstance;
i : Integer;
Begin
{ Look up this clearer in the list }
element := Hermes_ListLookup(ClearerList, handle);
If element = Nil Then
Begin
Hermes_ClearerRequest := False;
Exit;
End;
clr := element^.data;
{ If the clearer is the same, return 1 }
If Hermes_FormatEquals(clr^.format, format) Then
Begin
Hermes_ClearerRequest := True;
Exit;
End;
{ Otherwise look for a new clearer }
clr^.func := Nil;
For i := 0 To numClearers - 1 Do
Begin
If Clearers[i]^.bits = format^.bits Then
Begin
clr^.func := Clearers[i]^.func;
Hermes_FormatCopy(format, clr^.format);
Hermes_ClearerRequest := True;
Exit;
End;
End;
Hermes_ClearerRequest := False;
End;
Function Hermes_ClearerClear(handle : THermesHandle; pixels : Pointer;
x1, y1, width, height, pitch : Integer;
r, g, b : int32; index : char8) : Boolean;
Var
element : PHermesListElement;
info : THermesGenericInfo;
clr : PClearerInstance;
pixelval, d_r, d_g, d_b, d_a : int32;
iface : THermesClearInterface;
Begin
If (height <= 0) Or (width <= 0) Then
Begin
Hermes_ClearerClear := True;
Exit;
End;
{ Look up this clearer in the list }
element := Hermes_ListLookup(ClearerList, handle);
If (element = Nil) Or (element^.data = Nil) Then
Begin
Hermes_ClearerClear := False;
Exit;
End;
{ Get clearer instance from list element data }
clr := element^.data;
{ No conversion function assigned }
If clr^.func = Nil Then
Begin
Hermes_ClearerClear := False;
Exit;
End;
If clr^.format^.indexed Then
pixelval := index
Else
Begin
Hermes_Calculate_Generic_Info(24, 16, 8, 32,
Hermes_Topbit(clr^.format^.r),
Hermes_Topbit(clr^.format^.g),
Hermes_Topbit(clr^.format^.b),
Hermes_Topbit(clr^.format^.a), @info);
pixelval := (index Shl 24) Or (r Shl 16) Or (g Shl 8) Or b;
d_r := ((pixelval Shr info.r_right) Shl info.r_left) And clr^.format^.r;
d_g := ((pixelval Shr info.g_right) Shl info.g_left) And clr^.format^.g;
d_b := ((pixelval Shr info.b_right) Shl info.b_left) And clr^.format^.b;
d_a := ((pixelval Shr info.a_right) Shl info.a_left) And clr^.format^.a;
pixelval := d_r Or d_g Or d_b Or d_a;
End;
iface.dest := pixels;
Inc(iface.dest, y1*pitch + x1*(clr^.format^.bits Shr 3));
iface.width := width;
iface.height := height;
iface.add := pitch - width * (clr^.format^.bits Shr 3);
iface.value := pixelval;
{ Optimization }
If iface.add = 0 Then
Begin
iface.width := iface.width * iface.height;
iface.height := 1;
End;
clr^.func(@iface);
Hermes_ClearerClear := True;
End;