/*! \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; }
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; }
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); } } }