示例#1
0
/*!
    \internal

    Updates the region handle so that it is suitable for selection to
    a device with the given \a height.
 */
void QRegion::updateHandle(int targetHeight) const
{
    QRegion *self = const_cast<QRegion*>(this); // we're const here

    if (d->rgn != 0) {
        if (self->d->ref == 1) {
            // align region y axis to the top of the device
            POINTL ptl = { 0, targetHeight - d->height };
            GpiOffsetRegion(qt_display_ps(), d->rgn, &ptl);
            self->d->height = targetHeight;
            return;
        }
        // create a copy since the hande may be in use (this will reset d->rgn)
        *self = copy();
    }

    Q_ASSERT(d->rgn == 0);

    // new/updated/copied Qt region data, create a new HRGN for it
    self->d->height = targetHeight;
    if (d->qt_rgn) {
        if (d->qt_rgn->numRects > 0) {
            if (d->qt_rgn->numRects == 1) {
                // d->qt_rgn->rects is empty, use d->qt_rgn->extents instead
                const QRect r = d->qt_rgn->extents;
                RECTL rcl = { r.left(), d->height - (r.bottom() + 1),
                              r.right() + 1, d->height - r.top() };
                self->d->rgn = GpiCreateRegion(qt_display_ps(), 1, &rcl);
            } else {
                PRECTL rcls = new RECTL[d->qt_rgn->numRects];
                for (int i = 0; i < d->qt_rgn->numRects; ++i) {
                    QRect r = d->qt_rgn->rects.at(i);
                    // note RECTL is inclusive-exclusive here
                    rcls[i].xLeft = r.left();
                    rcls[i].yBottom = d->height - (r.bottom() + 1);
                    rcls[i].xRight = r.right() + 1;
                    rcls[i].yTop = d->height - r.top();
                }
                self->d->rgn = GpiCreateRegion(qt_display_ps(),
                                               d->qt_rgn->numRects, rcls);
                delete[] rcls;
            }
            return;
        }
    }

    // create an empty region
    self->d->rgn = GpiCreateRegion(qt_display_ps(), 0, NULL);
}
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::copy() const
{
    QRegion r ( data->is_null );
    r.data->hgt = 0;
    if ( !data->is_null && data->rgn ) {
        HPS hps = qt_display_ps();
        r.data->rgn = GpiCreateRegion( hps, 0, NULL );
        GpiCombineRegion( hps, r.data->rgn, data->rgn, NULL, CRGN_COPY );
        r.data->hgt = data->hgt;
    }
    return r;
}
/*!
 *  \internal
 *  Updates the region handle so that it is suitable for selection to
 *  a device with the given \a height.
 */
void QRegion::updateHandle( int target_height ) const
{
    QRegion *that = const_cast< QRegion *>( this ); // we're const here
    if ( !data->rgn ) {
        // a handle of a null region is requested, allocate an empty region
        that->data->rgn = GpiCreateRegion( qt_display_ps(), 0, NULL );
        that->data->hgt = target_height;
    } else if ( data->hgt != target_height ) {
        // align region y axis to the top of the device
        POINTL ptl = { 0, target_height - data->hgt };
        GpiOffsetRegion( qt_display_ps(), data->rgn, &ptl );
        that->data->hgt = target_height;
    }
}
QRegion QRegion::pmCombine( const QRegion &r, int op ) const
{
    LONG both = CRGN_NOP, left = CRGN_NOP, right = CRGN_NOP;
    switch ( op ) {
	case QRGN_OR:
	    both = CRGN_OR;
	    left = right = CRGN_COPY;
	    break;
	case QRGN_AND:
	    both = CRGN_AND;
	    break;
	case QRGN_SUB:
	    both = CRGN_DIFF;
	    left = CRGN_COPY;
	    break;
	case QRGN_XOR:
	    both = CRGN_XOR;
	    left = right = CRGN_COPY;
	    break;
	default:
#if defined(QT_CHECK_RANGE)
	    qWarning( "QRegion: Internal error in pmCombine" );
#else
	    ;
#endif
    }

    QRegion result( FALSE );
    if ( !data->rgn && !r.data->rgn )
        return result;
    HPS hps = qt_display_ps();
    result.data->rgn = GpiCreateRegion( hps, 0, NULL );
    LONG rc = RGN_NULL; 
    if ( data->rgn && r.data->rgn ) {
        updateHandle( r.data->hgt ); // bring to the same coordinate space
	rc = GpiCombineRegion( hps, result.data->rgn, data->rgn, r.data->rgn, both );
        result.data->hgt = r.data->hgt;
    } else if ( data->rgn && left != CRGN_NOP ) {
	rc = GpiCombineRegion( hps, result.data->rgn, data->rgn, 0, left );
        result.data->hgt = data->hgt;
    } else if ( r.data->rgn && right != CRGN_NOP ) {
	rc = GpiCombineRegion( hps, result.data->rgn, r.data->rgn, 0, right );
        result.data->hgt = r.data->hgt;
    }
    if ( rc == RGN_NULL || rc == RGN_ERROR ) {
        GpiDestroyRegion( hps, result.data->rgn );
        result.data->rgn = result.data->hgt = 0;
    }
    return result;
}
示例#6
0
TkRegion
TkCreateRegion()
{
    HRGN region;
    HPS hps;

    hps= WinGetPS(HWND_DESKTOP);
    region = GpiCreateRegion(hps, 0, NULL);
    WinReleasePS(hps);
#ifdef DEBUG
printf("TkCreateRegion region %x, hps %x\n", region, hps);
#endif
    return (TkRegion) region;
}
示例#7
0
void externalPaint(HWND hwnd)
{
    // hwnd is the value returned by QWidget::winId()

    RECTL rcl;
    WinQueryWindowRect(hwnd, &rcl);
    HPS hps = WinGetPS(hwnd);

    HRGN hrgn = GpiCreateRegion(hps, 1L, &rcl);
    ULONG rc = qt_WinProcessWindowObstacles(hwnd, NULL, hrgn, CRGN_DIFF,
                                            0 /* PWO_Default */);
    if (rc == RGN_RECT || rc == RGN_COMPLEX) {
        HRGN hrgnOld;
        GpiSetClipRegion (hps, hrgn, &hrgnOld);
        hrgn = hrgnOld;

        // Paint to hps using regular PM and GPI calls
    }

    GpiDestroyRegion (hps, hrgn);

    WinReleasePS (hps);
}
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;
}
//----------------------------------------------------------------------------
// NPP_Print:
//----------------------------------------------------------------------------
void NP_LOADDS
NPP_Print(NPP instance, NPPrint* printInfo)
{
    if(printInfo == 0   )   // trap invalid parm
        return;

    if (instance != 0   )
    {
        PluginInstance* This = (PluginInstance*) instance->pdata;

        if (printInfo->mode == NP_FULL)
        {
            //
            // *Developers*: If your plugin would like to take over
            // printing completely when it is in full-screen mode,
            // set printInfo->pluginPrinted to TRUE and print your
            // plugin as you see fit.  If your plugin wants Netscape
            // to handle printing in this case, set printInfo->pluginPrinted
            // to FALSE (the default) and do nothing.  If you do want
            // to handle printing yourself, printOne is true if the
            // print button (as opposed to the print menu) was clicked.
            // On the Macintosh, platformPrint is a THPrint; on Windows,
            // platformPrint is a structure (defined in npapi.h) containing
            // the printer name, port, etc.
            //
            void* platformPrint = printInfo->print.fullPrint.platformPrint;
            NPBool printOne = printInfo->print.fullPrint.printOne;

            printInfo->print.fullPrint.pluginPrinted = FALSE; // Do the default

        }
        else    // If not fullscreen, we must be embedded
        {
            //
            // *Developers*: If your plugin is embedded, or is full-screen
            // but you returned false in pluginPrinted above, NPP_Print
            // will be called with mode == NP_EMBED.  The NPWindow
            // in the printInfo gives the location and dimensions of
            // the embedded plugin on the printed page.  On the Macintosh,
            // platformPrint is the printer port; on Windows, platformPrint
            // is the handle to the printing device context.
            //
            NPWindow* printWindow = &(printInfo->print.embedPrint.window);
            void* platformPrint = printInfo->print.embedPrint.platformPrint;

            /* get Presentation Space and save it */
            HPS hps = (HPS)platformPrint;
            LONG saveID = GpiSavePS(hps);

            /* create GPI various data structures about the drawing area */
            POINTL offWindow = { -(int)printWindow->x, -(int)printWindow->y };
            // POINTL endPoint = { (int)printWindow->width, (int)printWindow->height };
            RECTL rect = { (int)printWindow->x,
                           (int)printWindow->y,
                           (int)printWindow->x + (int)printWindow->width,
                           (int)printWindow->y + (int)printWindow->height };

            /* get model transform so origin is 0,0 */
            MATRIXLF matModel;
            GpiQueryModelTransformMatrix(hps, 9L, &matModel);
            GpiTranslate(hps, &matModel, TRANSFORM_ADD, &offWindow);
            GpiSetModelTransformMatrix(hps, 9L, &matModel, TRANSFORM_REPLACE);

            /* set clipping region so we don't accidently draw outside our rectangle */
            HRGN hrgn, hrgnOld;
            GpiCreateRegion(hps, 1, &rect);
            GpiSetClipRegion(hps, hrgn, &hrgnOld);

            /* draw clock */
            // TBD

            /* restore PS after drawing and delete created objects */
            GpiDestroyRegion(hps, hrgn);
            GpiDestroyRegion(hps, hrgnOld);
            GpiRestorePS(hps, saveID);
        }
    }
}