Changeset 59 for trunk/src/kernel/qpixmap_pm.cpp
- Timestamp:
- Jan 29, 2006, 8:56:21 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel/qpixmap_pm.cpp
r56 r59 95 95 } 96 96 97 //@@TODO (dmik): later98 //void QPixmap::initAlphaPixmap( uchar *bytes, int length, BITMAPINFO *bmi )99 //{100 // if ( data->mcp )101 // freeCell( TRUE );102 // if ( !hdc )103 // hdc = alloc_mem_dc( 0, &data->old_hbm );104 //105 // HBITMAP hBitmap = CreateDIBSection( hdc, bmi, DIB_RGB_COLORS, (void**)&data->realAlphaBits, NULL, 0 );106 // if ( bytes )107 // memcpy( data->realAlphaBits, bytes, length );108 //109 // DeleteObject( SelectObject( hdc, data->old_hbm ) );110 // data->old_hbm = (HBITMAP)SelectObject( hdc, hBitmap );111 // DATA_HBM = hBitmap;112 //}113 114 97 115 98 void QPixmap::init( int w, int h, int d, bool bitmap, Optimization optim ) … … 123 106 124 107 static int serial = 0; 125 int dd = defaultDepth();108 const int dd = defaultDepth(); 126 109 127 110 if ( optim == DefaultOptim ) // use default optimization … … 162 145 bmh.cy = h; 163 146 bmh.cPlanes = 1; 164 if ( data->d == dd ) // compatible bitmap 147 if ( data->d == 1 ) // monocrome bitmap 148 bmh.cBitCount = 1; 149 else // compatible bitmap 165 150 bmh.cBitCount = dd; 166 else // monocrome bitmap167 bmh.cBitCount = 1;168 151 data->hbm = GpiCreateBitmap( hps, &bmh, 0, NULL, NULL ); 169 152 … … 188 171 if ( hps ) 189 172 GpiSetBitmap( hps, 0 ); 173 if ( data->hasRealAlpha && data->realAlphaBits ) { 174 delete[] data->realAlphaBits; 175 data->realAlphaBits = 0; 176 } 190 177 if ( data->mask ) { 191 178 delete data->mask; … … 221 208 data->d = 1; 222 209 223 int bitsbpl = (w +7)/8; // original # bytes per line210 int bitsbpl = (w + 7) / 8; // original # bytes per line 224 211 225 212 int bpl = ((w + 31) / 32) * 4; // bytes per scanline, … … 288 275 static int dd = 0; 289 276 if ( dd == 0 ) { 290 LONG formats [2];277 LONG formats[ 2 ]; 291 278 GpiQueryDeviceBitmapFormats( qt_display_ps(), 2, formats ); 292 dd = formats [0] * formats [1];279 dd = formats[ 0 ] * formats[ 1 ]; 293 280 } 294 281 return dd; … … 382 369 int w = width(); 383 370 int h = height(); 384 const QBitmap *m = data-> realAlphaBits? 0 : mask();371 const QBitmap *m = data->hasRealAlpha ? 0 : mask(); 385 372 int d = depth(); 386 373 int ncols = 2; … … 392 379 d = 32; // > 8 ==> 32 393 380 ncols = 0; 381 #if defined QT_CHECK_RANGE 382 if ( trueColorDepth() != 32 ) 383 qWarning( "QPixmap::convertToImage(): video driver doesn't seem to " 384 "support the 32-bpp color depth!" ); 385 // don't return since we still hope the driver can at least convert 386 // from/to 32-bpp bitmaps 387 #endif 394 388 } 395 389 396 390 QImage image( w, h, d, ncols, QImage::BigEndian ); 397 if ( data->realAlphaBits ) {398 qWarning( "QPixmap::convertToImage() for pixmaps with alpha is not yet implemented on OS/2" );399 //@@TODO (dmik): later400 //#ifndef Q_OS_TEMP401 // GdiFlush();402 //#endif403 // memcpy( image.bits(), data->realAlphaBits, image.numBytes() );404 // image.setAlphaBuffer( TRUE );405 //406 // // Windows has premultiplied alpha, so revert it407 // uchar *p = image.bits();408 // uchar *end = p + image.numBytes();409 // uchar alphaByte;410 // while ( p < end ) {411 // alphaByte = *(p+3);412 // if ( alphaByte == 0 ) {413 // *p = 255;414 // ++p;415 // *p = 255;416 // ++p;417 // *p = 255;418 // ++p;419 // ++p;420 // } else if ( alphaByte == 255 ) {421 // p += 4;422 // } else {423 // uchar alphaByte2 = alphaByte / 2;424 // *p = ( (int)(*p) * 255 + alphaByte2 ) / alphaByte;425 // ++p;426 // *p = ( (int)(*p) * 255 + alphaByte2 ) / alphaByte;427 // ++p;428 // *p = ( (int)(*p) * 255 + alphaByte2 ) / alphaByte;429 // ++p;430 // ++p;431 // }432 // }433 // return image;434 }435 391 436 392 // allocate header + ncols palette entries … … 447 403 GpiQueryBitmapBits( hps, 0, h, (PBYTE) image.bits(), (PBITMAPINFO2) bmi_data ); 448 404 405 if ( data->hasRealAlpha ) { 406 if ( data->realAlphaBits ) { 407 // incorporate the alpha channel to image data 408 // (see comments in convertFromImage() for details) 409 uchar *src = data->realAlphaBits; 410 int y = 0; 411 while ( y < image.height() ) { 412 uchar *dst = image.scanLine( y++ ); 413 uchar *end = dst + image.bytesPerLine(); 414 dst += 3; 415 while ( dst < end ) { 416 *dst = *(src++); 417 dst += 4; 418 } 419 } 420 } 421 image.setAlphaBuffer( TRUE ); 422 } 423 449 424 // flip the image top to bottom 450 425 { … … 550 525 } 551 526 552 553 527 bool QPixmap::convertFromImage( const QImage &img, int conversion_flags ) 554 528 { … … 582 556 } else if ( d == 1 ) { 583 557 if ( image.numColors() == 2 ) { 584 //@@TODO (dmik): the code below is necessary to prevent converting 585 // 1-bpp images with alpha channel to 8-bpp images. it is currently 586 // commented out only for compatibility with Qt/Win32; Qt/OS2 is ready 587 // to handle such images properly. 588 // QRgb c0 = image.color(0) | ~RGB_MASK; // Auto: convert to best 589 // QRgb c1 = image.color(1) | ~RGB_MASK; 558 // Note: 1-bpp images other than true black-white cannot be 559 // correctly stored as GPI bitmaps (it doesn't store the palette 560 // for them), so the code below ensures they will be converted 561 // to 8-bpp images first. However, black-white images with alpha 562 // channel will be also converted, though they can be stored 563 // as bitmaps. The correct code to prevent setting conv8 to TRUE 564 // for black-white bitmaps both with and w/o alpha should be: 565 // QRgb c0 = image.color(0) | ~RGB_MASK; 566 // QRgb c1 = image.color(1) | ~RGB_MASK; 567 // but it is left as is solely for compatibility with Qt/Win32 568 // (otherwise we would get visually different pixmaps). 590 569 QRgb c0 = image.color(0); // Auto: convert to best 591 570 QRgb c1 = image.color(1); … … 607 586 608 587 bool hasRealAlpha = FALSE; 609 if ( img.hasAlphaBuffer() 610 //@@TODO (dmik): remove later. 611 // && 612 // ( QApplication::winVersion() != Qt::WV_95 && 613 // QApplication::winVersion() != Qt::WV_NT ) 614 ) { 588 if ( img.hasAlphaBuffer() ) { 615 589 if (image.depth() == 8) { 616 590 const QRgb * const rgb = img.colorTable(); … … 623 597 } 624 598 if (hasRealAlpha) { 625 //@@TODO (dmik): also need to convert? guess yes. 626 // image = image.convertDepth(32, conversion_flags); 627 // d = image.depth(); 599 image = image.convertDepth(32, conversion_flags); 600 d = image.depth(); 628 601 } 629 602 } else if (image.depth() == 32) { … … 645 618 } 646 619 647 //@@TODO (dmik): temporary code. will be removed when alpha support is done.648 if ( hasRealAlpha ) {649 qWarning( "QPixmap::convertFromImage() for images with alpha is not yet implemented on OS/2" );650 hasRealAlpha = FALSE;651 }652 653 620 int w = image.width(); 654 621 int h = image.height(); 655 622 656 if ( width() == w && height() == h && ( (d == 1 && depth() == 1) || 657 (d != 1 && depth() != 1) ) ) { 658 if ( data->realAlphaBits && !hasRealAlpha ) { 659 //@@TODO (dmik): later 660 // // pixmap uses a DIB section, but image has no alpha channel, so we 661 // // can't reuse the old pixmap 662 // QPixmap pm(w, h, d == 1 ? 1 : -1, data->bitmap, data->optim); 663 // *this = pm; 664 } else { 665 // same size etc., use the existing pixmap 666 detach(); 667 if ( data->mask ) { // get rid of the mask 668 delete data->mask; 669 data->mask = 0; 670 if ( data->maskedHbm ) { 671 GpiDeleteBitmap( data->maskedHbm ); 672 data->maskedHbm = 0; 673 } 674 } 675 } 623 if ( width() == w && height() == h && 624 ( (d == 1 && depth() == 1) || 625 (d != 1 && depth() != 1 && hasRealAlpha == hasAlphaChannel()) ) ) { 626 // same size etc., use the existing pixmap 627 detach(); 628 if ( data->mask ) { // get rid of the mask 629 delete data->mask; 630 data->mask = 0; 631 if ( data->maskedHbm ) 632 prepareForMasking( FALSE, TRUE ); 633 } 676 634 } else { 677 635 // different size or depth, make a new pixmap 678 QPixmap pm( w, h, d == 1 ? 1 : -1, data->bitmap, data->optim);636 QPixmap pm( w, h, d == 1 ? 1 : -1, data->bitmap, data->optim ); 679 637 *this = pm; 680 638 } 639 640 #if defined QT_CHECK_RANGE 641 if ( d == 32 && trueColorDepth() != 32 ) 642 qWarning( "QPixmap::convertFromImage(): video driver doesn't seem to " 643 "support the 32-bpp color depth!" ); 644 // don't return since we still hope the driver can at least convert 645 // from/to 32-bpp bitmaps 646 #endif 681 647 682 648 int ncols = image.numColors(); … … 707 673 r->bBlue = qBlue( c ); 708 674 r->bGreen = qGreen( c ); 709 r->bRed = qRed( c );675 r->bRed = qRed( c ); 710 676 r->fcOptions = 0; 711 677 if ( doAlloc ) { … … 716 682 } 717 683 718 //@@TODO (dmik): later 719 //#ifndef Q_OS_TEMP 720 // if ( hasRealAlpha ) { 721 // initAlphaPixmap( image.bits(), image.numBytes(), bmi ); 722 // 723 // // Windows expects premultiplied alpha 724 // uchar *p = image.bits(); 725 // uchar *b = data->realAlphaBits; 726 // uchar *end = p + image.numBytes(); 727 // uchar alphaByte; 728 // while ( p < end ) { 729 // alphaByte = *(p+3); 730 // if ( alphaByte == 0 ) { 731 // *(b++) = 0; 732 // *(b++) = 0; 733 // *(b++) = 0; 734 // b++; 735 // p += 4; 736 // } else if ( alphaByte == 255 ) { 737 // b += 4; 738 // p += 4; 739 // } else { 740 // *(b++) = ( (*(p++)) * (int)alphaByte + 127 ) / 255; 741 // *(b++) = ( (*(p++)) * (int)alphaByte + 127 ) / 255; 742 // *(b++) = ( (*(p++)) * (int)alphaByte + 127 ) / 255; 743 // b++; 744 // p++; 745 // } 746 // } 747 // } 748 //#else 749 data->realAlphaBits = 0; 750 //#endif 751 752 if ( data->realAlphaBits == 0 ) { 753 // flip the image top to bottom 754 image.detach(); 755 int bpl = image.bytesPerLine(); 756 uchar *line = new uchar[bpl]; 757 uchar *top = image.scanLine( 0 ); 758 uchar *bottom = image.scanLine( h - 1 ); 759 while( top < bottom ) { 760 memcpy( line, top, bpl ); 761 memcpy( top, bottom, bpl ); 762 memcpy( bottom, line, bpl ); 763 top += bpl; 764 bottom -= bpl; 765 } 766 delete [] line; 767 GpiSetBitmapBits( hps, 0, h, (PBYTE) image.bits(), (PBITMAPINFO2) bmi_data ); 768 } 684 data->hasRealAlpha = hasRealAlpha; 685 686 // If we have real alpha bits and the default video driver depth is 32-bpp, 687 // we store the alpha channel in the unused high byte of the 32-bit pixel 688 // value to save memory and slightly optimize the performance (QImage already 689 // contains the alpha channel there, so nothing has to be done when setting 690 // bitmap bits). Otherwise we create a separate array to store the alpha 691 // channel from QImage. 692 693 if ( hasRealAlpha && depth() != 32 ) { 694 if ( data->realAlphaBits == 0 ) { 695 // alpha bits buffer doesn't exist yet, create it 696 data->realAlphaBits = new uchar [w * h]; 697 } 698 // store alpha bits flipping scan lines top to bottom 699 uchar *dst = data->realAlphaBits + w * (h - 1); 700 int y = 0; 701 while ( y < image.height() ) { 702 uchar *src = image.scanLine( y++ ); 703 uchar *end = src + image.bytesPerLine(); 704 src += 3; 705 while ( src < end ) { 706 *(dst++) = *src; 707 src += 4; 708 } 709 // go to the previous row 710 dst -= w * 2; 711 } 712 } 713 714 // flip the image top to bottom 715 image.detach(); 716 int bpl = image.bytesPerLine(); 717 uchar *line = new uchar[bpl]; 718 uchar *top = image.scanLine( 0 ); 719 uchar *bottom = image.scanLine( h - 1 ); 720 while( top < bottom ) { 721 memcpy( line, top, bpl ); 722 memcpy( top, bottom, bpl ); 723 memcpy( bottom, line, bpl ); 724 top += bpl; 725 bottom -= bpl; 726 } 727 delete [] line; 728 GpiSetBitmapBits( hps, 0, h, (PBYTE) image.bits(), (PBITMAPINFO2) bmi_data ); 769 729 770 730 if ( img.hasAlphaBuffer() ) { 771 731 QBitmap m; 772 732 m = img.createAlphaMask( conversion_flags ); 773 setMask( m ); 733 data->mask = new QBitmap( m ); 774 734 } 775 735 … … 834 794 h = QABS( h ); 835 795 w = QABS( w ); 836 if ( data->realAlphaBits == 0) {796 if ( !data->hasRealAlpha ) { 837 797 QPixmap pm( w, h, depth(), optimization() ); 838 798 POINTL ptls[] = { … … 869 829 } 870 830 871 if ( data-> realAlphaBits) {831 if ( data->hasRealAlpha ) { 872 832 bpp = 32; 873 833 } else { … … 877 837 } 878 838 879 sbpl = ((ws *bpp+31)/32)*4;880 sptr = new uchar[ hs*sbpl];839 sbpl = ((ws * bpp + 31) / 32) * 4; 840 sptr = new uchar[ hs * sbpl ]; 881 841 int ncols; 882 842 if ( bpp <= 8 ) { … … 886 846 } 887 847 848 #if defined QT_CHECK_RANGE 849 if ( bpp == 32 && trueColorDepth() != 32 ) 850 qWarning( "QPixmap::xForm(): video driver doesn't seem to " 851 "support the 32-bpp color depth!" ); 852 // don't return since we still hope the driver can at least convert 853 // from/to 32-bpp bitmaps 854 #endif 855 888 856 // allocate header + ncols palette entries 889 857 int bmi_data_len = sizeof(BITMAPINFOHEADER2) + 4 * ncols; … … 905 873 } 906 874 907 int result; 908 if ( data->realAlphaBits ) { 909 memcpy( sptr, data->realAlphaBits, sbpl*hs ); 910 result = 1; 911 } else { 912 result = GpiQueryBitmapBits( hps, 0, hs, (PBYTE) sptr, (PBITMAPINFO2) bmi_data ); 913 } 914 915 if ( !result ) { // error, return null pixmap 916 delete [] sptr; 917 delete [] bmi_data; 918 return QPixmap( 0, 0, 0, data->bitmap, NormalOptim ); 919 } 920 921 dbpl = ((w*bpp+31)/32)*4; 922 dbytes = dbpl*h; 875 GpiQueryBitmapBits( hps, 0, hs, (PBYTE) sptr, (PBITMAPINFO2) bmi_data ); 876 877 if ( data->hasRealAlpha && data->realAlphaBits ) { 878 // incorporate the alpha channel to image data 879 // (see comments in convertFromImage() for details) 880 int bpx = bpp / 8; 881 int inc = sbpl - bpx * ws; 882 uchar *src = data->realAlphaBits; 883 uchar *dst = sptr + 3; // move to the alpha byte 884 for ( int y = 0; y < hs; ++ y ) { 885 for ( int x = 0; x < ws; ++ x ) { 886 *dst = *(src++); 887 dst += bpx; 888 } 889 dst += inc; 890 } 891 } 892 893 dbpl = ((w * bpp + 31) / 32) * 4; 894 dbytes = dbpl * h; 923 895 924 896 dptr = new uchar[ dbytes ]; // create buffer for bits … … 928 900 else if ( bpp == 8 ) 929 901 memset( dptr, white.pixel(), dbytes ); 930 else if ( data-> realAlphaBits)902 else if ( data->hasRealAlpha ) 931 903 memset( dptr, 0x00, dbytes ); 932 904 else … … 935 907 int xbpl, p_inc; 936 908 if ( depth1 ) { 937 xbpl = (w +7)/8;909 xbpl = (w + 7) / 8; 938 910 p_inc = dbpl - xbpl; 939 911 } else { 940 xbpl = (w *bpp)/8;912 xbpl = (w * bpp) / 8; 941 913 p_inc = dbpl - xbpl; 942 914 } … … 963 935 bmh.cx = w; 964 936 bmh.cy = h; 965 if ( data->realAlphaBits ) { 966 qWarning( "QPixmap::xForm() for pixmaps with alpha is not yet implemented on OS/2" ); 967 /// @todo (dmik) later 968 // pm.initAlphaPixmap( dptr, dbytes, bmi ); 969 } else { 970 GpiSetBitmapBits( pm.hps, 0, h, (PBYTE) dptr, (PBITMAPINFO2) bmi_data ); 971 } 972 delete [] bmi_data; 973 delete [] dptr; 937 GpiSetBitmapBits( pm.hps, 0, h, (PBYTE) dptr, (PBITMAPINFO2) bmi_data ); 938 974 939 if ( data->mask ) { 975 940 QBitmap bm = data->selfmask ? *((QBitmap*)(&pm)) : … … 977 942 pm.setMask( bm ); 978 943 } 944 945 if ( data->hasRealAlpha ) { 946 pm.data->hasRealAlpha = TRUE; 947 if ( pm.depth() != 32 ) { 948 // we are not able to store the alpha channel in the bitmap bits, 949 // store it separately 950 pm.data->realAlphaBits = new uchar[ w * h ]; 951 int bpx = bpp / 8; 952 uchar *dst = pm.data->realAlphaBits; 953 uchar *src = dptr + 3; // move to the alpha byte 954 for ( int y = 0; y < h; ++ y ) { 955 for ( int x = 0; x < w; ++ x ) { 956 *(dst++) = *src; 957 src += bpx; 958 } 959 src += p_inc; 960 } 961 } 962 } 963 964 delete [] bmi_data; 965 delete [] dptr; 966 979 967 return pm; 980 968 } … … 988 976 bool QPixmap::hasAlpha() const 989 977 { 990 return data-> realAlphaBits|| data->mask;978 return data->hasRealAlpha || data->mask; 991 979 } 992 980 993 981 bool QPixmap::hasAlphaChannel() const 994 982 { 995 return data->realAlphaBits != 0; 996 } 997 998 //@@TODO (dmik): later 999 //void QPixmap::convertToAlphaPixmap( bool initAlpha ) 1000 //{ 1001 // char bmi_data[sizeof(BITMAPINFO)]; 1002 // memset( bmi_data, 0, sizeof(BITMAPINFO) ); 1003 // BITMAPINFO *bmi = (BITMAPINFO*)bmi_data; 1004 // BITMAPINFOHEADER *bmh = (BITMAPINFOHEADER*)bmi; 1005 // bmh->biSize = sizeof(BITMAPINFOHEADER); 1006 // bmh->biWidth = width(); 1007 // bmh->biHeight = -height(); // top-down bitmap 1008 // bmh->biPlanes = 1; 1009 // bmh->biBitCount = 32; 1010 // bmh->biCompression = BI_RGB; 1011 // bmh->biSizeImage = width() * height() * 4; 1012 // bmh->biClrUsed = 0; 1013 // bmh->biClrImportant = 0; 1014 // 1015 // QPixmap pm( width(), height(), -1 ); 1016 // pm.initAlphaPixmap( 0, 0, bmi ); 1017 // 1018 //#ifndef Q_OS_TEMP 1019 // GetDIBits( qt_display_dc(), DATA_HBM, 0, height(), pm.data->realAlphaBits, bmi, DIB_RGB_COLORS ); 1020 // if ( initAlpha ) { 1021 // // In bitBlt(), if the destination has an alpha channel and the source 1022 // // doesn't have one, we bitBlt() the source with the destination's 1023 // // alpha channel. In that case, there is no need to initialize the 1024 // // alpha values. 1025 // uchar *p = pm.data->realAlphaBits; 1026 // uchar *pe = p + bmh->biSizeImage; 1027 // if ( mask() ) { 1028 // QImage msk = mask()->convertToImage(); 1029 // int i = 0; 1030 // int w = width(); 1031 // int backgroundIndex = msk.color(0) == Qt::color0.rgb() ? 0 : 1; 1032 // while ( p < pe ) { 1033 // if ( msk.pixelIndex( i%w, i/w ) == backgroundIndex ) { 1034 // *(p++) = 0x00; 1035 // *(p++) = 0x00; 1036 // *(p++) = 0x00; 1037 // *(p++) = 0x00; 1038 // } else { 1039 // p += 3; 1040 // *(p++) = 0xff; 1041 // } 1042 // ++i; 1043 // } 1044 // } else { 1045 // p += 3; 1046 // while ( p < pe ) { 1047 // *p = 0xff; 1048 // p += 4; 1049 // } 1050 // } 1051 // } 1052 //#else 1053 // memcpy( pm.data->ppvBits, data->ppvBits, bmh->biSizeImage ); 1054 //#endif 1055 // if ( mask() ) 1056 // pm.setMask( *mask() ); 1057 // 1058 // *this = pm; 1059 //} 1060 // 1061 //void QPixmap::bitBltAlphaPixmap( QPixmap *dst, int dx, int dy, 1062 // const QPixmap *src, int sx, int sy, 1063 // int sw, int sh, bool useDstAlpha ) 1064 //{ 1065 // if ( sw < 0 ) 1066 // sw = src->width() - sx; 1067 // else 1068 // sw = QMIN( src->width()-sx, sw ); 1069 // sw = QMIN( dst->width()-dx, sw ); 1070 // 1071 // if ( sh < 0 ) 1072 // sh = src->height() - sy ; 1073 // else 1074 // sh = QMIN( src->height()-sy, sh ); 1075 // sh = QMIN( dst->height()-dy, sh ); 1076 // 1077 // if ( sw <= 0 || sh <= 0 ) 1078 // return; 1079 // 1080 //#ifndef Q_OS_TEMP 1081 // GdiFlush(); 1082 //#endif 1083 // uchar *sBits = src->data->realAlphaBits + ( sy * src->width() + sx ) * 4; 1084 // uchar *dBits = dst->data->realAlphaBits + ( dy * dst->width() + dx ) * 4; 1085 // int sw4 = sw * 4; 1086 // int src4 = src->width() * 4; 1087 // int dst4 = dst->width() * 4; 1088 // if ( useDstAlpha ) { 1089 // // Copy the source pixels premultiplied with the destination's alpha 1090 // // channel. The alpha channel remains the destination's alpha channel. 1091 // uchar *sCur; 1092 // uchar *dCur; 1093 // uchar alphaByte; 1094 // for ( int i=0; i<sh; i++ ) { 1095 // sCur = sBits; 1096 // dCur = dBits; 1097 // for ( int j=0; j<sw; j++ ) { 1098 // alphaByte = *(dCur+3); 1099 // if ( alphaByte == 0 || (*(sCur+3)) == 0 ) { 1100 // dCur += 4; 1101 // sCur += 4; 1102 // } else if ( alphaByte == 255 ) { 1103 // *(dCur++) = *(sCur++); 1104 // *(dCur++) = *(sCur++); 1105 // *(dCur++) = *(sCur++); 1106 // dCur++; 1107 // sCur++; 1108 // } else { 1109 // *(dCur++) = ( (*(sCur++)) * (int)alphaByte + 127 ) / 255; 1110 // *(dCur++) = ( (*(sCur++)) * (int)alphaByte + 127 ) / 255; 1111 // *(dCur++) = ( (*(sCur++)) * (int)alphaByte + 127 ) / 255; 1112 // dCur++; 1113 // sCur++; 1114 // } 1115 // } 1116 // sBits += src4; 1117 // dBits += dst4; 1118 // } 1119 // } else { 1120 // // Copy the source into the destination. Use the source's alpha 1121 // // channel. 1122 // for ( int i=0; i<sh; i++ ) { 1123 // memcpy( dBits, sBits, sw4 ); 1124 // sBits += src4; 1125 // dBits += dst4; 1126 // } 1127 // } 1128 //} 1129 1130 // Prepares for painting the masked pixmap: precomposes and selects the 1131 // masked pixmap (with transparent pixels made black) into this pixmap's hps. 1132 // If prepare = FALSE, it does the cleanup. Currently used in ::bitBlt() 1133 // and in QPixmap::createIcon(). 1134 void QPixmap::prepareForMasking( bool prepare ) 983 return data->hasRealAlpha; 984 } 985 986 /** 987 * \internal 988 * If \a prepare is TRUE, prepares for painting a pixmap with mask: precomposes 989 * and selects a masked bitmap (with transparent pixels made black) into this 990 * pixmap's hps. If \a prepare is FALSE, it does the cleanup. If \a force is 991 * TRUE on cleanup, the masked bitmap is destroyed regardless of the 992 * optimization type. 993 * 994 * Currently used in ::bitBlt() and in QPixmap::createIcon(). 995 */ 996 void QPixmap::prepareForMasking( bool prepare, bool force /* = FALSE */ ) 1135 997 { 1136 998 if ( !data->mask || data->selfmask ) … … 1175 1037 GpiSetBitmap( hps, data->hbm ); 1176 1038 // delete the precomposed masked pixmap when memory optimization 1177 // is in force or when no precomosing was done 1178 if ( 1179 data->maskedHbm && 1180 (data->optim != NormalOptim && data->optim != BestOptim) 1181 ) { 1039 // is in force (or force is TRUE) 1040 if ( data->maskedHbm && (force || (data->optim != NormalOptim && 1041 data->optim != BestOptim)) ) { 1182 1042 GpiDeleteBitmap( data->maskedHbm ); 1183 1043 data->maskedHbm = 0; … … 1295 1155 } 1296 1156 1157 void QPixmap::unfoldAlphaChannel() 1158 { 1159 // do nothing if there is no alpha channel or if it is already unfolded 1160 // (i.e. stored in a separate array) 1161 if ( !data->hasRealAlpha || data->realAlphaBits ) 1162 return; 1163 1164 Q_ASSERT( data->d == 32 ); 1165 if ( !data->d == 32 ) 1166 return; 1167 1168 data->realAlphaBits = new uchar[ data->w * data->h ]; 1169 1170 // no space for palette, since the depth is 32-bpp 1171 BITMAPINFOHEADER2 bmh; 1172 memset( &bmh, 0, sizeof(BITMAPINFOHEADER2) ); 1173 bmh.cbFix = sizeof(BITMAPINFOHEADER2); 1174 bmh.cx = data->w; 1175 bmh.cy = data->h; 1176 bmh.cPlanes = 1; 1177 bmh.cBitCount = data->d; 1178 1179 int bpl = ((data->d * data->w + 31) / 32) * 4; 1180 uchar *bits = new uchar [bpl * data->h]; 1181 1182 GpiQueryBitmapBits( hps, 0, data->h, (PBYTE) bits, (PBITMAPINFO2) &bmh ); 1183 1184 int bpx = data->d / 8; 1185 int inc = bpl - bpx * data->w; 1186 uchar *src = bits + 3; // move to the alpha byte 1187 uchar *dst = data->realAlphaBits; 1188 for ( int y = 0; y < data->h; ++ y ) { 1189 for ( int x = 0; x < data->w; ++ x ) { 1190 *(dst++) = *src; 1191 src += bpx; 1192 } 1193 src += inc; 1194 } 1195 1196 delete[] bits; 1197 } 1198 1199 /** 1200 * \internal 1201 * Converts the pixmap (actually, the pixmap's mask, if any) to the alpha 1202 * channel. Implies #unfoldAlphaChannel(). 1203 */ 1204 void QPixmap::convertToAlpha() 1205 { 1206 if ( isNull() || data->hasRealAlpha ) 1207 return; 1208 1209 if ( data->mask ) { 1210 // allocate header + 2 palette entries 1211 char *bmi_data = new char[ sizeof(BITMAPINFOHEADER2) + 8 ]; 1212 memset( bmi_data, 0, sizeof(BITMAPINFOHEADER2) ); 1213 BITMAPINFOHEADER2 &bmh = *(PBITMAPINFOHEADER2) bmi_data; 1214 bmh.cbFix = sizeof(BITMAPINFOHEADER2); 1215 bmh.cx = data->w; 1216 bmh.cy = data->h; 1217 bmh.cPlanes = 1; 1218 bmh.cBitCount = 1; 1219 bmh.cclrUsed = 2; 1220 1221 int bpl = ((data->w + 31) / 32) * 4; 1222 uchar *bits = new uchar [bpl * data->h]; 1223 1224 GpiQueryBitmapBits( data->mask->hps, 0, data->h, (PBYTE) bits, 1225 (PBITMAPINFO2) bmi_data ); 1226 1227 data->realAlphaBits = new uchar[ data->w * data->h ]; 1228 1229 int inc = bpl - data->w / 8; 1230 uchar *src = bits; 1231 uchar *dst = data->realAlphaBits; 1232 uchar m = 0x80; 1233 for ( int y = 0; y < data->h; ++ y ) { 1234 for ( int x = 0; x < data->w; ++ x ) { 1235 *(dst ++) = (*src) & m ? 0xFF : 0x00; 1236 m >>= 1; 1237 if ( !m ) { 1238 m = 0x80; 1239 ++ src; 1240 } 1241 } 1242 src += inc; 1243 } 1244 1245 data->hasRealAlpha = TRUE; 1246 1247 delete[] bits; 1248 delete[] bmi_data; 1249 } else { 1250 data->realAlphaBits = new uchar[ data->w * data->h ]; 1251 memset( data->realAlphaBits, 0xFF, data->w * data->h ); 1252 data->hasRealAlpha = TRUE; 1253 } 1254 } 1255 1256 /** 1257 * \internal 1258 * This depth is used when querying and setting bitmap bits for pixmaps 1259 * with alpha channel, either 24 or 32 (depending on the video driver caps). 1260 * \note This depth is not used to create bitmaps (#defaultDepth() is always 1261 * in charge for that purpose). 1262 */ 1263 //static 1264 int QPixmap::trueColorDepth() 1265 { 1266 static int tcd = 0; 1267 if ( tcd == 0 ) { 1268 HDC display_dc = GpiQueryDevice( qt_display_ps() ); 1269 LONG formatCnt = 0; 1270 DevQueryCaps( display_dc, CAPS_BITMAP_FORMATS, 1, &formatCnt ); 1271 LONG *formats = new LONG[ formatCnt * 2 ]; 1272 GpiQueryDeviceBitmapFormats( qt_display_ps(), formatCnt * 2, formats ); 1273 for( int i = 0; i < formatCnt * 2; i += 2 ) { 1274 if ( formats[ i ] == 1 && formats[ i + 1 ] == 32 ) { 1275 tcd = 32; 1276 break; 1277 } 1278 } 1279 delete[] formats; 1280 // if the 32-bpp format is not supported, we assume the 24-bpp 1281 // format that must be supported by all video drivers 1282 if ( tcd == 0 ) 1283 tcd = 24; 1284 } 1285 return tcd; 1286 } 1287 1297 1288 /*! 1298 1289 \internal … … 1306 1297 \param mini pixmap for a mini-sized pointer/icon 1307 1298 1299 \return PM handle of the created pointer or 0 in case of any error 1300 1308 1301 \note Due to a bug in WinCreatePointerIndirect, you can specify either 1309 1302 \a normal pixmap or \a mini pixmap, but not both (if both are specified, 1310 \a normal will be used). This may be fixed later. 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. 1305 1306 \warning This function is not portable. 1311 1307 */ 1312 1308 // static … … 1316 1312 // Due to a bug in WinCreatePointerIndirect (it always ignores 1317 1313 // hbmMiniPointer and hbmMiniColor fields), we can specify either a normal 1318 // icon (and get a mini icon autocreated by PM) or a mini icon (with a 1319 // normal icon autocreated by PM), but not both. This methods still accepts 1320 // pixmaps for both icon sizes (assuming that we will find a workaround one 1321 // day) but uses only one of them. 1314 // icon, but not both. This methods still accepts pixmaps for both icon 1315 // sizes (assuming that we will find a workaround one day) but uses only 1316 // one of them. 1322 1317 1323 1318 if ( normal && !normal->isNull() ) { … … 1347 1342 return; 1348 1343 } 1349 1344 1345 if ( sw < 0 ) 1346 sw = src->width() - sx; 1347 if ( sh < 0 ) 1348 sh = src->height() - sy; 1349 1350 // ensure coordinates are within borders, clip if necessary 1351 if ( sx < 0 || sy < 0 || sx + sw > src->width() || sy + sh > src->height() || 1352 dx < 0 || dy < 0 || dx + sw > dst->width() || dy + sh > dst->height() ) 1353 { 1354 int tx = dx - sx; 1355 int ty = dy - sy; 1356 QRect dr( 0, 0, dst->width(), dst->height() ); // dst rect 1357 QRect sr( tx, ty, src->width(), src->height() ); // src rect in dst coords 1358 QRect bltr( dx, dy, sw, sh ); // blit rect in dst coords 1359 bltr &= (dr & sr); 1360 if (bltr.isEmpty()) 1361 return; 1362 dx = bltr.x(); 1363 dy = bltr.y(); 1364 sx = dx - tx; 1365 sy = dy - ty; 1366 sw = bltr.width(); 1367 sh = bltr.height(); 1368 } 1369 1370 dst->detach(); 1371 1350 1372 // copy mask data 1351 1373 if ( src->data->mask ) { 1352 if ( ! 1374 if ( !dst->data->mask ) { 1353 1375 dst->data->mask = new QBitmap( dst->width(), dst->height() ); 1354 1355 1376 // new masks are fully opaque by default 1356 1377 dst->data->mask->fill( Qt::color1 ); 1357 1378 } else if ( dst->data->maskedHbm ) { 1358 1379 // reset the precomposed masked pixmap 1359 GpiDeleteBitmap( dst->data->maskedHbm ); 1360 dst->data->maskedHbm = 0; 1380 dst->prepareForMasking( FALSE, TRUE ); 1361 1381 } 1362 1382 … … 1364 1384 src->data->mask, sx, sy, sw, sh, Qt::CopyROP, TRUE ); 1365 1385 } 1366 1367 if ( src->data->realAlphaBits ) { 1368 qWarning( "::copyBlt() for pixmaps with alpha is not yet implemented on OS/2" ); 1369 //@@TODO (dmik): later 1370 // if ( !dst->data->realAlphaBits ) 1371 // dst->convertToAlphaPixmap(); 1372 // QPixmap::bitBltAlphaPixmap( dst, dx, dy, src, sx, sy, sw, sh, FALSE ); 1373 } else { 1374 // copy pixel data 1375 bitBlt( dst, dx, dy, src, sx, sy, sw, sh, Qt::CopyROP, TRUE ); 1376 } 1377 } 1386 1387 // copy alpha bits 1388 if ( src->data->hasRealAlpha || 1389 (src->data->mask && dst->data->hasRealAlpha) ) { 1390 if ( src->data->hasRealAlpha ) 1391 const_cast <QPixmap *> (src)->unfoldAlphaChannel(); 1392 else 1393 const_cast <QPixmap *> (src)->convertToAlpha(); 1394 if ( dst->data->hasRealAlpha ) 1395 dst->unfoldAlphaChannel(); 1396 else 1397 dst->convertToAlpha(); 1398 uchar *srca = src->data->realAlphaBits + src->width() * sy + sx; 1399 uchar *dsta = dst->data->realAlphaBits + dst->width() * dy + dx; 1400 for ( int y = 0; y < sh; ++ y ) { 1401 memcpy( dsta, srca, sw ); 1402 srca += src->width(); 1403 dsta += dst->width(); 1404 } 1405 } 1406 1407 // copy pixel data 1408 bitBlt( dst, dx, dy, src, sx, sy, sw, sh, Qt::CopyROP, TRUE ); 1409 }
Note:
See TracChangeset
for help on using the changeset viewer.