home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C++ / Applications / PICSee Dust 1.01 / Secondary Source / CropPICTs.cpp next >
Encoding:
C/C++ Source or Header  |  1995-11-13  |  6.3 KB  |  234 lines  |  [TEXT/CWIE]

  1. /*
  2.     Crop a PICT resource
  3.     ...allowing one to crop a PICS file or a series of PICT files
  4. */
  5.  
  6. #include <QDOffscreen.h>
  7. #include "CropPICTs.h"
  8. #include "PICS_Types.h"
  9. #include "SavePicture.h"
  10. #include "assert_mac.h"
  11. #include "QDUtils.h"        // For CenterRect
  12. #include "FileRegistry.h"
  13.  
  14. // ---------------------------------------------------------------------------
  15.  
  16. /*
  17.     The <picBuffer> is assumed to be at least the same or larger
  18.     dimensions than that of <inputPic>. If you pass the address of
  19.     an empty PicHandle to <croppedPic>, CropPICT will record the
  20.     cropped <inputPic> as a picture to <croppedPic>. If you pass NULL
  21.     instead, no picture will be saved.
  22.     
  23.     <destBuffer> may be the same as <picBuffer>
  24.     <srcCropRect> may be the same as <destCropRect>
  25. */
  26.  
  27. Boolean CropPICT(
  28.     const PicHandle    inputPic,
  29.     const GraphicsBufferPtr    picBuffer,
  30.     const GraphicsBufferPtr    destBuffer,
  31.     const Rect        *srcCropRect,
  32.     const Rect        *destCropRect,
  33.     PicHandle        *croppedPic) {
  34.  
  35.     GWorldPtr    saveWorld;
  36.     GDHandle    saveDev;
  37.     Rect        picRect;
  38.     Boolean        result;
  39.  
  40.     ASSERT(inputPic != NULL);
  41.     ASSERT(picBuffer != NULL);
  42.     ASSERT(destBuffer != NULL);
  43.     ASSERT(srcCropRect != NULL);
  44.     ASSERT(destCropRect != NULL);
  45.  
  46.     GetGWorld(&saveWorld, &saveDev);
  47.     SetGraphicsBuffer(picBuffer);
  48.     picRect = (**inputPic).picFrame;
  49.     FlushRectTopLeft(&picRect);
  50.     DrawPicture(inputPic, &picRect);
  51.  
  52.     result = CapturePICT(picBuffer, destBuffer, srcCropRect, destCropRect, croppedPic);
  53.  
  54.     SetGWorld(saveWorld, saveDev);    
  55.     return(result);
  56. } // END CropPICT
  57.  
  58. // ---------------------------------------------------------------------------
  59.  
  60. Boolean CapturePICT(
  61.     const GraphicsBufferPtr    srcBuffer,
  62.     const GraphicsBufferPtr    destBuffer,
  63.     const Rect        *srcRect,
  64.     const Rect        *destRect,
  65.     PicHandle        *croppedPic) {
  66.  
  67.     GWorldPtr    saveWorld;
  68.     GDHandle    saveDev;
  69.     Rect        clipRect;
  70.     RgnHandle    saveClip;
  71.     
  72.     ASSERT(srcBuffer != NULL);
  73.     ASSERT(destBuffer != NULL);
  74.     ASSERT(srcRect != NULL);
  75.     ASSERT(destRect != NULL);
  76.  
  77.     GetGWorld(&saveWorld, &saveDev);
  78.     SetGraphicsBuffer(destBuffer);
  79.  
  80.     if (croppedPic != NULL) {
  81.         saveClip = NewRgn();
  82.         ASSERT(saveClip != NULL);
  83.         GetClip(saveClip);
  84.         GetGraphicsBufferBounds(destBuffer, (CP_Rect*)&clipRect);
  85.         // It's in global coords so we have to adjust it
  86.         FlushRectTopLeft(&clipRect);
  87.         ClipRect(&clipRect);
  88.     
  89.         *croppedPic = OpenPicture(destRect);
  90.         ASSERT(*croppedPic != NULL);
  91.     }
  92.  
  93.     CopyGraphicsBuffer(srcBuffer, destBuffer,
  94.         (CP_Rect*)srcRect, (CP_Rect*)destRect);
  95.  
  96.     if (croppedPic != NULL) {
  97.         ClosePicture();
  98.         ASSERT(*croppedPic != NULL);
  99.  
  100.         SetClip(saveClip);
  101.         DisposeRgn(saveClip);
  102.         SetGWorld(saveWorld, saveDev);
  103.     }
  104.     
  105.     return(true);
  106. } // END CapturePICT
  107.  
  108. // ---------------------------------------------------------------------------
  109.  
  110. /*
  111.     This routine assumes you already have picked the input <picsFile> and
  112.     created the output <outputFile>. It also assumes that you have set the
  113.     depth of monitor <outputDevice> appropriately, prior to calling the routine.
  114.     (CropPICSFile uses the depth of <outputDevice> to determine the depth
  115.     of the output PICS frames).
  116.     
  117.     Technically, the order of the frames in a PICS file should be by
  118.     resource ID. However, a few programs just assume it's by the order
  119.     of the resources in the resource file. BIG MISTAKE! If you should
  120.     use ResEdit to cut and paste in the PICS file, the order will be
  121.     changed (but the resource id shouldn't be - and you can always change
  122.     that, unlike the order). So we'll be flexible by adding the
  123.     <traversePICSByID> parameter.
  124. */
  125.  
  126. OSErr CropPICSFile(
  127.     Boolean            traversePICSByID,
  128.     const Rect        *cropArea,
  129.     const GDHandle    outputDevice,
  130.     const FSSpec    *picsFile,
  131.     const FSSpec    *outputFile) {
  132.     
  133.     short inputFileRef;
  134.     short outputFileRef;
  135.     short numPicts;
  136.     
  137.     ASSERT(cropArea != NULL);
  138.     ASSERT(outputDevice != NULL);
  139.     ASSERT(picsFile != NULL);
  140.     ASSERT(outputFile != NULL);
  141.  
  142.     inputFileRef = FSpOpenResFile(picsFile, fsRdWrPerm);
  143.     if (inputFileRef == -1 || !RegisterFile(inputFileRef)) {
  144.         return(ResError());
  145.     }
  146.     
  147.     outputFileRef = FSpOpenResFile(outputFile, fsRdWrPerm);
  148.     if (outputFileRef == -1 || !RegisterFile(outputFileRef)) {
  149.         return(ResError());
  150.     }
  151.     
  152.     UseResFile(inputFileRef);
  153.     numPicts = Count1Resources(kPICSRsrcType);
  154.     if (numPicts < 1) {
  155.         (void)UnregisterFile(inputFileRef);
  156.         (void)UnregisterFile(outputFileRef);
  157.         CloseResFile(inputFileRef);
  158.         CloseResFile(outputFileRef);
  159.         return(-1);
  160.     }
  161.     
  162.     short        i;
  163.     short        resID;
  164.     PicHandle    inputPict;
  165.     PicHandle    outputPict;
  166.     Rect        cropBufferRect;
  167.     Rect        outputDeviceRect;
  168.     Rect        outputCropRect;
  169.     GBErr        gbErr;
  170.     GWorldPtr    saveWorld;
  171.     GDHandle    saveDev;
  172.     GraphicsBufferPtr cropBuffer;
  173.  
  174.     GetGWorld(&saveWorld, &saveDev);
  175.  
  176.     // Pre-fetch one PICT rsrc to get it's dimensions
  177.     inputPict = (PicHandle)Get1IndResource(kPICSRsrcType, 1);
  178.     cropBufferRect = (**inputPict).picFrame;
  179.  
  180.     // Allocate offscreen graphics buffer
  181.     outputDeviceRect = (**outputDevice).gdRect;
  182.     // Place cropBuffer onto the device we're to "work on" (make global coords)
  183.     CenterRect(&cropBufferRect, &outputDeviceRect);
  184.     gbErr = NewGraphicsBuffer(&cropBuffer, 0, (CP_Rect*)&cropBufferRect,
  185.         kGBOptimalFlag, 0);
  186.     // Restore to local coords
  187.     FlushRectTopLeft(&cropBufferRect);
  188.     
  189.     outputCropRect = *cropArea;
  190.     FlushRectTopLeft(&outputCropRect);
  191.  
  192.     // For PICS files, we'll assume the rsrc id ALWAYS starts at 128.
  193.     for (i = 1, resID = kPICSRsrcStartID; i <= numPicts; i++, resID++) {
  194.         if (traversePICSByID)
  195.             inputPict = (PicHandle)Get1Resource(kPICSRsrcType, resID);
  196.         else
  197.             inputPict = (PicHandle)Get1IndResource(kPICSRsrcType, i);
  198.  
  199.         if (inputPict == NULL) {
  200.             (void)UnregisterFile(inputFileRef);
  201.             (void)UnregisterFile(outputFileRef);
  202.             CloseResFile(inputFileRef);
  203.             CloseResFile(outputFileRef);
  204.             DisposeGraphicsBuffer(cropBuffer);
  205.             return(-2);
  206.         }
  207.  
  208.         // Crop it!
  209.         (void)CropPICT(inputPict, cropBuffer, cropBuffer,
  210.             cropArea, &outputCropRect, &outputPict);
  211.         ReleaseResource((Handle)inputPict);
  212.  
  213.         if (!SavePictureResource(outputPict, outputFileRef, resID, NULL)) {
  214.             (void)UnregisterFile(inputFileRef);
  215.             (void)UnregisterFile(outputFileRef);
  216.             CloseResFile(inputFileRef);
  217.             CloseResFile(outputFileRef);
  218.             DisposeGraphicsBuffer(cropBuffer);
  219.             return(-3);
  220.         }
  221.         
  222.         // Dispose & release memory
  223.         KillPicture(outputPict);
  224.     }
  225.  
  226.     SetGWorld(saveWorld, saveDev);
  227.     (void)UnregisterFile(inputFileRef);
  228.     (void)UnregisterFile(outputFileRef);
  229.     CloseResFile(inputFileRef);
  230.     CloseResFile(outputFileRef);
  231.     DisposeGraphicsBuffer(cropBuffer);
  232.     return(noErr);
  233. } // END CropPICSFile
  234.