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