home *** CD-ROM | disk | FTP | other *** search
- /*
- * FaceLift File I/O Routines.
- */
-
- # include "TransSkel.h"
- # include "TransDisplay.h"
-
- # include "FLMaca.h"
- # include "FLFileStuff.h"
- # include "FaceLift.h"
-
-
- static SFReply inFile;
- static SFReply outFile;
- static Str255 fName; /* map name and volume reference number */
- static int vRefNum;
-
- static Boolean docModified;
-
-
- /*
- * Clear the current file name, and cause the title of the map
- * window to be reset. Obviously, the first call to this must occur
- * after the map window is initialized.
- */
-
- void
- ClearMapName (void)
- {
- CopyString ("\puntitled", fName);
- SetMapName (fName);
- }
-
-
- void
- SetMapName (StringPtr name)
- {
- Str255 s;
-
- CopyString ("\pMap Name: ", s);
- AppendString (name, s);
- SetWTitle (mapWind, s);
- }
-
-
- /*
- * Check a ConvSpec to see that it makes sense
- */
-
- static Boolean
- CheckCSpec (ConvSpec *c)
- {
- int errCnt = 0;
- int size;
-
- if (FontIndex (c->font) < 0)
- {
- ErrWindMsge ("\pUnknown font number: ", c->font);
- ++errCnt;
- }
- if ((size = c->size) != anySize && (size < 1 || size > maxPtSize))
- {
- ErrWindMsge ("\pUnknown size: ", (int) size);
- ++errCnt;
- }
-
- return (errCnt == 0);
- }
-
-
- /*
- * Read map specifications from a file. Won't add duplicate or illegal
- * specifications.
- *
- * Assumes file is open and all mappings already cleared (for Open) or
- * not (for Append).
- *
- * Does not set undo variables or map changed variables.
- */
-
- static void
- ReadMap (int f)
- {
- MapSpec mSpec;
- int badCnt = 0;
- Str255 str;
- int ver;
-
- MakeFrontWind (mapWind);
- ErrWindInit (inFile.fName);
- if (!FileRead (f, (Ptr) &ver, (long) sizeof (int)))
- {
- Message1 ("\pCan't read map file.");
- }
- else if (ver != mapVersion)
- {
- NumToString ((long) ver, str);
- Message2 ("\pUnknown map file version: ", str);
- }
- else while (FileRead (f, (Ptr) &mSpec, (long) sizeof (MapSpec)))
- {
- /*
- * Need to check legality here, since the file may have been
- * created using the fonts from a font list other than the current
- * one.
- */
-
- if (CheckCSpec (&mSpec.inFmt) == false
- || CheckCSpec (&mSpec.outFmt) == false)
- {
- ++badCnt;
- continue;
- }
-
- if (StatMSpec (&mSpec))
- {
- ++badCnt;
- continue; /* already exists - don't use dups */
- }
-
- if (InsertMapping (&mSpec, mapList->nLines) == false)
- break;
- }
-
- (void) FSClose (f);
- ScrollToLine (mapList, 0); /* force scroll to top */
- SelectMapping (noLine); /* but leave unselected */
-
- if (badCnt)
- {
- NumToString ((long) badCnt, str);
- Message2 (str, "\p illegal or duplicate specifications were found and ignored");
- }
- }
-
-
- /*
- * Open a map. Clobber the current map first, set the map name
- * afterward.
- */
-
- Boolean
- OpenMap (void)
- {
- short f;
-
- if (GetInputFile ("\pOpen", faceType, &inFile)
- && OpenInputFile (&inFile, &f))
- {
- ClobberMap ();
- ReadMap (f);
- CopyString (inFile.fName, fName); /* some redundancy... */
- vRefNum = inFile.vRefNum;
- SetMapName (fName);
- return (true);
- }
- return (false);
- }
-
-
- /*
- * Add a map to the current map. Doesn't set map name afterward.
- */
-
- Boolean
- AddMap (void)
- {
- short f;
-
- if (GetInputFile ("\pAdd", faceType, &inFile)
- && OpenInputFile (&inFile, &f))
- {
- ReadMap (f);
- return (true);
- }
- return (false);
- }
-
-
- /*
- * Save map to file. askForName is true if should ask for name,
- * otherwise use current name. If name is "untitled", ask for a name
- * anyway. Sets the current name if it wasn't already set.
- *
- * The file is deleted if not written properly.
- */
-
- Boolean
- SaveMap (Boolean askForName)
- {
- short f;
- OSErr result;
- long amount;
- long pos;
- short ver;
- Boolean ok = false;
-
- if (GetOutputFile (askForName, fName, vRefNum, &outFile) == false)
- return (false);
- if (OpenOutputFile (&outFile, faceCreator, faceType, &f) == false)
- return (false);
-
- ver = mapVersion;
- if (FileWrite (f, (Ptr) &ver, (long) sizeof (int)))
- {
- amount = mapList->nLines * sizeof (MapSpec);
- if (FileWrite (f, (Ptr) &mapSpec, amount))
- ok = true;
- }
-
- (void) GetFPos (f, &pos);
- (void) SetEOF (f, pos);
- (void) FSClose (f);
- (void) FlushVol (nil /*f*/, outFile.vRefNum);
-
- if (!ok)
- {
- Message1 ("\pCould not write map");
- (void) FSDelete (outFile.fName, outFile.vRefNum);
- return (false);
- }
-
- CopyString (outFile.fName, fName); /* set map name */
- vRefNum = outFile.vRefNum;
- SetMapName (fName);
- return (true);
- }
-
-
- /* ---------------------------------------------------------------- */
- /* File-Copying Code */
- /* ---------------------------------------------------------------- */
-
-
- /*
- * Open both forks of the input and output files. Fail if
- * can't get them all open, and leave no forks open. Otherwise
- * return true.
- */
-
- static Boolean
- OpenForks (StringPtr inName, short inVRefNum,
- StringPtr outName, short outVRefNum,
- short *idf, short *irf, short *odf, short *orf)
- {
- if (FSOpen (inName, inVRefNum, idf) == noErr)
- {
- if (OpenRF (inName, inVRefNum, irf) == noErr)
- {
- if (FSOpen (outName, outVRefNum, odf) == noErr)
- {
- if (OpenRF (outName, outVRefNum, orf) == noErr)
- {
- return (true);
- }
- else
- Message1 ("\pCan't open output resource fork.");
- (void) FSClose (*odf);
- }
- else
- Message1 ("\pCan't open output data fork.");
- (void) FSClose (*irf);
- }
- else
- Message1 ("\pCan't open input resource fork.");
- (void) FSClose (*idf);
- }
- else
- Message1 ("\pCan't open input data fork.");
- return (false);
- }
-
-
- /*
- * Copy size bytes from one fork to another. Return false if
- * everything isn't right.
- */
-
- static Boolean
- CopyFork (int inRef, int outRef, long size)
- {
- Ptr p;
- long toWrite;
- long count;
- long pos;
- long blkSize;
- OSErr err;
-
- blkSize = CompactMem (size); /* see how big a block can be gotten */
- if (blkSize > size)
- blkSize = size; /* don't make bigger than needed */
- if (blkSize > 32768L)
- blkSize = 32768L; /* or bigger than 32K */
-
- if (blkSize == 0 && size != 0)
- {
- Message1 ("\pNo memory for copy.");
- return (false);
- }
-
- p = NewPtr (blkSize);
-
- toWrite = size;
- while (toWrite > 0)
- {
- count = (toWrite < blkSize ? toWrite : blkSize);
- if (!FileRead (inRef, p, count))
- {
- Message1 ("\pRead error");
- break;
- }
- if (!FileWrite (outRef, p, count))
- break; /* (FileWrite prints its own message) */
- toWrite -= blkSize;
- }
-
- DisposPtr (p);
- (void) GetFPos (outRef, &pos);
- (void) SetEOF (outRef, pos);
- if (pos != size)
- Message1 ("\pIncomplete copy");
- return (pos == size);
- }
-
-
- /*
- * Copy a file. It is assumed that input and output files
- * both exist, and are of matching creator and type.
- *
- * If space can't be allocated, should deallocate any already-
- * allocated space, or delete the file. This is a flaw.
- */
-
- static Boolean
- DoCopy (StringPtr inName, int inVRefNum, StringPtr outName, int outVRefNum)
- {
- short idf, irf, odf, orf;
- long idSize, irSize, odSize, orSize, dAlloc, rAlloc;
- Boolean result = false;
- OSErr err;
-
- if (OpenForks (inName, inVRefNum, outName, outVRefNum,
- &idf, &irf, &odf, &orf) == false)
- return (false);
-
- (void) GetEOF (idf, &idSize);
- (void) GetEOF (irf, &irSize);
- (void) SetEOF (odf, 0L); /* truncate both forks */
- (void) SetEOF (orf, 0L);
- /*(void) GetEOF (odf, &odSize);
- (void) GetEOF (orf, &orSize);
- dAlloc = idSize - odSize;
- rAlloc = irSize - orSize;
- if (dAlloc > 0 && (err = Allocate (odf, &dAlloc)) != noErr)
- FileErr (err);
- else if (rAlloc > 0 && (err = Allocate (orf, &rAlloc)) != noErr)
- FileErr (err);*/
- dAlloc = idSize;
- rAlloc = irSize;
- if ((err = Allocate (odf, &dAlloc)) != noErr)
- FileErr (err);
- else if ((err = Allocate (orf, &rAlloc)) != noErr)
- FileErr (err);
- else if (CopyFork (idf, odf, idSize) && CopyFork (irf, orf, irSize))
- result = true;
-
- (void) FSClose (idf);
- (void) FSClose (irf);
- (void) FSClose (odf);
- (void) FSClose (orf);
- (void) FlushVol (nil, outVRefNum);
- return (result);
- }
-
-
- /*
- * Rewrite a paragraph which has had the format information modified.
- * This attempts to be smart and write ONLY the format information.
- * The current file position is saved and restored, so this operation
- * is transparent to other things going on.
- *
- * If the paragraph isn't a text paragraph, it doesn't make sense to
- * rewrite the formats, so nothing is done.
- */
-
- static Boolean
- RewritePara (void)
- {
- long curFilePos;
- Boolean result;
-
- if (paraType != textPara)
- return;
- GetFPos (macaFRef, &curFilePos); /* get current position */
- FileSeek (macaFRef, paraFilePos + fmtOffset); /* seek to formats */
- HLock (paraBuf);
- result = FileWrite (macaFRef, *paraBuf + fmtOffset, (long) (formats * sizeof (Format)));
- HUnlock (paraBuf);
- FileSeek (macaFRef, curFilePos); /* restore position */
- return (result);
- }
-
-
- /*
- * Determine if a document format matches a map input format.
- *
- * This is an exercise in ugly programming. In languages w/o
- * short-circuiting of boolean expression evaluation, it would
- * be more efficient to have three separate tests.
- */
-
- static Boolean
- TestFormat (Format *fmt, ConvSpec *cSpec)
- {
- return ((cSpec->font == anyFont || cSpec->font == fmt->fmtFont)
- &&
- (cSpec->size == anySize || cSpec->size == fmt->fmtSize)
- &&
- (cSpec->style == anyStyle || cSpec->style == fmt->fmtStyle));
- }
-
-
- /*
- * Found a document format that matches a map input format. Change the
- * format to match the corresponding map output format (change only
- * those parts of the output format that aren't "same" (i.e., "any").
- * Set the flag that indicates whether the document has been changed.
- */
-
- static void
- ChangeFormat (Format *fmt, ConvSpec *cSpec)
- {
- if (cSpec->font != anyFont)
- fmt->fmtFont = cSpec->font;
- if (cSpec->size != anySize)
- fmt->fmtSize = cSpec->size;
- if (cSpec->style != anyStyle)
- fmt->fmtStyle = cSpec->style;
-
- docModified = true;
- }
-
-
- /*
- * Examine a document format, checking it against the map input
- * formats. If it matches any of them, change to the corresponding
- * map output format and stop checking against the map.
- */
-
- static Boolean
- MapFormat (Format *f)
- {
- int i;
-
- for (i = 0; i < mapList->nLines; ++i)
- {
- if (TestFormat (f, &mapSpec[i].inFmt))
- {
- ChangeFormat (f, &mapSpec[i].outFmt);
- return (true); /* quit looking */
- }
- }
- return (false); /* didn't match anything */
- }
-
-
- /*
- * Examine all the formats for a paragraph and change those
- * that match any of the input specifications. Return true if any
- * of them match, false if none do.
- *
- * For each format, cease checking as soon as a match is found.
- *
- * This routine is used for version 3 and version6, since format data
- * in paragraphs are stored the same way in both versions.
- */
-
- static Boolean
- FormatsChanged (void)
- {
- Boolean result = false;
- Format *f;
- Int16 i;
-
- HLock (paraBuf);
- f = (Format *) (*paraBuf + fmtOffset);
-
- for (i = 0; i < formats; ++i)
- {
- if (MapFormat (f++))
- result = true;
- }
-
- HUnlock (paraBuf);
- return (result);
- }
-
- /*
- * Version 3 and version 6 active face structures, as found in
- * the window variable structure.
- */
-
- typedef struct
- {
- int font;
- Byte size;
- Byte style;
- } Face3;
-
-
- typedef struct
- {
- Byte size;
- Byte style;
- int font;
- } Face6;
-
-
- static void
- CheckWindFormat3 (Windows3 *w, long pos)
- {
- Format f;
- Face3 face3;
-
- f.fmtFont = w->activeFont;
- f.fmtSize = w->activeFace.faceSize;
- f.fmtStyle = w->activeFace.faceStyle;
- if (MapFormat (&f))
- {
- face3.font = f.fmtFont;
- face3.size = f.fmtSize;
- face3.style = f.fmtStyle;
- FileSeek (macaFRef, pos);
- (void) FileWrite (macaFRef, (Ptr) &face3, (long) sizeof (Face3));
- }
- }
-
-
- static void
- CheckWindFormat6 (Windows6 *w, long pos)
- {
- Format f;
- Face6 face6;
-
- f.fmtFont = w->activeFont;
- f.fmtSize = w->activeFace.faceSize;
- f.fmtStyle = w->activeFace.faceStyle;
- if (MapFormat (&f))
- {
- face6.font = f.fmtFont;
- face6.size = f.fmtSize;
- face6.style = f.fmtStyle;
- FileSeek (macaFRef, pos);
- (void) FileWrite (macaFRef, (Ptr) &face6, (long) sizeof (Face6));
- }
- }
-
-
- /*
- * Check the active face information in each of the document's
- * sets of window variables, and change them if they match one
- * of the input specifications.
- */
-
- static void
- CheckWindowFormats (void)
- {
- switch (version)
- {
-
- case version3:
- CheckWindFormat3 (mainWind3, 170L);
- CheckWindFormat3 (headWind3, 204L);
- CheckWindFormat3 (footWind3, 238L);
- break;
-
- case version6:
- CheckWindFormat6 (footWind6, 202L);
- CheckWindFormat6 (headWind6, 248L);
- CheckWindFormat6 (mainWind6, 294L);
- break;
-
- }
- }
-
-
- /*
- * Change "active document" variable in document globals to -1
- * ("no document"), to signal MacWrite that all the paragraph
- * heights and line height arrays need recalculating.
- *
- * The result of the write isn't returned, because at this point
- * there's nothing else to do afterward anyway
- */
-
- static void
- ChangeGlobals (void)
- {
- Int16 buf = -1;
-
- switch (version)
- {
-
- case version3:
- FileSeek (macaFRef, 16L);
- break;
-
- case version6:
- FileSeek (macaFRef, 14L);
- break;
-
- }
- (void) FileWrite (macaFRef, (Ptr) &buf, (long) sizeof (Int16));
- }
-
-
- /*
- * Reformat document. inPlace is false if document should be
- * reformatted to another document.
- */
-
- void
- Reformat (Boolean inPlace)
- {
- short f;
- Boolean haveMeter = false;
-
- if (GetInputFile ("\pOpen", 'WORD', &inFile) == false)
- return;
-
- if (inPlace)
- outFile = inFile;
- else if (!GetOutputFile (true, inFile.fName, inFile.vRefNum, &outFile))
- return;
-
- if (inFile.vRefNum != outFile.vRefNum
- || CompareString (inFile.fName, outFile.fName) != 0)
- {
- if (OpenOutputFile (&outFile, 'MACA', 'WORD', &f) == false)
- {
- MeterEnd ();
- return;
- }
- (void) FSClose (f);
-
- MeterBegin ();
- haveMeter = true;
- MeterPos (5, 0);
- MeterString ("\pCopying: ");
- MeterString (inFile.fName);
- MeterPos (43, 1);
- MeterString ("\pTo: ");
- MeterString (outFile.fName);
- haveMeter = true;
- if (DoCopy (inFile.fName, inFile.vRefNum,
- outFile.fName, outFile.vRefNum) == false)
- {
- (void) FSDelete (outFile.fName, outFile.vRefNum);
- MeterEnd ();
- return;
- }
- }
-
- if (OpenMaca (outFile.fName, outFile.vRefNum)) /* convert in place */
- {
- if (!haveMeter)
- {
- MeterBegin ();
- haveMeter = true;
- }
- MeterErase ();
- MeterPos (5, 0);
- MeterString ("\pReformatting: ");
- MeterString (outFile.fName);
- StartMeterParaInfo (totalParas);
- docModified = false;
- while (ReadPara ())
- {
- SetMeterNum (paraNum + 1);
- if (paraType == textPara)
- {
- if (FormatsChanged ())
- if (!RewritePara ())
- break; /* write error */
- }
- }
- if (docModified)
- {
- CheckWindowFormats (); /* change active face in windows */
- ChangeGlobals (); /* change globals to force recalc */
- }
- CloseMaca ();
- }
- if (haveMeter)
- MeterEnd ();
- }
-
-
- /*
- * Add formats from MacWrite document to map. clobber indicates
- * whether to clobber the map first before adding formats.
- *
- * Return false if didn't get a file to add formats from.
- */
-
- Boolean
- AddFormats (StringPtr bTitle, Boolean clobber)
- {
- Format *fmt;
- MapSpec mSpec;
- int i, errCnt;
- Boolean loop = true;
- int size;
-
- if (!GetInputFile (bTitle, 'WORD', &inFile)
- || !OpenMaca (inFile.fName, inFile.vRefNum))
- return (false);
-
- if (clobber)
- {
- ClobberMap ();
- ClearMapName ();
- }
-
- MeterBegin ();
- MeterPos (5, 0);
- MeterString ("\pPulling formats from: ");
- MeterString (inFile.fName);
- StartMeterParaInfo (totalParas);
- ErrWindInit (inFile.fName);
-
- while (loop && ReadPara ())
- {
- SetMeterNum (paraNum + 1);
- errCnt = 0;
- if (paraType != textPara)
- continue;
-
- HLock (paraBuf);
- fmt = (Format *) (*paraBuf + fmtOffset);
- for (i = 0; i < formats; ++i, ++fmt)
- {
- if ((size = fmt->fmtSize) < 1 || size > maxPtSize)
- {
- ErrWindMsge ("\pUnknown size: ", size);
- ++errCnt;
- }
- if (FontIndex (fmt->fmtFont) <= 0)
- {
- ErrWindMsge ("\pUnknown font number: ", fmt->fmtFont);
- ++errCnt;
- }
- if (fmt->fmtStyle & anyStyle) /* this bit shouldn't be set */
- {
- ErrWindMsge ("\pUnknown style: ", (int) fmt->fmtStyle);
- ++errCnt;
- }
- if (errCnt)
- continue;
-
- FormatToMSpec (fmt, &mSpec);
- if (StatMSpec (&mSpec))
- {
- continue;
- }
-
- if (InsertMapping (&mSpec, mapList->nLines) == false)
- {
- loop = false;
- break;
- }
- }
- HUnlock (paraBuf);
- }
-
- CloseMaca ();
- MeterEnd ();
- return (true);
- }
-
-
- /*
- * Use a display window to show document format information.
- */
-
-
- /*
- * Display text paragraph info - version 3.
- *
- * (Also used right now for version 6 - since it only displays
- * formats and they're the same for both versions.)
- *
- * Lots of globals are assumed already set up.
- */
-
- static void
- ShowTextPara3and6 (void)
- {
- Format *fmt;
- Int16 i, fidx;
- Str255 s;
-
- fmt = (Format *) (*paraBuf + fmtOffset);
- for (i = 0; i < formats; ++i)
- {
- DisplayString ("\pchar ");
- DisplayShort (fmt->fmtPos);
- DisplayString ("\p font ");
- if (FontIndex (fmt->fmtFont) == -1 || fmt->fmtFont == anyFont)
- {
- DisplayShort (fmt->fmtFont);
- DisplayString ("\p (name unknown) ");
- }
- else
- {
- FontToStr (fmt->fmtFont, s, "\p???");
- DisplayString (s);
- }
- DisplayString ("\p size ");
- DisplayShort ((Int16) fmt->fmtSize);
- DisplayString ("\p style ");
- StyleToStr (fmt->fmtStyle, s, "\p???");
- DisplayString (s);
- DisplayLn ();
- ++fmt;
- }
- }
-
-
- /*
- * Display text paragraph info
- */
-
- static void
- ShowTextParaInfo (void)
- {
- DisplayString ("\p\rParagraph ");
- DisplayShort (paraNum);
- /*DisplayString ("\p Length ");
- DisplayShort (paraLen);
- DisplayString ("\p Text length ");
- DisplayShort (textLen);
- DisplayString ("\p # formats ");
- DisplayShort (formats);
- DisplayString ("\p format offset ");
- DisplayShort (fmtOffset);*/
- DisplayLn ();
-
- HLock (paraBuf);
- switch (version)
- {
-
- case version3:
- case version6:
- ShowTextPara3and6 ();
- break;
-
- }
- HUnlock (paraBuf);
- }
-
-
- void
- ShowFormats (void)
- {
- Str255 s;
-
- if (GetInputFile ("\pOpen", 'WORD', &inFile)
- && OpenMaca (inFile.fName, inFile.vRefNum))
- {
- SkelDoUpdates ();
-
- MeterBegin ();
- MeterPos (5, 0);
- MeterString ("\pShowing formats: ");
- MeterString (inFile.fName);
- StartMeterParaInfo (totalParas);
-
- CopyString ("\pFormats from \"", s);
- AppendString (inFile.fName, s);
- AppendString ("\p\"", s);
- DisplayWindow (s, true);
-
- while (ReadPara ())
- {
- SetMeterNum (paraNum + 1);
- if (paraType == textPara)
- {
- ShowTextParaInfo ();
- }
- if (MouseClick ())
- break;
- }
- CloseMaca ();
- MeterEnd ();
- }
- }
-