HRGN qt_pm_bitmapToRegion( const QBitmap& bitmap ) { HRGN region = 0; QImage image = bitmap.convertToImage(); const int maxrect = 256; RECTL rects[maxrect]; HPS hps = qt_display_ps(); #define FlushSpans \ { \ HRGN r = GpiCreateRegion( hps, n, rects ); \ if ( region ) { \ GpiCombineRegion( hps, region, region, r, CRGN_OR ); \ GpiDestroyRegion( hps, r ); \ } else { \ region = r; \ } \ } #define AddSpan \ { \ rects[n].xLeft = prev1; \ rects[n].yBottom = -(y+1); \ rects[n].xRight = x-1+1; \ rects[n].yTop = -y; \ n++; \ if ( n == maxrect ) { \ FlushSpans \ n = 0; \ } \ } int n = 0; int zero = 0x00; int x, y; for ( y = 0; y < image.height(); y++ ) { uchar *line = image.scanLine(y); int w = image.width(); uchar all = zero; int prev1 = -1; for ( x = 0; x < w; ) { uchar byte = line[x/8]; if ( x > w-8 || byte != all ) { for ( int b = 8; b > 0 && x < w; b-- ) { if ( !(byte & 0x80) == !all ) { // More of the same } else { // A change. if ( all != zero ) { AddSpan; all = zero; } else { prev1 = x; all = ~zero; } } byte <<= 1; x++; } } else { x += 8; } } if ( all != zero ) { AddSpan; } } if ( n ) { FlushSpans; } if ( !region ) region = GpiCreateRegion( hps, 0, NULL ); return region; }
Region qt_x11_bitmapToRegion(const QBitmap& bitmap) { Region region = XCreateRegion(); QImage image = bitmap.convertToImage(); XRectangle xr; #define AddSpan \ { \ xr.x = prev1; \ xr.y = y; \ xr.width = x-prev1-1; \ xr.height = 1; \ XUnionRectWithRegion( &xr, region, region ); \ } // deal with 0<->1 problem (not on X11 anymore) int zero=0;//(qGray(image.color(0)) < qGray(image.color(1)) ? 0x00 : 0xff); bool little = image.bitOrder() == QImage::LittleEndian; int x, y; for (y=0; y<image.height(); y++) { uchar *line = image.scanLine(y); int w = image.width(); uchar all=zero; int prev1 = -1; for (x=0; x<w; ) { uchar byte = line[x/8]; if ( x>w-8 || byte!=all ) { if ( little ) { for ( int b=8; b>0 && x<w; b-- ) { if ( !(byte&0x01) == !all ) { // More of the same } else { // A change. if ( all!=zero ) { AddSpan; all = zero; } else { prev1 = x; all = ~zero; } } byte >>= 1; x++; } } else { for ( int b=8; b>0 && x<w; b-- ) { if ( !(byte&0x80) == !all ) { // More of the same } else { // A change. if ( all!=zero ) { AddSpan; all = zero; } else { prev1 = x; all = ~zero; } } byte <<= 1; x++; } } } else { x+=8; } }