1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 #ifndef INCLUDED_SW_SOURCE_FILTER_INC_WRTSWTBL_HXX
20 #define INCLUDED_SW_SOURCE_FILTER_INC_WRTSWTBL_HXX
21 
22 #include <tools/color.hxx>
23 #include <tools/long.hxx>
24 #include <o3tl/sorted_vector.hxx>
25 
26 #include <swdllapi.h>
27 
28 #include <memory>
29 #include <vector>
30 #include <climits>
31 
32 class SwTableBox;
33 class SwTableLine;
34 class SwTableLines;
35 class SwHTMLTableLayout;
36 class SvxBrushItem;
37 
38 namespace editeng { class SvxBorderLine; }
39 
40 //       Code from the HTML filter for writing of tables
41 
42 #define COLFUZZY 20
43 #define ROWFUZZY 20
44 #define COL_DFLT_WIDTH ((2*COLFUZZY)+1)
45 #define ROW_DFLT_HEIGHT (2*ROWFUZZY)+1
46 
47 class SW_DLLPUBLIC SwWriteTableCell
48 {
49     const SwTableBox *pBox;             // SwTableBox of the cell
50     const SvxBrushItem *pBackground;    // inherited background of a row
51 
52     tools::Long nHeight;                   // fix/minimum height of a row
53 
54     sal_uInt32 nWidthOpt;           // width from option;
55 
56     sal_uInt16 nRow;                // start row
57     sal_uInt16 nCol;                // start column
58 
59     sal_uInt16 nRowSpan;            // spanned rows
60     sal_uInt16 nColSpan;            // spanned columns
61 
62     bool bPercentWidthOpt;
63 
64 public:
65 
SwWriteTableCell(const SwTableBox * pB,sal_uInt16 nR,sal_uInt16 nC,sal_uInt16 nRSpan,sal_uInt16 nCSpan,tools::Long nHght,const SvxBrushItem * pBGround)66     SwWriteTableCell(const SwTableBox *pB, sal_uInt16 nR, sal_uInt16 nC, sal_uInt16 nRSpan,
67         sal_uInt16 nCSpan, tools::Long nHght, const SvxBrushItem *pBGround)
68     : pBox( pB ), pBackground( pBGround ), nHeight( nHght ), nWidthOpt( 0 ),
69     nRow( nR ), nCol( nC ), nRowSpan( nRSpan ), nColSpan( nCSpan ),
70     bPercentWidthOpt( false )
71     {}
72 
GetBox() const73     const SwTableBox *GetBox() const { return pBox; }
74 
GetRow() const75     sal_uInt16 GetRow() const { return nRow; }
GetCol() const76     sal_uInt16 GetCol() const { return nCol; }
77 
GetRowSpan() const78     sal_uInt16 GetRowSpan() const { return nRowSpan; }
GetColSpan() const79     sal_uInt16 GetColSpan() const { return nColSpan; }
80 
GetHeight() const81     tools::Long GetHeight() const { return nHeight; }
82     sal_Int16 GetVertOri() const;
83 
GetBackground() const84     const SvxBrushItem *GetBackground() const { return pBackground; }
85 
SetWidthOpt(sal_uInt16 nWidth,bool bPercent)86     void SetWidthOpt( sal_uInt16 nWidth, bool bPercent )
87     {
88         nWidthOpt = nWidth; bPercentWidthOpt = bPercent;
89     }
90 
GetWidthOpt() const91     sal_uInt32 GetWidthOpt() const { return nWidthOpt; }
HasPercentWidthOpt() const92     bool HasPercentWidthOpt() const { return bPercentWidthOpt; }
93 };
94 
95 typedef std::vector<std::unique_ptr<SwWriteTableCell>> SwWriteTableCells;
96 
97 class SwWriteTableRow final
98 {
99     SwWriteTableCells m_Cells;       ///< all cells of the rows
100     const SvxBrushItem *pBackground; // background
101 
102     tools::Long nPos;                       // end position (twips) of the row
103     bool mbUseLayoutHeights;
104 
105     SwWriteTableRow & operator= (const SwWriteTableRow &) = delete;
106 
107     // GCC >= 3.4 needs accessible T (const T&) to pass T as const T& argument.
108     SwWriteTableRow( const SwWriteTableRow & );
109 
110 public:
111 
112     sal_uInt16 nTopBorder;          // thickness of upper/lower border
113     sal_uInt16 nBottomBorder;
114 
115     bool bTopBorder : 1;            // which borders are there?
116     bool bBottomBorder : 1;
117 
118     SwWriteTableRow( tools::Long nPos, bool bUseLayoutHeights );
119 
120     SwWriteTableCell *AddCell( const SwTableBox *pBox,
121                                  sal_uInt16 nRow, sal_uInt16 nCol,
122                                  sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
123                                  tools::Long nHeight,
124                                  const SvxBrushItem *pBackground );
125 
SetBackground(const SvxBrushItem * pBGround)126     void SetBackground( const SvxBrushItem *pBGround )
127     {
128         pBackground = pBGround;
129     }
GetBackground() const130     const SvxBrushItem *GetBackground() const { return pBackground; }
131 
HasTopBorder() const132     bool HasTopBorder() const                   { return bTopBorder; }
HasBottomBorder() const133     bool HasBottomBorder() const                { return bBottomBorder; }
134 
GetCells() const135     const SwWriteTableCells& GetCells() const   { return m_Cells; }
136 
137     inline bool operator==( const SwWriteTableRow& rRow ) const;
138     inline bool operator<( const SwWriteTableRow& rRow2 ) const;
139 };
140 
operator ==(const SwWriteTableRow & rRow) const141 inline bool SwWriteTableRow::operator==( const SwWriteTableRow& rRow ) const
142 {
143     // allow for some fuzzyness
144     return (nPos >= rRow.nPos ?  nPos - rRow.nPos : rRow.nPos - nPos ) <=
145         (mbUseLayoutHeights ? 0 : ROWFUZZY);
146 }
147 
operator <(const SwWriteTableRow & rRow) const148 inline bool SwWriteTableRow::operator<( const SwWriteTableRow& rRow ) const
149 {
150     // Since we only know the degrees of truth of 0 and 1 here, we also prefer to
151     // not let x==y and x<y at the same time ;-)
152     return nPos < rRow.nPos - (mbUseLayoutHeights ? 0 : ROWFUZZY);
153 }
154 
155 using SwWriteTableRows
156     = o3tl::sorted_vector< std::unique_ptr<SwWriteTableRow>, o3tl::less_uniqueptr_to<SwWriteTableRow> >;
157 
158 class SwWriteTableCol
159 {
160     sal_uInt32 nPos;                    // end position of the column
161 
162     sal_uInt32 nWidthOpt;
163 
164     bool bRelWidthOpt : 1;
165 
166 public:
167     bool bLeftBorder : 1;               // which borders are there?
168     bool bRightBorder : 1;
169 
170     SwWriteTableCol( sal_uInt32 nPosition );
171 
GetPos() const172     sal_uInt32 GetPos() const                       { return nPos; }
173 
HasLeftBorder() const174     bool HasLeftBorder() const                  { return bLeftBorder; }
175 
HasRightBorder() const176     bool HasRightBorder() const                 { return bRightBorder; }
177 
178     inline bool operator==( const SwWriteTableCol& rCol ) const;
179     inline bool operator<( const SwWriteTableCol& rCol ) const;
180 
SetWidthOpt(sal_uInt32 nWidth,bool bRel)181     void SetWidthOpt( sal_uInt32 nWidth, bool bRel )
182     {
183         nWidthOpt = nWidth; bRelWidthOpt = bRel;
184     }
GetWidthOpt() const185     sal_uInt32 GetWidthOpt() const                 { return nWidthOpt; }
HasRelWidthOpt() const186     bool HasRelWidthOpt() const                 { return bRelWidthOpt; }
187 };
188 
operator ==(const SwWriteTableCol & rCol) const189 inline bool SwWriteTableCol::operator==( const SwWriteTableCol& rCol ) const
190 {
191     // allow for some fuzzyness
192     return (nPos >= rCol.nPos ? nPos - rCol.nPos
193                                      : rCol.nPos - nPos ) <= COLFUZZY;
194 }
195 
operator <(const SwWriteTableCol & rCol) const196 inline bool SwWriteTableCol::operator<( const SwWriteTableCol& rCol ) const
197 {
198     // Since we only know the degrees of truth of 0 and 1 here, we also prefer to
199     // not let x==y and x<y at the same time ;-)
200     return nPos + COLFUZZY < rCol.nPos;
201 }
202 
203 struct SwWriteTableColLess {
operator ()SwWriteTableColLess204     bool operator()(std::unique_ptr<SwWriteTableCol> const & lhs, std::unique_ptr<SwWriteTableCol> const & rhs) {
205         return lhs->GetPos() < rhs->GetPos();
206     }
207 };
208 
209 class SwWriteTableCols : public o3tl::sorted_vector<std::unique_ptr<SwWriteTableCol>, SwWriteTableColLess> {
210 };
211 
212 class SwTable;
213 
214 class SW_DLLPUBLIC SwWriteTable
215 {
216 private:
217     const SwTable* m_pTable;
218 protected:
219     SwWriteTableCols m_aCols; // all columns
220     SwWriteTableRows m_aRows; // all rows
221 
222     Color      m_nBorderColor;        // border color
223 
224     sal_uInt16 m_nCellSpacing;        // thickness of the inner border
225     sal_uInt16 m_nCellPadding;        // distance of border to content
226 
227     sal_uInt16 m_nBorder;             // thickness of the outer border
228     sal_uInt16 m_nInnerBorder;        // thickness of the inner border
229     sal_uInt32 m_nBaseWidth;          // reference value for SwFormatFrameSize width
230 
231     sal_uInt16 m_nHeadEndRow;         // last row of the table heading
232 
233     sal_uInt16 m_nLeftSub;
234     sal_uInt16 m_nRightSub;
235 
236     sal_uInt32 m_nTabWidth;           // absolute/relative width of the table
237 
238     bool m_bRelWidths : 1;        // generate relative widths?
239     bool m_bUseLayoutHeights : 1; // use layout to determine the height?
240 #ifdef DBG_UTIL
241     bool m_bGetLineHeightCalled : 1;
242 #endif
243 
244     bool m_bColTags : 1;
245     bool m_bLayoutExport : 1;
246     bool m_bCollectBorderWidth : 1;
247 
248     virtual bool ShouldExpandSub( const SwTableBox *pBox,
249                                 bool bExpandedBefore, sal_uInt16 nDepth ) const;
250 
251     void CollectTableRowsCols( tools::Long nStartRPos, sal_uInt32 nStartCPos,
252                                tools::Long nParentLineHeight,
253                                sal_uInt32 nParentLineWidth,
254                                const SwTableLines& rLines,
255                                sal_uInt16 nDepth );
256 
257     void FillTableRowsCols( tools::Long nStartRPos, sal_uInt16 nStartRow,
258                             sal_uInt32 nStartCPos, sal_uInt16 nStartCol,
259                             tools::Long nParentLineHeight,
260                             sal_uInt32 nParentLineWidth,
261                             const SwTableLines& rLines,
262                             const SvxBrushItem* pLineBrush,
263                             sal_uInt16 nDepth,
264                             sal_uInt16 nNumOfHeaderRows );
265 
266     void MergeBorders( const editeng::SvxBorderLine* pBorderLine, bool bTable );
267 
268     sal_uInt16 MergeBoxBorders(const SwTableBox *pBox, size_t nRow, size_t nCol,
269                             sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
270                             sal_uInt16 &rTopBorder, sal_uInt16 &rBottomBorder );
271 
GetBaseWidth() const272     sal_uInt32 GetBaseWidth() const { return m_nBaseWidth; }
273 
HasRelWidths() const274     bool HasRelWidths() const { return m_bRelWidths; }
275 
276 public:
277     static sal_uInt32 GetBoxWidth( const SwTableBox *pBox );
278 
279     sal_uInt32 GetRawWidth( sal_uInt16 nCol, sal_uInt16 nColSpan ) const;
280     sal_uInt16 GetAbsWidth( sal_uInt16 nCol, sal_uInt16 nColSpan ) const;
281     sal_uInt16 GetRelWidth( sal_uInt16 nCol, sal_uInt16 nColSpan ) const;
282     sal_uInt16 GetPercentWidth( sal_uInt16 nCol, sal_uInt16 nColSpan ) const;
283 
284     tools::Long GetAbsHeight(tools::Long nRawWidth, size_t nRow, sal_uInt16 nRowSpan) const;
285 
GetAbsWidthRatio() const286     double GetAbsWidthRatio() const { return m_nTabWidth == m_nBaseWidth ? 1.0 : double(m_nTabWidth) / m_nBaseWidth; }
287 protected:
288     tools::Long GetLineHeight( const SwTableLine *pLine );
289     static tools::Long GetLineHeight( const SwTableBox *pBox );
290     static const SvxBrushItem *GetLineBrush( const SwTableBox *pBox,
291                                       SwWriteTableRow *pRow );
292 
293     sal_uInt16 GetLeftSpace( sal_uInt16 nCol ) const;
294     sal_uInt16 GetRightSpace(size_t nCol, sal_uInt16 nColSpan) const;
295 
296 public:
297     SwWriteTable(const SwTable* pTable, const SwTableLines& rLines, tools::Long nWidth, sal_uInt32 nBWidth,
298                  bool bRel, sal_uInt16 nMaxDepth = USHRT_MAX,
299                  sal_uInt16 nLeftSub=0, sal_uInt16 nRightSub=0, sal_uInt32 nNumOfRowsToRepeat=0);
300     SwWriteTable(const SwTable* pTable, const SwHTMLTableLayout *pLayoutInfo);
301     virtual ~SwWriteTable();
302 
GetRows() const303     const SwWriteTableRows& GetRows() const { return m_aRows; }
304 
GetTable() const305     const SwTable* GetTable() const { return m_pTable; }
306 };
307 
308 #endif
309 
310 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
311