410 lines
13 KiB
C
410 lines
13 KiB
C
/************************************************************/
|
|
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
|
|
/************************************************************/
|
|
|
|
/* doc.c -- MW document processing routines (non-resident) */
|
|
|
|
#define NOGDICAPMASKS
|
|
#define NOVIRTUALKEYCODES
|
|
#define NOWINMESSAGES
|
|
#define NOWINSTYLES
|
|
#define NOSYSMETRICS
|
|
#define NOMENUS
|
|
#define NOICON
|
|
#define NOKEYSTATE
|
|
#define NOSYSCOMMANDS
|
|
#define NORASTEROPS
|
|
#define NOSHOWWINDOW
|
|
#define NOATOM
|
|
#define NOBITMAP
|
|
#define NOBRUSH
|
|
#define NOCLIPBOARD
|
|
#define NOCOLOR
|
|
#define NOCREATESTRUCT
|
|
#define NOCTLMGR
|
|
#define NODRAWTEXT
|
|
#define NOFONT
|
|
#define NOGDI
|
|
#define NOHDC
|
|
#define NOMB
|
|
#define NOMEMMGR
|
|
#define NOMENUS
|
|
#define NOMETAFILE
|
|
#define NOMINMAX
|
|
#define NOMSG
|
|
#define NOOPENFILE
|
|
#define NOPEN
|
|
#define NOPOINT
|
|
#define NOREGION
|
|
#define NOSCROLL
|
|
#define NOSOUND
|
|
#define NOTEXTMETRIC
|
|
#define NOWH
|
|
#define NOWINOFFSETS
|
|
#define NOWNDCLASS
|
|
#define NOCOMM
|
|
#include <windows.h>
|
|
|
|
#include "mw.h"
|
|
#include "editdefs.h"
|
|
#include "docdefs.h"
|
|
#include "fontdefs.h"
|
|
#include "cmddefs.h"
|
|
#include "filedefs.h"
|
|
#include "str.h"
|
|
#include "fmtdefs.h"
|
|
#include "propdefs.h"
|
|
#include "fkpdefs.h"
|
|
#define NOKCCODES
|
|
#include "ch.h"
|
|
#include "stcdefs.h"
|
|
#include "printdef.h" /* printdefs.h */
|
|
#include "macro.h"
|
|
|
|
|
|
extern struct DOD (**hpdocdod)[];
|
|
extern int docMac;
|
|
extern int docScrap;
|
|
extern int docUndo;
|
|
#ifdef STYLES
|
|
#ifdef SAND
|
|
extern CHAR szSshtEmpty[];
|
|
#else
|
|
extern CHAR szSshtEmpty[];
|
|
#endif
|
|
#endif
|
|
|
|
/* E X T E R N A L S */
|
|
extern int docRulerSprm;
|
|
extern int vfSeeSel;
|
|
extern struct SEP vsepNormal;
|
|
extern struct CHP vchpNormal;
|
|
extern int docCur;
|
|
extern struct FLI vfli;
|
|
extern int vdocParaCache;
|
|
extern struct FCB (**hpfnfcb)[];
|
|
extern struct UAB vuab;
|
|
extern typeCP cpMacCur;
|
|
extern struct SEL selCur;
|
|
extern int vdocExpFetch;
|
|
extern CHAR (**hszSearch)[];
|
|
extern typeCP vcpFetch;
|
|
extern int vccpFetch;
|
|
extern CHAR *vpchFetch;
|
|
extern struct CHP vchpFetch;
|
|
#ifdef STYLES
|
|
extern struct PAP vpapCache;
|
|
extern CHAR mpusgstcBase[];
|
|
#endif
|
|
extern int vrefFile;
|
|
|
|
|
|
struct PGTB **HpgtbCreate();
|
|
|
|
|
|
#ifdef ENABLE /* This is never called */
|
|
int DocFromSz(sz, dty)
|
|
CHAR sz[];
|
|
/* Return doc if one with that name exists already */
|
|
{
|
|
int doc;
|
|
struct DOD *pdod = &(**hpdocdod)[0];
|
|
struct DOD *pdodMac = pdod + docMac;
|
|
|
|
if (sz[0] == 0)
|
|
return docNil;
|
|
|
|
for (doc = 0; pdod < pdodMac; ++pdod, ++doc)
|
|
if (pdod->hpctb != 0 && pdod->dty == dty &&
|
|
FSzSame(sz, **pdod->hszFile)
|
|
#ifdef SAND
|
|
&& (pdod->vref == vrefFile)
|
|
#endif
|
|
)
|
|
{
|
|
++pdod->cref;
|
|
return doc;
|
|
}
|
|
return docNil;
|
|
}
|
|
#endif
|
|
|
|
|
|
KillDoc(doc)
|
|
int doc;
|
|
{ /* Wipe this doc, destroying any changes since last save */
|
|
extern int vdocBitmapCache;
|
|
|
|
if (doc == docScrap)
|
|
return; /* Can't be killed no-how */
|
|
|
|
if (--(**hpdocdod)[doc].cref == 0)
|
|
{
|
|
struct FNTB **hfntb;
|
|
#ifdef CASHMERE
|
|
struct SETB **hsetb;
|
|
#else
|
|
struct SEP **hsep;
|
|
#endif
|
|
struct FFNTB **hffntb;
|
|
struct TBD (**hgtbd)[];
|
|
CHAR (**hsz)[];
|
|
int docSsht;
|
|
|
|
SmashDocFce( doc );
|
|
|
|
/* Kill style sheet doc if there is one. */
|
|
if ((docSsht = (**hpdocdod)[doc].docSsht) != docNil)
|
|
KillDoc(docSsht);
|
|
|
|
/* Free piece table, filename, and footnote (or style) table */
|
|
FreeH((**hpdocdod)[doc].hpctb);
|
|
(**hpdocdod)[doc].hpctb = 0; /* To show doc free */
|
|
if ((hsz = (**hpdocdod)[doc].hszFile) != 0)
|
|
FreeH(hsz);
|
|
if ((hfntb = (**hpdocdod)[doc].hfntb) != 0)
|
|
FreeH(hfntb);
|
|
#ifdef CASHMERE
|
|
if ((hsetb = (**hpdocdod)[doc].hsetb) != 0)
|
|
FreeH(hsetb);
|
|
#else
|
|
if ((hsep = (**hpdocdod)[doc].hsep) != 0)
|
|
FreeH(hsep);
|
|
#endif
|
|
|
|
if ((hgtbd = (**hpdocdod)[doc].hgtbd) != 0)
|
|
FreeH( hgtbd );
|
|
if ((hffntb = (**hpdocdod)[doc].hffntb) != 0)
|
|
FreeFfntb(hffntb);
|
|
|
|
if (doc == vdocBitmapCache)
|
|
FreeBitmapCache();
|
|
|
|
InvalidateCaches(doc);
|
|
if (docCur == doc)
|
|
docCur = docNil;
|
|
if (docRulerSprm == doc)
|
|
docRulerSprm = docNil;
|
|
if (vuab.doc == doc || vuab.doc2 == doc)
|
|
NoUndo();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#ifdef STYLES
|
|
struct SYTB **HsytbCreate(doc)
|
|
int doc;
|
|
{ /* Create a map from stc to cp for a style sheet */
|
|
typeCP cp, *pcp;
|
|
struct SYTB **hsytb;
|
|
typeCP cpMac;
|
|
int stc, usg, stcBase, stcMin;
|
|
int ch, cch, cchT;
|
|
int *pbchFprop, *mpstcbchFprop;
|
|
CHAR *pchFprop, *grpchFprop;
|
|
int iakd, iakdT, cakd, cakdBase;
|
|
struct AKD *rgakd, *pakd;
|
|
#ifdef DEBUG
|
|
int cakdTotal;
|
|
#endif
|
|
|
|
CHAR rgch[3];
|
|
CHAR mpchcakc[chMaxAscii];
|
|
typeCP mpstccp[stcMax];
|
|
|
|
/* First, clear out the stc-->cp map by filling with cpNil. */
|
|
for (stc = 0, pcp = &mpstccp[0]; stc < stcMax; stc++, pcp++)
|
|
*pcp = cpNil;
|
|
bltbc(mpchcakc, 0, chMaxAscii);
|
|
|
|
/* Now go through all entries in the style sheet. In this pass,
|
|
check for duplicates (and return 0 if in gallery mode), fill
|
|
mpstccp with appropriate entries for all defined stc's, and
|
|
count the length of all the styles so we can allocate the heap
|
|
block later. */
|
|
cpMac = (**hpdocdod)[doc].cpMac;
|
|
for (cp = 0, cch = 0, cakd = 1, cakdBase = 1; cp < cpMac; cp += ccpSshtEntry)
|
|
{
|
|
FetchRgch(&cchT, rgch, doc, cp, cpMac, 3);
|
|
stc = rgch[0]; /* stc is first cp of entry */
|
|
#ifdef DEBUG
|
|
Assert(stc < stcMax);
|
|
#endif
|
|
if (mpstccp[stc] != cpNil && doc == docCur)
|
|
{ /* Repeated entry */
|
|
Error(IDPMTStcRepeat);
|
|
goto ErrRet;
|
|
}
|
|
mpstccp[stc] = cp;
|
|
if (stc < stcSectMin)
|
|
{
|
|
FetchCp(doc, cp, 0, fcmProps);
|
|
cch += CchDiffer(&vchpFetch, &vchpNormal, cchCHP) + 1;
|
|
}
|
|
if (stc >= stcParaMin)
|
|
{
|
|
CachePara(doc, cp);
|
|
if (stc >= stcSectMin)
|
|
cch += CchDiffer(&vpapCache, &vsepNormal, cchSEP) + 1;
|
|
else
|
|
cch += CchDiffer(&vpapCache, &vpapStd, cchPAP) + 1;
|
|
}
|
|
ch = rgch[1];
|
|
if (ch != ' ')
|
|
{ /* Define an alt-key code for this style */
|
|
++cakd;
|
|
if (rgch[2] == ' ')
|
|
{
|
|
if (mpchcakc[ch]-- != 0)
|
|
{
|
|
Error(IDPMTAkcRepeat);
|
|
goto ErrRet;
|
|
}
|
|
++cakdBase;
|
|
}
|
|
else
|
|
{
|
|
++mpchcakc[ch]; /* increment before switch to avoid
|
|
the increment being taken
|
|
as for an int. */
|
|
switch (mpchcakc[ch])
|
|
{
|
|
case 0:
|
|
Error(IDPMTAkcRepeat);
|
|
goto ErrRet;
|
|
case 1:
|
|
++cakdBase;
|
|
++cakd;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Now allocate the heap block, using the total we got above. */
|
|
/* HEAP MOVEMENT */
|
|
hsytb = (struct SYTB **) HAllocate(cwSYTBBase + cwAKD * cakd +
|
|
CwFromCch(cch));
|
|
|
|
if (FNoHeap(hsytb))
|
|
return hOverflow;
|
|
|
|
/* Now go through the stc-->cp map, filling in the stc-->fprop map
|
|
in the sytb. For each stc that isn't defined, determine which
|
|
stc to alias it to (either the first of the usage or, if that
|
|
one isn't defined, the first one of the first usage). Copy the
|
|
actual CHP's, PAP's, and SEP's into grpchFprop. */
|
|
mpstcbchFprop = (**hsytb).mpstcbchFprop;
|
|
rgakd = (struct AKD *) (grpchFprop = (**hsytb).grpchFprop);
|
|
pchFprop = (CHAR *) &rgakd[cakd];
|
|
pcp = &mpstccp[0];
|
|
pbchFprop = &mpstcbchFprop[0];
|
|
*pbchFprop = bNil;
|
|
#ifdef DEBUG
|
|
cakdTotal = cakd;
|
|
#endif
|
|
for (stc = 0, usg = 0, stcBase = 0, stcMin = 0, iakd = 0;
|
|
stc < stcMax;
|
|
stc++, pcp++, pbchFprop++)
|
|
{
|
|
if (stc >= mpusgstcBase[usg + 1])
|
|
{ /* Crossed a usage or class boundary */
|
|
*pbchFprop = bNil;
|
|
stcBase = mpusgstcBase[++usg];
|
|
if (stcBase == stcParaMin || stcBase == stcSectMin)
|
|
{ /* Update the base; make std if none defined */
|
|
stcMin = stcBase;
|
|
}
|
|
}
|
|
if ((cp = *pcp) == cpNil)
|
|
{ /* No style defined; take first for usg or, failing
|
|
that, first style of this class. */
|
|
if ((*pbchFprop = mpstcbchFprop[stcBase]) == bNil)
|
|
*pbchFprop = mpstcbchFprop[stcMin];
|
|
}
|
|
else
|
|
{ /* New style; copy the looks and bump the pointers */
|
|
/* Char stc's have just FCHP; para has FPAP followed by
|
|
FCHP; sect has FSEP. */
|
|
*pbchFprop = pchFprop - grpchFprop;
|
|
if (stc >= stcParaMin)
|
|
{ /* Para or sect */
|
|
CachePara(doc, cp);
|
|
if (stc >= stcSectMin)
|
|
cchT = CchDiffer(&vpapCache, &vsepNormal, cchSEP);
|
|
else
|
|
cchT = CchDiffer(&vpapCache, &vpapStd, cchPAP);
|
|
if ((*pchFprop++ = cchT) != 0)
|
|
bltbyte(&vpapCache, pchFprop, cchT);
|
|
pchFprop += cchT;
|
|
}
|
|
if (stc < stcSectMin)
|
|
{ /* Char or para */
|
|
FetchCp(doc, cp, 0, fcmProps);
|
|
cchT = CchDiffer(&vchpFetch, &vchpNormal, cchCHP);
|
|
if ((*pchFprop++ = cchT) != 0)
|
|
bltbyte(&vchpFetch, pchFprop, cchT);
|
|
pchFprop += cchT;
|
|
}
|
|
/* Insert element in akd table */
|
|
FetchRgch(&cchT, rgch, doc, cp, cpMac, 3);
|
|
if ((ch = rgch[1]) == ' ')
|
|
continue;
|
|
if (rgch[2] == ' ')
|
|
{ /* Single-key akc */
|
|
pakd = &rgakd[iakd++];
|
|
pakd->ch = ch;
|
|
pakd->fMore = false;
|
|
pakd->ustciakd = stc;
|
|
}
|
|
else
|
|
{ /* Two-char akc */
|
|
for (iakdT = 0; iakdT < iakd; iakdT++)
|
|
if (rgakd[iakdT].ch == ch)
|
|
{
|
|
pakd = &rgakd[rgakd[iakdT].ustciakd +
|
|
--mpchcakc[ch]];
|
|
pakd->ch = rgch[2];
|
|
pakd->fMore = true;
|
|
pakd->ustciakd = stc;
|
|
do
|
|
if ((++pakd)->ch == rgch[2])
|
|
{
|
|
Error(IDPMTAkcRepeat);
|
|
FreeH(hsytb);
|
|
goto ErrRet;
|
|
}
|
|
while (pakd->fMore);
|
|
goto NextStc;
|
|
}
|
|
pakd = &rgakd[iakd++];
|
|
pakd->ch = ch;
|
|
pakd->fMore = true;
|
|
pakd->ustciakd = (cakd -= mpchcakc[ch]);
|
|
pakd = &rgakd[cakd + --mpchcakc[ch]];
|
|
pakd->ch = rgch[2];
|
|
pakd->fMore = false;
|
|
pakd->ustciakd = stc;
|
|
}
|
|
}
|
|
NextStc: ;
|
|
}
|
|
|
|
pakd = &rgakd[iakd++];
|
|
pakd->ch = ' ';
|
|
pakd->fMore = false;
|
|
pakd->ustciakd = stcNormal;
|
|
|
|
#ifdef DEBUG
|
|
Assert(grpchFprop + cchAKD * cakdTotal + cch == pchFprop && iakd == cakd);
|
|
#endif
|
|
return hsytb;
|
|
|
|
ErrRet:
|
|
Select(cp, cp + ccpSshtEntry);
|
|
vfSeeSel = true;
|
|
return 0;
|
|
}
|
|
#endif /* STYLES */
|
|
|