home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Miscellaneous / fontshow source / Fontshow.c next >
Encoding:
C/C++ Source or Header  |  1989-10-17  |  21.6 KB  |  770 lines  |  [TEXT/KAHL]

  1. /******************************************************************************
  2. *                                              The FontShow                                *
  3. *                                                                                                        *
  4. *            (c) 1989 Rainer Fuchs, Am Weingarten 13, 6000 Frankfurt 90, FRG         *
  5. *                                                                                                        *
  6. * History:    17. Oktober   1989 (v1.1.1) Compatible with EZ-Menu                     *
  7. *                10. Oktober   1989 (v1.1)     Font number added; Fontsize added        *
  8. *                 3. Oktober   1989 (v1.0)     multiple sample strings                  *
  9. *                 2. Oktober   1989 (v1.0b3) changed print format                         *
  10. *                26. September 1989 (v1.0b2) changed print format                        *
  11. *                25. September 1989 (v1.0b1) added character table                    *
  12. *                24. September 1989 (v0.0d1) first hack                                        *
  13. *                                                                                              *
  14. ******************************************************************************/
  15.  
  16. #include <PrintMgr.h>
  17. #include <ctype.h>
  18. #include <unix.h>
  19. #include "fontshow.h"
  20.  
  21. /********************************* Prototypes ********************************/
  22.  
  23. extern void ErrorMsg(int index);
  24. extern void ShowInfo(void);
  25. extern Boolean BreakCheck(void);
  26. extern void DrawPage(int i);
  27. extern void ShowFonts(void);
  28. extern int HowMany(void);
  29. extern void PrintFonts(void);
  30. extern pascal void DrawList(WindowPtr theWindow,int itemNo);
  31. extern pascal Boolean myFilter(DialogPtr theDialog,EventRecord *theEvent,
  32.                                int *itemHit);
  33. extern void InitList(WindowPtr theWindow);
  34. extern Boolean SelectFonts(void);
  35. extern void HandleMenu(long sel);
  36. extern void HandleMouseDown(EventRecord event);
  37. extern void MainLoop(void);
  38. extern void InitMenu(void);
  39. extern void InitText(void);
  40. extern void InitPrint(void);
  41. extern void BuildList(void);
  42. extern void InitThings(void);
  43. extern void CleanUp(void);
  44. extern void main(void);
  45.  
  46. /******************************** Global variables ****************************/
  47.  
  48. typedef struct {
  49.     Str255    fontName;                            /* font name                                */
  50.     int        fontNum;                                /* font number                                */
  51.     int        lineHeight;                            /* line height                                */
  52.     int         widMax;                                /* maximal character width                */
  53.     Boolean    flag;                                    /* flag set if font is selected        */
  54. }myFontInfo;                                        /* infos about each font              */
  55.  
  56. myFontInfo    **fontHdl;                            /* pointer to dynamic array of myFontInfos */
  57. ListHandle     myList;                                /* list of font names                     */
  58. CursHandle    myCursor[4];                        /* busy cursor                                 */
  59. MenuHandle     myMenus[5];                            /* menu bar                                    */
  60. THPrint        prRecHdl;                            /* print info                                 */
  61. Handle        myText;                                /* handle to sample text                 */
  62. int            textLength;                            /* sample text length                     */
  63. int             fontCount;                            /* nr of fonts in system                 */
  64. int            opt;                                    /* sample text or character map         */
  65. Boolean         prFlag;                                /* printer or screen output             */
  66. Boolean         quit;                                    /* quit main loop                         */
  67. int            fontSize;                            /* selected font size                    */
  68. int            oldItem;                                /* font size menu item                    */
  69.  
  70. /********************** Error and information handling ************************/
  71.  
  72. void ErrorMsg(index)                                /* alert                                     */
  73. int index;
  74. {
  75.    Str255 theString;
  76.    
  77.    InitCursor();
  78.    GetIndString(theString,128,index);        /* get error msg from rsrc             */
  79.    ParamText(theString,'','','');
  80.    StopAlert(128,NIL);                            /* show error dialog                         */
  81. }
  82.  
  83. void ShowInfo()                                    /* About FontShow…                         */
  84. {
  85.     DialogPtr     myDialog;
  86.     EventRecord    myEvent;
  87.     
  88.    myDialog=GetNewDialog(ABOUT,NIL,(WindowPtr)-1);    /* get dialog from rsrc        */
  89.    DrawDialog(myDialog);                                    /* draw it                        */
  90.    while(!GetNextEvent(keyDownMask|autoKeyMask|mDownMask,&myEvent))
  91.        SystemTask();                                /* wait until event                        */
  92.    DisposDialog(myDialog);                        /* dispose of dialog                        */
  93. }
  94.  
  95. /*********************** Sample text output *********************************/
  96.  
  97. Boolean BreakCheck()                                /* check for break after each page     */
  98. {
  99.     EventRecord theEvent;
  100.     WindowPtr     whichWindow;
  101.     
  102.      for(;;) {    /* mouse clicks in menu bar ignored for comp. with EZ-Menu 
  103.                      *sigh*      */
  104.          while(!GetNextEvent(keyDownMask|autoKeyMask|mDownMask,&theEvent))
  105.            SystemTask();                                /* wait until event                        */
  106.           if ((theEvent.what==keyDown) || (theEvent.what==autoKey)) /* keyDown?        */
  107.           return( (char)BitAnd(theEvent.message,charCodeMask)=='.' &&
  108.                    BitAnd(theEvent.modifiers, cmdKey) != 0);
  109.                           /* if Cmd-dot    then TRUE else FALSE                                */
  110.           else
  111.               if(theEvent.what==mouseDown && FindWindow(theEvent.where,&whichWindow)!=inMenuBar)
  112.                       return(FALSE);   /* click not in MenuBar */
  113.       }
  114. }
  115.  
  116. void DrawPage(i)                                    /* draw sample page                        */
  117. int i;
  118. {
  119.     myFontInfo      *myFont;
  120.     int               lineNr=0;
  121.     char              *pos;
  122.     register int from,to,nr;
  123.     register int c,x,y;
  124.     int             lineH;
  125.     int             wMax;
  126.     Str255         myStr;
  127.     char             buf[4];
  128.     
  129.     myFont= *fontHdl;                                /* Block is already locked !             */        
  130.     lineH=myFont[i].lineHeight;
  131.     wMax=myFont[i].widMax;
  132.  
  133.     TextFont(0);                                    /* draw font name in system font     */
  134.     TextSize(12);                                    /* and 12 pt size                            */
  135.     MoveTo(TOPH,TOPF);                            /*    goto title line                         */
  136.     DrawString(myFont[i].fontName);            /* draw font name                         */
  137.     DrawString("\p (ID=");
  138.     stci_d(buf,myFont[i].fontNum,3);
  139.     DrawString(CtoPstr(buf));
  140.     DrawString("\p)  ");
  141.     stci_d(buf,fontSize,2);
  142.     DrawString(CtoPstr(buf));
  143.     DrawString("\p point.");
  144.     
  145.     TextFont(myFont[i].fontNum);                /* set font                                 */
  146.     TextSize(fontSize);
  147.     
  148.     if(RealFont(myFont[i].fontNum,fontSize)) {
  149.         
  150.         /* sample text */
  151.         
  152.         if(opt==SAMPLE || prFlag) {
  153.             lineNr++;
  154.             HLock(myText);
  155.             from=nr=to=0;
  156.             pos=*myText;
  157.             while(to<textLength) {                    /* break text into single lines         */
  158.                 to++;
  159.                 if( (*pos++==0x0D) || (to==textLength)) {    /* search for CR                 */
  160.                     MoveTo( TOPH, TOPV + lineH*lineNr++ );    /* go to next line            */
  161.                     DrawText(*myText,from,to-from);            /* draw line                     */
  162.                     from = to;
  163.                 }
  164.             }
  165.             HUnlock(myText);
  166.         }
  167.         
  168.         /* sample string */
  169.         
  170.         if(opt==STRING || prFlag ) {
  171.             for(i=1;i;i++) {
  172.                 lineNr++;
  173.                 GetIndString(myStr,STRINGS,i);
  174.                 if(*myStr) {
  175.                     MoveTo( TOPH, TOPV + lineH*lineNr++ );
  176.                     DrawString(myStr);
  177.                 }
  178.                 else break;
  179.             }
  180.         }
  181.         
  182.         /* character map */
  183.     
  184.         if(opt==MAP || prFlag) {
  185.             lineNr++;
  186.             for(c=32;c<256;c++) {                    /* only printable characters            */
  187.                 if(c%32==0) {                            /* 32 char per row                        */
  188.                     x=TOPH;
  189.                     y=TOPV + lineH*lineNr++;        /* new line                                    */
  190.                 }
  191.                 MoveTo(x,y);
  192.                 if(isprint(c))                            /* skip 127                                    */
  193.                     DrawChar((char)c);
  194.                 else
  195.                     DrawChar(32);
  196.                 x+=wMax;                                    /* makes a pretty output                */
  197.             }
  198.         }
  199.     }
  200.     else {
  201.         TextSize(12);
  202.         TextFont(0);
  203.         DrawString("\p Font size not available.");
  204.     }
  205. }
  206.  
  207. void ShowFonts()                                    /* Display fonts                             */
  208. {
  209.     register int i;
  210.     DialogPtr     myDialog;
  211.     WindowPtr      myWindow;
  212.     
  213.     prFlag=FALSE;
  214.     
  215.     if(SelectFonts()) {                            /* only when select dialog is ok        */
  216.         myWindow=GetNewWindow( FONTWINDOW, NIL, (WindowPtr)-1 ); /* open a window */
  217.         myDialog=GetNewDialog(SCREENBREAK,NIL,myWindow);    /* show break information */
  218.         DrawDialog(myDialog);
  219.         SetPort(myWindow);                        
  220.         HLock(fontHdl);
  221.        for (i=0; i<fontCount;i++) {
  222.             if( (*fontHdl)[i].flag)    {            /* draw only selected fonts            */
  223.                 EraseRect(&myWindow->portRect);    /*    clear page                             */
  224.                 DrawPage(i);                        /* draw sample page                         */
  225.                 if (BreakCheck())                    /* check for break                         */
  226.                     break;
  227.             }
  228.         }
  229.         HUnlock(fontHdl);
  230.         DisposeWindow(myWindow);                /* close window and dialog                */
  231.         DisposDialog(myDialog);
  232.     }
  233. }
  234.  
  235. int HowMany()
  236. {
  237.     return( ((**prRecHdl).prJob.bJDocLoop==bDraftLoop) ? 
  238.                 (**prRecHdl).prJob.iCopies : 1 );
  239. }
  240.  
  241. void PrintFonts()                                    /* print fonts                             */
  242. {
  243.     TPPrPort         myPrPort;
  244.     TPrStatus     myPrStatus;
  245.     DialogPtr      mySpoolDlg,myPrintDlg;
  246.     GrafPtr         savePort;
  247.     register int i;
  248.     register int copies;
  249.     int              curs=0;
  250.     
  251.     prFlag=TRUE;                                    /* indicate printing                        */
  252.     
  253.     GetPort(&savePort);                            /* save old grafPort                     */
  254.     PrOpen();                                        /* open PrintMgr                            */
  255.     
  256.     if(SelectFonts() && PrJobDialog(prRecHdl)) { /* get print job infos             */
  257.     /* just in case last printout was cancelled by user: */
  258.         PrintErr=noErr;
  259.         for (copies=HowMany(); copies>0 && PrintErr==noErr; copies--) {
  260.         /* show status information: */
  261.             if((**prRecHdl).prJob.bJDocLoop==bSpoolLoop) 
  262.                 DrawDialog(mySpoolDlg=GetNewDialog(SPOOLINFO,NIL,(WindowPtr)-1));
  263.             else
  264.                 DrawDialog(myPrintDlg=GetNewDialog(PRINTINFO,NIL,(WindowPtr)-1));
  265.                 
  266.             SetCursor(*myCursor[curs++]);        /* we´re busy (rotating watch            */
  267.             if(curs==4) curs=0;
  268.         
  269.             myPrPort=PrOpenDoc(prRecHdl,NIL,NIL); /* open printPort                     */
  270.             SetPort(myPrPort);
  271.             TextSize(12);
  272.             HLock(fontHdl);
  273.            for (i=0; i<fontCount;i++) {
  274.            
  275.                 SetCursor(*myCursor[curs++]);    /* still busy                                 */
  276.                 if(curs==4) curs=0;
  277.         
  278.                if (PrintErr==noErr) {
  279.                     if( (*fontHdl)[i].flag)    {    /* print only selected fonts             */
  280.                         PrOpenPage(myPrPort,NIL);
  281.                         if(PrintErr==noErr)
  282.                             DrawPage(i);            /* print sample page                     */
  283.                         PrClosePage(myPrPort);    
  284.                     }
  285.                 }
  286.             }
  287.             HUnlock(fontHdl);
  288.             PrCloseDoc(myPrPort);                /* close printPort                        */
  289.             
  290.             /* now print spool file */
  291.             
  292.             if((**prRecHdl).prJob.bJDocLoop==bSpoolLoop && PrintErr==noErr) {
  293.                 DisposDialog(mySpoolDlg);
  294.                 DrawDialog(myPrintDlg=GetNewDialog(PRINTINFO,NIL,(WindowPtr)-1));
  295.                 PrPicFile(prRecHdl,NIL,NIL,NIL,&myPrStatus); /* print spool file     */
  296.             }
  297.             
  298.             DisposDialog(myPrintDlg);
  299.         }    
  300.         
  301.         InitCursor();
  302.         if(PrintErr!=noErr)                        
  303.                 ErrorMsg(ERR_PRINT);                /* something went wrong                 */
  304.         else
  305.             SysBeep(10);                            /* notify user                                */
  306.         PrClose();                                    /* close printing manager                */
  307.         SetPort(savePort);                        /* reset old grafPort                    */
  308.     }
  309. }
  310.  
  311. /**************************** Font dialog handling ****************************/
  312.  
  313. pascal void DrawList(theWindow,itemNo)        /* user item routine                        */
  314. WindowPtr theWindow;
  315. int          itemNo;
  316. {
  317.     Rect          rView;
  318.    RgnHandle theRgn;
  319.    int          itemType;
  320.    Handle      item;
  321.    Rect          box;
  322.    
  323.    GetDItem(theWindow,OK,&itemType,&item,&box); /* get rect of OK button         */
  324.    PenSize(3,3);
  325.    InsetRect(&box,-4,-4);                
  326.    FrameRoundRect(&box,16,16);                /* draw bold                                */
  327.    PenSize(1,1);
  328.        
  329.    HLock(myList);
  330.    rView=(**myList).rView;
  331.    InsetRect(&rView,-1,-1);
  332.    FrameRect(&rView);                            /* frame around list                     */
  333.    theRgn=(*theWindow).visRgn;
  334.    LUpdate(theRgn,myList);                        /* update list                             */
  335.    HUnlock(myList);
  336. }
  337.  
  338. pascal Boolean myFilter(theDialog,theEvent,itemHit) /* dialog filter                */
  339. DialogPtr     theDialog;
  340. EventRecord *theEvent;
  341. int             *itemHit;
  342. {
  343.    char       charCode;
  344.    GrafPtr savePort;
  345.    Cell       theCell;
  346.    Boolean flag;
  347.    
  348.    if ((theEvent->what==keyDown) || (theEvent->what==autoKey)) { 
  349.       charCode=(char)BitAnd(theEvent->message,charCodeMask);
  350.       if ((charCode==13) || (charCode==3)) {     /* OK button is default         */
  351.          *itemHit=1;
  352.          return(TRUE);
  353.       }
  354.       else if ((charCode=='.') && (BitAnd(theEvent->modifiers, cmdKey) != 0)) 
  355.       {                                          /* Cmd-dot cancels dialog                 */
  356.          *itemHit=2;
  357.          return(TRUE);
  358.       }
  359.       else return(FALSE);
  360.    }
  361.    
  362.    else {
  363.        if (*itemHit==FLIST) {                    /* list handling                             */
  364.           GetPort(&savePort);
  365.           SetPort((**myList).port);
  366.           GlobalToLocal(&(theEvent->where));    /* convert to local coordinates     */
  367.           flag=LClick(theEvent->where,theEvent->modifiers|cmdKey,myList);
  368.                                                   /* simulate cmd key to fool default list
  369.                                                   definition routine !!! */
  370.           SetPort(savePort);
  371.        }
  372.    
  373.        if(flag==TRUE) {                        /* double click is equal to ok            */
  374.          *itemHit=1;
  375.          return(TRUE);
  376.       }
  377.       else
  378.           return(FALSE);
  379.    }
  380. }
  381.  
  382. void InitList(theWindow)                        /* initialize font list                 */
  383. WindowPtr theWindow;
  384. {
  385.    int              itemType;
  386.    Handle          item;
  387.    Point          csize,theCell;
  388.    Rect              rView,dataBounds;
  389.    register int i;
  390.     myFontInfo      *myFont;
  391.    
  392.    GetDItem(theWindow,FLIST,&itemType,&item,&rView);
  393.    SetRect(&dataBounds,0,0,1,fontCount);    /* set borders of list                    */
  394.    SetPt(&csize,0,0);
  395.    rView.right-=15;                                /* leave room for scroll bar             */
  396.    myList=LNew(&rView,&dataBounds,csize,0,theWindow,TRUE,FALSE,FALSE,TRUE);
  397.    
  398.    HLock(fontHdl);
  399.    myFont= *fontHdl;
  400.    for (i=0; i<fontCount;i++) {                /* fill list with entries from myFontInfo array */
  401.       SetPt(&theCell,0,i);
  402.       LSetCell(myFont[i].fontName+1,*myFont[i].fontName,theCell,myList);
  403.       LSetSelect(myFont[i].flag,theCell,myList);    /* preselect entries            */
  404.    }
  405.    HUnlock(fontHdl);
  406. }
  407.  
  408. Boolean SelectFonts()                            /* handle font select dialog             */
  409. {  
  410.     register int i;
  411.     int               button;
  412.     int                itemType;
  413.     Handle            item;
  414.     Rect                box;
  415.     Cell                theCell;
  416.     Boolean            stop=FALSE;
  417.     myFontInfo      *myFont;
  418.     DialogPtr       myDialog=GetNewDialog(FONTLIST,NIL,(WindowPtr)-1);
  419.                                                             /* Auswahl-Dialog */
  420.  
  421.    GetDItem(myDialog,FLIST,&itemType,&item,&box);   /* get rect of list button */
  422.    SetDItem(myDialog,FLIST,userItem,DrawList,&box); /* install user item         */
  423.       
  424.     InitList(myDialog);                             /* initialize list                         */
  425.      
  426.    ShowWindow(myDialog);                        /* make dialog visible                    */
  427.    while (!stop) {
  428.       SystemTask();
  429.       ModalDialog(myFilter,&button);      /* Dialog anzeigen                         */
  430.       
  431.       switch (button) {
  432.           case EXALL:                               /* deselect all fonts                     */
  433.                for (i=0; i<fontCount;i++) {
  434.                   SetPt(&theCell,0,i);
  435.                   LSetSelect(FALSE,theCell,myList);
  436.                }
  437.                break;
  438.                
  439.          case INALL:                               /* select all fonts                         */
  440.                for (i=0; i<fontCount;i++) {
  441.                   SetPt(&theCell,0,i);
  442.                   LSetSelect(TRUE,theCell,myList);
  443.                }
  444.                break;
  445.            
  446.            case REVERT:                            /* revert to old                             */ 
  447.                HLock(fontHdl);
  448.                myFont= *fontHdl;
  449.                for (i=0; i<fontCount;i++) {
  450.                   SetPt(&theCell,0,i);
  451.                   LSetSelect(myFont[i].flag,theCell,myList);
  452.                }
  453.                HUnlock(fontHdl);
  454.                break;
  455.                
  456.            case Cancel:                            /* dialog cancelled                         */
  457.              stop=TRUE;
  458.              break;
  459.              
  460.          case OK:
  461.                   HLock(fontHdl);
  462.                myFont= *fontHdl;
  463.                for (i=0; i<fontCount;i++) {    /* update myFontInfo array             */
  464.                   SetPt(&theCell,0,i);
  465.                   myFont[i].flag=LGetSelect(FALSE,&theCell,myList);
  466.                }
  467.                HUnlock(fontHdl);
  468.                stop=TRUE;
  469.             break;
  470.       } /* end case */
  471.    }
  472.    
  473.    LDispose(myList);                                /* dispose of list                         */
  474.    DisposDialog(myDialog);                /* dispose of dialog                     */
  475.    return( (button==OK)?TRUE:FALSE);
  476. }
  477.  
  478. /**************************** Event handling ****************************/
  479.  
  480. void HandleMenu(sel)                                /* handle menu bar                         */
  481. long sel;
  482. {
  483.     int       theItem=LoWord(sel);
  484.     Str255  name;
  485.     GrafPtr savePort;
  486.     register int i;
  487.     myFontInfo *myFont;
  488.     FontInfo    fInfo;
  489.     
  490.     switch (HiWord(sel)) {
  491.         case APPLE_M:
  492.             GetItem(myMenus[APPLE], theItem, &name);
  493.             if(theItem==INFO)                        /* About…                                     */
  494.                 ShowInfo();
  495.             else {
  496.                 GetPort(&savePort);                /* save old grafPort (just in case…)*/
  497.                 OpenDeskAcc(&name);                /* open DA                                     */
  498.                 InitCursor();                        /* DA may have changed cursor         */
  499.                 SetPort(savePort);                /*    DA may have changed grafPort         */
  500.             }
  501.             break;
  502.             
  503.         case FILE_M:
  504.             switch(theItem) {
  505.                 case SETUP:
  506.                     PrOpen();                        /* open/close PrintMgr acc. to TN    */
  507.                     PrStlDialog(prRecHdl);        /* get page setup                         */
  508.                     PrClose();
  509.                     break;
  510.                     
  511.                 case DISPLAY:
  512.                     ShowFonts();
  513.                     break;
  514.                     
  515.                 case PRINT:
  516.                     PrintFonts();
  517.                     break;
  518.                     
  519.                 case QUIT:
  520.                     quit=TRUE;
  521.                     break;
  522.             }
  523.             break;
  524.             
  525.         case EDIT_M: 
  526.             SystemEdit(theItem-1); /* our application doesn´t handle EDIT menu     */
  527.             break;
  528.             
  529.         case OPTIONS_M:
  530.             CheckItem(myMenus[OPTIONS],opt,FALSE); /* deselect menu item            */
  531.             CheckItem(myMenus[OPTIONS],opt=theItem,TRUE); /* select new Item        */
  532.             break;
  533.             
  534.         case SIZE_M:
  535.             if(theItem!=oldItem) {
  536.                 SetCursor(*myCursor[0]);
  537.                 CheckItem(myMenus[SIZE],oldItem,FALSE);
  538.                 CheckItem(myMenus[SIZE],oldItem=theItem,TRUE);
  539.                 switch(oldItem) {
  540.                     case SIZE9:
  541.                         fontSize=9;
  542.                         break;
  543.                         
  544.                     case SIZE10:
  545.                         fontSize=10;
  546.                         break;
  547.                         
  548.                     case SIZE12:
  549.                         fontSize=12;
  550.                         break;
  551.                         
  552.                     case SIZE14:
  553.                         fontSize=14;
  554.                         break;
  555.                         
  556.                     case SIZE18:
  557.                         fontSize=18;
  558.                         break;
  559.                         
  560.                     case SIZE20:
  561.                         fontSize=20;
  562.                         break;
  563.                         
  564.                     case SIZE24:
  565.                         fontSize=24;
  566.                         break;
  567.                 }
  568.                 TextSize(fontSize);
  569.                 HLock(fontHdl);
  570.                myFont= *fontHdl;
  571.                for(i=0;i<fontCount;i++) {
  572.                     TextFont(myFont[i].fontNum);                                /* set font         */
  573.                     GetFontInfo(&fInfo);                                            /* and get font info */
  574.                     myFont[i].lineHeight = fInfo.ascent+fInfo.descent+fInfo.leading; /* calc. line height */
  575.                     myFont[i].widMax=fInfo.widMax;                            /* calc. char width */
  576.                 }
  577.                 HUnlock(fontHdl);
  578.                 TextSize(12);
  579.                 TextFont(0);
  580.                 InitCursor();
  581.             }
  582.             break;
  583.     }
  584.     HiliteMenu(0);
  585. }
  586.  
  587. void HandleMouseDown(theEvent)                /* handle mouseDown events             */
  588. EventRecord theEvent;
  589. {
  590.     WindowPtr whichWindow;
  591.     
  592.     switch (FindWindow( theEvent.where, &whichWindow )) {
  593.         case inDesk:
  594.             SysBeep(10);
  595.             break;
  596.             
  597.         case inMenuBar:
  598.             HandleMenu( MenuSelect(theEvent.where) ) ;
  599.             break;
  600.             
  601.         case inSysWindow:
  602.             SystemClick( &theEvent, whichWindow );
  603.             break;
  604.     } /* end switch */
  605. }
  606.  
  607. /*********************************** MainLoop() *******************************/
  608.  
  609. void MainLoop()
  610. {
  611.     EventRecord theEvent;
  612.     
  613.     quit=FALSE;
  614.     while(!quit){
  615.       SystemTask();
  616.         if (GetNextEvent (everyEvent, &theEvent))
  617.               switch (theEvent.what) {
  618.                 case mouseDown:                    /* mouse click                             */
  619.                     HandleMouseDown(theEvent);
  620.                     break;
  621.                     
  622.                 case keyDown:                         /* key click                                 */
  623.                 case autoKey:
  624.                     if ((theEvent.modifiers & cmdKey) != 0) /* we handle only Cmd-key */
  625.                         HandleMenu(MenuKey((char) (theEvent.message & charCodeMask)));
  626.                     break;
  627.             } /* end switch (and if) */
  628.     }    /* end while */
  629. }
  630.  
  631. /*************************** Initialization and main() *************************/
  632.  
  633. void InitMenu()                                    /* Draw menu bar                             */
  634. {
  635.     register int i;
  636.     
  637.     myMenus[APPLE]=GetMenu(APPLE_M);        
  638.     AddResMenu(myMenus[APPLE],'DRVR');        /* insert DAs in Apple-menu             */
  639.     
  640.     myMenus[FILE]=GetMenu(FILE_M);
  641.     myMenus[EDIT]=GetMenu(EDIT_M);
  642.     myMenus[OPTIONS]=GetMenu(OPTIONS_M);
  643.     myMenus[SIZE]=GetMenu(SIZE_M);
  644.     
  645.     CheckItem(myMenus[OPTIONS],opt=SAMPLE,TRUE); /* preselect "sample text"     */
  646.     CheckItem(myMenus[SIZE],oldItem=SIZE12,TRUE); /* preselect font size 12   */
  647.     fontSize=12;
  648.     
  649.     for(i=0;i<5;InsertMenu(myMenus[i++],0))
  650.         ;
  651.     DrawMenuBar();
  652. }
  653.  
  654. void InitText()                                    /* get sample text from rsrc            */
  655. {
  656.     myText=GetResource('TEXT',128);
  657.     textLength=(int)SizeResource(myText);
  658. }
  659.  
  660. void InitPrint()
  661. {
  662.     PrOpen();
  663.     prRecHdl=(THPrint)NewHandle(sizeof(TPrint));    /* get new print record            */
  664.     if(prRecHdl)
  665.         PrintDefault(prRecHdl);                    /* validate it                                */
  666.     else
  667.         ErrorMsg(ERR_NOROOM);
  668.     PrClose();
  669. }
  670.  
  671. void BuildList()                                    /* build font list                         */
  672. {
  673.     register     int i;
  674.     myFontInfo    *myFont;
  675.     FontInfo     fInfo;
  676.     MenuHandle    tempMenu;
  677.     
  678.       /* Get a fake menu; use the Menu Manager to fill it with font names - 
  679.           the Menu Manager sorts entries alphabetically !                                    */
  680.  
  681.    tempMenu = NewMenu(TEMP_M,"x");
  682.    AddResMenu(tempMenu,'FONT');
  683.    fontCount=CountMItems(tempMenu);
  684.    
  685.    /* dynamic allocation of heap space for myFontInfo array                         */
  686.    
  687.    if(fontHdl=(myFontInfo **)NewHandle(fontCount*sizeof(myFontInfo))) {
  688.        HLock(fontHdl);
  689.        TextSize(12);
  690.        myFont= *fontHdl;
  691.        for(i=0;i<fontCount;i++) {
  692.            GetItem(tempMenu,i+1,myFont[i].fontName);                /* get font names */
  693.             GetFNum(myFont[i].fontName,&myFont[i].fontNum);        /* get font numbers */
  694.             TextFont(myFont[i].fontNum);                                /* set font         */
  695.             GetFontInfo(&fInfo);                                            /* and get font info */
  696.             myFont[i].lineHeight = fInfo.ascent+fInfo.descent+fInfo.leading; /* calc. line height */
  697.             myFont[i].widMax=fInfo.widMax;                            /* calc. char width */
  698.             myFont[i].flag=TRUE;                                            /* preselect font */
  699.         }
  700.         HUnlock(fontHdl);
  701.     }
  702.     else
  703.         ErrorMsg(ERR_NOROOM);
  704.         
  705.     DisposeMenu(tempMenu);        /* We’re done with the menu; dispose of it         */
  706.     TextFont(0);                    /* and reset system font                                 */
  707. }
  708.  
  709. void InitThings()
  710. {
  711.     DialogPtr myDialog;
  712.     register int i;
  713.     
  714.    InitGraf(&thePort); 
  715.    MaxApplZone();                         /* we want it all, and we want it NOW !         */
  716.    MoreMasters();                 /* extra pointer blocks at the bottom of the heap */
  717.    MoreMasters();                             /* this is 5 X 64 master pointers    */
  718.    MoreMasters();
  719.    MoreMasters();
  720.    MoreMasters();
  721.  
  722.    InitFonts();                                    /* startup the font manager             */
  723.    InitWindows();                           /* startup the window manager         */
  724.    InitMenus();                             /* startup the menu manager             */
  725.    TEInit();                                /* startup the text edit manager     */
  726.    InitDialogs(NIL);                          /* startup the dialog manager         */
  727.    
  728.    FlushEvents(everyEvent,0);
  729.    
  730.    /* get the cursors we use and lock them down - no clutter                        */
  731.    
  732.    myCursor[0] = GetCursor(watchCursor);
  733.    myCursor[1] = GetCursor(128);
  734.    myCursor[2] = GetCursor(129);
  735.    myCursor[3] = GetCursor(130);
  736.  
  737.    for(i=0;i<4;i++) {
  738.        MoveHHi((Handle)myCursor[i]);
  739.        HLock((Handle)myCursor[i]);
  740.    }
  741.    
  742.     myDialog=GetNewDialog(WAIT,NIL,(WindowPtr)-1);     /* tell user we´re busy     */
  743.     DrawDialog(myDialog);
  744.     InitMenu();                                        /* build menus */
  745.     InitText();                                        /* get sample text                         */
  746.     InitPrint();                                    /* initialize printing                     */
  747.     BuildList();                                  /* build font name list                 */
  748.     DisposDialog(myDialog);
  749.     InitCursor();                                    /* show arrow cursor                     */
  750. }
  751.     
  752. void CleanUp()
  753. {
  754.     register int i;
  755.     
  756.    if(fontHdl)
  757.        DisposHandle(fontHdl);
  758.    if(prRecHdl)
  759.        DisposHandle(prRecHdl);
  760.    for(i=0;i<4;i++)
  761.        HUnlock((Handle)myCursor[i]);
  762. }
  763.  
  764. void main()
  765. {
  766.    InitThings();                           /* initializations                         */
  767.    if(fontHdl && prRecHdl)
  768.        MainLoop();                          /* main routine                             */
  769.    CleanUp();                              /* clean up                                 */
  770. }