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