QRegion::QRegion( const QRect &r, RegionType t ) { data = new QRegionData; Q_CHECK_PTR( data ); data->hgt = 0; data->is_null = FALSE; if ( r.isEmpty() ) { data->rgn = 0; } else { HPS hps = qt_display_ps(); if ( t == Rectangle ) { // rectangular region RECTL rcl = { r.left(), -(r.bottom()+1), r.right()+1, -r.top() }; data->rgn = GpiCreateRegion( hps, 1, &rcl ); } else if ( t == Ellipse ) { // elliptic region // if the width or height of the ellipse is odd, GPI always // converts it to a nearest even value, which is obviously stupid // (see also QPainter::drawArcInternal()). So, we don't use // GpiCreateEllipticRegion(), but create an array of points to // call GpiCreatePolygonRegion() instead. QPointArray a; a.makeArc( r.x(), r.y(), r.width(), r.height(), 0, 360 * 16 ); for ( uint i = 0; i < a.size(); ++ i ) a[i].ry() = -(a[i].y() + 1); // GpiCreatePolygonRegion() is bogus and always starts a poligon from // the current position. Make the last point the current one and reduce // the number of points by one. GpiMove( hps, (PPOINTL) &a[ a.size() - 1 ] ); POLYGON poly = { a.size() - 1, (PPOINTL) a.data() }; data->rgn = GpiCreatePolygonRegion( hps, 1, &poly, POLYGON_ALTERNATE ); } } }
QRegion::QRegion( const QPointArray &a, bool winding ) { data = new QRegionData; CHECK_PTR( data ); data->is_null = FALSE; data->rgn = XPolygonRegion( (XPoint*)a.data(), a.size(), winding ? WindingRule : EvenOddRule ); }
QRegion::QRegion( const QRect &r, RegionType t ) { QRect rr = r.normalize(); data = new QRegionData; CHECK_PTR( data ); data->is_null = FALSE; if ( t == Rectangle ) { // rectangular region data->rgn = XCreateRegion(); XRectangle xr; xr.x = rr.x(); xr.y = rr.y(); xr.width = rr.width(); xr.height = rr.height(); XUnionRectWithRegion( &xr, data->rgn, data->rgn ); } else if ( t == Ellipse ) { // elliptic region QPointArray a; a.makeEllipse( rr.x(), rr.y(), rr.width(), rr.height() ); data->rgn = XPolygonRegion( (XPoint*)a.data(), a.size(), EvenOddRule ); } }