</TABLE>
-
-
-
-
-
+<p>
+</p>
+
+<hr size="8"/>
+
+
+
+<table cellspacing='0' cellpadding='0'>
+ <tr align='left'>
+ <td width="30%" valign='top'>Error:</td>
+ <td width='5'></td>
+ <td>Sex sells better than <b>truth and honour</b></td><td align='right'>X For President is my agenda!</td>
+ </tr>
+ <tr align='left'>
+ <td valign='top'>Command:</td>
+ <td width='5'></td>
+ <td>Go out and spread the word, <b>we shall prevail!</b></td><td>X</td>
+ </tr>
+</table>
+<br><br>
+<table cellspacing='0' cellpadding='0'>
+ <tr align='left'>
+ <td valign='top'>Error:</td>
+ <td width='5'></td>
+ <td>Sex sells better than <b>truth and honour</b></td><td align='right'>X For President is my agenda!</td>
+ </tr>
+ <tr align='left'>
+ <td valign='top'>Command:</td>
+ <td width='5'></td>
+ <td>Go out and spread the word, <b>we shall prevail!</b></td><td>X</td>
+ </tr>
+</table>
+<br><br>
+<table width="200" cellspacing='0' cellpadding='0'>
+ <tr align='left'>
+ <td valign='top'>Error:</td>
+ <td width='5'></td>
+ <td nowrap>Sex sells better than <b>truth and honour</b></td><td align='right'>X For President is my agenda!</td>
+ </tr>
+ <tr align='left'>
+ <td valign='top'>Command:</td>
+ <td width='5'></td>
+ <td>Go out and spread the word, <b>we shall prevail!</b></td><td>X</td>
+ </tr>
+</table>
+<br><br>
+<table cellspacing='0' cellpadding='0'>
+ <tr align='left'>
+ <td valign='top'>Error:</td>
+ <td width='5'></td>
+ <td>
+ <table cellspacing='0' cellpadding='0'>
+ <tr align='left'>
+ <td valign='top'>Error:</td>
+ <td width='5'></td>
+ <td>Sex sells better than <b>truth and honour</b></td><td align='right'>X For President is my agenda!</td>
+ </tr>
+ <tr align='left'>
+ <td valign='top'>Command:</td>
+ <td width='5'></td>
+ <td>Go out and spread the word, <b>we shall prevail!</b></td>
+ <td>X</td>
+ </tr>
+ </table>
+ </td>
+ <td align='right'>X For President is my agenda!</td>
+ </tr>
+ <tr align='left'>
+ <td valign='top'>Command:</td>
+ <td width='5'></td>
+ <td>Go out and spread the word, <b>we shall prevail!</b></td>
+ <td>X</td>
+ </tr>
+</table>
+<br><br>
+<table cellspacing='0' cellpadding='0'>
+ <tr>
+ <td><ul><li>Just a small test</li></ul></td>
+ <td>Really, a test!</td>
+ </tr>
+</table>
#ifndef WXPRECOMP
#endif
-
-/*
-REMARKS:
- 1. This version of m_tables doesn't support auto-layout algorithm.
- This means that all columns are of same width unless explicitly specified.
-*/
-
-
#include "wx/html/forcelnk.h"
#include "wx/html/m_templ.h"
int colspan, rowspan;
int minheight, valign;
cellState flag;
+ bool nowrap;
};
else m_CellInfo[r][c].valign = wxHTML_ALIGN_CENTER;
}
+ // nowrap
+ if (tag.HasParam(wxT("NOWRAP")))
+ m_CellInfo[r][c].nowrap = true;
+ else
+ m_CellInfo[r][c].nowrap = false;
+
cell->SetIndent(m_Padding, wxHTML_INDENT_ALL, wxHTML_UNITS_PIXELS);
}
{
if (m_NumCols == 0 || m_ColsInfo[0].minWidth != -1) return;
+ m_MaxTotalWidth = 0;
+ int percentage = 0;
for (int c = 0; c < m_NumCols; c++)
{
for (int r = 0; r < m_NumRows; r++)
if (cell.flag == cellUsed)
{
cell.cont->Layout(2*m_Padding + 1);
- int width = cell.cont->GetWidth();
+ int maxWidth = cell.cont->GetMaxTotalWidth();
+ int width = cell.nowrap?maxWidth:cell.cont->GetWidth();
width -= (cell.colspan-1) * m_Spacing;
+ maxWidth -= (cell.colspan-1) * m_Spacing;
// HTML 4.0 says it is acceptable to distribute min/max
width /= cell.colspan;
- for (int j = 0; j < cell.colspan; j++)
+ maxWidth /= cell.colspan;
+ for (int j = 0; j < cell.colspan; j++) {
if (width > m_ColsInfo[c+j].minWidth)
m_ColsInfo[c+j].minWidth = width;
+ if (maxWidth > m_ColsInfo[c+j].maxWidth)
+ m_ColsInfo[c+j].maxWidth = maxWidth;
+ }
}
}
+ // Calculate maximum table width, required for nested tables
+ if (m_ColsInfo[c].units == wxHTML_UNITS_PIXELS)
+ m_MaxTotalWidth += wxMax(m_ColsInfo[c].width, m_ColsInfo[c].minWidth);
+ else if ((m_ColsInfo[c].units == wxHTML_UNITS_PERCENT) && (m_ColsInfo[c].width != 0))
+ percentage += m_ColsInfo[c].width;
+ else
+ m_MaxTotalWidth += m_ColsInfo[c].maxWidth;
}
-
- // FIXME -- compute maxWidth as well. Not needed yet, so there's no
- // point in computing it.
-}
+ if (percentage >= 100)
+ {
+ // Table would have infinite length
+ // Make it ridiculous large
+ m_MaxTotalWidth = 0xFFFFFF;
+ }
+ else
+ m_MaxTotalWidth = m_MaxTotalWidth * 100 / (100 - percentage);
+
+ m_MaxTotalWidth += (m_NumCols + 1) * m_Spacing;
+}
void wxHtmlTableCell::Layout(int w)
{
if (m_WidthFloatUnits == wxHTML_UNITS_PERCENT)
{
- if (m_WidthFloat < 0) m_Width = (100 + m_WidthFloat) * w / 100;
- else m_Width = m_WidthFloat * w / 100;
+ if (m_WidthFloat < 0)
+ {
+ if (m_WidthFloat < -100)
+ m_WidthFloat = -100;
+ m_Width = (100 + m_WidthFloat) * w / 100;
+ }
+ else
+ {
+ if (m_WidthFloat > 100)
+ m_WidthFloat = 100;
+ m_Width = m_WidthFloat * w / 100;
+ }
}
else
{
*/
- /* 1. setup columns widths: */
+ /* 1. setup columns widths:
+
+ The algorithm tries to keep the table size less than w if possible.
+ */
{
int wpix = m_Width - (m_NumCols + 1) * m_Spacing;
int i, j;
wpix -= m_ColsInfo[i].pixwidth;
}
- // 1b. setup floating-width columns:
- int wtemp = 0;
+ // 1b. Calculate maximum possible width if line wrapping would be disabled
+ // Recalculate total width if m_WidthFloat is zero to keep tables as small
+ // as possible.
+ int maxWidth = 0;
+ for (i = 0; i < m_NumCols; i++)
+ if (m_ColsInfo[i].width == 0)
+ {
+ maxWidth += m_ColsInfo[i].maxWidth;
+ }
+
+ if (!m_WidthFloat)
+ {
+ // Recalculate table width since no table width was initially given
+ int newWidth = m_Width - wpix + maxWidth;
+
+ // Make sure that floating-width columns will have the right size.
+ // Calculate sum of all floating-width columns
+ int percentage = 0;
+ for (i = 0; i < m_NumCols; i++)
+ if ((m_ColsInfo[i].units == wxHTML_UNITS_PERCENT) && (m_ColsInfo[i].width != 0))
+ percentage += m_ColsInfo[i].width;
+
+ if (percentage >= 100)
+ newWidth = w;
+ else
+ newWidth = newWidth * 100 / (100 - percentage);
+
+ newWidth = wxMin(newWidth, w - (m_NumCols + 1) * m_Spacing);
+ wpix -= m_Width - newWidth;
+ m_Width = newWidth;
+ }
+
+
+ // 1c. setup floating-width columns:
+ int wtemp = wpix;
for (i = 0; i < m_NumCols; i++)
if ((m_ColsInfo[i].units == wxHTML_UNITS_PERCENT) && (m_ColsInfo[i].width != 0))
{
- m_ColsInfo[i].pixwidth = wxMax(m_ColsInfo[i].width * wpix / 100,
- m_ColsInfo[i].minWidth);
- wtemp += m_ColsInfo[i].pixwidth;
+ m_ColsInfo[i].pixwidth = wxMin(m_ColsInfo[i].width, 100) * wpix / 100;
+
+ // Make sure to leave enough space for the other columns
+ int minRequired = 0;
+ for (j = 0; j < m_NumCols; j++)
+ {
+ if ((m_ColsInfo[j].units == wxHTML_UNITS_PERCENT && j > i) ||
+ !m_ColsInfo[j].width)
+ minRequired += m_ColsInfo[j].minWidth;
+ }
+ m_ColsInfo[i].pixwidth = wxMax(wxMin(wtemp - minRequired, m_ColsInfo[i].pixwidth), m_ColsInfo[i].minWidth);
+
+ wtemp -= m_ColsInfo[i].pixwidth;
}
- wpix -= wtemp;
+ wpix = wtemp;
+
+ // 1d. setup default columns (no width specification supplied):
+ // The algorithm assigns calculates the maximum possible width if line
+ // wrapping would be disabled and assigns column width as a fraction
+ // based upon the maximum width of a column
+ // FIXME: I'm not sure if this algorithm is conform to HTML standard,
+ // though it seems to be much better than the old one
- // 1c. setup defalut columns (no width specification supplied):
- // FIXME: This algorithm doesn't conform to HTML standard : it assigns
- // equal widths instead of optimal
for (i = j = 0; i < m_NumCols; i++)
if (m_ColsInfo[i].width == 0) j++;
+ if (wpix < 0)
+ wpix = 0;
+
+ // Assign widths
for (i = 0; i < m_NumCols; i++)
if (m_ColsInfo[i].width == 0)
{
- // FIXME: this is not optimal, because if we allocate more than
- // wpix/j pixels to one column, we should try to allocate
- // smaller place to other columns
- m_ColsInfo[i].pixwidth = wxMax(wpix/j, m_ColsInfo[i].minWidth);
+ // Assign with, make sure not to drop below minWidth
+ if (maxWidth)
+ m_ColsInfo[i].pixwidth = wpix * (m_ColsInfo[i].maxWidth / (float)maxWidth) + 0.5;
+ else
+ m_ColsInfo[i].pixwidth = wpix / j;
+
+ // Make sure to leave enough space for the other columns
+ int minRequired = 0;
+ int r;
+ for (r = i + 1; r < m_NumCols; r++)
+ {
+ if (!m_ColsInfo[r].width)
+ minRequired += m_ColsInfo[r].minWidth;
+ }
+ m_ColsInfo[i].pixwidth = wxMax(wxMin(wpix - minRequired, m_ColsInfo[i].pixwidth), m_ColsInfo[i].minWidth);
+
+ if (maxWidth)
+ {
+ if (m_ColsInfo[i].pixwidth > (wpix * (m_ColsInfo[i].maxWidth / (float)maxWidth) + 0.5))
+ {
+ int diff = m_ColsInfo[i].pixwidth - (wpix * m_ColsInfo[i].maxWidth / (float)maxWidth + 0.5);
+ maxWidth += diff - m_ColsInfo[i].maxWidth;
+ }
+ else
+ maxWidth -= m_ColsInfo[i].maxWidth;
+ }
+ wpix -= m_ColsInfo[i].pixwidth;
}
}
oldcont = c = m_WParser->OpenContainer();
- c->SetWidthFloat(tag, m_WParser->GetPixelScale());
- m_Table = new wxHtmlTableCell(c, tag, m_WParser->GetPixelScale());
+ m_Table = new wxHtmlTableCell(c, tag);
+
+ // width:
+ {
+ if (tag.HasParam(wxT("WIDTH")))
+ {
+ wxString wd = tag.GetParam(wxT("WIDTH"));
+
+ if (wd[wd.Length()-1] == wxT('%'))
+ {
+ int width = 0;
+ wxSscanf(wd.c_str(), wxT("%i%%"), &width);
+ m_Table->SetWidthFloat(width, wxHTML_UNITS_PERCENT);
+ }
+ else
+ {
+ int width = 0;
+ wxSscanf(wd.c_str(), wxT("%i"), &width);
+ m_Table->SetWidthFloat(m_WParser->GetPixelScale() * width, wxHTML_UNITS_PIXELS);
+ }
+ }
+ else
+ m_Table->SetWidthFloat(0, wxHTML_UNITS_PIXELS);
+ }
int oldAlign = m_WParser->GetAlign();
m_tAlign = wxEmptyString;
if (tag.HasParam(wxT("ALIGN")))