Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/inc/htmltbl.hxx
Line
Count
Source
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
20
#ifndef INCLUDED_SW_INC_HTMLTBL_HXX
21
#define INCLUDED_SW_INC_HTMLTBL_HXX
22
23
#include <memory>
24
#include <vcl/timer.hxx>
25
#include <editeng/svxenum.hxx>
26
27
#include "swtypes.hxx"
28
#include "node.hxx"
29
30
class SwTableBox;
31
class SwTable;
32
class SwHTMLTableLayout;
33
class SwDoc;
34
class SwFrameFormat;
35
36
0
#define HTMLTABLE_RESIZE_NOW (ULONG_MAX)
37
38
class SwHTMLTableLayoutCnts
39
{
40
    std::shared_ptr<SwHTMLTableLayoutCnts> m_xNext;   ///< The next content.
41
42
    /// Only one of the following two pointers may be set!
43
    SwTableBox *m_pBox;               ///< A Box.
44
    std::shared_ptr<SwHTMLTableLayout> m_xTable;      ///< A "table within a table".
45
46
    /** During first run there are still no boxes. In this case
47
       pStartNode is used instead of pBox. */
48
    const SwStartNode *m_pStartNode;
49
50
    /** The following counters indicate how often a pass has been
51
        done for this content. Therefore they are compared against
52
        a reference value. If 255 is reached the continue with 0.
53
        This avoids reinitialization on every resize. */
54
    sal_uInt8 m_nPass1Done;           ///< How many times has Pass 1 been called?
55
    sal_uInt8 m_nWidthSet;            ///< How many times has the width been set?
56
57
    bool m_bNoBreakTag;           ///< <NOBR>-Tag over complete content.
58
59
public:
60
61
    SwHTMLTableLayoutCnts(const SwStartNode* pSttNd, std::shared_ptr<SwHTMLTableLayout> aTab,
62
                          bool bNoBreakTag, std::shared_ptr<SwHTMLTableLayoutCnts>  rNxt);
63
64
413k
    void SetTableBox( SwTableBox *pBx ) { m_pBox = pBx; }
65
413k
    SwTableBox *GetTableBox() const { return m_pBox; }
66
67
88
    SwHTMLTableLayout *GetTable() const { return m_xTable.get(); }
68
69
    const SwStartNode *GetStartNode() const;
70
71
    /// Calculation of next node.
72
704k
    const std::shared_ptr<SwHTMLTableLayoutCnts>& GetNext() const { return m_xNext; }
73
74
413k
    void SetWidthSet( sal_uInt8 nRef ) { m_nWidthSet = nRef; }
75
481k
    bool IsWidthSet( sal_uInt8 nRef ) const { return nRef==m_nWidthSet; }
76
77
0
    void SetPass1Done( sal_uInt8 nRef ) { m_nPass1Done = nRef; }
78
0
    bool IsPass1Done( sal_uInt8 nRef ) const { return nRef==m_nPass1Done; }
79
80
0
    bool HasNoBreakTag() const { return m_bNoBreakTag; }
81
};
82
83
class SwHTMLTableLayoutCell
84
{
85
    std::shared_ptr<SwHTMLTableLayoutCnts> m_xContents;  ///< Content of cell.
86
87
    sal_uInt16 m_nRowSpan;               ///< ROWSPAN of cell.
88
    sal_uInt16 m_nColSpan;               ///< COLSPAN of cell.
89
    sal_uInt16 m_nWidthOption;           ///< Given width of cell in Twip or %.
90
91
    bool m_bPercentWidthOption : 1;  ///< nWidth is %-value.
92
    bool m_bNoWrapOption : 1;        ///< NOWRAP-option.
93
94
public:
95
96
    SwHTMLTableLayoutCell(std::shared_ptr<SwHTMLTableLayoutCnts> xCnts,
97
                         sal_uInt16 nRSpan, sal_uInt16 nCSpan,
98
                         sal_uInt16 nWidthOpt, bool bPercentWidthOpt,
99
                         bool bNWrapOpt );
100
101
    /// Set or get content of a cell.
102
195k
    void SetContents(std::shared_ptr<SwHTMLTableLayoutCnts> const& rCnts) { m_xContents = rCnts; }
103
963k
    const std::shared_ptr<SwHTMLTableLayoutCnts>& GetContents() const { return m_xContents; }
104
105
    inline void SetProtected();
106
107
    /// Set or get ROWSPAN/COLSPAN of cell.
108
2.46k
    void SetRowSpan( sal_uInt16 nRSpan ) { m_nRowSpan = nRSpan; }
109
0
    sal_uInt16 GetRowSpan() const { return m_nRowSpan; }
110
439k
    sal_uInt16 GetColSpan() const { return m_nColSpan; }
111
112
0
    sal_uInt16 GetWidthOption() const { return m_nWidthOption; }
113
0
    bool IsPercentWidthOption() const { return m_bPercentWidthOption; }
114
115
0
    bool HasNoWrapOption() const { return m_bNoWrapOption; }
116
};
117
118
class SwHTMLTableLayoutColumn
119
{
120
121
    /// Interim values of AutoLayoutPass1,
122
    sal_uLong m_nMinNoAlign, m_nMaxNoAlign, m_nAbsMinNoAlign;
123
124
    /// Results of AutoLayoutPass1
125
    sal_uLong m_nMin, m_nMax;
126
127
    /// Results of Pass 2.
128
    sal_uInt16 m_nAbsColWidth;                ///< In Twips.
129
    sal_uInt16 m_nRelColWidth;                ///< In Twips or relative to USHRT_MAX.
130
131
    sal_uInt16 m_nWidthOption;                ///< Options of <COL> or <TD>/<TH>.
132
133
    bool m_bRelWidthOption : 1;
134
    bool m_bLeftBorder : 1;
135
136
public:
137
138
    SwHTMLTableLayoutColumn( sal_uInt16 nColWidthOpt, bool bRelColWidthOpt,
139
                             bool bLBorder );
140
141
    inline void MergeCellWidthOption( sal_uInt16 nWidth, bool bPercent );
142
    inline void SetWidthOption( sal_uInt16 nWidth );
143
144
0
    sal_uInt16 GetWidthOption() const { return m_nWidthOption; }
145
0
    bool IsRelWidthOption() const { return m_bRelWidthOption; }
146
147
    inline void MergeMinMaxNoAlign( sal_uLong nMin, sal_uLong nMax, sal_uLong nAbsMin );
148
0
    sal_uLong GetMinNoAlign() const { return m_nMinNoAlign; }
149
0
    sal_uLong GetMaxNoAlign() const { return m_nMaxNoAlign; }
150
0
    sal_uLong GetAbsMinNoAlign() const { return m_nAbsMinNoAlign; }
151
    inline void ClearPass1Info( bool bWidthOpt );
152
153
    inline void SetMinMax( sal_uLong nMin, sal_uLong nMax );
154
0
    void SetMax( sal_uLong nVal ) { m_nMax = nVal; }
155
0
    void AddToMin( sal_uLong nVal ) { m_nMin += nVal; }
156
0
    void AddToMax( sal_uLong nVal ) { m_nMax += nVal; }
157
0
    sal_uLong GetMin() const { return m_nMin; }
158
0
    sal_uLong GetMax() const { return m_nMax; }
159
160
0
    void SetAbsColWidth( sal_uInt16 nWidth ) { m_nAbsColWidth = nWidth; }
161
26.5k
    sal_uInt16 GetAbsColWidth() const { return m_nAbsColWidth; }
162
163
0
    void SetRelColWidth( sal_uInt16 nWidth ) { m_nRelColWidth = nWidth; }
164
844k
    sal_uInt16 GetRelColWidth() const { return m_nRelColWidth; }
165
166
0
    bool HasLeftBorder() const { return m_bLeftBorder; }
167
};
168
169
class SwHTMLTableLayout
170
{
171
    Timer m_aResizeTimer;             ///< Timer for DelayedResize.
172
173
    std::vector<std::unique_ptr<SwHTMLTableLayoutColumn>> m_aColumns;
174
    std::vector<std::unique_ptr<SwHTMLTableLayoutCell>>   m_aCells;
175
176
    const SwTable *m_pSwTable;            ///< SwTable (Top-Table only).
177
178
    sal_uLong m_nMin;                     ///< Minimal width of table (Twips).
179
    sal_uLong m_nMax;                     ///< Maximal width of table (Twips).
180
181
    sal_uInt16 m_nRows;                   ///< Row count.
182
    sal_uInt16 m_nCols;                   ///< Column count.
183
184
    sal_uInt16 m_nLeftMargin;             ///< Space to left margin (from paragraph).
185
    sal_uInt16 m_nRightMargin;            ///< Space to left margin (from paragraph).
186
187
    sal_uInt16 m_nInhAbsLeftSpace;        ///< Space inherited from surrounding box
188
    sal_uInt16 m_nInhAbsRightSpace;       ///< that was added to boxes.
189
190
    sal_uInt16 m_nRelLeftFill;            ///< Width of boxes relative to alignment
191
    sal_uInt16 m_nRelRightFill;           ///< of tables in tables.
192
193
    sal_uInt16 m_nRelTabWidth;            ///< Relative width of table.
194
195
    sal_uInt16 m_nWidthOption;            ///< Width of table (in Twips or %).
196
    sal_uInt16 m_nCellPadding;            ///< Space to contents (in Twips).
197
    sal_uInt16 m_nCellSpacing;            ///< Cell spacing (in Twips).
198
    sal_uInt16 m_nBorder;                 /** Line strength of outer border, or rather the
199
                                        space needed for it as calculated by Netscape. */
200
201
    SwTwips m_nLeftBorderWidth;
202
    SwTwips m_nRightBorderWidth;
203
    sal_uInt16 m_nInhLeftBorderWidth;
204
    sal_uInt16 m_nInhRightBorderWidth;
205
    SwTwips m_nBorderWidth;
206
207
    sal_uInt16 m_nDelayedResizeAbsAvail;  ///< Param for delayed Resize.
208
    sal_uInt16 m_nLastResizeAbsAvail;
209
210
    sal_uInt8 m_nPass1Done;               ///< Reference-values for
211
    sal_uInt8 m_nWidthSet;                ///< the runs through loop.
212
213
    SvxAdjust m_eTableAdjust;             ///< Alignment of table.
214
215
    bool m_bColsOption : 1;           ///< Table has a COLS-option.
216
    bool m_bColTags : 1;              ///< Table has COL/COLGRP tags.
217
    bool m_bPercentWidthOption : 1;       ///< Width is given in percent.
218
    bool m_bUseRelWidth : 1;          ///< SwTable gets relative width.
219
220
    bool m_bMustResize : 1;           ///< Table width must be defined.
221
    bool m_bExportable : 1;           ///< Layout may be used for export.
222
    bool m_bBordersChanged : 1;       ///< Borders have been changed.
223
    bool m_bMayBeInFlyFrame : 1;      ///< Table could be within frame.
224
225
    bool m_bDelayedResizeRecalc : 1;  ///< Param for delayed Resize.
226
    bool m_bMustNotResize : 1;        ///< Table may not be resized.
227
    bool m_bMustNotRecalc : 1;        ///< Table may not be adapted to its contents.
228
229
    void AddBorderWidth( sal_uLong &rMin, sal_uLong &rMax, sal_uLong& rAbsMin,
230
                         sal_uInt16 nCol, sal_uInt16 nColSpan,
231
                         bool bSwBorders=true ) const;
232
    void SetBoxWidth( SwTableBox *pBox, sal_uInt16 nCol, sal_uInt16 nColSpan ) const;
233
234
    const SwStartNode *GetAnyBoxStartNode() const;
235
    SwFrameFormat *FindFlyFrameFormat() const;
236
0
    const SwDoc& GetDoc() const { return GetAnyBoxStartNode()->GetDoc(); }
237
238
    void Resize_( sal_uInt16 nAbsAvail, bool bRecalc );
239
240
    DECL_LINK( DelayedResize_Impl, Timer*, void );
241
242
    static sal_uInt16 GetBrowseWidthByVisArea( const SwDoc& rDoc );
243
public:
244
245
    SwHTMLTableLayout( const SwTable *pSwTable,
246
                       sal_uInt16 nRows, sal_uInt16 nCols, bool bColsOpt, bool ColTgs,
247
                       sal_uInt16 nWidth, bool bPercentWidth, sal_uInt16 nBorderOpt,
248
                       sal_uInt16 nCellPad, sal_uInt16 nCellSp, SvxAdjust eAdjust,
249
                       sal_uInt16 nLMargin, sal_uInt16 nRMargin, sal_uInt16 nBWidth,
250
                       sal_uInt16 nLeftBWidth, sal_uInt16 nRightBWidth );
251
252
    ~SwHTMLTableLayout();
253
254
    sal_uInt16 GetLeftCellSpace( sal_uInt16 nCol, sal_uInt16 nColSpan,
255
                             bool bSwBorders=true ) const;
256
    sal_uInt16 GetRightCellSpace( sal_uInt16 nCol, sal_uInt16 nColSpan,
257
                              bool bSwBorders=true ) const;
258
    inline sal_uInt16 GetInhCellSpace( sal_uInt16 nCol, sal_uInt16 nColSpan ) const;
259
260
    inline void SetInhBorderWidths( sal_uInt16 nLeft, sal_uInt16 nRight );
261
262
    void GetAvail( sal_uInt16 nCol, sal_uInt16 nColSpan, sal_uInt16& rAbsAvail,
263
                   sal_uInt16& rRelAvail ) const;
264
265
    void AutoLayoutPass1();
266
    void AutoLayoutPass2( sal_uInt16 nAbsAvail, sal_uInt16 nRelAvail,
267
                          sal_uInt16 nAbsLeftSpace, sal_uInt16 nAbsRightSpace,
268
                          sal_uInt16 nParentInhSpace );
269
    void SetWidths( bool bCallPass2=false, sal_uInt16 nAbsAvail=0,
270
                    sal_uInt16 nRelAvail=0, sal_uInt16 nAbsLeftSpace=0,
271
                    sal_uInt16 nAbsRightSpace=0,
272
                    sal_uInt16 nParentInhSpace=0 );
273
274
    inline SwHTMLTableLayoutColumn *GetColumn( sal_uInt16 nCol ) const;
275
    inline void SetColumn( std::unique_ptr<SwHTMLTableLayoutColumn> pCol, sal_uInt16 nCol );
276
277
    inline SwHTMLTableLayoutCell *GetCell( sal_uInt16 nRow, sal_uInt16 nCol ) const;
278
    inline void SetCell( std::unique_ptr<SwHTMLTableLayoutCell> pCell, sal_uInt16 nRow, sal_uInt16 nCol );
279
280
110
    sal_uLong GetMin() const { return m_nMin; }
281
336
    sal_uLong GetMax() const { return m_nMax; }
282
283
    inline tools::Long GetBrowseWidthMin() const;
284
285
0
    bool HasColsOption() const { return m_bColsOption; }
286
0
    bool HasColTags() const { return m_bColTags; }
287
288
68.3k
    bool IsTopTable() const  { return m_pSwTable != nullptr; }
289
290
68.3k
    void SetMustResize( bool bSet ) { m_bMustResize = bSet; }
291
134
    void SetMustNotResize( bool bSet ) { m_bMustNotResize = bSet; }
292
470
    void SetMustNotRecalc( bool bSet ) { m_bMustNotRecalc = bSet; }
293
294
    /** Recalculation of table widths for available width that has been passed.
295
     - If bRecalc is set, contents of boxes are included into calculation.
296
     - If bForce is set, table will be recalculated even if this was
297
       disallowed by SetMustNotResize.
298
     - If nDelay > 0 the calculation is delayed accordingly. Resizing calls
299
       occurring during delay-time are ignored, but the delay may be counted
300
       under certain circumstances.
301
     - If nDelay == HTMLTABLE_RESIZE_NOW, resize immediately and do not
302
       consider any resize-calls that might possibly be in order.
303
     - The return value indicates whether the table has been changed. */
304
    bool Resize( sal_uInt16 nAbsAvail, bool bRecalc=false, bool bForce=false,
305
                 sal_uLong nDelay=0 );
306
307
    void BordersChanged( sal_uInt16 nAbsAvail );
308
309
    /** Calculate available width. This works only if a layout or a
310
     SwViewShell exists. Otherwise returns 0.
311
     This is needed by HTML-filter because it doesn't have access to the layout.) */
312
    static sal_uInt16 GetBrowseWidth( const SwDoc& rDoc );
313
314
    /// Calculates available width by table-frame.
315
    sal_uInt16 GetBrowseWidthByTabFrame( const SwTabFrame& rTabFrame ) const;
316
317
    /** Calculates available width by the table-frame or
318
     static GetBrowseWidth if no layout exists. */
319
    sal_uInt16 GetBrowseWidthByTable( const SwDoc& rDoc ) const;
320
321
    /// For Export.
322
0
    sal_uInt16 GetWidthOption() const { return m_nWidthOption; }
323
0
    bool   HasPercentWidthOption() const { return m_bPercentWidthOption; }
324
325
0
    sal_uInt16 GetCellPadding() const { return m_nCellPadding; }
326
0
    sal_uInt16 GetCellSpacing() const { return m_nCellSpacing; }
327
0
    sal_uInt16 GetBorder() const { return m_nBorder; }
328
329
0
    sal_uInt16 GetRowCount() const { return m_nRows; }
330
0
    sal_uInt16 GetColCount() const { return m_nCols; }
331
332
68.3k
    void SetExportable( bool bSet ) { m_bExportable = bSet; }
333
0
    bool IsExportable() const { return m_bExportable; }
334
335
0
    bool HaveBordersChanged() const { return m_bBordersChanged; }
336
337
68.3k
    void SetMayBeInFlyFrame( bool bSet ) { m_bMayBeInFlyFrame = bSet; }
338
68.3k
    bool MayBeInFlyFrame() const { return m_bMayBeInFlyFrame; }
339
};
340
341
inline void SwHTMLTableLayoutCell::SetProtected()
342
0
{
343
0
    m_nRowSpan = 1;
344
0
    m_nColSpan = 1;
345
0
    m_xContents.reset();
346
0
}
347
348
inline void SwHTMLTableLayoutColumn::MergeMinMaxNoAlign( sal_uLong nCMin,
349
    sal_uLong nCMax,    sal_uLong nAbsMin )
350
0
{
351
0
    if( nCMin > m_nMinNoAlign )
352
0
        m_nMinNoAlign = nCMin;
353
0
    if( nCMax > m_nMaxNoAlign )
354
0
        m_nMaxNoAlign = nCMax;
355
0
    if( nAbsMin > m_nAbsMinNoAlign )
356
0
        m_nAbsMinNoAlign = nAbsMin;
357
0
}
358
359
inline void SwHTMLTableLayoutColumn::ClearPass1Info( bool bWidthOpt )
360
0
{
361
0
    m_nMinNoAlign = m_nMaxNoAlign = m_nAbsMinNoAlign = MINLAY;
362
0
    m_nMin = m_nMax = 0;
363
0
    if( bWidthOpt )
364
0
    {
365
0
        m_nWidthOption = 0;
366
0
        m_bRelWidthOption = false;
367
0
    }
368
0
}
369
370
inline void SwHTMLTableLayoutColumn::MergeCellWidthOption(
371
    sal_uInt16 nWidth, bool bRel )
372
0
{
373
0
    if( !m_nWidthOption ||
374
0
        (bRel==m_bRelWidthOption && m_nWidthOption < nWidth) )
375
0
    {
376
0
        m_nWidthOption = nWidth;
377
0
        m_bRelWidthOption = bRel;
378
0
    }
379
0
}
380
381
inline void SwHTMLTableLayoutColumn::SetMinMax( sal_uLong nMn, sal_uLong nMx )
382
0
{
383
0
    m_nMin = nMn;
384
0
    m_nMax = nMx;
385
0
}
386
387
inline sal_uInt16 SwHTMLTableLayout::GetInhCellSpace( sal_uInt16 nCol,
388
                                                  sal_uInt16 nColSpan ) const
389
0
{
390
0
    sal_uInt16 nSpace = 0;
391
0
    if( nCol==0 )
392
0
        nSpace = nSpace + m_nInhAbsLeftSpace;
393
0
    if( nCol+nColSpan==m_nCols )
394
0
        nSpace = nSpace + m_nInhAbsRightSpace;
395
396
0
    return nSpace;
397
0
}
398
399
inline SwHTMLTableLayoutColumn *SwHTMLTableLayout::GetColumn( sal_uInt16 nCol ) const
400
844k
{
401
844k
    return m_aColumns[nCol].get();
402
844k
}
403
404
inline void SwHTMLTableLayoutColumn::SetWidthOption( sal_uInt16 nWidth )
405
0
{
406
0
    m_nWidthOption = nWidth;
407
0
    m_bRelWidthOption = true;
408
0
}
409
410
inline void SwHTMLTableLayout::SetColumn( std::unique_ptr<SwHTMLTableLayoutColumn> pCol, sal_uInt16 nCol )
411
215k
{
412
215k
    m_aColumns[nCol] = std::move(pCol);
413
215k
}
414
415
inline SwHTMLTableLayoutCell *SwHTMLTableLayout::GetCell( sal_uInt16 nRow, sal_uInt16 nCol ) const
416
1.18M
{
417
1.18M
    return m_aCells[static_cast<size_t>(nRow)*m_nCols+nCol].get();
418
1.18M
}
419
420
inline void SwHTMLTableLayout::SetCell( std::unique_ptr<SwHTMLTableLayoutCell> pCell,
421
                               sal_uInt16 nRow, sal_uInt16 nCol )
422
481k
{
423
481k
    m_aCells[static_cast<size_t>(nRow)*m_nCols+nCol] = std::move(pCell);
424
481k
}
425
426
inline tools::Long SwHTMLTableLayout::GetBrowseWidthMin() const
427
0
{
428
0
    return static_cast<tools::Long>( (!m_nWidthOption || m_bPercentWidthOption) ? m_nMin : m_nRelTabWidth );
429
0
}
430
431
void SwHTMLTableLayout::SetInhBorderWidths( sal_uInt16 nLeft, sal_uInt16 nRight )
432
0
{
433
0
    m_nInhLeftBorderWidth = nLeft;
434
0
    m_nInhRightBorderWidth = nRight;
435
0
}
436
437
#endif
438
439
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */