diff -r 59758314f811 -r d4524d6a4472 Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/word2text_8c_source.html --- a/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/word2text_8c_source.html Fri Jun 11 15:24:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1521 +0,0 @@ - - -
- -00001 /* -00002 * word2text.c -00003 * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL -00004 * -00005 * Description: -00006 * MS Word to "text" functions -00007 */ -00008 -00009 #include <stdio.h> -00010 #include <stdlib.h> -00011 #include <string.h> -00012 #include <ctype.h> -00013 #if defined(__riscos) -00014 #include "DeskLib:Hourglass.h" -00015 #include "drawfile.h" -00016 #endif /* __riscos */ -00017 #include "antiword.h" -00018 -00019 -00020 #define INITIAL_SIZE 40 -00021 #define EXTENTION_SIZE 20 -00022 -00023 -00024 /* Macros to make sure all such statements will be identical */ -00025 #define OUTPUT_LINE() \ -00026 do {\ -00027 vAlign2Window(pDiag, pAnchor, lWidthMax, ucAlignment);\ -00028 TRACE_MSG("after vAlign2Window");\ -00029 pAnchor = pStartNewOutput(pAnchor, NULL);\ -00030 pOutput = pAnchor;\ -00031 } while(0) -00032 -00033 #define RESET_LINE() \ -00034 do {\ -00035 pAnchor = pStartNewOutput(pAnchor, NULL);\ -00036 pOutput = pAnchor;\ -00037 } while(0) -00038 -00039 #if defined(__riscos) -00040 /* Length of the document in characters */ -00041 static ULONG ulDocumentLength; -00042 /* Number of characters processed so far */ -00043 static ULONG ulCharCounter; -00044 static int iCurrPct, iPrevPct; -00045 #endif /* __riscos */ -00046 /* The document is in the format belonging to this version of Word */ -00047 static int iWordVersion = -1; -00048 /* Special treatment for files from Word 4/5/6 on an Apple Macintosh */ -00049 static BOOL bOldMacFile = FALSE; -00050 /* Section Information */ -00051 static const section_block_type *pSection = NULL; -00052 static const section_block_type *pSectionNext = NULL; -00053 /* All the (command line) options */ -00054 static options_type tOptions; -00055 /* Needed for reading a complete table row */ -00056 static const row_block_type *pRowInfo = NULL; -00057 static BOOL bStartRow = FALSE; -00058 static BOOL bEndRowNorm = FALSE; -00059 static BOOL bEndRowFast = FALSE; -00060 static BOOL bIsTableRow = FALSE; -00061 /* Index of the next style and font information */ -00062 static USHORT usIstdNext = ISTD_NORMAL; -00063 /* Needed for finding the start of a style */ -00064 static const style_block_type *pStyleInfo = NULL; -00065 static style_block_type tStyleNext; -00066 static BOOL bStartStyle = FALSE; -00067 static BOOL bStartStyleNext = FALSE; -00068 /* Needed for finding the start of a font */ -00069 static const font_block_type *pFontInfo = NULL; -00070 static font_block_type tFontNext; -00071 static BOOL bStartFont = FALSE; -00072 static BOOL bStartFontNext = FALSE; -00073 /* Needed for finding an image */ -00074 static ULONG ulFileOffsetImage = FC_INVALID; -00075 -00076 -00077 /* -00078 * vUpdateCounters - Update the counters for the hourglass -00079 */ -00080 static void -00081 vUpdateCounters(void) -00082 { -00083 #if defined(__riscos) -00084 ulCharCounter++; -00085 iCurrPct = (int)((ulCharCounter * 100) / ulDocumentLength); -00086 if (iCurrPct != iPrevPct) { -00087 Hourglass_Percentage(iCurrPct); -00088 iPrevPct = iCurrPct; -00089 } -00090 #endif /* __riscos */ -00091 } /* end of vUpdateCounters */ -00092 -00093 /* -00094 * bOutputContainsText - see if the output contains more than white space -00095 */ -00096 BOOL -00097 bOutputContainsText(const output_type *pAnchor) -00098 { -00099 const output_type *pCurr; -00100 size_t tIndex; -00101 -00102 fail(pAnchor == NULL); -00103 -00104 for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { -00105 fail(pCurr->lStringWidth < 0); -00106 for (tIndex = 0; tIndex < pCurr->tNextFree; tIndex++) { -00107 if (isspace((int)(UCHAR)pCurr->szStorage[tIndex])) { -00108 continue; -00109 } -00110 #if defined(DEBUG) -00111 if (pCurr->szStorage[tIndex] == FILLER_CHAR) { -00112 continue; -00113 } -00114 #endif /* DEBUG */ -00115 return TRUE; -00116 } -00117 } -00118 return FALSE; -00119 } /* end of bOutputContainsText */ -00120 -00121 /* -00122 * lTotalStringWidth - compute the total width of the output string -00123 */ -00124 static long -00125 lTotalStringWidth(const output_type *pAnchor) -00126 { -00127 const output_type *pCurr; -00128 long lTotal; -00129 -00130 lTotal = 0; -00131 for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { -00132 DBG_DEC_C(pCurr->lStringWidth < 0, pCurr->lStringWidth); -00133 fail(pCurr->lStringWidth < 0); -00134 lTotal += pCurr->lStringWidth; -00135 } -00136 return lTotal; -00137 } /* end of lTotalStringWidth */ -00138 -00139 /* -00140 * vStoreByte - store one byte -00141 */ -00142 static void -00143 vStoreByte(UCHAR ucChar, output_type *pOutput) -00144 { -00145 fail(pOutput == NULL); -00146 -00147 if (ucChar == 0) { -00148 pOutput->szStorage[pOutput->tNextFree] = '\0'; -00149 return; -00150 } -00151 -00152 while (pOutput->tNextFree + 2 > pOutput->tStorageSize) { -00153 pOutput->tStorageSize += EXTENTION_SIZE; -00154 pOutput->szStorage = xrealloc(pOutput->szStorage, -00155 pOutput->tStorageSize); -00156 } -00157 pOutput->szStorage[pOutput->tNextFree] = (char)ucChar; -00158 pOutput->szStorage[pOutput->tNextFree + 1] = '\0'; -00159 pOutput->tNextFree++; -00160 } /* end of vStoreByte */ -00161 -00162 /* -00163 * vStoreChar - store a character as one or more bytes -00164 */ -00165 static void -00166 vStoreChar(ULONG ulChar, BOOL bChangeAllowed, output_type *pOutput) -00167 { -00168 char szResult[4]; -00169 size_t tIndex, tLen; -00170 -00171 fail(pOutput == NULL); -00172 -00173 if (tOptions.eEncoding == encoding_utf_8 && bChangeAllowed) { -00174 DBG_HEX_C(ulChar > 0xffff, ulChar); -00175 fail(ulChar > 0xffff); -00176 tLen = tUcs2Utf8(ulChar, szResult, sizeof(szResult)); -00177 for (tIndex = 0; tIndex < tLen; tIndex++) { -00178 vStoreByte((UCHAR)szResult[tIndex], pOutput); -00179 } -00180 } else { -00181 DBG_HEX_C(ulChar > 0xff, ulChar); -00182 fail(ulChar > 0xff); -00183 vStoreByte((UCHAR)ulChar, pOutput); -00184 tLen = 1; -00185 } -00186 pOutput->lStringWidth += lComputeStringWidth( -00187 pOutput->szStorage + pOutput->tNextFree - tLen, -00188 tLen, -00189 pOutput->tFontRef, -00190 pOutput->usFontSize); -00191 } /* end of vStoreChar */ -00192 -00193 /* -00194 * vStoreCharacter - store one character -00195 */ -00196 static void -00197 vStoreCharacter(ULONG ulChar, output_type *pOutput) -00198 { -00199 vStoreChar(ulChar, TRUE, pOutput); -00200 } /* end of vStoreCharacter */ -00201 -00202 /* -00203 * vStoreString - store a string -00204 */ -00205 static void -00206 vStoreString(const char *szString, size_t tStringLength, output_type *pOutput) -00207 { -00208 size_t tIndex; -00209 -00210 fail(szString == NULL || pOutput == NULL); -00211 -00212 for (tIndex = 0; tIndex < tStringLength; tIndex++) { -00213 vStoreCharacter((ULONG)(UCHAR)szString[tIndex], pOutput); -00214 } -00215 } /* end of vStoreString */ -00216 -00217 /* -00218 * vStoreNumberAsDecimal - store a number as a decimal number -00219 */ -00220 static void -00221 vStoreNumberAsDecimal(UINT uiNumber, output_type *pOutput) -00222 { -00223 size_t tLen; -00224 char szString[3 * sizeof(UINT) + 1]; -00225 -00226 fail(uiNumber == 0); -00227 fail(pOutput == NULL); -00228 -00229 tLen = (size_t)sprintf(szString, "%u", uiNumber); -00230 vStoreString(szString, tLen, pOutput); -00231 } /* end of vStoreNumberAsDecimal */ -00232 -00233 /* -00234 * vStoreNumberAsRoman - store a number as a roman numerical -00235 */ -00236 static void -00237 vStoreNumberAsRoman(UINT uiNumber, output_type *pOutput) -00238 { -00239 size_t tLen; -00240 char szString[15]; -00241 -00242 fail(uiNumber == 0); -00243 fail(pOutput == NULL); -00244 -00245 tLen = tNumber2Roman(uiNumber, FALSE, szString); -00246 vStoreString(szString, tLen, pOutput); -00247 } /* end of vStoreNumberAsRoman */ -00248 -00249 /* -00250 * vStoreStyle - store a style -00251 */ -00252 static void -00253 vStoreStyle(diagram_type *pDiag, output_type *pOutput, -00254 const style_block_type *pStyle) -00255 { -00256 size_t tLen; -00257 char szString[120]; -00258 -00259 fail(pDiag == NULL); -00260 fail(pOutput == NULL); -00261 fail(pStyle == NULL); -00262 -00263 if (tOptions.eConversionType == conversion_xml) { -00264 vSetHeaders(pDiag, pStyle->usIstd); -00265 } else { -00266 tLen = tStyle2Window(szString, sizeof(szString), -00267 pStyle, pSection); -00268 vStoreString(szString, tLen, pOutput); -00269 } -00270 } /* end of vStoreStyle */ -00271 -00272 /* -00273 * vPutIndentation - output the specified amount of indentation -00274 */ -00275 static void -00276 vPutIndentation(diagram_type *pDiag, output_type *pOutput, -00277 BOOL bNoMarks, BOOL bFirstLine, -00278 UINT uiListNumber, UCHAR ucNFC, const char *szListChar, -00279 long lLeftIndentation, long lLeftIndentation1) -00280 { -00281 long lWidth; -00282 size_t tIndex, tNextFree; -00283 char szLine[30]; -00284 -00285 fail(pDiag == NULL); -00286 fail(pOutput == NULL); -00287 fail(szListChar == NULL); -00288 fail(lLeftIndentation < 0); -00289 -00290 if (tOptions.eConversionType == conversion_xml) { -00291 /* XML does its own indentation at rendering time */ -00292 return; -00293 } -00294 -00295 if (bNoMarks) { -00296 if (bFirstLine) { -00297 lLeftIndentation += lLeftIndentation1; -00298 } -00299 if (lLeftIndentation < 0) { -00300 lLeftIndentation = 0; -00301 } -00302 vSetLeftIndentation(pDiag, lLeftIndentation); -00303 return; -00304 } -00305 if (lLeftIndentation <= 0) { -00306 DBG_HEX_C(ucNFC != 0x00, ucNFC); -00307 vSetLeftIndentation(pDiag, 0); -00308 return; -00309 } -00310 -00311 #if defined(DEBUG) -00312 if (tOptions.eEncoding == encoding_utf_8) { -00313 fail(strlen(szListChar) > 3); -00314 } else { -00315 DBG_HEX_C(iscntrl((int)szListChar[0]), szListChar[0]); -00316 fail(iscntrl((int)szListChar[0])); -00317 fail(szListChar[1] != '\0'); -00318 } -00319 #endif /* DEBUG */ -00320 -00321 switch (ucNFC) { -00322 case LIST_ARABIC_NUM: -00323 case LIST_NUMBER_TXT: -00324 tNextFree = (size_t)sprintf(szLine, "%u", uiListNumber); -00325 break; -00326 case LIST_UPPER_ROMAN: -00327 case LIST_LOWER_ROMAN: -00328 tNextFree = tNumber2Roman(uiListNumber, -00329 ucNFC == LIST_UPPER_ROMAN, szLine); -00330 break; -00331 case LIST_UPPER_ALPHA: -00332 case LIST_LOWER_ALPHA: -00333 tNextFree = tNumber2Alpha(uiListNumber, -00334 ucNFC == LIST_UPPER_ALPHA, szLine); -00335 break; -00336 case LIST_ORDINAL_NUM: -00337 case LIST_ORDINAL_TXT: -00338 if (uiListNumber % 10 == 1 && uiListNumber != 11) { -00339 tNextFree = -00340 (size_t)sprintf(szLine, "%ust", uiListNumber); -00341 } else if (uiListNumber % 10 == 2 && uiListNumber != 12) { -00342 tNextFree = -00343 (size_t)sprintf(szLine, "%und", uiListNumber); -00344 } else if (uiListNumber % 10 == 3 && uiListNumber != 13) { -00345 tNextFree = -00346 (size_t)sprintf(szLine, "%urd", uiListNumber); -00347 } else { -00348 tNextFree = -00349 (size_t)sprintf(szLine, "%uth", uiListNumber); -00350 } -00351 break; -00352 case LIST_OUTLINE_NUM: -00353 tNextFree = (size_t)sprintf(szLine, "%02u", uiListNumber); -00354 break; -00355 case LIST_SPECIAL: -00356 case LIST_SPECIAL2: -00357 case LIST_BULLETS: -00358 tNextFree = 0; -00359 break; -00360 default: -00361 DBG_HEX(ucNFC); -00362 DBG_FIXME(); -00363 tNextFree = (size_t)sprintf(szLine, "%u", uiListNumber); -00364 break; -00365 } -00366 tNextFree += (size_t)sprintf(szLine + tNextFree, "%.3s", szListChar); -00367 szLine[tNextFree++] = ' '; -00368 szLine[tNextFree] = '\0'; -00369 lWidth = lComputeStringWidth(szLine, tNextFree, -00370 pOutput->tFontRef, pOutput->usFontSize); -00371 lLeftIndentation -= lWidth; -00372 if (lLeftIndentation < 0) { -00373 lLeftIndentation = 0; -00374 } -00375 vSetLeftIndentation(pDiag, lLeftIndentation); -00376 for (tIndex = 0; tIndex < tNextFree; tIndex++) { -00377 vStoreChar((ULONG)(UCHAR)szLine[tIndex], FALSE, pOutput); -00378 } -00379 } /* end of vPutIndentation */ -00380 -00381 /* -00382 * vPutSeparatorLine - output a separator line -00383 * -00384 * A separator line is a horizontal line two inches long. -00385 * Two inches equals 144000 millipoints. -00386 */ -00387 static void -00388 vPutSeparatorLine(output_type *pOutput) -00389 { -00390 long lCharWidth; -00391 int iCounter, iChars; -00392 char szOne[2]; -00393 -00394 fail(pOutput == NULL); -00395 -00396 szOne[0] = OUR_EM_DASH; -00397 szOne[1] = '\0'; -00398 lCharWidth = lComputeStringWidth(szOne, 1, -00399 pOutput->tFontRef, pOutput->usFontSize); -00400 NO_DBG_DEC(lCharWidth); -00401 iChars = (int)((144000 + lCharWidth / 2) / lCharWidth); -00402 NO_DBG_DEC(iChars); -00403 for (iCounter = 0; iCounter < iChars; iCounter++) { -00404 vStoreCharacter((ULONG)(UCHAR)OUR_EM_DASH, pOutput); -00405 } -00406 } /* end of vPutSeparatorLine */ -00407 -00408 /* -00409 * pStartNextOutput - start the next output record -00410 * -00411 * returns a pointer to the next record -00412 */ -00413 static output_type * -00414 pStartNextOutput(output_type *pCurrent) -00415 { -00416 output_type *pNew; -00417 -00418 TRACE_MSG("pStartNextOutput"); -00419 -00420 if (pCurrent->tNextFree == 0) { -00421 /* The current record is empty, re-use */ -00422 fail(pCurrent->szStorage[0] != '\0'); -00423 fail(pCurrent->lStringWidth != 0); -00424 return pCurrent; -00425 } -00426 /* The current record is in use, make a new one */ -00427 pNew = xmalloc(sizeof(*pNew)); -00428 pCurrent->pNext = pNew; -00429 pNew->tStorageSize = INITIAL_SIZE; -00430 pNew->szStorage = xmalloc(pNew->tStorageSize); -00431 pNew->szStorage[0] = '\0'; -00432 pNew->tNextFree = 0; -00433 pNew->lStringWidth = 0; -00434 pNew->ucFontColor = FONT_COLOR_DEFAULT; -00435 pNew->usFontStyle = FONT_REGULAR; -00436 pNew->tFontRef = (drawfile_fontref)0; -00437 pNew->usFontSize = DEFAULT_FONT_SIZE; -00438 pNew->pPrev = pCurrent; -00439 pNew->pNext = NULL; -00440 return pNew; -00441 } /* end of pStartNextOutput */ -00442 -00443 /* -00444 * pStartNewOutput -00445 */ -00446 static output_type * -00447 pStartNewOutput(output_type *pAnchor, output_type *pLeftOver) -00448 { -00449 output_type *pCurr, *pNext; -00450 USHORT usFontStyle, usFontSize; -00451 drawfile_fontref tFontRef; -00452 UCHAR ucFontColor; -00453 -00454 TRACE_MSG("pStartNewOutput"); -00455 -00456 ucFontColor = FONT_COLOR_DEFAULT; -00457 usFontStyle = FONT_REGULAR; -00458 tFontRef = (drawfile_fontref)0; -00459 usFontSize = DEFAULT_FONT_SIZE; -00460 /* Free the old output space */ -00461 pCurr = pAnchor; -00462 while (pCurr != NULL) { -00463 TRACE_MSG("Free the old output space"); -00464 pNext = pCurr->pNext; -00465 pCurr->szStorage = xfree(pCurr->szStorage); -00466 if (pCurr->pNext == NULL) { -00467 ucFontColor = pCurr->ucFontColor; -00468 usFontStyle = pCurr->usFontStyle; -00469 tFontRef = pCurr->tFontRef; -00470 usFontSize = pCurr->usFontSize; -00471 } -00472 pCurr = xfree(pCurr); -00473 pCurr = pNext; -00474 } -00475 if (pLeftOver == NULL) { -00476 /* Create new output space */ -00477 TRACE_MSG("Create new output space"); -00478 pLeftOver = xmalloc(sizeof(*pLeftOver)); -00479 pLeftOver->tStorageSize = INITIAL_SIZE; -00480 NO_DBG_DEC(pLeftOver->tStorageSize); -00481 TRACE_MSG("before 2nd xmalloc"); -00482 pLeftOver->szStorage = xmalloc(pLeftOver->tStorageSize); -00483 TRACE_MSG("after 2nd xmalloc"); -00484 pLeftOver->szStorage[0] = '\0'; -00485 pLeftOver->tNextFree = 0; -00486 pLeftOver->lStringWidth = 0; -00487 pLeftOver->ucFontColor = ucFontColor; -00488 pLeftOver->usFontStyle = usFontStyle; -00489 pLeftOver->tFontRef = tFontRef; -00490 pLeftOver->usFontSize = usFontSize; -00491 pLeftOver->pPrev = NULL; -00492 pLeftOver->pNext = NULL; -00493 } -00494 fail(!bCheckDoubleLinkedList(pLeftOver)); -00495 return pLeftOver; -00496 } /* end of pStartNewOutput */ -00497 -00498 /* -00499 * ulGetChar - get the next character from the specified list -00500 * -00501 * returns the next character of EOF -00502 */ -00503 static ULONG -00504 ulGetChar(FILE *pFile, list_id_enum eListID) -00505 { -00506 const font_block_type *pCurr; -00507 ULONG ulChar, ulFileOffset, ulCharPos; -00508 row_info_enum eRowInfo; -00509 USHORT usChar, usPropMod; -00510 BOOL bSkip; -00511 -00512 fail(pFile == NULL); -00513 -00514 pCurr = pFontInfo; -00515 bSkip = FALSE; -00516 for (;;) { -00517 usChar = usNextChar(pFile, eListID, -00518 &ulFileOffset, &ulCharPos, &usPropMod); -00519 if (usChar == (USHORT)EOF) { -00520 return (ULONG)EOF; -00521 } -00522 -00523 vUpdateCounters(); -00524 -00525 eRowInfo = ePropMod2RowInfo(usPropMod, iWordVersion); -00526 if (!bStartRow) { -00527 #if 0 -00528 bStartRow = eRowInfo == found_a_cell || -00529 (pRowInfo != NULL && -00530 ulFileOffset == pRowInfo->ulFileOffsetStart && -00531 eRowInfo != found_not_a_cell); -00532 #else -00533 bStartRow = pRowInfo != NULL && -00534 ulFileOffset == pRowInfo->ulFileOffsetStart; -00535 #endif -00536 NO_DBG_HEX_C(bStartRow, pRowInfo->ulFileOffsetStart); -00537 } -00538 if (!bEndRowNorm) { -00539 #if 0 -00540 bEndRow = eRowInfo == found_end_of_row || -00541 (pRowInfo != NULL && -00542 ulFileOffset == pRowInfo->ulFileOffsetEnd && -00543 eRowInfo != found_not_end_of_row); -00544 #else -00545 bEndRowNorm = pRowInfo != NULL && -00546 ulFileOffset == pRowInfo->ulFileOffsetEnd; -00547 #endif -00548 NO_DBG_HEX_C(bEndRowNorm, pRowInfo->ulFileOffsetEnd); -00549 } -00550 if (!bEndRowFast) { -00551 bEndRowFast = eRowInfo == found_end_of_row; -00552 NO_DBG_HEX_C(bEndRowFast, pRowInfo->ulFileOffsetEnd); -00553 } -00554 -00555 if (!bStartStyle) { -00556 bStartStyle = pStyleInfo != NULL && -00557 ulFileOffset == pStyleInfo->ulFileOffset; -00558 NO_DBG_HEX_C(bStartStyle, ulFileOffset); -00559 } -00560 if (pCurr != NULL && ulFileOffset == pCurr->ulFileOffset) { -00561 bStartFont = TRUE; -00562 NO_DBG_HEX(ulFileOffset); -00563 pFontInfo = pCurr; -00564 pCurr = pGetNextFontInfoListItem(pCurr); -00565 } -00566 -00567 /* Skip embedded characters */ -00568 if (usChar == START_EMBEDDED) { -00569 bSkip = TRUE; -00570 continue; -00571 } -00572 if (usChar == END_IGNORE || usChar == END_EMBEDDED) { -00573 bSkip = FALSE; -00574 continue; -00575 } -00576 if (bSkip) { -00577 continue; -00578 } -00579 ulChar = ulTranslateCharacters(usChar, -00580 ulFileOffset, -00581 iWordVersion, -00582 tOptions.eConversionType, -00583 tOptions.eEncoding, -00584 bOldMacFile); -00585 if (ulChar == IGNORE_CHARACTER) { -00586 continue; -00587 } -00588 if (ulChar == PICTURE) { -00589 ulFileOffsetImage = ulGetPictInfoListItem(ulFileOffset); -00590 } else { -00591 ulFileOffsetImage = FC_INVALID; -00592 } -00593 if (ulChar == PAR_END) { -00594 /* End of paragraph seen, prepare for the next */ -00595 vFillStyleFromStylesheet(usIstdNext, &tStyleNext); -00596 vCorrectStyleValues(&tStyleNext); -00597 bStartStyleNext = TRUE; -00598 vFillFontFromStylesheet(usIstdNext, &tFontNext); -00599 vCorrectFontValues(&tFontNext); -00600 bStartFontNext = TRUE; -00601 } -00602 if (ulChar == PAGE_BREAK) { -00603 /* Might be the start of a new section */ -00604 pSectionNext = pGetSectionInfo(pSection, ulCharPos); -00605 } -00606 return ulChar; -00607 } -00608 } /* end of ulGetChar */ -00609 -00610 /* -00611 * lGetWidthMax - get the maximum line width from the paragraph break value -00612 * -00613 * Returns the maximum line width in millipoints -00614 */ -00615 static long -00616 lGetWidthMax(int iParagraphBreak) -00617 { -00618 fail(iParagraphBreak < 0); -00619 -00620 if (iParagraphBreak == 0) { -00621 return LONG_MAX; -00622 } -00623 if (iParagraphBreak < MIN_SCREEN_WIDTH) { -00624 return lChar2MilliPoints(MIN_SCREEN_WIDTH); -00625 } -00626 if (iParagraphBreak > MAX_SCREEN_WIDTH) { -00627 return lChar2MilliPoints(MAX_SCREEN_WIDTH); -00628 } -00629 return lChar2MilliPoints(iParagraphBreak); -00630 } /* end of lGetWidthMax */ -00631 -00632 /* -00633 * bWordDecryptor - turn Word to something more useful -00634 * -00635 * returns TRUE when succesful, otherwise FALSE -00636 */ -00637 BOOL -00638 bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag) -00639 { -00640 imagedata_type tImage; -00641 const style_block_type *pStyleTmp; -00642 const font_block_type *pFontTmp; -00643 const char *szListChar; -00644 output_type *pAnchor, *pOutput, *pLeftOver; -00645 ULONG ulChar; -00646 long lBeforeIndentation, lAfterIndentation; -00647 long lLeftIndentation, lLeftIndentation1, lRightIndentation; -00648 long lWidthCurr, lWidthMax, lDefaultTabWidth, lHalfSpaceWidth, lTmp; -00649 list_id_enum eListID; -00650 image_info_enum eRes; -00651 UINT uiFootnoteNumber, uiEndnoteNumber, uiTmp; -00652 int iListSeqNumber; -00653 BOOL bWasTableRow, bTableFontClosed, bWasEndOfParagraph; -00654 BOOL bInList, bWasInList, bNoMarks, bFirstLine; -00655 BOOL bAllCapitals, bHiddenText, bMarkDelText, bSuccess; -00656 USHORT usListNumber; -00657 USHORT usFontStyle, usFontStyleMinimal, usFontSize, usTmp; -00658 UCHAR ucFontNumber, ucFontColor; -00659 UCHAR ucNFC, ucAlignment; -00660 -00661 fail(pFile == NULL || lFilesize <= 0 || pDiag == NULL); -00662 -00663 TRACE_MSG("bWordDecryptor"); -00664 -00665 iWordVersion = iInitDocument(pFile, lFilesize); -00666 if (iWordVersion < 0) { -00667 DBG_DEC(iWordVersion); -00668 return FALSE; -00669 } -00670 -00671 vGetOptions(&tOptions); -00672 bOldMacFile = bIsOldMacFile(); -00673 vPrepareHdrFtrText(pFile); -00674 vPrepareFootnoteText(pFile); -00675 -00676 vPrologue2(pDiag, iWordVersion); -00677 -00678 /* Initialisation */ -00679 #if defined(__riscos) -00680 ulCharCounter = 0; -00681 iCurrPct = 0; -00682 iPrevPct = -1; -00683 ulDocumentLength = ulGetDocumentLength(); -00684 #endif /* __riscos */ -00685 pSection = pGetSectionInfo(NULL, 0); -00686 pSectionNext = pSection; -00687 lDefaultTabWidth = lGetDefaultTabWidth(); -00688 DBG_DEC_C(lDefaultTabWidth != 36000, lDefaultTabWidth); -00689 pRowInfo = pGetNextRowInfoListItem(); -00690 DBG_HEX_C(pRowInfo != NULL, pRowInfo->ulFileOffsetStart); -00691 DBG_HEX_C(pRowInfo != NULL, pRowInfo->ulFileOffsetEnd); -00692 DBG_MSG_C(pRowInfo == NULL, "No rows at all"); -00693 bStartRow = FALSE; -00694 bEndRowNorm = FALSE; -00695 bEndRowFast = FALSE; -00696 bIsTableRow = FALSE; -00697 bWasTableRow = FALSE; -00698 vResetStyles(); -00699 pStyleInfo = pGetNextTextStyle(NULL); -00700 bStartStyle = FALSE; -00701 bInList = FALSE; -00702 bWasInList = FALSE; -00703 iListSeqNumber = 0; -00704 usIstdNext = ISTD_NORMAL; -00705 pAnchor = NULL; -00706 pFontInfo = pGetNextFontInfoListItem(NULL); -00707 DBG_HEX_C(pFontInfo != NULL, pFontInfo->ulFileOffset); -00708 DBG_MSG_C(pFontInfo == NULL, "No fonts at all"); -00709 bStartFont = FALSE; -00710 ucFontNumber = 0; -00711 usFontStyleMinimal = FONT_REGULAR; -00712 usFontStyle = FONT_REGULAR; -00713 usFontSize = DEFAULT_FONT_SIZE; -00714 ucFontColor = FONT_COLOR_DEFAULT; -00715 pAnchor = pStartNewOutput(pAnchor, NULL); -00716 pOutput = pAnchor; -00717 pOutput->ucFontColor = ucFontColor; -00718 pOutput->usFontStyle = usFontStyle; -00719 pOutput->tFontRef = tOpenFont(ucFontNumber, usFontStyle, usFontSize); -00720 pOutput->usFontSize = usFontSize; -00721 bTableFontClosed = TRUE; -00722 lBeforeIndentation = 0; -00723 lAfterIndentation = 0; -00724 lLeftIndentation = 0; -00725 lLeftIndentation1 = 0; -00726 lRightIndentation = 0; -00727 bWasEndOfParagraph = TRUE; -00728 bNoMarks = TRUE; -00729 bFirstLine = TRUE; -00730 ucNFC = LIST_BULLETS; -00731 if (pStyleInfo != NULL) { -00732 szListChar = pStyleInfo->szListChar; -00733 pStyleTmp = pStyleInfo; -00734 } else { -00735 if (tStyleNext.szListChar[0] == '\0') { -00736 vGetBulletValue(tOptions.eConversionType, -00737 tOptions.eEncoding, tStyleNext.szListChar, 4); -00738 } -00739 szListChar = tStyleNext.szListChar; -00740 pStyleTmp = &tStyleNext; -00741 } -00742 usListNumber = 0; -00743 ucAlignment = ALIGNMENT_LEFT; -00744 bAllCapitals = FALSE; -00745 bHiddenText = FALSE; -00746 bMarkDelText = FALSE; -00747 lWidthMax = lGetWidthMax(tOptions.iParagraphBreak); -00748 NO_DBG_DEC(lWidthMax); -00749 -00750 Hourglass_On(); -00751 -00752 uiFootnoteNumber = 0; -00753 uiEndnoteNumber = 0; -00754 eListID = text_list; -00755 for(;;) { -00756 ulChar = ulGetChar(pFile, eListID); -00757 if (ulChar == (ULONG)EOF) { -00758 if (bOutputContainsText(pAnchor)) { -00759 OUTPUT_LINE(); -00760 } else { -00761 RESET_LINE(); -00762 } -00763 switch (eListID) { -00764 case text_list: -00765 if (tOptions.eConversionType != -00766 conversion_xml) { -00767 eListID = footnote_list; -00768 if (uiFootnoteNumber != 0) { -00769 vPutSeparatorLine(pAnchor); -00770 OUTPUT_LINE(); -00771 uiFootnoteNumber = 0; -00772 } -00773 break; -00774 } -00775 /* No break or return */ -00776 case footnote_list: -00777 eListID = endnote_list; -00778 if (uiEndnoteNumber != 0) { -00779 vPutSeparatorLine(pAnchor); -00780 OUTPUT_LINE(); -00781 uiEndnoteNumber = 0; -00782 } -00783 break; -00784 case endnote_list: -00785 eListID = textbox_list; -00786 if (bExistsTextBox()) { -00787 vPutSeparatorLine(pAnchor); -00788 OUTPUT_LINE(); -00789 } -00790 break; -00791 case textbox_list: -00792 eListID = hdrtextbox_list; -00793 if (bExistsHdrTextBox()) { -00794 vPutSeparatorLine(pAnchor); -00795 OUTPUT_LINE(); -00796 } -00797 break; -00798 case hdrtextbox_list: -00799 default: -00800 eListID = end_of_lists; -00801 break; -00802 } -00803 if (eListID == end_of_lists) { -00804 break; -00805 } -00806 continue; -00807 } -00808 -00809 if (ulChar == UNKNOWN_NOTE_CHAR) { -00810 switch (eListID) { -00811 case footnote_list: -00812 ulChar = FOOTNOTE_CHAR; -00813 break; -00814 case endnote_list: -00815 ulChar = ENDNOTE_CHAR; -00816 break; -00817 default: -00818 break; -00819 } -00820 } -00821 -00822 if (bStartRow) { -00823 /* Begin of a tablerow found */ -00824 if (bOutputContainsText(pAnchor)) { -00825 OUTPUT_LINE(); -00826 } else { -00827 RESET_LINE(); -00828 } -00829 fail(pAnchor != pOutput); -00830 if (bTableFontClosed) { -00831 /* Start special table font */ -00832 vCloseFont(); -00833 /* -00834 * Compensate for the fact that Word uses -00835 * proportional fonts for its tables and we -00836 * only one fixed-width font -00837 */ -00838 uiTmp = ((UINT)usFontSize * 5 + 3) / 6; -00839 if (uiTmp < MIN_TABLEFONT_SIZE) { -00840 uiTmp = MIN_TABLEFONT_SIZE; -00841 } else if (uiTmp > MAX_TABLEFONT_SIZE) { -00842 uiTmp = MAX_TABLEFONT_SIZE; -00843 } -00844 pOutput->usFontSize = (USHORT)uiTmp; -00845 pOutput->tFontRef = -00846 tOpenTableFont(pOutput->usFontSize); -00847 pOutput->usFontStyle = FONT_REGULAR; -00848 pOutput->ucFontColor = FONT_COLOR_BLACK; -00849 bTableFontClosed = FALSE; -00850 } -00851 bIsTableRow = TRUE; -00852 bStartRow = FALSE; -00853 } -00854 -00855 if (bWasTableRow && -00856 !bIsTableRow && -00857 ulChar != PAR_END && -00858 ulChar != HARD_RETURN && -00859 ulChar != PAGE_BREAK && -00860 ulChar != COLUMN_FEED) { -00861 /* -00862 * The end of a table should be followed by an -00863 * empty line, like the end of a paragraph -00864 */ -00865 OUTPUT_LINE(); -00866 vEndOfParagraph(pDiag, -00867 pOutput->tFontRef, -00868 pOutput->usFontSize, -00869 (long)pOutput->usFontSize * 600); -00870 } -00871 -00872 switch (ulChar) { -00873 case PAGE_BREAK: -00874 case COLUMN_FEED: -00875 if (bIsTableRow) { -00876 /* Ignore when in a table */ -00877 break; -00878 } -00879 if (bOutputContainsText(pAnchor)) { -00880 OUTPUT_LINE(); -00881 } else { -00882 RESET_LINE(); -00883 } -00884 if (ulChar == PAGE_BREAK) { -00885 vEndOfPage(pDiag, lAfterIndentation, -00886 pSection != pSectionNext); -00887 } else { -00888 vEndOfParagraph(pDiag, -00889 pOutput->tFontRef, -00890 pOutput->usFontSize, -00891 lAfterIndentation); -00892 } -00893 break; -00894 default: -00895 break; -00896 } -00897 -00898 if (bStartFont || (bStartFontNext && ulChar != PAR_END)) { -00899 /* Begin of a font found */ -00900 if (bStartFont) { -00901 /* bStartFont takes priority */ -00902 fail(pFontInfo == NULL); -00903 pFontTmp = pFontInfo; -00904 } else { -00905 pFontTmp = &tFontNext; -00906 } -00907 bAllCapitals = bIsCapitals(pFontTmp->usFontStyle); -00908 bHiddenText = bIsHidden(pFontTmp->usFontStyle); -00909 bMarkDelText = bIsMarkDel(pFontTmp->usFontStyle); -00910 usTmp = pFontTmp->usFontStyle & -00911 (FONT_BOLD|FONT_ITALIC|FONT_UNDERLINE| -00912 FONT_STRIKE|FONT_MARKDEL| -00913 FONT_SUPERSCRIPT|FONT_SUBSCRIPT); -00914 if (!bIsTableRow && -00915 (usFontSize != pFontTmp->usFontSize || -00916 ucFontNumber != pFontTmp->ucFontNumber || -00917 usFontStyleMinimal != usTmp || -00918 ucFontColor != pFontTmp->ucFontColor)) { -00919 pOutput = pStartNextOutput(pOutput); -00920 vCloseFont(); -00921 pOutput->ucFontColor = pFontTmp->ucFontColor; -00922 pOutput->usFontStyle = pFontTmp->usFontStyle; -00923 pOutput->usFontSize = pFontTmp->usFontSize; -00924 pOutput->tFontRef = tOpenFont( -00925 pFontTmp->ucFontNumber, -00926 pFontTmp->usFontStyle, -00927 pFontTmp->usFontSize); -00928 fail(!bCheckDoubleLinkedList(pAnchor)); -00929 } -00930 ucFontNumber = pFontTmp->ucFontNumber; -00931 usFontSize = pFontTmp->usFontSize; -00932 ucFontColor = pFontTmp->ucFontColor; -00933 usFontStyle = pFontTmp->usFontStyle; -00934 usFontStyleMinimal = usTmp; -00935 if (bStartFont) { -00936 /* Get the next font info */ -00937 pFontInfo = pGetNextFontInfoListItem(pFontInfo); -00938 NO_DBG_HEX_C(pFontInfo != NULL, -00939 pFontInfo->ulFileOffset); -00940 DBG_MSG_C(pFontInfo == NULL, "No more fonts"); -00941 } -00942 bStartFont = FALSE; -00943 bStartFontNext = FALSE; -00944 } -00945 -00946 if (bStartStyle || (bStartStyleNext && ulChar != PAR_END)) { -00947 bFirstLine = TRUE; -00948 /* Begin of a style found */ -00949 if (bStartStyle) { -00950 /* bStartStyle takes priority */ -00951 fail(pStyleInfo == NULL); -00952 pStyleTmp = pStyleInfo; -00953 } else { -00954 pStyleTmp = &tStyleNext; -00955 } -00956 if (!bIsTableRow) { -00957 vStoreStyle(pDiag, pOutput, pStyleTmp); -00958 } -00959 usIstdNext = pStyleTmp->usIstdNext; -00960 lBeforeIndentation = -00961 lTwips2MilliPoints(pStyleTmp->usBeforeIndent); -00962 lAfterIndentation = -00963 lTwips2MilliPoints(pStyleTmp->usAfterIndent); -00964 lLeftIndentation = -00965 lTwips2MilliPoints(pStyleTmp->sLeftIndent); -00966 lLeftIndentation1 = -00967 lTwips2MilliPoints(pStyleTmp->sLeftIndent1); -00968 lRightIndentation = -00969 lTwips2MilliPoints(pStyleTmp->sRightIndent); -00970 bInList = bStyleImpliesList(pStyleTmp, iWordVersion); -00971 bNoMarks = !bInList || pStyleTmp->bNumPause; -00972 ucNFC = pStyleTmp->ucNFC; -00973 szListChar = pStyleTmp->szListChar; -00974 ucAlignment = pStyleTmp->ucAlignment; -00975 if (bInList && !bWasInList) { -00976 /* Start of a list */ -00977 iListSeqNumber++; -00978 vStartOfList(pDiag, ucNFC, -00979 bWasTableRow && !bIsTableRow); -00980 } -00981 if (!bInList && bWasInList) { -00982 /* End of a list */ -00983 vEndOfList(pDiag); -00984 } -00985 bWasInList = bInList; -00986 if (bStartStyle) { -00987 pStyleInfo = pGetNextTextStyle(pStyleInfo); -00988 NO_DBG_HEX_C(pStyleInfo != NULL, -00989 pStyleInfo->ulFileOffset); -00990 DBG_MSG_C(pStyleInfo == NULL, -00991 "No more styles"); -00992 } -00993 bStartStyle = FALSE; -00994 bStartStyleNext = FALSE; -00995 } -00996 -00997 if (bWasEndOfParagraph) { -00998 vStartOfParagraph1(pDiag, lBeforeIndentation); -00999 } -01000 -01001 if (!bIsTableRow && -01002 lTotalStringWidth(pAnchor) == 0) { -01003 if (!bNoMarks) { -01004 usListNumber = usGetListValue(iListSeqNumber, -01005 iWordVersion, -01006 pStyleTmp); -01007 } -01008 if (bInList && bFirstLine) { -01009 vStartOfListItem(pDiag, bNoMarks); -01010 } -01011 vPutIndentation(pDiag, pAnchor, bNoMarks, bFirstLine, -01012 usListNumber, ucNFC, szListChar, -01013 lLeftIndentation, lLeftIndentation1); -01014 bFirstLine = FALSE; -01015 /* One number or mark per paragraph will do */ -01016 bNoMarks = TRUE; -01017 } -01018 -01019 if (bWasEndOfParagraph) { -01020 vStartOfParagraph2(pDiag); -01021 bWasEndOfParagraph = FALSE; -01022 } -01023 -01024 switch (ulChar) { -01025 case PICTURE: -01026 (void)memset(&tImage, 0, sizeof(tImage)); -01027 eRes = eExamineImage(pFile, ulFileOffsetImage, &tImage); -01028 switch (eRes) { -01029 case image_no_information: -01030 bSuccess = FALSE; -01031 break; -01032 case image_minimal_information: -01033 case image_full_information: -01034 #if 0 -01035 if (bOutputContainsText(pAnchor)) { -01036 OUTPUT_LINE(); -01037 } else { -01038 RESET_LINE(); -01039 } -01040 #endif -01041 bSuccess = bTranslateImage(pDiag, pFile, -01042 eRes == image_minimal_information, -01043 ulFileOffsetImage, &tImage); -01044 break; -01045 default: -01046 DBG_DEC(eRes); -01047 bSuccess = FALSE; -01048 break; -01049 } -01050 if (!bSuccess) { -01051 vStoreString("[pic]", 5, pOutput); -01052 } -01053 break; -01054 case FOOTNOTE_CHAR: -01055 uiFootnoteNumber++; -01056 if (tOptions.eConversionType == conversion_xml) { -01057 vStoreCharacter((ULONG)FOOTNOTE_OR_ENDNOTE, -01058 pOutput); -01059 break; -01060 } -01061 vStoreCharacter((ULONG)'[', pOutput); -01062 vStoreNumberAsDecimal(uiFootnoteNumber, pOutput); -01063 vStoreCharacter((ULONG)']', pOutput); -01064 break; -01065 case ENDNOTE_CHAR: -01066 uiEndnoteNumber++; -01067 vStoreCharacter((ULONG)'[', pOutput); -01068 vStoreNumberAsRoman(uiEndnoteNumber, pOutput); -01069 vStoreCharacter((ULONG)']', pOutput); -01070 break; -01071 case UNKNOWN_NOTE_CHAR: -01072 vStoreString("[?]", 3, pOutput); -01073 break; -01074 case PAR_END: -01075 if (bIsTableRow) { -01076 vStoreCharacter((ULONG)'\n', pOutput); -01077 break; -01078 } -01079 if (bOutputContainsText(pAnchor)) { -01080 OUTPUT_LINE(); -01081 } else { -01082 vMove2NextLine(pDiag, -01083 pOutput->tFontRef, pOutput->usFontSize); -01084 RESET_LINE(); -01085 } -01086 vEndOfParagraph(pDiag, -01087 pOutput->tFontRef, -01088 pOutput->usFontSize, -01089 lAfterIndentation); -01090 bWasEndOfParagraph = TRUE; -01091 break; -01092 case HARD_RETURN: -01093 if (bIsTableRow) { -01094 vStoreCharacter((ULONG)'\n', pOutput); -01095 break; -01096 } -01097 if (bOutputContainsText(pAnchor)) { -01098 OUTPUT_LINE(); -01099 } else { -01100 vMove2NextLine(pDiag, -01101 pOutput->tFontRef, pOutput->usFontSize); -01102 RESET_LINE(); -01103 } -01104 break; -01105 case PAGE_BREAK: -01106 case COLUMN_FEED: -01107 pSection = pSectionNext; -01108 break; -01109 case TABLE_SEPARATOR: -01110 if (bIsTableRow) { -01111 vStoreCharacter(ulChar, pOutput); -01112 break; -01113 } -01114 vStoreCharacter((ULONG)' ', pOutput); -01115 vStoreCharacter((ULONG)TABLE_SEPARATOR_CHAR, pOutput); -01116 break; -01117 case TAB: -01118 if (bIsTableRow || -01119 tOptions.eConversionType == conversion_xml) { -01120 vStoreCharacter((ULONG)' ', pOutput); -01121 break; -01122 } -01123 if (tOptions.iParagraphBreak == 0 && -01124 (tOptions.eConversionType == conversion_text || -01125 tOptions.eConversionType == conversion_fmt_text)) { -01126 /* No logical lines, so no tab expansion */ -01127 vStoreCharacter(TAB, pOutput); -01128 break; -01129 } -01130 lHalfSpaceWidth = (lComputeSpaceWidth( -01131 pOutput->tFontRef, -01132 pOutput->usFontSize) + 1) / 2; -01133 lTmp = lTotalStringWidth(pAnchor); -01134 lTmp += lDrawUnits2MilliPoints(pDiag->lXleft); -01135 lTmp /= lDefaultTabWidth; -01136 do { -01137 vStoreCharacter((ULONG)FILLER_CHAR, pOutput); -01138 lWidthCurr = lTotalStringWidth(pAnchor); -01139 lWidthCurr += -01140 lDrawUnits2MilliPoints(pDiag->lXleft); -01141 } while (lTmp == lWidthCurr / lDefaultTabWidth && -01142 lWidthCurr < lWidthMax + lRightIndentation); -01143 break; -01144 default: -01145 if (bHiddenText && tOptions.bHideHiddenText) { -01146 continue; -01147 } -01148 if (bMarkDelText && tOptions.bRemoveRemovedText) { -01149 continue; -01150 } -01151 if (ulChar == UNICODE_ELLIPSIS && -01152 tOptions.eEncoding != encoding_utf_8) { -01153 vStoreString("...", 3, pOutput); -01154 } else { -01155 if (bAllCapitals) { -01156 ulChar = ulToUpper(ulChar); -01157 } -01158 vStoreCharacter(ulChar, pOutput); -01159 } -01160 break; -01161 } -01162 -01163 if (bWasTableRow && !bIsTableRow) { -01164 /* End of a table */ -01165 vEndOfTable(pDiag); -01166 /* Resume normal font */ -01167 NO_DBG_MSG("End of table font"); -01168 vCloseFont(); -01169 bTableFontClosed = TRUE; -01170 pOutput->ucFontColor = ucFontColor; -01171 pOutput->usFontStyle = usFontStyle; -01172 pOutput->usFontSize = usFontSize; -01173 pOutput->tFontRef = tOpenFont( -01174 ucFontNumber, usFontStyle, usFontSize); -01175 } -01176 bWasTableRow = bIsTableRow; -01177 -01178 if (bIsTableRow) { -01179 fail(pAnchor != pOutput); -01180 if (!bEndRowNorm && !bEndRowFast) { -01181 continue; -01182 } -01183 /* End of a table row */ -01184 if (bEndRowNorm) { -01185 fail(pRowInfo == NULL); -01186 vTableRow2Window(pDiag, pAnchor, pRowInfo, -01187 tOptions.eConversionType, -01188 tOptions.iParagraphBreak); -01189 } else { -01190 fail(!bEndRowFast); -01191 } -01192 /* Reset */ -01193 pAnchor = pStartNewOutput(pAnchor, NULL); -01194 pOutput = pAnchor; -01195 if (bEndRowNorm) { -01196 pRowInfo = pGetNextRowInfoListItem(); -01197 } -01198 bIsTableRow = FALSE; -01199 bEndRowNorm = FALSE; -01200 bEndRowFast = FALSE; -01201 NO_DBG_HEX_C(pRowInfo != NULL, -01202 pRowInfo->ulFileOffsetStart); -01203 NO_DBG_HEX_C(pRowInfo != NULL, -01204 pRowInfo->ulFileOffsetEnd); -01205 continue; -01206 } -01207 lWidthCurr = lTotalStringWidth(pAnchor); -01208 lWidthCurr += lDrawUnits2MilliPoints(pDiag->lXleft); -01209 if (lWidthCurr < lWidthMax + lRightIndentation) { -01210 continue; -01211 } -01212 pLeftOver = pSplitList(pAnchor); -01213 vJustify2Window(pDiag, pAnchor, -01214 lWidthMax, lRightIndentation, ucAlignment); -01215 pAnchor = pStartNewOutput(pAnchor, pLeftOver); -01216 for (pOutput = pAnchor; -01217 pOutput->pNext != NULL; -01218 pOutput = pOutput->pNext) -01219 ; /* EMPTY */ -01220 fail(pOutput == NULL); -01221 if (lTotalStringWidth(pAnchor) > 0) { -01222 vSetLeftIndentation(pDiag, lLeftIndentation); -01223 } -01224 } -01225 -01226 pAnchor = pStartNewOutput(pAnchor, NULL); -01227 pAnchor->szStorage = xfree(pAnchor->szStorage); -01228 pAnchor = xfree(pAnchor); -01229 vCloseFont(); -01230 vFreeDocument(); -01231 Hourglass_Off(); -01232 return TRUE; -01233 } /* end of bWordDecryptor */ -01234 -01235 /* -01236 * lLastStringWidth - compute the width of the last part of the output string -01237 */ -01238 static long -01239 lLastStringWidth(const output_type *pAnchor) -01240 { -01241 const output_type *pCurr, *pStart; -01242 -01243 pStart = NULL; -01244 for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { -01245 if (pCurr->tNextFree == 1 && -01246 (pCurr->szStorage[0] == PAR_END || -01247 pCurr->szStorage[0] == HARD_RETURN)) { -01248 /* Found a separator. Start after the separator */ -01249 pStart = pCurr->pNext; -01250 } -01251 } -01252 if (pStart == NULL) { -01253 /* No separators. Use the whole output string */ -01254 pStart = pAnchor; -01255 } -01256 return lTotalStringWidth(pStart); -01257 } /* end of lLastStringWidth */ -01258 -01259 /* -01260 * pHdrFtrDecryptor - turn a header/footer list element to something useful -01261 */ -01262 output_type * -01263 pHdrFtrDecryptor(FILE *pFile, ULONG ulCharPosStart, ULONG ulCharPosNext) -01264 { -01265 output_type *pAnchor, *pOutput, *pLeftOver; -01266 ULONG ulChar, ulFileOffset, ulCharPos; -01267 long lWidthCurr, lWidthMax; -01268 long lRightIndentation; -01269 USHORT usChar; -01270 UCHAR ucAlignment; -01271 BOOL bSkip; -01272 -01273 fail(iWordVersion < 0); -01274 fail(tOptions.eConversionType == conversion_unknown); -01275 fail(tOptions.eEncoding == 0); -01276 -01277 if (ulCharPosStart == ulCharPosNext) { -01278 /* There are no bytes to decrypt */ -01279 return NULL; -01280 } -01281 -01282 lRightIndentation = 0; -01283 ucAlignment = ALIGNMENT_LEFT; -01284 bSkip = FALSE; -01285 lWidthMax = lGetWidthMax(tOptions.iParagraphBreak); -01286 pAnchor = pStartNewOutput(NULL, NULL); -01287 pOutput = pAnchor; -01288 pOutput->tFontRef = tOpenFont(0, FONT_REGULAR, DEFAULT_FONT_SIZE); -01289 usChar = usToHdrFtrPosition(pFile, ulCharPosStart); -01290 ulCharPos = ulCharPosStart; -01291 ulFileOffset = ulCharPos2FileOffset(ulCharPos); -01292 while (usChar != (USHORT)EOF && ulCharPos != ulCharPosNext) { -01293 /* Skip embedded characters */ -01294 if (usChar == START_EMBEDDED) { -01295 bSkip = TRUE; -01296 } else if (usChar == END_IGNORE || usChar == END_EMBEDDED) { -01297 bSkip = FALSE; -01298 } -01299 /* Translate character */ -01300 if (bSkip || usChar == END_IGNORE || usChar == END_EMBEDDED) { -01301 ulChar = IGNORE_CHARACTER; -01302 } else { -01303 ulChar = ulTranslateCharacters(usChar, -01304 ulFileOffset, -01305 iWordVersion, -01306 tOptions.eConversionType, -01307 tOptions.eEncoding, -01308 bOldMacFile); -01309 } -01310 /* Process character */ -01311 if (ulChar != IGNORE_CHARACTER) { -01312 switch (ulChar) { -01313 case PICTURE: -01314 vStoreString("[pic]", 5, pOutput); -01315 break; -01316 case PAR_END: -01317 case HARD_RETURN: -01318 case PAGE_BREAK: -01319 case COLUMN_FEED: -01320 /* To the next substring */ -01321 pOutput = pStartNextOutput(pOutput); -01322 vCloseFont(); -01323 pOutput->tFontRef = tOpenFont(0, -01324 FONT_REGULAR, DEFAULT_FONT_SIZE); -01325 /* A substring with just one character */ -01326 if (ulChar == HARD_RETURN) { -01327 vStoreCharacter(HARD_RETURN, pOutput); -01328 } else { -01329 vStoreCharacter(PAR_END, pOutput); -01330 } -01331 /* To the next substring */ -01332 pOutput = pStartNextOutput(pOutput); -01333 vCloseFont(); -01334 pOutput->tFontRef = tOpenFont(0, -01335 FONT_REGULAR, DEFAULT_FONT_SIZE); -01336 fail(!bCheckDoubleLinkedList(pAnchor)); -01337 break; -01338 case TABLE_SEPARATOR: -01339 vStoreCharacter((ULONG)' ', pOutput); -01340 vStoreCharacter((ULONG)TABLE_SEPARATOR_CHAR, -01341 pOutput); -01342 break; -01343 case TAB: -01344 vStoreCharacter((ULONG)FILLER_CHAR, pOutput); -01345 break; -01346 default: -01347 vStoreCharacter(ulChar, pOutput); -01348 break; -01349 } -01350 } -01351 lWidthCurr = lLastStringWidth(pAnchor); -01352 if (lWidthCurr >= lWidthMax + lRightIndentation) { -01353 pLeftOver = pSplitList(pAnchor); -01354 for (pOutput = pAnchor; -01355 pOutput->pNext != NULL; -01356 pOutput = pOutput->pNext) -01357 ; /* EMPTY */ -01358 fail(pOutput == NULL); -01359 /* To the next substring */ -01360 pOutput = pStartNextOutput(pOutput); -01361 /* A substring with just one HARD_RETURN */ -01362 vStoreCharacter(HARD_RETURN, pOutput); -01363 /* Put the leftover piece(s) at the end */ -01364 pOutput->pNext = pLeftOver; -01365 if (pLeftOver != NULL) { -01366 pLeftOver->pPrev = pOutput; -01367 } -01368 fail(!bCheckDoubleLinkedList(pAnchor)); -01369 for (pOutput = pAnchor; -01370 pOutput->pNext != NULL; -01371 pOutput = pOutput->pNext) -01372 ; /* EMPTY */ -01373 fail(pOutput == NULL); -01374 } -01375 usChar = usNextChar(pFile, hdrftr_list, -01376 &ulFileOffset, &ulCharPos, NULL); -01377 } -01378 vCloseFont(); -01379 if (bOutputContainsText(pAnchor)) { -01380 return pAnchor; -01381 } -01382 pAnchor = pStartNewOutput(pAnchor, NULL); -01383 pAnchor->szStorage = xfree(pAnchor->szStorage); -01384 pAnchor = xfree(pAnchor); -01385 return NULL; -01386 } /* end of pHdrFtrDecryptor */ -01387 -01388 /* -01389 * pFootnoteDecryptor - turn a footnote text list element into text -01390 */ -01391 char * -01392 szFootnoteDecryptor(FILE *pFile, ULONG ulCharPosStart, ULONG ulCharPosNext) -01393 { -01394 char *szText; -01395 ULONG ulChar, ulFileOffset, ulCharPos; -01396 USHORT usChar; -01397 size_t tLen, tIndex, tNextFree, tStorageSize; -01398 char szResult[6]; -01399 BOOL bSkip; -01400 -01401 fail(iWordVersion < 0); -01402 fail(tOptions.eConversionType == conversion_unknown); -01403 fail(tOptions.eEncoding == 0); -01404 -01405 if (ulCharPosStart == ulCharPosNext) { -01406 /* There are no bytes to decrypt */ -01407 return NULL; -01408 } -01409 -01410 if (tOptions.eConversionType != conversion_xml) { -01411 /* Only implemented for XML output */ -01412 return NULL; -01413 } -01414 -01415 bSkip = FALSE; -01416 -01417 /* Initialise the text buffer */ -01418 tStorageSize = INITIAL_SIZE; -01419 szText = xmalloc(tStorageSize); -01420 tNextFree = 0; -01421 szText[tNextFree] = '\0'; -01422 -01423 /* Goto the start */ -01424 usChar = usToFootnotePosition(pFile, ulCharPosStart); -01425 ulCharPos = ulCharPosStart; -01426 ulFileOffset = ulCharPos2FileOffset(ulCharPos); -01427 /* Skip the unwanted starting characters */ -01428 while (usChar != (USHORT)EOF && ulCharPos != ulCharPosNext && -01429 (usChar == FOOTNOTE_OR_ENDNOTE || -01430 usChar == PAR_END || -01431 usChar == TAB || -01432 usChar == (USHORT)' ')) { -01433 usChar = usNextChar(pFile, footnote_list, -01434 &ulFileOffset, &ulCharPos, NULL); -01435 } -01436 /* Process the footnote text */ -01437 while (usChar != (USHORT)EOF && ulCharPos != ulCharPosNext) { -01438 /* Skip embedded characters */ -01439 if (usChar == START_EMBEDDED) { -01440 bSkip = TRUE; -01441 } else if (usChar == END_IGNORE || usChar == END_EMBEDDED) { -01442 bSkip = FALSE; -01443 } -01444 /* Translate character */ -01445 if (bSkip || -01446 usChar == END_IGNORE || -01447 usChar == END_EMBEDDED || -01448 usChar == FOOTNOTE_OR_ENDNOTE) { -01449 ulChar = IGNORE_CHARACTER; -01450 } else { -01451 ulChar = ulTranslateCharacters(usChar, -01452 ulFileOffset, -01453 iWordVersion, -01454 tOptions.eConversionType, -01455 tOptions.eEncoding, -01456 bOldMacFile); -01457 } -01458 /* Process character */ -01459 if (ulChar == PICTURE) { -01460 tLen = 5; -01461 strcpy(szResult, "[pic]"); -01462 } else if (ulChar == IGNORE_CHARACTER) { -01463 tLen = 0; -01464 szResult[0] = '\0'; -01465 } else { -01466 switch (ulChar) { -01467 case PAR_END: -01468 case HARD_RETURN: -01469 case PAGE_BREAK: -01470 case COLUMN_FEED: -01471 ulChar = (ULONG)PAR_END; -01472 break; -01473 case TAB: -01474 ulChar = (ULONG)' '; -01475 break; -01476 default: -01477 break; -01478 } -01479 tLen = tUcs2Utf8(ulChar, szResult, sizeof(szResult)); -01480 } -01481 /* Add the results to the text */ -01482 if (tNextFree + tLen + 1 > tStorageSize) { -01483 tStorageSize += EXTENTION_SIZE; -01484 szText = xrealloc(szText, tStorageSize); -01485 } -01486 for (tIndex = 0; tIndex < tLen; tIndex++) { -01487 szText[tNextFree++] = szResult[tIndex]; -01488 } -01489 szText[tNextFree] = '\0'; -01490 /* Next character */ -01491 usChar = usNextChar(pFile, footnote_list, -01492 &ulFileOffset, &ulCharPos, NULL); -01493 } -01494 /* Remove redundant spaces */ -01495 while (tNextFree != 0 && szText[tNextFree - 1] == ' ') { -01496 szText[tNextFree - 1] = '\0'; -01497 tNextFree--; -01498 } -01499 if (tNextFree == 0) { -01500 /* No text */ -01501 szText = xfree(szText); -01502 return NULL; -01503 } -01504 return szText; -01505 } /* end of szFootnoteDecryptor */ -