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.

374 lines
7.8 KiB

  1. #include "lsidefs.h"
  2. #include "sublutil.h"
  3. #include "dnutils.h"
  4. #include "lssubl.h"
  5. #include "lsdnode.h"
  6. #include "dninfo.h"
  7. #include "lsimeth.h"
  8. #include "iobj.h"
  9. #include "lsmem.h"
  10. #include "chnutils.h"
  11. #include "posichnk.h"
  12. #include "getfmtst.h"
  13. #include "lstext.h"
  14. #ifdef DEBUG
  15. #define DebugMemset(a,b,c) if ((a) != NULL) memset(a,b,c); else
  16. #else
  17. #define DebugMemset(a,b,c) (void)(0)
  18. #endif
  19. LSERR GetSpecialEffectsSublineCore(PLSSUBL plssubl,PLSIOBJCONTEXT plsiobjcontext,
  20. UINT* pfEffectsFlags)
  21. {
  22. PLSDNODE plsdn;
  23. PLSDNODE plsdnPrev;
  24. UINT fEffectsFlagsObject;
  25. DWORD iobj;
  26. LSERR lserr;
  27. LSIMETHODS* plsim;
  28. Assert(FIsLSSUBL(plssubl));
  29. *pfEffectsFlags = 0;
  30. plsdn = plssubl->plsdnFirst;
  31. plsdnPrev = NULL;
  32. while(plsdnPrev != plssubl->plsdnLast)
  33. {
  34. if (FIsDnodeReal(plsdn))
  35. {
  36. *pfEffectsFlags |= plsdn->u.real.lschp.EffectsFlags;
  37. iobj = IdObjFromDnode(plsdn);
  38. if (iobj != IobjTextFromLsc(plsiobjcontext) && !FIsDnodeSplat(plsdn))
  39. {
  40. plsim = PLsimFromLsc(plsiobjcontext, iobj);
  41. if (plsim->pfnGetSpecialEffectsInside != NULL)
  42. {
  43. lserr = plsim->pfnGetSpecialEffectsInside(plsdn->u.real.pdobj,
  44. &fEffectsFlagsObject);
  45. if (lserr != lserrNone)
  46. return lserr;
  47. *pfEffectsFlags |= fEffectsFlagsObject;
  48. }
  49. }
  50. }
  51. plsdnPrev = plsdn;
  52. plsdn = plsdn->plsdnNext;
  53. }
  54. return lserrNone;
  55. }
  56. LSERR GetObjDimSublineCore(
  57. PLSSUBL plssubl, /* IN: subline */
  58. POBJDIM pobjdim) /* OUT: dimension of subline */
  59. {
  60. PLSDNODE plsdnFirst = plssubl->plsdnFirst;
  61. PLSDNODE plsdnLast = plssubl->plsdnLast;
  62. /* skip autonumber for the main subline */
  63. if (FIsSubLineMain(plssubl))
  64. {
  65. while (plsdnFirst != NULL && plsdnFirst->cpFirst < 0)
  66. {
  67. plsdnFirst = plsdnFirst->plsdnNext;
  68. }
  69. /* because of splat right after autonumber plsdnFirst can be NULL */
  70. if (plsdnFirst == NULL)
  71. plsdnLast = NULL;
  72. }
  73. return FindListDims(plsdnFirst, plsdnLast, pobjdim);
  74. }
  75. LSERR GetDupSublineCore(
  76. PLSSUBL plssubl, /* IN: Subline Context */
  77. long* pdup) /* OUT: dup of subline */
  78. {
  79. FindListDup(plssubl->plsdnFirst, plssubl->cpLim, pdup);
  80. return lserrNone;
  81. }
  82. LSERR FIsSublineEmpty(
  83. PLSSUBL plssubl, /* IN: subline */
  84. BOOL* pfEmpty) /* OUT:is this subline empty */
  85. {
  86. PLSDNODE plsdnLast;
  87. Assert(FIsLSSUBL(plssubl));
  88. Assert((plssubl->plsdnFirst == NULL) == (plssubl->plsdnLast == NULL));
  89. plsdnLast = plssubl->plsdnLast;
  90. if (FIsSubLineMain(plssubl))
  91. {
  92. if (plsdnLast != NULL && FIsDnodeSplat(plsdnLast))
  93. {
  94. plsdnLast = plsdnLast->plsdnPrev;
  95. }
  96. *pfEmpty = (plsdnLast == NULL || FIsNotInContent(plsdnLast));
  97. }
  98. else
  99. {
  100. *pfEmpty = (plsdnLast == NULL );
  101. }
  102. return lserrNone;
  103. }
  104. LSERR DestroySublineCore(PLSSUBL plssubl,LSCBK* plscbk, POLS pols,
  105. PLSIOBJCONTEXT plsiobjcontext, BOOL fDontReleaseRuns)/* IN: subline to destroy */
  106. {
  107. LSERR lserr;
  108. Assert(FIsLSSUBL(plssubl));
  109. lserr = DestroyDnodeList(plscbk, pols, plsiobjcontext,
  110. plssubl->plsdnFirst, fDontReleaseRuns);
  111. if (lserr != lserrNone)
  112. return lserr;
  113. /* destroy chunk context */
  114. DestroyChunkContext(plssubl->plschunkcontext);
  115. /* destroy break context */
  116. Assert(plssubl->pbrkcontext != NULL); /* we don't expect main subline to be called */
  117. DebugMemset(plssubl->pbrkcontext, 0xE9, sizeof(BRKCONTEXT));
  118. plscbk->pfnDisposePtr(pols, plssubl->pbrkcontext);
  119. plssubl->tag = tagInvalid;
  120. DebugMemset(plssubl, 0xE9, sizeof(LSSUBL));
  121. plscbk->pfnDisposePtr(pols, plssubl);
  122. return lserrNone;
  123. }
  124. BOOL FAreTabsPensInSubline(
  125. PLSSUBL plssubl) /* IN: subline */
  126. {
  127. PLSDNODE plsdn;
  128. PLSDNODE plsdnPrev;
  129. BOOL fAreTabsPensInSubline;
  130. Assert(FIsLSSUBL(plssubl));
  131. fAreTabsPensInSubline = fFalse;
  132. plsdn = plssubl->plsdnFirst;
  133. plsdnPrev = NULL;
  134. while(plsdnPrev != plssubl->plsdnLast)
  135. {
  136. if (FIsDnodePen(plsdn) || plsdn->fTab)
  137. {
  138. fAreTabsPensInSubline = fTrue;
  139. break;
  140. }
  141. plsdnPrev = plsdn;
  142. plsdn = plsdn->plsdnNext;
  143. }
  144. return fAreTabsPensInSubline;
  145. }
  146. LSERR GetPlsrunFromSublineCore(
  147. PLSSUBL plssubl, /* IN: subline */
  148. DWORD crgPlsrun, /* IN: size of array */
  149. PLSRUN* rgPlsrun) /* OUT: array of plsruns */
  150. {
  151. DWORD i = 0;
  152. PLSDNODE plsdn;
  153. PLSDNODE plsdnPrev;
  154. Assert(FIsLSSUBL(plssubl));
  155. plsdn = plssubl->plsdnFirst;
  156. plsdnPrev = NULL;
  157. while(plsdnPrev != plssubl->plsdnLast && i < crgPlsrun)
  158. {
  159. if (FIsDnodeReal(plsdn))
  160. {
  161. rgPlsrun[i] = plsdn->u.real.plsrun;
  162. }
  163. else /* pen */
  164. {
  165. rgPlsrun[i] = NULL;
  166. }
  167. plsdnPrev = plsdn;
  168. plsdn = plsdn->plsdnNext;
  169. i++;
  170. }
  171. return lserrNone;
  172. }
  173. LSERR GetNumberDnodesCore(
  174. PLSSUBL plssubl, /* IN: subline */
  175. DWORD* cDnodes) /* OUT: numberof dnodes in subline */
  176. {
  177. PLSDNODE plsdn;
  178. PLSDNODE plsdnPrev;
  179. Assert(FIsLSSUBL(plssubl));
  180. *cDnodes = 0;
  181. plsdn = plssubl->plsdnFirst;
  182. plsdnPrev = NULL;
  183. while(plsdnPrev != plssubl->plsdnLast)
  184. {
  185. (*cDnodes)++;
  186. plsdnPrev = plsdn;
  187. plsdn = plsdn->plsdnNext;
  188. }
  189. return lserrNone;
  190. }
  191. LSERR GetVisibleDcpInSublineCore(
  192. PLSSUBL plssubl, /* IN: subline */
  193. LSDCP* pndcp) /* OUT:amount of visible characters in subline */
  194. {
  195. PLSDNODE plsdn;
  196. PLSDNODE plsdnPrev;
  197. Assert(FIsLSSUBL(plssubl));
  198. *pndcp = 0;
  199. plsdn = plssubl->plsdnFirst;
  200. plsdnPrev = NULL;
  201. while(plsdnPrev != plssubl->plsdnLast)
  202. {
  203. if (FIsDnodeReal(plsdn))
  204. {
  205. *pndcp += plsdn->dcp;
  206. }
  207. plsdnPrev = plsdn;
  208. plsdn = plsdn->plsdnNext;
  209. }
  210. return lserrNone;
  211. }
  212. LSERR GetDurTrailInSubline(
  213. PLSSUBL plssubl, /* IN: Subline Context */
  214. long* pdurTrail) /* OUT: width of trailing area
  215. in subline */
  216. {
  217. LSERR lserr;
  218. PLSCHUNKCONTEXT plschunkcontext;
  219. PLSDNODE plsdn;
  220. LSDCP dcpTrail;
  221. PLSDNODE plsdnStartTrail;
  222. LSDCP dcpStartTrailingText;
  223. int cDnodesTrailing;
  224. PLSDNODE plsdnTrailingObject;
  225. LSDCP dcpTrailingObject;
  226. BOOL fClosingBorderStartsTrailing;
  227. *pdurTrail = 0;
  228. plsdn = GetCurrentDnodeSubl(plssubl);
  229. plschunkcontext = PlschunkcontextFromSubline(plssubl);
  230. if (plsdn != NULL)
  231. {
  232. lserr = GetTrailingInfoForTextGroupChunk(plsdn,
  233. plsdn->dcp, IobjTextFromLsc(plschunkcontext->plsiobjcontext),
  234. pdurTrail, &dcpTrail, &plsdnStartTrail,
  235. &dcpStartTrailingText, &cDnodesTrailing,
  236. &plsdnTrailingObject, &dcpTrailingObject, &fClosingBorderStartsTrailing);
  237. if (lserr != lserrNone)
  238. return lserr;
  239. }
  240. return lserrNone;
  241. }
  242. LSERR GetDurTrailWithPensInSubline(
  243. PLSSUBL plssubl, /* IN: Subline Context */
  244. long* pdurTrail) /* OUT: width of trailing area
  245. in subline */
  246. {
  247. LSERR lserr;
  248. PLSCHUNKCONTEXT plschunkcontext;
  249. PLSDNODE plsdn;
  250. LSDCP dcpTrail;
  251. PLSDNODE plsdnStartTrail;
  252. LSDCP dcpStartTrailingText;
  253. int cDnodesTrailing;
  254. PLSDNODE plsdnTrailingObject;
  255. LSDCP dcpTrailingObject;
  256. BOOL fClosingBorderStartsTrailing;
  257. long durTrailLoc;
  258. BOOL fContinue = fTrue;
  259. *pdurTrail = 0;
  260. plsdn = GetCurrentDnodeSubl(plssubl);
  261. plschunkcontext = PlschunkcontextFromSubline(plssubl);
  262. while(fContinue)
  263. {
  264. if (plsdn != NULL)
  265. {
  266. lserr = GetTrailingInfoForTextGroupChunk(plsdn,
  267. plsdn->dcp, IobjTextFromLsc(plschunkcontext->plsiobjcontext),
  268. &durTrailLoc, &dcpTrail, &plsdnStartTrail,
  269. &dcpStartTrailingText, &cDnodesTrailing,
  270. &plsdnTrailingObject, &dcpTrailingObject, &fClosingBorderStartsTrailing);
  271. if (lserr != lserrNone)
  272. return lserr;
  273. *pdurTrail += durTrailLoc;
  274. if (dcpTrailingObject == 0)
  275. {
  276. /* we stopped just before group chunk, may be because of pen */
  277. Assert(FIsLSDNODE(plsdnTrailingObject));
  278. plsdn = plsdnTrailingObject->plsdnPrev;
  279. while(plsdn != NULL && FIsDnodePen(plsdn))
  280. {
  281. *pdurTrail += DurFromDnode(plsdn);
  282. plsdn = plsdn->plsdnPrev;
  283. }
  284. }
  285. else
  286. {
  287. fContinue = fFalse;
  288. }
  289. }
  290. else
  291. {
  292. fContinue = fFalse;
  293. }
  294. }
  295. return lserrNone;
  296. }