/************************************************************/ /* 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 #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 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); } }