mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2026-01-13 13:11:28 +01:00
224 lines
6.2 KiB
PHP
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;
|