WindowsXP-SP1/windows/richedit/lssrc/ntiman.c
2020-09-30 16:53:49 +02:00

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;
}