#include "enumcore.h" #include "lsc.h" #include "lssubl.h" #include "heights.h" #include "lsdnode.h" #include "dninfo.h" #include "lstfset.h" static LSERR EnumerateDnode(PLSC plsc, PLSDNODE pdn, POINTUV pt, BOOL fReverse, BOOL fGeometry, const POINT* pptOrg); // %%Function: EnumSublineCore // %%Contact: victork // /* * Enumerates subline calling enumeration callback for pens, methods for objects. * Provides geometry information if needed (Prepdisp should be done already in this case.) * Notice that auto-decimal tab is enumerated as a tab before Prepdisp and as a pen after. */ LSERR EnumSublineCore(PLSSUBL plssubl, BOOL fReverse, BOOL fGeometry, const POINT* pptOrg, long upLeftIndent) { LSERR lserr; LSCP cpLim = plssubl->cpLimDisplay; PLSC plsc = plssubl->plsc; PLSDNODE pdn; POINTUV pt = {0,0}; // init'ed to get rid of assert. if (plssubl->plsdnFirst == NULL) { return lserrNone; // early exit for empty sublines } Assert(!fGeometry || plssubl->fDupInvalid == fFalse); if (fReverse) { pdn = plssubl->plsdnFirst; if (fGeometry) { pt.u = upLeftIndent; pt.v = 0; while (FDnodeBeforeCpLim(pdn, cpLim)) { if (pdn->klsdn == klsdnReal) { pt.u += pdn->u.real.dup; } else { pt.u += pdn->u.pen.dup; pt.v += pdn->u.pen.dvp; } pdn = pdn->plsdnNext; } } pdn = plssubl->plsdnLastDisplay; while (pdn != NULL) { if (fGeometry) { // pt is now after pdn, downdate it to point before if (pdn->klsdn == klsdnReal) { pt.u -= pdn->u.real.dup; } else { pt.u -= pdn->u.pen.dup; pt.v -= pdn->u.pen.dvp; } } lserr = EnumerateDnode(plsc, pdn, pt, fReverse, fGeometry, pptOrg); if (lserr != lserrNone) return lserr; pdn = pdn->plsdnPrev; } } else { pdn = plssubl->plsdnFirst; pt.u = upLeftIndent; pt.v = 0; while (FDnodeBeforeCpLim(pdn, cpLim)) { lserr = EnumerateDnode(plsc, pdn, pt, fReverse, fGeometry, pptOrg); if (lserr != lserrNone) return lserr; if (fGeometry) { if (pdn->klsdn == klsdnReal) { pt.u += pdn->u.real.dup; } else { pt.u += pdn->u.pen.dup; pt.v += pdn->u.pen.dvp; } } pdn = pdn->plsdnNext; } } return lserrNone; } // %%Function: EnumerateDnode // %%Contact: victork // static LSERR EnumerateDnode(PLSC plsc, PLSDNODE pdn, POINTUV pt, BOOL fReverse, BOOL fGeometry, const POINT* pptOrg) { POINTUV ptRaised; POINT ptXY; LSTFLOW lstflow = pdn->plssubl->lstflow; if (pdn->klsdn == klsdnReal) { if (pdn->u.real.pdobj == NULL) { // How could it happen: // we substitute autodecimal tab by a pen at PrepareLineForDisplay time. // Pens don't require plsrun, so we are fine at display. // If Client doesn't ask for geometry, the substitution might not happen Assert (!fGeometry); Assert (pdn->fTab); Assert(pdn->cpFirst < 0); Assert(plsc->lsadjustcontext.fAutodecimalTabPresent); return plsc->lscbk.pfnEnumPen(plsc->pols, fFalse, lstflow, fReverse, fFalse, &ptXY, 0, 0); } else { if (fGeometry) { ptRaised = pt; ptRaised.v += pdn->u.real.lschp.dvpPos; LsPointXYFromPointUV(pptOrg, lstflow, &ptRaised, &(ptXY)); } return (*plsc->lsiobjcontext.rgobj[pdn->u.real.lschp.idObj].lsim.pfnEnum) (pdn->u.real.pdobj, pdn->u.real.plsrun, &(pdn->u.real.lschp), pdn->cpFirst, pdn->dcp, lstflow, fReverse, fGeometry, &ptXY, &pdn->u.real.objdim.heightsPres, pdn->u.real.dup); } } else { return plsc->lscbk.pfnEnumPen(plsc->pols, pdn->fBorderNode, lstflow, fReverse, fGeometry, &ptXY, pdn->u.pen.dup, pdn->u.pen.dvp); } }