|
|
/*
* sobjhelp.c * * This file contains implementations of methods that help * common simple objects handle breaking and queries. All objects * that use these routines must as the first entry in their dobj * structure define an SObjCommon entry which these routines * will cast dobj's to. * */
#include "lsdefs.h"
#include "lsidefs.h"
#include "plocchnk.h"
#include "pposichn.h"
#include "posichnk.h"
#include "locchnk.h"
#include "brkcond.h"
#include "pbrko.h"
#include "brko.h"
#include "lsqout.h"
#include "lsqin.h"
#include "objhelp.h"
#include "sobjhelp.h"
#include "memory.h"
#include "lsmem.h"
#include "brkkind.h"
#define GET_DUR(pdobj) (((PSOBJHELP)pdobj)->objdimAll.dur)
#define GET_OBJDIM(pdobj) (((PSOBJHELP)pdobj)->objdimAll)
#define GET_DCP(pdobj) (((PSOBJHELP)pdobj)->dcp)
#define GET_MODAFTER(pdobj) (((PSOBJHELP)pdobj)->durModAfter)
/* F I L L B R E A K O U T */ /*----------------------------------------------------------------------------
%%Function: FillBreakOut %%Contact: ricksa
Fill break output record. ----------------------------------------------------------------------------*/ static void FillBreakOut( PDOBJ pdobj, /* (IN): DOBJ for object */ DWORD ichnk, /* (IN): index in chunk */ PBRKOUT pbrkout) /* (OUT): break output record */ { pbrkout->posichnk.ichnk = ichnk; pbrkout->fSuccessful = fTrue; pbrkout->posichnk.dcp = GET_DCP(pdobj); pbrkout->objdim = GET_OBJDIM(pdobj); pbrkout->objdim.dur -= GET_MODAFTER(pdobj); }
/* S O B J T R U N C A T E C H U N K */ /*----------------------------------------------------------------------------
%%Function: SobjTruncateChunk %%Contact: ricksa
. ----------------------------------------------------------------------------*/ LSERR WINAPI SobjTruncateChunk( PCLOCCHNK plocchnk, /* (IN): locchnk to truncate */ PPOSICHNK posichnk) /* (OUT): truncation point */ { long urColumnMax = plocchnk->lsfgi.urColumnMax; long ur = plocchnk->ppointUvLoc[0].u; PDOBJ pdobj = NULL; DWORD i = 0;
AssertSz(plocchnk->ppointUvLoc[0].u <= urColumnMax, "SobjTruncateChunk - pen greater than column max");
while (ur <= urColumnMax) { AssertSz((i < plocchnk->clschnk), "SobjTruncateChunk exceeded group of chunks");
AssertSz(plocchnk->ppointUvLoc[i].u <= urColumnMax, "SobjTruncateChunk starting pen exceeds col max");
pdobj = plocchnk->plschnk[i].pdobj; ur = plocchnk->ppointUvLoc[i].u + GET_DUR(pdobj); i++; }
/* LS does not allow the truncation point to be at the beginning of the object */ AssertSz(pdobj != NULL, "SobjTruncateChunk - pdobj NULL!"); posichnk->ichnk = i - 1; posichnk->dcp = GET_DCP(pdobj);
return lserrNone; }
/* S O B J F I N D P R E V B R E A K C H U N K */ /*----------------------------------------------------------------------------
%%Function: SobjFindPrevBreakChunk %%Contact: ricksa
. ----------------------------------------------------------------------------*/ LSERR WINAPI SobjFindPrevBreakChunk( PCLOCCHNK pclocchnk, /* (IN): locchnk to break */ PCPOSICHNK pcpoischnk, /* (IN): place to start looking for break */ BRKCOND brkcond, /* (IN): recommmendation about the break after chunk */ PBRKOUT pbrkout) /* (OUT): results of breaking */ { PDOBJ pdobj; DWORD ichnk = pcpoischnk->ichnk;
AssertSz((int) brkcondPlease == 0, "SobjFindPrevBreakChunk - brcondPlease != 0");
ZeroMemory(pbrkout, sizeof(*pbrkout));
if (ichnk == ichnkOutside) { ichnk = pclocchnk->clschnk - 1; pbrkout->posichnk.ichnk = ichnk; pdobj = pclocchnk->plschnk[ichnk].pdobj;
if (GET_DUR(pdobj) - GET_MODAFTER(pdobj) + pclocchnk->ppointUvLoc[ichnk].u > pclocchnk->lsfgi.urColumnMax) { /* Are we at beginning of chunk? */ if (ichnk > 0) { /* No - use the prior object in chunk */ ichnk--; pdobj = pclocchnk->plschnk[ichnk].pdobj; } else { /* Yes. We need the break to happen before us. */ pbrkout->posichnk.ichnk = ichnk; return lserrNone; } }
if (brkcond != brkcondNever) { /* Break at end of chunk. */
FillBreakOut(pdobj, ichnk, pbrkout); return lserrNone; } /* Else break at the beginning of last part of chunk */ }
if (ichnk >= 1) { /* Break before the current object */ FillBreakOut(pclocchnk->plschnk[ichnk - 1].pdobj, ichnk - 1, pbrkout); }
return lserrNone; }
/* S O B J F I N D N E X T B R E A K C H U N K */ /*----------------------------------------------------------------------------
%%Function: SobjFindNextBreakChunk %%Contact: ricksa
. ----------------------------------------------------------------------------*/ LSERR WINAPI SobjFindNextBreakChunk( PCLOCCHNK pclocchnk, /* (IN): locchnk to break */ PCPOSICHNK pcpoischnk, /* (IN): place to start looking for break */ BRKCOND brkcond, /* (IN): recommmendation about the break before chunk */ PBRKOUT pbrkout) /* (OUT): results of breaking */ { DWORD ichnk = pcpoischnk->ichnk;
AssertSz((int) brkcondPlease == 0, "SobjFindNextBreakChunk - brcondPlease != 0");
ZeroMemory(pbrkout, sizeof(*pbrkout));
if (ichnkOutside == ichnk) { if (brkcondNever != brkcond) { pbrkout->fSuccessful = fTrue;
return lserrNone; }
/* can't break before so break after first item in chunk */ ichnk = 0; }
/* If not outside, we break at end of current dobj */ FillBreakOut(pclocchnk->plschnk[ichnk].pdobj, ichnk, pbrkout);
if (pclocchnk->clschnk - 1 == ichnk) { /* At the end of chunk. We can't say success for sure */ pbrkout->fSuccessful = fFalse; }
return lserrNone; }
/* S O B J F O R C E B R E A K C H U N K */ /*----------------------------------------------------------------------------
%%Function: SobjForceBreak %%Contact: ricksa
Force Break
. ----------------------------------------------------------------------------*/ LSERR WINAPI SobjForceBreakChunk( PCLOCCHNK pclocchnk, /* (IN): locchnk to break */ PCPOSICHNK pcposichnk, /* (IN): place to start looking for break */ PBRKOUT pbrkout) /* (OUT): results of breaking */ { DWORD ichnk = pcposichnk->ichnk;
ZeroMemory(pbrkout, sizeof(*pbrkout)); pbrkout->posichnk.ichnk = ichnk;
if (pclocchnk->lsfgi.fFirstOnLine && (0 == ichnk)) { FillBreakOut(pclocchnk->plschnk[ichnk].pdobj, ichnk, pbrkout); }
else if (ichnk == ichnkOutside) { /* Breaking after first object */ FillBreakOut(pclocchnk->plschnk[0].pdobj, 0, pbrkout); } else if (ichnk != 0) { FillBreakOut(pclocchnk->plschnk[ichnk-1].pdobj, ichnk-1, pbrkout); }
else /* Nothing, breaking before object */;
pbrkout->fSuccessful = fTrue; /* Force break is always successful! */
return lserrNone; }
|