3 * Copyright (C) 1998-2002 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
)
70 int iFodoOff
, iInfoLen
, iSize
, iIndex
, iTmp
;
74 fail(aucGrpprl
== NULL
|| pSection
== NULL
);
77 while (tBytes
>= (size_t)iFodoOff
+ 1) {
79 switch (ucGetByte(iFodoOff
, aucGrpprl
)) {
80 case 133: /* olstAnm */
81 iSize
= (int)ucGetByte(iFodoOff
+ 1, aucGrpprl
);
82 DBG_DEC_C(iSize
!= 212, iSize
);
83 for (iIndex
= 0, iTmp
= iFodoOff
+ 2;
84 iIndex
< 9 && iTmp
< iFodoOff
+ 2 + iSize
- 15;
85 iIndex
++, iTmp
+= 16) {
86 pSection
->aucNFC
[iIndex
] =
87 ucGetByte(iTmp
, aucGrpprl
);
88 DBG_DEC(pSection
->aucNFC
[iIndex
]);
89 ucTmp
= ucGetByte(iTmp
+ 3, aucGrpprl
);
91 if ((ucTmp
& BIT(2)) != 0) {
92 pSection
->usNeedPrevLvl
|=
95 if ((ucTmp
& BIT(3)) != 0) {
96 pSection
->usHangingIndent
|=
100 DBG_HEX(pSection
->usNeedPrevLvl
);
101 DBG_HEX(pSection
->usHangingIndent
);
104 ucTmp
= ucGetByte(iFodoOff
+ 1, aucGrpprl
);
106 pSection
->bNewPage
= ucTmp
!= 0 && ucTmp
!= 1;
108 case 144: /* ccolM1 */
109 usCcol
= 1 + usGetWord(iFodoOff
+ 1, aucGrpprl
);
116 iInfoLen
= iGet6InfoLength(iFodoOff
, aucGrpprl
);
119 iFodoOff
+= iInfoLen
;
121 } /* end of vGet6SectionInfo */
124 * Build the lists with Section Property Information for Word 6/7 files
127 vGet6SepInfo(FILE *pFile
, ULONG ulStartBlock
,
128 const ULONG
*aulBBD
, size_t tBBDLen
,
129 const UCHAR
*aucHeader
)
131 section_block_type tSection
;
132 ULONG
*aulSectPage
, *aulTextOffset
;
133 UCHAR
*aucBuffer
, *aucFpage
;
134 ULONG ulBeginSectInfo
;
135 size_t tSectInfoLen
, tOffset
, tSize
, tLen
, tBytes
;
139 fail(pFile
== NULL
|| aucHeader
== NULL
);
140 fail(ulStartBlock
> MAX_BLOCKNUMBER
&& ulStartBlock
!= END_OF_CHAIN
);
141 fail(aulBBD
== NULL
);
143 ulBeginSectInfo
= ulGetLong(0x88, aucHeader
); /* fcPlcfsed */
144 DBG_HEX(ulBeginSectInfo
);
145 tSectInfoLen
= (size_t)ulGetLong(0x8c, aucHeader
); /* lcbPlcfsed */
146 DBG_DEC(tSectInfoLen
);
147 if (tSectInfoLen
< 4) {
148 DBG_DEC(tSectInfoLen
);
152 aucBuffer
= xmalloc(tSectInfoLen
);
153 if (!bReadBuffer(pFile
, ulStartBlock
,
154 aulBBD
, tBBDLen
, BIG_BLOCK_SIZE
,
155 aucBuffer
, ulBeginSectInfo
, tSectInfoLen
)) {
156 aucBuffer
= xfree(aucBuffer
);
159 NO_DBG_PRINT_BLOCK(aucBuffer
, tSectInfoLen
);
161 /* Read the Section Descriptors */
162 tLen
= (tSectInfoLen
- 4) / 16;
163 tSize
= tLen
* sizeof(ULONG
);
164 /* Save the section offsets */
165 aulTextOffset
= xmalloc(tSize
);
166 for (iIndex
= 0, tOffset
= 0;
168 iIndex
++, tOffset
+= 4) {
169 aulTextOffset
[iIndex
] = ulGetLong(tOffset
, aucBuffer
);
171 /* Save the Sepx offsets */
172 aulSectPage
= xmalloc(tSize
);
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
;
224 BOOL bFound24_0
, bFound24_1
, bFound25_0
, bFound25_1
, bFound190
;
226 fail(iFodo
< 0 || aucGrpprl
== NULL
|| pRow
== NULL
);
234 while (iBytes
>= iFodoOff
+ 1) {
236 switch (ucGetByte(iFodo
+ iFodoOff
, aucGrpprl
)) {
237 case 24: /* fIntable */
238 if (odd(ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
))) {
245 if (odd(ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
))) {
251 case 190: /* cDefTable */
252 iSize
= (int)usGetWord(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
253 if (iSize
< 6 || iBytes
< iFodoOff
+ 7) {
259 iCol
= (int)ucGetByte(iFodo
+ iFodoOff
+ 3, aucGrpprl
);
261 iBytes
< iFodoOff
+ 3 + (iCol
+ 1) * 2) {
267 if (iCol
>= (int)elementsof(pRow
->asColumnWidth
)) {
269 werr(1, "The number of columns is corrupt");
271 pRow
->ucNumberOfColumns
= (UCHAR
)iCol
;
272 pRow
->iColumnWidthSum
= 0;
273 iPosPrev
= (int)(short)usGetWord(
274 iFodo
+ iFodoOff
+ 4,
276 for (iIndex
= 0; iIndex
< iCol
; iIndex
++) {
277 iPosCurr
= (int)(short)usGetWord(
278 iFodo
+ iFodoOff
+ 6 + iIndex
* 2,
280 pRow
->asColumnWidth
[iIndex
] =
281 (short)(iPosCurr
- iPosPrev
);
282 pRow
->iColumnWidthSum
+=
283 pRow
->asColumnWidth
[iIndex
];
293 iGet6InfoLength(iFodo
+ iFodoOff
, aucGrpprl
);
296 iFodoOff
+= iInfoLen
;
298 if (bFound24_1
&& bFound25_1
&& bFound190
) {
299 return found_end_of_row
;
301 if (bFound24_0
&& bFound25_0
&& !bFound190
) {
302 return found_not_end_of_row
;
308 return found_not_a_cell
;
310 return found_nothing
;
311 } /* end of eGet6RowInfo */
314 * Fill the style information block with information
315 * from a Word 6/7 file.
318 vGet6StyleInfo(int iFodo
,
319 const UCHAR
*aucGrpprl
, int iBytes
, style_block_type
*pStyle
)
321 int iFodoOff
, iInfoLen
;
322 int iTmp
, iDel
, iAdd
, iBefore
;
326 fail(iFodo
< 0 || aucGrpprl
== NULL
|| pStyle
== NULL
);
328 NO_DBG_DEC(pStyle
->usIstd
);
331 while (iBytes
>= iFodoOff
+ 1) {
333 switch (ucGetByte(iFodo
+ iFodoOff
, aucGrpprl
)) {
335 sTmp
= (short)ucGetByte(
336 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
340 pStyle
->ucAlignment
= ucGetByte(
341 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
344 iTmp
= (int)ucGetByte(
345 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
346 DBG_DEC_C(iTmp
< 52, iTmp
);
347 pStyle
->bInList
= TRUE
;
349 pStyle
->ucNFC
= ucGetByte(
350 iFodo
+ iFodoOff
+ 2, aucGrpprl
);
352 if (pStyle
->ucNFC
!= LIST_BULLETS
&& iTmp
>= 2) {
353 iBefore
= (int)ucGetByte(
354 iFodo
+ iFodoOff
+ 3, aucGrpprl
);
359 pStyle
->usStartAt
= usGetWord(
360 iFodo
+ iFodoOff
+ 12, aucGrpprl
);
362 if (iTmp
>= iBefore
+ 21) {
363 pStyle
->ucListCharacter
= ucGetByte(
364 iFodo
+ iFodoOff
+ iBefore
+ 22,
366 NO_DBG_CHR(pStyle
->ucListCharacter
);
369 case 13: /* nLvlAnm */
370 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
371 pStyle
->ucListLevel
= ucTmp
;
374 pStyle
->bNoNumbering
= TRUE
;
377 pStyle
->bNumPause
= TRUE
;
380 if ((int)ucTmp
== 0 || (int)ucTmp
>= 12) {
381 pStyle
->bNumPause
= TRUE
;
385 case 15: /* ChgTabsPapx */
386 iTmp
= (int)ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
392 iDel
= (int)ucGetByte(iFodo
+ iFodoOff
+ 2, aucGrpprl
);
393 if (iTmp
< 2 + 2 * iDel
) {
398 iAdd
= (int)ucGetByte(
399 iFodo
+ iFodoOff
+ 3 + 2 * iDel
, aucGrpprl
);
400 if (iTmp
< 2 + 2 * iDel
+ 2 * iAdd
) {
406 case 16: /* dxaRight */
407 pStyle
->sRightIndent
= (short)usGetWord(
408 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
409 NO_DBG_DEC(pStyle
->sRightIndent
);
411 case 17: /* dxaLeft */
412 pStyle
->sLeftIndent
= (short)usGetWord(
413 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
414 NO_DBG_DEC(pStyle
->sLeftIndent
);
416 case 18: /* Nest dxaLeft */
417 sTmp
= (short)usGetWord(
418 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
419 pStyle
->sLeftIndent
+= sTmp
;
420 if (pStyle
->sLeftIndent
< 0) {
421 pStyle
->sLeftIndent
= 0;
424 NO_DBG_DEC(pStyle
->sLeftIndent
);
426 case 21: /* dyaBefore */
427 pStyle
->usBeforeIndent
= usGetWord(
428 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
429 NO_DBG_DEC(pStyle
->usBeforeIndent
);
431 case 22: /* dyaAfter */
432 pStyle
->usAfterIndent
= usGetWord(
433 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
434 NO_DBG_DEC(pStyle
->usAfterIndent
);
441 iGet6InfoLength(iFodo
+ iFodoOff
, aucGrpprl
);
444 iFodoOff
+= iInfoLen
;
446 } /* end of vGet6StyleInfo */
449 * Build the lists with Paragraph Information for Word 6/7 files
452 vGet6PapInfo(FILE *pFile
, ULONG ulStartBlock
,
453 const ULONG
*aulBBD
, size_t tBBDLen
,
454 const UCHAR
*aucHeader
)
457 style_block_type tStyle
;
460 ULONG ulCharPos
, ulCharPosFirst
, ulCharPosLast
;
461 ULONG ulBeginParfInfo
;
462 size_t tParfInfoLen
, tParfPageNum
, tOffset
, tSize
, tLenOld
, tLen
;
463 int iIndex
, iIndex2
, iRun
, iFodo
, iLen
;
464 row_info_enum eRowInfo
;
465 USHORT usParfFirstPage
, usCount
, usIstd
;
466 UCHAR aucFpage
[BIG_BLOCK_SIZE
];
468 fail(pFile
== NULL
|| aucHeader
== NULL
);
469 fail(ulStartBlock
> MAX_BLOCKNUMBER
&& ulStartBlock
!= END_OF_CHAIN
);
470 fail(aulBBD
== NULL
);
472 ulBeginParfInfo
= ulGetLong(0xc0, aucHeader
); /* fcPlcfbtePapx */
473 NO_DBG_HEX(ulBeginParfInfo
);
474 tParfInfoLen
= (size_t)ulGetLong(0xc4, aucHeader
); /* lcbPlcfbtePapx */
475 NO_DBG_DEC(tParfInfoLen
);
476 if (tParfInfoLen
< 4) {
477 DBG_DEC(tParfInfoLen
);
481 aucBuffer
= xmalloc(tParfInfoLen
);
482 if (!bReadBuffer(pFile
, ulStartBlock
,
483 aulBBD
, tBBDLen
, BIG_BLOCK_SIZE
,
484 aucBuffer
, ulBeginParfInfo
, tParfInfoLen
)) {
485 aucBuffer
= xfree(aucBuffer
);
488 NO_DBG_PRINT_BLOCK(aucBuffer
, tParfInfoLen
);
490 tLen
= (tParfInfoLen
- 4) / 6;
491 tSize
= tLen
* sizeof(USHORT
);
492 ausParfPage
= xmalloc(tSize
);
493 for (iIndex
= 0, tOffset
= (tLen
+ 1) * 4;
495 iIndex
++, tOffset
+= 2) {
496 ausParfPage
[iIndex
] = usGetWord(tOffset
, aucBuffer
);
497 NO_DBG_DEC(ausParfPage
[iIndex
]);
499 DBG_HEX(ulGetLong(0, aucBuffer
));
500 aucBuffer
= xfree(aucBuffer
);
501 tParfPageNum
= (size_t)usGetWord(0x190, aucHeader
); /* cpnBtePap */
502 DBG_DEC(tParfPageNum
);
503 if (tLen
< tParfPageNum
) {
504 /* Replace ParfPage by a longer version */
506 usParfFirstPage
= usGetWord(0x18c, aucHeader
); /* pnPapFirst */
507 DBG_DEC(usParfFirstPage
);
508 tLen
+= tParfPageNum
- 1;
509 tSize
= tLen
* sizeof(USHORT
);
510 ausParfPage
= xrealloc(ausParfPage
, tSize
);
512 usCount
= usParfFirstPage
+ 1;
513 for (iIndex
= (int)tLenOld
; iIndex
< (int)tLen
; iIndex
++) {
514 ausParfPage
[iIndex
] = usCount
;
515 NO_DBG_DEC(ausParfPage
[iIndex
]);
520 (void)memset(&tRow
, 0, sizeof(tRow
));
521 ulCharPosFirst
= CP_INVALID
;
522 for (iIndex
= 0; iIndex
< (int)tLen
; iIndex
++) {
523 if (!bReadBuffer(pFile
, ulStartBlock
,
524 aulBBD
, tBBDLen
, BIG_BLOCK_SIZE
,
526 (ULONG
)ausParfPage
[iIndex
] * BIG_BLOCK_SIZE
,
530 iRun
= (int)ucGetByte(0x1ff, aucFpage
);
532 for (iIndex2
= 0; iIndex2
< iRun
; iIndex2
++) {
533 NO_DBG_HEX(ulGetLong(iIndex2
* 4, aucFpage
));
534 iFodo
= 2 * (int)ucGetByte(
535 (iRun
+ 1) * 4 + iIndex2
* 7, aucFpage
);
540 iLen
= 2 * (int)ucGetByte(iFodo
, aucFpage
);
542 usIstd
= (USHORT
)ucGetByte(iFodo
+ 1, aucFpage
);
543 vFillStyleFromStylesheet(usIstd
, &tStyle
);
544 vGet6StyleInfo(iFodo
, aucFpage
+ 3, iLen
- 3, &tStyle
);
545 ulCharPos
= ulGetLong(iIndex2
* 4, aucFpage
);
546 NO_DBG_HEX(ulCharPos
);
547 tStyle
.ulFileOffset
= ulCharPos2FileOffset(ulCharPos
);
548 vAdd2StyleInfoList(&tStyle
);
550 eRowInfo
= eGet6RowInfo(iFodo
,
551 aucFpage
+ 3, iLen
- 3, &tRow
);
554 if (ulCharPosFirst
!= CP_INVALID
) {
557 ulCharPosFirst
= ulGetLong(
558 iIndex2
* 4, aucFpage
);
559 NO_DBG_HEX(ulCharPosFirst
);
560 tRow
.ulCharPosStart
= ulCharPosFirst
;
561 tRow
.ulFileOffsetStart
=
562 ulCharPos2FileOffset(ulCharPosFirst
);
563 DBG_HEX_C(tRow
.ulFileOffsetStart
== FC_INVALID
,
566 case found_end_of_row
:
567 ulCharPosLast
= ulGetLong(
568 iIndex2
* 4, aucFpage
);
569 NO_DBG_HEX(ulCharPosLast
);
570 tRow
.ulCharPosEnd
= ulCharPosLast
;
571 tRow
.ulFileOffsetEnd
= ulCharPos2FileOffset(
573 DBG_HEX_C(tRow
.ulFileOffsetEnd
== FC_INVALID
,
575 vAdd2RowInfoList(&tRow
);
576 (void)memset(&tRow
, 0, sizeof(tRow
));
577 ulCharPosFirst
= CP_INVALID
;
587 ausParfPage
= xfree(ausParfPage
);
588 } /* end of vGet6PapInfo */
591 * Fill the font information block with information
592 * from a Word 6/7 file.
593 * Returns TRUE when successful, otherwise FALSE
596 vGet6FontInfo(int iFodo
, USHORT usIstd
,
597 const UCHAR
*aucGrpprl
, int iBytes
, font_block_type
*pFont
)
600 int iFodoOff
, iInfoLen
;
605 fail(iFodo
< 0 || aucGrpprl
== NULL
|| pFont
== NULL
);
608 while (iBytes
>= iFodoOff
+ 1) {
609 switch (ucGetByte(iFodo
+ iFodoOff
, aucGrpprl
)) {
610 case 65: /* fRMarkDel */
611 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
613 pFont
->ucFontstyle
&= ~FONT_MARKDEL
;
615 pFont
->ucFontstyle
|= FONT_MARKDEL
;
619 usTmp
= usGetWord(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
622 case 82: /* cDefault */
623 pFont
->ucFontstyle
&= FONT_HIDDEN
;
624 pFont
->ucFontcolor
= FONT_COLOR_DEFAULT
;
626 case 83: /* cPlain */
627 DBG_MSG("83: cPlain");
628 vFillFontFromStylesheet(usIstd
, pFont
);
631 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
634 pFont
->ucFontstyle
&= ~FONT_BOLD
;
637 pFont
->ucFontstyle
|= FONT_BOLD
;
639 case 128: /* Unchanged */
641 case 129: /* Negation */
642 pFont
->ucFontstyle
^= FONT_BOLD
;
650 case 86: /* fItalic */
651 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
654 pFont
->ucFontstyle
&= ~FONT_ITALIC
;
657 pFont
->ucFontstyle
|= FONT_ITALIC
;
659 case 128: /* Unchanged */
661 case 129: /* Negation */
662 pFont
->ucFontstyle
^= FONT_ITALIC
;
670 case 87: /* fStrike */
671 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
674 pFont
->ucFontstyle
&= ~FONT_STRIKE
;
677 pFont
->ucFontstyle
|= FONT_STRIKE
;
679 case 128: /* Unchanged */
681 case 129: /* Negation */
682 pFont
->ucFontstyle
^= FONT_STRIKE
;
690 case 90: /* fSmallCaps */
691 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
694 pFont
->ucFontstyle
&= ~FONT_SMALL_CAPITALS
;
697 pFont
->ucFontstyle
|= FONT_SMALL_CAPITALS
;
699 case 128: /* Unchanged */
701 case 129: /* Negation */
702 pFont
->ucFontstyle
^= FONT_SMALL_CAPITALS
;
711 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
714 pFont
->ucFontstyle
&= ~FONT_CAPITALS
;
717 pFont
->ucFontstyle
|= FONT_CAPITALS
;
719 case 128: /* Unchanged */
721 case 129: /* Negation */
722 pFont
->ucFontstyle
^= FONT_CAPITALS
;
730 case 92: /* fVanish */
731 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
734 pFont
->ucFontstyle
&= ~FONT_HIDDEN
;
737 pFont
->ucFontstyle
|= FONT_HIDDEN
;
739 case 128: /* Unchanged */
741 case 129: /* Negation */
742 pFont
->ucFontstyle
^= FONT_HIDDEN
;
751 usTmp
= usGetWord(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
752 if (usTmp
<= (USHORT
)UCHAR_MAX
) {
753 pFont
->ucFontnumber
= (UCHAR
)usTmp
;
755 pFont
->ucFontnumber
= 0;
759 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
760 if (ucTmp
== 0 || ucTmp
== 5) {
761 pFont
->ucFontstyle
&= ~FONT_UNDERLINE
;
763 NO_DBG_MSG("Underline text");
764 pFont
->ucFontstyle
|= FONT_UNDERLINE
;
766 DBG_MSG("Bold text");
767 pFont
->ucFontstyle
|= FONT_BOLD
;
771 case 95: /* cHps, cHpsPos */
772 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
774 pFont
->sFontsize
= (short)ucTmp
;
780 ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
783 usTmp
= usGetWord(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
784 if (usTmp
> (USHORT
)SHRT_MAX
) {
785 pFont
->sFontsize
= SHRT_MAX
;
787 pFont
->sFontsize
= (short)usTmp
;
791 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
793 DBG_MSG_C(ucTmp
== 1, "Superscript");
794 DBG_MSG_C(ucTmp
== 2, "Subscript");
797 sTmp
= (short)usGetWord(
798 iFodo
+ iFodoOff
+ 1, aucGrpprl
);
799 lTmp
= (long)pFont
->sFontsize
+ (long)sTmp
;
801 pFont
->sFontsize
= 8;
802 } else if (lTmp
> 32766) {
803 pFont
->sFontsize
= 32766;
805 pFont
->sFontsize
= (short)lTmp
;
811 iInfoLen
= iGet6InfoLength(iFodo
+ iFodoOff
, aucGrpprl
);
813 iFodoOff
+= iInfoLen
;
815 } /* end of vGet6FontInfo */
818 * Fill the picture information block with information
819 * from a Word 6/7 file.
820 * Returns TRUE when successful, otherwise FALSE
823 bGet6PicInfo(int iFodo
,
824 const UCHAR
*aucGrpprl
, int iBytes
, picture_block_type
*pPicture
)
826 int iFodoOff
, iInfoLen
;
830 fail(iFodo
< 0 || aucGrpprl
== NULL
|| pPicture
== NULL
);
834 while (iBytes
>= iFodoOff
+ 1) {
835 switch (ucGetByte(iFodo
+ iFodoOff
, aucGrpprl
)) {
837 pPicture
->ulPictureOffset
= ulGetLong(
838 iFodo
+ iFodoOff
+ 2, aucGrpprl
);
842 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
844 /* Not a picture, but a form field */
847 DBG_DEC_C(ucTmp
!= 0, ucTmp
);
850 ucTmp
= ucGetByte(iFodo
+ iFodoOff
+ 1, aucGrpprl
);
852 /* Not a picture, but an OLE object */
855 DBG_DEC_C(ucTmp
!= 0, ucTmp
);
860 iInfoLen
= iGet6InfoLength(iFodo
+ iFodoOff
, aucGrpprl
);
862 iFodoOff
+= iInfoLen
;
865 } /* end of bGet6PicInfo */
868 * Build the lists with Character Information for Word 6/7 files
871 vGet6ChrInfo(FILE *pFile
, ULONG ulStartBlock
,
872 const ULONG
*aulBBD
, size_t tBBDLen
, const UCHAR
*aucHeader
)
874 font_block_type tFont
;
875 picture_block_type tPicture
;
878 ULONG ulFileOffset
, ulCharPos
, ulBeginCharInfo
;
879 size_t tCharInfoLen
, tOffset
, tSize
, tLenOld
, tLen
, tCharPageNum
;
880 int iIndex
, iIndex2
, iRun
, iFodo
, iLen
;
881 USHORT usCharFirstPage
, usCount
, usIstd
;
882 UCHAR aucFpage
[BIG_BLOCK_SIZE
];
884 fail(pFile
== NULL
|| aucHeader
== NULL
);
885 fail(ulStartBlock
> MAX_BLOCKNUMBER
&& ulStartBlock
!= END_OF_CHAIN
);
886 fail(aulBBD
== NULL
);
888 ulBeginCharInfo
= ulGetLong(0xb8, aucHeader
); /* fcPlcfbteChpx */
889 NO_DBG_HEX(lBeginCharInfo
);
890 tCharInfoLen
= (size_t)ulGetLong(0xbc, aucHeader
); /* lcbPlcfbteChpx */
891 NO_DBG_DEC(tCharInfoLen
);
892 if (tCharInfoLen
< 4) {
893 DBG_DEC(tCharInfoLen
);
897 aucBuffer
= xmalloc(tCharInfoLen
);
898 if (!bReadBuffer(pFile
, ulStartBlock
,
899 aulBBD
, tBBDLen
, BIG_BLOCK_SIZE
,
900 aucBuffer
, ulBeginCharInfo
, tCharInfoLen
)) {
901 aucBuffer
= xfree(aucBuffer
);
905 tLen
= (tCharInfoLen
- 4) / 6;
906 tSize
= tLen
* sizeof(USHORT
);
907 ausCharPage
= xmalloc(tSize
);
908 for (iIndex
= 0, tOffset
= (tLen
+ 1) * 4;
910 iIndex
++, tOffset
+= 2) {
911 ausCharPage
[iIndex
] = usGetWord(tOffset
, aucBuffer
);
912 NO_DBG_DEC(ausCharPage
[iIndex
]);
914 DBG_HEX(ulGetLong(0, aucBuffer
));
915 aucBuffer
= xfree(aucBuffer
);
916 tCharPageNum
= (size_t)usGetWord(0x18e, aucHeader
); /* cpnBteChp */
917 DBG_DEC(tCharPageNum
);
918 if (tLen
< tCharPageNum
) {
919 /* Replace CharPage by a longer version */
921 usCharFirstPage
= usGetWord(0x18a, aucHeader
); /* pnChrFirst */
922 DBG_DEC(usCharFirstPage
);
923 tLen
+= tCharPageNum
- 1;
924 tSize
= tLen
* sizeof(USHORT
);
925 ausCharPage
= xrealloc(ausCharPage
, tSize
);
927 usCount
= usCharFirstPage
+ 1;
928 for (iIndex
= (int)tLenOld
; iIndex
< (int)tLen
; iIndex
++) {
929 ausCharPage
[iIndex
] = usCount
;
930 NO_DBG_DEC(ausCharPage
[iIndex
]);
935 for (iIndex
= 0; iIndex
< (int)tLen
; iIndex
++) {
936 if (!bReadBuffer(pFile
, ulStartBlock
,
937 aulBBD
, tBBDLen
, BIG_BLOCK_SIZE
,
939 (ULONG
)ausCharPage
[iIndex
] * BIG_BLOCK_SIZE
,
943 iRun
= (int)ucGetByte(0x1ff, aucFpage
);
945 for (iIndex2
= 0; iIndex2
< iRun
; iIndex2
++) {
946 ulCharPos
= ulGetLong(iIndex2
* 4, aucFpage
);
947 ulFileOffset
= ulCharPos2FileOffset(ulCharPos
);
948 iFodo
= 2 * (int)ucGetByte(
949 (iRun
+ 1) * 4 + iIndex2
, aucFpage
);
951 iLen
= (int)ucGetByte(iFodo
, aucFpage
);
953 usIstd
= usGetIstd(ulFileOffset
);
954 vFillFontFromStylesheet(usIstd
, &tFont
);
956 vGet6FontInfo(iFodo
, usIstd
,
957 aucFpage
+ 1, iLen
- 1, &tFont
);
959 tFont
.ulFileOffset
= ulFileOffset
;
960 vAdd2FontInfoList(&tFont
);
966 (void)memset(&tPicture
, 0, sizeof(tPicture
));
967 if (bGet6PicInfo(iFodo
, aucFpage
+ 1,
968 iLen
- 1, &tPicture
)) {
969 tPicture
.ulFileOffset
= ulFileOffset
;
970 tPicture
.ulFileOffsetPicture
=
971 ulDataPos2FileOffset(
972 tPicture
.ulPictureOffset
);
973 vAdd2PictInfoList(&tPicture
);
977 ausCharPage
= xfree(ausCharPage
);
978 } /* end of vGet6ChrInfo */