diff options
-rw-r--r-- | drawinglayer/source/processor2d/vclpixelprocessor2d.cxx | 42 | ||||
-rw-r--r-- | svx/source/unodraw/UnoGraphicExporter.cxx | 122 |
2 files changed, 59 insertions, 105 deletions
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index b1c974de028c..0845c3316643 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -41,7 +41,6 @@ #include "helperwrongspellrenderer.hxx" #include <drawinglayer/primitive2d/fillhatchprimitive2d.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> -#include <basegfx/polygon/b2dpolypolygontools.hxx> #include <vcl/hatch.hxx> #include <tools/diagnose_ex.h> #include <sal/log.hxx> @@ -136,27 +135,6 @@ namespace drawinglayer return true; } - //Resolves: tdf#105998 if we are a hairline along the very right/bottom edge - //of the canvas then distort the polygon inwards one pixel right/bottom so that - //the hairline falls inside the paintable area and becomes visible - Size aSize = mpOutputDevice->GetOutputSize(); - basegfx::B2DRange aRange = aLocalPolygon.getB2DRange(); - basegfx::B2DRange aOutputRange = aRange; - aOutputRange.transform(maCurrentTransformation); - if (std::round(aOutputRange.getMaxX()) == aSize.Width() || std::round(aOutputRange.getMaxY()) == aSize.Height()) - { - basegfx::B2DRange aOnePixel(0, 0, 1, 1); - aOnePixel.transform(maCurrentTransformation); - double fXOnePixel = 1.0 / aOnePixel.getMaxX(); - double fYOnePixel = 1.0 / aOnePixel.getMaxY(); - - basegfx::B2DPoint aTopLeft(aRange.getMinX(), aRange.getMinY()); - basegfx::B2DPoint aTopRight(aRange.getMaxX() - fXOnePixel, aRange.getMinY()); - basegfx::B2DPoint aBottomLeft(aRange.getMinX(), aRange.getMaxY() - fYOnePixel); - basegfx::B2DPoint aBottomRight(aRange.getMaxX() - fXOnePixel, aRange.getMaxY() - fYOnePixel); - aLocalPolygon = basegfx::utils::distort(aLocalPolygon, aRange, aTopLeft, aTopRight, aBottomLeft, aBottomRight); - } - const basegfx::BColor aLineColor(maBColorModifierStack.getModifiedColor(rSource.getBColor())); mpOutputDevice->SetFillColor(); @@ -204,10 +182,6 @@ namespace drawinglayer return true; } - const basegfx::BColor aLineColor( - maBColorModifierStack.getModifiedColor( - rSource.getLineAttribute().getColor())); - double fLineWidth(rSource.getLineAttribute().getWidth()); if(basegfx::fTools::more(fLineWidth, 0.0)) @@ -228,19 +202,9 @@ namespace drawinglayer fLineWidth = 0.0; } - //Related: tdf#105998 cut and paste as bitmap of shape from draw to - //writer. If we are a hairline along the very right/bottom edge of - //the canvas then fallback to defaults which can distort the - //hairline inside the paintable area - if (fLineWidth == 0.0) - { - Size aSize = mpOutputDevice->GetOutputSize(); - basegfx::B2DRange aRange = aHairLinePolyPolygon.getB2DRange(); - basegfx::B2DRange aOutputRange = aRange; - aOutputRange.transform(maCurrentTransformation); - if (std::round(aOutputRange.getMaxX()) == aSize.Width() || std::round(aOutputRange.getMaxY()) == aSize.Height()) - return false; - } + const basegfx::BColor aLineColor( + maBColorModifierStack.getModifiedColor( + rSource.getLineAttribute().getColor())); mpOutputDevice->SetFillColor(); mpOutputDevice->SetLineColor(Color(aLineColor)); diff --git a/svx/source/unodraw/UnoGraphicExporter.cxx b/svx/source/unodraw/UnoGraphicExporter.cxx index c929114e82cf..b9107915f4c6 100644 --- a/svx/source/unodraw/UnoGraphicExporter.cxx +++ b/svx/source/unodraw/UnoGraphicExporter.cxx @@ -178,83 +178,73 @@ namespace { /** creates a bitmap that is optionally transparent from a metafile */ - BitmapEx GetBitmapFromMetaFile( const GDIMetaFile& rMtf, bool bTransparent, const Size* pSize ) + BitmapEx GetBitmapFromMetaFile( const GDIMetaFile& rMtf, const Size* pSize ) { - BitmapEx aBmpEx; + // use new primitive conversion tooling + basegfx::B2DRange aRange(basegfx::B2DPoint(0.0, 0.0)); + sal_uInt32 nMaximumQuadraticPixels(500000); - if(bTransparent) + if(pSize) { - // use new primitive conversion tooling - basegfx::B2DRange aRange(basegfx::B2DPoint(0.0, 0.0)); - sal_uInt32 nMaximumQuadraticPixels(500000); + // 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))); - 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))); - - aRange.expand(basegfx::B2DPoint(aSize100th.Width(), aSize100th.Height())); - - // when explicitly pixels are requested from the GraphicExporter, use a *very* high limit - // of 16gb (4096x4096 pixels), else use the default for the converters - nMaximumQuadraticPixels = std::min(sal_uInt32(4096 * 4096), sal_uInt32(pSize->Width() * pSize->Height())); - } - else - { - // use 100th mm for primitive bitmap converter tool - const Size aSize100th(OutputDevice::LogicToLogic(rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MapMode(MapUnit::Map100thMM))); + aRange.expand(basegfx::B2DPoint(aSize100th.Width(), aSize100th.Height())); - aRange.expand(basegfx::B2DPoint(aSize100th.Width(), aSize100th.Height())); - } - - aBmpEx = convertMetafileToBitmapEx(rMtf, aRange, nMaximumQuadraticPixels); + // when explicitly pixels are requested from the GraphicExporter, use a *very* high limit + // of 16gb (4096x4096 pixels), else use the default for the converters + nMaximumQuadraticPixels = std::min(sal_uInt32(4096 * 4096), sal_uInt32(pSize->Width() * pSize->Height())); } else { - const SvtOptionsDrawinglayer aDrawinglayerOpt; - Size aTargetSize(0, 0); - - if(pSize) - { - // #i122820# If a concrete target size in pixels is given, use it - aTargetSize = *pSize; - - // get hairline and full bound rect to evtl. reduce given target pixel size when - // it is known that it will be expanded to get the right and bottom hairlines right - tools::Rectangle aHairlineRect; - const tools::Rectangle aRect(rMtf.GetBoundRect(*Application::GetDefaultDevice(), &aHairlineRect)); + // use 100th mm for primitive bitmap converter tool + const Size aSize100th(OutputDevice::LogicToLogic(rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MapMode(MapUnit::Map100thMM))); - if(!aRect.IsEmpty() && !aHairlineRect.IsEmpty()) - { - if(aRect.Right() == aHairlineRect.Right() || aRect.Bottom() == aHairlineRect.Bottom()) - { - if(aTargetSize.Width()) - { - aTargetSize.AdjustWidth( -1 ); - } - - if(aTargetSize.Height()) - { - aTargetSize.AdjustHeight( -1 ); - } - } - } - } + aRange.expand(basegfx::B2DPoint(aSize100th.Width(), aSize100th.Height())); + } - const GraphicConversionParameters aParameters( - aTargetSize, - true, // allow unlimited size - aDrawinglayerOpt.IsAntiAliasing(), - aDrawinglayerOpt.IsSnapHorVerLinesToDiscrete()); - const Graphic aGraphic(rMtf); + // get hairline and full bound rect to evtl. correct logic size by the + // equivalent of one pixel to make those visible at right and bottom + tools::Rectangle aHairlineRect; + const tools::Rectangle aRect(rMtf.GetBoundRect(*Application::GetDefaultDevice(), &aHairlineRect)); - aBmpEx = aGraphic.GetBitmapEx(aParameters); - aBmpEx.SetPrefMapMode( rMtf.GetPrefMapMode() ); - aBmpEx.SetPrefSize( rMtf.GetPrefSize() ); + if(!aRect.IsEmpty()) + { + // tdf#105998 Correct the Metafile using information from it's real sizes measured + // using rMtf.GetBoundRect above and a copy + const Size aOnePixelInMtf( + Application::GetDefaultDevice()->PixelToLogic( + Size(1, 1), + rMtf.GetPrefMapMode())); + GDIMetaFile aMtf(rMtf); + const Size aHalfPixelInMtf( + (aOnePixelInMtf.getWidth() + 1) / 2, + (aOnePixelInMtf.getHeight() + 1) / 2); + const bool bHairlineBR( + !aHairlineRect.IsEmpty() && (aRect.Right() == aHairlineRect.Right() || aRect.Bottom() == aHairlineRect.Bottom())); + + // Move the content to (0,0), usually TopLeft ist slightly + // negative. For better visualization, add a half pixel, too + aMtf.Move( + aHalfPixelInMtf.getWidth() - aRect.Left(), + aHalfPixelInMtf.getHeight() - aRect.Top()); + + // Do not Scale, but set the PrefSize. Some levels deeper the + // MetafilePrimitive will add a mapping to the decomposition + // (and possibly a clipping) to map the graphic content to + // a unit coordinate system. + // Size is the measured size plus one pixel if needed (bHairlineBR) + // and the moved half pixwel from above + aMtf.SetPrefSize( + Size( + aRect.getWidth() + (bHairlineBR ? aOnePixelInMtf.getWidth() : 0) + aHalfPixelInMtf.getWidth(), + aRect.getHeight() + (bHairlineBR ? aOnePixelInMtf.getHeight() : 0) + aHalfPixelInMtf.getHeight())); + + return convertMetafileToBitmapEx(aMtf, aRange, nMaximumQuadraticPixels); } - return aBmpEx; + return BitmapEx(); } Size* CalcSize( sal_Int32 nWidth, sal_Int32 nHeight, const Size& aBoundSize, Size& aOutSize ) @@ -788,7 +778,7 @@ bool GraphicExporter::GetGraphic( ExportSettings const & rSettings, Graphic& aGr if( rSettings.mbTranslucent ) { Size aOutSize; - aGraphic = GetBitmapFromMetaFile( aGraphic.GetGDIMetaFile(), true, CalcSize( rSettings.mnWidth, rSettings.mnHeight, aNewSize, aOutSize ) ); + aGraphic = GetBitmapFromMetaFile( aGraphic.GetGDIMetaFile(), CalcSize( rSettings.mnWidth, rSettings.mnHeight, aNewSize, aOutSize ) ); } } } @@ -978,7 +968,7 @@ bool GraphicExporter::GetGraphic( ExportSettings const & rSettings, Graphic& aGr if( !bVectorType ) { Size aOutSize; - aGraphic = GetBitmapFromMetaFile( aMtf, rSettings.mbTranslucent, CalcSize( rSettings.mnWidth, rSettings.mnHeight, aBoundSize, aOutSize ) ); + aGraphic = GetBitmapFromMetaFile( aMtf, CalcSize( rSettings.mnWidth, rSettings.mnHeight, aBoundSize, aOutSize ) ); } else { |