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