summaryrefslogtreecommitdiffstats
path: root/lotuswordpro/source/filter/lwpcelllayout.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'lotuswordpro/source/filter/lwpcelllayout.cxx')
-rw-r--r--lotuswordpro/source/filter/lwpcelllayout.cxx931
1 files changed, 931 insertions, 0 deletions
diff --git a/lotuswordpro/source/filter/lwpcelllayout.cxx b/lotuswordpro/source/filter/lwpcelllayout.cxx
new file mode 100644
index 000000000..cd5478e3f
--- /dev/null
+++ b/lotuswordpro/source/filter/lwpcelllayout.cxx
@@ -0,0 +1,931 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: IBM Corporation
+ *
+ * Copyright: 2008 by IBM Corporation
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+/**
+ * @file
+ * For LWP filter architecture prototype - cell layouts
+ */
+
+#include <memory>
+#include "lwpcelllayout.hxx"
+#include "lwpnumericfmt.hxx"
+#include "lwptable.hxx"
+#include "lwprowlayout.hxx"
+#include <lwpfilehdr.hxx>
+#include <lwpglobalmgr.hxx>
+
+#include <sal/log.hxx>
+#include <unotools/configmgr.hxx>
+
+#include <xfilter/xfstylemanager.hxx>
+#include <xfilter/xfcell.hxx>
+#include <xfilter/xfcellstyle.hxx>
+#include <xfilter/xfcolstyle.hxx>
+
+LwpCellLayout::LwpCellLayout(LwpObjectHeader const &objHdr, LwpSvStream* pStrm)
+ : LwpMiddleLayout(objHdr, pStrm)
+ , m_bConvertCell(false)
+ , crowid(0)
+ , ccolid(0)
+ , cType(LDT_NONE)
+{
+}
+
+LwpCellLayout::~LwpCellLayout()
+{}
+
+/**
+ * @short Get table layout pointer, if default cell layout, return NULL
+ * @param LwpTableLayout *
+ * @return
+ */
+LwpTableLayout * LwpCellLayout::GetTableLayout()
+{
+ LwpRowLayout * pRow = dynamic_cast<LwpRowLayout *>(GetParent().obj().get());
+ if(!pRow)
+ {
+ return nullptr;
+ }
+ LwpTableLayout * pTableLayout = pRow->GetParentTableLayout();
+ return pTableLayout;
+}
+/**
+ * @short Get table pointer, if default cell layout, return NULL
+ * @param LwpTable *
+ * @return
+ */
+LwpTable * LwpCellLayout::GetTable()
+{
+ LwpTableLayout * pTableLayout = GetTableLayout();
+ if(!pTableLayout)
+ {
+ return nullptr;
+ }
+ LwpTable *pTable = pTableLayout->GetTable();
+ return pTable;
+}
+/**
+ * @short Set current cell layout to cell layout map
+ * @param
+ * @return
+ */
+void LwpCellLayout::SetCellMap()
+{
+ LwpTableLayout * pTableLayout = GetTableLayout();
+ if (pTableLayout)
+ pTableLayout->SetWordProCellMap(crowid, ccolid, this);
+}
+/**
+ * @short Get actual width of this cell layout
+ * @param
+ * @return width (cm)
+ */
+double LwpCellLayout::GetActualWidth()
+{
+ //Get table layout
+ LwpTableLayout * pTableLayout = GetTableLayout();
+
+ if (pTableLayout == nullptr)
+ {
+ return GetGeometryWidth();
+ }
+
+ OUString strColStyle = pTableLayout->GetColumnWidth(ccolid);
+
+ XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
+ XFColStyle *pStyle = static_cast<XFColStyle *>(pXFStyleManager->FindStyle(strColStyle));
+ if(pStyle)
+ {
+ return pStyle->GetWidth();
+ }
+
+ return GetGeometryWidth();
+}
+
+/**
+ * @short Apply padding to cell style
+ * @param pCellStyle - pointer of XFCellStyle
+ * @return
+ */
+void LwpCellLayout::ApplyPadding(XFCellStyle *pCellStyle)
+{
+ double fLeft = GetMarginsValue(MARGIN_LEFT);
+ double fRight = GetMarginsValue(MARGIN_RIGHT);
+ double fTop = GetMarginsValue(MARGIN_TOP);
+ double fBottom = GetMarginsValue(MARGIN_BOTTOM);
+ pCellStyle->SetPadding(static_cast<float>(fLeft),static_cast<float>(fRight),static_cast<float>(fTop),static_cast<float>(fBottom));
+}
+/**
+ * @short Apply border to cell style according to cell position, default cell layout won't use this function
+ * @param
+ * @return pCellStyle - pointer of XFCellStyle
+ */
+void LwpCellLayout::ApplyBorders(XFCellStyle *pCellStyle)
+{
+ // judge cell border type
+ LwpCellBorderType eType = GetCellBorderType(crowid, ccolid, GetTableLayout());
+
+ // get left cell and judge if neighbour border is different
+ std::unique_ptr<XFBorders> xBorders(GetXFBorders());
+ if (!xBorders)
+ {
+ return;
+ }
+
+ switch (eType)
+ {
+ case enumNoBottomBorder:
+ xBorders->SetWidth(enumXFBorderBottom, 0);
+ break;
+ case enumNoLeftBorder:
+ xBorders->SetWidth(enumXFBorderLeft, 0);
+ break;
+ case enumNoLeftNoBottomBorder:
+ xBorders->SetWidth(enumXFBorderBottom, 0);
+ xBorders->SetWidth(enumXFBorderLeft, 0);
+ break;
+ case enumWholeBorder:
+ break;
+ default:
+ assert(false);
+ }
+ pCellStyle->SetBorders(xBorders.release());
+}
+/**
+ * @short Apply watermark to cell style
+ * @param pCellStyle - pointer of XFCellStyle
+ * @return
+ */
+void LwpCellLayout::ApplyWatermark(XFCellStyle *pCellStyle)
+{
+ std::unique_ptr<XFBGImage> xBGImage(GetXFBGImage());
+ if (xBGImage)
+ {
+ pCellStyle->SetBackImage(xBGImage);
+ }
+}
+
+/**
+ * @short Apply pattern fill to cell style
+ * @param pCellStyle - pointer of XFCellStyle
+ * @return
+ */
+void LwpCellLayout::ApplyPatternFill(XFCellStyle* pCellStyle)
+{
+ std::unique_ptr<XFBGImage> xXFBGImage(GetFillPattern());
+ if (xXFBGImage)
+ {
+ pCellStyle->SetBackImage(xXFBGImage);
+ }
+}
+
+/**
+ * @short Apply background to cell style
+ * @param pCellStyle - pointer of XFCellStyle
+ * @return
+ */
+void LwpCellLayout::ApplyBackGround(XFCellStyle* pCellStyle)
+{
+ if (IsPatternFill())
+ {
+ ApplyPatternFill(pCellStyle);
+ }
+ else
+ {
+ ApplyBackColor(pCellStyle);
+ }
+}
+/**
+ * @short Apply back color to cell style
+ * @param pCellStyle - pointer of XFCellStyle
+ * @return
+ */
+void LwpCellLayout::ApplyBackColor(XFCellStyle *pCellStyle)
+{
+ LwpColor* pColor = GetBackColor();
+ if(pColor && pColor->IsValidColor())
+ {
+ XFColor aXFColor(pColor->To24Color());
+ pCellStyle->SetBackColor(aXFColor);
+ }
+}
+/**
+ * @short register style of cell layout
+ * @param pCellStyle The style of the cell, which would be applied to the cell.
+ * @return
+ */
+void LwpCellLayout::ApplyFmtStyle(XFCellStyle *pCellStyle)
+{
+ LwpLayoutNumerics* pLayoutNumerics = dynamic_cast<LwpLayoutNumerics*>(cLayNumerics.obj().get());
+ if (!pLayoutNumerics)
+ {
+ // if current layout doesn't have format, go to based on layout
+ LwpCellLayout* pCellLayout = dynamic_cast<LwpCellLayout*>(GetBasedOnStyle().get());
+ if (pCellLayout)
+ {
+ pLayoutNumerics = dynamic_cast<LwpLayoutNumerics*>(pCellLayout->GetNumericsObject().obj().get());
+ }
+ }
+
+ // apply format style
+ if (pLayoutNumerics)
+ {
+ XFStyle* pStyle = pLayoutNumerics->Convert();
+ if (pStyle)
+ {
+ XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
+ m_NumfmtName = pXFStyleManager->AddStyle(std::unique_ptr<XFStyle>(pStyle)).m_pStyle->GetStyleName();
+ pCellStyle->SetDataStyle(m_NumfmtName);
+ }
+ }
+}
+/**
+ * @short get style name according to cell position, only table default cells use this function
+ * @param nRow - default cell position row number
+ * @param nCol - default cell position col number
+ * @return OUString - registered cell style name
+ */
+OUString const & LwpCellLayout::GetCellStyleName(sal_uInt16 nRow, sal_uInt16 nCol, LwpTableLayout * pTableLayout)
+{
+ // judge cell border type
+ LwpCellBorderType eType = GetCellBorderType(nRow, nCol, pTableLayout);
+ return m_CellStyleNames[eType];
+}
+/**
+* Make the XFCell
+* @param aTableID - ID of the table which this cell belongs to
+* @param bIsTopRow - whether current cell is top row
+* @param bIsRightCol - whether current cell is the rightest column
+* @return XFCell*
+*/
+rtl::Reference<XFCell> LwpCellLayout::ConvertCell(LwpObjectID aTableID, sal_uInt16 nRow, sal_uInt16 nCol)
+{
+ // if cell layout is aTableID's default cell layout
+ // it can't have any content, bypass these code
+ LwpTable * pTable = dynamic_cast<LwpTable *>(aTableID.obj().get());
+ if (!pTable)
+ {
+ assert(false);
+ return nullptr;
+ }
+ rtl::Reference<XFCell> xXFCell(new XFCell);
+ OUString aStyleName = m_StyleName;
+
+ // if cell layout is aTableID's default cell layout
+ // we should adjust its style by current position
+ if (pTable->GetDefaultCellStyle() == GetObjectID())
+ {
+ aStyleName = GetCellStyleName(nRow, nCol, pTable->GetTableLayout().get());
+ }
+
+ // content of cell
+ LwpStory* pStory = dynamic_cast<LwpStory*>(m_Content.obj().get());
+ if (pStory)
+ {
+ pStory->XFConvert(xXFCell.get());
+ }
+
+ ApplyProtect(xXFCell.get(), aTableID);
+ xXFCell->SetStyleName(aStyleName);
+ return xXFCell;
+}
+
+LwpPara* LwpCellLayout::GetLastParaOfPreviousStory()
+{
+ LwpObjectID* pPreStoryID = GetPreviousCellStory();
+ if (pPreStoryID && !(pPreStoryID->IsNull()))
+ {
+ LwpStory* pPreStory = dynamic_cast<LwpStory*>(pPreStoryID->obj(VO_STORY).get());
+ if (!pPreStory)
+ {
+ SAL_WARN("lwp", "unexpected null VO_STORY");
+ return nullptr;
+ }
+ return dynamic_cast<LwpPara*>(pPreStory->GetLastPara().obj(VO_PARA).get());
+ }
+ else
+ {
+ return nullptr;
+ }
+}
+
+/**
+ * @short Get previous cell which used for bullet inside cell
+ * @param
+ * @return LwpObjectID * - object ID of cell content story
+ */
+LwpObjectID * LwpCellLayout::GetPreviousCellStory()
+{
+ LwpTable *pTable = GetTable();
+ if (!pTable)
+ {
+ assert(false);
+ return nullptr;
+ }
+ sal_uInt16 nRow = crowid;
+ sal_uInt16 nCol = ccolid;
+
+ // if table is reset paragraph in columns, get cell on the top side of current cell
+ if (pTable->IsNumberDown())
+ {
+ if (nRow == 0)
+ {
+ return nullptr;
+ }
+ nRow -=1;
+ }
+ else
+ {
+ // if not, get cell on the left side of current cell
+ if (nCol == 0)
+ {
+ if (nRow == 0)
+ {
+ return nullptr;
+ }
+ else
+ {
+ nRow--;
+ nCol = pTable->GetColumn() - 1;
+ }
+ }
+ else
+ {
+ nCol -=1;
+ }
+ }
+
+ // get the object id pointer of previous cell story
+ LwpTableLayout * pTableLayout = GetTableLayout();
+ if (!pTableLayout)
+ {
+ assert(false);
+ return nullptr;
+ }
+ return pTableLayout->SearchCellStoryMap(nRow, nCol);
+}
+
+/**
+ * @short judge border type by cell neighbour
+ * @param nRow
+ * @param nCol
+ * @param pTableLayout
+ * @return LwpCellBorderType
+ */
+LwpCellBorderType LwpCellLayout::GetCellBorderType(sal_uInt16 nRow, sal_uInt16 nCol, LwpTableLayout * pTableLayout)
+{
+ if (!pTableLayout)
+ return enumWholeBorder;
+
+ // get left cell and judge if neighbour border is different
+ std::unique_ptr<XFBorders> xBorders(GetXFBorders());
+ if (!xBorders)
+ {
+ return enumWholeBorder;
+ }
+ XFBorder& rLeftBorder = xBorders->GetLeft();
+ XFBorder& rBottomBorder = xBorders->GetBottom();
+ bool bNoLeftBorder = false;
+ bool bNoBottomBorder = false;
+
+ LwpCellLayout * pLeftNeighbour = GetCellByRowCol(nRow, GetLeftColID(nCol), pTableLayout);
+ if (pLeftNeighbour)
+ {
+ std::unique_ptr<XFBorders> pNeighbourBorders = pLeftNeighbour->GetXFBorders();
+ if (pNeighbourBorders)
+ {
+ XFBorder& rRightBorder = pNeighbourBorders->GetRight();
+ if (rLeftBorder == rRightBorder)
+ {
+ // for these 2 types cell, left border should be ignored for sake of avoiding duplication border
+ // but if left border is different with right border of left cell
+ // we should not ignored it
+ bNoLeftBorder = true;
+ }
+ }
+
+ }
+
+ LwpCellLayout * pBelowNeighbour = GetCellByRowCol(GetBelowRowID(nRow), nCol, pTableLayout);
+ if (pBelowNeighbour) //&& (eType == enumRightNotLastCellBorder || eType == enumLeftNotLastCellBorder) )
+ {
+ std::unique_ptr<XFBorders> pBelowBorders = pBelowNeighbour->GetXFBorders();
+ if (pBelowBorders)
+ {
+ XFBorder& rTopBorder = pBelowBorders->GetTop();
+ if (rTopBorder == rBottomBorder)
+ {
+ // for these 2 types cell, bottom border should be ignored for sake of avoiding duplication border
+ // but if bottom border is different with right border of left cell
+ // we should not ignored it
+ bNoBottomBorder = true;
+ }
+ }
+ }
+
+ xBorders.reset();
+
+ if (bNoBottomBorder)
+ {
+ if (bNoLeftBorder)
+ {
+ return enumNoLeftNoBottomBorder;
+ }
+ return enumNoBottomBorder;
+ }
+ if (bNoLeftBorder)
+ {
+ return enumNoLeftBorder;
+ }
+ return enumWholeBorder;
+}
+
+/**
+ * @short Get neighbour cell by specifying ROW+COL
+ * @param nRow
+ * @param nCol
+ * @return LwpCellLayout *
+ */
+LwpCellLayout * LwpCellLayout::GetCellByRowCol(sal_uInt16 nRow, sal_uInt16 nCol, LwpTableLayout * pTableLayout)
+{
+ return pTableLayout->GetCellByRowCol(nRow, nCol);
+}
+/**
+ * @short Register table's default cell layout
+ * @param
+ * @return
+ */
+void LwpCellLayout::RegisterDefaultCell()
+{
+ XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
+ for (sal_uInt16 eLoop = enumWholeBorder; eLoop < enumCellBorderTopLimit; eLoop++)
+ {
+ // register cell style
+ std::unique_ptr<XFCellStyle> xCellStyle(new XFCellStyle());
+
+ ApplyPadding(xCellStyle.get());
+ ApplyBackColor(xCellStyle.get());
+ ApplyWatermark(xCellStyle.get());
+ ApplyFmtStyle(xCellStyle.get());
+ xCellStyle->SetAlignType(enumXFAlignNone, GetVerticalAlignmentType());
+
+ std::unique_ptr<XFBorders> xBorders(GetXFBorders());
+ if (xBorders)
+ {
+ switch(eLoop)
+ {
+ case enumNoBottomBorder:
+
+ //| |
+
+ // remove bottom line
+ xBorders->SetWidth(enumXFBorderBottom, 0);
+ break;
+ case enumNoLeftNoBottomBorder:
+
+ // |
+
+ // remove left and bottom
+ xBorders->SetWidth(enumXFBorderLeft, 0);
+ xBorders->SetWidth(enumXFBorderBottom, 0);
+ break;
+ case enumWholeBorder:
+
+ //||
+
+ // nothing to remove
+ break;
+ case enumNoLeftBorder:
+
+ //| |
+
+ // remove left line
+ xBorders->SetWidth(enumXFBorderLeft, 0);
+ break;
+ default:
+ assert(false);
+ }
+ xCellStyle->SetBorders(xBorders.release());
+ }
+ m_CellStyleNames[eLoop] = pXFStyleManager->AddStyle(std::move(xCellStyle)).m_pStyle->GetStyleName();
+ }
+}
+/**
+ * @short Register 4 types of cell style and register content styles
+ * @param
+ * @param
+ * @param
+ * @return
+ */
+void LwpCellLayout::RegisterStyle()
+{
+ rtl::Reference<LwpVirtualLayout> xParent(dynamic_cast<LwpVirtualLayout *>(GetParent().obj().get()));
+ if (!xParent.is() || xParent->GetLayoutType() != LWP_ROW_LAYOUT)
+ {
+ // default cell layout, we must register 4 styles for it
+ RegisterDefaultCell();
+ return;
+ }
+
+ // register cell style
+ std::unique_ptr<XFCellStyle> xCellStyle(new XFCellStyle);
+
+ ApplyPadding(xCellStyle.get());
+ ApplyBackGround(xCellStyle.get());
+ ApplyWatermark(xCellStyle.get());
+ ApplyFmtStyle(xCellStyle.get());
+ ApplyBorders(xCellStyle.get());
+
+ xCellStyle->SetAlignType(enumXFAlignNone, GetVerticalAlignmentType());
+
+ XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
+ m_StyleName = pXFStyleManager->AddStyle(std::move(xCellStyle)).m_pStyle->GetStyleName();
+
+ // content object register styles
+ rtl::Reference<LwpObject> pObj = m_Content.obj();
+ if (pObj.is())
+ {
+ pObj->SetFoundry(m_pFoundry);
+ pObj->DoRegisterStyle();
+ }
+
+ //register child layout style
+ RegisterChildStyle();
+}
+/**
+ * @short Read cell layout
+ * @param
+ * @return
+ */
+void LwpCellLayout::Read()
+{
+ LwpObjectStream* pStrm = m_pObjStrm.get();
+
+ LwpMiddleLayout::Read();
+
+ // before the layout hierarchy rework
+ if (LwpFileHeader::m_nFileRevision < 0x000b)
+ {
+ assert(false);
+ }
+ else
+ {
+ crowid = pStrm->QuickReaduInt16();
+ ccolid = static_cast<sal_uInt8>(pStrm->QuickReaduInt16()); // written as a lushort
+
+ sal_uInt16 type;
+
+ type = pStrm->QuickReaduInt16();
+ pStrm->SkipExtra();
+ cType = static_cast<LeaderDotType>(type);
+
+ cLayNumerics.ReadIndexed(pStrm);
+ cLayDiagonalLine.ReadIndexed(pStrm);
+
+ pStrm->SkipExtra();
+ }
+}
+
+/**
+* Apply protect attribute to cell of table
+* @param aTableID - ID of the table which the cell belongs to
+* @param
+* @return XFCell*
+*/
+void LwpCellLayout::ApplyProtect(XFCell * pCell, LwpObjectID aTableID)
+{
+ bool bProtected = false;
+ // judge current cell
+ if (GetIsProtected())
+ {
+ bProtected = true;
+ }
+ else
+ {
+ // judge base on
+ LwpCellLayout * pBase = dynamic_cast<LwpCellLayout *>(GetBasedOnStyle().get());
+ if (pBase && pBase->GetIsProtected())
+ {
+ bProtected = true;
+ }
+ else
+ {
+ // judge whole table
+ LwpTable * pTable = dynamic_cast<LwpTable *>(aTableID.obj().get());
+ rtl::Reference<LwpTableLayout> xTableLayout(pTable ? pTable->GetTableLayout() : nullptr);
+ LwpSuperTableLayout * pSuper = xTableLayout.is() ? xTableLayout->GetSuperTableLayout() : nullptr;
+ if (pSuper && pSuper->GetIsProtected())
+ {
+ bProtected = true;
+ }
+ }
+ }
+
+ pCell->SetProtect(bProtected);
+}
+
+LwpConnectedCellLayout::LwpConnectedCellLayout(LwpObjectHeader const &objHdr, LwpSvStream* pStrm)
+ : LwpCellLayout(objHdr, pStrm)
+ , cnumrows(0)
+ , cnumcols(0)
+ , m_nRealrowspan(0)
+ , m_nRealcolspan(0)
+{
+}
+
+LwpConnectedCellLayout::~LwpConnectedCellLayout()
+{}
+/**
+ * @short Set current connected cell layout to cell layout map
+ * @param pCellLayoutMap - cell layout map reference
+ * @return
+ */
+void LwpConnectedCellLayout::SetCellMap()
+{
+ LwpTableLayout * pTableLayout = GetTableLayout();
+ if (!pTableLayout)
+ return;
+
+ sal_uInt16 nRowSpan = m_nRealrowspan;
+
+ for (sal_uInt16 iLoop = 0; iLoop < nRowSpan; iLoop ++)
+ {
+ for (sal_uInt16 jLoop = 0; jLoop < cnumcols; jLoop ++)
+ pTableLayout->SetWordProCellMap(iLoop + crowid, jLoop + ccolid, this);
+ }
+}
+
+/**
+ * @short judge border type by cell neighbour
+ * @param nRow
+ * @param nCol
+ * @param pTableLayout
+ * @return LwpCellBorderType
+ */
+LwpCellBorderType LwpConnectedCellLayout::GetCellBorderType(sal_uInt16 nRow, sal_uInt16 nCol, LwpTableLayout * pTableLayout)
+{
+ if (!pTableLayout)
+ throw std::runtime_error("missing table layout");
+
+ sal_uInt16 nRowSpan = m_nRealrowspan;
+
+ // get left cell and judge if neighbour border is different
+ std::unique_ptr<XFBorders> xBorders(GetXFBorders());
+ if( !xBorders)
+ {
+ return enumWholeBorder;
+ }
+ XFBorder& rLeftBorder = xBorders->GetLeft();
+ XFBorder& rBottomBorder = xBorders->GetBottom();
+ bool bNoLeftBorder = true;
+ bool bNoBottomBorder = true;
+
+ if (nCol == 0)
+ {
+ bNoLeftBorder = false;
+ }
+ else
+ {
+ for (sal_uInt16 iLoop=0; iLoop < nRowSpan; iLoop++)
+ {
+ LwpCellLayout * pLeftNeighbour = GetCellByRowCol(nRow+iLoop, GetLeftColID(nCol), pTableLayout);
+ if (pLeftNeighbour)
+ {
+ std::unique_ptr<XFBorders> pNeighbourBorders(pLeftNeighbour->GetXFBorders());
+ if (pNeighbourBorders)
+ {
+ XFBorder& rRightBorder = pNeighbourBorders->GetRight();
+ if (rLeftBorder != rRightBorder)
+ {
+ // if left border is different with right border of left cell
+ // we should not ignored it
+ bNoLeftBorder = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ LwpTable* pTable = pTableLayout->GetTable();
+ if (!pTable)
+ throw std::runtime_error("missing table");
+
+ if ( (nRow + nRowSpan) == pTable->GetRow())
+ {
+ bNoBottomBorder = false;
+ }
+ else
+ {
+ for (sal_uInt16 iLoop = 0; iLoop < cnumcols; iLoop ++)
+ {
+ LwpCellLayout * pBelowNeighbour = GetCellByRowCol(nRow + nRowSpan, nCol+iLoop, pTableLayout);
+ if (pBelowNeighbour)
+ {
+ std::unique_ptr<XFBorders> pBelowBorders(pBelowNeighbour->GetXFBorders());
+ if (pBelowBorders)
+ {
+ XFBorder& rTopBorder = pBelowBorders->GetTop();
+ if (rTopBorder != rBottomBorder)
+ {
+ // if bottom border is different with right border of left cell
+ // we should not ignored it
+ bNoBottomBorder = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ xBorders.reset();
+
+ if (bNoBottomBorder)
+ {
+ if (bNoLeftBorder)
+ {
+ return enumNoLeftNoBottomBorder;
+ }
+ return enumNoBottomBorder;
+ }
+ if (bNoLeftBorder)
+ {
+ return enumNoLeftBorder;
+ }
+ return enumWholeBorder;
+}
+/**
+ * @short Read connected cell layout
+ * @param
+ * @return
+ */
+void LwpConnectedCellLayout::Read()
+{
+ LwpCellLayout::Read();
+
+ cnumrows = m_pObjStrm->QuickReaduInt16();
+ sal_uInt16 numcols = m_pObjStrm->QuickReaduInt16(); // written as a lushort
+ cnumcols = static_cast<sal_uInt8>(numcols);
+
+ m_nRealrowspan = cnumrows;
+ if (utl::ConfigManager::IsFuzzing())
+ m_nRealrowspan = std::min<sal_uInt16>(m_nRealrowspan, 128);
+ m_nRealcolspan = cnumcols;
+
+ m_pObjStrm->SkipExtra();
+}
+
+rtl::Reference<XFCell> LwpConnectedCellLayout::ConvertCell(LwpObjectID aTableID, sal_uInt16 nRow, sal_uInt16 nCol)
+{
+ rtl::Reference<XFCell> xXFCell = LwpCellLayout::ConvertCell(aTableID, nRow, nCol);
+ xXFCell->SetColumnSpaned(cnumcols);
+ return xXFCell;
+}
+
+/**
+ * @short parse connected cell layout
+ * @param pOutputStream - output stream
+ * @return
+ */
+void LwpConnectedCellLayout::Parse(IXFStream* /*pOutputStream*/)
+{
+}
+
+LwpHiddenCellLayout::LwpHiddenCellLayout(LwpObjectHeader const &objHdr, LwpSvStream* pStrm)
+ : LwpCellLayout(objHdr, pStrm)
+{}
+
+LwpHiddenCellLayout::~LwpHiddenCellLayout()
+{}
+/**
+ * @short Set current hidden cell layout to cell layout map
+ * @param
+ * @return
+ */
+void LwpHiddenCellLayout::SetCellMap()
+{
+}
+/**
+ * @short Read hidden cell layout
+ * @param
+ * @return
+ */
+void LwpHiddenCellLayout::Read()
+{
+ LwpCellLayout::Read();
+
+ cconnectedlayout.ReadIndexed(m_pObjStrm.get());
+ m_pObjStrm->SkipExtra();
+
+}
+/**
+ * @short Convert hidden cell layout
+ * @param aTableID - Object ID of table
+ * @return XFCell * - pointer to converted cell
+ */
+
+rtl::Reference<XFCell> LwpHiddenCellLayout::ConvertCell(LwpObjectID aTableID, sal_uInt16 nRow, sal_uInt16 nCol)
+{
+ if (!cconnectedlayout.obj().is())
+ return nullptr;
+ LwpConnectedCellLayout* pConnCell = dynamic_cast<LwpConnectedCellLayout* >(cconnectedlayout.obj().get());
+
+ if (!pConnCell || nRow < (pConnCell->GetNumrows()+pConnCell->GetRowID()))
+ return nullptr;
+ // if the hidden cell should be displayed for limit of SODC
+ // use the default cell layout
+ rtl::Reference<XFCell> xXFCell;
+ LwpTable *pTable = dynamic_cast<LwpTable *>(aTableID.obj().get());
+ if (pTable)
+ {
+ LwpCellLayout *pDefault = dynamic_cast<LwpCellLayout *>(pTable->GetDefaultCellStyle().obj().get());
+ if (pDefault)
+ {
+ xXFCell = pDefault->DoConvertCell(aTableID, nRow, nCol);
+ }
+ else
+ {
+ xXFCell = pConnCell->DoConvertCell(aTableID, nRow, nCol);
+ }
+ xXFCell->SetColumnSpaned(pConnCell->GetNumcols());
+ }
+ else
+ {
+ assert(false);
+ }
+ return xXFCell;
+}
+/**
+ * @short parse hidden cell layout
+ * @param pOutputStream - output stream
+ * @return
+ */
+ void LwpHiddenCellLayout::Parse(IXFStream* /*pOutputStream*/)
+{
+}
+
+LwpParallelColumnsBlock::LwpParallelColumnsBlock(LwpObjectHeader const &objHdr, LwpSvStream* pStrm):LwpCellLayout(objHdr, pStrm)
+{}
+
+LwpParallelColumnsBlock::~LwpParallelColumnsBlock()
+{}
+
+void LwpParallelColumnsBlock::Read()
+{
+ LwpCellLayout::Read();
+ m_pObjStrm->SkipExtra();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */