mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
605 lines
18 KiB
605 lines
18 KiB
/* 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;
|
|
|
|
}
|
|
|