/*
* 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 */
|