Changeset 108
- Timestamp:
- Jul 30, 2006, 11:27:57 AM (19 years ago)
- Location:
- trunk/src/kernel
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel/qpixmap_pm.cpp
r59 r108 1057 1057 h /= 2; 1058 1058 } 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; 1059 1070 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(); 1062 1098 #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 1069 1104 #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; 1077 1111 } 1078 1112 } … … 1092 1126 GpiSetBitmap( pm.hps, 0 ); 1093 1127 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. 1094 1134 1095 1135 POINTERINFO info; … … 1291 1331 Creates an OS/2 icon or pointer from two given pixmaps. 1292 1332 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 1293 1349 \param pointer true to create a pointer, false to create an icon 1294 1350 \param hotX X coordinate of the action point within the pointer/icon 1295 1351 \param hotY Y coordinate of the action point within the pointer/icon 1296 1352 \param normal pixmap for a normal-sized pointer/icon 1297 \param mini pixmap for a mini-sized pointer/icon1353 \param mini pixmap for a mini-sized (half-sized) pointer/icon 1298 1354 1299 1355 \return PM handle of the created pointer or 0 in case of any error 1300 1356 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. 1305 1364 1306 1365 \warning This function is not portable. … … 1312 1371 // Due to a bug in WinCreatePointerIndirect (it always ignores 1313 1372 // hbmMiniPointer and hbmMiniColor fields), we can specify either a normal 1314 // icon, but not both. This method sstill accepts pixmaps for both icon1373 // icon, but not both. This method still accepts pixmaps for both icon 1315 1374 // sizes (assuming that we will find a workaround one day) but uses only 1316 1375 // one of them. 1317 1376 1318 1377 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 ); 1326 1390 } 1327 1391 1328 1392 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 ); 1330 1394 1331 1395 return 0; -
trunk/src/kernel/qwidget_pm.cpp
r102 r108 1342 1342 if ( !pixmap.isNull() ) { // valid icon 1343 1343 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 ); 1364 1346 } 1365 1347
Note:
See TracChangeset
for help on using the changeset viewer.