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