Windows NT 4.0 source code leak
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.

280 lines
6.7 KiB

4 years ago
  1. /*****************************************************************************
  2. * *
  3. * TABLE.C *
  4. * *
  5. * Copyright (C) Microsoft Corporation 1990. *
  6. * All Rights reserved. *
  7. * *
  8. ******************************************************************************
  9. * *
  10. * Module Intent *
  11. * *
  12. * This module compiles tables into side by side paragraph structures. *
  13. * Eventually, it will also handle side by side paragraphs, and full *
  14. * table support. *
  15. * *
  16. *****************************************************************************/
  17. #include "stdafx.h"
  18. #pragma hdrstop
  19. #ifdef _DEBUG
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. /***************************************************************************
  24. *
  25. - Name: StartTable
  26. -
  27. * Purpose:
  28. * Starts table processing
  29. *
  30. * Arguments:
  31. * ptbl: Pointer to table information.
  32. *
  33. * Returns:
  34. * nothing.
  35. *
  36. * Globals:
  37. * This function uses the global wTextBufChCount to determine
  38. * whether or not to output the previous FCP. This way, tables
  39. * can occur at the very top of a topic (but only if they are
  40. * at the beginning of the RTF file.)
  41. *
  42. * +++
  43. *
  44. * Notes:
  45. *
  46. ***************************************************************************/
  47. void STDCALL StartTable(void)
  48. {
  49. if (tbl.tbs == tbsOff) {
  50. // Get rid of old FCP and start table processing
  51. if (wTextBufChCount) { // REVIEW (see Globals: comment above)
  52. VOutFCP(FALSE);
  53. pfInt = pfCur;
  54. VSaveTabTable();
  55. }
  56. tbl.tbs = tbsOn;
  57. tbl.wParaCmdBegin = 0;
  58. tbl.wParaTextBegin = 0;
  59. tbl.wParaTextCompBegin = 0;
  60. tbl.wObjrgTotal = 0;
  61. tbl.iCell = 0;
  62. }
  63. }
  64. /***************************************************************************
  65. *
  66. - Name: RcEndTable
  67. -
  68. * Purpose:
  69. * Finishes table processing on the given row, and outputs the entire
  70. * table FCP in side by side format.
  71. *
  72. * Arguments:
  73. * ptbl: Pointer to table information.
  74. *
  75. * Returns:
  76. * return code from RcCopyPbfQcb, or RC_Failure if tables were not
  77. * turned on from the \intbl command.
  78. *
  79. * Globals:
  80. * pbfCommand, all VOutFCP stuff.
  81. *
  82. * +++
  83. *
  84. * Notes:
  85. *
  86. ***************************************************************************/
  87. RC_TYPE STDCALL RcEndTable(void)
  88. {
  89. INT16 iT = iColumnNil;
  90. ASSERT(tbl.tbs == tbsOn);
  91. if (tbl.tbs != tbsOn)
  92. return RC_Failure;
  93. // Remove all text and commands since last valid FCP:
  94. pbfCommand->SetSize(tbl.wParaCmdBegin);
  95. pbfText->SetSize(tbl.wParaTextCompBegin);
  96. if (!pbfCommand->Add(&iT, sizeof(INT16)))
  97. OOM();
  98. tbl.tbs = tbsFinish;
  99. VOutFCP(FALSE);
  100. tbl.tbs = tbsOff;
  101. return RC_Success;
  102. }
  103. /***************************************************************************
  104. *
  105. - Name: RcAddFcpPtbl
  106. -
  107. * Purpose:
  108. * Puts a paragraph object into the command table for a table FCP.
  109. *
  110. * Arguments:
  111. * ptbl: Pointer to table information
  112. *
  113. * Returns:
  114. * General purpose return code. RC_Failure if tables were not turned on.
  115. *
  116. * Globals:
  117. *
  118. * +++
  119. *
  120. * Notes:
  121. *
  122. ***************************************************************************/
  123. RC_TYPE STDCALL RcAddFcpPtbl(void)
  124. {
  125. MOBJ mobj;
  126. MOPG mopg;
  127. ASSERT(tbl.tbs == tbsOn);
  128. if (tbl.tbs != tbsOn)
  129. return RC_Failure;
  130. // prepare object header
  131. mobj.bType = (BYTE) FCTYPE_PARAGROUP;
  132. #ifdef MAGIC
  133. mobj.bMagic = bMagicMOBJ;
  134. #endif
  135. // Fill the paragroup object and get the compressed size
  136. VSetParaGroupObject(&mopg);
  137. mopg.libText = tbl.wParaTextBegin; // do correction
  138. // compress the group object
  139. void* qcopgT = szScratchBuf + sizeof(INT16) + sizeof(MOBJ);
  140. int cbCOPG = CbPackMOPG(&mopg, qcopgT);
  141. int cbNewCommands = pbfCommand->GetSize() - tbl.wParaCmdBegin;
  142. mobj.lcbSize = cbCOPG + cbNewCommands;
  143. /*
  144. * Object regions in the current object equals total in this fcp minus
  145. * total already output in this fcp.
  146. */
  147. mobj.wObjInfo = adrs.wObjrg - tbl.wObjrgTotal;
  148. tbl.wObjrgTotal = adrs.wObjrg;
  149. // pack the object header
  150. int cbCOBJ = CbPackMOBJ(&mobj, szScratchBuf + sizeof(INT16));
  151. memmove(szScratchBuf + sizeof(INT16) + cbCOBJ, qcopgT, cbCOPG);
  152. *(INT16 *) szScratchBuf = tbl.iCell;
  153. int cbInsert = cbCOPG + cbCOBJ + sizeof(INT16);
  154. /* REVIEW:
  155. * We now need to insert the data in szScratchBuf before the new
  156. * commands that we have just been adding to the command buffer. What we
  157. * really need here is a side-by-side buffer to copy everything to.
  158. */
  159. // Expand the buffer:
  160. if (pbfCommand->Add(szScratchBuf, cbInsert)) {
  161. PBYTE qbCmd = pbfCommand->pbMem;
  162. memmove(qbCmd + tbl.wParaCmdBegin + cbInsert,
  163. qbCmd + tbl.wParaCmdBegin, cbNewCommands);
  164. memcpy(qbCmd + tbl.wParaCmdBegin, szScratchBuf, cbInsert);
  165. tbl.wParaCmdBegin = pbfCommand->GetSize();
  166. tbl.wParaTextCompBegin = pbfText->GetSize();
  167. tbl.wParaTextBegin = wTextBufChCount;
  168. return RC_Success;
  169. }
  170. else
  171. return RC_OutOfMemory;
  172. }
  173. /***************************************************************************
  174. *
  175. - Name: CbSetTableHeader
  176. -
  177. * Purpose:
  178. * Fills out a buffer with the header information for a table FCP.
  179. *
  180. * Arguments:
  181. * qv: A pointer to the buffer.
  182. * ptbl: Pointer to table information.
  183. *
  184. * Returns:
  185. * Number of bytes copied to the buffer.
  186. *
  187. * Globals:
  188. *
  189. * +++
  190. *
  191. * Notes:
  192. * This function needs a better mechanism to avoid buffer overflow.
  193. * Currently, the buffer does not overflow because there is a limit
  194. * to the number of columns a table can have, and hence to the size
  195. * of the header information.
  196. *
  197. ***************************************************************************/
  198. int STDCALL CbSetTableHeader(void* pv)
  199. {
  200. MCOL* pmcol;
  201. UINT iCell;
  202. HP hpTotal;
  203. WORD* pi;
  204. MSBS* pmsbs = (MSBS*) pv;
  205. pmsbs->bcCol = (BYTE) tbl.cCell;
  206. pmsbs -> fAbsolute = (BYTE) tbl.fAbsolute;
  207. ASSERT(tbl.cCell > 0);
  208. if (!tbl.fAbsolute) {
  209. pi = (WORD*) (pmsbs + 1);
  210. hpTotal = tbl.rghpCellx[tbl.cCell-1];
  211. *pi = hpTotal;
  212. pmcol = (MCOL*) (pi + 1);
  213. }
  214. else
  215. pmcol = (MCOL*) (pmsbs + 1);
  216. pmcol->xWidthSpace = MAX(0, tbl.hpLeft + tbl.hpSpace);
  217. pmcol->xWidthColumn = MAX(1,
  218. tbl.rghpCellx[0] - pmcol->xWidthSpace - (tbl.hpSpace / 2));
  219. ++pmcol;
  220. for (iCell = 1; iCell < tbl.cCell; ++iCell, ++pmcol) {
  221. pmcol->xWidthSpace = tbl.hpSpace;
  222. pmcol->xWidthColumn = MAX(1,
  223. tbl.rghpCellx[iCell] - tbl.rghpCellx[iCell - 1] - tbl.hpSpace);
  224. }
  225. if (!tbl.fAbsolute) {
  226. pi = (WORD*) (pmsbs + 1);
  227. pmcol = (MCOL*) (pi + 1);
  228. for (iCell = 0; iCell < tbl.cCell; ++iCell, ++pmcol) {
  229. int savewidth = pmcol->xWidthSpace;
  230. pmcol->xWidthSpace = (WORD)
  231. (DWORD) pmcol->xWidthSpace * 0x7FFF / hpTotal;
  232. pmcol->xWidthColumn = (WORD)
  233. (DWORD) pmcol->xWidthColumn * 0x7FFF / hpTotal;
  234. }
  235. }
  236. return ((PBYTE) pmcol - (PBYTE) pv);
  237. }