250 lines
6.5 KiB
C
250 lines
6.5 KiB
C
|
/*
|
||
|
* 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;
|
||
|
}
|
||
|
|