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.
684 lines
19 KiB
684 lines
19 KiB
#include "lsmem.h"
|
|
#include <limits.h>
|
|
|
|
#include "lsstring.h"
|
|
#include "txtils.h"
|
|
#include "txtln.h"
|
|
#include "txtobj.h"
|
|
|
|
/* Internal Functions prototypes */
|
|
static LSERR CheckReallocCharArrays(PLNOBJ plnobj, long cwch, long iwchLocalStart, long *cwchCorrect);
|
|
static LSERR CheckReallocSpacesArrays(PILSOBJ pobj, long cwSpaces);
|
|
static LSERR CopyCharsSpacesToDispList(PLNOBJ plnobj, WCHAR* rgwch, long cwch,
|
|
long* rgwSpaces, long cwSpaces);
|
|
static LSERR CopySpacesToDispList(PLNOBJ plnobj, long iNumOfSpaces, long durSpace);
|
|
|
|
/* Export Functions implementations */
|
|
|
|
/*----------------------------------------------------------------------------
|
|
%%Function: GetWidth
|
|
%%Contact: sergeyge
|
|
|
|
Fetches widths until end of run or right margin
|
|
|
|
Uses cache to improve performance
|
|
----------------------------------------------------------------------------*/
|
|
LSERR GetWidths(PLNOBJ plnobj, PLSRUN plsrun, long iwchStart, LPWSTR lpwch, LSCP cpFirst, long dcp, long durWidthExceed,
|
|
LSTFLOW lstflow, long* pcwchFetched, long* pdurWidth)
|
|
{
|
|
LSERR lserr;
|
|
PILSOBJ pilsobj;
|
|
long durWidth;
|
|
long cwch;
|
|
long iwchDur;
|
|
long cwchCorrect;
|
|
long cwchIter;
|
|
long durWidthIter;
|
|
BOOL fNothingReturned = fTrue;
|
|
|
|
pilsobj = plnobj->pilsobj;
|
|
|
|
durWidth = 0;
|
|
cwch = 0;
|
|
iwchDur = iwchStart;
|
|
*pcwchFetched = 0;
|
|
*pdurWidth = 0;
|
|
|
|
if (pilsobj->dcpFetchedWidth != 0 && cpFirst == pilsobj->cpFirstFetchedWidth &&
|
|
iwchStart == pilsobj->iwchFetchedWidth && lpwch[0] == pilsobj->wchFetchedWidthFirst)
|
|
{
|
|
Assert(dcp >= pilsobj->dcpFetchedWidth);
|
|
cwch = pilsobj->dcpFetchedWidth;
|
|
durWidth = pilsobj->durFetchedWidth;
|
|
/* FormatRegular assumes that First character exceeding right margin will stop GetCharWidth loop;
|
|
Special character could change situation---fix it.
|
|
*/
|
|
if (durWidth > durWidthExceed)
|
|
{
|
|
while(cwch > 1 && durWidth - durWidthExceed > pilsobj->pdur[iwchStart + cwch - 1])
|
|
{
|
|
cwch--;
|
|
durWidth -= pilsobj->pdur[iwchStart + cwch];
|
|
}
|
|
}
|
|
dcp -= cwch;
|
|
durWidthExceed -= durWidth;
|
|
iwchDur += cwch;
|
|
fNothingReturned = fFalse;
|
|
}
|
|
|
|
while (fNothingReturned || dcp > 0 && durWidthExceed >= 0)
|
|
{
|
|
lserr = CheckReallocCharArrays(plnobj, dcp, iwchDur, &cwchCorrect);
|
|
if (lserr != lserrNone) return lserr;
|
|
|
|
lserr = (*pilsobj->plscbk->pfnGetRunCharWidths)(pilsobj->pols, plsrun, lsdevReference,
|
|
&lpwch[cwch], cwchCorrect, (int)durWidthExceed,
|
|
lstflow, (int*)&pilsobj->pdur[iwchDur], &durWidthIter, &cwchIter);
|
|
if (lserr != lserrNone) return lserr;
|
|
|
|
Assert(durWidthIter >= 0);
|
|
Assert(durWidthIter <= uLsInfiniteRM);
|
|
|
|
Assert (durWidthIter <= uLsInfiniteRM - durWidth);
|
|
|
|
if (durWidthIter > uLsInfiniteRM - durWidth)
|
|
return lserrTooLongParagraph;
|
|
|
|
durWidth += durWidthIter;
|
|
|
|
durWidthExceed -= durWidthIter;
|
|
iwchDur += cwchIter;
|
|
cwch += cwchIter;
|
|
dcp -= cwchIter;
|
|
fNothingReturned = fFalse;
|
|
}
|
|
|
|
|
|
*pcwchFetched = cwch;
|
|
*pdurWidth = durWidth;
|
|
|
|
pilsobj->iwchFetchedWidth = iwchStart;
|
|
pilsobj->cpFirstFetchedWidth = cpFirst;
|
|
pilsobj->dcpFetchedWidth = cwch;
|
|
pilsobj->durFetchedWidth = durWidth;
|
|
|
|
return lserrNone;
|
|
}
|
|
|
|
|
|
/* F O R M A T S T R I N G */
|
|
/*----------------------------------------------------------------------------
|
|
%%Function: FormatString
|
|
%%Contact: sergeyge
|
|
|
|
Formats the local run
|
|
----------------------------------------------------------------------------*/
|
|
LSERR FormatString(PLNOBJ plnobj, PTXTOBJ pdobjText, WCHAR* rgwch, long cwch,
|
|
long* rgwSpaces, long cwSpaces, long durWidth)
|
|
{
|
|
LSERR lserr;
|
|
PILSOBJ pilsobj;
|
|
|
|
pilsobj = plnobj->pilsobj;
|
|
|
|
lserr = CopyCharsSpacesToDispList(plnobj, rgwch, cwch, rgwSpaces, cwSpaces);
|
|
if (lserr != lserrNone) return lserr;
|
|
|
|
/* fill out all related members from strils and output parameters */
|
|
pdobjText->iwchLim = pdobjText->iwchLim + cwch;
|
|
pdobjText->u.reg.iwSpacesLim = pdobjText->u.reg.iwSpacesLim + cwSpaces;
|
|
|
|
/* Fix Width Fetching state */
|
|
Assert((long)pilsobj->dcpFetchedWidth >= cwch);
|
|
Assert(pilsobj->durFetchedWidth >= durWidth);
|
|
|
|
pilsobj->iwchFetchedWidth = pilsobj->iwchFetchedWidth + cwch;
|
|
pilsobj->cpFirstFetchedWidth += cwch;
|
|
pilsobj->dcpFetchedWidth -= cwch;
|
|
pilsobj->durFetchedWidth -= durWidth;
|
|
|
|
return lserrNone;
|
|
}
|
|
|
|
/* F I L L R E G U L A R P R E S W I D T H S */
|
|
/*----------------------------------------------------------------------------
|
|
%%Function: MeasureStringFirst
|
|
%%Contact: sergeyge
|
|
|
|
Calculates dur of one character.
|
|
----------------------------------------------------------------------------*/
|
|
LSERR FillRegularPresWidths(PLNOBJ plnobj, PLSRUN plsrun, LSTFLOW lstflow, PTXTOBJ pdobjText)
|
|
{
|
|
LSERR lserr;
|
|
PILSOBJ pilsobj;
|
|
int* rgDup;
|
|
long dupJunk;
|
|
long limDupJunk;
|
|
|
|
pilsobj = plnobj->pilsobj;
|
|
|
|
if (pilsobj->fDisplay)
|
|
{
|
|
rgDup = (int *)&plnobj->pdup[pdobjText->iwchFirst];
|
|
|
|
if (!pilsobj->fPresEqualRef)
|
|
{
|
|
lserr = (*pilsobj->plscbk->pfnGetRunCharWidths)(pilsobj->pols, plsrun, lsdevPres,
|
|
&pilsobj->pwchOrig[pdobjText->iwchFirst], pdobjText->iwchLim - pdobjText->iwchFirst,
|
|
LONG_MAX, lstflow, rgDup, &dupJunk, &limDupJunk);
|
|
if (lserr != lserrNone) return lserr;
|
|
}
|
|
else /* fPresEqualRef */
|
|
{
|
|
memcpy(rgDup, &pilsobj->pdur[pdobjText->iwchFirst], sizeof(long) * (pdobjText->iwchLim - pdobjText->iwchFirst));
|
|
}
|
|
}
|
|
|
|
return lserrNone;
|
|
|
|
}
|
|
|
|
|
|
/* G E T O N E C H A R D U P */
|
|
/*----------------------------------------------------------------------------
|
|
%%Function: MeasureStringFirst
|
|
%%Contact: sergeyge
|
|
|
|
Calculates dur of one character.
|
|
----------------------------------------------------------------------------*/
|
|
LSERR GetOneCharDur(PILSOBJ pilsobj, PLSRUN plsrun, WCHAR wch, LSTFLOW lstflow, long* pdur)
|
|
{
|
|
LSERR lserr;
|
|
long durSumJunk;
|
|
long limDurJunk;
|
|
|
|
lserr = (*pilsobj->plscbk->pfnGetRunCharWidths)(pilsobj->pols, plsrun, lsdevReference, &wch, 1, LONG_MAX, lstflow,
|
|
(int*)pdur, &durSumJunk, &limDurJunk);
|
|
if (lserr != lserrNone) return lserr;
|
|
|
|
return lserrNone;
|
|
}
|
|
|
|
/* G E T O N E C H A R D U P */
|
|
/*----------------------------------------------------------------------------
|
|
%%Function: GetOneCharDup
|
|
%%Contact: sergeyge
|
|
|
|
Calculates dup of one character
|
|
----------------------------------------------------------------------------*/
|
|
LSERR GetOneCharDup(PILSOBJ pilsobj, PLSRUN plsrun, WCHAR wch, LSTFLOW lstflow, long dur, long* pdup)
|
|
{
|
|
LSERR lserr;
|
|
long dupSumJunk;
|
|
long limDupJunk;
|
|
|
|
*pdup = 0;
|
|
if (pilsobj->fDisplay)
|
|
{
|
|
if (!pilsobj->fPresEqualRef)
|
|
{
|
|
lserr = (*pilsobj->plscbk->pfnGetRunCharWidths)(pilsobj->pols, plsrun, lsdevPres, &wch, 1,
|
|
LONG_MAX, lstflow, (int*)pdup, &dupSumJunk, &limDupJunk);
|
|
if (lserr != lserrNone) return lserr;
|
|
}
|
|
else
|
|
{
|
|
*pdup = dur;
|
|
}
|
|
}
|
|
|
|
|
|
return lserrNone;
|
|
}
|
|
|
|
/* G E T V I S I D U P */
|
|
/*----------------------------------------------------------------------------
|
|
%%Function: GetVisiDup
|
|
%%Contact: sergeyge
|
|
|
|
Calculates dup of visi character character
|
|
----------------------------------------------------------------------------*/
|
|
LSERR GetVisiCharDup(PILSOBJ pilsobj, PLSRUN plsrun, WCHAR wch, LSTFLOW lstflow, long* pdup)
|
|
{
|
|
LSERR lserr;
|
|
long dupSumJunk;
|
|
long limDupJunk;
|
|
|
|
*pdup = 0;
|
|
if (pilsobj->fDisplay)
|
|
{
|
|
lserr = (*pilsobj->plscbk->pfnGetRunCharWidths)(pilsobj->pols, plsrun, lsdevPres, &wch, 1,
|
|
LONG_MAX, lstflow, (int*)pdup, &dupSumJunk, &limDupJunk);
|
|
if (lserr != lserrNone) return lserr;
|
|
}
|
|
|
|
return lserrNone;
|
|
}
|
|
|
|
|
|
/* A D D C H A R A C T E R W I T H W I D T H */
|
|
/*----------------------------------------------------------------------------
|
|
%%Function: AddCharacterWithWidth
|
|
%%Contact: sergeyge
|
|
|
|
Writes character code and its width in wchOrig, wch, dup, dur arrays.
|
|
Stores character code (in the VISI situation it can be different from wch)
|
|
in pilsobj->wchPrev.
|
|
----------------------------------------------------------------------------*/
|
|
LSERR AddCharacterWithWidth(PLNOBJ plnobj, PTXTOBJ pdobjText, WCHAR wchOrig, long durWidth, WCHAR wch, long dupWidth)
|
|
{
|
|
LSERR lserr;
|
|
PILSOBJ pilsobj;
|
|
long iwchLocalStart;
|
|
long cjunk;
|
|
|
|
pilsobj = plnobj->pilsobj;
|
|
|
|
iwchLocalStart = pilsobj->wchMac;
|
|
|
|
lserr = CheckReallocCharArrays(plnobj, 1, iwchLocalStart, &cjunk);
|
|
if (lserr != lserrNone) return lserr;
|
|
|
|
|
|
/* Fix cached width information before width in the pdur array is overwritten by durWidth.
|
|
Theoretically durWidth can be different from the cached value */
|
|
|
|
if (pilsobj->dcpFetchedWidth > 0)
|
|
{
|
|
pilsobj->iwchFetchedWidth ++;
|
|
pilsobj->cpFirstFetchedWidth ++;
|
|
pilsobj->dcpFetchedWidth --;
|
|
pilsobj->durFetchedWidth -= pilsobj->pdur[iwchLocalStart];
|
|
}
|
|
|
|
|
|
pilsobj->pwchOrig[iwchLocalStart] = wchOrig;
|
|
pilsobj->pdur[iwchLocalStart] = durWidth;
|
|
|
|
if (pilsobj->fDisplay)
|
|
{
|
|
plnobj->pwch[iwchLocalStart] = wch;
|
|
plnobj->pdup[iwchLocalStart] = dupWidth;
|
|
}
|
|
|
|
pilsobj->wchMac++;
|
|
|
|
pdobjText->iwchLim++;
|
|
|
|
Assert(pilsobj->wchMac == pdobjText->iwchLim);
|
|
|
|
|
|
return lserrNone;
|
|
}
|
|
|
|
/* F I X S P A C E S */
|
|
/*----------------------------------------------------------------------------
|
|
%%Function: FixSpaces
|
|
%%Contact: sergeyge
|
|
|
|
Fixes space character code for the Visi Spaces situation
|
|
----------------------------------------------------------------------------*/
|
|
void FixSpaces(PLNOBJ plnobj, PTXTOBJ pdobjText, WCHAR wch)
|
|
{
|
|
PILSOBJ pilsobj;
|
|
long i;
|
|
|
|
pilsobj = plnobj->pilsobj;
|
|
|
|
if (pilsobj->fDisplay)
|
|
{
|
|
for (i = pdobjText->u.reg.iwSpacesFirst; i < pdobjText->u.reg.iwSpacesLim; i++)
|
|
{
|
|
plnobj->pwch[pilsobj->pwSpaces[i]] = wch;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* A D D S P A C E S */
|
|
/*----------------------------------------------------------------------------
|
|
%%Function: AddTrailingSpaces
|
|
%%Contact: sergeyge
|
|
|
|
Adds trailing/bordered spaces to the disp list
|
|
----------------------------------------------------------------------------*/
|
|
LSERR AddSpaces(PLNOBJ plnobj, PTXTOBJ pdobjText, long durSpace, long iNumOfSpaces)
|
|
{
|
|
LSERR lserr;
|
|
|
|
lserr = CopySpacesToDispList(plnobj, iNumOfSpaces, durSpace);
|
|
if (lserr != lserrNone) return lserr;
|
|
|
|
pdobjText->iwchLim = pdobjText->iwchLim + iNumOfSpaces;
|
|
pdobjText->u.reg.iwSpacesLim = pdobjText->u.reg.iwSpacesLim + iNumOfSpaces;
|
|
|
|
/* Fix Fetched Widths part. For non-bordered case, this procedure is activated for
|
|
trailing spaces only, so this state should also be filled with 0s, but
|
|
for bordered case it must be flushed
|
|
*/
|
|
FlushStringState(plnobj->pilsobj);
|
|
|
|
return lserrNone;
|
|
}
|
|
|
|
/* I N C R E A S E W C H M A C B Y @ */
|
|
/*----------------------------------------------------------------------------
|
|
%%Function: IncreaseWchMacBy2
|
|
%%Contact: sergeyge
|
|
|
|
----------------------------------------------------------------------------*/
|
|
LSERR IncreaseWchMacBy2(PLNOBJ plnobj)
|
|
{
|
|
LSERR lserr;
|
|
long cwch;
|
|
|
|
lserr = CheckReallocCharArrays(plnobj, 2, plnobj->pilsobj->wchMac, &cwch);
|
|
if (lserr != lserrNone) return lserr;
|
|
|
|
Assert(cwch <= 2 && cwch > 0);
|
|
|
|
if (cwch == 1)
|
|
{
|
|
lserr = CheckReallocCharArrays(plnobj, 1, plnobj->pilsobj->wchMac + 1, &cwch);
|
|
if (lserr != lserrNone) return lserr;
|
|
Assert(cwch == 1);
|
|
}
|
|
|
|
plnobj->pilsobj->wchMac += 2;
|
|
|
|
return lserrNone;
|
|
}
|
|
|
|
/* Internal Functions Implementation */
|
|
|
|
|
|
/* C H E C K R E A L L O C C H A R A R R A Y S */
|
|
/*----------------------------------------------------------------------------
|
|
%%Function: ReallocCharArrays
|
|
%%Contact: sergeyge
|
|
|
|
Reallocates character based arrays, increasing them by delta
|
|
----------------------------------------------------------------------------*/
|
|
static LSERR CheckReallocCharArrays(PLNOBJ plnobj, long cwch, long iwchLocalStart, long *cwchCorrect)
|
|
{
|
|
PILSOBJ pilsobj;
|
|
WCHAR* pwch;
|
|
long* pdup;
|
|
long* pdur;
|
|
GMAP* pgmap;
|
|
TXTINF* ptxtinf;
|
|
long delta;
|
|
|
|
pilsobj = plnobj->pilsobj;
|
|
|
|
/* pdupPen was made equal to pdup at the CreateLnObj time;
|
|
it can be changed to pdupPenAlloc at Adjust time only */
|
|
Assert(plnobj->pdup == plnobj->pdupPen);
|
|
|
|
/* Constant 2 is not random. We need to have 2 extra places for characters
|
|
for breaking with AutoHyphen and YSR which adds one charcter and hyphen.
|
|
*/
|
|
if (iwchLocalStart + cwch <= (long)pilsobj->wchMax - 2)
|
|
{
|
|
*cwchCorrect = cwch;
|
|
}
|
|
else if (iwchLocalStart < (long)pilsobj->wchMax - 2)
|
|
{
|
|
*cwchCorrect = pilsobj->wchMax - 2 - iwchLocalStart;
|
|
}
|
|
else
|
|
{
|
|
Assert (iwchLocalStart == (long)pilsobj->wchMax - 2);
|
|
|
|
delta = wchAddM;
|
|
|
|
pwch = (*pilsobj->plscbk->pfnReallocPtr)(pilsobj->pols, pilsobj->pwchOrig, (pilsobj->wchMax + delta) * sizeof(WCHAR) );
|
|
if (pwch == NULL)
|
|
{
|
|
return lserrOutOfMemory;
|
|
}
|
|
pilsobj->pwchOrig = pwch;
|
|
|
|
pwch = (*pilsobj->plscbk->pfnReallocPtr)(pilsobj->pols, plnobj->pwch, (pilsobj->wchMax + delta) * sizeof(WCHAR) );
|
|
if (pwch == NULL)
|
|
{
|
|
return lserrOutOfMemory;
|
|
}
|
|
plnobj->pwch = pwch;
|
|
|
|
pdur = (*pilsobj->plscbk->pfnReallocPtr)(pilsobj->pols, pilsobj->pdur, (pilsobj->wchMax + delta) * sizeof(long) );
|
|
if (pdur == NULL)
|
|
{
|
|
return lserrOutOfMemory;
|
|
}
|
|
pilsobj->pdur = pdur;
|
|
|
|
pdup = (*pilsobj->plscbk->pfnReallocPtr)(pilsobj->pols, plnobj->pdup, (pilsobj->wchMax + delta) * sizeof(long) );
|
|
if (pdup == NULL)
|
|
{
|
|
return lserrOutOfMemory;
|
|
}
|
|
plnobj->pdup = pdup;
|
|
|
|
if (plnobj->pdupPenAlloc != NULL)
|
|
{
|
|
pdup = (*pilsobj->plscbk->pfnReallocPtr)(pilsobj->pols, plnobj->pdupPenAlloc, (pilsobj->wchMax + delta) * sizeof(long) );
|
|
if (pdup == NULL)
|
|
{
|
|
return lserrOutOfMemory;
|
|
}
|
|
plnobj->pdupPenAlloc = pdup;
|
|
}
|
|
|
|
if (plnobj->pgmap != NULL)
|
|
{
|
|
pgmap = (*pilsobj->plscbk->pfnReallocPtr)(pilsobj->pols, plnobj->pgmap, (pilsobj->wchMax + delta) * sizeof(GMAP) );
|
|
if (pgmap == NULL)
|
|
{
|
|
return lserrOutOfMemory;
|
|
}
|
|
plnobj->pgmap = pgmap;
|
|
}
|
|
|
|
if (pilsobj->pdurLeft != NULL)
|
|
{
|
|
pdur = (*pilsobj->plscbk->pfnReallocPtr)(pilsobj->pols, pilsobj->pdurLeft, (pilsobj->wchMax + delta) * sizeof(long) );
|
|
if (pdur == NULL)
|
|
{
|
|
return lserrOutOfMemory;
|
|
}
|
|
pilsobj->pdurLeft = pdur;
|
|
memset(&pilsobj->pdurLeft[pilsobj->wchMax], 0, sizeof(long) * delta );
|
|
}
|
|
|
|
if (pilsobj->pdurRight != NULL)
|
|
{
|
|
pdur = (*pilsobj->plscbk->pfnReallocPtr)(pilsobj->pols, pilsobj->pdurRight, (pilsobj->wchMax + delta) * sizeof(long) );
|
|
if (pdur == NULL)
|
|
{
|
|
return lserrOutOfMemory;
|
|
}
|
|
pilsobj->pdurRight = pdur;
|
|
memset(&pilsobj->pdurRight[pilsobj->wchMax], 0, sizeof(long) * delta);
|
|
}
|
|
|
|
if (pilsobj->pduAdjust != NULL)
|
|
{
|
|
pdur = (*pilsobj->plscbk->pfnReallocPtr)(pilsobj->pols, pilsobj->pduAdjust, (pilsobj->wchMax + delta) * sizeof(long) );
|
|
if (pdur == NULL)
|
|
{
|
|
return lserrOutOfMemory;
|
|
}
|
|
pilsobj->pduAdjust = pdur;
|
|
}
|
|
|
|
if (pilsobj->ptxtinf != NULL)
|
|
{
|
|
ptxtinf = (*pilsobj->plscbk->pfnReallocPtr)(pilsobj->pols, pilsobj->ptxtinf, (pilsobj->wchMax + delta) * sizeof(TXTINF) );
|
|
if (ptxtinf == NULL)
|
|
{
|
|
return lserrOutOfMemory;
|
|
}
|
|
pilsobj->ptxtinf = ptxtinf;
|
|
memset(&pilsobj->ptxtinf[pilsobj->wchMax], 0, sizeof(TXTINF) * delta);
|
|
}
|
|
|
|
pilsobj->wchMax += delta;
|
|
plnobj->wchMax = pilsobj->wchMax;
|
|
|
|
*cwchCorrect = delta;
|
|
if (cwch < delta)
|
|
*cwchCorrect = cwch;
|
|
}
|
|
|
|
/* see comment and Assert at the beginning of the file */
|
|
plnobj->pdupPen = plnobj->pdup;
|
|
|
|
return lserrNone;
|
|
|
|
}
|
|
|
|
|
|
/* C H E C K R E A L L O C S P A C E S A R R A Y S */
|
|
/*----------------------------------------------------------------------------
|
|
%%Function: CheckReallocSpacesArrays
|
|
%%Contact: sergeyge
|
|
|
|
Checks that there is enough space wSpaces
|
|
to accomodate characters & spaces from the current local run.
|
|
Reallocates these arrays if it is needed.
|
|
----------------------------------------------------------------------------*/
|
|
static LSERR CheckReallocSpacesArrays(PILSOBJ pilsobj, long cwSpaces)
|
|
{
|
|
long iwSpacesLocalStart;
|
|
long delta;
|
|
long* pwSpaces;
|
|
|
|
iwSpacesLocalStart = pilsobj->wSpacesMac;
|
|
|
|
/* check that there is enough space for spaces in pwSpaces */
|
|
if (iwSpacesLocalStart + cwSpaces > pilsobj->wSpacesMax)
|
|
{
|
|
delta = wchAddM;
|
|
if (delta < iwSpacesLocalStart + cwSpaces - pilsobj->wSpacesMax)
|
|
{
|
|
delta = iwSpacesLocalStart + cwSpaces - pilsobj->wSpacesMax;
|
|
}
|
|
pwSpaces = (*pilsobj->plscbk->pfnReallocPtr)(pilsobj->pols, pilsobj->pwSpaces, (pilsobj->wSpacesMax + delta) * sizeof(long) );
|
|
if (pwSpaces == NULL)
|
|
{
|
|
return lserrOutOfMemory;
|
|
}
|
|
pilsobj->pwSpaces = pwSpaces;
|
|
pilsobj->wSpacesMax += delta;
|
|
}
|
|
|
|
return lserrNone;
|
|
}
|
|
|
|
/* C O P Y C H A R S S P A C E S T O D I S P L I S T */
|
|
/*----------------------------------------------------------------------------
|
|
%%Function: CopyCharsSpacesToDispList
|
|
%%Contact: sergeyge
|
|
|
|
Fills wch, dur and wSpaces arrays
|
|
----------------------------------------------------------------------------*/
|
|
static LSERR CopyCharsSpacesToDispList(PLNOBJ plnobj, WCHAR* rgwch, long cwch,
|
|
long* rgwSpaces, long cwSpaces)
|
|
{
|
|
LSERR lserr;
|
|
PILSOBJ pilsobj;
|
|
long iwchLocalStart;
|
|
long iwSpacesLocalStart;
|
|
long i;
|
|
|
|
pilsobj = plnobj->pilsobj;
|
|
iwchLocalStart = pilsobj->wchMac;
|
|
iwSpacesLocalStart = pilsobj->wSpacesMac;
|
|
|
|
/* check that there is enough space for characters and their widths in pwch and pdup arrays */
|
|
lserr = CheckReallocSpacesArrays(pilsobj, cwSpaces);
|
|
if (lserr != lserrNone) return lserr;
|
|
|
|
/* fill pwch array */
|
|
memcpy(&pilsobj->pwchOrig[iwchLocalStart], rgwch, sizeof(rgwch[0]) * cwch);
|
|
memcpy(&plnobj->pwch[iwchLocalStart], rgwch, sizeof(rgwch[0]) * cwch);
|
|
pilsobj->wchMac += cwch;
|
|
|
|
/* fill pwSpaces array, note that spaces with idexes greater than cwch should not be copied */
|
|
for (i=0; i < cwSpaces && rgwSpaces[i] < cwch; i++)
|
|
{
|
|
pilsobj->pwSpaces[iwSpacesLocalStart + i] = iwchLocalStart + rgwSpaces[i];
|
|
}
|
|
|
|
pilsobj->wSpacesMac += i;
|
|
|
|
return lserrNone;
|
|
}
|
|
|
|
|
|
/* C O P Y S P A C E S T O D I S P L I S T */
|
|
/*----------------------------------------------------------------------------
|
|
%%Function: CopyTrailingSpacesToDispList
|
|
%%Contact: sergeyge
|
|
|
|
Fills wch, dur, dup, wSpaces arrays with the trailing spaces info
|
|
----------------------------------------------------------------------------*/
|
|
static LSERR CopySpacesToDispList(PLNOBJ plnobj, long iNumOfSpaces, long durSpace)
|
|
{
|
|
LSERR lserr;
|
|
PILSOBJ pilsobj;
|
|
long iwchLocalStart;
|
|
long iwSpacesLocalStart;
|
|
long i;
|
|
long cwch;
|
|
long iwchStartCheck;
|
|
long cwchCorrect;
|
|
|
|
pilsobj = plnobj->pilsobj;
|
|
iwchLocalStart = pilsobj->wchMac;
|
|
iwSpacesLocalStart = pilsobj->wSpacesMac;
|
|
|
|
cwch = iNumOfSpaces;
|
|
iwchStartCheck = iwchLocalStart;
|
|
|
|
while (cwch > 0)
|
|
{
|
|
lserr = CheckReallocCharArrays(plnobj, cwch, iwchStartCheck, &cwchCorrect);
|
|
if (lserr != lserrNone) return lserr;
|
|
|
|
iwchStartCheck += cwchCorrect;
|
|
cwch -= cwchCorrect;
|
|
}
|
|
|
|
lserr = CheckReallocSpacesArrays(pilsobj, iNumOfSpaces);
|
|
if (lserr != lserrNone) return lserr;
|
|
|
|
for (i=0; i < iNumOfSpaces; i++)
|
|
{
|
|
plnobj->pwch[iwchLocalStart + i] = pilsobj->wchSpace;
|
|
pilsobj->pwchOrig[iwchLocalStart + i] = pilsobj->wchSpace;
|
|
pilsobj->pdur[iwchLocalStart + i] = durSpace;
|
|
pilsobj->pwSpaces[iwSpacesLocalStart + i] = iwchLocalStart + i;
|
|
}
|
|
|
|
pilsobj->wchMac += iNumOfSpaces;
|
|
pilsobj->wSpacesMac += iNumOfSpaces;
|
|
|
|
return lserrNone;
|
|
}
|
|
|
|
/* F L A S H S T R I N G S T A T E */
|
|
/*----------------------------------------------------------------------------
|
|
%%Function: FlashStringState
|
|
%%Contact: sergeyge
|
|
|
|
----------------------------------------------------------------------------*/
|
|
void FlushStringState(PILSOBJ pilsobj)
|
|
{
|
|
pilsobj->iwchFetchedWidth = 0;
|
|
pilsobj->cpFirstFetchedWidth = 0;
|
|
pilsobj->dcpFetchedWidth = 0;
|
|
pilsobj->durFetchedWidth = 0;
|
|
}
|
|
|