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))
53 int TGHtml::CellSpacing(TGHtmlElement *pTable)
59 z = pTable->MarkupArg(
"cellspacing", 0);
61 relief = fTableRelief;
62 if (relief == HTML_RELIEF_RAISED || relief == HTML_RELIEF_SUNKEN) {
63 cellSpacing = DFLT_CELLSPACING_3D;
65 cellSpacing = DFLT_CELLSPACING_FLAT;
68 cellSpacing = atoi(z);
77 void TGHtml::StringHW(
const char *str,
int *h,
int *w)
80 int nw = 0, nh = 1, mw = 0;
108 TGString *TGHtml::TableText(TGHtmlTable *pTable,
int flag)
121 unsigned short maxw[HTML_MAX_COLUMNS];
122 short rspans[HTML_MAX_COLUMNS];
125 TGHtmlElement *p, *pEnd;
129 TGString attrstr(
"");
131 TGString *str =
new TGString(
"");
133 if (pTable->fType != Html_TABLE)
return str;
134 if (!(pEnd = pTable->fPEnd)) {
141 attrstr.Append(
"{ ");
142 AppendArglist(&attrstr, pTable);
143 attrstr.Append(
"} ");
145 for (j = 0; j < HTML_MAX_COLUMNS; j++) {
152 while (p && (p = p->fPNext)) {
165 if (!(p = FindEndNest(p, Html_EndTABLE, 0))) {
176 if (cols > numcols) numcols = cols;
183 attrstr.Append(
"{ { ");
184 AppendArglist(&attrstr, (TGHtmlMarkupElement *) p);
185 attrstr.Append(
"} ");
190 snprintf(buf, 100,
"%d ", maxh);
193 attrstr.Append(
"} ");
203 if ((!(cp = p->MarkupArg(
"colspan", 0))) || (cspans = atoi(cp)) <= 0) {
206 if ((cp = p->MarkupArg(
"rowspan", 0)) && (j = atoi(cp)) > 0 &&
207 cols < HTML_MAX_COLUMNS) {
215 while ((cspans - j) > 0) {
216 attrstr.Append(
"{ ");
217 if (!j) AppendArglist(&attrstr, (TGHtmlMarkupElement *) p);
218 attrstr.Append(
"} ");
229 while (cols <= HTML_MAX_COLUMNS && rspans[cols-1]-- > 1) {
234 cp = substr.GetString();
237 while ((cspans - j) > 0) {
241 StringHW(cp, &h, &w);
242 if (h > maxh) maxh = h;
243 if (cols > 0 && cols <= HTML_MAX_COLUMNS) {
244 if (w > maxw[cols-1]) {
256 substr.Append(((TGHtmlTextElement *)p)->fZText);
260 for (j = 0; j < p->fCount; j++) {
272 if (!(pEnd = FindEndNest(p, Html_EndCAPTION, 0))) {
279 snprintf(buf,
sizeof(buf),
"%d %d %d %d ", rows-1, cols-1,
280 substr.GetLength(), p->fElId);
286 while (nest--) str->Append(
"} ");
288 for (j = 0; j < numcols && j < HTML_MAX_COLUMNS; j++) {
289 snprintf(buf,
sizeof(buf),
"%d ", maxw[j]);
294 str->Append(istr.Data());
298 str->Append(attrstr.Data());
302 str->Append(imgstr.Data());
315 TGHtmlElement *TGHtml::FindEndNest(TGHtmlElement *sp,
int en,
326 if (p == lp)
return 0;
328 if (p->fType == Html_LI || p->fType == Html_EndUL ||
329 p->fType == Html_EndOL) {
330 if (p->fPPrev)
return p->fPPrev;
333 }
else if (p->fType == n) {
334 if (n == Html_OPTION) {
335 if (p->fPPrev)
return p->fPPrev;
339 }
else if (p->fType == en) {
340 if (!lvl--)
return p;
343 case Html_TABLE: p = ((TGHtmlTable *)p)->fPEnd;
break;
344 case Html_FORM: p = ((TGHtmlForm *)p)->fPEnd;
break;
345 default: p = p->fPNext;
374 TGHtmlElement *TGHtml::TableDimensions(TGHtmlTable *pStart,
int lineWidth)
377 TGHtmlElement *fPNext;
380 TGHtmlElement *inRow = 0;
383 int minW, maxW, requestedW;
397 int fromAbove[HTML_MAX_COLUMNS+1]={0};
398 int min0span[HTML_MAX_COLUMNS+1]={0};
399 int max0span[HTML_MAX_COLUMNS+1]={0};
400 int reqW[HTML_MAX_COLUMNS+1]={0};
408 int colMin[HTML_MAX_COLUMNS+1][HTML_MAX_COLUMNS+1];
409 # define ColMin(A,B) colMin[(A)-1][(B)-1]
410 # define ColReq(A,B) colMin[(B)-1][(A)-1]
412 if (pStart == 0 || pStart->fType != Html_TABLE)
return pStart;
414 if (pStart->fBgImage) pStart->fHasbg = 1;
416 TRACE_PUSH(HtmlTrace_Table1);
417 TRACE(HtmlTrace_Table1, (
"Starting TableDimensions... %s\n",
418 pStart->MarkupArg(
"name",
"")));
423 z = pStart->MarkupArg(
"border", 0);
424 if (z && *z == 0) z =
"2";
426 tbw = z ? atoi(z) : DFLT_BORDER;
427 if (fTableBorderMin && tbw < fTableBorderMin) tbw = fTableBorderMin;
428 pStart->fBorderWidth = tbw;
432 z = pStart->MarkupArg(
"cellpadding", 0);
433 cellPadding = z ? atoi(z) : DFLT_CELLPADDING;
434 cellSpacing = CellSpacing(pStart);
440 if (HtmlTraceMask & HtmlTrace_Table4) {
441 tbw = pStart->fBorderWidth = 2;
445 pStart->fStyle.fBgcolor = COLOR_Background;
449 separation = cellSpacing + 2 * (cellPadding + cbw);
450 margin = tbw + cellSpacing + cbw + cellPadding;
452 z = pStart->MarkupArg(
"hspace", 0);
456 z = pStart->MarkupArg(
"width", 0);
459 if (len > 0 && z[len-1] ==
'%') {
460 maxTableWidth = (atoi(z) * lineWidth) / 100;
462 maxTableWidth = atoi(z);
465 maxTableWidth = lineWidth;
467 maxTableWidth -= 2 * margin;
468 SETMAX(maxTableWidth, 1);
470 TRACE(HtmlTrace_Table1, (
"lineWidth = %d, maxTableWidth = %d, margin = %d\n",
471 lineWidth, maxTableWidth, margin));
473 for (p = pStart->fPNext; p; p = fPNext) {
474 if (p->fType == Html_EndTABLE) {
475 ((TGHtmlRef *)p)->fPOther = pStart;
486 ((TGHtmlRef *)p)->fPOther = pStart;
491 ((TGHtmlRef *)p)->fPOther = pStart;
496 ((TGHtmlRef *)p)->fPOther = pStart;
501 availWidth = maxTableWidth;
505 while (p && p->fType != Html_EndTABLE
506 && p->fType != Html_EndCAPTION) p = p->fPNext;
511 TGHtmlCell *cell = (TGHtmlCell *) p;
515 TGHtmlElement *pNew =
new TGHtmlRef(Html_TR, 1, 0, 0);
516 if (pNew == 0)
break;
519 pNew->fStyle = p->fStyle;
520 pNew->fFlags = p->fFlags;
522 p->fPPrev->fPNext = pNew;
529 }
while (iCol1 <= pStart->fNCol && fromAbove[iCol1] > iRow);
530 cell->fPTable = pStart;
532 colspan = cell->fColspan;
533 if (colspan == 0) colspan = 1;
534 if (iCol1 + colspan - 1 > pStart->fNCol) {
535 int nCol = iCol1 + colspan - 1;
536 if (nCol > HTML_MAX_COLUMNS) nCol = HTML_MAX_COLUMNS;
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);
552 hasbg = (pStart->fHasbg || ((TGHtmlRef *)cell->fPRow)->fBgImage ||
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;
568 TRACE(HtmlTrace_Table1,
569 (
"Row %d Column %d: min=%d max=%d req=%d stop at %s\n",
570 iRow, iCol1, minW, maxW, requestedW,
571 GetTokenName(((TGHtmlCell *)p)->fPEnd)));
575 if ((z = p->MarkupArg(
"rowspan", 0)) == 0) {
581 if (iCol1 + cell->fColspan <= HTML_MAX_COLUMNS) {
583 if (cell->fColspan == 0) {
584 SETMAX(min0span[iCol1], minW);
585 SETMAX(max0span[iCol1], maxW);
586 min = min0span[iCol1] + separation;
587 }
else if (colspan == 1) {
588 SETMAX(pStart->fMinW[iCol1], minW);
589 SETMAX(pStart->fMaxW[iCol1], maxW);
590 SETMAX(reqW[iCol1], requestedW);
591 min = pStart->fMinW[iCol1] + separation;
593 int n2 = cell->fColspan;
596 SETMAX(ColMin(iCol1, iCol1+n2-1), minW);
597 SETMAX(ColReq(iCol1, iCol1+n2-1), requestedW);
598 min = minW + separation;
599 for (ix = iCol1; ix < iCol1 + n2; ix++) {
601 SETMAX(pStart->fMaxW[ix], per);
607 rowspan = cell->fRowspan;
608 if (rowspan == 0) rowspan = LARGE_NUMBER;
610 for (i = iCol1; i < iCol1 + cell->fColspan && i < HTML_MAX_COLUMNS; i++) {
611 fromAbove[i] = iRow + rowspan;
614 if (cell->fColspan > 1) {
615 iCol1 += cell->fColspan - 1;
616 }
else if (cell->fColspan == 0) {
617 iCol1 = HTML_MAX_COLUMNS + 1;
625 if (HtmlTraceMask & HtmlTrace_Table6) {
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++) {
638 if (ColMin(i, j) > 0) {
640 printf(
"ColMin(%d,%d) = %d\n", i, j, ColMin(i, j));
642 if (ColReq(i, j) > 0) {
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;
658 pStart->fMaxW[i] = MAX(pStart->fMinW[i], reqW[i]);
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++) {
668 SETMAX(pStart->fMinW[j], minW);
669 SETMAX(pStart->fMaxW[j], maxW);
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++) {
750 if (HtmlTraceMask & HtmlTrace_Table6) {
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++) {
771 pStart->fMinW[0] += pStart->fMinW[i];
772 pStart->fMaxW[0] += pStart->fMaxW[i];
773 requestedW += MAX(reqW[i], pStart->fMinW[i]);
777 z = pStart->MarkupArg(
"width", 0);
781 if (len > 0 && z[len-1] ==
'%') {
782 totalWidth = (atoi(z) * lineWidth) / 100;
784 totalWidth = atoi(z);
786 SETMAX(totalWidth, pStart->fMinW[0]);
788 requestedW = totalWidth;
790 SETMAX(requestedW, totalWidth);
793 SETMAX(maxTableWidth, pStart->fMinW[0]);
794 if (lineWidth && (requestedW > lineWidth)) {
796 TRACE(HtmlTrace_Table5, (
"RequestedW reduced to lineWidth: %d -> %d\n",
797 requestedW, lineWidth));
799 requestedW = lineWidth;
801 if (requestedW > pStart->fMinW[0]) {
803 int *tminW = pStart->fMinW;
804 int *tmaxW = pStart->fMaxW;
806 TRACE(HtmlTrace_Table5,
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;
832 SETMAX(pStart->fMaxW[0], requestedW);
836 if (HtmlTraceMask & HtmlTrace_Table5) {
838 printf(
"Start with %s and ", GetTokenName(pStart));
839 printf(
"end with %s\n", GetTokenName(p));
841 printf(
"nCol=%d minWidth=%d maxWidth=%d\n",
842 pStart->fNCol, pStart->fMinW[0], pStart->fMaxW[0]);
843 for (i = 1; i <= pStart->fNCol; i++) {
845 printf(
"Column %d minWidth=%d maxWidth=%d\n",
846 i, pStart->fMinW[i], pStart->fMaxW[i]);
851 TRACE(HtmlTrace_Table1,
852 (
"Result of TableDimensions: min=%d max=%d nCol=%d\n",
853 pStart->fMinW[0], pStart->fMaxW[0], pStart->fNCol));
854 TRACE_POP(HtmlTrace_Table1);
878 TGHtmlElement *TGHtml::MinMax(TGHtmlElement *p,
int *pMin,
int *pMax,
890 TGHtmlElement *fPNext;
893 if (p->MarkupArg(
"nowrap", 0) != 0) {
894 wstyle |= STY_NoBreak;
897 for (p = p->fPNext; go && p; p = fPNext) {
910 TGHtmlTextElement *text = (TGHtmlTextElement *) p;
914 if (p->fStyle.fFlags & STY_Preformatted) {
924 TGHtmlSpaceElement *space = (TGHtmlSpaceElement *) p;
925 p->fStyle.fFlags |= wstyle;
926 if (p->fStyle.fFlags & STY_Preformatted) {
927 if (p->fFlags & HTML_NewLine) {
928 x1 = x2 = x3 = indent;
930 x1 += space->fW * p->fCount;
931 x2 += space->fW * p->fCount;
932 x3 += space->fW * p->fCount;
934 }
else if (p->fStyle.fFlags & STY_NoBreak) {
935 if (x1 > indent) x1 += space->fW;
936 if (x2 > indent) x2 += space->fW;
938 if (x1 > indent) x1 += space->fW;
945 TGHtmlImageMarkup *image = (TGHtmlImageMarkup *) p;
946 switch (image->fAlign) {
947 case IMAGE_ALIGN_Left:
948 case IMAGE_ALIGN_Right:
949 obstacle += image->fW;
950 x1 = obstacle + indent;
953 SETMAX(min, image->fW);
960 if (p->fStyle.fFlags & STY_Preformatted) {
973 TGHtmlTable *table = (TGHtmlTable *) p;
975 table->fHasbg = hasbg;
976 fPNext = TableDimensions(table, 0);
977 x1 = table->fMaxW[0] + indent + obstacle;
978 x2 = table->fMinW[0] + indent;
981 x1 = indent + obstacle;
983 if (fPNext && fPNext->fType == Html_EndTABLE) fPNext = fPNext->fPNext;
989 indent += HTML_INDENT;
990 x1 = indent + obstacle;
996 indent -= HTML_INDENT;
997 if (indent < 0) indent = 0;
998 x1 = indent + obstacle;
1002 case Html_BLOCKQUOTE:
1003 indent += 2 * HTML_INDENT;
1004 x1 = indent + obstacle;
1008 case Html_EndBLOCKQUOTE:
1009 indent -= 2 * HTML_INDENT;
1010 if (indent < 0) indent = 0;
1011 x1 = indent + obstacle;
1019 case Html_TEXTAREA: {
1020 TGHtmlInput *input = (TGHtmlInput *) p;
1021 x1 += input->fW + input->fPadLeft;
1022 if (p->fStyle.fFlags & STY_Preformatted) {
1023 x3 += input->fW + input->fPadLeft;
1026 x2 += input->fW + input->fPadLeft;
1028 SETMAX(min, indent + input->fW);
1050 x1 = indent + obstacle;
1081 #define VAlign_Unknown 0
1082 #define VAlign_Top 1
1083 #define VAlign_Bottom 2
1084 #define VAlign_Center 3
1085 #define VAlign_Baseline 4
1091 int TGHtmlMarkupElement::GetVerticalAlignment(
int dflt)
1096 z = MarkupArg(
"valign", 0);
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) {
1106 rc = VAlign_Baseline;
1118 TGHtmlElement *TGHtmlLayoutContext::TableLayout(TGHtmlTable *pTable)
1120 TGHtmlElement *pEnd1;
1122 TGHtmlElement *fPNext;
1123 TGHtmlElement *pCaption=0;
1147 #define N (HTML_MAX_COLUMNS+1)
1152 TGHtmlElement *apElem[N]={0};
1156 TGHtmlLayoutContext savedContext;
1157 TGHtmlLayoutContext cellContext;
1158 #ifdef TABLE_TRIM_BLANK
1159 extern int HtmlLineWasBlank;
1160 #endif // TABLE_TRIM_BLANK
1162 if (pTable == 0 || pTable->fType != Html_TABLE)
return pTable;
1164 TRACE_PUSH(HtmlTrace_Table2);
1165 TRACE(HtmlTrace_Table2, (
"Starting TableLayout() at %s\n",
1166 fHtml->GetTokenName(pTable)));
1168 for (i=0;i<N;i++) ymax[i]=0;
1175 ComputeMargins(&left_margin, &btm, &lineWidth);
1177 TRACE(HtmlTrace_Table2, (
"...btm=%d left=%d width=%d\n",
1178 btm, left_margin, lineWidth));
1182 pEnd1 = fHtml->TableDimensions(pTable, lineWidth);
1188 if (lineWidth < pTable->fMinW[0]) {
1189 WidenLine(pTable->fMinW[0], &left_margin, &btm, &lineWidth);
1191 TRACE(HtmlTrace_Table2, (
"Widen to btm=%d left=%d width=%d\n",
1192 btm, left_margin, lineWidth));
1194 savedContext = *
this;
1197 z = pTable->MarkupArg(
"width", 0);
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]) {
1209 width = pTable->fMinW[0];
1210 }
else if (specWidth <= pTable->fMaxW[0]) {
1213 width = pTable->fMaxW[0];
1219 z = pTable->MarkupArg(
"cellpadding", 0);
1220 cellPadding = z ? atoi(z) : DFLT_CELLPADDING;
1221 cellSpacing = fHtml->CellSpacing(pTable);
1223 z = pTable->MarkupArg(
"vspace", 0);
1224 vspace = z ? atoi(z) : DFLT_VSPACE;
1226 z = pTable->MarkupArg(
"hspace", 0);
1230 if (HtmlTraceMask & HtmlTrace_Table4) {
1233 if (vspace < 2) vspace = 2;
1238 tbw = pTable->fBorderWidth;
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) {
1253 int align = pTable->fStyle.fAlign;
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;
1261 if (width == pTable->fMaxW[0]) {
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;
1267 }
else if (width > pTable->fMaxW[0]) {
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;
1275 }
else if (width > pTable->fMinW[0]) {
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);
1301 SETMAX(fMaxX, pTable->fX + pTable->fW);
1302 btm += tbw + cellSpacing;
1305 for (i = 1; i <= n; i++) {
1312 for (iRow = 1; iRow <= pTable->fNRow; iRow++) {
1314 TRACE(HtmlTrace_Table2, (
"Row %d: btm=%d\n",iRow,btm));
1318 while (p && p->fType != Html_TR) {
1319 if (p->fType == Html_CAPTION) {
1321 while (p && p != pEnd1 && p->fType != Html_EndCAPTION) p = p->fPNext;
1325 TRACE(HtmlTrace_Table3, (
"Skipping token %s\n", fHtml->GetTokenName(p)));
1327 if (p) p = p->fPNext;
1332 defaultVAlign = p->GetVerticalAlignment(VAlign_Center);
1335 for (iCol = 1; iCol <= pTable->fNCol && iCol <= HTML_MAX_COLUMNS; iCol++) {
1336 if (lastRow[iCol] < iRow) ymax[iCol] = 0;
1339 for (p = p->fPNext; p && p->fType != Html_TR && p != pEnd1; p = fPNext) {
1342 TRACE(HtmlTrace_Table3, (
"Processing token %s\n", fHtml->GetTokenName(p)));
1351 }
while (iCol <= HTML_MAX_COLUMNS && lastRow[iCol] >= iRow);
1353 TRACE(HtmlTrace_Table2,
1354 (
"Column %d: x=%d w=%d\n",iCol,x[iCol],w[iCol]));
1358 if (iCol <= HTML_MAX_COLUMNS) {
1359 TGHtmlCell *cell = (TGHtmlCell *) p;
1361 fPNext = cell->fPEnd;
1362 if (cell->fRowspan == 0) {
1363 lastRow[iCol] = pTable->fNRow;
1365 lastRow[iCol] = iRow + cell->fRowspan - 1;
1370 valign[iCol] = p->GetVerticalAlignment(defaultVAlign);
1373 y[iCol] = btm + pad;
1374 cellContext.fHtml = fHtml;
1375 cellContext.fPStart = p->fPNext;
1376 cellContext.fPEnd = fPNext;
1377 cellContext.fHeadRoom = 0;
1378 cellContext.fTop = y[iCol];
1379 cellContext.fBottom = y[iCol];
1380 cellContext.fLeft = x[iCol];
1381 cellContext.fRight = 0;
1382 cellContext.fPageWidth = x[iCol] + w[iCol];
1383 colspan = cell->fColspan;
1386 i <= pTable->fNCol && i <= HTML_MAX_COLUMNS; i++) {
1387 cellContext.fPageWidth += w[i] + separation;
1388 lastRow[i] = lastRow[iCol];
1390 }
else if (colspan > 1) {
1392 i < iCol + colspan && i <= HTML_MAX_COLUMNS; i++) {
1393 cellContext.fPageWidth += w[i] + separation;
1394 lastRow[i] = lastRow[iCol];
1397 cellContext.fMaxX = 0;
1398 cellContext.fMaxY = 0;
1399 cellContext.fLeftMargin = 0;
1400 cellContext.fRightMargin = 0;
1401 cellContext.LayoutBlock();
1402 #ifdef TABLE_TRIM_BLANK
1405 if (HtmlLineWasBlank) {
1406 cellContext.fMaxY -= cellContext.headRoom;
1408 #endif // TABLE_TRIM_BLANK
1409 ymax[iCol] = cellContext.fMaxY;
1410 SETMAX(ymax[iCol], y[iCol]);
1411 cellContext.ClearMarginStack(&cellContext.fLeftMargin);
1412 cellContext.ClearMarginStack(&cellContext.fRightMargin);
1415 cell->fX = x[iCol] - pad;
1417 cell->fW = cellContext.fPageWidth + 2 * pad - x[iCol];
1419 TRACE(HtmlTrace_Table2,
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) {
1428 iCol = HTML_MAX_COLUMNS + 1;
1437 while (fPNext && fPNext != pEnd1 && fPNext->fType != Html_EndCAPTION) {
1438 fPNext = fPNext->fPNext;
1446 for (iCol = 1; iCol <= pTable->fNCol; iCol++) {
1447 if (lastRow[iCol] == iRow || iRow == pTable->fNRow) {
1448 SETMAX(rowBottom, ymax[iCol]);
1452 TRACE(HtmlTrace_Table2, (
"Total row height: %d..%d -> %d\n",
1453 btm,rowBottom,rowBottom-btm));
1456 for (iCol = 1; iCol <= pTable->fNCol; iCol++) {
1458 TGHtmlCell *apCell = (TGHtmlCell *) apElem[iCol];
1462 if (apElem[iCol] == 0 ||
1463 (iRow != pTable->fNRow && lastRow[iCol] > iRow))
continue;
1466 switch (valign[iCol]) {
1467 case VAlign_Unknown:
1469 dy = (rowBottom - ymax[iCol])/2;
1472 case VAlign_Baseline:
1476 dy = rowBottom - ymax[iCol];
1480 TGHtmlElement *pLast = apCell->fPEnd;
1482 TRACE(HtmlTrace_Table3, (
"Delta column %d by %d\n",iCol,dy));
1484 fHtml->MoveVertically(apElem[iCol]->fPNext, pLast, dy);
1488 apCell->fH = rowBottom + pad - apCell->fY;
1493 btm = rowBottom + pad + cellSpacing;
1497 pTable->fH = btm - pTable->fY;
1499 fBottom = btm + vspace;
1507 fHtml->ResetBlocks();
1512 if (strcasecmp(zAlign,
"left") == 0) {
1513 savedContext.fMaxX = fMaxX;
1514 savedContext.fMaxY = fMaxY;
1515 *
this = savedContext;
1516 PushMargin(&fLeftMargin, pTable->fW + 2, pTable->fY + pTable->fH + 2, 0);
1517 }
else if (strcasecmp(zAlign,
"right") == 0) {
1518 savedContext.fMaxX = fMaxX;
1519 savedContext.fMaxY = fMaxY;
1520 *
this = savedContext;
1521 PushMargin(&fRightMargin, pTable->fW + 2, pTable->fY + pTable->fH + 2, 0);
1526 TRACE(HtmlTrace_Table2, (
1527 "Done with TableLayout(). x=%d y=%d w=%d h=%d Return %s\n",
1528 pTable->fX, pTable->fY, pTable->fW, pTable->fH,
1529 fHtml->GetTokenName(pEnd1)));
1530 TRACE_POP(HtmlTrace_Table2);
1542 void TGHtml::MoveVertically(TGHtmlElement *p, TGHtmlElement *pLast1,
int dy)
1544 if (dy == 0)
return;
1546 while (p && p != pLast1) {
1549 ((TGHtmlAnchor *)p)->fY += dy;
1553 ((TGHtmlTextElement *)p)->fY += dy;
1557 ((TGHtmlLi *)p)->fY += dy;
1562 ((TGHtmlCell *)p)->fY += dy;
1566 ((TGHtmlTable *)p)->fY += dy;
1570 ((TGHtmlImageMarkup *)p)->fY += dy;
1578 ((TGHtmlInput *)p)->fY += dy;