#include "lsidefs.h" #include "autonum.h" #include "lscbk.h" #include #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); }