Source code of Windows XP (NT5)
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.

337 lines
9.1 KiB

  1. #include "dnutils.h"
  2. #include "dninfo.h"
  3. #include "iobj.h"
  4. #include "lsdnode.h"
  5. #include "lscbk.h"
  6. #include "qheap.h"
  7. #include "lstext.h"
  8. #include "lsmem.h" /* memset() prototype */
  9. #define FIsOutOfLine(plsc, plsdn) \
  10. (((plsdn) == NULL) || \
  11. (((plsc)->plslineCur->lslinfo.cpLim != 0) && ((plsc)->plslineCur->lslinfo.cpLim <= (plsdn)->cpFirst)))
  12. /* F I N D L I S T D U P */
  13. /*----------------------------------------------------------------------------
  14. %%Function: FindListDup
  15. %%Contact: igorzv
  16. Visit each node in the list of DNODES, until reaching cpLim
  17. Compute dup between start and end points.
  18. ----------------------------------------------------------------------------*/
  19. void FindListDup(PLSDNODE plsdnFirst, LSCP cpLim, long *pdup)
  20. {
  21. PLSDNODE plsdn;
  22. /* tolerate pldnFirst == NULL */
  23. *pdup = 0;
  24. plsdn = plsdnFirst;
  25. while (plsdn != NULL && plsdn->cpLimOriginal <= cpLim)
  26. {
  27. Assert(FIsLSDNODE(plsdn));
  28. *pdup += DupFromDnode(plsdn);
  29. plsdn = plsdn->plsdnNext;
  30. }
  31. }
  32. /* F I N D L I S T F I N A L P E N M O V E M E N T*/
  33. /*----------------------------------------------------------------------------
  34. %%Function: FindListFinalPenMovement
  35. %%Contact: igorzv
  36. Visit each node in the list of DNODES, until reaching cpLim
  37. Compute dur dvr dvp between start and end points.
  38. ----------------------------------------------------------------------------*/
  39. void FindListFinalPenMovement(PLSDNODE plsdnFirst, PLSDNODE plsdnLast, long *pdur, long *pdvr, long *pdvp)
  40. {
  41. PLSDNODE plsdn;
  42. /* tolerate pldnFirst == NULL */
  43. *pdur = 0;
  44. *pdvr = 0;
  45. *pdvp = 0;
  46. plsdn = plsdnFirst;
  47. while (plsdn != NULL && plsdn->plsdnPrev != plsdnLast)
  48. {
  49. Assert(FIsLSDNODE(plsdn));
  50. *pdur += DurFromDnode(plsdn);
  51. *pdvr += DvrFromDnode(plsdn);
  52. *pdvp += DvpFromDnode(plsdn);
  53. plsdn = plsdn->plsdnNext;
  54. }
  55. }
  56. /* F I N D L I S T D I M S */
  57. /*----------------------------------------------------------------------------
  58. %%Function: FindListDims
  59. %%Contact: igorzv
  60. Visit each node in the list of DNODES, until reaching plsdnLast.
  61. Compute OBJDIM which describes the list.
  62. ----------------------------------------------------------------------------*/
  63. LSERR FindListDims(PLSDNODE plsdnFirst, PLSDNODE plsdnLast, OBJDIM* pobjdimList)
  64. {
  65. PLSDNODE plsdn;
  66. long urPen = 0;
  67. long urLim = 0;
  68. long vpPen = 0;
  69. long vrPen = 0;
  70. OBJDIM objdimFound;
  71. long dvpNode, dvrNode, durNode;
  72. long dvpAscentNext;
  73. long dvrAscentNext;
  74. long dvpDescentNext;
  75. long dvrDescentNext;
  76. long dvpLineHeight;
  77. long dvrLineHeight;
  78. POBJDIM pobjdimNode;
  79. BOOL fFindLast;
  80. OBJDIM* pobjdimLastSkiped = NULL;
  81. /* N.B. Tolerate an empty input list! */
  82. Assert(((plsdnFirst == NULL) && (plsdnLast == NULL)) || (FIsLSDNODE(plsdnFirst) && FIsLSDNODE(plsdnLast)));
  83. /* the most efficient way to put zeroes in heights */
  84. memset(&objdimFound, 0, sizeof objdimFound);
  85. /* quick return if list is empty */
  86. if (plsdnFirst == NULL)
  87. {
  88. *pobjdimList = objdimFound; /* in objdim will be zeroes */
  89. return lserrNone;
  90. }
  91. fFindLast = fFalse;
  92. for (plsdn = plsdnFirst; !fFindLast ; plsdn = plsdn->plsdnNext)
  93. {
  94. if (plsdn == NULL)
  95. /* we dont found plsdnLast, so return error */
  96. return lserrInvalidParameter;
  97. if (plsdn == plsdnLast)
  98. fFindLast = fTrue;
  99. if (plsdn->klsdn == klsdnReal)
  100. {
  101. pobjdimNode = &plsdn->u.real.objdim;
  102. durNode = pobjdimNode->dur;
  103. Assert(durNode >= 0);
  104. dvrNode = 0;
  105. dvpNode = 0;
  106. dvpAscentNext = pobjdimNode->heightsPres.dvAscent + vpPen;
  107. dvrAscentNext = pobjdimNode->heightsRef.dvAscent + vrPen;
  108. dvpDescentNext = pobjdimNode->heightsPres.dvDescent - vpPen;
  109. dvrDescentNext = pobjdimNode->heightsRef.dvDescent - vrPen;
  110. dvpLineHeight = pobjdimNode->heightsPres.dvMultiLineHeight;
  111. dvrLineHeight = pobjdimNode->heightsRef.dvMultiLineHeight;
  112. if (dvrLineHeight != dvHeightIgnore) /* dvrLineHeight == dvHeightIgnore */
  113. /* for us is sign that we */
  114. { /* should not take into account for height calculation
  115. this dnode */
  116. if (objdimFound.heightsPres.dvAscent < dvpAscentNext)
  117. objdimFound.heightsPres.dvAscent = dvpAscentNext;
  118. if (objdimFound.heightsRef.dvAscent < dvrAscentNext)
  119. objdimFound.heightsRef.dvAscent = dvrAscentNext;
  120. if (objdimFound.heightsPres.dvDescent < dvpDescentNext)
  121. objdimFound.heightsPres.dvDescent = dvpDescentNext;
  122. if (objdimFound.heightsRef.dvDescent < dvrDescentNext)
  123. objdimFound.heightsRef.dvDescent = dvrDescentNext;
  124. if (objdimFound.heightsPres.dvMultiLineHeight < dvpLineHeight)
  125. objdimFound.heightsPres.dvMultiLineHeight = dvpLineHeight;
  126. if (objdimFound.heightsRef.dvMultiLineHeight < dvrLineHeight)
  127. objdimFound.heightsRef.dvMultiLineHeight = dvrLineHeight;
  128. }
  129. else /* if final heights is 0, we will take ascent and desent from
  130. this dnode */
  131. {
  132. pobjdimLastSkiped = pobjdimNode;
  133. }
  134. }
  135. else /* klsdnPenOrBorder*/
  136. {
  137. dvpNode = plsdn->u.pen.dvp;
  138. durNode = plsdn->u.pen.dur;
  139. dvrNode = plsdn->u.pen.dvr;
  140. }
  141. vpPen += dvpNode;
  142. urPen += durNode;
  143. vrPen += dvrNode;
  144. if (urLim < urPen)
  145. urLim = urPen;
  146. }
  147. if (objdimFound.heightsRef.dvAscent == 0 && objdimFound.heightsRef.dvDescent == 0
  148. && pobjdimLastSkiped != NULL)
  149. {
  150. objdimFound.heightsPres.dvAscent = pobjdimLastSkiped->heightsPres.dvAscent + vpPen;
  151. objdimFound.heightsRef.dvAscent = pobjdimLastSkiped->heightsRef.dvAscent + vrPen;
  152. objdimFound.heightsPres.dvDescent = pobjdimLastSkiped->heightsPres.dvDescent - vpPen;
  153. objdimFound.heightsRef.dvDescent = pobjdimLastSkiped->heightsRef.dvDescent - vrPen;
  154. objdimFound.heightsPres.dvMultiLineHeight = dvHeightIgnore;
  155. objdimFound.heightsRef.dvMultiLineHeight = dvHeightIgnore;
  156. }
  157. *pobjdimList = objdimFound;
  158. pobjdimList->dur = urLim;
  159. return lserrNone;
  160. }
  161. /* D E S T R O Y D N O D E L I S T */
  162. /*----------------------------------------------------------------------------
  163. %%Function: DestroyDnodeList
  164. %%Contact: igorzv
  165. Parameters:
  166. plscbk - (IN) callbacks
  167. pols - (IN) pols to pass for callbacks
  168. plsiobjcontext - (IN) object handlers
  169. plsdn - (IN) first dnode in list
  170. fDontReleaseRuns - (IN) not to call release run
  171. ----------------------------------------------------------------------------*/
  172. LSERR DestroyDnodeList(LSCBK* plscbk, POLS pols, PLSIOBJCONTEXT plsiobjcontext,
  173. PLSDNODE plsdn, BOOL fDontReleaseRuns)
  174. {
  175. LSERR lserr, lserrFinal = lserrNone;
  176. PLSDNODE plsdnNext;
  177. PDOBJ pdobj;
  178. PLSRUN plsrun;
  179. DWORD iobj;
  180. if (plsdn == NULL)
  181. return lserrNone;
  182. Assert(FIsLSDNODE(plsdn));
  183. /* link with this dnode should be broken before */
  184. Assert(plsdn->plsdnPrev == NULL || plsdn->plsdnPrev->plsdnNext != plsdn );
  185. for (; plsdn != NULL; plsdn = plsdnNext)
  186. {
  187. Assert(FIsLSDNODE(plsdn));
  188. if (plsdn->klsdn == klsdnReal)
  189. {
  190. if (plsdn->u.real.pinfosubl != NULL)
  191. {
  192. if (plsdn->u.real.pinfosubl->rgpsubl != NULL)
  193. {
  194. plscbk->pfnDisposePtr(pols, plsdn->u.real.pinfosubl->rgpsubl);
  195. }
  196. plscbk->pfnDisposePtr(pols, plsdn->u.real.pinfosubl);
  197. }
  198. iobj = plsdn->u.real.lschp.idObj;
  199. plsrun = plsdn->u.real.plsrun;
  200. pdobj = plsdn->u.real.pdobj;
  201. }
  202. else
  203. {
  204. Assert (FIsDnodePen(plsdn) || FIsDnodeBorder(plsdn));
  205. iobj = 0;
  206. plsrun = NULL;
  207. pdobj = NULL;
  208. }
  209. if (plsrun != NULL && !fDontReleaseRuns)
  210. {
  211. lserr = plscbk->pfnReleaseRun(pols, plsrun);
  212. if (lserr != lserrNone && lserrFinal == lserrNone)
  213. lserrFinal = lserr;
  214. }
  215. if (pdobj != NULL)
  216. {
  217. lserr = (PLsimFromLsc(plsiobjcontext, iobj))->pfnDestroyDObj (pdobj);
  218. if (lserr != lserrNone && lserrFinal == lserrNone)
  219. lserrFinal = lserr;
  220. }
  221. plsdn->tag = tagInvalid;
  222. plsdnNext = plsdn->plsdnNext;
  223. }
  224. return lserrFinal;
  225. }
  226. /* ---------------------------------------------------------------------- */
  227. /* D U R B O R D E R F R O M D N O D E I N S I D E*/
  228. /*----------------------------------------------------------------------------
  229. %%Function: DurBorderFromDnodeInside
  230. %%Contact: igorzv
  231. Parameters:
  232. plsdn - (IN) dnode inside borders
  233. ----------------------------------------------------------------------------*/
  234. long DurBorderFromDnodeInside(PLSDNODE plsdn) /* IN: dnode inside borders */
  235. {
  236. PLSDNODE plsdnBorder = plsdn;
  237. while (!FIsDnodeBorder(plsdnBorder))
  238. {
  239. plsdnBorder = plsdnBorder->plsdnPrev;
  240. Assert(FIsLSDNODE(plsdnBorder));
  241. }
  242. Assert(FIsDnodeBorder(plsdnBorder));
  243. Assert(plsdnBorder->fOpenBorder);
  244. return plsdnBorder->u.pen.dur;
  245. }
  246. /* ---------------------------------------------------------------------- */
  247. /* F S P A C E S O N L Y*/
  248. /*----------------------------------------------------------------------------
  249. %%Function: FSpacesOnly
  250. %%Contact: igorzv
  251. Parameters:
  252. plsdn - (IN) dnode
  253. iObjText- (IN) id for text dnode
  254. ----------------------------------------------------------------------------*/
  255. BOOL FSpacesOnly(PLSDNODE plsdn, DWORD iObjText)
  256. {
  257. DWORD dcpTrailing;
  258. long durTrailing;
  259. if (FIsDnodeSplat(plsdn))
  260. return fTrue;
  261. else if (FIsDnodeReal(plsdn)
  262. && (IdObjFromDnode(plsdn) == iObjText)
  263. && !(plsdn->fTab))
  264. {
  265. GetTrailInfoText(PdobjFromDnode(plsdn), plsdn->dcp,
  266. &dcpTrailing, &durTrailing);
  267. if (dcpTrailing == plsdn->dcp)
  268. return fTrue;
  269. }
  270. return fFalse;
  271. }