blob: 1038f479fb8eab626d16638402bf3a609d37199c [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "DFTable.h"
#include "DFDOM.h"
#include "DFCommon.h"
#include "DFPlatform.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
DFTableDimensions DFTableDimensionsMake(unsigned int rows, unsigned int cols)
{
DFTableDimensions dimensions;
dimensions.rows = rows;
dimensions.cols = cols;
return dimensions;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// DFCell //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
DFCell *DFCellNew(DFNode *element, unsigned int row, unsigned int col)
{
DFCell *cell = (DFCell *)xcalloc(1,sizeof(DFCell));
cell->retainCount = 1;
cell->element = element;
cell->row = row;
cell->col = col;
cell->rowSpan = 1;
cell->colSpan = 1;
return cell;
}
DFCell *DFCellRetain(DFCell *cell)
{
if (cell != NULL)
cell->retainCount++;
return cell;
}
void DFCellRelease(DFCell *cell)
{
if ((cell == NULL) || (--cell->retainCount > 0))
return;
free(cell);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// DFTable //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
DFTable *DFTableNew(unsigned int rows, unsigned int cols)
{
DFTable *table = (DFTable *)xcalloc(1,sizeof(DFTable));
table->retainCount = 1;
table->rows = rows;
table->cols = cols;
table->rowElements = (DFNode **)xcalloc(table->rows,sizeof(DFNode *));
table->colWidths = (double *)xcalloc(table->cols,sizeof(double));
table->cells = (DFCell ***)xcalloc(rows,sizeof(DFCell **));
for (unsigned int r = 0; r < table->rows; r++)
table->cells[r] = (DFCell **)xcalloc(cols,sizeof(DFCell *));
return table;
}
DFTable *DFTableRetain(DFTable *table)
{
if (table != NULL)
table->retainCount++;
return table;
}
void DFTableRelease(DFTable *table)
{
if ((table == NULL) || (--table->retainCount > 0))
return;
for (unsigned int r = 0; r < table->rows; r++) {
for (unsigned int c = 0; c < table->cols; c++) {
DFCellRelease(table->cells[r][c]);
}
free(table->cells[r]);
}
free(table->cells);
free(table->rowElements);
free(table->colWidths);
free(table);
}
DFCell *DFTableGetCell(DFTable *table, unsigned int row, unsigned int col)
{
assert((row >= 0) && (row < table->rows));
assert((col >= 0) && (col < table->cols));
return table->cells[row][col];
}
void DFTableSetCell(DFTable *table, unsigned int row, unsigned int col, DFCell *cell)
{
assert((row >= 0) && (row < table->rows));
assert((col >= 0) && (col < table->cols));
if (table->cells[row][col] != cell) {
DFCellRelease(table->cells[row][col]);
table->cells[row][col] = DFCellRetain(cell);
}
}
DFNode *DFTableGetRowElement(DFTable *table, unsigned int row)
{
assert(row < table->rows);
return table->rowElements[row];
}
void DFTableSetRowElement(DFTable *table, DFNode *element, unsigned int row)
{
assert(row < table->rows);
table->rowElements[row] = element;
}
void DFTablePrint(DFTable *table)
{
for (unsigned int row = 0; row < table->rows; row++) {
for (unsigned int col = 0; col < table->cols; col++) {
DFCell *cell = table->cells[row][col];
if (cell == NULL)
printf(" - ");
else
printf(" %5d/%d/%d",cell->element->seqNo,cell->colSpan,cell->rowSpan);
}
printf("\n");
}
}
double DFTableWidthForCol(DFTable *table, unsigned int col)
{
assert(col < table->cols);
if (col < table->cols)
return table->colWidths[col];
else
return 0; // For when assertions are disabled
}
double DFTablePctWidthForCol(DFTable *table, unsigned int col)
{
assert(col < table->cols);
if (col >= table->cols)
return 0; // For when assertions are disabled
if (table->totalColWidths <= 0)
return 0;
else
return 100.0*table->colWidths[col]/table->totalColWidths;
}
void DFTableSetColWidth(DFTable *table, unsigned int col, double width)
{
assert(col < table->cols);
if (col < table->cols) { // For when assertions are disabled
if (width < 0)
width = 0;
table->totalColWidths -= table->colWidths[col];
table->colWidths[col] = width;
table->totalColWidths += table->colWidths[col];
}
}
void DFTableFixZeroWidthCols(DFTable *table)
{
unsigned int nonZeroCols = 0;
for (unsigned int i = 0; i < table->cols; i++) {
if (table->colWidths[i] != 0)
nonZeroCols++;
}
double averageWidth = (nonZeroCols == 0) ? 1 : (table->totalColWidths/nonZeroCols);
for (unsigned int i = 0; i < table->cols; i++) {
if (table->colWidths[i] == 0) {
table->colWidths[i] = averageWidth;
table->totalColWidths += averageWidth;
}
}
}