~ubuntu-branches/ubuntu/saucy/lazarus/saucy

« back to all changes in this revision

Viewing changes to components/aggpas/src/agg_span_gouraud_rgba.pas

  • Committer: Package Import Robot
  • Author(s): Paul Gevers, Abou Al Montacir, Bart Martens, Paul Gevers
  • Date: 2013-06-08 14:12:17 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20130608141217-7k0cy9id8ifcnutc
Tags: 1.0.8+dfsg-1
[ Abou Al Montacir ]
* New upstream major release and multiple maintenace release offering many
  fixes and new features marking a new milestone for the Lazarus development
  and its stability level.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_fixes_branch
* LCL changes:
  - LCL is now a normal package.
      + Platform independent parts of the LCL are now in the package LCLBase
      + LCL is automatically recompiled when switching the target platform,
        unless pre-compiled binaries for this target are already installed.
      + No impact on existing projects.
      + Linker options needed by LCL are no more added to projects that do
        not use the LCL package.
  - Minor changes in LCL basic classes behaviour
      + TCustomForm.Create raises an exception if a form resource is not
        found.
      + TNotebook and TPage: a new implementation of these classes was added.
      + TDBNavigator: It is now possible to have focusable buttons by setting
        Options = [navFocusableButtons] and TabStop = True, useful for
        accessibility and for devices with neither mouse nor touch screen.
      + Names of TControlBorderSpacing.GetSideSpace and GetSpace were swapped
        and are now consistent. GetSideSpace = Around + GetSpace.
      + TForm.WindowState=wsFullscreen was added
      + TCanvas.TextFitInfo was added to calculate how many characters will
        fit into a specified Width. Useful for word-wrapping calculations.
      + TControl.GetColorResolvingParent and
        TControl.GetRGBColorResolvingParent were added, simplifying the work
        to obtain the final color of the control while resolving clDefault
        and the ParentColor.
      + LCLIntf.GetTextExtentExPoint now has a good default implementation
        which works in any platform not providing a specific implementation.
        However, Widgetset specific implementation is better, when available.
      + TTabControl was reorganized. Now it has the correct class hierarchy
        and inherits from TCustomTabControl as it should.
  - New unit in the LCL:
      + lazdialogs.pas: adds non-native versions of various native dialogs,
        for example TLazOpenDialog, TLazSaveDialog, TLazSelectDirectoryDialog.
        It is used by widgetsets which either do not have a native dialog, or
        do not wish to use it because it is limited. These dialogs can also be
        used by user applications directly.
      + lazdeviceapis.pas: offers an interface to more hardware devices such
        as the accelerometer, GPS, etc. See LazDeviceAPIs
      + lazcanvas.pas: provides a TFPImageCanvas descendent implementing
        drawing in a LCL-compatible way, but 100% in Pascal.
      + lazregions.pas. LazRegions is a wholly Pascal implementation of
        regions for canvas clipping, event clipping, finding in which control
        of a region tree one an event should reach, for drawing polygons, etc.
      + customdrawncontrols.pas, customdrawndrawers.pas,
        customdrawn_common.pas, customdrawn_android.pas and
        customdrawn_winxp.pas: are the Lazarus Custom Drawn Controls -controls
        which imitate the standard LCL ones, but with the difference that they
        are non-native and support skinning.
  - New APIs added to the LCL to improve support of accessibility software
    such as screen readers.
* IDE changes:
  - Many improvments.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/New_IDE_features_since#v1.0_.282012-08-29.29
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes#IDE_Changes
* Debugger / Editor changes:
  - Added pascal sources and breakpoints to the disassembler
  - Added threads dialog.
* Components changes:
  - TAChart: many fixes and new features
  - CodeTool: support Delphi style generics and new syntax extensions.
  - AggPas: removed to honor free licencing. (Closes: Bug#708695)
[Bart Martens]
* New debian/watch file fixing issues with upstream RC release.
[Abou Al Montacir]
* Avoid changing files in .pc hidden directory, these are used by quilt for
  internal purpose and could lead to surprises during build.
[Paul Gevers]
* Updated get-orig-source target and it compinion script orig-tar.sh so that they
  repack the source file, allowing bug 708695 to be fixed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
// Adaptation for high precision colors has been sponsored by 
24
 
// Liberty Technology Systems, Inc., visit http://lib-sys.com
25
 
//
26
 
// Liberty Technology Systems, Inc. is the provider of
27
 
// PostScript and PDF technology for software developers.
28
 
// 
29
 
// [Pascal Port History] -----------------------------------------------------
30
 
//
31
 
// 23.06.2006-Milano: ptrcomp adjustments
32
 
// 27.01.2006-Milano: Unit port establishment
33
 
//
34
 
{ agg_span_gouraud_rgba.pas }
35
 
unit
36
 
 agg_span_gouraud_rgba ;
37
 
 
38
 
INTERFACE
39
 
 
40
 
{$I agg_mode.inc }
41
 
 
42
 
uses
43
 
 agg_basics ,
44
 
 agg_color ,
45
 
 agg_dda_line ,
46
 
 agg_span_gouraud ,
47
 
 agg_span_allocator ,
48
 
 agg_math ;
49
 
 
50
 
{ TYPES DEFINITION }
51
 
const
52
 
 subpixel_shift = 4;
53
 
 subpixel_size  = 1 shl subpixel_shift;
54
 
 
55
 
type
56
 
 rgba_calc_ptr = ^rgba_calc;
57
 
 rgba_calc = object
58
 
   m_x1 ,m_y1 ,m_dx ,m_1dy : double;
59
 
 
60
 
   m_r1 ,m_g1 ,m_b1 ,m_a1 ,
61
 
   m_dr ,m_dg ,m_db ,m_da ,
62
 
   m_r  ,m_g  ,m_b  ,m_a  ,m_x : int;
63
 
 
64
 
   function  round(v : double ) : int;
65
 
   procedure init (c1 ,c2 : coord_type_ptr );
66
 
   procedure calc (y : double );
67
 
 
68
 
  end;
69
 
 
70
 
 span_gouraud_rgba_ptr = ^span_gouraud_rgba; 
71
 
 span_gouraud_rgba = object(span_gouraud )
72
 
   m_swap : boolean;
73
 
   m_y2   : int;
74
 
 
75
 
   m_rgba1 ,
76
 
   m_rgba2 ,
77
 
   m_rgba3 : rgba_calc;
78
 
 
79
 
   constructor Construct(alloc : span_allocator_ptr ); overload;
80
 
   constructor Construct(
81
 
                alloc : span_allocator_ptr;
82
 
                c1 ,c2 ,c3 : aggclr_ptr;
83
 
                x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,d : double ); overload;
84
 
 
85
 
   procedure prepare (max_span_len : unsigned ); virtual;
86
 
   function  generate(x ,y : int; len : unsigned ) : aggclr_ptr; virtual;
87
 
 
88
 
  // Agg 2.4 impl
89
 
   constructor Construct_(
90
 
                c1 ,c2 ,c3 : aggclr_ptr;
91
 
                x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double;
92
 
                d : double = 0 );
93
 
 
94
 
   procedure prepare_;
95
 
   procedure generate_(span : aggclr_ptr; x ,y : int; len : unsigned );
96
 
 
97
 
  end;
98
 
 
99
 
{ GLOBAL PROCEDURES }
100
 
 
101
 
 
102
 
IMPLEMENTATION
103
 
{ LOCAL VARIABLES & CONSTANTS }
104
 
{ UNIT IMPLEMENTATION }
105
 
{ ROUND }
106
 
function rgba_calc.round;
107
 
begin
108
 
 if v < 0.0 then
109
 
  result:=trunc(v - 0.5 )
110
 
 else
111
 
  result:=trunc(v + 0.5 );
112
 
 
113
 
end;
114
 
 
115
 
{ INIT }
116
 
procedure rgba_calc.init;
117
 
var
118
 
 dy : double;
119
 
 
120
 
begin
121
 
 m_x1:=c1.x - 0.5;
122
 
 m_y1:=c1.y - 0.5;
123
 
 m_dx:=c2.x - c1.x;
124
 
 
125
 
 dy:=c2.y - c1.y;
126
 
 
127
 
 if dy < 1e-5 then
128
 
  m_1dy:=1e5
129
 
 else
130
 
  m_1dy:=1.0 / dy;
131
 
 
132
 
 m_r1:=c1.color.r;
133
 
 m_g1:=c1.color.g;
134
 
 m_b1:=c1.color.b;
135
 
 m_a1:=c1.color.a;
136
 
 m_dr:=c2.color.r - m_r1;
137
 
 m_dg:=c2.color.g - m_g1;
138
 
 m_db:=c2.color.b - m_b1;
139
 
 m_da:=c2.color.a - m_a1;
140
 
 
141
 
end;
142
 
 
143
 
{ CALC }
144
 
procedure rgba_calc.calc;
145
 
var
146
 
 k : double;
147
 
 
148
 
begin
149
 
 k:=(y - m_y1 ) * m_1dy;
150
 
 
151
 
 if k < 0.0 then
152
 
  k:=0.0;
153
 
 
154
 
 if k > 1.0 then
155
 
  k:=1.0;
156
 
 
157
 
 m_r:=m_r1 + self.round(m_dr * k );
158
 
 m_g:=m_g1 + self.round(m_dg * k );
159
 
 m_b:=m_b1 + self.round(m_db * k );
160
 
 m_a:=m_a1 + self.round(m_da * k );
161
 
 m_x:=self.round((m_x1 + m_dx * k ) * subpixel_size );
162
 
 
163
 
end;
164
 
 
165
 
{ CONSTRUCT }
166
 
constructor span_gouraud_rgba.Construct(alloc : span_allocator_ptr );
167
 
begin
168
 
 inherited Construct(alloc );
169
 
 
170
 
end;
171
 
 
172
 
{ CONSTRUCT }
173
 
constructor span_gouraud_rgba.Construct(
174
 
                               alloc : span_allocator_ptr;
175
 
                               c1 ,c2 ,c3 : aggclr_ptr;
176
 
                               x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,d : double );
177
 
begin
178
 
 inherited Construct(alloc ,c1 ,c2 ,c3 ,x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,d );
179
 
 
180
 
end;
181
 
 
182
 
{ PREPARE }
183
 
procedure span_gouraud_rgba.prepare;
184
 
var
185
 
 coord : array[0..2 ] of coord_type;
186
 
 
187
 
begin
188
 
 inherited prepare(max_span_len );
189
 
 
190
 
 arrange_vertices(@coord );
191
 
 
192
 
 m_y2:=trunc(coord[1 ].y );
193
 
 
194
 
 m_swap:=
195
 
  calc_point_location(
196
 
   coord[0 ].x ,coord[0 ].y,
197
 
   coord[2 ].x ,coord[2 ].y,
198
 
   coord[1 ].x ,coord[1 ].y ) < 0.0;
199
 
 
200
 
 m_rgba1.init(@coord[0 ] ,@coord[2 ] );
201
 
 m_rgba2.init(@coord[0 ] ,@coord[1 ] );
202
 
 m_rgba3.init(@coord[1 ] ,@coord[2 ] );
203
 
 
204
 
end;
205
 
 
206
 
{ GENERATE }
207
 
function span_gouraud_rgba.generate;
208
 
const
209
 
 lim = agg_color.base_mask;
210
 
 
211
 
var
212
 
 pc1 ,pc2 ,t : rgba_calc_ptr;
213
 
 
214
 
 nlen ,start ,vr ,vg ,vb ,va : int;
215
 
 
216
 
 r ,g ,b ,a : dda_line_interpolator;
217
 
 
218
 
 span : aggclr_ptr;
219
 
 
220
 
begin
221
 
 m_rgba1.calc(y ); //(m_rgba1.m_1dy > 2) ? m_rgba1.m_y1 : y);
222
 
 
223
 
 pc1:=@m_rgba1;
224
 
 pc2:=@m_rgba2;
225
 
 
226
 
 if y <= m_y2 then
227
 
 // Bottom part of the triangle (first subtriangle)
228
 
  m_rgba2.calc(y + m_rgba2.m_1dy )
229
 
 else
230
 
  begin
231
 
  // Upper part (second subtriangle)
232
 
   m_rgba3.calc(y - m_rgba3.m_1dy );
233
 
 
234
 
   pc2:=@m_rgba3;
235
 
 
236
 
  end;
237
 
 
238
 
 if m_swap then
239
 
  begin
240
 
  // It means that the triangle is oriented clockwise,
241
 
  // so that we need to swap the controlling structures
242
 
   t  :=pc2;
243
 
   pc2:=pc1;
244
 
   pc1:=t;
245
 
 
246
 
  end;
247
 
 
248
 
// Get the horizontal length with subpixel accuracy
249
 
// and protect it from division by zero
250
 
 nlen:=Abs(pc2.m_x - pc1.m_x );
251
 
 
252
 
 if nlen <= 0 then
253
 
  nlen:=1;
254
 
 
255
 
 r.Construct(pc1.m_r ,pc2.m_r ,nlen ,14 );
256
 
 g.Construct(pc1.m_g ,pc2.m_g ,nlen ,14 );
257
 
 b.Construct(pc1.m_b ,pc2.m_b ,nlen ,14 );
258
 
 a.Construct(pc1.m_a ,pc2.m_a ,nlen ,14 );
259
 
 
260
 
// Calculate the starting point of the gradient with subpixel
261
 
// accuracy and correct (roll back) the interpolators.
262
 
// This operation will also clip the beginning of the span
263
 
// if necessary.
264
 
 start:=pc1.m_x - (x shl subpixel_shift );
265
 
 
266
 
 r.dec_operator(start );
267
 
 g.dec_operator(start );
268
 
 b.dec_operator(start );
269
 
 a.dec_operator(start );
270
 
 
271
 
 inc(nlen ,start );
272
 
 
273
 
 span:=_allocator.span;
274
 
 
275
 
// Beginning part of the span. Since we rolled back the
276
 
// interpolators, the color values may have overflow.
277
 
// So that, we render the beginning part with checking
278
 
// for overflow. It lasts until "start" is positive;
279
 
// typically it's 1-2 pixels, but may be more in some cases.
280
 
 while (len <> 0 ) and
281
 
       (start > 0 ) do
282
 
  begin
283
 
   vr:=r._y;
284
 
   vg:=g._y;
285
 
   vb:=b._y;
286
 
   va:=a._y;
287
 
 
288
 
   if vr < 0 then
289
 
    vr:=0;
290
 
 
291
 
   if vr > lim then
292
 
    vr:=lim;
293
 
 
294
 
   if vg < 0 then
295
 
    vg:=0;
296
 
 
297
 
   if vg > lim then
298
 
    vg:=lim;
299
 
 
300
 
   if vb < 0 then
301
 
    vb:=0;
302
 
 
303
 
   if vb > lim then
304
 
    vb:=lim;
305
 
 
306
 
   if va < 0 then
307
 
    va:=0;
308
 
 
309
 
   if va > lim then
310
 
    va:=lim;
311
 
 
312
 
   span.r:=int8u(vr );
313
 
   span.g:=int8u(vg );
314
 
   span.b:=int8u(vb );
315
 
   span.a:=int8u(va );
316
 
 
317
 
   r.inc_operator(subpixel_size );
318
 
   g.inc_operator(subpixel_size );
319
 
   b.inc_operator(subpixel_size );
320
 
   a.inc_operator(subpixel_size );
321
 
 
322
 
   dec(nlen ,subpixel_size );
323
 
   dec(start ,subpixel_size );
324
 
   inc(ptrcomp(span ) ,sizeof(aggclr ) );
325
 
   dec(len );
326
 
 
327
 
  end;
328
 
 
329
 
// Middle part, no checking for overflow.
330
 
// Actual spans can be longer than the calculated length
331
 
// because of anti-aliasing, thus, the interpolators can
332
 
// overflow. But while "nlen" is positive we are safe.
333
 
 while (len <> 0 ) and
334
 
       (nlen > 0 ) do
335
 
  begin
336
 
   span.r:=int8u(r._y );
337
 
   span.g:=int8u(g._y );
338
 
   span.b:=int8u(b._y );
339
 
   span.a:=int8u(a._y );
340
 
 
341
 
   r.inc_operator(subpixel_size );
342
 
   g.inc_operator(subpixel_size );
343
 
   b.inc_operator(subpixel_size );
344
 
   a.inc_operator(subpixel_size );
345
 
 
346
 
   dec(nlen ,subpixel_size );
347
 
   inc(ptrcomp(span ) ,sizeof(aggclr ) );
348
 
   dec(len );
349
 
 
350
 
  end;
351
 
 
352
 
// Ending part; checking for overflow.
353
 
// Typically it's 1-2 pixels, but may be more in some cases.
354
 
 while len <> 0 do
355
 
  begin
356
 
   vr:=r._y;
357
 
   vg:=g._y;
358
 
   vb:=b._y;
359
 
   va:=a._y;
360
 
 
361
 
   if vr < 0 then
362
 
    vr:=0;
363
 
 
364
 
   if vr > lim then
365
 
    vr:=lim;
366
 
 
367
 
   if vg < 0 then
368
 
    vg:=0;
369
 
 
370
 
   if vg > lim then
371
 
    vg:=lim;
372
 
 
373
 
   if vb < 0 then
374
 
    vb:=0;
375
 
 
376
 
   if vb > lim then
377
 
    vb:=lim;
378
 
 
379
 
   if va < 0 then
380
 
    va:=0;
381
 
 
382
 
   if va > lim then
383
 
    va:=lim;
384
 
 
385
 
   span.r:=int8u(vr );
386
 
   span.g:=int8u(vg );
387
 
   span.b:=int8u(vb );
388
 
   span.a:=int8u(va );
389
 
 
390
 
   r.inc_operator(subpixel_size );
391
 
   g.inc_operator(subpixel_size );
392
 
   b.inc_operator(subpixel_size );
393
 
   a.inc_operator(subpixel_size );
394
 
 
395
 
   inc(ptrcomp(span ) ,sizeof(aggclr ) );
396
 
   dec(len );
397
 
 
398
 
  end;
399
 
 
400
 
 result:=_allocator.span;
401
 
 
402
 
end;
403
 
 
404
 
{ CONSTRUCT_ }
405
 
constructor span_gouraud_rgba.Construct_(
406
 
             c1 ,c2 ,c3 : aggclr_ptr;
407
 
             x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double;
408
 
             d : double = 0 );
409
 
begin
410
 
 inherited Construct(NIL ,c1 ,c2 ,c3 ,x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,d );
411
 
 
412
 
end;
413
 
 
414
 
{ PREPARE_ }
415
 
procedure span_gouraud_rgba.prepare_;
416
 
var
417
 
 coord : array[0..2 ] of coord_type;
418
 
 
419
 
begin
420
 
 arrange_vertices(@coord );
421
 
 
422
 
 m_y2:=int(Trunc(coord[1 ].y ) );
423
 
 
424
 
 m_swap:=
425
 
  cross_product(
426
 
   coord[0 ].x ,coord[0 ].y,
427
 
   coord[2 ].x ,coord[2 ].y,
428
 
   coord[1 ].x ,coord[1 ].y ) < 0.0;
429
 
 
430
 
 m_rgba1.init(@coord[0 ] ,@coord[2 ] );
431
 
 m_rgba2.init(@coord[0 ] ,@coord[1 ] );
432
 
 m_rgba3.init(@coord[1 ] ,@coord[2 ] );
433
 
 
434
 
end;
435
 
 
436
 
{ GENERATE_ }
437
 
procedure span_gouraud_rgba.generate_(span : aggclr_ptr; x ,y : int; len : unsigned );
438
 
const
439
 
 lim = agg_color.base_mask;
440
 
 
441
 
var
442
 
 pc1 ,pc2 ,t : rgba_calc_ptr;
443
 
 
444
 
 nlen ,start ,vr ,vg ,vb ,va : int;
445
 
 
446
 
 r ,g ,b ,a : dda_line_interpolator;
447
 
 
448
 
begin
449
 
 m_rgba1.calc(y ); //(m_rgba1.m_1dy > 2) ? m_rgba1.m_y1 : y);
450
 
 
451
 
 pc1:=@m_rgba1;
452
 
 pc2:=@m_rgba2;
453
 
 
454
 
 if y <= m_y2 then
455
 
 // Bottom part of the triangle (first subtriangle)
456
 
  m_rgba2.calc(y + m_rgba2.m_1dy )
457
 
 else
458
 
  begin
459
 
  // Upper part (second subtriangle)
460
 
   m_rgba3.calc(y - m_rgba3.m_1dy );
461
 
 
462
 
   pc2:=@m_rgba3;
463
 
 
464
 
  end;
465
 
 
466
 
 if m_swap then
467
 
  begin
468
 
  // It means that the triangle is oriented clockwise,
469
 
  // so that we need to swap the controlling structures
470
 
   t  :=pc2;
471
 
   pc2:=pc1;
472
 
   pc1:=t;
473
 
 
474
 
  end;
475
 
 
476
 
// Get the horizontal length with subpixel accuracy
477
 
// and protect it from division by zero
478
 
 nlen:=Abs(pc2.m_x - pc1.m_x );
479
 
 
480
 
 if nlen <= 0 then
481
 
  nlen:=1;
482
 
 
483
 
 r.Construct(pc1.m_r ,pc2.m_r ,nlen ,14 );
484
 
 g.Construct(pc1.m_g ,pc2.m_g ,nlen ,14 );
485
 
 b.Construct(pc1.m_b ,pc2.m_b ,nlen ,14 );
486
 
 a.Construct(pc1.m_a ,pc2.m_a ,nlen ,14 );
487
 
 
488
 
// Calculate the starting point of the gradient with subpixel
489
 
// accuracy and correct (roll back) the interpolators.
490
 
// This operation will also clip the beginning of the span
491
 
// if necessary.
492
 
 start:=pc1.m_x - (x shl subpixel_shift );
493
 
 
494
 
 r.dec_operator(start );
495
 
 g.dec_operator(start );
496
 
 b.dec_operator(start );
497
 
 a.dec_operator(start );
498
 
 
499
 
 inc(nlen ,start );
500
 
 
501
 
// Beginning part of the span. Since we rolled back the
502
 
// interpolators, the color values may have overflow.
503
 
// So that, we render the beginning part with checking
504
 
// for overflow. It lasts until "start" is positive;
505
 
// typically it's 1-2 pixels, but may be more in some cases.
506
 
 while (len <> 0 ) and
507
 
       (start > 0 ) do
508
 
  begin
509
 
   vr:=r._y;
510
 
   vg:=g._y;
511
 
   vb:=b._y;
512
 
   va:=a._y;
513
 
 
514
 
   if vr < 0 then
515
 
    vr:=0;
516
 
 
517
 
   if vr > lim then
518
 
    vr:=lim;
519
 
 
520
 
   if vg < 0 then
521
 
    vg:=0;
522
 
 
523
 
   if vg > lim then
524
 
    vg:=lim;
525
 
 
526
 
   if vb < 0 then
527
 
    vb:=0;
528
 
 
529
 
   if vb > lim then
530
 
    vb:=lim;
531
 
 
532
 
   if va < 0 then
533
 
    va:=0;
534
 
 
535
 
   if va > lim then
536
 
    va:=lim;
537
 
 
538
 
   span.r:=int8u(vr );
539
 
   span.g:=int8u(vg );
540
 
   span.b:=int8u(vb );
541
 
   span.a:=int8u(va );
542
 
 
543
 
   r.inc_operator(subpixel_size );
544
 
   g.inc_operator(subpixel_size );
545
 
   b.inc_operator(subpixel_size );
546
 
   a.inc_operator(subpixel_size );
547
 
 
548
 
   dec(nlen ,subpixel_size );
549
 
   dec(start ,subpixel_size );
550
 
   inc(ptrcomp(span ) ,sizeof(aggclr ) );
551
 
   dec(len );
552
 
 
553
 
  end;
554
 
 
555
 
// Middle part, no checking for overflow.
556
 
// Actual spans can be longer than the calculated length
557
 
// because of anti-aliasing, thus, the interpolators can
558
 
// overflow. But while "nlen" is positive we are safe.
559
 
 while (len <> 0 ) and
560
 
       (nlen > 0 ) do
561
 
  begin
562
 
   span.r:=int8u(r._y );
563
 
   span.g:=int8u(g._y );
564
 
   span.b:=int8u(b._y );
565
 
   span.a:=int8u(a._y );
566
 
 
567
 
   r.inc_operator(subpixel_size );
568
 
   g.inc_operator(subpixel_size );
569
 
   b.inc_operator(subpixel_size );
570
 
   a.inc_operator(subpixel_size );
571
 
 
572
 
   dec(nlen ,subpixel_size );
573
 
   inc(ptrcomp(span ) ,sizeof(aggclr ) );
574
 
   dec(len );
575
 
 
576
 
  end;
577
 
 
578
 
// Ending part; checking for overflow.
579
 
// Typically it's 1-2 pixels, but may be more in some cases.
580
 
 while len <> 0 do
581
 
  begin
582
 
   vr:=r._y;
583
 
   vg:=g._y;
584
 
   vb:=b._y;
585
 
   va:=a._y;
586
 
 
587
 
   if vr < 0 then
588
 
    vr:=0;
589
 
 
590
 
   if vr > lim then
591
 
    vr:=lim;
592
 
 
593
 
   if vg < 0 then
594
 
    vg:=0;
595
 
 
596
 
   if vg > lim then
597
 
    vg:=lim;
598
 
 
599
 
   if vb < 0 then
600
 
    vb:=0;
601
 
 
602
 
   if vb > lim then
603
 
    vb:=lim;
604
 
 
605
 
   if va < 0 then
606
 
    va:=0;
607
 
 
608
 
   if va > lim then
609
 
    va:=lim;
610
 
 
611
 
   span.r:=int8u(vr );
612
 
   span.g:=int8u(vg );
613
 
   span.b:=int8u(vb );
614
 
   span.a:=int8u(va );
615
 
 
616
 
   r.inc_operator(subpixel_size );
617
 
   g.inc_operator(subpixel_size );
618
 
   b.inc_operator(subpixel_size );
619
 
   a.inc_operator(subpixel_size );
620
 
 
621
 
   inc(ptrcomp(span ) ,sizeof(aggclr ) );
622
 
   dec(len );
623
 
 
624
 
  end;
625
 
 
626
 
end;
627
 
 
628
 
END.
629