WindowsXP-SP1/windows/richedit/lssrc/autonum.c
2020-09-30 16:53:49 +02:00

691 lines
18 KiB
C

#include "lsidefs.h"
#include "autonum.h"
#include "lscbk.h"
#include <limits.h>
#include "lsmem.h" /* memset() */
#include "lsesc.h"
#include "fmti.h"
#include "objdim.h"
#include "lscrsubl.h"
#include "lssubset.h"
#include "lsdnfin.h"
#include "lsdssubl.h"
#include "dispi.h"
#include "lsdnode.h"
#include "tabutils.h"
#include "lscaltbd.h"
#include "lstbcon.h"
#include "lsdnset.h"
#include "lsensubl.h"
#include "dninfo.h"
struct ilsobj
{
POLS pols;
LSCBK lscbk;
PLSC plsc;
DWORD idObj;
LSESC lsescautonum;
};
struct dobj
{
PILSOBJ pilsobj; /* ILS object */
PLSSUBL plssubl; /* Handle to subline for autonumbering text */
};
#define ZeroMemory(a, b) memset(a, 0, b);
/* M A X */
/*----------------------------------------------------------------------------
%%Macro: Max
%%Contact: igorzv
Returns the maximum of two values a and b.
----------------------------------------------------------------------------*/
#define Max(a,b) ((a) < (b) ? (b) : (a))
/* A U T O N U M C R E A T E I L S O B J */
/*----------------------------------------------------------------------------
%%Function: autonumCreateILSObj
%%Contact: igorzv
Parameters
pols - (IN) client application context
plsc - (IN) ls context
pclscbk - (IN) callbacks to client application
idObj - (IN) id of the object
ppilsobj- (OUT)object ilsobj
Create the ILS object for all autonumbering objects.
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumCreateILSObj(POLS pols, PLSC plsc,
PCLSCBK pclscbk, DWORD idObj, PILSOBJ *ppilsobj)
{
PILSOBJ pilsobj;
pilsobj = pclscbk->pfnNewPtr(pols, sizeof(*pilsobj));
if (NULL == pilsobj)
{
return lserrOutOfMemory;
}
pilsobj->pols = pols;
pilsobj->lscbk = *pclscbk;
pilsobj->plsc = plsc;
pilsobj->idObj = idObj;
*ppilsobj = pilsobj;
return lserrNone;
}
/* S E T A U T O N U M C O N F I G */
/*----------------------------------------------------------------------------
%%Function: SetAutonumConfig
%%Contact: igorzv
Parameters
pilsobj - (IN) object ilsobj
plstxtconfig - (IN) definition of special characters
Set ecs character for autonumbering sequence
----------------------------------------------------------------------------*/
LSERR SetAutonumConfig(PILSOBJ pilsobj, const LSTXTCFG* plstxtconfig)
{
pilsobj->lsescautonum.wchFirst = plstxtconfig->wchEscAnmRun;
pilsobj->lsescautonum.wchLast = plstxtconfig->wchEscAnmRun;
return lserrNone;
}
/* A U T O N U M D E S T R O Y I L S O B J */
/*----------------------------------------------------------------------------
%%Function: AutonumDestroyILSObj
%%Contact: igorzv
Parameters
pilsobj - (IN) object ilsobj
Free all resources assocaiated with autonum ILS object.
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumDestroyILSObj(PILSOBJ pilsobj)
{
pilsobj->lscbk.pfnDisposePtr(pilsobj->pols, pilsobj);
return lserrNone;
}
/* A U T O N U M S E T D O C */
/*----------------------------------------------------------------------------
%%Function: AutonumSetDoc
%%Contact: igorzv
Parameters
pilsobj - (IN) object ilsobj
pclsdocinf - (IN) initialization data of the document level
Empty function
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumSetDoc(PILSOBJ pilsobj, PCLSDOCINF pclsdocinf)
{
Unreferenced(pilsobj);
Unreferenced(pclsdocinf);
return lserrNone;
}
/* A U T O N U M C R E A T E L N O B J */
/*----------------------------------------------------------------------------
%%Function: AutonumCreateLNObj
%%Contact: igorzv
Parameters
pilsobj - (IN) object ilsobj
pplnobj - (OUT)object lnobj
Create the Line Object for the autonum. No real need for a line
object so don't allocated it.
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumCreateLNObj( PCILSOBJ pcilsobj, PLNOBJ *pplnobj)
{
*pplnobj = (PLNOBJ) pcilsobj;
return lserrNone;
}
/* A U T O N U M D E S T R O Y L N O B J */
/*----------------------------------------------------------------------------
%%Function: AautonumDestroyLNObj
%%Contact: igorzv
Parameters
pplnobj - (IN) object lnobj
Frees resources associated with the autonum line object. Since
there isn't any this is a no-op.
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumDestroyLNObj(PLNOBJ plnobj)
{
Unreferenced(plnobj);
return lserrNone;
}
/* A U T O N U M F M T */
/*----------------------------------------------------------------------------
%%Function: AutonumFmt
%%Contact: igorzv
Parameters
pplnobj - (IN) object lnobj
pcfmtin - (IN) formatting input
pfmtres - (OUT)formatting result
Format the autonum object.
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumFmt(PLNOBJ plnobj, PCFMTIN pcfmtin, FMTRES *pfmtres)
{
PDOBJ pdobj;
LSERR lserr;
PILSOBJ pilsobj = (PILSOBJ) plnobj;
LSCP cpStartMain = pcfmtin->lsfgi.cpFirst;
LSCP cpOut;
LSTFLOW lstflow = pcfmtin->lsfgi.lstflow;
FMTRES fmtres;
OBJDIM objdimAll;
LSDCP dcp;
PLSDNODE plsdnFirst;
PLSDNODE plsdnLast;
BOOL fSuccessful;
/*
* Allocate the DOBJ
*/
pdobj = pilsobj->lscbk.pfnNewPtr(pilsobj->pols, sizeof(*pdobj));
if (NULL == pdobj)
{
return lserrOutOfMemory;
}
ZeroMemory(pdobj, sizeof(*pdobj));
pdobj->pilsobj = pilsobj;
/*
* Build main line of text
*/
lserr = LsCreateSubline(pilsobj->plsc, cpStartMain, uLsInfiniteRM,
lstflow, fFalse); /* because fContiguous is false
all tabs will be skipped*/
if (lserr != lserrNone)
{
AutonumDestroyDobj(pdobj);
return lserr;
}
lserr = LsFetchAppendToCurrentSubline(pilsobj->plsc, 0, &(pilsobj->lsescautonum),
1, &fSuccessful, &fmtres, &cpOut, &plsdnFirst, &plsdnLast);
/* because we formatting with uLsInfiniteRM margin result should be successful */
if (lserr != lserrNone)
{
AutonumDestroyDobj(pdobj);
return lserr;
}
if (fmtres != fmtrCompletedRun)
{
AutonumDestroyDobj(pdobj);
return lserrInvalidAutonumRun;
}
lserr = LsFinishCurrentSubline(pilsobj->plsc, &(pdobj->plssubl));
if (lserr != lserrNone)
{
AutonumDestroyDobj(pdobj);
return lserr;
}
// submit subline for display
lserr = LsdnSubmitSublines(pilsobj->plsc, pcfmtin->plsdnTop,
1, &(pdobj->plssubl),
fFalse, fFalse, fTrue, fFalse, fFalse);
if (lserr != lserrNone)
{
AutonumDestroyDobj(pdobj);
return lserr;
}
/*
* Calculate the object dimensions.
*/
lserr = LssbGetObjDimSubline(pdobj->plssubl, &lstflow, &objdimAll);
if (lserr != lserrNone)
{
AutonumDestroyDobj(pdobj);
return lserr;
}
/* for multiline heights use ascent */
objdimAll.heightsRef.dvMultiLineHeight = objdimAll.heightsRef.dvAscent;
objdimAll.heightsPres.dvMultiLineHeight = objdimAll.heightsPres.dvAscent;
dcp = cpOut - cpStartMain + 1; /* additional is esc character */
lserr = LsdnFinishRegular(pilsobj->plsc, dcp,
pcfmtin->lsfrun.plsrun, pcfmtin->lsfrun.plschp, pdobj,
&objdimAll);
if (lserr != lserrNone)
{
AutonumDestroyDobj(pdobj);
return lserr;
}
*pfmtres = fmtrCompletedRun;
return lserrNone;
}
/* A U T O N U M G E T S P E C I A L E F F E C T S I N S I D E */
/*----------------------------------------------------------------------------
%%Function: AutonumGetSpecialEffectsInside
%%Contact: igorzv
Parameters
pdobj - (IN) structure describes object
*pEffectsFlags - (OUT)Special effects for this object
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumGetSpecialEffectsInside(PDOBJ pdobj, UINT *pEffectsFlags)
{
return LsGetSpecialEffectsSubline(pdobj->plssubl, pEffectsFlags);
}
/* A U T O N U M C A L C P R E S E N T A T I O N */
/*----------------------------------------------------------------------------
%%Function: AutonumCalcPresentation
%%Contact: igorzv
Parameters
pdobj - (IN) structure describes object
dup - (IN) is not used
lskj - (IN) current justification mode
This just makes the line match the calculated presentation of the line.
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumCalcPresentation(PDOBJ pdobj, long dup, LSKJUST lskjust, BOOL fLastOnLine)
{
Unreferenced(dup);
Unreferenced(lskjust);
Unreferenced(fLastOnLine);
return LsMatchPresSubline(pdobj->plssubl);
}
/* A U T O N U M Q U E R Y P O I N T P C P */
/*----------------------------------------------------------------------------
%%Function: AutonumQueryPointPcp
%%Contact: igorzv
Should never be called
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumQueryPointPcp(PDOBJ pdobj, PCPOINTUV ppointuvQuery,
PCLSQIN plsqin, PLSQOUT plsqout)
{
Unreferenced(pdobj);
Unreferenced(ppointuvQuery);
Unreferenced(plsqin);
Unreferenced(plsqout);
NotReached();
return lserrInvalidParameter;
}
/* A U T O N U M Q U E R Y C P P P O I N T */
/*----------------------------------------------------------------------------
%%Function: AutonumQueryCpPpoint
%%Contact: igorzv
Should never be called
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumQueryCpPpoint(PDOBJ pdobj, LSDCP dcp,
PCLSQIN plsqin, PLSQOUT plsqout)
{
Unreferenced(pdobj);
Unreferenced(dcp);
Unreferenced(plsqin);
Unreferenced(plsqout);
NotReached();
return lserrInvalidParameter;
}
/* A U T O N U M T R U N C A T E C H U N K */
/*----------------------------------------------------------------------------
%%Function: AutonumTruncateChunk
%%Contact: igorzv
Should never be called
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumTruncateChunk(PCLOCCHNK pclocchnk, PPOSICHNK pposichnk)
{
Unreferenced(pclocchnk);
Unreferenced(pposichnk);
NotReached();
return lserrInvalidParameter;
}
/* A U T O N U M F I N D P R E V B R E A K C H U N K */
/*----------------------------------------------------------------------------
%%Function: AutonumFindPrevBreakChunk
%%Contact: igorzv
Should never be called
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumFindPrevBreakChunk(PCLOCCHNK pclocchnk, PCPOSICHNK pposichnk,
BRKCOND brkcond, PBRKOUT pbrkout)
{
Unreferenced(pclocchnk);
Unreferenced(pposichnk);
Unreferenced(brkcond);
Unreferenced(pbrkout);
NotReached();
return lserrInvalidParameter;
}
/* A U T O N U M F I N D N E X T B R E A K C H U N K */
/*----------------------------------------------------------------------------
%%Function: AutonumFindNextBreakChunk
%%Contact: igorzv
Should never be called
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumFindNextBreakChunk(PCLOCCHNK pclocchnk, PCPOSICHNK pposichnk,
BRKCOND brkcond, PBRKOUT pbrkout)
{
Unreferenced(pclocchnk);
Unreferenced(pposichnk);
Unreferenced(brkcond);
Unreferenced(pbrkout);
NotReached();
return lserrInvalidParameter;
}
/* A U T O N U M F O R C E B R E A K C H U N K */
/*----------------------------------------------------------------------------
%%Function: AutonumForceBreakChunk
%%Contact: igorzv
Should never be called
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumForceBreakChunk(PCLOCCHNK pclocchnk, PCPOSICHNK pposichnk,
PBRKOUT pbrkout)
{
Unreferenced(pclocchnk);
Unreferenced(pposichnk);
Unreferenced(pbrkout);
NotReached();
return lserrInvalidParameter;
}
/* A U T O N U M S E T B R E A K */
/*----------------------------------------------------------------------------
%%Function: AutonumSetBreak
%%Contact: igorzv
Should never be called
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumSetBreak(PDOBJ pdobj, BRKKIND brkkind, DWORD nbreakrecord,
BREAKREC* rgbreakrec, DWORD* pnactualbreakrecord)
{
Unreferenced(pdobj);
Unreferenced(brkkind);
Unreferenced(rgbreakrec);
Unreferenced(nbreakrecord);
Unreferenced(pnactualbreakrecord);
NotReached();
return lserrInvalidParameter;
}
/* A U T O N U M D I S P L A Y */
/*----------------------------------------------------------------------------
%%Function: AutonumDisplay
%%Contact: igorzv
Parameters
pdobj - (IN) structure describes object
pcdispin - (IN) info for display
Displays subline
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumDisplay(PDOBJ pdobj, PCDISPIN pcdispin)
{
BOOL fDisplayed;
LSERR lserr = LssbFDoneDisplay(pdobj->plssubl, &fDisplayed);
if (lserr != lserrNone)
{
return lserr;
}
if (fDisplayed)
{
return lserrNone;
}
else
{
/* display the autonum line */
return LsDisplaySubline(pdobj->plssubl, &(pcdispin->ptPen), pcdispin->kDispMode,
pcdispin->prcClip);
}
}
/* A U T O N U M D E S T R O Y D O B J */
/*----------------------------------------------------------------------------
%%Function: AutonumDestroyDobj
%%Contact: igorzv
Parameters
pdobj - (IN) structure describes object
Free all resources connected with the input dobj.
----------------------------------------------------------------------------*/
LSERR WINAPI AutonumDestroyDobj(PDOBJ pdobj)
{
LSERR lserr = lserrNone;
PILSOBJ pilsobj = pdobj->pilsobj;
if (pdobj->plssubl != NULL)
{
lserr = LsDestroySubline(pdobj->plssubl);
}
pilsobj->lscbk.pfnDisposePtr(pilsobj->pols, pdobj);
return lserr;
}
/* A L L I G N A U T O N U M 95 */
/*----------------------------------------------------------------------------
%%Function: AllignAutonum95
%%Contact: igorzv
Parameters
durSpaceAnm - (IN) space after autonumber
durWidthAnm - (IN) distance from indent to main text
lskalignAnM - (IN) allignment for autonumber
plsdnAnmAfter - (IN) tab dnode to put durAfter
durUsed - (IN) width of autonumbering text
pdurBefore - (OUT)calculated distance from indent to autonumber
pdurAfter - (OUT)calculated distance from autonumber to main text
Calculates space before and after autonumber for the case Word95 model.
----------------------------------------------------------------------------*/
void AllignAutonum95(long durSpaceAnm, long durWidthAnm, LSKALIGN lskalignAnm,
long durUsed, PLSDNODE plsdnAnmAfter, long* pdurBefore, long* pdurAfter)
{
long durExtra;
long durJust;
long durRemain;
durExtra = Max(0, durWidthAnm - durUsed);
durRemain = Max(0, durExtra - durSpaceAnm);
*pdurBefore = 0;
switch (lskalignAnm)
{
case lskalLeft:
*pdurAfter = Max(durSpaceAnm,durExtra);
break;
case lskalCentered:
durJust = ((DWORD)durExtra) / 2;
if (durJust >= durSpaceAnm)
{
*pdurBefore = durJust;
*pdurAfter = durJust;
}
else
{
/* Justified will not fit -- treat as flushleft */
*pdurBefore = durRemain;
*pdurAfter = durSpaceAnm;
}
break;
case lskalRight:
*pdurBefore = durRemain;
*pdurAfter = durSpaceAnm;
break;
default:
NotReached();
}
Assert(FIsDnodeReal(plsdnAnmAfter));
Assert(plsdnAnmAfter->fTab);
SetDnodeDurFmt(plsdnAnmAfter, *pdurAfter);
plsdnAnmAfter->icaltbd = 0xFF; /* spoil icaltbd */
}
/* A L L I G N A U T O N U M */
/*----------------------------------------------------------------------------
%%Function: AllignAutonum
%%Contact: igorzv
Parameters
plstabscontext - (IN) tabs context
lskalignAnm - (IN) allignment for autonumber
fAllignmentAfter- (IN) is there tab after autonumber
plsdnAnmAfter - (IN) tab dnode to put durAfter
urAfterAnm - (IN) pen position after autonumber
durUsed - (IN) width of autonumbering text
pdurBefore - (OUT)calculated distance from indent to autonumber
pdurAfter - (OUT)calculated distance from autonumber to main text
Calculates space before and after autonumber for the case Word95 model.
----------------------------------------------------------------------------*/
LSERR AllignAutonum(PLSTABSCONTEXT plstabscontext, LSKALIGN lskalignAnm,
BOOL fAllignmentAfter, PLSDNODE plsdnAnmAfter,
long urAfterAnm, long durUsed,
long* pdurBefore, long* pdurAfter)
{
LSERR lserr;
LSKTAB lsktab;
BOOL fBreakThroughTab;
LSCALTBD* plscaltbd;
/* resolving durBefore */
switch (lskalignAnm)
{
case lskalLeft:
*pdurBefore = 0;
break;
case lskalCentered:
*pdurBefore = -durUsed/2;
break;
case lskalRight:
*pdurBefore = -durUsed;
break;
default:
NotReached();
}
/* resolving durAfter */
*pdurAfter = 0;
if (fAllignmentAfter)
{
Assert(FIsDnodeReal(plsdnAnmAfter));
Assert(plsdnAnmAfter->fTab);
plsdnAnmAfter->fTabForAutonumber = fTrue;
urAfterAnm += *pdurBefore;
lserr = GetCurTabInfoCore(plstabscontext, plsdnAnmAfter,
urAfterAnm, fTrue, &lsktab, &fBreakThroughTab);
if (lserr != lserrNone)
return lserr;
plscaltbd = &(plstabscontext->pcaltbd[plsdnAnmAfter->icaltbd]);
*pdurAfter = plsdnAnmAfter->u.real.objdim.dur;
}
return lserrNone;
}
LSERR WINAPI AutonumEnumerate(PDOBJ pdobj, PLSRUN plsrun, PCLSCHP plschp, LSCP cpFirst, LSDCP dcp,
LSTFLOW lstflow, BOOL fReverseOrder, BOOL fGeometryProvided,
const POINT* pptStart, PCHEIGHTS pheightsPres, long dupRun)
{
Unreferenced(plschp);
Unreferenced(plsrun);
Unreferenced(cpFirst);
Unreferenced(dcp);
Unreferenced(lstflow);
Unreferenced(fGeometryProvided);
Unreferenced(pheightsPres);
Unreferenced(dupRun);
return LsEnumSubline(pdobj->plssubl, fReverseOrder, fGeometryProvided,
pptStart);
}