diff -r 59758314f811 -r d4524d6a4472 Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/out2window_8c_source.html --- a/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/out2window_8c_source.html Fri Jun 11 15:24:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,784 +0,0 @@ - - -
- -00001 /* -00002 * out2window.c -00003 * Copyright (C) 1998-2005 A.J. van Os; Released under GPL -00004 * -00005 * Description: -00006 * Output to a text window -00007 */ -00008 -00009 #include <string.h> -00010 #include <stdlib.h> -00011 #include <ctype.h> -00012 #include "antiword.h" -00013 -00014 /* Used for numbering the chapters */ -00015 static unsigned int auiHdrCounter[9]; -00016 -00017 -00018 /* -00019 * vString2Diagram - put a string into a diagram -00020 */ -00021 static void -00022 vString2Diagram(diagram_type *pDiag, output_type *pAnchor) -00023 { -00024 output_type *pOutput; -00025 long lWidth; -00026 USHORT usMaxFontSize; -00027 -00028 TRACE_MSG("vString2Diagram"); -00029 -00030 fail(pDiag == NULL); -00031 fail(pAnchor == NULL); -00032 -00033 /* Compute the maximum fontsize in this string */ -00034 usMaxFontSize = MIN_FONT_SIZE; -00035 for (pOutput = pAnchor; pOutput != NULL; pOutput = pOutput->pNext) { -00036 if (pOutput->usFontSize > usMaxFontSize) { -00037 usMaxFontSize = pOutput->usFontSize; -00038 } -00039 } -00040 -00041 /* Goto the next line */ -00042 vMove2NextLine(pDiag, pAnchor->tFontRef, usMaxFontSize); -00043 -00044 /* Output all substrings */ -00045 for (pOutput = pAnchor; pOutput != NULL; pOutput = pOutput->pNext) { -00046 lWidth = lMilliPoints2DrawUnits(pOutput->lStringWidth); -00047 vSubstring2Diagram(pDiag, pOutput->szStorage, -00048 pOutput->tNextFree, lWidth, pOutput->ucFontColor, -00049 pOutput->usFontStyle, pOutput->tFontRef, -00050 pOutput->usFontSize, usMaxFontSize); -00051 } -00052 -00053 /* Goto the start of the line */ -00054 pDiag->lXleft = 0; -00055 TRACE_MSG("leaving vString2Diagram"); -00056 } /* end of vString2Diagram */ -00057 -00058 /* -00059 * vSetLeftIndentation - set the left indentation of the specified diagram -00060 */ -00061 void -00062 vSetLeftIndentation(diagram_type *pDiag, long lLeftIndentation) -00063 { -00064 long lX; -00065 -00066 TRACE_MSG("vSetLeftIndentation"); -00067 -00068 fail(pDiag == NULL); -00069 fail(lLeftIndentation < 0); -00070 -00071 lX = lMilliPoints2DrawUnits(lLeftIndentation); -00072 if (lX > 0) { -00073 pDiag->lXleft = lX; -00074 } else { -00075 pDiag->lXleft = 0; -00076 } -00077 } /* end of vSetLeftIndentation */ -00078 -00079 /* -00080 * lComputeNetWidth - compute the net string width -00081 */ -00082 static long -00083 lComputeNetWidth(output_type *pAnchor) -00084 { -00085 output_type *pTmp; -00086 long lNetWidth; -00087 -00088 TRACE_MSG("lComputeNetWidth"); -00089 -00090 fail(pAnchor == NULL); -00091 -00092 /* Step 1: Count all but the last sub-string */ -00093 lNetWidth = 0; -00094 for (pTmp = pAnchor; pTmp->pNext != NULL; pTmp = pTmp->pNext) { -00095 fail(pTmp->lStringWidth < 0); -00096 lNetWidth += pTmp->lStringWidth; -00097 } -00098 fail(pTmp == NULL); -00099 fail(pTmp->pNext != NULL); -00100 -00101 /* Step 2: remove the white-space from the end of the string */ -00102 while (pTmp->tNextFree != 0 && -00103 isspace((int)(UCHAR)pTmp->szStorage[pTmp->tNextFree - 1])) { -00104 pTmp->szStorage[pTmp->tNextFree - 1] = '\0'; -00105 pTmp->tNextFree--; -00106 NO_DBG_DEC(pTmp->lStringWidth); -00107 pTmp->lStringWidth = lComputeStringWidth( -00108 pTmp->szStorage, -00109 pTmp->tNextFree, -00110 pTmp->tFontRef, -00111 pTmp->usFontSize); -00112 NO_DBG_DEC(pTmp->lStringWidth); -00113 } -00114 -00115 /* Step 3: Count the last sub-string */ -00116 lNetWidth += pTmp->lStringWidth; -00117 return lNetWidth; -00118 } /* end of lComputeNetWidth */ -00119 -00120 /* -00121 * iComputeHoles - compute number of holes -00122 * (A hole is a number of whitespace characters followed by a -00123 * non-whitespace character) -00124 */ -00125 static int -00126 iComputeHoles(output_type *pAnchor) -00127 { -00128 output_type *pTmp; -00129 size_t tIndex; -00130 int iCounter; -00131 BOOL bWasSpace, bIsSpace; -00132 -00133 TRACE_MSG("iComputeHoles"); -00134 -00135 fail(pAnchor == NULL); -00136 -00137 iCounter = 0; -00138 bIsSpace = FALSE; -00139 /* Count the holes */ -00140 for (pTmp = pAnchor; pTmp != NULL; pTmp = pTmp->pNext) { -00141 fail(pTmp->tNextFree != strlen(pTmp->szStorage)); -00142 for (tIndex = 0; tIndex <= pTmp->tNextFree; tIndex++) { -00143 bWasSpace = bIsSpace; -00144 bIsSpace = isspace((int)(UCHAR)pTmp->szStorage[tIndex]); -00145 if (bWasSpace && !bIsSpace) { -00146 iCounter++; -00147 } -00148 } -00149 } -00150 return iCounter; -00151 } /* end of iComputeHoles */ -00152 -00153 /* -00154 * vAlign2Window - Align a string and insert it into the text -00155 */ -00156 void -00157 vAlign2Window(diagram_type *pDiag, output_type *pAnchor, -00158 long lScreenWidth, UCHAR ucAlignment) -00159 { -00160 long lNetWidth, lLeftIndentation; -00161 -00162 TRACE_MSG("vAlign2Window"); -00163 -00164 fail(pDiag == NULL || pAnchor == NULL); -00165 fail(lScreenWidth < lChar2MilliPoints(MIN_SCREEN_WIDTH)); -00166 -00167 lNetWidth = lComputeNetWidth(pAnchor); -00168 -00169 if (lScreenWidth > lChar2MilliPoints(MAX_SCREEN_WIDTH) || -00170 lNetWidth <= 0) { -00171 /* -00172 * Screenwidth is "infinite", so no alignment is possible -00173 * Don't bother to align an empty line -00174 */ -00175 vString2Diagram(pDiag, pAnchor); -00176 TRACE_MSG("leaving vAlign2Window #1"); -00177 return; -00178 } -00179 -00180 switch (ucAlignment) { -00181 case ALIGNMENT_CENTER: -00182 lLeftIndentation = (lScreenWidth - lNetWidth) / 2; -00183 DBG_DEC_C(lLeftIndentation < 0, lLeftIndentation); -00184 if (lLeftIndentation > 0) { -00185 vSetLeftIndentation(pDiag, lLeftIndentation); -00186 } -00187 break; -00188 case ALIGNMENT_RIGHT: -00189 lLeftIndentation = lScreenWidth - lNetWidth; -00190 DBG_DEC_C(lLeftIndentation < 0, lLeftIndentation); -00191 if (lLeftIndentation > 0) { -00192 vSetLeftIndentation(pDiag, lLeftIndentation); -00193 } -00194 break; -00195 case ALIGNMENT_JUSTIFY: -00196 case ALIGNMENT_LEFT: -00197 default: -00198 break; -00199 } -00200 vString2Diagram(pDiag, pAnchor); -00201 TRACE_MSG("leaving vAlign2Window #2"); -00202 } /* end of vAlign2Window */ -00203 -00204 /* -00205 * vJustify2Window - Justify a string and insert it into the text -00206 */ -00207 void -00208 vJustify2Window(diagram_type *pDiag, output_type *pAnchor, -00209 long lScreenWidth, long lRightIndentation, UCHAR ucAlignment) -00210 { -00211 output_type *pTmp; -00212 char *pcNew, *pcOld, *szStorage; -00213 long lNetWidth, lSpaceWidth, lToAdd; -00214 int iFillerLen, iHoles; -00215 -00216 TRACE_MSG("vJustify2Window"); -00217 -00218 fail(pDiag == NULL || pAnchor == NULL); -00219 fail(lScreenWidth < MIN_SCREEN_WIDTH); -00220 fail(lRightIndentation > 0); -00221 -00222 if (ucAlignment != ALIGNMENT_JUSTIFY) { -00223 vAlign2Window(pDiag, pAnchor, lScreenWidth, ucAlignment); -00224 return; -00225 } -00226 -00227 lNetWidth = lComputeNetWidth(pAnchor); -00228 -00229 if (lScreenWidth > lChar2MilliPoints(MAX_SCREEN_WIDTH) || -00230 lNetWidth <= 0) { -00231 /* -00232 * Screenwidth is "infinite", so justify is not possible -00233 * Don't bother to justify an empty line -00234 */ -00235 vString2Diagram(pDiag, pAnchor); -00236 TRACE_MSG("leaving vJustify2Window #1"); -00237 return; -00238 } -00239 -00240 /* Justify */ -00241 fail(ucAlignment != ALIGNMENT_JUSTIFY); -00242 lSpaceWidth = lComputeStringWidth(" ", 1, -00243 pAnchor->tFontRef, pAnchor->usFontSize); -00244 lToAdd = lScreenWidth - -00245 lNetWidth - -00246 lDrawUnits2MilliPoints(pDiag->lXleft) + -00247 lRightIndentation; -00248 #if defined(DEBUG) -00249 if (lToAdd / lSpaceWidth < -1) { -00250 DBG_DEC(lSpaceWidth); -00251 DBG_DEC(lToAdd); -00252 DBG_DEC(lScreenWidth); -00253 DBG_DEC(lNetWidth); -00254 DBG_DEC(lDrawUnits2MilliPoints(pDiag->lXleft)); -00255 DBG_DEC(pDiag->lXleft); -00256 DBG_DEC(lRightIndentation); -00257 } -00258 #endif /* DEBUG */ -00259 lToAdd /= lSpaceWidth; -00260 DBG_DEC_C(lToAdd < 0, lToAdd); -00261 if (lToAdd <= 0) { -00262 vString2Diagram(pDiag, pAnchor); -00263 TRACE_MSG("leaving vJustify2Window #2"); -00264 return; -00265 } -00266 -00267 /* Justify by adding spaces */ -00268 iHoles = iComputeHoles(pAnchor); -00269 for (pTmp = pAnchor; pTmp != NULL; pTmp = pTmp->pNext) { -00270 fail(pTmp->tNextFree != strlen(pTmp->szStorage)); -00271 fail(lToAdd < 0); -00272 szStorage = xmalloc(pTmp->tNextFree + (size_t)lToAdd + 1); -00273 pcNew = szStorage; -00274 for (pcOld = pTmp->szStorage; *pcOld != '\0'; pcOld++) { -00275 *pcNew++ = *pcOld; -00276 if (*pcOld == ' ' && -00277 *(pcOld + 1) != ' ' && -00278 iHoles > 0) { -00279 iFillerLen = (int)(lToAdd / iHoles); -00280 lToAdd -= iFillerLen; -00281 iHoles--; -00282 for (; iFillerLen > 0; iFillerLen--) { -00283 *pcNew++ = ' '; -00284 } -00285 } -00286 } -00287 *pcNew = '\0'; -00288 pTmp->szStorage = xfree(pTmp->szStorage); -00289 pTmp->szStorage = szStorage; -00290 pTmp->tStorageSize = pTmp->tNextFree + (size_t)lToAdd + 1; -00291 pTmp->lStringWidth += -00292 (pcNew - szStorage - (long)pTmp->tNextFree) * -00293 lSpaceWidth; -00294 fail(pcNew < szStorage); -00295 pTmp->tNextFree = (size_t)(pcNew - szStorage); -00296 fail(pTmp->tNextFree != strlen(pTmp->szStorage)); -00297 } -00298 DBG_DEC_C(lToAdd != 0, lToAdd); -00299 vString2Diagram(pDiag, pAnchor); -00300 TRACE_MSG("leaving vJustify2Window #3"); -00301 } /* end of vJustify2Window */ -00302 -00303 /* -00304 * vResetStyles - reset the style information variables -00305 */ -00306 void -00307 vResetStyles(void) -00308 { -00309 TRACE_MSG("vResetStyles"); -00310 -00311 (void)memset(auiHdrCounter, 0, sizeof(auiHdrCounter)); -00312 } /* end of vResetStyles */ -00313 -00314 /* -00315 * tStyle2Window - Add the style characters to the line -00316 * -00317 * Returns the length of the resulting string -00318 */ -00319 size_t -00320 tStyle2Window(char *szLine, size_t tLineSize, const style_block_type *pStyle, -00321 const section_block_type *pSection) -00322 { -00323 char *pcTxt; -00324 size_t tIndex, tStyleIndex; -00325 BOOL bNeedPrevLvl; -00326 level_type_enum eNumType; -00327 UCHAR ucNFC; -00328 -00329 TRACE_MSG("tStyle2Window"); -00330 -00331 fail(szLine == NULL || pStyle == NULL || pSection == NULL); -00332 -00333 if (pStyle->usIstd == 0 || pStyle->usIstd > 9) { -00334 szLine[0] = '\0'; -00335 return 0; -00336 } -00337 -00338 /* Set the numbers */ -00339 tStyleIndex = (size_t)pStyle->usIstd - 1; -00340 for (tIndex = 0; tIndex < 9; tIndex++) { -00341 if (tIndex == tStyleIndex) { -00342 auiHdrCounter[tIndex]++; -00343 } else if (tIndex > tStyleIndex) { -00344 auiHdrCounter[tIndex] = 0; -00345 } else if (auiHdrCounter[tIndex] == 0) { -00346 auiHdrCounter[tIndex] = 1; -00347 } -00348 } -00349 -00350 eNumType = eGetNumType(pStyle->ucNumLevel); -00351 if (eNumType != level_type_outline) { -00352 szLine[0] = '\0'; -00353 return 0; -00354 } -00355 -00356 /* Print the numbers */ -00357 pcTxt = szLine; -00358 bNeedPrevLvl = (pSection->usNeedPrevLvl & BIT(tStyleIndex)) != 0; -00359 for (tIndex = 0; tIndex <= tStyleIndex; tIndex++) { -00360 if (tIndex == tStyleIndex || -00361 (bNeedPrevLvl && tIndex < tStyleIndex)) { -00362 if (pcTxt - szLine >= tLineSize - 25) { -00363 /* Prevent a possible buffer overflow */ -00364 DBG_DEC(pcTxt - szLine); -00365 DBG_DEC(tLineSize - 25); -00366 DBG_FIXME(); -00367 szLine[0] = '\0'; -00368 return 0; -00369 } -00370 ucNFC = pSection->aucNFC[tIndex]; -00371 switch(ucNFC) { -00372 case LIST_ARABIC_NUM: -00373 case LIST_NUMBER_TXT: -00374 case LIST_ORDINAL_TXT: -00375 pcTxt += sprintf(pcTxt, "%u", -00376 auiHdrCounter[tIndex]); -00377 break; -00378 case LIST_UPPER_ROMAN: -00379 case LIST_LOWER_ROMAN: -00380 pcTxt += tNumber2Roman( -00381 auiHdrCounter[tIndex], -00382 ucNFC == LIST_UPPER_ROMAN, -00383 pcTxt); -00384 break; -00385 case LIST_UPPER_ALPHA: -00386 case LIST_LOWER_ALPHA: -00387 pcTxt += tNumber2Alpha( -00388 auiHdrCounter[tIndex], -00389 ucNFC == LIST_UPPER_ALPHA, -00390 pcTxt); -00391 break; -00392 case LIST_OUTLINE_NUM: -00393 pcTxt += sprintf(pcTxt, "%02u", -00394 auiHdrCounter[tIndex]); -00395 break; -00396 default: -00397 DBG_DEC(ucNFC); -00398 DBG_FIXME(); -00399 pcTxt += sprintf(pcTxt, "%u", -00400 auiHdrCounter[tIndex]); -00401 break; -00402 } -00403 if (tIndex < tStyleIndex) { -00404 *pcTxt++ = '.'; -00405 } else if (tIndex == tStyleIndex) { -00406 *pcTxt++ = ' '; -00407 } -00408 } -00409 } -00410 *pcTxt = '\0'; -00411 NO_DBG_MSG_C((int)pStyle->usIstd >= 1 && -00412 (int)pStyle->usIstd <= 9 && -00413 eNumType != level_type_none && -00414 eNumType != level_type_outline, szLine); -00415 NO_DBG_MSG_C(szLine[0] != '\0', szLine); -00416 fail(pcTxt < szLine); -00417 return (size_t)(pcTxt - szLine); -00418 } /* end of tStyle2Window */ -00419 -00420 /* -00421 * vRemoveRowEnd - remove the end of table row indicator -00422 * -00423 * Remove the double TABLE_SEPARATOR characters from the end of the string. -00424 * Special: remove the TABLE_SEPARATOR, 0x0a sequence -00425 */ -00426 static void -00427 vRemoveRowEnd(char *szRowTxt) -00428 { -00429 int iLastIndex; -00430 -00431 TRACE_MSG("vRemoveRowEnd"); -00432 -00433 fail(szRowTxt == NULL || szRowTxt[0] == '\0'); -00434 -00435 iLastIndex = (int)strlen(szRowTxt) - 1; -00436 -00437 if (szRowTxt[iLastIndex] == TABLE_SEPARATOR || -00438 szRowTxt[iLastIndex] == (char)0x0a) { -00439 szRowTxt[iLastIndex] = '\0'; -00440 iLastIndex--; -00441 } else { -00442 DBG_HEX(szRowTxt[iLastIndex]); -00443 } -00444 -00445 if (iLastIndex >= 0 && szRowTxt[iLastIndex] == (char)0x0a) { -00446 szRowTxt[iLastIndex] = '\0'; -00447 iLastIndex--; -00448 } -00449 -00450 if (iLastIndex >= 0 && szRowTxt[iLastIndex] == TABLE_SEPARATOR) { -00451 szRowTxt[iLastIndex] = '\0'; -00452 return; -00453 } -00454 -00455 DBG_DEC(iLastIndex); -00456 DBG_HEX(szRowTxt[iLastIndex]); -00457 DBG_MSG(szRowTxt); -00458 } /* end of vRemoveRowEnd */ -00459 -00460 /* -00461 * tComputeStringLengthMax - max string length in relation to max column width -00462 * -00463 * Return the maximum string length -00464 */ -00465 static size_t -00466 tComputeStringLengthMax(const char *szString, size_t tColumnWidthMax) -00467 { -00468 const char *pcTmp; -00469 size_t tLengthMax, tLenPrev, tLen, tWidth; -00470 -00471 TRACE_MSG("tComputeStringLengthMax"); -00472 -00473 fail(szString == NULL); -00474 fail(tColumnWidthMax == 0); -00475 -00476 pcTmp = strchr(szString, '\n'); -00477 if (pcTmp != NULL) { -00478 tLengthMax = (size_t)(pcTmp - szString + 1); -00479 } else { -00480 tLengthMax = strlen(szString); -00481 } -00482 if (tLengthMax == 0) { -00483 return 0; -00484 } -00485 -00486 tLen = 0; -00487 tWidth = 0; -00488 for (;;) { -00489 tLenPrev = tLen; -00490 tLen += tGetCharacterLength(szString + tLen); -00491 DBG_DEC_C(tLen > tLengthMax, tLen); -00492 DBG_DEC_C(tLen > tLengthMax, tLengthMax); -00493 fail(tLen > tLengthMax); -00494 tWidth = tCountColumns(szString, tLen); -00495 if (tWidth > tColumnWidthMax) { -00496 return tLenPrev; -00497 } -00498 if (tLen >= tLengthMax) { -00499 return tLengthMax; -00500 } -00501 } -00502 } /* end of tComputeStringLengthMax */ -00503 -00504 /* -00505 * tGetBreakingPoint - get the number of bytes that fit the column -00506 * -00507 * Returns the number of bytes that fit the column -00508 */ -00509 static size_t -00510 tGetBreakingPoint(const char *szString, -00511 size_t tLen, size_t tWidth, size_t tColumnWidthMax) -00512 { -00513 int iIndex; -00514 -00515 TRACE_MSG("tGetBreakingPoint"); -00516 -00517 fail(szString == NULL); -00518 fail(tLen > strlen(szString)); -00519 fail(tWidth > tColumnWidthMax); -00520 -00521 if (tWidth < tColumnWidthMax || -00522 (tWidth == tColumnWidthMax && -00523 (szString[tLen] == ' ' || -00524 szString[tLen] == '\n' || -00525 szString[tLen] == '\0'))) { -00526 /* The string already fits, do nothing */ -00527 return tLen; -00528 } -00529 /* Search for a breaking point */ -00530 for (iIndex = (int)tLen - 1; iIndex >= 0; iIndex--) { -00531 if (szString[iIndex] == ' ') { -00532 return (size_t)iIndex; -00533 } -00534 } -00535 /* No breaking point found, just fill the column */ -00536 return tLen; -00537 } /* end of tGetBreakingPoint */ -00538 -00539 /* -00540 * tComputeColumnWidthMax - compute the maximum column width -00541 */ -00542 static size_t -00543 tComputeColumnWidthMax(short sWidth, long lCharWidth, double dFactor) -00544 { -00545 size_t tColumnWidthMax; -00546 -00547 TRACE_MSG("tComputeColumnWidthMax"); -00548 -00549 fail(sWidth < 0); -00550 fail(lCharWidth <= 0); -00551 fail(dFactor <= 0.0); -00552 -00553 tColumnWidthMax = (size_t)( -00554 (lTwips2MilliPoints(sWidth) * dFactor + lCharWidth / 2.0) / -00555 lCharWidth); -00556 if (tColumnWidthMax == 0) { -00557 /* Minimum column width */ -00558 return 1; -00559 } -00560 if (tColumnWidthMax > 1) { -00561 /* Make room for the TABLE_SEPARATOR_CHAR */ -00562 tColumnWidthMax--; -00563 } -00564 NO_DBG_DEC(tColumnWidthMax); -00565 return tColumnWidthMax; -00566 } /* end of tComputeColumnWidthMax */ -00567 -00568 /* -00569 * vTableRow2Window - put a table row into a diagram -00570 */ -00571 void -00572 vTableRow2Window(diagram_type *pDiag, output_type *pOutput, -00573 const row_block_type *pRowInfo, -00574 conversion_type eConversionType, int iParagraphBreak) -00575 { -00576 output_type tRow; -00577 char *aszColTxt[TABLE_COLUMN_MAX]; -00578 char *szLine, *pcTxt; -00579 double dMagnify; -00580 long lCharWidthLarge, lCharWidthSmall; -00581 size_t tColumnWidthTotal, atColumnWidthMax[TABLE_COLUMN_MAX]; -00582 size_t tSize, tColumnWidthMax, tWidth, tLen; -00583 int iIndex, iNbrOfColumns, iTmp; -00584 BOOL bNotReady; -00585 -00586 TRACE_MSG("vTableRow2Window"); -00587 -00588 fail(pDiag == NULL || pOutput == NULL || pRowInfo == NULL); -00589 fail(pOutput->szStorage == NULL); -00590 fail(pOutput->pNext != NULL); -00591 fail(iParagraphBreak < 0); -00592 -00593 /* Character sizes */ -00594 lCharWidthLarge = lComputeStringWidth("W", 1, -00595 pOutput->tFontRef, pOutput->usFontSize); -00596 NO_DBG_DEC(lCharWidthLarge); -00597 lCharWidthSmall = lComputeStringWidth("i", 1, -00598 pOutput->tFontRef, pOutput->usFontSize); -00599 NO_DBG_DEC(lCharWidthSmall); -00600 /* For the time being: use a fixed width font */ -00601 fail(lCharWidthLarge != lCharWidthSmall); -00602 -00603 vRemoveRowEnd(pOutput->szStorage); -00604 -00605 /* Split the row text into a set of column texts */ -00606 aszColTxt[0] = pOutput->szStorage; -00607 for (iNbrOfColumns = 1; -00608 iNbrOfColumns < TABLE_COLUMN_MAX; -00609 iNbrOfColumns++) { -00610 aszColTxt[iNbrOfColumns] = -00611 strchr(aszColTxt[iNbrOfColumns - 1], -00612 TABLE_SEPARATOR); -00613 if (aszColTxt[iNbrOfColumns] == NULL) { -00614 break; -00615 } -00616 *aszColTxt[iNbrOfColumns] = '\0'; -00617 aszColTxt[iNbrOfColumns]++; -00618 NO_DBG_DEC(iNbrOfColumns); -00619 NO_DBG_MSG(aszColTxt[iNbrOfColumns]); -00620 } -00621 -00622 /* Work around a bug in Word */ -00623 while (iNbrOfColumns > (int)pRowInfo->ucNumberOfColumns && -00624 pRowInfo->asColumnWidth[iNbrOfColumns] == 0) { -00625 iNbrOfColumns--; -00626 } -00627 -00628 DBG_DEC_C(iNbrOfColumns != (int)pRowInfo->ucNumberOfColumns, -00629 iNbrOfColumns); -00630 DBG_DEC_C(iNbrOfColumns != (int)pRowInfo->ucNumberOfColumns, -00631 pRowInfo->ucNumberOfColumns); -00632 if (iNbrOfColumns != (int)pRowInfo->ucNumberOfColumns) { -00633 werr(0, "Skipping an unmatched table row"); -00634 return; -00635 } -00636 -00637 #if defined(__FULL_TEXT_SEARCH) -00638 /* No table formatting: use for full-text search (untested) */ -00639 for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) { -00640 fprintf(pDiag->pOutFile, "%s\n" , aszColTxt[iIndex]); -00641 } -00642 #else -00643 if (bAddTableRow(pDiag, aszColTxt, iNbrOfColumns, -00644 pRowInfo->asColumnWidth, pRowInfo->ucBorderInfo)) { -00645 /* All work has been done */ -00646 return; -00647 } -00648 -00649 /* Fill the table with maximum column widths */ -00650 if (eConversionType == conversion_text || -00651 eConversionType == conversion_fmt_text) { -00652 if (iParagraphBreak == 0 || -00653 iParagraphBreak >= MAX_SCREEN_WIDTH) { -00654 dMagnify = (double)MAX_SCREEN_WIDTH; -00655 } else if (iParagraphBreak <= MIN_SCREEN_WIDTH) { -00656 dMagnify = (double)MIN_SCREEN_WIDTH; -00657 } else { -00658 dMagnify = (double)iParagraphBreak; -00659 } -00660 dMagnify /= (double)DEFAULT_SCREEN_WIDTH; -00661 DBG_FLT_C(dMagnify < 0.99 || dMagnify > 1.01, dMagnify); -00662 } else { -00663 dMagnify = 1.0; -00664 } -00665 tColumnWidthTotal = 0; -00666 for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) { -00667 atColumnWidthMax[iIndex] = tComputeColumnWidthMax( -00668 pRowInfo->asColumnWidth[iIndex], -00669 lCharWidthLarge, -00670 dMagnify); -00671 tColumnWidthTotal += atColumnWidthMax[iIndex]; -00672 } -00673 -00674 /* -00675 * Get enough space for the row. -00676 * Worst case: three bytes per UTF-8 character -00677 */ -00678 tSize = 3 * (1 + tColumnWidthTotal + (size_t)iNbrOfColumns + 3); -00679 szLine = xmalloc(tSize); -00680 -00681 do { -00682 /* Print one line of a table row */ -00683 bNotReady = FALSE; -00684 pcTxt = szLine; -00685 *pcTxt++ = TABLE_SEPARATOR_CHAR; -00686 for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) { -00687 tColumnWidthMax = atColumnWidthMax[iIndex]; -00688 if (aszColTxt[iIndex] == NULL) { -00689 /* Add an empty column */ -00690 for (iTmp = 0; -00691 iTmp < (int)tColumnWidthMax; -00692 iTmp++) { -00693 *pcTxt++ = (char)FILLER_CHAR; -00694 } -00695 *pcTxt++ = TABLE_SEPARATOR_CHAR; -00696 *pcTxt = '\0'; -00697 continue; -00698 } -00699 /* Compute the length and width of the column text */ -00700 tLen = tComputeStringLengthMax( -00701 aszColTxt[iIndex], tColumnWidthMax); -00702 NO_DBG_DEC(tLen); -00703 while (tLen != 0 && -00704 (aszColTxt[iIndex][tLen - 1] == '\n' || -00705 aszColTxt[iIndex][tLen - 1] == ' ')) { -00706 aszColTxt[iIndex][tLen - 1] = ' '; -00707 tLen--; -00708 } -00709 tWidth = tCountColumns(aszColTxt[iIndex], tLen); -00710 fail(tWidth > tColumnWidthMax); -00711 tLen = tGetBreakingPoint(aszColTxt[iIndex], -00712 tLen, tWidth, tColumnWidthMax); -00713 tWidth = tCountColumns(aszColTxt[iIndex], tLen); -00714 if (tLen == 0 && *aszColTxt[iIndex] == '\0') { -00715 /* No text at all */ -00716 aszColTxt[iIndex] = NULL; -00717 } else { -00718 /* Add the text */ -00719 pcTxt += sprintf(pcTxt, -00720 "%.*s", (int)tLen, aszColTxt[iIndex]); -00721 if (tLen == 0 && *aszColTxt[iIndex] != ' ') { -00722 tLen = tGetCharacterLength( -00723 aszColTxt[iIndex]); -00724 DBG_CHR(*aszColTxt[iIndex]); -00725 DBG_FIXME(); -00726 fail(tLen == 0); -00727 } -00728 aszColTxt[iIndex] += tLen; -00729 while (*aszColTxt[iIndex] == ' ') { -00730 aszColTxt[iIndex]++; -00731 } -00732 if (*aszColTxt[iIndex] == '\0') { -00733 /* This row is now complete */ -00734 aszColTxt[iIndex] = NULL; -00735 } else { -00736 /* This row needs more lines */ -00737 bNotReady = TRUE; -00738 } -00739 } -00740 /* Fill up the rest */ -00741 for (iTmp = 0; -00742 iTmp < (int)tColumnWidthMax - (int)tWidth; -00743 iTmp++) { -00744 *pcTxt++ = (char)FILLER_CHAR; -00745 } -00746 /* End of column */ -00747 *pcTxt++ = TABLE_SEPARATOR_CHAR; -00748 *pcTxt = '\0'; -00749 } -00750 /* Output the table row line */ -00751 *pcTxt = '\0'; -00752 tRow = *pOutput; -00753 tRow.szStorage = szLine; -00754 fail(pcTxt < szLine); -00755 tRow.tNextFree = (size_t)(pcTxt - szLine); -00756 tRow.lStringWidth = lComputeStringWidth( -00757 tRow.szStorage, -00758 tRow.tNextFree, -00759 tRow.tFontRef, -00760 tRow.usFontSize); -00761 vString2Diagram(pDiag, &tRow); -00762 TRACE_MSG("after vString2Diagram in vTableRow2Window"); -00763 } while (bNotReady); -00764 /* Clean up before you leave */ -00765 szLine = xfree(szLine); -00766 TRACE_MSG("leaving vTableRow2Window"); -00767 #endif /* __FULL_TEXT_SEARCH */ -00768 } /* end of vTableRow2Window */ -