Imported from antiword-0.36.tar.gz.
[antiword.git] / fontlist.c
blob9ea872bf59cc533f63c5554f3ae878637aa00375
1 /*
2 * fontlist.c
3 * Copyright (C) 1998-2002 A.J. van Os; Released under 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"
14 /* Variables needed to write the Font Information List */
15 static font_desc_type *pAnchor = NULL;
16 static font_desc_type *pFontLast = NULL;
20 * vDestroyFontInfoList - destroy the Font Information List
22 void
23 vDestroyFontInfoList(void)
25 font_desc_type *pCurr, *pNext;
27 DBG_MSG("vDestroyFontInfoList");
29 /* Free the Font Information List */
30 pCurr = pAnchor;
31 while (pCurr != NULL) {
32 pNext = pCurr->pNext;
33 pCurr = xfree(pCurr);
34 pCurr = pNext;
36 pAnchor = NULL;
37 /* Reset all control variables */
38 pFontLast = NULL;
39 } /* end of vDestroyFontInfoList */
42 * vCorrectFontValues - correct font values to values Antiword can use
44 void
45 vCorrectFontValues(font_block_type *pFontBlock)
47 UINT uiRealSize;
48 USHORT usRealStyle;
50 uiRealSize = pFontBlock->usFontSize;
51 usRealStyle = pFontBlock->usFontStyle;
52 if (bIsSmallCapitals(pFontBlock->usFontStyle)) {
53 /* Small capitals become normal capitals in a smaller font */
54 uiRealSize = (uiRealSize * 4 + 2) / 5;
55 usRealStyle &= ~FONT_SMALL_CAPITALS;
56 usRealStyle |= FONT_CAPITALS;
58 if (bIsSuperscript(pFontBlock->usFontStyle) ||
59 bIsSubscript(pFontBlock->usFontStyle)) {
60 /* Superscript and subscript use a smaller fontsize */
61 uiRealSize = (uiRealSize * 2 + 1) / 3;
64 if (uiRealSize < MIN_FONT_SIZE) {
65 DBG_DEC(uiRealSize);
66 uiRealSize = MIN_FONT_SIZE;
67 } else if (uiRealSize > MAX_FONT_SIZE) {
68 DBG_DEC(uiRealSize);
69 uiRealSize = MAX_FONT_SIZE;
72 pFontBlock->usFontSize = (USHORT)uiRealSize;
73 if (pFontBlock->ucFontColor == 8) {
74 /* White text to light gray text */
75 pFontBlock->ucFontColor = 16;
77 pFontBlock->usFontStyle = usRealStyle;
78 } /* end of vCorrectFontValues */
81 * vAdd2FontInfoList - Add an element to the Font Information List
83 void
84 vAdd2FontInfoList(const font_block_type *pFontBlock)
86 font_desc_type *pListMember;
88 fail(pFontBlock == NULL);
90 NO_DBG_MSG("bAdd2FontInfoList");
92 if (pFontBlock->ulFileOffset == FC_INVALID) {
94 * This offset is really past the end of the file,
95 * so don't waste any memory by storing it.
97 return;
100 NO_DBG_HEX(pFontBlock->ulFileOffset);
101 NO_DBG_DEC_C(pFontBlock->ucFontNumber != 0,
102 pFontBlock->ucFontNumber);
103 NO_DBG_DEC_C(pFontBlock->usFontSize != DEFAULT_FONT_SIZE,
104 pFontBlock->usFontSize);
105 NO_DBG_DEC_C(pFontBlock->ucFontColor != 0,
106 pFontBlock->ucFontColor);
107 NO_DBG_HEX_C(pFontBlock->usFontStyle != 0x00,
108 pFontBlock->usFontStyle);
110 if (pFontLast != NULL &&
111 pFontLast->tInfo.ulFileOffset == pFontBlock->ulFileOffset) {
113 * If two consecutive fonts share the same
114 * offset, remember only the last font
116 fail(pFontLast->pNext != NULL);
117 pFontLast->tInfo = *pFontBlock;
118 return;
121 /* Create list member */
122 pListMember = xmalloc(sizeof(font_desc_type));
123 /* Fill the list member */
124 pListMember->tInfo = *pFontBlock;
125 pListMember->pNext = NULL;
126 /* Correct the values where needed */
127 vCorrectFontValues(&pListMember->tInfo);
128 /* Add the new member to the list */
129 if (pAnchor == NULL) {
130 pAnchor = pListMember;
131 } else {
132 fail(pFontLast == NULL);
133 pFontLast->pNext = pListMember;
135 pFontLast = pListMember;
136 } /* end of vAdd2FontInfoList */
139 * Get the record that follows the given recored in the Font Information List
141 const font_block_type *
142 pGetNextFontInfoListItem(const font_block_type *pCurr)
144 const font_desc_type *pRecord;
145 size_t tOffset;
147 if (pCurr == NULL) {
148 if (pAnchor == NULL) {
149 /* There are no records */
150 return NULL;
152 /* The first record is the only one without a predecessor */
153 return &pAnchor->tInfo;
155 tOffset = offsetof(font_desc_type, tInfo);
156 /* Many casts to prevent alignment warnings */
157 pRecord = (font_desc_type *)(void *)((char *)pCurr - tOffset);
158 fail(pCurr != &pRecord->tInfo);
159 if (pRecord->pNext == NULL) {
160 /* The last record has no successor */
161 return NULL;
163 return &pRecord->pNext->tInfo;
164 } /* end of pGetNextFontInfoListItem */