228 lines
6.7 KiB
C
228 lines
6.7 KiB
C
|
#include "ntiman.h"
|
||
|
#include "plschcon.h"
|
||
|
#include "lschcon.h"
|
||
|
#include "dninfo.h"
|
||
|
#include "iobj.h"
|
||
|
#include "chnutils.h"
|
||
|
#include "lstext.h"
|
||
|
#include "lscfmtfl.h"
|
||
|
|
||
|
#define FNominalToIdealNeeded(plschnkcontext, grpf, lskjust) \
|
||
|
((plschnkcontext)->grpfTnti != 0) || \
|
||
|
FNominalToIdealBecauseOfParagraphProperties(grpf, lskjust)
|
||
|
|
||
|
|
||
|
LSERR ApplyNominalToIdeal(
|
||
|
PLSCHUNKCONTEXT plschunkcontext, /* LS chunk context */
|
||
|
PLSIOBJCONTEXT plsiobjcontext, /* installed objects */
|
||
|
DWORD grpf, /* grpf */
|
||
|
LSKJUST lskjust, /* kind of justification */
|
||
|
BOOL fIsSublineMain, /* fIsSubLineMain */
|
||
|
BOOL fLineContainsAutoNumber,
|
||
|
PLSDNODE plsdnLast) /* dnode until which we should do nominal to ideal */
|
||
|
{
|
||
|
LSERR lserr;
|
||
|
PLSDNODE plsdnPrev;
|
||
|
BOOL fSuccessful;
|
||
|
WCHAR wchar;
|
||
|
PLSRUN plsrunText;
|
||
|
HEIGHTS heightsText;
|
||
|
MWCLS mwcls;
|
||
|
DWORD iobj;
|
||
|
LSIMETHODS* plsim;
|
||
|
long durChange;
|
||
|
PLSDNODE plsdnLastContent;
|
||
|
|
||
|
|
||
|
|
||
|
plsdnLastContent = plsdnLast;
|
||
|
// skip borders
|
||
|
while(plsdnLastContent != NULL && FIsDnodeBorder(plsdnLastContent))
|
||
|
{
|
||
|
plsdnLastContent = plsdnLastContent->plsdnPrev;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* if there are now dnodes in line or nominal to ideal has been already applied
|
||
|
return right away */
|
||
|
if (plsdnLastContent == NULL || plschunkcontext->fNTIAppliedToLastChunk)
|
||
|
return lserrNone;
|
||
|
|
||
|
Assert(FIsLSDNODE(plsdnLastContent));
|
||
|
|
||
|
|
||
|
/*if last dnode text */
|
||
|
if (FIsDnodeReal(plsdnLastContent) && !(plsdnLastContent->fTab) &&
|
||
|
(IdObjFromDnode(plsdnLastContent) == IobjTextFromLsc(plsiobjcontext)))
|
||
|
{
|
||
|
|
||
|
lserr = FillChunkArray(plschunkcontext, plsdnLastContent);
|
||
|
if (lserr != lserrNone)
|
||
|
return lserr;
|
||
|
|
||
|
if (FNominalToIdealNeeded(plschunkcontext, grpf, lskjust))
|
||
|
{
|
||
|
lserr = NominalToIdealText(
|
||
|
plschunkcontext->grpfTnti,
|
||
|
LstflowFromDnode(plsdnLastContent),
|
||
|
(FIsFirstOnLine(plschunkcontext->pplsdnChunk[0]) && fIsSublineMain),
|
||
|
fLineContainsAutoNumber ,
|
||
|
plschunkcontext->locchnkCurrent.clschnk,
|
||
|
plschunkcontext->locchnkCurrent.plschnk);
|
||
|
if (lserr != lserrNone)
|
||
|
return lserr;
|
||
|
SetNTIAppliedToLastChunk(plschunkcontext);
|
||
|
|
||
|
/* apply width modification between preceding object and first text */
|
||
|
plsdnPrev = plschunkcontext->pplsdnChunk[0]->plsdnPrev;
|
||
|
if (plsdnPrev != NULL && FIsDnodeReal(plsdnPrev) && !plsdnPrev->fTab)
|
||
|
{
|
||
|
lserr = GetFirstCharInChunk(plschunkcontext->locchnkCurrent.clschnk,
|
||
|
plschunkcontext->locchnkCurrent.plschnk, &fSuccessful,
|
||
|
&wchar, &plsrunText, &heightsText, &mwcls);
|
||
|
if (lserr != lserrNone)
|
||
|
return lserr;
|
||
|
|
||
|
if (fSuccessful)
|
||
|
{
|
||
|
iobj = IdObjFromDnode(plsdnPrev);
|
||
|
plsim = PLsimFromLsc(plsiobjcontext, iobj);
|
||
|
if (plsim->pfnGetModWidthFollowingChar != NULL)
|
||
|
{
|
||
|
lserr = plsim->pfnGetModWidthFollowingChar(plsdnPrev->u.real.pdobj,
|
||
|
plsdnPrev->u.real.plsrun, plsrunText, &heightsText, wchar,
|
||
|
mwcls, &durChange);
|
||
|
if (lserr != lserrNone)
|
||
|
return lserr;
|
||
|
|
||
|
if (durChange != 0)
|
||
|
{
|
||
|
lserr = ModifyFirstCharInChunk(
|
||
|
plschunkcontext->locchnkCurrent.clschnk,
|
||
|
plschunkcontext->locchnkCurrent.plschnk,
|
||
|
durChange);
|
||
|
if (lserr != lserrNone)
|
||
|
return lserr;
|
||
|
}
|
||
|
} /* object has this method */
|
||
|
} /* call back from text was successful */
|
||
|
} /* there is non-text object before chunk of text */
|
||
|
} /* nominal to ideal is needed */
|
||
|
} /* last dnode text after autonumbering */
|
||
|
|
||
|
return lserrNone;
|
||
|
}
|
||
|
|
||
|
LSERR ApplyModWidthToPrecedingChar(
|
||
|
PLSCHUNKCONTEXT plschunkcontext, /* LS chunk context */
|
||
|
PLSIOBJCONTEXT plsiobjcontext, /* installed objects */
|
||
|
DWORD grpf, /* grpf */
|
||
|
LSKJUST lskjust, /* kind of justification */
|
||
|
PLSDNODE plsdnNonText) /* non-text dnode after text */
|
||
|
{
|
||
|
LSERR lserr;
|
||
|
BOOL fSuccessful;
|
||
|
WCHAR wchar;
|
||
|
PLSRUN plsrunText;
|
||
|
HEIGHTS heightsText;
|
||
|
MWCLS mwcls;
|
||
|
DWORD iobj;
|
||
|
LSIMETHODS* plsim;
|
||
|
long durChange;
|
||
|
PLSDNODE plsdnPrev;
|
||
|
|
||
|
Assert(FIsLSDNODE(plsdnNonText));
|
||
|
|
||
|
plsdnPrev = plsdnNonText->plsdnPrev;
|
||
|
|
||
|
/*if Prev dnode text */
|
||
|
if (plsdnPrev != NULL && FIsDnodeReal(plsdnPrev) && !(plsdnPrev->fTab) &&
|
||
|
(IdObjFromDnode(plsdnPrev) == IobjTextFromLsc(plsiobjcontext)))
|
||
|
{
|
||
|
|
||
|
if (plschunkcontext->FChunkValid)
|
||
|
{
|
||
|
/* chunk we have is exactly what we need */
|
||
|
Assert(plschunkcontext->locchnkCurrent.clschnk != 0);
|
||
|
Assert(!plschunkcontext->FGroupChunk);
|
||
|
Assert((plschunkcontext->pplsdnChunk[plschunkcontext->locchnkCurrent.clschnk - 1])
|
||
|
->plsdnNext == plsdnNonText);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lserr = FillChunkArray(plschunkcontext, plsdnPrev);
|
||
|
if (lserr != lserrNone)
|
||
|
return lserr;
|
||
|
}
|
||
|
|
||
|
if (FNominalToIdealNeeded(plschunkcontext, grpf, lskjust))
|
||
|
{
|
||
|
/* apply width modification between text and following object */
|
||
|
lserr = GetLastCharInChunk(plschunkcontext->locchnkCurrent.clschnk,
|
||
|
plschunkcontext->locchnkCurrent.plschnk, &fSuccessful,
|
||
|
&wchar, &plsrunText, &heightsText, &mwcls);
|
||
|
if (lserr != lserrNone)
|
||
|
return lserr;
|
||
|
|
||
|
if (fSuccessful)
|
||
|
{
|
||
|
iobj = IdObjFromDnode(plsdnNonText);
|
||
|
plsim = PLsimFromLsc(plsiobjcontext, iobj);
|
||
|
if (plsim->pfnGetModWidthPrecedingChar != NULL)
|
||
|
{
|
||
|
lserr = plsim->pfnGetModWidthPrecedingChar(plsdnNonText->u.real.pdobj,
|
||
|
plsdnNonText->u.real.plsrun, plsrunText, &heightsText, wchar,
|
||
|
mwcls, &durChange);
|
||
|
if (lserr != lserrNone)
|
||
|
return lserr;
|
||
|
|
||
|
if (durChange != 0)
|
||
|
{
|
||
|
lserr = ModifyLastCharInChunk(
|
||
|
plschunkcontext->locchnkCurrent.clschnk,
|
||
|
plschunkcontext->locchnkCurrent.plschnk,
|
||
|
durChange);
|
||
|
if (lserr != lserrNone)
|
||
|
return lserr;
|
||
|
}
|
||
|
} /* object has this method */
|
||
|
} /* call back from text was successful */
|
||
|
} /* nominal to ideal is needed */
|
||
|
} /* there is text before */
|
||
|
return lserrNone;
|
||
|
|
||
|
}
|
||
|
|
||
|
LSERR CutPossibleContextViolation(
|
||
|
PLSCHUNKCONTEXT plschunkcontext, /* LS chunk context */
|
||
|
PLSDNODE plsdnLast) /* last text dnode */
|
||
|
{
|
||
|
LSERR lserr;
|
||
|
|
||
|
Assert(FIsLSDNODE(plsdnLast));
|
||
|
|
||
|
|
||
|
if (plschunkcontext->FChunkValid)
|
||
|
{
|
||
|
/* chunk we have is exactly what we need */
|
||
|
Assert(plschunkcontext->locchnkCurrent.clschnk != 0);
|
||
|
Assert(!plschunkcontext->FGroupChunk);
|
||
|
Assert((plschunkcontext->pplsdnChunk[plschunkcontext->locchnkCurrent.clschnk - 1])
|
||
|
== plsdnLast);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lserr = FillChunkArray(plschunkcontext, plsdnLast);
|
||
|
if (lserr != lserrNone)
|
||
|
return lserr;
|
||
|
}
|
||
|
|
||
|
lserr = CutTextDobj(plschunkcontext->locchnkCurrent.clschnk,
|
||
|
plschunkcontext->locchnkCurrent.plschnk);
|
||
|
if (lserr != lserrNone)
|
||
|
return lserr;
|
||
|
|
||
|
|
||
|
return lserrNone;
|
||
|
|
||
|
}
|