hdrftrlist.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /*
  2. * hdrftrlist.c
  3. * Copyright (C) 2004,2005 A.J. van Os; Released under GNU GPL
  4. *
  5. * Description:
  6. * Build, read and destroy list(s) of Word Header/footer information
  7. */
  8. #include <string.h>
  9. #include "antiword.h"
  10. #define HDR_EVEN_PAGES 0
  11. #define HDR_ODD_PAGES 1
  12. #define FTR_EVEN_PAGES 2
  13. #define FTR_ODD_PAGES 3
  14. #define HDR_FIRST_PAGE 4
  15. #define FTR_FIRST_PAGE 5
  16. /*
  17. * Private structures to hide the way the information
  18. * is stored from the rest of the program
  19. */
  20. typedef struct hdrftr_local_tag {
  21. hdrftr_block_type tInfo;
  22. ULONG ulCharPosStart;
  23. ULONG ulCharPosNext;
  24. BOOL bUseful;
  25. BOOL bTextOriginal;
  26. } hdrftr_local_type;
  27. typedef struct hdrftr_mem_tag {
  28. hdrftr_local_type atElement[6];
  29. } hdrftr_mem_type;
  30. /* Variables needed to write the Header/footer Information List */
  31. static hdrftr_mem_type *pHdrFtrList = NULL;
  32. static size_t tHdrFtrLen = 0;
  33. /*
  34. * vDestroyHdrFtrInfoList - destroy the Header/footer Information List
  35. */
  36. void
  37. vDestroyHdrFtrInfoList(void)
  38. {
  39. hdrftr_mem_type *pRecord;
  40. output_type *pCurr, *pNext;
  41. size_t tHdrFtr, tIndex;
  42. DBG_MSG("vDestroyHdrFtrInfoList");
  43. /* Free the Header/footer Information List */
  44. for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
  45. pRecord = pHdrFtrList + tHdrFtr;
  46. for (tIndex = 0;
  47. tIndex < elementsof(pRecord->atElement);
  48. tIndex++) {
  49. if (!pRecord->atElement[tIndex].bTextOriginal) {
  50. continue;
  51. }
  52. pCurr = pRecord->atElement[tIndex].tInfo.pText;
  53. while (pCurr != NULL) {
  54. pCurr->szStorage = xfree(pCurr->szStorage);
  55. pNext = pCurr->pNext;
  56. pCurr = xfree(pCurr);
  57. pCurr = pNext;
  58. }
  59. }
  60. }
  61. pHdrFtrList = xfree(pHdrFtrList);
  62. /* Reset all control variables */
  63. tHdrFtrLen = 0;
  64. } /* end of vDestroyHdrFtrInfoList */
  65. /*
  66. * vCreat8HdrFtrInfoList - Create the Header/footer Information List
  67. */
  68. void
  69. vCreat8HdrFtrInfoList(const ULONG *aulCharPos, size_t tLength)
  70. {
  71. hdrftr_mem_type *pListMember;
  72. size_t tHdrFtr, tIndex, tMainIndex;
  73. fail(aulCharPos == NULL);
  74. DBG_DEC(tLength);
  75. if (tLength <= 1) {
  76. return;
  77. }
  78. tHdrFtrLen = tLength / 12;
  79. if (tLength % 12 != 0 && tLength % 12 != 1) {
  80. tHdrFtrLen++;
  81. }
  82. DBG_DEC(tHdrFtrLen);
  83. pHdrFtrList = xcalloc(tHdrFtrLen, sizeof(hdrftr_mem_type));
  84. for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
  85. pListMember = pHdrFtrList + tHdrFtr;
  86. for (tIndex = 0, tMainIndex = tHdrFtr * 12;
  87. tIndex < 6 && tMainIndex < tLength;
  88. tIndex++, tMainIndex++) {
  89. pListMember->atElement[tIndex].tInfo.pText = NULL;
  90. pListMember->atElement[tIndex].ulCharPosStart =
  91. aulCharPos[tMainIndex];
  92. if (tMainIndex + 1 < tLength) {
  93. pListMember->atElement[tIndex].ulCharPosNext =
  94. aulCharPos[tMainIndex + 1];
  95. } else {
  96. pListMember->atElement[tIndex].ulCharPosNext =
  97. aulCharPos[tMainIndex];
  98. }
  99. }
  100. }
  101. } /* end of vCreat8HdrFtrInfoList */
  102. /*
  103. * vCreat6HdrFtrInfoList - Create the Header/footer Information List
  104. */
  105. void
  106. vCreat6HdrFtrInfoList(const ULONG *aulCharPos, size_t tLength)
  107. {
  108. static const size_t atIndex[] =
  109. { SIZE_T_MAX, SIZE_T_MAX, FTR_FIRST_PAGE, HDR_FIRST_PAGE,
  110. FTR_ODD_PAGES, FTR_EVEN_PAGES, HDR_ODD_PAGES, HDR_EVEN_PAGES,
  111. };
  112. hdrftr_mem_type *pListMember;
  113. size_t tHdrFtr, tTmp, tIndex, tMainIndex, tBit;
  114. UCHAR ucDopSpecification, ucSepSpecification;
  115. fail(aulCharPos == NULL);
  116. DBG_DEC(tLength);
  117. if (tLength <= 1) {
  118. return;
  119. }
  120. tHdrFtrLen = tGetNumberOfSections();
  121. if (tHdrFtrLen == 0) {
  122. tHdrFtrLen = 1;
  123. }
  124. DBG_DEC(tHdrFtrLen);
  125. pHdrFtrList = xcalloc(tHdrFtrLen, sizeof(hdrftr_mem_type));
  126. /* Get the start index in aulCharPos */
  127. ucDopSpecification = ucGetDopHdrFtrSpecification();
  128. DBG_HEX(ucDopSpecification & 0xe0);
  129. tMainIndex = 0;
  130. for (tBit = 7; tBit >= 5; tBit--) {
  131. if ((ucDopSpecification & BIT(tBit)) != 0) {
  132. tMainIndex++;
  133. }
  134. }
  135. DBG_DEC(tMainIndex);
  136. for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
  137. ucSepSpecification = ucGetSepHdrFtrSpecification(tHdrFtr);
  138. DBG_HEX(ucSepSpecification & 0xfc);
  139. pListMember = pHdrFtrList + tHdrFtr;
  140. for (tTmp = 0;
  141. tTmp < elementsof(pListMember->atElement);
  142. tTmp++) {
  143. pListMember->atElement[tTmp].tInfo.pText = NULL;
  144. }
  145. for (tBit = 7; tBit >= 2; tBit--) {
  146. if (tMainIndex >= tLength) {
  147. break;
  148. }
  149. if ((ucSepSpecification & BIT(tBit)) == 0) {
  150. continue;
  151. }
  152. tIndex = atIndex[tBit];
  153. fail(tIndex >= 6);
  154. pListMember->atElement[tIndex].ulCharPosStart =
  155. aulCharPos[tMainIndex];
  156. if (tMainIndex + 1 < tLength) {
  157. pListMember->atElement[tIndex].ulCharPosNext =
  158. aulCharPos[tMainIndex + 1];
  159. } else {
  160. pListMember->atElement[tIndex].ulCharPosNext =
  161. aulCharPos[tMainIndex];
  162. }
  163. tMainIndex++;
  164. }
  165. }
  166. } /* end of vCreat6HdrFtrInfoList */
  167. /*
  168. * vCreat2HdrFtrInfoList - Create the Header/footer Information List
  169. */
  170. void
  171. vCreat2HdrFtrInfoList(const ULONG *aulCharPos, size_t tLength)
  172. {
  173. vCreat6HdrFtrInfoList(aulCharPos, tLength);
  174. } /* end of vCreat2HdrFtrInfoList */
  175. /*
  176. * pGetHdrFtrInfo - get the Header/footer information
  177. */
  178. const hdrftr_block_type *
  179. pGetHdrFtrInfo(int iSectionIndex,
  180. BOOL bWantHeader, BOOL bOddPage, BOOL bFirstInSection)
  181. {
  182. hdrftr_mem_type *pCurr;
  183. fail(iSectionIndex < 0);
  184. fail(pHdrFtrList == NULL && tHdrFtrLen != 0);
  185. if (pHdrFtrList == NULL || tHdrFtrLen == 0) {
  186. /* No information */
  187. return NULL;
  188. }
  189. if (iSectionIndex < 0) {
  190. iSectionIndex = 0;
  191. } else if (iSectionIndex >= (int)tHdrFtrLen) {
  192. iSectionIndex = (int)(tHdrFtrLen - 1);
  193. }
  194. pCurr = pHdrFtrList + iSectionIndex;
  195. if (bFirstInSection) {
  196. if (bWantHeader) {
  197. return &pCurr->atElement[HDR_FIRST_PAGE].tInfo;
  198. } else {
  199. return &pCurr->atElement[FTR_FIRST_PAGE].tInfo;
  200. }
  201. } else {
  202. if (bWantHeader) {
  203. if (bOddPage) {
  204. return &pCurr->atElement[HDR_ODD_PAGES].tInfo;
  205. } else {
  206. return &pCurr->atElement[HDR_EVEN_PAGES].tInfo;
  207. }
  208. } else {
  209. if (bOddPage) {
  210. return &pCurr->atElement[FTR_ODD_PAGES].tInfo;
  211. } else {
  212. return &pCurr->atElement[FTR_EVEN_PAGES].tInfo;
  213. }
  214. }
  215. }
  216. } /* end of pGetHdrFtrInfo */
  217. /*
  218. * lComputeHdrFtrHeight - compute the height of a header or footer
  219. *
  220. * Returns the height in DrawUnits
  221. */
  222. static long
  223. lComputeHdrFtrHeight(const output_type *pAnchor)
  224. {
  225. const output_type *pCurr;
  226. long lTotal;
  227. USHORT usFontSizeMax;
  228. lTotal = 0;
  229. usFontSizeMax = 0;
  230. for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
  231. if (pCurr->tNextFree == 1) {
  232. if (pCurr->szStorage[0] == PAR_END) {
  233. /* End of a paragraph */
  234. lTotal += lComputeLeading(usFontSizeMax);
  235. lTotal += lMilliPoints2DrawUnits(
  236. (long)pCurr->usFontSize * 200);
  237. usFontSizeMax = 0;
  238. continue;
  239. }
  240. if (pCurr->szStorage[0] == HARD_RETURN) {
  241. /* End of a line */
  242. lTotal += lComputeLeading(usFontSizeMax);
  243. usFontSizeMax = 0;
  244. continue;
  245. }
  246. }
  247. if (pCurr->usFontSize > usFontSizeMax) {
  248. usFontSizeMax = pCurr->usFontSize;
  249. }
  250. }
  251. if (usFontSizeMax != 0) {
  252. /* Height of the last paragraph */
  253. lTotal += lComputeLeading(usFontSizeMax);
  254. }
  255. return lTotal;
  256. } /* end of lComputeHdrFtrHeight */
  257. /*
  258. * vPrepareHdrFtrText - prepare the header/footer text
  259. */
  260. void
  261. vPrepareHdrFtrText(FILE *pFile)
  262. {
  263. hdrftr_mem_type *pCurr, *pPrev;
  264. hdrftr_local_type *pTmp;
  265. output_type *pText;
  266. size_t tHdrFtr, tIndex;
  267. fail(pFile == NULL);
  268. fail(pHdrFtrList == NULL && tHdrFtrLen != 0);
  269. if (pHdrFtrList == NULL || tHdrFtrLen == 0) {
  270. /* No information */
  271. return;
  272. }
  273. /* Fill text, text height and useful-ness */
  274. for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
  275. pCurr = pHdrFtrList + tHdrFtr;
  276. for (tIndex = 0;
  277. tIndex < elementsof(pHdrFtrList->atElement);
  278. tIndex++) {
  279. pTmp = &pCurr->atElement[tIndex];
  280. pTmp->bUseful =
  281. pTmp->ulCharPosStart != pTmp->ulCharPosNext;
  282. if (pTmp->bUseful) {
  283. pText = pHdrFtrDecryptor(pFile,
  284. pTmp->ulCharPosStart,
  285. pTmp->ulCharPosNext);
  286. pTmp->tInfo.pText = pText;
  287. pTmp->tInfo.lHeight =
  288. lComputeHdrFtrHeight(pText);
  289. pTmp->bTextOriginal = pText != NULL;
  290. } else {
  291. pTmp->tInfo.pText = NULL;
  292. pTmp->tInfo.lHeight = 0;
  293. pTmp->bTextOriginal = FALSE;
  294. }
  295. }
  296. }
  297. /* Replace not-useful records by using inheritance */
  298. if (pHdrFtrList->atElement[HDR_FIRST_PAGE].bUseful) {
  299. pTmp = &pHdrFtrList->atElement[HDR_ODD_PAGES];
  300. if (!pTmp->bUseful) {
  301. *pTmp = pHdrFtrList->atElement[HDR_FIRST_PAGE];
  302. pTmp->bTextOriginal = FALSE;
  303. }
  304. pTmp = &pHdrFtrList->atElement[HDR_EVEN_PAGES];
  305. if (!pTmp->bUseful) {
  306. *pTmp = pHdrFtrList->atElement[HDR_FIRST_PAGE];
  307. pTmp->bTextOriginal = FALSE;
  308. }
  309. }
  310. if (pHdrFtrList->atElement[FTR_FIRST_PAGE].bUseful) {
  311. pTmp = &pHdrFtrList->atElement[FTR_ODD_PAGES];
  312. if (!pTmp->bUseful) {
  313. *pTmp = pHdrFtrList->atElement[FTR_FIRST_PAGE];
  314. pTmp->bTextOriginal = FALSE;
  315. }
  316. pTmp = &pHdrFtrList->atElement[FTR_EVEN_PAGES];
  317. if (!pTmp->bUseful) {
  318. *pTmp = pHdrFtrList->atElement[FTR_FIRST_PAGE];
  319. pTmp->bTextOriginal = FALSE;
  320. }
  321. }
  322. for (tHdrFtr = 1, pCurr = &pHdrFtrList[1];
  323. tHdrFtr < tHdrFtrLen;
  324. tHdrFtr++, pCurr++) {
  325. pPrev = pCurr - 1;
  326. for (tIndex = 0;
  327. tIndex < elementsof(pHdrFtrList->atElement);
  328. tIndex++) {
  329. if (!pCurr->atElement[tIndex].bUseful &&
  330. pPrev->atElement[tIndex].bUseful) {
  331. pCurr->atElement[tIndex] =
  332. pPrev->atElement[tIndex];
  333. pCurr->atElement[tIndex].bTextOriginal = FALSE;
  334. }
  335. }
  336. }
  337. } /* end of vPrepareHdrFtrText */