home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / utils / rtfprsr / trf_tbl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  5.7 KB  |  290 lines

  1. /*
  2.     trf-table.c - table writing functions
  3.  
  4.     Ugly ugly ugly.
  5. */
  6.  
  7. # include    <stdio.h>
  8. # include    <sys/types.h>
  9. # include    "rtf.h"
  10. # include    "rtf2troff.h"
  11.  
  12.  
  13. static int    CellBorderLocIndex ();
  14. static int    VCellBorderType ();
  15. static char    *VCellBorderStr ();
  16. static char    *HCellBorderStr ();
  17.  
  18.  
  19. /*
  20.     Border type tokens *follow* cell border location specifiers.
  21. */
  22.  
  23. void TblAttr ()
  24. {
  25. double    inch = (double) rtfParam / (double) rtfTpi;
  26. int    i, j, loc;
  27.  
  28.     switch (rtfMinor)
  29.     {
  30.     case rtfCellBordBottom:
  31.     case rtfCellBordTop:
  32.     case rtfCellBordLeft:
  33.     case rtfCellBordRight:
  34.         if (its->nCells >= maxCell)
  35.         {
  36.             fprintf (stderr,
  37.                 "Borders specified for too many cells\n");
  38.             break;
  39.         }
  40.         loc = CellBorderLocIndex (rtfMinor);
  41.         /*
  42.             Get border type tokens until non-type token seen,
  43.             then route non-type token normally.
  44.         */
  45.         for (;;)
  46.         {
  47.             (void) RTFGetToken ();
  48.             if (!RTFCheckCM (rtfControl, rtfParAttr)
  49.                 || (rtfMinor != rtfBorderSingle
  50.                     && rtfMinor != rtfBorderThick
  51.                     && rtfMinor != rtfBorderShadow
  52.                     && rtfMinor != rtfBorderDouble
  53.                     && rtfMinor != rtfBorderDot
  54.                     && rtfMinor != rtfBorderHair))
  55.                 break;
  56.             if (its->nCells < maxCell)
  57.                 its->border[its->nCells][loc] = rtfMinor;
  58.         }
  59.         RTFRouteToken ();    /* send non-border through router */
  60.         break;
  61.     case rtfRowDef:
  62.         its->tableHeader = 0;
  63.         its->nCells = 0;
  64.         its->curCell = 0;
  65.         for (i = 0; i < maxCell; i++)
  66.         {
  67.             its->cellPos[i] = 0;
  68.             for (j = 0; j < 4; j++)
  69.                 its->border[i][j] = rtfNoBorderType;
  70.         }
  71.         its->tableLeft = 0;
  72.         its->cellGap = 0;
  73.         break;
  74.     case rtfRowLeft:
  75.         break;
  76.     case rtfRowRight:
  77.         break;
  78.     case rtfRowCenter:
  79.         break;
  80.     case rtfRowGapH:
  81.         its->cellGap = inch;
  82.         break;
  83.     case rtfRowHt:
  84.         break;
  85.     case rtfRowLeftEdge:
  86.         its->tableLeft = inch;
  87.         break;
  88.     case rtfCellPos:
  89.         if (its->nCells >= maxCell)
  90.             fprintf (f, "max. table row cell count (%d) exceeded\n",
  91.                             maxCell);
  92.         else
  93.             its->cellPos[its->nCells++] = inch;
  94.         break;
  95.     case rtfMergeRngFirst:
  96.         break;
  97.     case rtfMergePrevious:
  98.         break;
  99.     }
  100. }
  101.  
  102.  
  103. void BeginTbl ()
  104. {
  105. int    i, n;
  106. double    cwid;
  107. char    *p;
  108.  
  109.     Flush ();
  110.     FlushState ();
  111.     SaveTblFPV ();        /* save current font, ps, vs */
  112.     fprintf (f, ".TS\n");
  113.     fprintf (f, "center tab(^);\n");
  114.     for (i = 0; i < its->nCells; i++)
  115.     {
  116.         if ((p = VCellBorderStr (VCellBorderType (i))) != NULL)
  117.             fprintf (f, "%s ", p);
  118.         cwid = its->cellPos[i];
  119.         if (i > 0)
  120.             cwid -= its->cellPos[i-1];
  121.         cwid -= EnWidth ();
  122.         fprintf (f, "l1w(%gi) ", cwid);
  123.     }
  124.     if ((p = VCellBorderStr (VCellBorderType (its->nCells))) != NULL)
  125.         fprintf (f, "%s ", p);
  126.     fprintf (f, ".\n");
  127.     ++its->tableHeader;
  128.  
  129.     /* print top borders */
  130.     n = 0;
  131.     for (i = 0; i < its->nCells; i++)
  132.     {
  133.         if (its->border[i][topIndex] != rtfNoBorderType)
  134.             ++n;
  135.     }
  136.     if (n > 0)
  137.     {
  138.         for (i = 0; i < its->nCells; i++)
  139.         {
  140.             if (i > 0)
  141.                 fprintf (f, "^");
  142.             if ((p = HCellBorderStr (its->border[i][topIndex]))
  143.                                 != NULL)
  144.                 fprintf (f, "%s", p);
  145.         }
  146.         fprintf (f, "\n");
  147.     }
  148. }
  149.  
  150.  
  151. void EndTbl ()
  152. {
  153. int    i, n;
  154. char    *p;
  155.  
  156.     /* print bottom borders */
  157.     n = 0;
  158.     for (i = 0; i < its->nCells; i++)
  159.     {
  160.         if (its->border[i][bottomIndex] != rtfNoBorderType)
  161.             ++n;
  162.     }
  163.     if (n > 0)
  164.     {
  165.         for (i = 0; i < its->nCells; i++)
  166.         {
  167.             if (i > 0)
  168.                 fprintf (f, "^");
  169.             if ((p = HCellBorderStr (its->border[i][bottomIndex]))
  170.                                 != NULL)
  171.                 fprintf (f, "%s", p);
  172.         }
  173.         fprintf (f, "\n");
  174.     }
  175.     fprintf (f, ".TE\n");    /* this undoes ps/vs... */
  176.     FlushTblFPV ();        /* so redo it.  ugh. */
  177.     FlushState ();
  178.     its->tableHeader = 0;
  179.     its->curCell = 0;
  180. }
  181.  
  182.  
  183. /*
  184.     BeginCell() called when first \intbl in row is seen and after
  185.     each \cell; EndCell() called whenever \cell or \row are seen.
  186.     These do nothing if the cell number is greater than would be
  187.     expected given the number of cell positions found in the table
  188.     layout information.  (It *is* possible to find information
  189.     beyond the last cell; Word for Macintosh, at least, seems to put an
  190.     empty cell at the end of each row.)
  191. */
  192.  
  193. void BeginCell ()
  194. {
  195.     /* accept cells 0..nCells-1 */
  196.     if (its->curCell < its->nCells)
  197.     {
  198.         Flush ();
  199.         fprintf (f, "T{\n");
  200.         /*FlushState ();*/
  201.         FlushTblFPV ();        /* set up correct font, ps, vs */
  202.     }
  203.     inTable = 1;
  204. }
  205.  
  206.  
  207. void EndCell ()
  208. {
  209.     Flush ();
  210.     /* accept cells 0..nCells-1 */
  211.     if (its->curCell < its->nCells)
  212.     {
  213.         fprintf (f, "T}");
  214.     }
  215.     ++its->curCell;
  216.     if (its->curCell < its->nCells)
  217.         fprintf (f, "^");    /* more cells to go */
  218.     else if (its->curCell == its->nCells)
  219.         fprintf (f, "\n");    /* no more cells to go */
  220.     inTable = 0;
  221. }
  222.  
  223.  
  224. static int CellBorderLocIndex (loc)
  225. int    loc;
  226. {
  227.     switch (loc)
  228.     {
  229.     case rtfCellBordLeft: return (leftIndex);
  230.     case rtfCellBordRight: return (rightIndex);
  231.     case rtfCellBordTop: return (topIndex);
  232.     case rtfCellBordBottom: return (bottomIndex);
  233.     }
  234.     fprintf (stderr, "CellBorderLocIndex: bad argument (%d)\n", loc);
  235.     exit (1);
  236. }
  237.  
  238.  
  239. /*
  240.     Determine vertical border for left of cell i.  Takes into account
  241.     right border of i-1 and left border of i, with the latter taking
  242.     precedence.  Two special cases are handled implicitly in code
  243.     below.  When i = 0, return left border of cell 0.  When i = nCells,
  244.     return right border of cell nCells-1.
  245. */
  246.  
  247. static int VCellBorderType (i)
  248. int    i;
  249. {
  250. int    border = rtfNoBorderType;
  251.  
  252.     if (i >= 0 && i < its->nCells)
  253.         border = its->border[i][leftIndex];
  254.     if (i > 0 && i <= its->nCells && border == rtfNoBorderType)
  255.         border = its->border[i-1][rightIndex];
  256.     return (border);
  257. }
  258.  
  259.  
  260. static char *VCellBorderStr (type)
  261. int    type;
  262. {
  263.     switch (type)
  264.     {
  265.     case rtfBorderShadow:
  266.     case rtfBorderThick:
  267.     case rtfBorderDot:
  268.     case rtfBorderHair:
  269.     case rtfBorderSingle: return ("|");
  270.     case rtfBorderDouble: return ("||");
  271.     }
  272.     return (NULL);
  273. }
  274.  
  275.  
  276. static char *HCellBorderStr (type)
  277. int    type;
  278. {
  279.     switch (type)
  280.     {
  281.     case rtfBorderShadow:
  282.     case rtfBorderThick:
  283.     case rtfBorderDot:
  284.     case rtfBorderHair:
  285.     case rtfBorderSingle: return ("_");
  286.     case rtfBorderDouble: return ("=");
  287.     }
  288.     return (NULL);
  289. }
  290.