Bug Summary

File:home/maarten/src/libreoffice/core/sc/source/ui/view/printfun.cxx
Warning:line 2574, column 40
Division by zero

Annotated Source Code

Press '?' to see keyboard shortcuts

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