1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
10 * Sun Microsystems Inc., October, 2000
12 * GNU Lesser General Public License Version 2.1
13 * =============================================
14 * Copyright 2000 by Sun Microsystems, Inc.
15 * 901 San Antonio Road, Palo Alto, CA 94303, USA
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License version 2.1, as published by the Free Software Foundation.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32 * Sun Industry Standards Source License Version 1.1
33 * =================================================
34 * The contents of this file are subject to the Sun Industry Standards
35 * Source License Version 1.1 (the "License"); You may not use this file
36 * except in compliance with the License. You may obtain a copy of the
37 * License at http://www.openoffice.org/license.html.
39 * Software provided under this License is provided on an "AS IS" basis,
40 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43 * See the License for the specific provisions governing your rights and
44 * obligations concerning the Software.
46 * The Initial Developer of the Original Code is: IBM Corporation
48 * Copyright: 2008 by IBM Corporation
50 * All Rights Reserved.
52 * Contributor(s): _______________________________________
55 ************************************************************************/
58 * For LWP filter architecture prototype - table layouts
61 #include <lwpglobalmgr.hxx>
62 #include "lwptablelayout.hxx"
63 #include <lwpfoundry.hxx>
64 #include <lwpobjfactory.hxx>
65 #include "lwpholder.hxx"
66 #include "lwptable.hxx"
67 #include "lwptblcell.hxx"
68 #include "lwpnumericfmt.hxx"
69 #include "lwpdlvlist.hxx"
70 #include "lwppara.hxx"
72 #include <xfilter/xfstylemanager.hxx>
73 #include <xfilter/xftablestyle.hxx>
74 #include <xfilter/xfrow.hxx>
75 #include <xfilter/xfrowstyle.hxx>
76 #include <xfilter/xfcell.hxx>
77 #include <xfilter/xfcellstyle.hxx>
78 #include <xfilter/xfcolstyle.hxx>
79 #include <xfilter/xfframestyle.hxx>
80 #include <xfilter/xfframe.hxx>
81 #include <xfilter/xffloatframe.hxx>
82 #include "lwpframelayout.hxx"
83 #include <xfilter/xfparastyle.hxx>
87 LwpSuperTableLayout::LwpSuperTableLayout(LwpObjectHeader
const &objHdr
, LwpSvStream
* pStrm
)
88 : LwpPlacableLayout(objHdr
, pStrm
)
90 m_pFrame
.reset(new LwpFrame(this) );
93 LwpSuperTableLayout::~LwpSuperTableLayout()
97 * @short Read super table layout record
99 void LwpSuperTableLayout::Read()
101 LwpPlacableLayout::Read();
102 m_pObjStrm
->SkipExtra();
106 * @short Get child table layout
107 * @return pointer to table layout
109 LwpTableLayout
* LwpSuperTableLayout::GetTableLayout()
111 LwpObjectID
& rID
= GetChildTail();
115 LwpLayout
* pLayout
= dynamic_cast<LwpLayout
*>(rID
.obj().get());
120 if (pLayout
->GetLayoutType() == LWP_TABLE_LAYOUT
)
122 return dynamic_cast<LwpTableLayout
*>(pLayout
);
124 rID
= pLayout
->GetPrevious();
130 * @short Get effective heading table layout, the one just before table layout is the only one which is effective
131 * @return LwpTableHeadingLayout* - pointer to table heading layout
133 LwpTableHeadingLayout
* LwpSuperTableLayout::GetTableHeadingLayout()
135 LwpObjectID
& rID
= GetChildTail();
139 LwpLayout
* pLayout
= dynamic_cast<LwpLayout
*>(rID
.obj().get());
145 if (pLayout
->GetLayoutType() == LWP_TABLE_HEADING_LAYOUT
)
147 return dynamic_cast<LwpTableHeadingLayout
*>(pLayout
);
149 rID
= pLayout
->GetPrevious();
155 * @short Register super table layout style
157 void LwpSuperTableLayout::RegisterNewStyle()
159 // if this layout is style of real table entry
160 LwpTableLayout
* pTableLayout
= GetTableLayout();
161 if (pTableLayout
!= nullptr)
163 pTableLayout
->SetFoundry(m_pFoundry
);
164 pTableLayout
->RegisterStyle();
168 * @short Judge whether table size is according to content, borrowed from Word Pro code
172 bool LwpSuperTableLayout::IsSizeRightToContent()
174 /* Only "with paragraph above" tables can size right to content. */
175 if (GetRelativeType() == LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE
)
176 return LwpPlacableLayout::IsSizeRightToContent();
181 * @short Judge whether table is justifiable, borrowed from Word Pro code
185 bool LwpSuperTableLayout::IsJustifiable()
187 return (GetRelativeType() != LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE
|| IsSizeRightToContent());
190 * @short Get width of frame outside table
191 * @param pTableStyle - pointer of XFTableStyle
192 * @return double - table width
194 double LwpSuperTableLayout::GetWidth()
196 double dWidth
= GetTableWidth();
197 double dLeft
= GetMarginsValue(MARGIN_LEFT
);
198 double dRight
= GetMarginsValue(MARGIN_RIGHT
);
200 return (dWidth
+ dLeft
+ dRight
);
203 * @short Get width of table
204 * @param pTableStyle - pointer of XFTableStyle
205 * @return double - table width
207 double LwpSuperTableLayout::GetTableWidth()
209 sal_Int32 nWidth
= 0;
210 if(!IsJustifiable() || ((nWidth
= LwpMiddleLayout::GetMinimumWidth()) <= 0))
212 LwpTableLayout
* pTableLayout
= GetTableLayout();
215 SAL_WARN("lwp", "missing table layout, early return");
218 LwpTable
*pTable
= pTableLayout
->GetTable();
221 SAL_WARN("lwp", "missing table, early return");
224 double dDefaultWidth
= pTable
->GetWidth();
225 sal_uInt16 nCol
= pTable
->GetColumn();
229 for(sal_uInt16 i
=0; i
< nCol
; i
++)
231 LwpObjectID
& rColumnID
= pTableLayout
->GetColumnLayoutHead();
232 LwpColumnLayout
* pColumnLayout
= dynamic_cast<LwpColumnLayout
*>(rColumnID
.obj().get());
233 double dColumnWidth
= dDefaultWidth
;
234 std::set
<LwpColumnLayout
*> aSeen
;
235 while (pColumnLayout
)
237 aSeen
.insert(pColumnLayout
);
238 if(pColumnLayout
->GetColumnID() == i
)
240 dColumnWidth
= pColumnLayout
->GetWidth();
243 rColumnID
= pColumnLayout
->GetNext();
244 pColumnLayout
= dynamic_cast<LwpColumnLayout
*>(rColumnID
.obj().get());
245 if (aSeen
.find(pColumnLayout
) != aSeen
.end())
246 throw std::runtime_error("loop in conversion");
248 dWidth
+= dColumnWidth
;
254 double dLeft
= GetMarginsValue(MARGIN_LEFT
);
255 double dRight
= GetMarginsValue(MARGIN_RIGHT
);
256 return LwpTools::ConvertFromUnitsToMetric(nWidth
)-dLeft
-dRight
;
260 * @short Apply shadow to table
261 * @param pTableStyle - pointer of XFTableStyle
264 void LwpSuperTableLayout::ApplyShadow(XFTableStyle
*pTableStyle
)
266 // use shadow property of supertable
267 std::unique_ptr
<XFShadow
> pXFShadow(GetXFShadow());
270 pTableStyle
->SetShadow(pXFShadow
->GetPosition(), pXFShadow
->GetOffset(), pXFShadow
->GetColor());
274 * @short Apply pattern fill to table style
275 * @param pTableStyle - pointer of XFTableStyle
278 void LwpSuperTableLayout::ApplyPatternFill(XFTableStyle
* pTableStyle
)
280 std::unique_ptr
<XFBGImage
> xXFBGImage(GetFillPattern());
283 pTableStyle
->SetBackImage(xXFBGImage
);
288 * @short Apply background to table style
289 * @param pTableStyle - pointer of XFTableStyle
292 void LwpSuperTableLayout::ApplyBackGround(XFTableStyle
* pTableStyle
)
296 ApplyPatternFill(pTableStyle
);
300 ApplyBackColor(pTableStyle
);
304 * @short Apply back color to table
305 * @param pTableStyle - pointer of XFTableStyle
308 void LwpSuperTableLayout::ApplyBackColor(XFTableStyle
*pTableStyle
)
310 LwpColor
* pColor
= GetBackColor();
311 if(pColor
&& pColor
->IsValidColor())
313 XFColor
aColor(pColor
->To24Color());
314 pTableStyle
->SetBackColor(aColor
);
318 * @short Apply watermark to table
319 * @param pTableStyle - pointer of XFTableStyle
322 void LwpSuperTableLayout::ApplyWatermark(XFTableStyle
*pTableStyle
)
324 std::unique_ptr
<XFBGImage
> xBGImage(GetXFBGImage());
327 pTableStyle
->SetBackImage(xBGImage
);
331 * @short Apply alignment to table
332 * @param pTableStyle - pointer of XFTableStyle
335 void LwpSuperTableLayout::ApplyAlignment(XFTableStyle
* pTableStyle
)
338 if (LwpLayoutGeometry
* pGeometry
= GetGeometry())
339 aPoint
= pGeometry
->GetOrigin();
340 double dXOffset
= LwpTools::ConvertFromUnitsToMetric(aPoint
.GetX());
342 // add left padding to alignment distance
343 double dLeft
= GetMarginsValue(MARGIN_LEFT
);
345 pTableStyle
->SetAlign(enumXFAlignStart
, dXOffset
+ dLeft
);
348 * @short Add table to container
349 * @param pCont - pointer of container
352 void LwpSuperTableLayout::XFConvert(XFContentContainer
* pCont
)
354 if ( LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE
== GetRelativeType()
355 && (!GetContainerLayout().is() || !GetContainerLayout()->IsCell()) )
357 LwpTableLayout
* pTableLayout
= GetTableLayout();
360 pTableLayout
->XFConvert(pCont
);
363 else if(IsRelativeAnchored())
365 //anchor to paragraph except "with paragraph above"
366 XFConvertFrame(pCont
);
370 //anchor to page, frame, cell
371 m_pFrame
->XFConvert(pCont
);
375 * @short convert frame which anchor to page
379 void LwpSuperTableLayout::XFConvertFrame(XFContentContainer
* pCont
, sal_Int32 nStart
, sal_Int32 nEnd
, bool bAll
)
383 rtl::Reference
<XFFrame
> xXFFrame
;
386 xXFFrame
.set(new XFFrame
);
390 xXFFrame
.set(new XFFloatFrame(nStart
, nEnd
, bAll
));
393 m_pFrame
->Parse(xXFFrame
.get(), static_cast<sal_uInt16
>(nStart
));
394 //parse table, and add table to frame
395 LwpTableLayout
* pTableLayout
= GetTableLayout();
398 pTableLayout
->XFConvert(xXFFrame
.get());
400 //add frame to the container
401 pCont
->Add(xXFFrame
.get());
406 * @short register frame style
410 void LwpSuperTableLayout::RegisterFrameStyle()
412 std::unique_ptr
<XFFrameStyle
> xFrameStyle(new XFFrameStyle
);
413 m_pFrame
->RegisterStyle(xFrameStyle
);
416 LwpTableLayout::LwpTableLayout(LwpObjectHeader
const &objHdr
, LwpSvStream
* pStrm
)
417 : LwpLayout(objHdr
, pStrm
)
420 , m_pDefaultCellLayout(nullptr)
425 * @short Get neighbour cell by specifying ROW+COL
428 * @return LwpCellLayout *
430 LwpCellLayout
* LwpTableLayout::GetCellByRowCol(sal_uInt16 nRow
, sal_uInt16 nCol
)
432 if (nRow
>= m_nRows
|| nCol
>= m_nCols
)
435 return m_WordProCellsMap
[static_cast<size_t>(nRow
)*m_nCols
+ nCol
];
439 * @short traverse all table cells
444 void LwpTableLayout::TraverseTable()
446 sal_uInt32 nCount
= m_nRows
*m_nCols
;
448 // new cell map nRow*nCOl and initialize
449 m_WordProCellsMap
.insert(m_WordProCellsMap
.end(), nCount
, m_pDefaultCellLayout
);
452 LwpObjectID
& rRowID
= GetChildHead();
453 LwpRowLayout
* pRowLayout
= dynamic_cast<LwpRowLayout
*>(rRowID
.obj().get());
454 std::set
<LwpRowLayout
*> aSeen
;
457 aSeen
.insert(pRowLayout
);
459 pRowLayout
->SetRowMap();
461 // for 's analysis job
462 m_RowsMap
[pRowLayout
->GetRowID()] = pRowLayout
;
463 pRowLayout
->CollectMergeInfo();
464 // end for 's analysis
466 rRowID
= pRowLayout
->GetNext();
467 pRowLayout
= dynamic_cast<LwpRowLayout
*>(rRowID
.obj().get());
468 if (aSeen
.find(pRowLayout
) != aSeen
.end())
469 throw std::runtime_error("loop in conversion");
474 * @short search the cell map
475 * @param nRow - row id (0 based)
476 * @param nRow - row id (0 based)
477 * @return LwpObjectID * - pointer to cell story object ID
479 LwpObjectID
* LwpTableLayout::SearchCellStoryMap(sal_uInt16 nRow
, sal_uInt16 nCol
)
481 if (nRow
>= m_nRows
|| nCol
>= m_nCols
)
486 LwpCellLayout
* pCell
= GetCellByRowCol(nRow
, nCol
);
489 // maybe connected cell layout
490 // maybe default cell layout
491 if (nRow
!= pCell
->GetRowID() || nCol
!= pCell
->GetColID())
495 return &pCell
->GetContent();
502 * @short Get parent super table layout of table layout
503 * @return LwpSuperTableLayout * - pointer of parent super table layout
505 LwpSuperTableLayout
* LwpTableLayout::GetSuperTableLayout()
507 return dynamic_cast<LwpSuperTableLayout
*>(GetParent().obj().get());
510 * @short Get table pointer
511 * @return LwpTable * - content table pointer
513 LwpTable
* LwpTableLayout::GetTable()
515 LwpTable
*pTable
= dynamic_cast<LwpTable
*>(m_Content
.obj().get());
519 * @short Get column style name by column ID
520 * @param sal_uInt16 -- col id(0 based)
521 * @return OUString - name of column style
523 OUString
LwpTableLayout::GetColumnWidth(sal_uInt16 nCol
)
528 return m_DefaultColumnStyleName
;
531 LwpColumnLayout
* pCol
= m_aColumns
[nCol
];
534 return pCol
->GetStyleName();
537 return m_DefaultColumnStyleName
;
540 * @short analyze all columns to get whole table width and width of all columns
541 * @short and register all column styles
544 void LwpTableLayout::RegisterColumns()
546 LwpTable
* pTable
= GetTable();
548 throw std::range_error("corrupt LwpTableLayout");
550 LwpSuperTableLayout
* pSuper
= GetSuperTableLayout();
552 throw std::range_error("corrupt LwpTableLayout");
554 sal_uInt16 nCols
= m_nCols
;
556 m_aColumns
.resize(nCols
);
557 std::unique_ptr
<bool[]> pWidthCalculated( new bool[nCols
] );
558 for(sal_uInt16 i
=0;i
<nCols
; i
++)
560 pWidthCalculated
[i
] = false;
561 m_aColumns
[i
] = nullptr;
564 double dDefaultColumn
= pTable
->GetWidth();
565 sal_uInt16 nJustifiableColumn
= nCols
;
567 double dTableWidth
= pSuper
->GetTableWidth();
569 // Get total width of justifiable columns
570 // NOTICE: all default columns are regarded as justifiable columns
571 LwpObjectID
& rColumnID
= GetColumnLayoutHead();
572 LwpColumnLayout
* pColumnLayout
= dynamic_cast<LwpColumnLayout
*>(rColumnID
.obj().get());
573 std::set
<LwpColumnLayout
*> aSeen
;
574 while (pColumnLayout
)
576 aSeen
.insert(pColumnLayout
);
578 auto nColId
= pColumnLayout
->GetColumnID();
581 throw std::range_error("corrupt LwpTableLayout");
583 m_aColumns
[nColId
] = pColumnLayout
;
584 if (!pColumnLayout
->IsJustifiable())
586 pWidthCalculated
[nColId
] = true;
587 dTableWidth
-= pColumnLayout
->GetWidth();
588 nJustifiableColumn
--;
591 rColumnID
= pColumnLayout
->GetNext();
592 pColumnLayout
= dynamic_cast<LwpColumnLayout
*>(rColumnID
.obj().get());
594 if (aSeen
.find(pColumnLayout
) != aSeen
.end())
595 throw std::runtime_error("loop in conversion");
598 // if all columns are not justifiable, the rightmost column will be changed to justifiable
599 if (nJustifiableColumn
== 0 && nCols
!= 0)
601 nJustifiableColumn
++;
602 if (m_aColumns
[nCols
- 1])
604 pWidthCalculated
[nCols
-1] = false;
605 dTableWidth
+= m_aColumns
[nCols
-1]->GetWidth();
610 dTableWidth
= dDefaultColumn
;
615 // justifiable columns will share the remain width averagely
616 dDefaultColumn
= nJustifiableColumn
? dTableWidth
/nJustifiableColumn
: 0;
618 // register default column style
619 std::unique_ptr
<XFColStyle
> xColStyle(new XFColStyle
);
620 xColStyle
->SetWidth(static_cast<float>(dDefaultColumn
));
622 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
623 m_DefaultColumnStyleName
= pXFStyleManager
->AddStyle(std::move(xColStyle
)).m_pStyle
->GetStyleName();
625 // register existed column style
627 for( i
=0;i
<nCols
; i
++)
631 m_aColumns
[i
]->SetFoundry(m_pFoundry
);
632 if(!pWidthCalculated
[i
])
634 // justifiable ----register style with calculated value
635 m_aColumns
[i
]->SetStyleName(m_DefaultColumnStyleName
);
639 // not justifiable ---- register style with original value
640 m_aColumns
[i
]->RegisterStyle(m_aColumns
[i
]->GetWidth());
646 * @short register all row styles
649 void LwpTableLayout::RegisterRows()
651 LwpTable
* pTable
= GetTable();
652 if (pTable
== nullptr)
658 // register default row style
659 std::unique_ptr
<XFRowStyle
> xRowStyle(new XFRowStyle
);
660 if (m_nDirection
& 0x0030)
662 xRowStyle
->SetMinRowHeight(static_cast<float>(pTable
->GetHeight()));
666 xRowStyle
->SetRowHeight(static_cast<float>(pTable
->GetHeight()));
668 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
669 m_DefaultRowStyleName
= pXFStyleManager
->AddStyle(std::move(xRowStyle
)).m_pStyle
->GetStyleName();
671 // register style of rows
672 LwpObjectID
& rRowID
= GetChildHead();
673 LwpRowLayout
* pRowLayout
= dynamic_cast<LwpRowLayout
*>(rRowID
.obj().get());
676 pRowLayout
->SetFoundry(m_pFoundry
);
677 pRowLayout
->RegisterStyle();
679 rRowID
= pRowLayout
->GetNext();
680 pRowLayout
= dynamic_cast<LwpRowLayout
*>(rRowID
.obj().get());
684 * @short register table style, if needed, including frame style
687 void LwpTableLayout::RegisterStyle()
689 // get super table layout
690 LwpSuperTableLayout
* pSuper
= GetSuperTableLayout();
695 LwpTable
* pTable
= GetTable();
696 if (pTable
== nullptr)
698 SAL_WARN("lwp", "missing table, early return");
702 // get row/column number of this table
703 m_nRows
= pTable
->GetRow();
704 m_nCols
= pTable
->GetColumn();
705 //http://www.danielsays.com/ss-gallery-win1x2x3x-lotus-word-pro-96.html
706 //tables with up to 255 rows and 8192 columns
707 //the row limit tallies with the casting of m_nCols to an unsigned char
709 if (m_nRows
> MAX_NUM_ROWS
)
710 throw std::runtime_error("max legal row exceeded");
711 if (m_nCols
> MAX_NUM_COLS
)
712 throw std::runtime_error("max legal column exceeded");
714 // get default cell layout of current table
715 LwpObjectID
& rID
= pTable
->GetDefaultCellStyle();
716 m_pDefaultCellLayout
= dynamic_cast<LwpCellLayout
*>(rID
.obj().get());
718 // register columns styles
721 // register style of whole table
722 std::unique_ptr
<XFTableStyle
> xTableStyle(new XFTableStyle
);
724 sal_uInt8 nType
= pSuper
->GetRelativeType();
725 // If the table is not "with paragraph above" placement, create an frame style
726 // by supertable layout
727 if ( LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE
== nType
728 && (!pSuper
->GetContainerLayout().is() || !pSuper
->GetContainerLayout()->IsCell()) )
731 pSuper
->ApplyBackGround(xTableStyle
.get());
732 pSuper
->ApplyWatermark(xTableStyle
.get());
733 pSuper
->ApplyShadow(xTableStyle
.get());
734 pSuper
->ApplyAlignment(xTableStyle
.get());
735 xTableStyle
->SetWidth(pSuper
->GetTableWidth());
739 pSuper
->RegisterFrameStyle();
740 xTableStyle
->SetAlign(enumXFAlignCenter
);
741 xTableStyle
->SetWidth(pSuper
->GetTableWidth());
743 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
744 m_StyleName
= pXFStyleManager
->AddStyle(std::move(xTableStyle
)).m_pStyle
->GetStyleName();
746 //convert to OO table now and register row style traverse
749 SplitConflictCells();
751 // Register rows layouts, it must be after SplitConflictCells
757 // the old code doesn't check if the LwpFoundry pointer is NULL,
758 // so the NULL pointer cause sodc freeze. Add code to check the pointer.
759 if (GetFoundry() && GetTable())
760 PutCellVals(GetFoundry(), GetTable()->GetObjectID());
763 * @short read table layout
766 void LwpTableLayout::ParseTable()
768 // get super table layout
769 LwpSuperTableLayout
* pSuper
= GetSuperTableLayout();
772 throw std::runtime_error("missing super table");
775 if (m_pXFTable
.get())
777 throw std::runtime_error("this table is already parsed");
780 // set name of object
781 m_pXFTable
.set(new XFTable
);
782 m_pXFTable
->SetTableName(pSuper
->GetName().str());
784 m_pXFTable
->SetStyleName(m_StyleName
);
786 sal_uInt16 nRow
= m_nRows
;
787 sal_uInt8 nCol
= static_cast<sal_uInt8
>(m_nCols
);
789 //process header rows
790 LwpTableHeadingLayout
* pTableHeading
;
791 pTableHeading
= pSuper
->GetTableHeadingLayout();
792 sal_uInt16 nStartHeadRow
;
793 sal_uInt16 nEndHeadRow
;
794 sal_uInt16 nContentRow
;
797 pTableHeading
->GetStartEndRow(nStartHeadRow
,nEndHeadRow
);
798 if (nStartHeadRow
!= 0)
799 ConvertTable(m_pXFTable
,0,nRow
,0,nCol
);
802 nContentRow
= ConvertHeadingRow(m_pXFTable
,nStartHeadRow
,nEndHeadRow
+1);
803 ConvertTable(m_pXFTable
,nContentRow
,nRow
,0,nCol
);
807 ConvertTable(m_pXFTable
,0,nRow
,0,nCol
);
811 * @short read table layout
814 void LwpTableLayout::Read()
818 // before layout hierarchy rework!
819 if(LwpFileHeader::m_nFileRevision
< 0x000b)
823 m_ColumnLayout
.ReadIndexed(m_pObjStrm
.get());
825 m_pObjStrm
->SkipExtra();
829 * @short Convert table
831 * @return pCont - container which will contain table
833 void LwpTableLayout::XFConvert(XFContentContainer
* pCont
)
836 throw std::runtime_error("missing table");
837 pCont
->Add(m_pXFTable
.get());
840 * @short convert heading row
841 * @param pXFTable - pointer of table
842 * @param nStartRow - start heading row ID
843 * @param nEndRow - end heading row ID
845 sal_uInt16
LwpTableLayout::ConvertHeadingRow(
846 rtl::Reference
<XFTable
> const & pXFTable
, sal_uInt16 nStartHeadRow
, sal_uInt16 nEndHeadRow
)
848 sal_uInt16 nContentRow
;
849 sal_uInt8 nCol
= static_cast<sal_uInt8
>(GetTable()->GetColumn());
850 rtl::Reference
<XFTable
> pTmpTable( new XFTable
);
852 ConvertTable(pTmpTable
.get(),nStartHeadRow
,nEndHeadRow
,0,nCol
);
854 sal_uInt16 nRowNum
= pTmpTable
->GetRowCount();
855 std::unique_ptr
<sal_uInt8
[]> CellMark( new sal_uInt8
[nRowNum
] );
859 XFRow
* pXFRow
= pTmpTable
->GetRow(1);
860 pXFTable
->AddHeaderRow(pXFRow
);
861 pTmpTable
->RemoveRow(1);
862 nContentRow
= nEndHeadRow
;
866 sal_uInt8 nFirstColSpann
= 1;
867 const bool bFindFlag
= FindSplitColMark(pTmpTable
.get(),CellMark
.get(),nFirstColSpann
);
869 if (bFindFlag
)//split to 2 cells
871 SplitRowToCells(pTmpTable
.get(),pXFTable
,nFirstColSpann
,CellMark
.get());
872 nContentRow
= nEndHeadRow
;
874 else//can not split,the first row will be the heading row,the rest will be content row
876 XFRow
* pXFRow
= pTmpTable
->GetRow(1);
877 pXFTable
->AddHeaderRow(pXFRow
);
878 pTmpTable
->RemoveRow(1);
879 nContentRow
= m_RowsMap
[0]->GetCurMaxSpannedRows(0,nCol
);
885 void LwpTableLayout::SplitRowToCells(XFTable
* pTmpTable
, rtl::Reference
<XFTable
> const & pXFTable
,
886 sal_uInt8 nFirstColSpann
,const sal_uInt8
* pCellMark
)
889 sal_uInt16 nRowNum
= pTmpTable
->GetRowCount();
890 sal_uInt8 nCol
= static_cast<sal_uInt8
>(GetTable()->GetColumn());
892 rtl::Reference
<XFRow
> xXFRow(new XFRow
);
894 //register style for heading row
897 std::unique_ptr
<XFRowStyle
> xRowStyle(new XFRowStyle
);
898 XFRow
* pRow
= pTmpTable
->GetRow(1);
900 throw std::runtime_error("missing row");
901 styleName
= pRow
->GetStyleName();
903 // get settings of the row and assign them to new row style
904 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
905 XFRowStyle
*pTempRowStyle
= static_cast<XFRowStyle
*>(pXFStyleManager
->FindStyle(styleName
));
907 *xRowStyle
= *pTempRowStyle
;
909 for (i
=1;i
<=nRowNum
;i
++)
911 styleName
= pTmpTable
->GetRow(i
)->GetStyleName();
912 fHeight
+=static_cast<XFRowStyle
*>(pXFStyleManager
->FindStyle(styleName
))->GetRowHeight();
914 if (m_nDirection
& 0x0030)
916 xRowStyle
->SetMinRowHeight(static_cast<float>(fHeight
));
920 xRowStyle
->SetRowHeight(static_cast<float>(fHeight
));
922 xXFRow
->SetStyleName(pXFStyleManager
->AddStyle(std::move(xRowStyle
)).m_pStyle
->GetStyleName());
924 //construct heading row
925 rtl::Reference
<XFCell
> xXFCell1(new XFCell
);
926 rtl::Reference
<XFCell
> xXFCell2(new XFCell
);
927 rtl::Reference
<XFTable
> xSubTable1(new XFTable
);
928 rtl::Reference
<XFTable
> xSubTable2(new XFTable
);
930 rtl::Reference
<XFCell
> xNewCell
;
932 for (i
=1;i
<=nRowNum
;i
++)
934 pOldRow
= pTmpTable
->GetRow(i
);
935 rtl::Reference
<XFRow
> xNewRow(new XFRow
);
936 xNewRow
->SetStyleName(pOldRow
->GetStyleName());
937 for (sal_uInt8 j
=1;j
<=pCellMark
[i
];j
++)
939 xNewCell
= pOldRow
->GetCell(j
);
940 xNewRow
->AddCell(xNewCell
);
942 xSubTable1
->AddRow(xNewRow
);
944 ConvertColumn(xSubTable1
.get(), 0, nFirstColSpann
);//add column info
946 xXFCell1
->Add(xSubTable1
.get());
947 xXFCell1
->SetColumnSpaned(nFirstColSpann
);
948 xXFRow
->AddCell(xXFCell1
);
950 for (i
=1;i
<=nRowNum
;i
++)
952 pOldRow
= pTmpTable
->GetRow(i
);
953 rtl::Reference
<XFRow
> xNewRow(new XFRow
);
954 xNewRow
->SetStyleName(pOldRow
->GetStyleName());
955 for(sal_Int32 j
=pCellMark
[i
]+1;j
<=pOldRow
->GetCellCount();j
++)
957 xNewCell
= pOldRow
->GetCell(j
);
958 xNewRow
->AddCell(xNewCell
);
960 xSubTable2
->AddRow(xNewRow
);
963 ConvertColumn(xSubTable2
.get(), nFirstColSpann
, nCol
);//add column info
964 xXFCell2
->Add(xSubTable2
.get());
965 xXFCell2
->SetColumnSpaned(nCol
-nFirstColSpann
);
966 xXFRow
->AddCell(xXFCell2
);
968 pXFTable
->AddHeaderRow(xXFRow
.get());
971 for (i
=1;i
<=nRowNum
;i
++)
973 pOldRow
= pTmpTable
->GetRow(i
);
974 for(sal_Int32 j
=1;j
<=pOldRow
->GetCellCount();j
++)
975 pOldRow
->RemoveCell(j
);
976 pTmpTable
->RemoveRow(i
);
981 * @short find if the heading rows can be split to 2 cells
982 * @param pXFTable - pointer of tmp XFtable
983 * @param CellMark - pointer of cell mark array
985 bool LwpTableLayout::FindSplitColMark(XFTable
* pXFTable
, sal_uInt8
* pCellMark
,
986 sal_uInt8
& nMaxColSpan
)
988 sal_uInt16 nRowNum
= pXFTable
->GetRowCount();
989 sal_uInt8 nColNum
= static_cast<sal_uInt8
>(pXFTable
->GetColumnCount());
992 bool bFindFlag
= false;
995 for(sal_uInt8 i
=1;i
<=nColNum
;i
++)
999 //find current max column span
1001 for (nRowLoop
=1;nRowLoop
<=nRowNum
;nRowLoop
++)
1004 for(sal_uInt8 nCellLoop
=1; nCellLoop
<i
+1; nCellLoop
++)
1006 pTmpRow
= pXFTable
->GetRow(nRowLoop
);
1007 XFCell
* pCell
= pTmpRow
->GetCell(nCellLoop
);
1009 nColSpan
+= static_cast<sal_uInt8
>(pCell
->GetColSpaned());
1013 if (nColSpan
> nMaxColSpan
)
1014 nMaxColSpan
= nColSpan
;
1015 pCellMark
[nRowLoop
] = 0;//reset all cell mark to zero
1018 //find if other row has the same column
1019 for (nRowLoop
=1;nRowLoop
<=nRowNum
;nRowLoop
++)
1021 pTmpRow
= pXFTable
->GetRow(nRowLoop
);
1023 sal_Int32 nCellMark
= 0;
1024 for (sal_Int32 nCellLoop
=1; nCellLoop
<=pTmpRow
->GetCellCount(); nCellLoop
++)
1026 if (nCount
>nMaxColSpan
)
1028 nCount
+= static_cast<sal_uInt8
>(pTmpRow
->GetCell(nCellLoop
)->GetColSpaned());
1029 if (nCount
== nMaxColSpan
)
1031 nCellMark
= nCellLoop
;
1038 pCellMark
[nRowLoop
] = nCellMark
;
1040 for(nRowLoop
=1;nRowLoop
<=nRowNum
;nRowLoop
++)//check if all ==0,break
1042 if (pCellMark
[nRowLoop
] == 0)
1045 if (nRowLoop
== nRowNum
+1)
1056 * @short convert word pro table to SODC table
1057 * @param pXFTable - pointer of table
1058 * @param nStartRow - start row ID
1059 * @param nEndRow - end row ID
1060 * @param nStartCol - start column ID
1061 * @param nEndCol - end column ID
1063 void LwpTableLayout::ConvertTable(rtl::Reference
<XFTable
> const & pXFTable
, sal_uInt16 nStartRow
,
1064 sal_uInt16 nEndRow
,sal_uInt8 nStartCol
,sal_uInt8 nEndCol
)
1066 //out put column info TO BE CHANGED
1067 ConvertColumn(pXFTable
,nStartCol
,nEndCol
);
1069 std::map
<sal_uInt16
,LwpRowLayout
*>::iterator iter
;
1071 for (sal_uInt16 i
=nStartRow
; i
<nEndRow
;)
1073 iter
= m_RowsMap
.find(i
);
1074 if (iter
== m_RowsMap
.end())
1076 ConvertDefaultRow(pXFTable
,nStartCol
,nEndCol
,i
);
1081 LwpRowLayout
* pRow
= iter
->second
;
1082 if (pRow
->GetCurMaxSpannedRows(nStartCol
,nEndCol
) == 1)
1084 pRow
->ConvertCommonRow(pXFTable
,nStartCol
,nEndCol
);
1089 pRow
->ConvertRow(pXFTable
,nStartCol
,nEndCol
);
1090 i
+= pRow
->GetCurMaxSpannedRows(nStartCol
,nEndCol
);
1097 * @short apply numeric value and formula to cell
1098 * @param pFoundry - pointer of foundry
1099 * @param aTableID - table ID
1101 void LwpTableLayout::PutCellVals(LwpFoundry
* pFoundry
, LwpObjectID aTableID
)
1104 // The old code doesn't check if the LwpFoundry pointer is NULL, so the NULL
1105 // pointer cause sodc frozen. Add code to check the pointer.
1106 if( !pFoundry
) return;
1110 LwpDLVListHeadHolder
* pHolder
= dynamic_cast<LwpDLVListHeadHolder
*>(pFoundry
->GetNumberManager().GetTableRangeID().obj().get());
1112 LwpTableRange
* pTableRange
= pHolder
? dynamic_cast<LwpTableRange
*>(pHolder
->GetHeadID().obj().get()) : nullptr;
1115 std::set
<LwpTableRange
*> aTableSeen
;
1118 aTableSeen
.insert(pTableRange
);
1119 LwpObjectID aID
= pTableRange
->GetTableID();
1120 if (aID
== aTableID
)
1124 pTableRange
= pTableRange
->GetNext();
1125 if (aTableSeen
.find(pTableRange
) != aTableSeen
.end())
1126 throw std::runtime_error("loop in conversion");
1132 LwpCellRange
* pRange
= dynamic_cast<LwpCellRange
*>(pTableRange
->GetCellRangeID().obj().get());
1136 LwpFolder
* pFolder
= dynamic_cast<LwpFolder
*>(pRange
->GetFolderID().obj().get());
1140 LwpObjectID aRowListID
= pFolder
->GetChildHeadID();
1141 LwpRowList
* pRowList
= dynamic_cast<LwpRowList
*>(aRowListID
.obj().get());
1144 std::set
<LwpRowList
*> aOuterSeen
;
1147 aOuterSeen
.insert(pRowList
);
1148 sal_uInt16 nRowID
= pRowList
->GetRowID();
1150 LwpCellList
* pCellList
= dynamic_cast<LwpCellList
*>(pRowList
->GetChildHeadID().obj().get());
1152 std::set
<LwpCellList
*> aSeen
;
1155 aSeen
.insert(pCellList
);
1157 sal_uInt16 nColID
= pCellList
->GetColumnID();
1159 XFCell
* pCell
= GetCellsMap(nRowID
,static_cast<sal_uInt8
>(nColID
));
1162 pCellList
->Convert(pCell
, this);
1165 PostProcessParagraph(pCell
, nRowID
, nColID
);
1169 throw std::runtime_error("Hidden cell would not be in cellsmap");
1172 pCellList
= dynamic_cast<LwpCellList
*>(pCellList
->GetNextID().obj().get());
1173 if (aSeen
.find(pCellList
) != aSeen
.end())
1174 throw std::runtime_error("loop in conversion");
1177 pRowList
= dynamic_cast<LwpRowList
*>(pRowList
->GetNextID().obj().get());
1178 if (aOuterSeen
.find(pRowList
) != aOuterSeen
.end())
1179 throw std::runtime_error("loop in conversion");
1183 SAL_WARN("lwp", "bad PutCellVals");
1188 * @short 1. set number right alignment to right if number 2. remove tab added before if number
1189 * @param pCell - cell which to be process
1190 * @param nRowID - row number in Word Pro file
1191 * @param nColID - column number in Word Pro file
1193 void LwpTableLayout::PostProcessParagraph(XFCell
*pCell
, sal_uInt16 nRowID
, sal_uInt16 nColID
)
1195 // if number right, set alignment to right
1196 LwpCellLayout
* pCellLayout
= GetCellByRowCol(nRowID
, nColID
);
1199 rtl::Reference
<XFContent
> first(
1200 pCell
->FindFirstContent(enumXFContentPara
));
1201 XFParagraph
* pXFPara
= static_cast<XFParagraph
*>(first
.get());
1204 XFColor aNullColor
= XFColor();
1208 OUString sNumfmt
= pCellLayout
->GetNumfmtName();
1209 bool bColorMod
= false;
1210 XFNumberStyle
* pNumStyle
= nullptr;
1211 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
1212 if (!sNumfmt
.isEmpty())
1214 pNumStyle
= static_cast<XFNumberStyle
*>(pXFStyleManager
->FindStyle( sNumfmt
));
1215 XFColor aColor
= pNumStyle
->GetColor();
1216 if ( aColor
!= aNullColor
)
1217 bColorMod
= true;//end
1220 XFParaStyle
* pStyle
= pXFStyleManager
->FindParaStyle(pXFPara
->GetStyleName());
1221 if ((pStyle
&& pStyle
->GetNumberRight()) || bColorMod
)
1223 std::unique_ptr
<XFParaStyle
> xOverStyle(new XFParaStyle
);
1227 *xOverStyle
= *pStyle
;
1229 if (pStyle
->GetNumberRight())
1230 xOverStyle
->SetAlignType(enumXFAlignEnd
);
1235 rtl::Reference
<XFFont
> xFont
= xOverStyle
->GetFont();
1238 XFColor aColor
= xFont
->GetColor();
1239 if ( aColor
== aNullColor
)
1241 rtl::Reference
<XFFont
> pNewFont(new XFFont
);
1242 aColor
= pNumStyle
->GetColor();
1243 pNewFont
->SetColor(aColor
);
1244 xOverStyle
->SetFont(pNewFont
);
1249 xOverStyle
->SetStyleName("");
1250 OUString StyleName
= pXFStyleManager
->AddStyle(std::move(xOverStyle
)).m_pStyle
->GetStyleName();
1252 pXFPara
->SetStyleName(StyleName
);
1259 * @short Parse all cols of table
1260 * @param pXFTable - pointer to created XFTable
1262 void LwpTableLayout::ConvertColumn(rtl::Reference
<XFTable
> const & pXFTable
, sal_uInt8 nStartCol
, sal_uInt8 nEndCol
)
1264 LwpTable
* pTable
= GetTable();
1271 for (sal_uInt32 iLoop
= 0; iLoop
< static_cast<sal_uInt32
>(nEndCol
)-nStartCol
; ++iLoop
)
1274 LwpObjectID
& rColID
= GetColumnLayoutHead();
1275 LwpColumnLayout
* pColumnLayout
= dynamic_cast<LwpColumnLayout
*>(rColID
.obj().get());
1276 while (pColumnLayout
)
1278 if (pColumnLayout
->GetColumnID() == (iLoop
+nStartCol
))
1280 pXFTable
->SetColumnStyle(iLoop
+1, pColumnLayout
->GetStyleName());
1283 rColID
= pColumnLayout
->GetNext();
1284 pColumnLayout
= dynamic_cast<LwpColumnLayout
*>(rColID
.obj().get());
1288 pXFTable
->SetColumnStyle(iLoop
+1, m_DefaultColumnStyleName
);
1293 * @short split conflict merged cells
1295 void LwpTableLayout::SplitConflictCells()
1297 LwpTable
* pTable
= GetTable();
1300 sal_uInt16 nCol
= pTable
->GetColumn();
1301 sal_uInt16 nRow
= pTable
->GetRow();
1303 sal_uInt16 nEffectRows
;
1304 std::map
<sal_uInt16
,LwpRowLayout
*>::iterator iter1
;
1305 std::map
<sal_uInt16
,LwpRowLayout
*>::iterator iter2
;
1306 LwpRowLayout
* pRowLayout
;
1307 LwpRowLayout
* pEffectRow
;
1309 for (sal_uInt16 i
=0; i
<nRow
; )
1311 iter1
= m_RowsMap
.find(i
);
1312 if (iter1
== m_RowsMap
.end())//default rows
1317 pRowLayout
= iter1
->second
;
1318 if (!pRowLayout
->GetMergeCellFlag())
1325 nEffectRows
= i
+ pRowLayout
->GetCurMaxSpannedRows(0,static_cast<sal_uInt8
>(nCol
));
1327 for (sal_uInt16 j
= i
+1; j
<nEffectRows
; j
++)
1329 iter2
= m_RowsMap
.find(j
);
1330 if (iter2
== m_RowsMap
.end())
1332 pEffectRow
= iter2
->second
;
1333 if (!pEffectRow
->GetMergeCellFlag())
1336 pEffectRow
->SetCellSplit(nEffectRows
);
1344 * @short add default row which are missing in the file
1345 * @param pXFTable - pointer to new created table
1346 * @param nStartCol - starting column
1347 * @param nEndCol - end column
1350 void LwpTableLayout::ConvertDefaultRow(rtl::Reference
<XFTable
> const & pXFTable
, sal_uInt8 nStartCol
,
1351 sal_uInt8 nEndCol
, sal_uInt16 nRowID
)
1353 // current row doesn't exist in the file
1354 rtl::Reference
<XFRow
> xRow(new XFRow
);
1355 xRow
->SetStyleName(m_DefaultRowStyleName
);
1357 for (sal_uInt16 j
=0;j
< nEndCol
-nStartCol
; j
++)
1359 // if table has default cell layout, use it to ConvertCell
1360 // otherwise use blank cell
1361 rtl::Reference
<XFCell
> xCell
;
1362 if (m_pDefaultCellLayout
)
1364 xCell
= m_pDefaultCellLayout
->DoConvertCell(
1365 GetTable()->GetObjectID(),nRowID
,j
+nStartCol
);
1369 xCell
.set(new XFCell
);
1371 xRow
->AddCell(xCell
);
1374 pXFTable
->AddRow(xRow
);
1377 * @short set cell map info
1378 * @param pXFCell - pointer to xfcell
1379 * @param nRow - row id
1380 * @param nCol - column id
1382 void LwpTableLayout::SetCellsMap(sal_uInt16 nRow
,sal_uInt8 nCol
,XFCell
* pXFCell
)
1384 std::pair
<std::pair
<sal_uInt16
,sal_uInt8
>,XFCell
*> cell
;
1385 std::pair
<sal_uInt16
,sal_uInt8
> pos
;
1389 cell
.second
= pXFCell
;
1390 m_CellsMap
.insert(cell
);
1394 * @short get cell map info
1395 * @param nRow - row id
1396 * @param nCol - column id
1399 XFCell
* LwpTableLayout::GetCellsMap(sal_uInt16 nRow
,sal_uInt8 nCol
)
1401 std::pair
<sal_uInt16
,sal_uInt8
> pos
;
1404 std::map
<std::pair
<sal_uInt16
,sal_uInt8
>,XFCell
*>::iterator iter
;
1405 iter
= m_CellsMap
.find(pos
);
1406 if (iter
== m_CellsMap
.end())
1408 return iter
->second
;
1411 * @descr Get row layout by row id
1412 * @param nRow - row id
1414 LwpRowLayout
* LwpTableLayout::GetRowLayout(sal_uInt16 nRow
)
1416 LwpObjectID
& rRowID
= GetChildHead();
1417 LwpRowLayout
* pRowLayout
= dynamic_cast<LwpRowLayout
*>(rRowID
.obj().get());
1420 if(pRowLayout
->GetRowID() == nRow
)
1423 rRowID
= pRowLayout
->GetNext();
1424 pRowLayout
= dynamic_cast<LwpRowLayout
*>(rRowID
.obj().get());
1430 LwpColumnLayout::LwpColumnLayout(LwpObjectHeader
const &objHdr
, LwpSvStream
* pStrm
)
1431 : LwpVirtualLayout(objHdr
, pStrm
)
1436 LwpColumnLayout::~LwpColumnLayout()
1438 void LwpColumnLayout::Read()
1440 LwpObjectStream
* pStrm
= m_pObjStrm
.get();
1442 LwpVirtualLayout::Read();
1446 colid
= pStrm
->QuickReaduInt16(); // forced to lushort
1447 ccolid
= static_cast<sal_uInt8
>(colid
);
1448 cwidth
= pStrm
->QuickReadInt32();
1453 void LwpColumnLayout::RegisterStyle(double dCalculatedWidth
)
1455 std::unique_ptr
<XFColStyle
> xColStyle(new XFColStyle
);
1456 xColStyle
->SetWidth(static_cast<float>(dCalculatedWidth
));
1457 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
1458 m_StyleName
= pXFStyleManager
->AddStyle(std::move(xColStyle
)).m_pStyle
->GetStyleName();
1461 LwpTableHeadingLayout::LwpTableHeadingLayout(LwpObjectHeader
const &objHdr
, LwpSvStream
* pStrm
)
1462 : LwpTableLayout(objHdr
, pStrm
)
1467 LwpTableHeadingLayout::~LwpTableHeadingLayout()
1470 * @short read table heading layout
1474 void LwpTableHeadingLayout::Read()
1476 LwpTableLayout::Read();
1478 cStartRow
= m_pObjStrm
->QuickReaduInt16();
1479 cEndRow
= m_pObjStrm
->QuickReaduInt16();
1481 m_pObjStrm
->SkipExtra();
1485 * @short get start and end row number of table heading
1487 * @return *pStartRow - starting row number
1488 * @return *pEndRow - end row number
1490 void LwpTableHeadingLayout::GetStartEndRow(sal_uInt16
& nStartRow
, sal_uInt16
& nEndRow
)
1492 nStartRow
= cStartRow
;
1496 LwpSuperParallelColumnLayout::LwpSuperParallelColumnLayout(LwpObjectHeader
const &objHdr
, LwpSvStream
* pStrm
):LwpSuperTableLayout(objHdr
, pStrm
)
1499 LwpSuperParallelColumnLayout::~LwpSuperParallelColumnLayout()
1502 void LwpSuperParallelColumnLayout::Read()
1504 LwpSuperTableLayout::Read();
1505 m_pObjStrm
->SkipExtra();
1509 LwpSuperGlossaryLayout::LwpSuperGlossaryLayout(LwpObjectHeader
const &objHdr
, LwpSvStream
* pStrm
):LwpSuperTableLayout(objHdr
, pStrm
)
1513 LwpSuperGlossaryLayout::~LwpSuperGlossaryLayout()
1517 void LwpSuperGlossaryLayout::Read()
1519 LwpSuperTableLayout::Read();
1520 m_pObjStrm
->SkipExtra();
1523 LwpParallelColumnsLayout::LwpParallelColumnsLayout(LwpObjectHeader
const &objHdr
, LwpSvStream
* pStrm
):LwpTableLayout(objHdr
, pStrm
)
1527 LwpParallelColumnsLayout::~LwpParallelColumnsLayout()
1531 void LwpParallelColumnsLayout::Read()
1533 LwpTableLayout::Read();
1534 m_pObjStrm
->SkipExtra();
1537 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */