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