home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Text⁄Files / FaceLift / FaceLift Folder / FLIO.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-16  |  17.7 KB  |  898 lines  |  [TEXT/KAHL]

  1. /*
  2.  * FaceLift File I/O Routines.
  3.  */
  4.  
  5. # include    "TransSkel.h"
  6. # include    "TransDisplay.h"
  7.  
  8. # include    "FLMaca.h"
  9. # include    "FLFileStuff.h"
  10. # include    "FaceLift.h"
  11.  
  12.  
  13. static SFReply    inFile;
  14. static SFReply    outFile;
  15. static Str255    fName;        /* map name and volume reference number */
  16. static int        vRefNum;
  17.  
  18. static Boolean    docModified;
  19.  
  20.  
  21. /*
  22.  * Clear the current file name, and cause the title of the map
  23.  * window to be reset.  Obviously, the first call to this must occur
  24.  * after the map window is initialized.
  25.  */
  26.  
  27. void
  28. ClearMapName (void)
  29. {
  30.     CopyString ("\puntitled", fName);
  31.     SetMapName (fName);
  32. }
  33.  
  34.  
  35. void
  36. SetMapName (StringPtr name)
  37. {
  38. Str255    s;
  39.  
  40.     CopyString ("\pMap Name:  ", s);
  41.     AppendString (name, s);
  42.     SetWTitle (mapWind, s);
  43. }
  44.  
  45.  
  46. /*
  47.  * Check a ConvSpec to see that it makes sense
  48.  */
  49.  
  50. static Boolean
  51. CheckCSpec (ConvSpec *c)
  52. {
  53. int        errCnt = 0;
  54. int    size;
  55.  
  56.     if (FontIndex (c->font) < 0)
  57.     {
  58.         ErrWindMsge ("\pUnknown font number: ", c->font);
  59.         ++errCnt;
  60.     }
  61.     if ((size = c->size) != anySize && (size < 1 || size > maxPtSize))
  62.     {
  63.         ErrWindMsge ("\pUnknown size: ", (int) size);
  64.         ++errCnt;
  65.     }
  66.  
  67.     return (errCnt == 0);
  68. }
  69.  
  70.  
  71. /*
  72.  * Read map specifications from a file.  Won't add duplicate or illegal
  73.  * specifications.
  74.  *
  75.  * Assumes file is open and all mappings already cleared (for Open) or
  76.  * not (for Append).
  77.  *
  78.  * Does not set undo variables or map changed variables.
  79.  */
  80.  
  81. static void
  82. ReadMap (int f)
  83. {
  84. MapSpec    mSpec;
  85. int        badCnt = 0;
  86. Str255    str;
  87. int        ver;
  88.  
  89.     MakeFrontWind (mapWind);
  90.     ErrWindInit (inFile.fName);
  91.     if (!FileRead (f, (Ptr) &ver, (long) sizeof (int)))
  92.     {
  93.         Message1 ("\pCan't read map file.");
  94.     }
  95.     else if (ver != mapVersion)
  96.     {
  97.         NumToString ((long) ver, str);
  98.         Message2 ("\pUnknown map file version:  ", str);
  99.     }
  100.     else while (FileRead (f, (Ptr) &mSpec, (long) sizeof (MapSpec)))
  101.     {
  102.         /*
  103.          * Need to check legality here, since the file may have been
  104.          * created using the fonts from a font list other than the current
  105.          * one.
  106.          */
  107.  
  108.         if (CheckCSpec (&mSpec.inFmt) == false
  109.             || CheckCSpec (&mSpec.outFmt) == false)
  110.         {
  111.             ++badCnt;
  112.             continue;
  113.         }
  114.  
  115.         if (StatMSpec (&mSpec))
  116.         {
  117.             ++badCnt;
  118.             continue;            /* already exists - don't use dups */
  119.         }
  120.  
  121.         if (InsertMapping (&mSpec, mapList->nLines) == false)
  122.             break;
  123.     }
  124.  
  125.     (void) FSClose (f);
  126.     ScrollToLine (mapList, 0);        /* force scroll to top */
  127.     SelectMapping (noLine);            /* but leave unselected */
  128.  
  129.     if (badCnt)
  130.     {
  131.         NumToString ((long) badCnt, str);
  132.         Message2 (str, "\p illegal or duplicate specifications were found and ignored");
  133.     }
  134. }
  135.  
  136.  
  137. /*
  138.  * Open a map.  Clobber the current map first, set the map name
  139.  * afterward.
  140.  */
  141.  
  142. Boolean
  143. OpenMap (void)
  144. {
  145. short    f;
  146.  
  147.     if (GetInputFile ("\pOpen", faceType, &inFile)
  148.         && OpenInputFile (&inFile, &f))
  149.     {
  150.         ClobberMap ();
  151.         ReadMap (f);
  152.         CopyString (inFile.fName, fName);    /* some redundancy... */
  153.         vRefNum = inFile.vRefNum;
  154.         SetMapName (fName);
  155.         return (true);
  156.     }
  157.     return (false);
  158. }
  159.  
  160.  
  161. /*
  162.  * Add a map to the current map.  Doesn't set map name afterward.
  163.  */
  164.  
  165. Boolean
  166. AddMap (void)
  167. {
  168. short    f;
  169.  
  170.     if (GetInputFile ("\pAdd", faceType, &inFile)
  171.         && OpenInputFile (&inFile, &f))
  172.     {
  173.         ReadMap (f);
  174.         return (true);
  175.     }
  176.     return (false);
  177. }
  178.  
  179.  
  180. /*
  181.  * Save map to file.  askForName is true if should ask for name,
  182.  * otherwise use current name.  If name is "untitled", ask for a name
  183.  * anyway.  Sets the current name if it wasn't already set.
  184.  *
  185.  * The file is deleted if not written properly.
  186.  */
  187.  
  188. Boolean
  189. SaveMap (Boolean askForName)
  190. {
  191. short    f;
  192. OSErr    result;
  193. long    amount;
  194. long    pos;
  195. short    ver;
  196. Boolean    ok = false;
  197.  
  198.     if (GetOutputFile (askForName, fName, vRefNum, &outFile) == false)
  199.         return (false);
  200.     if (OpenOutputFile (&outFile, faceCreator, faceType, &f) == false)
  201.         return (false);
  202.  
  203.     ver = mapVersion;
  204.     if (FileWrite (f, (Ptr) &ver, (long) sizeof (int)))
  205.     {
  206.         amount = mapList->nLines * sizeof (MapSpec);
  207.         if (FileWrite (f, (Ptr) &mapSpec, amount))
  208.             ok = true;
  209.     }
  210.  
  211.     (void) GetFPos (f, &pos);
  212.     (void) SetEOF (f, pos);
  213.     (void) FSClose (f);
  214.     (void) FlushVol (nil /*f*/, outFile.vRefNum);
  215.  
  216.     if (!ok)
  217.     {
  218.         Message1 ("\pCould not write map");
  219.         (void) FSDelete (outFile.fName, outFile.vRefNum);
  220.         return (false);
  221.     }
  222.  
  223.     CopyString (outFile.fName, fName);        /* set map name */
  224.     vRefNum = outFile.vRefNum;
  225.     SetMapName (fName);
  226.     return (true);
  227. }
  228.  
  229.  
  230. /* ---------------------------------------------------------------- */
  231. /*                        File-Copying Code                            */
  232. /* ---------------------------------------------------------------- */
  233.  
  234.  
  235. /*
  236.  * Open both forks of the input and output files.  Fail if
  237.  * can't get them all open, and leave no forks open.  Otherwise
  238.  * return true.
  239.  */
  240.  
  241. static Boolean
  242. OpenForks (StringPtr inName, short inVRefNum,
  243.                     StringPtr outName, short outVRefNum,
  244.                     short *idf, short *irf, short *odf, short *orf)
  245. {
  246.     if (FSOpen (inName, inVRefNum, idf) == noErr)
  247.     {
  248.         if (OpenRF (inName, inVRefNum, irf) == noErr)
  249.         {
  250.             if (FSOpen (outName, outVRefNum, odf) == noErr)
  251.             {
  252.                 if (OpenRF (outName, outVRefNum, orf) == noErr)
  253.                 {
  254.                     return (true);
  255.                 }
  256.                 else
  257.                     Message1 ("\pCan't open output resource fork.");
  258.                 (void) FSClose (*odf);
  259.             }
  260.             else
  261.                 Message1 ("\pCan't open output data fork.");
  262.             (void) FSClose (*irf);
  263.         }
  264.         else
  265.             Message1 ("\pCan't open input resource fork.");
  266.         (void) FSClose (*idf);
  267.     }
  268.     else
  269.         Message1 ("\pCan't open input data fork.");
  270.     return (false);
  271. }
  272.  
  273.  
  274. /*
  275.  * Copy size bytes from one fork to another.  Return false if
  276.  * everything isn't right.
  277.  */
  278.  
  279. static Boolean
  280. CopyFork (int inRef, int outRef, long size)
  281. {
  282. Ptr        p;
  283. long    toWrite;
  284. long    count;
  285. long    pos;
  286. long    blkSize;
  287. OSErr    err;
  288.  
  289.     blkSize = CompactMem (size);    /* see how big a block can be gotten */
  290.     if (blkSize > size)
  291.         blkSize = size;                /* don't make bigger than needed */
  292.     if (blkSize > 32768L)
  293.         blkSize = 32768L;            /* or bigger than 32K */
  294.  
  295.     if (blkSize == 0 && size != 0)
  296.     {
  297.         Message1 ("\pNo memory for copy.");
  298.         return (false);
  299.     }
  300.  
  301.     p = NewPtr (blkSize);
  302.  
  303.     toWrite = size;
  304.     while (toWrite > 0)
  305.     {
  306.         count = (toWrite < blkSize ? toWrite : blkSize);
  307.         if (!FileRead (inRef, p, count))
  308.         {
  309.             Message1 ("\pRead error");
  310.             break;
  311.         }
  312.         if (!FileWrite (outRef, p, count))
  313.             break;                /* (FileWrite prints its own message) */
  314.         toWrite -= blkSize;
  315.     }
  316.  
  317.     DisposPtr (p);
  318.     (void) GetFPos (outRef, &pos);
  319.     (void) SetEOF (outRef, pos);
  320.     if (pos != size)
  321.         Message1 ("\pIncomplete copy");
  322.     return (pos == size);
  323. }
  324.  
  325.  
  326. /*
  327.  * Copy a file.  It is assumed that input and output files
  328.  * both exist, and are of matching creator and type.
  329.  *
  330.  * If space can't be allocated, should deallocate any already-
  331.  * allocated space, or delete the file.  This is a flaw.
  332.  */
  333.  
  334. static Boolean
  335. DoCopy (StringPtr inName, int inVRefNum, StringPtr outName, int outVRefNum)
  336. {
  337. short    idf, irf, odf, orf;
  338. long    idSize, irSize, odSize, orSize, dAlloc, rAlloc;
  339. Boolean    result = false;
  340. OSErr    err;
  341.  
  342.     if (OpenForks (inName, inVRefNum, outName, outVRefNum,
  343.             &idf, &irf, &odf, &orf) == false)
  344.         return (false);
  345.  
  346.     (void) GetEOF (idf, &idSize);
  347.     (void) GetEOF (irf, &irSize);
  348.     (void) SetEOF (odf, 0L);        /* truncate both forks */
  349.     (void) SetEOF (orf, 0L);
  350.     /*(void) GetEOF (odf, &odSize);
  351.     (void) GetEOF (orf, &orSize);
  352.     dAlloc = idSize - odSize;
  353.     rAlloc = irSize - orSize;
  354.     if (dAlloc > 0 && (err = Allocate (odf, &dAlloc)) != noErr)
  355.         FileErr (err);
  356.     else if (rAlloc > 0 && (err = Allocate (orf, &rAlloc)) != noErr)
  357.         FileErr (err);*/
  358.     dAlloc = idSize;
  359.     rAlloc = irSize;
  360.     if ((err = Allocate (odf, &dAlloc)) != noErr)
  361.         FileErr (err);
  362.     else if ((err = Allocate (orf, &rAlloc)) != noErr)
  363.         FileErr (err);
  364.     else if (CopyFork (idf, odf, idSize) && CopyFork (irf, orf, irSize))
  365.         result = true;
  366.  
  367.     (void) FSClose (idf);
  368.     (void) FSClose (irf);
  369.     (void) FSClose (odf);
  370.     (void) FSClose (orf);
  371.     (void) FlushVol (nil, outVRefNum);
  372.     return (result);
  373. }
  374.  
  375.  
  376. /*
  377.  * Rewrite a paragraph which has had the format information modified.
  378.  * This attempts to be smart and write ONLY the format information.
  379.  * The current file position is saved and restored, so this operation
  380.  * is transparent to other things going on.
  381.  *    
  382.  * If the paragraph isn't a text paragraph, it doesn't make sense to
  383.  * rewrite the formats, so nothing is done.
  384.  */
  385.  
  386. static Boolean
  387. RewritePara (void)
  388. {
  389. long    curFilePos;
  390. Boolean    result;
  391.  
  392.     if (paraType != textPara)
  393.         return;
  394.     GetFPos (macaFRef, &curFilePos);                /* get current position */
  395.     FileSeek (macaFRef, paraFilePos + fmtOffset);    /* seek to formats */
  396.     HLock (paraBuf);
  397.     result = FileWrite (macaFRef, *paraBuf + fmtOffset, (long) (formats * sizeof (Format)));
  398.     HUnlock (paraBuf);
  399.     FileSeek (macaFRef, curFilePos);                /* restore position */
  400.     return (result);
  401. }
  402.  
  403.  
  404. /*
  405.  * Determine if a document format matches a map input format.
  406.  *
  407.  * This is an exercise in ugly programming.  In languages w/o
  408.  * short-circuiting of boolean expression evaluation, it would
  409.  * be more efficient to have three separate tests.
  410.  */
  411.  
  412. static Boolean
  413. TestFormat (Format *fmt, ConvSpec *cSpec)
  414. {
  415.     return ((cSpec->font == anyFont || cSpec->font == fmt->fmtFont)
  416.                                     &&
  417.             (cSpec->size == anySize || cSpec->size == fmt->fmtSize)
  418.                                     &&
  419.           (cSpec->style == anyStyle || cSpec->style == fmt->fmtStyle));
  420. }
  421.  
  422.  
  423. /*
  424.  * Found a document format that matches a map input format.  Change the
  425.  * format to match the corresponding map output format (change only
  426.  * those parts of the output format that aren't "same" (i.e., "any").
  427.  * Set the flag that indicates whether the document has been changed.
  428.  */
  429.  
  430. static void
  431. ChangeFormat (Format *fmt, ConvSpec *cSpec)
  432. {
  433.     if (cSpec->font != anyFont)
  434.         fmt->fmtFont = cSpec->font;
  435.     if (cSpec->size != anySize)
  436.         fmt->fmtSize = cSpec->size;
  437.     if (cSpec->style != anyStyle)
  438.         fmt->fmtStyle = cSpec->style;
  439.  
  440.     docModified = true;
  441. }
  442.  
  443.  
  444. /*
  445.  * Examine a document format, checking it against the map input
  446.  * formats.  If it matches any of them, change to the corresponding
  447.  * map output format and stop checking against the map.
  448.  */
  449.  
  450. static Boolean
  451. MapFormat (Format *f)
  452. {
  453. int    i;
  454.  
  455.     for (i = 0; i < mapList->nLines; ++i)
  456.     {
  457.         if (TestFormat (f, &mapSpec[i].inFmt))
  458.         {
  459.             ChangeFormat (f, &mapSpec[i].outFmt);
  460.             return (true);        /* quit looking */
  461.         }
  462.     }
  463.     return (false);        /* didn't match anything */
  464. }
  465.  
  466.  
  467. /*
  468.  * Examine all the formats for a paragraph and change those
  469.  * that match any of the input specifications.  Return true if any
  470.  * of them match, false if none do.
  471.  *
  472.  * For each format, cease checking as soon as a match is found.
  473.  *
  474.  * This routine is used for version 3 and version6, since format data
  475.  * in paragraphs are stored the same way in both versions.
  476.  */
  477.  
  478. static Boolean
  479. FormatsChanged (void)
  480. {
  481. Boolean    result = false;
  482. Format        *f;
  483. Int16        i;
  484.  
  485.     HLock (paraBuf);
  486.     f = (Format *) (*paraBuf + fmtOffset);
  487.  
  488.     for (i = 0; i < formats; ++i)
  489.     {
  490.         if (MapFormat (f++))
  491.             result = true;
  492.     }
  493.  
  494.     HUnlock (paraBuf);
  495.     return (result);
  496. }
  497.  
  498. /*
  499.  * Version 3 and version 6 active face structures, as found in
  500.  * the window variable structure.
  501.  */
  502.  
  503. typedef struct
  504. {
  505.     int        font;
  506.     Byte    size;
  507.     Byte    style;
  508. } Face3;
  509.  
  510.  
  511. typedef struct
  512. {
  513.     Byte    size;
  514.     Byte    style;
  515.     int        font;
  516. } Face6;
  517.  
  518.  
  519. static void
  520. CheckWindFormat3 (Windows3 *w, long pos)
  521. {
  522. Format    f;
  523. Face3    face3;
  524.  
  525.     f.fmtFont = w->activeFont;
  526.     f.fmtSize = w->activeFace.faceSize;
  527.     f.fmtStyle = w->activeFace.faceStyle;
  528.     if (MapFormat (&f))
  529.     {
  530.         face3.font = f.fmtFont;
  531.         face3.size = f.fmtSize;
  532.         face3.style = f.fmtStyle;
  533.         FileSeek (macaFRef, pos);
  534.         (void) FileWrite (macaFRef, (Ptr) &face3, (long) sizeof (Face3));
  535.     }
  536. }
  537.  
  538.  
  539. static void
  540. CheckWindFormat6 (Windows6 *w, long pos)
  541. {
  542. Format    f;
  543. Face6    face6;
  544.  
  545.     f.fmtFont = w->activeFont;
  546.     f.fmtSize = w->activeFace.faceSize;
  547.     f.fmtStyle = w->activeFace.faceStyle;
  548.     if (MapFormat (&f))
  549.     {
  550.         face6.font = f.fmtFont;
  551.         face6.size = f.fmtSize;
  552.         face6.style = f.fmtStyle;
  553.         FileSeek (macaFRef, pos);
  554.         (void) FileWrite (macaFRef, (Ptr) &face6, (long) sizeof (Face6));
  555.     }
  556. }
  557.  
  558.  
  559. /*
  560.  * Check the active face information in each of the document's
  561.  * sets of window variables, and change them if they match one
  562.  * of the input specifications.
  563.  */
  564.  
  565. static void
  566. CheckWindowFormats (void)
  567. {
  568.     switch (version)
  569.     {
  570.  
  571.     case version3:
  572.         CheckWindFormat3 (mainWind3, 170L);
  573.         CheckWindFormat3 (headWind3, 204L);
  574.         CheckWindFormat3 (footWind3, 238L);
  575.         break;
  576.     
  577.     case version6:
  578.         CheckWindFormat6 (footWind6, 202L);
  579.         CheckWindFormat6 (headWind6, 248L);
  580.         CheckWindFormat6 (mainWind6, 294L);
  581.         break;
  582.     
  583.     }
  584. }
  585.  
  586.  
  587. /*
  588.  * Change "active document" variable in document globals to -1
  589.  * ("no document"), to signal MacWrite that all the paragraph
  590.  * heights and line height arrays need recalculating.
  591.  *
  592.  * The result of the write isn't returned, because at this point
  593.  * there's nothing else to do afterward anyway
  594.  */
  595.  
  596. static void
  597. ChangeGlobals (void)
  598. {
  599. Int16    buf = -1;
  600.  
  601.     switch (version)
  602.     {
  603.  
  604.     case version3:
  605.         FileSeek (macaFRef, 16L);
  606.         break;
  607.  
  608.     case version6:
  609.         FileSeek (macaFRef, 14L);
  610.         break;
  611.  
  612.     }
  613.     (void) FileWrite (macaFRef, (Ptr) &buf, (long) sizeof (Int16));
  614. }
  615.  
  616.  
  617. /*
  618.  * Reformat document.  inPlace is false if document should be
  619.  * reformatted to another document.
  620.  */
  621.  
  622. void
  623. Reformat (Boolean inPlace)
  624. {
  625. short    f;
  626. Boolean    haveMeter = false;
  627.  
  628.     if (GetInputFile ("\pOpen", 'WORD', &inFile) == false)
  629.         return;
  630.  
  631.     if (inPlace)
  632.         outFile = inFile;
  633.     else if (!GetOutputFile (true, inFile.fName, inFile.vRefNum, &outFile))
  634.         return;
  635.  
  636.     if (inFile.vRefNum != outFile.vRefNum
  637.         || CompareString (inFile.fName, outFile.fName) != 0)
  638.     {
  639.         if (OpenOutputFile (&outFile, 'MACA', 'WORD', &f) == false)
  640.         {
  641.             MeterEnd ();
  642.             return;
  643.         }
  644.         (void) FSClose (f);
  645.  
  646.         MeterBegin ();
  647.         haveMeter = true;
  648.         MeterPos (5, 0);
  649.         MeterString ("\pCopying:  ");
  650.         MeterString (inFile.fName);
  651.         MeterPos (43, 1);
  652.         MeterString ("\pTo:  ");
  653.         MeterString (outFile.fName);
  654.         haveMeter = true;
  655.         if (DoCopy (inFile.fName, inFile.vRefNum,
  656.                             outFile.fName, outFile.vRefNum) == false)
  657.         {
  658.             (void) FSDelete (outFile.fName, outFile.vRefNum);
  659.             MeterEnd ();
  660.             return;
  661.         }
  662.     }
  663.  
  664.     if (OpenMaca (outFile.fName, outFile.vRefNum))    /* convert in place */
  665.     {
  666.         if (!haveMeter)
  667.         {
  668.             MeterBegin ();
  669.             haveMeter = true;
  670.         }
  671.         MeterErase ();
  672.         MeterPos (5, 0);
  673.         MeterString ("\pReformatting:  ");
  674.         MeterString (outFile.fName);
  675.         StartMeterParaInfo (totalParas);
  676.         docModified = false;
  677.         while (ReadPara ())
  678.         {
  679.             SetMeterNum (paraNum + 1);
  680.             if (paraType == textPara)
  681.             {
  682.                 if (FormatsChanged ())
  683.                     if (!RewritePara ())
  684.                         break;                /* write error */
  685.             }
  686.         }
  687.         if (docModified)
  688.         {
  689.             CheckWindowFormats ();    /* change active face in windows */
  690.             ChangeGlobals ();    /* change globals to force recalc */
  691.         }
  692.         CloseMaca ();
  693.     }
  694.     if (haveMeter)
  695.         MeterEnd ();
  696. }
  697.  
  698.  
  699. /*
  700.  * Add formats from MacWrite document to map.  clobber indicates
  701.  * whether to clobber the map first before adding formats.
  702.  *
  703.  * Return false if didn't get a file to add formats from.
  704.  */
  705.  
  706. Boolean
  707. AddFormats (StringPtr bTitle, Boolean clobber)
  708. {
  709. Format    *fmt;
  710. MapSpec    mSpec;
  711. int        i, errCnt;
  712. Boolean    loop = true;
  713. int    size;
  714.  
  715.     if (!GetInputFile (bTitle, 'WORD', &inFile)
  716.         || !OpenMaca (inFile.fName, inFile.vRefNum))
  717.         return (false);
  718.     
  719.     if (clobber)
  720.     {
  721.         ClobberMap ();
  722.         ClearMapName ();
  723.     }
  724.  
  725.     MeterBegin ();
  726.     MeterPos (5, 0);
  727.     MeterString ("\pPulling formats from:  ");
  728.     MeterString (inFile.fName);
  729.     StartMeterParaInfo (totalParas);
  730.     ErrWindInit (inFile.fName);
  731.  
  732.     while (loop && ReadPara ())
  733.     {
  734.         SetMeterNum (paraNum + 1);
  735.         errCnt = 0;
  736.         if (paraType != textPara)
  737.             continue;
  738.  
  739.         HLock (paraBuf);
  740.         fmt = (Format *) (*paraBuf + fmtOffset);
  741.         for (i = 0; i < formats; ++i, ++fmt)
  742.         {
  743.             if ((size = fmt->fmtSize)  < 1 || size > maxPtSize)
  744.             {
  745.                 ErrWindMsge ("\pUnknown size: ", size);
  746.                 ++errCnt;
  747.             }
  748.             if (FontIndex (fmt->fmtFont) <= 0)
  749.             {
  750.                 ErrWindMsge ("\pUnknown font number: ", fmt->fmtFont);
  751.                 ++errCnt;
  752.             }
  753.             if (fmt->fmtStyle & anyStyle)    /* this bit shouldn't be set */
  754.             {
  755.                 ErrWindMsge ("\pUnknown style: ", (int) fmt->fmtStyle);
  756.                 ++errCnt;
  757.             }
  758.             if (errCnt)
  759.                 continue;
  760.  
  761.             FormatToMSpec (fmt, &mSpec);
  762.             if (StatMSpec (&mSpec))
  763.             {
  764.                 continue;
  765.             }
  766.  
  767.             if (InsertMapping (&mSpec, mapList->nLines) == false)
  768.             {
  769.                 loop = false;
  770.                 break;
  771.             }
  772.         }
  773.         HUnlock (paraBuf);
  774.     }
  775.  
  776.     CloseMaca ();
  777.     MeterEnd ();
  778.     return (true);
  779. }
  780.  
  781.  
  782. /*
  783.  * Use a display window to show document format information.
  784.  */
  785.  
  786.  
  787. /*
  788.  * Display text paragraph info - version 3.
  789.  *
  790.  * (Also used right now for version 6 - since it only displays
  791.  * formats and they're the same for both versions.)
  792.  *
  793.  * Lots of globals are assumed already set up.
  794.  */
  795.  
  796. static void
  797. ShowTextPara3and6 (void)
  798. {
  799. Format    *fmt;
  800. Int16    i, fidx;
  801. Str255    s;
  802.  
  803.     fmt = (Format *) (*paraBuf + fmtOffset);
  804.     for (i = 0; i < formats; ++i)
  805.     {
  806.         DisplayString ("\pchar ");
  807.         DisplayShort (fmt->fmtPos);
  808.         DisplayString ("\p font ");
  809.         if (FontIndex (fmt->fmtFont) == -1 || fmt->fmtFont == anyFont)
  810.         {
  811.             DisplayShort (fmt->fmtFont);
  812.             DisplayString ("\p (name unknown) ");
  813.         }
  814.         else
  815.         {
  816.             FontToStr (fmt->fmtFont, s, "\p???");
  817.             DisplayString (s);
  818.         }
  819.         DisplayString ("\p size ");
  820.         DisplayShort ((Int16) fmt->fmtSize);
  821.         DisplayString ("\p style ");
  822.         StyleToStr (fmt->fmtStyle, s, "\p???");
  823.         DisplayString (s);
  824.         DisplayLn ();
  825.         ++fmt;
  826.     }
  827. }
  828.  
  829.  
  830. /*
  831.  * Display text paragraph info
  832.  */
  833.  
  834. static void
  835. ShowTextParaInfo (void)
  836. {
  837.     DisplayString ("\p\rParagraph ");
  838.     DisplayShort (paraNum);
  839.     /*DisplayString ("\p Length ");
  840.     DisplayShort (paraLen);
  841.     DisplayString ("\p Text length ");
  842.     DisplayShort (textLen);
  843.     DisplayString ("\p # formats ");
  844.     DisplayShort (formats);
  845.     DisplayString ("\p format offset ");
  846.     DisplayShort (fmtOffset);*/
  847.     DisplayLn ();
  848.  
  849.     HLock (paraBuf);
  850.     switch (version)
  851.     {
  852.  
  853.     case version3:
  854.     case version6:
  855.         ShowTextPara3and6 ();
  856.         break;
  857.  
  858.     }
  859.     HUnlock (paraBuf);
  860. }
  861.  
  862.  
  863. void
  864. ShowFormats (void)
  865. {
  866. Str255    s;
  867.  
  868.     if (GetInputFile ("\pOpen", 'WORD', &inFile)
  869.         && OpenMaca (inFile.fName, inFile.vRefNum))
  870.     {
  871.         SkelDoUpdates ();
  872.  
  873.         MeterBegin ();
  874.         MeterPos (5, 0);
  875.         MeterString ("\pShowing formats:  ");
  876.         MeterString (inFile.fName);
  877.         StartMeterParaInfo (totalParas);
  878.  
  879.         CopyString ("\pFormats from \"", s);
  880.         AppendString (inFile.fName, s);
  881.         AppendString ("\p\"", s);
  882.         DisplayWindow (s, true);
  883.  
  884.         while (ReadPara ())
  885.         {
  886.             SetMeterNum (paraNum + 1);
  887.             if (paraType == textPara)
  888.             {
  889.                 ShowTextParaInfo ();
  890.             }
  891.             if (MouseClick ())
  892.                 break;
  893.         }
  894.         CloseMaca ();
  895.         MeterEnd ();
  896.     }
  897. }
  898.