Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * tabstops.c
 * Copyright (C) 1999-2004 A.J. van Os; Released under GNU GPL
 *
 * Description:
 * Read the tab stop information from a MS Word file
 */

#include <stdio.h>
#include "antiword.h"

#define HALF_INCH       36000L  /* In millipoints */

static long     lDefaultTabWidth = HALF_INCH;


/*
 * vSet0DefaultTabWidth -
 */
static void
vSet0DefaultTabWidth(const UCHAR *aucHeader)
{
        USHORT  usTmp;

        fail(aucHeader == NULL);

        usTmp = usGetWord(0x70, aucHeader); /* dxaTab */
        DBG_DEC(usTmp);
        lDefaultTabWidth = usTmp == 0 ? HALF_INCH : lTwips2MilliPoints(usTmp);
        DBG_DEC(lDefaultTabWidth);
} /* end of vSet0DefaultTabWidth */

/*
 * vSet2DefaultTabWidth -
 */
static void
vSet2DefaultTabWidth(FILE *pFile, const UCHAR *aucHeader)
{
        UCHAR   *aucBuffer;
        ULONG   ulBeginDocpInfo;
        size_t  tDocpInfoLen;
        USHORT  usTmp;

        fail(pFile == NULL || aucHeader == NULL);

        ulBeginDocpInfo = ulGetLong(0x112, aucHeader); /* fcDop */
        DBG_HEX(ulBeginDocpInfo);
        tDocpInfoLen = (size_t)usGetWord(0x116, aucHeader); /* cbDop */
        DBG_DEC(tDocpInfoLen);
        if (tDocpInfoLen < 12) {
                DBG_MSG("No TAB information");
                return;
        }

        aucBuffer = xmalloc(tDocpInfoLen);
        if (!bReadBytes(aucBuffer, tDocpInfoLen, ulBeginDocpInfo, pFile)) {
                aucBuffer = xfree(aucBuffer);
                return;
        }
        usTmp = usGetWord(0x0a, aucBuffer); /* dxaTab */
        lDefaultTabWidth = usTmp == 0 ? HALF_INCH : lTwips2MilliPoints(usTmp);
        DBG_DEC(lDefaultTabWidth);
        aucBuffer = xfree(aucBuffer);
} /* end of vSet2DefaultTabWidth */

/*
 * vSet6DefaultTabWidth -
 */
static void
vSet6DefaultTabWidth(FILE *pFile, ULONG ulStartBlock,
        const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader)
{
        UCHAR   *aucBuffer;
        ULONG   ulBeginDocpInfo;
        size_t  tDocpInfoLen;
        USHORT  usTmp;

        ulBeginDocpInfo = ulGetLong(0x150, aucHeader); /* fcDop */
        DBG_HEX(ulBeginDocpInfo);
        tDocpInfoLen = (size_t)ulGetLong(0x154, aucHeader); /* lcbDop */
        DBG_DEC(tDocpInfoLen);
        if (tDocpInfoLen < 12) {
                DBG_MSG("No TAB information");
                return;
        }

        aucBuffer = xmalloc(tDocpInfoLen);
        if (!bReadBuffer(pFile, ulStartBlock,
                        aulBBD, tBBDLen, BIG_BLOCK_SIZE,
                        aucBuffer, ulBeginDocpInfo, tDocpInfoLen)) {
                aucBuffer = xfree(aucBuffer);
                return;
        }
        usTmp = usGetWord(0x0a, aucBuffer); /* dxaTab */
        lDefaultTabWidth = usTmp == 0 ? HALF_INCH : lTwips2MilliPoints(usTmp);
        DBG_DEC(lDefaultTabWidth);
        aucBuffer = xfree(aucBuffer);
} /* end of vSet6DefaultTabWidth */

/*
 * vSet8DefaultTabWidth -
 */
static void
vSet8DefaultTabWidth(FILE *pFile, const pps_info_type *pPPS,
        const ULONG *aulBBD, size_t tBBDLen,
        const ULONG *aulSBD, size_t tSBDLen,
        const UCHAR *aucHeader)
{
        const ULONG     *aulBlockDepot;
        UCHAR   *aucBuffer;
        ULONG   ulBeginDocpInfo;
        size_t  tDocpInfoLen, tBlockDepotLen, tBlockSize;
        USHORT  usTmp;

        ulBeginDocpInfo = ulGetLong(0x192, aucHeader); /* fcDop */
        DBG_HEX(ulBeginDocpInfo);
        tDocpInfoLen = (size_t)ulGetLong(0x196, aucHeader); /* lcbDop */
        DBG_DEC(tDocpInfoLen);
        if (tDocpInfoLen < 12) {
                DBG_MSG("No TAB information");
                return;
        }

        DBG_DEC(pPPS->tTable.ulSB);
        DBG_HEX(pPPS->tTable.ulSize);
        if (pPPS->tTable.ulSize == 0) {
                DBG_MSG("No TAB information");
                return;
        }

        if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
                /* Use the Small Block Depot */
                aulBlockDepot = aulSBD;
                tBlockDepotLen = tSBDLen;
                tBlockSize = SMALL_BLOCK_SIZE;
        } else {
                /* Use the Big Block Depot */
                aulBlockDepot = aulBBD;
                tBlockDepotLen = tBBDLen;
                tBlockSize = BIG_BLOCK_SIZE;
        }
        aucBuffer = xmalloc(tDocpInfoLen);
        if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
                        aulBlockDepot, tBlockDepotLen, tBlockSize,
                        aucBuffer, ulBeginDocpInfo, tDocpInfoLen)) {
                aucBuffer = xfree(aucBuffer);
                return;
        }
        usTmp = usGetWord(0x0a, aucBuffer); /* dxaTab */
        lDefaultTabWidth = usTmp == 0 ? HALF_INCH : lTwips2MilliPoints(usTmp);
        DBG_DEC(lDefaultTabWidth);
        aucBuffer = xfree(aucBuffer);
} /* end of vSet8DefaultTabWidth */

/*
 * vSetDefaultTabWidth -
 */
void
vSetDefaultTabWidth(FILE *pFile, const pps_info_type *pPPS,
        const ULONG *aulBBD, size_t tBBDLen,
        const ULONG *aulSBD, size_t tSBDLen,
        const UCHAR *aucHeader, int iWordVersion)
{
        fail(pFile == NULL && iWordVersion >= 1);
        fail(pPPS == NULL && iWordVersion >= 6);
        fail(aulBBD == NULL && tBBDLen != 0);
        fail(aulSBD == NULL && tSBDLen != 0);
        fail(aucHeader == NULL);

        /* Reset to the default default value */
        lDefaultTabWidth = HALF_INCH;

        switch (iWordVersion) {
        case 0:
                vSet0DefaultTabWidth(aucHeader);
                break;
        case 1:
        case 2:
                vSet2DefaultTabWidth(pFile, aucHeader);
                break;
        case 4:
        case 5:
                break;
        case 6:
        case 7:
                vSet6DefaultTabWidth(pFile, pPPS->tWordDocument.ulSB,
                                aulBBD, tBBDLen, aucHeader);
                break;
        case 8:
                vSet8DefaultTabWidth(pFile, pPPS,
                                aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
                break;
        default:
                werr(0, "Sorry, no TAB information");
                break;
        }
} /* end of vSetDefaultTabWidth */

#if 0
/*
 * lGetDefaultTabWidth - Get the default tabwidth in millipoints
 */
long
lGetDefaultTabWidth(void)
{
        if (lDefaultTabWidth <= 0) {
                DBG_DEC(lDefaultTabWidth);
                return lTwips2MilliPoints(1);
        }
        return lDefaultTabWidth;
} /* end of lGetDefaultTabWidth */
#endif