home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / anwor032.zip / antiword.0.32 / fontlist.c < prev    next >
C/C++ Source or Header  |  2001-10-02  |  5KB  |  200 lines

  1. /*
  2.  * fontlist.c
  3.  * Copyright (C) 1998-2001 A.J. van Os; Released under GPL
  4.  *
  5.  * Description:
  6.  * Build, read and destroy a list of Word font information
  7.  */
  8.  
  9. #include <stdlib.h>
  10. #include <stddef.h>
  11. #include "antiword.h"
  12.  
  13.  
  14. /* Variables needed to write the Font Information List */
  15. static font_desc_type    *pAnchor = NULL;
  16. static font_desc_type    *pFontLast = NULL;
  17.  
  18.  
  19. /*
  20.  * vDestroyFontInfoList - destroy the Font Information List
  21.  */
  22. void
  23. vDestroyFontInfoList(void)
  24. {
  25.     font_desc_type    *pCurr, *pNext;
  26.  
  27.     DBG_MSG("vDestroyFontInfoList");
  28.  
  29.     /* Free the Font Information List */
  30.     pCurr = pAnchor;
  31.     while (pCurr != NULL) {
  32.         pNext = pCurr->pNext;
  33.         pCurr = xfree(pCurr);
  34.         pCurr = pNext;
  35.     }
  36.     pAnchor = NULL;
  37.     /* Reset all control variables */
  38.     pFontLast = NULL;
  39. } /* end of vDestroyFontInfoList */
  40.  
  41. /*
  42.  * vAdd2FontInfoList - Add an element to the Font Information List
  43.  */
  44. void
  45. vAdd2FontInfoList(const font_block_type *pFontBlock)
  46. {
  47.     font_desc_type    *pListMember;
  48.     int        iRealSize;
  49.     unsigned char    ucRealStyle;
  50.  
  51.     fail(pFontBlock == NULL);
  52.     fail(pFontBlock->lFileOffset < -1);
  53.  
  54.     NO_DBG_MSG("bAdd2FontInfoList");
  55.  
  56.     if (pFontBlock->lFileOffset < 0) {
  57.         /*
  58.          * This offset is really past the end of the file,
  59.          * so don't waste any memory by storing it.
  60.          */
  61.         return;
  62.     }
  63.  
  64.     iRealSize = pFontBlock->sFontsize;
  65.     ucRealStyle = pFontBlock->ucFontstyle;
  66.     if (bIsSmallCapitals(pFontBlock->ucFontstyle)) {
  67.         /* Small capitals become normal capitals in a smaller font */
  68.         iRealSize = (iRealSize * 8 + 5) / 10;
  69.         ucRealStyle &= ~FONT_SMALL_CAPITALS;
  70.         ucRealStyle |= FONT_CAPITALS;
  71.     }
  72.     if (iRealSize < MIN_FONT_SIZE) {
  73.         DBG_DEC(iRealSize);
  74.         iRealSize = MIN_FONT_SIZE;
  75.     } else if (iRealSize > MAX_FONT_SIZE) {
  76.         DBG_DEC(iRealSize);
  77.         iRealSize = MAX_FONT_SIZE;
  78.     }
  79.  
  80.     if (pFontLast != NULL &&
  81.         pFontLast->tInfo.ucFontnumber == pFontBlock->ucFontnumber &&
  82.         pFontLast->tInfo.sFontsize == iRealSize &&
  83.         pFontLast->tInfo.ucFontcolor == pFontBlock->ucFontcolor &&
  84.         pFontLast->tInfo.ucFontstyle == ucRealStyle) {
  85.         /*
  86.          * The new record would be the same as the one last added
  87.          * to the list and is therefore redundant
  88.          */
  89.         return;
  90.     }
  91.  
  92.     NO_DBG_HEX(pFontBlock->iFileOffset);
  93.     NO_DBG_DEC_C(pFontBlock->ucFontnumber != 0,
  94.                     pFontBlock->ucFontnumber);
  95.     NO_DBG_DEC_C(pFontBlock->sFontsize != DEFAULT_FONT_SIZE,
  96.                     pFontBlock->sFontsize);
  97.     NO_DBG_DEC_C(pFontBlock->ucFontcolor != 0,
  98.                     pFontBlock->ucFontcolor);
  99.     NO_DBG_HEX_C(pFontBlock->ucFontstyle != 0x00,
  100.                     pFontBlock->ucFontstyle);
  101.  
  102.     if (pFontLast != NULL &&
  103.         pFontLast->tInfo.lFileOffset == pFontBlock->lFileOffset) {
  104.         /*
  105.          * If two consecutive fonts share the same
  106.          * offset, remember only the last font
  107.          */
  108.         fail(pFontLast->pNext != NULL);
  109.         pFontLast->tInfo = *pFontBlock;
  110.         return;
  111.     }
  112.  
  113.     /* Create list member */
  114.     pListMember = xmalloc(sizeof(font_desc_type));
  115.     /* Fill the list member */
  116.     pListMember->tInfo = *pFontBlock;
  117.     pListMember->pNext = NULL;
  118.     /* Correct the values where needed */
  119.     pListMember->tInfo.sFontsize = (short)iRealSize;
  120.     pListMember->tInfo.ucFontstyle = ucRealStyle;
  121.     /* Add the new member to the list */
  122.     if (pAnchor == NULL) {
  123.         pAnchor = pListMember;
  124.     } else {
  125.         fail(pFontLast == NULL);
  126.         pFontLast->pNext = pListMember;
  127.     }
  128.     pFontLast = pListMember;
  129. } /* end of vAdd2FontInfoList */
  130.  
  131. /*
  132.  * vReset2FontInfoList - Add a reset element to the Font Information List
  133.  */
  134. void
  135. vReset2FontInfoList(long lFileOffset)
  136. {
  137.     font_block_type    tFontBlock;
  138.  
  139.     fail(lFileOffset < -1);
  140.  
  141.     NO_DBG_MSG("bReset2FontInfoList");
  142.  
  143.     if (lFileOffset < 0) {
  144.         /*
  145.          * This offset is really past the end of the file,
  146.          * so don't waste any memory by storing it.
  147.          */
  148.         return;
  149.     }
  150.  
  151.     if (pFontLast == NULL) {
  152.         /* There are no values to reset */
  153.         return;
  154.     }
  155.     if (pFontLast->tInfo.ucFontstyle == FONT_REGULAR &&
  156.         pFontLast->tInfo.sFontsize == DEFAULT_FONT_SIZE &&
  157.         pFontLast->tInfo.ucFontnumber == 0 &&
  158.         pFontLast->tInfo.ucFontcolor == FONT_COLOR_DEFAULT) {
  159.         /* All values are at their defaults, no reset is needed */
  160.         return;
  161.     }
  162.     /* Copy and set the default values */
  163.     tFontBlock = pFontLast->tInfo;
  164.     tFontBlock.lFileOffset = lFileOffset;
  165.     tFontBlock.ucFontnumber = 0;
  166.     tFontBlock.sFontsize = DEFAULT_FONT_SIZE;
  167.     tFontBlock.ucFontcolor = FONT_COLOR_DEFAULT;
  168.     tFontBlock.ucFontstyle = FONT_REGULAR;
  169.     /* Add the block to the list */
  170.     vAdd2FontInfoList(&tFontBlock);
  171. } /* end of vReset2FontInfoList */
  172.  
  173. /*
  174.  * Get the record that follows the given recored in the Font Information List
  175.  */
  176. const font_block_type *
  177. pGetNextFontInfoListItem(const font_block_type *pCurr)
  178. {
  179.     const font_desc_type    *pRecord;
  180.     size_t    tOffset;
  181.  
  182.     if (pCurr == NULL) {
  183.         if (pAnchor == NULL) {
  184.             /* There are no records */
  185.             return NULL;
  186.         }
  187.         /* The first record is the only one without a predecessor */
  188.         return &pAnchor->tInfo;
  189.     }
  190.     tOffset = offsetof(font_desc_type, tInfo);
  191.     /* Many casts to prevent alignment warnings */
  192.     pRecord = (font_desc_type *)(void *)((char *)pCurr - tOffset);
  193.     fail(pCurr != &pRecord->tInfo);
  194.     if (pRecord->pNext == NULL) {
  195.         /* The last record has no successor */
  196.         return NULL;
  197.     }
  198.     return &pRecord->pNext->tInfo;
  199. } /* end of pGetNextFontInfoListItem */
  200.