📄 htmltable.cpp
字号:
{ int tableWidth = width - border; int addSize = 0; columnOpt = columnPos.copy(); if (tableWidth > columnPos[ totalCols ] ) { // We have some space to spare addSize = tableWidth - columnPos[ totalCols]; if ((percent <= 0) && (!isFixedWidth())) { // Variable width Table, if (columnPrefPos[totalCols] < tableWidth) { // don't scale beyond preferred width. addSize = columnPrefPos[totalCols] - columnPos[ totalCols]; } } } if (addSize > 0) { scaleColumns(0, totalCols-1, addSize); }}void HTMLTable::scaleColumns(unsigned int c_start, unsigned int c_end, int tooAdd){ unsigned int r, c; int colspan; int addSize; int minWidth, prefWidth; int totalAllowed, totalRequested; int borderExtra = ( border == 0 ) ? 0 : 1; int tableWidth = width - border; int *prefColumnWidth; // satisfy fixed width cells for ( colspan = 0; colspan <= 1; colspan++) { for ( r = 0; r < totalRows; r++ ) { for ( c = c_start; c <= c_end; c++ ) { HTMLTableCell *cell = cells[r][c]; if (cell == 0L) continue; if ( r < totalRows - 1 && cells[r+1][c] == cell ) continue; /* Fixed cells only */ if ( !cell->isFixedWidth() ) continue; if (colspan == 0) { // colSpan == 1 if (cell->colSpan() != 1) continue; } else { // colSpan > 1 if (cell->colSpan() <= 1) continue; if ( c < totalCols - 1 && cells[r][c+1] == cell ) continue; } minWidth = columnOpt[c+1] - columnOpt[c+1-cell->colSpan()]; prefWidth = cell->getWidth() + padding + padding + spacing + borderExtra; if (prefWidth <= minWidth) continue; addSize = (prefWidth - minWidth); tooAdd -= addSize; if (colspan == 0) { unsigned int c1; // Just add this to the column size for ( c1 = c+1; c1 <= totalCols; c1++ ) columnOpt[c1] += addSize; } else { unsigned int c_b = c+1-cell->colSpan(); // Some end-conditions are required here to prevent looping if (c_b < c_start) continue; if ((c_b == c_start) && (c == c_end)) continue; // scale the columns covered by 'cell' first scaleColumns(c_b, c, addSize); } // if colspan } // for c } // for r } // for colspan // satisfy percentage width cells for ( r = 0; r < totalRows; r++ ) { totalRequested = 0; if (tooAdd <= 0) // No space left! { return; } /* first calculate how much we would like to add in this row */ for ( c = c_start; c <= c_end; c++ ) { HTMLTableCell *cell = cells[r][c]; if (cell == 0L) continue; if ( r < totalRows - 1 && cells[r+1][c] == cell ) continue; if ( c < totalCols - 1 && cells[r][c+1] == cell ) continue; /* Percentage cells only */ if ( cell->getPercent() <= 0 ) continue; // Only cells with a colspan which fits within c_begin .. c_start if (cell->colSpan() > 1) { unsigned int c_b = c+1-cell->colSpan(); if (c_b < c_start) continue; if ((c_b == c_start) && (c == c_end)) continue; } minWidth = columnOpt[c+1] - columnOpt[c+1-cell->colSpan()]; prefWidth = tableWidth * cell->getPercent() / 100 + padding + padding + spacing + borderExtra; if (prefWidth <= minWidth) continue; totalRequested += (prefWidth - minWidth); } // for c if (totalRequested == 0) // Nothing to do continue; totalAllowed = tooAdd; // Do the actual adjusting of the percentage cells for ( colspan = 0; colspan <= 1; colspan++) { for ( c = c_start; c <= c_end; c++ ) { HTMLTableCell *cell = cells[r][c]; if (cell == 0L) continue; if ( c < totalCols - 1 && cells[r][c+1] == cell ) continue; if ( r < totalRows - 1 && cells[r+1][c] == cell ) continue; /* Percentage cells only */ if ( cell->getPercent() <= 0 ) continue; // Only cells with a colspan which fits within c_begin .. c_start if (cell->colSpan() > 1) { unsigned int c_b = c+1-cell->colSpan(); if (colspan == 0) continue; if (c_b < c_start) continue; if ((c_b == c_start) && (c == c_end)) continue; } else { if (colspan != 0) continue; } minWidth = columnOpt[c+1] - columnOpt[c+1-cell->colSpan()]; prefWidth = tableWidth * cell->getPercent() / 100 + padding + padding + spacing + borderExtra; if (prefWidth <= minWidth) continue; addSize = (prefWidth - minWidth); if (totalRequested > totalAllowed) // We can't honour the request, scale it { addSize = addSize * totalAllowed / totalRequested; totalRequested -= (prefWidth - minWidth); totalAllowed -= addSize; } tooAdd -= addSize; if (colspan == 0) { unsigned int c1; // Just add this to the column size for ( c1 = c+1; c1 <= totalCols; c1++ ) columnOpt[c1] += addSize; } else { unsigned int c_b = c+1-cell->colSpan(); // Some end-conditions are required here to prevent looping if (c_b < c_start) continue; if ((c_b == c_start) && (c == c_end)) continue; // scale the columns covered by 'cell' first scaleColumns(c_b, c, addSize); } // if colspan } // for c } // for colspan } // for r // This should not be calculated on a row by row basis totalRequested = 0; if (tooAdd <= 0) // No space left! { return; } prefColumnWidth = new int [totalCols]; bool *fixedCol = new bool [totalCols]; bool *percentCol = new bool [totalCols]; bool *variableCol = new bool [totalCols]; //printf("columnOpt1: "); //for ( c = 0; c < totalCols; c++ ) //printf("%d ", columnOpt[c+1]); //printf("\n"); /* first calculate how much we would like to add in each column */ for ( c = c_start; c <= c_end; c++ ) { minWidth = columnOpt[c+1] - columnOpt[c]; prefColumnWidth[c] = minWidth; fixedCol[c] = false; percentCol[c] = false; variableCol[c] = true; for ( r = 0; r < totalRows; r++ ) { int prefCellWidth; HTMLTableCell *cell = cells[r][c]; if (cell == 0L) continue; if ( r < totalRows - 1 && cells[r+1][c] == cell ) continue; if (cell->isFixedWidth()) { // fixed width prefCellWidth = cell->getWidth() + padding + padding + spacing + borderExtra; fixedCol[c] = true; variableCol[c] = false; } else if (cell->getPercent() > 0) { // percentage width prefCellWidth = tableWidth * cell->getPercent() / 100 + padding + padding + spacing + borderExtra; percentCol[c] = true; variableCol[c] = false; } else { // variable width prefCellWidth = cell->calcPreferredWidth() + padding + padding + spacing + borderExtra; } prefCellWidth = prefCellWidth / cell->colSpan(); if (prefCellWidth > prefColumnWidth[c]) prefColumnWidth[c] = prefCellWidth; } if (prefColumnWidth[c] > minWidth) { totalRequested += (prefColumnWidth[c] - minWidth); } else { prefColumnWidth[c] = 0; } } // for c if (totalRequested > 0) // Nothing to do { totalAllowed = tooAdd; // Do the actual adjusting of the variable width cells for ( c = c_start; c <= c_end; c++ ) { unsigned int c1; minWidth = columnOpt[c+1] - columnOpt[c]; prefWidth = prefColumnWidth[c]; if (prefWidth <= minWidth || fixedCol[c] || percentCol[c]) continue; addSize = (prefWidth - minWidth); if (totalRequested > totalAllowed) // We can't honour the request, scale it { addSize = addSize * totalAllowed / totalRequested; totalRequested -= (prefWidth - minWidth); totalAllowed -= addSize; } tooAdd -= addSize; // Just add this to the column size for ( c1 = c+1; c1 <= totalCols; c1++ ) columnOpt[c1] += addSize; } // for c } delete [] prefColumnWidth; //printf("columnOpt2: "); //for ( c = 0; c < totalCols; c++ ) //printf("%d ", columnOpt[c+1]); //printf("\n"); // Spread the remaining space equally across all variable columns if (tooAdd > 0) tooAdd = scaleSelectedColumns(c_start, c_end, tooAdd, variableCol); //printf("columnOpt3: "); //for ( c = 0; c < totalCols; c++ ) // //printf("%d ", columnOpt[c+1]); //printf("\n"); // Spread the remaining space equally across all percentage columns if (tooAdd > 0) tooAdd = scaleSelectedColumns(c_start, c_end, tooAdd, percentCol); //printf("columnOpt4: "); //for ( c = 0; c < totalCols; c++ ) //printf("%d ", columnOpt[c+1]); //printf("\n"); // Still something left... Change fixed columns if (tooAdd > 0) tooAdd = scaleSelectedColumns(c_start, c_end, tooAdd, fixedCol); //printf("columnOpt5: "); //for ( c = 0; c < totalCols; c++ ) //printf("%d ", columnOpt[c+1]); //printf("\n"); delete [] fixedCol; delete [] percentCol; delete [] variableCol; }intHTMLTable::scaleSelectedColumns(int c_start, int c_end, int tooAdd, bool *selected){ int c, c1; if (tooAdd <= 0) return tooAdd; int numSelected = 0; for ( c = c_start; c <= c_end; c++ ) if( selected[c] ) numSelected++; if(numSelected < 1) return tooAdd; int addSize = tooAdd / numSelected; int left = tooAdd - addSize * numSelected; for( c = c_start; c <= c_end; c++) { if( !selected[c] ) continue; tooAdd -= addSize; for ( c1 = c+1; c1 <= (int)totalCols; c1++ ) { columnOpt[c1] += addSize; if ( left ) columnOpt[c1]++; } if(left) { tooAdd--; left--; } } return tooAdd;}// New table layout functionvoid HTMLTable::addRowInfo(int _row, int _colInfoIndex){ rowInfo[_row].entry[rowInfo[_row].nrEntries++] = _colInfoIndex;}// New table layout functionint HTMLTable::addColInfo(int _startCol, int _colSpan, int _minSize, int _prefSize, int _maxSize, ColType _colType){ unsigned int indx; // Is there already some info present? for(indx = 0; indx < totalColInfos; indx++) { if ((colInfo[indx].startCol == _startCol) && (colInfo[indx].colSpan == _colSpan)) break; } if (indx == totalColInfos) { // No colInfo present allocate some totalColInfos++; if (totalColInfos >= colInfo.size()) { colInfo.resize( colInfo.size() + totalCols ); } colInfo[indx].startCol = _startCol; colInfo[indx].colSpan = _colSpan; colInfo[indx].minSize = _minSize; colInfo[indx].prefSize = _prefSize; colInfo[indx].maxSize = _maxSize; colInfo[indx].colType = _colType; } else { if (_minSize > colInfo[indx].minSize) colInfo[indx].minSize = _minSize; // Fixed < Percent < Variable if (_colType < colInfo[indx].colType) { colInfo[indx].prefSize = _prefSize; } else if (_colType == colInfo[indx].colType) { if (_prefSize > colInfo[indx].prefSize) colInfo[indx].prefSize = _prefSize; } } return (indx); /* Return the ColInfo Index */} // New table layout function//// Both the minimum and preferred column sizes are calculated here.// The hard part is choosing the actual sizes based on these two.void HTMLTable::calcColInfo(){ unsigned int r, c; int borderExtra = ( border == 0 ) ? 0 : 1; // Allocate some memory for column info colInfo.resize( totalCols*2 ); rowInfo = (RowInfo_t *) malloc( totalRows * sizeof(RowInfo_t) ); totalColInfos = 0; for ( r = 0; r < totalRows; r++ ) { rowInfo[r].entry = (int *) malloc( totalCols * sizeof(int)); rowInfo[r].nrEntries = 0; for ( c = 0; c < totalCols; c++ ) { HTMLTableCell *cell = cells[r][c]; int min_size; int pref_size; int colInfoIndex; ColType col_type; if ( cell == 0 ) continue; if ( (c > 0) && (cells[r][c-1] == cell) ) continue; if ( (r > 0) && (cells[r-1][c] == cell) ) continue; // calculate minimum size min_size = cell->calcMinWidth() + padding + padding + spacing + borderExtra; // calculate preferred pos if ( cell->getPercent() > 0 ) { pref_size = ( max_width * cell->getPercent() / 100 ) + padding + padding + spacing + borderExtra; col_type = Percent; } else if ( cell->isFixedWidth() ) { pref_size = cell->getWidth() + padding + padding + spacing + borderExtra; col_type = Fixed; } else { pref_size = cell->calcPreferredWidth() + padding + padding + spacing + borderExtra; col_type = Variable; } colInfoIndex = addColInfo(c, cell->colSpan(), min_size, pref_size, max_width, col_type); addRowInfo(r, colInfoIndex); } } // Remove redundant rows unsigned int i; unsigned int totalRowInfos; totalRowInfos = 1; for(i = 1; i < totalRows; i++) { bool unique = TRUE; for(unsigned int j = 0; (j < totalRowInfos) && (unique == TRUE); j++) { unsigned k; if (rowInfo[i].nrEntries == rowInfo[j].nrEntries) unique = FALSE; else { bool match = TRUE; k = rowInfo[i].nrEntries; while (k--) { if (rowInfo[i].entry[k] != rowInfo[j].entry[k]) { match = FALSE; break; } } if (match) unique = FALSE; } } if (!unique) { free( rowInfo[i].entry); } else { if (totalRowInfos != i) { rowInfo[totalRowInfos].entry = rowInfo[i].entry; rowInfo[totalRowInfos].nrEntries = rowInfo[i].nrEntries; } totalRowInfos++; } } // Calculate pref width and min width for each row _minWidth = 0; _prefWidth = 0; for(i = 0; i < totalRowInfos; i++) { int min = 0; int pref = 0; for(int j = 0; j < rowInfo[i].nrEntries; j++) { int index = rowInfo[i].entry[j]; min += colInfo[index].minSize; pref += colInfo[index].prefSize; } rowInfo[i].minSize = min; rowInfo[i].prefSize = pref; if (_minWidth < min) { _minWidth = min; } if (_prefWidth < pref) { _prefWidth = pref; } } if ( isFixedWidth() ) { // Our minimum width is at least our fixed width if (width > _minWidth) _minWidth = width; // And our actual width is at least our minimum width. if (width < _minWidth) width = _minWidth; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -