Ignore:
Timestamp:
Mar 22, 2006, 4:15:38 PM (19 years ago)
Author:
dmik
Message:

On OS/2, use regions to scan polygons in order to determine which chunks they intersect with. This should be as fast as QPolygonScanner, but produces much better results (and no artefacts).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/canvas/qcanvas.cpp

    r67 r71  
    10821082
    10831083#ifndef QT_NO_TRANSFORMATIONS
     1084#if !defined(Q_WS_PM)
    10841085        // For translation-only transformation, it is safe to include the right
    10851086        // and bottom edges, but otherwise, these must be excluded since they
     
    10901091        else
    10911092            a = QPointArray( all );
     1093#else
     1094        // Polygons on OS/2 already include the right and bottom edges
     1095        // (why shouldn't they do that?) Indeed, this important moment is not
     1096        // defined in Qt at all.
     1097        QPointArray a( all );
     1098#endif
    10921099
    10931100        a = (wm*twm).map(a);
    10941101#else
     1102#if !defined(Q_WS_PM)
    10951103        QPointArray a( QRect(all.x(),all.y(),all.width()+1,all.height()+1) );
     1104#else       
     1105        QPointArray a( all );
     1106#endif       
    10961107#endif
    10971108        if ( view->viewport()->backgroundMode() == NoBackground ) {
     
    39403951            int x2r = x2%8;
    39413952#ifdef QCANVAS_POLYGONS_DEBUG
    3942             if ( dbg_ptr ) dbg_ptr->setPen(Qt::yellow);
     3953            if ( dbg_ptr ) dbg_ptr->setPen(Qt::darkGray);
    39433954#endif
    39443955            if ( x1q == x2q ) {
    39453956                uchar newbits = (~l[x1q]) & (((2<<(x2r-x1r))-1)<<x1r);
    39463957                if ( newbits ) {
     3958                    addBits(x1r,x2r,newbits,x1q*8,y);
     3959                    l[x1q] |= newbits;
    39473960#ifdef QCANVAS_POLYGONS_DEBUG
    39483961                    if ( dbg_ptr ) dbg_ptr->setPen(Qt::darkGreen);
    39493962#endif
    3950                     addBits(x1r,x2r,newbits,x1q*8,y);
    3951                     l[x1q] |= newbits;
    39523963                }
    39533964            } else {
    3954 #ifdef QCANVAS_POLYGONS_DEBUG
    3955                 if ( dbg_ptr ) dbg_ptr->setPen(Qt::blue);
    3956 #endif
    39573965                uchar newbits1 = (~l[x1q]) & (0xff<<x1r);
    39583966                if ( newbits1 ) {
     3967                    addBits(x1r,7,newbits1,x1q*8,y);
     3968                    l[x1q] |= newbits1;
    39593969#ifdef QCANVAS_POLYGONS_DEBUG
    39603970                    if ( dbg_ptr ) dbg_ptr->setPen(Qt::green);
    39613971#endif
    3962                     addBits(x1r,7,newbits1,x1q*8,y);
    3963                     l[x1q] |= newbits1;
    39643972                }
    39653973                for (int i=x1q+1; i<x2q; i++) {
     
    39673975                        addBits(0,7,~l[i],i*8,y);
    39683976                        l[i]=0xff;
     3977#ifdef QCANVAS_POLYGONS_DEBUG
     3978                        if ( dbg_ptr ) dbg_ptr->setPen(Qt::black);
     3979#endif
    39693980                    }
    39703981                }
    39713982                uchar newbits2 = (~l[x2q]) & (0xff>>(7-x2r));
    39723983                if ( newbits2 ) {
     3984                    addBits(0,x2r,newbits2,x2q*8,y);
     3985                    l[x2q] |= newbits2;
    39733986#ifdef QCANVAS_POLYGONS_DEBUG
    39743987                    if ( dbg_ptr ) dbg_ptr->setPen(Qt::red);
    39753988#endif
    3976                     addBits(0,x2r,newbits2,x2q*8,y);
    3977                     l[x2q] |= newbits2;
    39783989                }
    39793990            }
     
    39873998    }
    39883999
     4000#if defined(Q_WS_PM)
     4001    // We cannot use QPolygonScanner, because:
     4002    // a) polygons in OS/2 are all-inclusive, but
     4003    // b) specifying the Bottom edge inclusion in QPolygonScanner::scan()
     4004    //    doesn't actually work (seems that the code from Xserver always
     4005    //    internally assumes that right and bottom edges are excluded).
     4006    // Instead of getting into and fixing the Xserver code, I decided to use
     4007    // region's rectangles to determine polygon spans. It should be as fast
     4008    // as the Xserver code, but gives us one more advantage: spans detected
     4009    // this way precisely repeat the actual polygon pixels drawn on the screen
     4010    // (because both regions and polygons are created/drawn by GPI using the
     4011    // same line and fill routines), so all chunks will be correctly detected.
     4012   
     4013    void scanPolygon( const QPointArray &pa, bool wind )
     4014    {
     4015        int cs = canvas->chunkSize();
     4016        QRegion rgn = QRegion( pa, wind );
     4017        QMemArray <QRect> rects = rgn.rects();
     4018        for ( size_t i = 0; i < rects.size(); ++ i ) {
     4019            const QRect &r = rects[i];
     4020            int width = r.width() - 1;
     4021            // I think I saw null rects in regions a couple of times...
     4022            if ( width < 0 || r.height() == 0 )
     4023                continue;
     4024            QPoint pt( r.topLeft() );
     4025            while ( 1 ) {
     4026                doSpans( 1, &pt, &width );
     4027#ifdef QCANVAS_POLYGONS_DEBUG
     4028                if ( dbg_ptr ) {
     4029                    dbg_ptr->setPen( Qt::cyan );
     4030                    QPoint ptd = pt;
     4031                    ++ ptd.ry();
     4032                    int j = 1;
     4033                    for ( ; j < cs && ptd.y() < r.bottom(); ++ j, ++ ptd.ry() )
     4034                        dbg_ptr->drawLine( ptd, ptd + QPoint( width, 0 ) );
     4035                }
     4036#endif
     4037                if ( pt.y() == r.bottom() )
     4038                    break;
     4039                pt.ry() += cs;
     4040                if ( pt.y() > r.bottom() )
     4041                    pt.ry() = r.bottom();
     4042            }
     4043        }
     4044    }
     4045#endif // !defined(Q_WS_PM)
     4046
    39894047    int pnt;
    39904048    QPointArray result;
     
    40034061        return pa;
    40044062    }
    4005 
     4063   
    40064064    QPolygonalProcessor processor(canvas(),pa);
    40074065
     4066#if defined(Q_WS_PM)
     4067    processor.scanPolygon( pa, wind );
     4068#else
    40084069    scanPolygon(pa, wind, processor);
     4070#endif   
    40094071
    40104072    return processor.result;
     
    53525414}
    53535415
     5416#if !defined(Q_WS_PM)
     5417
    53545418class QCanvasPolygonScanner : public QPolygonScanner {
    53555419    QPolygonalProcessor& processor;
     
    53715435}
    53725436
     5437#endif   
    53735438
    53745439#endif // QT_NO_CANVAS
Note: See TracChangeset for help on using the changeset viewer.