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.

377 lines
8.7 KiB

  1. #include "lstxttab.h"
  2. #include "lstxtmap.h"
  3. #include "lsdnset.h"
  4. #include "objdim.h"
  5. #include "txtils.h"
  6. #include "txtln.h"
  7. #include "txtobj.h"
  8. LSERR SetTabLeader(PDOBJ pdobj, WCHAR wch)
  9. {
  10. Assert(((PTXTOBJ)pdobj)->txtkind == txtkindTab);
  11. ((PTXTOBJ)pdobj)->u.tab.wchTabLeader = wch;
  12. return lserrNone;
  13. }
  14. /* L S G E T D E C I M A L P O I N T */
  15. /*----------------------------------------------------------------------------
  16. %%Function: LsGetDecimalPoint
  17. %%Contact: sergeyge
  18. Finds dobj, containing decimal point and reports its index as well as
  19. relative and dur from the beginning of dobj until decimal point.
  20. ----------------------------------------------------------------------------*/
  21. LSERR LsGetDecimalPoint(const LSGRCHNK* plsgrchnk, enum lsdevice lsdev, DWORD* pigrchnk, long* pduToDecimal)
  22. {
  23. LSERR lserr;
  24. DWORD clsgrchnk;
  25. PLSCHNK rglschnk;
  26. POLS pols;
  27. PLSRUN plsrun;
  28. PLNOBJ ptxtln;
  29. PILSOBJ pilsobj;
  30. PTXTOBJ ptxtobj;
  31. WCHAR* rgwch;
  32. long* rgdu;
  33. long* rgwSpaces;
  34. long itxtobj;
  35. long iwch;
  36. long iwchSpace;
  37. long iwSpace;
  38. BOOL fInDigits;
  39. BOOL fDigit;
  40. WCHAR wchDec;
  41. WCHAR wchThou;
  42. BOOL fThouIsSpace;
  43. BOOL fFound;
  44. BOOL fRealPointFound;
  45. long iwchDecimal = 0;
  46. long du;
  47. BOOL fGlyphBased;
  48. long iFirst;
  49. long iLim;
  50. long iDecimal;
  51. long i;
  52. clsgrchnk = plsgrchnk->clsgrchnk;
  53. if (clsgrchnk == 0)
  54. {
  55. *pigrchnk = idobjOutside;
  56. *pduToDecimal = 0;
  57. return lserrNone;
  58. }
  59. rglschnk = plsgrchnk->plschnk;
  60. ptxtln = ((PTXTOBJ)rglschnk[0].pdobj)->plnobj;
  61. pilsobj = ptxtln->pilsobj;
  62. pols = pilsobj->pols;
  63. rgwch = pilsobj->pwchOrig;
  64. rgwSpaces = pilsobj->pwSpaces;
  65. fInDigits = fFalse;
  66. fFound = fFalse;
  67. fRealPointFound = fFalse;
  68. for (itxtobj = 0; !fFound && itxtobj < (long)clsgrchnk; itxtobj++)
  69. {
  70. ptxtobj = (PTXTOBJ)rglschnk[itxtobj].pdobj;
  71. fGlyphBased = ptxtobj->txtf & txtfGlyphBased;
  72. plsrun = rglschnk[itxtobj].plsrun;
  73. lserr = (*pilsobj->plscbk->pfnGetNumericSeparators)(pols, plsrun, &wchDec, &wchThou);
  74. if (lserr != lserrNone) return lserr;
  75. fThouIsSpace = (wchThou == pilsobj->wchSpace || wchThou == pilsobj->wchNonBreakSpace);
  76. if (ptxtobj->txtkind == txtkindRegular)
  77. {
  78. iwSpace = ptxtobj->u.reg.iwSpacesFirst;
  79. if (iwSpace == ptxtobj->u.reg.iwSpacesLim)
  80. {
  81. iwchSpace = ptxtobj->iwchLim;
  82. }
  83. else
  84. {
  85. iwchSpace = rgwSpaces[iwSpace];
  86. }
  87. for (iwch = ptxtobj->iwchFirst; !fFound && iwch < ptxtobj->iwchLim; iwch++)
  88. {
  89. if (!fGlyphBased || FIwchOneToOne(pilsobj, iwch))
  90. {
  91. if (iwch == iwchSpace)
  92. {
  93. if (fInDigits && !fThouIsSpace)
  94. {
  95. iwchDecimal = iwch;
  96. fFound = fTrue;
  97. }
  98. else
  99. {
  100. iwSpace++;
  101. if (iwSpace == ptxtobj->u.reg.iwSpacesLim)
  102. {
  103. iwchSpace = ptxtobj->iwchLim;
  104. }
  105. else
  106. {
  107. iwchSpace = rgwSpaces[iwSpace];
  108. }
  109. }
  110. }
  111. else if (rgwch[iwch] == wchDec)
  112. {
  113. iwchDecimal = iwch;
  114. fFound = fTrue;
  115. fRealPointFound = fTrue;
  116. }
  117. else
  118. {
  119. lserr = (*pilsobj->plscbk->pfnCheckForDigit)(pols, plsrun, rgwch[iwch], &fDigit);
  120. if (lserr != lserrNone) return lserr;
  121. if (fDigit)
  122. {
  123. fInDigits = fTrue;
  124. }
  125. else
  126. {
  127. iwchDecimal = iwch;
  128. fFound = (fInDigits && rgwch[iwch] != wchThou);
  129. }
  130. }
  131. }
  132. } /* for (iwch= ... */
  133. } /* if (txtkind == txtkindRegular */
  134. else if (ptxtobj->txtkind == txtkindNonBreakSpace)
  135. {
  136. if (fInDigits && !fThouIsSpace)
  137. {
  138. iwchDecimal = ptxtobj->iwchFirst;
  139. fFound = fTrue;
  140. }
  141. }
  142. else if (ptxtobj->txtkind == txtkindEOL)
  143. {
  144. iwchDecimal = ptxtobj->iwchFirst;
  145. fFound = fTrue;
  146. }
  147. else /* All other dobj's interrupt digits */
  148. {
  149. if (fInDigits && ptxtobj->iwchLim > ptxtobj->iwchFirst)
  150. {
  151. iwchDecimal = ptxtobj->iwchFirst;
  152. fFound = fTrue;
  153. }
  154. }
  155. if (!fFound && (plsgrchnk->pcont[itxtobj] & fcontNonTextAfter))
  156. {
  157. iwchDecimal = ptxtobj->iwchLim;
  158. fFound = fInDigits;
  159. }
  160. } /* for (itxtobj= ... */
  161. itxtobj--;
  162. Assert(itxtobj >= 0);
  163. ptxtobj = (PTXTOBJ)rglschnk[itxtobj].pdobj;
  164. if (fFound)
  165. {
  166. /* If we stopped because of digit followed by non-digit
  167. (real decimal point was not found) break after digit rather than before following character
  168. If we stopped because of EOP after non-digit, IF statement will work correctly as well
  169. */
  170. if (itxtobj > 0 && !fRealPointFound && iwchDecimal == ptxtobj->iwchFirst && !(plsgrchnk->pcont[itxtobj] & fcontNonTextBefore))
  171. {
  172. itxtobj--;
  173. ptxtobj = (PTXTOBJ)rglschnk[itxtobj].pdobj;
  174. iwchDecimal = ptxtobj->iwchLim;
  175. }
  176. if (ptxtobj->txtf & txtfGlyphBased)
  177. {
  178. if (lsdev == lsdevReference)
  179. rgdu = pilsobj->pdurGind;
  180. else
  181. rgdu = ptxtln->pdupGind;
  182. iFirst = ptxtobj->igindFirst;
  183. iLim = ptxtobj->igindLim;
  184. iDecimal = IgindFirstFromIwch(ptxtobj, iwchDecimal);
  185. Assert (iDecimal >= ptxtobj->igindFirst);
  186. }
  187. else
  188. {
  189. if (lsdev == lsdevReference)
  190. rgdu = pilsobj->pdur;
  191. else
  192. rgdu = ptxtln->pdup;
  193. iFirst = ptxtobj->iwchFirst;
  194. iLim = ptxtobj->iwchLim;
  195. iDecimal = iwchDecimal;
  196. Assert (iDecimal >= ptxtobj->iwchFirst);
  197. }
  198. du = 0;
  199. for (i = iFirst; i < iDecimal; i++)
  200. {
  201. du += rgdu[i];
  202. }
  203. *pigrchnk = itxtobj;
  204. *pduToDecimal = du;
  205. }
  206. else
  207. {
  208. *pigrchnk = idobjOutside;
  209. *pduToDecimal = 0;
  210. }
  211. return lserrNone;
  212. }
  213. /* L S G E T C H A R T A B */
  214. /*----------------------------------------------------------------------------
  215. %%Function: LsGetCharTab
  216. %%Contact: sergeyge
  217. Finds dobj, containing char for char tab point and reports its index as well as
  218. relative and dur from the beginning of dobj until decimal point.
  219. ----------------------------------------------------------------------------*/
  220. LSERR LsGetCharTab(const LSGRCHNK* plsgrchnk, WCHAR wchCharTab, enum lsdevice lsdev,
  221. DWORD* pigrchnk, long* pduToCharacter)
  222. {
  223. DWORD clsgrchnk;
  224. PLSCHNK rglschnk;
  225. POLS pols;
  226. PLSRUN plsrun;
  227. PLNOBJ ptxtln;
  228. PILSOBJ pilsobj;
  229. PTXTOBJ ptxtobj;
  230. WCHAR* rgwch;
  231. long* rgdu;
  232. long itxtobj;
  233. long iwch;
  234. BOOL fFound;
  235. long itxtobjCharTab = 0;
  236. long iwchCharTab = 0;
  237. long du;
  238. BOOL fGlyphBased;
  239. long iFirst;
  240. long iLim;
  241. long iCharTab;
  242. long i;
  243. clsgrchnk = plsgrchnk->clsgrchnk;
  244. if (clsgrchnk == 0)
  245. {
  246. *pigrchnk = idobjOutside;
  247. *pduToCharacter = 0;
  248. return lserrNone;
  249. }
  250. rglschnk = plsgrchnk->plschnk;
  251. ptxtln = ((PTXTOBJ)rglschnk[0].pdobj)->plnobj;
  252. pilsobj = ptxtln->pilsobj;
  253. pols = pilsobj->pols;
  254. rgwch = pilsobj->pwchOrig;
  255. fFound = fFalse;
  256. for (itxtobj = 0; !fFound && itxtobj < (long)clsgrchnk; itxtobj++)
  257. {
  258. ptxtobj = (PTXTOBJ)rglschnk[itxtobj].pdobj;
  259. fGlyphBased = ptxtobj->txtf & txtfGlyphBased;
  260. plsrun = rglschnk[itxtobj].plsrun;
  261. if (ptxtobj->txtkind == txtkindRegular)
  262. {
  263. for (iwch = ptxtobj->iwchFirst; !fFound && iwch < ptxtobj->iwchLim; iwch++)
  264. {
  265. if (!fGlyphBased || FIwchOneToOne(pilsobj, iwch))
  266. {
  267. if (rgwch[iwch] == wchCharTab)
  268. {
  269. itxtobjCharTab = itxtobj;
  270. iwchCharTab = iwch;
  271. fFound = fTrue;
  272. }
  273. }
  274. } /* for (iwch= ... */
  275. } /* if (txtkind == txtkindRegular */
  276. else if (ptxtobj->txtkind == txtkindEOL)
  277. {
  278. /* If we stopped because of EOP
  279. (real character is not found) break after previous character rather than before EOP.
  280. It is important for BiDi.
  281. */
  282. if (itxtobj > 0 && !(plsgrchnk->pcont[itxtobj] & fcontNonTextBefore))
  283. {
  284. itxtobjCharTab = itxtobj - 1;
  285. iwchCharTab = ((PTXTOBJ)rglschnk[itxtobjCharTab].pdobj)->iwchLim;
  286. }
  287. else
  288. {
  289. itxtobjCharTab = itxtobj;
  290. iwchCharTab = ptxtobj->iwchFirst;
  291. }
  292. fFound = fTrue;
  293. }
  294. } /* for (itxtobj= ... */
  295. if (fFound)
  296. {
  297. ptxtobj = (PTXTOBJ)rglschnk[itxtobjCharTab].pdobj;
  298. if (ptxtobj->txtf & txtfGlyphBased)
  299. {
  300. if (lsdev == lsdevReference)
  301. rgdu = pilsobj->pdurGind;
  302. else
  303. rgdu = ptxtln->pdupGind;
  304. iFirst = ptxtobj->igindFirst;
  305. iLim = ptxtobj->igindLim;
  306. iCharTab = IgindFirstFromIwch(ptxtobj, iwchCharTab);
  307. Assert (iCharTab >= ptxtobj->igindFirst);
  308. }
  309. else
  310. {
  311. if (lsdev == lsdevReference)
  312. rgdu = pilsobj->pdur;
  313. else
  314. rgdu = ptxtln->pdup;
  315. iFirst = ptxtobj->iwchFirst;
  316. iLim = ptxtobj->iwchLim;
  317. iCharTab = iwchCharTab;
  318. Assert (iCharTab >= ptxtobj->iwchFirst);
  319. }
  320. du = 0;
  321. for (i = iFirst; i < iCharTab; i++)
  322. {
  323. du += rgdu[i];
  324. }
  325. *pigrchnk = itxtobjCharTab;
  326. *pduToCharacter = du;
  327. }
  328. else
  329. {
  330. *pigrchnk = idobjOutside;
  331. *pduToCharacter = 0;
  332. }
  333. return lserrNone;
  334. }