/* -*- 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 .
*/
usingnamespace css; using com::sun::star::uno::Reference; using com::sun::star::uno::XInterface; using com::sun::star::uno::UNO_QUERY; using com::sun::star::uno::Sequence; using com::sun::star::container::XNameContainer; using com::sun::star::beans::XPropertySet;
if( bCrop )
{ if( bRectClip )
{ // #i29534# Store crop rect for later forwarding to // PDF writer
tools::Rectangle aCropRect = aClipPolyPoly.GetBoundRect();
rOut.IntersectClipRegion(aCropRect);
} else
{
rOut.IntersectClipRegion(vcl::Region(aClipPolyPoly));
}
}
}
bRet = lclDrawObj(rOut, aPt, aSz, *this, aAttr);
if( bCropped )
rOut.Pop();
rOut.SetDrawMode( nOldDrawMode );
return bRet;
}
void GraphicObject::DrawTiled(OutputDevice& rOut, const tools::Rectangle& rArea, const Size& rSize, const Size& rOffset, int nTileCacheSize1D)
{ if (rSize.IsEmpty()) return;
const MapMode aOutMapMode(rOut.GetMapMode()); // #106258# Clamp size to 1 for zero values. This is okay, since // logical size of zero is handled above already const Size aOutTileSize( ::std::max( tools::Long(1), rOut.LogicToPixel( rSize, aOutMapMode ).Width() ),
::std::max( tools::Long(1), rOut.LogicToPixel( rSize, aOutMapMode ).Height() ) );
//#i69780 clip final tile size to a sane max size while ((static_cast<sal_Int64>(rSize.Width()) * nTileCacheSize1D) > SAL_MAX_UINT16)
nTileCacheSize1D /= 2; while ((static_cast<sal_Int64>(rSize.Height()) * nTileCacheSize1D) > SAL_MAX_UINT16)
nTileCacheSize1D /= 2;
if (aMapGraph.GetMapUnit() == MapUnit::MapPixel)
{ // crops are in 1/100th mm -> to aMapGraph -> to MapUnit::MapPixel
aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel(
Size(rAttr.GetLeftCrop(), rAttr.GetTopCrop()),
aMap100);
aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel(
Size(rAttr.GetRightCrop(), rAttr.GetBottomCrop()),
aMap100);
} else
{ // crops are in GraphicObject units -> to aMapGraph
aCropLeftTop = OutputDevice::LogicToLogic(
Size(rAttr.GetLeftCrop(), rAttr.GetTopCrop()),
aMap100,
aMapGraph);
aCropRightBottom = OutputDevice::LogicToLogic(
Size(rAttr.GetRightCrop(), rAttr.GetBottomCrop()),
aMap100,
aMapGraph);
}
// #104115# If the metafile is cropped, give it a special // treatment: clip against the remaining area, scale up such // that this area later fills the desired size, and move the // origin to the upper left edge of that area. if( rAttr.IsCropped() )
{ const MapMode aMtfMapMode( aMtf.GetPrefMapMode() );
// #104115# To correctly crop rotated metafiles, clip by view rectangle
aMtf.AddAction( new MetaISectRectClipRegionAction( aClipRect ), 0 );
// #104115# To crop the metafile, scale larger than the output rectangle
aMtf.Scale( static_cast<double>(rDestSize.Width()) / (aSrcSize.Width() - aCropLeftTop.Width() - aCropRightBottom.Width()), static_cast<double>(rDestSize.Height()) / (aSrcSize.Height() - aCropLeftTop.Height() - aCropRightBottom.Height()) );
// #104115# Adapt the pref size by hand (scale changes it // proportionally, but we want it to be smaller than the // former size, to crop the excess out)
aMtf.SetPrefSize( Size( static_cast<tools::Long>(static_cast<double>(rDestSize.Width()) * (1.0 + (aCropLeftTop.Width() + aCropRightBottom.Width()) / aSrcSize.Width()) + .5), static_cast<tools::Long>(static_cast<double>(rDestSize.Height()) * (1.0 + (aCropLeftTop.Height() + aCropRightBottom.Height()) / aSrcSize.Height()) + .5) ) );
// #104115# Adapt the origin of the new mapmode, such that it // is shifted to the place where the cropped output starts
Point aNewOrigin( static_cast<tools::Long>(static_cast<double>(aMtfMapMode.GetOrigin().X()) + rDestSize.Width() * aCropLeftTop.Width() / (aSrcSize.Width() - aCropLeftTop.Width() - aCropRightBottom.Width()) + .5), static_cast<tools::Long>(static_cast<double>(aMtfMapMode.GetOrigin().Y()) + rDestSize.Height() * aCropLeftTop.Height() / (aSrcSize.Height() - aCropLeftTop.Height() - aCropRightBottom.Height()) + .5) );
MapMode aNewMap( rDestMap );
aNewMap.SetOrigin( OutputDevice::LogicToLogic(aNewOrigin, aMtfMapMode, rDestMap) );
aMtf.SetPrefMapMode( aNewMap );
} else
{
aMtf.Scale( Fraction( rDestSize.Width(), aSrcSize.Width() ), Fraction( rDestSize.Height(), aSrcSize.Height() ) );
aMtf.SetPrefMapMode( rDestMap );
}
// convert crops to pixel if(rAttr.IsCropped())
{ if (aMapGraph.GetMapUnit() == MapUnit::MapPixel)
{ // crops are in 1/100th mm -> to MapUnit::MapPixel
aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel(
Size(rAttr.GetLeftCrop(), rAttr.GetTopCrop()),
aMap100);
aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel(
Size(rAttr.GetRightCrop(), rAttr.GetBottomCrop()),
aMap100);
} else
{ // crops are in GraphicObject units -> to MapUnit::MapPixel
aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel(
Size(rAttr.GetLeftCrop(), rAttr.GetTopCrop()),
aMapGraph);
aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel(
Size(rAttr.GetRightCrop(), rAttr.GetBottomCrop()),
aMapGraph);
}
// convert from prefmapmode to pixel
Size aSrcSizePixel(
Application::GetDefaultDevice()->LogicToPixel(
aSrcSize,
aMapGraph));
if(rAttr.IsCropped()
&& (aSrcSizePixel.Width() != aBitmapEx.GetSizePixel().Width() || aSrcSizePixel.Height() != aBitmapEx.GetSizePixel().Height())
&& aSrcSizePixel.Width())
{ // the size in pixels calculated from Graphic's internal MapMode (aTransGraphic.GetPrefMapMode()) // and its internal size (aTransGraphic.GetPrefSize()) is different from its real pixel size. // This can be interpreted as this values to be set wrong, but needs to be corrected since e.g. // existing cropping is calculated based on this logic values already. // aBitmapEx.Scale(aSrcSizePixel);
// another possibility is to adapt the values created so far with a factor; this // will keep the original Bitmap untouched and thus quality will not change // caution: convert to double first, else pretty big errors may occur constdouble fFactorX(static_cast<double>(aBitmapEx.GetSizePixel().Width()) / aSrcSizePixel.Width()); constdouble fFactorY(static_cast<double>(aBitmapEx.GetSizePixel().Height()) / aSrcSizePixel.Height());
// cropping affects this frame, apply it then // do _not_ apply enlargement, this is done below
ImplTransformBitmap( aAnimationFrame.maBitmapEx, rAttr, Size(), Size(),
aCropRectRel, rDestSize, false );
aAnim.Replace( aAnimationFrame, nFrame );
} // else: bitmap completely within crop area, // i.e. nothing is cropped away
}
// if topleft has changed, we must move all frames to the // right and bottom, resp. if( aCropLeftTop.Width() < 0 ||
aCropLeftTop.Height() < 0 )
{
Point aPosOffset( aCropLeftTop.Width() < 0 ? -aCropLeftTop.Width() : 0,
aCropLeftTop.Height() < 0 ? -aCropLeftTop.Height() : 0 );
// calculate scalings between real image size and logic object size. This // is necessary since the crop values are relative to original bitmap size
basegfx::B2DVector GraphicObject::calculateCropScaling( double fWidth, double fHeight, double fLeftCrop, double fTopCrop, double fRightCrop, double fBottomCrop) const
{ const MapMode aMapMode100thmm(MapUnit::Map100thMM);
Size aBitmapSize(GetPrefSize()); double fFactorX(1.0); double fFactorY(1.0);
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.