3 * Copyright (C) 1998-2003 A.J. van Os; Released under GPL
6 * Read the property information from a MS Word 6 or 7 file
15 * iGet6InfoLength - the length of the information for Word 6/7 files
18 iGet6InfoLength(int iByteNbr
, const UCHAR
*aucGrpprl
)
22 switch (ucGetByte(iByteNbr
, aucGrpprl
)) {
23 case 2: case 16: case 17: case 18: case 19: case 21: case 22:
24 case 26: case 27: case 28: case 30: case 31: case 32: case 33:
25 case 34: case 35: case 36: case 38: case 39: case 40: case 41:
26 case 42: case 43: case 45: case 46: case 47: case 48: case 49:
27 case 69: case 72: case 80: case 93: case 96: case 97: case 99:
28 case 101: case 105: case 106: case 107: case 109: case 110: case 121:
29 case 122: case 123: case 124: case 140: case 141: case 144: case 145:
30 case 148: case 149: case 154: case 155: case 156: case 157: case 160:
31 case 161: case 164: case 165: case 166: case 167: case 168: case 169:
32 case 170: case 171: case 182: case 183: case 184: case 189: case 195:
35 case 3: case 12: case 15: case 81: case 103: case 108: case 188:
37 return 2 + (int)ucGetByte(iByteNbr
+ 1, aucGrpprl
);
38 case 20: case 70: case 74: case 192: case 194: case 196: case 200:
41 iTmp
= (int)ucGetByte(iByteNbr
+ 1, aucGrpprl
);
43 iDel
= (int)ucGetByte(iByteNbr
+ 2, aucGrpprl
);
44 iAdd
= (int)ucGetByte(
45 iByteNbr
+ 3 + iDel
* 4, aucGrpprl
);
46 iTmp
= 2 + iDel
* 4 + iAdd
* 3;
49 case 68: case 193: case 199:
51 case 73: case 95: case 136: case 137:
60 } /* end of iGet6InfoLength */
63 * Fill the section information block with information
64 * from a Word 6/7 file.
67 vGet6SectionInfo(const UCHAR
*aucGrpprl
, size_t tBytes
,
68 section_block_type
*pSection
)
71 int iFodoOff
, iInfoLen
, iSize
, iTmp
;
75 fail(aucGrpprl
== NULL
|| pSection
== NULL
);
78 while (tBytes
>= (size_t)iFodoOff
+ 1) {
80 switch (ucGetByte(iFodoOff
, aucGrpprl
)) {
81 case 133: /* olstAnm */
82 iSize
= (int)ucGetByte(iFodoOff
+ 1, aucGrpprl
);
83 DBG_DEC_C(iSize
!= 212, iSize
);
84 for (uiIndex
= 0, iTmp
= iFodoOff
+ 2;
85 uiIndex
< 9 && iTmp
< iFodoOff
+ 2 + iSize
- 15;
86 uiIndex
++, iTmp
+= 16) {
87 pSection
->aucNFC
[uiIndex
] =
88 ucGetByte(iTmp
, aucGrpprl
);
89 NO_DBG_DEC(pSection
->aucNFC
[uiIndex
]);
90 ucTmp
= ucGetByte(iTmp
+ 3, aucGrpprl
);
92 if ((ucTmp
& BIT(2)) != 0) {
93 pSection
->usNeedPrevLvl
|=
96 if ((ucTmp
& BIT(3)) != 0) {
97 pSection
->usHangingIndent
|=
101 DBG_HEX(pSection
->usNeedPrevLvl
);
102 DBG_HEX(pSection
->usHangingIndent
);
105 ucTmp
= ucGetByte(iFodoOff
+ 1, aucGrpprl
);
107 pSection
->bNewPage
= ucTmp
!= 0 && ucTmp
!= 1;
109 case 144: /* ccolM1 */
110 usCcol
= 1 + usGetWord(iFodoOff
+ 1, aucGrpprl
);
117 iInfoLen
= iGet6InfoLength(iFodoOff
, aucGrpprl
);
120 iFodoOff
+= iInfoLen
;
122 } /* end of vGet6SectionInfo */
125 * Build the lists with Section Property Information for Word 6/7 files
128 vGet6SepInfo(FILE *pFile
, ULONG ulStartBlock
,
129 const ULONG
*aulBBD
, size_t tBBDLen
,
130 const UCHAR
*aucHeader
)
132 section_block_type tSection
;
133 ULONG
*aulSectPage
, *aulTextOffset
;
134 UCHAR
*aucBuffer
, *aucFpage
;
135 ULONG ulBeginSectInfo
;
136 size_t tSectInfoLen
, tOffset
, tLen
, tBytes
;
140 fail(pFile
== NULL
|| aucHeader
== NULL
);
141 fail(ulStartBlock
> MAX_BLOCKNUMBER
&& ulStartBlock
!= END_OF_CHAIN
);
142 fail(aulBBD
== NULL
);
144 ulBeginSectInfo
= ulGetLong(0x88, aucHeader
); /* fcPlcfsed */
145 DBG_HEX(ulBeginSectInfo
);
146 tSectInfoLen
= (size_t)ulGetLong(0x8c, aucHeader
); /* lcbPlcfsed */
147 DBG_DEC(tSectInfoLen
);
148 if (tSectInfoLen
< 4) {
149 DBG_DEC(tSectInfoLen
);
153 aucBuffer
= xmalloc(tSectInfoLen
);
154 if (!bReadBuffer(pFile
, ulStartBlock
,
155 aulBBD
, tBBDLen
, BIG_BLOCK_SIZE
,
156 aucBuffer
, ulBeginSectInfo
, tSectInfoLen
)) {
157 aucBuffer
= xfree(aucBuffer
);
160 NO_DBG_PRINT_BLOCK(aucBuffer
, tSectInfoLen
);
162 /* Read the Section Descriptors */
163 tLen
= (tSectInfoLen
- 4) / 16;
164 /* Save the section offsets */
165 aulTextOffset
= xcalloc(tLen
, sizeof(ULONG
));
166 for (iIndex
= 0, tOffset
= 0;
168 iIndex
++, tOffset
+= 4) {
169 aulTextOffset
[iIndex
] = ulGetLong(tOffset
, aucBuffer
);
171 /* Save the Sepx offsets */
172 aulSectPage
= xcalloc(tLen
, sizeof(ULONG
));
173 for (iIndex
= 0, tOffset
= (tLen
+ 1) * 4;
175 iIndex
++, tOffset
+= 12) {
176 aulSectPage
[iIndex
] = ulGetLong(tOffset
+ 2, aucBuffer
);
177 NO_DBG_HEX(aulSectPage
[iIndex
]); /* fcSepx */
179 aucBuffer
= xfree(aucBuffer
);
181 /* Read the Section Properties */
182 for (iIndex
= 0; iIndex
< (int)tLen
; iIndex
++) {
183 if (aulSectPage
[iIndex
] == FC_INVALID
) {
184 vDefault2SectionInfoList(aulTextOffset
[iIndex
]);
187 /* Get the number of bytes to read */
188 if (!bReadBuffer(pFile
, ulStartBlock
,
189 aulBBD
, tBBDLen
, BIG_BLOCK_SIZE
,
190 aucTmp
, aulSectPage
[iIndex
], 2)) {
193 tBytes
= 2 + (size_t)usGetWord(0, aucTmp
);
196 aucFpage
= xmalloc(tBytes
);
197 if (!bReadBuffer(pFile
, ulStartBlock
,
198 aulBBD
, tBBDLen
, BIG_BLOCK_SIZE
,
199 aucFpage
, aulSectPage
[iIndex
], tBytes
)) {
200 aucFpage
= xfree(aucFpage
);
203 NO_DBG_PRINT_BLOCK(aucFpage
, tBytes
);
204 /* Process the bytes */
205 vGetDefaultSection(&tSection
);
206 vGet6SectionInfo(aucFpage
+ 2, tBytes
- 2, &tSection
);
207 vAdd2SectionInfoList(&tSection
, aulTextOffset
[iIndex
]);
208 aucFpage
= xfree(aucFpage
);
210 aulTextOffset
= xfree(aulTextOffset
);
211 aulSectPage
= xfree(aulSectPage
);
212 } /* end of vGet6SepInfo */
215 * Translate the rowinfo to a member of the row_info enumeration
218 eGet6RowInfo(int iFodo
,
219 const UCHAR
*aucGrpprl
, int iBytes
, row_block_type
*pRow
)
221 int iFodoOff
, iInfoLen
;
222 int iIndex
, iSize
, iCol
;
223 int iPosCurr
, iPosPrev
;
225 BOOL bFound24_0
, bFound24_1
, bFound25_0
, bFound25_1
, bFound190
;
227 fail(iFodo
< 0 || aucGrpprl
== NULL
|| pRow
== NULL
);
235 while (iBytes
>= iFodoOff
+ 1) {
237 switch (ucGetByte(iFodo
+ iFodoOff
, aucGrpprl
)) {
238 case 24: /* fIntable */
239 if (odd(ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
))) {
246 if (odd(ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
))) {
252 case 38: /* brcTop */
253 usTmp
= usGetWord(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
255 NO_DBG_DEC(usTmp
>> 3);
257 pRow
->ucBorderInfo
&= ~TABLE_BORDER_TOP
;
259 pRow
->ucBorderInfo
|= TABLE_BORDER_TOP
;
262 case 39: /* brcLeft */
263 usTmp
= usGetWord(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
265 NO_DBG_DEC(usTmp
>> 3);
267 pRow
->ucBorderInfo
&= ~TABLE_BORDER_LEFT
;
269 pRow
->ucBorderInfo
|= TABLE_BORDER_LEFT
;
272 case 40: /* brcBottom */
273 usTmp
= usGetWord(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
275 NO_DBG_DEC(usTmp
>> 3);
277 pRow
->ucBorderInfo
&= ~TABLE_BORDER_BOTTOM
;
279 pRow
->ucBorderInfo
|= TABLE_BORDER_BOTTOM
;
282 case 41: /* brcRight */
283 usTmp
= usGetWord(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
285 NO_DBG_DEC(usTmp
>> 3);
287 pRow
->ucBorderInfo
&= ~TABLE_BORDER_RIGHT
;
289 pRow
->ucBorderInfo
|= TABLE_BORDER_RIGHT
;
292 case 190: /* cDefTable */
293 iSize
= (int)usGetWord(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
294 if (iSize
< 6 || iBytes
< iFodoOff
+ 7) {
300 iCol
= (int)ucGetByte(iFodo
+ iFodoOff
+ 3, aucGrpprl
);
302 iBytes
< iFodoOff
+ 3 + (iCol
+ 1) * 2) {
308 if (iCol
>= (int)elementsof(pRow
->asColumnWidth
)) {
310 werr(1, "The number of columns is corrupt");
312 pRow
->ucNumberOfColumns
= (UCHAR
)iCol
;
313 pRow
->iColumnWidthSum
= 0;
314 iPosPrev
= (int)(short)usGetWord(
315 iFodo
+ iFodoOff
+ 4,
317 for (iIndex
= 0; iIndex
< iCol
; iIndex
++) {
318 iPosCurr
= (int)(short)usGetWord(
319 iFodo
+ iFodoOff
+ 6 + iIndex
* 2,
321 pRow
->asColumnWidth
[iIndex
] =
322 (short)(iPosCurr
- iPosPrev
);
323 pRow
->iColumnWidthSum
+=
324 pRow
->asColumnWidth
[iIndex
];
334 iGet6InfoLength(iFodo
+ iFodoOff
, aucGrpprl
);
337 iFodoOff
+= iInfoLen
;
339 if (bFound24_1
&& bFound25_1
&& bFound190
) {
340 return found_end_of_row
;
342 if (bFound24_0
&& bFound25_0
&& !bFound190
) {
343 return found_not_end_of_row
;
349 return found_not_a_cell
;
351 return found_nothing
;
352 } /* end of eGet6RowInfo */
355 * Fill the style information block with information
356 * from a Word 6/7 file.
359 vGet6StyleInfo(int iFodo
,
360 const UCHAR
*aucGrpprl
, int iBytes
, style_block_type
*pStyle
)
362 int iFodoOff
, iInfoLen
;
363 int iTmp
, iDel
, iAdd
, iBefore
;
367 fail(iFodo
< 0 || aucGrpprl
== NULL
|| pStyle
== NULL
);
369 NO_DBG_DEC(pStyle
->usIstd
);
372 while (iBytes
>= iFodoOff
+ 1) {
374 switch (ucGetByte(iFodo
+ iFodoOff
, aucGrpprl
)) {
376 sTmp
= (short)ucGetByte(
377 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
381 pStyle
->ucAlignment
= ucGetByte(
382 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
385 iTmp
= (int)ucGetByte(
386 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
387 DBG_DEC_C(iTmp
< 52, iTmp
);
389 pStyle
->ucNFC
= ucGetByte(
390 iFodo
+ iFodoOff
+ 2, aucGrpprl
);
392 if (pStyle
->ucNFC
!= LIST_BULLETS
&& iTmp
>= 2) {
393 iBefore
= (int)ucGetByte(
394 iFodo
+ iFodoOff
+ 3, aucGrpprl
);
399 pStyle
->usStartAt
= usGetWord(
400 iFodo
+ iFodoOff
+ 12, aucGrpprl
);
402 if (iTmp
>= iBefore
+ 21) {
403 pStyle
->usListChar
= (USHORT
)ucGetByte(
404 iFodo
+ iFodoOff
+ iBefore
+ 22,
406 NO_DBG_HEX(pStyle
->usListChar
);
409 case 13: /* nLvlAnm */
410 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
411 pStyle
->ucNumLevel
= ucTmp
;
413 eGetNumType(ucTmp
) == level_type_pause
;
415 case 15: /* ChgTabsPapx */
416 iTmp
= (int)ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
422 iDel
= (int)ucGetByte(iFodo
+ iFodoOff
+ 2, aucGrpprl
);
423 if (iTmp
< 2 + 2 * iDel
) {
428 iAdd
= (int)ucGetByte(
429 iFodo
+ iFodoOff
+ 3 + 2 * iDel
, aucGrpprl
);
430 if (iTmp
< 2 + 2 * iDel
+ 2 * iAdd
) {
436 case 16: /* dxaRight */
437 pStyle
->sRightIndent
= (short)usGetWord(
438 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
439 NO_DBG_DEC(pStyle
->sRightIndent
);
441 case 17: /* dxaLeft */
442 pStyle
->sLeftIndent
= (short)usGetWord(
443 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
444 NO_DBG_DEC(pStyle
->sLeftIndent
);
446 case 18: /* Nest dxaLeft */
447 sTmp
= (short)usGetWord(
448 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
449 pStyle
->sLeftIndent
+= sTmp
;
450 if (pStyle
->sLeftIndent
< 0) {
451 pStyle
->sLeftIndent
= 0;
454 NO_DBG_DEC(pStyle
->sLeftIndent
);
456 case 19: /* dxaLeft1 */
457 pStyle
->sLeftIndent1
= (short)usGetWord(
458 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
459 NO_DBG_DEC(pStyle
->sLeftIndent1
);
461 case 21: /* dyaBefore */
462 pStyle
->usBeforeIndent
= usGetWord(
463 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
464 NO_DBG_DEC(pStyle
->usBeforeIndent
);
466 case 22: /* dyaAfter */
467 pStyle
->usAfterIndent
= usGetWord(
468 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
469 NO_DBG_DEC(pStyle
->usAfterIndent
);
476 iGet6InfoLength(iFodo
+ iFodoOff
, aucGrpprl
);
479 iFodoOff
+= iInfoLen
;
481 } /* end of vGet6StyleInfo */
484 * Build the lists with Paragraph Information for Word 6/7 files
487 vGet6PapInfo(FILE *pFile
, ULONG ulStartBlock
,
488 const ULONG
*aulBBD
, size_t tBBDLen
,
489 const UCHAR
*aucHeader
)
492 style_block_type tStyle
;
495 ULONG ulCharPos
, ulCharPosFirst
, ulCharPosLast
;
496 ULONG ulBeginParfInfo
;
497 size_t tParfInfoLen
, tParfPageNum
, tOffset
, tSize
, tLenOld
, tLen
;
498 int iIndex
, iIndex2
, iRun
, iFodo
, iLen
;
499 row_info_enum eRowInfo
;
500 USHORT usParfFirstPage
, usCount
, usIstd
;
501 UCHAR aucFpage
[BIG_BLOCK_SIZE
];
503 fail(pFile
== NULL
|| aucHeader
== NULL
);
504 fail(ulStartBlock
> MAX_BLOCKNUMBER
&& ulStartBlock
!= END_OF_CHAIN
);
505 fail(aulBBD
== NULL
);
507 ulBeginParfInfo
= ulGetLong(0xc0, aucHeader
); /* fcPlcfbtePapx */
508 NO_DBG_HEX(ulBeginParfInfo
);
509 tParfInfoLen
= (size_t)ulGetLong(0xc4, aucHeader
); /* lcbPlcfbtePapx */
510 NO_DBG_DEC(tParfInfoLen
);
511 if (tParfInfoLen
< 4) {
512 DBG_DEC(tParfInfoLen
);
516 aucBuffer
= xmalloc(tParfInfoLen
);
517 if (!bReadBuffer(pFile
, ulStartBlock
,
518 aulBBD
, tBBDLen
, BIG_BLOCK_SIZE
,
519 aucBuffer
, ulBeginParfInfo
, tParfInfoLen
)) {
520 aucBuffer
= xfree(aucBuffer
);
523 NO_DBG_PRINT_BLOCK(aucBuffer
, tParfInfoLen
);
525 tLen
= (tParfInfoLen
- 4) / 6;
526 ausParfPage
= xcalloc(tLen
, sizeof(USHORT
));
527 for (iIndex
= 0, tOffset
= (tLen
+ 1) * 4;
529 iIndex
++, tOffset
+= 2) {
530 ausParfPage
[iIndex
] = usGetWord(tOffset
, aucBuffer
);
531 NO_DBG_DEC(ausParfPage
[iIndex
]);
533 DBG_HEX(ulGetLong(0, aucBuffer
));
534 aucBuffer
= xfree(aucBuffer
);
535 tParfPageNum
= (size_t)usGetWord(0x190, aucHeader
); /* cpnBtePap */
536 DBG_DEC(tParfPageNum
);
537 if (tLen
< tParfPageNum
) {
538 /* Replace ParfPage by a longer version */
540 usParfFirstPage
= usGetWord(0x18c, aucHeader
); /* pnPapFirst */
541 DBG_DEC(usParfFirstPage
);
542 tLen
+= tParfPageNum
- 1;
543 tSize
= tLen
* sizeof(USHORT
);
544 ausParfPage
= xrealloc(ausParfPage
, tSize
);
546 usCount
= usParfFirstPage
+ 1;
547 for (iIndex
= (int)tLenOld
; iIndex
< (int)tLen
; iIndex
++) {
548 ausParfPage
[iIndex
] = usCount
;
549 NO_DBG_DEC(ausParfPage
[iIndex
]);
554 (void)memset(&tRow
, 0, sizeof(tRow
));
555 ulCharPosFirst
= CP_INVALID
;
556 for (iIndex
= 0; iIndex
< (int)tLen
; iIndex
++) {
557 if (!bReadBuffer(pFile
, ulStartBlock
,
558 aulBBD
, tBBDLen
, BIG_BLOCK_SIZE
,
560 (ULONG
)ausParfPage
[iIndex
] * BIG_BLOCK_SIZE
,
564 iRun
= (int)ucGetByte(0x1ff, aucFpage
);
566 for (iIndex2
= 0; iIndex2
< iRun
; iIndex2
++) {
567 NO_DBG_HEX(ulGetLong(iIndex2
* 4, aucFpage
));
568 iFodo
= 2 * (int)ucGetByte(
569 (iRun
+ 1) * 4 + iIndex2
* 7, aucFpage
);
574 iLen
= 2 * (int)ucGetByte(iFodo
, aucFpage
);
576 usIstd
= (USHORT
)ucGetByte(iFodo
+ 1, aucFpage
);
577 vFillStyleFromStylesheet(usIstd
, &tStyle
);
578 vGet6StyleInfo(iFodo
, aucFpage
+ 3, iLen
- 3, &tStyle
);
579 ulCharPos
= ulGetLong(iIndex2
* 4, aucFpage
);
580 NO_DBG_HEX(ulCharPos
);
581 tStyle
.ulFileOffset
= ulCharPos2FileOffset(ulCharPos
);
582 vAdd2StyleInfoList(&tStyle
);
584 eRowInfo
= eGet6RowInfo(iFodo
,
585 aucFpage
+ 3, iLen
- 3, &tRow
);
588 if (ulCharPosFirst
!= CP_INVALID
) {
591 ulCharPosFirst
= ulGetLong(
592 iIndex2
* 4, aucFpage
);
593 NO_DBG_HEX(ulCharPosFirst
);
594 tRow
.ulCharPosStart
= ulCharPosFirst
;
595 tRow
.ulFileOffsetStart
=
596 ulCharPos2FileOffset(ulCharPosFirst
);
597 DBG_HEX_C(tRow
.ulFileOffsetStart
== FC_INVALID
,
600 case found_end_of_row
:
601 ulCharPosLast
= ulGetLong(
602 iIndex2
* 4, aucFpage
);
603 NO_DBG_HEX(ulCharPosLast
);
604 tRow
.ulCharPosEnd
= ulCharPosLast
;
605 tRow
.ulFileOffsetEnd
= ulCharPos2FileOffset(
607 DBG_HEX_C(tRow
.ulFileOffsetEnd
== FC_INVALID
,
609 vAdd2RowInfoList(&tRow
);
610 (void)memset(&tRow
, 0, sizeof(tRow
));
611 ulCharPosFirst
= CP_INVALID
;
621 ausParfPage
= xfree(ausParfPage
);
622 } /* end of vGet6PapInfo */
625 * Fill the font information block with information
626 * from a Word 6/7 file.
627 * Returns TRUE when successful, otherwise FALSE
630 vGet6FontInfo(int iFodo
, USHORT usIstd
,
631 const UCHAR
*aucGrpprl
, int iBytes
, font_block_type
*pFont
)
634 int iFodoOff
, iInfoLen
;
638 fail(iFodo
< 0 || aucGrpprl
== NULL
|| pFont
== NULL
);
641 while (iBytes
>= iFodoOff
+ 1) {
642 switch (ucGetByte(iFodo
+ iFodoOff
, aucGrpprl
)) {
643 case 65: /* fRMarkDel */
644 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
646 pFont
->usFontStyle
&= ~FONT_MARKDEL
;
648 pFont
->usFontStyle
|= FONT_MARKDEL
;
652 usTmp
= usGetWord(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
655 case 82: /* cDefault */
656 pFont
->usFontStyle
&= FONT_HIDDEN
;
657 pFont
->ucFontColor
= FONT_COLOR_DEFAULT
;
659 case 83: /* cPlain */
660 DBG_MSG("83: cPlain");
661 vFillFontFromStylesheet(usIstd
, pFont
);
664 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
667 pFont
->usFontStyle
&= ~FONT_BOLD
;
670 pFont
->usFontStyle
|= FONT_BOLD
;
672 case 128: /* Unchanged */
674 case 129: /* Negation */
675 pFont
->usFontStyle
^= FONT_BOLD
;
683 case 86: /* fItalic */
684 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
687 pFont
->usFontStyle
&= ~FONT_ITALIC
;
690 pFont
->usFontStyle
|= FONT_ITALIC
;
692 case 128: /* Unchanged */
694 case 129: /* Negation */
695 pFont
->usFontStyle
^= FONT_ITALIC
;
703 case 87: /* fStrike */
704 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
707 pFont
->usFontStyle
&= ~FONT_STRIKE
;
710 pFont
->usFontStyle
|= FONT_STRIKE
;
712 case 128: /* Unchanged */
714 case 129: /* Negation */
715 pFont
->usFontStyle
^= FONT_STRIKE
;
723 case 90: /* fSmallCaps */
724 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
727 pFont
->usFontStyle
&= ~FONT_SMALL_CAPITALS
;
730 pFont
->usFontStyle
|= FONT_SMALL_CAPITALS
;
732 case 128: /* Unchanged */
734 case 129: /* Negation */
735 pFont
->usFontStyle
^= FONT_SMALL_CAPITALS
;
744 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
747 pFont
->usFontStyle
&= ~FONT_CAPITALS
;
750 pFont
->usFontStyle
|= FONT_CAPITALS
;
752 case 128: /* Unchanged */
754 case 129: /* Negation */
755 pFont
->usFontStyle
^= FONT_CAPITALS
;
763 case 92: /* fVanish */
764 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
767 pFont
->usFontStyle
&= ~FONT_HIDDEN
;
770 pFont
->usFontStyle
|= FONT_HIDDEN
;
772 case 128: /* Unchanged */
774 case 129: /* Negation */
775 pFont
->usFontStyle
^= FONT_HIDDEN
;
784 usTmp
= usGetWord(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
785 if (usTmp
<= (USHORT
)UCHAR_MAX
) {
786 pFont
->ucFontNumber
= (UCHAR
)usTmp
;
788 pFont
->ucFontNumber
= 0;
792 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
793 if (ucTmp
== 0 || ucTmp
== 5) {
794 pFont
->usFontStyle
&= ~FONT_UNDERLINE
;
796 NO_DBG_MSG("Underline text");
797 pFont
->usFontStyle
|= FONT_UNDERLINE
;
799 DBG_MSG("Bold text");
800 pFont
->usFontStyle
|= FONT_BOLD
;
804 case 95: /* cHps, cHpsPos */
805 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
807 pFont
->usFontSize
= (USHORT
)ucTmp
;
813 ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
817 usGetWord(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
820 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
823 pFont
->usFontStyle
|= FONT_SUPERSCRIPT
;
824 NO_DBG_MSG("Superscript");
825 } else if (ucTmp
== 2) {
826 pFont
->usFontStyle
|= FONT_SUBSCRIPT
;
827 NO_DBG_MSG("Subscript");
831 usTmp
= usGetWord(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
832 lTmp
= (long)pFont
->usFontSize
+ (long)usTmp
;
834 pFont
->usFontSize
= 8;
835 } else if (lTmp
> 32766) {
836 pFont
->usFontSize
= 32766;
838 pFont
->usFontSize
= (USHORT
)lTmp
;
844 iInfoLen
= iGet6InfoLength(iFodo
+ iFodoOff
, aucGrpprl
);
846 iFodoOff
+= iInfoLen
;
848 } /* end of vGet6FontInfo */
851 * Fill the picture information block with information
852 * from a Word 6/7 file.
853 * Returns TRUE when successful, otherwise FALSE
856 bGet6PicInfo(int iFodo
,
857 const UCHAR
*aucGrpprl
, int iBytes
, picture_block_type
*pPicture
)
859 int iFodoOff
, iInfoLen
;
863 fail(iFodo
< 0 || aucGrpprl
== NULL
|| pPicture
== NULL
);
867 while (iBytes
>= iFodoOff
+ 1) {
868 switch (ucGetByte(iFodo
+ iFodoOff
, aucGrpprl
)) {
870 pPicture
->ulPictureOffset
= ulGetLong(
871 iFodo
+ iFodoOff
+ 2, aucGrpprl
);
875 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
877 /* Not a picture, but a form field */
880 DBG_DEC_C(ucTmp
!= 0, ucTmp
);
883 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
885 /* Not a picture, but an OLE object */
888 DBG_DEC_C(ucTmp
!= 0, ucTmp
);
893 iInfoLen
= iGet6InfoLength(iFodo
+ iFodoOff
, aucGrpprl
);
895 iFodoOff
+= iInfoLen
;
898 } /* end of bGet6PicInfo */
901 * Build the lists with Character Information for Word 6/7 files
904 vGet6ChrInfo(FILE *pFile
, ULONG ulStartBlock
,
905 const ULONG
*aulBBD
, size_t tBBDLen
, const UCHAR
*aucHeader
)
907 font_block_type tFont
;
908 picture_block_type tPicture
;
911 ULONG ulFileOffset
, ulCharPos
, ulBeginCharInfo
;
912 size_t tCharInfoLen
, tOffset
, tSize
, tLenOld
, tLen
, tCharPageNum
;
913 int iIndex
, iIndex2
, iRun
, iFodo
, iLen
;
914 USHORT usCharFirstPage
, usCount
, usIstd
;
915 UCHAR aucFpage
[BIG_BLOCK_SIZE
];
917 fail(pFile
== NULL
|| aucHeader
== NULL
);
918 fail(ulStartBlock
> MAX_BLOCKNUMBER
&& ulStartBlock
!= END_OF_CHAIN
);
919 fail(aulBBD
== NULL
);
921 ulBeginCharInfo
= ulGetLong(0xb8, aucHeader
); /* fcPlcfbteChpx */
922 NO_DBG_HEX(lBeginCharInfo
);
923 tCharInfoLen
= (size_t)ulGetLong(0xbc, aucHeader
); /* lcbPlcfbteChpx */
924 NO_DBG_DEC(tCharInfoLen
);
925 if (tCharInfoLen
< 4) {
926 DBG_DEC(tCharInfoLen
);
930 aucBuffer
= xmalloc(tCharInfoLen
);
931 if (!bReadBuffer(pFile
, ulStartBlock
,
932 aulBBD
, tBBDLen
, BIG_BLOCK_SIZE
,
933 aucBuffer
, ulBeginCharInfo
, tCharInfoLen
)) {
934 aucBuffer
= xfree(aucBuffer
);
938 tLen
= (tCharInfoLen
- 4) / 6;
939 ausCharPage
= xcalloc(tLen
, sizeof(USHORT
));
940 for (iIndex
= 0, tOffset
= (tLen
+ 1) * 4;
942 iIndex
++, tOffset
+= 2) {
943 ausCharPage
[iIndex
] = usGetWord(tOffset
, aucBuffer
);
944 NO_DBG_DEC(ausCharPage
[iIndex
]);
946 DBG_HEX(ulGetLong(0, aucBuffer
));
947 aucBuffer
= xfree(aucBuffer
);
948 tCharPageNum
= (size_t)usGetWord(0x18e, aucHeader
); /* cpnBteChp */
949 DBG_DEC(tCharPageNum
);
950 if (tLen
< tCharPageNum
) {
951 /* Replace CharPage by a longer version */
953 usCharFirstPage
= usGetWord(0x18a, aucHeader
); /* pnChrFirst */
954 DBG_DEC(usCharFirstPage
);
955 tLen
+= tCharPageNum
- 1;
956 tSize
= tLen
* sizeof(USHORT
);
957 ausCharPage
= xrealloc(ausCharPage
, tSize
);
959 usCount
= usCharFirstPage
+ 1;
960 for (iIndex
= (int)tLenOld
; iIndex
< (int)tLen
; iIndex
++) {
961 ausCharPage
[iIndex
] = usCount
;
962 NO_DBG_DEC(ausCharPage
[iIndex
]);
967 for (iIndex
= 0; iIndex
< (int)tLen
; iIndex
++) {
968 if (!bReadBuffer(pFile
, ulStartBlock
,
969 aulBBD
, tBBDLen
, BIG_BLOCK_SIZE
,
971 (ULONG
)ausCharPage
[iIndex
] * BIG_BLOCK_SIZE
,
975 iRun
= (int)ucGetByte(0x1ff, aucFpage
);
977 for (iIndex2
= 0; iIndex2
< iRun
; iIndex2
++) {
978 ulCharPos
= ulGetLong(iIndex2
* 4, aucFpage
);
979 ulFileOffset
= ulCharPos2FileOffset(ulCharPos
);
980 iFodo
= 2 * (int)ucGetByte(
981 (iRun
+ 1) * 4 + iIndex2
, aucFpage
);
983 iLen
= (int)ucGetByte(iFodo
, aucFpage
);
985 usIstd
= usGetIstd(ulFileOffset
);
986 vFillFontFromStylesheet(usIstd
, &tFont
);
988 vGet6FontInfo(iFodo
, usIstd
,
989 aucFpage
+ 1, iLen
- 1, &tFont
);
991 tFont
.ulFileOffset
= ulFileOffset
;
992 vAdd2FontInfoList(&tFont
);
998 (void)memset(&tPicture
, 0, sizeof(tPicture
));
999 if (bGet6PicInfo(iFodo
, aucFpage
+ 1,
1000 iLen
- 1, &tPicture
)) {
1001 tPicture
.ulFileOffset
= ulFileOffset
;
1002 tPicture
.ulFileOffsetPicture
=
1003 ulDataPos2FileOffset(
1004 tPicture
.ulPictureOffset
);
1005 vAdd2PictInfoList(&tPicture
);
1009 ausCharPage
= xfree(ausCharPage
);
1010 } /* end of vGet6ChrInfo */