|
|
/* LSDNFIN.C */ #include "lsdnfin.h"
#include "lsidefs.h"
#include "lsc.h"
#include "getfmtst.h"
#include "setfmtst.h"
#include "dninfo.h"
#include "lschp.h"
#include "lsffi.h"
#include "iobj.h"
#include "dnutils.h"
#include "lsfrun.h"
#include "lsfetch.h"
#include "qheap.h"
#include "sublutil.h"
#include "lsmem.h"
#include "lscfmtfl.h"
#include "ntiman.h"
#ifdef DEBUG
#define DebugMemset(a,b,c) if ((a) != NULL) memset(a,b,c); else
#else
#define DebugMemset(a,b,c) (void)(0)
#endif
#define IsLschpFlagsValid(plsc, plschp) fTrue
/* Word violates condition bellow and it is not very important to us, so I deleted body of this macro,
but not deleted macro itself to have a place where to put such checks later */
// ((((plsc)->lsadjustcontext.lsbrj == lsbrjBreakWithCompJustify) || ((plsc)->lsadjustcontext.lskj == lskjSnapGrid)) ? \ // fTrue :\ // (!((plschp)->fCompressOnRun || (plschp)->fCompressSpace || (plschp)->fCompressTable)))
/* L S D N F I N I S H R E G U L A R */ /*----------------------------------------------------------------------------
%%Function: LsdnFinishRegular %%Contact: igorzv
Parameters: plsc - (IN) ptr to line services context lsdcp - (IN) dcp adopted plsrun - (IN) plsrun of dnode plschp - (IN) plschp of dnode pdobj - (IN) pdobj of dnode pobjdim - (IN) pobjdim of dnode
Finish creating dnode ----------------------------------------------------------------------------*/
LSERR WINAPI LsdnFinishRegular( PLSC plsc, LSDCP lsdcp, PLSRUN plsrun, PCLSCHP plschp, PDOBJ pdobj, PCOBJDIM pobjdim) { PLSDNODE plsdn; LSERR lserr; PLSSUBL plssubl; if (!FIsLSC(plsc)) return lserrInvalidParameter;
if (!FFormattingAllowed(plsc)) return lserrFormattingFunctionDisabled;
/* all sublines should be closed */ if (GetCurrentSubline(plsc) != NULL) return lserrFormattingFunctionDisabled;
plsdn = GetDnodeToFinish(plsc); if (plsdn == NULL) return lserrFiniFunctionDisabled;
plssubl = SublineFromDnode(plsdn);
plsdn->u.real.pdobj = pdobj; /* if handler changed plsrun that we passed to him than we should release previous one */ /* Attention: we have assumption here that new one has another plsrun */ if (plsdn->u.real.plsrun != plsrun && !plsc->fDontReleaseRuns) { lserr = plsc->lscbk.pfnReleaseRun(plsc->pols, plsdn->u.real.plsrun); plsdn->u.real.plsrun = plsrun; /* to release it later */ if (lserr != lserrNone) return lserr; }
plsdn->dcp = lsdcp; plsdn->cpLimOriginal = plsdn->cpFirst + lsdcp; Assert(FIsDnodeReal(plsdn)); /* this is default value */ Assert(pobjdim->dur >= 0); SetDnodeObjdimFmt(plsdn, *pobjdim);
Assert(IsLschpFlagsValid(plsc, plschp)); plsdn->u.real.lschp = *plschp; /* Special effects */ plsc->plslineCur->lslinfo.EffectsFlags |= plschp->EffectsFlags; /* set flags for display */ if (plschp->dvpPos != 0) TurnOnNonZeroDvpPosEncounted(plsc); AddToAggregatedDisplayFlags(plsc, plschp); if (FApplyNominalToIdeal(plschp)) TurnOnNominalToIdealEncounted(plsc);
if (plsdn->u.real.lschp.idObj == idObjTextChp) plsdn->u.real.lschp.idObj = (WORD) IobjTextFromLsc(&plsc->lsiobjcontext);
AssertImplies(plsc->lsdocinf.fPresEqualRef, plsdn->u.real.objdim.heightsPres.dvAscent == plsdn->u.real.objdim.heightsRef.dvAscent); AssertImplies(plsc->lsdocinf.fPresEqualRef, plsdn->u.real.objdim.heightsPres.dvDescent == plsdn->u.real.objdim.heightsRef.dvDescent); AssertImplies(plsc->lsdocinf.fPresEqualRef, plsdn->u.real.objdim.heightsPres.dvMultiLineHeight == plsdn->u.real.objdim.heightsRef.dvMultiLineHeight);
/* nobody can change current dnode after plsdn was constructed */ Assert(GetCurrentDnodeSubl(plssubl) == plsdn->plsdnPrev);
*(GetWhereToPutLinkSubl(plssubl, plsdn->plsdnPrev)) = plsdn; SetCurrentDnodeSubl(plssubl, plsdn); SetDnodeToFinish(plsc, NULL); AdvanceCurrentCpLimSubl(plssubl, lsdcp); AdvanceCurrentUrSubl(plssubl, pobjdim->dur); return lserrNone; }
/* L S D N F I N I S H R E G U L A R A D D A D V A N C E D P E N */ /*----------------------------------------------------------------------------
%%Function: LsdnFinishRegularAddAdvancePen %%Contact: igorzv
Parameters: plsc - (IN) ptr to line services context lsdcp - (IN) dcp adopted plsrun - (IN) plsrun of dnode plschp - (IN) plschp of dnode pdobj - (IN) pdobj of dnode pobjdim - (IN) pobjdim of dnode durPen - (IN) dur of advanced pen dvrPen - (IN) dvr of advanced pen dvpPen - (IN) dvp of advanced pen
Finish creating dnode and add advanced pen after such dnode ----------------------------------------------------------------------------*/
LSERR WINAPI LsdnFinishRegularAddAdvancePen( PLSC plsc, /* IN: Pointer to LS Context */ LSDCP lsdcp, /* IN: dcp adopted */ PLSRUN plsrun, /* IN: PLSRUN */ PCLSCHP plschp, /* IN: CHP */ PDOBJ pdobj, /* IN: PDOBJ */ PCOBJDIM pobjdim, /* IN: OBJDIM */ long durPen, /* IN: durPen */ long dvrPen, /* IN: dvrPen */ long dvpPen) /* IN: dvpPen */ { LSERR lserr; PLSDNODE plsdnPrev; PLSDNODE plsdnPen; PLSSUBL plssubl;
/* we don't have checks of parameters here because they are in LsdnFinishRegular */
plsdnPrev = GetDnodeToFinish(plsc); /* we should store it before calling LsdnFinishRegular */ plssubl = SublineFromDnode(plsdnPrev); lserr = LsdnFinishRegular(plsc, lsdcp, plsrun, plschp, pdobj, pobjdim); if (lserr != lserrNone) return lserr;
/* create and fill in pen dnode */ plsdnPen = PvNewQuick(GetPqhAllDNodes(plsc), sizeof *plsdnPen); if (plsdnPen == NULL) return lserrOutOfMemory; plsdnPen->tag = tagLSDNODE; plsdnPen->cpFirst = GetCurrentCpLimSubl(plssubl); plsdnPen->cpLimOriginal = plsdnPen->cpFirst; plsdnPen->plsdnPrev = plsdnPrev; plsdnPen->plsdnNext = NULL; plsdnPen->plssubl = plssubl; plsdnPen->dcp = 0; /* flush all flags, bellow check that result is what we expect */ \ *((DWORD *) ((&(plsdnPen)->dcp)+1)) = 0;\ Assert((plsdnPen)->fRigidDup == fFalse);\ Assert((plsdnPen)->fTab == fFalse);\ Assert((plsdnPen)->icaltbd == 0);\ Assert((plsdnPen)->fBorderNode == fFalse);\ Assert((plsdnPen)->fOpenBorder == fFalse);\ Assert((plsdnPen)->fEndOfSection == fFalse); \ Assert((plsdnPen)->fEndOfColumn == fFalse); \ Assert((plsdnPen)->fEndOfPage == fFalse); \ Assert((plsdnPen)->fEndOfPara == fFalse); \ Assert((plsdnPen)->fAltEndOfPara == fFalse); \ Assert((plsdnPen)->fSoftCR == fFalse); \ Assert((plsdnPen)->fInsideBorder == fFalse); \ Assert((plsdnPen)->fAutoDecTab == fFalse); \ Assert((plsdnPen)->fTabForAutonumber == fFalse); plsdnPen->klsdn = klsdnPenBorder; plsdnPen->fAdvancedPen = fTrue; SetPenBorderDurFmt(plsdnPen, durPen); plsdnPen->u.pen.dvr = dvrPen; plsdnPen->u.pen.dvp = dvpPen; /* maintain list */ plsdnPrev->plsdnNext = plsdnPen; SetCurrentDnodeSubl(plssubl, plsdnPen); AdvanceCurrentUrSubl(plssubl, durPen); AdvanceCurrentVrSubl(plssubl, dvrPen);
if (durPen < 0) plsc->fAdvanceBack = fTrue;
TurnOnNonRealDnodeEncounted(plsc); return lserrNone; }
/* L S D N F I N I S H D E L E T E */ /*----------------------------------------------------------------------------
%%Function: LsdnFinishDelete %%Contact: igorzv
Parameters: plsc - (IN) ptr to line services context lsdcp - (IN) dcp adopted
Delete dnode due to the will of formater ----------------------------------------------------------------------------*/
LSERR WINAPI LsdnFinishDelete( PLSC plsc, /* IN: Pointer to LS Context */ LSDCP lsdcp) /* IN: dcp to add */ { PLSDNODE plsdn; PLSSUBL plssubl; LSERR lserr; if (!FIsLSC(plsc)) return lserrInvalidParameter;
if (!FFormattingAllowed(plsc)) return lserrFormattingFunctionDisabled;
/* all sublines should be closed */ if (GetCurrentSubline(plsc) != NULL) return lserrFormattingFunctionDisabled;
plsdn = GetDnodeToFinish(plsc); if (plsdn == NULL) return lserrFiniFunctionDisabled;
plssubl = SublineFromDnode(plsdn);
/* nobody can change current dnode after plsdn was constructed */ Assert(GetCurrentDnodeSubl(plssubl) == plsdn->plsdnPrev);
Assert(plsdn->plsdnNext == NULL); lserr = DestroyDnodeList (&plsc->lscbk, plsc->pols, &plsc->lsiobjcontext, plsdn, plsc->fDontReleaseRuns); if (lserr != lserrNone) return lserr;
SetDnodeToFinish(plsc, NULL); AdvanceCurrentCpLimSubl(plssubl, lsdcp);
return lserrNone; }
/* L S D N F I N I S H P E N */ /*----------------------------------------------------------------------------
%%Function: LsdnFinishSimpleRegular %%Contact: igorzv
Parameters: plsc - (IN) ptr to line services context lsdcp - (IN) dcp adopted plsrun - (IN) plsrun of dnode plschp - (IN) plschp of dnode dur, dvr, dvp - (IN) variables to put in pen dnode
Finish dnode as a pen ----------------------------------------------------------------------------*/
LSERR WINAPI LsdnFinishByPen(PLSC plsc, /* IN: Pointer to LS Context */ LSDCP lsdcp, /* IN: dcp adopted */ PLSRUN plsrun, /* IN: PLSRUN */ PDOBJ pdobj, /* IN: PDOBJ */ long durPen, /* IN: dur */ long dvrPen, /* IN: dvr */ long dvpPen) /* IN: dvp */ { PLSDNODE plsdn; LSERR lserr; PLSSUBL plssubl; if (!FIsLSC(plsc)) return lserrInvalidParameter;
if (!FFormattingAllowed(plsc)) return lserrFormattingFunctionDisabled;
/* all sublines should be closed */ if (GetCurrentSubline(plsc) != NULL) return lserrFormattingFunctionDisabled;
plsdn = GetDnodeToFinish(plsc); if (plsdn == NULL) return lserrFiniFunctionDisabled;
plssubl = SublineFromDnode(plsdn);
if (plsrun != NULL && !plsc->fDontReleaseRuns) { lserr = plsc->lscbk.pfnReleaseRun(plsc->pols, plsrun); if (lserr != lserrNone) return lserr; }
/* caller pass pdobj to us only to destroy it*/ if (pdobj != NULL) { Assert(plsdn->u.real.lschp.idObj != idObjTextChp); lserr = (PLsimFromLsc(&plsc->lsiobjcontext, plsdn->u.real.lschp.idObj))->pfnDestroyDObj (pdobj); if (lserr != lserrNone) return lserr; }
plsdn->dcp = lsdcp; plsdn->cpLimOriginal = plsdn->cpFirst + lsdcp; plsdn->klsdn = klsdnPenBorder; plsdn->fBorderNode = fFalse; SetPenBorderDurFmt(plsdn, durPen); plsdn->u.pen.dvr = dvrPen; plsdn->u.pen.dvp = dvpPen;
/* nobody can change current dnode after plsdn was constructed */ Assert(GetCurrentDnodeSubl(plssubl) == plsdn->plsdnPrev);
*(GetWhereToPutLinkSubl(plssubl, plsdn->plsdnPrev)) = plsdn; SetCurrentDnodeSubl(plssubl, plsdn); SetDnodeToFinish(plsc, NULL); AdvanceCurrentCpLimSubl(plssubl, lsdcp); AdvanceCurrentUrSubl(plssubl, durPen); AdvanceCurrentVrSubl(plssubl, dvrPen);
TurnOnNonRealDnodeEncounted(plsc);
return lserrNone; }
/* L S D N F I N I S H B Y S U B L I N E*/ /*----------------------------------------------------------------------------
%%Function: LsdnFinishBySubline %%Contact: igorzv
Parameters: plsc - (IN) ptr to line services context lsdcp - (IN) increase cp by this number before hanldler ends plssubl - (IN) subline to substitute dnode to finish
Delete dnode and include child list in the upper level ----------------------------------------------------------------------------*/
LSERR WINAPI LsdnFinishBySubline(PLSC plsc, /* IN: Pointer to LS Context */ LSDCP lsdcp, /* IN: dcp adopted */ PLSSUBL plssubl) /* IN: Subline context */ { PLSDNODE plsdnParent; PLSDNODE plsdnChildFirst; PLSDNODE plsdnChildCurrent, plsdnChildPrevious; PLSSUBL plssublParent; LSERR lserr;
if (!FIsLSC(plsc)) return lserrInvalidParameter;
if (!FFormattingAllowed(plsc)) return lserrFormattingFunctionDisabled;
/* all sublines should be closed */ if (GetCurrentSubline(plsc) != NULL) return lserrFormattingFunctionDisabled;
plsdnParent = GetDnodeToFinish(plsc); if (plsdnParent == NULL) return lserrFiniFunctionDisabled;
plssublParent = SublineFromDnode(plsdnParent);
AdvanceCurrentCpLimSubl(plssublParent, lsdcp);
plsdnChildFirst = plssubl->plsdnFirst;
/* go through child list change subline and calculate resulting pen movement */ plsdnChildCurrent = plsdnChildFirst; plsdnChildPrevious = NULL; while (plsdnChildPrevious != plssubl->plsdnLast) { plsdnChildCurrent->plssubl = plssublParent; AdvanceCurrentUrSubl(plssublParent, DurFromDnode(plsdnChildCurrent)); AdvanceCurrentVrSubl(plssublParent, DvrFromDnode(plsdnChildCurrent)); plsdnChildPrevious = plsdnChildCurrent; plsdnChildCurrent = plsdnChildCurrent->plsdnNext; }
/* include subline's list to upper level */ *(GetWhereToPutLinkSubl(plssublParent, plsdnParent->plsdnPrev)) = plsdnChildFirst; if (plsdnChildFirst != NULL && plsdnParent->plsdnPrev != NULL) plsdnChildFirst->plsdnPrev = plsdnParent->plsdnPrev;
/* if subline's list is empty than dnode before parent should be made current */ if (plsdnChildFirst == NULL) { /* if subline's list is empty than dnode before parent should be made current */ SetCurrentDnodeSubl(plssublParent, plsdnParent->plsdnPrev); } else { /* else last dnode in subline is now current dnode */ SetCurrentDnodeSubl(plssublParent, plssubl->plsdnLast); }
/* delete parent dnode */ lserr = DestroyDnodeList (&plsc->lscbk, plsc->pols, &plsc->lsiobjcontext, plsdnParent, plsc->fDontReleaseRuns); if (lserr != lserrNone) return lserr;
/* set first dnode of subline to NULL and destroy subline will not erase dnodes that has
been promoted to the upper level */ plssubl->plsdnFirst = NULL;
lserr = DestroySublineCore(plssubl,&plsc->lscbk, plsc->pols, &plsc->lsiobjcontext, plsc->fDontReleaseRuns); if (lserr != lserrNone) return lserr;
SetDnodeToFinish(plsc, NULL); return lserrNone; }
/* L S D N F I N I S H D E L E T E A L L*/ /*----------------------------------------------------------------------------
%%Function: LsdnFinishDeleteAll %%Contact: igorzv
Parameters: plsc - (IN) ptr to line services context dcpToAdvance - (IN) increase cp by this number before hanldler ends
Delete parent dnode and include child list in the upper level ----------------------------------------------------------------------------*/
LSERR WINAPI LsdnFinishDeleteAll(PLSC plsc, /* IN: Pointer to LS Context */ LSDCP lsdcp) /* IN: dcp adopted */ { PLSDNODE plsdnParent; PLSDNODE plsdnFirstOnLine; PLSDNODE plsdnFirstInContents; PLSDNODE plsdnLastBeforeContents; LSERR lserr; long dvpPen; long durPen; long dvrPen; PLSSUBL plssublMain;
if (!FIsLSC(plsc)) return lserrInvalidParameter;
if (!FFormattingAllowed(plsc)) return lserrFormattingFunctionDisabled;
/* all sublines should be closed */ if (GetCurrentSubline(plsc) != NULL) return lserrFormattingFunctionDisabled;
plsdnParent = GetDnodeToFinish(plsc); if (plsdnParent == NULL) return lserrFiniFunctionDisabled;
plssublMain = &plsc->plslineCur->lssubl;
AdvanceCurrentCpLimSubl(plssublMain, lsdcp); plsdnFirstOnLine = plssublMain->plsdnFirst;
plsdnFirstInContents = plsdnFirstOnLine; plsdnLastBeforeContents = NULL; while (plsdnFirstInContents != NULL && FIsNotInContent(plsdnFirstInContents)) { plsdnLastBeforeContents = plsdnFirstInContents; plsdnFirstInContents = plsdnFirstInContents->plsdnNext; }
/* restore state as it was before starting formatting content*/ plsc->lstabscontext.plsdnPendingTab = NULL; plsc->plslineCur->lslinfo.fAdvanced = 0; plsc->plslineCur->lslinfo.EffectsFlags = 0;
/* break link with contest*/ if (plsdnFirstInContents != NULL) *(GetWhereToPutLinkSubl(plssublMain, plsdnFirstInContents->plsdnPrev)) = NULL; /* set dnode to append */ SetCurrentDnodeSubl(plssublMain, plsdnLastBeforeContents); /* set current subline */ SetCurrentSubline(plsc, plssublMain);
/* recalculate current position */ if (plsdnFirstInContents != NULL) { FindListFinalPenMovement(plsdnFirstInContents, plssublMain->plsdnLast, &durPen, &dvrPen, &dvpPen); AdvanceCurrentUrSubl(plssublMain, -durPen); AdvanceCurrentVrSubl(plssublMain, -dvrPen);
}
/* delete content before this parent dnode */ if (plsdnFirstInContents != NULL) { lserr = DestroyDnodeList (&plsc->lscbk, plsc->pols, &plsc->lsiobjcontext, plsdnFirstInContents, plsc->fDontReleaseRuns); if (lserr != lserrNone) return lserr; }
/* delete parent dnode and child list*/ lserr = DestroyDnodeList (&plsc->lscbk, plsc->pols, &plsc->lsiobjcontext, plsdnParent, plsc->fDontReleaseRuns); if (lserr != lserrNone) return lserr;
SetDnodeToFinish(plsc, NULL);
return lserrNone; }
LSERR WINAPI LsdnFinishByOneChar( /* allows replacement by simple DNODE only */ PLSC plsc, /* IN: Pointer to LS Context */ long urColumnMax, /* IN: urColumnMax */ WCHAR ch, /* IN: character to replace */ PCLSCHP plschp, /* IN: lschp for character */ PLSRUN plsrun, /* IN: plsrun for character */ FMTRES* pfmtres) /* OUT:Result of the Repl formatter*/ { LSERR lserr; LSFRUN lsfrun; PLSDNODE plsdn; PLSSUBL plssubl; if (!FIsLSC(plsc)) return lserrInvalidParameter;
if (!FFormattingAllowed(plsc)) return lserrFormattingFunctionDisabled;
/* all sublines should be closed */ if (GetCurrentSubline(plsc) != NULL) return lserrFormattingFunctionDisabled;
plsdn = GetDnodeToFinish(plsc); if (plsdn == NULL) return lserrFiniFunctionDisabled;
plssubl = SublineFromDnode(plsdn);
/* nobody can change current dnode after plsdn was constructed */ Assert(GetCurrentDnodeSubl(plssubl) == plsdn->plsdnPrev);
if (plsdn->dcp != 1) return lserrWrongFiniFunction;
lserr = LsdnFinishDelete(plsc, 0); if (lserr != lserrNone) return lserr;
Assert(IsLschpFlagsValid(plsc, plschp)); lsfrun.plschp = plschp; /* Special effects */ plsc->plslineCur->lslinfo.EffectsFlags |= plschp->EffectsFlags; lsfrun.plsrun = plsrun; lsfrun.lpwchRun = &ch; lsfrun.cwchRun = 1;
/* to ProcessOneRun work properly we need to temporarely restore current subline */ SetCurrentSubline(plsc, plssubl); lserr = ProcessOneRun(plsc, urColumnMax, &lsfrun, NULL, 0, pfmtres); if (lserr != lserrNone) return lserr;
SetCurrentSubline(plsc, NULL);
return lserrNone;
}
|