fontlist.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * fontlist.c
  3. * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL
  4. *
  5. * Description:
  6. * Build, read and destroy a list of Word font information
  7. */
  8. #include <stdlib.h>
  9. #include <stddef.h>
  10. #include "antiword.h"
  11. /*
  12. * Private structure to hide the way the information
  13. * is stored from the rest of the program
  14. */
  15. typedef struct font_desc_tag {
  16. font_block_type tInfo;
  17. struct font_desc_tag *pNext;
  18. } font_mem_type;
  19. /* Variables needed to write the Font Information List */
  20. static font_mem_type *pAnchor = NULL;
  21. static font_mem_type *pFontLast = NULL;
  22. /*
  23. * vDestroyFontInfoList - destroy the Font Information List
  24. */
  25. void
  26. vDestroyFontInfoList(void)
  27. {
  28. font_mem_type *pCurr, *pNext;
  29. DBG_MSG("vDestroyFontInfoList");
  30. /* Free the Font Information List */
  31. pCurr = pAnchor;
  32. while (pCurr != NULL) {
  33. pNext = pCurr->pNext;
  34. pCurr = xfree(pCurr);
  35. pCurr = pNext;
  36. }
  37. pAnchor = NULL;
  38. /* Reset all control variables */
  39. pFontLast = NULL;
  40. } /* end of vDestroyFontInfoList */
  41. /*
  42. * vCorrectFontValues - correct font values to values Antiword can use
  43. */
  44. void
  45. vCorrectFontValues(font_block_type *pFontBlock)
  46. {
  47. UINT uiRealSize;
  48. USHORT usRealStyle;
  49. uiRealSize = pFontBlock->usFontSize;
  50. usRealStyle = pFontBlock->usFontStyle;
  51. if (bIsSmallCapitals(pFontBlock->usFontStyle)) {
  52. /* Small capitals become normal capitals in a smaller font */
  53. uiRealSize = (uiRealSize * 4 + 2) / 5;
  54. usRealStyle &= ~FONT_SMALL_CAPITALS;
  55. usRealStyle |= FONT_CAPITALS;
  56. }
  57. if (bIsSuperscript(pFontBlock->usFontStyle) ||
  58. bIsSubscript(pFontBlock->usFontStyle)) {
  59. /* Superscript and subscript use a smaller fontsize */
  60. uiRealSize = (uiRealSize * 2 + 1) / 3;
  61. }
  62. if (uiRealSize < MIN_FONT_SIZE) {
  63. DBG_DEC(uiRealSize);
  64. uiRealSize = MIN_FONT_SIZE;
  65. } else if (uiRealSize > MAX_FONT_SIZE) {
  66. DBG_DEC(uiRealSize);
  67. uiRealSize = MAX_FONT_SIZE;
  68. }
  69. pFontBlock->usFontSize = (USHORT)uiRealSize;
  70. if (pFontBlock->ucFontColor == 8) {
  71. /* White text to light gray text */
  72. pFontBlock->ucFontColor = 16;
  73. }
  74. pFontBlock->usFontStyle = usRealStyle;
  75. } /* end of vCorrectFontValues */
  76. /*
  77. * vAdd2FontInfoList - Add an element to the Font Information List
  78. */
  79. void
  80. vAdd2FontInfoList(const font_block_type *pFontBlock)
  81. {
  82. font_mem_type *pListMember;
  83. fail(pFontBlock == NULL);
  84. NO_DBG_MSG("bAdd2FontInfoList");
  85. if (pFontBlock->ulFileOffset == FC_INVALID) {
  86. /*
  87. * This offset is really past the end of the file,
  88. * so don't waste any memory by storing it.
  89. */
  90. return;
  91. }
  92. NO_DBG_HEX(pFontBlock->ulFileOffset);
  93. NO_DBG_DEC_C(pFontBlock->ucFontNumber != 0,
  94. pFontBlock->ucFontNumber);
  95. NO_DBG_DEC_C(pFontBlock->usFontSize != DEFAULT_FONT_SIZE,
  96. pFontBlock->usFontSize);
  97. NO_DBG_DEC_C(pFontBlock->ucFontColor != 0,
  98. pFontBlock->ucFontColor);
  99. NO_DBG_HEX_C(pFontBlock->usFontStyle != 0x00,
  100. pFontBlock->usFontStyle);
  101. if (pFontLast != NULL &&
  102. pFontLast->tInfo.ulFileOffset == pFontBlock->ulFileOffset) {
  103. /*
  104. * If two consecutive fonts share the same
  105. * offset, remember only the last font
  106. */
  107. fail(pFontLast->pNext != NULL);
  108. pFontLast->tInfo = *pFontBlock;
  109. return;
  110. }
  111. /* Create list member */
  112. pListMember = xmalloc(sizeof(font_mem_type));
  113. /* Fill the list member */
  114. pListMember->tInfo = *pFontBlock;
  115. pListMember->pNext = NULL;
  116. /* Correct the values where needed */
  117. vCorrectFontValues(&pListMember->tInfo);
  118. /* Add the new member to the list */
  119. if (pAnchor == NULL) {
  120. pAnchor = pListMember;
  121. } else {
  122. fail(pFontLast == NULL);
  123. pFontLast->pNext = pListMember;
  124. }
  125. pFontLast = pListMember;
  126. } /* end of vAdd2FontInfoList */
  127. /*
  128. * Get the record that follows the given recored in the Font Information List
  129. */
  130. const font_block_type *
  131. pGetNextFontInfoListItem(const font_block_type *pCurr)
  132. {
  133. const font_mem_type *pRecord;
  134. size_t tOffset;
  135. if (pCurr == NULL) {
  136. if (pAnchor == NULL) {
  137. /* There are no records */
  138. return NULL;
  139. }
  140. /* The first record is the only one without a predecessor */
  141. return &pAnchor->tInfo;
  142. }
  143. tOffset = offsetof(font_mem_type, tInfo);
  144. /* Many casts to prevent alignment warnings */
  145. pRecord = (font_mem_type *)(void *)((char *)pCurr - tOffset);
  146. fail(pCurr != &pRecord->tInfo);
  147. if (pRecord->pNext == NULL) {
  148. /* The last record has no successor */
  149. return NULL;
  150. }
  151. return &pRecord->pNext->tInfo;
  152. } /* end of pGetNextFontInfoListItem */