1f5736e95SDavid du Colombier /*
2f5736e95SDavid du Colombier * tabstops.c
3*25b329d5SDavid du Colombier * Copyright (C) 1999-2004 A.J. van Os; Released under GNU GPL
4f5736e95SDavid du Colombier *
5f5736e95SDavid du Colombier * Description:
6f5736e95SDavid du Colombier * Read the tab stop information from a MS Word file
7f5736e95SDavid du Colombier */
8f5736e95SDavid du Colombier
9f5736e95SDavid du Colombier #include <stdio.h>
10f5736e95SDavid du Colombier #include "antiword.h"
11f5736e95SDavid du Colombier
12f5736e95SDavid du Colombier #define HALF_INCH 36000L /* In millipoints */
13f5736e95SDavid du Colombier
14f5736e95SDavid du Colombier static long lDefaultTabWidth = HALF_INCH;
15f5736e95SDavid du Colombier
16f5736e95SDavid du Colombier
17f5736e95SDavid du Colombier /*
18f5736e95SDavid du Colombier * vSet0DefaultTabWidth -
19f5736e95SDavid du Colombier */
20f5736e95SDavid du Colombier static void
vSet0DefaultTabWidth(const UCHAR * aucHeader)21f5736e95SDavid du Colombier vSet0DefaultTabWidth(const UCHAR *aucHeader)
22f5736e95SDavid du Colombier {
23f5736e95SDavid du Colombier USHORT usTmp;
24f5736e95SDavid du Colombier
25f5736e95SDavid du Colombier fail(aucHeader == NULL);
26f5736e95SDavid du Colombier
27f5736e95SDavid du Colombier usTmp = usGetWord(0x70, aucHeader); /* dxaTab */
28f5736e95SDavid du Colombier DBG_DEC(usTmp);
29f5736e95SDavid du Colombier lDefaultTabWidth = usTmp == 0 ? HALF_INCH : lTwips2MilliPoints(usTmp);
30f5736e95SDavid du Colombier DBG_DEC(lDefaultTabWidth);
31f5736e95SDavid du Colombier } /* end of vSet0DefaultTabWidth */
32f5736e95SDavid du Colombier
33f5736e95SDavid du Colombier /*
34f5736e95SDavid du Colombier * vSet2DefaultTabWidth -
35f5736e95SDavid du Colombier */
36f5736e95SDavid du Colombier static void
vSet2DefaultTabWidth(FILE * pFile,const UCHAR * aucHeader)37f5736e95SDavid du Colombier vSet2DefaultTabWidth(FILE *pFile, const UCHAR *aucHeader)
38f5736e95SDavid du Colombier {
39f5736e95SDavid du Colombier UCHAR *aucBuffer;
40f5736e95SDavid du Colombier ULONG ulBeginDocpInfo;
41f5736e95SDavid du Colombier size_t tDocpInfoLen;
42f5736e95SDavid du Colombier USHORT usTmp;
43f5736e95SDavid du Colombier
44f5736e95SDavid du Colombier fail(pFile == NULL || aucHeader == NULL);
45f5736e95SDavid du Colombier
46f5736e95SDavid du Colombier ulBeginDocpInfo = ulGetLong(0x112, aucHeader); /* fcDop */
47f5736e95SDavid du Colombier DBG_HEX(ulBeginDocpInfo);
48f5736e95SDavid du Colombier tDocpInfoLen = (size_t)usGetWord(0x116, aucHeader); /* cbDop */
49f5736e95SDavid du Colombier DBG_DEC(tDocpInfoLen);
50f5736e95SDavid du Colombier if (tDocpInfoLen < 12) {
51f5736e95SDavid du Colombier DBG_MSG("No TAB information");
52f5736e95SDavid du Colombier return;
53f5736e95SDavid du Colombier }
54f5736e95SDavid du Colombier
55f5736e95SDavid du Colombier aucBuffer = xmalloc(tDocpInfoLen);
56f5736e95SDavid du Colombier if (!bReadBytes(aucBuffer, tDocpInfoLen, ulBeginDocpInfo, pFile)) {
57f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
58f5736e95SDavid du Colombier return;
59f5736e95SDavid du Colombier }
60f5736e95SDavid du Colombier usTmp = usGetWord(0x0a, aucBuffer); /* dxaTab */
61f5736e95SDavid du Colombier lDefaultTabWidth = usTmp == 0 ? HALF_INCH : lTwips2MilliPoints(usTmp);
62f5736e95SDavid du Colombier DBG_DEC(lDefaultTabWidth);
63f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
64f5736e95SDavid du Colombier } /* end of vSet2DefaultTabWidth */
65f5736e95SDavid du Colombier
66f5736e95SDavid du Colombier /*
67f5736e95SDavid du Colombier * vSet6DefaultTabWidth -
68f5736e95SDavid du Colombier */
69f5736e95SDavid du Colombier static void
vSet6DefaultTabWidth(FILE * pFile,ULONG ulStartBlock,const ULONG * aulBBD,size_t tBBDLen,const UCHAR * aucHeader)70f5736e95SDavid du Colombier vSet6DefaultTabWidth(FILE *pFile, ULONG ulStartBlock,
71f5736e95SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader)
72f5736e95SDavid du Colombier {
73f5736e95SDavid du Colombier UCHAR *aucBuffer;
74f5736e95SDavid du Colombier ULONG ulBeginDocpInfo;
75f5736e95SDavid du Colombier size_t tDocpInfoLen;
76f5736e95SDavid du Colombier USHORT usTmp;
77f5736e95SDavid du Colombier
78f5736e95SDavid du Colombier ulBeginDocpInfo = ulGetLong(0x150, aucHeader); /* fcDop */
79f5736e95SDavid du Colombier DBG_HEX(ulBeginDocpInfo);
80f5736e95SDavid du Colombier tDocpInfoLen = (size_t)ulGetLong(0x154, aucHeader); /* lcbDop */
81f5736e95SDavid du Colombier DBG_DEC(tDocpInfoLen);
82f5736e95SDavid du Colombier if (tDocpInfoLen < 12) {
83f5736e95SDavid du Colombier DBG_MSG("No TAB information");
84f5736e95SDavid du Colombier return;
85f5736e95SDavid du Colombier }
86f5736e95SDavid du Colombier
87f5736e95SDavid du Colombier aucBuffer = xmalloc(tDocpInfoLen);
88f5736e95SDavid du Colombier if (!bReadBuffer(pFile, ulStartBlock,
89f5736e95SDavid du Colombier aulBBD, tBBDLen, BIG_BLOCK_SIZE,
90f5736e95SDavid du Colombier aucBuffer, ulBeginDocpInfo, tDocpInfoLen)) {
91f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
92f5736e95SDavid du Colombier return;
93f5736e95SDavid du Colombier }
94f5736e95SDavid du Colombier usTmp = usGetWord(0x0a, aucBuffer); /* dxaTab */
95f5736e95SDavid du Colombier lDefaultTabWidth = usTmp == 0 ? HALF_INCH : lTwips2MilliPoints(usTmp);
96f5736e95SDavid du Colombier DBG_DEC(lDefaultTabWidth);
97f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
98f5736e95SDavid du Colombier } /* end of vSet6DefaultTabWidth */
99f5736e95SDavid du Colombier
100f5736e95SDavid du Colombier /*
101f5736e95SDavid du Colombier * vSet8DefaultTabWidth -
102f5736e95SDavid du Colombier */
103f5736e95SDavid du Colombier 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)104f5736e95SDavid du Colombier vSet8DefaultTabWidth(FILE *pFile, const pps_info_type *pPPS,
105f5736e95SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
106f5736e95SDavid du Colombier const ULONG *aulSBD, size_t tSBDLen,
107f5736e95SDavid du Colombier const UCHAR *aucHeader)
108f5736e95SDavid du Colombier {
109f5736e95SDavid du Colombier const ULONG *aulBlockDepot;
110f5736e95SDavid du Colombier UCHAR *aucBuffer;
111f5736e95SDavid du Colombier ULONG ulBeginDocpInfo;
112f5736e95SDavid du Colombier size_t tDocpInfoLen, tBlockDepotLen, tBlockSize;
113*25b329d5SDavid du Colombier USHORT usTmp;
114f5736e95SDavid du Colombier
115f5736e95SDavid du Colombier ulBeginDocpInfo = ulGetLong(0x192, aucHeader); /* fcDop */
116f5736e95SDavid du Colombier DBG_HEX(ulBeginDocpInfo);
117f5736e95SDavid du Colombier tDocpInfoLen = (size_t)ulGetLong(0x196, aucHeader); /* lcbDop */
118f5736e95SDavid du Colombier DBG_DEC(tDocpInfoLen);
119f5736e95SDavid du Colombier if (tDocpInfoLen < 12) {
120f5736e95SDavid du Colombier DBG_MSG("No TAB information");
121f5736e95SDavid du Colombier return;
122f5736e95SDavid du Colombier }
123f5736e95SDavid du Colombier
124*25b329d5SDavid du Colombier DBG_DEC(pPPS->tTable.ulSB);
125*25b329d5SDavid du Colombier DBG_HEX(pPPS->tTable.ulSize);
126*25b329d5SDavid du Colombier if (pPPS->tTable.ulSize == 0) {
127f5736e95SDavid du Colombier DBG_MSG("No TAB information");
128f5736e95SDavid du Colombier return;
129f5736e95SDavid du Colombier }
130*25b329d5SDavid du Colombier
131*25b329d5SDavid du Colombier if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
132f5736e95SDavid du Colombier /* Use the Small Block Depot */
133f5736e95SDavid du Colombier aulBlockDepot = aulSBD;
134f5736e95SDavid du Colombier tBlockDepotLen = tSBDLen;
135f5736e95SDavid du Colombier tBlockSize = SMALL_BLOCK_SIZE;
136f5736e95SDavid du Colombier } else {
137f5736e95SDavid du Colombier /* Use the Big Block Depot */
138f5736e95SDavid du Colombier aulBlockDepot = aulBBD;
139f5736e95SDavid du Colombier tBlockDepotLen = tBBDLen;
140f5736e95SDavid du Colombier tBlockSize = BIG_BLOCK_SIZE;
141f5736e95SDavid du Colombier }
142f5736e95SDavid du Colombier aucBuffer = xmalloc(tDocpInfoLen);
143*25b329d5SDavid du Colombier if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
144f5736e95SDavid du Colombier aulBlockDepot, tBlockDepotLen, tBlockSize,
145f5736e95SDavid du Colombier aucBuffer, ulBeginDocpInfo, tDocpInfoLen)) {
146f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
147f5736e95SDavid du Colombier return;
148f5736e95SDavid du Colombier }
149f5736e95SDavid du Colombier usTmp = usGetWord(0x0a, aucBuffer); /* dxaTab */
150f5736e95SDavid du Colombier lDefaultTabWidth = usTmp == 0 ? HALF_INCH : lTwips2MilliPoints(usTmp);
151f5736e95SDavid du Colombier DBG_DEC(lDefaultTabWidth);
152f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
153f5736e95SDavid du Colombier } /* end of vSet8DefaultTabWidth */
154f5736e95SDavid du Colombier
155f5736e95SDavid du Colombier /*
156f5736e95SDavid du Colombier * vSetDefaultTabWidth -
157f5736e95SDavid du Colombier */
158f5736e95SDavid du Colombier 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)159f5736e95SDavid du Colombier vSetDefaultTabWidth(FILE *pFile, const pps_info_type *pPPS,
160f5736e95SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
161f5736e95SDavid du Colombier const ULONG *aulSBD, size_t tSBDLen,
162f5736e95SDavid du Colombier const UCHAR *aucHeader, int iWordVersion)
163f5736e95SDavid du Colombier {
164f5736e95SDavid du Colombier fail(pFile == NULL && iWordVersion >= 1);
165f5736e95SDavid du Colombier fail(pPPS == NULL && iWordVersion >= 6);
166f5736e95SDavid du Colombier fail(aulBBD == NULL && tBBDLen != 0);
167f5736e95SDavid du Colombier fail(aulSBD == NULL && tSBDLen != 0);
168f5736e95SDavid du Colombier fail(aucHeader == NULL);
169f5736e95SDavid du Colombier
170f5736e95SDavid du Colombier /* Reset to the default default value */
171f5736e95SDavid du Colombier lDefaultTabWidth = HALF_INCH;
172f5736e95SDavid du Colombier
173f5736e95SDavid du Colombier switch (iWordVersion) {
174f5736e95SDavid du Colombier case 0:
175f5736e95SDavid du Colombier vSet0DefaultTabWidth(aucHeader);
176f5736e95SDavid du Colombier break;
177f5736e95SDavid du Colombier case 1:
178f5736e95SDavid du Colombier case 2:
179f5736e95SDavid du Colombier vSet2DefaultTabWidth(pFile, aucHeader);
180f5736e95SDavid du Colombier break;
181f5736e95SDavid du Colombier case 4:
182f5736e95SDavid du Colombier case 5:
183f5736e95SDavid du Colombier break;
184f5736e95SDavid du Colombier case 6:
185f5736e95SDavid du Colombier case 7:
186f5736e95SDavid du Colombier vSet6DefaultTabWidth(pFile, pPPS->tWordDocument.ulSB,
187f5736e95SDavid du Colombier aulBBD, tBBDLen, aucHeader);
188f5736e95SDavid du Colombier break;
189f5736e95SDavid du Colombier case 8:
190f5736e95SDavid du Colombier vSet8DefaultTabWidth(pFile, pPPS,
191f5736e95SDavid du Colombier aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
192f5736e95SDavid du Colombier break;
193f5736e95SDavid du Colombier default:
194f5736e95SDavid du Colombier werr(0, "Sorry, no TAB information");
195f5736e95SDavid du Colombier break;
196f5736e95SDavid du Colombier }
197f5736e95SDavid du Colombier } /* end of vSetDefaultTabWidth */
198f5736e95SDavid du Colombier
199*25b329d5SDavid du Colombier #if 0
200f5736e95SDavid du Colombier /*
201f5736e95SDavid du Colombier * lGetDefaultTabWidth - Get the default tabwidth in millipoints
202f5736e95SDavid du Colombier */
203f5736e95SDavid du Colombier long
204f5736e95SDavid du Colombier lGetDefaultTabWidth(void)
205f5736e95SDavid du Colombier {
206f5736e95SDavid du Colombier if (lDefaultTabWidth <= 0) {
207f5736e95SDavid du Colombier DBG_DEC(lDefaultTabWidth);
208f5736e95SDavid du Colombier return lTwips2MilliPoints(1);
209f5736e95SDavid du Colombier }
210f5736e95SDavid du Colombier return lDefaultTabWidth;
211f5736e95SDavid du Colombier } /* end of lGetDefaultTabWidth */
212*25b329d5SDavid du Colombier #endif
213