Imported from antiword-0.37.tar.gz.
[antiword.git] / fontlist.c
blobd55efbb2edb2b9e6acac80d8c9f42122b5881b46
1 /*
2 * fontlist.c
3 * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL
5 * Description:
6 * Build, read and destroy a list of Word font information
7 */
9 #include <stdlib.h>
10 #include <stddef.h>
11 #include "antiword.h"
15 * Private structure to hide the way the information
16 * is stored from the rest of the program
18 typedef struct font_desc_tag {
19 font_block_type tInfo;
20 struct font_desc_tag *pNext;
21 } font_mem_type;
23 /* Variables needed to write the Font Information List */
24 static font_mem_type *pAnchor = NULL;
25 static font_mem_type *pFontLast = NULL;
29 * vDestroyFontInfoList - destroy the Font Information List
31 void
32 vDestroyFontInfoList(void)
34 font_mem_type *pCurr, *pNext;
36 DBG_MSG("vDestroyFontInfoList");
38 /* Free the Font Information List */
39 pCurr = pAnchor;
40 while (pCurr != NULL) {
41 pNext = pCurr->pNext;
42 pCurr = xfree(pCurr);
43 pCurr = pNext;
45 pAnchor = NULL;
46 /* Reset all control variables */
47 pFontLast = NULL;
48 } /* end of vDestroyFontInfoList */
51 * vCorrectFontValues - correct font values to values Antiword can use
53 void
54 vCorrectFontValues(font_block_type *pFontBlock)
56 UINT uiRealSize;
57 USHORT usRealStyle;
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;
67 if (bIsSuperscript(pFontBlock->usFontStyle) ||
68 bIsSubscript(pFontBlock->usFontStyle)) {
69 /* Superscript and subscript use a smaller fontsize */
70 uiRealSize = (uiRealSize * 2 + 1) / 3;
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;
81 pFontBlock->usFontSize = (USHORT)uiRealSize;
82 if (pFontBlock->ucFontColor == 8) {
83 /* White text to light gray text */
84 pFontBlock->ucFontColor = 16;
86 pFontBlock->usFontStyle = usRealStyle;
87 } /* end of vCorrectFontValues */
90 * vAdd2FontInfoList - Add an element to the Font Information List
92 void
93 vAdd2FontInfoList(const font_block_type *pFontBlock)
95 font_mem_type *pListMember;
97 fail(pFontBlock == NULL);
99 NO_DBG_MSG("bAdd2FontInfoList");
101 if (pFontBlock->ulFileOffset == FC_INVALID) {
103 * This offset is really past the end of the file,
104 * so don't waste any memory by storing it.
106 return;
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);
119 if (pFontLast != NULL &&
120 pFontLast->tInfo.ulFileOffset == pFontBlock->ulFileOffset) {
122 * If two consecutive fonts share the same
123 * offset, remember only the last font
125 fail(pFontLast->pNext != NULL);
126 pFontLast->tInfo = *pFontBlock;
127 return;
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;
144 pFontLast = pListMember;
145 } /* end of vAdd2FontInfoList */
148 * Get the record that follows the given recored in the Font Information List
150 const font_block_type *
151 pGetNextFontInfoListItem(const font_block_type *pCurr)
153 const font_mem_type *pRecord;
154 size_t tOffset;
156 if (pCurr == NULL) {
157 if (pAnchor == NULL) {
158 /* There are no records */
159 return NULL;
161 /* The first record is the only one without a predecessor */
162 return &pAnchor->tInfo;
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;
172 return &pRecord->pNext->tInfo;
173 } /* end of pGetNextFontInfoListItem */