Imported from antiword-0.36.tar.gz.
[antiword.git] / prop0.c
blob0e01dcb545d17b96e6b4b21f01509c8baff1443c
1 /*
2 * prop0.c
3 * Copyright (C) 2002,2003 A.J. van Os; Released under GNU GPL
5 * Description:
6 * Read the property information from a Word for DOS file
7 */
9 #include <string.h>
10 #include "antiword.h"
14 * Fill the section information block with information
15 * from a Word for DOS file.
17 static void
18 vGet0SectionInfo(const UCHAR *aucGrpprl, size_t tBytes,
19 section_block_type *pSection)
21 USHORT usCcol;
22 UCHAR ucTmp;
24 fail(aucGrpprl == NULL || pSection == NULL);
26 if (tBytes < 2) {
27 return;
29 /* bkc */
30 ucTmp = ucGetByte(1, aucGrpprl);
31 DBG_HEX(ucTmp);
32 ucTmp &= 0x07;
33 DBG_HEX(ucTmp);
34 pSection->bNewPage = ucTmp != 0 && ucTmp != 1;
35 if (tBytes < 18) {
36 return;
38 /* ccolM1 */
39 usCcol = (USHORT)ucGetByte(17, aucGrpprl);
40 DBG_DEC(usCcol);
41 } /* end of vGet0SectionInfo */
44 * Build the lists with Section Property Information for Word for DOS files
46 void
47 vGet0SepInfo(FILE *pFile, const UCHAR *aucHeader)
49 section_block_type tSection;
50 UCHAR *aucBuffer;
51 ULONG ulBeginSectInfo, ulBeginNextBlock;
52 ULONG ulSectPage, ulTextOffset;
53 size_t tSectInfoLen, tBytes;
54 int iIndex, iSections;
55 UCHAR aucTmp[2], aucFpage[35];
57 fail(pFile == NULL || aucHeader == NULL);
59 ulBeginSectInfo = 128 * (ULONG)usGetWord(0x18, aucHeader);
60 DBG_HEX(ulBeginSectInfo);
61 ulBeginNextBlock = 128 * (ULONG)usGetWord(0x1a, aucHeader);
62 DBG_HEX(ulBeginNextBlock);
63 if (ulBeginSectInfo == ulBeginNextBlock) {
64 /* There is no section information block */
65 return;
68 /* Get the the number of sections */
69 if (!bReadBytes(aucTmp, 2, ulBeginSectInfo, pFile)) {
70 return;
72 iSections = (int)usGetWord(0, aucTmp);
73 NO_DBG_DEC(iSections);
75 /* Read the Section Descriptors */
76 tSectInfoLen = 10 * (size_t)iSections;
77 NO_DBG_DEC(tSectInfoLen);
78 aucBuffer = xmalloc(tSectInfoLen);
79 if (!bReadBytes(aucBuffer, tSectInfoLen, ulBeginSectInfo + 4, pFile)) {
80 aucBuffer = xfree(aucBuffer);
81 return;
83 NO_DBG_PRINT_BLOCK(aucBuffer, tSectInfoLen);
85 /* Read the Section Properties */
86 for (iIndex = 0; iIndex < iSections; iIndex++) {
87 ulTextOffset = ulGetLong(10 * iIndex, aucBuffer);
88 NO_DBG_HEX(ulTextOffset);
89 ulSectPage = ulGetLong(10 * iIndex + 6, aucBuffer);
90 NO_DBG_HEX(ulSectPage);
91 if (ulSectPage == FC_INVALID || /* Must use defaults */
92 ulSectPage < 128 || /* Should not happen */
93 ulSectPage >= ulBeginSectInfo) { /* Should not happen */
94 DBG_HEX_C(ulSectPage != FC_INVALID, ulSectPage);
95 vDefault2SectionInfoList(ulTextOffset);
96 continue;
98 /* Get the number of bytes to read */
99 if (!bReadBytes(aucTmp, 1, ulSectPage, pFile)) {
100 continue;
102 tBytes = 1 + (size_t)ucGetByte(0, aucTmp);
103 NO_DBG_DEC(tBytes);
104 if (tBytes > sizeof(aucFpage)) {
105 DBG_DEC(tBytes);
106 tBytes = sizeof(aucFpage);
108 /* Read the bytes */
109 if (!bReadBytes(aucFpage, tBytes, ulSectPage, pFile)) {
110 continue;
112 NO_DBG_PRINT_BLOCK(aucFpage, tBytes);
113 /* Process the bytes */
114 vGetDefaultSection(&tSection);
115 vGet0SectionInfo(aucFpage + 1, tBytes - 1, &tSection);
116 vAdd2SectionInfoList(&tSection, ulTextOffset);
118 /* Clean up before you leave */
119 aucBuffer = xfree(aucBuffer);
120 } /* end of vGet0SepInfo */
123 * Fill the style information block with information
124 * from a Word for DOS file.
126 static void
127 vGet0StyleInfo(int iFodo, const UCHAR *aucGrpprl, style_block_type *pStyle)
129 int iBytes;
130 UCHAR ucTmp;
132 fail(iFodo <= 0 || aucGrpprl == NULL || pStyle == NULL);
134 pStyle->usIstdNext = ISTD_NORMAL;
136 iBytes = (int)ucGetByte(iFodo, aucGrpprl);
137 if (iBytes < 1) {
138 return;
140 /* stc if styled */
141 ucTmp = ucGetByte(iFodo + 1, aucGrpprl);
142 if ((ucTmp & BIT(0)) != 0) {
143 ucTmp >>= 1;
144 if (ucTmp >= 88 && ucTmp <= 94) {
145 /* Header levels 1 through 7 */
146 pStyle->usIstd = ucTmp - 87;
147 pStyle->ucNumLevel = 1;
150 if (iBytes < 2) {
151 return;
153 /* jc */
154 ucTmp = ucGetByte(iFodo + 2, aucGrpprl);
155 pStyle->ucAlignment = ucTmp & 0x02;
156 if (iBytes < 3) {
157 return;
159 /* stc */
160 ucTmp = ucGetByte(iFodo + 3, aucGrpprl);
161 ucTmp &= 0x7f;
162 if (ucTmp >= 88 && ucTmp <= 94) {
163 /* Header levels 1 through 7 */
164 pStyle->usIstd = ucTmp - 87;
165 pStyle->ucNumLevel = 1;
167 if (iBytes < 6) {
168 return;
170 /* dxaRight */
171 pStyle->sRightIndent = (short)usGetWord(iFodo + 5, aucGrpprl);
172 NO_DBG_DEC(pStyle->sRightIndent);
173 if (iBytes < 8) {
174 return;
176 /* dxaLeft */
177 pStyle->sLeftIndent = (short)usGetWord(iFodo + 7, aucGrpprl);
178 NO_DBG_DEC(pStyle->sLeftIndent);
179 if (iBytes < 10) {
180 return;
182 /* dxaLeft1 */
183 pStyle->sLeftIndent1 = (short)usGetWord(iFodo + 9, aucGrpprl);
184 NO_DBG_DEC(pStyle->sLeftIndent1);
185 if (iBytes < 14) {
186 return;
188 /* dyaBefore */
189 pStyle->usBeforeIndent = usGetWord(iFodo + 13, aucGrpprl);
190 NO_DBG_DEC(pStyle->usBeforeIndent);
191 if (iBytes < 16) {
192 return;
194 /* dyaAfter */
195 pStyle->usAfterIndent = usGetWord(iFodo + 15, aucGrpprl);
196 NO_DBG_DEC(pStyle->usAfterIndent);
197 } /* end of vGet0StyleInfo */
200 * Build the lists with Paragraph Information for Word for DOS files
202 void
203 vGet0PapInfo(FILE *pFile, const UCHAR *aucHeader)
205 style_block_type tStyle;
206 ULONG ulBeginParfInfo, ulCharPos, ulCharPosNext;
207 int iIndex, iRun, iFodo;
208 UCHAR aucFpage[128];
210 fail(pFile == NULL || aucHeader == NULL);
212 ulBeginParfInfo = 128 * (ULONG)usGetWord(0x12, aucHeader);
213 NO_DBG_HEX(ulBeginParfInfo);
215 do {
216 if (!bReadBytes(aucFpage, 128, ulBeginParfInfo, pFile)) {
217 return;
219 NO_DBG_PRINT_BLOCK(aucFpage, 128);
220 ulCharPosNext = ulGetLong(0, aucFpage);
221 iRun = (int)ucGetByte(0x7f, aucFpage);
222 NO_DBG_DEC(iRun);
223 for (iIndex = 0; iIndex < iRun; iIndex++) {
224 iFodo = (int)usGetWord(6 * iIndex + 8, aucFpage);
225 if (iFodo <= 0 || iFodo > 0x79) {
226 DBG_DEC_C(iFodo != (int)0xffff, iFodo);
227 continue;
229 vFillStyleFromStylesheet(0, &tStyle);
230 vGet0StyleInfo(iFodo, aucFpage + 4, &tStyle);
231 ulCharPos = ulCharPosNext;
232 ulCharPosNext = ulGetLong(6 * iIndex + 4, aucFpage);
233 tStyle.ulFileOffset = ulCharPos;
234 vAdd2StyleInfoList(&tStyle);
236 ulBeginParfInfo += 128;
237 } while (ulCharPosNext == ulBeginParfInfo);
238 } /* end of vGet0PapInfo */
241 * Fill the font information block with information
242 * from a Word for DOS file.
244 static void
245 vGet0FontInfo(int iFodo, const UCHAR *aucGrpprl, font_block_type *pFont)
247 int iBytes;
248 UCHAR ucTmp;
250 fail(iFodo <= 0 || aucGrpprl == NULL || pFont == NULL);
252 iBytes = (int)ucGetByte(iFodo, aucGrpprl);
253 if (iBytes < 2) {
254 return;
256 /* fBold, fItalic, cFtc */
257 ucTmp = ucGetByte(iFodo + 2, aucGrpprl);
258 if ((ucTmp & BIT(0)) != 0) {
259 pFont->usFontStyle |= FONT_BOLD;
261 if ((ucTmp & BIT(1)) != 0) {
262 pFont->usFontStyle |= FONT_ITALIC;
264 pFont->ucFontNumber = ucTmp >> 2;
265 NO_DBG_DEC(pFont->ucFontNumber);
266 if (iBytes < 3) {
267 return;
269 /* cHps */
270 pFont->usFontSize = (USHORT)ucGetByte(iFodo + 3, aucGrpprl);
271 NO_DBG_DEC(pFont->usFontSize);
272 if (iBytes < 4) {
273 return;
275 /* cKul, fStrike, fCaps, fSmallCaps, fVanish */
276 ucTmp = ucGetByte(iFodo + 4, aucGrpprl);
277 if ((ucTmp & BIT(0)) != 0 || (ucTmp & BIT(2)) != 0) {
278 pFont->usFontStyle |= FONT_UNDERLINE;
280 if ((ucTmp & BIT(1)) != 0) {
281 pFont->usFontStyle |= FONT_STRIKE;
283 if ((ucTmp & BIT(4)) != 0) {
284 pFont->usFontStyle |= FONT_CAPITALS;
286 if ((ucTmp & BIT(5)) != 0) {
287 pFont->usFontStyle |= FONT_SMALL_CAPITALS;
289 if ((ucTmp & BIT(7)) != 0) {
290 pFont->usFontStyle |= FONT_HIDDEN;
292 DBG_HEX(pFont->usFontStyle);
293 if (iBytes < 6) {
294 return;
296 /* cIss */
297 ucTmp = ucGetByte(iFodo + 6, aucGrpprl);
298 if (ucTmp != 0) {
299 if (ucTmp < 128) {
300 pFont->usFontStyle |= FONT_SUPERSCRIPT;
301 DBG_MSG("Superscript");
302 } else {
303 pFont->usFontStyle |= FONT_SUBSCRIPT;
304 DBG_MSG("Subscript");
307 if (iBytes < 7) {
308 return;
310 /* cIco */
311 ucTmp = ucGetByte(iFodo + 7, aucGrpprl);
312 switch (ucTmp & 0x07) {
313 case 0: pFont->ucFontColor = FONT_COLOR_BLACK; break;
314 case 1: pFont->ucFontColor = FONT_COLOR_RED; break;
315 case 2: pFont->ucFontColor = FONT_COLOR_GREEN; break;
316 case 3: pFont->ucFontColor = FONT_COLOR_BLUE; break;
317 case 4: pFont->ucFontColor = FONT_COLOR_CYAN; break;
318 case 5: pFont->ucFontColor = FONT_COLOR_MAGENTA; break;
319 case 6: pFont->ucFontColor = FONT_COLOR_YELLOW; break;
320 case 7: pFont->ucFontColor = FONT_COLOR_WHITE; break;
321 default:pFont->ucFontColor = FONT_COLOR_BLACK; break;
323 NO_DBG_DEC(pFont->ucFontColor);
324 } /* end of vGet0FontInfo */
327 * Build the lists with Character Information for Word for DOS files
329 void
330 vGet0ChrInfo(FILE *pFile, const UCHAR *aucHeader)
332 font_block_type tFont;
333 ULONG ulBeginCharInfo, ulCharPos, ulCharPosNext;
334 int iIndex, iRun, iFodo;
335 UCHAR aucFpage[128];
337 fail(pFile == NULL || aucHeader == NULL);
339 ulBeginCharInfo = ulGetLong(0x0e, aucHeader);
340 NO_DBG_HEX(ulBeginCharInfo);
341 ulBeginCharInfo = ROUND128(ulBeginCharInfo);
342 NO_DBG_HEX(ulBeginCharInfo);
344 do {
345 if (!bReadBytes(aucFpage, 128, ulBeginCharInfo, pFile)) {
346 return;
348 NO_DBG_PRINT_BLOCK(aucFpage, 128);
349 ulCharPosNext = ulGetLong(0, aucFpage);
350 iRun = (int)ucGetByte(0x7f, aucFpage);
351 NO_DBG_DEC(iRun);
352 for (iIndex = 0; iIndex < iRun; iIndex++) {
353 iFodo = (int)usGetWord(6 * iIndex + 8, aucFpage);
354 if (iFodo <= 0 || iFodo > 0x79) {
355 DBG_DEC_C(iFodo != (int)0xffff, iFodo);
356 continue;
358 vFillFontFromStylesheet(0, &tFont);
359 vGet0FontInfo(iFodo, aucFpage + 4, &tFont);
360 ulCharPos = ulCharPosNext;
361 ulCharPosNext = ulGetLong(6 * iIndex + 4, aucFpage);
362 tFont.ulFileOffset = ulCharPos;
363 vAdd2FontInfoList(&tFont);
365 ulBeginCharInfo += 128;
366 } while (ulCharPosNext == ulBeginCharInfo);
367 } /* end of vGet0ChrInfo */