1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4 (Public License)
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
6 // Pascal Port By: Milan Marusinec alias Milano
7 //                 milan@marusinec.sk
8 //                 http://www.aggpas.org
9 // Copyright (c) 2005-2006
10 //
11 // Permission to copy, use, modify, sell and distribute this software
12 // is granted provided this copyright notice appears in all copies.
13 // This software is provided "as is" without express or implied
14 // warranty, and with no claim as to its suitability for any purpose.
15 //
16 //----------------------------------------------------------------------------
17 // Contact: mcseem@antigrain.com
18 //          mcseemagg@yahoo.com
19 //          http://www.antigrain.com
20 //
21 //----------------------------------------------------------------------------
22 //
23 // Class scanline_p - a general purpose scanline container with packed spans.
24 //
25 //----------------------------------------------------------------------------
26 //
27 // Adaptation for 32-bit screen coordinates (scanline32_p) has been sponsored by
28 // Liberty Technology Systems, Inc., visit http://lib-sys.com
29 //
30 // Liberty Technology Systems, Inc. is the provider of
31 // PostScript and PDF technology for software developers.
32 //
33 // [Pascal Port History] -----------------------------------------------------
34 //
35 // 23.06.2006-Milano: ptrcomp adjustments
36 // 23.11.2005-Milano: ...
37 // 18.11.2005-Milano: Unit port establishment
38 //
39 { agg_scanline_p.pas }
40 unit
41  agg_scanline_p ;
42 
43 INTERFACE
44 
45 {$I agg_mode.inc }
46 
47 uses
48  agg_basics ,
49  agg_scanline ;
50 
51 { TYPES DEFINITION }
52 type
53  span_p8_ptr = ^span_p8;
54  span_p8 = record
55    x   ,
56    len : int16; // If negative, it's a solid span, covers is valid
57 
58    covers : int8u_ptr;
59 
60   end;
61 
62  scanline_p8_ptr = ^scanline_p8;
63  scanline_p8 = object(scanline )
64    m_max_len : unsigned;
65    m_last_x  ,
66    m_y       : int;
67 
68    m_covers    ,
69    m_cover_ptr : int8u_ptr;
70 
71    m_spans    ,
72    m_cur_span : span_p8_ptr;
73 
74    constructor Construct;
75    destructor  Destruct;
76 
77    procedure reset(min_x ,max_x : int ); virtual;
78    procedure reset_spans; virtual;
79 
80    procedure finalize (y_ : int ); virtual;
81    procedure add_cell (x : int; cover : unsigned ); virtual;
82    procedure add_cells(x : int; len : unsigned; covers : int8u_ptr ); virtual;
83    procedure add_span (x : int; len ,cover : unsigned ); virtual;
84 
85    function  y : int; virtual;
86    function  num_spans : unsigned; virtual;
87    function  begin_ : pointer; virtual;
88 
89    function  sz_of_span : unsigned; virtual;
90 
91   end;
92 
93 { GLOBAL PROCEDURES }
94 
95 
96 IMPLEMENTATION
97 { LOCAL VARIABLES & CONSTANTS }
98 { UNIT IMPLEMENTATION }
99 { CONSTRUCT }
100 constructor scanline_p8.Construct;
101 begin
102  m_max_len:=0;
103  m_last_x :=$7FFFFFF0;
104 
105  m_y:=0;
106 
107  m_covers   :=NIL;
108  m_cover_ptr:=NIL;
109 
110  m_spans   :=NIL;
111  m_cur_span:=NIL;
112 
113 end;
114 
115 { DESTRUCT }
116 destructor scanline_p8.Destruct;
117 begin
118  agg_freemem(pointer(m_spans ) ,m_max_len * sizeof(span_p8 ) );
119  agg_freemem(pointer(m_covers ) ,m_max_len * sizeof(int8u ) );
120 
121 end;
122 
123 { RESET }
124 procedure scanline_p8.reset;
125 var
126  max_len : unsigned;
127 
128 begin
129  max_len:=max_x - min_x + 3;
130 
131  if max_len > m_max_len then
132   begin
133    agg_freemem(pointer(m_covers ) ,m_max_len * sizeof(int8u ) );
134    agg_freemem(pointer(m_spans ) ,m_max_len * sizeof(span_p8 ) );
135 
136    agg_getmem(pointer(m_covers ) ,max_len * sizeof(int8u ) );
137    agg_getmem(pointer(m_spans ) ,max_len * sizeof(span_p8 ) );
138 
139    m_max_len:=max_len;
140 
141   end;
142 
143  m_last_x:=$7FFFFFF0;
144 
145  m_cover_ptr:=m_covers;
146  m_cur_span :=m_spans;
147 
148  m_cur_span.len:=0;
149 
150 end;
151 
152 { RESET_SPANS }
153 procedure scanline_p8.reset_spans;
154 begin
155  m_last_x:=$7FFFFFF0;
156 
157  m_cover_ptr:=m_covers;
158  m_cur_span :=m_spans;
159 
160  m_cur_span.len:=0;
161 
162 end;
163 
164 { FINALIZE }
165 procedure scanline_p8.finalize;
166 begin
167  m_y:=y_;
168 
169 end;
170 
171 { ADD_CELL }
172 procedure scanline_p8.add_cell;
173 begin
174  m_cover_ptr^:=int8u(cover );
175 
176  if (x = m_last_x + 1 ) and
177     (m_cur_span.len > 0 ) then
178   inc(m_cur_span.len )
179 
180  else
181   begin
182    inc(ptrcomp(m_cur_span ) ,sizeof(span_p8 ) );
183 
184    m_cur_span.covers:=m_cover_ptr;
185 
186    m_cur_span.x  :=int16(x );
187    m_cur_span.len:=1;
188 
189   end;
190 
191  m_last_x:=x;
192 
193  inc(ptrcomp(m_cover_ptr ) ,sizeof(int8u ) );
194 
195 end;
196 
197 { ADD_CELLS }
198 procedure scanline_p8.add_cells;
199 begin
200  move(covers^ ,m_cover_ptr^ ,len * sizeof(int8u ) );
201 
202  if (x = m_last_x + 1 ) and
203     (m_cur_span.len > 0 ) then
204   inc(m_cur_span.len ,int16(len ) )
205 
206  else
207   begin
208    inc(ptrcomp(m_cur_span ) ,sizeof(span_p8 ) );
209 
210    m_cur_span.covers:=m_cover_ptr;
211    m_cur_span.x     :=int16(x );
212    m_cur_span.len   :=int16(len );
213 
214   end;
215 
216  inc(ptrcomp(m_cover_ptr ) ,len * sizeof(int8u ) );
217 
218  m_last_x:=x + len - 1;
219 
220 end;
221 
222 { ADD_SPAN }
223 procedure scanline_p8.add_span;
224 begin
225  if (x = m_last_x + 1 ) and
226     (m_cur_span.len < 0 ) and
227     (cover = m_cur_span.covers^ ) then
228   dec(m_cur_span.len ,int16(len ) )
229 
230  else
231   begin
232    m_cover_ptr^:=int8u(cover );
233 
234    inc(ptrcomp(m_cur_span ) ,sizeof(span_p8 ) );
235 
236    m_cur_span.covers:=m_cover_ptr;
237    m_cur_span.x     :=int16(x );
238    m_cur_span.len   :=int16(len );
239    m_cur_span.len   :=-m_cur_span.len;
240 
241    inc(ptrcomp(m_cover_ptr ) ,sizeof(int8u ) );
242 
243   end;
244 
245  m_last_x:=x + len - 1;
246 
247 end;
248 
249 { Y }
250 function scanline_p8.y;
251 begin
252  result:=m_y;
253 
254 end;
255 
256 { NUM_SPANS }
257 function scanline_p8.num_spans;
258 begin
259  result:=(ptrcomp(m_cur_span ) - ptrcomp(m_spans ) ) div sizeof(span_p8 );
260 
261 end;
262 
263 { BEGIN_ }
264 function scanline_p8.begin_;
265 begin
266  result:=span_p8_ptr(ptrcomp(m_spans ) + sizeof(span_p8 ) );
267 
268 end;
269 
270 { SZ_OF_SPAN }
271 function scanline_p8.sz_of_span;
272 begin
273  result:=sizeof(span_p8 );
274 
275 end;
276 
277 END.
278 
279