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 <tools/fract.hxx>
21 #include <osl/diagnose.h>
22 #include <viewsh.hxx>
23 #include <pagefrm.hxx>
24 #include <viewimp.hxx>
25 #include <printdata.hxx>
26 #include <ptqueue.hxx>
27 #include <fntcache.hxx>
28
29 #include "vprint.hxx"
30
31 using namespace ::com::sun::star;
32
PagePreviewLayout()33 SwPagePreviewLayout* SwViewShell::PagePreviewLayout()
34 {
35 return Imp()->PagePreviewLayout();
36 }
37
ShowPreviewSelection(sal_uInt16 nSelPage)38 void SwViewShell::ShowPreviewSelection( sal_uInt16 nSelPage )
39 {
40 Imp()->InvalidateAccessiblePreviewSelection( nSelPage );
41 }
42
43 // adjust view options for page preview
AdjustOptionsForPagePreview(SwPrintData const & rPrintOptions)44 void SwViewShell::AdjustOptionsForPagePreview(SwPrintData const& rPrintOptions)
45 {
46 if ( !IsPreview() )
47 {
48 OSL_FAIL( "view shell doesn't belongs to a page preview - no adjustment of its view options");
49 return;
50 }
51
52 PrepareForPrint( rPrintOptions );
53 }
54
55 /// print brochure
56 // consider empty pages on calculation of the scaling
57 // for a page to be printed.
PrintProspect(OutputDevice * pOutDev,const SwPrintData & rPrintData,sal_Int32 nRenderer)58 void SwViewShell::PrintProspect(
59 OutputDevice *pOutDev,
60 const SwPrintData &rPrintData,
61 sal_Int32 nRenderer // the index in the vector of prospect pages to be printed
62 )
63 {
64 const sal_Int32 nMaxRenderer = rPrintData.GetRenderData().GetPagePairsForProspectPrinting().size() - 1;
65 OSL_ENSURE( 0 <= nRenderer && nRenderer <= nMaxRenderer, "nRenderer out of bounds");
66 Printer *pPrinter = dynamic_cast< Printer * >(pOutDev);
67 if (!pPrinter || nMaxRenderer < 0 || nRenderer < 0 || nRenderer > nMaxRenderer)
68 return;
69
70 // save settings of OutputDevice (should be done always since the
71 // output device is now provided by a call from outside the Writer)
72 pPrinter->Push();
73
74 std::pair< sal_Int32, sal_Int32 > rPagesToPrint =
75 rPrintData.GetRenderData().GetPagePairsForProspectPrinting()[ nRenderer ];
76 OSL_ENSURE( rPagesToPrint.first == -1 || rPrintData.GetRenderData().GetValidPagesSet().count( rPagesToPrint.first ) == 1, "first Page not valid" );
77 OSL_ENSURE( rPagesToPrint.second == -1 || rPrintData.GetRenderData().GetValidPagesSet().count( rPagesToPrint.second ) == 1, "second Page not valid" );
78
79 // create a new shell for the printer
80 SwViewShell aShell( *this, nullptr, pPrinter );
81
82 CurrShell aCurr( &aShell );
83
84 aShell.PrepareForPrint( rPrintData );
85
86 //!! applying view options and formatting the document should now only be done in getRendererCount!
87
88 MapMode aMapMode( MapUnit::MapTwip );
89 Size aPrtSize( pPrinter->PixelToLogic( pPrinter->GetPaperSizePixel(), aMapMode ) );
90
91 SwTwips nMaxRowSz, nMaxColSz;
92
93 const SwPageFrame *pStPage = nullptr;
94 const SwPageFrame *pNxtPage = nullptr;
95 if (rPagesToPrint.first > 0)
96 {
97 pStPage = sw_getPage(*aShell.GetLayout(), rPagesToPrint.first);
98 }
99 if (rPagesToPrint.second > 0)
100 {
101 pNxtPage = sw_getPage(*aShell.GetLayout(), rPagesToPrint.second);
102 }
103
104 // i#14016 consider empty pages on calculation
105 // of page size, used for calculation of scaling.
106 Size aSttPageSize;
107 if ( pStPage )
108 {
109 if ( pStPage->IsEmptyPage() )
110 {
111 if ( pStPage->GetPhyPageNum() % 2 == 0 )
112 aSttPageSize = pStPage->GetPrev()->getFrameArea().SSize();
113 else
114 aSttPageSize = pStPage->GetNext()->getFrameArea().SSize();
115 }
116 else
117 {
118 aSttPageSize = pStPage->getFrameArea().SSize();
119 }
120 }
121 Size aNxtPageSize;
122 if ( pNxtPage )
123 {
124 if ( pNxtPage->IsEmptyPage() )
125 {
126 if ( pNxtPage->GetPhyPageNum() % 2 == 0 )
127 aNxtPageSize = pNxtPage->GetPrev()->getFrameArea().SSize();
128 else
129 aNxtPageSize = pNxtPage->GetNext()->getFrameArea().SSize();
130 }
131 else
132 {
133 aNxtPageSize = pNxtPage->getFrameArea().SSize();
134 }
135 }
136
137 if( !pStPage )
138 {
139 nMaxColSz = 2 * aNxtPageSize.Width();
140 nMaxRowSz = aNxtPageSize.Height();
141 }
142 else if( !pNxtPage )
143 {
144 nMaxColSz = 2 * aSttPageSize.Width();
145 nMaxRowSz = aSttPageSize.Height();
146 }
147 else
148 {
149 nMaxColSz = aNxtPageSize.Width() + aSttPageSize.Width();
150 nMaxRowSz = std::max( aNxtPageSize.Height(), aSttPageSize.Height() );
151 }
152
153 // set the MapMode
154 aMapMode.SetOrigin( Point() );
155 {
156 Fraction aScX( aPrtSize.Width(), nMaxColSz );
157 Fraction aScY( aPrtSize.Height(), nMaxRowSz );
158 if( aScX < aScY )
159 aScY = aScX;
160
161 {
162 // Round percentages for Drawings so that these can paint their objects properly
163 aScY *= Fraction( 1000, 1 );
164 tools::Long nTmp = static_cast<tools::Long>(aScY);
165 if( 1 < nTmp )
166 --nTmp;
167 else
168 nTmp = 1;
169 aScY = Fraction( nTmp, 1000 );
170 }
171
172 aMapMode.SetScaleY( aScY );
173 aMapMode.SetScaleX( aScY );
174 }
175
176 Size aTmpPrtSize( pPrinter->PixelToLogic( pPrinter->GetPaperSizePixel(), aMapMode ) );
177
178 // calculate start point for equal border on all sides
179 Point aSttPt( (aTmpPrtSize.Width() - nMaxColSz) / 2,
180 (aTmpPrtSize.Height() - nMaxRowSz) / 2 );
181 for( int nC = 0; nC < 2; ++nC )
182 {
183 if( pStPage )
184 {
185 aShell.Imp()->SetFirstVisPageInvalid();
186 aShell.maVisArea = pStPage->getFrameArea();
187
188 Point aPos( aSttPt );
189 aPos -= aShell.maVisArea.Pos();
190 aMapMode.SetOrigin( aPos );
191 pPrinter->SetMapMode( aMapMode );
192 pStPage->GetUpper()->PaintSwFrame( *pOutDev, pStPage->getFrameArea() );
193 }
194
195 pStPage = pNxtPage;
196 aSttPt.AdjustX(aTmpPrtSize.Width() / 2 );
197 }
198
199 SwPaintQueue::Repaint();
200
201 //!! applying/modifying view options and formatting the document should now only be done in getRendererCount!
202
203 pFntCache->Flush();
204
205 // restore settings of OutputDevice (should be done always now since the
206 // output device is now provided by a call from outside the Writer)
207 pPrinter->Pop();
208 }
209
210 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
211