/* -*- 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 .
*/
// putting the StatusIndicator that we got from the MediaDescriptor into our local FilterData copy if ( rSettings.mxStatusIndicator.is() )
{ int i = rSettings.maFilterData.getLength();
rSettings.maFilterData.realloc( i + 1 ); auto pFilterData = rSettings.maFilterData.getArray();
pFilterData[ i ].Name = "StatusIndicator";
pFilterData[ i ].Value <<= rSettings.mxStatusIndicator;
}
}
// tdf#96922 deactivate EditView PageVisualization, including PageBackground // (formerly 'wiese'). Do *not* switch off MasterPageVisualizationAllowed, we // want MasterPage content if a whole SdrPage is exported
pView->SetPageDecorationAllowed(false);
// AW: Here the current version was filtering out the MetaActionType::CLIPREGIONs // from the metafile. I asked some other developers why this was done, but no // one knew a direct reason. Since it's in for long time, it may be an old // piece of code. MetaFiles save and load ClipRegions with polygons with preserving // the polygons, so a resolution-independent roundtrip is supported. Removed this // code since it destroys some MetaFiles where ClipRegions are used. Anyways, // just filtering them out is a hack, at least the encapsulated content would need // to be clipped geometrically.
aGraphic = Graphic(aMtf);
// #118804# only accept for bitmap graphics, else the // conversion to bitmap will happen anywhere without size control // as evtl. defined in rSettings.mnWidth/mnHeight
bSingleGraphic = true;
}
}
} elseif( rSettings.mbScrollText )
{
SdrObject* pObj = aShapes.front(); auto pTextObj = DynCastSdrTextObj( pObj); if( pTextObj && pTextObj->HasText() )
{
tools::Rectangle aScrollRectangle;
tools::Rectangle aPaintRectangle;
// setup pref size and mapmode
pMtf->SetPrefSize( aTextRect.GetSize() );
// set actual origin (mtf is at actual shape // output position)
MapMode aLocalMapMode( aMap );
aLocalMapMode.SetOrigin(
Point( -aPaintRectangle.Left(),
-aPaintRectangle.Top() ) );
pMtf->SetPrefMapMode( aLocalMapMode );
if( !bSingleGraphic )
{ // create a metafile for all shapes
ScopedVclPtrInstance< VirtualDevice > aOut;
// calculate bound rect for all shapes // tdf#126319 I did not convert all rendering to primitives, // that would be too much for this fix. But I did so for the // range calculation to get a valid high quality range. // Based on that the conversion is reliable. With the BoundRect // fetched from the Metafile it was just not possible to get the // examples from the task handled in a way to fit all cases - // due to bad-quality range data from it.
basegfx::B2DRange aBound; const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
// tdf#126319 Immediately add needed offset to create metafile, // that avoids to do it later by Metafile::Move what would be expensive
aOutMap.SetOrigin(
Point(
basegfx::fround<tools::Long>(-aBound.getMinX() - aHalfPixelInMtf.getWidth()),
basegfx::fround<tools::Long>(-aBound.getMinY() - aHalfPixelInMtf.getHeight()) ) );
aOut->SetRelativeMapMode( aOutMap );
sdr::contact::DisplayInfo aDisplayInfo;
if(mpCurrentPage)
{ if(mpCurrentPage->TRG_HasMasterPage() && pPage->IsMasterPage())
{ // MasterPage is processed as another page's SubContent
aDisplayInfo.SetProcessLayers(mpCurrentPage->TRG_GetMasterPageVisibleLayers());
aDisplayInfo.SetSubContentActive(true);
}
}
if(!aShapes.empty())
{ // more effective way to paint a vector of SdrObjects. Hand over the processed page // to have it in the
ImplExportCheckVisisbilityRedirector aCheckVisibilityRedirector(mpCurrentPage);
sdr::contact::ObjectContactOfObjListPainter aMultiObjectPainter(*aOut, std::move(aShapes), mpCurrentPage);
aMultiObjectPainter.SetViewObjectContactRedirector(&aCheckVisibilityRedirector);
// tdf#126319 Immediately add needed size to target's PrefSize // tdf#150102 Checked that in aBound is indeed the size - 1 (probably // due to old integer stuff using Size()/Rectangle() and getWidth()/GetWidth() // with the old one-less paradigm somewhere), so just correct to the // correct size. Be aware that checking of tdf#126319 is needed, but // looks good in my tests. Still: Changing the central UNO API Metafile // export is always a risky thing, so it will have to show if this will // not influence something else. const Size aBoundSize(
basegfx::fround<tools::Long>(aBound.getWidth() + 1),
basegfx::fround<tools::Long>(aBound.getHeight() + 1));
aMtf.SetPrefMapMode( aMap );
aMtf.SetPrefSize( aBoundSize );
// create the output stuff
Graphic aGraphic = maGraphic;
ErrCode nStatus = ERRCODE_NONE; if (maGraphic.IsNone())
{ bool bAntiAliasing = SvtOptionsDrawinglayer::IsAntiAliasing();
AllSettings aAllSettings = Application::GetSettings();
StyleSettings aStyleSettings = aAllSettings.GetStyleSettings(); bool bUseFontAAFromSystem = aStyleSettings.GetUseFontAAFromSystem(); bool bUseSubpixelAA = aStyleSettings.GetUseSubpixelAA();
aStyleSettings.SetUseSubpixelAA(false); if (aSettings.meAntiAliasing != TRISTATE_INDET)
{ // This is safe to do globally as we own the solar mutex.
SvtOptionsDrawinglayer::SetAntiAliasing(aSettings.meAntiAliasing == TRISTATE_TRUE, /*bTemporary*/true); // Opt in to have AA affect font rendering as well.
aStyleSettings.SetUseFontAAFromSystem(false);
}
aAllSettings.SetStyleSettings(aStyleSettings);
Application::SetSettings(aAllSettings, /*bTemporary*/true);
nStatus = GetGraphic( aSettings, aGraphic, bVectorType ) ? ERRCODE_NONE : ERRCODE_GRFILTER_FILTERERROR; if (aSettings.meAntiAliasing != TRISTATE_INDET)
{
SvtOptionsDrawinglayer::SetAntiAliasing(bAntiAliasing, /*bTemporary*/true);
aStyleSettings.SetUseFontAAFromSystem(bUseFontAAFromSystem);
}
aStyleSettings.SetUseSubpixelAA(bUseSubpixelAA);
aAllSettings.SetStyleSettings(aStyleSettings);
Application::SetSettings(aAllSettings, /*bTemporary*/true);
}
if( nStatus == ERRCODE_NONE )
{ // export graphic only if it has a size const Size aGraphSize( aGraphic.GetPrefSize() ); if ( aGraphSize.IsEmpty() )
{
nStatus = ERRCODE_GRFILTER_FILTERERROR;
} else
{ // now we have a graphic, so export it if( aSettings.mxGraphicRenderer.is() )
{ // render graphic directly into given renderer
aSettings.mxGraphicRenderer->render( aGraphic.GetXGraphic() );
} elseif( aSettings.mxOutputStream.is() )
{ // TODO: Either utilize optional XSeekable functionality for the // SvOutputStream, or adapt the graphic filter to not seek anymore.
SvMemoryStream aStream( 1024, 1024 );
/** the source 'document' could be a XDrawPage, a XShape or a generic XShapes */ void SAL_CALL GraphicExporter::setSourceDocument( const Reference< lang::XComponent >& xComponent )
{
::SolarMutexGuard aGuard;
mxShapes = nullptr;
mpUnoPage = nullptr;
try
{ // any break inside this one loop while will throw an IllegalArgumentException do
{
mxPage.set( xComponent, UNO_QUERY );
mxShapes.set( xComponent, UNO_QUERY );
mxShape.set( xComponent, UNO_QUERY );
// Step 1: try a generic XShapes if( !mxPage.is() && !mxShape.is() && mxShapes.is() )
{ // we do not support empty shape collections if( 0 == mxShapes->getCount() ) break;
// get first shape to detect corresponding page and model
mxShapes->getByIndex(0) >>= mxShape;
} else
{
mxShapes = nullptr;
}
// Step 2: try a shape if( mxShape.is() )
{ if (nullptr == SdrObject::getSdrObjectFromXShape(mxShape))
{ // This is not a Draw shape, let's see if it's a Writer one.
uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY); if (!xPropertySet.is()) break;
uno::Reference<graphic::XGraphic> xGraphic(
xPropertySet->getPropertyValue(u"Graphic"_ustr), uno::UNO_QUERY); if (!xGraphic.is()) break;
maGraphic = Graphic(xGraphic); if (!maGraphic.IsNone()) return; else break;
}
// get page for this shape
Reference< XChild > xChild( mxShape, UNO_QUERY ); if( !xChild.is() ) break;
// test all but the first shape if they have the same page than // the first shape for( sal_Int32 nIndex = 1; bOk && ( nIndex < nCount ); nIndex++ )
{
mxShapes->getByIndex( nIndex ) >>= xShape;
pObj = SdrObject::getSdrObjectFromXShape(xShape);
bOk = pObj && pObj->getSdrPageFromSdrObject() == pPage;
}
if( !bOk ) break;
}
// no errors so far return;
} while( false );
} catch( Exception& )
{
}
/** creates a bitmap that is optionally transparent from a metafile
*/
BitmapEx GetBitmapFromMetaFile(const GDIMetaFile& rMtf, const Size* pSize)
{ // use new primitive conversion tooling
basegfx::B2DRange aRange(basegfx::B2DPoint(0.0, 0.0));
sal_uInt32 nMaximumQuadraticPixels;
if (pSize)
{ // use 100th mm for primitive bitmap converter tool, input is pixel // use a real OutDev to get the correct DPI, the static LogicToLogic assumes 72dpi which is wrong (!) const Size aSize100th(
Application::GetDefaultDevice()->PixelToLogic(*pSize, MapMode(MapUnit::Map100thMM)));
// when explicitly pixels are requested from the GraphicExporter, use a *very* high limit // of 16gb (4096x4096 pixels)
nMaximumQuadraticPixels = 4096 * 4096;
} else
{ // use 100th mm for primitive bitmap converter tool const Size aSize100th(OutputDevice::LogicToLogic(rMtf.GetPrefSize(), rMtf.GetPrefMapMode(),
MapMode(MapUnit::Map100thMM)));
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.