summaryrefslogtreecommitdiffstats
path: root/lotuswordpro/source/filter/lwprowlayout.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /lotuswordpro/source/filter/lwprowlayout.cxx
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lotuswordpro/source/filter/lwprowlayout.cxx')
-rw-r--r--lotuswordpro/source/filter/lwprowlayout.cxx499
1 files changed, 499 insertions, 0 deletions
diff --git a/lotuswordpro/source/filter/lwprowlayout.cxx b/lotuswordpro/source/filter/lwprowlayout.cxx
new file mode 100644
index 000000000..b5583d19e
--- /dev/null
+++ b/lotuswordpro/source/filter/lwprowlayout.cxx
@@ -0,0 +1,499 @@
+/* -*- 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 - row layouts
+ */
+
+#include "lwprowlayout.hxx"
+#include "lwptable.hxx"
+#include <lwpglobalmgr.hxx>
+#include <xfilter/xfstylemanager.hxx>
+#include <xfilter/xfrow.hxx>
+#include <xfilter/xfrowstyle.hxx>
+#include <xfilter/xftable.hxx>
+#include <xfilter/xfcell.hxx>
+#include <o3tl/sorted_vector.hxx>
+
+LwpRowLayout::LwpRowLayout(LwpObjectHeader const &objHdr, LwpSvStream* pStrm)
+ : LwpVirtualLayout(objHdr, pStrm)
+ , crowid(0)
+ , cheight(0)
+ , cLeaderDotCount(0)
+ , cLeaderDotY(0)
+ , cRowFlags(0)
+{
+ m_ConnCellList.clear();
+}
+
+LwpRowLayout::~LwpRowLayout()
+{}
+
+/**
+ * @short register row style
+ * @param
+ * @param
+ * @param
+ * @return
+ */
+void LwpRowLayout::SetRowMap()
+{
+ LwpObjectID *pCellID= &GetChildHead();
+ LwpCellLayout * pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
+
+ o3tl::sorted_vector<LwpCellLayout*> aSeen;
+ while(pCellLayout)
+ {
+ bool bAlreadySeen = !aSeen.insert(pCellLayout).second;
+ if (bAlreadySeen)
+ throw std::runtime_error("loop in conversion");
+
+ pCellLayout->SetCellMap();
+
+ pCellID = &pCellLayout->GetNext();
+ pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
+ }
+}
+/**
+ * @short register row style
+ * @param
+ * @param
+ * @param
+ * @return
+ */
+void LwpRowLayout::RegisterStyle()
+{
+ // register row style
+ std::unique_ptr<XFRowStyle> pRowStyle(new XFRowStyle());
+
+ if (m_nDirection & 0x0030)
+ {
+ pRowStyle->SetMinRowHeight(static_cast<float>(LwpTools::ConvertFromUnitsToMetric(cheight)));
+ }
+ else
+ {
+ pRowStyle->SetRowHeight(static_cast<float>(LwpTools::ConvertFromUnitsToMetric(cheight)));
+ }
+ XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
+ m_StyleName = pXFStyleManager->AddStyle(std::move(pRowStyle)).m_pStyle->GetStyleName();
+
+ LwpTableLayout* pTableLayout = GetParentTableLayout();
+ if (pTableLayout)
+ {
+ pTableLayout->GetTable();
+ }
+ // register cells' style
+ LwpObjectID *pCellID= &GetChildHead();
+ LwpCellLayout * pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
+
+ o3tl::sorted_vector<LwpCellLayout*> aSeen;
+ while (pCellLayout)
+ {
+ bool bAlreadySeen = !aSeen.insert(pCellLayout).second;
+ if (bAlreadySeen)
+ throw std::runtime_error("loop in conversion");
+
+ pCellLayout->SetFoundry(m_pFoundry);
+ pCellLayout->RegisterStyle();
+ pCellID = &pCellLayout->GetNext();
+ pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
+ }
+
+}
+/**
+ * @short register row style
+ * @param
+ * @param
+ * @param
+ * @return
+ */
+void LwpRowLayout::Read()
+{
+ #define MAXUNIT (0x7fffffffL) // Highest positive UNIT value
+ LwpObjectStream* pStrm = m_pObjStrm.get();
+
+ LwpVirtualLayout::Read();
+
+ //skip CLiteLayout data;
+ LwpAtomHolder ContentClass;
+ ContentClass.Read(pStrm);
+ pStrm->SkipExtra();
+
+ // Row layout content
+ crowid = pStrm->QuickReaduInt16();
+ cheight = pStrm->QuickReadInt32();
+ cLeaderDotCount = static_cast<sal_uInt8>(pStrm->QuickReaduInt16()); // was written as lushort.
+ cLeaderDotY = MAXUNIT; // Sentinel meaning "not calculated yet"
+ cRowFlags = static_cast<sal_uInt8>(pStrm->QuickReaduInt16()); // was written as lushort.
+
+ pStrm->SkipExtra();
+}
+
+/**
+ * @short Parse rows with connect cell
+ * @param pXFTable - pointer to created XFTable
+ */
+void LwpRowLayout::ConvertRow(rtl::Reference<XFTable> const & pXFTable,sal_uInt8 nStartCol,sal_uInt8 nEndCol)
+{
+ LwpTableLayout* pTableLayout = GetParentTableLayout();
+ if (!pTableLayout)
+ throw std::runtime_error("missing TableLayout");
+ LwpTable* pTable = pTableLayout->GetTable();
+
+ //calculate the connected cell position
+ sal_Int32 nMarkConnCell = FindMarkConnCell(nStartCol,nEndCol);
+
+ //if there is no connected cell
+ if (nMarkConnCell == -1)
+ {
+ ConvertCommonRow(pXFTable,nStartCol,nEndCol);
+ return;
+ }
+
+ //register connect row style
+ sal_uInt16 nRowMark = crowid + GetCurMaxSpannedRows(nStartCol,nEndCol);
+ rtl::Reference<XFRow> xXFRow(new XFRow);
+ RegisterCurRowStyle(xXFRow.get(), nRowMark);
+
+ //if there is connected cell
+ for (sal_uInt8 i=nStartCol; i<nEndCol; )
+ {
+ rtl::Reference<XFCell> xXFCell;
+ sal_uInt8 nColMark;
+
+ if (nMarkConnCell == -1)
+ nColMark = nEndCol;
+ else
+ nColMark = m_ConnCellList[nMarkConnCell]->GetColID();
+
+ if (nColMark > i)//create subtable
+ {
+ xXFCell.set(new XFCell);
+ xXFCell->SetColumnSpaned(nColMark-i);
+ rtl::Reference<XFTable> xSubTable(new XFTable);
+ pTableLayout->ConvertTable(xSubTable,crowid,nRowMark,i,nColMark);
+ xXFCell->Add(xSubTable.get());
+ i = nColMark;
+ }
+ else
+ {
+ sal_uInt8 nColID = m_ConnCellList[nMarkConnCell]->GetColID()
+ +m_ConnCellList[nMarkConnCell]->GetNumcols()-1;
+ xXFCell = m_ConnCellList[nMarkConnCell]->DoConvertCell(
+ pTable->GetObjectID(),
+ crowid+m_ConnCellList[nMarkConnCell]->GetNumrows()-1,
+ m_ConnCellList[nMarkConnCell]->GetColID());
+
+ //set all cell in this merge cell to cellsmap
+ pTableLayout->SetCellsMap(crowid, i, nRowMark - 1, nColID, xXFCell.get());
+
+ i += m_ConnCellList[nMarkConnCell]->GetNumcols();
+ nMarkConnCell = FindNextMarkConnCell(static_cast<sal_uInt16>(nMarkConnCell),nEndCol);
+ }
+
+ if (xXFCell)
+ xXFRow->AddCell(xXFCell);
+ }
+ pXFTable->AddRow(xXFRow);
+}
+
+/**
+ * @short register row style in SODC table
+ * @param pXFRow - pointer of row
+ * @param nRowMark - spanned row number
+ */
+void LwpRowLayout::RegisterCurRowStyle(XFRow* pXFRow,sal_uInt16 nRowMark)
+{
+ XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
+ XFRowStyle* pRowStyle = static_cast<XFRowStyle*>(pXFStyleManager->FindStyle(m_StyleName));
+ if (!pRowStyle)
+ return;
+ double fHeight = pRowStyle->GetRowHeight();
+
+ std::unique_ptr<XFRowStyle> pNewStyle(new XFRowStyle);
+ *pNewStyle = *pRowStyle;
+ LwpTableLayout* pTableLayout = GetParentTableLayout();
+ if (!pTableLayout)
+ {
+ return;
+ }
+ std::map<sal_uInt16,LwpRowLayout*> RowsMap = pTableLayout->GetRowsMap();
+
+ for (sal_uInt16 i=crowid+1; i<nRowMark;i++)
+ {
+ std::map<sal_uInt16,LwpRowLayout*>::iterator iter = RowsMap.find(i);
+ if (iter == RowsMap.end())
+ {
+ pRowStyle = static_cast<XFRowStyle*>(
+ pXFStyleManager->FindStyle(pTableLayout->GetDefaultRowStyleName()));
+ }
+ else
+ {
+ pRowStyle = static_cast<XFRowStyle*>(
+ pXFStyleManager->FindStyle(iter->second->GetStyleName()));
+ }
+ if (!pRowStyle)
+ throw std::runtime_error("missing RowStyle");
+ fHeight += pRowStyle->GetRowHeight();
+ }
+
+ if (m_nDirection & 0x0030)
+ {
+ pNewStyle->SetMinRowHeight(static_cast<float>(fHeight));
+ }
+ else
+ {
+ pNewStyle->SetRowHeight(static_cast<float>(fHeight));
+ }
+
+ pXFRow->SetStyleName(pXFStyleManager->AddStyle(std::move(pNewStyle)).m_pStyle->GetStyleName());
+}
+
+/**
+ * @short find max merge cell in a given column range
+ * @param nStartCol - start column ID
+ * @param nEndCol - end column ID
+ */
+sal_Int32 LwpRowLayout::FindMarkConnCell(sal_uInt8 nStartCol,sal_uInt8 nEndCol)
+{
+ if (m_ConnCellList.empty())
+ return -1;
+
+ sal_uInt16 nSpannRows = 1;
+ sal_Int32 nMarkConnCell = -1;
+
+ for (size_t i=0;i<m_ConnCellList.size();i++)
+ {
+ if (m_ConnCellList[i]->GetColID()>=nEndCol)
+ break;
+ if (m_ConnCellList[i]->GetColID()>=nStartCol)
+ {
+ if (m_ConnCellList[i]->GetNumrows()>nSpannRows)
+ {
+ nSpannRows = m_ConnCellList[i]->GetNumrows();
+ nMarkConnCell = i;
+ }
+ }
+ }
+ return nMarkConnCell;
+}
+
+/**
+ * @short find next merge cell with the same spanned row number with current merge cell
+ * @param nStartCol - start column ID
+ * @param nEndCol - end column ID
+ */
+sal_Int32 LwpRowLayout::FindNextMarkConnCell(sal_uInt16 nMarkConnCell,sal_uInt8 nEndCol)
+{
+ sal_uInt16 nMaxRows = m_ConnCellList[nMarkConnCell]->GetNumrows();
+
+ for (size_t i=nMarkConnCell+1;i<m_ConnCellList.size();i++)
+ {
+ if (m_ConnCellList[i]->GetColID()>=nEndCol)
+ break;
+ if (m_ConnCellList[i]->GetNumrows() == nMaxRows)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+/**
+ * @short get max spanned row numbers in a given column range
+ * @param nStartCol - start column ID
+ * @param nEndCol - end column ID
+ */
+sal_uInt16 LwpRowLayout::GetCurMaxSpannedRows(sal_uInt8 nStartCol,sal_uInt8 nEndCol)
+{
+ sal_Int32 nMarkConnCell = FindMarkConnCell(nStartCol,nEndCol);
+ if (nMarkConnCell == -1)
+ return 1;
+ else
+ return m_ConnCellList[nMarkConnCell]->GetNumrows();
+}
+/**
+ * @short convert row with rowlayout,but no merge cells
+ * @param pXFTable - pointer of table
+ * @param nStartCol - start column ID
+ * @param nEndCol - end column ID
+ */
+void LwpRowLayout::ConvertCommonRow(rtl::Reference<XFTable> const & pXFTable, sal_uInt8 nStartCol, sal_uInt8 nEndCol)
+{
+ LwpTableLayout* pTableLayout = GetParentTableLayout();
+ if (!pTableLayout)
+ return;
+ LwpTable* pTable = pTableLayout->GetTable();
+ if (!pTable)
+ return;
+
+ rtl::Reference<XFRow> xRow(new XFRow);
+ xRow->SetStyleName(m_StyleName);
+
+ sal_uInt8 nCellStartCol,nCellEndCol;
+
+ for (sal_uInt16 i = nStartCol; i < nEndCol; i++)
+ {
+ // add row to table
+ LwpObjectID *pCellID= &GetChildHead();
+ LwpCellLayout * pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
+ nCellStartCol = i;//mark the begin position of cell
+ nCellEndCol = i;//mark the end position of cell
+ rtl::Reference<XFCell> xCell;
+ while(pCellLayout)
+ {
+ if (pCellLayout->GetColID() == i)
+ {
+ if (pCellLayout->GetLayoutType() == LWP_CONNECTED_CELL_LAYOUT)
+ {
+ LwpConnectedCellLayout* pConnCell = static_cast<LwpConnectedCellLayout*>(pCellLayout);
+ auto nNumCols = pConnCell->GetNumcols();
+ if (!nNumCols)
+ throw std::runtime_error("loop in conversion");
+ auto nNewEndCol = i + nNumCols - 1;
+ if (nNewEndCol > std::numeric_limits<sal_uInt8>::max())
+ throw std::range_error("column index too large");
+ nCellEndCol = nNewEndCol;
+ i = nCellEndCol;
+ }
+ xCell = pCellLayout->DoConvertCell(pTable->GetObjectID(),crowid,i);
+ break;
+ }
+ pCellID = &pCellLayout->GetNext();
+ pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
+ }
+ if (!pCellLayout)
+ {
+ // if table has default cell layout, use it to ConvertCell
+ // otherwise use blank cell
+ LwpCellLayout * pDefaultCell = pTableLayout->GetDefaultCellLayout();
+ if (pDefaultCell)
+ {
+ xCell = pDefaultCell->DoConvertCell(
+ pTable->GetObjectID(),crowid, i);
+ }
+ else
+ {
+ xCell.set(new XFCell);
+ }
+ }
+ xRow->AddCell(xCell);
+
+ pTableLayout->SetCellsMap(crowid, nCellStartCol, crowid, nCellEndCol, xCell.get()); //set to cellsmap
+ }
+
+ pXFTable->AddRow(xRow);
+}
+/**
+ * @short collect merge cell info when register row styles
+ */
+void LwpRowLayout::CollectMergeInfo()
+{
+ LwpObjectID *pCellID= &GetChildHead();
+ LwpCellLayout * pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
+
+ while(pCellLayout)
+ {
+ if (pCellLayout->GetLayoutType() == LWP_CONNECTED_CELL_LAYOUT)
+ {
+ LwpConnectedCellLayout* pConnCell = static_cast<LwpConnectedCellLayout*>(pCellLayout);
+ m_ConnCellList.push_back(pConnCell);
+ }
+ pCellID = &pCellLayout->GetNext();
+ pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
+ }
+}
+/**
+ * @short split merge cells in this row
+ * @param nEffectRows - max spanned number of previous row
+ */
+void LwpRowLayout::SetCellSplit(sal_uInt16 nEffectRows)
+{
+ for (LwpConnectedCellLayout* pConnCell : m_ConnCellList)
+ {
+ sal_uInt16 nRowSpan;
+ if (o3tl::checked_add(pConnCell->GetRowID(), pConnCell->GetNumrows(), nRowSpan))
+ throw std::range_error("bad span");
+ if (nRowSpan > nEffectRows)
+ {
+ if (o3tl::checked_sub(nEffectRows, pConnCell->GetRowID(), nRowSpan))
+ throw std::range_error("bad span");
+ pConnCell->SetNumrows(nRowSpan);
+ }
+ }
+}
+/**
+ * @short check if the row has merge cell
+ */
+bool LwpRowLayout::GetMergeCellFlag() const
+{
+ return !m_ConnCellList.empty();
+}
+
+LwpRowHeadingLayout::LwpRowHeadingLayout(LwpObjectHeader const &objHdr, LwpSvStream* pStrm)
+ : LwpRowLayout(objHdr, pStrm)
+{}
+
+LwpRowHeadingLayout::~LwpRowHeadingLayout()
+{}
+void LwpRowHeadingLayout::Read()
+{
+ LwpRowLayout::Read();
+
+ cRowLayout.ReadIndexed(m_pObjStrm.get());
+ m_pObjStrm->SkipExtra();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */