examples/PIPS/antiword/src/fontlist.c

00001 /*
00002  * fontlist.c
00003  * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL
00004  *
00005  * Description:
00006  * Build, read and destroy a list of Word font information
00007  */
00008 
00009 #include <stdlib.h>
00010 #include <stddef.h>
00011 #include "antiword.h"
00012 
00013 
00014 /*
00015  * Private structure to hide the way the information
00016  * is stored from the rest of the program
00017  */
00018 typedef struct font_desc_tag {
00019         font_block_type tInfo;
00020         struct font_desc_tag    *pNext;
00021 } font_mem_type;
00022 
00023 /* Variables needed to write the Font Information List */
00024 static font_mem_type    *pAnchor = NULL;
00025 static font_mem_type    *pFontLast = NULL;
00026 
00027 
00028 /*
00029  * vDestroyFontInfoList - destroy the Font Information List
00030  */
00031 void
00032 vDestroyFontInfoList(void)
00033 {
00034         font_mem_type   *pCurr, *pNext;
00035 
00036         DBG_MSG("vDestroyFontInfoList");
00037 
00038         /* Free the Font Information List */
00039         pCurr = pAnchor;
00040         while (pCurr != NULL) {
00041                 pNext = pCurr->pNext;
00042                 pCurr = xfree(pCurr);
00043                 pCurr = pNext;
00044         }
00045         pAnchor = NULL;
00046         /* Reset all control variables */
00047         pFontLast = NULL;
00048 } /* end of vDestroyFontInfoList */
00049 
00050 /*
00051  * vCorrectFontValues - correct font values to values Antiword can use
00052  */
00053 void
00054 vCorrectFontValues(font_block_type *pFontBlock)
00055 {
00056         UINT    uiRealSize;
00057         USHORT  usRealStyle;
00058 
00059         uiRealSize = pFontBlock->usFontSize;
00060         usRealStyle = pFontBlock->usFontStyle;
00061         if (bIsSmallCapitals(pFontBlock->usFontStyle)) {
00062                 /* Small capitals become normal capitals in a smaller font */
00063                 uiRealSize = (uiRealSize * 4 + 2) / 5;
00064                 usRealStyle &= ~FONT_SMALL_CAPITALS;
00065                 usRealStyle |= FONT_CAPITALS;
00066         }
00067         if (bIsSuperscript(pFontBlock->usFontStyle) ||
00068             bIsSubscript(pFontBlock->usFontStyle)) {
00069                 /* Superscript and subscript use a smaller fontsize */
00070                 uiRealSize = (uiRealSize * 2 + 1) / 3;
00071         }
00072 
00073         if (uiRealSize < MIN_FONT_SIZE) {
00074                 DBG_DEC(uiRealSize);
00075                 uiRealSize = MIN_FONT_SIZE;
00076         } else if (uiRealSize > MAX_FONT_SIZE) {
00077                 DBG_DEC(uiRealSize);
00078                 uiRealSize = MAX_FONT_SIZE;
00079         }
00080 
00081         pFontBlock->usFontSize = (USHORT)uiRealSize;
00082         if (pFontBlock->ucFontColor == 8) {
00083                 /* White text to light gray text */
00084                 pFontBlock->ucFontColor = 16;
00085         }
00086         pFontBlock->usFontStyle = usRealStyle;
00087 } /* end of vCorrectFontValues */
00088 
00089 /*
00090  * vAdd2FontInfoList - Add an element to the Font Information List
00091  */
00092 void
00093 vAdd2FontInfoList(const font_block_type *pFontBlock)
00094 {
00095         font_mem_type   *pListMember;
00096 
00097         fail(pFontBlock == NULL);
00098 
00099         NO_DBG_MSG("bAdd2FontInfoList");
00100 
00101         if (pFontBlock->ulFileOffset == FC_INVALID) {
00102                 /*
00103                  * This offset is really past the end of the file,
00104                  * so don't waste any memory by storing it.
00105                  */
00106                 return;
00107         }
00108 
00109         NO_DBG_HEX(pFontBlock->ulFileOffset);
00110         NO_DBG_DEC_C(pFontBlock->ucFontNumber != 0,
00111                                         pFontBlock->ucFontNumber);
00112         NO_DBG_DEC_C(pFontBlock->usFontSize != DEFAULT_FONT_SIZE,
00113                                         pFontBlock->usFontSize);
00114         NO_DBG_DEC_C(pFontBlock->ucFontColor != 0,
00115                                         pFontBlock->ucFontColor);
00116         NO_DBG_HEX_C(pFontBlock->usFontStyle != 0x00,
00117                                         pFontBlock->usFontStyle);
00118 
00119         if (pFontLast != NULL &&
00120             pFontLast->tInfo.ulFileOffset == pFontBlock->ulFileOffset) {
00121                 /*
00122                  * If two consecutive fonts share the same
00123                  * offset, remember only the last font
00124                  */
00125                 fail(pFontLast->pNext != NULL);
00126                 pFontLast->tInfo = *pFontBlock;
00127                 return;
00128         }
00129 
00130         /* Create list member */
00131         pListMember = xmalloc(sizeof(font_mem_type));
00132         /* Fill the list member */
00133         pListMember->tInfo = *pFontBlock;
00134         pListMember->pNext = NULL;
00135         /* Correct the values where needed */
00136         vCorrectFontValues(&pListMember->tInfo);
00137         /* Add the new member to the list */
00138         if (pAnchor == NULL) {
00139                 pAnchor = pListMember;
00140         } else {
00141                 fail(pFontLast == NULL);
00142                 pFontLast->pNext = pListMember;
00143         }
00144         pFontLast = pListMember;
00145 } /* end of vAdd2FontInfoList */
00146 
00147 /*
00148  * Get the record that follows the given recored in the Font Information List
00149  */
00150 const font_block_type *
00151 pGetNextFontInfoListItem(const font_block_type *pCurr)
00152 {
00153         const font_mem_type     *pRecord;
00154         size_t  tOffset;
00155 
00156         if (pCurr == NULL) {
00157                 if (pAnchor == NULL) {
00158                         /* There are no records */
00159                         return NULL;
00160                 }
00161                 /* The first record is the only one without a predecessor */
00162                 return &pAnchor->tInfo;
00163         }
00164         tOffset = offsetof(font_mem_type, tInfo);
00165         /* Many casts to prevent alignment warnings */
00166         pRecord = (font_mem_type *)(void *)((char *)pCurr - tOffset);
00167         fail(pCurr != &pRecord->tInfo);
00168         if (pRecord->pNext == NULL) {
00169                 /* The last record has no successor */
00170                 return NULL;
00171         }
00172         return &pRecord->pNext->tInfo;
00173 } /* end of pGetNextFontInfoListItem */

Generated by  doxygen 1.6.2