diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/out2window_8c_source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/out2window_8c_source.html Tue Mar 30 16:16:55 2010 +0100 @@ -0,0 +1,784 @@ + + + + +TB9.2 Example Applications: examples/PIPS/antiword/src/out2window.c Source File + + + + + +

examples/PIPS/antiword/src/out2window.c

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 */
+
+
Generated by  + +doxygen 1.6.2
+ +