|
|
#include "lsdnset.h"
#include "lsc.h"
#include "lsdnode.h"
#include "dnutils.h"
#include "iobj.h"
#include "ntiman.h"
#include "tabutils.h"
#include "getfmtst.h"
#include "setfmtst.h"
#include "lstext.h"
#include "dninfo.h"
#include "chnutils.h"
#include "lssubl.h"
#include "sublutil.h"
#include "lscfmtfl.h"
#include "iobjln.h"
#include "lsmem.h" /* memset() */
#define FColinearTflows(t1, t2) \
(((t1) & fUVertical) == ((t2) & fUVertical))
/* L S D N Q U E R Y O B J D I M R A N G E */ /*----------------------------------------------------------------------------
%%Function: LsdnQueryObjDimRange %%Contact: igorzv Parameters: plsc - (IN) ptr to line services context plsdnFirst - (IN) first dnode in the range plsdnLast - (IN) last dnode in the range pobjdim - (OUT) geometry of the range
----------------------------------------------------------------------------*/
LSERR WINAPI LsdnQueryObjDimRange(PLSC plsc, PLSDNODE plsdnFirst, PLSDNODE plsdnLast, POBJDIM pobjdim) { PLSDNODE plsdn; LSERR lserr;
if (pobjdim == NULL) return lserrNullOutputParameter;
if (!FIsLSC(plsc)) return lserrInvalidContext;
/* if client call us with empty range return right away */ if (plsdnFirst == NULL) { if (plsdnLast != NULL) return lserrInvalidDnode; memset(pobjdim, 0, sizeof(OBJDIM)); return lserrNone; }
if (!FIsLSDNODE(plsdnFirst)) return lserrInvalidDnode; if (!FIsLSDNODE(plsdnLast)) return lserrInvalidDnode; if (plsdnFirst->plssubl != plsdnLast->plssubl) return lserrInvalidDnode;
/* we should call NominalToIdeal if we are in formating stage and range intersects last chunk
and this chunk is chunk of text*/ plsdn = plsdnLast; /* to find chunk where we are we should skip back borders */ while (plsdn != NULL && FIsDnodeBorder(plsdn)) { plsdn = plsdn->plsdnPrev; }
if ((plsc->lsstate == LsStateFormatting) && FNominalToIdealEncounted(plsc) && (plsdn != NULL) && FIsDnodeReal(plsdn) && (IdObjFromDnode(plsdn) == IobjTextFromLsc(&plsc->lsiobjcontext)) ) { for(; !FIsChunkBoundary(plsdn->plsdnNext, IobjTextFromLsc(&plsc->lsiobjcontext), plsdnLast->cpFirst); plsdn=plsdn->plsdnNext); if (plsdn->plsdnNext == NULL) { lserr = ApplyNominalToIdeal(PlschunkcontextFromSubline(plsdnFirst->plssubl), &plsc->lsiobjcontext, plsc->grpfManager, plsc->lsadjustcontext.lskj, FIsSubLineMain(SublineFromDnode(plsdn)), FLineContainsAutoNumber(plsc), plsdn); if (lserr != lserrNone) return lserr; } }
return FindListDims(plsdnFirst, plsdnLast, pobjdim);
}
/* L S D N G E T C U R T A B I N F O */ /*----------------------------------------------------------------------------
%%Function: LsdnGetCurTabInfo %%Contact: igorzv Parameters: plsc - (IN) ptr to line services context plsktab - (OUT) type of current tab
Finds tab stop nearest to the current pen position and returns type of such tab stop. ----------------------------------------------------------------------------*/
LSERR WINAPI LsdnGetCurTabInfo(PLSC plsc, LSKTAB* plsktab) { PLSDNODE plsdnTab; LSTABSCONTEXT* plstabscontext; BOOL fBreakThroughTab; LSERR lserr; long urNewMargin; if (!FIsLSC(plsc)) return lserrInvalidParameter;
if (!FFormattingAllowed(plsc)) return lserrFormattingFunctionDisabled;
if (plsktab == NULL) return lserrInvalidParameter;
plsdnTab = GetCurrentDnode(plsc); plstabscontext = &(plsc->lstabscontext);
Assert(FIsLSDNODE(plsdnTab)); if (!plsdnTab->fTab) return lserrCurrentDnodeIsNotTab; Assert(FIsDnodeReal(plsdnTab));
if (plstabscontext->plsdnPendingTab != NULL) return lserrPendingTabIsNotResolved;
lserr = GetCurTabInfoCore(&plsc->lstabscontext, plsdnTab, GetCurrentUr(plsc), fFalse, plsktab, &fBreakThroughTab); if (lserr != lserrNone) return lserr;
TurnOnTabEncounted(plsc); if (*plsktab != lsktLeft) TurnOnNonLeftTabEncounted(plsc);
/* move current pen position */ AdvanceCurrentUr(plsc, DurFromDnode(plsdnTab));
if (fBreakThroughTab) { lserr = GetMarginAfterBreakThroughTab(&plsc->lstabscontext, plsdnTab, &urNewMargin); if (lserr != lserrNone) return lserr;
SetBreakthroughLine(plsc, urNewMargin); }
return lserrNone;
}
/* L S D N R E S O L V E P R E V T A B */ /*----------------------------------------------------------------------------
%%Function: LsdnResolvePrevTab %%Contact: igorzv Parameters: plsc - (IN) ptr to line services context
----------------------------------------------------------------------------*/
LSERR WINAPI LsdnResolvePrevTab(PLSC plsc) { long dur; LSERR lserr;
if (!FIsLSC(plsc)) return lserrInvalidParameter;
if (!FFormattingAllowed(plsc)) return lserrFormattingFunctionDisabled;
lserr = ResolvePrevTabCore(&plsc->lstabscontext, GetCurrentDnode(plsc), GetCurrentUr(plsc), &dur); if (lserr != lserrNone) return lserr;
AdvanceCurrentUr(plsc, dur);
return lserrNone;
}
/* L S D N S K I P C U R T A B */ /*----------------------------------------------------------------------------
%%Function: LsdnSkipCurTab %%Contact: igorzv Parameters: plsc - (IN) ptr to line services context
----------------------------------------------------------------------------*/
LSERR WINAPI LsdnSkipCurTab(PLSC plsc) /* IN: Pointer to LS Context */ {
PLSDNODE plsdnTab; LSTABSCONTEXT* plstabscontext;
if (!FIsLSC(plsc)) return lserrInvalidParameter;
if (!FFormattingAllowed(plsc)) return lserrFormattingFunctionDisabled;
plsdnTab = GetCurrentDnode(plsc); plstabscontext = &(plsc->lstabscontext);
Assert(FIsLSDNODE(plsdnTab)); if (!plsdnTab->fTab) return lserrCurrentDnodeIsNotTab; Assert(FIsDnodeReal(plsdnTab));
if (plstabscontext->plsdnPendingTab != NULL) { CancelPendingTab(&plsc->lstabscontext); } else { AdvanceCurrentUr(plsc, - plsdnTab->u.real.objdim.dur); SetDnodeDurFmt(plsdnTab, 0); }
return lserrNone; }
/* L S D N S E T R I G I D D U P */ /*----------------------------------------------------------------------------
%%Function: LsdnSetRigidDup %%Contact: igorzv Parameters: plsc - (IN) ptr to line services context plsdn - (IN) dnode to be modified dup - (IN) dup to put in the dnode
----------------------------------------------------------------------------*/
LSERR WINAPI LsdnSetRigidDup(PLSC plsc, PLSDNODE plsdn, long dup) {
if (!FIsLSC(plsc)) return lserrInvalidParameter;
if (!FIsLSDNODE(plsdn)) return lserrInvalidParameter;
if (!FFormattingAllowed(plsc)) return lserrFormattingFunctionDisabled;
plsdn->fRigidDup = fTrue;
if (plsdn->klsdn == klsdnReal) { plsdn->u.real.dup = dup; } else { plsdn->u.pen.dup = dup; }
return lserrNone; }
/* L S D N G E T D U P */ /*----------------------------------------------------------------------------
%%Function: LsdnGetDup %%Contact: igorzv Parameters: plsc - (IN) ptr to line services context plsdn - (IN) dnode queried dup - (OUT) dup of this dnode
----------------------------------------------------------------------------*/ LSERR WINAPI LsdnGetDup(PLSC plsc, PLSDNODE plsdn, long* pdup) {
if (!FIsLSC(plsc)) return lserrInvalidParameter;
if (!FIsLSDNODE(plsdn)) return lserrInvalidParameter;
/* check that dup in dnode is valid */
if (plsdn->plssubl->fDupInvalid && !plsdn->fRigidDup) return lserrDupInvalid;
*pdup = DupFromDnode(plsdn);
return lserrNone; }
/* L S D N R E S E T O B J D I M */ /*----------------------------------------------------------------------------
%%Function: LsdnResetObjDim %%Contact: igorzv Parameters: plsc - (IN) ptr to line services context plsdn - (IN) dnode to be modified pobjdimNew - (IN) new dimensions of the dnode
----------------------------------------------------------------------------*/
LSERR WINAPI LsdnResetObjDim(PLSC plsc, PLSDNODE plsdn, PCOBJDIM pobjdimNew)
{ long durOld;
if (!FIsLSC(plsc)) return lserrInvalidParameter; if (!FIsLSDNODE(plsdn)) return lserrInvalidParameter; if (!FIsDnodeReal(plsdn)) return lserrInvalidParameter;
/* we should be in the stage of formatting or breaking */ if (!FFormattingAllowed(plsc) && !FBreakingAllowed(plsc)) return lserrFormattingFunctionDisabled;
durOld = plsdn->u.real.objdim.dur; SetDnodeObjdimFmt(plsdn, *pobjdimNew);
/* update current pen position */ AdvanceCurrentUrSubl(plsdn->plssubl, (plsdn->u.real.objdim.dur - durOld));
return lserrNone; }
/* L S D N R E S E T P E N N O D E */ /*----------------------------------------------------------------------------
%%Function: LsdnResetPenNode %%Contact: igorzv Parameters: plsc - (IN) ptr to line services context plsdnPen - (IN) dnode to be modified dvpPen - (IN) new dvp of the dnode durPen - (IN) new dur of the dnode dvrPen - (IN) new dvr of the dnode
----------------------------------------------------------------------------*/
LSERR WINAPI LsdnResetPenNode(PLSC plsc, PLSDNODE plsdnPen, long dvpPen, long durPen, long dvrPen)
{ long durOld; long dvrOld;
if (!FIsLSC(plsc)) return lserrInvalidParameter; if (!FIsLSDNODE(plsdnPen)) return lserrInvalidParameter; if (!FIsDnodePen(plsdnPen)) return lserrInvalidParameter;
/* we should be in the stage of formatting */ if (!FFormattingAllowed(plsc)) return lserrFormattingFunctionDisabled; if (GetDnodeToFinish(plsc) == NULL) return lserrFormattingFunctionDisabled; if (!FIsDnodeReal(GetDnodeToFinish(plsc)) ) return lserrFormattingFunctionDisabled; if (plsdnPen->plssubl != GetCurrentSubline(plsc)) return lserrInvalidParameter;
durOld = plsdnPen->u.pen.dur; dvrOld = plsdnPen->u.pen.dvr;
plsdnPen->u.pen.dvp = dvpPen; SetPenBorderDurFmt(plsdnPen, durPen); plsdnPen->u.pen.dvr = dvrPen;
/* update current pen position */ AdvanceCurrentUr(plsc, plsdnPen->u.pen.dur - durOld); AdvanceCurrentVr(plsc, plsdnPen->u.pen.dvr - dvrOld);
return lserrNone; }
/* L S D N Q U E R Y N O D E */ /*----------------------------------------------------------------------------
%%Function: LsdnQueryPenNode %%Contact: igorzv Parameters: plsc - (IN) ptr to line services context plsdnPen - (IN) dnode quried pdvpPen - (OUT) dvp of the dnode pdurPen - (OUT) dur of the dnode pdvrPen - (OUT) dvr of the dnode
----------------------------------------------------------------------------*/
LSERR WINAPI LsdnQueryPenNode(PLSC plsc, PLSDNODE plsdnPen, long* pdvpPen, long* pdurPen, long* pdvrPen)
{
if (!FIsLSC(plsc)) return lserrInvalidParameter; if (!FIsLSDNODE(plsdnPen)) return lserrInvalidParameter; if (!FIsDnodePen(plsdnPen)) return lserrInvalidParameter;
*pdvpPen = plsdnPen->u.pen.dvp; *pdurPen = plsdnPen->u.pen.dur; *pdvrPen = plsdnPen->u.pen.dvr;
return lserrNone; }
/* L S D N S E T A B S B A S E L I N E */ /*----------------------------------------------------------------------------
%%Function: LsdnSetAbsBaseLine %%Contact: igorzv Parameters: plsc - (IN) ptr to line services context vaAdvanceNew - (IN) new vaBase
----------------------------------------------------------------------------*/
LSERR WINAPI LsdnSetAbsBaseLine(PLSC plsc, long vaAdvanceNew) {
if (!FIsLSC(plsc)) return lserrInvalidParameter;
/* we should be in the stage of formatting*/ if (!FFormattingAllowed(plsc)) return lserrFormattingFunctionDisabled; plsc->plslineCur->lslinfo.fAdvanced = fTrue; plsc->plslineCur->lslinfo.vaAdvance = vaAdvanceNew;
return lserrNone; }
#define PlnobjFromLsc(plsc,iobj) ((Assert(FIsLSC(plsc)), PlnobjFromLsline((plsc)->plslineCur,iobj)))
/* L S D N M O D I F Y P A R A E N D I N G*/ /*----------------------------------------------------------------------------
%%Function: LsdnModifyParaEnding %%Contact: igorzv Parameters: plsc - (IN) ptr to line services context lskeop - (IN) Kind of line ending
----------------------------------------------------------------------------*/ LSERR WINAPI LsdnModifyParaEnding(PLSC plsc, LSKEOP lskeop) { LSERR lserr; DWORD iobjText; PLNOBJ plnobjText;
if (!FIsLSC(plsc)) return lserrInvalidParameter;
/* we should be in the stage of formatting*/ if (!FFormattingAllowed(plsc)) return lserrFormattingFunctionDisabled; iobjText = IobjTextFromLsc(&plsc->lsiobjcontext); plnobjText = PlnobjFromLsc(plsc, iobjText);
lserr = ModifyTextLineEnding(plnobjText, lskeop);
return lserr; }
/* L S D N D I S T R I B U T E */ /*----------------------------------------------------------------------------
%%Function: LsdnDistribute %%Contact: igorzv Parameters: plsc - (IN) ptr to line services context plsdnFirst - (IN) first dnode in the range plsdnFirst - (IN) last dnode in the range durToDistribute - (IN) amount to distribute between dnodes
----------------------------------------------------------------------------*/
LSERR WINAPI LsdnDistribute(PLSC plsc, PLSDNODE plsdnFirst, PLSDNODE plsdnLast, long durToDistribute)
{ GRCHUNKEXT grchunkext; LSERR lserr; long durToNonText; if (!FIsLSC(plsc)) return lserrInvalidParameter; if (!FIsLSDNODE(plsdnFirst)) return lserrInvalidParameter; if (!FIsLSDNODE(plsdnLast)) return lserrInvalidParameter;
/* we should be in the stage of formatting or breaking*/ if (!FFormattingAllowed(plsc) && !FBreakingAllowed(plsc)) return lserrFormattingFunctionDisabled;
InitGroupChunkExt(PlschunkcontextFromSubline(plsdnFirst->plssubl), IobjTextFromLsc(&plsc->lsiobjcontext), &grchunkext);
/* skip first pen dnodes */
while (FIsDnodePen(plsdnFirst) && (plsdnFirst != plsdnLast)) { plsdnFirst = plsdnFirst->plsdnNext; if (plsdnFirst == NULL) /* plsdnFirst and plksdnLast are not in the same level */ return lserrInvalidParameter; }
if (FIsDnodePen(plsdnFirst)) /* only pens are in the list so there is no business for us */ return lserrNone;
while (FIsDnodePen(plsdnLast) && (plsdnLast != plsdnFirst)) { plsdnLast = plsdnLast->plsdnPrev; if (plsdnLast == NULL) /* plsdnFirst and plksdnLast are not in the same level */ return lserrInvalidParameter; }
Assert(!FIsDnodePen(plsdnLast));
lserr = CollectTextGroupChunk(plsdnFirst, plsdnLast->cpFirst + plsdnLast->dcp, CollectSublinesNone, &grchunkext); if (lserr != lserrNone) return lserr;
/* Because of rigid dup it doesn't make sense to change dur of non text objects
We inforce text to distrubute everything among text by setting amount of non text to 0 */
return DistributeInText(&(grchunkext.lsgrchnk), LstflowFromSubline(SublineFromDnode(plsdnFirst)), 0, durToDistribute, &durToNonText);
}
/* L S D N S U B M I T S U B L I N E S */ /*----------------------------------------------------------------------------
%%Function: LsdnSubmitSublines %%Contact: igorzv Parameters: plsc - (IN) ptr to line services context plsdnode - (IN) dnode cSubline - (IN) amount of submitted sublines rgpsubl - (IN) array of submitted sublines fUseForJustification - (IN) to use for justification fUseForCompression - (IN) to use for compression fUseForDisplay - (IN) to use for display fUseForDecimalTab - (IN) to use for decimal tab fUseForTrailingArea - (IN) to use for calculating trailing area
----------------------------------------------------------------------------*/
LSERR WINAPI LsdnSubmitSublines(PLSC plsc, PLSDNODE plsdnode, DWORD cSubline, PLSSUBL* rgpsubl, BOOL fUseForJustification, BOOL fUseForCompression, BOOL fUseForDisplay, BOOL fUseForDecimalTab, BOOL fUseForTrailingArea) { DWORD i; BOOL fEmpty = fFalse; BOOL fEmptyWork; BOOL fTabOrPen = fFalse; BOOL fNotColinearTflow = fFalse; BOOL fNotSameTflow = fFalse; LSERR lserr; if (!FIsLSC(plsc)) return lserrInvalidParameter; if (!FIsLSDNODE(plsdnode)) return lserrInvalidParameter; if (!FIsDnodeReal(plsdnode)) return lserrInvalidParameter;
/* we should be in the stage of formatting or breaking*/ if (!FFormattingAllowed(plsc) && !FBreakingAllowed(plsc)) return lserrFormattingFunctionDisabled;
/* this procedure can be called many times for the same dnode, so
we should dispose memory allocated in previous call */ if (plsdnode->u.real.pinfosubl != NULL) { if (plsdnode->u.real.pinfosubl->rgpsubl != NULL) { plsc->lscbk.pfnDisposePtr(plsc->pols, plsdnode->u.real.pinfosubl->rgpsubl); }
plsc->lscbk.pfnDisposePtr(plsc->pols, plsdnode->u.real.pinfosubl); plsdnode->u.real.pinfosubl = NULL; }
/* if nothing submitted return right away */ if (cSubline == 0) return lserrNone;
TurnOnSubmittedSublineEncounted(plsc);
/* calculate some properties of sublines to decide accept or not */ for (i = 0; i < cSubline; i++) { if (rgpsubl[i] == NULL) return lserrInvalidParameter; if (!FIsLSSUBL(rgpsubl[i])) return lserrInvalidParameter;
lserr = FIsSublineEmpty(rgpsubl[i], &fEmptyWork); if (lserr != lserrNone) return lserr; if (fEmptyWork) fEmpty = fTrue;
if (FAreTabsPensInSubline(rgpsubl[i])) fTabOrPen = fTrue;
if (LstflowFromSubline(SublineFromDnode(plsdnode)) != LstflowFromSubline(rgpsubl[i])) fNotSameTflow = fTrue; if (!FColinearTflows(LstflowFromSubline(SublineFromDnode(plsdnode)), LstflowFromSubline(rgpsubl[i]))) fNotColinearTflow = fTrue; }
plsdnode->u.real.pinfosubl = plsc->lscbk.pfnNewPtr(plsc->pols, sizeof(*(plsdnode->u.real.pinfosubl)));
if (plsdnode->u.real.pinfosubl == NULL) return lserrOutOfMemory;
plsdnode->u.real.pinfosubl->cSubline = cSubline; plsdnode->u.real.pinfosubl->rgpsubl = plsc->lscbk.pfnNewPtr(plsc->pols, sizeof(PLSSUBL) * cSubline); if (plsdnode->u.real.pinfosubl->rgpsubl == NULL) return lserrOutOfMemory;
/* copy array of sublines */ for (i = 0; i < cSubline; i++) { plsdnode->u.real.pinfosubl->rgpsubl[i] = rgpsubl[i]; }
/* set flags */ plsdnode->u.real.pinfosubl->fUseForJustification = fUseForJustification && !fEmpty && !fTabOrPen && !fNotColinearTflow ; plsdnode->u.real.pinfosubl->fUseForCompression = fUseForCompression && plsdnode->u.real.pinfosubl->fUseForJustification; /* if subline is submitted for compression it should also submitted for justification */ plsdnode->u.real.pinfosubl->fUseForTrailingArea = fUseForTrailingArea && plsdnode->u.real.pinfosubl->fUseForCompression; /* if subline is submitted for trailing area it should also be submitted for compression
which implies submitting for justification */ plsdnode->u.real.pinfosubl->fUseForDisplay = fUseForDisplay && !fEmpty && !(plsc->grpfManager & fFmiDrawInCharCodes); plsdnode->u.real.pinfosubl->fUseForDecimalTab = fUseForDecimalTab && !fEmpty && !fTabOrPen;
return lserrNone; }
/* L S D N G E T F O R M A T D E P T H */ /*----------------------------------------------------------------------------
%%Function: LsdnGetFormatDepth %%Contact: igorzv Parameters: plsc - (IN) ptr to line services context pnDepthFormatLineMax - (OUT) maximum depth of sublines
----------------------------------------------------------------------------*/
LSERR WINAPI LsdnGetFormatDepth( PLSC plsc, /* IN: Pointer to LS Context */ DWORD* pnDepthFormatLineMax) /* OUT: nDepthFormatLineMax */ { if (!FIsLSC(plsc)) return lserrInvalidParameter;
/* we should be in the stage of formatting or breaking*/ if (!FFormattingAllowed(plsc) && !FBreakingAllowed(plsc)) return lserrFormattingFunctionDisabled;
Assert(FWorkWithCurrentLine(plsc));
*pnDepthFormatLineMax = plsc->plslineCur->lslinfo.nDepthFormatLineMax;
return lserrNone; }
|