[comp.sys.mac.programmer] Rolling your own 32-bit offscreen pixmaps

jwhitnell@cup.portal.com (Jerry D Whitnell) (08/03/90)

Tim M. Writes...
|In article <32082@cup.portal.com> jwhitnell@cup.portal.com (Jerry D Whitnell)
writes:
|>A couple of things to check:  the pixelType, pixelSize, cmdCount and cmpSize
|>fields in the PixMap.  For 32-bit PixMaps, they should be chunky, 32, 3 and 8
.
|>Also check the gdType field in the graphics device, it should be direct RGB,
|>not CLUT.
|
|Um, I agree with everything here except the pixelType.  According to the
|32-bit quickdraw manual, page 3, pixelType should be RGBDirect = 16, not
|chunky = 0.

Ah, yes, just testing you...  Do as I do, not as I say :-).


The only difference I could find between your code and mine is the settting
of the GDevice flags.  You set yours to $4001, I set mine to:

#define kGDFlags  ((1 << screenActive) + (1 << noDriver) +\
		(1<<ramInit) + (1<<gdDevType))


Here is an extraction of the C version that seems to work (Mac II fx with
no 32-bit QuickDraw).

void CGrafPtrOffscreen :: IGrafPtrOffscreen(Rect *offBounds, CTabHandle 
itsColors,
         int depth )

        {
#define kGDFlags                        ((1 << screenActive) + (1 << noDriver) 
+ (1<<ramInit) + (1<<gdDevType))
#define kNoDriver                       0                               
        /* passed to NewGDevice. */
#define kModeForNoDriver        -1                                      /* 
passed to NewGDevice. */

                Boolean                         oldPerm;
                Boolean                         dummy;                  
        /* dummy result for PermAllocation. */
                /*fi:                           FailInfo;*/
                GDHandle                        anOffDevice;
                OSErr                           retCode;
                PixMapHandle            gdPMap;


                fOffPort = NULL;
                fOffDevice = NULL;
                fBigBuff = NULL;
                fDepth = depth;
                
                this->IOffscreen();

                this->SaveOldWorld();

                this->MakeStorage( offBounds, depth );

                anOffDevice = NewGDevice(kNoDriver, kModeForNoDriver);
                fOffDevice = anOffDevice;

                MoveHHi( (Handle) fOffDevice );
                HLock( (Handle) fOffDevice );

                (**fOffDevice).gdID = 0;                                /* no 
ID for search & complement procs */
                (**fOffDevice).gdType = clutType;               /* color table 
type fer sure. */
                gdPMap = (**fOffDevice).gdPMap;
                
                if ( depth != 32 ) {
                        DisposCTable((**gdPMap).pmTable); 
                        if ( itsColors == NULL )
                                itsColors = GetCTable( depth );
                        /*else
                                retCode = HandToHand((Handle *)&itsColors);*/
        
                        (**gdPMap).pmTable = itsColors; 
                        MakeITable((**gdPMap).pmTable, 
				(**fOffDevice).gdITable, 3);
                        retCode = QDError(); 
                }
                (**fOffDevice).gdResPref = 3;
                (**fOffDevice).gdSearchProc = NULL;     
                (**fOffDevice).gdCompProc = NULL;

                (**fOffDevice).gdFlags = kGDFlags;

        
                (**gdPMap).rowBytes = fRowBytes | 0x8000;
                (**gdPMap).pixelSize = depth;
                if ( depth == 32 ) {
                        (**gdPMap).cmpCount = 3;
                        (**gdPMap).cmpSize = 8;
                        (**gdPMap).pixelType = RGBDirect;
                } else {
                        assert( depth <= 8 );
                        (**gdPMap).cmpCount = 1;
                        (**gdPMap).cmpSize = depth;
                        (**gdPMap).pixelType = 0;
                }

                (**gdPMap).baseAddr = fBigBuff; 
                (**gdPMap).bounds = *offBounds; 

                (**fOffDevice).gdRect = *offBounds;
                
                HUnlock((Handle)fOffDevice);


                SetGDevice(fOffDevice);

                MakeOffPort( offBounds );
                
                this->SetupOffWorld();
           	EraseRect(offBounds);           
                this->RestoreOldWorld();

        }

void CGrafakeOffrt(Rect *offBounds ) {
                fOffPort = (CGrafPtr) NewPointer( sizeof(CGrafPort) );
        
                OpenCPort(fOffPort);                                    
        /* make a new port offscreen. */


                RectRgn(fOffPort->visRgn, offBounds);

              fOffPort->portRect = *offBounds;

}

void CCGrafPtrOffscreen :: MakeStorage(Rect *offBounds, int depth ) {
        long                            docW, docH;
        Ptr                                     aBuffPointer;

        docW = offBounds->right - offBounds->left;
        docW = (docW + 31) / 32;
        docW *= 32;
        fRowBytes = docW * depth / 8;
        docH = offBounds->bottom - offBounds->top;

        aBuffPointer = NewPointer(docH * fRowBytes);
        fBigBuff = aBuffPointer;
}


No guraentees that it compiles, etc.  But it may help

Jerry Whitnell