windows-nt/Source/XPSP1/NT/base/mvdm/wow16/write/doc.c
2020-09-26 16:20:57 +08:00

410 lines
13 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/************************************************************/
/* 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 */