433 lines
13 KiB
C
433 lines
13 KiB
C
|
/************************************************************/
|
|||
|
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
|
|||
|
/************************************************************/
|
|||
|
|
|||
|
/* AddPrm.c -- Routines to add prms and sprms to docs */
|
|||
|
#define NOGDICAPMASKS
|
|||
|
#define NOVIRTUALKEYCODES
|
|||
|
#define NOWINMESSAGES
|
|||
|
#define NOWINSTYLES
|
|||
|
#define NOSYSMETRICS
|
|||
|
#define NOMENUS
|
|||
|
#define NOKEYSTATE
|
|||
|
#define NOSYSCOMMANDS
|
|||
|
#define NORASTEROPS
|
|||
|
#define NOSHOWWINDOW
|
|||
|
#define NOSYSMETRICS
|
|||
|
#define NOATOM
|
|||
|
#define NOBITMAP
|
|||
|
#define NOBRUSH
|
|||
|
#define NOPEN
|
|||
|
#define NOCLIPBOARD
|
|||
|
#define NOCOLOR
|
|||
|
#define NOCTLMGR
|
|||
|
#define NOWNDCLASS
|
|||
|
#define NODRAWTEXT
|
|||
|
#define NOFONT
|
|||
|
#define NOGDI
|
|||
|
#define NOHDC
|
|||
|
#define NOMB
|
|||
|
#define NOMENUS
|
|||
|
#define NOMETAFILE
|
|||
|
#define NOMSG
|
|||
|
#define NOTEXTMETRIC
|
|||
|
#define NOSOUND
|
|||
|
#define NOSCROLL
|
|||
|
#define NOCOMM
|
|||
|
/* no everything except MEMMGR */
|
|||
|
#include <windows.h>
|
|||
|
|
|||
|
#include "mw.h"
|
|||
|
#include "cmddefs.h"
|
|||
|
#include "code.h"
|
|||
|
#include "ch.h"
|
|||
|
#include "docdefs.h"
|
|||
|
#include "editdefs.h"
|
|||
|
#include "str.h"
|
|||
|
#include "prmdefs.h"
|
|||
|
#include "propdefs.h"
|
|||
|
#include "filedefs.h"
|
|||
|
#include "stcdefs.h"
|
|||
|
#include "fkpdefs.h"
|
|||
|
#include "macro.h"
|
|||
|
#include "dispdefs.h"
|
|||
|
|
|||
|
/* E X T E R N A L S */
|
|||
|
|
|||
|
extern int docCur;
|
|||
|
extern struct SEL selCur;
|
|||
|
extern struct DOD (**hpdocdod)[];
|
|||
|
extern struct UAB vuab;
|
|||
|
extern int vfSysFull;
|
|||
|
extern CHAR dnsprm[];
|
|||
|
extern struct CHP vchpSel;
|
|||
|
extern typeCP vcpLimParaCache;
|
|||
|
extern typeCP cpMacCur;
|
|||
|
extern typeCP CpLimNoSpaces();
|
|||
|
extern int ferror;
|
|||
|
|
|||
|
/* G L O B A L S */
|
|||
|
|
|||
|
struct FPRM fprmCache = { 0 };
|
|||
|
struct PRM prmCache = {0,0,0,0};
|
|||
|
|
|||
|
|
|||
|
/* A D D O N E S P R M */
|
|||
|
/* applies sprm at psprm to the current selection. Take care of
|
|||
|
undoing, invalidation, special endmark cases, and extension of selection
|
|||
|
to paragraph boundaries */
|
|||
|
void AddOneSprm(psprm, fSetUndo)
|
|||
|
CHAR *psprm;
|
|||
|
int fSetUndo; /* True if we need to set up the undo buffer */
|
|||
|
{
|
|||
|
int cch;
|
|||
|
int fParaSprm = fFalse;
|
|||
|
typeCP cpFirst, cpLim, dcp;
|
|||
|
|
|||
|
if (!FWriteOk( fwcNil ))
|
|||
|
return;
|
|||
|
|
|||
|
if ((dnsprm[*psprm] & ESPRM_sgc) != sgcChar)
|
|||
|
{
|
|||
|
typeCP dcpExtraPara = cp0;
|
|||
|
|
|||
|
cpFirst = CpFirstSty( selCur.cpFirst, styPara );
|
|||
|
CachePara( docCur, CpMax( selCur.cpLim - 1, selCur.cpFirst ) );
|
|||
|
cpLim = vcpLimParaCache;
|
|||
|
|
|||
|
dcp = cpLim - cpFirst;
|
|||
|
|
|||
|
/* Check for para following selection that has no Eol */
|
|||
|
|
|||
|
if (cpLim < cpMacCur)
|
|||
|
{
|
|||
|
/* Note that in this case only, dcp (the # of cp's affected
|
|||
|
by the change) does not equal (cpLim - cpFirst)
|
|||
|
(the # of cp's to which the sprm should apply) */
|
|||
|
CachePara( docCur, cpLim );
|
|||
|
dcpExtraPara = vcpLimParaCache - cpLim;
|
|||
|
}
|
|||
|
|
|||
|
if (cpFirst + dcp + dcpExtraPara > cpMacCur)
|
|||
|
{ /* Last para affected has no Eol -- add one */
|
|||
|
struct SEL selSave;
|
|||
|
|
|||
|
dcp += dcpExtraPara;
|
|||
|
Assert( cpFirst + dcp == cpMacCur + (typeCP) ccpEol);
|
|||
|
|
|||
|
if (fSetUndo)
|
|||
|
{
|
|||
|
SetUndo( uacReplNS, docCur, cpFirst, dcp,
|
|||
|
docNil, cpNil, dcp - ccpEol, 0 );
|
|||
|
fSetUndo = fFalse;
|
|||
|
}
|
|||
|
/* Add an eol. Save the current selection so
|
|||
|
it does not get adjusted */
|
|||
|
selSave = selCur;
|
|||
|
InsertEolInsert(docCur,cpMacCur);
|
|||
|
selCur = selSave;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{ /* Char sprm -- eliminate trailing spaces from the
|
|||
|
affected region, so we don't underline spaces after words. */
|
|||
|
cpFirst = selCur.cpFirst;
|
|||
|
cpLim = CpLimNoSpaces(selCur.cpFirst, selCur.cpLim);
|
|||
|
dcp = cpLim - cpFirst;
|
|||
|
if (dcp == 0)
|
|||
|
{ /* Doing character looks to the insert point... */
|
|||
|
if (fSetUndo)
|
|||
|
SetUndo(uacReplNS, docCur, cpFirst, cp0,
|
|||
|
docNil, cp0, cp0, 0);
|
|||
|
DoSprm(&vchpSel, 0, *psprm, psprm + 1);
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (fSetUndo)
|
|||
|
SetUndo(uacReplNS, docCur, cpFirst, dcp, docNil, cpNil, dcp, 0);
|
|||
|
|
|||
|
if (ferror) /* not enough memory to store info for undo operation */
|
|||
|
{
|
|||
|
NoUndo();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
AddSprmCps(psprm, docCur, cpFirst, cpLim);
|
|||
|
AdjustCp( docCur, cpFirst, dcp, dcp );
|
|||
|
}
|
|||
|
|
|||
|
/* E X P A N D C U R S E L */
|
|||
|
ExpandCurSel(pselSave)
|
|||
|
struct SEL *pselSave;
|
|||
|
{
|
|||
|
*pselSave = selCur;
|
|||
|
|
|||
|
selCur.cpFirst = CpFirstSty(selCur.cpFirst, styPara);
|
|||
|
CachePara(docCur, CpMax(selCur.cpLim - 1, selCur.cpFirst));
|
|||
|
selCur.cpLim = vcpLimParaCache;
|
|||
|
}
|
|||
|
|
|||
|
/* E N D L O O K S E L */
|
|||
|
EndLookSel(pselSave, fPara)
|
|||
|
struct SEL *pselSave; BOOL fPara;
|
|||
|
{
|
|||
|
typeCP cpLim, cpFirst, dcp;
|
|||
|
dcp = (cpLim = selCur.cpLim) - (cpFirst = selCur.cpFirst);
|
|||
|
if (fPara)
|
|||
|
{
|
|||
|
TrashCache();
|
|||
|
if (cpLim <= cpMacCur)
|
|||
|
{
|
|||
|
CachePara(docCur, selCur.cpLim);
|
|||
|
if (vcpLimParaCache > cpMacCur) /* Last (partial) paragraph */
|
|||
|
dcp = cpMacCur - cpFirst + 1;
|
|||
|
}
|
|||
|
}
|
|||
|
AdjustCp(docCur, cpFirst, dcp, dcp);
|
|||
|
|
|||
|
selCur = *pselSave;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/* A D D S P R M */
|
|||
|
|
|||
|
AddSprm(psprm)
|
|||
|
CHAR *psprm;
|
|||
|
{ /* Add a single property modifier to the pieces contained in selCur. */
|
|||
|
AddSprmCps(psprm, docCur, selCur.cpFirst, selCur.cpLim);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/* A D D S P R M C P S */
|
|||
|
AddSprmCps(char *psprm, int doc, typeCP cpFirst, typeCP cpLim)
|
|||
|
{
|
|||
|
struct PCTB **hpctb;
|
|||
|
int ipcdFirst, ipcdLim, ipcd;
|
|||
|
struct DOD *pdod;
|
|||
|
int cch;
|
|||
|
struct PCD *ppcd;
|
|||
|
|
|||
|
/* First get address of piece table and split off desired pieces. */
|
|||
|
pdod = &(**hpdocdod)[doc];
|
|||
|
hpctb = pdod->hpctb;
|
|||
|
pdod->fFormatted = fTrue;
|
|||
|
ipcdFirst = IpcdSplit(hpctb, cpFirst);
|
|||
|
ipcdLim = IpcdSplit(hpctb, cpLim);
|
|||
|
if (ferror)
|
|||
|
/* Ran out of memory trying to expand piece table */
|
|||
|
return;
|
|||
|
|
|||
|
/* Now just add this sprm to the pieces. */
|
|||
|
FreezeHp();
|
|||
|
for (ipcd = ipcdFirst, ppcd = &(**hpctb).rgpcd[ipcdFirst];
|
|||
|
ipcd < ipcdLim && !vfSysFull; ++ipcd, ++ppcd)
|
|||
|
ppcd->prm = PrmAppend(ppcd->prm, psprm);
|
|||
|
MeltHp();
|
|||
|
}
|
|||
|
|
|||
|
/* P R M A P P E N D */
|
|||
|
|
|||
|
struct PRM PrmAppend(struct PRM prm, CHAR *psprm)
|
|||
|
{ /* Append <sprm, val> to the chain of sprm's in prm. Return new prm. */
|
|||
|
struct FPRM *pfprmOld;
|
|||
|
CHAR *pfsprm;
|
|||
|
CHAR *pfsprmOld;
|
|||
|
int sprm = *psprm;
|
|||
|
int sprmOld;
|
|||
|
register int esprm = dnsprm[sprm];
|
|||
|
register int esprmOld;
|
|||
|
int cchNew = (esprm & ESPRM_cch);
|
|||
|
int cchOld;
|
|||
|
int sgc = (esprm & ESPRM_sgc);
|
|||
|
int spr = (esprm & ESPRM_spr);
|
|||
|
int fSame = (esprm & ESPRM_fSame);
|
|||
|
int fClobber = (esprm & ESPRM_fClobber);
|
|||
|
int dval = 0;
|
|||
|
int cch;
|
|||
|
int cchT;
|
|||
|
typeFC fcPrm;
|
|||
|
|
|||
|
struct FPRM fprm;
|
|||
|
|
|||
|
if (cchNew == 0) cchNew = CchPsprm(psprm);
|
|||
|
|
|||
|
pfsprm = fprm.grpfsprm;
|
|||
|
|
|||
|
if (prm.fComplex)
|
|||
|
{ /* Get the old list of sprm's from scratch file; copy it to fprm. */
|
|||
|
pfprmOld = (struct FPRM *) PchFromFc(fnScratch,
|
|||
|
//(typeFC)(unsigned)(((struct PRMX *) &prm)->bfprm << 1), &cch);
|
|||
|
fcSCRATCHPRM(prm), &cch);
|
|||
|
pfsprmOld = pfprmOld->grpfsprm;
|
|||
|
cchT = cch = pfprmOld->cch;
|
|||
|
while (cchT)
|
|||
|
{ /* Copy grpsprm, removing ones which we will clobber */
|
|||
|
sprmOld = *pfsprmOld;
|
|||
|
esprmOld = dnsprm[sprmOld];
|
|||
|
if ((cchOld = (esprmOld & ESPRM_cch)) == 0)
|
|||
|
cchOld = CchPsprm(pfsprmOld);
|
|||
|
#ifdef DEBUG
|
|||
|
if (cchOld == 0)
|
|||
|
panic();
|
|||
|
#endif
|
|||
|
if (sprmOld == sprm && fSame ||
|
|||
|
(esprmOld & ESPRM_sgc) == sgc &&
|
|||
|
(esprmOld & ESPRM_spr) <= spr && fClobber)
|
|||
|
{
|
|||
|
/* make sure we properly coalesce change
|
|||
|
size prms */
|
|||
|
if (sprm == sprmOld && sprm == sprmCChgHps)
|
|||
|
dval += *(pfsprmOld + 1);
|
|||
|
cch -= cchOld;
|
|||
|
}
|
|||
|
/* CHps overrides CChgHps */
|
|||
|
else if (sprmOld == sprmCChgHps && sprm == sprmCHps)
|
|||
|
{
|
|||
|
cch -= cchOld;
|
|||
|
}
|
|||
|
else
|
|||
|
pfsprm = (CHAR *)bltbyte(pfsprmOld, pfsprm, cchOld);
|
|||
|
pfsprmOld += cchOld;
|
|||
|
cchT -= cchOld;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{ /* No file entry yet; convert simple prm to fsprm */
|
|||
|
int valOld = prm.val;
|
|||
|
sprmOld = prm.sprm;
|
|||
|
esprmOld = dnsprm[sprmOld];
|
|||
|
|
|||
|
if (bPRMNIL(prm) ||
|
|||
|
sprmOld == sprm && fSame ||
|
|||
|
(esprmOld & ESPRM_sgc) == sgc &&
|
|||
|
(esprmOld & ESPRM_spr) <= spr && fClobber)
|
|||
|
{
|
|||
|
/* make sure we are combinning consecutive sprmCChgHps */
|
|||
|
if (sprm == sprmOld && sprm == sprmCChgHps)
|
|||
|
dval += valOld;
|
|||
|
cch = 0;
|
|||
|
}
|
|||
|
/* CHps overrides CChgHps */
|
|||
|
else if (sprmOld == sprmCChgHps && sprm == sprmCHps)
|
|||
|
{
|
|||
|
cch = 0;
|
|||
|
}
|
|||
|
else
|
|||
|
{ /* Save old sprm */
|
|||
|
*pfsprm++ = sprmOld;
|
|||
|
if ((cch = (esprmOld & ESPRM_cch)) == 2)
|
|||
|
*pfsprm++ = valOld;
|
|||
|
}
|
|||
|
}
|
|||
|
/* we have: cch = length of old prm after removal of clobbered/etc. entries.
|
|||
|
cchNew: length of the entry to be appended.
|
|||
|
dval: correction for 2nd byte of new entry
|
|||
|
pfsprm: where 1st byte of new entry will go
|
|||
|
*/
|
|||
|
bltbyte((CHAR *) psprm, pfsprm, imin(cchNew, cchMaxGrpfsprm - cch));
|
|||
|
*(pfsprm + 1) += dval;
|
|||
|
|
|||
|
if (cch == 0 && cchNew <= 2)
|
|||
|
{ /* Pack sprm and val into a prm word. */
|
|||
|
struct PRM prmT;
|
|||
|
prmT.dummy=0;
|
|||
|
bltbyte(pfsprm, (CHAR *) &prmT, cchNew);
|
|||
|
prmT.fComplex = false;
|
|||
|
prmT.sprm = *pfsprm;
|
|||
|
return (prmT);
|
|||
|
}
|
|||
|
|
|||
|
if ((cch += cchNew) > cchMaxGrpfsprm)
|
|||
|
{
|
|||
|
int fSave = ferror;
|
|||
|
Error(IDPMT2Complex);
|
|||
|
ferror = fSave;
|
|||
|
return (prm);
|
|||
|
}
|
|||
|
if (vfSysFull)
|
|||
|
return prm; /* Assume disk full message already given */
|
|||
|
|
|||
|
fprm.cch = cch;
|
|||
|
|
|||
|
/* Check newly created prm to see if same as previous */
|
|||
|
if (CchDiffer(&fprmCache, &fprm, cch + 1) == 0)
|
|||
|
return prmCache;
|
|||
|
bltbyte(&fprm, &fprmCache, cch + 1);
|
|||
|
|
|||
|
AlignFn(fnScratch, cch = ((cch >> 1) + 1) << 1, fTrue);
|
|||
|
prm.fComplex = fTrue;
|
|||
|
|
|||
|
//((struct PRMX)prm).bfprm = FcWScratch((CHAR *) &fprm, cch) >> 1;
|
|||
|
|
|||
|
fcPrm = FcWScratch((CHAR *) &fprm, cch) >> 1;
|
|||
|
((struct PRMX *)&prm)->bfprm_hi = (fcPrm >> 16) & 0x7F;
|
|||
|
((struct PRMX *)&prm)->bfprm_low = fcPrm & 0xFFFF;
|
|||
|
|
|||
|
prmCache = prm;
|
|||
|
return prm;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/* A P P L Y C L O O K S */
|
|||
|
/* character looks. val is a 1 char value */
|
|||
|
ApplyCLooks(pchp, sprm, val)
|
|||
|
struct CHP *pchp;
|
|||
|
int sprm, val;
|
|||
|
{
|
|||
|
/* Assemble sprm */
|
|||
|
CHAR rgbSprm[1 + cchINT];
|
|||
|
CHAR *pch = &rgbSprm[0];
|
|||
|
*pch++ = sprm;
|
|||
|
*pch = val;
|
|||
|
|
|||
|
if (pchp == 0)
|
|||
|
{
|
|||
|
/* apply looks to current selection */
|
|||
|
AddOneSprm(rgbSprm, fTrue);
|
|||
|
vuab.uac = uacChLook;
|
|||
|
SetUndoMenuStr(IDSTRUndoLook);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/* apply looks to pchp */
|
|||
|
DoSprm(pchp, 0, sprm, pch);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/* A P P L Y L O O K S P A R A S */
|
|||
|
/* val is a char value */
|
|||
|
ApplyLooksParaS(pchp, sprm, val)
|
|||
|
struct CHP *pchp;
|
|||
|
int sprm, val;
|
|||
|
{
|
|||
|
int valT = 0;
|
|||
|
CHAR *pch = (CHAR *)&valT;
|
|||
|
*pch = val;
|
|||
|
/* all the above is just to prepare bltbyte later gets the right byte order */
|
|||
|
ApplyLooksPara(pchp, sprm, valT);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/* A P P L Y L O O K S P A R A */
|
|||
|
/* val is an integer value. Char val's must have been bltbyte'd into val */
|
|||
|
ApplyLooksPara(pchp, sprm, val)
|
|||
|
struct CHP *pchp;
|
|||
|
int sprm, val;
|
|||
|
{
|
|||
|
|
|||
|
if (FWriteOk(fwcNil)) /* Check for out-of-memory/ read-only */
|
|||
|
{
|
|||
|
CHAR rgbSprm[1 + cchINT];
|
|||
|
CHAR *pch = &rgbSprm[0];
|
|||
|
|
|||
|
*pch++ = sprm;
|
|||
|
bltbyte(&val, pch, cchINT);
|
|||
|
AddOneSprm(rgbSprm, fTrue);
|
|||
|
vuab.uac = uacChLook;
|
|||
|
SetUndoMenuStr(IDSTRUndoLook);
|
|||
|
}
|
|||
|
}
|
|||
|
|