clear.inc 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. {
  2. Free Pascal port of the Hermes C library.
  3. Copyright (C) 2001-2003 Nikolay Nikolov ([email protected])
  4. Original C version by Christian Nentwich ([email protected])
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. This library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. }
  17. {Function Hermes_ClearerInstance : THermesHandle;
  18. Procedure Hermes_ClearerReturn(handle : THermesHandle);
  19. Function Hermes_ClearerRequest(handle : THermesHandle; format : PHermesFormat) : Boolean;
  20. Function Hermes_ClearerClear(handle : THermesHandle; pixels : Pointer;
  21. x1, y1, width, height, pitch : Integer;
  22. r, g, b : int32; index : char8) : Boolean;}
  23. Type
  24. PClearerInstance = ^TClearerInstance;
  25. TClearerInstance = Record
  26. format : PHermesFormat;
  27. func : THermesClearPtr;
  28. End;
  29. Const
  30. {ClearerList is a list of TClearerInstance}
  31. ClearerList : PHermesList = Nil;
  32. CLEARrefcount : Integer = 0;
  33. ClearCurrenthandle : THermesHandle = 0;
  34. Function Hermes_ClearerInstance : THermesHandle;
  35. Var
  36. element : PHermesListElement;
  37. newinstance : PClearerInstance;
  38. Begin
  39. If CLEARrefcount = 0 Then
  40. Begin
  41. ClearerList := Hermes_ListNew;
  42. If ClearerList = Nil Then
  43. Begin
  44. Hermes_ClearerInstance := 0;
  45. Exit;
  46. End;
  47. End;
  48. element := Hermes_ListElementNew(ClearCurrenthandle + 1);
  49. If element = Nil Then
  50. Begin
  51. Hermes_ClearerInstance := 0;
  52. Exit;
  53. End;
  54. newinstance := malloc(SizeOf(TClearerInstance));
  55. If newinstance = Nil Then
  56. Begin
  57. Hermes_ClearerInstance := 0;
  58. Exit;
  59. End;
  60. newinstance^.func := Nil;
  61. newinstance^.format := Hermes_FormatNewEmpty;
  62. If newinstance^.format = Nil Then
  63. Begin
  64. Hermes_ClearerInstance := 0;
  65. Exit;
  66. End;
  67. element^.data := newinstance;
  68. Hermes_ListAdd(ClearerList, element);
  69. Inc(CLEARrefcount);
  70. Inc(ClearCurrenthandle);
  71. Hermes_ClearerInstance := ClearCurrenthandle;
  72. End;
  73. Procedure Hermes_ClearerFreeHandleCallback(q : Pointer);
  74. Begin
  75. free(PClearerInstance(q)^.format);
  76. End;
  77. Procedure Hermes_ClearerReturn(handle : THermesHandle);
  78. Var
  79. element : PHermesListElement;
  80. instance : PClearerInstance;
  81. Begin
  82. Dec(CLEARrefcount);
  83. If Hermes_ListDeleteElement(ClearerList, handle, @Hermes_ClearerFreeHandleCallback) = False Then
  84. Exit;
  85. If CLEARrefcount = 0 Then
  86. Begin
  87. { Dirty fix: Free the format pointers in all the clearer instances }
  88. { The list functions need updating to allow member deletion! }
  89. element := ClearerList^.first;
  90. While element <> Nil Do
  91. Begin
  92. instance := element^.data;
  93. free(instance^.format);
  94. element := element^.next;
  95. End;
  96. Hermes_ListDestroy(ClearerList);
  97. End;
  98. End;
  99. Function Hermes_ClearerRequest(handle : THermesHandle; format : PHermesFormat) : Boolean;
  100. Var
  101. element : PHermesListElement;
  102. clr : PClearerInstance;
  103. i : Integer;
  104. Begin
  105. { Look up this clearer in the list }
  106. element := Hermes_ListLookup(ClearerList, handle);
  107. If element = Nil Then
  108. Begin
  109. Hermes_ClearerRequest := False;
  110. Exit;
  111. End;
  112. clr := element^.data;
  113. { If the clearer is the same, return 1 }
  114. If Hermes_FormatEquals(clr^.format, format) Then
  115. Begin
  116. Hermes_ClearerRequest := True;
  117. Exit;
  118. End;
  119. { Otherwise look for a new clearer }
  120. clr^.func := Nil;
  121. For i := 0 To numClearers - 1 Do
  122. Begin
  123. If Clearers[i]^.bits = format^.bits Then
  124. Begin
  125. clr^.func := Clearers[i]^.func;
  126. Hermes_FormatCopy(format, clr^.format);
  127. Hermes_ClearerRequest := True;
  128. Exit;
  129. End;
  130. End;
  131. Hermes_ClearerRequest := False;
  132. End;
  133. Function Hermes_ClearerClear(handle : THermesHandle; pixels : Pointer;
  134. x1, y1, width, height, pitch : Integer;
  135. r, g, b : int32; index : char8) : Boolean;
  136. Var
  137. element : PHermesListElement;
  138. info : THermesGenericInfo;
  139. clr : PClearerInstance;
  140. pixelval, d_r, d_g, d_b, d_a : int32;
  141. iface : THermesClearInterface;
  142. Begin
  143. If (height <= 0) Or (width <= 0) Then
  144. Begin
  145. Hermes_ClearerClear := True;
  146. Exit;
  147. End;
  148. { Look up this clearer in the list }
  149. element := Hermes_ListLookup(ClearerList, handle);
  150. If (element = Nil) Or (element^.data = Nil) Then
  151. Begin
  152. Hermes_ClearerClear := False;
  153. Exit;
  154. End;
  155. { Get clearer instance from list element data }
  156. clr := element^.data;
  157. { No conversion function assigned }
  158. If clr^.func = Nil Then
  159. Begin
  160. Hermes_ClearerClear := False;
  161. Exit;
  162. End;
  163. If clr^.format^.indexed Then
  164. pixelval := index
  165. Else
  166. Begin
  167. Hermes_Calculate_Generic_Info(24, 16, 8, 32,
  168. Hermes_Topbit(clr^.format^.r),
  169. Hermes_Topbit(clr^.format^.g),
  170. Hermes_Topbit(clr^.format^.b),
  171. Hermes_Topbit(clr^.format^.a), @info);
  172. pixelval := (index Shl 24) Or (r Shl 16) Or (g Shl 8) Or b;
  173. d_r := ((pixelval Shr info.r_right) Shl info.r_left) And clr^.format^.r;
  174. d_g := ((pixelval Shr info.g_right) Shl info.g_left) And clr^.format^.g;
  175. d_b := ((pixelval Shr info.b_right) Shl info.b_left) And clr^.format^.b;
  176. d_a := ((pixelval Shr info.a_right) Shl info.a_left) And clr^.format^.a;
  177. pixelval := d_r Or d_g Or d_b Or d_a;
  178. End;
  179. iface.dest := pixels;
  180. Inc(iface.dest, y1*pitch + x1*(clr^.format^.bits Shr 3));
  181. iface.width := width;
  182. iface.height := height;
  183. iface.add := pitch - width * (clr^.format^.bits Shr 3);
  184. iface.value := pixelval;
  185. { Optimization }
  186. If iface.add = 0 Then
  187. Begin
  188. iface.width := iface.width * iface.height;
  189. iface.height := 1;
  190. End;
  191. clr^.func(@iface);
  192. Hermes_ClearerClear := True;
  193. End;