/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
/** Convenience class to extract values from the sequence of properties given to one of the XRenderable methods.
*/ class PrintOptions
{ public:
PrintOptions ( const vcl::PrinterOptionsHelper& rHelper,
std::vector<sal_Int32>&& rSlidesPerPage)
: mrProperties(rHelper),
maSlidesPerPage(std::move(rSlidesPerPage))
{
}
/** When the value of the property with name pName is a boolean then return its value. When the property is unknown then bDefaultValue is returned. Otherwise <FALSE/> is returned.
*/ bool GetBoolValue ( constchar* pName, constbool bDefaultValue) const
{ bool bValue = mrProperties.getBoolValue( pName, bDefaultValue ); return bValue;
}
/** Return <TRUE/> when the value of the property with name pName is an integer and its value is nTriggerValue. Otherwise <FALSE/> is returned.
*/ bool GetBoolValue ( constchar* pName, const sal_Int32 nTriggerValue) const
{
sal_Int32 nValue = static_cast<sal_Int32>(mrProperties.getIntValue( pName, 0 )); return nValue == nTriggerValue;
}
};
/** A collection of values that helps to reduce the number of arguments given to some functions. Note that not all values are set at the same time.
*/ class PrintInfo
{ public:
PrintInfo (
Printer* pPrinter, constbool bPrintMarkedOnly)
: mpPrinter(pPrinter),
mnDrawMode(DrawModeFlags::Default),
maPrintSize(0,0),
maPageSize(0,0),
meOrientation(Orientation::Portrait),
mbPrintMarkedOnly(bPrintMarkedOnly)
{}
/** Output one page of the document to the given printer. Note that more than one document page may be output to one printer page.
*/ void PrintPage (
Printer& rPrinter,
::sd::View& rPrintView,
SdPage& rPage,
View const * pView, constbool bPrintMarkedOnly, const SdrLayerIDSet& rVisibleLayers, const SdrLayerIDSet& rPrintableLayers)
{
rPrintView.ShowSdrPage(&rPage);
// Set the visible layers
SdrPageView* pPageView = rPrintView.GetSdrPageView();
OSL_ASSERT(pPageView!=nullptr);
pPageView->SetVisibleLayers(rVisibleLayers);
pPageView->SetPrintableLayers(rPrintableLayers);
if (pView!=nullptr && bPrintMarkedOnly)
pView->DrawMarkedObj(rPrinter); else
rPrintView.CompleteRedraw(&rPrinter,
vcl::Region(::tools::Rectangle(Point(0,0), rPage.GetSize())));
rPrinter.SetMapMode(aOriginalMapMode);
rPrintView.HideSdrPage();
}
/** Output a string (that typically is not part of a document page) to the given printer.
*/ void PrintMessage (
Printer& rPrinter, const OUString& rsPageString, const Point& rPageStringOffset)
{ const vcl::Font aOriginalFont (rPrinter.OutputDevice::GetFont());
rPrinter.SetFont(vcl::Font(FAMILY_SWISS, Size(0, 423)));
rPrinter.DrawText(rPageStringOffset, rsPageString);
rPrinter.SetFont(aOriginalFont);
}
/** Read the resources and process then into a sequence of properties that can be passed to the printing dialog.
*/ class DialogCreator
{ public:
DialogCreator (ViewShellBase &rBase, bool bImpress, sal_Int32 nCurPage)
: mrBase(rBase)
, mbImpress(bImpress)
, mnCurPage(nCurPage)
{
ProcessResource();
}
AddDialogControl( vcl::PrinterOptionsHelper::setBoolControlOpt(u"printdatetime"_ustr,
SdResId(STR_IMPRESS_PRINT_UI_IS_PRINT_DATE),
u".HelpID:vcl:PrintDialog:IsPrintDateTime:CheckBox"_ustr ,
u"IsPrintDateTime"_ustr , // Separate settings for time and date in Impress/Draw -> Print page, check that both are set
mbImpress ?
officecfg::Office::Impress::Print::Other::Date::get() &&
officecfg::Office::Impress::Print::Other::Time::get() :
officecfg::Office::Draw::Print::Other::Date::get() &&
officecfg::Office::Draw::Print::Other::Time::get()
)
);
Sequence<OUString> GetSlidesPerPageSequence()
{ const Sequence<OUString> aChoice (
CreateChoice(STR_IMPRESS_PRINT_UI_SLIDESPERPAGE_CHOICES, SAL_N_ELEMENTS(STR_IMPRESS_PRINT_UI_SLIDESPERPAGE_CHOICES)));
maSlidesPerPage.clear();
maSlidesPerPage.push_back(0); // first is using the default
std::transform(std::next(aChoice.begin()), aChoice.end(), std::back_inserter(maSlidesPerPage),
[](const OUString& rChoice) -> sal_Int32 { return rChoice.toInt32(); }); return aChoice;
}
};
/** The Prepare... methods of the DocumentRenderer::Implementation class create a set of PrinterPage objects that contain all necessary information to do the actual printing. There is one PrinterPage object per printed page. Derived classes implement the actual, mode specific printing.
This and all derived classes support the asynchronous printing process by not storing pointers to any data with lifetime shorter than the PrinterPage objects, i.e. slides, shapes, (one of) the outliner (of the document).
*/ class PrinterPage
{ public:
PrinterPage ( const PageKind ePageKind, const MapMode& rMapMode, constbool bPrintMarkedOnly,
OUString sPageString, const Point& rPageStringOffset, const DrawModeFlags nDrawMode, const Orientation eOrientation, const sal_uInt16 nPaperTray)
: mePageKind(ePageKind),
maMap(rMapMode),
mbPrintMarkedOnly(bPrintMarkedOnly),
msPageString(std::move(sPageString)),
maPageStringOffset(rPageStringOffset),
mnDrawMode(nDrawMode),
meOrientation(eOrientation),
mnPaperTray(nPaperTray)
{
}
// Clone the current page to create an independent instance for modifications. // This ensures that changes made to pNotesPage do not affect the original page.
rtl::Reference<SdPage> pNotesPage
= static_cast<SdPage*>(pPageToPrint->CloneSdrPage(rDocument).get());
// Adjusts the objects on the notes page to fit the new page size.
::tools::Rectangle aNewBorderRect(-1, -1, -1, -1);
pNotesPage->ScaleObjects(aPageSize, aNewBorderRect, true);
// If AutoGrowHeight property is enabled and the notes page has a lower border, // use the lower border but if there is no lower border, use the bottom margin // to determine the first page break position. // If AutoGrow is not enabled, the notes object defines the first page break.
::tools::Long nNotesPageBottom
= bAutoGrow ? (pNotesPage->GetLowerBorder() != 0)
? aPageSize.Height() - pNotesPage->GetLowerBorder()
: aPageSize.Height() - nBottom
: aNotesPt.Y() + aNotesSize.Height(); if (mbScaled)
{
sal_Int32 nTextHeight = aNotesPt.Y() + pOut->GetTextHeight(); if (bAutoGrow && (nTextHeight > nNotesPageBottom))
{
pNotesObj->SetMergedItem(SdrOnOffItem(SDRATTR_TEXT_AUTOGROWHEIGHT, false));
if (nUpperSpace != 0 && (i > 0) && (j == 0))
nLineHeight += nUpperSpace;
sal_Int32 nNextPosY = nCurrentPosY + nLineHeight;
if (nNextPosY > nNotesPageBottom)
{ // If the current or the next page matches the print page // calculate and add a page break, since we only want to add // a page break if the page is relevant. if (mnPageNumb == nActualPageNumb
|| mnPageNumb == nActualPageNumb + 1)
{ if (!aPageBreaks.empty())
{ // determine the page break at the bottom of the page // for pages that have both a previous and a following page
aPageBreaks.emplace_back(
nPrevParaIdx - aPageBreaks[0].first, nPrevLineLen);
} else
{ if (mnPageNumb == 1 || (nLineCount > 1 && j != 0))
{ // first page or multi-line paragraphs
aPageBreaks.emplace_back(nPrevParaIdx, nPrevLineLen);
} else
{ // single-line paragraphs
aPageBreaks.emplace_back(nPrevParaIdx + 1, 0);
}
}
// Collect the page objects of the handout master.
std::vector<SdrPageObj*> aHandoutPageObjects;
SdrObjListIter aShapeIter (&rHandoutPage); while (aShapeIter.IsMore())
{
SdrPageObj* pPageObj = dynamic_cast<SdrPageObj*>(aShapeIter.Next()); if (pPageObj)
aHandoutPageObjects.push_back(pPageObj);
} if (aHandoutPageObjects.empty()) return;
// Connect page objects with pages.
std::vector<SdrPageObj*>::iterator aPageObjIter (aHandoutPageObjects.begin()); for (std::vector<sal_uInt16>::const_iterator
iPageIndex(maPageIndices.begin()),
iEnd(maPageIndices.end());
iPageIndex!=iEnd && aPageObjIter!=aHandoutPageObjects.end();
++iPageIndex)
{ // Check if the page still exists. if (*iPageIndex >= rDocument.GetSdPageCount(PageKind::Standard)) continue;
// if there are more page objects than pages left, set the rest to invisible int nHangoverCount = 0; while (aPageObjIter != aHandoutPageObjects.end())
{
(*aPageObjIter++)->SetReferencedPage(nullptr);
nHangoverCount++;
}
// Hide outlines for objects that have pages attached. if (nHangoverCount > 0)
{ int nSkip = aHandoutPageObjects.size() - nHangoverCount;
aShapeIter.Reset(); while (aShapeIter.IsMore())
{
SdrPathObj* pPathObj = dynamic_cast<SdrPathObj*>(aShapeIter.Next()); if (pPathObj)
{ if (nSkip > 0)
--nSkip; else
pPathObj->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
}
}
}
if (rHint.GetId() == SfxHintId::Dying)
{
mbIsDisposed = true;
}
}
/** Process the sequence of properties given to one of the XRenderable methods.
*/ void ProcessProperties (const css::uno::Sequence<css::beans::PropertyValue >& rOptions)
{
OSL_ASSERT(!mbIsDisposed); if (mbIsDisposed) return;
// The RenderDevice property is handled specially: its value is // stored in mpPrinter instead of being retrieved on demand.
Any aDev( getValue( u"RenderDevice"_ustr ) );
Reference<awt::XDevice> xRenderDevice;
/** Return the number of pages that are to be printed.
*/
sal_Int32 GetPrintPageCount() const
{
OSL_ASSERT(!mbIsDisposed); if (mbIsDisposed) return 0; else return maPrinterPages.size();
}
/** Return a sequence of properties that can be returned by the XRenderable::getRenderer() method.
*/
css::uno::Sequence<css::beans::PropertyValue> GetProperties () const
{
css::uno::Sequence<css::beans::PropertyValue> aProperties{
comphelper::makePropertyValue(u"ExtraPrintUIOptions"_ustr,
comphelper::containerToSequence(m_aUIProperties)),
comphelper::makePropertyValue(u"PageSize"_ustr, maPrintSize), // FIXME: is this always true ?
comphelper::makePropertyValue(u"PageIncludesNonprintableArea"_ustr, true)
};
return aProperties;
}
/** Print one of the prepared pages.
*/ void PrintPage (const sal_Int32 nIndex)
{
OSL_ASSERT(!mbIsDisposed); if (mbIsDisposed) return;
Printer& rPrinter (*mpPrinter);
std::shared_ptr<ViewShell> pViewShell (mrBase.GetMainViewShell()); if ( ! pViewShell) return;
// Set page orientation. if ( ! rPrinter.SetOrientation(pPage->GetOrientation()))
{ if ( ! mbHasOrientationWarningBeenShown
&& mpOptions->IsWarningOrientation())
{
mbHasOrientationWarningBeenShown = true; // Show warning that the orientation could not be set.
std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(
pViewShell->GetFrameWeld(), VclMessageType::Warning, VclButtonsType::OkCancel,
SdResId(STR_WARN_PRINTFORMAT_FAILURE)));
xWarn->set_default_response(RET_CANCEL); if (xWarn->run() != RET_OK) return;
}
}
// Set the draw mode.
rPrinter.SetDrawMode(pPage->GetDrawMode());
// Set paper tray.
rPrinter.SetPaperBin(pPage->GetPaperTray());
// Print the actual page.
pPage->Print(
rPrinter,
*pDocument,
*pViewShell,
pDrawViewShell ? pDrawViewShell->GetView() : nullptr,
*mpPrintView,
pViewShell->GetFrameView()->GetVisibleLayers(),
pViewShell->GetFrameView()->GetPrintableLayers());
// Draw and Notes should usually abide by their specified paper size
Size aPaperSize; if (!mpOptions->IsPrinterPreferred(pDocument->GetDocumentType()))
{
aPaperSize.setWidth(rInfo.maPageSize.Width());
aPaperSize.setHeight(rInfo.maPageSize.Height());
} else
{
aPaperSize.setWidth(rInfo.mpPrinter->GetPaperSize().Width());
aPaperSize.setHeight(rInfo.mpPrinter->GetPaperSize().Height());
if (!mpOptions->IsBooklet())
lcl_AdjustPageSize(aPaperSize, rInfo.mpPrinter->GetPrintPageSize());
}
/** Top most method for preparing printer pages. In this and the other Prepare... methods the various special cases are detected and handled. For every page that is to be printed (that may contain several slides) one PrinterPage object is created and inserted into maPrinterPages.
*/ void PreparePages()
{
mpPrintView.reset();
maPrinterPages.clear();
mbHasOrientationWarningBeenShown = false;
// When in outline view then apply all pending changes to the model. if( auto pOutlineViewShell = dynamic_cast< OutlineViewShell *>( pShell ) )
pOutlineViewShell->PrepareClose (false);
// Collect some frequently used data. if (mpOptions->IsDate())
{
aInfo.msTimeDate += GetSdrGlobalData().GetLocaleData().getDate( Date( Date::SYSTEM ) );
aInfo.msTimeDate += " ";
}
if (mpOptions->IsTime())
aInfo.msTimeDate += GetSdrGlobalData().GetLocaleData().getTime( ::tools::Time( ::tools::Time::SYSTEM ), false );
// Draw and Notes should usually use specified paper size when printing if (!mpOptions->IsPrinterPreferred(mrBase.GetDocShell()->GetDocumentType()))
{
aInfo.maPrintSize = mrBase.GetDocument()->GetSdPage(0, PageKind::Standard)->GetSize();
maPrintSize = awt::Size(aInfo.maPrintSize.Width(),
aInfo.maPrintSize.Height());
} else
{
aInfo.maPrintSize = aInfo.mpPrinter->GetOutputSize();
maPrintSize = awt::Size(
aInfo.mpPrinter->GetPaperSize().Width(),
aInfo.mpPrinter->GetPaperSize().Height());
}
if (mpOptions->IsDraw())
PrepareStdOrNotes(PageKind::Standard, aInfo); if (mpOptions->IsNotes())
PrepareStdOrNotes(PageKind::Notes, aInfo); if (mpOptions->IsHandout())
{
InitHandoutTemplate();
PrepareHandout(aInfo);
} if (mpOptions->IsOutline())
PrepareOutline(aInfo);
rOutliner.SetControlWord(nSavedControlWord);
}
/** Create the page objects of the handout template. When the actual printing takes place then the page objects are assigned different sets of slides for each printed page (see HandoutPrinterPage::Print).
*/ void InitHandoutTemplate()
{ const sal_Int32 nSlidesPerHandout (mpOptions->GetHandoutPageCount()); constbool bHandoutHorizontal (mpOptions->IsHandoutHorizontal());
AutoLayout eLayout = AUTOLAYOUT_HANDOUT6; switch (nSlidesPerHandout)
{ case 0: eLayout = AUTOLAYOUT_NONE; break; // AUTOLAYOUT_HANDOUT1; break; case 1: eLayout = AUTOLAYOUT_HANDOUT1; break; case 2: eLayout = AUTOLAYOUT_HANDOUT2; break; case 3: eLayout = AUTOLAYOUT_HANDOUT3; break; case 4: eLayout = AUTOLAYOUT_HANDOUT4; break; default: case 6: eLayout = AUTOLAYOUT_HANDOUT6; break; case 9: eLayout = AUTOLAYOUT_HANDOUT9; break;
}
/** Detect whether the specified slide is to be printed. @return When the slide is not to be printed then <NULL/> is returned. Otherwise a pointer to the slide is returned.
*/
SdPage* GetFilteredPage ( const sal_Int32 nPageIndex, const PageKind ePageKind) const
{
OSL_ASSERT(mrBase.GetDocument() != nullptr);
OSL_ASSERT(nPageIndex>=0);
SdPage* pPage = mrBase.GetDocument()->GetSdPage(
sal::static_int_cast<sal_uInt16>(nPageIndex),
ePageKind); if (pPage == nullptr) return nullptr; if ( ! pPage->IsExcluded() || mpOptions->IsPrintExcluded()) return pPage; else return nullptr;
}
/** Prepare the outline of the document for printing. There is no fixed number of slides whose outline data is put onto one printer page. If the current printer page has enough room for the outline of the current slide then that is added. Otherwise a new printer page is started.
*/ void PrepareOutline (PrintInfo const & rInfo)
{
MapMode aMap (rInfo.maMap);
Point aPageOfs (rInfo.mpPrinter->GetPageOffset() );
aMap.SetScaleX(Fraction(1,2));
aMap.SetScaleY(Fraction(1,2));
mpPrinter->SetMapMode(aMap);
for (const rtl::Reference<SdrObject>& pObj : *pPage)
{ if (pObj->GetObjInventor() == SdrInventor::Default
&& pObj->GetObjIdentifier() == SdrObjKind::OutlineText)
{
pTextObj = DynCastSdrTextObj(pObj.get()); if (pTextObj) break;
}
}
bool bSubTitle (false); if (!pTextObj)
{
bSubTitle = true;
pTextObj = DynCastSdrTextObj(pPage->GetPresObj(PresObjKind::Text)); // is there a subtitle?
}
if (pTextObj!=nullptr
&& !pTextObj->IsEmptyPresObj()
&& pTextObj->GetOutlinerParaObject())
{
pOutliner->AddText(*(pTextObj->GetOutlinerParaObject()));
}
if (bSubTitle )
{ const sal_Int32 nParaCount2 (pOutliner->GetParagraphCount()); for (sal_Int32 nPara=nParaCount1; nPara<nParaCount2; ++nPara)
{
Paragraph* pP = pOutliner->GetParagraph(nPara); if (pP!=nullptr && pOutliner->GetDepth(nPara) > 0)
pOutliner->SetDepth(pP, 0);
}
}
nH = pOutliner->GetTextHeight();
}
// Remove the last paragraph when that does not fit completely on // the current page. if (nH > nPageH && pPara!=nullptr)
{
sal_Int32 nCnt = pOutliner->GetAbsPos(
pOutliner->GetParagraph( pOutliner->GetParagraphCount() - 1 ) );
sal_Int32 nParaPos = pOutliner->GetAbsPos( pPara );
nCnt -= nParaPos;
pPara = pOutliner->GetParagraph( ++nParaPos ); if ( nCnt && pPara )
{
pOutliner->Remove(pPara, nCnt);
--nIndex;
}
}
if (GetFilteredPage(nPageIndex, PageKind::Standard))
aPageIndices.push_back(nPageIndex); elseif (!bLastLoop) continue;
// Create a printer page when we have found one page for each // placeholder or when this is the last (and special) loop. if ( !aPageIndices.empty() && CheckForFrontBackPages( nPageIndex )
&& (aPageIndices.size() == nShapeCount || bLastLoop) )
{
maPrinterPages.push_back(
std::make_shared<HandoutPrinterPage>(
nPrinterPageIndex++,
std::move(aPageIndices),
aMap,
rInfo.msTimeDate,
aPageOfs,
rInfo.mnDrawMode,
rInfo.meOrientation,
nPaperBin));
aPageIndices.clear();
}
}
}
if (mpOptions->IsBooklet())
PrepareBooklet(ePageKind, rInfo); else
PrepareRegularPages(ePageKind, rInfo);
}
/** Prepare slides in a non-booklet way: one slide per one to many printer pages.
*/ void PrepareRegularPages ( const PageKind ePageKind,
PrintInfo& rInfo)
{
std::shared_ptr<ViewShell> pViewShell (mrBase.GetMainViewShell());
pViewShell->WriteFrameViewData();
sal_Int32 nPageCount = mrBase.GetDocument()->GetSdPageCount(PageKind::Standard);
StringRangeEnumerator aRangeEnum(
mpOptions->GetPrinterSelection(nPageCount, GetCurrentPageIndex()),
0, nPageCount-1); for (StringRangeEnumerator::Iterator
it = aRangeEnum.begin(),
itEnd = aRangeEnum.end();
it != itEnd;
++it)
{
SdPage* pPage = GetFilteredPage(*it, ePageKind); if (pPage == nullptr) continue;
MapMode aMap (rInfo.maMap);
Size aPageSize = pPage->GetSize();
if (mpOptions->IsPageSize())
{
Size aPrintSize = rInfo.maPrintSize;
lcl_AdjustPageSize(aPageSize, aPrintSize);
/** Print one standard slide or notes page on one to many printer pages. More than on printer page is used when the slide is larger than the printable area.
*/ void PrepareScaledPage ( const sal_Int32 nPageIndex, const SdPage& rPage, const PageKind ePageKind, const PrintInfo& rInfo)
{ const Point aPageOffset (rInfo.mpPrinter->GetPageOffset());
// For pages larger than the printable area there are three options: // 1. Scale down to the page to the printable area. // 2. Print only the upper left part of the page (without the unprintable borders). // 3. Split the page into parts of the size of the printable area. constbool bScalePage (mpOptions->IsPageSize()); constbool bCutPage (mpOptions->IsCutPage());
MapMode aMap (rInfo.maMap); if ( (bScalePage || bCutPage) && CheckForFrontBackPages( nPageIndex ) )
{ // Handle 1 and 2.
// if CutPage is set then do not move it, otherwise move the // scaled page to printable area if (ePageKind == PageKind::Standard)
{
maPrinterPages.push_back(
std::make_shared<RegularPrinterPage>(
sal::static_int_cast<sal_uInt16>(nPageIndex),
ePageKind,
aMap,
rInfo.mbPrintMarkedOnly,
rInfo.msPageString,
aPageOffset,
rInfo.mnDrawMode,
rInfo.meOrientation,
nPaperBin));
} elseif (SdPage* pPage = GetFilteredPage(nPageIndex, PageKind::Notes))// Notes
{
SdDrawDocument* pDocument = mrBase.GetMainViewShell()->GetDoc();
// Clone the current page to create an independent instance. // This ensures that changes made to pNotesPage do not affect the original page.
rtl::Reference<SdPage> pNotesPage
= static_cast<SdPage*>(pPage->CloneSdrPage(*pDocument).get());
Size aPageSize = bScalePage ? pNotesPage->GetSize() : rInfo.mpPrinter->GetPrintPageSize(); // Adjusts the objects on the notes page to fit the new page size.
::tools::Rectangle aNewBorderRect(-1, -1, -1, -1);
pNotesPage->ScaleObjects(aPageSize, aNewBorderRect, true);
for (sal_Int32 i = 1; i <= nNotePageCount; i++)
{ // set page numbers
sal_Int32 nPageNumb = i;
OUString sPageNumb = rInfo.msPageString; if (!sPageNumb.isEmpty() && nNotePageCount > 1)
{
OUString sTmp; if (!rInfo.msTimeDate.isEmpty())
{
sTmp += " ";
}
sTmp += SdResId(STR_PAGE_NAME) + " " + OUString::number(i);
sPageNumb += sTmp;
}
maPrinterPages.push_back(
std::make_shared<NotesPrinterPage>(
sal::static_int_cast<sal_uInt16>(nPageIndex),
nPageNumb,
nNotePageCount,
bScalePage,
PageKind::Notes,
aMap,
rInfo.mbPrintMarkedOnly,
sPageNumb,
aPageOffset,
rInfo.mnDrawMode,
rInfo.meOrientation,
nPaperBin));
}
pOut->Clear();
pOut->SetUpdateLayout(bSavedUpdateMode);
pOut->Init(nSaveOutlMode);
} else// scaled page
{
maPrinterPages.push_back(
std::make_shared<NotesPrinterPage>(
sal::static_int_cast<sal_uInt16>(nPageIndex),
sal_Int32(0),
sal_Int32(0),
bScalePage,
PageKind::Notes,
aMap,
rInfo.mbPrintMarkedOnly,
rInfo.msPageString,
aPageOffset,
rInfo.mnDrawMode,
rInfo.meOrientation,
nPaperBin));
}
}
} else
{ // Handle 3. Print parts of the page in the size of the // printable area until the whole page is covered.
// keep the page content at its position if it fits, otherwise // move it to the printable area const ::tools::Long nPageWidth (
rInfo.maPageSize.Width() - rPage.GetLeftBorder() - rPage.GetRightBorder()); const ::tools::Long nPageHeight (
rInfo.maPageSize.Height() - rPage.GetUpperBorder() - rPage.GetLowerBorder());
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.