123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- {
- Free Pascal port of the Hermes C library.
- Copyright (C) 2001-2003 Nikolay Nikolov ([email protected])
- Original C version by Christian Nentwich ([email protected])
- 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;
|