diff options
author | Armin Le Grand <Armin.Le.Grand@cib.de> | 2017-06-12 15:27:16 +0200 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2017-07-15 11:01:29 +0200 |
commit | 5868745db74ae930edb0058490076d82aaeafbe9 (patch) | |
tree | 78bea29cb44b770d9e3affef2a303d0d38722d85 /vcl/source | |
parent | 83535a28c57ffb59f795dd35332d6b3426071e32 (diff) |
emfplus: make VectorFormats Emf/Wmf/Svg work
make complete turn around and internal buffering
for Emf/Wmf/Svg work, including images in ODF and
re-save from UI. The correct FileType has to be
determined. It has shown that *.wmf exist that really
contain *.emf, so this turn around will not alter
the binary data, but may change the mimetype
Change-Id: I4fd92629236c12114f7b7c30234a3d3a9917dfaf
Diffstat (limited to 'vcl/source')
-rw-r--r-- | vcl/source/filter/graphicfilter.cxx | 86 | ||||
-rw-r--r-- | vcl/source/gdi/impgraph.cxx | 55 | ||||
-rw-r--r-- | vcl/source/gdi/vectorgraphicdata.cxx | 24 |
3 files changed, 133 insertions, 32 deletions
diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx index 98655baffa4a..a436999af548 100644 --- a/vcl/source/filter/graphicfilter.cxx +++ b/vcl/source/filter/graphicfilter.cxx @@ -1766,8 +1766,8 @@ ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, else if( aFilterName.equalsIgnoreAsciiCase( IMP_WMF ) || aFilterName.equalsIgnoreAsciiCase( IMP_EMF ) ) { - static bool bCheckEmf = false; - if (bCheckEmf) + static bool bCheckEmfWmf = true; + if (bCheckEmfWmf) { if (rGraphic.IsDummyContext()) rGraphic.SetDummyContext(false); @@ -1782,14 +1782,20 @@ ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, if (!rIStream.GetError()) { - VectorGraphicDataPtr aVectorGraphicDataPtr(new VectorGraphicData(aNewData, rPath, VectorGraphicDataType::Emf)); + const bool bIsWmf(aFilterName.equalsIgnoreAsciiCase(IMP_WMF)); + const VectorGraphicDataType aDataType(bIsWmf ? VectorGraphicDataType::Wmf : VectorGraphicDataType::Emf); + VectorGraphicDataPtr aVectorGraphicDataPtr( + new VectorGraphicData( + aNewData, + rPath, + aDataType)); rGraphic = Graphic(aVectorGraphicDataPtr); bOkay = true; } if (bOkay) { - eLinkType = GfxLinkType::NativeSvg; + eLinkType = GfxLinkType::NativeWmf; } else { @@ -2114,21 +2120,69 @@ ErrCode GraphicFilter::ExportGraphic( const Graphic& rGraphic, const OUString& r } else if ( aFilterName.equalsIgnoreAsciiCase( EXP_WMF ) ) { - // #i119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically - if ( !ConvertGDIMetaFileToWMF( aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem ) ) - nStatus = ERRCODE_GRFILTER_FORMATERROR; + bool bDone(false); - if( rOStm.GetError() ) - nStatus = ERRCODE_GRFILTER_IOERROR; + // do we have a native Vector Graphic Data RenderGraphic, whose data can be written directly? + const VectorGraphicDataPtr& aVectorGraphicDataPtr(rGraphic.getVectorGraphicData()); + + if (aVectorGraphicDataPtr.get() + && aVectorGraphicDataPtr->getVectorGraphicDataArrayLength() + && VectorGraphicDataType::Wmf == aVectorGraphicDataPtr->getVectorGraphicDataType()) + { + rOStm.WriteBytes(aVectorGraphicDataPtr->getVectorGraphicDataArray().getConstArray(), aVectorGraphicDataPtr->getVectorGraphicDataArrayLength()); + + if (rOStm.GetError()) + { + nStatus = ERRCODE_GRFILTER_IOERROR; + } + else + { + bDone = true; + } + } + + if (!bDone) + { + // #i119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically + if (!ConvertGDIMetaFileToWMF(aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem)) + nStatus = ERRCODE_GRFILTER_FORMATERROR; + + if (rOStm.GetError()) + nStatus = ERRCODE_GRFILTER_IOERROR; + } } else if ( aFilterName.equalsIgnoreAsciiCase( EXP_EMF ) ) { - // #i119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically - if ( !ConvertGDIMetaFileToEMF(aGraphic.GetGDIMetaFile(), rOStm)) - nStatus = ERRCODE_GRFILTER_FORMATERROR; + bool bDone(false); - if( rOStm.GetError() ) - nStatus = ERRCODE_GRFILTER_IOERROR; + // do we have a native Vector Graphic Data RenderGraphic, whose data can be written directly? + const VectorGraphicDataPtr& aVectorGraphicDataPtr(rGraphic.getVectorGraphicData()); + + if (aVectorGraphicDataPtr.get() + && aVectorGraphicDataPtr->getVectorGraphicDataArrayLength() + && VectorGraphicDataType::Emf == aVectorGraphicDataPtr->getVectorGraphicDataType()) + { + rOStm.WriteBytes(aVectorGraphicDataPtr->getVectorGraphicDataArray().getConstArray(), aVectorGraphicDataPtr->getVectorGraphicDataArrayLength()); + + if (rOStm.GetError()) + { + nStatus = ERRCODE_GRFILTER_IOERROR; + } + else + { + bDone = true; + } + } + + if (!bDone) + { + // #i119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically + if (!ConvertGDIMetaFileToEMF(aGraphic.GetGDIMetaFile(), rOStm)) + nStatus = ERRCODE_GRFILTER_FORMATERROR; + + if (rOStm.GetError()) + nStatus = ERRCODE_GRFILTER_IOERROR; + } } else if( aFilterName.equalsIgnoreAsciiCase( EXP_JPEG ) ) { @@ -2199,7 +2253,9 @@ ErrCode GraphicFilter::ExportGraphic( const Graphic& rGraphic, const OUString& r // do we have a native Vector Graphic Data RenderGraphic, whose data can be written directly? const VectorGraphicDataPtr& aVectorGraphicDataPtr(rGraphic.getVectorGraphicData()); - if (aVectorGraphicDataPtr.get() && aVectorGraphicDataPtr->getVectorGraphicDataArrayLength()) + if (aVectorGraphicDataPtr.get() + && aVectorGraphicDataPtr->getVectorGraphicDataArrayLength() + && VectorGraphicDataType::Svg == aVectorGraphicDataPtr->getVectorGraphicDataType()) { rOStm.WriteBytes(aVectorGraphicDataPtr->getVectorGraphicDataArray().getConstArray(), aVectorGraphicDataPtr->getVectorGraphicDataArrayLength()); diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index dfacf2ca49d5..14ccf012b765 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -284,20 +284,13 @@ bool ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const { if(maVectorGraphicData == rImpGraphic.maVectorGraphicData) { + // equal instances bRet = true; } else if(rImpGraphic.maVectorGraphicData) { - if(maVectorGraphicData->getVectorGraphicDataArrayLength() == rImpGraphic.maVectorGraphicData->getVectorGraphicDataArrayLength()) - { - if(0 == memcmp( - maVectorGraphicData->getVectorGraphicDataArray().getConstArray(), - rImpGraphic.maVectorGraphicData->getVectorGraphicDataArray().getConstArray(), - maVectorGraphicData->getVectorGraphicDataArrayLength())) - { - bRet = true; - } - } + // equal content + bRet = (*maVectorGraphicData) == (*rImpGraphic.maVectorGraphicData); } } else if (maPdfData.hasElements()) @@ -1513,12 +1506,14 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic ) // try to stream in Svg defining data (length, byte array and evtl. path) // See below (operator<<) for more information const sal_uInt32 nSvgMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16) | (sal_uInt32('g') << 8) | sal_uInt32('0')); + const sal_uInt32 nWmfMagic((sal_uInt32('w') << 24) | (sal_uInt32('m') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0')); + const sal_uInt32 nEmfMagic((sal_uInt32('e') << 24) | (sal_uInt32('m') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0')); sal_uInt32 nMagic; rIStm.Seek(nStmPos1); rIStm.ResetError(); rIStm.ReadUInt32( nMagic ); - if (nSvgMagic == nMagic) + if (nSvgMagic == nMagic || nWmfMagic == nMagic || nEmfMagic == nMagic) { sal_uInt32 nVectorGraphicDataArrayLength(0); rIStm.ReadUInt32(nVectorGraphicDataArrayLength); @@ -1532,7 +1527,18 @@ void ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic ) if (!rIStm.GetError()) { - VectorGraphicDataPtr aVectorGraphicDataPtr(new VectorGraphicData(aNewData, aPath, VectorGraphicDataType::Svg)); + VectorGraphicDataType aDataType(VectorGraphicDataType::Svg); + + if (nWmfMagic == nMagic) + { + aDataType = VectorGraphicDataType::Wmf; + } + else if (nEmfMagic == nMagic) + { + aDataType = VectorGraphicDataType::Emf; + } + + VectorGraphicDataPtr aVectorGraphicDataPtr(new VectorGraphicData(aNewData, aPath, aDataType)); rImpGraphic = aVectorGraphicDataPtr; } } @@ -1606,13 +1612,32 @@ void WriteImpGraphic(SvStream& rOStm, const ImpGraphic& rImpGraphic) { if(rImpGraphic.getVectorGraphicData().get()) { - // stream out Svg defining data (length, byte array and evtl. path) + // stream out Vector GHraphic defining data (length, byte array and evtl. path) // this is used e.g. in swapping out graphic data and in transporting it over UNO API // as sequence of bytes, but AFAIK not written anywhere to any kind of file, so it should be // no problem to extend it; only used at runtime - const sal_uInt32 nSvgMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16) | (sal_uInt32('g') << 8) | sal_uInt32('0')); + switch (rImpGraphic.getVectorGraphicData()->getVectorGraphicDataType()) + { + case VectorGraphicDataType::Wmf: + { + const sal_uInt32 nWmfMagic((sal_uInt32('w') << 24) | (sal_uInt32('m') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0')); + rOStm.WriteUInt32(nWmfMagic); + break; + } + case VectorGraphicDataType::Emf: + { + const sal_uInt32 nEmfMagic((sal_uInt32('e') << 24) | (sal_uInt32('m') << 16) | (sal_uInt32('f') << 8) | sal_uInt32('0')); + rOStm.WriteUInt32(nEmfMagic); + break; + } + default: // case VectorGraphicDataType::Svg: + { + const sal_uInt32 nSvgMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16) | (sal_uInt32('g') << 8) | sal_uInt32('0')); + rOStm.WriteUInt32(nSvgMagic); + break; + } + } - rOStm.WriteUInt32( nSvgMagic ); rOStm.WriteUInt32( rImpGraphic.getVectorGraphicData()->getVectorGraphicDataArrayLength() ); rOStm.WriteBytes(rImpGraphic.getVectorGraphicData()->getVectorGraphicDataArray().getConstArray(), rImpGraphic.getVectorGraphicData()->getVectorGraphicDataArrayLength()); diff --git a/vcl/source/gdi/vectorgraphicdata.cxx b/vcl/source/gdi/vectorgraphicdata.cxx index bb18ccc925bf..d68cb80333ad 100644 --- a/vcl/source/gdi/vectorgraphicdata.cxx +++ b/vcl/source/gdi/vectorgraphicdata.cxx @@ -106,6 +106,25 @@ size_t estimateSize( return nRet; } +bool VectorGraphicData::operator==(const VectorGraphicData& rCandidate) const +{ + if (getVectorGraphicDataType() == rCandidate.getVectorGraphicDataType()) + { + if (getVectorGraphicDataArrayLength() == rCandidate.getVectorGraphicDataArrayLength()) + { + if (0 == memcmp( + getVectorGraphicDataArray().getConstArray(), + rCandidate.getVectorGraphicDataArray().getConstArray(), + getVectorGraphicDataArrayLength())) + { + return true; + } + } + } + + return false; +} + void VectorGraphicData::ensureReplacement() { ensureSequenceAndRange(); @@ -128,12 +147,13 @@ void VectorGraphicData::ensureSequenceAndRange() if(myInputStream.is()) { - // create SVG interpreter + // create Vector Graphic Data interpreter try { uno::Reference<uno::XComponentContext> xContext(::comphelper::getProcessComponentContext()); - if (VectorGraphicDataType::Emf == getVectorGraphicDataType()) + if (VectorGraphicDataType::Emf == getVectorGraphicDataType() + || VectorGraphicDataType::Wmf == getVectorGraphicDataType()) { const uno::Reference< graphic::XEmfParser > xEmfParser = graphic::EmfTools::create(xContext); |