336 lines
9.4 KiB
C
336 lines
9.4 KiB
C
|
/************************************************************/
|
|||
|
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
|
|||
|
/************************************************************/
|
|||
|
|
|||
|
#define NOCLIPBOARD
|
|||
|
#define NOGDICAPMASKS
|
|||
|
#define NOCTLMGR
|
|||
|
#define NOWINSTYLES
|
|||
|
#define NOWINMESSAGES
|
|||
|
#define NOVIRTUALKEYCODES
|
|||
|
#define NOSYSMETRICS
|
|||
|
#define NOMENUS
|
|||
|
#define NOGDI
|
|||
|
#define NOKEYSTATE
|
|||
|
#define NOHDC
|
|||
|
#define NOGDI
|
|||
|
#define NORASTEROPS
|
|||
|
#define NOSYSCOMMANDS
|
|||
|
#define NOSHOWWINDOW
|
|||
|
#define NOCOLOR
|
|||
|
#define NOATOM
|
|||
|
#define NOBITMAP
|
|||
|
#define NOICON
|
|||
|
#define NOBRUSH
|
|||
|
#define NOCREATESTRUCT
|
|||
|
#define NOMB
|
|||
|
#define NOFONT
|
|||
|
#define NOMSG
|
|||
|
#define NOOPENFILE
|
|||
|
#define NOPEN
|
|||
|
#define NOPOINT
|
|||
|
#define NORECT
|
|||
|
#define NOREGION
|
|||
|
#define NOSCROLL
|
|||
|
#define NOSOUND
|
|||
|
#define NOWH
|
|||
|
#define NOWINOFFSETS
|
|||
|
#define NOWNDCLASS
|
|||
|
#define NOCOMM
|
|||
|
#include <windows.h>
|
|||
|
#include "mw.h"
|
|||
|
#include "cmddefs.h"
|
|||
|
#define NOKCCODES
|
|||
|
#include "ch.h"
|
|||
|
#include "docdefs.h"
|
|||
|
#include "prmdefs.h"
|
|||
|
#include "propdefs.h"
|
|||
|
#include "filedefs.h"
|
|||
|
#include "stcdefs.h"
|
|||
|
#include "fkpdefs.h"
|
|||
|
#include "editdefs.h"
|
|||
|
#include "wwdefs.h"
|
|||
|
#include "dispdefs.h"
|
|||
|
|
|||
|
/* E X T E R N A L S */
|
|||
|
extern struct WWD rgwwd[];
|
|||
|
extern int docCur;
|
|||
|
extern struct CHP vchpFetch;
|
|||
|
extern struct CHP vchpInsert;
|
|||
|
extern struct CHP vchpSel;
|
|||
|
extern struct CHP vchpNormal;
|
|||
|
extern struct FKPD vfkpdParaIns;
|
|||
|
extern typeFC fcMacPapIns;
|
|||
|
extern struct PAP *vppapNormal;
|
|||
|
extern struct PAP vpapPrevIns;
|
|||
|
extern struct FCB (**hpfnfcb)[];
|
|||
|
extern struct BPS *mpibpbps;
|
|||
|
extern CHAR (*rgbp)[cbSector];
|
|||
|
|
|||
|
extern typePN PnAlloc();
|
|||
|
|
|||
|
|
|||
|
InsertRgch(doc, cp, rgch, cch, pchp, ppap)
|
|||
|
int doc, cch;
|
|||
|
typeCP cp;
|
|||
|
CHAR rgch[];
|
|||
|
struct CHP *pchp;
|
|||
|
struct PAP *ppap;
|
|||
|
{ /* Insert cch characters from rgch into doc before cp */
|
|||
|
typeFC fc;
|
|||
|
struct CHP chp;
|
|||
|
|
|||
|
/* First finish off the previous CHAR run if necessary */
|
|||
|
if (pchp == 0)
|
|||
|
{ /* Make looks be those of PREVIOUS character */
|
|||
|
CachePara(doc,cp);
|
|||
|
FetchCp(doc, CpMax(cp0, cp - 1), 0, fcmProps);
|
|||
|
blt(&vchpFetch, &chp, cwCHP);
|
|||
|
chp.fSpecial = false;
|
|||
|
pchp = &chp;
|
|||
|
}
|
|||
|
NewChpIns(pchp);
|
|||
|
|
|||
|
/* Now write the characters to the scratch file */
|
|||
|
fc = FcWScratch(rgch, cch);
|
|||
|
|
|||
|
/* Now insert a paragraph run if we inserted an EOL */
|
|||
|
if (ppap != 0)
|
|||
|
{ /* Inserting EOL--must be last character of rgch */
|
|||
|
AddRunScratch(&vfkpdParaIns, ppap, vppapNormal,
|
|||
|
FParaEq(ppap, &vpapPrevIns) &&
|
|||
|
vfkpdParaIns.brun != 0 ? -cchPAP : cchPAP,
|
|||
|
fcMacPapIns = (**hpfnfcb)[fnScratch].fcMac);
|
|||
|
blt(ppap, &vpapPrevIns, cwPAP);
|
|||
|
}
|
|||
|
|
|||
|
/* Finally, insert the piece into the document */
|
|||
|
Replace(doc, cp, cp0, fnScratch, fc, (typeFC) cch);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
InsertEolInsert(doc,cp)
|
|||
|
int doc;
|
|||
|
typeCP cp;
|
|||
|
{
|
|||
|
struct PAP papT;
|
|||
|
struct CHP chpT;
|
|||
|
CHAR rgch[2];
|
|||
|
|
|||
|
/* (MEMO) Here's the problem: When we insert or paste into a running head or
|
|||
|
foot, we expect all paras to have a non-0 rhc. This gets called from
|
|||
|
Replace to put in an Eol when we are inserting or pasting in front of
|
|||
|
a picture. It needs, therefore, to have running head properties when
|
|||
|
appropriate. In a future world, cpMinDocument, cpMinHeader, cpMacHeader,
|
|||
|
cpMinFooter, and cpMacFooter will be document attributes instead of
|
|||
|
globals, and will be duly adjusted by AdjustCp. Then, we can trash the
|
|||
|
somewhat kludgy check for doc==docCur and editing header/footer,
|
|||
|
and instead check for cp within header/footer bounds for doc. */
|
|||
|
|
|||
|
papT = *vppapNormal;
|
|||
|
if (doc==docCur)
|
|||
|
if (wwdCurrentDoc.fEditHeader)
|
|||
|
papT.rhc = RHC_fOdd + RHC_fEven;
|
|||
|
else if (wwdCurrentDoc.fEditFooter)
|
|||
|
papT.rhc = RHC_fBottom + RHC_fOdd + RHC_fEven;
|
|||
|
|
|||
|
#ifdef CRLF
|
|||
|
rgch[0] = chReturn;
|
|||
|
rgch[1] = chEol;
|
|||
|
chpT = vchpSel;
|
|||
|
chpT.fSpecial = fFalse;
|
|||
|
InsertRgch(doc, cp, rgch, 2, &chpT, &papT);
|
|||
|
#else
|
|||
|
rgch[0] = chEol;
|
|||
|
chpT = vchpSel;
|
|||
|
chpT.fSpecial = fFalse;
|
|||
|
InsertRgch(doc, cp, rgch, 1, &chpT, &papT);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
InsertEolPap(doc, cp, ppap)
|
|||
|
int doc;
|
|||
|
typeCP cp;
|
|||
|
struct PAP *ppap;
|
|||
|
{
|
|||
|
extern struct CHP vchpAbs;
|
|||
|
struct CHP chpT;
|
|||
|
#ifdef CRLF
|
|||
|
CHAR rgch [2];
|
|||
|
#else
|
|||
|
CHAR rgch [1];
|
|||
|
#endif
|
|||
|
|
|||
|
/* We must get props here instead of using vchpNormal because of the
|
|||
|
"10-point kludge". We don't want to change the default font
|
|||
|
just because we have to insert a new pap */
|
|||
|
|
|||
|
FetchCp( doc, cp, 0, fcmProps );
|
|||
|
chpT = vchpAbs;
|
|||
|
chpT.fSpecial = fFalse;
|
|||
|
|
|||
|
#ifdef CRLF
|
|||
|
rgch [0] = chReturn;
|
|||
|
rgch [1] = chEol;
|
|||
|
InsertRgch(doc, cp, rgch, 2, &chpT, ppap);
|
|||
|
#else
|
|||
|
InsertRgch(doc, cp, rgch, 1, &chpT, ppap);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
AddRunScratch(pfkpd, pchProp, pchStd, cchProp, fcLim)
|
|||
|
struct FKPD *pfkpd;
|
|||
|
CHAR *pchProp, *pchStd;
|
|||
|
int cchProp;
|
|||
|
typeFC fcLim;
|
|||
|
{ /* Add a CHAR or para run to the scratch file FKP (see FAddRun) */
|
|||
|
struct FKP *pfkp;
|
|||
|
CHAR *pchFprop;
|
|||
|
struct RUN *prun;
|
|||
|
int ibp;
|
|||
|
|
|||
|
pfkp = (struct FKP *) rgbp[ibp = IbpEnsureValid(fnScratch, pfkpd->pn)];
|
|||
|
pchFprop = &pfkp->rgb[pfkpd->bchFprop];
|
|||
|
prun = (struct RUN *) &pfkp->rgb[pfkpd->brun];
|
|||
|
|
|||
|
|
|||
|
while (!FAddRun(fnScratch, pfkp, &pchFprop, &prun, pchProp, pchStd, cchProp,
|
|||
|
fcLim))
|
|||
|
{ /* Go to a new page; didn't fit. */
|
|||
|
int ibte = pfkpd->ibteMac;
|
|||
|
struct BTE (**hgbte)[] = pfkpd->hgbte;
|
|||
|
|
|||
|
/* Create new entry in bin table for filled page */
|
|||
|
if (!FChngSizeH(hgbte, ((pfkpd->ibteMac = ibte + 1) * sizeof (struct BTE)) / sizeof (int),
|
|||
|
false))
|
|||
|
return;
|
|||
|
(**hgbte)[ibte].fcLim = (prun - 1)->fcLim;
|
|||
|
(**hgbte)[ibte].pn = pfkpd->pn;
|
|||
|
|
|||
|
/* Allocate new page */
|
|||
|
pfkpd->pn = PnAlloc(fnScratch);
|
|||
|
pfkpd->brun = 0;
|
|||
|
pfkpd->bchFprop = cbFkp;
|
|||
|
|
|||
|
if (cchProp < 0) /* New page, so force output of fprop */
|
|||
|
cchProp = -cchProp;
|
|||
|
|
|||
|
/* Reset pointers and fill in fcFirst */
|
|||
|
pfkp = (struct FKP *) rgbp[ibp = IbpEnsureValid(fnScratch, pfkpd->pn)];
|
|||
|
pfkp->fcFirst = (prun - 1)->fcLim;
|
|||
|
pchFprop = &pfkp->rgb[pfkpd->bchFprop];
|
|||
|
prun = (struct RUN *) &pfkp->rgb[pfkpd->brun];
|
|||
|
}
|
|||
|
|
|||
|
mpibpbps[ibp].fDirty = true;
|
|||
|
pfkpd->brun = (CHAR *) prun - &pfkp->rgb[0];
|
|||
|
pfkpd->bchFprop = pchFprop - &pfkp->rgb[0];
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
int FAddRun(fn, pfkp, ppchFprop, pprun, pchProp, pchStd, cchProp, fcLim)
|
|||
|
int fn, cchProp;
|
|||
|
struct FKP *pfkp;
|
|||
|
CHAR **ppchFprop, *pchProp, *pchStd;
|
|||
|
struct RUN **pprun;
|
|||
|
typeFC fcLim;
|
|||
|
{ /* Add a run and FCHP/FPAP to the current FKP. */
|
|||
|
/* Make a new page if it won't fit. */
|
|||
|
/* If cchProp < 0, don't make new fprop if page not full */
|
|||
|
int cch;
|
|||
|
|
|||
|
/* If there's not even enough room for a run, force new fprop */
|
|||
|
if (cchProp < 0 && (CHAR *) (*pprun + 1) > *ppchFprop)
|
|||
|
cchProp = -cchProp;
|
|||
|
|
|||
|
if (cchProp > 0)
|
|||
|
{ /* Make a new fprop */
|
|||
|
/* Compute length of FPAP/FCHP */
|
|||
|
if (cchProp == cchPAP)
|
|||
|
{
|
|||
|
/* compute difference from vppapNormal */
|
|||
|
if (((struct PAP *)pchProp)->rgtbd[0].dxa != 0)
|
|||
|
{
|
|||
|
int itbd;
|
|||
|
/* find end of tab table */
|
|||
|
for (itbd = 1; itbd < itbdMax; itbd++)
|
|||
|
if (((struct PAP *)pchProp)->rgtbd[itbd].dxa == 0)
|
|||
|
{
|
|||
|
cch = cwPAPBase * cchINT + (itbd + 1) * cchTBD;
|
|||
|
goto HaveCch;
|
|||
|
}
|
|||
|
}
|
|||
|
cchProp = cwPAPBase * cchINT;
|
|||
|
}
|
|||
|
cch = CchDiffer(pchProp, pchStd, cchProp);
|
|||
|
HaveCch:
|
|||
|
if (cch > 0)
|
|||
|
++cch;
|
|||
|
|
|||
|
/* Determine whether info will fit on this page */
|
|||
|
if ((CHAR *) (*pprun + 1) > *ppchFprop - cch)
|
|||
|
{ /* Go to new page; this one is full */
|
|||
|
if (fn == fnScratch)
|
|||
|
return false; /* Let AddRunScratch handle this */
|
|||
|
WriteRgch(fn, pfkp, cbSector);
|
|||
|
pfkp->fcFirst = (*pprun - 1)->fcLim;
|
|||
|
*ppchFprop = &pfkp->rgb[cbFkp];
|
|||
|
*pprun = (struct RUN *) pfkp->rgb;
|
|||
|
}
|
|||
|
|
|||
|
/* If new FPAP is needed, make it */
|
|||
|
if (cch > 0)
|
|||
|
{
|
|||
|
(*pprun)->b = (*ppchFprop -= cch) - pfkp->rgb;
|
|||
|
**ppchFprop = --cch;
|
|||
|
bltbyte(pchProp, *ppchFprop + 1, cch);
|
|||
|
}
|
|||
|
else /* Use standard props */
|
|||
|
(*pprun)->b = bNil;
|
|||
|
}
|
|||
|
else /* Point to previous fprop */
|
|||
|
(*pprun)->b = (*pprun - 1)->b;
|
|||
|
|
|||
|
/* Replaced old sequence (see below) */
|
|||
|
(*pprun)->fcLim = fcLim;
|
|||
|
pfkp->crun = ++(*pprun) - (struct RUN *) pfkp->rgb;
|
|||
|
|
|||
|
/* Used to be like this, but CMERGE -Oa (assume no aliasing)
|
|||
|
option made it not work -- "*pprun" is an alias for the
|
|||
|
postincremented value of *pprun */
|
|||
|
/*(*pprun)++->fcLim = fcLim;
|
|||
|
pfkp->crun = *pprun - (struct RUN *) pfkp->rgb; */
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/* F P A R A E Q */
|
|||
|
/* compares two PAP structures. Problem: tab tables are not fixed length
|
|||
|
but are terminated by 0 dxa. */
|
|||
|
FParaEq(ppap1, ppap2)
|
|||
|
struct PAP *ppap1, *ppap2;
|
|||
|
{
|
|||
|
struct TBD *ptbd1 = ppap1->rgtbd, *ptbd2 = ppap2->rgtbd;
|
|||
|
while (ptbd1->dxa == ptbd2->dxa)
|
|||
|
{
|
|||
|
if (ptbd1->dxa == 0)
|
|||
|
return CchDiffer(ppap1, ppap2, cchPAP) == 0;
|
|||
|
if (*(long *)ptbd1 != *(long *)ptbd2) break;
|
|||
|
ptbd1++; ptbd2++;
|
|||
|
}
|
|||
|
return fFalse;
|
|||
|
}
|
|||
|
|