summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2018-08-16 20:20:47 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2018-08-17 21:27:40 +0200
commit046df0a876b3d948bb1e14443c00c180bc8cccaa (patch)
tree9619fa49b3f1b66302cbae973603f1c3f41ba3b0
parentbc28d51cb88c796da241d1ab914bbe6bb174cc49 (diff)
tdf#105998: Enhanced fix for MetafileToBitmap at better place
Change-Id: I220bdbe196a68ef2df25885dceee70e15b760410 Reviewed-on: https://gerrit.libreoffice.org/59220 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
-rw-r--r--drawinglayer/source/processor2d/vclpixelprocessor2d.cxx42
-rw-r--r--svx/source/unodraw/UnoGraphicExporter.cxx122
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
{