Coverage Report

Created: 2026-05-16 09:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/view/printfun.cxx
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
#include <scitems.hxx>
21
#include <editeng/eeitem.hxx>
22
23
#include <printfun.hxx>
24
25
#include <editeng/adjustitem.hxx>
26
#include <editeng/borderline.hxx>
27
#include <editeng/boxitem.hxx>
28
#include <editeng/brushitem.hxx>
29
#include <svtools/colorcfg.hxx>
30
#include <editeng/editstat.hxx>
31
#include <svx/fmview.hxx>
32
#include <vcl/pdfextoutdevdata.hxx>
33
#include <editeng/frmdiritem.hxx>
34
#include <editeng/lrspitem.hxx>
35
#include <editeng/paperinf.hxx>
36
#include <editeng/pbinitem.hxx>
37
#include <editeng/shaditem.hxx>
38
#include <editeng/sizeitem.hxx>
39
#include <editeng/fhgtitem.hxx>
40
#include <editeng/ulspitem.hxx>
41
#include <sfx2/printer.hxx>
42
#include <tools/multisel.hxx>
43
#include <sfx2/docfile.hxx>
44
#include <tools/urlobj.hxx>
45
#include <osl/diagnose.h>
46
47
#include <editutil.hxx>
48
#include <docsh.hxx>
49
#include <output.hxx>
50
#include <viewdata.hxx>
51
#include <viewopti.hxx>
52
#include <stlpool.hxx>
53
#include <pagepar.hxx>
54
#include <attrib.hxx>
55
#include <patattr.hxx>
56
#include <dociter.hxx>
57
#include <globstr.hrc>
58
#include <scresid.hxx>
59
#include <pagedata.hxx>
60
#include <printopt.hxx>
61
#include <prevloc.hxx>
62
#include <scmod.hxx>
63
#include <drwlayer.hxx>
64
#include <fillinfo.hxx>
65
#include <postit.hxx>
66
67
#include <memory>
68
#include <com/sun/star/document/XDocumentProperties.hpp>
69
70
85.0k
#define ZOOM_MIN    10
71
72
namespace{
73
74
bool lcl_GetBool(const SfxItemSet* pSet, sal_uInt16 nWhich)
75
258k
{
76
258k
    return static_cast<const SfxBoolItem&>(pSet->Get(nWhich)).GetValue();
77
258k
}
78
79
sal_uInt16 lcl_GetUShort(const SfxItemSet* pSet, sal_uInt16 nWhich)
80
43.0k
{
81
43.0k
    return static_cast<const SfxUInt16Item&>(pSet->Get(nWhich)).GetValue();
82
43.0k
}
83
84
bool lcl_GetShow(const SfxItemSet* pSet, sal_uInt16 nWhich)
85
129k
{
86
129k
    return ScVObjMode::VOBJ_MODE_SHOW == static_cast<const ScViewObjectModeItem&>(pSet->Get(nWhich)).GetValue();
87
129k
}
88
89
90
} // namespace
91
92
ScPageRowEntry::ScPageRowEntry(const ScPageRowEntry& r)
93
0
{
94
0
    nStartRow = r.nStartRow;
95
0
    nEndRow   = r.nEndRow;
96
0
    nPagesX   = r.nPagesX;
97
0
    aHidden   = r.aHidden;
98
0
    aHidden.resize(nPagesX, false);
99
0
}
100
101
ScPageRowEntry& ScPageRowEntry::operator=(const ScPageRowEntry& r)
102
0
{
103
0
    nStartRow = r.nStartRow;
104
0
    nEndRow   = r.nEndRow;
105
0
    nPagesX   = r.nPagesX;
106
0
    aHidden   = r.aHidden;
107
0
    aHidden.resize(nPagesX, false);
108
0
    return *this;
109
0
}
110
111
void ScPageRowEntry::SetPagesX(size_t nNew)
112
42.0k
{
113
42.0k
    nPagesX = nNew;
114
42.0k
    aHidden.resize(nPagesX, false);
115
42.0k
}
116
117
void ScPageRowEntry::SetHidden(size_t nX)
118
0
{
119
0
    if ( nX < nPagesX )
120
0
    {
121
0
        if ( nX+1 == nPagesX )  // last page?
122
0
            --nPagesX;
123
0
        else
124
0
        {
125
0
            aHidden.resize(nPagesX, false);
126
0
            aHidden[nX] = true;
127
0
        }
128
0
    }
129
0
}
130
131
bool ScPageRowEntry::IsHidden(size_t nX) const
132
0
{
133
0
    return nX >= nPagesX || aHidden[nX];       //! inline?
134
0
}
135
136
size_t ScPageRowEntry::CountVisible() const
137
0
{
138
0
    if (!aHidden.empty())
139
0
    {
140
0
        size_t nVis = 0;
141
0
        for (size_t i=0; i<nPagesX; i++)
142
0
            if (!aHidden[i])
143
0
                ++nVis;
144
0
        return nVis;
145
0
    }
146
0
    else
147
0
        return nPagesX;
148
0
}
149
150
static tools::Long lcl_LineTotal(const ::editeng::SvxBorderLine* pLine)
151
521k
{
152
521k
    return pLine ? ( pLine->GetScaledWidth() ) : 0;
153
521k
}
154
155
void ScPrintFunc::Construct( const ScPrintOptions* pOptions )
156
43.0k
{
157
43.0k
    rDocShell.UpdatePendingRowHeights( nPrintTab );
158
159
43.0k
    SfxPrinter* pDocPrinter = rDoc.GetPrinter();   // use the printer, even for preview
160
43.0k
    if (pDocPrinter)
161
43.0k
        aOldPrinterMode = pDocPrinter->GetMapMode();
162
163
    //  unified MapMode for all calls (e.g. Repaint!!!)
164
    //  else, EditEngine outputs different text heights
165
43.0k
    pDev->SetMapMode(MapMode(MapUnit::MapPixel));
166
167
43.0k
    pBorderItem = nullptr;
168
43.0k
    pBackgroundItem = nullptr;
169
43.0k
    pShadowItem = nullptr;
170
171
43.0k
    pEditEngine = nullptr;
172
43.0k
    pEditDefaults = nullptr;
173
174
43.0k
    ScStyleSheetPool* pStylePool    = rDoc.GetStyleSheetPool();
175
43.0k
    SfxStyleSheetBase* pStyleSheet  = pStylePool->Find(
176
43.0k
                                            rDoc.GetPageStyle( nPrintTab ),
177
43.0k
                                            SfxStyleFamily::Page );
178
43.0k
    if (pStyleSheet)
179
43.0k
        pParamSet = &pStyleSheet->GetItemSet();
180
0
    else
181
0
    {
182
0
        OSL_FAIL("Template not found" );
183
0
        pParamSet = nullptr;
184
0
    }
185
186
43.0k
    if (!bFromPrintState)
187
43.0k
        nZoom = 100;
188
43.0k
    nManualZoom = 100;
189
43.0k
    bClearWin = false;
190
43.0k
    bUseStyleColor = false;
191
43.0k
    bIsRender = false;
192
193
43.0k
    InitParam(pOptions);
194
195
43.0k
    pPageData = nullptr;       // is only needed for initialisation
196
43.0k
}
197
198
ScPrintFunc::ScPrintFunc(ScDocShell& rShell, SfxPrinter* pNewPrinter, SCTAB nTab, tools::Long nPage,
199
                         tools::Long nDocP, const ScRange* pArea, const ScPrintOptions* pOptions,
200
                         ScPageBreakData* pData, Size aSize, bool bPrintLandscape, bool bUsed)
201
43.0k
    :   rDocShell           ( rShell ),
202
43.0k
        rDoc(rDocShell.GetDocument()),
203
43.0k
        pPrinter            ( pNewPrinter ),
204
43.0k
        pDrawView           ( nullptr ),
205
43.0k
        nPrintTab           ( nTab ),
206
43.0k
        nPageStart          ( nPage ),
207
43.0k
        nDocPages           ( nDocP ),
208
43.0k
        pUserArea           ( pArea ),
209
43.0k
        bFromPrintState     ( false ),
210
43.0k
        bSourceRangeValid   ( false ),
211
43.0k
        bPrintCurrentTable  ( false ),
212
43.0k
        bMultiArea          ( false ),
213
43.0k
        mbHasPrintRange(true),
214
43.0k
        nTabPages           ( 0 ),
215
43.0k
        nTotalPages         ( 0 ),
216
43.0k
        bPrintAreaValid     ( false ),
217
43.0k
        pPageData           ( pData ),
218
43.0k
        aPrintPageSize      ( aSize ),
219
43.0k
        bPrintPageLandscape ( bPrintLandscape ),
220
43.0k
        bUsePrintDialogSetting ( bUsed )
221
43.0k
{
222
43.0k
    pDev = pPrinter.get();
223
43.0k
    aSrcOffset = pPrinter->PixelToLogic(pPrinter->GetPageOffsetPixel(), MapMode(MapUnit::Map100thMM));
224
43.0k
    m_aRanges.m_xPageEndX = std::make_shared<std::vector<SCCOL>>();
225
43.0k
    m_aRanges.m_xPageEndY = std::make_shared<std::vector<SCROW>>();
226
43.0k
    m_aRanges.m_xPageRows = std::make_shared<std::map<size_t, ScPageRowEntry>>();
227
43.0k
    Construct( pOptions );
228
43.0k
}
229
230
ScPrintFunc::ScPrintFunc(ScDocShell& rShell, SfxPrinter* pNewPrinter, const ScPrintState& rState,
231
                         const ScPrintOptions* pOptions, Size aSize, bool bPrintLandscape,
232
                         bool bUsed)
233
0
    :   rDocShell           ( rShell ),
234
0
        rDoc(rDocShell.GetDocument()),
235
0
        pPrinter            ( pNewPrinter ),
236
0
        pDrawView           ( nullptr ),
237
0
        pUserArea           ( nullptr ),
238
0
        bSourceRangeValid   ( false ),
239
0
        bPrintCurrentTable  ( false ),
240
0
        bMultiArea          ( false ),
241
0
        mbHasPrintRange(true),
242
0
        pPageData           ( nullptr ),
243
0
        aPrintPageSize      ( aSize ),
244
0
        bPrintPageLandscape ( bPrintLandscape ),
245
0
        bUsePrintDialogSetting ( bUsed )
246
0
{
247
0
    pDev = pPrinter.get();
248
249
0
    nPrintTab   = rState.nPrintTab;
250
0
    nStartCol   = rState.nStartCol;
251
0
    nStartRow   = rState.nStartRow;
252
0
    nEndCol     = rState.nEndCol;
253
0
    nEndRow     = rState.nEndRow;
254
0
    bPrintAreaValid = rState.bPrintAreaValid;
255
0
    nZoom       = rState.nZoom;
256
0
    m_aRanges = rState.m_aRanges;
257
0
    nTabPages   = rState.nTabPages;
258
0
    nTotalPages = rState.nTotalPages;
259
0
    nPageStart  = rState.nPageStart;
260
0
    nDocPages   = rState.nDocPages;
261
0
    bFromPrintState = true;
262
263
0
    aSrcOffset = pPrinter->PixelToLogic(pPrinter->GetPageOffsetPixel(), MapMode(MapUnit::Map100thMM));
264
0
    Construct( pOptions );
265
0
}
266
267
ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell& rShell, SCTAB nTab,
268
                            tools::Long nPage, tools::Long nDocP, const ScRange* pArea,
269
                            const ScPrintOptions* pOptions )
270
0
    :   rDocShell           ( rShell ),
271
0
        rDoc(rDocShell.GetDocument()),
272
0
        pPrinter            ( nullptr ),
273
0
        pDrawView           ( nullptr ),
274
0
        nPrintTab           ( nTab ),
275
0
        nPageStart          ( nPage ),
276
0
        nDocPages           ( nDocP ),
277
0
        pUserArea           ( pArea ),
278
0
        bFromPrintState     ( false ),
279
0
        bSourceRangeValid   ( false ),
280
0
        bPrintCurrentTable  ( false ),
281
0
        bMultiArea          ( false ),
282
0
        mbHasPrintRange(true),
283
0
        nTabPages           ( 0 ),
284
0
        nTotalPages         ( 0 ),
285
0
        bPrintAreaValid     ( false ),
286
0
        pPageData           ( nullptr ),
287
0
        aPrintPageSize      ( Size() ),
288
0
        bPrintPageLandscape ( false ),
289
0
        bUsePrintDialogSetting ( false )
290
0
{
291
0
    pDev = pOutDev;
292
0
    m_aRanges.m_xPageEndX = std::make_shared<std::vector<SCCOL>>();
293
0
    m_aRanges.m_xPageEndY = std::make_shared<std::vector<SCROW>>();
294
0
    m_aRanges.m_xPageRows = std::make_shared<std::map<size_t, ScPageRowEntry>>();
295
0
    Construct( pOptions );
296
0
}
297
298
ScPrintFunc::ScPrintFunc(OutputDevice* pOutDev, ScDocShell& rShell, const ScPrintState& rState,
299
                         const ScPrintOptions* pOptions, Size aSize, bool bPrintLandscape,
300
                         bool bUsed)
301
0
    :   rDocShell           ( rShell ),
302
0
        rDoc(rDocShell.GetDocument()),
303
0
        pPrinter            ( nullptr ),
304
0
        pDrawView           ( nullptr ),
305
0
        pUserArea           ( nullptr ),
306
0
        bSourceRangeValid   ( false ),
307
0
        bPrintCurrentTable  ( false ),
308
0
        bMultiArea          ( false ),
309
0
        mbHasPrintRange(true),
310
0
        pPageData           ( nullptr ),
311
0
        aPrintPageSize      ( aSize ),
312
0
        bPrintPageLandscape ( bPrintLandscape ),
313
0
        bUsePrintDialogSetting ( bUsed )
314
0
{
315
0
    pDev = pOutDev;
316
317
0
    nPrintTab   = rState.nPrintTab;
318
0
    nStartCol   = rState.nStartCol;
319
0
    nStartRow   = rState.nStartRow;
320
0
    nEndCol     = rState.nEndCol;
321
0
    nEndRow     = rState.nEndRow;
322
0
    bPrintAreaValid = rState.bPrintAreaValid;
323
0
    nZoom       = rState.nZoom;
324
0
    m_aRanges   = rState.m_aRanges;
325
0
    nTabPages   = rState.nTabPages;
326
0
    nTotalPages = rState.nTotalPages;
327
0
    nPageStart  = rState.nPageStart;
328
0
    nDocPages   = rState.nDocPages;
329
0
    bFromPrintState = true;
330
331
0
    Construct( pOptions );
332
0
}
333
334
void ScPrintFunc::GetPrintState(ScPrintState& rState)
335
0
{
336
0
    rState.nPrintTab    = nPrintTab;
337
0
    rState.nStartCol    = nStartCol;
338
0
    rState.nStartRow    = nStartRow;
339
0
    rState.nEndCol      = nEndCol;
340
0
    rState.nEndRow      = nEndRow;
341
0
    rState.bPrintAreaValid = bPrintAreaValid;
342
0
    rState.nZoom        = nZoom;
343
0
    rState.nTabPages    = nTabPages;
344
0
    rState.nTotalPages  = nTotalPages;
345
0
    rState.nPageStart   = nPageStart;
346
0
    rState.nDocPages    = nDocPages;
347
0
    rState.m_aRanges = m_aRanges;
348
0
}
349
350
bool ScPrintFunc::GetLastSourceRange( ScRange& rRange ) const
351
0
{
352
0
    rRange = aLastSourceRange;
353
0
    return bSourceRangeValid;
354
0
}
355
356
void ScPrintFunc::FillPageData()
357
0
{
358
0
    if (!pPageData)
359
0
        return;
360
361
0
    sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() );
362
0
    ScPrintRangeData& rData = pPageData->GetData(nCount);       // count up
363
364
0
    assert( bPrintAreaValid );
365
0
    rData.SetPrintRange( ScRange( nStartCol, nStartRow, nPrintTab,
366
0
                                    nEndCol, nEndRow, nPrintTab ) );
367
    // #i123672#
368
0
    if(m_aRanges.m_xPageEndX->empty())
369
0
    {
370
0
        OSL_ENSURE(false, "vector access error for maPageEndX (!)");
371
0
    }
372
0
    else
373
0
    {
374
0
        rData.SetPagesX( m_aRanges.m_nPagesX, m_aRanges.m_xPageEndX->data());
375
0
    }
376
377
    // #i123672#
378
0
    if(m_aRanges.m_xPageEndY->empty())
379
0
    {
380
0
        OSL_ENSURE(false, "vector access error for maPageEndY (!)");
381
0
    }
382
0
    else
383
0
    {
384
0
        rData.SetPagesY( m_aRanges.m_nTotalY, m_aRanges.m_xPageEndY->data());
385
0
    }
386
387
    //  Settings
388
0
    rData.SetTopDown( aTableParam.bTopDown );
389
0
    rData.SetAutomatic( !aAreaParam.bPrintArea );
390
0
}
391
392
ScPrintFunc::~ScPrintFunc()
393
43.0k
{
394
43.0k
    pEditDefaults.reset();
395
43.0k
    pEditEngine.reset();
396
397
    //  Printer settings are now restored from outside
398
399
    //  For DrawingLayer/Charts, the MapMode of the printer (RefDevice) must always be correct
400
43.0k
    SfxPrinter* pDocPrinter = rDoc.GetPrinter();   // use Preview also for the printer
401
43.0k
    if (pDocPrinter)
402
43.0k
        pDocPrinter->SetMapMode(aOldPrinterMode);
403
43.0k
}
404
405
void ScPrintFunc::SetDrawView( FmFormView* pNew )
406
0
{
407
0
    pDrawView = pNew;
408
0
}
409
410
static void lcl_HidePrint( const ScTableInfo& rTabInfo, SCCOL nX1, SCCOL nX2 )
411
0
{
412
0
    for (SCSIZE nArrY=1; nArrY+1<rTabInfo.mnArrCount; nArrY++)
413
0
    {
414
0
        RowInfo* pThisRowInfo = &rTabInfo.mpRowInfo[nArrY];
415
0
        for (SCCOL nX=nX1; nX<=nX2; nX++)
416
0
        {
417
0
            ScCellInfo& rCellInfo = pThisRowInfo->cellInfo(nX);
418
0
            ScBasicCellInfo& rBasicCellInfo = pThisRowInfo->basicCellInfo(nX);
419
0
            if (!rBasicCellInfo.bEmptyCellText)
420
0
                if (rCellInfo.pPatternAttr->
421
0
                            GetItem(ATTR_PROTECTION, rCellInfo.pConditionSet).GetHidePrint())
422
0
                {
423
0
                    rCellInfo.maCell.clear();
424
0
                    rBasicCellInfo.bEmptyCellText = true;
425
0
                }
426
0
        }
427
0
    }
428
0
}
429
430
//      output to Device (static)
431
//
432
//      is used for:
433
//      -   Clipboard/Bitmap
434
//      -   Ole-Object (DocShell::Draw)
435
//      -   Preview of templates
436
437
void ScPrintFunc::DrawToDev(ScDocument& rDoc, OutputDevice* pDev, double /* nPrintFactor */,
438
                            const tools::Rectangle& rBound, ScViewData& rViewData, bool bMetaFile)
439
0
{
440
0
    if (rDoc.GetMaxTableNumber() < 0)
441
0
        return;
442
443
    //! evaluate nPrintFactor !!!
444
445
0
    SCTAB nTab = rViewData.CurrentTabForData();
446
447
0
    bool bDoGrid, bNullVal, bFormula;
448
0
    ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
449
0
    SfxStyleSheetBase* pStyleSheet = pStylePool->Find( rDoc.GetPageStyle( nTab ), SfxStyleFamily::Page );
450
0
    if (pStyleSheet)
451
0
    {
452
0
        SfxItemSet& rSet = pStyleSheet->GetItemSet();
453
0
        bDoGrid  = rSet.Get(ATTR_PAGE_GRID).GetValue();
454
0
        bNullVal = rSet.Get(ATTR_PAGE_NULLVALS).GetValue();
455
0
        bFormula = rSet.Get(ATTR_PAGE_FORMULAS).GetValue();
456
0
    }
457
0
    else
458
0
    {
459
0
        const ScViewOptions& rOpt = rDoc.GetViewOptions();
460
0
        bDoGrid  = rOpt.GetOption(sc::ViewOption::GRID);
461
0
        bNullVal = rOpt.GetOption(sc::ViewOption::NULLVALS);
462
0
        bFormula = rOpt.GetOption(sc::ViewOption::FORMULAS);
463
0
    }
464
465
0
    MapMode aMode = pDev->GetMapMode();
466
467
0
    tools::Rectangle aRect = rBound;
468
469
0
    if (aRect.Right() < aRect.Left() || aRect.Bottom() < aRect.Top())
470
0
        aRect = tools::Rectangle( Point(), pDev->GetOutputSize() );
471
472
0
    SCCOL nX1 = 0;
473
0
    SCROW nY1 = 0;
474
0
    SCCOL nX2 = OLE_STD_CELLS_X - 1;
475
0
    SCROW nY2 = OLE_STD_CELLS_Y - 1;
476
0
    if (bMetaFile)
477
0
    {
478
0
        ScRange aRange = rDoc.GetRange( nTab, rBound );
479
0
        nX1 = aRange.aStart.Col();
480
0
        nY1 = aRange.aStart.Row();
481
0
        nX2 = aRange.aEnd.Col();
482
0
        nY2 = aRange.aEnd.Row();
483
0
    }
484
0
    else
485
0
    {
486
0
        ScSplitPos eWhich = rViewData.GetActivePart();
487
0
        ScHSplitPos eHWhich = WhichH(eWhich);
488
0
        ScVSplitPos eVWhich = WhichV(eWhich);
489
0
        nX1 = rViewData.GetPosX(eHWhich);
490
0
        nY1 = rViewData.GetPosY(eVWhich);
491
0
        nX2 = nX1 + rViewData.VisibleCellsX(eHWhich);
492
0
        if (nX2>nX1) --nX2;
493
0
        nY2 = nY1 + rViewData.VisibleCellsY(eVWhich);
494
0
        if (nY2>nY1) --nY2;
495
0
    }
496
497
0
    if (nX1 > rDoc.MaxCol()) nX1 = rDoc.MaxCol();
498
0
    if (nX2 > rDoc.MaxCol()) nX2 = rDoc.MaxCol();
499
0
    if (nY1 > rDoc.MaxRow()) nY1 = rDoc.MaxRow();
500
0
    if (nY2 > rDoc.MaxRow()) nY2 = rDoc.MaxRow();
501
502
0
    tools::Long nDevSizeX = aRect.Right()-aRect.Left()+1;
503
0
    tools::Long nDevSizeY = aRect.Bottom()-aRect.Top()+1;
504
505
0
    tools::Long nTwipsSizeX = 0;
506
0
    for (SCCOL i=nX1; i<=nX2; i++)
507
0
        nTwipsSizeX += rDoc.GetColWidth( i, nTab );
508
0
    tools::Long nTwipsSizeY = rDoc.GetRowHeight( nY1, nY2, nTab );
509
510
    //  if no lines, still space for the outline frame (20 Twips = 1pt)
511
    //  (HasLines initializes aLines to 0,0,0,0)
512
0
    nTwipsSizeX += 20;
513
0
    nTwipsSizeY += 20;
514
515
0
    double nScaleX = static_cast<double>(nDevSizeX) / nTwipsSizeX;
516
0
    double nScaleY = static_cast<double>(nDevSizeY) / nTwipsSizeY;
517
518
                            //!     hand over Flag at FillInfo !!!!!
519
0
    ScRange aERange;
520
0
    bool bEmbed = rDoc.IsEmbedded();
521
0
    if (bEmbed)
522
0
    {
523
0
        rDoc.GetEmbedded(aERange);
524
0
        rDoc.ResetEmbedded();
525
0
    }
526
527
    //  Assemble data
528
529
0
    ScTableInfo aTabInfo(nY1, nY2, false);
530
0
    rDoc.FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
531
0
                   nScaleX, nScaleY, false, bFormula );
532
0
    lcl_HidePrint( aTabInfo, nX1, nX2 );
533
534
0
    if (bEmbed)
535
0
        rDoc.SetEmbedded(aERange);
536
537
0
    tools::Long nScrX = aRect.Left();
538
0
    tools::Long nScrY = aRect.Top();
539
540
    //  If no lines, still leave space for grid lines
541
    //  (would be elseways cut away)
542
    // tdf#135891 - adjust the x position to ensure the correct starting point
543
0
    const Size aOnePixel = pDev->PixelToLogic(Size(1, 1));
544
0
    nScrX += aOnePixel.Width();
545
0
    nScrY += 1;
546
547
0
    ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, &rDoc, nTab,
548
0
                                nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
549
0
    aOutputData.SetMetaFileMode(bMetaFile);
550
0
    aOutputData.SetShowNullValues(bNullVal);
551
0
    aOutputData.SetShowFormulas(bFormula);
552
553
0
    vcl::PDFExtOutDevData* pPDF = dynamic_cast<vcl::PDFExtOutDevData*>(pDev->GetExtOutDevData());
554
0
    bool bTaggedPDF = pPDF && pPDF->GetIsExportTaggedPDF();
555
0
    if (bTaggedPDF)
556
0
    {
557
0
        bool bReopen = aOutputData.ReopenPDFStructureElement(vcl::pdf::StructElement::Part);
558
0
        if (!bReopen)
559
0
        {
560
0
            sal_Int32 nId = pPDF->EnsureStructureElement(nullptr);
561
0
            pPDF->InitStructureElement(nId, vcl::pdf::StructElement::Part, u"Worksheet"_ustr);
562
0
            pPDF->BeginStructureElement(nId);
563
0
            pPDF->GetScPDFState()->m_WorksheetId = nId;
564
0
        }
565
0
    }
566
567
0
    ScDrawLayer* pModel = rDoc.GetDrawLayer();
568
0
    std::unique_ptr<FmFormView> pDrawView;
569
570
0
    if( pModel )
571
0
    {
572
0
        pDrawView.reset(
573
0
            new FmFormView(
574
0
                *pModel,
575
0
                pDev));
576
0
        pDrawView->ShowSdrPage(pDrawView->GetModel().GetPage(nTab));
577
0
        pDrawView->SetPrintPreview();
578
0
        aOutputData.SetDrawView( pDrawView.get() );
579
0
    }
580
581
    //! SetUseStyleColor ??
582
583
0
    if ( bMetaFile && pDev->IsVirtual() )
584
0
        aOutputData.SetSnapPixel();
585
586
0
    Point aLogStart = pDev->PixelToLogic(Point(nScrX, nScrY), MapMode(MapUnit::Map100thMM));
587
0
    tools::Long nLogStX = aLogStart.X();
588
0
    tools::Long nLogStY = aLogStart.Y();
589
590
    //!     nZoom for GetFont in OutputData ???
591
592
0
    if (!bMetaFile)
593
0
        pDev->SetMapMode(rViewData.GetLogicMode(rViewData.GetActivePart()));
594
595
    // #i72502#
596
0
    const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
597
0
    aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
598
599
0
    if (!bMetaFile)
600
0
        pDev->SetMapMode(aMode);
601
602
0
    aOutputData.DrawBackground(*pDev);
603
604
0
    aOutputData.DrawShadow();
605
0
    aOutputData.DrawFrame(*pDev);
606
0
    aOutputData.DrawSparklines(*pDev);
607
0
    aOutputData.DrawStrings();
608
609
0
    if (!bMetaFile)
610
0
        pDev->SetMapMode(rViewData.GetLogicMode(rViewData.GetActivePart()));
611
612
0
    aOutputData.DrawEdit(!bMetaFile);
613
614
0
    if (bDoGrid)
615
0
    {
616
0
        if (!bMetaFile)
617
0
            pDev->SetMapMode(aMode);
618
619
0
        aOutputData.DrawGrid(*pDev, true, false);    // no page breaks
620
621
0
        pDev->SetLineColor( COL_BLACK );
622
623
0
        Size aOne = pDev->PixelToLogic( Size(1,1) );
624
0
        if (bMetaFile)
625
0
            aOne = Size(1,1);   // compatible with DrawGrid
626
0
        tools::Long nRight = nScrX + aOutputData.GetScrW() - aOne.Width();
627
0
        tools::Long nBottom = nScrY + aOutputData.GetScrH() - aOne.Height();
628
629
0
        bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
630
631
        // extra line at the left edge for left-to-right, right for right-to-left
632
0
        if ( bLayoutRTL )
633
0
            pDev->DrawLine( Point(nRight,nScrY), Point(nRight,nBottom) );
634
0
        else
635
0
            pDev->DrawLine( Point(nScrX,nScrY), Point(nScrX,nBottom) );
636
        // extra line at the top in both cases
637
0
        pDev->DrawLine( Point(nScrX,nScrY), Point(nRight,nScrY) );
638
0
    }
639
640
    // #i72502#
641
0
    aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
642
643
0
    if (bTaggedPDF)
644
0
        pPDF->EndStructureElement();
645
646
0
    aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
647
0
    aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
648
0
}
649
650
//          Printing
651
652
static void lcl_FillHFParam( ScPrintHFParam& rParam, const SfxItemSet* pHFSet )
653
86.0k
{
654
    //  nDistance must be initialized differently before
655
86.0k
    if ( pHFSet == nullptr )
656
77.2k
    {
657
77.2k
        rParam.bEnable  = false;
658
77.2k
        rParam.pBorder  = nullptr;
659
77.2k
        rParam.pBack    = nullptr;
660
77.2k
        rParam.pShadow  = nullptr;
661
77.2k
    }
662
8.84k
    else
663
8.84k
    {
664
8.84k
        rParam.bEnable  = pHFSet->Get(ATTR_PAGE_ON).GetValue();
665
8.84k
        rParam.bDynamic = pHFSet->Get(ATTR_PAGE_DYNAMIC).GetValue();
666
8.84k
        rParam.bShared  = pHFSet->Get(ATTR_PAGE_SHARED).GetValue();
667
8.84k
        rParam.bSharedFirst = pHFSet->Get(ATTR_PAGE_SHARED_FIRST).GetValue();
668
8.84k
        rParam.nHeight  = pHFSet->Get(ATTR_PAGE_SIZE).GetSize().Height();
669
8.84k
        const SvxLRSpaceItem* pHFLR = &pHFSet->Get(ATTR_LRSPACE);
670
8.84k
        tools::Long nTmp;
671
8.84k
        nTmp = pHFLR->ResolveLeft();
672
8.84k
        rParam.nLeft = nTmp < 0 ? 0 : sal_uInt16(nTmp);
673
8.84k
        nTmp = pHFLR->ResolveRight({});
674
8.84k
        rParam.nRight = nTmp < 0 ? 0 : sal_uInt16(nTmp);
675
8.84k
        rParam.pBorder  = &pHFSet->Get(ATTR_BORDER);
676
8.84k
        rParam.pBack    = &pHFSet->Get(ATTR_BACKGROUND);
677
8.84k
        rParam.pShadow  = &pHFSet->Get(ATTR_SHADOW);
678
679
//   now back in the dialog:
680
//      rParam.nHeight += rParam.nDistance;             // not in the dialog any more ???
681
682
8.84k
        rParam.nHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
683
8.84k
                          lcl_LineTotal( rParam.pBorder->GetBottom() );
684
685
8.84k
        rParam.nManHeight = rParam.nHeight;
686
8.84k
    }
687
688
86.0k
    if (!rParam.bEnable)
689
77.2k
        rParam.nHeight = 0;
690
86.0k
}
691
692
//  bNew = TRUE:    search for used part of the document
693
//  bNew = FALSE:   only limit whole lines/columns
694
695
bool ScPrintFunc::AdjustPrintArea( bool bNew )
696
84.1k
{
697
84.1k
    SCCOL nOldEndCol = nEndCol; // only important for !bNew
698
84.1k
    SCROW nOldEndRow = nEndRow;
699
84.1k
    bool bChangeCol = true;     // at bNew both are being adjusted
700
84.1k
    bool bChangeRow = true;
701
702
84.1k
    bool bNotes = aTableParam.bNotes;
703
84.1k
    if ( bNew )
704
41.9k
    {
705
41.9k
        nStartCol = 0;
706
41.9k
        nStartRow = 0;
707
41.9k
        if (!rDoc.GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes ) && aTableParam.bSkipEmpty)
708
0
            return false;   // nothing
709
41.9k
        bPrintAreaValid = true;
710
41.9k
    }
711
42.1k
    else
712
42.1k
    {
713
42.1k
        bool bFound = true;
714
42.1k
        bChangeCol = ( nStartCol == 0 && nEndCol == rDoc.MaxCol() );
715
42.1k
        bChangeRow = ( nStartRow == 0 && nEndRow == rDoc.MaxRow() );
716
42.1k
        bool bForcedChangeRow = false;
717
718
        // #i53558# Crop entire column of old row limit to real print area with
719
        // some fuzzyness.
720
42.1k
        if (!bChangeRow && nStartRow == 0)
721
41.9k
        {
722
41.9k
            SCROW nPAEndRow;
723
41.9k
            bFound = rDoc.GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nPAEndRow, bNotes );
724
            // Say we don't want to print more than ~1000 empty rows, which are
725
            // about 14 pages intentionally left blank...
726
41.9k
            const SCROW nFuzzy = 23*42;
727
41.9k
            if (nPAEndRow + nFuzzy < nEndRow)
728
0
            {
729
0
                bForcedChangeRow = true;
730
0
                nEndRow = nPAEndRow;
731
0
            }
732
41.9k
            else
733
41.9k
                bFound = true;  // user seems to _want_ to print some empty rows
734
41.9k
        }
735
        // TODO: in case we extend the number of columns we may have to do the
736
        // same for horizontal cropping.
737
738
42.1k
        if ( bChangeCol && bChangeRow )
739
0
            bFound = rDoc.GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes );
740
42.1k
        else if ( bChangeCol )
741
0
            bFound = rDoc.GetPrintAreaHor( nPrintTab, nStartRow, nEndRow, nEndCol );
742
42.1k
        else if ( bChangeRow )
743
25
            bFound = rDoc.GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nEndRow, bNotes );
744
745
42.1k
        if (!bFound)
746
25
            return false;   // empty
747
748
42.1k
        bPrintAreaValid = true;
749
42.1k
        if (bForcedChangeRow)
750
0
            bChangeRow = true;
751
42.1k
    }
752
753
84.1k
    assert( bPrintAreaValid );
754
84.0k
    rDoc.ExtendMerge( nStartCol,nStartRow, nEndCol,nEndRow, nPrintTab );  // no Refresh, incl. Attrs
755
756
84.0k
    if ( bChangeCol )
757
41.9k
    {
758
41.9k
        OutputDevice* pRefDev = rDoc.GetPrinter();       // use the printer also for Preview
759
41.9k
        pRefDev->SetMapMode(MapMode(MapUnit::MapPixel)); // important for GetNeededSize
760
761
41.9k
        rDoc.ExtendPrintArea( pRefDev,
762
41.9k
                            nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow );
763
        // changing nEndCol
764
41.9k
    }
765
766
84.0k
    if ( nEndCol < rDoc.MaxCol() && rDoc.HasAttrib(
767
84.0k
                    nEndCol,nStartRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HasAttrFlags::ShadowRight ) )
768
0
        ++nEndCol;
769
84.0k
    if ( nEndRow < rDoc.MaxRow() && rDoc.HasAttrib(
770
84.0k
                    nStartCol,nEndRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HasAttrFlags::ShadowDown ) )
771
0
        ++nEndRow;
772
773
84.0k
    if (!bChangeCol) nEndCol = nOldEndCol;
774
84.0k
    if (!bChangeRow) nEndRow = nOldEndRow;
775
776
84.0k
    return true;
777
84.1k
}
778
779
tools::Long ScPrintFunc::TextHeight( const EditTextObject* pObject )
780
267k
{
781
267k
    if (!pObject)
782
109k
        return 0;
783
784
157k
    pEditEngine->SetTextTempDefaults(*pObject, *pEditDefaults);
785
786
157k
    return static_cast<tools::Long>(pEditEngine->GetTextHeight());
787
267k
}
788
789
//  nZoom must be set !!!
790
//  and the respective Twip-MapMode configured
791
void ScPrintFunc::UpdateHFHeight( ScPrintHFParam& rParam )
792
192k
{
793
192k
    OSL_ENSURE( aPageSize.Width(), "UpdateHFHeight without aPageSize");
794
795
192k
    if (!(rParam.bEnable && rParam.bDynamic))
796
162k
        return;
797
798
    //  calculate nHeight from content
799
29.7k
    MakeEditEngine();
800
29.7k
    tools::Long nPaperWidth = ( aPageSize.Width() - nLeftMargin - nRightMargin -
801
29.7k
                            rParam.nLeft - rParam.nRight ) * 100 / nZoom;
802
29.7k
    if (rParam.pBorder)
803
29.7k
        nPaperWidth -= ( rParam.pBorder->GetDistance(SvxBoxItemLine::LEFT) +
804
29.7k
                         rParam.pBorder->GetDistance(SvxBoxItemLine::RIGHT) +
805
29.7k
                         lcl_LineTotal(rParam.pBorder->GetLeft()) +
806
29.7k
                         lcl_LineTotal(rParam.pBorder->GetRight()) ) * 100 / nZoom;
807
808
29.7k
    if (rParam.pShadow && rParam.pShadow->GetLocation() != SvxShadowLocation::NONE)
809
0
        nPaperWidth -= ( rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::LEFT) +
810
0
                         rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::RIGHT) ) * 100 / nZoom;
811
812
29.7k
    if (nPaperWidth <= 0)
813
6
    {
814
6
        SAL_WARN("sc.ui", "Header/Footer unreasonably narrow width of: " << nPaperWidth << ", cannot calculate height");
815
6
        return;
816
6
    }
817
818
29.7k
    pEditEngine->SetPaperSize( Size( nPaperWidth, 10000 ) );
819
820
29.7k
    tools::Long nMaxHeight = 0;
821
29.7k
    if ( rParam.pLeft )
822
29.7k
    {
823
29.7k
        nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetLeftArea() ) );
824
29.7k
        nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetCenterArea() ) );
825
29.7k
        nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetRightArea() ) );
826
29.7k
    }
827
29.7k
    if ( rParam.pRight )
828
29.7k
    {
829
29.7k
        nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetLeftArea() ) );
830
29.7k
        nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetCenterArea() ) );
831
29.7k
        nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetRightArea() ) );
832
29.7k
    }
833
29.7k
    if ( rParam.pFirst )
834
29.7k
    {
835
29.7k
        nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pFirst->GetLeftArea() ) );
836
29.7k
        nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pFirst->GetCenterArea() ) );
837
29.7k
        nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pFirst->GetRightArea() ) );
838
29.7k
    }
839
840
29.7k
    rParam.nHeight = nMaxHeight + rParam.nDistance;
841
29.7k
    if (rParam.pBorder)
842
29.7k
        rParam.nHeight += rParam.pBorder->GetDistance(SvxBoxItemLine::TOP) +
843
29.7k
                          rParam.pBorder->GetDistance(SvxBoxItemLine::BOTTOM) +
844
29.7k
                          lcl_LineTotal( rParam.pBorder->GetTop() ) +
845
29.7k
                          lcl_LineTotal( rParam.pBorder->GetBottom() );
846
29.7k
    if (rParam.pShadow && rParam.pShadow->GetLocation() != SvxShadowLocation::NONE)
847
0
        rParam.nHeight += rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::TOP) +
848
0
                          rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::BOTTOM);
849
850
29.7k
    if (rParam.nHeight < rParam.nManHeight)
851
27.6k
        rParam.nHeight = rParam.nManHeight;         // configured minimum
852
29.7k
}
853
854
void ScPrintFunc::InitParam( const ScPrintOptions* pOptions )
855
43.0k
{
856
43.0k
    if (!pParamSet)
857
0
        return;
858
859
    // TabPage "Page"
860
43.0k
    const SvxLRSpaceItem* pLRItem = &pParamSet->Get( ATTR_LRSPACE );
861
43.0k
    tools::Long nTmp;
862
43.0k
    nTmp = pLRItem->ResolveLeft();
863
43.0k
    nLeftMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
864
43.0k
    nTmp = pLRItem->ResolveRight({});
865
43.0k
    nRightMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
866
43.0k
    const SvxULSpaceItem* pULItem = &pParamSet->Get( ATTR_ULSPACE );
867
43.0k
    nTopMargin    = pULItem->GetUpper();
868
43.0k
    nBottomMargin = pULItem->GetLower();
869
870
43.0k
    const SvxPageItem* pPageItem = &pParamSet->Get( ATTR_PAGE );
871
43.0k
    nPageUsage          = pPageItem->GetPageUsage();
872
43.0k
    bLandscape          = bUsePrintDialogSetting ? bPrintPageLandscape : pPageItem->IsLandscape();
873
43.0k
    aFieldData.eNumType = pPageItem->GetNumType();
874
875
43.0k
    bCenterHor = pParamSet->Get(ATTR_PAGE_HORCENTER).GetValue();
876
43.0k
    bCenterVer = pParamSet->Get(ATTR_PAGE_VERCENTER).GetValue();
877
878
43.0k
    aPageSize = bUsePrintDialogSetting ? aPrintPageSize : pParamSet->Get(ATTR_PAGE_SIZE).GetSize();
879
43.0k
    if ( !aPageSize.Width() || !aPageSize.Height() )
880
0
    {
881
0
        OSL_FAIL("PageSize Null ?!?!?");
882
0
        aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
883
0
    }
884
885
43.0k
    pBorderItem     = &pParamSet->Get(ATTR_BORDER);
886
43.0k
    pBackgroundItem = &pParamSet->Get(ATTR_BACKGROUND);
887
43.0k
    pShadowItem     = &pParamSet->Get(ATTR_SHADOW);
888
889
                                // TabPage "Headline"
890
891
43.0k
    aHdr.pLeft      = &pParamSet->Get(ATTR_PAGE_HEADERLEFT);      // Content
892
43.0k
    aHdr.pRight     = &pParamSet->Get(ATTR_PAGE_HEADERRIGHT);
893
43.0k
    aHdr.pFirst     = &pParamSet->Get(ATTR_PAGE_HEADERFIRST);
894
895
43.0k
    const SfxItemSet* pHeaderSet = nullptr;
896
43.0k
    if ( const SvxSetItem* pHeaderSetItem = pParamSet->GetItemIfSet( ATTR_PAGE_HEADERSET, false ) )
897
3.92k
    {
898
3.92k
        pHeaderSet = &pHeaderSetItem->GetItemSet();
899
                                                        // Headline has space below
900
3.92k
        aHdr.nDistance  = pHeaderSet->Get(ATTR_ULSPACE).GetLower();
901
3.92k
    }
902
43.0k
    lcl_FillHFParam( aHdr, pHeaderSet );
903
904
                                // TabPage "Footline"
905
906
43.0k
    aFtr.pLeft      = &pParamSet->Get(ATTR_PAGE_FOOTERLEFT);      // Content
907
43.0k
    aFtr.pRight     = &pParamSet->Get(ATTR_PAGE_FOOTERRIGHT);
908
43.0k
    aFtr.pFirst     = &pParamSet->Get(ATTR_PAGE_FOOTERFIRST);
909
910
43.0k
    const SfxItemSet* pFooterSet = nullptr;
911
43.0k
    if ( const SvxSetItem* pFooterSetItem = pParamSet->GetItemIfSet( ATTR_PAGE_FOOTERSET, false ) )
912
4.91k
    {
913
4.91k
        pFooterSet = &pFooterSetItem->GetItemSet();
914
                                                        // Footline has space above
915
4.91k
        aFtr.nDistance  = pFooterSet->Get(ATTR_ULSPACE).GetUpper();
916
4.91k
    }
917
43.0k
    lcl_FillHFParam( aFtr, pFooterSet );
918
919
    // Compile Table-/Area-Params from single Items
920
921
    // TabPage "Table"
922
923
43.0k
    const SfxUInt16Item*     pScaleItem          = nullptr;
924
43.0k
    const ScPageScaleToItem* pScaleToItem        = nullptr;
925
43.0k
    const SfxUInt16Item*     pScaleToPagesItem   = nullptr;
926
43.0k
    SfxItemState             eState;
927
928
43.0k
    eState = pParamSet->GetItemState( ATTR_PAGE_SCALE, false,
929
43.0k
                                      reinterpret_cast<const SfxPoolItem**>(&pScaleItem) );
930
43.0k
    if ( SfxItemState::DEFAULT == eState )
931
43.0k
        pScaleItem = &pParamSet->GetPool()->GetUserOrPoolDefaultItem( ATTR_PAGE_SCALE );
932
933
43.0k
    eState = pParamSet->GetItemState( ATTR_PAGE_SCALETO, false,
934
43.0k
                                      reinterpret_cast<const SfxPoolItem**>(&pScaleToItem) );
935
43.0k
    if ( SfxItemState::DEFAULT == eState )
936
43.0k
        pScaleToItem = &pParamSet->GetPool()->GetUserOrPoolDefaultItem( ATTR_PAGE_SCALETO );
937
938
43.0k
    eState = pParamSet->GetItemState( ATTR_PAGE_SCALETOPAGES, false,
939
43.0k
                                      reinterpret_cast<const SfxPoolItem**>(&pScaleToPagesItem) );
940
43.0k
    if ( SfxItemState::DEFAULT == eState )
941
43.0k
        pScaleToPagesItem = &pParamSet->GetPool()->GetUserOrPoolDefaultItem( ATTR_PAGE_SCALETOPAGES );
942
943
43.0k
    OSL_ENSURE( pScaleItem && pScaleToItem && pScaleToPagesItem, "Missing ScaleItem! :-/" );
944
945
43.0k
    aTableParam.bCellContent    = true;
946
43.0k
    aTableParam.bNotes          = lcl_GetBool(pParamSet,ATTR_PAGE_NOTES);
947
43.0k
    aTableParam.bGrid           = lcl_GetBool(pParamSet,ATTR_PAGE_GRID);
948
43.0k
    aTableParam.bHeaders        = lcl_GetBool(pParamSet,ATTR_PAGE_HEADERS);
949
43.0k
    aTableParam.bFormulas       = lcl_GetBool(pParamSet,ATTR_PAGE_FORMULAS);
950
43.0k
    aTableParam.bNullVals       = lcl_GetBool(pParamSet,ATTR_PAGE_NULLVALS);
951
43.0k
    aTableParam.bCharts         = lcl_GetShow(pParamSet,ATTR_PAGE_CHARTS);
952
43.0k
    aTableParam.bObjects        = lcl_GetShow(pParamSet,ATTR_PAGE_OBJECTS);
953
43.0k
    aTableParam.bDrawings       = lcl_GetShow(pParamSet,ATTR_PAGE_DRAWINGS);
954
43.0k
    aTableParam.bTopDown        = lcl_GetBool(pParamSet,ATTR_PAGE_TOPDOWN);
955
43.0k
    aTableParam.bLeftRight      = !aTableParam.bLeftRight;
956
43.0k
    aTableParam.nFirstPageNo    = lcl_GetUShort(pParamSet,ATTR_PAGE_FIRSTPAGENO);
957
43.0k
    if (!aTableParam.nFirstPageNo)
958
137
        aTableParam.nFirstPageNo = static_cast<sal_uInt16>(nPageStart);     // from previous table
959
960
43.0k
    if ( pScaleItem && pScaleToItem && pScaleToPagesItem )
961
43.0k
    {
962
43.0k
        sal_uInt16  nScaleAll     = pScaleItem->GetValue();
963
43.0k
        sal_uInt16  nScaleToPages = pScaleToPagesItem->GetValue();
964
965
43.0k
        aTableParam.bScaleNone      = (nScaleAll     == 100);
966
43.0k
        aTableParam.bScaleAll       = (nScaleAll      > 0  );
967
43.0k
        aTableParam.bScaleTo        = pScaleToItem->IsValid();
968
43.0k
        aTableParam.bScalePageNum   = (nScaleToPages  > 0  );
969
43.0k
        aTableParam.nScaleAll       = nScaleAll;
970
43.0k
        aTableParam.nScaleWidth     = pScaleToItem->GetWidth();
971
43.0k
        aTableParam.nScaleHeight    = pScaleToItem->GetHeight();
972
43.0k
        aTableParam.nScalePageNum   = nScaleToPages;
973
43.0k
    }
974
0
    else
975
0
    {
976
0
        aTableParam.bScaleNone      = true;
977
0
        aTableParam.bScaleAll       = false;
978
0
        aTableParam.bScaleTo        = false;
979
0
        aTableParam.bScalePageNum   = false;
980
0
        aTableParam.nScaleAll       = 0;
981
0
        aTableParam.nScaleWidth     = 0;
982
0
        aTableParam.nScaleHeight    = 0;
983
0
        aTableParam.nScalePageNum   = 0;
984
0
    }
985
986
    //  skip empty pages only if options with that flag are passed
987
43.0k
    aTableParam.bSkipEmpty = pOptions && pOptions->GetSkipEmpty();
988
43.0k
    if ( pPageData )
989
0
        aTableParam.bSkipEmpty = false;
990
    // If pPageData is set, only the breaks are interesting for the
991
    // pagebreak preview, empty pages are not addressed separately.
992
993
43.0k
    aTableParam.bForceBreaks = pOptions && pOptions->GetForceBreaks();
994
995
    // TabPage "Parts":
996
997
    //! walk through all PrintAreas of the table !!!
998
43.0k
    const ScRange*  pPrintArea = rDoc.GetPrintRange( nPrintTab, 0 );
999
43.0k
    std::optional<ScRange> oRepeatCol = rDoc.GetRepeatColRange( nPrintTab );
1000
43.0k
    std::optional<ScRange> oRepeatRow = rDoc.GetRepeatRowRange( nPrintTab );
1001
1002
    //  ignoring ATTR_PAGE_PRINTTABLES
1003
1004
43.0k
    bool bHasPrintRange = rDoc.HasPrintRange();
1005
43.0k
    sal_uInt16 nPrintRangeCount = rDoc.GetPrintRangeCount(nPrintTab);
1006
43.0k
    bool bPrintEntireSheet = rDoc.IsPrintEntireSheet(nPrintTab);
1007
1008
43.0k
    if (!bPrintEntireSheet && !nPrintRangeCount)
1009
1.09k
        mbHasPrintRange = false;
1010
1011
43.0k
    if ( pUserArea )                                    // UserArea (selection) has priority
1012
0
    {
1013
0
        bPrintCurrentTable    =
1014
0
        aAreaParam.bPrintArea = true;                   // Selection
1015
0
        aAreaParam.aPrintArea = *pUserArea;
1016
1017
        //  The table-query is already in DocShell::Print, here always
1018
0
        aAreaParam.aPrintArea.aStart.SetTab(nPrintTab);
1019
0
        aAreaParam.aPrintArea.aEnd.SetTab(nPrintTab);
1020
0
    }
1021
43.0k
    else if (bHasPrintRange)
1022
42.9k
    {
1023
42.9k
        if ( pPrintArea )                               // at least one set?
1024
119
        {
1025
119
            bPrintCurrentTable    =
1026
119
            aAreaParam.bPrintArea = true;
1027
119
            aAreaParam.aPrintArea = *pPrintArea;
1028
1029
119
            bMultiArea = nPrintRangeCount > 1;
1030
119
        }
1031
42.7k
        else
1032
42.7k
        {
1033
            // do not print hidden sheets with "Print entire sheet" flag
1034
42.7k
            bPrintCurrentTable = rDoc.IsPrintEntireSheet( nPrintTab ) && rDoc.IsVisible( nPrintTab );
1035
42.7k
            aAreaParam.bPrintArea = !bPrintCurrentTable;    // otherwise the table is always counted
1036
42.7k
        }
1037
42.9k
    }
1038
128
    else
1039
128
    {
1040
        //  don't print hidden tables if there's no print range defined there
1041
128
        if ( rDoc.IsVisible( nPrintTab ) )
1042
128
        {
1043
128
            aAreaParam.bPrintArea = false;
1044
128
            bPrintCurrentTable = true;
1045
128
        }
1046
0
        else
1047
0
        {
1048
0
            aAreaParam.bPrintArea = true;   // otherwise the table is always counted
1049
0
            bPrintCurrentTable = false;
1050
0
        }
1051
128
    }
1052
1053
43.0k
    if ( oRepeatCol )
1054
311
    {
1055
311
        aAreaParam.bRepeatCol = true;
1056
311
        nRepeatStartCol = oRepeatCol->aStart.Col();
1057
311
        nRepeatEndCol   = oRepeatCol->aEnd  .Col();
1058
311
    }
1059
42.7k
    else
1060
42.7k
    {
1061
42.7k
        aAreaParam.bRepeatCol = false;
1062
42.7k
        nRepeatStartCol = nRepeatEndCol = SCCOL_REPEAT_NONE;
1063
42.7k
    }
1064
1065
43.0k
    if ( oRepeatRow )
1066
833
    {
1067
833
        aAreaParam.bRepeatRow = true;
1068
833
        nRepeatStartRow = oRepeatRow->aStart.Row();
1069
833
        nRepeatEndRow   = oRepeatRow->aEnd  .Row();
1070
833
    }
1071
42.2k
    else
1072
42.2k
    {
1073
42.2k
        aAreaParam.bRepeatRow = false;
1074
42.2k
        nRepeatStartRow = nRepeatEndRow = SCROW_REPEAT_NONE;
1075
42.2k
    }
1076
1077
            //  Split pages
1078
1079
43.0k
    if (!bPrintAreaValid)
1080
43.0k
    {
1081
43.0k
        nTabPages = CountPages();                                   // also calculates zoom
1082
43.0k
        nTotalPages = nTabPages;
1083
43.0k
        nTotalPages += CountNotePages();
1084
43.0k
    }
1085
0
    else
1086
0
    {
1087
0
        CalcPages();            // search breaks only
1088
0
        CountNotePages();       // Count notes, even if number of pages is already known
1089
0
    }
1090
1091
43.0k
    if (nDocPages)
1092
0
        aFieldData.nTotalPages = nDocPages;
1093
43.0k
    else
1094
43.0k
        aFieldData.nTotalPages = nTotalPages;
1095
1096
43.0k
    SetDateTime( DateTime( DateTime::SYSTEM ) );
1097
1098
43.0k
    if( rDocShell.getDocProperties()->getTitle().getLength() != 0 )
1099
0
        aFieldData.aTitle = rDocShell.getDocProperties()->getTitle();
1100
43.0k
    else
1101
43.0k
        aFieldData.aTitle = rDocShell.GetTitle();
1102
1103
43.0k
    const INetURLObject& rURLObj = rDocShell.GetMedium()->GetURLObject();
1104
1105
    // The doc names (long and short) are meant to be printed. They should be in human readable
1106
    // format, not with a URL encoding.
1107
43.0k
    aFieldData.aLongDocName = rURLObj.GetMainURL(INetURLObject::DecodeMechanism::WithCharset);
1108
43.0k
    if ( !aFieldData.aLongDocName.isEmpty() )
1109
0
        aFieldData.aShortDocName = rURLObj.GetLastName(INetURLObject::DecodeMechanism::WithCharset);
1110
43.0k
    else
1111
43.0k
        aFieldData.aShortDocName = aFieldData.aLongDocName = aFieldData.aTitle;
1112
1113
    //  Printer settings (Orientation, Paper) at DoPrint
1114
43.0k
}
1115
1116
Size ScPrintFunc::GetDataSize() const
1117
0
{
1118
0
    Size aSize = aPageSize;
1119
0
    aSize.AdjustWidth( -(nLeftMargin + nRightMargin) );
1120
0
    aSize.AdjustHeight( -(nTopMargin + nBottomMargin) );
1121
0
    aSize.AdjustHeight( -(aHdr.nHeight + aFtr.nHeight) );
1122
0
    return aSize;
1123
0
}
1124
1125
void ScPrintFunc::GetScaleData( Size& rPhysSize, tools::Long& rDocHdr, tools::Long& rDocFtr )
1126
0
{
1127
0
    rPhysSize = aPageSize;
1128
0
    rPhysSize.AdjustWidth( -(nLeftMargin + nRightMargin) );
1129
0
    rPhysSize.AdjustHeight( -(nTopMargin + nBottomMargin) );
1130
1131
0
    rDocHdr = aHdr.nHeight;
1132
0
    rDocFtr = aFtr.nHeight;
1133
0
}
1134
1135
void ScPrintFunc::SetDateTime( const DateTime& rDateTime )
1136
43.0k
{
1137
43.0k
    aFieldData.aDateTime = rDateTime;
1138
43.0k
}
1139
1140
static void lcl_DrawGraphic( const Graphic &rGraphic, vcl::RenderContext& rOutDev,
1141
                      const tools::Rectangle &rGrf, const tools::Rectangle &rOut )
1142
0
{
1143
0
    const bool bNotInside = !rOut.Contains( rGrf );
1144
0
    if ( bNotInside )
1145
0
    {
1146
0
        rOutDev.Push();
1147
0
        rOutDev.IntersectClipRegion( rOut );
1148
0
    }
1149
1150
0
    rGraphic.Draw(rOutDev, rGrf.TopLeft(), rGrf.GetSize());
1151
1152
0
    if ( bNotInside )
1153
0
        rOutDev.Pop();
1154
0
}
1155
1156
static void lcl_DrawGraphic( const SvxBrushItem &rBrush, vcl::RenderContext& rOutDev, const OutputDevice* pRefDev,
1157
                        const tools::Rectangle &rOrg, const tools::Rectangle &rOut,
1158
                        OUString const & referer )
1159
0
{
1160
0
    Size aGrfSize(0,0);
1161
0
    const Graphic *pGraphic = rBrush.GetGraphic(referer);
1162
0
    SvxGraphicPosition ePos;
1163
0
    if ( pGraphic && pGraphic->IsSupportedGraphic() )
1164
0
    {
1165
0
        const MapMode aMapMM( MapUnit::Map100thMM );
1166
0
        if ( pGraphic->GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel )
1167
0
            aGrfSize = pRefDev->PixelToLogic( pGraphic->GetPrefSize(), aMapMM );
1168
0
        else
1169
0
            aGrfSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
1170
0
                                    pGraphic->GetPrefMapMode(), aMapMM );
1171
0
        ePos = rBrush.GetGraphicPos();
1172
0
    }
1173
0
    else
1174
0
        ePos = GPOS_NONE;
1175
1176
0
    Point aPos;
1177
0
    Size aDrawSize = aGrfSize;
1178
1179
0
    bool bDraw = true;
1180
0
    switch ( ePos )
1181
0
    {
1182
0
        case GPOS_LT: aPos = rOrg.TopLeft();
1183
0
                      break;
1184
0
        case GPOS_MT: aPos.setY( rOrg.Top() );
1185
0
                      aPos.setX( rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2 );
1186
0
                      break;
1187
0
        case GPOS_RT: aPos.setY( rOrg.Top() );
1188
0
                      aPos.setX( rOrg.Right() - aGrfSize.Width() );
1189
0
                      break;
1190
1191
0
        case GPOS_LM: aPos.setY( rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2 );
1192
0
                      aPos.setX( rOrg.Left() );
1193
0
                      break;
1194
0
        case GPOS_MM: aPos.setY( rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2 );
1195
0
                      aPos.setX( rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2 );
1196
0
                      break;
1197
0
        case GPOS_RM: aPos.setY( rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2 );
1198
0
                      aPos.setX( rOrg.Right() - aGrfSize.Width() );
1199
0
                      break;
1200
1201
0
        case GPOS_LB: aPos.setY( rOrg.Bottom() - aGrfSize.Height() );
1202
0
                      aPos.setX( rOrg.Left() );
1203
0
                      break;
1204
0
        case GPOS_MB: aPos.setY( rOrg.Bottom() - aGrfSize.Height() );
1205
0
                      aPos.setX( rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2 );
1206
0
                      break;
1207
0
        case GPOS_RB: aPos.setY( rOrg.Bottom() - aGrfSize.Height() );
1208
0
                      aPos.setX( rOrg.Right() - aGrfSize.Width() );
1209
0
                      break;
1210
1211
0
        case GPOS_AREA:
1212
0
                      aPos = rOrg.TopLeft();
1213
0
                      aDrawSize = rOrg.GetSize();
1214
0
                      break;
1215
0
        case GPOS_TILED:
1216
0
                    {
1217
                        //  use GraphicObject::DrawTiled instead of an own loop
1218
                        //  (pixel rounding is handled correctly, and a very small bitmap
1219
                        //  is duplicated into a bigger one for better performance)
1220
1221
0
                        GraphicObject aObject( *pGraphic );
1222
1223
0
                        if( rOutDev.GetOutDevType() == OUTDEV_PDF &&
1224
0
                            (aObject.GetType() == GraphicType::Bitmap || aObject.GetType() == GraphicType::Default) )
1225
0
                        {
1226
                            // For PDF export, every draw
1227
                            // operation for bitmaps takes a noticeable
1228
                            // amount of place (~50 characters). Thus,
1229
                            // optimize between tile bitmap size and
1230
                            // number of drawing operations here.
1231
                            //
1232
                            //                  A_out
1233
                            // n_chars = k1 *  ---------- + k2 * A_bitmap
1234
                            //                  A_bitmap
1235
                            //
1236
                            // minimum n_chars is obtained for (derive for
1237
                            // A_bitmap, set to 0, take positive
1238
                            // solution):
1239
                            //                   k1
1240
                            // A_bitmap = Sqrt( ---- A_out )
1241
                            //                   k2
1242
                            //
1243
                            // where k1 is the number of chars per draw
1244
                            // operation, and k2 is the number of chars
1245
                            // per bitmap pixel. This is approximately 50
1246
                            // and 7 for current PDF writer, respectively.
1247
1248
0
                            const double    k1( 50 );
1249
0
                            const double    k2( 7 );
1250
0
                            const Size      aSize( rOrg.GetSize() );
1251
0
                            const double    Abitmap( k1/k2 * aSize.Width()*aSize.Height() );
1252
1253
0
                            aObject.DrawTiled( rOutDev, rOrg, aGrfSize, Size(0,0),
1254
0
                                               ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) );
1255
0
                        }
1256
0
                        else
1257
0
                        {
1258
0
                            aObject.DrawTiled( rOutDev, rOrg, aGrfSize, Size(0,0) );
1259
0
                        }
1260
1261
0
                        bDraw = false;
1262
0
                    }
1263
0
                    break;
1264
1265
0
        case GPOS_NONE:
1266
0
                      bDraw = false;
1267
0
                      break;
1268
1269
0
        default: OSL_ENSURE( false, "new Graphic position?" );
1270
0
    }
1271
0
    tools::Rectangle aGrf( aPos,aDrawSize );
1272
0
    if ( bDraw && aGrf.Overlaps( rOut ) )
1273
0
    {
1274
0
        lcl_DrawGraphic( *pGraphic, rOutDev, aGrf, rOut );
1275
0
    }
1276
0
}
1277
1278
// The frame is drawn inwards
1279
1280
void ScPrintFunc::DrawBorder( tools::Long nScrX, tools::Long nScrY, tools::Long nScrW, tools::Long nScrH,
1281
                                const SvxBoxItem* pBorderData, const SvxBrushItem* pBackground,
1282
                                const SvxShadowItem* pShadow )
1283
0
{
1284
    //!     direct output from SvxBoxItem !!!
1285
1286
0
    if (pBorderData)
1287
0
        if ( !pBorderData->GetTop() && !pBorderData->GetBottom() && !pBorderData->GetLeft() &&
1288
0
                                        !pBorderData->GetRight() )
1289
0
            pBorderData = nullptr;
1290
1291
0
    if (!pBorderData && !pBackground && !pShadow)
1292
0
        return;                                 // nothing to do
1293
1294
0
    tools::Long nLeft   = 0;
1295
0
    tools::Long nRight  = 0;
1296
0
    tools::Long nTop    = 0;
1297
0
    tools::Long nBottom = 0;
1298
1299
    //  aFrameRect - outside around frame, without shadow
1300
0
    if ( pShadow && pShadow->GetLocation() != SvxShadowLocation::NONE )
1301
0
    {
1302
0
        nLeft   += static_cast<tools::Long>( pShadow->CalcShadowSpace(SvxShadowItemSide::LEFT)   * nScaleX );
1303
0
        nRight  += static_cast<tools::Long>( pShadow->CalcShadowSpace(SvxShadowItemSide::RIGHT)  * nScaleX );
1304
0
        nTop    += static_cast<tools::Long>( pShadow->CalcShadowSpace(SvxShadowItemSide::TOP)    * nScaleY );
1305
0
        nBottom += static_cast<tools::Long>( pShadow->CalcShadowSpace(SvxShadowItemSide::BOTTOM) * nScaleY );
1306
0
    }
1307
0
    tools::Rectangle aFrameRect( Point(nScrX+nLeft, nScrY+nTop),
1308
0
                          Size(nScrW-nLeft-nRight, nScrH-nTop-nBottom) );
1309
1310
    //  center of frame, to paint lines through OutputData
1311
0
    if (pBorderData)
1312
0
    {
1313
0
        nLeft   += static_cast<tools::Long>( lcl_LineTotal(pBorderData->GetLeft())   * nScaleX / 2 );
1314
0
        nRight  += static_cast<tools::Long>( lcl_LineTotal(pBorderData->GetRight())  * nScaleX / 2 );
1315
0
        nTop    += static_cast<tools::Long>( lcl_LineTotal(pBorderData->GetTop())    * nScaleY / 2 );
1316
0
        nBottom += static_cast<tools::Long>( lcl_LineTotal(pBorderData->GetBottom()) * nScaleY / 2 );
1317
0
    }
1318
0
    tools::Long nEffHeight = nScrH - nTop - nBottom;
1319
0
    tools::Long nEffWidth = nScrW - nLeft - nRight;
1320
0
    if (nEffHeight<=0 || nEffWidth<=0)
1321
0
        return;                                 // empty
1322
1323
0
    if ( pBackground )
1324
0
    {
1325
0
        if (pBackground->GetGraphicPos() != GPOS_NONE)
1326
0
        {
1327
0
            OutputDevice* pRefDev;
1328
0
            if ( bIsRender )
1329
0
                pRefDev = pDev;                 // don't use printer for PDF
1330
0
            else
1331
0
                pRefDev = rDoc.GetPrinter();    // use printer also for preview
1332
0
            OUString referer;
1333
0
            if (rDocShell.HasName()) {
1334
0
                referer = rDocShell.GetMedium()->GetName();
1335
0
            }
1336
0
            lcl_DrawGraphic(*pBackground, *pDev, pRefDev, aFrameRect, aFrameRect, referer);
1337
0
        }
1338
0
        else
1339
0
        {
1340
0
            if (pBackground->GetColor() == COL_TRANSPARENT)
1341
0
                pDev->SetFillColor();
1342
0
            else
1343
0
                pDev->SetFillColor(pBackground->GetColor());
1344
0
            pDev->SetLineColor();
1345
0
            pDev->DrawRect(aFrameRect);
1346
0
        }
1347
0
    }
1348
1349
0
    if ( pShadow && pShadow->GetLocation() != SvxShadowLocation::NONE )
1350
0
    {
1351
0
        pDev->SetFillColor(pShadow->GetColor());
1352
0
        pDev->SetLineColor();
1353
0
        tools::Long nShadowX = static_cast<tools::Long>( pShadow->GetWidth() * nScaleX );
1354
0
        tools::Long nShadowY = static_cast<tools::Long>( pShadow->GetWidth() * nScaleY );
1355
0
        switch (pShadow->GetLocation())
1356
0
        {
1357
0
            case SvxShadowLocation::TopLeft:
1358
0
                pDev->DrawRect( tools::Rectangle(
1359
0
                        aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
1360
0
                        aFrameRect.Right()-nShadowX, aFrameRect.Top() ) );
1361
0
                pDev->DrawRect( tools::Rectangle(
1362
0
                        aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
1363
0
                        aFrameRect.Left(), aFrameRect.Bottom()-nShadowY ) );
1364
0
                break;
1365
0
            case SvxShadowLocation::TopRight:
1366
0
                pDev->DrawRect( tools::Rectangle(
1367
0
                        aFrameRect.Left()+nShadowX, aFrameRect.Top()-nShadowY,
1368
0
                        aFrameRect.Right()+nShadowX, aFrameRect.Top() ) );
1369
0
                pDev->DrawRect( tools::Rectangle(
1370
0
                        aFrameRect.Right(), aFrameRect.Top()-nShadowY,
1371
0
                        aFrameRect.Right()+nShadowX, aFrameRect.Bottom()-nShadowY ) );
1372
0
                break;
1373
0
            case SvxShadowLocation::BottomLeft:
1374
0
                pDev->DrawRect( tools::Rectangle(
1375
0
                        aFrameRect.Left()-nShadowX, aFrameRect.Bottom(),
1376
0
                        aFrameRect.Right()-nShadowX, aFrameRect.Bottom()+nShadowY ) );
1377
0
                pDev->DrawRect( tools::Rectangle(
1378
0
                        aFrameRect.Left()-nShadowX, aFrameRect.Top()+nShadowY,
1379
0
                        aFrameRect.Left(), aFrameRect.Bottom()+nShadowY ) );
1380
0
                break;
1381
0
            case SvxShadowLocation::BottomRight:
1382
0
                pDev->DrawRect( tools::Rectangle(
1383
0
                        aFrameRect.Left()+nShadowX, aFrameRect.Bottom(),
1384
0
                        aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
1385
0
                pDev->DrawRect( tools::Rectangle(
1386
0
                        aFrameRect.Right(), aFrameRect.Top()+nShadowY,
1387
0
                        aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
1388
0
                break;
1389
0
            default:
1390
0
            {
1391
                // added to avoid warnings
1392
0
            }
1393
0
        }
1394
0
    }
1395
1396
0
    if (!pBorderData)
1397
0
        return;
1398
1399
0
    ScDocumentUniquePtr pBorderDoc(new ScDocument( SCDOCMODE_UNDO ));
1400
0
    pBorderDoc->InitUndo( rDoc, 0,0, true,true );
1401
0
    pBorderDoc->ApplyAttr( 0,0,0, *pBorderData );
1402
1403
0
    ScTableInfo aTabInfo(0, 1, false);
1404
0
    pBorderDoc->FillInfo( aTabInfo, 0,0, 0,0, 0,
1405
0
                                        nScaleX, nScaleY, false, false );
1406
0
    OSL_ENSURE(aTabInfo.mnArrCount,"nArrCount == 0");
1407
1408
0
    aTabInfo.mpRowInfo[1].nHeight = static_cast<sal_uInt16>(nEffHeight);
1409
0
    aTabInfo.mpRowInfo[0].basicCellInfo(0).nWidth =
1410
0
        aTabInfo.mpRowInfo[1].basicCellInfo(0).nWidth = static_cast<sal_uInt16>(nEffWidth);
1411
1412
0
    ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pBorderDoc.get(), 0,
1413
0
                                nScrX+nLeft, nScrY+nTop, 0,0, 0,0, nScaleX, nScaleY );
1414
0
    aOutputData.SetUseStyleColor( bUseStyleColor );
1415
1416
0
    aOutputData.DrawFrame(*pDev);
1417
0
}
1418
1419
void ScPrintFunc::PrintColHdr( SCCOL nX1, SCCOL nX2, tools::Long nScrX, tools::Long nScrY )
1420
0
{
1421
0
    bool bLayoutRTL = rDoc.IsLayoutRTL( nPrintTab );
1422
0
    tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
1423
1424
0
    Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1425
0
    tools::Long nOneX = aOnePixel.Width();
1426
0
    tools::Long nOneY = aOnePixel.Height();
1427
0
    SCCOL nCol;
1428
1429
0
    tools::Long nHeight = static_cast<tools::Long>(PRINT_HEADER_HEIGHT * nScaleY);
1430
0
    tools::Long nEndY = nScrY + nHeight - nOneY;
1431
1432
0
    tools::Long nPosX = nScrX;
1433
0
    if ( bLayoutRTL )
1434
0
    {
1435
0
        for (nCol=nX1; nCol<=nX2; nCol++)
1436
0
            nPosX += static_cast<tools::Long>( rDoc.GetColWidth( nCol, nPrintTab ) * nScaleX );
1437
0
    }
1438
0
    else
1439
0
        nPosX -= nOneX;
1440
0
    tools::Long nPosY = nScrY - nOneY;
1441
0
    OUString aText;
1442
1443
0
    for (nCol=nX1; nCol<=nX2; nCol++)
1444
0
    {
1445
0
        sal_uInt16 nDocW = rDoc.GetColWidth( nCol, nPrintTab );
1446
0
        if (nDocW)
1447
0
        {
1448
0
            tools::Long nWidth = static_cast<tools::Long>(nDocW * nScaleX);
1449
0
            tools::Long nEndX = nPosX + nWidth * nLayoutSign;
1450
1451
0
            pDev->DrawRect( tools::Rectangle( nPosX,nPosY,nEndX,nEndY ) );
1452
1453
0
            aText = ::ScColToAlpha( nCol);
1454
0
            tools::Long nTextWidth = pDev->GetTextWidth(aText);
1455
0
            tools::Long nTextHeight = pDev->GetTextHeight();
1456
0
            tools::Long nAddX = ( nWidth  - nTextWidth  ) / 2;
1457
0
            tools::Long nAddY = ( nHeight - nTextHeight ) / 2;
1458
0
            tools::Long nTextPosX = nPosX+nAddX;
1459
0
            if ( bLayoutRTL )
1460
0
                nTextPosX -= nWidth;
1461
0
            pDev->DrawText( Point( nTextPosX,nPosY+nAddY ), aText );
1462
1463
0
            nPosX = nEndX;
1464
0
        }
1465
0
    }
1466
0
}
1467
1468
void ScPrintFunc::PrintRowHdr( SCROW nY1, SCROW nY2, tools::Long nScrX, tools::Long nScrY )
1469
0
{
1470
0
    Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1471
0
    tools::Long nOneX = aOnePixel.Width();
1472
0
    tools::Long nOneY = aOnePixel.Height();
1473
1474
0
    bool bLayoutRTL = rDoc.IsLayoutRTL( nPrintTab );
1475
1476
0
    tools::Long nWidth = static_cast<tools::Long>(PRINT_HEADER_WIDTH * nScaleX);
1477
0
    tools::Long nEndX = nScrX + nWidth;
1478
0
    tools::Long nPosX = nScrX;
1479
0
    if ( !bLayoutRTL )
1480
0
    {
1481
0
        nEndX -= nOneX;
1482
0
        nPosX -= nOneX;
1483
0
    }
1484
0
    tools::Long nPosY = nScrY - nOneY;
1485
0
    OUString aText;
1486
1487
0
    for (SCROW nRow=nY1; nRow<=nY2; nRow++)
1488
0
    {
1489
0
        sal_uInt16 nDocH = rDoc.GetRowHeight( nRow, nPrintTab );
1490
0
        if (nDocH)
1491
0
        {
1492
0
            tools::Long nHeight = static_cast<tools::Long>(nDocH * nScaleY);
1493
0
            tools::Long nEndY = nPosY + nHeight;
1494
1495
0
            pDev->DrawRect( tools::Rectangle( nPosX,nPosY,nEndX,nEndY ) );
1496
1497
0
            aText = OUString::number( nRow+1 );
1498
0
            tools::Long nTextWidth = pDev->GetTextWidth(aText);
1499
0
            tools::Long nTextHeight = pDev->GetTextHeight();
1500
0
            tools::Long nAddX = ( nWidth  - nTextWidth  ) / 2;
1501
0
            tools::Long nAddY = ( nHeight - nTextHeight ) / 2;
1502
0
            pDev->DrawText( Point( nPosX+nAddX,nPosY+nAddY ), aText );
1503
1504
0
            nPosY = nEndY;
1505
0
        }
1506
0
    }
1507
0
}
1508
1509
void ScPrintFunc::LocateColHdr( SCCOL nX1, SCCOL nX2, tools::Long nScrX, tools::Long nScrY,
1510
                                bool bRepCol, ScPreviewLocationData& rLocationData )
1511
0
{
1512
0
    Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1513
0
    tools::Long nOneX = aOnePixel.Width();
1514
0
    tools::Long nOneY = aOnePixel.Height();
1515
1516
0
    tools::Long nHeight = static_cast<tools::Long>(PRINT_HEADER_HEIGHT * nScaleY);
1517
0
    tools::Long nEndY = nScrY + nHeight - nOneY;
1518
1519
0
    tools::Long nPosX = nScrX - nOneX;
1520
0
    for (SCCOL nCol=nX1; nCol<=nX2; nCol++)
1521
0
    {
1522
0
        sal_uInt16 nDocW = rDoc.GetColWidth( nCol, nPrintTab );
1523
0
        if (nDocW)
1524
0
            nPosX += static_cast<tools::Long>(nDocW * nScaleX);
1525
0
    }
1526
0
    tools::Rectangle aCellRect( nScrX, nScrY, nPosX, nEndY );
1527
0
    rLocationData.AddColHeaders( aCellRect, nX1, nX2, bRepCol );
1528
0
}
1529
1530
void ScPrintFunc::LocateRowHdr( SCROW nY1, SCROW nY2, tools::Long nScrX, tools::Long nScrY,
1531
                                bool bRepRow, ScPreviewLocationData& rLocationData )
1532
0
{
1533
0
    Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1534
0
    tools::Long nOneX = aOnePixel.Width();
1535
0
    tools::Long nOneY = aOnePixel.Height();
1536
1537
0
    bool bLayoutRTL = rDoc.IsLayoutRTL( nPrintTab );
1538
1539
0
    tools::Long nWidth = static_cast<tools::Long>(PRINT_HEADER_WIDTH * nScaleX);
1540
0
    tools::Long nEndX = nScrX + nWidth;
1541
0
    if ( !bLayoutRTL )
1542
0
        nEndX -= nOneX;
1543
1544
0
    tools::Long nPosY = nScrY - nOneY;
1545
0
    nPosY += rDoc.GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
1546
0
    tools::Rectangle aCellRect( nScrX, nScrY, nEndX, nPosY );
1547
0
    rLocationData.AddRowHeaders( aCellRect, nY1, nY2, bRepRow );
1548
0
}
1549
1550
void ScPrintFunc::LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1551
                                tools::Long nScrX, tools::Long nScrY, bool bRepCol, bool bRepRow,
1552
                                ScPreviewLocationData& rLocationData )
1553
0
{
1554
    //  get MapMode for drawing objects (same MapMode as in ScOutputData::PrintDrawingLayer)
1555
1556
0
    Point aLogPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
1557
0
    tools::Long nLogStX = aLogPos.X();
1558
0
    tools::Long nLogStY = aLogPos.Y();
1559
1560
0
    SCCOL nCol;
1561
0
    Point aTwipOffset;
1562
0
    for (nCol=0; nCol<nX1; nCol++)
1563
0
        aTwipOffset.AdjustX( -(rDoc.GetColWidth( nCol, nPrintTab )) );
1564
0
    aTwipOffset.AdjustY( -sal_Int32(rDoc.GetRowHeight( 0, nY1-1, nPrintTab )) );
1565
1566
0
    Point aMMOffset(o3tl::convert(aTwipOffset, o3tl::Length::twip, o3tl::Length::mm100));
1567
0
    aMMOffset += Point( nLogStX, nLogStY );
1568
0
    MapMode aDrawMapMode( MapUnit::Map100thMM, aMMOffset, aLogicMode.GetScaleX(), aLogicMode.GetScaleY() );
1569
1570
    //  get pixel rectangle
1571
1572
0
    Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1573
0
    tools::Long nOneX = aOnePixel.Width();
1574
0
    tools::Long nOneY = aOnePixel.Height();
1575
1576
0
    tools::Long nPosX = nScrX - nOneX;
1577
0
    for (nCol=nX1; nCol<=nX2; nCol++)
1578
0
    {
1579
0
        sal_uInt16 nDocW = rDoc.GetColWidth( nCol, nPrintTab );
1580
0
        if (nDocW)
1581
0
            nPosX += static_cast<tools::Long>(nDocW * nScaleX);
1582
0
    }
1583
1584
0
    tools::Long nPosY = nScrY - nOneY;
1585
0
    nPosY += rDoc.GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
1586
0
    tools::Rectangle aCellRect( nScrX, nScrY, nPosX, nPosY );
1587
0
    rLocationData.AddCellRange( aCellRect, ScRange( nX1,nY1,nPrintTab, nX2,nY2,nPrintTab ),
1588
0
                                bRepCol, bRepRow, aDrawMapMode );
1589
0
}
1590
1591
void ScPrintFunc::PrintArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1592
                                tools::Long nScrX, tools::Long nScrY,
1593
                                bool bShLeft, bool bShTop, bool bShRight, bool bShBottom )
1594
0
{
1595
    // #i47547# nothing to do if the end of the print area is before the end of
1596
    // the repeat columns/rows (don't use negative size for ScOutputData)
1597
0
    if ( nX2 < nX1 || nY2 < nY1 )
1598
0
        return;
1599
1600
                            //!     hand over Flag at FillInfo  !!!!!
1601
0
    ScRange aERange;
1602
0
    bool bEmbed = rDoc.IsEmbedded();
1603
0
    if (bEmbed)
1604
0
    {
1605
0
        rDoc.GetEmbedded(aERange);
1606
0
        rDoc.ResetEmbedded();
1607
0
    }
1608
1609
0
    Point aPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
1610
0
    tools::Long nLogStX = aPos.X();
1611
0
    tools::Long nLogStY = aPos.Y();
1612
1613
                    //  Assemble data
1614
1615
0
    ScTableInfo aTabInfo(nY1, nY2, true);
1616
0
    rDoc.FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nPrintTab,
1617
0
                                        nScaleX, nScaleY, true, aTableParam.bFormulas );
1618
0
    lcl_HidePrint( aTabInfo, nX1, nX2 );
1619
1620
0
    if (bEmbed)
1621
0
        rDoc.SetEmbedded(aERange);
1622
1623
0
    ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, &rDoc, nPrintTab,
1624
0
                                nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
1625
1626
0
    vcl::PDFExtOutDevData* pPDF = dynamic_cast<vcl::PDFExtOutDevData*>(pDev->GetExtOutDevData());
1627
0
    bool bTaggedPDF = pPDF && pPDF->GetIsExportTaggedPDF();
1628
0
    if (bTaggedPDF)
1629
0
    {
1630
0
        bool bReopen = aOutputData.ReopenPDFStructureElement(vcl::pdf::StructElement::Part);
1631
0
        if (!bReopen)
1632
0
        {
1633
0
            sal_Int32 nId = pPDF->EnsureStructureElement(nullptr);
1634
0
            pPDF->InitStructureElement(nId, vcl::pdf::StructElement::Part, u"Worksheet"_ustr);
1635
0
            pPDF->BeginStructureElement(nId);
1636
0
            pPDF->GetScPDFState()->m_WorksheetId = nId;
1637
0
        }
1638
0
    }
1639
1640
0
    aOutputData.SetDrawView( pDrawView );
1641
1642
    // test if all paint parts are hidden, then a paint is not necessary at all
1643
0
    const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
1644
0
    const bool bHideAllDrawingLayer( pDrawView && pDrawView->getHideOle() && pDrawView->getHideChart()
1645
0
            && pDrawView->getHideDraw() && pDrawView->getHideFormControl() );
1646
1647
0
    if(!bHideAllDrawingLayer)
1648
0
    {
1649
0
        pDev->SetMapMode(aLogicMode);
1650
        //  don's set Clipping here (Mapmode is being moved)
1651
1652
        // #i72502#
1653
0
        aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
1654
0
    }
1655
1656
0
    pDev->SetMapMode(aOffsetMode);
1657
1658
0
    aOutputData.SetShowFormulas( aTableParam.bFormulas );
1659
0
    aOutputData.SetShowNullValues( aTableParam.bNullVals );
1660
0
    aOutputData.SetUseStyleColor( bUseStyleColor );
1661
1662
0
    Color aGridColor( COL_BLACK );
1663
0
    if ( bUseStyleColor )
1664
0
        aGridColor = ScModule::get()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor;
1665
0
    aOutputData.SetGridColor( aGridColor );
1666
1667
0
    if ( !pPrinter )
1668
0
    {
1669
0
        OutputDevice* pRefDev = rDoc.GetPrinter();      // use the printer also for Preview
1670
0
        double fPrintFrac = double(nZoom) / 100.0;              // without nManualZoom
1671
        //  MapMode, as it would arrive at the printer:
1672
0
        pRefDev->SetMapMode( MapMode( MapUnit::Map100thMM, Point(), fPrintFrac, fPrintFrac ) );
1673
1674
        //  when rendering (PDF), don't use printer as ref device, but printer's MapMode
1675
        //  has to be set anyway, as charts still use it (#106409#)
1676
0
        if ( !bIsRender )
1677
0
            aOutputData.SetRefDevice( pRefDev );
1678
0
    }
1679
1680
0
    if( aTableParam.bCellContent )
1681
0
        aOutputData.DrawBackground(*pDev);
1682
1683
0
    pDev->SetClipRegion(vcl::Region(tools::Rectangle(
1684
0
                aPos, Size(aOutputData.GetScrW(), aOutputData.GetScrH()))));
1685
0
    pDev->SetClipRegion();
1686
1687
0
    if( aTableParam.bCellContent )
1688
0
    {
1689
0
        aOutputData.DrawExtraShadow( bShLeft, bShTop, bShRight, bShBottom );
1690
0
        aOutputData.DrawFrame(*pDev);
1691
0
        aOutputData.DrawSparklines(*pDev);
1692
0
        aOutputData.DrawStrings();
1693
0
        aOutputData.DrawEdit(false);
1694
0
    }
1695
1696
0
    if (aTableParam.bGrid)
1697
0
        aOutputData.DrawGrid(*pDev, true, false);    // no page breaks
1698
1699
0
    aOutputData.AddPDFNotes();      // has no effect if not rendering PDF with notes enabled
1700
1701
    // test if all paint parts are hidden, then a paint is not necessary at all
1702
0
    if(!bHideAllDrawingLayer)
1703
0
    {
1704
        // #i72502#
1705
0
        aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
1706
0
    }
1707
1708
0
    if (bTaggedPDF)
1709
0
    {
1710
0
        aOutputData.PrintDrawingLayer(SC_LAYER_CONTROLS, aMMOffset);
1711
0
        pPDF->EndStructureElement();
1712
0
    }
1713
1714
    // #i72502#
1715
0
    aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
1716
1717
0
    if (!bTaggedPDF)
1718
0
        aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
1719
0
}
1720
1721
bool ScPrintFunc::IsMirror( tools::Long nPageNo )          // Mirror margins?
1722
0
{
1723
0
    return nPageUsage == SvxPageUsage::Mirror && (nPageNo & 1);
1724
0
}
1725
1726
bool ScPrintFunc::IsLeft( tools::Long nPageNo )            // left foot notes?
1727
0
{
1728
0
    bool bLeft;
1729
0
    if (nPageUsage == SvxPageUsage::Left)
1730
0
        bLeft = true;
1731
0
    else if (nPageUsage == SvxPageUsage::Right)
1732
0
        bLeft = false;
1733
0
    else
1734
0
        bLeft = (nPageNo & 1) != 0;
1735
0
    return bLeft;
1736
0
}
1737
1738
void ScPrintFunc::MakeTableString()
1739
0
{
1740
0
    OUString aTmp;
1741
0
    rDoc.GetName(nPrintTab, aTmp);
1742
0
    aFieldData.aTabName = aTmp;
1743
0
}
1744
1745
void ScPrintFunc::MakeEditEngine()
1746
29.7k
{
1747
29.7k
    if (!pEditEngine)
1748
5.53k
    {
1749
        //  can't use document's edit engine pool here,
1750
        //  because pool must have twips as default metric
1751
5.53k
        pEditEngine.reset( new ScHeaderEditEngine( EditEngine::CreatePool().get() ) );
1752
1753
5.53k
        pEditEngine->EnableUndo(false);
1754
        //fdo#45869 we want text to be positioned as it would be for the
1755
        //high dpi printed output, not as would be ideal for the 96dpi preview
1756
        //window itself
1757
5.53k
        pEditEngine->SetRefDevice(pPrinter ? pPrinter : rDoc.GetRefDevice());
1758
5.53k
        pEditEngine->SetWordDelimiters(
1759
5.53k
                ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
1760
5.53k
        pEditEngine->SetControlWord( pEditEngine->GetControlWord() & ~EEControlBits::RTFSTYLESHEETS );
1761
5.53k
        rDoc.ApplyAsianEditSettings( *pEditEngine );
1762
5.53k
        pEditEngine->EnableAutoColor( bUseStyleColor );
1763
1764
        //  Default-Set for alignment
1765
5.53k
        pEditDefaults.reset( new SfxItemSet( pEditEngine->GetEmptyItemSet() ) );
1766
1767
5.53k
        const ScPatternAttr& rPattern(rDoc.getCellAttributeHelper().getDefaultCellAttribute());
1768
1769
5.53k
        rPattern.FillEditItemSet( pEditDefaults.get() );
1770
        //  FillEditItemSet adjusts font height to 1/100th mm,
1771
        //  but for header/footer twips is needed, as in the PatternAttr:
1772
5.53k
        pEditDefaults->Put( rPattern.GetItem(ATTR_FONT_HEIGHT).CloneSetWhich(EE_CHAR_FONTHEIGHT) );
1773
5.53k
        pEditDefaults->Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT).CloneSetWhich(EE_CHAR_FONTHEIGHT_CJK) );
1774
5.53k
        pEditDefaults->Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT).CloneSetWhich(EE_CHAR_FONTHEIGHT_CTL) );
1775
        //  don't use font color, because background color is not used
1776
        //! there's no way to set the background for note pages
1777
5.53k
        pEditDefaults->ClearItem( EE_CHAR_COLOR );
1778
5.53k
        if (ScGlobal::IsSystemRTL())
1779
0
            pEditDefaults->Put( SvxFrameDirectionItem( SvxFrameDirection::Horizontal_RL_TB, EE_PARA_WRITINGDIR ) );
1780
5.53k
    }
1781
1782
29.7k
    pEditEngine->SetData( aFieldData );     // Set page count etc.
1783
29.7k
}
1784
1785
//  nStartY = logic
1786
void ScPrintFunc::PrintHF( tools::Long nPageNo, bool bHeader, tools::Long nStartY,
1787
                            bool bDoPrint, ScPreviewLocationData* pLocationData )
1788
0
{
1789
0
    vcl::PDFExtOutDevData* pPDF = dynamic_cast<vcl::PDFExtOutDevData*>(pDev->GetExtOutDevData());
1790
0
    bool bTaggedPDF = pPDF && pPDF->GetIsExportTaggedPDF();
1791
0
    if (bTaggedPDF)
1792
0
        pPDF->WrapBeginStructureElement(vcl::pdf::StructElement::NonStructElement);
1793
1794
0
    const ScPrintHFParam& rParam = bHeader ? aHdr : aFtr;
1795
1796
0
    pDev->SetMapMode( aTwipMode );          // Head-/Footlines in Twips
1797
1798
0
    bool bFirst = 0 == nPageNo && !rParam.bSharedFirst;
1799
0
    bool bLeft = IsLeft(nPageNo) && !rParam.bShared;
1800
0
    const ScPageHFItem* pHFItem = bFirst ? rParam.pFirst : (bLeft ? rParam.pLeft : rParam.pRight);
1801
1802
0
    tools::Long nLineStartX = aPageRect.Left()  + rParam.nLeft;
1803
0
    tools::Long nLineEndX   = aPageRect.Right() - rParam.nRight;
1804
0
    tools::Long nLineWidth  = nLineEndX - nLineStartX + 1;
1805
1806
    //  Edit-Engine
1807
1808
0
    Point aStart( nLineStartX, nStartY );
1809
0
    Size aPaperSize( nLineWidth, rParam.nHeight-rParam.nDistance );
1810
0
    if ( rParam.pBorder )
1811
0
    {
1812
0
        tools::Long nLeft = lcl_LineTotal( rParam.pBorder->GetLeft() ) + rParam.pBorder->GetDistance(SvxBoxItemLine::LEFT);
1813
0
        tools::Long nTop = lcl_LineTotal( rParam.pBorder->GetTop() ) + rParam.pBorder->GetDistance(SvxBoxItemLine::TOP);
1814
0
        aStart.AdjustX(nLeft );
1815
0
        aStart.AdjustY(nTop );
1816
0
        aPaperSize.AdjustWidth( -(nLeft + lcl_LineTotal( rParam.pBorder->GetRight() ) + rParam.pBorder->GetDistance(SvxBoxItemLine::RIGHT)) );
1817
0
        aPaperSize.AdjustHeight( -(nTop + lcl_LineTotal( rParam.pBorder->GetBottom() ) + rParam.pBorder->GetDistance(SvxBoxItemLine::BOTTOM)) );
1818
0
    }
1819
1820
0
    if ( rParam.pShadow && rParam.pShadow->GetLocation() != SvxShadowLocation::NONE )
1821
0
    {
1822
0
        tools::Long nLeft  = rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::LEFT);
1823
0
        tools::Long nTop   = rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::TOP);
1824
0
        aStart.AdjustX(nLeft );
1825
0
        aStart.AdjustY(nTop );
1826
0
        aPaperSize.AdjustWidth( -(nLeft + rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::RIGHT)) );
1827
0
        aPaperSize.AdjustHeight( -(nTop + rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::BOTTOM)) );
1828
0
    }
1829
1830
0
    aFieldData.nPageNo = nPageNo+aTableParam.nFirstPageNo;
1831
0
    MakeEditEngine();
1832
1833
0
    pEditEngine->SetPaperSize(aPaperSize);
1834
1835
    //  Frame / Background
1836
1837
0
    Point aBorderStart( nLineStartX, nStartY );
1838
0
    Size aBorderSize( nLineWidth, rParam.nHeight-rParam.nDistance );
1839
0
    if ( rParam.bDynamic )
1840
0
    {
1841
        //  adjust here again, for even/odd head-/footlines
1842
        //  and probably other breaks by variable (page number etc.)
1843
1844
0
        tools::Long nMaxHeight = 0;
1845
0
        nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetLeftArea() ) );
1846
0
        nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetCenterArea() ) );
1847
0
        nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetRightArea() ) );
1848
0
        if (rParam.pBorder)
1849
0
            nMaxHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
1850
0
                          lcl_LineTotal( rParam.pBorder->GetBottom() ) +
1851
0
                                    rParam.pBorder->GetDistance(SvxBoxItemLine::TOP) +
1852
0
                                    rParam.pBorder->GetDistance(SvxBoxItemLine::BOTTOM);
1853
0
        if (rParam.pShadow && rParam.pShadow->GetLocation() != SvxShadowLocation::NONE)
1854
0
            nMaxHeight += rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::TOP) +
1855
0
                          rParam.pShadow->CalcShadowSpace(SvxShadowItemSide::BOTTOM);
1856
1857
0
        if (nMaxHeight < rParam.nManHeight-rParam.nDistance)
1858
0
            nMaxHeight = rParam.nManHeight-rParam.nDistance;        // configured Minimum
1859
1860
0
        aBorderSize.setHeight( nMaxHeight );
1861
0
    }
1862
1863
0
    if ( bDoPrint )
1864
0
    {
1865
0
        double nOldScaleX = nScaleX;
1866
0
        double nOldScaleY = nScaleY;
1867
0
        nScaleX = nScaleY = 1.0;            // output directly in Twips
1868
0
        DrawBorder( aBorderStart.X(), aBorderStart.Y(), aBorderSize.Width(), aBorderSize.Height(),
1869
0
                        rParam.pBorder, rParam.pBack, rParam.pShadow );
1870
0
        nScaleX = nOldScaleX;
1871
0
        nScaleY = nOldScaleY;
1872
1873
        //  Clipping for Text
1874
1875
0
        pDev->SetClipRegion(vcl::Region(tools::Rectangle(aStart, aPaperSize)));
1876
1877
        //  left
1878
1879
0
        const EditTextObject* pObject = pHFItem->GetLeftArea();
1880
0
        if (pObject)
1881
0
        {
1882
0
            pEditDefaults->Put( SvxAdjustItem( SvxAdjust::Left, EE_PARA_JUST ) );
1883
0
            pEditEngine->SetTextTempDefaults(*pObject, *pEditDefaults);
1884
0
            Point aDraw = aStart;
1885
0
            tools::Long nDif = aPaperSize.Height() - static_cast<tools::Long>(pEditEngine->GetTextHeight());
1886
0
            if (nDif > 0)
1887
0
                aDraw.AdjustY(nDif / 2 );
1888
0
            pEditEngine->DrawText_ToPosition(*pDev, aDraw);
1889
0
        }
1890
1891
        //  center
1892
1893
0
        pObject = pHFItem->GetCenterArea();
1894
0
        if (pObject)
1895
0
        {
1896
0
            pEditDefaults->Put( SvxAdjustItem( SvxAdjust::Center, EE_PARA_JUST ) );
1897
0
            pEditEngine->SetTextTempDefaults(*pObject, *pEditDefaults);
1898
0
            Point aDraw = aStart;
1899
0
            tools::Long nDif = aPaperSize.Height() - static_cast<tools::Long>(pEditEngine->GetTextHeight());
1900
0
            if (nDif > 0)
1901
0
                aDraw.AdjustY(nDif / 2 );
1902
0
            pEditEngine->DrawText_ToPosition(*pDev, aDraw);
1903
0
        }
1904
1905
        //  right
1906
1907
0
        pObject = pHFItem->GetRightArea();
1908
0
        if (pObject)
1909
0
        {
1910
0
            pEditDefaults->Put( SvxAdjustItem( SvxAdjust::Right, EE_PARA_JUST ) );
1911
0
            pEditEngine->SetTextTempDefaults(*pObject, *pEditDefaults);
1912
0
            Point aDraw = aStart;
1913
0
            tools::Long nDif = aPaperSize.Height() - static_cast<tools::Long>(pEditEngine->GetTextHeight());
1914
0
            if (nDif > 0)
1915
0
                aDraw.AdjustY(nDif / 2 );
1916
0
            pEditEngine->DrawText_ToPosition(*pDev, aDraw);
1917
0
        }
1918
1919
0
        pDev->SetClipRegion();
1920
0
    }
1921
1922
0
    if ( pLocationData )
1923
0
    {
1924
0
        tools::Rectangle aHeaderRect( aBorderStart, aBorderSize );
1925
0
        pLocationData->AddHeaderFooter( aHeaderRect, bHeader, bLeft );
1926
0
    }
1927
1928
0
    if (bTaggedPDF)
1929
0
        pPDF->EndStructureElement();
1930
0
}
1931
1932
tools::Long ScPrintFunc::DoNotes( tools::Long nNoteStart, bool bDoPrint, ScPreviewLocationData* pLocationData )
1933
0
{
1934
0
    if (bDoPrint)
1935
0
        pDev->SetMapMode(aTwipMode);
1936
1937
0
    MakeEditEngine();
1938
0
    pEditDefaults->Put( SvxAdjustItem( SvxAdjust::Left, EE_PARA_JUST ) );
1939
0
    pEditEngine->SetDefaults( *pEditDefaults );
1940
1941
0
    vcl::Font aMarkFont;
1942
0
    ScAutoFontColorMode eColorMode = bUseStyleColor ? ScAutoFontColorMode::Display : ScAutoFontColorMode::Print;
1943
0
    rDoc.getCellAttributeHelper().getDefaultCellAttribute().fillFont(aMarkFont, eColorMode);
1944
0
    pDev->SetFont(aMarkFont);
1945
0
    tools::Long nMarkLen = pDev->GetTextWidth(u"GW99999:"_ustr);
1946
    // without Space-Char, because it rarely arrives there
1947
1948
0
    Size aDataSize = aPageRect.GetSize();
1949
0
    if ( nMarkLen > aDataSize.Width() / 2 )     // everything much too small?
1950
0
        nMarkLen = aDataSize.Width() / 2;       // split the page appropriately
1951
0
    aDataSize.AdjustWidth( -nMarkLen );
1952
1953
0
    pEditEngine->SetPaperSize( aDataSize );
1954
0
    tools::Long nPosX = aPageRect.Left() + nMarkLen;
1955
0
    tools::Long nPosY = aPageRect.Top();
1956
1957
0
    tools::Long nCount = 0;
1958
0
    tools::Long nSize = aNotePosList.size();
1959
0
    bool bOk;
1960
0
    do
1961
0
    {
1962
0
        bOk = false;
1963
0
        if ( nNoteStart + nCount < nSize)
1964
0
        {
1965
0
            ScAddress &rPos = aNotePosList[ nNoteStart + nCount ];
1966
1967
0
            if( const ScPostIt* pNote = rDoc.GetNote( rPos ) )
1968
0
            {
1969
0
                if(const EditTextObject *pEditText = pNote->GetEditTextObject())
1970
0
                    pEditEngine->SetTextCurrentDefaults(*pEditText);
1971
0
                tools::Long nTextHeight = pEditEngine->GetTextHeight();
1972
0
                if ( nPosY + nTextHeight < aPageRect.Bottom() )
1973
0
                {
1974
0
                    if (bDoPrint)
1975
0
                    {
1976
0
                        pEditEngine->DrawText_ToPosition(*pDev, Point(nPosX, nPosY));
1977
1978
0
                        OUString aMarkStr(rPos.Format(ScRefFlags::VALID, &rDoc, rDoc.GetAddressConvention()) + ":");
1979
1980
                        //  cell position also via EditEngine, for correct positioning
1981
0
                        pEditEngine->SetTextCurrentDefaults(aMarkStr);
1982
0
                        pEditEngine->DrawText_ToPosition(*pDev, Point(aPageRect.Left(), nPosY));
1983
0
                    }
1984
1985
0
                    if ( pLocationData )
1986
0
                    {
1987
0
                        tools::Rectangle aTextRect( Point( nPosX, nPosY ), Size( aDataSize.Width(), nTextHeight ) );
1988
0
                        pLocationData->AddNoteText( aTextRect, rPos );
1989
0
                        tools::Rectangle aMarkRect( Point( aPageRect.Left(), nPosY ), Size( nMarkLen, nTextHeight ) );
1990
0
                        pLocationData->AddNoteMark( aMarkRect, rPos );
1991
0
                    }
1992
1993
0
                    nPosY += nTextHeight;
1994
0
                    nPosY += 200;                   // Distance
1995
0
                    ++nCount;
1996
0
                    bOk = true;
1997
0
                }
1998
0
            }
1999
0
        }
2000
0
    }
2001
0
    while (bOk);
2002
2003
0
    return nCount;
2004
0
}
2005
2006
tools::Long ScPrintFunc::PrintNotes( tools::Long nPageNo, tools::Long nNoteStart, bool bDoPrint, ScPreviewLocationData* pLocationData )
2007
0
{
2008
0
    if ( nNoteStart >= static_cast<tools::Long>(aNotePosList.size()) || !aTableParam.bNotes )
2009
0
        return 0;
2010
2011
0
    if ( bDoPrint && bClearWin )
2012
0
    {
2013
        //!  aggregate PrintPage !!!
2014
2015
0
        Color aBackgroundColor( COL_WHITE );
2016
0
        if ( bUseStyleColor )
2017
0
            aBackgroundColor = ScModule::get()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
2018
2019
0
        pDev->SetMapMode(aOffsetMode);
2020
0
        pDev->SetLineColor();
2021
0
        pDev->SetFillColor(aBackgroundColor);
2022
0
        pDev->DrawRect(tools::Rectangle(Point(),
2023
0
                Size(static_cast<tools::Long>(aPageSize.Width() * nScaleX * 100 / nZoom),
2024
0
                     static_cast<tools::Long>(aPageSize.Height() * nScaleY * 100 / nZoom))));
2025
0
    }
2026
2027
    //      adjust aPageRect for left/right page
2028
2029
0
    tools::Rectangle aTempRect( Point(), aPageSize );
2030
0
    if (IsMirror(nPageNo))
2031
0
    {
2032
0
        aPageRect.SetLeft( ( aTempRect.Left()  + nRightMargin ) * 100 / nZoom );
2033
0
        aPageRect.SetRight( ( aTempRect.Right() - nLeftMargin  ) * 100 / nZoom );
2034
0
    }
2035
0
    else
2036
0
    {
2037
0
        aPageRect.SetLeft( ( aTempRect.Left()  + nLeftMargin  ) * 100 / nZoom );
2038
0
        aPageRect.SetRight( ( aTempRect.Right() - nRightMargin ) * 100 / nZoom );
2039
0
    }
2040
2041
0
    if ( pPrinter && bDoPrint )
2042
0
    {
2043
0
        OSL_FAIL( "StartPage does not exist anymore" );
2044
0
    }
2045
2046
0
    if ( bDoPrint || pLocationData )
2047
0
    {
2048
        //  Head and foot lines
2049
2050
0
        if (aHdr.bEnable)
2051
0
        {
2052
0
            tools::Long nHeaderY = aPageRect.Top()-aHdr.nHeight;
2053
0
            PrintHF( nPageNo, true, nHeaderY, bDoPrint, pLocationData );
2054
0
        }
2055
0
        if (aFtr.bEnable)
2056
0
        {
2057
0
            tools::Long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
2058
0
            PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData );
2059
0
        }
2060
0
    }
2061
2062
0
    tools::Long nCount = DoNotes( nNoteStart, bDoPrint, pLocationData );
2063
2064
0
    if ( pPrinter && bDoPrint )
2065
0
    {
2066
0
        OSL_FAIL( "EndPage does not exist anymore" );
2067
0
    }
2068
2069
0
    return nCount;
2070
0
}
2071
2072
void ScPrintFunc::PrintPage( tools::Long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
2073
                                bool bDoPrint, ScPreviewLocationData* pLocationData )
2074
0
{
2075
0
    bool bLayoutRTL = rDoc.IsLayoutRTL( nPrintTab );
2076
0
    tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
2077
2078
    //  nPageNo is the page number within all sheets of one "start page" setting
2079
2080
0
    if ( bClearWin && bDoPrint )
2081
0
    {
2082
        //  must exactly fit to painting the frame in preview.cxx !!!
2083
2084
0
        Color aBackgroundColor( COL_WHITE );
2085
0
        if ( bUseStyleColor )
2086
0
            aBackgroundColor = ScModule::get()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
2087
2088
0
        pDev->SetMapMode(aOffsetMode);
2089
0
        pDev->SetLineColor();
2090
0
        pDev->SetFillColor(aBackgroundColor);
2091
0
        pDev->DrawRect(tools::Rectangle(Point(),
2092
0
                Size(static_cast<tools::Long>(aPageSize.Width() * nScaleX * 100 / nZoom),
2093
0
                     static_cast<tools::Long>(aPageSize.Height() * nScaleY * 100 / nZoom))));
2094
0
    }
2095
2096
    //      adjust aPageRect for left/right page
2097
2098
0
    tools::Rectangle aTempRect( Point(), aPageSize );
2099
0
    if (IsMirror(nPageNo))
2100
0
    {
2101
0
        aPageRect.SetLeft( ( aTempRect.Left()  + nRightMargin ) * 100 / nZoom );
2102
0
        aPageRect.SetRight( ( aTempRect.Right() - nLeftMargin  ) * 100 / nZoom );
2103
0
    }
2104
0
    else
2105
0
    {
2106
0
        aPageRect.SetLeft( ( aTempRect.Left()  + nLeftMargin  ) * 100 / nZoom );
2107
0
        aPageRect.SetRight( ( aTempRect.Right() - nRightMargin ) * 100 / nZoom );
2108
0
    }
2109
2110
0
    if ( aAreaParam.bRepeatCol )
2111
0
        if ( nX1 > nRepeatStartCol && nX1 <= nRepeatEndCol )
2112
0
            nX1 = nRepeatEndCol + 1;
2113
0
    bool bDoRepCol = (aAreaParam.bRepeatCol && nX1 > nRepeatEndCol);
2114
0
    if ( aAreaParam.bRepeatRow )
2115
0
        if ( nY1 > nRepeatStartRow && nY1 <= nRepeatEndRow )
2116
0
            nY1 = nRepeatEndRow + 1;
2117
0
    bool bDoRepRow = (aAreaParam.bRepeatRow && nY1 > nRepeatEndRow);
2118
2119
    // use new object hide flags in SdrPaintView
2120
0
    if(pDrawView)
2121
0
    {
2122
0
        pDrawView->setHideOle(!aTableParam.bObjects);
2123
0
        pDrawView->setHideChart(!aTableParam.bCharts);
2124
0
        pDrawView->setHideDraw(!aTableParam.bDrawings);
2125
0
        pDrawView->setHideFormControl(!aTableParam.bDrawings);
2126
0
    }
2127
2128
0
    if ( pPrinter && bDoPrint )
2129
0
    {
2130
0
        OSL_FAIL( "StartPage does not exist anymore" );
2131
0
    }
2132
2133
    //  head and foot lines (without centering)
2134
2135
0
    if (aHdr.bEnable)
2136
0
    {
2137
0
        tools::Long nHeaderY = aPageRect.Top()-aHdr.nHeight;
2138
0
        PrintHF( nPageNo, true, nHeaderY, bDoPrint, pLocationData );
2139
0
    }
2140
0
    if (aFtr.bEnable)
2141
0
    {
2142
0
        tools::Long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
2143
0
        PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData );
2144
0
    }
2145
2146
    //  Position ( margins / centering )
2147
2148
0
    tools::Long nLeftSpace = aPageRect.Left();     // Document-Twips
2149
0
    tools::Long nTopSpace  = aPageRect.Top();
2150
0
    if ( bCenterHor || bLayoutRTL )
2151
0
    {
2152
0
        tools::Long nDataWidth = 0;
2153
0
        SCCOL i;
2154
0
        for (i=nX1; i<=nX2; i++)
2155
0
            nDataWidth += rDoc.GetColWidth( i,nPrintTab );
2156
0
        if (bDoRepCol)
2157
0
            for (i=nRepeatStartCol; i<=nRepeatEndCol; i++)
2158
0
                nDataWidth += rDoc.GetColWidth( i,nPrintTab );
2159
0
        if (aTableParam.bHeaders)
2160
0
            nDataWidth += tools::Long(PRINT_HEADER_WIDTH);
2161
0
        if (pBorderItem)
2162
0
            nDataWidth += pBorderItem->GetDistance(SvxBoxItemLine::LEFT) +
2163
0
                           pBorderItem->GetDistance(SvxBoxItemLine::RIGHT);        //! Line width?
2164
0
        if (pShadowItem && pShadowItem->GetLocation() != SvxShadowLocation::NONE)
2165
0
            nDataWidth += pShadowItem->CalcShadowSpace(SvxShadowItemSide::LEFT) +
2166
0
                           pShadowItem->CalcShadowSpace(SvxShadowItemSide::RIGHT);
2167
0
        if ( bCenterHor )
2168
0
        {
2169
0
            nLeftSpace += ( aPageRect.GetWidth() - nDataWidth ) / 2;        // LTR or RTL
2170
0
            if (pBorderItem)
2171
0
                nLeftSpace -= lcl_LineTotal(pBorderItem->GetLeft());
2172
0
        }
2173
0
        else if ( bLayoutRTL )
2174
0
            nLeftSpace += aPageRect.GetWidth() - nDataWidth;                // align to the right edge of the page
2175
0
    }
2176
0
    if ( bCenterVer )
2177
0
    {
2178
0
        tools::Long nDataHeight = rDoc.GetRowHeight( nY1, nY2, nPrintTab);
2179
0
        if (bDoRepRow)
2180
0
            nDataHeight += rDoc.GetRowHeight( nRepeatStartRow,
2181
0
                    nRepeatEndRow, nPrintTab);
2182
0
        if (aTableParam.bHeaders)
2183
0
            nDataHeight += tools::Long(PRINT_HEADER_HEIGHT);
2184
0
        if (pBorderItem)
2185
0
            nDataHeight += pBorderItem->GetDistance(SvxBoxItemLine::TOP) +
2186
0
                           pBorderItem->GetDistance(SvxBoxItemLine::BOTTOM);       //! Line width?
2187
0
        if (pShadowItem && pShadowItem->GetLocation() != SvxShadowLocation::NONE)
2188
0
            nDataHeight += pShadowItem->CalcShadowSpace(SvxShadowItemSide::TOP) +
2189
0
                           pShadowItem->CalcShadowSpace(SvxShadowItemSide::BOTTOM);
2190
0
        nTopSpace += ( aPageRect.GetHeight() - nDataHeight ) / 2;
2191
0
        if (pBorderItem)
2192
0
            nTopSpace -= lcl_LineTotal(pBorderItem->GetTop());
2193
0
    }
2194
2195
    //  calculate sizes of the elements for partitioning
2196
    //  (header, repeat, data)
2197
2198
0
    tools::Long nHeaderWidth   = 0;
2199
0
    tools::Long nHeaderHeight  = 0;
2200
0
    tools::Long nRepeatWidth   = 0;
2201
0
    tools::Long nRepeatHeight  = 0;
2202
0
    tools::Long nContentWidth  = 0;        // scaled - not the same as nDataWidth above
2203
0
    tools::Long nContentHeight = 0;
2204
0
    if (aTableParam.bHeaders)
2205
0
    {
2206
0
        nHeaderWidth  = static_cast<tools::Long>(PRINT_HEADER_WIDTH * nScaleX);
2207
0
        nHeaderHeight = static_cast<tools::Long>(PRINT_HEADER_HEIGHT * nScaleY);
2208
0
    }
2209
0
    if (bDoRepCol)
2210
0
        for (SCCOL i=nRepeatStartCol; i<=nRepeatEndCol; i++)
2211
0
            nRepeatWidth += static_cast<tools::Long>(rDoc.GetColWidth(i,nPrintTab) * nScaleX);
2212
0
    if (bDoRepRow)
2213
0
        nRepeatHeight += rDoc.GetScaledRowHeight( nRepeatStartRow,
2214
0
                nRepeatEndRow, nPrintTab, nScaleY);
2215
0
    for (SCCOL i=nX1; i<=nX2; i++)
2216
0
        nContentWidth += static_cast<tools::Long>(rDoc.GetColWidth(i,nPrintTab) * nScaleX);
2217
0
    nContentHeight += rDoc.GetScaledRowHeight( nY1, nY2, nPrintTab,
2218
0
            nScaleY);
2219
2220
    //  partition the page
2221
2222
0
    tools::Long nStartX = static_cast<tools::Long>( nLeftSpace * nScaleX );
2223
0
    tools::Long nStartY = static_cast<tools::Long>( nTopSpace  * nScaleY );
2224
0
    tools::Long nInnerStartX = nStartX;
2225
0
    tools::Long nInnerStartY = nStartY;
2226
0
    if (pBorderItem)
2227
0
    {
2228
0
        nInnerStartX += static_cast<tools::Long>( ( lcl_LineTotal(pBorderItem->GetLeft()) +
2229
0
                                    pBorderItem->GetDistance(SvxBoxItemLine::LEFT) ) * nScaleX );
2230
0
        nInnerStartY += static_cast<tools::Long>( ( lcl_LineTotal(pBorderItem->GetTop()) +
2231
0
                                    pBorderItem->GetDistance(SvxBoxItemLine::TOP) ) * nScaleY );
2232
0
    }
2233
0
    if (pShadowItem && pShadowItem->GetLocation() != SvxShadowLocation::NONE)
2234
0
    {
2235
0
        nInnerStartX += static_cast<tools::Long>( pShadowItem->CalcShadowSpace(SvxShadowItemSide::LEFT) * nScaleX );
2236
0
        nInnerStartY += static_cast<tools::Long>( pShadowItem->CalcShadowSpace(SvxShadowItemSide::TOP) * nScaleY );
2237
0
    }
2238
2239
0
    if ( bLayoutRTL )
2240
0
    {
2241
        //  arrange elements starting from the right edge
2242
0
        nInnerStartX += nHeaderWidth + nRepeatWidth + nContentWidth;
2243
2244
        //  make rounding easier so the elements are really next to each other in preview
2245
0
        Size aOffsetOnePixel = pDev->PixelToLogic( Size(1,1), aOffsetMode );
2246
0
        tools::Long nOffsetOneX = aOffsetOnePixel.Width();
2247
0
        nInnerStartX += nOffsetOneX / 2;
2248
0
    }
2249
2250
0
    tools::Long nFrameStartX = nInnerStartX;
2251
0
    tools::Long nFrameStartY = nInnerStartY;
2252
2253
0
    tools::Long nRepStartX = nInnerStartX + nHeaderWidth * nLayoutSign;    // widths/heights are 0 if not used
2254
0
    tools::Long nRepStartY = nInnerStartY + nHeaderHeight;
2255
0
    tools::Long nDataX = nRepStartX + nRepeatWidth * nLayoutSign;
2256
0
    tools::Long nDataY = nRepStartY + nRepeatHeight;
2257
0
    tools::Long nEndX = nDataX + nContentWidth * nLayoutSign;
2258
0
    tools::Long nEndY = nDataY + nContentHeight;
2259
0
    tools::Long nFrameEndX = nEndX;
2260
0
    tools::Long nFrameEndY = nEndY;
2261
2262
0
    if ( bLayoutRTL )
2263
0
    {
2264
        //  each element's start position is its left edge
2265
        //! subtract one pixel less?
2266
0
        nInnerStartX -= nHeaderWidth;       // used for header
2267
0
        nRepStartX   -= nRepeatWidth;
2268
0
        nDataX       -= nContentWidth;
2269
2270
        //  continue right of the main elements again
2271
0
        nEndX += nHeaderWidth + nRepeatWidth + nContentWidth;
2272
0
    }
2273
2274
    //  Page frame / background
2275
2276
    //! adjust nEndX/Y
2277
2278
0
    tools::Long nBorderEndX = nEndX;
2279
0
    tools::Long nBorderEndY = nEndY;
2280
0
    if (pBorderItem)
2281
0
    {
2282
0
        nBorderEndX += static_cast<tools::Long>( ( lcl_LineTotal(pBorderItem->GetRight()) +
2283
0
                                    pBorderItem->GetDistance(SvxBoxItemLine::RIGHT) ) * nScaleX );
2284
0
        nBorderEndY += static_cast<tools::Long>( ( lcl_LineTotal(pBorderItem->GetBottom()) +
2285
0
                                    pBorderItem->GetDistance(SvxBoxItemLine::BOTTOM) ) * nScaleY );
2286
0
    }
2287
0
    if (pShadowItem && pShadowItem->GetLocation() != SvxShadowLocation::NONE)
2288
0
    {
2289
0
        nBorderEndX += static_cast<tools::Long>( pShadowItem->CalcShadowSpace(SvxShadowItemSide::RIGHT) * nScaleX );
2290
0
        nBorderEndY += static_cast<tools::Long>( pShadowItem->CalcShadowSpace(SvxShadowItemSide::BOTTOM) * nScaleY );
2291
0
    }
2292
2293
0
    if ( bDoPrint )
2294
0
    {
2295
0
        pDev->SetMapMode( aOffsetMode );
2296
0
        DrawBorder( nStartX, nStartY, nBorderEndX-nStartX, nBorderEndY-nStartY,
2297
0
                        pBorderItem, pBackgroundItem, pShadowItem );
2298
2299
0
        pDev->SetMapMode( aTwipMode );
2300
0
    }
2301
2302
0
    pDev->SetMapMode( aOffsetMode );
2303
2304
    //  Output repeating rows/columns
2305
2306
0
    if (bDoRepCol && bDoRepRow)
2307
0
    {
2308
0
        if ( bDoPrint )
2309
0
            PrintArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
2310
0
                            nRepStartX,nRepStartY, true, true, false, false );
2311
0
        if ( pLocationData )
2312
0
            LocateArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
2313
0
                            nRepStartX,nRepStartY, true, true, *pLocationData );
2314
0
    }
2315
0
    if (bDoRepCol)
2316
0
    {
2317
0
        if ( bDoPrint )
2318
0
            PrintArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY,
2319
0
                        true, !bDoRepRow, false, true );
2320
0
        if ( pLocationData )
2321
0
            LocateArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY, true, false, *pLocationData );
2322
0
    }
2323
0
    if (bDoRepRow)
2324
0
    {
2325
0
        if ( bDoPrint )
2326
0
            PrintArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY,
2327
0
                        !bDoRepCol, true, true, false );
2328
0
        if ( pLocationData )
2329
0
            LocateArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, false, true, *pLocationData );
2330
0
    }
2331
2332
    //  output data
2333
2334
0
    if ( bDoPrint )
2335
0
        PrintArea( nX1,nY1, nX2,nY2, nDataX,nDataY, !bDoRepCol,!bDoRepRow, true, true );
2336
0
    if ( pLocationData )
2337
0
        LocateArea( nX1,nY1, nX2,nY2, nDataX,nDataY, false,false, *pLocationData );
2338
2339
    //  output column/row headers
2340
    //  after data (through probably shadow)
2341
2342
0
    Color aGridColor( COL_BLACK );
2343
0
    if ( bUseStyleColor )
2344
0
        aGridColor = ScModule::get()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor;
2345
2346
0
    if (aTableParam.bHeaders)
2347
0
    {
2348
0
        if ( bDoPrint )
2349
0
        {
2350
0
            pDev->SetLineColor( aGridColor );
2351
0
            pDev->SetFillColor();
2352
0
            pDev->SetMapMode(aOffsetMode);
2353
0
        }
2354
2355
0
        ScPatternAttr aPattern(rDoc.getCellAttributeHelper());
2356
0
        vcl::Font aFont;
2357
0
        ScAutoFontColorMode eColorMode = bUseStyleColor ? ScAutoFontColorMode::Display : ScAutoFontColorMode::Print;
2358
0
        aPattern.fillFont(aFont, eColorMode, pDev);
2359
0
        pDev->SetFont(aFont);
2360
2361
0
        if (bDoRepCol)
2362
0
        {
2363
0
            if ( bDoPrint )
2364
0
                PrintColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY );
2365
0
            if ( pLocationData )
2366
0
                LocateColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY, true, *pLocationData );
2367
0
        }
2368
0
        if ( bDoPrint )
2369
0
            PrintColHdr( nX1,nX2, nDataX,nInnerStartY );
2370
0
        if ( pLocationData )
2371
0
            LocateColHdr( nX1,nX2, nDataX,nInnerStartY, false, *pLocationData );
2372
0
        if (bDoRepRow)
2373
0
        {
2374
0
            if ( bDoPrint )
2375
0
                PrintRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY );
2376
0
            if ( pLocationData )
2377
0
                LocateRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY, true, *pLocationData );
2378
0
        }
2379
0
        if ( bDoPrint )
2380
0
            PrintRowHdr( nY1,nY2, nInnerStartX,nDataY );
2381
0
        if ( pLocationData )
2382
0
            LocateRowHdr( nY1,nY2, nInnerStartX,nDataY, false, *pLocationData );
2383
0
    }
2384
2385
    //  simple frame
2386
2387
0
    if ( bDoPrint && ( aTableParam.bGrid || aTableParam.bHeaders ) )
2388
0
    {
2389
0
        Size aOnePixel = pDev->PixelToLogic(Size(1,1));
2390
0
        tools::Long nOneX = aOnePixel.Width();
2391
0
        tools::Long nOneY = aOnePixel.Height();
2392
2393
0
        tools::Long nLeftX   = nFrameStartX;
2394
0
        tools::Long nTopY    = nFrameStartY - nOneY;
2395
0
        tools::Long nRightX  = nFrameEndX;
2396
0
        tools::Long nBottomY = nFrameEndY - nOneY;
2397
0
        if ( !bLayoutRTL )
2398
0
        {
2399
0
            nLeftX   -= nOneX;
2400
0
            nRightX  -= nOneX;
2401
0
        }
2402
0
        pDev->SetMapMode(aOffsetMode);
2403
0
        pDev->SetLineColor( aGridColor );
2404
0
        pDev->SetFillColor();
2405
0
        pDev->DrawRect( tools::Rectangle( nLeftX, nTopY, nRightX, nBottomY ) );
2406
        //  nEndX/Y without frame-adaptation
2407
0
    }
2408
2409
0
    if ( pPrinter && bDoPrint )
2410
0
    {
2411
0
        OSL_FAIL( "EndPage does not exist anymore" );
2412
0
    }
2413
2414
0
    aLastSourceRange = ScRange( nX1, nY1, nPrintTab, nX2, nY2, nPrintTab );
2415
0
    bSourceRangeValid = true;
2416
0
}
2417
2418
void ScPrintFunc::SetOffset( const Point& rOfs )
2419
0
{
2420
0
    aSrcOffset = rOfs;
2421
0
}
2422
2423
void ScPrintFunc::SetManualZoom( sal_uInt16 nNewZoom )
2424
0
{
2425
0
    nManualZoom = nNewZoom;
2426
0
}
2427
2428
void ScPrintFunc::SetClearFlag( bool bFlag )
2429
0
{
2430
0
    bClearWin = bFlag;
2431
0
}
2432
2433
void ScPrintFunc::SetUseStyleColor( bool bFlag )
2434
0
{
2435
0
    bUseStyleColor = bFlag;
2436
0
    if (pEditEngine)
2437
0
        pEditEngine->EnableAutoColor( bUseStyleColor );
2438
0
}
2439
2440
void ScPrintFunc::SetRenderFlag( bool bFlag )
2441
0
{
2442
0
    bIsRender = bFlag;      // set when using XRenderable (PDF)
2443
0
}
2444
2445
void ScPrintFunc::SetExclusivelyDrawOleAndDrawObjects()
2446
0
{
2447
0
    aTableParam.bCellContent = false;
2448
0
    aTableParam.bNotes = false;
2449
0
    aTableParam.bGrid = false;
2450
0
    aTableParam.bHeaders = false;
2451
0
    aTableParam.bFormulas = false;
2452
0
    aTableParam.bNullVals = false;
2453
0
}
2454
2455
//  UpdatePages is only called from outside to set the breaks correctly for viewing
2456
//  - always without UserArea
2457
2458
bool ScPrintFunc::UpdatePages()
2459
43.0k
{
2460
43.0k
    if (!pParamSet)
2461
0
        return false;
2462
2463
    //  Zoom
2464
2465
43.0k
    nZoom = 100;
2466
43.0k
    if (aTableParam.bScalePageNum || aTableParam.bScaleTo)
2467
0
        nZoom = ZOOM_MIN;                       // correct for breaks
2468
43.0k
    else if (aTableParam.bScaleAll)
2469
43.0k
    {
2470
43.0k
        nZoom = aTableParam.nScaleAll;
2471
43.0k
        if ( nZoom <= ZOOM_MIN )
2472
0
            nZoom = ZOOM_MIN;
2473
43.0k
    }
2474
2475
43.0k
    OUString aName = rDoc.GetPageStyle( nPrintTab );
2476
43.0k
    SCTAB nTabCount = rDoc.GetTableCount();
2477
97.1k
    for (SCTAB nTab=0; nTab<nTabCount; nTab++)
2478
54.1k
        if ( nTab==nPrintTab || rDoc.GetPageStyle(nTab)==aName )
2479
54.0k
        {
2480
            //  Repeating rows/columns
2481
54.0k
            rDoc.SetRepeatArea( nTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
2482
2483
            //  set breaks
2484
54.0k
            ResetBreaks(nTab);
2485
54.0k
            rDocShell.PostPaint(0,0,nTab,rDoc.MaxCol(),rDoc.MaxRow(),nTab, PaintPartFlags::Grid);
2486
54.0k
        }
2487
2488
43.0k
    return true;
2489
43.0k
}
2490
2491
tools::Long ScPrintFunc::CountPages()                       // sets also nPagesX, nPagesY
2492
43.0k
{
2493
43.0k
    bool bAreaOk = false;
2494
2495
43.0k
    if (rDoc.HasTable( nPrintTab ))
2496
43.0k
    {
2497
43.0k
        if (aAreaParam.bPrintArea)                          // Specify print area?
2498
1.08k
        {
2499
1.08k
            if ( bPrintCurrentTable )
2500
119
            {
2501
119
                ScRange& rRange = aAreaParam.aPrintArea;
2502
2503
                //  Here, no comparison of the tables any more. Area is always valid for this table
2504
                //  If comparison should be done here, the table of print ranges must be adjusted
2505
                //  when inserting tables etc.!
2506
2507
119
                nStartCol = rRange.aStart.Col();
2508
119
                nStartRow = rRange.aStart.Row();
2509
119
                nEndCol   = rRange.aEnd  .Col();
2510
119
                nEndRow   = rRange.aEnd  .Row();
2511
119
                bAreaOk   = AdjustPrintArea(false);         // limit
2512
119
            }
2513
967
            else
2514
967
                bAreaOk = false;
2515
1.08k
        }
2516
41.9k
        else                                                // search from document
2517
41.9k
            bAreaOk = AdjustPrintArea(true);
2518
43.0k
    }
2519
2520
43.0k
    if (bAreaOk)
2521
42.0k
    {
2522
42.0k
        tools::Long nPages = 0;
2523
42.0k
        size_t nY;
2524
42.0k
        if (bMultiArea)
2525
0
        {
2526
0
            sal_uInt16 nRCount = rDoc.GetPrintRangeCount( nPrintTab );
2527
0
            for (sal_uInt16 i=0; i<nRCount; i++)
2528
0
            {
2529
0
                CalcZoom(i);
2530
0
                if ( aTableParam.bSkipEmpty )
2531
0
                    for (nY=0; nY< m_aRanges.m_nPagesY; nY++)
2532
0
                        nPages += (*m_aRanges.m_xPageRows)[nY].CountVisible();
2533
0
                else
2534
0
                    nPages += static_cast<tools::Long>(m_aRanges.m_nPagesX) * m_aRanges.m_nPagesY;
2535
0
                if ( pPageData )
2536
0
                    FillPageData();
2537
0
            }
2538
0
        }
2539
42.0k
        else
2540
42.0k
        {
2541
42.0k
            CalcZoom(RANGENO_NORANGE);                      // calculate Zoom
2542
42.0k
            if ( aTableParam.bSkipEmpty )
2543
0
                for (nY=0; nY<m_aRanges.m_nPagesY; nY++)
2544
0
                    nPages += (*m_aRanges.m_xPageRows)[nY].CountVisible();
2545
42.0k
            else
2546
42.0k
                nPages += static_cast<tools::Long>(m_aRanges.m_nPagesX) * m_aRanges.m_nPagesY;
2547
42.0k
            if ( pPageData )
2548
0
                FillPageData();
2549
42.0k
        }
2550
42.0k
        return nPages;
2551
42.0k
    }
2552
992
    else
2553
992
    {
2554
992
        m_aRanges.m_nPagesX = m_aRanges.m_nPagesY = m_aRanges.m_nTotalY = 0;
2555
992
        return 0;
2556
992
    }
2557
43.0k
}
2558
2559
tools::Long ScPrintFunc::CountNotePages()
2560
43.0k
{
2561
43.0k
    if ( !aTableParam.bNotes || !bPrintCurrentTable )
2562
43.0k
        return 0;
2563
2564
0
    bool bError = false;
2565
0
    if (!aAreaParam.bPrintArea)
2566
0
        bError = !AdjustPrintArea(true);            // completely search in Doc
2567
2568
0
    sal_uInt16 nRepeats = 1;                        // how often go through it ?
2569
0
    if (bMultiArea)
2570
0
        nRepeats = rDoc.GetPrintRangeCount(nPrintTab);
2571
0
    if (bError)
2572
0
        nRepeats = 0;
2573
2574
0
    for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
2575
0
    {
2576
0
        bool bDoThis = true;
2577
0
        if (bMultiArea)             // go through all Areas
2578
0
        {
2579
0
            const ScRange* pThisRange = rDoc.GetPrintRange( nPrintTab, nStep );
2580
0
            if ( pThisRange )
2581
0
            {
2582
0
                nStartCol = pThisRange->aStart.Col();
2583
0
                nStartRow = pThisRange->aStart.Row();
2584
0
                nEndCol   = pThisRange->aEnd  .Col();
2585
0
                nEndRow   = pThisRange->aEnd  .Row();
2586
0
                bDoThis = AdjustPrintArea(false);
2587
0
            }
2588
0
        }
2589
2590
0
        if (bDoThis)
2591
0
        {
2592
0
            assert( bPrintAreaValid );
2593
0
            for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
2594
0
            {
2595
0
                if (rDoc.HasColNotes(nCol, nPrintTab))
2596
0
                {
2597
0
                    for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
2598
0
                    {
2599
0
                        if ( rDoc.HasNote(nCol, nRow, nPrintTab) )
2600
0
                            aNotePosList.emplace_back( nCol, nRow, nPrintTab );
2601
0
                    }
2602
0
                }
2603
0
            }
2604
0
        }
2605
0
    }
2606
2607
0
    tools::Long nPages = 0;
2608
0
    tools::Long nNoteNr = 0;
2609
0
    tools::Long nNoteAdd;
2610
0
    do
2611
0
    {
2612
0
        nNoteAdd = PrintNotes( nPages, nNoteNr, false, nullptr );
2613
0
        if (nNoteAdd)
2614
0
        {
2615
0
            nNoteNr += nNoteAdd;
2616
0
            ++nPages;
2617
0
        }
2618
0
    }
2619
0
    while (nNoteAdd);
2620
2621
0
    return nPages;
2622
43.0k
}
2623
2624
void ScPrintFunc::InitModes()               // set MapModes from  nZoom etc.
2625
96.1k
{
2626
96.1k
    aOffset = Point( aSrcOffset.X()*100/nZoom, aSrcOffset.Y()*100/nZoom );
2627
2628
96.1k
    tools::Long nEffZoom = nZoom * static_cast<tools::Long>(nManualZoom);
2629
96.1k
    constexpr auto HMM_PER_TWIPS = o3tl::convert(1.0, o3tl::Length::twip, o3tl::Length::mm100);
2630
96.1k
    nScaleX = nScaleY = HMM_PER_TWIPS;  // output in 1/100 mm
2631
2632
96.1k
    double fZoomFract = double(nEffZoom) / 10000;
2633
96.1k
    double fHorFract = fZoomFract;
2634
2635
96.1k
    if ( !pPrinter && !bIsRender )                          // adjust scale for preview
2636
0
    {
2637
0
        double nFact = rDocShell.GetOutputFactor();
2638
0
        fHorFract = double(nEffZoom) / nFact  / 10000;
2639
0
    }
2640
2641
96.1k
    aLogicMode = MapMode( MapUnit::Map100thMM, Point(), fHorFract, fZoomFract );
2642
2643
96.1k
    Point aLogicOfs( -aOffset.X(), -aOffset.Y() );
2644
96.1k
    aOffsetMode = MapMode( MapUnit::Map100thMM, aLogicOfs, fHorFract, fZoomFract );
2645
2646
96.1k
    Point aTwipsOfs( static_cast<tools::Long>( -aOffset.X() / nScaleX + 0.5 ), static_cast<tools::Long>( -aOffset.Y() / nScaleY + 0.5 ) );
2647
96.1k
    aTwipMode = MapMode( MapUnit::MapTwip, aTwipsOfs, fHorFract, fZoomFract );
2648
96.1k
}
2649
2650
void ScPrintFunc::ApplyPrintSettings()
2651
0
{
2652
0
    if ( !pPrinter )
2653
0
        return;
2654
2655
    //  Configure Printer to Printing
2656
2657
0
    Size aEnumSize = aPageSize;
2658
2659
0
    pPrinter->SetOrientation( bLandscape ? Orientation::Landscape : Orientation::Portrait );
2660
0
    if ( bLandscape )
2661
0
    {
2662
            // landscape is always interpreted as a rotation by 90 degrees !
2663
            // this leads to non WYSIWIG but at least it prints!
2664
            // #i21775#
2665
0
            tools::Long nTemp = aEnumSize.Width();
2666
0
            aEnumSize.setWidth( aEnumSize.Height() );
2667
0
            aEnumSize.setHeight( nTemp );
2668
0
    }
2669
0
    Paper ePaper = SvxPaperInfo::GetSvxPaper( aEnumSize, MapUnit::MapTwip );
2670
0
    sal_uInt16 nPaperBin = pParamSet->Get(ATTR_PAGE_PAPERBIN).GetValue();
2671
2672
0
    pPrinter->SetPaper( ePaper );
2673
0
    if ( PAPER_USER == ePaper )
2674
0
    {
2675
0
        MapMode aPrinterMode = pPrinter->GetMapMode();
2676
0
        MapMode aLocalMode( MapUnit::MapTwip );
2677
0
        pPrinter->SetMapMode( aLocalMode );
2678
0
        pPrinter->SetPaperSizeUser( aEnumSize );
2679
0
        pPrinter->SetMapMode( aPrinterMode );
2680
0
    }
2681
2682
0
    pPrinter->SetPaperBin( nPaperBin );
2683
0
}
2684
2685
//  rPageRanges   = range for all tables
2686
//  nStartPage    = rPageRanges starts at nStartPage
2687
//  nDisplayStart = continuous number for displaying the page number
2688
2689
tools::Long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges,
2690
                                tools::Long nStartPage, tools::Long nDisplayStart, bool bDoPrint,
2691
                                ScPreviewLocationData* pLocationData )
2692
0
{
2693
0
    OSL_ENSURE(pDev,"Device == NULL");
2694
0
    if (!pParamSet)
2695
0
        return 0;
2696
2697
0
    if ( pPrinter && bDoPrint )
2698
0
        ApplyPrintSettings();
2699
2700
0
    InitModes();
2701
0
    if ( pLocationData )
2702
0
    {
2703
0
        pLocationData->SetCellMapMode( aOffsetMode );
2704
0
        pLocationData->SetPrintTab( nPrintTab );
2705
0
    }
2706
2707
0
    MakeTableString();
2708
2709
0
    tools::Long nPageNo = 0;
2710
0
    tools::Long nPrinted = 0;
2711
0
    tools::Long nEndPage = rPageRanges.GetTotalRange().Max();
2712
2713
0
    sal_uInt16 nRepeats = 1;
2714
0
    if (bMultiArea)
2715
0
        nRepeats = rDoc.GetPrintRangeCount(nPrintTab);
2716
0
    for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
2717
0
    {
2718
0
        if (bMultiArea)                     // replace area
2719
0
        {
2720
0
            CalcZoom(nStep);                // also sets nStartCol etc. new
2721
0
            InitModes();
2722
0
        }
2723
2724
0
        SCCOL nX1;
2725
0
        SCROW nY1;
2726
0
        SCCOL nX2;
2727
0
        SCROW nY2;
2728
0
        size_t nCountX;
2729
0
        size_t nCountY;
2730
2731
0
        if (aTableParam.bTopDown)                           // top-bottom
2732
0
        {
2733
0
            nX1 = nStartCol;
2734
0
            for (nCountX=0; nCountX<m_aRanges.m_nPagesX; nCountX++)
2735
0
            {
2736
0
                OSL_ENSURE(nCountX < m_aRanges.m_xPageEndX->size(), "vector access error for aPageEndX (!)");
2737
0
                nX2 = (*m_aRanges.m_xPageEndX)[nCountX];
2738
0
                for (nCountY=0; nCountY<m_aRanges.m_nPagesY; nCountY++)
2739
0
                {
2740
0
                    auto& rPageRow = (*m_aRanges.m_xPageRows)[nCountY];
2741
0
                    nY1 = rPageRow.GetStartRow();
2742
0
                    nY2 = rPageRow.GetEndRow();
2743
0
                    if ( !aTableParam.bSkipEmpty || !rPageRow.IsHidden(nCountX) )
2744
0
                    {
2745
0
                        if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
2746
0
                        {
2747
0
                            PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
2748
0
                                        bDoPrint, pLocationData );
2749
0
                            ++nPrinted;
2750
0
                        }
2751
0
                        ++nPageNo;
2752
0
                    }
2753
0
                }
2754
0
                nX1 = nX2 + 1;
2755
0
            }
2756
0
        }
2757
0
        else                                                // left to right
2758
0
        {
2759
0
            for (nCountY=0; nCountY<m_aRanges.m_nPagesY; nCountY++)
2760
0
            {
2761
0
                auto& rPageRow = (*m_aRanges.m_xPageRows)[nCountY];
2762
0
                nY1 = rPageRow.GetStartRow();
2763
0
                nY2 = rPageRow.GetEndRow();
2764
0
                nX1 = nStartCol;
2765
0
                for (nCountX=0; nCountX<m_aRanges.m_nPagesX; nCountX++)
2766
0
                {
2767
0
                    OSL_ENSURE(nCountX < m_aRanges.m_xPageEndX->size(), "vector access error for aPageEndX");
2768
0
                    nX2 = (*m_aRanges.m_xPageEndX)[nCountX];
2769
0
                    if ( !aTableParam.bSkipEmpty || !rPageRow.IsHidden(nCountX) )
2770
0
                    {
2771
0
                        if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
2772
0
                        {
2773
0
                            PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
2774
0
                                        bDoPrint, pLocationData );
2775
0
                            ++nPrinted;
2776
0
                        }
2777
0
                        ++nPageNo;
2778
0
                    }
2779
0
                    nX1 = nX2 + 1;
2780
0
                }
2781
0
            }
2782
0
        }
2783
0
    }
2784
2785
0
    aFieldData.aTabName = ScResId( STR_NOTES );
2786
2787
0
    tools::Long nNoteNr = 0;
2788
0
    tools::Long nNoteAdd;
2789
0
    do
2790
0
    {
2791
0
        if ( nPageNo+nStartPage <= nEndPage )
2792
0
        {
2793
0
            bool bPageSelected = rPageRanges.IsSelected( nPageNo+nStartPage+1 );
2794
0
            nNoteAdd = PrintNotes( nPageNo+nStartPage, nNoteNr, bDoPrint && bPageSelected,
2795
0
                                    ( bPageSelected ? pLocationData : nullptr ) );
2796
0
            if ( nNoteAdd )
2797
0
            {
2798
0
                nNoteNr += nNoteAdd;
2799
0
                if (bPageSelected)
2800
0
                {
2801
0
                    ++nPrinted;
2802
0
                    bSourceRangeValid = false;      // last page was no cell range
2803
0
                }
2804
0
                ++nPageNo;
2805
0
            }
2806
0
        }
2807
0
        else
2808
0
            nNoteAdd = 0;
2809
0
    }
2810
0
    while (nNoteAdd);
2811
2812
0
    if ( bMultiArea )
2813
0
        ResetBreaks(nPrintTab);                         //breaks correct for displaying
2814
2815
0
    return nPrinted;
2816
0
}
2817
2818
void ScPrintFunc::CalcZoom( sal_uInt16 nRangeNo )                       // calculate zoom
2819
42.0k
{
2820
42.0k
    sal_uInt16 nRCount = rDoc.GetPrintRangeCount( nPrintTab );
2821
42.0k
    const ScRange* pThisRange = nullptr;
2822
42.0k
    if (nRangeNo != RANGENO_NORANGE && nRangeNo < nRCount)
2823
0
        pThisRange = rDoc.GetPrintRange( nPrintTab, nRangeNo );
2824
42.0k
    if ( pThisRange )
2825
0
    {
2826
0
        nStartCol = pThisRange->aStart.Col();
2827
0
        nStartRow = pThisRange->aStart.Row();
2828
0
        nEndCol   = pThisRange->aEnd  .Col();
2829
0
        nEndRow   = pThisRange->aEnd  .Row();
2830
0
    }
2831
2832
42.0k
    if (!AdjustPrintArea(false))                        // empty
2833
0
    {
2834
0
        nZoom = 100;
2835
0
        m_aRanges.m_nPagesX = m_aRanges.m_nPagesY = m_aRanges.m_nTotalY = 0;
2836
0
        return;
2837
0
    }
2838
2839
42.0k
    rDoc.SetRepeatArea( nPrintTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
2840
2841
42.0k
    if (aTableParam.bScalePageNum)
2842
0
    {
2843
0
        nZoom = 100;
2844
0
        sal_uInt16 nPagesToFit = aTableParam.nScalePageNum;
2845
2846
        // If manual breaks are forced, calculate minimum # pages required
2847
0
        if (aTableParam.bForceBreaks)
2848
0
        {
2849
0
             sal_uInt16 nMinPages = 0;
2850
0
             std::set<SCROW> aRowBreaks;
2851
0
             std::set<SCCOL> aColBreaks;
2852
0
             rDoc.GetAllRowBreaks(aRowBreaks, nPrintTab, false, true);
2853
0
             rDoc.GetAllColBreaks(aColBreaks, nPrintTab, false, true);
2854
0
             nMinPages = (aRowBreaks.size() + 1) * (aColBreaks.size() + 1);
2855
2856
             // #i54993# use min forced by breaks if it's > # pages in
2857
             // scale parameter to avoid bottoming out at <= ZOOM_MIN
2858
0
             nPagesToFit = std::max(nMinPages, nPagesToFit);
2859
0
        }
2860
2861
0
        sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
2862
0
        while (true)
2863
0
        {
2864
0
            if (nZoom <= ZOOM_MIN)
2865
0
                break;
2866
2867
0
            CalcPages();
2868
0
            bool bFitsPage = (m_aRanges.m_nPagesX * m_aRanges.m_nPagesY <= nPagesToFit);
2869
2870
0
            if (bFitsPage)
2871
0
            {
2872
0
                if (nZoom == 100)
2873
                    // If it fits at 100%, it's good enough for me.
2874
0
                    break;
2875
2876
0
                nLastFitZoom = nZoom;
2877
0
                nZoom = (nLastNonFitZoom + nZoom) / 2;
2878
2879
0
                if (nLastFitZoom == nZoom)
2880
                    // It converged.  Use this zoom level.
2881
0
                    break;
2882
0
            }
2883
0
            else
2884
0
            {
2885
0
                if (nZoom - nLastFitZoom <= 1)
2886
0
                {
2887
0
                    nZoom = nLastFitZoom;
2888
0
                    CalcPages();
2889
0
                    break;
2890
0
                }
2891
2892
0
                nLastNonFitZoom = nZoom;
2893
0
                nZoom = (nLastFitZoom + nZoom) / 2;
2894
0
            }
2895
0
        }
2896
0
    }
2897
42.0k
    else if (aTableParam.bScaleTo)
2898
0
    {
2899
0
        nZoom = 100;
2900
0
        sal_uInt16 nW = aTableParam.nScaleWidth;
2901
0
        sal_uInt16 nH = aTableParam.nScaleHeight;
2902
2903
        // If manual breaks are forced, calculate minimum # pages required
2904
0
        if (aTableParam.bForceBreaks)
2905
0
        {
2906
0
             sal_uInt16 nMinPagesW = 0, nMinPagesH = 0;
2907
0
             std::set<SCROW> aRowBreaks;
2908
0
             std::set<SCCOL> aColBreaks;
2909
0
             rDoc.GetAllRowBreaks(aRowBreaks, nPrintTab, false, true);
2910
0
             rDoc.GetAllColBreaks(aColBreaks, nPrintTab, false, true);
2911
0
             nMinPagesW = aColBreaks.size() + 1;
2912
0
             nMinPagesH = aRowBreaks.size() + 1;
2913
2914
             // #i54993# use min forced by breaks if it's > # pages in
2915
             // scale parameters to avoid bottoming out at <= ZOOM_MIN
2916
0
             nW = std::max(nMinPagesW, nW);
2917
0
             nH = std::max(nMinPagesH, nH);
2918
0
        }
2919
2920
0
        sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
2921
0
        while (true)
2922
0
        {
2923
0
            if (nZoom <= ZOOM_MIN)
2924
0
                break;
2925
2926
0
            CalcPages();
2927
0
            bool bFitsPage = ((!nW || (m_aRanges.m_nPagesX <= nW)) && (!nH || (m_aRanges.m_nPagesY <= nH)));
2928
2929
0
            if (bFitsPage)
2930
0
            {
2931
0
                if (nZoom == 100)
2932
                    // If it fits at 100%, it's good enough for me.
2933
0
                    break;
2934
2935
0
                nLastFitZoom = nZoom;
2936
0
                nZoom = (nLastNonFitZoom + nZoom) / 2;
2937
2938
0
                if (nLastFitZoom == nZoom)
2939
                    // It converged.  Use this zoom level.
2940
0
                    break;
2941
0
            }
2942
0
            else
2943
0
            {
2944
0
                if (nZoom - nLastFitZoom <= 1)
2945
0
                {
2946
0
                    nZoom = nLastFitZoom;
2947
0
                    CalcPages();
2948
0
                    break;
2949
0
                }
2950
2951
0
                nLastNonFitZoom = nZoom;
2952
0
                nZoom = (nLastFitZoom + nZoom) / 2;
2953
0
            }
2954
0
        }
2955
        // tdf#103516 remove the almost blank page(s) for better
2956
        // interoperability by using slightly smaller zoom
2957
0
        if (nW > 0 && nH == 0 && m_aRanges.m_nPagesY > 1)
2958
0
        {
2959
0
            sal_uInt32 nLastPagesY = m_aRanges.m_nPagesY;
2960
0
            nLastFitZoom = nZoom;
2961
0
            nZoom *= 0.98;
2962
0
            if (nZoom < nLastFitZoom)
2963
0
            {
2964
0
                CalcPages();
2965
                // same page count with smaller zoom: use the original zoom
2966
0
                if (m_aRanges.m_nPagesY == nLastPagesY)
2967
0
                {
2968
0
                    nZoom = nLastFitZoom;
2969
0
                    CalcPages();
2970
0
                }
2971
0
            }
2972
0
        }
2973
0
    }
2974
42.0k
    else if (aTableParam.bScaleAll)
2975
42.0k
    {
2976
42.0k
        nZoom = aTableParam.nScaleAll;
2977
42.0k
        if ( nZoom <= ZOOM_MIN )
2978
0
            nZoom = ZOOM_MIN;
2979
42.0k
        CalcPages();
2980
42.0k
    }
2981
0
    else
2982
0
    {
2983
0
        OSL_ENSURE( aTableParam.bScaleNone, "no scale flag is set" );
2984
0
        nZoom = 100;
2985
0
        CalcPages();
2986
0
    }
2987
42.0k
}
2988
2989
Size ScPrintFunc::GetDocPageSize()
2990
96.1k
{
2991
                        // Adjust height of head/foot line
2992
2993
96.1k
    InitModes();                            // initialize aTwipMode from nZoom
2994
96.1k
    pDev->SetMapMode( aTwipMode );          // head/foot line in Twips
2995
96.1k
    UpdateHFHeight( aHdr );
2996
96.1k
    UpdateHFHeight( aFtr );
2997
2998
                        //  Page size in Document-Twips
2999
                        //  Calculating Left / Right also in PrintPage
3000
3001
96.1k
    aPageRect = tools::Rectangle( Point(), aPageSize );
3002
96.1k
    aPageRect.SetLeft( ( aPageRect.Left()   + nLeftMargin                  ) * 100 / nZoom );
3003
96.1k
    aPageRect.SetRight( ( aPageRect.Right()  - nRightMargin                 ) * 100 / nZoom );
3004
96.1k
    aPageRect.SetTop( ( aPageRect.Top()    + nTopMargin    ) * 100 / nZoom + aHdr.nHeight );
3005
96.1k
    aPageRect.SetBottom( ( aPageRect.Bottom() - nBottomMargin ) * 100 / nZoom - aFtr.nHeight );
3006
3007
96.1k
    Size aDocPageSize = aPageRect.GetSize();
3008
96.1k
    if (aTableParam.bHeaders)
3009
0
    {
3010
0
        aDocPageSize.AdjustWidth( -(tools::Long(PRINT_HEADER_WIDTH)) );
3011
0
        aDocPageSize.AdjustHeight( -(tools::Long(PRINT_HEADER_HEIGHT)) );
3012
0
    }
3013
96.1k
    if (pBorderItem)
3014
96.1k
    {
3015
96.1k
        aDocPageSize.AdjustWidth( -(lcl_LineTotal(pBorderItem->GetLeft()) +
3016
96.1k
                                 lcl_LineTotal(pBorderItem->GetRight()) +
3017
96.1k
                                 pBorderItem->GetDistance(SvxBoxItemLine::LEFT) +
3018
96.1k
                                 pBorderItem->GetDistance(SvxBoxItemLine::RIGHT)) );
3019
96.1k
        aDocPageSize.AdjustHeight( -(lcl_LineTotal(pBorderItem->GetTop()) +
3020
96.1k
                                 lcl_LineTotal(pBorderItem->GetBottom()) +
3021
96.1k
                                 pBorderItem->GetDistance(SvxBoxItemLine::TOP) +
3022
96.1k
                                 pBorderItem->GetDistance(SvxBoxItemLine::BOTTOM)) );
3023
96.1k
    }
3024
96.1k
    if (pShadowItem && pShadowItem->GetLocation() != SvxShadowLocation::NONE)
3025
0
    {
3026
0
        aDocPageSize.AdjustWidth( -(pShadowItem->CalcShadowSpace(SvxShadowItemSide::LEFT) +
3027
0
                                 pShadowItem->CalcShadowSpace(SvxShadowItemSide::RIGHT)) );
3028
0
        aDocPageSize.AdjustHeight( -(pShadowItem->CalcShadowSpace(SvxShadowItemSide::TOP) +
3029
0
                                 pShadowItem->CalcShadowSpace(SvxShadowItemSide::BOTTOM)) );
3030
0
    }
3031
96.1k
    return aDocPageSize;
3032
96.1k
}
3033
3034
void ScPrintFunc::ResetBreaks( SCTAB nTab )         // Set Breaks correctly for view
3035
54.0k
{
3036
54.0k
    rDoc.SetPageSize( nTab, GetDocPageSize() );
3037
54.0k
    rDoc.UpdatePageBreaks( nTab );
3038
54.0k
}
3039
3040
static void lcl_SetHidden( const ScDocument& rDoc, SCTAB nPrintTab, ScPageRowEntry& rPageRowEntry,
3041
                    SCCOL nStartCol, const std::vector< SCCOL >& rPageEndX )
3042
0
{
3043
0
    size_t nPagesX   = rPageRowEntry.GetPagesX();
3044
0
    SCROW nStartRow = rPageRowEntry.GetStartRow();
3045
0
    SCROW nEndRow   = rPageRowEntry.GetEndRow();
3046
3047
0
    bool bLeftIsEmpty = false;
3048
0
    ScRange aTempRange;
3049
0
    tools::Rectangle aTempRect = rDoc.GetMMRect( 0,0, 0,0, 0 );
3050
3051
0
    for (size_t i=0; i<nPagesX; i++)
3052
0
    {
3053
0
        OSL_ENSURE(i < rPageEndX.size(), "vector access error for aPageEndX");
3054
0
        SCCOL nEndCol = rPageEndX[i];
3055
0
        if ( rDoc.IsPrintEmpty( nStartCol, nStartRow, nEndCol, nEndRow, nPrintTab,
3056
0
                                    bLeftIsEmpty, &aTempRange, &aTempRect ) )
3057
0
        {
3058
0
            rPageRowEntry.SetHidden(i);
3059
0
            bLeftIsEmpty = true;
3060
0
        }
3061
0
        else
3062
0
            bLeftIsEmpty = false;
3063
3064
0
        nStartCol = nEndCol+1;
3065
0
    }
3066
0
}
3067
3068
void ScPrintFunc::CalcPages()               // calculates aPageRect and pages from nZoom
3069
42.0k
{
3070
42.0k
    assert( bPrintAreaValid );
3071
3072
42.0k
    sc::PrintPageRangesInput aInput(aTableParam.bSkipEmpty, aAreaParam.bPrintArea,
3073
42.0k
                                    ScRange(nStartCol, nStartRow, nPrintTab, nEndCol, nEndRow, nPrintTab),
3074
42.0k
                                    GetDocPageSize());
3075
42.0k
    m_aRanges.calculate(rDoc, aInput);
3076
42.0k
}
3077
3078
namespace sc
3079
{
3080
3081
PrintPageRanges::PrintPageRanges()
3082
43.0k
    : m_nPagesX(0)
3083
43.0k
    , m_nPagesY(0)
3084
43.0k
    , m_nTotalY(0)
3085
43.0k
{}
3086
3087
void PrintPageRanges::calculate(ScDocument& rDoc, PrintPageRangesInput const& rInput)
3088
42.0k
{
3089
    // Already calculated?
3090
42.0k
    if (m_aInput == rInput)
3091
0
        return;
3092
3093
42.0k
    m_aInput = rInput;
3094
3095
42.0k
    rDoc.SetPageSize(m_aInput.getPrintTab(), m_aInput.m_aDocSize);
3096
3097
    // Clear the map to prevent any outdated values to "survive" when
3098
    // we have to recalculate the new values anyway
3099
42.0k
    m_xPageRows->clear();
3100
3101
    // #i123672# use dynamic mem to react on size changes
3102
42.0k
    if (m_xPageEndX->size() < static_cast<size_t>(rDoc.MaxCol()) + 1)
3103
42.0k
    {
3104
42.0k
        m_xPageEndX->resize(rDoc.MaxCol()+1, SCCOL());
3105
42.0k
    }
3106
3107
42.0k
    if (m_aInput.m_bPrintArea)
3108
94
    {
3109
94
        ScRange aRange(m_aInput.getStartColumn(), m_aInput.getStartRow(), m_aInput.getPrintTab(), m_aInput.getEndColumn(), m_aInput.getEndRow(), m_aInput.getPrintTab());
3110
94
        rDoc.UpdatePageBreaks(m_aInput.getPrintTab(), &aRange);
3111
94
    }
3112
41.9k
    else
3113
41.9k
    {
3114
41.9k
        rDoc.UpdatePageBreaks(m_aInput.getPrintTab()); // else, end is marked
3115
41.9k
    }
3116
3117
42.0k
    const size_t nRealCnt = m_aInput.getEndRow() - m_aInput.getStartRow() + 1;
3118
3119
    // #i123672# use dynamic mem to react on size changes
3120
42.0k
    if (m_xPageEndY->size() < nRealCnt+1)
3121
42.0k
    {
3122
42.0k
        m_xPageEndY->resize(nRealCnt + 1, SCROW());
3123
42.0k
    }
3124
3125
    //  Page alignment/splitting after breaks in Col/RowFlags
3126
    //  Of several breaks in a hidden area, only one counts.
3127
3128
42.0k
    m_nPagesX = 0;
3129
42.0k
    m_nPagesY = 0;
3130
42.0k
    m_nTotalY = 0;
3131
3132
42.0k
    bool bVisCol = false;
3133
90.5k
    for (SCCOL i = m_aInput.getStartColumn(); i <= m_aInput.getEndColumn(); i++)
3134
48.5k
    {
3135
48.5k
        bool bHidden = rDoc.ColHidden(i, m_aInput.getPrintTab());
3136
48.5k
        bool bPageBreak(rDoc.HasColBreak(i, m_aInput.getPrintTab()) & ScBreakType::Page);
3137
48.5k
        if (i > m_aInput.getStartColumn() && bVisCol && bPageBreak)
3138
236
        {
3139
236
            OSL_ENSURE(m_nPagesX < m_xPageEndX->size(), "vector access error for aPageEndX");
3140
236
            (*m_xPageEndX)[m_nPagesX] = i-1;
3141
236
            ++m_nPagesX;
3142
236
            bVisCol = false;
3143
236
        }
3144
48.5k
        if (!bHidden)
3145
48.5k
            bVisCol = true;
3146
48.5k
    }
3147
42.0k
    if (bVisCol) // also at the end, no empty pages
3148
42.0k
    {
3149
42.0k
        OSL_ENSURE(m_nPagesX < m_xPageEndX->size(), "vector access error for aPageEndX");
3150
42.0k
        (*m_xPageEndX)[m_nPagesX] = m_aInput.getEndColumn();
3151
42.0k
        ++m_nPagesX;
3152
42.0k
    }
3153
3154
42.0k
    bool bVisRow = false;
3155
42.0k
    SCROW nPageStartRow = m_aInput.getStartRow();
3156
42.0k
    SCROW nLastVisibleRow = -1;
3157
3158
42.0k
    std::unique_ptr<ScRowBreakIterator> pRowBreakIter(rDoc.GetRowBreakIterator(m_aInput.getPrintTab()));
3159
42.0k
    SCROW nNextPageBreak = pRowBreakIter->first();
3160
42.0k
    while (nNextPageBreak != ScRowBreakIterator::NOT_FOUND && nNextPageBreak < m_aInput.getStartRow())
3161
        // Skip until the page break position is at the start row or greater.
3162
0
        nNextPageBreak = pRowBreakIter->next();
3163
3164
86.0k
    for (SCROW nRow = m_aInput.getStartRow(); nRow <= m_aInput.getEndRow(); ++nRow)
3165
43.9k
    {
3166
43.9k
        bool bPageBreak = (nNextPageBreak == nRow);
3167
43.9k
        if (bPageBreak)
3168
99
            nNextPageBreak = pRowBreakIter->next();
3169
3170
43.9k
        if (nRow > m_aInput.getStartRow() && bVisRow && bPageBreak)
3171
9
        {
3172
9
            OSL_ENSURE(m_nTotalY < m_xPageEndY->size(), "vector access error for rPageEndY");
3173
9
            (*m_xPageEndY)[m_nTotalY] = nRow - 1;
3174
9
            ++m_nTotalY;
3175
3176
9
            if (!m_aInput.m_bSkipEmpty || !rDoc.IsPrintEmpty(m_aInput.getStartColumn(), nPageStartRow, m_aInput.getEndColumn(), nRow-1, m_aInput.getPrintTab()))
3177
9
            {
3178
9
                auto& rPageRow = (*m_xPageRows)[m_nPagesY];
3179
9
                rPageRow.SetStartRow(nPageStartRow);
3180
9
                rPageRow.SetEndRow(nRow - 1);
3181
9
                rPageRow.SetPagesX(m_nPagesX);
3182
9
                if (m_aInput.m_bSkipEmpty)
3183
0
                    lcl_SetHidden(rDoc, m_aInput.getPrintTab(), rPageRow, m_aInput.getStartColumn(), *m_xPageEndX);
3184
9
                ++m_nPagesY;
3185
9
            }
3186
3187
9
            nPageStartRow = nRow;
3188
9
            bVisRow = false;
3189
9
        }
3190
3191
43.9k
        if (nRow <= nLastVisibleRow)
3192
1.93k
        {
3193
            // This row is still visible.  Don't bother calling RowHidden() to
3194
            // find out, for speed optimization.
3195
1.93k
            bVisRow = true;
3196
1.93k
            continue;
3197
1.93k
        }
3198
3199
42.0k
        SCROW nLastRow = -1;
3200
42.0k
        if (!rDoc.RowHidden(nRow, m_aInput.getPrintTab(), nullptr, &nLastRow))
3201
42.0k
        {
3202
42.0k
            bVisRow = true;
3203
42.0k
            nLastVisibleRow = nLastRow;
3204
42.0k
        }
3205
0
        else
3206
0
        {
3207
            // Skip all hidden rows until next pagebreak.
3208
0
            nRow = ((nNextPageBreak == ScRowBreakIterator::NOT_FOUND) ? nLastRow :
3209
0
                    std::min(nLastRow, nNextPageBreak - 1));
3210
0
        }
3211
42.0k
    }
3212
3213
42.0k
    if (!bVisRow)
3214
0
        return;
3215
3216
42.0k
    OSL_ENSURE(m_nTotalY < m_xPageEndY->size(), "vector access error for maPageEndY");
3217
42.0k
    (*m_xPageEndY)[m_nTotalY] = m_aInput.getEndRow();
3218
42.0k
    ++m_nTotalY;
3219
3220
42.0k
    if (!m_aInput.m_bSkipEmpty || !rDoc.IsPrintEmpty(m_aInput.getStartColumn(), nPageStartRow, m_aInput.getEndColumn(), m_aInput.getEndRow(), m_aInput.getPrintTab()))
3221
42.0k
    {
3222
42.0k
        auto& rPageRow = (*m_xPageRows)[m_nPagesY];
3223
42.0k
        rPageRow.SetStartRow(nPageStartRow);
3224
42.0k
        rPageRow.SetEndRow(m_aInput.getEndRow());
3225
42.0k
        rPageRow.SetPagesX(m_nPagesX);
3226
42.0k
        if (m_aInput.m_bSkipEmpty)
3227
0
            lcl_SetHidden(rDoc, m_aInput.getPrintTab(), rPageRow, m_aInput.getStartColumn(), *m_xPageEndX);
3228
42.0k
        ++m_nPagesY;
3229
42.0k
    }
3230
42.0k
}
3231
3232
} // end namespace sc
3233
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */