Logo Search packages:      
Sourcecode: inkscape version File versions

void IntLigne::Copy ( int  nbSub,
BitLigne **  as 
)

Transform a line of bits into pixel coverage values.

Alpha values are computed from supersampled data, so we have to scan the BitLigne left to right, summing the bits in each pixel. The alpha value is then "number of bits"/(nbSub*nbSub)". Full bits and partial bits are treated as equals because the method produces ugly results otherwise.

Parameters:
nbSub Number of BitLigne in the array "a".

Definition at line 527 of file int-line.cpp.

References Copy().

{
    if ( nbSub <= 0 ) {
        Reset();
        return;
    }

    if ( nbSub == 1 ) {
        Copy(as[0]);
        return;
    }
    
    // compute the min-max of the pixels to be rasterized from the min-max of the  inpur bitlignes
    int curMin = as[0]->curMin;
    int curMax = as[0]->curMax;
    for (int i = 1; i < nbSub; i++) {
        if ( as[i]->curMin < curMin ) {
            curMin = as[i]->curMin;
        }
        if ( as[i]->curMax > curMax ) {
            curMax = as[i]->curMax;
        }
    }
    
    if ( curMin < as[0]->st ) {
        curMin = as[0]->st;
    }

    if ( curMax > as[0]->en ) {
        curMax = as[0]->en;
    }
    
    if ( curMax <= curMin ) {
        Reset();
        return;
    }

    nbBord = 0;
    nbRun = 0;
    
    int lastVal = 0;
    int lastStart = 0;
    bool startExists = false;
    float spA;
    int masks[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};

    int  theSt = as[0]->st;
    if ( nbSub == 4 ) {
        // special case for 4*4 supersampling, to avoid a few loops
        uint32_t c_full[4];
        c_full[0] = as[0]->fullB[(curMin - theSt) >> 3] | as[0]->partB[(curMin - theSt) >> 3];
        c_full[0] <<= 4 * ((curMin - theSt) & 7);
        c_full[1] = as[1]->fullB[(curMin - theSt) >> 3] | as[1]->partB[(curMin - theSt) >> 3];
        c_full[1] <<= 4 * ((curMin - theSt) & 7);
        c_full[2] = as[2]->fullB[(curMin - theSt) >> 3] | as[2]->partB[(curMin - theSt) >> 3];
        c_full[2] <<= 4* ((curMin - theSt) & 7);
        c_full[3] = as[3]->fullB[(curMin - theSt) >> 3] | as[3]->partB[(curMin - theSt) >> 3];
        c_full[3] <<= 4* ((curMin - theSt) & 7);
        
        spA = 1.0 / (4 * 4);
        for (int i = curMin; i <= curMax; i++) {
            int nbBit = 0;

            if ( c_full[0] == 0 && c_full[1] == 0 && c_full[2] == 0 && c_full[3] == 0 ) {

                if ( startExists ) {
                    AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA);
                }
                startExists = false;
                i = theSt + (((i - theSt) & (~7) ) + 7);
                
            } else if ( c_full[0] == 0xFFFFFFFF && c_full[1] == 0xFFFFFFFF &&
                        c_full[2] == 0xFFFFFFFF && c_full[3] == 0xFFFFFFFF ) {
                
                if ( startExists ) {
                    if ( lastVal == 4*4) {
                    } else {
                        AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA);
                        lastStart = i;
                    }
                } else {
                    lastStart = i;
                }
                lastVal = 4*4;
                startExists = true;
                i = theSt + (((i - theSt) & (~7) ) + 7);
                
            } else {
                nbBit += masks[c_full[0] >> 28];
                nbBit += masks[c_full[1] >> 28];
                nbBit += masks[c_full[2] >> 28];
                nbBit += masks[c_full[3] >> 28];
                
                if ( nbBit > 0 ) {
                    if ( startExists ) {
                        if ( lastVal == nbBit ) {
                            // on continue le run
                        } else {
                            AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA);
                            lastStart = i;
                            lastVal = nbBit;
                        }
                    } else {
                        lastStart = i;
                        lastVal = nbBit;
                        startExists = true;
                    }
                } else {
                    if ( startExists ) {
                        AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA);
                    }
                    startExists = false;
                }
            }
            int chg = (i + 1 - theSt) & 7;
            if ( chg == 0 ) {
                if ( i < curMax ) {
                    c_full[0] = as[0]->fullB[(i + 1 - theSt) >> 3] | as[0]->partB[(i + 1 - theSt) >> 3];
                    c_full[1] = as[1]->fullB[(i + 1 - theSt) >> 3] | as[1]->partB[(i + 1 - theSt) >> 3];
                    c_full[2] = as[2]->fullB[(i + 1 - theSt) >> 3] | as[2]->partB[(i + 1 - theSt) >> 3];
                    c_full[3] = as[3]->fullB[(i + 1 - theSt) >> 3] | as[3]->partB[(i + 1 - theSt) >> 3];
                } else {
                    // end of line. byebye
                }
            } else {
                c_full[0] <<= 4;
                c_full[1] <<= 4;
                c_full[2] <<= 4;
                c_full[3] <<= 4;
            }
        }
        
    } else {

        uint32_t c_full[16]; // we take nbSub < 16, since 16*16 supersampling makes a 1/256 precision in alpha values
        // and that's the max of what 32bit argb can represent
        // in fact, we'll treat it as 4*nbSub supersampling, so that's a half truth and a full lazyness from me
        //  uint32_t  c_part[16];
        // start by putting the bits of the nbSub BitLignes in as[] in their respective c_full

        for (int i = 0; i < nbSub; i++) {
            // fullB and partB treated equally
            c_full[i] = as[i]->fullB[(curMin - theSt) >> 3] | as[i]->partB[(curMin - theSt) >> 3]; 
            c_full[i] <<= 4 * ((curMin - theSt) & 7);
            /*          c_part[i]=as[i]->partB[(curMin-theSt)>>3];
                  c_part[i]<<=4*((curMin-theSt)&7);*/
        }

        spA = 1.0 / (4 * nbSub); // contribution to the alpha value of a single bit of the supersampled data
        for (int i = curMin; i <= curMax;i++) {
            int  nbBit = 0;
            //                int nbPartBit=0;
            // a little acceleration: if the lines only contain full or empty bits, we can flush
            // what's remaining in the c_full at best we flush an entire c_full, ie 32 bits, or 32/4=8 pixels
            bool allEmpty = true;
            bool allFull = true;
            for (int j = 0; j < nbSub; j++) {
                if ( c_full[j] != 0 /*|| c_part[j] != 0*/ ) {
                    allEmpty=false;
                    break;
                }
            }
            
            if ( allEmpty ) {
                // the remaining bits in c_full[] are empty: flush
                if ( startExists ) {
                    AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA);
                }
                startExists = false;
                i = theSt + (((i - theSt) & (~7) ) + 7);
            } else {
                for (int j = 0; j < nbSub; j++) {
                    if ( c_full[j] != 0xFFFFFFFF ) {
                        allFull=false;
                        break;
                    }
                }
                
                if ( allFull ) {
                    // the remaining bits in c_full[] are empty: flush
                    if ( startExists ) {
                        if ( lastVal == 4 * nbSub) {
                        } else {
                            AddRun(lastStart, i, ((float) lastVal) * spA,((float) lastVal) * spA);
                            lastStart = i;
                        }
                    } else {
                        lastStart = i;
                    }
                    lastVal = 4 * nbSub;
                    startExists = true;
                    i = theSt + (((i - theSt) & (~7) ) + 7);
                } else {
                    // alpha values will be between 0 and 1, so we have more work to do
                    // compute how many bit this pixel holds
                    for (int j = 0; j < nbSub; j++) {
                        nbBit += masks[c_full[j] >> 28];
//                                  nbPartBit+=masks[c_part[j]>>28];
                    }
                    // and add a single-pixel run if needed, or extend the current run if the alpha value hasn't changed
                    if ( nbBit > 0 ) {
                        if ( startExists ) {
                            if ( lastVal == nbBit ) {
                                // alpha value hasn't changed: we continue
                            } else {
                                // alpha value did change: put the run that was being done,...
                                AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA);
                                // ... and start a new one
                                lastStart = i;
                                lastVal = nbBit;
                            }
                        } else {
                            // alpha value was 0, so we "create" a new run with alpha nbBit
                            lastStart = i;
                            lastVal = nbBit;
                            startExists = true;
                        }
                    } else {
                        if ( startExists ) {
                            AddRun(lastStart, i, ((float) lastVal) * spA,((float) lastVal) * spA);
                        }
                        startExists = false;
                    }
                }
            }
            // move to the right: shift bits in the c_full[], and if we shifted everything, load the next c_full[]
            int chg = (i + 1 - theSt) & 7;
            if ( chg == 0 ) {
                if ( i < curMax ) {
                    for (int j = 0; j < nbSub; j++) {
                        c_full[j] = as[j]->fullB[(i + 1 - theSt) >> 3] | as[j]->partB[(i + 1 - theSt) >> 3];
                        //                c_part[j]=as[j]->partB[(i+1-theSt)>>3];
                    }
                } else {
                    // end of line. byebye
                }        
            } else {
                for (int j = 0; j < nbSub; j++) {
                    c_full[j]<<=4;
                    //              c_part[j]<<=4;
                }
            }
        }
    }
    
    if ( startExists ) {
        AddRun(lastStart, curMax + 1, ((float) lastVal) * spA,((float) lastVal) * spA);
    }
}


Generated by  Doxygen 1.6.0   Back to index