Leaked source code of windows server 2003
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.

227 lines
6.7 KiB

  1. #include "ntiman.h"
  2. #include "plschcon.h"
  3. #include "lschcon.h"
  4. #include "dninfo.h"
  5. #include "iobj.h"
  6. #include "chnutils.h"
  7. #include "lstext.h"
  8. #include "lscfmtfl.h"
  9. #define FNominalToIdealNeeded(plschnkcontext, grpf, lskjust) \
  10. ((plschnkcontext)->grpfTnti != 0) || \
  11. FNominalToIdealBecauseOfParagraphProperties(grpf, lskjust)
  12. LSERR ApplyNominalToIdeal(
  13. PLSCHUNKCONTEXT plschunkcontext, /* LS chunk context */
  14. PLSIOBJCONTEXT plsiobjcontext, /* installed objects */
  15. DWORD grpf, /* grpf */
  16. LSKJUST lskjust, /* kind of justification */
  17. BOOL fIsSublineMain, /* fIsSubLineMain */
  18. BOOL fLineContainsAutoNumber,
  19. PLSDNODE plsdnLast) /* dnode until which we should do nominal to ideal */
  20. {
  21. LSERR lserr;
  22. PLSDNODE plsdnPrev;
  23. BOOL fSuccessful;
  24. WCHAR wchar;
  25. PLSRUN plsrunText;
  26. HEIGHTS heightsText;
  27. MWCLS mwcls;
  28. DWORD iobj;
  29. LSIMETHODS* plsim;
  30. long durChange;
  31. PLSDNODE plsdnLastContent;
  32. plsdnLastContent = plsdnLast;
  33. // skip borders
  34. while(plsdnLastContent != NULL && FIsDnodeBorder(plsdnLastContent))
  35. {
  36. plsdnLastContent = plsdnLastContent->plsdnPrev;
  37. }
  38. /* if there are now dnodes in line or nominal to ideal has been already applied
  39. return right away */
  40. if (plsdnLastContent == NULL || plschunkcontext->fNTIAppliedToLastChunk)
  41. return lserrNone;
  42. Assert(FIsLSDNODE(plsdnLastContent));
  43. /*if last dnode text */
  44. if (FIsDnodeReal(plsdnLastContent) && !(plsdnLastContent->fTab) &&
  45. (IdObjFromDnode(plsdnLastContent) == IobjTextFromLsc(plsiobjcontext)))
  46. {
  47. lserr = FillChunkArray(plschunkcontext, plsdnLastContent);
  48. if (lserr != lserrNone)
  49. return lserr;
  50. if (FNominalToIdealNeeded(plschunkcontext, grpf, lskjust))
  51. {
  52. lserr = NominalToIdealText(
  53. plschunkcontext->grpfTnti,
  54. LstflowFromDnode(plsdnLastContent),
  55. (FIsFirstOnLine(plschunkcontext->pplsdnChunk[0]) && fIsSublineMain),
  56. fLineContainsAutoNumber ,
  57. plschunkcontext->locchnkCurrent.clschnk,
  58. plschunkcontext->locchnkCurrent.plschnk);
  59. if (lserr != lserrNone)
  60. return lserr;
  61. SetNTIAppliedToLastChunk(plschunkcontext);
  62. /* apply width modification between preceding object and first text */
  63. plsdnPrev = plschunkcontext->pplsdnChunk[0]->plsdnPrev;
  64. if (plsdnPrev != NULL && FIsDnodeReal(plsdnPrev) && !plsdnPrev->fTab)
  65. {
  66. lserr = GetFirstCharInChunk(plschunkcontext->locchnkCurrent.clschnk,
  67. plschunkcontext->locchnkCurrent.plschnk, &fSuccessful,
  68. &wchar, &plsrunText, &heightsText, &mwcls);
  69. if (lserr != lserrNone)
  70. return lserr;
  71. if (fSuccessful)
  72. {
  73. iobj = IdObjFromDnode(plsdnPrev);
  74. plsim = PLsimFromLsc(plsiobjcontext, iobj);
  75. if (plsim->pfnGetModWidthFollowingChar != NULL)
  76. {
  77. lserr = plsim->pfnGetModWidthFollowingChar(plsdnPrev->u.real.pdobj,
  78. plsdnPrev->u.real.plsrun, plsrunText, &heightsText, wchar,
  79. mwcls, &durChange);
  80. if (lserr != lserrNone)
  81. return lserr;
  82. if (durChange != 0)
  83. {
  84. lserr = ModifyFirstCharInChunk(
  85. plschunkcontext->locchnkCurrent.clschnk,
  86. plschunkcontext->locchnkCurrent.plschnk,
  87. durChange);
  88. if (lserr != lserrNone)
  89. return lserr;
  90. }
  91. } /* object has this method */
  92. } /* call back from text was successful */
  93. } /* there is non-text object before chunk of text */
  94. } /* nominal to ideal is needed */
  95. } /* last dnode text after autonumbering */
  96. return lserrNone;
  97. }
  98. LSERR ApplyModWidthToPrecedingChar(
  99. PLSCHUNKCONTEXT plschunkcontext, /* LS chunk context */
  100. PLSIOBJCONTEXT plsiobjcontext, /* installed objects */
  101. DWORD grpf, /* grpf */
  102. LSKJUST lskjust, /* kind of justification */
  103. PLSDNODE plsdnNonText) /* non-text dnode after text */
  104. {
  105. LSERR lserr;
  106. BOOL fSuccessful;
  107. WCHAR wchar;
  108. PLSRUN plsrunText;
  109. HEIGHTS heightsText;
  110. MWCLS mwcls;
  111. DWORD iobj;
  112. LSIMETHODS* plsim;
  113. long durChange;
  114. PLSDNODE plsdnPrev;
  115. Assert(FIsLSDNODE(plsdnNonText));
  116. plsdnPrev = plsdnNonText->plsdnPrev;
  117. /*if Prev dnode text */
  118. if (plsdnPrev != NULL && FIsDnodeReal(plsdnPrev) && !(plsdnPrev->fTab) &&
  119. (IdObjFromDnode(plsdnPrev) == IobjTextFromLsc(plsiobjcontext)))
  120. {
  121. if (plschunkcontext->FChunkValid)
  122. {
  123. /* chunk we have is exactly what we need */
  124. Assert(plschunkcontext->locchnkCurrent.clschnk != 0);
  125. Assert(!plschunkcontext->FGroupChunk);
  126. Assert((plschunkcontext->pplsdnChunk[plschunkcontext->locchnkCurrent.clschnk - 1])
  127. ->plsdnNext == plsdnNonText);
  128. }
  129. else
  130. {
  131. lserr = FillChunkArray(plschunkcontext, plsdnPrev);
  132. if (lserr != lserrNone)
  133. return lserr;
  134. }
  135. if (FNominalToIdealNeeded(plschunkcontext, grpf, lskjust))
  136. {
  137. /* apply width modification between text and following object */
  138. lserr = GetLastCharInChunk(plschunkcontext->locchnkCurrent.clschnk,
  139. plschunkcontext->locchnkCurrent.plschnk, &fSuccessful,
  140. &wchar, &plsrunText, &heightsText, &mwcls);
  141. if (lserr != lserrNone)
  142. return lserr;
  143. if (fSuccessful)
  144. {
  145. iobj = IdObjFromDnode(plsdnNonText);
  146. plsim = PLsimFromLsc(plsiobjcontext, iobj);
  147. if (plsim->pfnGetModWidthPrecedingChar != NULL)
  148. {
  149. lserr = plsim->pfnGetModWidthPrecedingChar(plsdnNonText->u.real.pdobj,
  150. plsdnNonText->u.real.plsrun, plsrunText, &heightsText, wchar,
  151. mwcls, &durChange);
  152. if (lserr != lserrNone)
  153. return lserr;
  154. if (durChange != 0)
  155. {
  156. lserr = ModifyLastCharInChunk(
  157. plschunkcontext->locchnkCurrent.clschnk,
  158. plschunkcontext->locchnkCurrent.plschnk,
  159. durChange);
  160. if (lserr != lserrNone)
  161. return lserr;
  162. }
  163. } /* object has this method */
  164. } /* call back from text was successful */
  165. } /* nominal to ideal is needed */
  166. } /* there is text before */
  167. return lserrNone;
  168. }
  169. LSERR CutPossibleContextViolation(
  170. PLSCHUNKCONTEXT plschunkcontext, /* LS chunk context */
  171. PLSDNODE plsdnLast) /* last text dnode */
  172. {
  173. LSERR lserr;
  174. Assert(FIsLSDNODE(plsdnLast));
  175. if (plschunkcontext->FChunkValid)
  176. {
  177. /* chunk we have is exactly what we need */
  178. Assert(plschunkcontext->locchnkCurrent.clschnk != 0);
  179. Assert(!plschunkcontext->FGroupChunk);
  180. Assert((plschunkcontext->pplsdnChunk[plschunkcontext->locchnkCurrent.clschnk - 1])
  181. == plsdnLast);
  182. }
  183. else
  184. {
  185. lserr = FillChunkArray(plschunkcontext, plsdnLast);
  186. if (lserr != lserrNone)
  187. return lserr;
  188. }
  189. lserr = CutTextDobj(plschunkcontext->locchnkCurrent.clschnk,
  190. plschunkcontext->locchnkCurrent.plschnk);
  191. if (lserr != lserrNone)
  192. return lserr;
  193. return lserrNone;
  194. }