2
* \file livarot/int-line.cpp
4
* Implementation of coverage with integer boundaries.
12
#include <glib/gmem.h>
18
#include "livarot/int-line.h"
19
#include "livarot/float-line.h"
20
#include "livarot/BitLigne.h"
30
firstAc = lastAc = -1;
48
void IntLigne::Reset()
52
firstAc = lastAc = -1;
55
int IntLigne::AddBord(int spos, float sval, int epos, float eval)
57
if ( nbBord + 1 >= maxBord ) {
58
maxBord = 2 * nbBord + 2;
59
bords = (int_ligne_bord *) g_realloc(bords, maxBord * sizeof(int_ligne_bord));
66
bords[n].start = true;
68
bords[n].prev = bords[n].next = -1;
73
bords[n].start = false;
75
bords[n].prev = bords[n].next = -1;
81
float IntLigne::RemainingValAt(int at)
86
int nn = bords[no].other;
87
sum += ValAt(at, bords[nn].pos, bords[no].pos, bords[nn].val, bords[no].val);
93
void IntLigne::Flatten()
101
firstAc = lastAc = -1;
103
for (int i = 0; i < nbBord; i++) {
107
qsort(bords, nbBord, sizeof(int_ligne_bord), IntLigne::CmpBord);
108
for (int i = 0; i < nbBord; i++) {
109
bords[bords[i].prev].next = i;
112
for (int i = 0; i < nbBord; i++) {
113
bords[i].other = bords[bords[i].other].next;
118
bool startExists = false;
120
for (int i = 0; i < nbBord; ) {
121
int cur = bords[i].pos;
125
while ( i < nbBord && bords[i].pos == cur && bords[i].start == false ) {
127
leftV += bords[i].val;
130
midV = RemainingValAt(cur);
131
while ( i < nbBord && bords[i].pos == cur && bords[i].start == true ) {
132
rightV += bords[i].val;
133
Enqueue(bords[i].other);
138
AddRun(lastStart, cur, lastVal, leftV + midV);
140
if ( firstAc >= 0 ) {
142
lastVal = midV + rightV;
151
void IntLigne::Affiche()
153
printf("%i : \n", nbRun);
154
for (int i = 0; i < nbRun;i++) {
155
printf("(%i %f -> %i %f) ", runs[i].st, runs[i].vst, runs[i].en, runs[i].ven); // localization ok
160
int IntLigne::AddRun(int st, int en, float vst, float ven)
166
if ( nbRun >= maxRun ) {
167
maxRun = 2 * nbRun + 1;
168
runs = (int_ligne_run *) g_realloc(runs, maxRun * sizeof(int_ligne_run));
179
void IntLigne::Booleen(IntLigne *a, IntLigne *b, BooleanOp mod)
182
if ( a->nbRun <= 0 && b->nbRun <= 0 ) {
186
if ( a->nbRun <= 0 ) {
187
if ( mod == bool_op_union || mod == bool_op_symdiff ) {
193
if ( b->nbRun <= 0 ) {
194
if ( mod == bool_op_union || mod == bool_op_diff || mod == bool_op_symdiff ) {
202
int curPos = (a->runs[0].st < b->runs[0].st) ? a->runs[0].st : b->runs[0].st;
203
int nextPos = curPos;
206
if ( curPos == a->runs[0].st ) {
207
valA = a->runs[0].vst;
209
if ( curPos == b->runs[0].st ) {
210
valB = b->runs[0].vst;
213
while ( curA < a->nbRun && curB < b->nbRun ) {
214
int_ligne_run runA = a->runs[curA];
215
int_ligne_run runB = b->runs[curB];
216
const bool inA = ( curPos >= runA.st && curPos < runA.en );
217
const bool inB = ( curPos >= runB.st && curPos < runB.en );
224
if ( curPos < runA.st ) {
225
if ( curPos < runB.st ) {
226
startA = runA.st <= runB.st;
227
startB = runA.st >= runB.st;
228
nextPos = startA ? runA.st : runB.st;
229
} else if ( curPos >= runB.st ) {
230
startA = runA.st <= runB.en;
231
endB = runA.st >= runB.en;
232
nextPos = startA ? runA.st : runB.en;
234
} else if ( curPos == runA.st ) {
235
if ( curPos < runB.st ) {
236
endA = runA.en <= runB.st;
237
startB = runA.en >= runB.st;
238
nextPos = startB ? runB.en : runA.st;
239
} else if ( curPos == runB.st ) {
240
endA = runA.en <= runB.en;
241
endB = runA.en >= runB.en;
242
nextPos = endA? runA.en : runB.en;
244
endA = runA.en <= runB.en;
245
endB = runA.en >= runB.en;
246
nextPos = endA ? runA.en : runB.en;
249
if ( curPos < runB.st ) {
250
endA = runA.en <= runB.st;
251
startB = runA.en >= runB.st;
252
nextPos = startB ? runB.st : runA.en;
253
} else if ( curPos == runB.st ) {
254
endA = runA.en <= runB.en;
255
endB = runA.en >= runB.en;
256
nextPos = endA ? runA.en : runB.en;
258
endA = runA.en <= runB.en;
259
endB = runA.en >= runB.en;
260
nextPos = endA ? runA.en : runB.en;
266
valA = inA ? ValAt(nextPos, runA.st, runA.en, runA.vst, runA.ven) : 0;
267
valB = inB ? ValAt(nextPos, runB.st, runB.en, runB.vst, runB.ven) : 0;
269
if ( mod == bool_op_union ) {
272
AddRun(curPos, nextPos, oValA + oValB, valA + valB);
275
} else if ( mod == bool_op_inters ) {
278
AddRun(curPos, nextPos, oValA * oValB, valA * valB);
281
} else if ( mod == bool_op_diff ) {
284
AddRun(curPos, nextPos, oValA - oValB, valA - valB);
287
} else if ( mod == bool_op_symdiff ) {
288
if ( inA && !(inB) ) {
289
AddRun(curPos, nextPos, oValA - oValB, valA - valB);
291
if ( !(inA) && inB ) {
292
AddRun(curPos, nextPos, oValB - oValA, valB - valA);
298
// inA=true; these are never used
309
if ( curA < a->nbRun && a->runs[curA].st == curPos ) {
310
valA = a->runs[curA].vst;
317
if ( curB < b->nbRun && b->runs[curB].st == curPos ) {
318
valB = b->runs[curB].vst;
323
while ( curA < a->nbRun ) {
324
int_ligne_run runA = a->runs[curA];
325
const bool inA = ( curPos >= runA.st && curPos < runA.en );
326
const bool inB = false;
330
if ( curPos < runA.st ) {
333
} else if ( curPos >= runA.st ) {
340
valA = inA ? ValAt(nextPos,runA.st, runA.en, runA.vst, runA.ven) : 0;
343
if ( mod == bool_op_union ) {
345
AddRun(curPos, nextPos, oValA + oValB, valA + valB);
347
} else if ( mod == bool_op_inters ) {
349
AddRun(curPos, nextPos, oValA * oValB, valA * valB);
351
} else if ( mod == bool_op_diff ) {
353
AddRun(curPos, nextPos, oValA - oValB, valA - valB);
355
} else if ( mod == bool_op_symdiff ) {
356
if ( inA && !(inB) ) {
357
AddRun(curPos, nextPos, oValA - oValB, valA - valB);
359
if ( !(inA) && inB ) {
360
AddRun(curPos,nextPos,oValB-oValA,valB-valA);
373
if ( curA < a->nbRun && a->runs[curA].st == curPos ) {
374
valA = a->runs[curA].vst;
379
while ( curB < b->nbRun ) {
380
int_ligne_run runB = b->runs[curB];
381
const bool inB = ( curPos >= runB.st && curPos < runB.en );
382
const bool inA = false;
386
if ( curPos < runB.st ) {
389
} else if ( curPos >= runB.st ) {
396
valB = inB ? ValAt(nextPos, runB.st, runB.en, runB.vst, runB.ven) : 0;
399
if ( mod == bool_op_union ) {
401
AddRun(curPos, nextPos, oValA + oValB,valA + valB);
403
} else if ( mod == bool_op_inters ) {
405
AddRun(curPos, nextPos, oValA * oValB, valA * valB);
407
} else if ( mod == bool_op_diff ) {
409
AddRun(curPos, nextPos, oValA - oValB, valA - valB);
411
} else if ( mod == bool_op_symdiff ) {
412
if ( inA && !(inB) ) {
413
AddRun(curPos, nextPos, oValA - oValB,valA - valB);
415
if ( !(inA) && inB ) {
416
AddRun(curPos, nextPos, oValB - oValA, valB - valA);
429
if ( curB < b->nbRun && b->runs[curB].st == curPos ) {
430
valB = b->runs[curB].vst;
437
* Transform a line of bits into pixel coverage values.
439
* This is where you go from supersampled data to alpha values.
440
* \see IntLigne::Copy(int nbSub,BitLigne* *a).
442
void IntLigne::Copy(BitLigne* a)
444
if ( a->curMax <= a->curMin ) {
449
if ( a->curMin < a->st ) {
453
if ( a->curMax < a->st ) {
458
if ( a->curMin > a->en ) {
463
if ( a->curMax > a->en ) {
472
bool startExists = false;
474
int masks[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
476
uint32_t c_full = a->fullB[(a->curMin-a->st) >> 3];
477
uint32_t c_part = a->partB[(a->curMin-a->st) >> 3];
478
c_full <<= 4 * ((a->curMin - a->st) & 0x00000007);
479
c_part <<= 4 * ((a->curMin - a->st) & 0x00000007);
480
for (int i = a->curMin; i <= a->curMax; i++) {
481
int nbBit = masks[c_full >> 28] + masks[c_part >> 28];
485
if ( lastVal == nbBit ) {
486
// on continue le run
488
AddRun(lastStart, i, ((float) lastVal) / 4, ((float) lastVal) / 4);
499
AddRun(lastStart, i, ((float) lastVal) / 4, ((float) lastVal) / 4);
503
int chg = (i + 1 - a->st) & 0x00000007;
505
c_full = a->fullB[(i + 1 - a->st) >> 3];
506
c_part = a->partB[(i + 1 - a->st) >> 3];
513
AddRun(lastStart, a->curMax + 1, ((float) lastVal) / 4, ((float) lastVal) / 4);
518
* Transform a line of bits into pixel coverage values.
520
* Alpha values are computed from supersampled data, so we have to scan the
521
* BitLigne left to right, summing the bits in each pixel. The alpha value
522
* is then "number of bits"/(nbSub*nbSub)". Full bits and partial bits are
523
* treated as equals because the method produces ugly results otherwise.
525
* \param nbSub Number of BitLigne in the array "a".
527
void IntLigne::Copy(int nbSub, BitLigne **as)
539
// compute the min-max of the pixels to be rasterized from the min-max of the inpur bitlignes
540
int curMin = as[0]->curMin;
541
int curMax = as[0]->curMax;
542
for (int i = 1; i < nbSub; i++) {
543
if ( as[i]->curMin < curMin ) {
544
curMin = as[i]->curMin;
546
if ( as[i]->curMax > curMax ) {
547
curMax = as[i]->curMax;
551
if ( curMin < as[0]->st ) {
555
if ( curMax > as[0]->en ) {
559
if ( curMax <= curMin ) {
569
bool startExists = false;
571
int masks[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
573
int theSt = as[0]->st;
575
// special case for 4*4 supersampling, to avoid a few loops
577
c_full[0] = as[0]->fullB[(curMin - theSt) >> 3] | as[0]->partB[(curMin - theSt) >> 3];
578
c_full[0] <<= 4 * ((curMin - theSt) & 7);
579
c_full[1] = as[1]->fullB[(curMin - theSt) >> 3] | as[1]->partB[(curMin - theSt) >> 3];
580
c_full[1] <<= 4 * ((curMin - theSt) & 7);
581
c_full[2] = as[2]->fullB[(curMin - theSt) >> 3] | as[2]->partB[(curMin - theSt) >> 3];
582
c_full[2] <<= 4* ((curMin - theSt) & 7);
583
c_full[3] = as[3]->fullB[(curMin - theSt) >> 3] | as[3]->partB[(curMin - theSt) >> 3];
584
c_full[3] <<= 4* ((curMin - theSt) & 7);
587
for (int i = curMin; i <= curMax; i++) {
590
if ( c_full[0] == 0 && c_full[1] == 0 && c_full[2] == 0 && c_full[3] == 0 ) {
593
AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA);
596
i = theSt + (((i - theSt) & (~7) ) + 7);
598
} else if ( c_full[0] == 0xFFFFFFFF && c_full[1] == 0xFFFFFFFF &&
599
c_full[2] == 0xFFFFFFFF && c_full[3] == 0xFFFFFFFF ) {
602
if ( lastVal == 4*4) {
604
AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA);
612
i = theSt + (((i - theSt) & (~7) ) + 7);
615
nbBit += masks[c_full[0] >> 28];
616
nbBit += masks[c_full[1] >> 28];
617
nbBit += masks[c_full[2] >> 28];
618
nbBit += masks[c_full[3] >> 28];
622
if ( lastVal == nbBit ) {
623
// on continue le run
625
AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA);
636
AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA);
641
int chg = (i + 1 - theSt) & 7;
644
c_full[0] = as[0]->fullB[(i + 1 - theSt) >> 3] | as[0]->partB[(i + 1 - theSt) >> 3];
645
c_full[1] = as[1]->fullB[(i + 1 - theSt) >> 3] | as[1]->partB[(i + 1 - theSt) >> 3];
646
c_full[2] = as[2]->fullB[(i + 1 - theSt) >> 3] | as[2]->partB[(i + 1 - theSt) >> 3];
647
c_full[3] = as[3]->fullB[(i + 1 - theSt) >> 3] | as[3]->partB[(i + 1 - theSt) >> 3];
649
// end of line. byebye
661
uint32_t c_full[16]; // we take nbSub < 16, since 16*16 supersampling makes a 1/256 precision in alpha values
662
// and that's the max of what 32bit argb can represent
663
// in fact, we'll treat it as 4*nbSub supersampling, so that's a half truth and a full lazyness from me
664
// uint32_t c_part[16];
665
// start by putting the bits of the nbSub BitLignes in as[] in their respective c_full
667
for (int i = 0; i < nbSub; i++) {
668
// fullB and partB treated equally
669
c_full[i] = as[i]->fullB[(curMin - theSt) >> 3] | as[i]->partB[(curMin - theSt) >> 3];
670
c_full[i] <<= 4 * ((curMin - theSt) & 7);
671
/* c_part[i]=as[i]->partB[(curMin-theSt)>>3];
672
c_part[i]<<=4*((curMin-theSt)&7);*/
675
spA = 1.0 / (4 * nbSub); // contribution to the alpha value of a single bit of the supersampled data
676
for (int i = curMin; i <= curMax;i++) {
679
// a little acceleration: if the lines only contain full or empty bits, we can flush
680
// what's remaining in the c_full at best we flush an entire c_full, ie 32 bits, or 32/4=8 pixels
681
bool allEmpty = true;
683
for (int j = 0; j < nbSub; j++) {
684
if ( c_full[j] != 0 /*|| c_part[j] != 0*/ ) {
691
// the remaining bits in c_full[] are empty: flush
693
AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA);
696
i = theSt + (((i - theSt) & (~7) ) + 7);
698
for (int j = 0; j < nbSub; j++) {
699
if ( c_full[j] != 0xFFFFFFFF ) {
706
// the remaining bits in c_full[] are empty: flush
708
if ( lastVal == 4 * nbSub) {
710
AddRun(lastStart, i, ((float) lastVal) * spA,((float) lastVal) * spA);
718
i = theSt + (((i - theSt) & (~7) ) + 7);
720
// alpha values will be between 0 and 1, so we have more work to do
721
// compute how many bit this pixel holds
722
for (int j = 0; j < nbSub; j++) {
723
nbBit += masks[c_full[j] >> 28];
724
// nbPartBit+=masks[c_part[j]>>28];
726
// and add a single-pixel run if needed, or extend the current run if the alpha value hasn't changed
729
if ( lastVal == nbBit ) {
730
// alpha value hasn't changed: we continue
732
// alpha value did change: put the run that was being done,...
733
AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA);
734
// ... and start a new one
739
// alpha value was 0, so we "create" a new run with alpha nbBit
746
AddRun(lastStart, i, ((float) lastVal) * spA,((float) lastVal) * spA);
752
// move to the right: shift bits in the c_full[], and if we shifted everything, load the next c_full[]
753
int chg = (i + 1 - theSt) & 7;
756
for (int j = 0; j < nbSub; j++) {
757
c_full[j] = as[j]->fullB[(i + 1 - theSt) >> 3] | as[j]->partB[(i + 1 - theSt) >> 3];
758
// c_part[j]=as[j]->partB[(i+1-theSt)>>3];
761
// end of line. byebye
764
for (int j = 0; j < nbSub; j++) {
773
AddRun(lastStart, curMax + 1, ((float) lastVal) * spA,((float) lastVal) * spA);
777
/// Copy another IntLigne
778
void IntLigne::Copy(IntLigne *a)
780
if ( a->nbRun <= 0 ) {
787
if ( nbRun > maxRun ) {
789
runs = (int_ligne_run*) g_realloc(runs, maxRun * sizeof(int_ligne_run));
791
memcpy(runs, a->runs, nbRun * sizeof(int_ligne_run));
796
* Copy a FloatLigne's runs.
798
* Compute non-overlapping runs with integer boundaries from a set of runs
799
* with floating-point boundaries. This involves replacing floating-point
800
* boundaries that are not integer by single-pixel runs, so this function
801
* contains plenty of rounding and float->integer conversion (read:
805
* Optimization Questions: Why is this called so often compared with the
806
* other Copy() routines? How does AddRun() look for optimization potential?
808
void IntLigne::Copy(FloatLigne* a)
810
if ( a->runs.empty() ) {
816
printf("\nfloatligne:\n");
822
firstAc = lastAc = -1;
823
bool pixExists = false;
824
int curPos = (int) floor(a->runs[0].st) - 1;
826
float tolerance = 0.00001;
828
// we take each run of the FloatLigne in sequence and make single-pixel runs of its boundaries as needed
829
// since the float_ligne_runs are non-overlapping, when a single-pixel run intersects with another runs,
830
// it must intersect with the single-pixel run created for the end of that run. so instead of creating a new
831
// int_ligne_run, we just add the coverage to that run.
832
for (int i = 0; i < int(a->runs.size()); i++) {
833
float_ligne_run runA = a->runs[i];
834
float curStF = floor(runA.st);
835
float curEnF = floor(runA.en);
836
int curSt = (int) curStF;
837
int curEn = (int) curEnF;
839
// stEx: start boundary is not integer -> create single-pixel run for it
840
// enEx: end boundary is not integer -> create single-pixel run for it
841
// miEx: the runs minus the eventual single-pixel runs is not empty
846
float miStF = curStF;
849
if ( runA.en - curEnF < tolerance ) {
853
// msv and mev are the start and end value of the middle section of the run, that is the run minus the
854
// single-pixel runs creaed for its boundaries
855
if ( runA.st-curStF < tolerance /*miSt == runA.st*/ ) {
861
if ( enEx == false && miSt == curEn ) {
864
// msv=a->ValAt(miSt,runA.st,runA.en,runA.vst,runA.ven);
865
msv = runA.vst + (miStF-runA.st) * runA.pente;
869
if ( miSt >= curEn ) {
872
if ( stEx == false && miEx == false /*curEn == runA.st*/ ) {
874
} else if ( enEx == false /*curEn == runA.en*/ ) {
877
// mev=a->ValAt(curEn,runA.st,runA.en,runA.vst,runA.ven);
878
mev = runA.vst + (curEnF-runA.st) * runA.pente;
881
// check the different cases
882
if ( stEx && enEx ) {
884
if ( curEn > curSt ) {
886
if ( curPos < curSt ) {
887
AddRun(curPos,curPos+1,lastSurf,lastSurf);
888
lastSurf=0.5*(msv+a->runs[i].vst)*(miStF-a->runs[i].st);
889
AddRun(curSt,curSt+1,lastSurf,lastSurf);
891
lastSurf+=0.5*(msv+a->runs[i].vst)*(miStF-a->runs[i].st);
892
AddRun(curSt,curSt+1,lastSurf,lastSurf);
896
lastSurf=0.5*(msv+a->runs[i].vst)*(miStF-a->runs[i].st);
897
AddRun(curSt,curSt+1,lastSurf,lastSurf);
899
} else if ( pixExists ) {
900
if ( curPos < curSt ) {
901
AddRun(curPos,curPos+1,lastSurf,lastSurf);
902
lastSurf=0.5*(a->runs[i].ven+a->runs[i].vst)*(a->runs[i].en-a->runs[i].st);
905
lastSurf += 0.5 * (a->runs[i].ven+a->runs[i].vst)*(a->runs[i].en-a->runs[i].st);
908
lastSurf=0.5*(a->runs[i].ven+a->runs[i].vst)*(a->runs[i].en-a->runs[i].st);
912
} else if ( pixExists ) {
913
if ( curPos < curSt ) {
914
AddRun(curPos,curPos+1,lastSurf,lastSurf);
915
lastSurf = 0.5 * (msv+a->runs[i].vst) * (miStF-a->runs[i].st);
916
AddRun(curSt,curSt+1,lastSurf,lastSurf);
918
lastSurf += 0.5 * (msv+a->runs[i].vst) * (miStF-a->runs[i].st);
919
AddRun(curSt,curSt+1,lastSurf,lastSurf);
923
lastSurf = 0.5 * (msv+a->runs[i].vst) * (miStF-a->runs[i].st);
924
AddRun(curSt,curSt+1,lastSurf,lastSurf);
927
if ( pixExists && curPos < miSt ) {
928
AddRun(curPos,curPos+1,lastSurf,lastSurf);
931
AddRun(miSt,curEn,msv,mev);
934
if ( curEn > curSt ) {
935
lastSurf=0.5*(mev+a->runs[i].ven)*(a->runs[i].en-curEnF);
938
} else if ( ! stEx ) {
940
AddRun(curPos,curPos+1,lastSurf,lastSurf);
942
lastSurf=0.5*(mev+a->runs[i].ven)*(a->runs[i].en-curEnF);
949
AddRun(curPos,curPos+1,lastSurf,lastSurf);
952
printf("-> intligne:\n");
958
void IntLigne::Enqueue(int no)
961
firstAc = lastAc = no;
962
bords[no].prev = bords[no].next = -1;
965
bords[no].prev = lastAc;
966
bords[lastAc].next = no;
972
void IntLigne::Dequeue(int no)
974
if ( no == firstAc ) {
975
if ( no == lastAc ) {
976
firstAc = lastAc = -1;
978
firstAc = bords[no].next;
980
} else if ( no == lastAc ) {
981
lastAc = bords[no].prev;
984
if ( bords[no].prev >= 0 ) {
985
bords[bords[no].prev].next = bords[no].next;
987
if ( bords[no].next >= 0 ) {
988
bords[bords[no].next].prev = bords[no].prev;
991
bords[no].prev = bords[no].next = -1;
997
* The parameters have the same meaning as in the AlphaLigne class.
999
void IntLigne::Raster(raster_info &dest, void *color, RasterInRunFunc worker)
1005
int min = runs[0].st;
1006
int max = runs[nbRun-1].en;
1007
if ( dest.endPix <= min || dest.startPix >= max ) {
1012
for (curRun = 0; curRun < nbRun; curRun++) {
1013
if ( runs[curRun].en > dest.startPix ) {
1018
if ( curRun >= nbRun ) {
1022
if ( runs[curRun].st < dest.startPix ) {
1023
int nst = runs[curRun].st;
1024
int nen = runs[curRun].en;
1025
float vst = runs[curRun].vst;
1026
float ven = runs[curRun].ven;
1027
float nvst = (vst * (nen - dest.startPix) + ven * (dest.startPix - nst)) / ((float) (nen - nst));
1028
if ( runs[curRun].en <= dest.endPix ) {
1029
(worker)(dest, color, dest.startPix, nvst, runs[curRun].en, runs[curRun].ven);
1031
float nven = (vst * (nen - dest.endPix) + ven * (dest.endPix - nst)) / ((float)(nen - nst));
1032
(worker)(dest, color, dest.startPix, nvst, dest.endPix, nven);
1038
for (; (curRun < nbRun && runs[curRun].en <= dest.endPix); curRun++) {
1039
(worker)(dest, color, runs[curRun].st, runs[curRun].vst, runs[curRun].en, runs[curRun].ven);
1040
//Buffer::RasterRun(*dest,color,runs[curRun].st,runs[curRun].vst,runs[curRun].en,runs[curRun].ven);
1043
if ( curRun >= nbRun ) {
1047
if ( runs[curRun].st < dest.endPix && runs[curRun].en > dest.endPix ) {
1048
int const nst = runs[curRun].st;
1049
int const nen = runs[curRun].en;
1050
float const vst = runs[curRun].vst;
1051
float const ven = runs[curRun].ven;
1052
float const nven = (vst * (nen - dest.endPix) + ven * (dest.endPix - nst)) / ((float)(nen - nst));
1054
(worker)(dest,color,runs[curRun].st,runs[curRun].vst,dest.endPix,nven);
1064
c-file-style:"stroustrup"
1065
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1066
indent-tabs-mode:nil
1070
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :