Changeset 108


Ignore:
Timestamp:
Jul 30, 2006, 11:27:57 AM (19 years ago)
Author:
dmik
Message:

Widgets: Added the non-scaling threshold when setting a top-level widgets's icon. This allows to avoid scaling pixmaps close to the target icon size (e.g. 16x16 to 20x20) to give them a better look (such pixmaps are centered instead of scaling).

Location:
trunk/src/kernel
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel/qpixmap_pm.cpp

    r59 r108  
    10571057            h /= 2;
    10581058        }
     1059
     1060        QPixmap pm = *this;
     1061
     1062#if !defined(QT_PM_NO_ICON_THRESHOLD)
     1063        // non-scalable threshold
     1064        enum { tmax = 12 };
     1065        int tw = w / 4;
     1066        int th = h / 4;
     1067        // difference
     1068        int dw = w - data->w;
     1069        int dh = h - data->h;
    10591070       
    1060         QPixmap pm = *this;
    1061         if ( data->w != w || data->h != h ) {
     1071        if ( (tw <= tmax && th <= tmax) &&
     1072             ((data->w >= data->h && dw > 0 && dw <= tw) ||
     1073              (dh > 0 && dh <= th)) ) {
     1074            pm = QPixmap( w, h );
     1075            LONG ofsx = dw / 2;
     1076            LONG ofsy = dh / 2;
     1077            POINTL ptls[] = {
     1078                { ofsx, ofsy }, { data->w + ofsx, data->h + ofsy },
     1079                { 0, 0 },
     1080            };
     1081            GpiBitBlt( pm.hps, hps, 3, ptls, ROP_SRCCOPY, BBO_IGNORE );
     1082            QBitmap msk = QBitmap( w, h );
     1083            msk.fill( color0 );
     1084            if ( data->mask ) {
     1085                GpiBitBlt( msk.hps, data->mask->hps, 3, ptls, ROP_SRCCOPY, BBO_IGNORE );
     1086            } else {
     1087                GpiBitBlt( msk.hps, NULL, 3, ptls, ROP_ONE, BBO_IGNORE );
     1088            }
     1089            pm.setMask( msk );
     1090            // correct the hot spot
     1091            hotX += ofsx;
     1092            hotY += ofsy;
     1093        } else
     1094#endif       
     1095        {
     1096            if ( data->w != w || data->h != h ) {
     1097                QImage i = convertToImage();
    10621098#if !defined(QT_NO_IMAGE_SMOOTHSCALE)
    1063             // do smooth resize until icon is two or more times bigger
    1064             // than the pixmap
    1065             if ( data->w * 2 > w || data->h * 2 > h ) {
    1066                 QImage i = convertToImage();
    1067                 pm = QPixmap( i.smoothScale( w, h ) );
    1068             } else
     1099                // do smooth resize until icon is two or more times bigger
     1100                // than the pixmap
     1101                if ( data->w * 2 > w || data->h * 2 > h ) {
     1102                    pm = QPixmap( i.smoothScale( w, h ) );
     1103                } else
    10691104#endif
    1070             {
    1071                 pm = QPixmap( w, h );
    1072                 POINTL ptls[] = {
    1073                     { 0, 0 }, { w, h },
    1074                     { 0, 0 }, { data->w, data->h },
    1075                 };
    1076                 GpiBitBlt( pm.hps, hps, 4, ptls, ROP_SRCCOPY, BBO_IGNORE );
     1105                {
     1106                    pm = QPixmap( i.scale( w, h ) );
     1107                }
     1108                // correct the hot spot
     1109                hotX = hotX * w / data->w;
     1110                hotY = hotY * h / data->h;
    10771111            }
    10781112        }
     
    10921126        GpiSetBitmap( pm.hps, 0 );       
    10931127        GpiSetBitmap( msk.hps, 0 );
     1128       
     1129        // Due to a bug in WinCreatePointerIndirect, it always ignores
     1130        // hbmMiniPointer and hbmMiniColor fields, so we use only hbmPointer
     1131        // and hbmColor. Thankfully, PM will assign it correctly either to
     1132        // the "normal" or to the "mini" slot depending on the actual icon
     1133        // width and height.
    10941134       
    10951135        POINTERINFO info;
     
    12911331    Creates an OS/2 icon or pointer from two given pixmaps.
    12921332   
     1333    If either of the pixmaps doesn't match eaxctly to the system-defined icon
     1334    or pointer size, it will be scaled to that size without keeping proportions.
     1335    However, to avoid scaling of small pixmaps that will most likely make them
     1336    unreadable, there is a non-scalable threshold that causes a pixmap to be
     1337    centered rather than scaled. The non-scalable threshold value is 1/4 of the
     1338    system-defined size but no more than 12 pixels (if more, then the threshold
     1339    is not applied). Here are examples of non-scalable pixmap sizes for common
     1340    icon/pointer sizes:
     1341   
     1342    icon size         non-scalable pixmap sizes
     1343    ---------         -------------------------
     1344    16 px             12..16 px
     1345    20 px             15..20 px
     1346    32 px             24..32 px
     1347    40 px             30..40 px
     1348   
    12931349    \param pointer true to create a pointer, false to create an icon
    12941350    \param hotX X coordinate of the action point within the pointer/icon
    12951351    \param hotY Y coordinate of the action point within the pointer/icon
    12961352    \param normal pixmap for a normal-sized pointer/icon
    1297     \param mini pixmap for a mini-sized pointer/icon
     1353    \param mini pixmap for a mini-sized (half-sized) pointer/icon
    12981354   
    12991355    \return PM handle of the created pointer or 0 in case of any error
    13001356   
    1301     \note Due to a bug in WinCreatePointerIndirect, you can specify either
    1302     \a normal pixmap or \a mini pixmap, but not both (if both are specified,
    1303     \a normal will be used). PM will use scaling to draw a pointer of the
    1304     other size when necessary. This bug may be fixed later.
     1357    \note Due to a bug in WinCreatePointerIndirect, you can specify either a
     1358    \a normal pixmap or \a mini pixmap, but not both. If both are specified,
     1359    the \a normal will be used so that if its size is equal to or larger than
     1360    the normal pointer/icon size (taking the threshold into account), it will
     1361    be used as a normal pointer/icon, otherwise as a mini one. PM will use
     1362    its own scaling to draw a pointer/icon of the other size when necessary.
     1363    This bug may be fixed later.
    13051364   
    13061365    \warning This function is not portable.   
     
    13121371    // Due to a bug in WinCreatePointerIndirect (it always ignores
    13131372    // hbmMiniPointer and hbmMiniColor fields), we can specify either a normal
    1314     // icon, but not both. This methods still accepts pixmaps for both icon
     1373    // icon, but not both. This method still accepts pixmaps for both icon
    13151374    // sizes (assuming that we will find a workaround one day) but uses only
    13161375    // one of them.
    13171376   
    13181377    if ( normal && !normal->isNull() ) {
    1319 #ifdef QT_CHECK_RANGE
    1320         if ( mini && !mini->isNull() )
    1321             qWarning( "QPixmap::createIcon(): due to a bug in WinCreatePointerIndirect "
    1322                       "either a normal or a mini pixmap should be specified, "
    1323                       "but not both. Will use a normal pixmap." );
    1324 #endif   
    1325         return const_cast <QPixmap *> (normal)->createIcon( pointer, hotX, hotY, false );
     1378        // If the specified normal pixmap is equal to or larger than the normal
     1379        // icon size (taking the threshold into account), then we use it to
     1380        // create a normal icon, otherwise a mini one.
     1381        int w = WinQuerySysValue( HWND_DESKTOP, pointer ? SV_CXPOINTER : SV_CXICON );
     1382        int h = WinQuerySysValue( HWND_DESKTOP, pointer ? SV_CYPOINTER : SV_CYICON );
     1383#if !defined(QT_PM_NO_ICON_THRESHOLD)
     1384        // apply the threshold (see private QPixmap::createIcon() above)
     1385        if ( w / 4 <= 12 ) w -= w / 4;
     1386        if ( h / 4 <= 12 ) h -= h / 4;
     1387#endif       
     1388        bool mini = normal->width() < w && normal->height() < h;
     1389        return const_cast <QPixmap *> (normal)->createIcon( pointer, hotX, hotY, mini );
    13261390    }
    13271391   
    13281392    if ( mini && !mini->isNull() )
    1329         return const_cast <QPixmap *> (mini)->createIcon( pointer, hotX, hotY, true );
     1393        return const_cast <QPixmap *> (mini)->createIcon( pointer, hotX, hotY, TRUE );
    13301394   
    13311395    return 0;
  • trunk/src/kernel/qwidget_pm.cpp

    r102 r108  
    13421342    if ( !pixmap.isNull() ) {                   // valid icon
    13431343        x->icon = new QPixmap( pixmap );
    1344        
    1345         if ( isTopLevel() ) {
    1346             const QPixmap *normal = 0;
    1347             const QPixmap *mini = 0;
    1348            
    1349             // QPixmap::createIcon() is not yet capable to create both normal
    1350             // and mini icons (due to a bug in WinCreateIconIndirect), so
    1351             // if the specified pixmap is equal or larger than the normal icon
    1352             // size, then we create a normal icon, otherwise a mini one.
    1353            
    1354             int iconw = WinQuerySysValue( HWND_DESKTOP, SV_CXICON );
    1355             int iconh = WinQuerySysValue( HWND_DESKTOP, SV_CYICON );
    1356             if ( pixmap.width() >= iconw && pixmap.height() >= iconh ) {
    1357                 normal = &pixmap;
    1358             } else {
    1359                 mini = &pixmap;
    1360             }
    1361            
    1362             x->pmIcon = QPixmap::createIcon( false, 0, 0, normal, mini );
    1363         }
     1344        if ( isTopLevel() )
     1345            x->pmIcon = QPixmap::createIcon( FALSE, 0, 0, &pixmap, &pixmap );
    13641346    }
    13651347
Note: See TracChangeset for help on using the changeset viewer.