sc/inc/fillinfo.hxx              |   30 +++++-
 sc/source/core/data/fillinfo.cxx |  191 ++++++++++++++++++---------------------
 sc/source/ui/inc/output.hxx      |    2 
 sc/source/ui/view/gridwin4.cxx   |    4 
 sc/source/ui/view/output.cxx     |  161 +++++++++++++++-----------------
 sc/source/ui/view/output2.cxx    |   68 ++++++-------
 sc/source/ui/view/printfun.cxx   |    6 -
 7 files changed, 237 insertions(+), 225 deletions(-)

New commits:
commit d48e68407931fc33044aa7f3fc9e971897fac610
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Tue Feb 8 20:02:04 2022 +0100
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Thu Feb 10 09:38:54 2022 +0100

    clean up accessing CellInfo array in RowInfo
    
    The array allocates one extra item before and after, which means
    all indexing must add 1 to column number. And a lot of the code
    uses array index variables instead of column numbers, which
    makes it confusing whether the value is +1 or not. To sort this
    out, hide the array inside RowInfo and provide access functions
    that will hide those +1 from caller code, plus it will do error
    checking.
    
    Change-Id: Ia91bd76e15fc6c96c09f27c742d71001f4c4151c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129698
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/sc/inc/fillinfo.hxx b/sc/inc/fillinfo.hxx
index 9c8681d8f43e..e5926808bf60 100644
--- a/sc/inc/fillinfo.hxx
+++ b/sc/inc/fillinfo.hxx
@@ -176,7 +176,26 @@ struct RowInfo
     RowInfo(const RowInfo&) = delete;
     const RowInfo& operator=(const RowInfo&) = delete;
 
-    CellInfo*           pCellInfo;
+    CellInfo&           cellInfo(SCCOL nCol)
+    {
+#ifdef DBG_UTIL
+        assert( nCol >= -1 && nCol <= nCols + 1 );
+#endif
+        return pCellInfo[ nCol + 1 ];
+    }
+    const CellInfo&     cellInfo(SCCOL nCol) const
+    {
+        return const_cast<RowInfo*>(this)->cellInfo(nCol);
+    }
+
+    void                allocCellInfo(SCCOL cols)
+    {
+#ifdef DBG_UTIL
+        nCols = cols;
+#endif
+        pCellInfo = new CellInfo[ cols + 2 ];
+    }
+    void                freeCellInfo() { delete[] pCellInfo; }
 
     sal_uInt16          nHeight;
     SCROW               nRowNo;
@@ -186,6 +205,15 @@ struct RowInfo
     bool                bAutoFilter:1;
     bool                bPivotButton:1;
     bool                bChanged:1;           // TRUE, if not tested
+
+private:
+    // This class allocates CellInfo with also one item extra before and after.
+    // To make handling easier, this is private and access functions take care 
of adjusting
+    // the array indexes and error-checking.
+    CellInfo*           pCellInfo;
+#ifdef DBG_UTIL
+    SCCOL               nCols;
+#endif
 };
 
 struct ScTableInfo
diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx
index e8480553fef3..1dca158f1e28 100644
--- a/sc/source/core/data/fillinfo.cxx
+++ b/sc/source/core/data/fillinfo.cxx
@@ -53,7 +53,7 @@ static void lcl_GetMergeRange( SCCOL nX, SCROW nY, SCSIZE 
nArrY,
                             SCCOL nX1, SCROW nY1, SCTAB nTab,
                             SCCOL& rStartX, SCROW& rStartY, SCCOL& rEndX, 
SCROW& rEndY )
 {
-    CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nX+1];
+    CellInfo* pInfo = &pRowInfo[nArrY].cellInfo(nX);
 
     rStartX = nX;
     rStartY = nY;
@@ -67,8 +67,8 @@ static void lcl_GetMergeRange( SCCOL nX, SCROW nY, SCSIZE 
nArrY,
         --rStartX;
         if (rStartX >= nX1 && !pDoc->ColHidden(rStartX, nTab, nullptr, 
&nLastCol))
         {
-            bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped;
-            bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
+            bHOver = pRowInfo[nArrY].cellInfo(rStartX).bHOverlapped;
+            bVOver = pRowInfo[nArrY].cellInfo(rStartX).bVOverlapped;
         }
         else
         {
@@ -90,7 +90,7 @@ static void lcl_GetMergeRange( SCCOL nX, SCROW nY, SCSIZE 
nArrY,
             !pDoc->RowHidden(rStartY, nTab, nullptr, &nLastRow) &&
             pRowInfo[nArrY].nRowNo == rStartY)
         {
-            bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped;
+            bVOver = pRowInfo[nArrY].cellInfo(rStartX).bVOverlapped;
         }
         else
         {
@@ -106,7 +106,7 @@ static void lcl_GetMergeRange( SCCOL nX, SCROW nY, SCSIZE 
nArrY,
         !pDoc->RowHidden(rStartY, nTab, nullptr, &nLastRow) &&
         pRowInfo[nArrY].nRowNo == rStartY)
     {
-        pMerge = &pRowInfo[nArrY].pCellInfo[rStartX+1].pPatternAttr->
+        pMerge = &pRowInfo[nArrY].cellInfo(rStartX).pPatternAttr->
                                         GetItem(ATTR_MERGE);
     }
     else
@@ -123,7 +123,7 @@ class RowInfoFiller
     ScDocument& mrDoc;
     SCTAB mnTab;
     RowInfo* mpRowInfo;
-    SCCOL mnArrX;
+    SCCOL mnCol;
     SCSIZE mnArrY;
     SCROW mnHiddenEndRow;
     bool mbHiddenRow;
@@ -147,15 +147,15 @@ class RowInfoFiller
         alignArray(nRow);
 
         RowInfo& rThisRowInfo = mpRowInfo[mnArrY];
-        CellInfo& rInfo = rThisRowInfo.pCellInfo[mnArrX];
+        CellInfo& rInfo = rThisRowInfo.cellInfo(mnCol);
         rInfo.maCell = rCell;
         rInfo.bEmptyCellText = false;
         ++mnArrY;
     }
 
 public:
-    RowInfoFiller(ScDocument& rDoc, SCTAB nTab, RowInfo* pRowInfo, SCCOL 
nArrX, SCSIZE nArrY) :
-        mrDoc(rDoc), mnTab(nTab), mpRowInfo(pRowInfo), mnArrX(nArrX), 
mnArrY(nArrY),
+    RowInfoFiller(ScDocument& rDoc, SCTAB nTab, RowInfo* pRowInfo, SCCOL nCol, 
SCSIZE nArrY) :
+        mrDoc(rDoc), mnTab(nTab), mpRowInfo(pRowInfo), mnCol(nCol), 
mnArrY(nArrY),
         mnHiddenEndRow(-1), mbHiddenRow(false) {}
 
     void operator() (size_t nRow, double fVal)
@@ -212,7 +212,7 @@ void initRowInfo(const ScDocument* pDoc, RowInfo* pRowInfo, 
const SCSIZE nMaxRow
         if ( rArrRow==0 || nDocHeight || nY > pDoc->MaxRow() )
         {
             RowInfo* pThisRowInfo = &pRowInfo[rArrRow];
-            pThisRowInfo->pCellInfo = nullptr;                 // is loaded 
below
+            // pThisRowInfo->pCellInfo is set below using allocCellInfo()
 
             sal_uInt16 nHeight = static_cast<sal_uInt16>(
                 std::clamp(
@@ -246,11 +246,11 @@ void initCellInfo(RowInfo* pRowInfo, SCSIZE nArrCount, 
SCCOL nRotMax,
     for (SCSIZE nArrRow = 0; nArrRow < nArrCount; ++nArrRow)
     {
         RowInfo& rThisRowInfo = pRowInfo[nArrRow];
-        rThisRowInfo.pCellInfo = new CellInfo[nRotMax + 1 + 2];  // to delete 
the caller!
+        rThisRowInfo.allocCellInfo( nRotMax + 1 );
 
-        for (SCCOL nArrCol = 0; nArrCol <= nRotMax+2; ++nArrCol) // Preassign 
cell info
+        for (SCCOL nCol = -1; nCol <= nRotMax+1; ++nCol) // Preassign cell info
         {
-            CellInfo& rInfo = rThisRowInfo.pCellInfo[nArrCol];
+            CellInfo& rInfo = rThisRowInfo.cellInfo(nCol);
             rInfo.bEmptyCellText = true;
             rInfo.pShadowAttr    = pDefShadow;
         }
@@ -259,18 +259,17 @@ void initCellInfo(RowInfo* pRowInfo, SCSIZE nArrCount, 
SCCOL nRotMax,
 
 void initColWidths(RowInfo* pRowInfo, const ScDocument* pDoc, double 
fColScale, SCTAB nTab, SCCOL nCol2, SCCOL nRotMax)
 {
-    for (SCCOL nArrCol=nCol2+3; nArrCol<=nRotMax+2; nArrCol++)    // Add 
remaining widths
+    for (SCCOL nCol=nCol2+2; nCol<=nRotMax+1; nCol++)    // Add remaining 
widths
     {
-        SCCOL nX = nArrCol-1;
-        if ( pDoc->ValidCol(nX) )
+        if ( pDoc->ValidCol(nCol) )
         {
-            if (!pDoc->ColHidden(nX, nTab))
+            if (!pDoc->ColHidden(nCol, nTab))
             {
-                sal_uInt16 nThisWidth = 
static_cast<sal_uInt16>(pDoc->GetColWidth( nX, nTab ) * fColScale);
+                sal_uInt16 nThisWidth = 
static_cast<sal_uInt16>(pDoc->GetColWidth( nCol, nTab ) * fColScale);
                 if (!nThisWidth)
                     nThisWidth = 1;
 
-                pRowInfo[0].pCellInfo[nArrCol].nWidth = nThisWidth;
+                pRowInfo[0].cellInfo(nCol).nWidth = nThisWidth;
             }
         }
     }
@@ -395,7 +394,7 @@ void ScDocument::FillInfo(
 
         OSL_ENSURE( nArrCount>2, "nArrCount too small" );
         FindMaxRotCol( nTab, &pRowInfo[1], nArrCount-1, nCol1, nCol2 );
-        //  FindMaxRotCol setzt nRotMaxCol
+        //  FindMaxRotCol sets nRotMaxCol
 
         for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
             if (pRowInfo[nArrRow].nRotMaxCol != SC_ROTMAX_NONE && 
pRowInfo[nArrRow].nRotMaxCol > nRotMax)
@@ -412,31 +411,29 @@ void ScDocument::FillInfo(
     if (pCondFormList)
         pCondFormList->startRendering();
 
-    for (SCCOL nArrCol=0; nArrCol<=nCol2+2; nArrCol++)                    // 
left & right + 1
+    for (SCCOL nCol=-1; nCol<=nCol2+1; nCol++)                    // left & 
right + 1
     {
-        SCCOL nX = (nArrCol>0) ? nArrCol-1 : MaxCol()+1;                    // 
negative -> invalid
-
-        if (ValidCol(nX))
+        if (ValidCol(nCol))
         {
             // #i58049#, #i57939# Hidden columns must be skipped here, or 
their attributes
             // will disturb the output
 
             // TODO: Optimize this loop.
-            if (!ColHidden(nX, nTab))
+            if (!ColHidden(nCol, nTab))
             {
-                sal_uInt16 nThisWidth = 
static_cast<sal_uInt16>(std::clamp(GetColWidth( nX, nTab ) * fColScale, 1.0, 
double(std::numeric_limits<sal_uInt16>::max())));
+                sal_uInt16 nThisWidth = 
static_cast<sal_uInt16>(std::clamp(GetColWidth( nCol, nTab ) * fColScale, 1.0, 
double(std::numeric_limits<sal_uInt16>::max())));
 
-                pRowInfo[0].pCellInfo[nArrCol].nWidth = nThisWidth;           
//TODO: this should be enough
+                pRowInfo[0].cellInfo(nCol).nWidth = nThisWidth;           
//TODO: this should be enough
 
                 const ScAttrArray* pThisAttrArr; // Attribute
-                if (nX < maTabs[nTab]->GetAllocatedColumnsCount())
+                if (nCol < maTabs[nTab]->GetAllocatedColumnsCount())
                 {
-                    ScColumn* pThisCol = &maTabs[nTab]->aCol[nX]; // Column 
data
+                    ScColumn* pThisCol = &maTabs[nTab]->aCol[nCol]; // Column 
data
 
                     nArrRow = 1;
                     // Iterate between rows nY1 and nY2 and pick up non-empty
                     // cells that are not hidden.
-                    RowInfoFiller aFunc(*this, nTab, pRowInfo, nArrCol, 
nArrRow);
+                    RowInfoFiller aFunc(*this, nTab, pRowInfo, nCol, nArrRow);
                     sc::ParseAllNonEmpty(pThisCol->maCells.begin(), 
pThisCol->maCells, nRow1, nRow2,
                                          aFunc);
 
@@ -445,7 +442,7 @@ void ScDocument::FillInfo(
                 else
                     pThisAttrArr = &maTabs[nTab]->aDefaultColAttrArray;
 
-                if (nX+1 >= nCol1)                                // 
Attribute/Blockmark from nX1-1
+                if (nCol+1 >= nCol1)                                // 
Attribute/Blockmark from nX1-1
                 {
                     nArrRow = 0;
 
@@ -519,7 +516,7 @@ void ScDocument::FillInfo(
                             bool bRowHidden = RowHidden(nCurRow, nTab, 
nullptr, &nLastHiddenRow);
                             if ( nArrRow==0 || !bRowHidden )
                             {
-                                if ( GetPreviewCellStyle( nX, nCurRow, nTab  ) 
!= nullptr )
+                                if ( GetPreviewCellStyle( nCol, nCurRow, nTab  
) != nullptr )
                                     bAnyPreview = true;
                                 RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
                                 if (pBackground != pDefBackground)          // 
Column background == Default ?
@@ -531,7 +528,7 @@ void ScDocument::FillInfo(
                                 if (bPivotButton || bPivotPopupButton)
                                     pThisRowInfo->bPivotButton = true;
 
-                                CellInfo* pInfo = 
&pThisRowInfo->pCellInfo[nArrCol];
+                                CellInfo* pInfo = 
&pThisRowInfo->cellInfo(nCol);
                                 pInfo->pBackground  = pBackground;
                                 pInfo->pPatternAttr = pPattern;
                                 pInfo->bMerged      = bMerged;
@@ -555,7 +552,7 @@ void ScDocument::FillInfo(
 
                                 if (bContainsCondFormat && pCondFormList)
                                 {
-                                    bAnyCondition |= 
handleConditionalFormat(*pCondFormList, rCondFormats, pInfo, pStlPool, 
ScAddress(nX, nCurRow, nTab),
+                                    bAnyCondition |= 
handleConditionalFormat(*pCondFormList, rCondFormats, pInfo, pStlPool, 
ScAddress(nCol, nCurRow, nTab),
                                             bHidden, bHideFormula, 
bTabProtect);
                                 }
 
@@ -580,7 +577,7 @@ void ScDocument::FillInfo(
                     if (pMarkData && pMarkData->IsMultiMarked())
                     {
                         //  Block marks
-                        ScMarkArray aThisMarkArr(pMarkData->GetMarkArray( nX 
));
+                        ScMarkArray aThisMarkArr(pMarkData->GetMarkArray( nCol 
));
                         nArrRow = 1;
                         nCurRow = nRow1;                                      
// single rows
 
@@ -610,7 +607,7 @@ void ScDocument::FillInfo(
                     for (nArrRow=1; nArrRow+1<nArrCount; nArrRow++)
                     {
                         RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
-                        CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
+                        CellInfo* pInfo = &pThisRowInfo->cellInfo(nCol);
 
                         pInfo->nWidth       = nThisWidth;           //TODO: or 
check only 0 ??
                     }
@@ -618,7 +615,7 @@ void ScDocument::FillInfo(
             }
         }
         else
-            pRowInfo[0].pCellInfo[nArrCol].nWidth = STD_COL_WIDTH;
+            pRowInfo[0].cellInfo(nCol).nWidth = STD_COL_WIDTH;
         // STD_COL_WIDTH farthest to the left and right is needed for 
DrawExtraShadow
     }
 
@@ -632,10 +629,9 @@ void ScDocument::FillInfo(
     {
         for (nArrRow=0; nArrRow<nArrCount; nArrRow++)
         {
-            for (SCCOL nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++)             
     // 1 more left and right
+            for (SCCOL nCol=nCol1-1; nCol<=nCol2+1; nCol++)                  
// 1 more left and right
             {
-                CellInfo* pInfo = &pRowInfo[nArrRow].pCellInfo[nArrCol];
-                SCCOL nCol = (nArrCol>0) ? nArrCol-1 : MaxCol()+1;
+                CellInfo* pInfo = &pRowInfo[nArrRow].cellInfo(nCol);
                 ScPatternAttr* pModifiedPatt = nullptr;
 
                 if ( ValidCol(nCol) && pRowInfo[nArrRow].nRowNo <= MaxRow() )
@@ -697,10 +693,9 @@ void ScDocument::FillInfo(
             RowInfo* pThisRowInfo = &pRowInfo[nArrRow];
             SCROW nSignedY = nArrRow ? pThisRowInfo->nRowNo : nRow1-1;
 
-            for (SCCOL nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++)             
     // 1 more left and right
+            for (SCCOL nCol=nCol1-1; nCol<=nCol2+1; nCol++)                  
// 1 more left and right
             {
-                SCCOL nSignedX = nArrCol - 1;
-                CellInfo* pInfo = &pThisRowInfo->pCellInfo[nArrCol];
+                CellInfo* pInfo = &pThisRowInfo->cellInfo(nCol);
 
                 if (pInfo->bMerged || pInfo->bHOverlapped || 
pInfo->bVOverlapped)
                 {
@@ -708,7 +703,7 @@ void ScDocument::FillInfo(
                     SCROW nStartY;
                     SCCOL nEndX;
                     SCROW nEndY;
-                    lcl_GetMergeRange( nSignedX,nSignedY, nArrRow, 
this,pRowInfo, nCol1,nRow1,nTab,
+                    lcl_GetMergeRange( nCol,nSignedY, nArrRow, this,pRowInfo, 
nCol1,nRow1,nTab,
                                         nStartX,nStartY, nEndX,nEndY );
                     const ScPatternAttr* pStartPattern = GetPattern( 
nStartX,nStartY,nTab );
                     const SfxItemSet* pStartCond = GetCondResult( 
nStartX,nStartY,nTab );
@@ -742,12 +737,12 @@ void ScDocument::FillInfo(
             bool bTop = ( nArrRow == 0 );
             bool bBottom = ( nArrRow+1 == nArrCount );
 
-            for (SCCOL nArrCol=nCol1; nArrCol<=nCol2+2; nArrCol++)             
     // 1 more left and right
+            for (SCCOL nCol=nCol1-1; nCol<=nCol2+1; nCol++)                  
// 1 more left and right
             {
-                bool bLeft = ( nArrCol == nCol1 );
-                bool bRight = ( nArrCol == nCol2+2 );
+                bool bLeft = ( nCol == nCol1-1 );
+                bool bRight = ( nCol == nCol2+1 );
 
-                CellInfo* pInfo = &pRowInfo[nArrRow].pCellInfo[nArrCol];
+                CellInfo* pInfo = &pRowInfo[nArrRow].cellInfo(nCol);
                 const SvxShadowItem* pThisAttr = pInfo->pShadowAttr;
                 SvxShadowLocation eLoc = pThisAttr ? pThisAttr->GetLocation() 
: SvxShadowLocation::NONE;
                 if (eLoc != SvxShadowLocation::NONE)
@@ -757,19 +752,19 @@ void ScDocument::FillInfo(
                     SCCOL nDxPos = 1;
                     SCCOL nDxNeg = -1;
 
-                    while ( nArrCol+nDxPos < nCol2+2 && 
pRowInfo[0].pCellInfo[nArrCol+nDxPos].nWidth == 0 )
+                    while ( nCol+nDxPos < nCol2+1 && 
pRowInfo[0].cellInfo(nCol+nDxPos).nWidth == 0 )
                         ++nDxPos;
-                    while ( nArrCol+nDxNeg > nCol1 && 
pRowInfo[0].pCellInfo[nArrCol+nDxNeg].nWidth == 0 )
+                    while ( nCol+nDxNeg > nCol1-1 && 
pRowInfo[0].cellInfo(nCol+nDxNeg).nWidth == 0 )
                         --nDxNeg;
 
                     bool bLeftDiff = !bLeft &&
-                            
pRowInfo[nArrRow].pCellInfo[nArrCol+nDxNeg].pShadowAttr->GetLocation() == 
SvxShadowLocation::NONE;
+                            
pRowInfo[nArrRow].cellInfo(nCol+nDxNeg).pShadowAttr->GetLocation() == 
SvxShadowLocation::NONE;
                     bool bRightDiff = !bRight &&
-                            
pRowInfo[nArrRow].pCellInfo[nArrCol+nDxPos].pShadowAttr->GetLocation() == 
SvxShadowLocation::NONE;
+                            
pRowInfo[nArrRow].cellInfo(nCol+nDxPos).pShadowAttr->GetLocation() == 
SvxShadowLocation::NONE;
                     bool bTopDiff = !bTop &&
-                            
pRowInfo[nArrRow-1].pCellInfo[nArrCol].pShadowAttr->GetLocation() == 
SvxShadowLocation::NONE;
+                            
pRowInfo[nArrRow-1].cellInfo(nCol).pShadowAttr->GetLocation() == 
SvxShadowLocation::NONE;
                     bool bBottomDiff = !bBottom &&
-                            
pRowInfo[nArrRow+1].pCellInfo[nArrCol].pShadowAttr->GetLocation() == 
SvxShadowLocation::NONE;
+                            
pRowInfo[nArrRow+1].cellInfo(nCol).pShadowAttr->GetLocation() == 
SvxShadowLocation::NONE;
 
                     if ( bLayoutRTL )
                     {
@@ -791,80 +786,80 @@ void ScDocument::FillInfo(
                         case SvxShadowLocation::BottomRight:
                             if (bBottomDiff)
                             {
-                                
pRowInfo[nArrRow+1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
-                                
pRowInfo[nArrRow+1].pCellInfo[nArrCol].eHShadowPart =
+                                
pRowInfo[nArrRow+1].cellInfo(nCol).pHShadowOrigin = pThisAttr;
+                                
pRowInfo[nArrRow+1].cellInfo(nCol).eHShadowPart =
                                                 bLeftDiff ? SC_SHADOW_HSTART : 
SC_SHADOW_HORIZ;
                             }
                             if (bRightDiff)
                             {
-                                
pRowInfo[nArrRow].pCellInfo[nArrCol+1].pVShadowOrigin = pThisAttr;
-                                
pRowInfo[nArrRow].pCellInfo[nArrCol+1].eVShadowPart =
+                                
pRowInfo[nArrRow].cellInfo(nCol+1).pVShadowOrigin = pThisAttr;
+                                
pRowInfo[nArrRow].cellInfo(nCol+1).eVShadowPart =
                                                 bTopDiff ? SC_SHADOW_VSTART : 
SC_SHADOW_VERT;
                             }
                             if (bBottomDiff && bRightDiff)
                             {
-                                
pRowInfo[nArrRow+1].pCellInfo[nArrCol+1].pHShadowOrigin = pThisAttr;
-                                
pRowInfo[nArrRow+1].pCellInfo[nArrCol+1].eHShadowPart = SC_SHADOW_CORNER;
+                                
pRowInfo[nArrRow+1].cellInfo(nCol).pHShadowOrigin = pThisAttr;
+                                
pRowInfo[nArrRow+1].cellInfo(nCol).eHShadowPart = SC_SHADOW_CORNER;
                             }
                             break;
 
                         case SvxShadowLocation::BottomLeft:
                             if (bBottomDiff)
                             {
-                                
pRowInfo[nArrRow+1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
-                                
pRowInfo[nArrRow+1].pCellInfo[nArrCol].eHShadowPart =
+                                
pRowInfo[nArrRow+1].cellInfo(nCol).pHShadowOrigin = pThisAttr;
+                                
pRowInfo[nArrRow+1].cellInfo(nCol).eHShadowPart =
                                                 bRightDiff ? SC_SHADOW_HSTART 
: SC_SHADOW_HORIZ;
                             }
                             if (bLeftDiff)
                             {
-                                
pRowInfo[nArrRow].pCellInfo[nArrCol-1].pVShadowOrigin = pThisAttr;
-                                
pRowInfo[nArrRow].pCellInfo[nArrCol-1].eVShadowPart =
+                                
pRowInfo[nArrRow].cellInfo(nCol-1).pVShadowOrigin = pThisAttr;
+                                
pRowInfo[nArrRow].cellInfo(nCol-1).eVShadowPart =
                                                 bTopDiff ? SC_SHADOW_VSTART : 
SC_SHADOW_VERT;
                             }
                             if (bBottomDiff && bLeftDiff)
                             {
-                                
pRowInfo[nArrRow+1].pCellInfo[nArrCol-1].pHShadowOrigin = pThisAttr;
-                                
pRowInfo[nArrRow+1].pCellInfo[nArrCol-1].eHShadowPart = SC_SHADOW_CORNER;
+                                
pRowInfo[nArrRow+1].cellInfo(nCol-1).pHShadowOrigin = pThisAttr;
+                                
pRowInfo[nArrRow+1].cellInfo(nCol-1).eHShadowPart = SC_SHADOW_CORNER;
                             }
                             break;
 
                         case SvxShadowLocation::TopRight:
                             if (bTopDiff)
                             {
-                                
pRowInfo[nArrRow-1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
-                                
pRowInfo[nArrRow-1].pCellInfo[nArrCol].eHShadowPart =
+                                
pRowInfo[nArrRow-1].cellInfo(nCol).pHShadowOrigin = pThisAttr;
+                                
pRowInfo[nArrRow-1].cellInfo(nCol).eHShadowPart =
                                                 bLeftDiff ? SC_SHADOW_HSTART : 
SC_SHADOW_HORIZ;
                             }
                             if (bRightDiff)
                             {
-                                
pRowInfo[nArrRow].pCellInfo[nArrCol+1].pVShadowOrigin = pThisAttr;
-                                
pRowInfo[nArrRow].pCellInfo[nArrCol+1].eVShadowPart =
+                                
pRowInfo[nArrRow].cellInfo(nCol+1).pVShadowOrigin = pThisAttr;
+                                
pRowInfo[nArrRow].cellInfo(nCol+1).eVShadowPart =
                                                 bBottomDiff ? SC_SHADOW_VSTART 
: SC_SHADOW_VERT;
                             }
                             if (bTopDiff && bRightDiff)
                             {
-                                
pRowInfo[nArrRow-1].pCellInfo[nArrCol+1].pHShadowOrigin = pThisAttr;
-                                
pRowInfo[nArrRow-1].pCellInfo[nArrCol+1].eHShadowPart = SC_SHADOW_CORNER;
+                                
pRowInfo[nArrRow-1].cellInfo(nCol+1).pHShadowOrigin = pThisAttr;
+                                
pRowInfo[nArrRow-1].cellInfo(nCol+1).eHShadowPart = SC_SHADOW_CORNER;
                             }
                             break;
 
                         case SvxShadowLocation::TopLeft:
                             if (bTopDiff)
                             {
-                                
pRowInfo[nArrRow-1].pCellInfo[nArrCol].pHShadowOrigin = pThisAttr;
-                                
pRowInfo[nArrRow-1].pCellInfo[nArrCol].eHShadowPart =
+                                
pRowInfo[nArrRow-1].cellInfo(nCol).pHShadowOrigin = pThisAttr;
+                                
pRowInfo[nArrRow-1].cellInfo(nCol).eHShadowPart =
                                                 bRightDiff ? SC_SHADOW_HSTART 
: SC_SHADOW_HORIZ;
                             }
                             if (bLeftDiff)
                             {
-                                
pRowInfo[nArrRow].pCellInfo[nArrCol-1].pVShadowOrigin = pThisAttr;
-                                
pRowInfo[nArrRow].pCellInfo[nArrCol-1].eVShadowPart =
+                                
pRowInfo[nArrRow].cellInfo(nCol-1).pVShadowOrigin = pThisAttr;
+                                
pRowInfo[nArrRow].cellInfo(nCol-1).eVShadowPart =
                                                 bBottomDiff ? SC_SHADOW_VSTART 
: SC_SHADOW_VERT;
                             }
                             if (bTopDiff && bLeftDiff)
                             {
-                                
pRowInfo[nArrRow-1].pCellInfo[nArrCol-1].pHShadowOrigin = pThisAttr;
-                                
pRowInfo[nArrRow-1].pCellInfo[nArrCol-1].eHShadowPart = SC_SHADOW_CORNER;
+                                
pRowInfo[nArrRow-1].cellInfo(nCol-1).pHShadowOrigin = pThisAttr;
+                                
pRowInfo[nArrRow-1].cellInfo(nCol-1).eHShadowPart = SC_SHADOW_CORNER;
                             }
                             break;
 
@@ -882,9 +877,9 @@ void ScDocument::FillInfo(
     // *** create the frame border array ***
 
     // RowInfo structs are filled in the range [ 0 , nArrCount-1 ]
-    // each RowInfo contains CellInfo structs in the range [ nX1-1 , nX2+1 ]
+    // each RowInfo contains CellInfo structs in the range [ nCol1-1 , nCol2+1 
]
 
-    size_t nColCount = nCol2 - nCol1 + 3;
+    size_t nColCount = nCol2 - nCol1 + 1 + 2;
     size_t nRowCount = nArrCount;
 
     svx::frame::Array& rArray = rTabInfo.maArray;
@@ -895,21 +890,22 @@ void ScDocument::FillInfo(
         sal_uInt16 nCellInfoY = static_cast< sal_uInt16 >( nRow );
         RowInfo& rThisRowInfo = pRowInfo[ nCellInfoY ];
 
-        for( size_t nCol = 0; nCol < nColCount; ++nCol )
+        for( SCCOL nCol = nCol1 - 1; nCol <= nCol2 + 1; ++nCol ) // 1 more 
left and right
         {
-            sal_uInt16 nCellInfoX = static_cast< sal_uInt16 >( nCol + nCol1 );
-            const CellInfo& rInfo = rThisRowInfo.pCellInfo[ nCellInfoX ];
-
+            const CellInfo& rInfo = rThisRowInfo.cellInfo( nCol );
             const SvxBoxItem* pBox = rInfo.pLinesAttr;
             const SvxLineItem* pTLBR = rInfo.mpTLBRLine;
             const SvxLineItem* pBLTR = rInfo.mpBLTRLine;
 
-            size_t nFirstCol = nCol;
+            size_t colToIndex = -(nCol1 - 1);
+            // These are rArray indexes (0-based), not really rows/columns.
+            size_t nX = nCol + colToIndex;
+            size_t nFirstCol = nX;
             size_t nFirstRow = nRow;
 
             // *** merged cells *** -------------------------------------------
 
-            if( !rArray.IsMerged( nCol, nRow ) && (rInfo.bMerged || 
rInfo.bHOverlapped || rInfo.bVOverlapped) )
+            if( !rArray.IsMerged( nX, nRow ) && (rInfo.bMerged || 
rInfo.bHOverlapped || rInfo.bVOverlapped) )
             {
                 // *** insert merged range in svx::frame::Array ***
 
@@ -918,11 +914,10 @@ void ScDocument::FillInfo(
                     complete merged range, then calculate dimensions and
                     document position of the visible range. */
 
-                // note: document columns are always one less than CellInfoX 
coords
                 // note: document rows must be looked up in RowInfo structs
 
                 // current column and row in document coordinates
-                SCCOL nCurrDocCol = static_cast< SCCOL >( nCellInfoX - 1 );
+                SCCOL nCurrDocCol = nCol;
                 SCROW nCurrDocRow = static_cast< SCROW >( (nCellInfoY > 0) ? 
rThisRowInfo.nRowNo : (nRow1 - 1) );
 
                 // find entire merged range in document, returns signed 
document coordinates
@@ -938,15 +933,13 @@ void ScDocument::FillInfo(
                 SCCOL nLastRealDocCol  = nLastRealDocColS;
                 SCROW nLastRealDocRow  = nLastRealDocRowS;
 
-                // first visible column (nX1-1 is first processed document 
column)
+                // first visible column (nCol1-1 is first processed document 
column)
                 SCCOL nFirstDocCol = (nCol1 > 0) ? ::std::max< SCCOL >( 
nFirstRealDocCol, nCol1 - 1 ) : nFirstRealDocCol;
-                sal_uInt16 nFirstCellInfoX = static_cast< sal_uInt16 >( 
nFirstDocCol + 1 );
-                nFirstCol = static_cast< size_t >( nFirstCellInfoX - nCol1 );
+                nFirstCol = nFirstDocCol + colToIndex;
 
-                // last visible column (nX2+1 is last processed document 
column)
+                // last visible column (nCol2+1 is last processed document 
column)
                 SCCOL nLastDocCol = (nCol2 < MaxCol()) ? ::std::min< SCCOL >( 
nLastRealDocCol, nCol2 + 1 ) : nLastRealDocCol;
-                sal_uInt16 nLastCellInfoX = static_cast< sal_uInt16 >( 
nLastDocCol + 1 );
-                size_t nLastCol = static_cast< size_t >( nLastCellInfoX - 
nCol1 );
+                size_t nLastCol = nLastDocCol + colToIndex;
 
                 // first visible row
                 sal_uInt16 nFirstCellInfoY = nCellInfoY;
@@ -975,7 +968,7 @@ void ScDocument::FillInfo(
                     tools::Long nSize = 0;
                     for( SCCOL nDocCol = nFirstRealDocCol; nDocCol < 
nFirstDocCol; ++nDocCol )
                         nSize += std::max( tools::Long(GetColWidth( nDocCol, 
nTab ) * fColScale), tools::Long(1) );
-                    rArray.SetAddMergedLeftSize( nCol, nRow, nSize );
+                    rArray.SetAddMergedLeftSize( nX, nRow, nSize );
                 }
                 // additional space after last column
                 if( nLastCol + 1 == nColCount )
@@ -983,7 +976,7 @@ void ScDocument::FillInfo(
                     tools::Long nSize = 0;
                     for( SCCOL nDocCol = nLastDocCol + 1; nDocCol <= 
nLastRealDocCol; ++nDocCol )
                         nSize += std::max( tools::Long(GetColWidth( nDocCol, 
nTab ) * fColScale), tools::Long(1) );
-                    rArray.SetAddMergedRightSize( nCol, nRow, nSize );
+                    rArray.SetAddMergedRightSize( nX, nRow, nSize );
                 }
                 // additional space above first row
                 if( nFirstRow == 0 )
@@ -991,7 +984,7 @@ void ScDocument::FillInfo(
                     tools::Long nSize = 0;
                     for( SCROW nDocRow = nFirstRealDocRow; nDocRow < 
nFirstDocRow; ++nDocRow )
                         nSize += std::max( tools::Long(GetRowHeight( nDocRow, 
nTab ) * fRowScale), tools::Long(1) );
-                    rArray.SetAddMergedTopSize( nCol, nRow, nSize );
+                    rArray.SetAddMergedTopSize( nX, nRow, nSize );
                 }
                 // additional space beyond last row
                 if( nLastRow + 1 == nRowCount )
@@ -999,7 +992,7 @@ void ScDocument::FillInfo(
                     tools::Long nSize = 0;
                     for( SCROW nDocRow = nLastDocRow + 1; nDocRow <= 
nLastRealDocRow; ++nDocRow )
                         nSize += std::max( tools::Long(GetRowHeight( nDocRow, 
nTab ) * fRowScale), tools::Long(1) );
-                    rArray.SetAddMergedBottomSize( nCol, nRow, nSize );
+                    rArray.SetAddMergedBottomSize( nX, nRow, nSize );
                 }
 
                 // *** use line attributes from real origin cell ***
@@ -1055,7 +1048,7 @@ ScTableInfo::ScTableInfo(const SCSIZE capacity)
 ScTableInfo::~ScTableInfo()
 {
     for( SCSIZE nIdx = 0; nIdx < mnArrCapacity; ++nIdx )
-        delete [] mpRowInfo[ nIdx ].pCellInfo;
+        mpRowInfo[ nIdx ].freeCellInfo();
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index 64720edf5e85..61873156d264 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -138,7 +138,7 @@ private:
         const ScPatternAttr*    mpOldPattern;
         const SfxItemSet*       mpOldCondSet;
         const SfxItemSet*       mpOldPreviewFontSet;
-        const RowInfo*          mpThisRowInfo;
+        RowInfo*                mpThisRowInfo;
         const std::vector<editeng::MisspellRanges>* mpMisspellRanges;
 
         explicit DrawEditParam(const ScPatternAttr* pPattern, const 
SfxItemSet* pCondSet, bool bCellIsValue);
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index f71c73514a27..17c4057e8337 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -2044,7 +2044,7 @@ void ScGridWindow::DrawButtons(SCCOL nX1, SCCOL nX2, 
const ScTableInfo& rTabInfo
 
             for (nCol=nX1; nCol<=nX2; nCol++)
             {
-                CellInfo* pInfo = &pThisRowInfo->pCellInfo[nCol+1];
+                CellInfo* pInfo = &pThisRowInfo->cellInfo(nCol);
                 //if several columns merged on a row, there should be only one 
auto button at the end of the columns.
                 //if several rows merged on a column, the button may be in the 
middle, so "!pInfo->bVOverlapped" should not be used
                 if ( pInfo->bAutoFilter && !pInfo->bHOverlapped )
@@ -2124,7 +2124,7 @@ void ScGridWindow::DrawButtons(SCCOL nX1, SCCOL nX2, 
const ScTableInfo& rTabInfo
             nRow = pThisRowInfo->nRowNo;
             for (nCol=nX1; nCol<=nX2; nCol++)
             {
-                CellInfo* pInfo = &pThisRowInfo->pCellInfo[nCol+1];
+                CellInfo* pInfo = &pThisRowInfo->cellInfo(nCol);
                 if (pInfo->bHOverlapped || pInfo->bVOverlapped)
                     continue;
 
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index 2f9674a1edae..776c164cd2d7 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -195,7 +195,7 @@ ScOutputData::ScOutputData( OutputDevice* pNewDev, 
ScOutputType eNewType,
 
     nScrW = 0;
     for (SCCOL nX=nVisX1; nX<=nVisX2; nX++)
-        nScrW += pRowInfo[0].pCellInfo[nX+1].nWidth;
+        nScrW += pRowInfo[0].cellInfo(nX).nWidth;
 
     nMirrorW = nScrW;
 
@@ -368,9 +368,7 @@ void ScOutputData::DrawGrid(vcl::RenderContext& 
rRenderContext, bool bGrid, bool
 
     for (nX=nX1; nX<=nX2; nX++)
     {
-        SCCOL nXplus1 = nX+1;
-        SCCOL nXplus2 = nX+2;
-        sal_uInt16 nWidth = pRowInfo[0].pCellInfo[nXplus1].nWidth;
+        sal_uInt16 nWidth = pRowInfo[0].cellInfo(nX).nWidth;
         if (nWidth)
         {
             nPosX += nWidth * nLayoutSign;
@@ -378,7 +376,7 @@ void ScOutputData::DrawGrid(vcl::RenderContext& 
rRenderContext, bool bGrid, bool
             if ( bPage )
             {
                 // Search also in hidden part for page breaks
-                SCCOL nCol = nXplus1;
+                SCCOL nCol = nX + 1;
                 while (nCol <= mpDoc->MaxCol())
                 {
                     nBreak = mpDoc->HasColBreak(nCol, nTab);
@@ -411,16 +409,16 @@ void ScOutputData::DrawGrid(vcl::RenderContext& 
rRenderContext, bool bGrid, bool
 
             bool bDraw = bGrid || nBreakOld != ScBreakType::NONE || 
bMergeCover; // simple grid only if set that way
 
-            sal_uInt16 nWidthXplus2 = pRowInfo[0].pCellInfo[nXplus2].nWidth;
+            sal_uInt16 nWidthXplus1 = pRowInfo[0].cellInfo(nX+1).nWidth;
             bSingle = false; //! get into Fillinfo !!!!!
             if ( nX<mpDoc->MaxCol() && !bSingle )
             {
-                bSingle = ( nWidthXplus2 == 0 );
+                bSingle = ( nWidthXplus1 == 0 );
                 for (nArrY=1; nArrY+1<nArrCount && !bSingle; nArrY++)
                 {
-                    if (pRowInfo[nArrY].pCellInfo[nXplus2].bHOverlapped)
+                    if (pRowInfo[nArrY].cellInfo(nX+1).bHOverlapped)
                         bSingle = true;
-                    if (pRowInfo[nArrY].pCellInfo[nXplus1].bHideGrid)
+                    if (pRowInfo[nArrY].cellInfo(nX).bHideGrid)
                         bSingle = true;
                 }
             }
@@ -429,7 +427,7 @@ void ScOutputData::DrawGrid(vcl::RenderContext& 
rRenderContext, bool bGrid, bool
             {
                 if ( nX<mpDoc->MaxCol() && bSingle )
                 {
-                    SCCOL nVisX = nXplus1;
+                    SCCOL nVisX = nX + 1;
                     while ( nVisX < mpDoc->MaxCol() && 
!mpDoc->GetColWidth(nVisX,nTab) )
                         ++nVisX;
 
@@ -439,22 +437,22 @@ void ScOutputData::DrawGrid(vcl::RenderContext& 
rRenderContext, bool bGrid, bool
                         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
                         const tools::Long nNextY = nPosY + 
pThisRowInfo->nHeight;
 
-                        bool bHOver = 
pThisRowInfo->pCellInfo[nXplus1].bHideGrid;
+                        bool bHOver = pThisRowInfo->cellInfo(nX).bHideGrid;
                         if (!bHOver)
                         {
-                            if (nWidthXplus2)
-                                bHOver = 
pThisRowInfo->pCellInfo[nXplus2].bHOverlapped;
+                            if (nWidthXplus1)
+                                bHOver = 
pThisRowInfo->cellInfo(nX+1).bHOverlapped;
                             else
                             {
                                 if (nVisX <= nX2)
-                                    bHOver = 
pThisRowInfo->pCellInfo[nVisX+1].bHOverlapped;
+                                    bHOver = 
pThisRowInfo->cellInfo(nVisX).bHOverlapped;
                                 else
                                     bHOver = mpDoc->GetAttr(
                                                 
nVisX,pThisRowInfo->nRowNo,nTab,ATTR_MERGE_FLAG)
                                                 ->IsHorOverlapped();
                                 if (bHOver)
                                     bHOver = mpDoc->GetAttr(
-                                                
nXplus1,pThisRowInfo->nRowNo,nTab,ATTR_MERGE_FLAG)
+                                                nX + 
1,pThisRowInfo->nRowNo,nTab,ATTR_MERGE_FLAG)
                                                 ->IsHorOverlapped();
                             }
                         }
@@ -532,7 +530,7 @@ void ScOutputData::DrawGrid(vcl::RenderContext& 
rRenderContext, bool bGrid, bool
             bSingle = !bNextYisNextRow;             // Hidden
             for (SCCOL i=nX1; i<=nX2 && !bSingle; i++)
             {
-                if (pRowInfo[nArrYplus1].pCellInfo[i+1].bVOverlapped)
+                if (pRowInfo[nArrYplus1].cellInfo(i).bVOverlapped)
                     bSingle = true;
             }
 
@@ -548,12 +546,12 @@ void ScOutputData::DrawGrid(vcl::RenderContext& 
rRenderContext, bool bGrid, bool
 
                     for (SCCOL i=nX1; i<=nX2; i++)
                     {
-                        const tools::Long nNextX = nPosX + 
pRowInfo[0].pCellInfo[i+1].nWidth * nLayoutSign;
+                        const tools::Long nNextX = nPosX + 
pRowInfo[0].cellInfo(i).nWidth * nLayoutSign;
                         if (nNextX != nPosX)                                // 
visible
                         {
                             bool bVOver;
                             if ( bNextYisNextRow )
-                                bVOver = 
pRowInfo[nArrYplus1].pCellInfo[i+1].bVOverlapped;
+                                bVOver = 
pRowInfo[nArrYplus1].cellInfo(i).bVOverlapped;
                             else
                             {
                                 bVOver = mpDoc->GetAttr(
@@ -608,7 +606,7 @@ void ScOutputData::SetPagebreakMode( ScPageBreakData* 
pPageData )
                                            pThisRowInfo->nRowNo <= nEndY )
             {
                 for (SCCOL nX=nStartX; nX<=nEndX; nX++)
-                    pThisRowInfo->pCellInfo[nX+1].bPrinted = true;
+                    pThisRowInfo->cellInfo(nX).bPrinted = true;
             }
         }
     }
@@ -633,7 +631,7 @@ void ScOutputData::SetCellRotations()
 
             for (SCCOL nX=0; nX<=nRotMax; nX++)
             {
-                CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+                CellInfo* pInfo = &pThisRowInfo->cellInfo(nX);
                 const ScPatternAttr* pPattern = pInfo->pPatternAttr;
                 const SfxItemSet* pCondSet = pInfo->pConditionSet;
 
@@ -757,8 +755,8 @@ static bool lcl_EqualBack( const RowInfo& rFirst, const 
RowInfo& rOther,
     {
         for ( nX=nX1; nX<=nX2; nX++ )
         {
-            const ScPatternAttr* pPat1 = rFirst.pCellInfo[nX+1].pPatternAttr;
-            const ScPatternAttr* pPat2 = rOther.pCellInfo[nX+1].pPatternAttr;
+            const ScPatternAttr* pPat1 = rFirst.cellInfo(nX).pPatternAttr;
+            const ScPatternAttr* pPat2 = rOther.cellInfo(nX).pPatternAttr;
             if ( !pPat1 || !pPat2 ||
                     &pPat1->GetItem(ATTR_PROTECTION) != 
&pPat2->GetItem(ATTR_PROTECTION) )
                 return false;
@@ -767,32 +765,32 @@ static bool lcl_EqualBack( const RowInfo& rFirst, const 
RowInfo& rOther,
     else
     {
         for ( nX=nX1; nX<=nX2; nX++ )
-            if ( rFirst.pCellInfo[nX+1].pBackground != 
rOther.pCellInfo[nX+1].pBackground )
+            if ( rFirst.cellInfo(nX).pBackground != 
rOther.cellInfo(nX).pBackground )
                 return false;
     }
 
     if ( rFirst.nRotMaxCol != SC_ROTMAX_NONE || rOther.nRotMaxCol != 
SC_ROTMAX_NONE )
         for ( nX=nX1; nX<=nX2; nX++ )
-            if ( rFirst.pCellInfo[nX+1].nRotateDir != 
rOther.pCellInfo[nX+1].nRotateDir )
+            if ( rFirst.cellInfo(nX).nRotateDir != 
rOther.cellInfo(nX).nRotateDir )
                 return false;
 
     if ( bPagebreakMode )
         for ( nX=nX1; nX<=nX2; nX++ )
-            if ( rFirst.pCellInfo[nX+1].bPrinted != 
rOther.pCellInfo[nX+1].bPrinted )
+            if ( rFirst.cellInfo(nX).bPrinted != rOther.cellInfo(nX).bPrinted )
                 return false;
 
     for ( nX=nX1; nX<=nX2; nX++ )
     {
-        std::optional<Color> const & pCol1 = 
rFirst.pCellInfo[nX+1].mxColorScale;
-        std::optional<Color> const & pCol2 = 
rOther.pCellInfo[nX+1].mxColorScale;
+        std::optional<Color> const & pCol1 = rFirst.cellInfo(nX).mxColorScale;
+        std::optional<Color> const & pCol2 = rOther.cellInfo(nX).mxColorScale;
         if( (pCol1 && !pCol2) || (!pCol1 && pCol2) )
             return false;
 
         if (pCol1 && (*pCol1 != *pCol2))
             return false;
 
-        const ScDataBarInfo* pInfo1 = rFirst.pCellInfo[nX+1].pDataBar.get();
-        const ScDataBarInfo* pInfo2 = rOther.pCellInfo[nX+1].pDataBar.get();
+        const ScDataBarInfo* pInfo1 = rFirst.cellInfo(nX).pDataBar.get();
+        const ScDataBarInfo* pInfo2 = rOther.cellInfo(nX).pDataBar.get();
 
         if( (pInfo1 && !pInfo2) || (!pInfo1 && pInfo2) )
             return false;
@@ -801,8 +799,8 @@ static bool lcl_EqualBack( const RowInfo& rFirst, const 
RowInfo& rOther,
             return false;
 
         // each cell with an icon set should be painted the same way
-        const ScIconSetInfo* pIconSet1 = rFirst.pCellInfo[nX+1].pIconSet.get();
-        const ScIconSetInfo* pIconSet2 = rOther.pCellInfo[nX+1].pIconSet.get();
+        const ScIconSetInfo* pIconSet1 = rFirst.cellInfo(nX).pIconSet.get();
+        const ScIconSetInfo* pIconSet2 = rOther.cellInfo(nX).pIconSet.get();
 
         if(pIconSet1 || pIconSet2)
             return false;
@@ -1097,7 +1095,7 @@ void ScOutputData::DrawBackground(vcl::RenderContext& 
rRenderContext)
 
                 for (SCCOL nX=nX1; nX + nMergedCols <= nX2 + 1; nX += 
nOldMerged)
                 {
-                    CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+nMergedCols];
+                    CellInfo* pInfo = 
&pThisRowInfo->cellInfo(nX-1+nMergedCols);
 
                     nOldMerged = nMergedCols;
 
@@ -1158,7 +1156,7 @@ void ScOutputData::DrawBackground(vcl::RenderContext& 
rRenderContext)
                         SCCOL nCol = nX+nOldMerged+nMerged;
                         if (nCol > nX2+2)
                             break;
-                        nPosX += pRowInfo[0].pCellInfo[nCol].nWidth * 
nLayoutSign;
+                        nPosX += pRowInfo[0].cellInfo(nCol-1).nWidth * 
nLayoutSign;
                     }
                 }
 
@@ -1210,22 +1208,22 @@ void ScOutputData::DrawExtraShadow(bool bLeft, bool 
bTop, bool bRight, bool bBot
 
         if ( pThisRowInfo->bChanged && !bSkipY )
         {
-            tools::Long nPosX = nInitPosX - pRowInfo[0].pCellInfo[nX1].nWidth 
* nLayoutSign;
-            for (SCCOL nArrX=nX1; nArrX<=nX2+2; nArrX++)
+            tools::Long nPosX = nInitPosX - pRowInfo[0].cellInfo(nX1-1).nWidth 
* nLayoutSign;
+            for (SCCOL nCol=nX1-1; nCol<=nX2+1; nCol++)
             {
-                bool bCornerX = ( nArrX==nX1 || nArrX==nX2+2 );
-                bool bSkipX = ( nArrX==nX1 && !bLeft ) || ( nArrX==nX2+2 && 
!bRight );
+                bool bCornerX = ( nCol==nX1-1 || nCol==nX2+1 );
+                bool bSkipX = ( nCol==nX1-1 && !bLeft ) || ( nCol==nX2+1 && 
!bRight );
 
                 for (sal_uInt16 nPass=0; nPass<2; nPass++) // horizontal / 
vertical
                 {
                     const SvxShadowItem* pAttr = nPass ?
-                            pThisRowInfo->pCellInfo[nArrX].pVShadowOrigin :
-                            pThisRowInfo->pCellInfo[nArrX].pHShadowOrigin;
+                            pThisRowInfo->cellInfo(nCol).pVShadowOrigin :
+                            pThisRowInfo->cellInfo(nCol).pHShadowOrigin;
                     if ( pAttr && !bSkipX )
                     {
                         ScShadowPart ePart = nPass ?
-                                pThisRowInfo->pCellInfo[nArrX].eVShadowPart :
-                                pThisRowInfo->pCellInfo[nArrX].eHShadowPart;
+                                pThisRowInfo->cellInfo(nCol).eVShadowPart :
+                                pThisRowInfo->cellInfo(nCol).eHShadowPart;
 
                         bool bDo = true;
                         if ( (nPass==0 && bCornerX) || (nPass==1 && bCornerY) )
@@ -1234,15 +1232,15 @@ void ScOutputData::DrawExtraShadow(bool bLeft, bool 
bTop, bool bRight, bool bBot
 
                         if (bDo)
                         {
-                            tools::Long nThisWidth = 
pRowInfo[0].pCellInfo[nArrX].nWidth;
+                            tools::Long nThisWidth = 
pRowInfo[0].cellInfo(nCol).nWidth;
                             tools::Long nMaxWidth = nThisWidth;
                             if (!nMaxWidth)
                             {
                                 //! direction must depend on shadow location
-                                SCCOL nWx = nArrX;      // nX+1
-                                while (nWx<nX2 && 
!pRowInfo[0].pCellInfo[nWx+1].nWidth)
+                                SCCOL nWx = nCol+1;
+                                while (nWx<nX2 && 
!pRowInfo[0].cellInfo(nWx).nWidth)
                                     ++nWx;
-                                nMaxWidth = 
pRowInfo[0].pCellInfo[nWx+1].nWidth;
+                                nMaxWidth = pRowInfo[0].cellInfo(nWx).nWidth;
                             }
 
                             // rectangle is in logical orientation
@@ -1314,7 +1312,7 @@ void ScOutputData::DrawExtraShadow(bool bLeft, bool bTop, 
bool bRight, bool bBot
                     }
                 }
 
-                nPosX += pRowInfo[0].pCellInfo[nArrX].nWidth * nLayoutSign;
+                nPosX += pRowInfo[0].cellInfo(nCol).nWidth * nLayoutSign;
             }
         }
         nPosY += nRowHeight;
@@ -1376,11 +1374,6 @@ static tools::Long lclGetSnappedY( const OutputDevice& 
rDev, tools::Long nPosY,
     return (bSnapPixel && nPosY) ? rDev.PixelToLogic( rDev.LogicToPixel( Size( 
0, nPosY ) ) ).Height() : nPosY;
 }
 
-static size_t lclGetArrayColFromCellInfoX( sal_uInt16 nCellInfoX, sal_uInt16 
nCellInfoFirstX, sal_uInt16 nCellInfoLastX, bool bRTL )
-{
-    return static_cast< size_t >( bRTL ? (nCellInfoLastX + 2 - nCellInfoX) : 
(nCellInfoX - nCellInfoFirstX) );
-}
-
 void ScOutputData::DrawFrame(vcl::RenderContext& rRenderContext)
 {
     DrawModeFlags nOldDrawMode = rRenderContext.GetDrawMode();
@@ -1453,19 +1446,19 @@ void ScOutputData::DrawFrame(vcl::RenderContext& 
rRenderContext)
 
     // column widths
 
-    // column nX1 is not visible (dummy for borders from left) - subtract its 
width from initial position
+    // column nX1-1 is not visible (dummy for borders from left) - subtract 
its width from initial position
     // subtract 1 unit more, because position 0 is first *in* cell, grid line 
is one unit above
-    tools::Long nOldPosX = nInitPosX - nLayoutSign * (1 + pRowInfo[ 0 
].pCellInfo[ nX1 ].nWidth);
+    tools::Long nOldPosX = nInitPosX - nLayoutSign * (1 + pRowInfo[ 0 
].cellInfo( nX1 - 1 ).nWidth);
     tools::Long nOldSnapX = lclGetSnappedX( rRenderContext, nOldPosX, 
bSnapPixel );
     // set X offset for left-to-right sheets; for right-to-left sheets this is 
done after for() loop
     if( !bLayoutRTL )
         rArray.SetXOffset( nOldSnapX );
-    for( sal_uInt16 nInfoIdx = nX1; nInfoIdx <= nX2 + 2; ++nInfoIdx )
+    for( SCCOL nCol = nX1 - 1; nCol <= nX2 + 1; ++nCol )
     {
-        size_t nCol = lclGetArrayColFromCellInfoX( nInfoIdx, nX1, nX2, 
bLayoutRTL );
-        tools::Long nNewPosX = nOldPosX + pRowInfo[ 0 ].pCellInfo[ nInfoIdx 
].nWidth * nLayoutSign;
+        size_t nArrCol = bLayoutRTL ? nX2 + 1 - nCol : nCol - (nX1 - 1);
+        tools::Long nNewPosX = nOldPosX + pRowInfo[ 0 ].cellInfo( nCol 
).nWidth * nLayoutSign;
         tools::Long nNewSnapX = lclGetSnappedX( rRenderContext, nNewPosX, 
bSnapPixel );
-        rArray.SetColWidth( nCol, std::abs( nNewSnapX - nOldSnapX ) );
+        rArray.SetColWidth( nArrCol, std::abs( nNewSnapX - nOldSnapX ) );
         nOldPosX = nNewPosX;
         nOldSnapX = nNewSnapX;
     }
@@ -1561,10 +1554,8 @@ void ScOutputData::DrawRotatedFrame(vcl::RenderContext& 
rRenderContext)
             {
                 if (nX==nX1) nPosX = nInitPosX;     // calculated individually 
for preceding positions
 
-                sal_uInt16 nArrX = nX + 1;
-
-                CellInfo* pInfo = &rThisRowInfo.pCellInfo[nArrX];
-                tools::Long nColWidth = pRowInfo[0].pCellInfo[nArrX].nWidth;
+                CellInfo* pInfo = &rThisRowInfo.cellInfo(nX);
+                tools::Long nColWidth = pRowInfo[0].cellInfo(nX).nWidth;
                 if ( pInfo->nRotateDir > ScRotateDir::Standard &&
                         !pInfo->bHOverlapped && !pInfo->bVOverlapped )
                 {
@@ -1593,7 +1584,7 @@ void ScOutputData::DrawRotatedFrame(vcl::RenderContext& 
rRenderContext)
                             while (nCol > nX)
                             {
                                 --nCol;
-                                nPosX -= nLayoutSign * 
static_cast<tools::Long>(pRowInfo[0].pCellInfo[nCol + 1].nWidth);
+                                nPosX -= nLayoutSign * 
static_cast<tools::Long>(pRowInfo[0].cellInfo(nCol).nWidth);
                             }
                         }
 
@@ -1833,7 +1824,7 @@ void ScOutputData::FindChanged()
         RowInfo* pThisRowInfo = &pRowInfo[nArrY];
         for (nX=nX1; nX<=nX2; nX++)
         {
-            const ScRefCellValue& rCell = pThisRowInfo->pCellInfo[nX+1].maCell;
+            const ScRefCellValue& rCell = pThisRowInfo->cellInfo(nX).maCell;
 
             if (rCell.meType != CELLTYPE_FORMULA)
                 continue;
@@ -1882,7 +1873,7 @@ void ScOutputData::FindChanged()
             RowInfo* pThisRowInfo = &pRowInfo[nArrY];
             for (nX=nX1; nX<=nX2; nX++)
             {
-                const ScRefCellValue& rCell = 
pThisRowInfo->pCellInfo[nX+1].maCell;
+                const ScRefCellValue& rCell = 
pThisRowInfo->cellInfo(nX).maCell;
 
                 if (rCell.meType != CELLTYPE_FORMULA)
                     continue;
@@ -1897,11 +1888,11 @@ void ScOutputData::FindChanged()
                     continue;
 
                 pThisRowInfo->bChanged = true;
-                if ( pThisRowInfo->pCellInfo[nX+1].bMerged )
+                if ( pThisRowInfo->cellInfo(nX).bMerged )
                 {
                     SCSIZE nOverY = nArrY + 1;
                     while ( nOverY<nArrCount &&
-                            pRowInfo[nOverY].pCellInfo[nX+1].bVOverlapped )
+                            pRowInfo[nOverY].cellInfo(nX).bVOverlapped )
                     {
                         pRowInfo[nOverY].bChanged = true;
                         ++nOverY;
@@ -1988,10 +1979,10 @@ ReferenceMark ScOutputData::FillReferenceMark( SCCOL 
nRefStartX, SCROW nRefStart
             }
             if ( nX==nRefEndX )
             {
-                nMaxX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 2 ) * 
nLayoutSign;
+                nMaxX = nPosX + ( pRowInfo[0].cellInfo(nX).nWidth - 2 ) * 
nLayoutSign;
                 bRight = true;
             }
-            nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+            nPosX += pRowInfo[0].cellInfo(nX).nWidth * nLayoutSign;
         }
 
         if (bTop && bBottom && bLeft && bRight)
@@ -2080,10 +2071,10 @@ void ScOutputData::DrawRefMark( SCCOL nRefStartX, SCROW 
nRefStartY,
         }
         if ( nX==nRefEndX )
         {
-            nMaxX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 2 ) * 
nLayoutSign;
+            nMaxX = nPosX + ( pRowInfo[0].cellInfo(nX).nWidth - 2 ) * 
nLayoutSign;
             bRight = true;
         }
-        nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+        nPosX += pRowInfo[0].cellInfo(nX).nWidth * nLayoutSign;
     }
 
     if ( nMaxX * nLayoutSign < nMinX * nLayoutSign || nMaxY < nMinY )
@@ -2207,10 +2198,10 @@ void ScOutputData::DrawOneChange( SCCOL nRefStartX, 
SCROW nRefStartY,
         }
         if ( nX==nRefEndX )
         {
-            nMaxX = nPosX + ( pRowInfo[0].pCellInfo[nX+1].nWidth - 1 ) * 
nLayoutSign;
+            nMaxX = nPosX + ( pRowInfo[0].cellInfo(nX).nWidth - 1 ) * 
nLayoutSign;
             bRight = true;
         }
-        nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+        nPosX += pRowInfo[0].cellInfo(nX).nWidth * nLayoutSign;
     }
 
     if ( nMaxX * nLayoutSign < nMinX * nLayoutSign || nMaxY < nMinY )
@@ -2338,7 +2329,7 @@ void ScOutputData::DrawNoteMarks(vcl::RenderContext& 
rRenderContext)
             tools::Long nPosX = nInitPosX;
             for (SCCOL nX=nX1; nX<=nX2; nX++)
             {
-                CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+                CellInfo* pInfo = &pThisRowInfo->cellInfo(nX);
                 bool bIsMerged = false;
 
                 if ( nX==nX1 && pInfo->bHOverlapped && !pInfo->bVOverlapped )
@@ -2367,14 +2358,14 @@ void ScOutputData::DrawNoteMarks(vcl::RenderContext& 
rRenderContext)
                         bFirst = false;
                     }
 
-                    tools::Long nMarkX = nPosX + ( 
pRowInfo[0].pCellInfo[nX+1].nWidth - 4 ) * nLayoutSign;
+                    tools::Long nMarkX = nPosX + ( 
pRowInfo[0].cellInfo(nX).nWidth - 4 ) * nLayoutSign;
                     if ( bIsMerged || pInfo->bMerged )
                     {
                         //  if merged, add widths of all cells
                         SCCOL nNextX = nX + 1;
-                        while ( nNextX <= nX2 + 1 && 
pThisRowInfo->pCellInfo[nNextX+1].bHOverlapped )
+                        while ( nNextX <= nX2 + 1 && 
pThisRowInfo->cellInfo(nNextX).bHOverlapped )
                         {
-                            nMarkX += pRowInfo[0].pCellInfo[nNextX+1].nWidth * 
nLayoutSign;
+                            nMarkX += pRowInfo[0].cellInfo(nNextX).nWidth * 
nLayoutSign;
                             ++nNextX;
                         }
                     }
@@ -2382,7 +2373,7 @@ void ScOutputData::DrawNoteMarks(vcl::RenderContext& 
rRenderContext)
                         rRenderContext.DrawRect( tools::Rectangle( 
nMarkX-5*nLayoutSign,nPosY,nMarkX+1*nLayoutSign,nPosY+6 ) );
                 }
 
-                nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+                nPosX += pRowInfo[0].cellInfo(nX).nWidth * nLayoutSign;
             }
         }
         nPosY += pThisRowInfo->nHeight;
@@ -2413,7 +2404,7 @@ void ScOutputData::AddPDFNotes()
             tools::Long nPosX = nInitPosX;
             for (SCCOL nX=nX1; nX<=nX2; nX++)
             {
-                CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+                CellInfo* pInfo = &pThisRowInfo->cellInfo(nX);
                 bool bIsMerged = false;
                 SCROW nY = pRowInfo[nArrY].nRowNo;
                 SCCOL nMergeX = nX;
@@ -2433,14 +2424,14 @@ void ScOutputData::AddPDFNotes()
                     tools::Long nNoteWidth = static_cast<tools::Long>( 
SC_CLIPMARK_SIZE * mnPPTX );
                     tools::Long nNoteHeight = static_cast<tools::Long>( 
SC_CLIPMARK_SIZE * mnPPTY );
 
-                    tools::Long nMarkX = nPosX + ( 
pRowInfo[0].pCellInfo[nX+1].nWidth - nNoteWidth ) * nLayoutSign;
+                    tools::Long nMarkX = nPosX + ( 
pRowInfo[0].cellInfo(nX).nWidth - nNoteWidth ) * nLayoutSign;
                     if ( bIsMerged || pInfo->bMerged )
                     {
                         //  if merged, add widths of all cells
                         SCCOL nNextX = nX + 1;
-                        while ( nNextX <= nX2 + 1 && 
pThisRowInfo->pCellInfo[nNextX+1].bHOverlapped )
+                        while ( nNextX <= nX2 + 1 && 
pThisRowInfo->cellInfo(nNextX).bHOverlapped )
                         {
-                            nMarkX += pRowInfo[0].pCellInfo[nNextX+1].nWidth * 
nLayoutSign;
+                            nMarkX += pRowInfo[0].cellInfo(nNextX).nWidth * 
nLayoutSign;
                             ++nNextX;
                         }
                     }
@@ -2464,7 +2455,7 @@ void ScOutputData::AddPDFNotes()
                     }
                 }
 
-                nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+                nPosX += pRowInfo[0].cellInfo(nX).nWidth * nLayoutSign;
             }
         }
         nPosY += pThisRowInfo->nHeight;
@@ -2504,7 +2495,7 @@ void ScOutputData::DrawClipMarks()
             tools::Long nPosX = nInitPosX;
             for (SCCOL nX=nX1; nX<=nX2; nX++)
             {
-                CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+                CellInfo* pInfo = &pThisRowInfo->cellInfo(nX);
                 if (pInfo->nClipMark != ScClipMark::NONE)
                 {
                     if (pInfo->bHOverlapped || pInfo->bVOverlapped)
@@ -2546,7 +2537,7 @@ void ScOutputData::DrawClipMarks()
                     }
                     else
                     {
-                        tools::Long nOutWidth = 
pRowInfo[0].pCellInfo[nX+1].nWidth;
+                        tools::Long nOutWidth = 
pRowInfo[0].cellInfo(nX).nWidth;
                         tools::Long nOutHeight = pThisRowInfo->nHeight;
 
                         if ( pInfo->bMerged && pInfo->pPatternAttr )
@@ -2617,7 +2608,7 @@ void ScOutputData::DrawClipMarks()
                         }
                     }
                 }
-                nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+                nPosX += pRowInfo[0].cellInfo(nX).nWidth * nLayoutSign;
             }
         }
         nPosY += pThisRowInfo->nHeight;
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 60cc1d4861a3..78cec1f661ef 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -991,7 +991,7 @@ bool ScOutputData::GetMergeOrigin( SCCOL nX, SCROW nY, 
SCSIZE nArrY,
     if (!mpDoc->ColHidden(nX, nTab) && nX >= nX1 && nX <= nX2
             && !mpDoc->RowHidden(nY, nTab) && nY >= nY1 && nY <= nY2)
     {
-        CellInfo* pInfo = &pRowInfo[nArrY].pCellInfo[nX+1];
+        CellInfo* pInfo = &pRowInfo[nArrY].cellInfo(nX);
         bHOver = pInfo->bHOverlapped;
         bVOver = pInfo->bVOverlapped;
     }
@@ -1021,8 +1021,8 @@ bool ScOutputData::GetMergeOrigin( SCCOL nX, SCROW nY, 
SCSIZE nArrY,
 
         if (rOverX >= nX1 && !bHidden)
         {
-            bHOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bHOverlapped;
-            bVOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bVOverlapped;
+            bHOver = pRowInfo[nArrY].cellInfo(rOverX).bHOverlapped;
+            bVOver = pRowInfo[nArrY].cellInfo(rOverX).bVOverlapped;
         }
         else
         {
@@ -1047,7 +1047,7 @@ bool ScOutputData::GetMergeOrigin( SCCOL nX, SCROW nY, 
SCSIZE nArrY,
             !mpDoc->RowHidden(rOverY, nTab) &&
             pRowInfo[nArrY].nRowNo == rOverY)
         {
-            bVOver = pRowInfo[nArrY].pCellInfo[rOverX+1].bVOverlapped;
+            bVOver = pRowInfo[nArrY].cellInfo(rOverX).bVOverlapped;
         }
         else
         {
@@ -1159,7 +1159,7 @@ bool ScOutputData::IsEmptyCellText( const RowInfo* 
pThisRowInfo, SCCOL nX, SCROW
 
     bool bEmpty;
     if ( pThisRowInfo && nX <= nX2 )
-        bEmpty = pThisRowInfo->pCellInfo[nX+1].bEmptyCellText;
+        bEmpty = pThisRowInfo->cellInfo(nX).bEmptyCellText;
     else
     {
         ScRefCellValue aCell(*mpDoc, ScAddress(nX, nY, nTab));
@@ -1245,7 +1245,7 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, 
tools::Long nPosX, too
     {
         //! extra member function for width?
         tools::Long nColWidth = ( nCompCol <= nX2 ) ?
-                pRowInfo[0].pCellInfo[nCompCol+1].nWidth :
+                pRowInfo[0].cellInfo(nCompCol).nWidth :
                 static_cast<tools::Long>( mpDoc->GetColWidth( nCompCol, nTab ) 
* mnPPTX );
         nCellPosX += nColWidth * nLayoutSign;
         ++nCompCol;
@@ -1254,7 +1254,7 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, 
tools::Long nPosX, too
     {
         --nCompCol;
         tools::Long nColWidth = ( nCompCol <= nX2 ) ?
-                pRowInfo[0].pCellInfo[nCompCol+1].nWidth :
+                pRowInfo[0].cellInfo(nCompCol).nWidth :
                 static_cast<tools::Long>( mpDoc->GetColWidth( nCompCol, nTab ) 
* mnPPTX );
         nCellPosX -= nColWidth * nLayoutSign;
     }
@@ -1293,7 +1293,7 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, 
tools::Long nPosX, too
     for ( tools::Long i=0; i<nMergeCols; i++ )
     {
         tools::Long nColWidth = ( nCellX+i <= nX2 ) ?
-                pRowInfo[0].pCellInfo[nCellX+i+1].nWidth :
+                pRowInfo[0].cellInfo(nCellX+i).nWidth :
                 static_cast<tools::Long>( mpDoc->GetColWidth( 
sal::static_int_cast<SCCOL>(nCellX+i), nTab ) * mnPPTX );
         nMergeSizeX += nColWidth;
     }
@@ -1369,13 +1369,13 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE 
nArrY, tools::Long nPosX, too
                 rParam.maClipRect.AdjustRight(nAdd * nLayoutSign );
 
                 if ( rThisRowInfo.nRowNo == nCellY && nRightX >= nX1 && 
nRightX <= nX2 )
-                    rThisRowInfo.pCellInfo[nRightX].bHideGrid = true;
+                    rThisRowInfo.cellInfo(nRightX-1).bHideGrid = true;
             }
 
             while ( nLeftMissing > 0 && nLeftX > 0 && ( bOverwrite || 
IsAvailable( nLeftX-1, nCellY ) ) )
             {
                 if ( rThisRowInfo.nRowNo == nCellY && nLeftX >= nX1 && nLeftX 
<= nX2 )
-                    rThisRowInfo.pCellInfo[nLeftX].bHideGrid = true;
+                    rThisRowInfo.cellInfo(nLeftX-1).bHideGrid = true;
 
                 --nLeftX;
                 tools::Long nAdd = static_cast<tools::Long>( 
mpDoc->GetColWidth( nLeftX, nTab ) * mnPPTX );
@@ -1388,14 +1388,14 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE 
nArrY, tools::Long nPosX, too
         //  even if rThisRowInfo isn't for nCellY (merged cells).
         if ( nRightMissing > 0 && bMarkClipped && nRightX >= nX1 && nRightX <= 
nX2 && !bBreak && !bCellIsValue )
         {
-            rThisRowInfo.pCellInfo[nRightX+1].nClipMark |= ScClipMark::Right;
+            rThisRowInfo.cellInfo(nRightX).nClipMark |= ScClipMark::Right;
             bAnyClipped = true;
             tools::Long nMarkPixel = static_cast<tools::Long>( 
SC_CLIPMARK_SIZE * mnPPTX );
             rParam.maClipRect.AdjustRight( -(nMarkPixel * nLayoutSign) );
         }
         if ( nLeftMissing > 0 && bMarkClipped && nLeftX >= nX1 && nLeftX <= 
nX2 && !bBreak && !bCellIsValue )
         {
-            rThisRowInfo.pCellInfo[nLeftX+1].nClipMark |= ScClipMark::Left;
+            rThisRowInfo.cellInfo(nLeftX).nClipMark |= ScClipMark::Left;
             bAnyClipped = true;
             tools::Long nMarkPixel = static_cast<tools::Long>( 
SC_CLIPMARK_SIZE * mnPPTX );
             rParam.maClipRect.AdjustLeft(nMarkPixel * nLayoutSign );
@@ -1566,11 +1566,11 @@ tools::Rectangle ScOutputData::LayoutStrings(bool 
bPixelToLogic, bool bPaint, co
         {
             tools::Long nPosX = nInitPosX;
             if ( nLoopStartX < nX1 )
-                nPosX -= pRowInfo[0].pCellInfo[nLoopStartX+1].nWidth * 
nLayoutSign;
+                nPosX -= pRowInfo[0].cellInfo(nLoopStartX).nWidth * 
nLayoutSign;
             for (SCCOL nX=nLoopStartX; nX<=nX2; nX++)
             {
                 bool bMergeEmpty = false;
-                CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+                const CellInfo* pInfo = &pThisRowInfo->cellInfo(nX);
                 bool bEmpty = nX < nX1 || pInfo->bEmptyCellText;
 
                 SCCOL nCellX = nX;                  // position where the cell 
really starts
@@ -1659,7 +1659,7 @@ tools::Rectangle ScOutputData::LayoutStrings(bool 
bPixelToLogic, bool bPaint, co
                 if (bDoCell)
                 {
                     if ( nCellY == nY && nCellX == nX && nCellX >= nX1 && 
nCellX <= nX2 )
-                        aCell = pThisRowInfo->pCellInfo[nCellX+1].maCell;
+                        aCell = pThisRowInfo->cellInfo(nCellX).maCell;
                     else
                         GetVisibleCell( nCellX, nCellY, nTab, aCell );      // 
get from document
                     if (aCell.isEmpty())
@@ -1679,7 +1679,7 @@ tools::Rectangle ScOutputData::LayoutStrings(bool 
bPixelToLogic, bool bPaint, co
                 {
                     if ( nCellY == nY && nCellX >= nX1 && nCellX <= nX2 )
                     {
-                        CellInfo& rCellInfo = 
pThisRowInfo->pCellInfo[nCellX+1];
+                        CellInfo& rCellInfo = pThisRowInfo->cellInfo(nCellX);
                         pPattern = rCellInfo.pPatternAttr;
                         pCondSet = rCellInfo.pConditionSet;
 
@@ -1897,7 +1897,7 @@ tools::Rectangle ScOutputData::LayoutStrings(bool 
bPixelToLogic, bool bPaint, co
                     //  right are handled by the flag for nX2
                     SCCOL nMarkX = ( nCellX <= nX2 ) ? nCellX : nX2;
                     RowInfo* pMarkRowInfo = ( nCellY == nY ) ? pThisRowInfo : 
&pRowInfo[0];
-                    pMarkRowInfo->pCellInfo[nMarkX+1].bEditEngine = true;
+                    pMarkRowInfo->cellInfo(nMarkX).bEditEngine = true;
                     bDoCell = false;    // don't draw here
                 }
                 if ( bDoCell )
@@ -2173,7 +2173,7 @@ tools::Rectangle ScOutputData::LayoutStrings(bool 
bPixelToLogic, bool bPaint, co
                         }
                     }
                 }
-                nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+                nPosX += pRowInfo[0].cellInfo(nX).nWidth * nLayoutSign;
             }
         }
         nPosY += pRowInfo[nArrY].nHeight;
@@ -3129,10 +3129,10 @@ void ScOutputData::DrawEditStandard(DrawEditParam& 
rParam)
             {
                 //  anywhere in the merged area...
                 SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
-                pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY 
: 1].pCellInfo[nClipX+1];
+                pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY 
: 1].cellInfo(nClipX);
             }
             else
-                pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
+                pClipMarkCell = &rParam.mpThisRowInfo->cellInfo(rParam.mnX);
 
             pClipMarkCell->nClipMark |= ScClipMark::Right;      //! also allow 
left?
             bAnyClipped = true;
@@ -3234,10 +3234,10 @@ void ScOutputData::ShowClipMarks( DrawEditParam& 
rParam, tools::Long nEngineWidt
     {
         //  anywhere in the merged area...
         SCCOL nClipX = (rParam.mnX < nX1) ? nX1 : rParam.mnX;
-        pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 
1].pCellInfo[nClipX + 1];
+        pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 
1].cellInfo(nClipX);
     }
     else
-        pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX + 1];
+        pClipMarkCell = &rParam.mpThisRowInfo->cellInfo(rParam.mnX);
 
     bAnyClipped = true;
     bVertical = true;
@@ -3970,10 +3970,10 @@ void ScOutputData::DrawEditStacked(DrawEditParam& 
rParam)
             {
                 //  anywhere in the merged area...
                 SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
-                pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY 
: 1].pCellInfo[nClipX+1];
+                pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY 
: 1].cellInfo(nClipX);
             }
             else
-                pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
+                pClipMarkCell = &rParam.mpThisRowInfo->cellInfo(rParam.mnX);
 
             pClipMarkCell->nClipMark |= ScClipMark::Right;      //! also allow 
left?
             bAnyClipped = true;
@@ -4257,10 +4257,10 @@ void ScOutputData::DrawEditAsianVertical(DrawEditParam& 
rParam)
             {
                 //  anywhere in the merged area...
                 SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
-                pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY 
: 1].pCellInfo[nClipX+1];
+                pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY 
: 1].cellInfo(nClipX);
             }
             else
-                pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
+                pClipMarkCell = &rParam.mpThisRowInfo->cellInfo(rParam.mnX);
 
             pClipMarkCell->nClipMark |= ScClipMark::Right;      //! also allow 
left?
             bAnyClipped = true;
@@ -4354,7 +4354,7 @@ void ScOutputData::DrawEdit(bool bPixelToLogic)
                 std::unique_ptr< ScPatternAttr > pPreviewPattr;
                 if (nX==nX1) nPosX = nInitPosX;                 // positions 
before nX1 are calculated individually
 
-                CellInfo*   pInfo = &pThisRowInfo->pCellInfo[nX+1];
+                const CellInfo* pInfo = &pThisRowInfo->cellInfo(nX);
                 if (pInfo->bEditEngine)
                 {
                     SCROW nY = pThisRowInfo->nRowNo;
@@ -4377,7 +4377,7 @@ void ScOutputData::DrawEdit(bool bPixelToLogic)
                             bDoCell = true;
                         }
                     }
-                    else if ( nX == nX2 && 
pThisRowInfo->pCellInfo[nX+1].maCell.isEmpty() )
+                    else if ( nX == nX2 && 
pThisRowInfo->cellInfo(nX).maCell.isEmpty() )
                     {
                         //  Rest of a long text further to the right?
 
@@ -4408,7 +4408,7 @@ void ScOutputData::DrawEdit(bool bPixelToLogic)
                         if ( nCellY == nY && nCellX >= nX1 && nCellX <= nX2 &&
                              !mpDoc->ColHidden(nCellX, nTab) )
                         {
-                            CellInfo& rCellInfo = 
pThisRowInfo->pCellInfo[nCellX+1];
+                            CellInfo& rCellInfo = 
pThisRowInfo->cellInfo(nCellX);
                             pPattern = rCellInfo.pPatternAttr;
                             pCondSet = rCellInfo.pConditionSet;
                             aCell = rCellInfo.maCell;
@@ -4495,7 +4495,7 @@ void ScOutputData::DrawEdit(bool bPixelToLogic)
                         bHyphenatorSet = aParam.mbHyphenatorSet;
                     }
                 }
-                nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+                nPosX += pRowInfo[0].cellInfo(nX).nWidth * nLayoutSign;
             }
         }
         nRowPosY += pRowInfo[nArrY].nHeight;
@@ -4551,7 +4551,7 @@ void ScOutputData::DrawRotated(bool bPixelToLogic)
             {
                 if (nX==nX1) nPosX = nInitPosX;                 // positions 
before nX1 are calculated individually
 
-                CellInfo* pInfo = &pThisRowInfo->pCellInfo[nX+1];
+                const CellInfo* pInfo = &pThisRowInfo->cellInfo(nX);
                 if ( pInfo->nRotateDir != ScRotateDir::NONE )
                 {
                     SCROW nY = pThisRowInfo->nRowNo;
@@ -4590,7 +4590,7 @@ void ScOutputData::DrawRotated(bool bPixelToLogic)
                         if (aCell.isEmpty() || IsEmptyCellText(pThisRowInfo, 
nX, nY))
                             bHidden = true;     // nRotateDir is also set 
without a cell
 
-                        tools::Long nCellWidth = 
static_cast<tools::Long>(pRowInfo[0].pCellInfo[nX+1].nWidth);
+                        tools::Long nCellWidth = 
static_cast<tools::Long>(pRowInfo[0].cellInfo(nX).nWidth);
 
                         SvxCellHorJustify eHorJust =
                                             
pPattern->GetItem(ATTR_HOR_JUSTIFY, pCondSet).GetValue();
@@ -4617,7 +4617,7 @@ void ScOutputData::DrawRotated(bool bPixelToLogic)
                                 while (nCol > nX)
                                 {
                                     --nCol;
-                                    nStartX -= nLayoutSign * 
static_cast<tools::Long>(pRowInfo[0].pCellInfo[nCol+1].nWidth);
+                                    nStartX -= nLayoutSign * 
static_cast<tools::Long>(pRowInfo[0].cellInfo(nCol).nWidth);
                                 }
                             }
                         }
@@ -5140,7 +5140,7 @@ void ScOutputData::DrawRotated(bool bPixelToLogic)
                         }
                     }
                 }
-                nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
+                nPosX += pRowInfo[0].cellInfo(nX).nWidth * nLayoutSign;
             }
         }
         nRowPosY += pRowInfo[nArrY].nHeight;
diff --git a/sc/source/ui/view/printfun.cxx b/sc/source/ui/view/printfun.cxx
index ccd015552074..dd2195b61401 100644
--- a/sc/source/ui/view/printfun.cxx
+++ b/sc/source/ui/view/printfun.cxx
@@ -443,7 +443,7 @@ static void lcl_HidePrint( const ScTableInfo& rTabInfo, 
SCCOL nX1, SCCOL nX2 )
         RowInfo* pThisRowInfo = &rTabInfo.mpRowInfo[nArrY];
         for (SCCOL nX=nX1; nX<=nX2; nX++)
         {
-            CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nX+1];
+            CellInfo& rCellInfo = pThisRowInfo->cellInfo(nX);
             if (!rCellInfo.bEmptyCellText)
                 if (rCellInfo.pPatternAttr->
                             GetItem(ATTR_PROTECTION, 
rCellInfo.pConditionSet).GetHidePrint())
@@ -1407,8 +1407,8 @@ void ScPrintFunc::DrawBorder( tools::Long nScrX, 
tools::Long nScrY, tools::Long
     OSL_ENSURE(aTabInfo.mnArrCount,"nArrCount == 0");
 
     aTabInfo.mpRowInfo[1].nHeight = static_cast<sal_uInt16>(nEffHeight);
-    aTabInfo.mpRowInfo[0].pCellInfo[1].nWidth =
-        aTabInfo.mpRowInfo[1].pCellInfo[1].nWidth = 
static_cast<sal_uInt16>(nEffWidth);
+    aTabInfo.mpRowInfo[0].cellInfo(0).nWidth =
+        aTabInfo.mpRowInfo[1].cellInfo(0).nWidth = 
static_cast<sal_uInt16>(nEffWidth);
 
     ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, 
pBorderDoc.get(), 0,
                                 nScrX+nLeft, nScrY+nTop, 0,0, 0,0, nScaleX, 
nScaleY );

Reply via email to