39#define DFLT_CELLSPACING_3D     5 
   40#define DFLT_CELLSPACING_FLAT   0 
   41#define DFLT_CELLPADDING        2 
   46#define SETMAX(A,B)  if ((A) < (B)) { (A) = (B); } 
   47#define MAX(A,B)     ((A) < (B) ? (B) : (A)) 
   68      cellSpacing = atoi(z);
 
   80   int nw = 0, nh = 1, mw = 0;
 
  134   if (!(pEnd = pTable->
fPEnd)) {
 
  152   while (p && (p = p->
fPNext)) {
 
  176            if (cols > numcols) numcols = cols;
 
  203            if ((!(cp = p->
MarkupArg(
"colspan", 0))) || (cspans = atoi(cp)) <= 0) {
 
  206            if ((cp = p->
MarkupArg(
"rowspan", 0)) && (j = atoi(cp)) > 0 &&
 
  215               while ((cspans - j) > 0) {
 
  237            while ((cspans - j) > 0) {
 
  242                  if (
h > maxh) maxh = 
h;
 
  244                     if (w > maxw[cols-1]) {
 
  260            for (j = 0; j < p->
fCount; j++) {
 
  279            snprintf(buf, 
sizeof(buf), 
"%d %d %d %d ", rows-1, cols-1,
 
  286   while (nest--) str->
Append(
"} ");
 
  289      snprintf(buf, 
sizeof(buf), 
"%d ", maxw[j]);
 
  326      if (p == lp) 
return 0;
 
  333      } 
else if (p->
fType == 
n) {
 
  339      } 
else if (p->
fType == en) {
 
  340         if (!lvl--) 
return p;
 
  383   int minW, maxW, requestedW;        
 
  409# define ColMin(A,B) colMin[(A)-1][(B)-1] 
  410# define ColReq(A,B) colMin[(B)-1][(A)-1] 
  424   if (z && *z == 0) z = 
"2";
 
  449   separation = cellSpacing + 2 * (cellPadding + cbw);
 
  450   margin = tbw + cellSpacing + cbw + cellPadding;
 
  459      if (len > 0 && z[len-1] == 
'%') {
 
  460         maxTableWidth = (atoi(z) * lineWidth) / 100;
 
  462         maxTableWidth = atoi(z);
 
  465      maxTableWidth = lineWidth;
 
  467   maxTableWidth -= 2 * margin;
 
  471         lineWidth, maxTableWidth, margin));
 
  473   for (p = pStart->
fPNext; p; p = fPNext) {
 
  501            availWidth = maxTableWidth;
 
  516               if (pNew == 0) 
break;
 
  529            } 
while (iCol1 <= pStart->fNCol && fromAbove[iCol1] > iRow);
 
  533            if (colspan == 0) colspan = 1;
 
  534            if (iCol1 + colspan - 1 > pStart->
fNCol) {
 
  535               int nCol = iCol1 + colspan - 1;
 
  537               for (i = pStart->
fNCol + 1; i <= nCol; i++) {
 
  539                  pStart->
fMinW[i] = 0;
 
  540                  pStart->
fMaxW[i] = 0;
 
  544                  for (j = 1; j < i; j++) {
 
  549               pStart->
fNCol = nCol;
 
  551            noWrap = (p->
MarkupArg(
"nowrap", 0) != 0);
 
  554            fPNext = 
MinMax(p, &minW, &maxW, availWidth, hasbg);
 
  555            cell->
fPEnd = fPNext;
 
  557            if ((z = p->
MarkupArg(
"width", 0)) != 0) {
 
  558               for (i = 0; isdigit(z[i]) || z[i] == 
'.'; i++) {}
 
  559               if (strcmp(z, 
"*") == 0) {
 
  560                  requestedW = availWidth;
 
  561               } 
else if (z[i] == 0) {
 
  562                  requestedW = atoi(z);
 
  563               } 
else if (z[i] == 
'%') {
 
  564                  requestedW = (atoi(z) * maxTableWidth + 99) / 100;
 
  569                  (
"Row %d Column %d: min=%d max=%d req=%d stop at %s\n",
 
  570                  iRow, iCol1, minW, maxW, requestedW,
 
  575               if ((z = p->
MarkupArg(
"rowspan", 0)) == 0) { 
 
  584                  SETMAX(min0span[iCol1], minW);
 
  585                  SETMAX(max0span[iCol1], maxW);
 
  586                  min = min0span[iCol1] + separation;
 
  587               } 
else if (colspan == 1) {
 
  590                  SETMAX(reqW[iCol1], requestedW);
 
  591                  min = pStart->
fMinW[iCol1] + separation;
 
  598                  min = minW + separation;
 
  599                  for (ix = iCol1; ix < iCol1 + n2; ix++) {
 
  611                  fromAbove[i] = iRow + rowspan;
 
  626      const char *zSpace = 
"";
 
  628      for (i = 1; i <= pStart->
fNCol; i++) {
 
  629         printf(
"%s%d:%d..%d", zSpace, i, pStart->
fMinW[i], pStart->
fMaxW[i]);
 
  631            printf(
"(w=%d)", reqW[i]);
 
  636      for (i = 1; i < pStart->
fNCol; i++) {
 
  637         for (j = i+1; j <= pStart->
fNCol; j++) {
 
  640               printf(
"ColMin(%d,%d) = %d\n", i, j, 
ColMin(i, j));
 
  644               printf(
"ColReq(%d,%d) = %d\n", i, j, 
ColReq(i, j));
 
  653   for (i = 1; i <= pStart->
fNCol; i++) {
 
  654      int sumMin, sumReq, sumMax;
 
  663      if (min0span[i] > 0 || max0span[i] > 0) {
 
  664         int n2 = pStart->
fNCol - i + 1;
 
  665         minW = (min0span[i] + (n2 - 1) * (1 - separation)) / n2;
 
  666         maxW = (max0span[i] + (n2 - 1) * (1 - separation)) / n2;
 
  667         for (j = i; j <= pStart->
fNCol; j++) {
 
  679      sumMin = pStart->
fMinW[i];
 
  680      sumMax = pStart->
fMaxW[i];
 
  681      for (j = i-1; j >= 1; j--) {
 
  684         sumMin += pStart->
fMinW[j];
 
  685         sumMax += pStart->
fMaxW[j];
 
  693            int *tminW = pStart->
fMinW;
 
  694            int *tmaxW = pStart->
fMaxW;
 
  695            if (sumMin < sumMax) {
 
  696               scale = (double) (cmin - sumMin) / (double) (sumMax - sumMin);
 
  697               for (k = j; k <= i; k++) {
 
  699                  tminW[k] = (int) ((tmaxW[k] - tminW[k]) * scale + tminW[k]);
 
  702            } 
else if (sumMin > 0) {
 
  703               scale = (double) cmin / (
double) sumMin;
 
  704               for (k = j; k <= i; k++) {
 
  706                  tminW[k] = tmaxW[k] = (int) (tminW[k] * scale);
 
  710               int unit = cmin / (i - j + 1);
 
  711               for (k = j; k <= i; k++) {
 
  712                  tminW[k] = tmaxW[k] = unit;
 
  723            int *tmaxW = pStart->
fMaxW;
 
  724            if (sumReq < sumMax) {
 
  725               scale = (double) (creq - sumReq) / (double) (sumMax - sumReq);
 
  726               for (k = j; k <= i; k++) {
 
  728                  reqW[k] = (int) ((tmaxW[k] - reqW[k]) * scale + reqW[k]);
 
  731            } 
else if (sumReq > 0) {
 
  732               scale = (double) creq / (
double) sumReq;
 
  733               for (k = j; k <= i; k++) {
 
  735                  reqW[k] = (int) (reqW[k] * scale);
 
  739               int unit = creq / (i - j + 1);
 
  740               for (k = j; k <= i; k++) {
 
  751      const char *zSpace = 
"";
 
  753      for (i = 1; i <= pStart->
fNCol; i++) {
 
  754         printf(
"%s%d:%d..%d", zSpace, i, pStart->
fMinW[i], pStart->
fMaxW[i]);
 
  756            printf(
"(w=%d)", reqW[i]);
 
  767   requestedW = tbw * 2 + (
n + 1) * cellSpacing + 
n * 2 * (cellPadding + cbw);
 
  768   pStart->
fMinW[0] = requestedW;
 
  769   pStart->
fMaxW[0] = requestedW;
 
  770   for (i = 1; i <= pStart->
fNCol; i++) {
 
  773      requestedW += 
MAX(reqW[i], pStart->
fMinW[i]);
 
  781      if (len > 0 && z[len-1] == 
'%') {
 
  782         totalWidth = (atoi(z) * lineWidth) / 100;
 
  784         totalWidth = atoi(z);
 
  788      requestedW = totalWidth;
 
  790      SETMAX(requestedW, totalWidth); 
 
  794   if (lineWidth && (requestedW > lineWidth)) {
 
  797            requestedW, lineWidth));
 
  799      requestedW = lineWidth;
 
  801   if (requestedW > pStart->
fMinW[0]) {
 
  803      int *tminW = pStart->
fMinW;
 
  804      int *tmaxW = pStart->
fMaxW;
 
  807            (
"Expanding table minW from %d to %d.  (reqW=%d width=%s)\n",
 
  808             tminW[0], requestedW, requestedW, z));
 
  810      if (tmaxW[0] > tminW[0]) {
 
  811         scale = (double) (requestedW - tminW[0]) / (double) (tmaxW[0] - tminW[0]);
 
  812         for (i = 1; i <= pStart->
fNCol; i++) {
 
  813            tminW[i] += (int) ((tmaxW[i] - tminW[i]) * scale);
 
  814            SETMAX(tmaxW[i], tminW[i]);
 
  816      } 
else if (tminW[0] > 0) {
 
  817         scale = requestedW / (double) tminW[0];
 
  818         for (i = 1; i <= pStart->
fNCol; i++) {
 
  819            tminW[i] = (int) (tminW[i] * scale);
 
  820            tmaxW[i] = (int) (tmaxW[i] * scale);
 
  822      } 
else if (pStart->
fNCol > 0) {
 
  823         int unit = (requestedW - margin) / pStart->
fNCol - separation;
 
  824         if (unit < 0) unit = 0;
 
  825         for (i = 1; i <= pStart->
fNCol; i++) {
 
  826            tminW[i] = tmaxW[i] = unit;
 
  829         tminW[0] = tmaxW[0] = requestedW;
 
  831      pStart->
fMinW[0] = requestedW;
 
  841      printf(
"nCol=%d minWidth=%d maxWidth=%d\n",
 
  843      for (i = 1; i <= pStart->
fNCol; i++) {
 
  845         printf(
"Column %d minWidth=%d maxWidth=%d\n",
 
  852         (
"Result of TableDimensions: min=%d max=%d nCol=%d\n",
 
  897   for (p = p->
fPNext; go && p; p = fPNext) {
 
  949                  obstacle += image->
fW;
 
 1081#define VAlign_Unknown    0 
 1083#define VAlign_Bottom     2 
 1084#define VAlign_Center     3 
 1085#define VAlign_Baseline   4 
 1099   } 
else if (strcasecmp(z, 
"top") == 0) {
 
 1101   } 
else if (strcasecmp(z, 
"bottom") == 0) {
 
 1103   } 
else if (strcasecmp(z, 
"center") == 0) {
 
 1105   } 
else if (strcasecmp(z, 
"baseline") == 0) {
 
 1147#define N (HTML_MAX_COLUMNS+1) 
 1158#ifdef TABLE_TRIM_BLANK 
 1159   extern int HtmlLineWasBlank;
 
 1168   for (i=0;i<
N;i++) 
ymax[i]=0;
 
 1178                           btm, left_margin, lineWidth));
 
 1188   if (lineWidth < pTable->fMinW[0]) {
 
 1192                             btm, left_margin, lineWidth));
 
 1194   savedContext = *
this;
 
 1199      int len = strlen(z);
 
 1200      if (len > 0 && z[len-1] == 
'%') {
 
 1201         specWidth = (atoi(z) * lineWidth) / 100;
 
 1203         specWidth = atoi(z);
 
 1206      specWidth = lineWidth;
 
 1208   if (specWidth < pTable->fMinW[0]) {
 
 1210   } 
else if (specWidth <= pTable->fMaxW[0]) {
 
 1219   z = pTable->
MarkupArg(
"cellpadding", 0);
 
 1233      if (vspace < 2) vspace = 2;
 
 1240   pad = cellPadding + cbw;
 
 1241   separation = cellSpacing + 2 * pad;
 
 1242   x[1] = left_margin + tbw + cellSpacing + pad;
 
 1245   if (n <= 0 || pTable->fMaxW[0] <= 0) {
 
 1251   zAlign = pTable->
MarkupArg(
"align", 
"");
 
 1252   if (
width <= lineWidth) {
 
 1254      if (align == 
ALIGN_Right || strcasecmp(zAlign, 
"right") == 0) {
 
 1255         x[1] += lineWidth - 
width;
 
 1256      } 
else if (align == 
ALIGN_Center && strcasecmp(zAlign, 
"left") != 0) {
 
 1257         x[1] += (lineWidth - 
width) / 2;
 
 1262      w[1] = pTable->
fMaxW[1];
 
 1263      for (i = 2; i <= 
n; i++) {
 
 1264         w[i] = pTable->
fMaxW[i];
 
 1265         x[i] = 
x[i-1] + w[i-1] + separation;
 
 1268      int *tmaxW = pTable->
fMaxW;
 
 1269      double scale = ((double) 
width) / (double) tmaxW[0];
 
 1270      w[1] = (int) (tmaxW[1] * scale);
 
 1271      for (i = 2; i <= 
n; i++) {
 
 1272         w[i] = (int) (tmaxW[i] * scale);
 
 1273         x[i] = 
x[i-1] + w[i-1] + separation;
 
 1277      int *tminW = pTable->
fMinW;
 
 1278      int *tmaxW = pTable->
fMaxW;
 
 1279      scale = (double) (
width - tminW[0]) / (double) (tmaxW[0] - tminW[0]);
 
 1280      w[1] = (int) (tminW[1] + (tmaxW[1] - tminW[1]) * scale);
 
 1281      for (i = 2; i <= 
n; i++) {
 
 1282         w[i] = (int) (tminW[i] + (tmaxW[i] - tminW[i]) * scale);
 
 1283         x[i] = 
x[i-1] + w[i-1] + separation;
 
 1286      w[1] = pTable->
fMinW[1];
 
 1287      for (i = 2; i <= 
n; i++) {
 
 1288         w[i] = pTable->
fMinW[i];
 
 1289         x[i] = 
x[i-1] + w[i-1] + separation;
 
 1292   w[
n] = 
width - ((
x[
n] - 
x[1]) + 2 * (tbw + pad + cellSpacing));
 
 1299   pTable->
fX = 
x[1] - (tbw + cellSpacing + pad);
 
 1302   btm += tbw + cellSpacing;
 
 1305   for (i = 1; i <= 
n; i++) {
 
 1312   for (iRow = 1; iRow <= pTable->
fNRow; iRow++) {
 
 1336         if (lastRow[iCol] < iRow) 
ymax[iCol] = 0;
 
 1354                     (
"Column %d: x=%d w=%d\n",iCol,
x[iCol],w[iCol]));
 
 1361                  fPNext = cell->
fPEnd;
 
 1363                     lastRow[iCol] = pTable->
fNRow;
 
 1365                     lastRow[iCol] = iRow + cell->
fRowspan - 1;
 
 1373                  y[iCol] = btm + pad;
 
 1376                  cellContext.
fPEnd     = fPNext;
 
 1378                  cellContext.
fTop      = 
y[iCol];
 
 1380                  cellContext.
fLeft     = 
x[iCol];
 
 1388                        lastRow[i] = lastRow[iCol];
 
 1390                  } 
else if (colspan > 1) {
 
 1394                        lastRow[i] = lastRow[iCol];
 
 1397                  cellContext.
fMaxX = 0;
 
 1398                  cellContext.
fMaxY = 0;
 
 1402#ifdef TABLE_TRIM_BLANK 
 1405                  if (HtmlLineWasBlank) {
 
 1406                     cellContext.
fMaxY -= cellContext.headRoom;
 
 1415                  cell->
fX = 
x[iCol] - pad;
 
 1420                        (
"Column %d top=%d bottom=%d h=%d left=%d w=%d\n",
 
 1421                        iCol, 
y[iCol], 
ymax[iCol], 
ymax[iCol]-
y[iCol],
 
 1422                        cell->
fX, cell->
fW));
 
 1426                     iCol += colspan - 1;
 
 1427                  } 
else if (colspan == 0) {
 
 1446      for (iCol = 1; iCol <= pTable->
fNCol; iCol++) {
 
 1447         if (lastRow[iCol] == iRow || iRow == pTable->
fNRow) {
 
 1453                             btm,rowBottom,rowBottom-btm));
 
 1456      for (iCol = 1; iCol <= pTable->
fNCol; iCol++) {
 
 1462         if (apElem[iCol] == 0 ||
 
 1463             (iRow != pTable->
fNRow && lastRow[iCol] > iRow)) 
continue;
 
 1466            switch (valign[iCol]) {
 
 1469                  dy = (rowBottom - 
ymax[iCol])/2;
 
 1476                  dy = rowBottom - 
ymax[iCol];
 
 1488            apCell->
fH = rowBottom + pad - apCell->
fY;
 
 1493         btm = rowBottom + pad + cellSpacing;
 
 1497      pTable->
fH = btm - pTable->
fY;
 
 1512      if (strcasecmp(zAlign, 
"left") == 0) {
 
 1515         *
this = savedContext;
 
 1517      } 
else if (strcasecmp(zAlign, 
"right") == 0) {
 
 1520         *
this = savedContext;
 
 1527            "Done with TableLayout().  x=%d y=%d w=%d h=%d Return %s\n",
 
 1528            pTable->
fX, pTable->
fY, pTable->
fW, pTable->
fH,
 
 1544   if (dy == 0) 
return;
 
 1546   while (p && p != pLast1) {
 
static const double x2[5]
 
static const double x1[5]
 
static const double x3[11]
 
static void indent(ostringstream &buf, int indent_level)
 
include TDocParser_001 C image html pict1_TDocParser_001 png width
 
#define DFLT_CELLSPACING_FLAT
 
#define DFLT_CELLSPACING_3D
 
#define HTML_RELIEF_SUNKEN
 
#define HTML_RELIEF_RAISED
 
#define IMAGE_ALIGN_Right
 
#define TRACE(Flag, Args)
 
virtual int GetVerticalAlignment(int dflt)
 
virtual const char * MarkupArg(const char *, const char *)
 
void ComputeMargins(int *pX, int *pY, int *pW)
Compute the current margins for layout.
 
TGHtmlElement * TableLayout(TGHtmlTable *p)
Do all layout for a single table.
 
void LayoutBlock()
Do as much layout as possible on the block of text defined by the HtmlLayoutContext.
 
SHtmlMargin_t * fRightMargin
 
void PushMargin(SHtmlMargin_t **ppMargin, int indent, int bottom, int tag)
Push a new margin onto the given margin stack.
 
void ClearMarginStack(SHtmlMargin_t **ppMargin)
Clear a margin stack to reclaim memory.
 
void WidenLine(int reqWidth, int *pX, int *pY, int *pW)
Move past obstacles until a linewidth of reqWidth is obtained, or until all obstacles are cleared.
 
SHtmlMargin_t * fLeftMargin
 
virtual int GetVerticalAlignment(int dflt)
Return the vertical alignment specified by the given element.
 
virtual const char * MarkupArg(const char *tag, const char *zDefault)
Lookup an argument in the given markup with the name given.
 
int fMinW[HTML_MAX_COLUMNS+1]
 
int fMaxW[HTML_MAX_COLUMNS+1]
 
void MoveVertically(TGHtmlElement *p, TGHtmlElement *pLast, int dy)
Move all elements in the given list vertically by the amount dy.
 
TGHtmlElement * MinMax(TGHtmlElement *p, int *pMin, int *pMax, int lineWidth, int hasbg)
Given a list of elements, compute the minimum and maximum width needed to render the list.
 
void StringHW(const char *str, int *h, int *w)
Return the height and width of string.
 
int CellSpacing(TGHtmlElement *pTable)
Return the appropriate cell spacing for the given table.
 
void AppendArglist(TGString *str, TGHtmlMarkupElement *pElem)
Append all the arguments of the given markup to the given TGString.
 
TGString * TableText(TGHtmlTable *pTable, int flags)
Return text and images from a table as lists.
 
TGHtmlElement * FindEndNest(TGHtmlElement *sp, int en, TGHtmlElement *lp)
Find End tag en, but ignore intervening begin/end tag pairs.
 
char * GetTokenName(TGHtmlElement *p)
Returns token name of html element p.
 
TGHtmlElement * TableDimensions(TGHtmlTable *pStart, int lineWidth)
pStart points to a
 
const char * GetString() const
 
const char * Data() const
 
TString & Append(const char *cs)