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);
|
||
}
|
||
}
|
||
|