home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Snippets / Imaging Examples 1.0.1 / Imaging.c < prev    next >
Encoding:
Text File  |  1995-12-01  |  13.6 KB  |  654 lines  |  [TEXT/CWIE]

  1. // Imaging Examples
  2. // by Ken Long <kenlong@netcom.com>
  3. // updated for CW7 and THINK 7 on 951201
  4.  
  5. #include <GestaltEqu.h>
  6.  
  7. #define over qd.screenBits.bounds.right
  8. #define down qd.screenBits.bounds.bottom
  9.  
  10. MenuHandle appleMenu, fileMenu, editMenu, widthMenu;
  11.  
  12. enum {
  13.     appleID = 1,
  14.     fileID,
  15.     editID,
  16.     widthID
  17.     };
  18.  
  19. enum {
  20.     openItem = 1,
  21.     closeItem,
  22.     quitItem = 4
  23.     };
  24.  
  25. enum {
  26.     lineItem = 1,
  27.     sizeItem,
  28.     pattItem,
  29.     rectItem,
  30.     fillItem,
  31.     ovalItem,
  32.     arcsItem,
  33.     dumbItem,
  34.     clipItem,
  35.     triaItem,
  36.     filCItem,
  37.     cPatItem
  38. };
  39.  
  40. WindowPtr shell_window, aboutWindow;
  41. Rect dragRect;
  42. Rect windRect;
  43. short width = 5;
  44. //OSErr QDError;
  45.  
  46. //• Prototypes:
  47. void MyDrawLines (void);
  48. void MyResizePens (void);
  49. void MyRepatternPens (void);
  50. void MyDrawRects (void);
  51. void MyPaintAndFillRects (void);
  52. void MyDrawOvals (void);
  53. void MyDrawArcAndPaintWedge (void);
  54. void MyDrawDumbbell (void);
  55. RgnHandle MyFillClipRegion (void);
  56. void MyDrawTriangle (void);
  57. void MyPaintAndFillColorRects (void);
  58. void SetUpWindow (void);
  59. void SetUpMenus (void);
  60. void AdjustMenus (void);
  61. short enable (MenuHandle menu, short item, short ok);
  62. void HandleMenu (long mSelect);
  63. void InitMacintosh (void);
  64. void HandleMouseDown (EventRecord *theEvent);
  65. void HandleEvent (void);
  66. int DoAbout (void);
  67. Boolean ColorChecksOut (void);
  68. void main (void);
  69.  
  70. //• Routines:
  71.  
  72. void MyDrawLines ()
  73. {
  74.     MoveTo (20, 20);
  75.     LineTo (70, 20);
  76.     LineTo (70, 70);
  77.     LineTo (20, 70);
  78.     LineTo (20, 20);
  79.  
  80.     Move (70, 0);
  81.     Line (50, 0);
  82.     Line (0, 50);
  83.     Line (-50, 0);
  84.     Line (0, -50);
  85. }
  86.  
  87. void MyResizePens ()
  88. {
  89.     PenSize (2, 8);
  90.     MoveTo (20, 20);
  91.     LineTo (70, 20); 
  92.     LineTo (70, 70); 
  93.     LineTo (20, 70); 
  94.     LineTo (20, 20);
  95.     PenSize (8, 2);
  96.     Move (70, 0);
  97.     Line (50, 0); 
  98.     Line (0, 50); 
  99.     Line (-50, 0); 
  100.     Line (0, -50);
  101.     PenNormal ();
  102. }
  103.  
  104. void MyRepatternPens ()
  105. {
  106.     PenSize (2, 8);
  107.     PenPat (&qd.ltGray);
  108.     MoveTo (20, 20);
  109.     LineTo (70, 20); 
  110.     LineTo (70, 70); 
  111.     LineTo (20, 70); 
  112.     LineTo (20, 20);
  113.  
  114.     PenSize (8, 2);
  115.     PenPat (&qd.dkGray);
  116.     Move (70, 0);
  117.     Line (50, 0); 
  118.     Line (0, 50); 
  119.     Line (-50, 0); 
  120.     Line (0, -50);
  121.     PenNormal (); 
  122. }
  123.  
  124. void MyDrawRects ()
  125. {
  126.     Rect firstRect, secondRect;
  127.  
  128.     PenSize (2, 2);
  129.  
  130.     firstRect.top = 20;
  131.     firstRect.left = 20;
  132.     firstRect.bottom = 70;
  133.     firstRect.right = 70;
  134.     FrameRect (&firstRect);
  135.  
  136.     SetRect (&secondRect, 90, 20, 140, 70);
  137.     FrameRect (&secondRect);
  138.  
  139.     PenNormal ();
  140. }
  141.  
  142. void MyPaintAndFillRects ()
  143. {
  144.     Rect firstRect, secondRect;
  145.  
  146.     PenNormal ();
  147.     SetRect (&firstRect, 20, 20, 70, 70);
  148.     PaintRect (&firstRect);
  149.     SetRect (&secondRect, 90, 20, 140, 70);
  150.     FillRect (&secondRect, &qd.ltGray);
  151. }
  152.  
  153. void MyDrawOvals ()
  154. {
  155.     Rect firstRect, secondRect;
  156.  
  157.     PenSize (2, 2);
  158.     SetRect (&firstRect, 20, 20, 70, 70);    //• Create a bounding rectangle.
  159.     FrameOval (&firstRect);                    //• Draw the oval.
  160.     SetRect (&secondRect, 90, 20, 140, 70);    //• Create a bounding rectangle.
  161.     FrameOval (&secondRect);                //• Draw the oval.
  162.     PenNormal ();
  163. }
  164.  
  165. void MyDrawArcAndPaintWedge ()
  166. {
  167.     Rect firstRect, secondRect;
  168.  
  169.     SetRect (&firstRect, 20, 20, 70, 70);            //• create a bounding rectangle.
  170.     FrameArc (&firstRect, 45, 135);            //• draw an arc.
  171.     SetRect (&secondRect, 90, 20, 140, 70);            //• create a bounding rectangle.
  172.     PaintArc (&secondRect, 45, 135);            //• draw a wedge.
  173. }
  174.  
  175. void MyDrawDumbbell ()
  176. {
  177.     long grow;
  178.     RgnHandle dumbbell;
  179.     Rect tempRect;
  180.     Size *kMinReserve;
  181.     
  182. //     if (MaxMem (&grow) > kMinReserve)
  183. //     {
  184.         dumbbell = NewRgn ();            //• Create a new region.
  185.         OpenRgn ();                        //• Begin drawing instructions.
  186.         SetRect (&tempRect, 20, 20, 30, 50);
  187.         FrameOval (&tempRect);            //• Form the left "weight".
  188.         SetRect (&tempRect, 25, 30, 85, 40); 
  189.         FrameRect (&tempRect);            //• Form the bar.
  190.         SetRect (&tempRect, 80, 20, 90, 50); 
  191.         FrameOval (&tempRect);            //• Form the right "weight".
  192.         CloseRgn (dumbbell);            //• Stop collecting.
  193.         FillRgn (dumbbell, &qd.black);    //• Draw the shape onscreen.
  194. //         if (QDError != noErr)
  195. //             ; //• Likely error is that there is insufficient memory.
  196.         DisposeRgn (dumbbell);            //• Dispose of the region.
  197. //    }
  198. }
  199.  
  200. RgnHandle MyFillClipRegion ()
  201. {
  202.     long grow;
  203.     Rect newClip;
  204.     RgnHandle oldClipRegion;
  205.     RgnHandle newClipRegion;
  206.     WindowPtr myWindow;
  207.  
  208.     //• ("if" statement ommented out because it's not a memory demo)
  209. //     if (MaxMem (&grow) > kMinReserve)
  210. //     {
  211.         //• Allocate old clipping region.
  212.         oldClipRegion = NewRgn ();        
  213.         myWindow = FrontWindow ();        //• Get the front window.
  214.  
  215.         //• Make the front window the current graphics port.
  216.         SetPort (myWindow);        
  217.         
  218.         //• Save the old clipping region.
  219.         GetClip (oldClipRegion);    
  220.  
  221.         //• Create a new rectangle.
  222.         newClip = myWindow->portRect;        
  223.  
  224.         //• Exclude vertical scroll bar.
  225.         newClip.right = newClip.right - 15;            
  226.  
  227.         //• Exclude horizontal scroll bar.
  228.         newClip.bottom = newClip.bottom - 15;            
  229.  
  230.         //• Make the new rectangle the clipping region.
  231.         ClipRect (&newClip);    
  232.  
  233.         //• Allocate new clipping region.
  234.         newClipRegion = NewRgn ();        
  235.         RectRgn (newClipRegion, &newClip);
  236.  
  237.         //• Paint clipping region gray.
  238.         FillRgn (newClipRegion, &qd.ltGray);        
  239.  
  240.         //• Restore previous clipping region.
  241.         SetClip (oldClipRegion);
  242.                 
  243. //         if (QDError != noErr)
  244. //             ; //• likely error is that there is insufficient memory.
  245.  
  246.         //• Dispose previous clipping region.
  247.         DisposeRgn (oldClipRegion);        
  248.         return (newClipRegion);
  249. //    }
  250. }
  251.  
  252. void MyDrawTriangle ()
  253. {
  254.     PolyHandle triPoly;
  255.  
  256.     triPoly = OpenPoly ();        //• Save handle and begin collecting lines.
  257.     MoveTo (300, 100);            //• Move to first point.
  258.     LineTo (400, 200);            //• Form the triangle's sides.
  259.     LineTo (200, 200);    
  260.     ClosePoly ();                //• Stop collecting lines.
  261.     FillPoly (triPoly, &qd.gray);//• Fill the polygon with gray.
  262.  
  263. //     if (QDError != noErr)
  264. //         ; //• likely error is that there is insufficient memory.
  265.  
  266.     KillPoly (triPoly)    ; //• dispose of its memory.
  267. }
  268.  
  269. void MyPaintAndFillColorRects ()
  270. {
  271.     Rect firstRect, secondRect;
  272.     
  273.     RGBColor myDarkBlue;
  274.     RGBColor myMediumGreen;
  275.  
  276.     //• create dark blue color.
  277.     myDarkBlue.red = 0x0000;
  278.     myDarkBlue.green = 0x0000;
  279.     myDarkBlue.blue = 0x9999;
  280.     
  281.     //• create medium green color.
  282.     myMediumGreen.red = 0x3206;
  283.     myMediumGreen.green = 0x9038;
  284.     myMediumGreen.blue = 0x013D;
  285.     RGBForeColor (&myDarkBlue);                //• Draw with dark blue pen.
  286.     
  287.     PenMode (patCopy);
  288.     SetRect (&firstRect, 20, 20, 70, 70);
  289.     PaintRect (&firstRect);                    //• Paint a dark blue rectangle.
  290.     RGBForeColor (&myMediumGreen);            //• Draw with a medium green pen.
  291.     SetRect (&secondRect, 90, 20, 140, 70);
  292.     FillRect (&secondRect, &qd.ltGray);        //• Paint a medium green rectangle.
  293. }
  294.  
  295. void MyPaintPixelPatternRects ()
  296. {
  297.     Rect firstRect, secondRect;
  298.     PixPatHandle myPenPattern, myFillPattern;
  299.  
  300.     myPenPattern = GetPixPat (128);            //• Get a pixel pattern.
  301.     PenPixPat (myPenPattern);                //• Assign the pattern to the pen.
  302.     SetRect (&firstRect, 20, 20, 70, 70);
  303.     PaintRect (&firstRect);                    //• Paint with the pen's pixel pattern.
  304.     DisposePixPat (myPenPattern);            //• Dispose of the pixel pattern.
  305.  
  306.     myFillPattern = GetPixPat (129);        //• Get another pixel pattern.
  307.     SetRect (&secondRect, 90, 20, 140, 70);
  308.     FillCRect (&secondRect, myFillPattern);    //• Fill with this pattern.
  309.     DisposePixPat (myFillPattern);            //• Dispose of the pixel pattern.
  310. }
  311.  
  312. void SetUpWindow (void)
  313. {
  314.     dragRect = qd.screenBits.bounds;
  315.  
  316.     SetRect (&windRect, over / 2 - 240, 
  317.                         down / 2 - 150, 
  318.                         over / 2 + 240, 
  319.                         down / 2 + 150);
  320.     
  321.     shell_window = NewCWindow (0L, &windRect, "\pitty bitty bytes™", true, noGrowDocProc, (WindowPtr) -1L, true, 0);
  322.     SetPort (shell_window);
  323. }
  324.  
  325. void SetUpMenus (void)
  326. {
  327.     InsertMenu (appleMenu = NewMenu (appleID, "\p\024"), 0);
  328.     AppendMenu (appleMenu, "\pAbout the demo");
  329.     AddResMenu (appleMenu, 'DRVR');
  330.  
  331.     InsertMenu (fileMenu = NewMenu (fileID, "\pFile"), 0);
  332.     AppendMenu (fileMenu, "\pOpen/O;Close/W;(-;Quit/Q");
  333.  
  334.     InsertMenu (editMenu = NewMenu (editID, "\pEdit"), 0);
  335.     AppendMenu (editMenu, "\pUndo/Z;(-;Cut/X;Copy/C;Paste/V;Clear");
  336.     
  337.     InsertMenu (widthMenu = NewMenu (widthID, "\pExamples"), 0);
  338.     AppendMenu (widthMenu, "\pMyDrawLines/1");
  339.     AppendMenu (widthMenu, "\pMyResizePens/2");
  340.     AppendMenu (widthMenu, "\pMyRepatternPens/3");
  341.     AppendMenu (widthMenu, "\pMyDrawRects/4");
  342.     AppendMenu (widthMenu, "\pMyPaintAndFillRects/5");
  343.     AppendMenu (widthMenu, "\pMyDrawOvals/6");
  344.     AppendMenu (widthMenu, "\pMyDrawArcAndPaintWedge/7");
  345.     AppendMenu (widthMenu, "\pMyDrawDumbell/8");
  346.     AppendMenu (widthMenu, "\pMyFillClipRegion/9");
  347.     AppendMenu (widthMenu, "\pMyDrawTriangle/0");
  348.     AppendMenu (widthMenu, "\pMyPaintAndFillColorRects/-");
  349.     AppendMenu (widthMenu, "\pMyPaintPixelPatternRects/=");
  350.     DrawMenuBar ();
  351. }
  352.  
  353. void AdjustMenus (void)
  354. {
  355.     register WindowPeek wp = (WindowPeek) FrontWindow ();
  356.     short kind = wp ? wp->windowKind : 0;
  357.     Boolean DA = kind < 0;
  358.  
  359.     enable (editMenu, 1, DA);
  360.     enable (editMenu, 3, DA);
  361.     enable (editMenu, 4, DA);
  362.     enable (editMenu, 5, DA);
  363.     enable (editMenu, 6, DA);
  364.  
  365.     enable (fileMenu, openItem, ! ((WindowPeek) shell_window)->visible);
  366.     enable (fileMenu, closeItem, DA || ((WindowPeek) shell_window)->visible);
  367.  
  368. //    CheckItem (widthMenu, width, true);
  369. }
  370.  
  371. short enable (MenuHandle menu, short item, short ok)
  372. {
  373.     if (ok)
  374.         EnableItem (menu, item);
  375.     else
  376.         DisableItem (menu, item);
  377. }
  378.  
  379. Nag ()
  380. {
  381.     MoveTo (40, 40);
  382.     DrawString ("\pBetter get a COLOR Mac!");    
  383. }
  384.  
  385. void HandleMenu (long mSelect)
  386. {
  387.     short menuID = HiWord (mSelect);
  388.     short menuItem = LoWord (mSelect);
  389.     Str255 name;
  390.     GrafPtr savePort;
  391.     WindowPeek frontWindow;
  392.     RGBColor none;
  393.     
  394.     Rect circleStart = shell_window->portRect;
  395.     
  396.     switch (menuID)
  397.     {
  398.         case appleID:
  399.             if (menuItem == 1)
  400.             {
  401.                 EraseRect (&circleStart);
  402.                 DoAbout ();
  403.             }
  404.             else
  405.                 {
  406.                     GetPort (&savePort);
  407.                     GetItem (appleMenu, menuItem, name);
  408.                     OpenDeskAcc (name);
  409.                     SetPort (savePort);
  410.             }
  411.         break;
  412.  
  413.         case fileID:
  414.         switch (menuItem)
  415.         {
  416.             case openItem:
  417.                 ShowWindow (shell_window);
  418.                 SelectWindow (shell_window);
  419.             break;
  420.                                      
  421.             case closeItem:
  422.                 if ((frontWindow = (WindowPeek) FrontWindow ()) == 0L)
  423.                     break;
  424.  
  425.                 if (frontWindow->windowKind < 0)
  426.                     CloseDeskAcc (frontWindow->windowKind);
  427.                 else 
  428.                     if (frontWindow = (WindowPeek) shell_window)
  429.                         ExitToShell ();
  430.                     break;
  431.  
  432.             case quitItem:
  433.                 ExitToShell ();
  434.             break;
  435.         }
  436.         break;
  437.  
  438.         case editID:
  439.         if (!SystemEdit (menuItem-1))
  440.             SysBeep (5);
  441.         break;
  442.  
  443.         case widthID:
  444.         {
  445.             SetPort (shell_window);        //• This is to make sure.
  446.  
  447.             //• Wipe the slate before ____.
  448.             EraseRect (&shell_window->portRect);    
  449.             ForeColor (blackColor);        //• In case it changed.
  450.             
  451.             switch (menuItem)    //• Pick a number between 1 and 10.
  452.             {
  453.                 case lineItem:
  454.                     MyDrawLines ();
  455.                 break;
  456.  
  457.                 case sizeItem:
  458.                     MyResizePens ();
  459.                 break;
  460.  
  461.                 case pattItem:
  462.                     MyRepatternPens ();    
  463.                 break;
  464.  
  465.                 case rectItem:
  466.                     MyDrawRects ();    
  467.                 break;
  468.  
  469.                 case fillItem:    
  470.                     MyPaintAndFillRects ();
  471.                 break;
  472.  
  473.                 case ovalItem:
  474.                     MyDrawOvals ();
  475.                 break;
  476.  
  477.                 case arcsItem:
  478.                     MyDrawArcAndPaintWedge ();
  479.                 break;
  480.  
  481.                 case dumbItem:
  482.                     MyDrawDumbbell ();
  483.                 break;
  484.  
  485.                 case clipItem:
  486.                     MyFillClipRegion ();    
  487.                 break;
  488.  
  489.                 case triaItem:
  490.                     MyDrawTriangle ();
  491.                 break;
  492.                 
  493.                 case filCItem:
  494.                     if (ColorChecksOut ())
  495.                         MyPaintAndFillColorRects ();
  496.                     else
  497.                         Nag ();
  498.                 break;
  499.                 
  500.                 case cPatItem:
  501.                     if (ColorChecksOut ())
  502.                         MyPaintPixelPatternRects ();
  503.                     else
  504.                         Nag ();
  505.                 break;
  506.             }
  507.             BackColor (whiteColor);
  508.             ForeColor (blackColor);
  509.             PenNormal ();
  510.         }
  511.         break;
  512.     }
  513. }
  514.  
  515. void InitMacintosh (void)
  516. {
  517.     MaxApplZone ();
  518.  
  519.     InitGraf (&qd.thePort);
  520.     InitFonts ();
  521.     FlushEvents (everyEvent, 0);
  522.     InitWindows ();
  523.     InitMenus ();
  524.     TEInit ();
  525.     InitDialogs (0L);
  526.     InitCursor ();
  527. }
  528.  
  529. void HandleMouseDown (EventRecord *theEvent)
  530. {
  531.     WindowPtr theWindow;
  532.     short windowCode = FindWindow (theEvent->where, &theWindow);
  533.  
  534.     switch (windowCode)
  535.     {
  536.         case inSysWindow: 
  537.             SystemClick (theEvent, theWindow);
  538.         break;
  539.  
  540.         case inMenuBar:
  541.             AdjustMenus ();
  542.             HandleMenu (MenuSelect (theEvent->where));
  543.         break;
  544.  
  545.         case inDrag:
  546.             if (theWindow == shell_window)
  547.                 DragWindow (shell_window, theEvent->where, &dragRect);
  548.         break;
  549.  
  550.         case inContent:
  551.             if (theWindow == shell_window)
  552.             {
  553.                 if (theWindow != FrontWindow ())
  554.                     SelectWindow (shell_window);
  555.                 else
  556.                     InvalRect (&shell_window->portRect);
  557.             }
  558.         break;
  559.  
  560.         case inGoAway:
  561.             if (theWindow == shell_window && 
  562.                 TrackGoAway (shell_window, theEvent->where))
  563.                 ExitToShell ();
  564.             if (theWindow == aboutWindow && 
  565.                 TrackGoAway (aboutWindow, theEvent->where))
  566.                 HideWindow (aboutWindow);
  567.         break;
  568.     }
  569. }
  570.  
  571. void HandleEvent (void)
  572. {
  573.     short ok;
  574.     EventRecord theEvent;
  575.  
  576.     HiliteMenu (0);
  577.     SystemTask (); /* Handle desk accessories */
  578.  
  579.     ok = GetNextEvent (everyEvent, &theEvent);
  580.     if (ok)
  581.         switch (theEvent.what)
  582.         {
  583.             case mouseDown:
  584.                 HandleMouseDown (&theEvent);
  585.             break;
  586.  
  587.             case keyDown: 
  588.             case autoKey:
  589.                 if ((theEvent.modifiers & cmdKey) != 0)
  590.                 {
  591.                     AdjustMenus ();
  592.                     HandleMenu (MenuKey ((char) (theEvent.message & charCodeMask)));
  593.                 }
  594.             break;
  595.  
  596.             case updateEvt:
  597.                 BeginUpdate (shell_window);
  598.                 EndUpdate (shell_window);
  599.             break;
  600.  
  601.             case activateEvt:
  602.                 InvalRect (&shell_window->portRect);
  603.             break;
  604.         }
  605. }
  606.  
  607. DoAbout ()
  608. {
  609.     Rect boutRect;
  610.     
  611.     SetRect (&boutRect, over / 2 - 200, 
  612.                         down / 2 - 100, 
  613.                         over / 2 + 200, 
  614.                         down / 2 + 100);
  615.     
  616.     aboutWindow = NewWindow (0L, &boutRect, "\pSay WHAT?", 
  617.                              true, noGrowDocProc, (WindowPtr) -1L, 
  618.                              true, 0);
  619.     SetPort (aboutWindow);
  620.     
  621.     MoveTo (20,20);
  622.     DrawString ("\pFrustrated by no C source examples in IM?");
  623.     MoveTo (20,40);
  624.     DrawString ("\pWell, itty bitty bytes™ to the rescue!");
  625.     MoveTo (20,60);
  626.     DrawString ("\pTranslated to C by Kenneth A. Long.");
  627.     MoveTo (20,80);
  628.     DrawString ("\pThese are 12 examples from \"Imaging\"");
  629. }
  630.  
  631. Boolean    ColorChecksOut (void)
  632. {
  633.     unsigned char    version[ 4 ];
  634.     OSErr            err;
  635.     
  636.     err = Gestalt( gestaltQuickdrawVersion, (long *)version );
  637.     
  638.     if ( version[ 2 ] > 0 )
  639.         return( true );
  640.     else
  641.         return( false );
  642. }
  643.  
  644. void main (void)
  645. {
  646.     InitMacintosh ();
  647.     SetUpMenus ();
  648.     SetUpWindow ();
  649.  
  650.     for (;;)
  651.         HandleEvent ();
  652. }
  653.  
  654.