diff options
author | Chris Sherlock <chris.sherlock79@gmail.com> | 2016-02-13 16:08:01 +1100 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2016-02-14 20:51:08 +0000 |
commit | f8355221ae62b89a706f2d04b63eda658f3ccfa5 (patch) | |
tree | 6a01919926776dc5c36ffb825dc69b46ba66fbac /vcl/source | |
parent | 19fb09dce67d29d480ff39c538209b887f661dc9 (diff) |
tdf#85761 vcl: JPEG export does not save PPI values correctly
JPEG values are currently hardcoded to 96PPI when we export JPEGs. The
Graphic class doesn't have an easy way to get the PPI, but this can
actually be calculated from the pref size and pref map mode (no idea
why it is called "Pref").
Interestingly, you need to get a multiplier to work this out, relative
to units of 100th mm. The EPS filter code had a function that does
exactly this, but it's entirely based on MapMode units so it was really
implemented in the wrong class IMO. I have thus moved it out of PSWriter
and into MapMode.
This also fixes tdf#65695, which was partially fixed, but had the JPEG
PPI hardcoded to 96dpi.
Also fixes tdf#97481.
Change-Id: Iedb674141dd4e22fcbfb7be357dc777f732aa3aa
Reviewed-on: https://gerrit.libreoffice.org/22339
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl/source')
-rw-r--r-- | vcl/source/filter/jpeg/JpegWriter.cxx | 6 | ||||
-rw-r--r-- | vcl/source/filter/jpeg/jpeg.h | 4 | ||||
-rw-r--r-- | vcl/source/filter/jpeg/jpegc.cxx | 6 | ||||
-rw-r--r-- | vcl/source/gdi/graph.cxx | 26 | ||||
-rw-r--r-- | vcl/source/gdi/mapmod.cxx | 47 |
5 files changed, 81 insertions, 8 deletions
diff --git a/vcl/source/filter/jpeg/JpegWriter.cxx b/vcl/source/filter/jpeg/JpegWriter.cxx index 94632167e003..35c04797c07f 100644 --- a/vcl/source/filter/jpeg/JpegWriter.cxx +++ b/vcl/source/filter/jpeg/JpegWriter.cxx @@ -227,7 +227,11 @@ bool JPEGWriter::Write( const Graphic& rGraphic ) if( !mbNative ) mpBuffer = new sal_uInt8[ AlignedWidth4Bytes( mbGreys ? mpReadAccess->Width() * 8L : mpReadAccess->Width() * 24L ) ]; - bRet = WriteJPEG( this, &mrStream, mpReadAccess->Width(), mpReadAccess->Height(), mbGreys, mnQuality, maChromaSubsampling, mxStatusIndicator ); + SAL_INFO("vcl", "\nJPEG Export - DPI X: " << rGraphic.GetPPI().getX() << "\nJPEG Export - DPI Y: " << rGraphic.GetPPI().getY()); + + bRet = WriteJPEG( this, &mrStream, mpReadAccess->Width(), + mpReadAccess->Height(), rGraphic.GetPPI(), mbGreys, + mnQuality, maChromaSubsampling, mxStatusIndicator ); delete[] mpBuffer; mpBuffer = nullptr; diff --git a/vcl/source/filter/jpeg/jpeg.h b/vcl/source/filter/jpeg/jpeg.h index 1f8c21f62aac..63c4b2ac3d28 100644 --- a/vcl/source/filter/jpeg/jpeg.h +++ b/vcl/source/filter/jpeg/jpeg.h @@ -24,6 +24,7 @@ #include <com/sun/star/uno/Reference.hxx> #include <sal/types.h> +#include <basegfx/vector/b2dsize.hxx> #include <jpeglib.h> @@ -38,7 +39,8 @@ void jpeg_svstream_src (j_decompress_ptr cinfo, void* infile); void jpeg_svstream_dest (j_compress_ptr cinfo, void* outfile); -bool WriteJPEG( JPEGWriter* pJPEGWriter, void* pOutputStream, long nWidth, long nHeight, bool bGreyScale, +bool WriteJPEG( JPEGWriter* pJPEGWriter, void* pOutputStream, + long nWidth, long nHeight, basegfx::B2DSize aPPI, bool bGreyScale, long nQualityPercent, long aChromaSubsampling, css::uno::Reference<css::task::XStatusIndicator> const & status); diff --git a/vcl/source/filter/jpeg/jpegc.cxx b/vcl/source/filter/jpeg/jpegc.cxx index d42ae785b623..ef3c91c736bf 100644 --- a/vcl/source/filter/jpeg/jpegc.cxx +++ b/vcl/source/filter/jpeg/jpegc.cxx @@ -231,7 +231,7 @@ void ReadJPEG( JPEGReader* pJPEGReader, void* pInputStream, long* pLines, } bool WriteJPEG( JPEGWriter* pJPEGWriter, void* pOutputStream, - long nWidth, long nHeight, bool bGreys, + long nWidth, long nHeight, basegfx::B2DSize aPPI, bool bGreys, long nQualityPercent, long aChromaSubsampling, css::uno::Reference<css::task::XStatusIndicator> const & status ) { @@ -270,8 +270,8 @@ bool WriteJPEG( JPEGWriter* pJPEGWriter, void* pOutputStream, jpeg_set_quality( &cinfo, (int) nQualityPercent, FALSE ); cinfo.density_unit = 1; - cinfo.X_density = 96; - cinfo.Y_density = 96; + cinfo.X_density = aPPI.getX(); + cinfo.Y_density = aPPI.getY(); if ( ( nWidth > 128 ) || ( nHeight > 128 ) ) jpeg_simple_progression( &cinfo ); diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx index 6acf9b19abe3..2c14d8f3bc9a 100644 --- a/vcl/source/gdi/graph.cxx +++ b/vcl/source/gdi/graph.cxx @@ -37,8 +37,8 @@ static void ImplDrawDefault( OutputDevice* pOutDev, const OUString* pText, vcl::Font* pFont, const Bitmap* pBitmap, const BitmapEx* pBitmapEx, const Point& rDestPt, const Size& rDestSize ) { - sal_uInt16 nPixel = (sal_uInt16) pOutDev->PixelToLogic( Size( 1, 1 ) ).Width(); - sal_uInt16 nPixelWidth = nPixel; + sal_uInt16 nPixel = (sal_uInt16) pOutDev->PixelToLogic( Size( 1, 1 ) ).Width(); + sal_uInt16 nPixelWidth = nPixel; Point aPoint( rDestPt.X() + nPixelWidth, rDestPt.Y() + nPixelWidth ); Size aSize( rDestSize.Width() - ( nPixelWidth << 1 ), rDestSize.Height() - ( nPixelWidth << 1 ) ); bool bFilled = ( pBitmap != nullptr || pBitmapEx != nullptr || pFont != nullptr ); @@ -407,6 +407,28 @@ void Graphic::SetPrefMapMode( const MapMode& rPrefMapMode ) mpImpGraphic->ImplSetPrefMapMode( rPrefMapMode ); } +basegfx::B2DSize Graphic::GetPPI() const +{ + MapMode aMapMode = GetPrefMapMode(); + + double fWidthInches = ( GetPrefSize().Width() * aMapMode.GetUnitMultiplier() ) / 2540; + double fHeightInches = ( GetPrefSize().Height() * aMapMode.GetUnitMultiplier() ) / 2540; + double fPpiX = 0; + double fPpiY = 0; + + if ( fWidthInches > 0 || fHeightInches > 0 ) // we don't want a divide by 0 situation + { + fPpiX = GetSizePixel().Width() / fWidthInches; + fPpiY = GetSizePixel().Height() / fHeightInches; + } + else + { + SAL_WARN("vcl", "PPI X is " << fPpiX << " and PPI Y is " << fPpiY << ": thus we are making this 0 DPI. This is unlikely."); + } + + return basegfx::B2DSize( fPpiX, fPpiY ); +} + Size Graphic::GetSizePixel( const OutputDevice* pRefDevice ) const { Size aRet; diff --git a/vcl/source/gdi/mapmod.cxx b/vcl/source/gdi/mapmod.cxx index c95351829bdf..0c4bc512fd62 100644 --- a/vcl/source/gdi/mapmod.cxx +++ b/vcl/source/gdi/mapmod.cxx @@ -25,7 +25,6 @@ #include <tools/vcompat.hxx> #include <tools/debug.hxx> - struct MapMode::ImplMapMode { sal_uLong mnRefCount; @@ -208,6 +207,52 @@ void MapMode::SetScaleY( const Fraction& rScaleY ) mpImplMapMode->maScaleY.ReduceInaccurate(32); } +double MapMode::GetUnitMultiplier() const +{ + double nMul; + switch ( GetMapUnit() ) + { + case MAP_PIXEL : + case MAP_SYSFONT : + case MAP_APPFONT : + + case MAP_100TH_MM : + nMul = 1; + break; + case MAP_10TH_MM : + nMul = 10; + break; + case MAP_MM : + nMul = 100; + break; + case MAP_CM : + nMul = 1000; + break; + case MAP_1000TH_INCH : + nMul = 2.54; + break; + case MAP_100TH_INCH : + nMul = 25.4; + break; + case MAP_10TH_INCH : + nMul = 254; + break; + case MAP_INCH : + nMul = 2540; + break; + case MAP_TWIP : + nMul = 1.76388889; + break; + case MAP_POINT : + nMul = 35.27777778; + break; + default: + nMul = 1.0; + break; + } + return nMul; +} + MapMode& MapMode::operator=( const MapMode& rMapMode ) { DBG_ASSERT( rMapMode.mpImplMapMode->mnRefCount < 0xFFFFFFFE, "MapMode: RefCount overflow" ); |