vlc_linux/vlc-3.0.16/modules/gui/qt/util/pictureflow.cpp
// Renders a slide to offscreen buffer. Returns a rect of the rendered area.
// col1 and col2 limit the column for rendering.
Renders a slide to offscreen buffer. Returns a rect of the rendered area.
col1 and col2 limit the column for rendering.
Renders a slide to offscreen buffer . Returns a rect of the rendered area . col1 and col2 limit the column for rendering .
QRect PictureFlowSoftwareRenderer::renderSlide(const SlideInfo &slide, int col1, int col2)
{
    int blend = slide.blend;
    if (!blend)
        return QRect();
    QModelIndex index;
    QString artURL;
    VLCModel *m = static_cast<VLCModel*>( state->model );
    if( m )
    {
        index = m->index( slide.slideIndex, 0, m->currentIndex().parent() );
        if( !index.isValid() )
            return QRect();
        artURL = m->data( index, COLUMN_COVER ).toString();
    }
    QString key = QString("%1%2%3%4").arg(VLCModel::getMeta( index, COLUMN_TITLE )).arg( VLCModel::getMeta( index, COLUMN_ARTIST ) ).arg(index.data( VLCModel::CURRENT_ITEM_ROLE ).toBool() ).arg( artURL );
    QImage* src;
    if( cache.contains( key ) )
       src = cache.value( key );
    else
    {
       src = surface( index );
       cache.insert( key, src );
    }
    if (!src)
        return QRect();
    QRect rect(0, 0, 0, 0);
    int sw = src->height();
    int sh = src->width();
    int h = buffer.height();
    int w = buffer.width();
    if (col1 > col2) {
        int c = col2;
        col2 = col1;
        col1 = c;
    }
    col1 = (col1 >= 0) ? col1 : 0;
    col2 = (col2 >= 0) ? col2 : w - 1;
    col1 = qMin(col1, w - 1);
    col2 = qMin(col2, w - 1);
    int zoom = 100;
    int distance = h * 100 / zoom;
    PFreal sdx = fcos(slide.angle);
    PFreal sdy = fsin(slide.angle);
    PFreal xs = slide.cx - state->slideWidth * sdx / 2;
    PFreal ys = slide.cy - state->slideWidth * sdy / 2;
    PFreal dist = distance * PFREAL_ONE;
    int xi = qMax((PFreal)0, ((w * PFREAL_ONE / 2) + fdiv(xs * h, dist + ys)) >> PFREAL_SHIFT);
    if (xi >= w)
    {
        return rect;
    }
    bool flag = false;
    rect.setLeft(xi);
    for (int x = qMax(xi, col1); x <= col2; x++) {
        PFreal hity = 0;
        PFreal fk = rays[x];
        if (sdy) {
            fk = fk - fdiv(sdx, sdy);
            hity = -fdiv((rays[x] * distance - slide.cx + slide.cy * sdx / sdy), fk);
        }
        dist = distance * PFREAL_ONE + hity;
        if (dist < 0)
            continue;
        PFreal hitx = fmul(dist, rays[x]);
        PFreal hitdist = fdiv(hitx - slide.cx, sdx);
        int column = sw / 2 + (hitdist >> PFREAL_SHIFT);
        if (column >= sw)
            break;
        if (column < 0)
            continue;
        rect.setRight(x);
        if (!flag)
            rect.setLeft(x);
        flag = true;
        int y1 = h / 2;
        int y2 = y1 + 1;
        QRgb* pixel1 = (QRgb*)(buffer.scanLine(y1)) + x;
        QRgb* pixel2 = (QRgb*)(buffer.scanLine(y2)) + x;
        QRgb pixelstep = pixel2 - pixel1;
        int center = (sh / 2);
        int dy = dist / h;
        int p1 = center * PFREAL_ONE - dy / 2;
        int p2 = center * PFREAL_ONE + dy / 2;
        const QRgb *ptr = (const QRgb*)(src->scanLine(column));
            while ((y1 >= 0) && (y2 < h) && (p1 >= 0)) {
                QRgb c1 = ptr[p1 >> PFREAL_SHIFT];
                QRgb c2 = ptr[p2 >> PFREAL_SHIFT];
                *pixel1 = blendColor(c1, *pixel1+0*bgcolor, blend);
                *pixel2 = blendColor(c2, *pixel2+0*bgcolor, blend);
                p1 -= dy;
                p2 += dy;
                y1--;
                y2++;
                pixel1 -= pixelstep;
                pixel2 += pixelstep;
            }
    }
    rect.setTop(0);
    rect.setBottom(h - 1);
    return rect;
}
QRect PictureFlowSoftwareRenderer :: renderSlide ( const SlideInfo & slide , int col1 , int col2 ) { int blend = slide . blend ; if ( ! blend ) return QRect ( ) ; QModelIndex index ; QString artURL ; VLCModel * m = static_cast < VLCModel * > ( state -> model ) ; if ( m ) { index = m -> index ( slide . slideIndex , 0 , m -> currentIndex ( ) . parent ( ) ) ; if ( ! index . isValid ( ) ) return QRect ( ) ; artURL = m -> data ( index , COLUMN_COVER ) . toString ( ) ; } QString key = QString ( " " ) . arg ( VLCModel :: getMeta ( index , COLUMN_TITLE ) ) . arg ( VLCModel :: getMeta ( index , COLUMN_ARTIST ) ) . arg ( index . data ( VLCModel :: CURRENT_ITEM_ROLE ) . toBool ( ) ) . arg ( artURL ) ; QImage * src ; if ( cache . contains ( key ) ) src = cache . value ( key ) ; else { src = surface ( index ) ; cache . insert ( key , src ) ; } if ( ! src ) return QRect ( ) ; QRect rect ( 0 , 0 , 0 , 0 ) ; int sw = src -> height ( ) ; int sh = src -> width ( ) ; int h = buffer . height ( ) ; int w = buffer . width ( ) ; if ( col1 > col2 ) { int c = col2 ; col2 = col1 ; col1 = c ; } col1 = ( col1 >= 0 ) ? col1 : 0 ; col2 = ( col2 >= 0 ) ? col2 : w - 1 ; col1 = qMin ( col1 , w - 1 ) ; col2 = qMin ( col2 , w - 1 ) ; int zoom = 100 ; int distance = h * 100 / zoom ; PFreal sdx = fcos ( slide . angle ) ; PFreal sdy = fsin ( slide . angle ) ; PFreal xs = slide . cx - state -> slideWidth * sdx / 2 ; PFreal ys = slide . cy - state -> slideWidth * sdy / 2 ; PFreal dist = distance * PFREAL_ONE ; int xi = qMax ( ( PFreal ) 0 , ( ( w * PFREAL_ONE / 2 ) + fdiv ( xs * h , dist + ys ) ) >> PFREAL_SHIFT ) ; if ( xi >= w ) { return rect ; } bool flag = false ; rect . setLeft ( xi ) ; for ( int x = qMax ( xi , col1 ) ; x <= col2 ; x ++ ) { PFreal hity = 0 ; PFreal fk = rays [ x ] ; if ( sdy ) { fk = fk - fdiv ( sdx , sdy ) ; hity = - fdiv ( ( rays [ x ] * distance - slide . cx + slide . cy * sdx / sdy ) , fk ) ; } dist = distance * PFREAL_ONE + hity ; if ( dist < 0 ) continue ; PFreal hitx = fmul ( dist , rays [ x ] ) ; PFreal hitdist = fdiv ( hitx - slide . cx , sdx ) ; int column = sw / 2 + ( hitdist >> PFREAL_SHIFT ) ; if ( column >= sw ) break ; if ( column < 0 ) continue ; rect . setRight ( x ) ; if ( ! flag ) rect . setLeft ( x ) ; flag = true ; int y1 = h / 2 ; int y2 = y1 + 1 ; QRgb * pixel1 = ( QRgb * ) ( buffer . scanLine ( y1 ) ) + x ; QRgb * pixel2 = ( QRgb * ) ( buffer . scanLine ( y2 ) ) + x ; QRgb pixelstep = pixel2 - pixel1 ; int center = ( sh / 2 ) ; int dy = dist / h ; int p1 = center * PFREAL_ONE - dy / 2 ; int p2 = center * PFREAL_ONE + dy / 2 ; const QRgb * ptr = ( const QRgb * ) ( src -> scanLine ( column ) ) ; while ( ( y1 >= 0 ) && ( y2 < h ) && ( p1 >= 0 ) ) { QRgb c1 = ptr [ p1 >> PFREAL_SHIFT ] ; QRgb c2 = ptr [ p2 >> PFREAL_SHIFT ] ; * pixel1 = blendColor ( c1 , * pixel1 + 0 * bgcolor , blend ) ; * pixel2 = blendColor ( c2 , * pixel2 + 0 * bgcolor , blend ) ; p1 -= dy ; p2 += dy ; y1 -- ; y2 ++ ; pixel1 -= pixelstep ; pixel2 += pixelstep ; } } rect . setTop ( 0 ) ; rect . setBottom ( h - 1 ) ; return rect ; }
Renders a slide to offscreen buffer.
Renders a slide to offscreen buffer .