Logo Search packages:      
Sourcecode: inkscape version File versions

void FloatLigne::Flatten ( void   ) 

Extract a set of non-overlapping runs from the boundaries.

We scan the boundaries left to right, maintaining a set of coverage portions currently being scanned. For each such portion, the function will add the index of its first boundary in an array; but instead of allocating another array, it uses a field in float_ligne_bord: pend_ind. The outcome is that an array of float_ligne_run is produced.

Definition at line 440 of file float-line.cpp.

References bords, RemainingValAt(), Reset(), runs, and s_first.

Referenced by Inkscape::Text::Layout::ShapeScanlineMaker::makeScanline().

{
    if ( int(bords.size()) <= 1 ) {
        Reset();
        return;
    }
    
    runs.clear();

//    qsort(bords,bords.size(),sizeof(float_ligne_bord),FloatLigne::CmpBord);
//    SortBords(0,bords.size()-1);
  
    float totPente = 0;
    float totStart = 0;
    float totX = bords[0].pos;
    
    bool startExists = false;
    float lastStart = 0;
    float lastVal = 0;
    int pending = 0;
    
//    for (int i=0;i<bords.size();) {
    // read the list from left to right, adding a run for each boundary crossed, minus runs with alpha=0
    for (int i=/*0*/s_first; i>=0 && i < int(bords.size()) ;) {
        
        float cur = bords[i].pos;  // position of the current boundary (there may be several boundaries at this position)
        float leftV = 0;  // deltas in coverage value at this position
        float rightV = 0;
        float leftP = 0; // deltas in coverage increase per unit length at this position
        float rightP = 0;
        
        // more precisely, leftV is the sum of decreases of coverage value,
        // while rightV is the sum of increases, so that leftV+rightV is the delta.
        // idem for leftP and rightP
    
        // start by scanning all boundaries that end a portion at this position
        while ( i >= 0 && i < int(bords.size()) && bords[i].pos == cur && bords[i].start == false ) {
            leftV += bords[i].val;
            leftP += bords[i].pente;
            
#ifndef faster_flatten
            // we need to remove the boundary that started this coverage portion for the pending list
            if ( bords[i].other >= 0 && bords[i].other < int(bords.size()) ) {
                // so we use the pend_inv "array"
                int const k = bords[bords[i].other].pend_inv;
                if ( k >= 0 && k < pending ) {
                    // and update the pend_ind array and its inverse pend_inv
                    bords[k].pend_ind = bords[pending - 1].pend_ind;
                    bords[bords[k].pend_ind].pend_inv = k;
                }
            }
#endif
            
            // one less portion pending
            pending--;
            // and we move to the next boundary in the doubly linked list
            i=bords[i].s_next;
            //i++;
        }
        
        // then scan all boundaries that start a portion at this position
        while ( i >= 0 && i < int(bords.size()) && bords[i].pos == cur && bords[i].start == true ) {
            rightV += bords[i].val;
            rightP += bords[i].pente;
#ifndef faster_flatten
            bords[pending].pend_ind=i;
            bords[i].pend_inv=pending;
#endif
            pending++;
            i = bords[i].s_next;
            //i++;
        }

        // coverage value at end of the run will be "start coverage"+"delta per unit length"*"length"
        totStart = totStart + totPente * (cur - totX);
    
        if ( startExists ) {
            // add that run
            AddRun(lastStart, cur, lastVal, totStart, totPente);
        }
        // update "delta coverage per unit length"
        totPente += rightP - leftP;
        // not really needed here
        totStart += rightV - leftV;
        // update position
        totX = cur;
        if ( pending > 0 ) {
            startExists = true;
            
#ifndef faster_flatten
            // to avoid accumulation of numerical errors, we compute an accurate coverage for this position "cur"
            totStart = RemainingValAt(cur, pending);
#endif
            lastVal = totStart;
            lastStart = cur;
        } else {
            startExists = false;
            totStart = 0;
            totPente = 0;
        }
    }
}


Generated by  Doxygen 1.6.0   Back to index