summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/inc/scmatrix.hxx6
-rw-r--r--sc/source/core/tool/scmatrix.cxx72
-rw-r--r--sc/source/filter/oox/workbookhelper.cxx2
-rw-r--r--sc/source/ui/docshell/externalrefmgr.cxx340
4 files changed, 295 insertions, 125 deletions
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 9287f556b41f..d05743710642 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -160,6 +160,12 @@ public:
#endif
}
+ /** Checks nC or nR for zero and uses GetElementsMax() whether a matrix of
+ the size of nC*nR could be allocated. A zero size (both nC and nR zero)
+ matrix is allowed for later resize.
+ */
+ bool static IsSizeAllocatable( SCSIZE nC, SCSIZE nR );
+
/// Value or boolean.
inline static bool IsValueType( ScMatValType nType )
{
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index e2dde4e53bf3..2bbe9938447a 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -333,14 +333,32 @@ void ScMatrixImpl::Clear()
void ScMatrixImpl::Resize(SCSIZE nC, SCSIZE nR)
{
- maMat.resize(nR, nC);
- maMatFlag.resize(nR, nC);
+ if (ScMatrix::IsSizeAllocatable( nC, nR))
+ {
+ maMat.resize(nR, nC);
+ maMatFlag.resize(nR, nC);
+ }
+ else
+ {
+ // Invalid matrix size, allocate 1x1 matrix with error value.
+ maMat.resize(1, 1, CreateDoubleError( errStackOverflow));
+ maMatFlag.resize(1, 1);
+ }
}
void ScMatrixImpl::Resize(SCSIZE nC, SCSIZE nR, double fVal)
{
- maMat.resize(nR, nC, fVal);
- maMatFlag.resize(nR, nC);
+ if (ScMatrix::IsSizeAllocatable( nC, nR))
+ {
+ maMat.resize(nR, nC, fVal);
+ maMatFlag.resize(nR, nC);
+ }
+ else
+ {
+ // Invalid matrix size, allocate 1x1 matrix with error value.
+ maMat.resize(1, 1, CreateDoubleError( errStackOverflow));
+ maMatFlag.resize(1, 1);
+ }
}
void ScMatrixImpl::SetErrorInterpreter( ScInterpreter* p)
@@ -2225,28 +2243,52 @@ void ScMatrix::DecRef() const
delete this;
}
-ScFullMatrix::ScFullMatrix( SCSIZE nC, SCSIZE nR) :
- ScMatrix(),
- pImpl(new ScMatrixImpl(nC, nR))
+bool ScMatrix::IsSizeAllocatable( SCSIZE nC, SCSIZE nR )
{
SAL_WARN_IF( !nC, "sc", "ScMatrix with 0 columns!");
SAL_WARN_IF( !nR, "sc", "ScMatrix with 0 rows!");
+ // 0-size matrix is valid, it could be resized later.
+ if ((nC && !nR) || (!nC && nR))
+ {
+ SAL_WARN( "sc", "ScMatrix one-dimensional zero: " << nC << " columns * " << nR << " rows");
+ return false;
+ }
+ if (nC && nR && (nC > (ScMatrix::GetElementsMax() / nR)))
+ {
+ SAL_WARN( "sc", "ScMatrix overflow: " << nC << " columns * " << nR << " rows");
+ return false;
+ }
+ return true;
+}
+
+ScFullMatrix::ScFullMatrix( SCSIZE nC, SCSIZE nR) :
+ ScMatrix()
+{
+ if (ScMatrix::IsSizeAllocatable( nC, nR))
+ pImpl.reset( new ScMatrixImpl( nC, nR));
+ else
+ // Invalid matrix size, allocate 1x1 matrix with error value.
+ pImpl.reset( new ScMatrixImpl( 1,1, CreateDoubleError( errStackOverflow)));
}
ScFullMatrix::ScFullMatrix(SCSIZE nC, SCSIZE nR, double fInitVal) :
- ScMatrix(),
- pImpl(new ScMatrixImpl(nC, nR, fInitVal))
+ ScMatrix()
{
- SAL_WARN_IF( !nC, "sc", "ScMatrix with 0 columns!");
- SAL_WARN_IF( !nR, "sc", "ScMatrix with 0 rows!");
+ if (ScMatrix::IsSizeAllocatable( nC, nR))
+ pImpl.reset( new ScMatrixImpl( nC, nR, fInitVal));
+ else
+ // Invalid matrix size, allocate 1x1 matrix with error value.
+ pImpl.reset( new ScMatrixImpl( 1,1, CreateDoubleError( errStackOverflow)));
}
ScFullMatrix::ScFullMatrix( size_t nC, size_t nR, const std::vector<double>& rInitVals ) :
- ScMatrix(),
- pImpl(new ScMatrixImpl(nC, nR, rInitVals))
+ ScMatrix()
{
- SAL_WARN_IF( !nC, "sc", "ScMatrix with 0 columns!");
- SAL_WARN_IF( !nR, "sc", "ScMatrix with 0 rows!");
+ if (ScMatrix::IsSizeAllocatable( nC, nR))
+ pImpl.reset( new ScMatrixImpl( nC, nR, rInitVals));
+ else
+ // Invalid matrix size, allocate 1x1 matrix with error value.
+ pImpl.reset( new ScMatrixImpl( 1,1, CreateDoubleError( errStackOverflow)));
}
ScFullMatrix::~ScFullMatrix()
diff --git a/sc/source/filter/oox/workbookhelper.cxx b/sc/source/filter/oox/workbookhelper.cxx
index 27bee11b41c2..99b889af7274 100644
--- a/sc/source/filter/oox/workbookhelper.cxx
+++ b/sc/source/filter/oox/workbookhelper.cxx
@@ -604,7 +604,7 @@ void WorkbookGlobals::initialize( bool bWorkbookFile )
// #i76026# disable Undo while loading the document
mpDoc->EnableUndo(false);
// #i79826# disable calculating automatic row height while loading the document
- mpDoc->EnableAdjustHeight(true);
+ mpDoc->EnableAdjustHeight(false);
// disable automatic update of linked sheets and DDE links
mpDoc->EnableExecuteLink(false);
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 90b570327876..65065ab74cb8 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -580,9 +580,9 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
const ScAddress& s = rRange.aStart;
const ScAddress& e = rRange.aEnd;
- SCTAB nTab1 = s.Tab(), nTab2 = e.Tab();
- SCCOL nCol1 = s.Col(), nCol2 = e.Col();
- SCROW nRow1 = s.Row(), nRow2 = e.Row();
+ const SCTAB nTab1 = s.Tab(), nTab2 = e.Tab();
+ const SCCOL nCol1 = s.Col(), nCol2 = e.Col();
+ const SCROW nRow1 = s.Row(), nRow2 = e.Row();
// Make sure I have all the tables cached.
size_t nTabFirstId = itrTabId->second;
@@ -616,58 +616,120 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
return TokenArrayRef();
}
- ScMatrixRef xMat = new ScFullMatrix(
- static_cast<SCSIZE>(nDataCol2-nDataCol1+1), static_cast<SCSIZE>(nDataRow2-nDataRow1+1));
+ SCSIZE nMatrixColumns = static_cast<SCSIZE>(nDataCol2-nDataCol1+1);
+ SCSIZE nMatrixRows = static_cast<SCSIZE>(nDataRow2-nDataRow1+1);
+ ScMatrixRef xMat = new ScFullMatrix( nMatrixColumns, nMatrixRows);
- // Only fill non-empty cells, for better performance.
+ // Needed in shrink and fill.
vector<SCROW> aRows;
pTab->getAllRows(aRows, nDataRow1, nDataRow2);
- for (vector<SCROW>::const_iterator itr = aRows.begin(), itrEnd = aRows.end(); itr != itrEnd; ++itr)
+ bool bFill = true;
+
+ // Check if size could be allocated and if not skip the fill, there's
+ // one error element instead. But retry first with the actual data area
+ // if that is smaller than the original range, which works for most
+ // functions just not some that operate/compare with the original size
+ // and expect empty values in non-data areas.
+ // Restrict this though to ranges of entire columns or rows, other
+ // ranges might be on purpose. (Other special cases to handle?)
+ /* TODO: sparse matrix could help */
+ SCSIZE nMatCols, nMatRows;
+ xMat->GetDimensions( nMatCols, nMatRows);
+ if (nMatCols != nMatrixColumns || nMatRows != nMatrixRows)
{
- SCROW nRow = *itr;
- vector<SCCOL> aCols;
- pTab->getAllCols(nRow, aCols, nDataCol1, nDataCol2);
- for (vector<SCCOL>::const_iterator itrCol = aCols.begin(), itrColEnd = aCols.end(); itrCol != itrColEnd; ++itrCol)
+ bFill = false;
+ if (aRows.empty())
{
- SCCOL nCol = *itrCol;
- TokenRef pToken = pTab->getCell(nCol, nRow);
- if (!pToken)
- // This should never happen!
- return TokenArrayRef();
-
- SCSIZE nC = nCol - nDataCol1, nR = nRow - nDataRow1;
- switch (pToken->GetType())
+ // There's no data at all. Set the one matrix element to empty
+ // for column-repeated and row-repeated access.
+ xMat->PutEmpty(0,0);
+ }
+ else if ((nCol1 == 0 && nCol2 == MAXCOL) || (nRow1 == 0 && nRow2 == MAXROW))
+ {
+ nDataRow1 = aRows.front();
+ nDataRow2 = aRows.back();
+ SCCOL nMinCol = std::numeric_limits<SCCOL>::max();
+ SCCOL nMaxCol = std::numeric_limits<SCCOL>::min();
+ for (vector<SCROW>::const_iterator itr = aRows.begin(), itrEnd = aRows.end(); itr != itrEnd; ++itr)
+ {
+ vector<SCCOL> aCols;
+ pTab->getAllCols(*itr, aCols, nDataCol1, nDataCol2);
+ if (!aCols.empty())
+ {
+ nMinCol = std::min( nMinCol, aCols.front());
+ nMaxCol = std::max( nMaxCol, aCols.back());
+ }
+ }
+
+ if (nMinCol <= nMaxCol && ((static_cast<SCSIZE>(nMaxCol-nMinCol+1) < nMatrixColumns) ||
+ (static_cast<SCSIZE>(nDataRow2-nDataRow1+1) < nMatrixRows)))
{
- case svDouble:
- xMat->PutDouble(pToken->GetDouble(), nC, nR);
- break;
- case svString:
- xMat->PutString(pToken->GetString(), nC, nR);
- break;
- default:
- ;
+ nMatrixColumns = static_cast<SCSIZE>(nMaxCol-nMinCol+1);
+ nMatrixRows = static_cast<SCSIZE>(nDataRow2-nDataRow1+1);
+ xMat = new ScFullMatrix( nMatrixColumns, nMatrixRows);
+ xMat->GetDimensions( nMatCols, nMatRows);
+ if (nMatCols == nMatrixColumns && nMatRows == nMatrixRows)
+ {
+ nDataCol1 = nMinCol;
+ nDataCol2 = nMaxCol;
+ bFill = true;
+ }
}
}
}
- if (!bFirstTab)
- pArray->AddOpCode(ocSep);
+ if (bFill)
+ {
+ // Only fill non-empty cells, for better performance.
+ for (vector<SCROW>::const_iterator itr = aRows.begin(), itrEnd = aRows.end(); itr != itrEnd; ++itr)
+ {
+ SCROW nRow = *itr;
+ vector<SCCOL> aCols;
+ pTab->getAllCols(nRow, aCols, nDataCol1, nDataCol2);
+ for (vector<SCCOL>::const_iterator itrCol = aCols.begin(), itrColEnd = aCols.end(); itrCol != itrColEnd; ++itrCol)
+ {
+ SCCOL nCol = *itrCol;
+ TokenRef pToken = pTab->getCell(nCol, nRow);
+ if (!pToken)
+ // This should never happen!
+ return TokenArrayRef();
+
+ SCSIZE nC = nCol - nDataCol1, nR = nRow - nDataRow1;
+ switch (pToken->GetType())
+ {
+ case svDouble:
+ xMat->PutDouble(pToken->GetDouble(), nC, nR);
+ break;
+ case svString:
+ xMat->PutString(pToken->GetString(), nC, nR);
+ break;
+ default:
+ ;
+ }
+ }
+ }
- ScMatrixToken aToken(xMat);
- if (!pArray)
- pArray.reset(new ScTokenArray);
- pArray->AddToken(aToken);
+ if (!bFirstTab)
+ pArray->AddOpCode(ocSep);
- bFirstTab = false;
+ ScMatrixToken aToken(xMat);
+ if (!pArray)
+ pArray.reset(new ScTokenArray);
+ pArray->AddToken(aToken);
- if (!pNewRange)
- pNewRange.reset(new ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0));
- else
- pNewRange->ExtendTo(ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0));
+ bFirstTab = false;
+
+ if (!pNewRange)
+ pNewRange.reset(new ScRange(nDataCol1, nDataRow1, nTab, nDataCol2, nDataRow2, nTab));
+ else
+ pNewRange->ExtendTo(ScRange(nDataCol1, nDataRow1, nTab, nDataCol2, nDataRow2, nTab));
+ }
}
- if (pNewRange)
+ rDoc.maRangeArrays.insert( RangeArrayMap::value_type(aCacheRange, pArray));
+ if (pNewRange && *pNewRange != aCacheRange)
rDoc.maRangeArrays.insert( RangeArrayMap::value_type(*pNewRange, pArray));
+
return pArray;
}
@@ -791,37 +853,56 @@ void ScExternalRefCache::setCellRangeData(sal_uInt16 nFileId, const ScRange& rRa
pTabData.reset(new Table);
const ScMatrixRef& pMat = itrData->mpRangeData;
- for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
+ SCSIZE nMatCols, nMatRows;
+ pMat->GetDimensions( nMatCols, nMatRows);
+ if (nMatCols > static_cast<SCSIZE>(nCol2 - nCol1) && nMatRows > static_cast<SCSIZE>(nRow2 - nRow1))
{
- const SCSIZE nR = nRow - nRow1;
- for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+ for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
{
- const SCSIZE nC = nCol - nCol1;
+ const SCSIZE nR = nRow - nRow1;
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+ {
+ const SCSIZE nC = nCol - nCol1;
- ScMatrixValue value = pMat->Get(nC, nR);
+ ScMatrixValue value = pMat->Get(nC, nR);
- TokenRef pToken;
+ TokenRef pToken;
- switch (value.nType) {
- case SC_MATVAL_VALUE:
- case SC_MATVAL_BOOLEAN:
- pToken.reset(new formula::FormulaDoubleToken(value.fVal));
- break;
- case SC_MATVAL_STRING:
- pToken.reset(new formula::FormulaStringToken(value.aStr));
- break;
- default:
- // Don't cache empty cells.
- break;
- }
+ switch (value.nType) {
+ case SC_MATVAL_VALUE:
+ case SC_MATVAL_BOOLEAN:
+ pToken.reset(new formula::FormulaDoubleToken(value.fVal));
+ break;
+ case SC_MATVAL_STRING:
+ pToken.reset(new formula::FormulaStringToken(value.aStr));
+ break;
+ default:
+ // Don't cache empty cells.
+ break;
+ }
- if (pToken)
- // Don't mark this cell 'cached' here, for better performance.
- pTabData->setCell(nCol, nRow, pToken, 0, false);
+ if (pToken)
+ // Don't mark this cell 'cached' here, for better performance.
+ pTabData->setCell(nCol, nRow, pToken, 0, false);
+ }
+ }
+ // Mark the whole range 'cached'.
+ pTabData->setCachedCellRange(nCol1, nRow1, nCol2, nRow2);
+ }
+ else
+ {
+ // This may happen due to a matrix not been allocated earlier, in
+ // which case it should have exactly one error element.
+ SAL_WARN("sc.ui","ScExternalRefCache::setCellRangeData - matrix size mismatch");
+ if (nMatCols != 1 || nMatRows != 1)
+ SAL_WARN("sc.ui","ScExternalRefCache::setCellRangeData - not a one element matrix");
+ else
+ {
+ sal_uInt16 nErr = GetDoubleErrorValue( pMat->GetDouble(0,0));
+ SAL_WARN("sc.ui","ScExternalRefCache::setCellRangeData - matrix error value is " << nErr <<
+ (nErr ? ", ok" : ", not ok"));
}
}
- // Mark the whole range 'cached'.
- pTabData->setCachedCellRange(nCol1, nRow1, nCol2, nRow2);
}
size_t nTabLastId = nTabFirstId + rRange.aEnd.Tab() - rRange.aStart.Tab();
@@ -1467,9 +1548,9 @@ static std::unique_ptr<ScTokenArray> convertToTokenArray(
ScAddress& s = rRange.aStart;
ScAddress& e = rRange.aEnd;
- SCTAB nTab1 = s.Tab(), nTab2 = e.Tab();
- SCCOL nCol1 = s.Col(), nCol2 = e.Col();
- SCROW nRow1 = s.Row(), nRow2 = e.Row();
+ const SCTAB nTab1 = s.Tab(), nTab2 = e.Tab();
+ const SCCOL nCol1 = s.Col(), nCol2 = e.Col();
+ const SCROW nRow1 = s.Row(), nRow2 = e.Row();
if (nTab2 != nTab1)
// For now, we don't support multi-sheet ranges intentionally because
@@ -1502,62 +1583,103 @@ static std::unique_ptr<ScTokenArray> convertToTokenArray(
else
pUsedRange.reset(new ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0));
- ScMatrixRef xMat = new ScFullMatrix(
- static_cast<SCSIZE>(nCol2-nCol1+1), static_cast<SCSIZE>(nRow2-nRow1+1));
-
- ColumnBatch<svl::SharedString> aStringBatch(pHostDoc, pSrcDoc, CELLTYPE_STRING, CELLTYPE_EDIT);
- ColumnBatch<double> aDoubleBatch(pHostDoc, pSrcDoc, CELLTYPE_VALUE, CELLTYPE_VALUE);
+ SCSIZE nMatrixColumns = static_cast<SCSIZE>(nCol2-nCol1+1);
+ SCSIZE nMatrixRows = static_cast<SCSIZE>(nRow2-nRow1+1);
+ ScMatrixRef xMat = new ScFullMatrix( nMatrixColumns, nMatrixRows);
+
+ bool bFill = true;
+ SCCOL nEffectiveCol1 = nCol1;
+ SCROW nEffectiveRow1 = nRow1;
+
+ // Check if size could be allocated and if not skip the fill, there's
+ // one error element instead. But retry first with the actual data area
+ // if that is smaller than the original range, which works for most
+ // functions just not some that operate/compare with the original size
+ // and expect empty values in non-data areas.
+ // Restrict this though to ranges of entire columns or rows, other
+ // ranges might be on purpose. (Other special cases to handle?)
+ /* TODO: sparse matrix could help */
+ SCSIZE nMatCols, nMatRows;
+ xMat->GetDimensions( nMatCols, nMatRows);
+ if (nMatCols != nMatrixColumns || nMatRows != nMatrixRows)
+ {
+ bFill = false;
+ if ((nCol1 == 0 && nCol2 == MAXCOL) || (nRow1 == 0 && nRow2 == MAXROW))
+ {
+ if ((static_cast<SCSIZE>(nDataCol2-nDataCol1+1) < nMatrixColumns) ||
+ (static_cast<SCSIZE>(nDataRow2-nDataRow1+1) < nMatrixRows))
+ {
+ nMatrixColumns = static_cast<SCSIZE>(nDataCol2-nDataCol1+1);
+ nMatrixRows = static_cast<SCSIZE>(nDataRow2-nDataRow1+1);
+ xMat = new ScFullMatrix( nMatrixColumns, nMatrixRows);
+ xMat->GetDimensions( nMatCols, nMatRows);
+ if (nMatCols == nMatrixColumns && nMatRows == nMatrixRows)
+ {
+ nEffectiveCol1 = nDataCol1;
+ nEffectiveRow1 = nDataRow1;
+ bFill = true;
+ }
+ }
+ }
+ }
- for (SCCOL nCol = nDataCol1; nCol <= nDataCol2; ++nCol)
+ if (bFill)
{
- const SCSIZE nC = nCol - nCol1;
- for (SCROW nRow = nDataRow1; nRow <= nDataRow2; ++nRow)
+ ColumnBatch<svl::SharedString> aStringBatch(pHostDoc, pSrcDoc, CELLTYPE_STRING, CELLTYPE_EDIT);
+ ColumnBatch<double> aDoubleBatch(pHostDoc, pSrcDoc, CELLTYPE_VALUE, CELLTYPE_VALUE);
+
+ for (SCCOL nCol = nDataCol1; nCol <= nDataCol2; ++nCol)
{
- const SCSIZE nR = nRow - nRow1;
+ const SCSIZE nC = nCol - nEffectiveCol1;
+ for (SCROW nRow = nDataRow1; nRow <= nDataRow2; ++nRow)
+ {
+ const SCSIZE nR = nRow - nEffectiveRow1;
- ScRefCellValue aCell(*pSrcDoc, ScAddress(nCol, nRow, nTab));
+ ScRefCellValue aCell(*pSrcDoc, ScAddress(nCol, nRow, nTab));
- aStringBatch.update(aCell, nC, nR, xMat);
- aDoubleBatch.update(aCell, nC, nR, xMat);
+ aStringBatch.update(aCell, nC, nR, xMat);
+ aDoubleBatch.update(aCell, nC, nR, xMat);
- if (aCell.hasEmptyValue())
- // Skip empty cells. Matrix's default values are empty elements.
- continue;
+ if (aCell.hasEmptyValue())
+ // Skip empty cells. Matrix's default values are empty elements.
+ continue;
- switch (aCell.meType)
- {
- case CELLTYPE_FORMULA:
+ switch (aCell.meType)
{
- ScFormulaCell* pFCell = aCell.mpFormula;
- sal_uInt16 nError = pFCell->GetErrCode();
- if (nError)
- xMat->PutDouble( CreateDoubleError( nError), nC, nR);
- else if (pFCell->IsValue())
- {
- double fVal = pFCell->GetValue();
- xMat->PutDouble(fVal, nC, nR);
- }
- else
- {
- svl::SharedString aStr = pFCell->GetString();
- aStr = pHostDoc->GetSharedStringPool().intern(aStr.getString());
- xMat->PutString(aStr, nC, nR);
- }
+ case CELLTYPE_FORMULA:
+ {
+ ScFormulaCell* pFCell = aCell.mpFormula;
+ sal_uInt16 nError = pFCell->GetErrCode();
+ if (nError)
+ xMat->PutDouble( CreateDoubleError( nError), nC, nR);
+ else if (pFCell->IsValue())
+ {
+ double fVal = pFCell->GetValue();
+ xMat->PutDouble(fVal, nC, nR);
+ }
+ else
+ {
+ svl::SharedString aStr = pFCell->GetString();
+ aStr = pHostDoc->GetSharedStringPool().intern(aStr.getString());
+ xMat->PutString(aStr, nC, nR);
+ }
+ }
+ break;
+ // These are handled in batch:
+ case CELLTYPE_VALUE:
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ break;
+ default:
+ OSL_FAIL("attempted to convert an unknown cell type.");
}
- break;
- // These are handled in batch:
- case CELLTYPE_VALUE:
- case CELLTYPE_STRING:
- case CELLTYPE_EDIT:
- break;
- default:
- OSL_FAIL("attempted to convert an unknown cell type.");
}
- }
- aStringBatch.flush(nC, xMat);
- aDoubleBatch.flush(nC, xMat);
+ aStringBatch.flush(nC, xMat);
+ aDoubleBatch.flush(nC, xMat);
+ }
}
+
if (!bFirstTab)
pArray->AddOpCode(ocSep);