examples/PIPS/antiword/src/hdrftrlist.c

00001 /*
00002  * hdrftrlist.c
00003  * Copyright (C) 2004,2005 A.J. van Os; Released under GNU GPL
00004  *
00005  * Description:
00006  * Build, read and destroy list(s) of Word Header/footer information
00007  */
00008 
00009 #include <string.h>
00010 #include "antiword.h"
00011 
00012 
00013 #define HDR_EVEN_PAGES  0
00014 #define HDR_ODD_PAGES   1
00015 #define FTR_EVEN_PAGES  2
00016 #define FTR_ODD_PAGES   3
00017 #define HDR_FIRST_PAGE  4
00018 #define FTR_FIRST_PAGE  5
00019 
00020 /*
00021  * Private structures to hide the way the information
00022  * is stored from the rest of the program
00023  */
00024 typedef struct hdrftr_local_tag {
00025         hdrftr_block_type       tInfo;
00026         ULONG                   ulCharPosStart;
00027         ULONG                   ulCharPosNext;
00028         BOOL                    bUseful;
00029         BOOL                    bTextOriginal;
00030 } hdrftr_local_type;
00031 typedef struct hdrftr_mem_tag {
00032         hdrftr_local_type       atElement[6];
00033 } hdrftr_mem_type;
00034 
00035 /* Variables needed to write the Header/footer Information List */
00036 static hdrftr_mem_type  *pHdrFtrList = NULL;
00037 static size_t           tHdrFtrLen = 0;
00038 
00039 
00040 /*
00041  * vDestroyHdrFtrInfoList - destroy the Header/footer Information List
00042  */
00043 void
00044 vDestroyHdrFtrInfoList(void)
00045 {
00046         hdrftr_mem_type *pRecord;
00047         output_type     *pCurr, *pNext;
00048         size_t          tHdrFtr, tIndex;
00049 
00050         DBG_MSG("vDestroyHdrFtrInfoList");
00051 
00052         /* Free the Header/footer Information List */
00053         for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
00054                 pRecord = pHdrFtrList + tHdrFtr;
00055                 for (tIndex = 0;
00056                      tIndex < elementsof(pRecord->atElement);
00057                      tIndex++) {
00058                         if (!pRecord->atElement[tIndex].bTextOriginal) {
00059                                 continue;
00060                         }
00061                         pCurr = pRecord->atElement[tIndex].tInfo.pText;
00062                         while (pCurr != NULL) {
00063                                 pCurr->szStorage = xfree(pCurr->szStorage);
00064                                 pNext = pCurr->pNext;
00065                                 pCurr = xfree(pCurr);
00066                                 pCurr = pNext;
00067                         }
00068                 }
00069         }
00070         pHdrFtrList = xfree(pHdrFtrList);
00071         /* Reset all control variables */
00072         tHdrFtrLen = 0;
00073 } /* end of vDestroyHdrFtrInfoList */
00074 
00075 /*
00076  * vCreat8HdrFtrInfoList - Create the Header/footer Information List
00077  */
00078 void
00079 vCreat8HdrFtrInfoList(const ULONG *aulCharPos, size_t tLength)
00080 {
00081         hdrftr_mem_type *pListMember;
00082         size_t  tHdrFtr, tIndex, tMainIndex;
00083 
00084         fail(aulCharPos == NULL);
00085 
00086         DBG_DEC(tLength);
00087         if (tLength <= 1) {
00088                 return;
00089         }
00090         tHdrFtrLen = tLength / 12;
00091         if (tLength % 12 != 0 && tLength % 12 != 1) {
00092                 tHdrFtrLen++;
00093         }
00094         DBG_DEC(tHdrFtrLen);
00095 
00096         pHdrFtrList = xcalloc(tHdrFtrLen, sizeof(hdrftr_mem_type));
00097 
00098         for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
00099                 pListMember = pHdrFtrList + tHdrFtr;
00100                 for (tIndex = 0, tMainIndex = tHdrFtr * 12;
00101                      tIndex < 6 && tMainIndex < tLength;
00102                      tIndex++, tMainIndex++) {
00103                         pListMember->atElement[tIndex].tInfo.pText = NULL;
00104                         pListMember->atElement[tIndex].ulCharPosStart =
00105                                                 aulCharPos[tMainIndex];
00106                         if (tMainIndex + 1 < tLength) {
00107                                 pListMember->atElement[tIndex].ulCharPosNext =
00108                                         aulCharPos[tMainIndex + 1];
00109                         } else {
00110                                 pListMember->atElement[tIndex].ulCharPosNext =
00111                                         aulCharPos[tMainIndex];
00112                         }
00113                 }
00114         }
00115 } /* end of vCreat8HdrFtrInfoList */
00116 
00117 /*
00118  * vCreat6HdrFtrInfoList - Create the Header/footer Information List
00119  */
00120 void
00121 vCreat6HdrFtrInfoList(const ULONG *aulCharPos, size_t tLength)
00122 {
00123         static const size_t     atIndex[] =
00124                 { SIZE_T_MAX, SIZE_T_MAX, FTR_FIRST_PAGE, HDR_FIRST_PAGE,
00125                   FTR_ODD_PAGES, FTR_EVEN_PAGES, HDR_ODD_PAGES, HDR_EVEN_PAGES,
00126                 };
00127         hdrftr_mem_type *pListMember;
00128         size_t  tHdrFtr, tTmp, tIndex, tMainIndex, tBit;
00129         UCHAR   ucDopSpecification, ucSepSpecification;
00130 
00131         fail(aulCharPos == NULL);
00132 
00133         DBG_DEC(tLength);
00134         if (tLength <= 1) {
00135                 return;
00136         }
00137         tHdrFtrLen = tGetNumberOfSections();
00138         if (tHdrFtrLen == 0) {
00139                 tHdrFtrLen = 1;
00140         }
00141         DBG_DEC(tHdrFtrLen);
00142 
00143         pHdrFtrList = xcalloc(tHdrFtrLen, sizeof(hdrftr_mem_type));
00144 
00145         /* Get the start index in aulCharPos */
00146         ucDopSpecification = ucGetDopHdrFtrSpecification();
00147         DBG_HEX(ucDopSpecification & 0xe0);
00148         tMainIndex = 0;
00149         for (tBit = 7; tBit >= 5; tBit--) {
00150                 if ((ucDopSpecification & BIT(tBit)) != 0) {
00151                         tMainIndex++;
00152                 }
00153         }
00154         DBG_DEC(tMainIndex);
00155 
00156         for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
00157                 ucSepSpecification = ucGetSepHdrFtrSpecification(tHdrFtr);
00158                 DBG_HEX(ucSepSpecification & 0xfc);
00159                 pListMember = pHdrFtrList + tHdrFtr;
00160                 for (tTmp = 0;
00161                      tTmp < elementsof(pListMember->atElement);
00162                      tTmp++) {
00163                         pListMember->atElement[tTmp].tInfo.pText = NULL;
00164                 }
00165                 for (tBit = 7; tBit >= 2; tBit--) {
00166                         if (tMainIndex >= tLength) {
00167                                 break;
00168                         }
00169                         if ((ucSepSpecification & BIT(tBit)) == 0) {
00170                                 continue;
00171                         }
00172                         tIndex = atIndex[tBit];
00173                         fail(tIndex >= 6);
00174                         pListMember->atElement[tIndex].ulCharPosStart =
00175                                 aulCharPos[tMainIndex];
00176                         if (tMainIndex + 1 < tLength) {
00177                                 pListMember->atElement[tIndex].ulCharPosNext =
00178                                         aulCharPos[tMainIndex + 1];
00179                         } else {
00180                                 pListMember->atElement[tIndex].ulCharPosNext =
00181                                         aulCharPos[tMainIndex];
00182                         }
00183                         tMainIndex++;
00184                 }
00185         }
00186 } /* end of vCreat6HdrFtrInfoList */
00187 
00188 /*
00189  * vCreat2HdrFtrInfoList - Create the Header/footer Information List
00190  */
00191 void
00192 vCreat2HdrFtrInfoList(const ULONG *aulCharPos, size_t tLength)
00193 {
00194         vCreat6HdrFtrInfoList(aulCharPos, tLength);
00195 } /* end of vCreat2HdrFtrInfoList */
00196 
00197 /*
00198  * pGetHdrFtrInfo - get the Header/footer information
00199  */
00200 const hdrftr_block_type *
00201 pGetHdrFtrInfo(int iSectionIndex,
00202         BOOL bWantHeader, BOOL bOddPage, BOOL bFirstInSection)
00203 {
00204         hdrftr_mem_type *pCurr;
00205 
00206         fail(iSectionIndex < 0);
00207         fail(pHdrFtrList == NULL && tHdrFtrLen != 0);
00208 
00209         if (pHdrFtrList == NULL || tHdrFtrLen == 0) {
00210                 /* No information */
00211                 return NULL;
00212         }
00213 
00214         if (iSectionIndex < 0) {
00215                 iSectionIndex = 0;
00216         } else if (iSectionIndex >= (int)tHdrFtrLen) {
00217                 iSectionIndex = (int)(tHdrFtrLen - 1);
00218         }
00219 
00220         pCurr = pHdrFtrList + iSectionIndex;
00221 
00222         if (bFirstInSection) {
00223                 if (bWantHeader) {
00224                         return &pCurr->atElement[HDR_FIRST_PAGE].tInfo;
00225                 } else {
00226                         return &pCurr->atElement[FTR_FIRST_PAGE].tInfo;
00227                 }
00228         } else {
00229                 if (bWantHeader) {
00230                         if (bOddPage) {
00231                                 return &pCurr->atElement[HDR_ODD_PAGES].tInfo;
00232                         } else {
00233                                 return &pCurr->atElement[HDR_EVEN_PAGES].tInfo;
00234                         }
00235                 } else {
00236                         if (bOddPage) {
00237                                 return &pCurr->atElement[FTR_ODD_PAGES].tInfo;
00238                         } else {
00239                                 return &pCurr->atElement[FTR_EVEN_PAGES].tInfo;
00240                         }
00241                 }
00242         }
00243 } /* end of pGetHdrFtrInfo */
00244 
00245 /*
00246  * lComputeHdrFtrHeight - compute the height of a header or footer
00247  *
00248  * Returns the height in DrawUnits
00249  */
00250 static long
00251 lComputeHdrFtrHeight(const output_type *pAnchor)
00252 {
00253         const output_type *pCurr;
00254         long    lTotal;
00255         USHORT  usFontSizeMax;
00256 
00257         lTotal = 0;
00258         usFontSizeMax = 0;
00259         for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
00260                 if (pCurr->tNextFree == 1) {
00261                         if (pCurr->szStorage[0] == PAR_END) {
00262                                 /* End of a paragraph */
00263                                 lTotal += lComputeLeading(usFontSizeMax);
00264                                 lTotal += lMilliPoints2DrawUnits(
00265                                                 (long)pCurr->usFontSize * 200);
00266                                 usFontSizeMax = 0;
00267                                 continue;
00268                         }
00269                         if (pCurr->szStorage[0] == HARD_RETURN) {
00270                                 /* End of a line */
00271                                 lTotal += lComputeLeading(usFontSizeMax);
00272                                 usFontSizeMax = 0;
00273                                 continue;
00274                         }
00275                 }
00276                 if (pCurr->usFontSize > usFontSizeMax) {
00277                         usFontSizeMax = pCurr->usFontSize;
00278                 }
00279         }
00280         if (usFontSizeMax != 0) {
00281                 /* Height of the last paragraph */
00282                 lTotal += lComputeLeading(usFontSizeMax);
00283         }
00284         return lTotal;
00285 } /* end of lComputeHdrFtrHeight */
00286 
00287 /*
00288  * vPrepareHdrFtrText - prepare the header/footer text
00289  */
00290 void
00291 vPrepareHdrFtrText(FILE *pFile)
00292 {
00293         hdrftr_mem_type         *pCurr, *pPrev;
00294         hdrftr_local_type       *pTmp;
00295         output_type             *pText;
00296         size_t          tHdrFtr, tIndex;
00297 
00298         fail(pFile == NULL);
00299         fail(pHdrFtrList == NULL && tHdrFtrLen != 0);
00300 
00301         if (pHdrFtrList == NULL || tHdrFtrLen == 0) {
00302                 /* No information */
00303                 return;
00304         }
00305 
00306         /* Fill text, text height and useful-ness */
00307         for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
00308                 pCurr = pHdrFtrList + tHdrFtr;
00309                 for (tIndex = 0;
00310                      tIndex < elementsof(pHdrFtrList->atElement);
00311                      tIndex++) {
00312                         pTmp = &pCurr->atElement[tIndex];
00313                         pTmp->bUseful =
00314                                 pTmp->ulCharPosStart != pTmp->ulCharPosNext;
00315                         if (pTmp->bUseful) {
00316                                 pText = pHdrFtrDecryptor(pFile,
00317                                                 pTmp->ulCharPosStart,
00318                                                 pTmp->ulCharPosNext);
00319                                 pTmp->tInfo.pText = pText;
00320                                 pTmp->tInfo.lHeight =
00321                                                 lComputeHdrFtrHeight(pText);
00322                                 pTmp->bTextOriginal = pText != NULL;
00323                         } else {
00324                                 pTmp->tInfo.pText = NULL;
00325                                 pTmp->tInfo.lHeight = 0;
00326                                 pTmp->bTextOriginal = FALSE;
00327                         }
00328                 }
00329         }
00330 
00331         /* Replace not-useful records by using inheritance */
00332         if (pHdrFtrList->atElement[HDR_FIRST_PAGE].bUseful) {
00333                 pTmp = &pHdrFtrList->atElement[HDR_ODD_PAGES];
00334                 if (!pTmp->bUseful) {
00335                         *pTmp = pHdrFtrList->atElement[HDR_FIRST_PAGE];
00336                         pTmp->bTextOriginal = FALSE;
00337                 }
00338                 pTmp = &pHdrFtrList->atElement[HDR_EVEN_PAGES];
00339                 if (!pTmp->bUseful) {
00340                         *pTmp = pHdrFtrList->atElement[HDR_FIRST_PAGE];
00341                         pTmp->bTextOriginal = FALSE;
00342                 }
00343         }
00344         if (pHdrFtrList->atElement[FTR_FIRST_PAGE].bUseful) {
00345                 pTmp = &pHdrFtrList->atElement[FTR_ODD_PAGES];
00346                 if (!pTmp->bUseful) {
00347                         *pTmp = pHdrFtrList->atElement[FTR_FIRST_PAGE];
00348                         pTmp->bTextOriginal = FALSE;
00349                 }
00350                 pTmp = &pHdrFtrList->atElement[FTR_EVEN_PAGES];
00351                 if (!pTmp->bUseful) {
00352                         *pTmp = pHdrFtrList->atElement[FTR_FIRST_PAGE];
00353                         pTmp->bTextOriginal = FALSE;
00354                 }
00355         }
00356         for (tHdrFtr = 1, pCurr = &pHdrFtrList[1];
00357              tHdrFtr < tHdrFtrLen;
00358              tHdrFtr++, pCurr++) {
00359                 pPrev = pCurr - 1;
00360                 for (tIndex = 0;
00361                      tIndex < elementsof(pHdrFtrList->atElement);
00362                      tIndex++) {
00363                         if (!pCurr->atElement[tIndex].bUseful &&
00364                             pPrev->atElement[tIndex].bUseful) {
00365                                 pCurr->atElement[tIndex] =
00366                                                 pPrev->atElement[tIndex];
00367                                 pCurr->atElement[tIndex].bTextOriginal = FALSE;
00368                         }
00369                 }
00370         }
00371 } /* end of vPrepareHdrFtrText */

Generated by  doxygen 1.6.2