]>
git.saurik.com Git - wxWidgets.git/blob - src/html/m_tables.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/html/m_tables.cpp 
   3 // Purpose:     wxHtml module for tables 
   4 // Author:      Vaclav Slavik 
   6 // Copyright:   (c) 1999 Vaclav Slavik 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 #include "wx/wxprec.h" 
  16 #if wxUSE_HTML && wxUSE_STREAMS 
  21 #include "wx/html/forcelnk.h" 
  22 #include "wx/html/m_templ.h" 
  24 #include "wx/html/htmlcell.h" 
  26 FORCE_LINK_ME(m_tables
) 
  29 #define TABLE_BORDER_CLR_1  wxColour(0xC5, 0xC2, 0xC5) 
  30 #define TABLE_BORDER_CLR_2  wxColour(0x62, 0x61, 0x62) 
  33 //----------------------------------------------------------------------------- 
  35 //----------------------------------------------------------------------------- 
  41             // width of the column either in pixels or percents 
  42             // ('width' is the number, 'units' determines its meaning) 
  43     int minWidth
, maxWidth
; 
  44             // minimal/maximal column width. This is needed by HTML 4.0 
  45             // layouting algorithm and can be determined by trying to 
  46             // layout table cells with width=1 and width=infinity 
  47     int leftpos
, pixwidth
, maxrealwidth
; 
  48             // temporary (depends on actual width of table) 
  60     wxHtmlContainerCell 
*cont
; 
  62     int minheight
, valign
; 
  68 class wxHtmlTableCell 
: public wxHtmlContainerCell
 
  71     /* These are real attributes: */ 
  73     // should we draw borders or not? 
  75     // number of columns; rows 
  76     int m_NumCols
, m_NumRows
; 
  77     // array of column information 
  78     colStruct 
*m_ColsInfo
; 
  79     // 2D array of all cells in the table : m_CellInfo[row][column] 
  80     cellStruct 
**m_CellInfo
; 
  81     // spaces between cells 
  83     // cells internal indentation 
  87     /* ...and these are valid only when parsing the table: */ 
  89     // number of actual column (ranging from 0..m_NumCols) 
  90     int m_ActualCol
, m_ActualRow
; 
  92     // default values (for table and row): 
  93     wxColour m_tBkg
, m_rBkg
; 
  94     wxString m_tValign
, m_rValign
; 
 100     wxHtmlTableCell(wxHtmlContainerCell 
*parent
, const wxHtmlTag
& tag
, double pixel_scale 
= 1.0); 
 101     virtual ~wxHtmlTableCell(); 
 103     virtual void RemoveExtraSpacing(bool top
, bool bottom
); 
 105     virtual void Layout(int w
); 
 107     void AddRow(const wxHtmlTag
& tag
); 
 108     void AddCell(wxHtmlContainerCell 
*cell
, const wxHtmlTag
& tag
); 
 111     // Reallocates memory to given number of cols/rows 
 112     // and changes m_NumCols/m_NumRows value to reflect this change 
 113     // NOTE! You CAN'T change m_NumCols/m_NumRows before calling this!! 
 114     void ReallocCols(int cols
); 
 115     void ReallocRows(int rows
); 
 117     // Computes minimal and maximal widths of columns. Needs to be called 
 118     // only once, before first Layout(). 
 119     void ComputeMinMaxWidths(); 
 121     DECLARE_NO_COPY_CLASS(wxHtmlTableCell
) 
 126 wxHtmlTableCell::wxHtmlTableCell(wxHtmlContainerCell 
*parent
, const wxHtmlTag
& tag
, double pixel_scale
) 
 127  : wxHtmlContainerCell(parent
) 
 129     m_PixelScale 
= pixel_scale
; 
 131             (tag
.HasParam(wxT("BORDER")) && tag
.GetParam(wxT("BORDER")) != wxT("0")); 
 133     m_NumCols 
= m_NumRows 
= 0; 
 135     m_ActualCol 
= m_ActualRow 
= -1; 
 138     if (tag
.HasParam(wxT("BGCOLOR"))) 
 139         tag
.GetParamAsColour(wxT("BGCOLOR"), &m_tBkg
); 
 140     if (tag
.HasParam(wxT("VALIGN"))) 
 141         m_tValign 
= tag
.GetParam(wxT("VALIGN")); 
 143         m_tValign 
= wxEmptyString
; 
 144     if (!tag
.GetParamAsInt(wxT("CELLSPACING"), &m_Spacing
)) 
 146     if (!tag
.GetParamAsInt(wxT("CELLPADDING"), &m_Padding
)) 
 148     m_Spacing 
= (int)(m_PixelScale 
* (double)m_Spacing
); 
 149     m_Padding 
= (int)(m_PixelScale 
* (double)m_Padding
); 
 152         SetBorder(TABLE_BORDER_CLR_1
, TABLE_BORDER_CLR_2
); 
 157 wxHtmlTableCell::~wxHtmlTableCell() 
 159     if (m_ColsInfo
) free(m_ColsInfo
); 
 162         for (int i 
= 0; i 
< m_NumRows
; i
++) 
 169 void wxHtmlTableCell::RemoveExtraSpacing(bool WXUNUSED(top
), 
 170                                          bool WXUNUSED(bottom
)) 
 172     // Don't remove any spacing in the table -- it's always desirable, 
 173     // because it's part of table's definition. 
 174     // (If wxHtmlContainerCell::RemoveExtraSpacing() was applied to tables, 
 175     // then upper left cell of a table would be positioned above other cells 
 176     // if the table was the first element on the page.) 
 179 void wxHtmlTableCell::ReallocCols(int cols
) 
 183     for (i 
= 0; i 
< m_NumRows
; i
++) 
 185         m_CellInfo
[i
] = (cellStruct
*) realloc(m_CellInfo
[i
], sizeof(cellStruct
) * cols
); 
 186         for (j 
= m_NumCols
; j 
< cols
; j
++) 
 187             m_CellInfo
[i
][j
].flag 
= cellFree
; 
 190     m_ColsInfo 
= (colStruct
*) realloc(m_ColsInfo
, sizeof(colStruct
) * cols
); 
 191     for (j 
= m_NumCols
; j 
< cols
; j
++) 
 193            m_ColsInfo
[j
].width 
= 0; 
 194            m_ColsInfo
[j
].units 
= wxHTML_UNITS_PERCENT
; 
 195            m_ColsInfo
[j
].minWidth 
= m_ColsInfo
[j
].maxWidth 
= -1; 
 203 void wxHtmlTableCell::ReallocRows(int rows
) 
 205     m_CellInfo 
= (cellStruct
**) realloc(m_CellInfo
, sizeof(cellStruct
*) * rows
); 
 206     for (int row 
= m_NumRows
; row 
< rows 
; row
++) 
 209             m_CellInfo
[row
] = NULL
; 
 212             m_CellInfo
[row
] = (cellStruct
*) malloc(sizeof(cellStruct
) * m_NumCols
); 
 213             for (int col 
= 0; col 
< m_NumCols
; col
++) 
 214                 m_CellInfo
[row
][col
].flag 
= cellFree
; 
 221 void wxHtmlTableCell::AddRow(const wxHtmlTag
& tag
) 
 224     // VS: real allocation of row entry is done in AddCell in order 
 225     //     to correctly handle empty rows (i.e. "<tr></tr>") 
 226     //     m_ActualCol == -1 indicates that AddCell has to allocate new row. 
 230     if (tag
.HasParam(wxT("BGCOLOR"))) 
 231         tag
.GetParamAsColour(wxT("BGCOLOR"), &m_rBkg
); 
 232     if (tag
.HasParam(wxT("VALIGN"))) 
 233         m_rValign 
= tag
.GetParam(wxT("VALIGN")); 
 235         m_rValign 
= m_tValign
; 
 240 void wxHtmlTableCell::AddCell(wxHtmlContainerCell 
*cell
, const wxHtmlTag
& tag
) 
 242     // Is this cell in new row? 
 243     // VS: we can't do it in AddRow, see my comment there 
 244     if (m_ActualCol 
== -1) 
 246         if (m_ActualRow 
+ 1 > m_NumRows 
- 1) 
 247             ReallocRows(m_ActualRow 
+ 2); 
 255     } while ((m_ActualCol 
< m_NumCols
) && 
 256              (m_CellInfo
[m_ActualRow
][m_ActualCol
].flag 
!= cellFree
)); 
 258     if (m_ActualCol 
> m_NumCols 
- 1) 
 259         ReallocCols(m_ActualCol 
+ 1); 
 261     int r 
= m_ActualRow
, c 
= m_ActualCol
; 
 263     m_CellInfo
[r
][c
].cont 
= cell
; 
 264     m_CellInfo
[r
][c
].colspan 
= 1; 
 265     m_CellInfo
[r
][c
].rowspan 
= 1; 
 266     m_CellInfo
[r
][c
].flag 
= cellUsed
; 
 267     m_CellInfo
[r
][c
].minheight 
= 0; 
 268     m_CellInfo
[r
][c
].valign 
= wxHTML_ALIGN_TOP
; 
 270     /* scan for parameters: */ 
 274         if (tag
.HasParam(wxT("WIDTH"))) 
 276             wxString wd 
= tag
.GetParam(wxT("WIDTH")); 
 278             if (wd
[wd
.length()-1] == wxT('%')) 
 280                 wxSscanf(wd
.c_str(), wxT("%i%%"), &m_ColsInfo
[c
].width
); 
 281                 m_ColsInfo
[c
].units 
= wxHTML_UNITS_PERCENT
; 
 285                 wxSscanf(wd
.c_str(), wxT("%i"), &m_ColsInfo
[c
].width
); 
 286                 m_ColsInfo
[c
].width 
= (int)(m_PixelScale 
* (double)m_ColsInfo
[c
].width
); 
 287                 m_ColsInfo
[c
].units 
= wxHTML_UNITS_PIXELS
; 
 295         tag
.GetParamAsInt(wxT("COLSPAN"), &m_CellInfo
[r
][c
].colspan
); 
 296         tag
.GetParamAsInt(wxT("ROWSPAN"), &m_CellInfo
[r
][c
].rowspan
); 
 298         // VS: the standard says this about col/rowspan: 
 299         //     "This attribute specifies the number of rows spanned by the 
 300         //     current cell. The default value of this attribute is one ("1"). 
 301         //     The value zero ("0") means that the cell spans all rows from the 
 302         //     current row to the last row of the table." All mainstream 
 303         //     browsers act as if 0==1, though, and so does wxHTML. 
 304         if (m_CellInfo
[r
][c
].colspan 
< 1) 
 305             m_CellInfo
[r
][c
].colspan 
= 1; 
 306         if (m_CellInfo
[r
][c
].rowspan 
< 1) 
 307             m_CellInfo
[r
][c
].rowspan 
= 1; 
 309         if ((m_CellInfo
[r
][c
].colspan 
> 1) || (m_CellInfo
[r
][c
].rowspan 
> 1)) 
 313             if (r 
+ m_CellInfo
[r
][c
].rowspan 
> m_NumRows
) 
 314                 ReallocRows(r 
+ m_CellInfo
[r
][c
].rowspan
); 
 315             if (c 
+ m_CellInfo
[r
][c
].colspan 
> m_NumCols
) 
 316                 ReallocCols(c 
+ m_CellInfo
[r
][c
].colspan
); 
 317             for (i 
= r
; i 
< r 
+ m_CellInfo
[r
][c
].rowspan
; i
++) 
 318                 for (j 
= c
; j 
< c 
+ m_CellInfo
[r
][c
].colspan
; j
++) 
 319                     m_CellInfo
[i
][j
].flag 
= cellSpan
; 
 320             m_CellInfo
[r
][c
].flag 
= cellUsed
; 
 326         wxColour bk 
= m_rBkg
; 
 327         if (tag
.HasParam(wxT("BGCOLOR"))) 
 328             tag
.GetParamAsColour(wxT("BGCOLOR"), &bk
); 
 330             cell
->SetBackgroundColour(bk
); 
 333         cell
->SetBorder(TABLE_BORDER_CLR_2
, TABLE_BORDER_CLR_1
); 
 335     // vertical alignment: 
 338         if (tag
.HasParam(wxT("VALIGN"))) 
 339             valign 
= tag
.GetParam(wxT("VALIGN")); 
 343         if (valign 
== wxT("TOP")) 
 344             m_CellInfo
[r
][c
].valign 
= wxHTML_ALIGN_TOP
; 
 345         else if (valign 
== wxT("BOTTOM")) 
 346             m_CellInfo
[r
][c
].valign 
= wxHTML_ALIGN_BOTTOM
; 
 347         else m_CellInfo
[r
][c
].valign 
= wxHTML_ALIGN_CENTER
; 
 351     if (tag
.HasParam(wxT("NOWRAP"))) 
 352         m_CellInfo
[r
][c
].nowrap 
= true; 
 354         m_CellInfo
[r
][c
].nowrap 
= false; 
 356     cell
->SetIndent(m_Padding
, wxHTML_INDENT_ALL
, wxHTML_UNITS_PIXELS
); 
 359 void wxHtmlTableCell::ComputeMinMaxWidths() 
 361     if (m_NumCols 
== 0 || m_ColsInfo
[0].minWidth 
!= wxDefaultCoord
) return; 
 365     for (int c 
= 0; c 
< m_NumCols
; c
++) 
 367         for (int r 
= 0; r 
< m_NumRows
; r
++) 
 369             cellStruct
& cell 
= m_CellInfo
[r
][c
]; 
 370             if (cell
.flag 
== cellUsed
) 
 372                 cell
.cont
->Layout(2*m_Padding 
+ 1); 
 373                 int maxWidth 
= cell
.cont
->GetMaxTotalWidth(); 
 374                 int width 
= cell
.nowrap
?maxWidth
:cell
.cont
->GetWidth(); 
 375                 width 
-= (cell
.colspan
-1) * m_Spacing
; 
 376                 maxWidth 
-= (cell
.colspan
-1) * m_Spacing
; 
 377                 // HTML 4.0 says it is acceptable to distribute min/max 
 378                 width 
/= cell
.colspan
; 
 379                 maxWidth 
/= cell
.colspan
; 
 380                 for (int j 
= 0; j 
< cell
.colspan
; j
++) { 
 381                     if (width 
> m_ColsInfo
[c
+j
].minWidth
) 
 382                         m_ColsInfo
[c
+j
].minWidth 
= width
; 
 383                     if (maxWidth 
> m_ColsInfo
[c
+j
].maxWidth
) 
 384                         m_ColsInfo
[c
+j
].maxWidth 
= maxWidth
; 
 388         // Calculate maximum table width, required for nested tables 
 389         if (m_ColsInfo
[c
].units 
== wxHTML_UNITS_PIXELS
) 
 390             m_MaxTotalWidth 
+= wxMax(m_ColsInfo
[c
].width
, m_ColsInfo
[c
].minWidth
); 
 391         else if ((m_ColsInfo
[c
].units 
== wxHTML_UNITS_PERCENT
) && (m_ColsInfo
[c
].width 
!= 0)) 
 392             percentage 
+= m_ColsInfo
[c
].width
; 
 394             m_MaxTotalWidth 
+= m_ColsInfo
[c
].maxWidth
; 
 397     if (percentage 
>= 100) 
 399         // Table would have infinite length 
 400         // Make it ridiculous large 
 401         m_MaxTotalWidth 
= 0xFFFFFF; 
 404         m_MaxTotalWidth 
= m_MaxTotalWidth 
* 100 / (100 - percentage
); 
 406     m_MaxTotalWidth 
+= (m_NumCols 
+ 1) * m_Spacing
; 
 409 void wxHtmlTableCell::Layout(int w
) 
 411     ComputeMinMaxWidths(); 
 413     wxHtmlCell::Layout(w
); 
 421     if (m_WidthFloatUnits 
== wxHTML_UNITS_PERCENT
) 
 423         if (m_WidthFloat 
< 0) 
 425             if (m_WidthFloat 
< -100) 
 427             m_Width 
= (100 + m_WidthFloat
) * w 
/ 100; 
 431             if (m_WidthFloat 
> 100) 
 433             m_Width 
= m_WidthFloat 
* w 
/ 100; 
 438         if (m_WidthFloat 
< 0) m_Width 
= w 
+ m_WidthFloat
; 
 439         else m_Width 
= m_WidthFloat
; 
 449     /* 1.  setup columns widths: 
 451            The algorithm tries to keep the table size less than w if possible. 
 454         int wpix 
= m_Width 
- (m_NumCols 
+ 1) * m_Spacing
; 
 457         // 1a. setup fixed-width columns: 
 458         for (i 
= 0; i 
< m_NumCols
; i
++) 
 459             if (m_ColsInfo
[i
].units 
== wxHTML_UNITS_PIXELS
) 
 461                 m_ColsInfo
[i
].pixwidth 
= wxMax(m_ColsInfo
[i
].width
, 
 462                                                m_ColsInfo
[i
].minWidth
); 
 463                 wpix 
-= m_ColsInfo
[i
].pixwidth
; 
 466         // 1b. Calculate maximum possible width if line wrapping would be disabled 
 467         // Recalculate total width if m_WidthFloat is zero to keep tables as small 
 470         for (i 
= 0; i 
< m_NumCols
; i
++) 
 471             if (m_ColsInfo
[i
].width 
== 0) 
 473                 maxWidth 
+= m_ColsInfo
[i
].maxWidth
; 
 478             // Recalculate table width since no table width was initially given 
 479             int newWidth 
= m_Width 
- wpix 
+  maxWidth
; 
 481             // Make sure that floating-width columns will have the right size. 
 482             // Calculate sum of all floating-width columns 
 484             for (i 
= 0; i 
< m_NumCols
; i
++) 
 485                 if ((m_ColsInfo
[i
].units 
== wxHTML_UNITS_PERCENT
) && (m_ColsInfo
[i
].width 
!= 0)) 
 486                     percentage 
+= m_ColsInfo
[i
].width
; 
 488             if (percentage 
>= 100) 
 491                 newWidth 
= newWidth 
* 100 / (100 - percentage
); 
 493             newWidth 
= wxMin(newWidth
, w 
- (m_NumCols 
+ 1) * m_Spacing
); 
 494             wpix 
-= m_Width 
- newWidth
; 
 499         // 1c. setup floating-width columns: 
 501         for (i 
= 0; i 
< m_NumCols
; i
++) 
 502             if ((m_ColsInfo
[i
].units 
== wxHTML_UNITS_PERCENT
) && (m_ColsInfo
[i
].width 
!= 0)) 
 504                 m_ColsInfo
[i
].pixwidth 
= wxMin(m_ColsInfo
[i
].width
, 100) * wpix 
/ 100; 
 506                 // Make sure to leave enough space for the other columns 
 508                 for (j 
= 0; j 
< m_NumCols
; j
++) 
 510                     if ((m_ColsInfo
[j
].units 
== wxHTML_UNITS_PERCENT 
&& j 
> i
) || 
 511                         !m_ColsInfo
[j
].width
) 
 512                         minRequired 
+= m_ColsInfo
[j
].minWidth
; 
 514                 m_ColsInfo
[i
].pixwidth 
= wxMax(wxMin(wtemp 
- minRequired
, m_ColsInfo
[i
].pixwidth
), m_ColsInfo
[i
].minWidth
); 
 516                 wtemp 
-= m_ColsInfo
[i
].pixwidth
; 
 520         // 1d. setup default columns (no width specification supplied): 
 521         // The algorithm assigns calculates the maximum possible width if line 
 522         // wrapping would be disabled and assigns column width as a fraction 
 523         // based upon the maximum width of a column 
 524         // FIXME: I'm not sure if this algorithm is conform to HTML standard, 
 525         //        though it seems to be much better than the old one 
 527         for (i 
= j 
= 0; i 
< m_NumCols
; i
++) 
 528             if (m_ColsInfo
[i
].width 
== 0) j
++; 
 533         for (i 
= 0; i 
< m_NumCols
; i
++) 
 534             if (m_ColsInfo
[i
].width 
== 0) 
 536                 // Assign with, make sure not to drop below minWidth 
 538                     m_ColsInfo
[i
].pixwidth 
= (int)(wpix 
* (m_ColsInfo
[i
].maxWidth 
/ (float)maxWidth
) + 0.5); 
 540                     m_ColsInfo
[i
].pixwidth 
= wpix 
/ j
; 
 542                 // Make sure to leave enough space for the other columns 
 545                 for (r 
= i 
+ 1; r 
< m_NumCols
; r
++) 
 547                     if (!m_ColsInfo
[r
].width
) 
 548                         minRequired 
+= m_ColsInfo
[r
].minWidth
; 
 550                 m_ColsInfo
[i
].pixwidth 
= wxMax(wxMin(wpix 
- minRequired
, m_ColsInfo
[i
].pixwidth
), m_ColsInfo
[i
].minWidth
); 
 554                     if (m_ColsInfo
[i
].pixwidth 
> (wpix 
* (m_ColsInfo
[i
].maxWidth 
/ (float)maxWidth
) + 0.5)) 
 556                         int diff 
= (int)(m_ColsInfo
[i
].pixwidth 
- (wpix 
* m_ColsInfo
[i
].maxWidth 
/ (float)maxWidth 
+ 0.5)); 
 557                         maxWidth 
+= diff 
- m_ColsInfo
[i
].maxWidth
; 
 560                         maxWidth 
-= m_ColsInfo
[i
].maxWidth
; 
 562                 wpix 
-= m_ColsInfo
[i
].pixwidth
; 
 566     /* 2.  compute positions of columns: */ 
 568         int wpos 
= m_Spacing
; 
 569         for (int i 
= 0; i 
< m_NumCols
; i
++) 
 571             m_ColsInfo
[i
].leftpos 
= wpos
; 
 572             wpos 
+= m_ColsInfo
[i
].pixwidth 
+ m_Spacing
; 
 576     /* 3.  sub-layout all cells: */ 
 578         int *ypos 
= new int[m_NumRows 
+ 1]; 
 582         wxHtmlContainerCell 
*actcell
; 
 585         for (actrow 
= 1; actrow 
<= m_NumRows
; actrow
++) ypos
[actrow
] = -1; 
 586         for (actrow 
= 0; actrow 
< m_NumRows
; actrow
++) 
 588             if (ypos
[actrow
] == -1) ypos
[actrow
] = ypos
[actrow
-1]; 
 589             // 3a. sub-layout and detect max height: 
 591             for (actcol 
= 0; actcol 
< m_NumCols
; actcol
++) { 
 592                 if (m_CellInfo
[actrow
][actcol
].flag 
!= cellUsed
) continue; 
 593                 actcell 
= m_CellInfo
[actrow
][actcol
].cont
; 
 595                 for (int i 
= actcol
; i 
< m_CellInfo
[actrow
][actcol
].colspan 
+ actcol
; i
++) 
 596                     fullwid 
+= m_ColsInfo
[i
].pixwidth
; 
 597                 fullwid 
+= (m_CellInfo
[actrow
][actcol
].colspan 
- 1) * m_Spacing
; 
 598                 actcell
->SetMinHeight(m_CellInfo
[actrow
][actcol
].minheight
, m_CellInfo
[actrow
][actcol
].valign
); 
 599                 actcell
->Layout(fullwid
); 
 601                 if (ypos
[actrow
] + actcell
->GetHeight() + m_CellInfo
[actrow
][actcol
].rowspan 
* m_Spacing 
> ypos
[actrow 
+ m_CellInfo
[actrow
][actcol
].rowspan
]) 
 602                     ypos
[actrow 
+ m_CellInfo
[actrow
][actcol
].rowspan
] = 
 603                             ypos
[actrow
] + actcell
->GetHeight() + m_CellInfo
[actrow
][actcol
].rowspan 
* m_Spacing
; 
 607         for (actrow 
= 0; actrow 
< m_NumRows
; actrow
++) 
 609             // 3b. place cells in row & let'em all have same height: 
 611             for (actcol 
= 0; actcol 
< m_NumCols
; actcol
++) 
 613                 if (m_CellInfo
[actrow
][actcol
].flag 
!= cellUsed
) continue; 
 614                 actcell 
= m_CellInfo
[actrow
][actcol
].cont
; 
 615                 actcell
->SetMinHeight( 
 616                                  ypos
[actrow 
+ m_CellInfo
[actrow
][actcol
].rowspan
] - ypos
[actrow
] -  m_Spacing
, 
 617                                  m_CellInfo
[actrow
][actcol
].valign
); 
 619                 for (int i 
= actcol
; i 
< m_CellInfo
[actrow
][actcol
].colspan 
+ actcol
; i
++) 
 620                     fullwid 
+= m_ColsInfo
[i
].pixwidth
; 
 621                 fullwid 
+= (m_CellInfo
[actrow
][actcol
].colspan 
- 1) * m_Spacing
; 
 622                 actcell
->Layout(fullwid
); 
 623                 actcell
->SetPos(m_ColsInfo
[actcol
].leftpos
, ypos
[actrow
]); 
 626         m_Height 
= ypos
[m_NumRows
]; 
 630     /* 4. adjust table's width if it was too small: */ 
 633         int twidth 
= m_ColsInfo
[m_NumCols
-1].leftpos 
+ 
 634                      m_ColsInfo
[m_NumCols
-1].pixwidth 
+ m_Spacing
; 
 635         if (twidth 
> m_Width
) 
 645 //----------------------------------------------------------------------------- 
 646 // The tables handler: 
 647 //----------------------------------------------------------------------------- 
 650 TAG_HANDLER_BEGIN(TABLE
, "TABLE,TR,TD,TH") 
 653         wxHtmlTableCell
* m_Table
; 
 654         wxString m_tAlign
, m_rAlign
; 
 656     TAG_HANDLER_CONSTR(TABLE
) 
 659         m_tAlign 
= m_rAlign 
= wxEmptyString
; 
 663     TAG_HANDLER_PROC(tag
) 
 665         wxHtmlContainerCell 
*c
; 
 667         // new table started, backup upper-level table (if any) and create new: 
 668         if (tag
.GetName() == wxT("TABLE")) 
 670             wxHtmlTableCell 
*oldt 
= m_Table
; 
 671             wxHtmlContainerCell 
*oldcont
; 
 673             oldcont 
= c 
= m_WParser
->OpenContainer(); 
 675             m_Table 
= new wxHtmlTableCell(c
, tag
); 
 679                 if (tag
.HasParam(wxT("WIDTH"))) 
 681                     wxString wd 
= tag
.GetParam(wxT("WIDTH")); 
 683                     if (wd
[wd
.length()-1] == wxT('%')) 
 686                         wxSscanf(wd
.c_str(), wxT("%i%%"), &width
); 
 687                         m_Table
->SetWidthFloat(width
, wxHTML_UNITS_PERCENT
); 
 692                         wxSscanf(wd
.c_str(), wxT("%i"), &width
); 
 693                         m_Table
->SetWidthFloat((int)(m_WParser
->GetPixelScale() * width
), wxHTML_UNITS_PIXELS
); 
 697                     m_Table
->SetWidthFloat(0, wxHTML_UNITS_PIXELS
); 
 699             int oldAlign 
= m_WParser
->GetAlign(); 
 700             m_tAlign 
= wxEmptyString
; 
 701             if (tag
.HasParam(wxT("ALIGN"))) 
 702                 m_tAlign 
= tag
.GetParam(wxT("ALIGN")); 
 706             m_WParser
->SetAlign(oldAlign
); 
 707             m_WParser
->SetContainer(oldcont
); 
 708             m_WParser
->CloseContainer(); 
 718             if (tag
.GetName() == wxT("TR")) 
 720                 m_Table
->AddRow(tag
); 
 722                 if (tag
.HasParam(wxT("ALIGN"))) 
 723                     m_rAlign 
= tag
.GetParam(wxT("ALIGN")); 
 729                 c 
= m_WParser
->SetContainer(new wxHtmlContainerCell(m_Table
)); 
 730                 m_Table
->AddCell(c
, tag
); 
 732                 m_WParser
->OpenContainer(); 
 734                 if (tag
.GetName() == wxT("TH")) /*header style*/ 
 735                     m_WParser
->SetAlign(wxHTML_ALIGN_CENTER
); 
 737                     m_WParser
->SetAlign(wxHTML_ALIGN_LEFT
); 
 742                 if (tag
.HasParam(wxT("ALIGN"))) 
 743                     als 
= tag
.GetParam(wxT("ALIGN")); 
 745                 if (als 
== wxT("RIGHT")) 
 746                     m_WParser
->SetAlign(wxHTML_ALIGN_RIGHT
); 
 747                 else if (als 
== wxT("LEFT")) 
 748                     m_WParser
->SetAlign(wxHTML_ALIGN_LEFT
); 
 749                 else if (als 
== wxT("CENTER")) 
 750                     m_WParser
->SetAlign(wxHTML_ALIGN_CENTER
); 
 752                 m_WParser
->OpenContainer(); 
 758 TAG_HANDLER_END(TABLE
) 
 764 TAGS_MODULE_BEGIN(Tables
) 
 766     TAGS_MODULE_ADD(TABLE
) 
 768 TAGS_MODULE_END(Tables
)