ShrinkToBW.c

/*
    File:       ShrinkToBW.c
 
    Contains:   this file contains a routine to illustrate the use of copybits to generate thumbnail images
 
    Written by:     
 
    Copyright:  Copyright © 1994-1999 by Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
 
    Change History (most recent first):
                7/14/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                
 
*/
#include "CarbonPrefix.h"
#include <QDOffscreen.h>
#include <PictUtils.h>
#include <Windows.h>
 
extern RGBColor kRGBBlack ;
extern RGBColor kRGBWhite ;
extern Point gStaggerPos ;
 
void ShrinkToBWPict( WindowPtr theWindow );
 
 
#define SCALEFACTOR     15  // percent
 
void ShrinkToBWPict( WindowPtr theWindow )
{
    Rect        theBounds, tempRect, tempRect2 ;
    GWorldPtr   theOldWorld, theNewWorld ;
    OSErr       theErr ;
    CGrafPtr    savedPort ;
    WindowPtr   newWindow ;
    GDHandle    oldDevice ;
    
    PaletteHandle   thePictPalette = nil ;
    CTabHandle      thePictCTab = nil ;
    
    float       scaleFactor = SCALEFACTOR / 100.0 ;
    
    
    // get the GWorld from the window refcon
    theOldWorld = (GWorldPtr)GetWRefCon ( theWindow );
    
    // get the bounds of the window
    //theBounds = theOldWorld->portRect ;
    GetPortBounds ( theOldWorld, &theBounds );
    
    // apply the scaling factor
    theBounds.top = scaleFactor * theBounds.top ;
    theBounds.left = scaleFactor * theBounds.left ;
    theBounds.bottom = scaleFactor * theBounds.bottom ;
    theBounds.right = scaleFactor * theBounds.right ;
    
    // make a new one-bit gworld to hold the shrunken image
    theErr = NewGWorld( &theNewWorld, 1, &theBounds, nil, nil, 0L ) ;
    
    if( theErr != noErr ) 
        return ;
    
    // save the world
    GetGWorld( &savedPort, &oldDevice ) ;
    SetGWorld( theNewWorld, nil ) ;
    
    
    RGBForeColor( &kRGBBlack ) ;        // ensure the fg and bg colors are 
    RGBBackColor( &kRGBWhite ) ;        // as anticipated
    EraseRect( &theBounds ) ;           // clear the area for the pict
    PenMode( srcCopy ) ;                // ensure the t/f mode is as expected
 
 
    // render the image into the offscreen buffer
    
    /*CopyBits( &((GrafPtr)theOldWorld)->portBits,
              &((GrafPtr)theNewWorld)->portBits,
              &theOldWorld->portRect,
              &theNewWorld->portRect,
              patCopy | ditherCopy,
              nil ) ;*/
    CopyBits(   GetPortBitMapForCopyBits(theOldWorld),
                GetPortBitMapForCopyBits(theNewWorld),
                GetPortBounds(theOldWorld, &tempRect),
                GetPortBounds(theNewWorld, &tempRect2),
                patCopy | ditherCopy,
                nil );
    
    SetGWorld( savedPort, oldDevice ) ;
    
    // create the window
    OffsetRect( &theBounds, gStaggerPos.h, gStaggerPos.v) ;
    gStaggerPos.h += 16 ;
    gStaggerPos.v += 16 ;       // heh - should roll these around, but you wont 
                                // create more than a couple of windows, will you  :-)
                                 
    newWindow  = NewCWindow( nil, &theBounds, "\pplayTime", true, 
                                documentProc, (WindowPtr)-1, true, (long)theNewWorld ); 
    
    // make sure it is visible
    ShowWindow( newWindow ) ;
    
    SetGWorld( (CGrafPtr)newWindow, nil ) ;
    
    // invalidate the content region of the window - we don't do any drawing to it here.
    // Not suppoted in carbon, use InvalWindowRect
    //InvalRect ( &theBounds );
    InvalWindowRect ( newWindow, &theBounds ); 
    
    SetGWorld( savedPort, oldDevice ) ;
}