home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / macintosh-c / macc-carbon-demos-nonbinhex.sit / macc-carbon-demos-nonbinhex / chap15-demo / CarbonPrinting.c < prev    next >
C/C++ Source or Header  |  2001-06-25  |  25KB  |  878 lines

  1. // *******************************************************************************************
  2. // CarbonPrinting.c
  3. // *******************************************************************************************
  4.  
  5. // ………………………………………………………………………………………………………………………………………………………………………………………………………………………… includes
  6.  
  7. #include "CarbonPrinting.h"
  8.  
  9. // …………………………………………………………………………………………………………………………………………………………………………………………………… global variables
  10.  
  11. Boolean                    gRunningOnX = false;
  12. WindowRef                gDocumentWindowRef, gPrintInfoWindowRef;
  13. SInt16                    gFontNumber;
  14. SInt16                    gFontSize;
  15. Boolean                    gDone;
  16. PMItemUPP                gNewItemEvaluateFunctionUPP;
  17. ModalFilterUPP    gEventFilterUPP;
  18. PMPrintSettings gPrintSettings = kPMNoPrintSettings;
  19. PMDialog                gPMDialog;
  20. UInt32                    gFirstPage, gLastPage, gCopies;
  21. Boolean                    gDrawPrintSettingsStuff;
  22.  
  23. // ************************************************************************************** main
  24.  
  25. void  main(void)
  26. {
  27.     MenuBarHandle        menubarHdl;
  28.     SInt32                    response;
  29.     MenuRef                    menuRef;
  30.     docStructureHdl    docStrucHdl;
  31.     SInt16                    fontNum;
  32.     RGBColor                whiteColour    = { 0xFFFF, 0xFFFF, 0xFFFF };
  33.     RGBColor                blueColour    = { 0x4444, 0x4444, 0x9999 };
  34.     Rect                        portRect;
  35.     EventRecord            eventStructure;
  36.     Boolean                    gotEvent;
  37.  
  38.     // ………………………………………………………………………………………………………………………………………………………………………………………………… do prelimiaries
  39.  
  40.     doPreliminaries();
  41.  
  42.     // ……………………………………………………………………………………………………………………………………………………………………… set up menu bar and menus
  43.  
  44.     menubarHdl = GetNewMBar(rMenubar);
  45.     if(menubarHdl == NULL)
  46.         ExitToShell();
  47.     SetMenuBar(menubarHdl);
  48.     DrawMenuBar();
  49.  
  50.     Gestalt(gestaltMenuMgrAttr,&response);
  51.     if(response & gestaltMenuMgrAquaLayoutMask)
  52.     {
  53.         menuRef = GetMenuRef(mFile);
  54.         if(menuRef != NULL)
  55.         {
  56.             DeleteMenuItem(menuRef,iQuit);
  57.             DeleteMenuItem(menuRef,iQuit - 1);
  58.         }
  59.  
  60.         gRunningOnX = true;
  61.     }
  62.  
  63.     // …………………………………………………………………………………………………… open document window and attach document structure
  64.  
  65.     if(!(gDocumentWindowRef = GetNewCWindow(rDocWindow,NULL,(WindowRef)-1)))
  66.         ExitToShell();
  67.     
  68.     SetPortWindowPort(gDocumentWindowRef);
  69.     GetFNum("\pGeneva",&fontNum);
  70.     TextFont(fontNum);
  71.     TextSize(10);
  72.     gFontNumber = fontNum;
  73.     gFontSize = 10;
  74.     
  75.     if(!(docStrucHdl = (docStructureHdl) NewHandle(sizeof(docStructure))))
  76.         ExitToShell();
  77.     SetWRefCon(gDocumentWindowRef,(SInt32) docStrucHdl);
  78.  
  79.     (*docStrucHdl)->printSession    = NULL;
  80.     (*docStrucHdl)->pageFormat        = kPMNoPageFormat;
  81.     (*docStrucHdl)->printSettings = kPMNoPrintSettings;
  82.  
  83.     // …………………………………………………………………………………………………………………………………………………… open printing information window
  84.     
  85.     if(!(gPrintInfoWindowRef = GetNewCWindow(rInfoWindow,NULL,(WindowRef)-1)))
  86.         ExitToShell();
  87.         
  88.     SetPortWindowPort(gPrintInfoWindowRef);
  89.     TextFont(fontNum);
  90.     TextSize(10);
  91.     RGBForeColor(&whiteColour);
  92.     RGBBackColor(&blueColour);
  93.     GetWindowPortBounds(gPrintInfoWindowRef,&portRect);
  94.     EraseRect(&portRect);
  95.  
  96.     // …………………………………………………………………………………………………………………………………………… load and display simulated document
  97.  
  98.     doGetDocument();
  99.  
  100.     // ……………………………………………………………………………………………………………………………………………………………………………………………………………… event loop
  101.  
  102.     gDone = false;
  103.  
  104.     while(!gDone)
  105.     {
  106.         gotEvent = WaitNextEvent(everyEvent,&eventStructure,MAX_UINT32,NULL);
  107.         if(gotEvent)
  108.             doEvents(&eventStructure);
  109.     }
  110. }
  111.  
  112. // *************************************************************************** doPreliminaries
  113.  
  114. void  doPreliminaries(void)
  115. {
  116.     OSErr    osError;
  117.  
  118.     MoreMasterPointers(128);
  119.     InitCursor();
  120.     FlushEvents(everyEvent,0);
  121.  
  122.     osError = AEInstallEventHandler(kCoreEventClass,kAEQuitApplication,
  123.                                                         NewAEEventHandlerUPP((AEEventHandlerProcPtr) quitAppEventHandler),
  124.                                                         0L,false);
  125.     if(osError != noErr)
  126.         ExitToShell();
  127. }
  128.  
  129. // **************************************************************************** doQuitAppEvent
  130.  
  131.  OSErr  quitAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefcon)
  132. {
  133.     OSErr            osError;
  134.     DescType    returnedType;
  135.     Size            actualSize;
  136.  
  137.     osError = AEGetAttributePtr(appEvent,keyMissedKeywordAttr,typeWildCard,&returnedType,NULL,0,
  138.                                                             &actualSize);
  139.  
  140.     if(osError == errAEDescNotFound)
  141.     {
  142.         gDone = true;
  143.         osError = noErr;
  144.     } 
  145.     else if(osError == noErr)
  146.         osError = errAEParamMissed;
  147.  
  148.     return osError;
  149. }
  150.  
  151. // ***************************************************************************** doGetDocument
  152.  
  153. void  doGetDocument(void)
  154. {
  155.     docStructureHdl    docStrucHdl;
  156.     Rect                        portRect, destRect, viewRect;
  157.     Handle                    textHdl;
  158.     
  159.     SetPortWindowPort(gDocumentWindowRef);
  160.  
  161.     docStrucHdl = (docStructureHdl) GetWRefCon(gDocumentWindowRef);    
  162.  
  163.     GetWindowPortBounds(gDocumentWindowRef,&portRect);    
  164.     destRect = portRect;
  165.     InsetRect(&destRect,4,4);
  166.     destRect.bottom +=4;
  167.     viewRect = destRect;
  168.     (*docStrucHdl)->editTextStrucHdl = TENew(&destRect,&viewRect);
  169.  
  170.     textHdl = GetResource('TEXT',rText);
  171.     if(textHdl == NULL)
  172.         ExitToShell();
  173.  
  174.     HLock(textHdl);
  175.     TEInsert(*textHdl,GetHandleSize(textHdl),(*docStrucHdl)->editTextStrucHdl);
  176.     HUnlock(textHdl);
  177.     
  178.     ReleaseResource(textHdl);
  179.  
  180.     (*docStrucHdl)->pictureHdl = GetPicture(rPicture);
  181.     if((*docStrucHdl)->pictureHdl == NULL)
  182.         ExitToShell();
  183.  
  184.     InvalWindowRect(gDocumentWindowRef,&portRect);
  185. }
  186.  
  187. // ********************************************************************************** doEvents
  188.  
  189. void    doEvents(EventRecord *eventStrucPtr)
  190. {
  191.     WindowRef                windowRef;
  192.     WindowPartCode    partCode;
  193.  
  194.     windowRef = (WindowRef) eventStrucPtr->message;
  195.  
  196.     switch(eventStrucPtr->what)
  197.     {
  198.         case kHighLevelEvent:
  199.             AEProcessAppleEvent(eventStrucPtr);
  200.             break;
  201.  
  202.         case mouseDown:
  203.             partCode = FindWindow(eventStrucPtr->where,&windowRef);
  204.             switch(partCode)
  205.             {
  206.                 case inMenuBar:
  207.                     doMenuChoice(MenuSelect(eventStrucPtr->where));
  208.                     break;
  209.  
  210.                 case inContent:
  211.                     if(windowRef != FrontWindow())
  212.                         SelectWindow(windowRef);
  213.                     break;
  214.  
  215.                 case inDrag:
  216.                     DragWindow(windowRef,eventStrucPtr->where,NULL);
  217.                     break;
  218.             }
  219.             break;
  220.  
  221.         case keyDown:
  222.             if((eventStrucPtr->modifiers & cmdKey) != 0)
  223.                 doMenuChoice(MenuEvent(eventStrucPtr));
  224.             break;
  225.  
  226.         case updateEvt:
  227.             doUpdate(eventStrucPtr);
  228.             break;
  229.     }
  230. }
  231.  
  232. // ********************************************************************************** doUpdate
  233.  
  234. void  doUpdate(EventRecord *eventStrucPtr)
  235. {
  236.     WindowRef    windowRef;
  237.     GrafPtr        oldPort;
  238.     Rect            portRect;
  239.         
  240.     windowRef = (WindowRef) eventStrucPtr->message;
  241.     
  242.     GetPort(&oldPort);
  243.  
  244.     BeginUpdate(windowRef);
  245.     
  246.     if(windowRef == gDocumentWindowRef)
  247.         doUpdateDocumentWindow(windowRef);
  248.     else if(windowRef == gPrintInfoWindowRef)
  249.     {
  250.         SetPortWindowPort(gPrintInfoWindowRef);
  251.         GetWindowPortBounds(gPrintInfoWindowRef,&portRect);
  252.         EraseRect(&portRect);
  253.         doDrawPrintInfo();
  254.     }
  255.  
  256.     EndUpdate(windowRef);
  257.  
  258.     SetPort(oldPort);
  259. }
  260.  
  261. // ******************************************************************** doUpdateDocumentWindow
  262.  
  263. void  doUpdateDocumentWindow(WindowRef windowRef)
  264. {
  265.     Rect                        portRect, pictureRect, savedDestRect;
  266.     docStructureHdl    docStrucHdl;
  267.     SInt16                    savedFontNum, savedFontSize, savedLineHeight, fontNum;
  268.  
  269.     SetPortWindowPort(windowRef);
  270.     GetWindowPortBounds(gDocumentWindowRef,&portRect);
  271.     docStrucHdl = (docStructureHdl) GetWRefCon(windowRef);
  272.  
  273.     savedDestRect = (*(*docStrucHdl)->editTextStrucHdl)->destRect;
  274.     savedFontNum = (*(*docStrucHdl)->editTextStrucHdl)->txFont;
  275.     savedFontSize = (*(*docStrucHdl)->editTextStrucHdl)->txSize;
  276.     savedLineHeight = (*(*docStrucHdl)->editTextStrucHdl)->lineHeight;
  277.  
  278.     (*(*docStrucHdl)->editTextStrucHdl)->destRect = portRect;
  279.     InsetRect(&(*(*docStrucHdl)->editTextStrucHdl)->destRect,4,4);
  280.     (*(*docStrucHdl)->editTextStrucHdl)->destRect.bottom += 4;
  281.     GetFNum("\pGeneva",&fontNum);
  282.     (*(*docStrucHdl)->editTextStrucHdl)->txFont = fontNum;
  283.     (*(*docStrucHdl)->editTextStrucHdl)->txSize = 10;
  284.     (*(*docStrucHdl)->editTextStrucHdl)->lineHeight = 13;
  285.     TECalText((*docStrucHdl)->editTextStrucHdl);
  286.     TEUpdate(&portRect,(*docStrucHdl)->editTextStrucHdl);    
  287.  
  288.     (*(*docStrucHdl)->editTextStrucHdl)->destRect = savedDestRect;
  289.     (*(*docStrucHdl)->editTextStrucHdl)->txFont = savedFontNum;
  290.     (*(*docStrucHdl)->editTextStrucHdl)->txFont = savedFontSize;
  291.     (*(*docStrucHdl)->editTextStrucHdl)->lineHeight = savedLineHeight;
  292.  
  293.     SetRect(&pictureRect,2,2,180,134);
  294.     DrawPicture((*docStrucHdl)->pictureHdl,&pictureRect);
  295. }
  296.  
  297. // ****************************************************************************** doMenuChoice
  298.  
  299. void  doMenuChoice(SInt32 menuChoice)
  300. {
  301.     MenuID                menuID;
  302.     MenuItemIndex    menuItem;
  303.     OSStatus            osStatus;
  304.     Rect                    portRect;
  305.  
  306.     menuID = HiWord(menuChoice);
  307.     menuItem = LoWord(menuChoice);
  308.  
  309.     if(menuID == 0)
  310.         return;
  311.  
  312.     switch(menuID)
  313.     {
  314.         case mAppleApplication:
  315.             if(menuItem == iAbout)
  316.                 SysBeep(10);
  317.             break;
  318.             
  319.         case mFile:
  320.             if(menuItem == iPageSetup)
  321.             {
  322.                 osStatus = doPageSetUpDialog(gDocumentWindowRef);
  323.                 if(osStatus != kPMNoError)
  324.                     doErrorAlert(osStatus);
  325.             }
  326.             
  327.             if(menuItem == iPrint)
  328.             {
  329.                 osStatus = doPrintSettingsDialog(gDocumentWindowRef);
  330.                 if(osStatus == kPMNoError)
  331.                 {
  332.                     osStatus = doPrinting(gDocumentWindowRef);
  333.                     if(osStatus != kPMNoError)
  334.                         doErrorAlert(osStatus);
  335.                 }
  336.                 else if(osStatus != kPMCancel)
  337.                     doErrorAlert(osStatus);
  338.             }
  339.  
  340.             GetWindowPortBounds(gPrintInfoWindowRef,&portRect);
  341.             InvalWindowRect(gPrintInfoWindowRef,&portRect);
  342.             
  343.             if(menuItem == iQuit)
  344.                 gDone = true;
  345.     
  346.             break;
  347.     }
  348.  
  349.     HiliteMenu(0);
  350. }
  351.  
  352. // ************************************************************** doCreateOrValidatePageFormat
  353.  
  354. OSStatus  doCreateOrValidatePageFormat(WindowRef windowRef)
  355. {
  356.     docStructureHdl    docStrucHdl;
  357.     OSStatus                osStatus            = kPMNoError;
  358.     PMPrintSession    printSession    = NULL;
  359.     PMPageFormat        pageFormat        = kPMNoPageFormat;
  360.  
  361.     docStrucHdl = (docStructureHdl) GetWRefCon(windowRef);    
  362.     HLock((Handle) docStrucHdl);
  363.  
  364.     // …………………………………………………………………………………………………………………………………………………………………………… create printing session
  365.  
  366.     osStatus = PMCreateSession(&printSession);
  367.  
  368.     // ………………………… if necessary, create and store page format object, otherwise validate existing
  369.     
  370.     if(osStatus == noErr)
  371.     {
  372.         if((*docStrucHdl)->pageFormat == kPMNoPageFormat)
  373.         {
  374.             osStatus = PMCreatePageFormat(&pageFormat);
  375.  
  376.             if((osStatus == kPMNoError) && (pageFormat != kPMNoPageFormat))
  377.             {
  378.                 osStatus = PMSessionDefaultPageFormat(printSession,pageFormat);
  379.  
  380.                 if(osStatus == kPMNoError)
  381.                     (*docStrucHdl)->pageFormat = pageFormat;
  382.             }
  383.             else
  384.             {
  385.                 if(osStatus == kPMNoError)
  386.                     osStatus = kPMGeneralError;
  387.             }
  388.         }
  389.         else
  390.         {
  391.             osStatus = PMSessionValidatePageFormat(printSession,(*docStrucHdl)->pageFormat,
  392.                                                                                          kPMDontWantBoolean);
  393.         }
  394.     }
  395.  
  396.     // …………………………………………………………………………………………………………………… store printing session, or clean up if error
  397.  
  398.     if(osStatus == kPMNoError)
  399.         (*docStrucHdl)->printSession = printSession;
  400.     else
  401.     {
  402.         if(pageFormat != kPMNoPageFormat)
  403.             PMRelease(pageFormat);
  404.         if(printSession != NULL)
  405.             PMRelease(printSession);
  406.     }
  407.  
  408.     HUnlock((Handle) docStrucHdl);
  409.  
  410.     return osStatus;
  411. }
  412.  
  413. // ************************************************************************* doPageSetUpDialog
  414.  
  415. OSStatus  doPageSetUpDialog(WindowRef windowRef)
  416. {
  417.     OSStatus                osStatus = kPMNoError;
  418.     docStructureHdl    docStrucHdl;
  419.     Boolean                    userClickedOKButton;
  420.  
  421.     osStatus = doCreateOrValidatePageFormat(windowRef);
  422.     if(osStatus != kPMNoError)
  423.         return osStatus;
  424.  
  425.     docStrucHdl = (docStructureHdl) GetWRefCon(windowRef);    
  426.     HLock((Handle) docStrucHdl);
  427.  
  428.     osStatus = PMSessionPageSetupDialog((*docStrucHdl)->printSession,(*docStrucHdl)->pageFormat,
  429.                                                                             &userClickedOKButton);
  430.  
  431.     if((*docStrucHdl)->printSession != NULL)
  432.     {
  433.         PMRelease((*docStrucHdl)->printSession);
  434.         (*docStrucHdl)->printSession = NULL;
  435.     }
  436.  
  437.     HUnlock((Handle) docStrucHdl);
  438.     gDrawPrintSettingsStuff = false;
  439.  
  440.     return osStatus;
  441. }
  442.  
  443. // ********************************************************************* doPrintSettingsDialog
  444.  
  445. OSStatus  doPrintSettingsDialog(WindowRef windowRef)
  446. {
  447.     OSStatus                            osStatus            = kPMNoError;
  448.     docStructureHdl                docStrucHdl;
  449.     PMPrintSettings                printSettings = kPMNoPrintSettings;
  450.     CFStringRef                        stringRef;
  451.     PMPrintDialogInitUPP    initialisationFunctionUPP;
  452.     Boolean                                userClickedPrintButton;
  453.  
  454.     osStatus = doCreateOrValidatePageFormat(windowRef);
  455.     if(osStatus != kPMNoError)
  456.         return osStatus;
  457.  
  458.     docStrucHdl = (docStructureHdl) GetWRefCon(windowRef);    
  459.     HLock((Handle) docStrucHdl);
  460.  
  461.     osStatus = PMCreatePrintSettings(&printSettings);
  462.     if((osStatus == kPMNoError) && (printSettings != kPMNoPrintSettings))
  463.     {
  464.         osStatus = CopyWindowTitleAsCFString(windowRef,&stringRef);
  465.         if(osStatus == noErr)
  466.         {
  467.             osStatus = PMSetJobNameCFString(printSettings,stringRef);
  468.             CFRelease(stringRef);
  469.         }
  470.  
  471.         if(osStatus == noErr)
  472.             osStatus = PMSessionDefaultPrintSettings((*docStrucHdl)->printSession,printSettings);
  473.         
  474.         if(osStatus == kPMNoError)
  475.         {
  476.             (*docStrucHdl)->printSettings = printSettings;
  477.             printSettings = kPMNoPrintSettings;
  478.         }
  479.     }
  480.     
  481.     if(osStatus == kPMNoError)
  482.     {
  483.         if(gRunningOnX)
  484.         {
  485.             PMSetPageRange((*docStrucHdl)->printSettings,1,kPMPrintAllPages);
  486.             PMSetFirstPage((*docStrucHdl)->printSettings,1,false);
  487.             PMSetLastPage((*docStrucHdl)->printSettings,9999,false);
  488.         }
  489.     }
  490.         
  491.     if(osStatus == kPMNoError)
  492.     {
  493.         initialisationFunctionUPP        = NewPMPrintDialogInitUPP((PMPrintDialogInitProcPtr)
  494.                                                                                                                     initialisationFunction);
  495.         gNewItemEvaluateFunctionUPP = NewPMItemUPP((PMItemProcPtr) itemEvaluationFunction);
  496.         gEventFilterUPP                            = NewModalFilterUPP((ModalFilterProcPtr) eventFilter);
  497.  
  498.         osStatus = PMSessionPrintDialogInit((*docStrucHdl)->printSession,
  499.                                                                                 (*docStrucHdl)->printSettings,
  500.                                                                                 (*docStrucHdl)->pageFormat,&gPMDialog);
  501.         if(osStatus == kPMNoError)
  502.             osStatus = PMSessionPrintDialogMain((*docStrucHdl)->printSession,
  503.                                                                                     (*docStrucHdl)->printSettings,
  504.                                                                                     (*docStrucHdl)->pageFormat,
  505.                                                                                     &userClickedPrintButton,initialisationFunctionUPP);
  506.  
  507.         if(osStatus == kPMNoError && !userClickedPrintButton)
  508.             osStatus = kPMCancel;
  509.  
  510.         DisposePMPrintDialogInitUPP(initialisationFunctionUPP);
  511.         DisposePMItemUPP(gNewItemEvaluateFunctionUPP);
  512.         DisposeModalFilterUPP(gEventFilterUPP);
  513.     }
  514.  
  515.     if(osStatus != kPMNoError || osStatus == kPMCancel)
  516.     {
  517.         if((*docStrucHdl)->printSettings != kPMNoPrintSettings)
  518.         {
  519.             PMRelease((*docStrucHdl)->printSettings);
  520.             (*docStrucHdl)->printSettings = kPMNoPrintSettings;
  521.         }
  522.         if((*docStrucHdl)->printSession != NULL)
  523.         {
  524.             PMRelease((*docStrucHdl)->printSession);
  525.             (*docStrucHdl)->printSession = NULL;
  526.         }
  527.     }        
  528.  
  529.     HUnlock((Handle) docStrucHdl);
  530.     gDrawPrintSettingsStuff = userClickedPrintButton;
  531.  
  532.     return osStatus;
  533. }
  534.  
  535. // ******************************************************************************** doPrinting
  536.  
  537. OSStatus  doPrinting(WindowRef windowRef)
  538. {
  539.     docStructureHdl    docStrucHdl;
  540.     OSStatus                osStatus = kPMNoError;
  541.     UInt32                    firstPage, lastPage, numberOfPages;
  542.     PMRect                    adjustedPageRect;
  543.     Rect                        pageRect;
  544.     SInt16                    page;
  545.     GrafPtr                    oldPort, currentPort, printingPort;
  546.  
  547.     GetPort(&oldPort);
  548.     docStrucHdl = (docStructureHdl) GetWRefCon(windowRef);    
  549.     HLock((Handle) docStrucHdl);
  550.  
  551.     // ………………………………………………………………… get first and last page to print as set by user in Print dialog
  552.  
  553.     osStatus = PMGetFirstPage((*docStrucHdl)->printSettings,&firstPage);
  554.  
  555.     if(osStatus == kPMNoError)
  556.         osStatus = PMGetLastPage((*docStrucHdl)->printSettings,&lastPage);
  557.  
  558.     // for demo purposes, store first, last page and copies for Some Printing Information window
  559.  
  560.     gFirstPage = firstPage;
  561.     gLastPage = lastPage;
  562.     PMGetCopies((*docStrucHdl)->printSettings,&gCopies);
  563.  
  564.     // …………………………………… get actual number of pages in document and, if necessary, adjust last page
  565.  
  566.     if(osStatus == kPMNoError)
  567.         osStatus = PMGetAdjustedPageRect((*docStrucHdl)->pageFormat,&adjustedPageRect);
  568.  
  569.     if(osStatus == kPMNoError)
  570.     {
  571.         pageRect.top        = adjustedPageRect.top;
  572.         pageRect.left        = adjustedPageRect.left;
  573.         pageRect.bottom    = adjustedPageRect.bottom;
  574.         pageRect.right    = adjustedPageRect.right;
  575.  
  576.         numberOfPages = doCalcNumberOfPages(windowRef,pageRect);
  577.         if(numberOfPages < lastPage)
  578.             lastPage = numberOfPages;
  579.     }
  580.  
  581.     // ………………………………………………………………………………… for Mac OS X, set first and last page for progress dialog
  582.  
  583.     if(gRunningOnX)
  584.     {
  585.         if(osStatus == kPMNoError)
  586.             osStatus = PMSetFirstPage((*docStrucHdl)->printSettings,firstPage,false);
  587.  
  588.         if(osStatus == kPMNoError)
  589.             osStatus = PMSetLastPage((*docStrucHdl)->printSettings,lastPage,false);
  590.     }
  591.  
  592.     // ……………………………………………………………………………………………………………………………………………………………………………………………………… printing loop
  593.  
  594.     if(osStatus == kPMNoError)
  595.     {
  596.         osStatus = PMSessionBeginDocument((*docStrucHdl)->printSession,
  597.                                                                             (*docStrucHdl)->printSettings,
  598.                                                                             (*docStrucHdl)->pageFormat);
  599.         if(osStatus == kPMNoError)
  600.         {
  601.             page = 1;
  602.  
  603.             while((page <= lastPage) && (osStatus == kPMNoError) &&
  604.                         (PMSessionError((*docStrucHdl)->printSession) == kPMNoError))
  605.             {
  606.                 osStatus = PMSessionBeginPage((*docStrucHdl)->printSession,
  607.                                                                             (*docStrucHdl)->pageFormat,NULL);
  608.                 if(osStatus != kPMNoError)
  609.                     break;
  610.     
  611.                 GetPort(¤tPort);
  612.                         
  613.                 osStatus = PMSessionGetGraphicsContext((*docStrucHdl)->printSession,
  614.                                                                                              kPMGraphicsContextQuickdraw,
  615.                                                                                              (void **) &printingPort);
  616.                 if(osStatus == kPMNoError)
  617.                 {
  618.                     SetPort(printingPort);
  619.                     doDrawPage(windowRef,pageRect,page,numberOfPages);
  620.                     SetPort(currentPort);
  621.                 }
  622.                     
  623.                 osStatus = PMSessionEndPage((*docStrucHdl)->printSession);
  624.                 if(osStatus != kPMNoError)
  625.                     break;
  626.                         
  627.                 page++;
  628.             }
  629.         }
  630.             
  631.         PMSessionEndDocument((*docStrucHdl)->printSession);
  632.     }
  633.  
  634.     // …………………………………………………………………………………………………………………………………………………………………………………………………………………… clean up
  635.  
  636.     if((*docStrucHdl)->printSettings != kPMNoPrintSettings)
  637.     {
  638.         PMRelease((*docStrucHdl)->printSettings);
  639.         (*docStrucHdl)->printSettings = kPMNoPrintSettings;
  640.     }
  641.     if((*docStrucHdl)->printSession != NULL)
  642.     {
  643.         PMRelease((*docStrucHdl)->printSession);
  644.         (*docStrucHdl)->printSession = NULL;
  645.     }
  646.  
  647.     HUnlock((Handle) docStrucHdl);
  648.     SetPort(oldPort);
  649.  
  650.     return osStatus;
  651. }
  652.  
  653. // *********************************************************************** doCalcNumberOfPages
  654.  
  655. SInt16  doCalcNumberOfPages(WindowRef windowRef,Rect pageRect)
  656. {
  657.     docStructureHdl    docStrucHdl;
  658.     FontInfo                fontInfo;
  659.     Rect                        destRect;
  660.     SInt16                    heightDestRect, linesPerPage, numberOfPages;
  661.  
  662.     docStrucHdl = (docStructureHdl) GetWRefCon(windowRef);    
  663.     
  664.     TextFont(gFontNumber);
  665.     TextSize(gFontSize);
  666.     GetFontInfo(&fontInfo);
  667.  
  668.     (*(*docStrucHdl)->editTextStrucHdl)->txFont = gFontNumber;
  669.     (*(*docStrucHdl)->editTextStrucHdl)->txSize = gFontSize;
  670.     (*(*docStrucHdl)->editTextStrucHdl)->lineHeight = fontInfo.ascent + fontInfo.descent
  671.                                                                                                         + fontInfo.leading;
  672.  
  673.     SetRect(&destRect,pageRect.left + kMargin,pageRect.top + (kMargin * 1.5), 
  674.                     pageRect.right - kMargin,pageRect.bottom - (kMargin * 1.5));
  675.  
  676.     (*(*docStrucHdl)->editTextStrucHdl)->destRect = destRect;
  677.  
  678.     TECalText((*docStrucHdl)->editTextStrucHdl);
  679.  
  680.     heightDestRect = destRect.bottom - destRect.top;
  681.     linesPerPage = heightDestRect / (*(*docStrucHdl)->editTextStrucHdl)->lineHeight; 
  682.     numberOfPages = ((*(*docStrucHdl)->editTextStrucHdl)->nLines / linesPerPage) + 1;    
  683.  
  684.     return(numberOfPages);
  685. }
  686.  
  687. // ******************************************************************************** doDrawPage
  688.  
  689. void  doDrawPage(WindowRef windowRef,Rect pageRect,SInt16 pageNumber,SInt16 numberOfpages)
  690. {
  691.     docStructureHdl    docStrucHdl;
  692.     TEHandle                docEditTextStrucHdl, pageEditTextStrucHdl;
  693.     PicHandle                pictureHdl;
  694.     Rect                        destRect, pictureRect;
  695.     SInt16                    heightDestRect, linesPerPage, numberOfLines;
  696.     Handle                    textHdl;
  697.     SInt32                    startOffset, endOffset;
  698.     Str255                    theString;
  699.  
  700.     TextFont(gFontNumber);
  701.     TextSize(gFontSize);
  702.  
  703.     docStrucHdl = (docStructureHdl) GetWRefCon(windowRef);    
  704.     docEditTextStrucHdl    = (*docStrucHdl)->editTextStrucHdl;
  705.     pictureHdl = (*docStrucHdl)->pictureHdl;
  706.  
  707.     destRect = (*docEditTextStrucHdl)->destRect;
  708.     heightDestRect = destRect.bottom - destRect.top;
  709.     linesPerPage = heightDestRect / (*docEditTextStrucHdl)->lineHeight; 
  710.     numberOfLines = (*docEditTextStrucHdl)->nLines;
  711.  
  712.     startOffset = (*docEditTextStrucHdl)->lineStarts[(pageNumber - 1) * linesPerPage];
  713.     if(pageNumber == numberOfpages)
  714.         endOffset = (*docEditTextStrucHdl)->lineStarts[numberOfLines];
  715.     else
  716.         endOffset = (*docEditTextStrucHdl)->lineStarts[pageNumber * linesPerPage];
  717.  
  718.     pageEditTextStrucHdl = TENew(&destRect,&destRect);
  719.     textHdl = (*docEditTextStrucHdl)->hText;
  720.     HLock(textHdl);
  721.     TEInsert(*textHdl + startOffset,endOffset - startOffset,pageEditTextStrucHdl);
  722.     TEDispose(pageEditTextStrucHdl);
  723.  
  724.     if(pageNumber == 1)
  725.     {
  726.         SetRect(&pictureRect,destRect.left,destRect.top,
  727.                         destRect.left + ((*pictureHdl)->picFrame.right - (*pictureHdl)->picFrame.left),
  728.                         destRect.top + ((*pictureHdl)->picFrame.bottom - (*pictureHdl)->picFrame.top));
  729.         DrawPicture(pictureHdl,&pictureRect);
  730.     }
  731.  
  732.     MoveTo(destRect.left,pageRect.bottom - 25);
  733.     NumToString((SInt32) pageNumber,theString);
  734.     DrawString(theString);
  735. }
  736.  
  737. // *************************************************************************** doDrawPrintInfo
  738.  
  739. void  doDrawPrintInfo(void)
  740. {
  741.     docStructureHdl    docStrucHdl;
  742.     OSStatus                osStatus = kPMNoError;
  743.     PMRect                    theRect;
  744.     Str255                    s2, s3;
  745.     PMResolution        resolution;
  746.     double                    scale;
  747.     PMOrientation        orientation;
  748.  
  749.     docStrucHdl = (docStructureHdl) GetWRefCon(gDocumentWindowRef);    
  750.     if((*docStrucHdl)->pageFormat == kPMNoPageFormat)
  751.         return;
  752.  
  753.     HLock((Handle) docStrucHdl);
  754.  
  755.     MoveTo(20,25);
  756.     TextFace(bold);
  757.     DrawString("\pFrom PMPageFormat Object:");
  758.     TextFace(normal);
  759.  
  760.     PMGetAdjustedPaperRect((*docStrucHdl)->pageFormat,&theRect);
  761.     NumToString((SInt32) theRect.top,s2);
  762.     NumToString((SInt32) theRect.left,s3);
  763.     doDrawRectStrings("\pPaper Rectangle (top,left):",20,45,s2,190,45,s3);
  764.     NumToString((SInt32) theRect.bottom,s2);
  765.     NumToString((SInt32) theRect.right,s3);
  766.     doDrawRectStrings("\pPaper Rectangle (bottom,right):",20,60,s2,190,60,s3);
  767.  
  768.     PMGetAdjustedPageRect((*docStrucHdl)->pageFormat,&theRect);
  769.     NumToString((SInt32) theRect.top,s2);
  770.     NumToString((SInt32) theRect.left,s3);
  771.     doDrawRectStrings("\pPage Rectangle (top,left):",20,75,s2,190,75,s3);
  772.     NumToString((SInt32) theRect.bottom,s2);
  773.     NumToString((SInt32) theRect.right,s3);
  774.     doDrawRectStrings("\pPage Rectangle (bottom,right):",20,90,s2,190,90,s3);
  775.  
  776.     PMGetResolution((*docStrucHdl)->pageFormat,&resolution);
  777.     MoveTo(20,105);
  778.     DrawString("\pDrawing Resolution (Vertical):");
  779.     NumToString((SInt32) resolution.vRes,s2);
  780.     MoveTo(190,105);
  781.     DrawString(s2);
  782.     DrawString("\p dpi");
  783.     MoveTo(20,120);
  784.     DrawString("\pDrawing Resolution (Horizontal):");
  785.     NumToString((SInt32) resolution.hRes,s2);
  786.     MoveTo(190,120);
  787.     DrawString(s2);
  788.     DrawString("\p dpi");
  789.  
  790.     PMGetScale((*docStrucHdl)->pageFormat,&scale);
  791.     MoveTo(20,135);
  792.     DrawString("\pScale:");
  793.     NumToString((SInt32) scale,s2);
  794.     MoveTo(190,135);
  795.     DrawString(s2);
  796.     DrawString("\p%");
  797.  
  798.     PMGetOrientation((*docStrucHdl)->pageFormat,&orientation);
  799.     MoveTo(20,150);
  800.     DrawString("\pPage Orientation:");
  801.     MoveTo(190,150);
  802.     if(orientation == kPMPortrait)
  803.         DrawString("\pPortrait");
  804.     else if(orientation == kPMLandscape)
  805.         DrawString("\pLandscape");
  806.  
  807.     if(gDrawPrintSettingsStuff)
  808.     {
  809.         MoveTo(20,170);
  810.         TextFace(bold);
  811.         DrawString("\pFrom PMPrintSettings Object:");
  812.         TextFace(normal);
  813.  
  814.         MoveTo(20,190);
  815.         DrawString("\pFirst Page:");
  816.         NumToString((SInt32) gFirstPage,s2);
  817.         MoveTo(190,190);
  818.         DrawString(s2);
  819.  
  820.         MoveTo(20,205);
  821.         DrawString("\pLast Page:");
  822.         NumToString((SInt32) gLastPage,s2);
  823.         MoveTo(190,205);
  824.         DrawString(s2);
  825.  
  826.         MoveTo(20,220);
  827.         DrawString("\pNumber of Copies:");
  828.         NumToString((SInt32) gCopies,s2);
  829.         MoveTo(190,220);
  830.         DrawString(s2);
  831.     }
  832.  
  833.     HUnlock((Handle) docStrucHdl);
  834. }
  835.  
  836. // ************************************************************************* doDrawRectStrings
  837.  
  838. void  doDrawRectStrings(Str255 s1,SInt16 x1,SInt16 y1,Str255 s2,SInt16 x2,SInt16 y2,Str255 s3)
  839. {
  840.     MoveTo(x1,y1);
  841.     DrawString(s1);
  842.     MoveTo(x2,y2);
  843.     DrawString("\p(");
  844.     DrawString(s2);
  845.     DrawString("\p,");
  846.     DrawString(s3);
  847.     DrawString("\p)");
  848. }
  849.  
  850. // ****************************************************************************** doErrorAlert
  851.  
  852. void  doErrorAlert(OSStatus errorType)
  853. {
  854.     Str255    theString, errorString = "\pCarbon Printing Manager Error ";
  855.     SInt16    itemHit;
  856.  
  857.     NumToString((SInt32) errorType,theString);
  858.     doConcatPStrings(errorString,theString);
  859.  
  860.     StandardAlert(kAlertCautionAlert,errorString,NULL,NULL,&itemHit);
  861. }
  862.  
  863. // ************************************************************************** doConcatPStrings
  864.  
  865. void  doConcatPStrings(Str255 targetString,Str255 appendString)
  866. {
  867.     SInt16    appendLength;
  868.  
  869.     appendLength = MIN(appendString[0],255 - targetString[0]);
  870.  
  871.     if(appendLength > 0)
  872.     {
  873.         BlockMoveData(appendString+1,targetString+targetString[0]+1,(SInt32) appendLength);
  874.         targetString[0] += appendLength;
  875.     }
  876. }
  877.  
  878. // *******************************************************************************************