[Libreoffice-commits] core.git: Branch 'feature/emfplusprimitiveparser' - drawinglayer/source emfio/inc emfio/source include/drawinglayer include/oox include/vcl offapi/com oox/source svtools/source vcl/Library_vcl.mk vcl/qa vcl/source writerfilter/source xmlsecurity/workben
Armin Le Grand
Armin.Le.Grand at cib.de
Fri Jun 16 15:19:00 UTC 2017
drawinglayer/source/primitive2d/metafileprimitive2d.cxx | 7
emfio/inc/wmfreader.hxx | 8
emfio/source/emfuno/xemfparser.cxx | 161 -
emfio/source/reader/mtftools.cxx | 3
emfio/source/reader/wmfreader.cxx | 54
include/drawinglayer/primitive2d/metafileprimitive2d.hxx | 6
include/oox/helper/graphichelper.hxx | 8
include/vcl/gdimetafiletools.hxx | 9
include/vcl/graphicfilter.hxx | 6
include/vcl/vectorgraphicdata.hxx | 11
include/vcl/wmf.hxx | 33
include/vcl/wmfexternal.hxx | 55
offapi/com/sun/star/graphic/XEmfParser.idl | 8
oox/source/drawingml/shape.cxx | 2
oox/source/helper/graphichelper.cxx | 6
oox/source/vml/vmlshape.cxx | 2
svtools/source/graphic/provider.cxx | 4
vcl/Library_vcl.mk | 4
vcl/qa/cppunit/wmf/wmfimporttest.cxx | 1
vcl/source/filter/graphicfilter.cxx | 72
vcl/source/filter/wmf/enhwmf.cxx | 1966 -------------
vcl/source/filter/wmf/winmtf.cxx | 2248 ---------------
vcl/source/filter/wmf/winmtf.hxx | 723 ----
vcl/source/filter/wmf/winwmf.cxx | 1836 ------------
vcl/source/filter/wmf/wmf.cxx | 73
vcl/source/filter/wmf/wmfexternal.cxx | 76
vcl/source/gdi/impgraph.cxx | 27
vcl/source/gdi/vectorgraphicdata.cxx | 32
writerfilter/source/rtftok/rtfdocumentimpl.cxx | 4
xmlsecurity/workben/pdfverify.cxx | 2
30 files changed, 408 insertions(+), 7039 deletions(-)
New commits:
commit e76f931777616c10660ef11d3b348efb3107a23b
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date: Fri Jun 16 17:16:22 2017 +0200
emfplus: completed isolation/migration of Emf/Wmf
Decided to keep the migrated/isolated Emf/Wmf reader
which are now hidden behind a Uno Api. Had to re-implement
WMF_EXTERNALHEADER (now WmfExternal, own file/header)
to not break anything. It *seems* to just scale something
and could be done after import, but I could not be sure.
Also needed a callback hook to allow getting the Metafile
out of a MetafilePrimitive in a lower module (vcl relative
to drawinglayer) which is needed as long as primitives
are not completely on Uno Api. Deleted all Emf/Wmf reader
stuff from vcl.
Change-Id: Ic5540defa8ec770728280df4df3f12e1f48cfc3a
diff --git a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
index e07033aa50d5..4737f78c765b 100644
--- a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
@@ -3244,6 +3244,13 @@ namespace drawinglayer
return aRetval;
}
+ // from MetafileAccessor
+ bool MetafilePrimitive2D::accessMetafile(GDIMetaFile& rTargetMetafile) const
+ {
+ rTargetMetafile = maMetaFile;
+ return true;
+ }
+
// provide unique ID
ImplPrimitive2DIDBlock(MetafilePrimitive2D, PRIMITIVE2D_ID_METAFILEPRIMITIVE2D)
diff --git a/emfio/inc/wmfreader.hxx b/emfio/inc/wmfreader.hxx
index e0566bb95cfb..1cd6077b05d8 100644
--- a/emfio/inc/wmfreader.hxx
+++ b/emfio/inc/wmfreader.hxx
@@ -23,6 +23,9 @@
#include <mtftools.hxx>
#include <tools/stream.hxx>
+// predefines
+struct WmfExternal;
+
namespace emfio
{
class WmfReader : public MtfTools
@@ -46,6 +49,9 @@ namespace emfio
sal_uInt32 mnSkipActions;
sal_uInt32 mnCurrentAction;
+ // eventually handed over external header
+ const WmfExternal* mpExternalHeader;
+
// reads header of the WMF-Datei
bool ReadHeader();
@@ -59,7 +65,7 @@ namespace emfio
void GetPlaceableBound(tools::Rectangle& rSize, SvStream* pStrm);
public:
- WmfReader(SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile);
+ WmfReader(SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile, const WmfExternal* pExternalHeader);
// read WMF file from stream and fill the GDIMetaFile
void ReadWMF();
diff --git a/emfio/source/emfuno/xemfparser.cxx b/emfio/source/emfuno/xemfparser.cxx
index 89d34dff1521..433210c5ecd2 100644
--- a/emfio/source/emfuno/xemfparser.cxx
+++ b/emfio/source/emfuno/xemfparser.cxx
@@ -33,7 +33,6 @@
#include <vcl/svapp.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
-#include <vcl/wmf.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
@@ -69,7 +68,8 @@ namespace emfio
// XEmfParser
virtual uno::Sequence< uno::Reference< ::graphic::XPrimitive2D > > SAL_CALL getDecomposition(
const uno::Reference< ::io::XInputStream >& xEmfStream,
- const OUString& aAbsolutePath) override;
+ const OUString& aAbsolutePath,
+ const uno::Sequence< ::beans::PropertyValue >& rProperties) override;
// XServiceInfo
virtual OUString SAL_CALL getImplementationName() override;
@@ -113,114 +113,85 @@ namespace emfio
uno::Sequence< uno::Reference< ::graphic::XPrimitive2D > > XEmfParser::getDecomposition(
const uno::Reference< ::io::XInputStream >& xEmfStream,
- const OUString& aAbsolutePath )
+ const OUString& aAbsolutePath,
+ const uno::Sequence< ::beans::PropertyValue >& rProperties)
{
drawinglayer::primitive2d::Primitive2DContainer aRetval;
if (xEmfStream.is())
{
- static bool bTestCode(false);
+ WmfExternal aExternalHeader;
+ const bool bExternalHeaderUsed(aExternalHeader.setSequence(rProperties));
- if (bTestCode)
+ // rough check - import and conv to primitive
+ GDIMetaFile aMtf;
+ std::unique_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream(xEmfStream));
+ sal_uInt32 nMetaType(0);
+ sal_uInt32 nOrgPos = pStream->Tell();
+
+ SvStreamEndian nOrigNumberFormat = pStream->GetEndian();
+ pStream->SetEndian(SvStreamEndian::LITTLE);
+
+ pStream->Seek(0x28);
+ pStream->ReadUInt32(nMetaType);
+ pStream->Seek(nOrgPos);
+
+ if (nMetaType == 0x464d4520)
+ {
+ emfio::EmfReader(*pStream, aMtf).ReadEnhWMF();
+ }
+ else
+ {
+ emfio::WmfReader(*pStream, aMtf, bExternalHeaderUsed ? &aExternalHeader : nullptr).ReadWMF();
+ }
+
+ pStream->SetEndian(nOrigNumberFormat);
+ Size aSize(aMtf.GetPrefSize());
+
+ if (aMtf.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel)
{
- static bool bUseOldFilterEmbedded(true);
-
- if (bUseOldFilterEmbedded)
- {
- GDIMetaFile aMtf;
- std::unique_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream(xEmfStream));
-
- if (pStream && ConvertWMFToGDIMetaFile(*pStream, aMtf, nullptr, nullptr))
- {
-
- Size aSize(aMtf.GetPrefSize());
-
- if (aMtf.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel)
- {
- aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, MapUnit::Map100thMM);
- }
- else
- {
- aSize = OutputDevice::LogicToLogic(aSize, aMtf.GetPrefMapMode(), MapMode(MapUnit::Map100thMM));
- }
-
- const basegfx::B2DHomMatrix aMetafileTransform(
- basegfx::tools::createScaleB2DHomMatrix(
- aSize.Width(),
- aSize.Height()));
-
- aRetval.push_back(
- new drawinglayer::primitive2d::MetafilePrimitive2D(
- aMetafileTransform,
- aMtf));
- }
- }
-
- if(aRetval.empty())
- {
- // for test, just create some graphic data that will get visualized
- const basegfx::B2DRange aRange(1000, 1000, 5000, 5000);
- const basegfx::BColor aColor(1.0, 0.0, 0.0);
- const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange));
-
- aRetval.push_back(new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aOutline), aColor));
- }
+ aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, MapUnit::Map100thMM);
}
else
{
- // new parser here
- bool bBla = true;
-
- // rouch check - import and conv to primitive
- GDIMetaFile aMtf;
- std::unique_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream(xEmfStream));
- sal_uInt32 nMetaType(0);
- sal_uInt32 nOrgPos = pStream->Tell();
-
- SvStreamEndian nOrigNumberFormat = pStream->GetEndian();
- pStream->SetEndian(SvStreamEndian::LITTLE);
-
- pStream->Seek(0x28);
- pStream->ReadUInt32(nMetaType);
- pStream->Seek(nOrgPos);
-
- if (nMetaType == 0x464d4520)
- {
- emfio::EmfReader(*pStream, aMtf).ReadEnhWMF();
- }
- else
- {
- emfio::WmfReader(*pStream, aMtf).ReadWMF();
- }
-
- pStream->SetEndian(nOrigNumberFormat);
- Size aSize(aMtf.GetPrefSize());
-
- if (aMtf.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel)
- {
- aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, MapUnit::Map100thMM);
- }
- else
- {
- aSize = OutputDevice::LogicToLogic(aSize, aMtf.GetPrefMapMode(), MapMode(MapUnit::Map100thMM));
- }
-
- const basegfx::B2DHomMatrix aMetafileTransform(
- basegfx::tools::createScaleB2DHomMatrix(
- aSize.Width(),
- aSize.Height()));
-
- // force to use decomposition directly to get rid of the metafile
- const css::uno::Sequence< css::beans::PropertyValue > aViewParameters;
- drawinglayer::primitive2d::MetafilePrimitive2D aMetafilePrimitive2D(
+ aSize = OutputDevice::LogicToLogic(aSize, aMtf.GetPrefMapMode(), MapMode(MapUnit::Map100thMM));
+ }
+
+ // use size
+ const basegfx::B2DHomMatrix aMetafileTransform(
+ basegfx::tools::createScaleB2DHomMatrix(
+ aSize.Width(),
+ aSize.Height()));
+
+ // ...and create a single MetafilePrimitive2D containing the Metafile.
+ // CAUTION: Currently, ReadWindowMetafile uses the local VectorGraphicData
+ // and a MetafileAccessor hook at the MetafilePrimitive2D inside of
+ // ImpGraphic::ImplGetGDIMetaFile to get the Metafile. Thus, the first
+ // and only primitive in this case *has to be* a MetafilePrimitive2D.
+ aRetval.push_back(
+ new drawinglayer::primitive2d::MetafilePrimitive2D(
aMetafileTransform,
- aMtf);
- aRetval.append(aMetafilePrimitive2D.getDecomposition(aViewParameters));
+ aMtf));
+ // // force to use decomposition directly to get rid of the metafile
+ // const css::uno::Sequence< css::beans::PropertyValue > aViewParameters;
+ // drawinglayer::primitive2d::MetafilePrimitive2D aMetafilePrimitive2D(
+ // aMetafileTransform,
+ // aMtf);
+ // aRetval.append(aMetafilePrimitive2D.getDecomposition(aViewParameters));
+
+ // if (aRetval.empty())
+ // {
+ // // for test, just create some graphic data that will get visualized
+ // const basegfx::B2DRange aRange(1000, 1000, 5000, 5000);
+ // const basegfx::BColor aColor(1.0, 0.0, 0.0);
+ // const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange));
+ //
+ // aRetval.push_back(new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aOutline), aColor));
+ // }
- }
}
else
{
diff --git a/emfio/source/reader/mtftools.cxx b/emfio/source/reader/mtftools.cxx
index 96d4d5232e7e..05b8cf43bed0 100644
--- a/emfio/source/reader/mtftools.cxx
+++ b/emfio/source/reader/mtftools.cxx
@@ -20,13 +20,10 @@
#include <mtftools.hxx>
#include <memory>
-//#include "winmtf.hxx"
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
-//#include <vcl/metaact.hxx>
#include <vcl/graphictools.hxx>
#include <vcl/canvastools.hxx>
-//#include <vcl/metric.hxx>
#include <vcl/svapp.hxx>
#include <tools/fract.hxx>
#include <rtl/strbuf.hxx>
diff --git a/emfio/source/reader/wmfreader.cxx b/emfio/source/reader/wmfreader.cxx
index dd41a7a1abbb..9cbe518d7e28 100644
--- a/emfio/source/reader/wmfreader.cxx
+++ b/emfio/source/reader/wmfreader.cxx
@@ -1242,26 +1242,45 @@ namespace emfio
{
mnUnitsPerInch = 96;
+ if (mpExternalHeader != nullptr
+ && mpExternalHeader->xExt > 0
+ && mpExternalHeader->yExt > 0
+ && (mpExternalHeader->mapMode == MM_ISOTROPIC || mpExternalHeader->mapMode == MM_ANISOTROPIC))
+ {
+ // #n417818#: If we have an external header then overwrite the bounds!
+ tools::Rectangle aExtRect(0, 0,
+ (double)mpExternalHeader->xExt * 567 * mnUnitsPerInch / 1440000,
+ (double)mpExternalHeader->yExt * 567 * mnUnitsPerInch / 1440000);
+ aPlaceableBound = aExtRect;
+
+ SAL_INFO("vcl.wmf", "External header size "
+ " t: " << aPlaceableBound.Left() << " l: " << aPlaceableBound.Top()
+ << " b: " << aPlaceableBound.Right() << " r: " << aPlaceableBound.Bottom());
- mpInputStream->Seek( nStrmPos + 18 ); // set the streampos to the start of the metaactions
- GetPlaceableBound( aPlaceableBound, mpInputStream );
-
- // The image size is not known so normalize the calculated bounds so that the
- // resulting image is not too big
- const double fMaxWidth = static_cast<double>(aMaxWidth);
- if (aPlaceableBound.GetWidth() > aMaxWidth)
+ SetMapMode(mpExternalHeader->mapMode);
+ }
+ else
{
- double fRatio = aPlaceableBound.GetWidth() / fMaxWidth;
+ mpInputStream->Seek(nStrmPos + 18); // set the streampos to the start of the metaactions
+ GetPlaceableBound(aPlaceableBound, mpInputStream);
- aPlaceableBound = tools::Rectangle(
- aPlaceableBound.Left() / fRatio,
- aPlaceableBound.Top() / fRatio,
- aPlaceableBound.Right() / fRatio,
- aPlaceableBound.Bottom() / fRatio);
+ // The image size is not known so normalize the calculated bounds so that the
+ // resulting image is not too big
+ const double fMaxWidth = static_cast<double>(aMaxWidth);
+ if (aPlaceableBound.GetWidth() > aMaxWidth)
+ {
+ double fRatio = aPlaceableBound.GetWidth() / fMaxWidth;
- SAL_INFO("vcl.wmf", "Placeable bounds "
- " t: " << aPlaceableBound.Left() << " l: " << aPlaceableBound.Top()
- << " b: " << aPlaceableBound.Right() << " r: " << aPlaceableBound.Bottom());
+ aPlaceableBound = tools::Rectangle(
+ aPlaceableBound.Left() / fRatio,
+ aPlaceableBound.Top() / fRatio,
+ aPlaceableBound.Right() / fRatio,
+ aPlaceableBound.Bottom() / fRatio);
+
+ SAL_INFO("vcl.wmf", "Placeable bounds "
+ " t: " << aPlaceableBound.Left() << " l: " << aPlaceableBound.Top()
+ << " b: " << aPlaceableBound.Right() << " r: " << aPlaceableBound.Bottom());
+ }
}
mpInputStream->Seek( nStrmPos );
@@ -1800,7 +1819,7 @@ namespace emfio
}
}
- WmfReader::WmfReader(SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile)
+ WmfReader::WmfReader(SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile, const WmfExternal* pExternalHeader)
: MtfTools(rGDIMetaFile, rStreamWMF)
, mnUnitsPerInch(96)
, mnRecSize(0)
@@ -1810,6 +1829,7 @@ namespace emfio
, mnEMFSize(0)
, mnSkipActions(0)
, mnCurrentAction(0)
+ , mpExternalHeader(pExternalHeader)
{
}
}
diff --git a/include/drawinglayer/primitive2d/metafileprimitive2d.hxx b/include/drawinglayer/primitive2d/metafileprimitive2d.hxx
index 0d1503809a81..e849e38b5752 100644
--- a/include/drawinglayer/primitive2d/metafileprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/metafileprimitive2d.hxx
@@ -25,6 +25,7 @@
#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <vcl/gdimtf.hxx>
+#include <vcl/gdimetafiletools.hxx>
// MetafilePrimitive2D class
@@ -53,7 +54,7 @@ namespace drawinglayer
have many advantages; Metafile would no longer have to be rendered by
sub-systems and a standard way for converting Metafiles would exist.
*/
- class DRAWINGLAYER_DLLPUBLIC MetafilePrimitive2D : public BufferedDecompositionPrimitive2D
+ class DRAWINGLAYER_DLLPUBLIC MetafilePrimitive2D : public BufferedDecompositionPrimitive2D, public MetafileAccessor
{
private:
/// the geometry definition
@@ -81,6 +82,9 @@ namespace drawinglayer
/// get range
virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const override;
+ /// from MetafileAccessor
+ virtual bool accessMetafile(GDIMetaFile& rTargetMetafile) const;
+
/// provide unique ID
DeclPrimitive2DIDBlock()
};
diff --git a/include/oox/helper/graphichelper.hxx b/include/oox/helper/graphichelper.hxx
index 651e9407b4ec..545bdd0fd938 100644
--- a/include/oox/helper/graphichelper.hxx
+++ b/include/oox/helper/graphichelper.hxx
@@ -33,7 +33,7 @@
#include <sal/types.h>
#include <com/sun/star/graphic/XGraphicProvider2.hpp>
-struct WMF_EXTERNALHEADER;
+struct WmfExternal;
namespace com { namespace sun { namespace star {
namespace awt { struct Point; }
@@ -113,7 +113,7 @@ public:
css::uno::Reference< css::graphic::XGraphic >
importGraphic(
const css::uno::Reference< css::io::XInputStream >& rxInStrm,
- const WMF_EXTERNALHEADER* pExtHeader = nullptr ) const;
+ const WmfExternal* pExtHeader = nullptr ) const;
/** Imports graphics from the passed input streams. */
std::vector< css::uno::Reference<css::graphic::XGraphic> >
@@ -127,7 +127,7 @@ public:
css::uno::Reference< css::graphic::XGraphic >
importEmbeddedGraphic(
const OUString& rStreamName,
- const WMF_EXTERNALHEADER* pExtHeader = nullptr ) const;
+ const WmfExternal* pExtHeader = nullptr ) const;
/** Imports graphics from the storage with the passed stream names. */
void importEmbeddedGraphics(const std::vector<OUString>& rStreamNames) const;
@@ -141,7 +141,7 @@ public:
@return The URL of the created and internally cached graphic object. */
OUString importGraphicObject(
const css::uno::Reference< css::io::XInputStream >& rxInStrm,
- const WMF_EXTERNALHEADER* pExtHeader ) const;
+ const WmfExternal* pExtHeader ) const;
/** Creates a persistent graphic object from the passed binary memory block.
@return The URL of the created and internally cached graphic object. */
diff --git a/include/vcl/gdimetafiletools.hxx b/include/vcl/gdimetafiletools.hxx
index 592c70714bfd..ea47ced5032e 100644
--- a/include/vcl/gdimetafiletools.hxx
+++ b/include/vcl/gdimetafiletools.hxx
@@ -39,6 +39,15 @@ void VCL_DLLPUBLIC clipMetafileContentAgainstOwnRegions(GDIMetaFile& rSource);
bool VCL_DLLPUBLIC usesClipActions(const GDIMetaFile& rSource);
+// hook to access metafile members in classes of modules above vcl. Currently
+// used in MetafilePrimitive2D to be able to access the local Metafile member
+// e.g. from vcl module
+class VCL_DLLPUBLIC MetafileAccessor
+{
+public:
+ virtual bool accessMetafile(GDIMetaFile& rTargetMetafile) const = 0;
+};
+
#endif // INCLUDED_VCL_GDIMETAFILETOOLS_HXX
diff --git a/include/vcl/graphicfilter.hxx b/include/vcl/graphicfilter.hxx
index 01b6e07f58d0..73adc2013e0b 100644
--- a/include/vcl/graphicfilter.hxx
+++ b/include/vcl/graphicfilter.hxx
@@ -33,7 +33,7 @@
class FilterConfigCache;
class SvStream;
-struct WMF_EXTERNALHEADER;
+struct WmfExternal;
struct ConvertData;
#define ERRCODE_GRFILTER_OPENERROR (ERRCODE_AREA_VCL | ERRCODE_CLASS_GENERAL | 1)
@@ -281,7 +281,7 @@ public:
SvStream& rStream,
sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW,
sal_uInt16 * pDeterminedFormat = nullptr, GraphicFilterImportFlags nImportFlags = GraphicFilterImportFlags::NONE,
- WMF_EXTERNALHEADER *pExtHeader = nullptr );
+ WmfExternal *pExtHeader = nullptr );
/// Imports multiple graphics.
///
@@ -293,7 +293,7 @@ public:
sal_uInt16 nFormat,
sal_uInt16 * pDeterminedFormat, GraphicFilterImportFlags nImportFlags,
css::uno::Sequence< css::beans::PropertyValue >* pFilterData,
- WMF_EXTERNALHEADER *pExtHeader = nullptr );
+ WmfExternal *pExtHeader = nullptr );
const FilterErrorEx& GetLastError() const { return *pErrorEx;}
void ResetLastError();
diff --git a/include/vcl/vectorgraphicdata.hxx b/include/vcl/vectorgraphicdata.hxx
index 6a259a5567e3..a045b01ee46e 100644
--- a/include/vcl/vectorgraphicdata.hxx
+++ b/include/vcl/vectorgraphicdata.hxx
@@ -23,6 +23,7 @@
#include <basegfx/range/b2drange.hxx>
#include <com/sun/star/graphic/XPrimitive2D.hpp>
#include <vcl/bitmapex.hxx>
+#include <vcl/wmfexternal.hxx>
#include <rtl/ustring.hxx>
#include <deque>
@@ -57,12 +58,14 @@ private:
// on demand created content
basegfx::B2DRange maRange;
- std::deque< css::uno::Reference< css::graphic::XPrimitive2D > >
- maSequence;
+ std::deque< css::uno::Reference< css::graphic::XPrimitive2D > > maSequence;
BitmapEx maReplacement;
size_t mNestedBitmapSize;
VectorGraphicDataType meVectorGraphicDataType;
+ // extra:
+ WmfExternal* mpExternalHeader;
+
// on demand creators
void ensureReplacement();
void ensureSequenceAndRange();
@@ -78,10 +81,14 @@ public:
VectorGraphicData(
const OUString& rPath,
VectorGraphicDataType eVectorDataType);
+ ~VectorGraphicData();
/// compare op
bool operator==(const VectorGraphicData& rCandidate) const;
+ /// special: needed for emf/wmf, maybe replaced by scaling the result later (?)
+ void setWmfExternalHeader(const WmfExternal& aExtHeader);
+
/// data read
const VectorGraphicDataArray& getVectorGraphicDataArray() const { return maVectorGraphicDataArray; }
sal_uInt32 getVectorGraphicDataArrayLength() const { return maVectorGraphicDataArray.getLength(); }
diff --git a/include/vcl/wmf.hxx b/include/vcl/wmf.hxx
index 67d6aa4f122b..c172cd45e86b 100644
--- a/include/vcl/wmf.hxx
+++ b/include/vcl/wmf.hxx
@@ -25,38 +25,7 @@
class FilterConfigItem;
class GDIMetaFile;
class SvStream;
-
-struct WMF_EXTERNALHEADER
-{
- sal_uInt16 xExt;
- sal_uInt16 yExt;
-
- /** One of the following values:
- <ul>
- <li>MM_TEXT</li>
- <li>MM_LOMETRIC</li>
- <li>MM_HIMETRIC</li>
- <li>MM_LOENGLISH</li>
- <li>MM_HIENGLISH</li>
- <li>MM_TWIPS</li>
- <li>MM_ISOTROPIC</li>
- <li>MM_ANISOTROPIC</li>
- </ul>
- If this value is 0, then no external mapmode has been defined,
- the internal one should then be used.
- */
- sal_uInt16 mapMode;
-
- WMF_EXTERNALHEADER() :
- xExt( 0 ),
- yExt( 0 ),
- mapMode( 0 )
- {
- }
-};
-
-// for 1st test, export
-VCL_DLLPUBLIC bool ConvertWMFToGDIMetaFile( SvStream & rStreamWMF, GDIMetaFile & rGDIMetaFile, FilterConfigItem* pConfigItem, WMF_EXTERNALHEADER *pExtHeader );
+struct WmfExternal;
VCL_DLLPUBLIC bool ReadWindowMetafile( SvStream& rStream, GDIMetaFile& rMTF );
diff --git a/include/vcl/wmfexternal.hxx b/include/vcl/wmfexternal.hxx
new file mode 100644
index 000000000000..30c58ab0bcb0
--- /dev/null
+++ b/include/vcl/wmfexternal.hxx
@@ -0,0 +1,55 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_VCL_WMFEXTERNAL_HXX
+#define INCLUDED_VCL_WMFEXTERNAL_HXX
+
+#include <vcl/dllapi.h>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+struct VCL_DLLPUBLIC WmfExternal
+{
+ sal_uInt16 xExt;
+ sal_uInt16 yExt;
+
+ /** One of the following values:
+ <ul>
+ <li>MM_TEXT</li>
+ <li>MM_LOMETRIC</li>
+ <li>MM_HIMETRIC</li>
+ <li>MM_LOENGLISH</li>
+ <li>MM_HIENGLISH</li>
+ <li>MM_TWIPS</li>
+ <li>MM_ISOTROPIC</li>
+ <li>MM_ANISOTROPIC</li>
+ </ul>
+ If this value is 0, then no external mapmode has been defined,
+ the internal one should then be used.
+ */
+ sal_uInt16 mapMode;
+
+ WmfExternal();
+ css::uno::Sequence< css::beans::PropertyValue > getSequence() const;
+ bool setSequence(const css::uno::Sequence< css::beans::PropertyValue >& rSequence);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/offapi/com/sun/star/graphic/XEmfParser.idl b/offapi/com/sun/star/graphic/XEmfParser.idl
index 6c55a8a0b963..42cb2cbe6459 100644
--- a/offapi/com/sun/star/graphic/XEmfParser.idl
+++ b/offapi/com/sun/star/graphic/XEmfParser.idl
@@ -41,10 +41,14 @@ interface XEmfParser : ::com::sun::star::uno::XInterface
@param aAbsolutePath
The path containing the WMF/EMF/EMF+ data
- */
+
+ @param Properties
+ Optional values to override MapMode and size
+*/
sequence< XPrimitive2D > getDecomposition(
[in] io::XInputStream xEmfStream,
- [in] string aAbsolutePath);
+ [in] string aAbsolutePath,
+ [in] ::com::sun::star::beans::PropertyValues Properties);
};
}; }; }; };
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 7d04518b5f25..72927d116cd0 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -1291,7 +1291,7 @@ OUString Shape::finalizeServiceName( XmlFilterBase& rFilter, const OUString& rSe
if( !aGraphicPath.isEmpty() )
{
// Transfer shape's width and height to graphicsfilter (can be used by WMF/EMF)
- WMF_EXTERNALHEADER aExtHeader;
+ WmfExternal aExtHeader;
aExtHeader.mapMode = 8; // MM_ANISOTROPIC
aExtHeader.xExt = rShapeRect.Width;
aExtHeader.yExt = rShapeRect.Height;
diff --git a/oox/source/helper/graphichelper.cxx b/oox/source/helper/graphichelper.cxx
index 30c570b01eec..6c150729a589 100644
--- a/oox/source/helper/graphichelper.cxx
+++ b/oox/source/helper/graphichelper.cxx
@@ -234,7 +234,7 @@ awt::Size GraphicHelper::convertHmmToAppFont( const awt::Size& rHmm ) const
// Graphics and graphic objects ----------------------------------------------
Reference< XGraphic > GraphicHelper::importGraphic( const Reference< XInputStream >& rxInStrm,
- const WMF_EXTERNALHEADER* pExtHeader ) const
+ const WmfExternal* pExtHeader ) const
{
Reference< XGraphic > xGraphic;
if( rxInStrm.is() && mxGraphicProvider.is() ) try
@@ -331,7 +331,7 @@ void GraphicHelper::importEmbeddedGraphics(const std::vector<OUString>& rStreamN
}
}
-Reference< XGraphic > GraphicHelper::importEmbeddedGraphic( const OUString& rStreamName, const WMF_EXTERNALHEADER* pExtHeader ) const
+Reference< XGraphic > GraphicHelper::importEmbeddedGraphic( const OUString& rStreamName, const WmfExternal* pExtHeader ) const
{
Reference< XGraphic > xGraphic;
OSL_ENSURE( !rStreamName.isEmpty(), "GraphicHelper::importEmbeddedGraphic - empty stream name" );
@@ -367,7 +367,7 @@ OUString GraphicHelper::createGraphicObject( const Reference< XGraphic >& rxGrap
}
OUString GraphicHelper::importGraphicObject( const Reference< XInputStream >& rxInStrm,
- const WMF_EXTERNALHEADER* pExtHeader ) const
+ const WmfExternal* pExtHeader ) const
{
return createGraphicObject( importGraphic( rxInStrm, pExtHeader ) );
}
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index 8d85b14701fb..c51afb75d40b 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -1141,7 +1141,7 @@ Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes
// set the replacement graphic
if( !aGraphicPath.isEmpty() )
{
- WMF_EXTERNALHEADER aExtHeader;
+ WmfExternal aExtHeader;
aExtHeader.mapMode = 8;
aExtHeader.xExt = rShapeRect.Width;
aExtHeader.yExt = rShapeRect.Height;
diff --git a/svtools/source/graphic/provider.cxx b/svtools/source/graphic/provider.cxx
index 1bdcee7812a9..f837b0b9ef0a 100644
--- a/svtools/source/graphic/provider.cxx
+++ b/svtools/source/graphic/provider.cxx
@@ -413,11 +413,11 @@ uno::Reference< ::graphic::XGraphic > SAL_CALL GraphicProvider::queryGraphic( co
::Graphic aVCLGraphic;
// Define APM Header if goal height and width are defined
- WMF_EXTERNALHEADER aExtHeader;
+ WmfExternal aExtHeader;
aExtHeader.xExt = nExtWidth;
aExtHeader.yExt = nExtHeight;
aExtHeader.mapMode = nExtMapMode;
- WMF_EXTERNALHEADER *pExtHeader = nullptr;
+ WmfExternal *pExtHeader = nullptr;
if ( nExtMapMode > 0 )
pExtHeader = &aExtHeader;
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 9735c606a1a8..2ad89aced588 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -373,10 +373,8 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/filter/jpeg/JpegWriter \
vcl/source/filter/jpeg/JpegTransform \
vcl/source/filter/wmf/emfwr \
- vcl/source/filter/wmf/enhwmf \
- vcl/source/filter/wmf/winmtf \
- vcl/source/filter/wmf/winwmf \
vcl/source/filter/wmf/wmf \
+ vcl/source/filter/wmf/wmfexternal \
vcl/source/filter/wmf/wmfwr \
vcl/source/font/PhysicalFontCollection \
vcl/source/font/PhysicalFontFace \
diff --git a/vcl/qa/cppunit/wmf/wmfimporttest.cxx b/vcl/qa/cppunit/wmf/wmfimporttest.cxx
index ca9900c18ad9..40ac1d5b02af 100644
--- a/vcl/qa/cppunit/wmf/wmfimporttest.cxx
+++ b/vcl/qa/cppunit/wmf/wmfimporttest.cxx
@@ -23,7 +23,6 @@
#include <unotest/bootstrapfixturebase.hxx>
#include <vcl/wmf.hxx>
#include <vcl/metaact.hxx>
-#include <winmtf.hxx>
using namespace css;
diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx
index 84314080e265..491d27645d68 100644
--- a/vcl/source/filter/graphicfilter.cxx
+++ b/vcl/source/filter/graphicfilter.cxx
@@ -1312,7 +1312,7 @@ ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const INetURLObject& rP
}
sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, SvStream& rIStream,
- sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, GraphicFilterImportFlags nImportFlags, WMF_EXTERNALHEADER *pExtHeader )
+ sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, GraphicFilterImportFlags nImportFlags, WmfExternal *pExtHeader )
{
return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, nullptr, pExtHeader );
}
@@ -1467,7 +1467,7 @@ void GraphicFilter::ImportGraphics(std::vector< std::shared_ptr<Graphic> >& rGra
ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, SvStream& rIStream,
sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, GraphicFilterImportFlags nImportFlags,
css::uno::Sequence< css::beans::PropertyValue >* pFilterData,
- WMF_EXTERNALHEADER *pExtHeader )
+ WmfExternal *pExtHeader )
{
OUString aFilterName;
OUString aExternalFilterName;
@@ -1771,52 +1771,46 @@ ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath,
else if( aFilterName.equalsIgnoreAsciiCase( IMP_WMF ) ||
aFilterName.equalsIgnoreAsciiCase( IMP_EMF ) )
{
- static bool bCheckEmfWmf = true;
- if (bCheckEmfWmf)
- {
- if (rGraphic.IsDummyContext())
- rGraphic.SetDummyContext(false);
+ // use new UNO API service, do not directly import but create a
+ // Graphic that contains the original data and decomposes to
+ // primitives on demand
+ if (rGraphic.IsDummyContext())
+ rGraphic.SetDummyContext(false);
- const sal_uInt32 nStreamPosition(rIStream.Tell());
- const sal_uInt32 nStreamLength(rIStream.Seek(STREAM_SEEK_TO_END) - nStreamPosition);
- VectorGraphicDataArray aNewData(nStreamLength);
- bool bOkay(false);
+ const sal_uInt32 nStreamPosition(rIStream.Tell());
+ const sal_uInt32 nStreamLength(rIStream.Seek(STREAM_SEEK_TO_END) - nStreamPosition);
+ VectorGraphicDataArray aNewData(nStreamLength);
+ bool bOkay(false);
- rIStream.Seek(nStreamPosition);
- rIStream.ReadBytes(aNewData.begin(), nStreamLength);
+ rIStream.Seek(nStreamPosition);
+ rIStream.ReadBytes(aNewData.begin(), nStreamLength);
- if (!rIStream.GetError())
+ if (!rIStream.GetError())
+ {
+ const bool bIsWmf(aFilterName.equalsIgnoreAsciiCase(IMP_WMF));
+ const VectorGraphicDataType aDataType(bIsWmf ? VectorGraphicDataType::Wmf : VectorGraphicDataType::Emf);
+ VectorGraphicDataPtr aVectorGraphicDataPtr(
+ new VectorGraphicData(
+ aNewData,
+ rPath,
+ aDataType));
+
+ if (pExtHeader)
{
- 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;
+ aVectorGraphicDataPtr->setWmfExternalHeader(*pExtHeader);
}
- if (bOkay)
- {
- eLinkType = GfxLinkType::NativeWmf;
- }
- else
- {
- nStatus = ERRCODE_GRFILTER_FILTERERROR;
- }
+ rGraphic = Graphic(aVectorGraphicDataPtr);
+ bOkay = true;
+ }
+
+ if (bOkay)
+ {
+ eLinkType = GfxLinkType::NativeWmf;
}
else
{
- GDIMetaFile aMtf;
- if (!ConvertWMFToGDIMetaFile(rIStream, aMtf, nullptr, pExtHeader))
- nStatus = ERRCODE_GRFILTER_FORMATERROR;
- else
- {
- rGraphic = aMtf;
- eLinkType = GfxLinkType::NativeWmf;
- }
+ nStatus = ERRCODE_GRFILTER_FILTERERROR;
}
}
else if( aFilterName.equalsIgnoreAsciiCase( IMP_SVSGF )
diff --git a/vcl/source/filter/wmf/enhwmf.cxx b/vcl/source/filter/wmf/enhwmf.cxx
deleted file mode 100644
index 22125d747dbe..000000000000
--- a/vcl/source/filter/wmf/enhwmf.cxx
+++ /dev/null
@@ -1,1966 +0,0 @@
-/* -*- 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 .
- */
-
-#include <osl/endian.h>
-#include <basegfx/matrix/b2dhommatrix.hxx>
-#include <vcl/dibtools.hxx>
-#include <o3tl/make_unique.hxx>
-
-#include "winmtf.hxx"
-
-#include <memory>
-
-#ifdef DBG_UTIL
-#include <tools/stream.hxx>
-#include <vcl/pngwrite.hxx>
-#endif
-
-using namespace std;
-
-// GDI-Array
-
-#define EMR_HEADER 1
-#define EMR_POLYBEZIER 2
-#define EMR_POLYGON 3
-#define EMR_POLYLINE 4
-#define EMR_POLYBEZIERTO 5
-#define EMR_POLYLINETO 6
-#define EMR_POLYPOLYLINE 7
-#define EMR_POLYPOLYGON 8
-#define EMR_SETWINDOWEXTEX 9
-#define EMR_SETWINDOWORGEX 10
-#define EMR_SETVIEWPORTEXTEX 11
-#define EMR_SETVIEWPORTORGEX 12
-#define EMR_SETBRUSHORGEX 13
-#define EMR_EOF 14
-#define EMR_SETPIXELV 15
-#define EMR_SETMAPPERFLAGS 16
-#define EMR_SETMAPMODE 17
-#define EMR_SETBKMODE 18
-#define EMR_SETPOLYFILLMODE 19
-#define EMR_SETROP2 20
-#define EMR_SETSTRETCHBLTMODE 21
-#define EMR_SETTEXTALIGN 22
-#define EMR_SETCOLORADJUSTMENT 23
-#define EMR_SETTEXTCOLOR 24
-#define EMR_SETBKCOLOR 25
-#define EMR_OFFSETCLIPRGN 26
-#define EMR_MOVETOEX 27
-#define EMR_SETMETARGN 28
-#define EMR_EXCLUDECLIPRECT 29
-#define EMR_INTERSECTCLIPRECT 30
-#define EMR_SCALEVIEWPORTEXTEX 31
-#define EMR_SCALEWINDOWEXTEX 32
-#define EMR_SAVEDC 33
-#define EMR_RESTOREDC 34
-#define EMR_SETWORLDTRANSFORM 35
-#define EMR_MODIFYWORLDTRANSFORM 36
-#define EMR_SELECTOBJECT 37
-#define EMR_CREATEPEN 38
-#define EMR_CREATEBRUSHINDIRECT 39
-#define EMR_DELETEOBJECT 40
-#define EMR_ANGLEARC 41
-#define EMR_ELLIPSE 42
-#define EMR_RECTANGLE 43
-#define EMR_ROUNDRECT 44
-#define EMR_ARC 45
-#define EMR_CHORD 46
-#define EMR_PIE 47
-#define EMR_SELECTPALETTE 48
-#define EMR_CREATEPALETTE 49
-#define EMR_SETPALETTEENTRIES 50
-#define EMR_RESIZEPALETTE 51
-#define EMR_REALIZEPALETTE 52
-#define EMR_EXTFLOODFILL 53
-#define EMR_LINETO 54
-#define EMR_ARCTO 55
-#define EMR_POLYDRAW 56
-#define EMR_SETARCDIRECTION 57
-#define EMR_SETMITERLIMIT 58
-#define EMR_BEGINPATH 59
-#define EMR_ENDPATH 60
-#define EMR_CLOSEFIGURE 61
-#define EMR_FILLPATH 62
-#define EMR_STROKEANDFILLPATH 63
-#define EMR_STROKEPATH 64
-#define EMR_FLATTENPATH 65
-#define EMR_WIDENPATH 66
-#define EMR_SELECTCLIPPATH 67
-#define EMR_ABORTPATH 68
-
-#define EMR_COMMENT 70 // Contains arbitrary private data.
-// Comment Identifiers:
-#define EMR_COMMENT_EMFPLUS 0x2B464D45 // Contains embedded EMF+ records.
-#define EMR_COMMENT_EMFSPOOL 0x00000000 // Contains embedded EMFSPOOL records.
-#define EMR_COMMENT_PUBLIC 0x43494447 // Specify extensions to EMF processing.
-
-#define EMR_FILLRGN 71
-#define EMR_FRAMERGN 72
-#define EMR_INVERTRGN 73
-#define EMR_PAINTRGN 74
-#define EMR_EXTSELECTCLIPRGN 75
-#define EMR_BITBLT 76
-#define EMR_STRETCHBLT 77
-#define EMR_MASKBLT 78
-#define EMR_PLGBLT 79
-#define EMR_SETDIBITSTODEVICE 80
-#define EMR_STRETCHDIBITS 81
-#define EMR_EXTCREATEFONTINDIRECTW 82
-#define EMR_EXTTEXTOUTA 83
-#define EMR_EXTTEXTOUTW 84
-#define EMR_POLYBEZIER16 85
-#define EMR_POLYGON16 86
-#define EMR_POLYLINE16 87
-#define EMR_POLYBEZIERTO16 88
-#define EMR_POLYLINETO16 89
-#define EMR_POLYPOLYLINE16 90
-#define EMR_POLYPOLYGON16 91
-#define EMR_POLYDRAW16 92
-#define EMR_CREATEMONOBRUSH 93
-#define EMR_CREATEDIBPATTERNBRUSHPT 94
-#define EMR_EXTCREATEPEN 95
-#define EMR_POLYTEXTOUTA 96
-#define EMR_POLYTEXTOUTW 97
-
-// WINDOWS VERSION >= 0x400
-#define EMR_SETICMMODE 98
-#define EMR_CREATECOLORSPACE 99
-#define EMR_SETCOLORSPACE 100
-#define EMR_DELETECOLORSPACE 101
-#define EMR_GLSRECORD 102
-#define EMR_GLSBOUNDEDRECORD 103
-#define EMR_PIXELFORMAT 104
-
-// WINDOWS VERSION >= 0x500
-#define EMR_DRAWESCAPE 105
-#define EMR_EXTESCAPE 106
-#define EMR_STARTDOC 107
-#define EMR_SMALLTEXTOUT 108
-#define EMR_FORCEUFIMAPPING 109
-#define EMR_NAMEDESCAPE 110
-#define EMR_COLORCORRECTPALETTE 111
-#define EMR_SETICMPROFILEA 112
-#define EMR_SETICMPROFILEW 113
-#define EMR_ALPHABLEND 114
-#define EMR_ALPHADIBBLEND 115
-#define EMR_TRANSPARENTBLT 116
-#define EMR_TRANSPARENTDIB 117
-#define EMR_GRADIENTFILL 118
-#define EMR_SETLINKEDUFIS 119
-#define EMR_SETTEXTJUSTIFICATION 120
-
-namespace
-{
-
-const char *
-record_type_name(sal_uInt32 nRecType)
-{
-#ifndef SAL_LOG_INFO
- (void) nRecType;
- return "";
-#else
- switch( nRecType )
- {
- case EMR_HEADER: return "HEADER";
- case EMR_POLYBEZIER: return "POLYBEZIER";
- case EMR_POLYGON: return "POLYGON";
- case EMR_POLYLINE: return "POLYLINE";
- case EMR_POLYBEZIERTO: return "POLYBEZIERTO";
- case EMR_POLYLINETO: return "POLYLINETO";
- case EMR_POLYPOLYLINE: return "POLYPOLYLINE";
- case EMR_POLYPOLYGON: return "POLYPOLYGON";
- case EMR_SETWINDOWEXTEX: return "SETWINDOWEXTEX";
- case EMR_SETWINDOWORGEX: return "SETWINDOWORGEX";
- case EMR_SETVIEWPORTEXTEX: return "SETVIEWPORTEXTEX";
- case EMR_SETVIEWPORTORGEX: return "SETVIEWPORTORGEX";
- case EMR_SETBRUSHORGEX: return "SETBRUSHORGEX";
- case EMR_EOF: return "EOF";
- case EMR_SETPIXELV: return "SETPIXELV";
- case EMR_SETMAPPERFLAGS: return "SETMAPPERFLAGS";
- case EMR_SETMAPMODE: return "SETMAPMODE";
- case EMR_SETBKMODE: return "SETBKMODE";
- case EMR_SETPOLYFILLMODE: return "SETPOLYFILLMODE";
- case EMR_SETROP2: return "SETROP2";
- case EMR_SETSTRETCHBLTMODE: return "SETSTRETCHBLTMODE";
- case EMR_SETTEXTALIGN: return "SETTEXTALIGN";
- case EMR_SETCOLORADJUSTMENT: return "SETCOLORADJUSTMENT";
- case EMR_SETTEXTCOLOR: return "SETTEXTCOLOR";
- case EMR_SETBKCOLOR: return "SETBKCOLOR";
- case EMR_OFFSETCLIPRGN: return "OFFSETCLIPRGN";
- case EMR_MOVETOEX: return "MOVETOEX";
- case EMR_SETMETARGN: return "SETMETARGN";
- case EMR_EXCLUDECLIPRECT: return "EXCLUDECLIPRECT";
- case EMR_INTERSECTCLIPRECT: return "INTERSECTCLIPRECT";
- case EMR_SCALEVIEWPORTEXTEX: return "SCALEVIEWPORTEXTEX";
- case EMR_SCALEWINDOWEXTEX: return "SCALEWINDOWEXTEX";
- case EMR_SAVEDC: return "SAVEDC";
- case EMR_RESTOREDC: return "RESTOREDC";
- case EMR_SETWORLDTRANSFORM: return "SETWORLDTRANSFORM";
- case EMR_MODIFYWORLDTRANSFORM: return "MODIFYWORLDTRANSFORM";
- case EMR_SELECTOBJECT: return "SELECTOBJECT";
- case EMR_CREATEPEN: return "CREATEPEN";
- case EMR_CREATEBRUSHINDIRECT: return "CREATEBRUSHINDIRECT";
- case EMR_DELETEOBJECT: return "DELETEOBJECT";
- case EMR_ANGLEARC: return "ANGLEARC";
- case EMR_ELLIPSE: return "ELLIPSE";
- case EMR_RECTANGLE: return "RECTANGLE";
- case EMR_ROUNDRECT: return "ROUNDRECT";
- case EMR_ARC: return "ARC";
- case EMR_CHORD: return "CHORD";
- case EMR_PIE: return "PIE";
- case EMR_SELECTPALETTE: return "SELECTPALETTE";
- case EMR_CREATEPALETTE: return "CREATEPALETTE";
- case EMR_SETPALETTEENTRIES: return "SETPALETTEENTRIES";
- case EMR_RESIZEPALETTE: return "RESIZEPALETTE";
- case EMR_REALIZEPALETTE: return "REALIZEPALETTE";
- case EMR_EXTFLOODFILL: return "EXTFLOODFILL";
- case EMR_LINETO: return "LINETO";
- case EMR_ARCTO: return "ARCTO";
- case EMR_POLYDRAW: return "POLYDRAW";
- case EMR_SETARCDIRECTION: return "SETARCDIRECTION";
- case EMR_SETMITERLIMIT: return "SETMITERLIMIT";
- case EMR_BEGINPATH: return "BEGINPATH";
- case EMR_ENDPATH: return "ENDPATH";
- case EMR_CLOSEFIGURE: return "CLOSEFIGURE";
- case EMR_FILLPATH: return "FILLPATH";
- case EMR_STROKEANDFILLPATH: return "STROKEANDFILLPATH";
- case EMR_STROKEPATH: return "STROKEPATH";
- case EMR_FLATTENPATH: return "FLATTENPATH";
- case EMR_WIDENPATH: return "WIDENPATH";
- case EMR_SELECTCLIPPATH: return "SELECTCLIPPATH";
- case EMR_ABORTPATH: return "ABORTPATH";
- case EMR_COMMENT: return "COMMENT";
- case EMR_FILLRGN: return "FILLRGN";
- case EMR_FRAMERGN: return "FRAMERGN";
- case EMR_INVERTRGN: return "INVERTRGN";
- case EMR_PAINTRGN: return "PAINTRGN";
- case EMR_EXTSELECTCLIPRGN: return "EXTSELECTCLIPRGN";
- case EMR_BITBLT: return "BITBLT";
- case EMR_STRETCHBLT: return "STRETCHBLT";
- case EMR_MASKBLT: return "MASKBLT";
- case EMR_PLGBLT: return "PLGBLT";
- case EMR_SETDIBITSTODEVICE: return "SETDIBITSTODEVICE";
- case EMR_STRETCHDIBITS: return "STRETCHDIBITS";
- case EMR_EXTCREATEFONTINDIRECTW: return "EXTCREATEFONTINDIRECTW";
- case EMR_EXTTEXTOUTA: return "EXTTEXTOUTA";
- case EMR_EXTTEXTOUTW: return "EXTTEXTOUTW";
- case EMR_POLYBEZIER16: return "POLYBEZIER16";
- case EMR_POLYGON16: return "POLYGON16";
- case EMR_POLYLINE16: return "POLYLINE16";
- case EMR_POLYBEZIERTO16: return "POLYBEZIERTO16";
- case EMR_POLYLINETO16: return "POLYLINETO16";
- case EMR_POLYPOLYLINE16: return "POLYPOLYLINE16";
- case EMR_POLYPOLYGON16: return "POLYPOLYGON16";
- case EMR_POLYDRAW16: return "POLYDRAW16";
- case EMR_CREATEMONOBRUSH: return "CREATEMONOBRUSH";
- case EMR_CREATEDIBPATTERNBRUSHPT: return "CREATEDIBPATTERNBRUSHPT";
- case EMR_EXTCREATEPEN: return "EXTCREATEPEN";
- case EMR_POLYTEXTOUTA: return "POLYTEXTOUTA";
- case EMR_POLYTEXTOUTW: return "POLYTEXTOUTW";
- case EMR_SETICMMODE: return "SETICMMODE";
- case EMR_CREATECOLORSPACE: return "CREATECOLORSPACE";
- case EMR_SETCOLORSPACE: return "SETCOLORSPACE";
- case EMR_DELETECOLORSPACE: return "DELETECOLORSPACE";
- case EMR_GLSRECORD: return "GLSRECORD";
- case EMR_GLSBOUNDEDRECORD: return "GLSBOUNDEDRECORD";
- case EMR_PIXELFORMAT: return "PIXELFORMAT";
- case EMR_DRAWESCAPE: return "DRAWESCAPE";
- case EMR_EXTESCAPE: return "EXTESCAPE";
- case EMR_STARTDOC: return "STARTDOC";
- case EMR_SMALLTEXTOUT: return "SMALLTEXTOUT";
- case EMR_FORCEUFIMAPPING: return "FORCEUFIMAPPING";
- case EMR_NAMEDESCAPE: return "NAMEDESCAPE";
- case EMR_COLORCORRECTPALETTE: return "COLORCORRECTPALETTE";
- case EMR_SETICMPROFILEA: return "SETICMPROFILEA";
- case EMR_SETICMPROFILEW: return "SETICMPROFILEW";
- case EMR_ALPHABLEND: return "ALPHABLEND";
- case EMR_ALPHADIBBLEND: return "ALPHADIBBLEND";
- case EMR_TRANSPARENTBLT: return "TRANSPARENTBLT";
- case EMR_TRANSPARENTDIB: return "TRANSPARENTDIB";
- case EMR_GRADIENTFILL: return "GRADIENTFILL";
- case EMR_SETLINKEDUFIS: return "SETLINKEDUFIS";
- case EMR_SETTEXTJUSTIFICATION: return "SETTEXTJUSTIFICATION";
- default:
- // Yes, return a pointer to a static buffer. This is a very
- // local debugging output function, so no big deal.
- static char buffer[11];
- sprintf(buffer, "0x%08" SAL_PRIxUINT32, nRecType);
- return buffer;
- }
-#endif
-}
-
-#ifdef OSL_BIGENDIAN
-// little endian <-> big endian switch
-static float GetSwapFloat(SvStream& rStream)
-{
- float fTmp;
- sal_Int8* pPtr = (sal_Int8*)&fTmp;
- rStream.ReadSChar(pPtr[3]);
- rStream.ReadSChar(pPtr[2]);
- rStream.ReadSChar(pPtr[1]);
- rStream.ReadSChar(pPtr[0]);
- return fTmp;
-}
-#endif
-
-struct BLENDFUNCTION
-{
- unsigned char aBlendOperation;
- unsigned char aBlendFlags;
- unsigned char aSrcConstantAlpha;
- unsigned char aAlphaFormat;
-
- friend SvStream& operator>>(SvStream& rInStream, BLENDFUNCTION& rBlendFun);
-};
-
-SvStream& operator>>(SvStream& rInStream, BLENDFUNCTION& rBlendFun)
-{
- rInStream.ReadUChar(rBlendFun.aBlendOperation);
- rInStream.ReadUChar(rBlendFun.aBlendFlags);
- rInStream.ReadUChar(rBlendFun.aSrcConstantAlpha);
- rInStream.ReadUChar(rBlendFun.aAlphaFormat);
- return rInStream;
-}
-
-SvStream& operator>>(SvStream& rInStream, XForm& rXForm)
-{
- if (sizeof(float) != 4)
- {
- OSL_FAIL( "EnhWMFReader::sizeof( float ) != 4" );
- rXForm = XForm();
- }
- else
- {
-#ifdef OSL_BIGENDIAN
- rXForm.eM11 = GetSwapFloat(rInStream);
- rXForm.eM12 = GetSwapFloat(rInStream);
- rXForm.eM21 = GetSwapFloat(rInStream);
- rXForm.eM22 = GetSwapFloat(rInStream);
- rXForm.eDx = GetSwapFloat(rInStream);
- rXForm.eDy = GetSwapFloat(rInStream);
-#else
- rInStream.ReadFloat(rXForm.eM11);
- rInStream.ReadFloat(rXForm.eM12);
- rInStream.ReadFloat(rXForm.eM21);
- rInStream.ReadFloat(rXForm.eM22);
- rInStream.ReadFloat(rXForm.eDx);
- rInStream.ReadFloat(rXForm.eDy);
-#endif
- }
- return rInStream;
-}
-
-bool ImplReadRegion( tools::PolyPolygon& rPolyPoly, SvStream& rStream, sal_uInt32 nLen )
-{
- if (nLen == 0)
- return false;
-
- sal_uInt32 nHdSize, nType, nCount, nRgnSize, i;
- rStream.ReadUInt32(nHdSize);
- rStream.ReadUInt32(nType);
- rStream.ReadUInt32(nCount);
- rStream.ReadUInt32(nRgnSize);
-
- if ( nCount > 0
- && nType == RDH_RECTANGLES
- && nLen >= ((nCount << 4) + (nHdSize - 16)))
- {
- sal_Int32 nx1, ny1, nx2, ny2;
-
- for (i = 0; i < nCount; i++)
- {
- rStream.ReadInt32(nx1);
- rStream.ReadInt32(ny1);
- rStream.ReadInt32(nx2);
- rStream.ReadInt32(ny2);
-
- tools::Rectangle aRectangle(Point(nx1, ny1), Point(nx2, ny2));
-
- tools::Polygon aPolygon(aRectangle);
- tools::PolyPolygon aPolyPolyOr1(aPolygon);
- tools::PolyPolygon aPolyPolyOr2(rPolyPoly);
- rPolyPoly.GetUnion(aPolyPolyOr1, aPolyPolyOr2);
- rPolyPoly = aPolyPolyOr2;
- }
- return true;
- }
- return false;
-}
-
-} // anonymous namespace
-
-EnhWMFReader::EnhWMFReader(SvStream& rStream,GDIMetaFile& rGDIMetaFile,FilterConfigItem* pConfigItem)
- : WinMtf(rGDIMetaFile, rStream , pConfigItem)
- , bRecordPath(false)
- , nRecordCount(0)
- , bEMFPlus(false)
-{}
-
-EnhWMFReader::~EnhWMFReader()
-{}
-
-void EnhWMFReader::ReadEMFPlusComment(sal_uInt32 length, bool& bHaveDC)
-{
- if (!bEMFPlus) {
- pOut->PassEMFPlusHeaderInfo();
-
-#if OSL_DEBUG_LEVEL > 1
- // debug code - write the stream to debug file /tmp/emf-stream.emf
- sal_uInt64 const pos = pWMF->Tell();
- pWMF->Seek(0);
- SvFileStream file( OUString( "/tmp/emf-stream.emf" ), StreamMode::WRITE | StreamMode::TRUNC );
-
- pWMF->WriteStream(file);
- file.Flush();
- file.Close();
-
- pWMF->Seek( pos );
-#endif
-
- }
- bEMFPlus = true;
-
- sal_uInt64 const pos = pWMF->Tell();
- void *buffer = malloc( length );
- pOut->PassEMFPlus( buffer, pWMF->ReadBytes(buffer, length) );
- free( buffer );
- pWMF->Seek( pos );
-
- bHaveDC = false;
-
- // skip in SeekRel if impossibly unavailable
- sal_uInt32 nRemainder = length;
-
- const size_t nRequiredHeaderSize = 12;
- while (nRemainder >= nRequiredHeaderSize)
- {
- sal_uInt16 type(0), flags(0);
- sal_uInt32 size(0), dataSize(0);
-
- pWMF->ReadUInt16( type ).ReadUInt16( flags ).ReadUInt32( size ).ReadUInt32( dataSize );
- nRemainder -= nRequiredHeaderSize;
-
- SAL_INFO ("vcl.emf", "\t\tEMF+ record type: " << std::hex << type << std::dec);
-
- // Get Device Context
- // TODO We should use EmfPlusRecordType::GetDC instead
- if( type == 0x4004 )
- {
- bHaveDC = true;
- SAL_INFO ("vcl.emf", "\t\tEMF+ lock DC (device context)");
- }
-
- // Get the length of the remaining data of this record based
- // on the alleged size
- sal_uInt32 nRemainingRecordData = size >= nRequiredHeaderSize ?
- size-nRequiredHeaderSize : 0;
- // clip to available size
- nRemainingRecordData = std::min(nRemainingRecordData, nRemainder);
- pWMF->SeekRel(nRemainingRecordData);
- nRemainder -= nRemainingRecordData;
- }
- pWMF->SeekRel(nRemainder);
-}
-
-/**
- * Reads polygons from the stream.
- * The \<class T> parameter is for the type of the points (sal_uInt32 or sal_uInt16).
- * The \<class Drawer> parameter is a c++11 lambda for the method that will draw the polygon.
- * skipFirst: if the first point read is the 0th point or the 1st point in the array.
- * */
-template <class T, class Drawer>
-void EnhWMFReader::ReadAndDrawPolygon(Drawer drawer, const bool skipFirst)
-{
- sal_uInt32 nPoints(0), nStartIndex(0);
- pWMF->SeekRel( 16 );
- pWMF->ReadUInt32( nPoints );
- if (skipFirst)
- {
- nPoints ++;
- nStartIndex ++;
- }
-
- tools::Polygon aPolygon = ReadPolygon<T>(nStartIndex, nPoints);
- drawer(pOut, aPolygon, skipFirst, bRecordPath);
-}
-
-/**
- * Reads polygons from the stream.
- * The \<class T> parameter is for the type of the points
- * nStartIndex: which is the starting index in the polygon of the first point read
- * nPoints: number of points
- * pWMF: the stream containing the polygons
- * */
-template <class T>
-tools::Polygon EnhWMFReader::ReadPolygon(sal_uInt32 nStartIndex, sal_uInt32 nPoints)
-{
- bool bRecordOk = nPoints <= SAL_MAX_UINT16;
- SAL_WARN_IF(!bRecordOk, "vcl.emf", "polygon record has more polygons than we can handle");
- if (!bRecordOk)
- return tools::Polygon();
-
- tools::Polygon aPolygon(nPoints);
- for (sal_uInt32 i = nStartIndex ; i < nPoints && pWMF->good(); i++ )
- {
- T nX, nY;
- *pWMF >> nX >> nY;
- if (!pWMF->good())
- {
- SAL_WARN("vcl.emf", "short read on polygon, truncating");
- aPolygon.SetSize(i);
- break;
- }
- aPolygon[ i ] = Point( nX, nY );
- }
-
- return aPolygon;
-}
-
-/**
- * Reads a polyline from the WMF file and draws it
- * The \<class T> parameter refers to the type of the points. (e.g. sal_uInt16 or sal_uInt32)
- * */
-template <class T>
-void EnhWMFReader::ReadAndDrawPolyLine()
-{
- sal_uInt32 nPoints;
- sal_uInt32 i, nNumberOfPolylines( 0 ), nCount( 0 );
- pWMF->SeekRel( 0x10 ); // TODO Skipping Bounds. A 128-bit WMF RectL object (specifies the bounding rectangle in device units.)
- pWMF->ReadUInt32( nNumberOfPolylines );
- pWMF->ReadUInt32( nCount ); // total number of points in all polylines
- if (pWMF->Tell() >= nEndPos)
- return;
-
- // taking the amount of points of each polygon, retrieving the total number of points
- if ( pWMF->good() &&
- ( nNumberOfPolylines < SAL_MAX_UINT32 / sizeof( sal_uInt16 ) ) &&
- ( nNumberOfPolylines * sizeof( sal_uInt16 ) ) <= ( nEndPos - pWMF->Tell() )
- )
- {
- std::unique_ptr< sal_uInt32[] > pnPolylinePointCount( new sal_uInt32[ nNumberOfPolylines ] );
- for ( i = 0; i < nNumberOfPolylines && pWMF->good(); i++ )
- {
- pWMF->ReadUInt32( nPoints );
- pnPolylinePointCount[ i ] = nPoints;
- }
- // Get polyline points:
- for ( i = 0; ( i < nNumberOfPolylines ) && pWMF->good(); i++ )
- {
- tools::Polygon aPolygon = ReadPolygon< T >( 0, pnPolylinePointCount[ i ] );
- pOut->DrawPolyLine( aPolygon, false, bRecordPath );
- }
- }
-}
-
-// these are referenced from inside the templates
-
-SvStream& operator>>(SvStream& rStream, sal_Int16 &n)
-{
- return rStream.ReadInt16(n);
-}
-
-SvStream& operator>>(SvStream& rStream, sal_Int32 &n)
-{
- return rStream.ReadInt32(n);
-}
-
-/**
- * Reads a poly polygon from the WMF file and draws it.
- * The \<class T> parameter refers to the type of the points. (e.g. sal_uInt16 or sal_uInt32)
- * */
-template <class T>
-void EnhWMFReader::ReadAndDrawPolyPolygon()
-{
- sal_uInt32 nPoly(0), nGesPoints(0), nReadPoints(0);
- pWMF->SeekRel( 0x10 );
- // Number of polygons
- pWMF->ReadUInt32( nPoly ).ReadUInt32( nGesPoints );
- if (pWMF->Tell() >= nEndPos)
- return;
- if (!pWMF->good())
- return;
- //check against numeric overflowing
- if (nGesPoints >= SAL_MAX_UINT32 / sizeof(Point))
- return;
- if (nPoly >= SAL_MAX_UINT32 / sizeof(sal_uInt16))
- return;
- if (nPoly * sizeof(sal_uInt16) > nEndPos - pWMF->Tell())
- return;
-
- // Get number of points in each polygon
- std::vector<sal_uInt16> aPoints(nPoly);
- for (sal_uInt32 i = 0; i < nPoly && pWMF->good(); ++i)
- {
- sal_uInt32 nPoints(0);
- pWMF->ReadUInt32( nPoints );
- aPoints[i] = (sal_uInt16)nPoints;
- }
- if ( pWMF->good() && ( nGesPoints * (sizeof(T)+sizeof(T)) ) <= ( nEndPos - pWMF->Tell() ) )
- {
- // Get polygon points
- tools::PolyPolygon aPolyPoly(nPoly, nPoly);
- for (sal_uInt32 i = 0; i < nPoly && pWMF->good(); ++i)
- {
- const sal_uInt16 nPointCount(aPoints[i]);
- std::vector<Point> aPtAry(nPointCount);
- for (sal_uInt16 j = 0; j < nPointCount && pWMF->good(); ++j)
- {
- T nX(0), nY(0);
- *pWMF >> nX >> nY;
- aPtAry[j] = Point( nX, nY );
- ++nReadPoints;
- }
-
- aPolyPoly.Insert(tools::Polygon(aPtAry.size(), aPtAry.data()));
- }
-
- pOut->DrawPolyPolygon(aPolyPoly, bRecordPath);
- }
-
- OSL_ENSURE(nReadPoints == nGesPoints, "The number Points processed from EMR_POLYPOLYGON is unequal imported number (!)");
-}
-
-bool EnhWMFReader::ReadEnhWMF()
-{
- sal_uInt32 nStretchBltMode = 0;
- sal_uInt32 nNextPos(0),
- nW(0), nH(0), nColor(0), nIndex(0),
- nDat32(0), nNom1(0), nDen1(0), nNom2(0), nDen2(0);
- sal_Int32 nX32(0), nY32(0), nx32(0), ny32(0);
-
- bool bStatus = ReadHeader();
- bool bHaveDC = false;
-
- static bool bEnableEMFPlus = ( getenv( "EMF_PLUS_DISABLE" ) == nullptr );
-
- while( bStatus && nRecordCount-- && pWMF->good())
- {
- sal_uInt32 nRecType(0), nRecSize(0);
- pWMF->ReadUInt32(nRecType).ReadUInt32(nRecSize);
-
- if ( !pWMF->good() || ( nRecSize < 8 ) || ( nRecSize & 3 ) ) // Parameters are always divisible by 4
- {
- bStatus = false;
- break;
- }
-
- auto nCurPos = pWMF->Tell();
-
- if (nEndPos < nCurPos - 8)
- {
- bStatus = false;
- break;
- }
-
- const sal_uInt32 nMaxPossibleRecSize = nEndPos - (nCurPos - 8);
- if (nRecSize > nMaxPossibleRecSize)
- {
- bStatus = false;
- break;
- }
-
- nNextPos = nCurPos + (nRecSize - 8);
-
- if( !aBmpSaveList.empty()
- && ( nRecType != EMR_STRETCHBLT )
- && ( nRecType != EMR_STRETCHDIBITS )
- ) {
- pOut->ResolveBitmapActions( aBmpSaveList );
- }
-
- bool bFlag = false;
-
- SAL_INFO ("vcl.emf", "0x" << std::hex << (nNextPos - nRecSize) << "-0x" << nNextPos << " " << record_type_name(nRecType) << " size: " << nRecSize << std::dec);
-
- if( bEnableEMFPlus && nRecType == EMR_COMMENT ) {
- sal_uInt32 length;
-
- pWMF->ReadUInt32( length );
-
- SAL_INFO("vcl.emf", "\tGDI comment, length: " << length);
-
- if( pWMF->good() && length >= 4 && length <= pWMF->remainingSize() ) {
- sal_uInt32 nCommentId;
-
- pWMF->ReadUInt32( nCommentId );
-
- SAL_INFO ("vcl.emf", "\t\tbegin " << (char)(nCommentId & 0xff) << (char)((nCommentId & 0xff00) >> 8) << (char)((nCommentId & 0xff0000) >> 16) << (char)((nCommentId & 0xff000000) >> 24) << " id: 0x" << std::hex << nCommentId << std::dec);
-
- if( nCommentId == EMR_COMMENT_EMFPLUS && nRecSize >= 12 )
- {
- // [MS-EMF] 2.3.3: DataSize includes both CommentIdentifier and CommentRecordParm fields.
- // We have already read 4-byte CommentIdentifier, so reduce length appropriately
- ReadEMFPlusComment( length-4, bHaveDC );
- }
- else if( nCommentId == EMR_COMMENT_PUBLIC && nRecSize >= 12 )
- {
- // TODO: ReadGDIComment()
- }
- else if( nCommentId == EMR_COMMENT_EMFSPOOL && nRecSize >= 12 )
- {
- // TODO Implement reading EMFSPOOL comment
-
- }
- else
- {
- SAL_INFO ("vcl.emf", "\t\tunknown id: 0x" << std::hex << nCommentId << std::dec);
- }
- }
- }
- else if( !bEMFPlus || bHaveDC || nRecType == EMR_EOF )
- {
- switch( nRecType )
- {
- case EMR_POLYBEZIERTO :
- ReadAndDrawPolygon<sal_Int32>( [] ( std::unique_ptr<WinMtfOutput> &pWinMtfOutput, tools::Polygon& rPolygon, bool aTo, bool aRecordPath )
- { pWinMtfOutput->DrawPolyBezier( rPolygon, aTo, aRecordPath ); }, true );
- break;
- case EMR_POLYBEZIER :
- ReadAndDrawPolygon<sal_Int32>( [] ( std::unique_ptr<WinMtfOutput> &pWinMtfOutput, tools::Polygon& rPolygon, bool aTo, bool aRecordPath )
- { pWinMtfOutput->DrawPolyBezier( rPolygon, aTo, aRecordPath ); }, false );
- break;
-
- case EMR_POLYGON :
- ReadAndDrawPolygon<sal_Int32>( [] ( std::unique_ptr<WinMtfOutput> &pWinMtfOutput, tools::Polygon& rPolygon, bool /*aTo*/, bool aRecordPath )
- { pWinMtfOutput->DrawPolygon( rPolygon, aRecordPath ); }, false );
- break;
-
- case EMR_POLYLINETO :
- ReadAndDrawPolygon<sal_Int32>( [] ( std::unique_ptr<WinMtfOutput> &pWinMtfOutput, tools::Polygon& rPolygon, bool aTo, bool aRecordPath )
- { pWinMtfOutput->DrawPolyLine( rPolygon, aTo, aRecordPath ); }, true );
- break;
-
- case EMR_POLYLINE :
- ReadAndDrawPolygon<sal_Int32>( [] ( std::unique_ptr<WinMtfOutput> &pWinMtfOutput, tools::Polygon& rPolygon, bool aTo, bool aRecordPath )
- { pWinMtfOutput->DrawPolyLine( rPolygon, aTo, aRecordPath ); }, false );
- break;
-
- case EMR_POLYPOLYLINE :
- ReadAndDrawPolyLine<sal_Int32>();
- break;
-
- case EMR_POLYPOLYGON :
- ReadAndDrawPolyPolygon<sal_Int32>();
- break;
-
- case EMR_SETWINDOWEXTEX :
- {
- pWMF->ReadUInt32( nW ).ReadUInt32( nH );
- pOut->SetWinExt( Size( nW, nH ), true);
- }
- break;
-
- case EMR_SETWINDOWORGEX :
- {
- pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
- pOut->SetWinOrg( Point( nX32, nY32 ), true);
- }
- break;
-
- case EMR_SCALEWINDOWEXTEX :
- {
- pWMF->ReadUInt32( nNom1 ).ReadUInt32( nDen1 ).ReadUInt32( nNom2 ).ReadUInt32( nDen2 );
- pOut->ScaleWinExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 );
- }
- break;
-
- case EMR_SETVIEWPORTORGEX :
- {
- pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
- pOut->SetDevOrg( Point( nX32, nY32 ) );
- }
- break;
-
- case EMR_SCALEVIEWPORTEXTEX :
- {
- pWMF->ReadUInt32( nNom1 ).ReadUInt32( nDen1 ).ReadUInt32( nNom2 ).ReadUInt32( nDen2 );
- pOut->ScaleDevExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 );
- }
- break;
-
- case EMR_SETVIEWPORTEXTEX :
- {
- pWMF->ReadUInt32( nW ).ReadUInt32( nH );
- pOut->SetDevExt( Size( nW, nH ) );
- }
- break;
-
- case EMR_EOF :
- nRecordCount = 0;
- break;
-
- case EMR_SETPIXELV :
- {
- pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
- pOut->DrawPixel( Point( nX32, nY32 ), ReadColor() );
- }
- break;
-
- case EMR_SETMAPMODE :
- {
- sal_uInt32 nMapMode;
- pWMF->ReadUInt32( nMapMode );
- pOut->SetMapMode( nMapMode );
- }
- break;
-
- case EMR_SETBKMODE :
- {
- pWMF->ReadUInt32( nDat32 );
- pOut->SetBkMode( static_cast<BkMode>(nDat32) );
- }
- break;
-
- case EMR_SETPOLYFILLMODE :
- break;
-
- case EMR_SETROP2 :
- {
- pWMF->ReadUInt32( nDat32 );
- pOut->SetRasterOp( (WMFRasterOp)nDat32 );
- }
- break;
-
- case EMR_SETSTRETCHBLTMODE :
- {
- pWMF->ReadUInt32( nStretchBltMode );
- }
- break;
-
- case EMR_SETTEXTALIGN :
- {
- pWMF->ReadUInt32( nDat32 );
- pOut->SetTextAlign( nDat32 );
- }
- break;
-
- case EMR_SETTEXTCOLOR :
- {
- pOut->SetTextColor( ReadColor() );
- }
- break;
-
- case EMR_SETBKCOLOR :
- {
- pOut->SetBkColor( ReadColor() );
- }
- break;
-
- case EMR_OFFSETCLIPRGN :
- {
- pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
- pOut->MoveClipRegion( Size( nX32, nY32 ) );
- }
- break;
-
- case EMR_MOVETOEX :
- {
- pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
- pOut->MoveTo( Point( nX32, nY32 ), bRecordPath );
- }
- break;
-
- case EMR_INTERSECTCLIPRECT :
- {
- pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 );
- pOut->IntersectClipRect( ReadRectangle( nX32, nY32, nx32, ny32 ) );
- }
- break;
-
- case EMR_SAVEDC :
- {
- pOut->Push();
- }
- break;
-
- case EMR_RESTOREDC :
- {
- pOut->Pop();
- }
- break;
-
- case EMR_SETWORLDTRANSFORM :
- {
- XForm aTempXForm;
- *pWMF >> aTempXForm;
- pOut->SetWorldTransform( aTempXForm );
- }
- break;
-
- case EMR_MODIFYWORLDTRANSFORM :
- {
- sal_uInt32 nMode;
- XForm aTempXForm;
- *pWMF >> aTempXForm;
- pWMF->ReadUInt32( nMode );
- pOut->ModifyWorldTransform( aTempXForm, nMode );
- }
- break;
-
- case EMR_SELECTOBJECT :
- {
- pWMF->ReadUInt32( nIndex );
- pOut->SelectObject( nIndex );
- }
- break;
-
- case EMR_CREATEPEN :
- {
- pWMF->ReadUInt32( nIndex );
- if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
- {
-
- LineInfo aLineInfo;
- sal_uInt32 nStyle;
- Size aSize;
- // #fdo39428 Remove SvStream operator>>(long&)
- sal_Int32 nTmpW(0), nTmpH(0);
-
- pWMF->ReadUInt32( nStyle ).ReadInt32( nTmpW ).ReadInt32( nTmpH );
- aSize.Width() = nTmpW;
- aSize.Height() = nTmpH;
-
- if ( aSize.Width() )
- aLineInfo.SetWidth( aSize.Width() );
-
- bool bTransparent = false;
- switch( nStyle & PS_STYLE_MASK )
- {
- case PS_DASHDOTDOT :
- aLineInfo.SetStyle( LineStyle::Dash );
- aLineInfo.SetDashCount( 1 );
- aLineInfo.SetDotCount( 2 );
- break;
- case PS_DASHDOT :
- aLineInfo.SetStyle( LineStyle::Dash );
- aLineInfo.SetDashCount( 1 );
- aLineInfo.SetDotCount( 1 );
- break;
- case PS_DOT :
- aLineInfo.SetStyle( LineStyle::Dash );
- aLineInfo.SetDashCount( 0 );
- aLineInfo.SetDotCount( 1 );
- break;
- case PS_DASH :
- aLineInfo.SetStyle( LineStyle::Dash );
- aLineInfo.SetDashCount( 1 );
- aLineInfo.SetDotCount( 0 );
- break;
- case PS_NULL :
- bTransparent = true;
- aLineInfo.SetStyle( LineStyle::NONE );
- break;
- case PS_INSIDEFRAME :
- case PS_SOLID :
- default :
- aLineInfo.SetStyle( LineStyle::Solid );
- }
- switch( nStyle & PS_ENDCAP_STYLE_MASK )
- {
- case PS_ENDCAP_ROUND :
- if ( aSize.Width() )
- {
- aLineInfo.SetLineCap( css::drawing::LineCap_ROUND );
- break;
- }
- SAL_FALLTHROUGH;
- case PS_ENDCAP_SQUARE :
- if ( aSize.Width() )
- {
- aLineInfo.SetLineCap( css::drawing::LineCap_SQUARE );
- break;
- }
- SAL_FALLTHROUGH;
- case PS_ENDCAP_FLAT :
- default :
- aLineInfo.SetLineCap( css::drawing::LineCap_BUTT );
- }
- switch( nStyle & PS_JOIN_STYLE_MASK )
- {
- case PS_JOIN_ROUND :
- aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Round );
- break;
- case PS_JOIN_MITER :
- aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Miter );
- break;
- case PS_JOIN_BEVEL :
- aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Bevel );
- break;
- default :
- aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::NONE );
- }
- pOut->CreateObjectIndexed(nIndex, o3tl::make_unique<WinMtfLineStyle>( ReadColor(), aLineInfo, bTransparent ));
- }
- }
- break;
-
- case EMR_EXTCREATEPEN :
- {
- sal_Int32 elpHatch;
- sal_uInt32 offBmi, cbBmi, offBits, cbBits, nStyle, nWidth, nBrushStyle, elpNumEntries;
- Color aColorRef;
-
- pWMF->ReadUInt32( nIndex );
- if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
- {
- pWMF->ReadUInt32( offBmi ).ReadUInt32( cbBmi ).ReadUInt32( offBits ).ReadUInt32( cbBits ). ReadUInt32( nStyle ).ReadUInt32( nWidth ).ReadUInt32( nBrushStyle );
- aColorRef = ReadColor();
- pWMF->ReadInt32( elpHatch ).ReadUInt32( elpNumEntries );
-
- LineInfo aLineInfo;
- if ( nWidth )
- aLineInfo.SetWidth( nWidth );
-
- bool bTransparent = false;
-
- switch( nStyle & PS_STYLE_MASK )
- {
- case PS_DASHDOTDOT :
- aLineInfo.SetStyle( LineStyle::Dash );
- aLineInfo.SetDashCount( 1 );
- aLineInfo.SetDotCount( 2 );
- break;
- case PS_DASHDOT :
- aLineInfo.SetStyle( LineStyle::Dash );
- aLineInfo.SetDashCount( 1 );
- aLineInfo.SetDotCount( 1 );
- break;
- case PS_DOT :
- aLineInfo.SetStyle( LineStyle::Dash );
- aLineInfo.SetDashCount( 0 );
- aLineInfo.SetDotCount( 1 );
- break;
- case PS_DASH :
- aLineInfo.SetStyle( LineStyle::Dash );
- aLineInfo.SetDashCount( 1 );
- aLineInfo.SetDotCount( 0 );
- break;
- case PS_NULL :
- bTransparent = true;
- aLineInfo.SetStyle( LineStyle::NONE );
- break;
-
- case PS_INSIDEFRAME :
- case PS_SOLID :
- default :
- aLineInfo.SetStyle( LineStyle::Solid );
- }
- switch( nStyle & PS_ENDCAP_STYLE_MASK )
- {
- case PS_ENDCAP_ROUND :
- if ( aLineInfo.GetWidth() )
- {
- aLineInfo.SetLineCap( css::drawing::LineCap_ROUND );
- break;
- }
- SAL_FALLTHROUGH;
- case PS_ENDCAP_SQUARE :
- if ( aLineInfo.GetWidth() )
- {
- aLineInfo.SetLineCap( css::drawing::LineCap_SQUARE );
- break;
- }
- SAL_FALLTHROUGH;
- case PS_ENDCAP_FLAT :
- default :
- aLineInfo.SetLineCap( css::drawing::LineCap_BUTT );
- }
- switch( nStyle & PS_JOIN_STYLE_MASK )
- {
- case PS_JOIN_ROUND :
- aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Round );
- break;
- case PS_JOIN_MITER :
- aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Miter );
- break;
- case PS_JOIN_BEVEL :
- aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Bevel );
- break;
- default :
- aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::NONE );
- }
- pOut->CreateObjectIndexed(nIndex, o3tl::make_unique<WinMtfLineStyle>( aColorRef, aLineInfo, bTransparent ));
- }
- }
- break;
-
- case EMR_CREATEBRUSHINDIRECT :
- {
- sal_uInt32 nStyle;
- pWMF->ReadUInt32( nIndex );
- if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
- {
- pWMF->ReadUInt32( nStyle );
- pOut->CreateObjectIndexed(nIndex, o3tl::make_unique<WinMtfFillStyle>( ReadColor(), ( nStyle == BS_HOLLOW ) ));
- }
- }
- break;
-
- case EMR_DELETEOBJECT :
- {
- pWMF->ReadUInt32( nIndex );
- if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
- pOut->DeleteObject( nIndex );
- }
- break;
-
- case EMR_ELLIPSE :
- {
- pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 );
- pOut->DrawEllipse( ReadRectangle( nX32, nY32, nx32, ny32 ) );
- }
- break;
-
- case EMR_RECTANGLE :
- {
- pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 );
- pOut->DrawRect( ReadRectangle( nX32, nY32, nx32, ny32 ) );
- }
- break;
-
- case EMR_ROUNDRECT :
- {
- pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nW ).ReadUInt32( nH );
- Size aSize( Size( nW, nH ) );
- pOut->DrawRoundRect( ReadRectangle( nX32, nY32, nx32, ny32 ), aSize );
- }
- break;
-
- case EMR_ARC :
- {
- sal_uInt32 nStartX, nStartY, nEndX, nEndY;
- pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY );
- pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
- }
- break;
-
- case EMR_CHORD :
- {
- sal_uInt32 nStartX, nStartY, nEndX, nEndY;
- pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY );
- pOut->DrawChord( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
- }
- break;
-
- case EMR_PIE :
- {
- sal_uInt32 nStartX, nStartY, nEndX, nEndY;
- pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY );
- const tools::Rectangle aRect( ReadRectangle( nX32, nY32, nx32, ny32 ));
-
- // #i73608# OutputDevice deviates from WMF
- // semantics. start==end means full ellipse here.
- if( nStartX == nEndX && nStartY == nEndY )
- pOut->DrawEllipse( aRect );
- else
- pOut->DrawPie( aRect, Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
- }
- break;
-
- case EMR_LINETO :
- {
- pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
- pOut->LineTo( Point( nX32, nY32 ), bRecordPath );
- }
- break;
-
- case EMR_ARCTO :
- {
- sal_uInt32 nStartX, nStartY, nEndX, nEndY;
- pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY );
- pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), true );
- }
- break;
-
- case EMR_BEGINPATH :
- {
- pOut->ClearPath();
- bRecordPath = true;
- }
- break;
-
- case EMR_ABORTPATH :
- pOut->ClearPath();
- SAL_FALLTHROUGH;
- case EMR_ENDPATH :
- bRecordPath = false;
- break;
-
- case EMR_CLOSEFIGURE :
- pOut->ClosePath();
- break;
-
- case EMR_FILLPATH :
- pOut->StrokeAndFillPath( false, true );
- break;
-
- case EMR_STROKEANDFILLPATH :
- pOut->StrokeAndFillPath( true, true );
- break;
-
- case EMR_STROKEPATH :
- pOut->StrokeAndFillPath( true, false );
- break;
-
- case EMR_SELECTCLIPPATH :
- {
- sal_Int32 nClippingMode;
- pWMF->ReadInt32(nClippingMode);
- pOut->SetClipPath(pOut->GetPathObj(), nClippingMode, true);
- }
- break;
-
- case EMR_EXTSELECTCLIPRGN :
- {
- sal_Int32 nClippingMode, cbRgnData;
- pWMF->ReadInt32(cbRgnData);
- pWMF->ReadInt32(nClippingMode);
-
- // This record's region data should be ignored if mode
- // is RGN_COPY - see EMF spec section 2.3.2.2
- if (nClippingMode == RGN_COPY)
- {
- pOut->SetDefaultClipPath();
- }
- else
- {
- tools::PolyPolygon aPolyPoly;
- if (cbRgnData)
- ImplReadRegion(aPolyPoly, *pWMF, nRecSize);
- pOut->SetClipPath(aPolyPoly, nClippingMode, false);
- }
-
- }
- break;
-
- case EMR_ALPHABLEND:
- {
- sal_Int32 xDest(0), yDest(0), cxDest(0), cyDest(0);
-
- BLENDFUNCTION aFunc;
- sal_Int32 xSrc(0), ySrc(0), cxSrc(0), cySrc(0);
- XForm xformSrc;
- sal_uInt32 BkColorSrc(0), iUsageSrc(0), offBmiSrc(0);
- sal_uInt32 cbBmiSrc(0), offBitsSrc(0), cbBitsSrc(0);
-
- sal_uInt32 nStart = pWMF->Tell() - 8;
- pWMF->SeekRel( 0x10 );
-
- pWMF->ReadInt32( xDest ).ReadInt32( yDest ).ReadInt32( cxDest ).ReadInt32( cyDest );
- *pWMF >> aFunc;
- pWMF->ReadInt32( xSrc ).ReadInt32( ySrc );
- *pWMF >> xformSrc;
- pWMF->ReadUInt32( BkColorSrc ).ReadUInt32( iUsageSrc ).ReadUInt32( offBmiSrc ).ReadUInt32( cbBmiSrc )
- .ReadUInt32( offBitsSrc ).ReadUInt32( cbBitsSrc ).ReadInt32( cxSrc ).ReadInt32( cySrc ) ;
-
- sal_uInt32 dwRop = SRCAND|SRCINVERT;
- tools::Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) );
-
- if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) )
- bStatus = false;
- else
- {
- const sal_uInt32 nSourceSize = cbBmiSrc + cbBitsSrc + 14;
- bool bSafeRead = nSourceSize <= (nEndPos - nStartPos);
- sal_uInt32 nDeltaToDIB5HeaderSize(0);
- const bool bReadAlpha(0x01 == aFunc.aAlphaFormat);
- if (bSafeRead && bReadAlpha)
- {
- // we need to read alpha channel data if AlphaFormat of BLENDFUNCTION is
- // AC_SRC_ALPHA (==0x01). To read it, create a temp DIB-File which is ready
- // for DIB-5 format
- const sal_uInt32 nHeaderSize = getDIBV5HeaderSize();
- if (cbBmiSrc > nHeaderSize)
- bSafeRead = false;
- else
- nDeltaToDIB5HeaderSize = nHeaderSize - cbBmiSrc;
- }
- if (bSafeRead)
- {
- const sal_uInt32 nTargetSize(cbBmiSrc + nDeltaToDIB5HeaderSize + cbBitsSrc + 14);
- char* pBuf = new char[ nTargetSize ];
- SvMemoryStream aTmp( pBuf, nTargetSize, StreamMode::READ | StreamMode::WRITE );
-
- aTmp.ObjectOwnsMemory( true );
-
- // write BM-Header (14 bytes)
- aTmp.WriteUChar( 'B' )
- .WriteUChar( 'M' )
- .WriteUInt32( cbBitsSrc )
- .WriteUInt16( 0 )
- .WriteUInt16( 0 )
- .WriteUInt32( cbBmiSrc + nDeltaToDIB5HeaderSize + 14 );
-
- // copy DIBInfoHeader from source (cbBmiSrc bytes)
- pWMF->Seek( nStart + offBmiSrc );
- pWMF->ReadBytes(pBuf + 14, cbBmiSrc);
-
- if (bReadAlpha)
- {
- // need to add values for all stuff that DIBV5Header is bigger
- // than DIBInfoHeader, all values are correctly initialized to zero,
- // so we can use memset here
- memset(pBuf + cbBmiSrc + 14, 0, nDeltaToDIB5HeaderSize);
- }
-
- // copy bitmap data from source (offBitsSrc bytes)
- pWMF->Seek( nStart + offBitsSrc );
- pWMF->ReadBytes(pBuf + 14 + nDeltaToDIB5HeaderSize + cbBmiSrc, cbBitsSrc);
- aTmp.Seek( 0 );
-
- // prepare to read and fill BitmapEx
- BitmapEx aBitmapEx;
-
- if(bReadAlpha)
- {
- Bitmap aBitmap;
- AlphaMask aAlpha;
-
- if(ReadDIBV5(aBitmap, aAlpha, aTmp))
- {
- aBitmapEx = BitmapEx(aBitmap, aAlpha);
- }
- }
- else
- {
- Bitmap aBitmap;
-
- if(ReadDIB(aBitmap, aTmp, true))
- {
- if(0xff != aFunc.aSrcConstantAlpha)
- {
- // add const alpha channel
- aBitmapEx = BitmapEx(
- aBitmap,
- AlphaMask(aBitmap.GetSizePixel(), &aFunc.aSrcConstantAlpha));
- }
- else
- {
- // just use Bitmap
- aBitmapEx = BitmapEx(aBitmap);
- }
- }
- }
-
- if(!aBitmapEx.IsEmpty())
- {
- // test if it is sensible to crop
- if ( ( cxSrc > 0 ) && ( cySrc > 0 ) &&
- ( xSrc >= 0 ) && ( ySrc >= 0 ) &&
- ( xSrc + cxSrc < aBitmapEx.GetSizePixel().Width() ) &&
- ( ySrc + cySrc < aBitmapEx.GetSizePixel().Height() ) )
- {
- const tools::Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
-
- aBitmapEx.Crop( aCropRect );
- }
-
-#ifdef DBG_UTIL
- static bool bDoSaveForVisualControl(false);
-
- if(bDoSaveForVisualControl)
- {
- SvFileStream aNew("c:\\metafile_content.png", StreamMode::WRITE|StreamMode::TRUNC);
- vcl::PNGWriter aPNGWriter(aBitmapEx);
- aPNGWriter.Write(aNew);
- }
-#endif
- aBmpSaveList.emplace_back(new BSaveStruct(aBitmapEx, aRect, dwRop));
- }
- }
- }
- }
- break;
-
- case EMR_BITBLT : // PASSTHROUGH INTENDED
- case EMR_STRETCHBLT :
- {
- sal_Int32 xDest, yDest, cxDest, cyDest, xSrc, ySrc, cxSrc, cySrc;
- sal_uInt32 dwRop, iUsageSrc, offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc;
- XForm xformSrc;
-
- sal_uInt32 nStart = pWMF->Tell() - 8;
-
- pWMF->SeekRel( 0x10 );
- pWMF->ReadInt32( xDest ).ReadInt32( yDest ).ReadInt32( cxDest ).ReadInt32( cyDest ).ReadUInt32( dwRop ).ReadInt32( xSrc ).ReadInt32( ySrc )
- >> xformSrc;
- pWMF->ReadUInt32( nColor ).ReadUInt32( iUsageSrc ).ReadUInt32( offBmiSrc ).ReadUInt32( cbBmiSrc )
- .ReadUInt32( offBitsSrc ).ReadUInt32( cbBitsSrc );
-
- if ( nRecType == EMR_STRETCHBLT )
- pWMF->ReadInt32( cxSrc ).ReadInt32( cySrc );
- else
- cxSrc = cySrc = 0;
-
- Bitmap aBitmap;
- tools::Rectangle aRect( Point( xDest, yDest ), Size( cxDest, cyDest ) );
-
- if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) )
- bStatus = false;
- else
- {
- sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14;
- if ( nSize <= ( nEndPos - nStartPos ) )
- {
- char* pBuf = new char[ nSize ];
- SvMemoryStream aTmp( pBuf, nSize, StreamMode::READ | StreamMode::WRITE );
- aTmp.ObjectOwnsMemory( true );
- aTmp.WriteUChar( 'B' )
- .WriteUChar( 'M' )
- .WriteUInt32( cbBitsSrc )
- .WriteUInt16( 0 )
- .WriteUInt16( 0 )
- .WriteUInt32( cbBmiSrc + 14 );
- pWMF->Seek( nStart + offBmiSrc );
- pWMF->ReadBytes(pBuf + 14, cbBmiSrc);
- pWMF->Seek( nStart + offBitsSrc );
- pWMF->ReadBytes(pBuf + 14 + cbBmiSrc, cbBitsSrc);
- aTmp.Seek( 0 );
- ReadDIB(aBitmap, aTmp, true);
-
- // test if it is sensible to crop
- if ( ( cxSrc > 0 ) && ( cySrc > 0 ) &&
- ( xSrc >= 0 ) && ( ySrc >= 0 ) &&
- ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) &&
- ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) )
- {
- tools::Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
- aBitmap.Crop( aCropRect );
- }
- aBmpSaveList.emplace_back(new BSaveStruct(aBitmap, aRect, dwRop));
- }
- }
- }
- break;
-
- case EMR_STRETCHDIBITS :
- {
- sal_Int32 xDest, yDest, xSrc, ySrc, cxSrc, cySrc, cxDest, cyDest;
- sal_uInt32 offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc, iUsageSrc, dwRop;
- sal_uInt32 nStart = pWMF->Tell() - 8;
-
- pWMF->SeekRel( 0x10 );
- pWMF->ReadInt32( xDest )
- .ReadInt32( yDest )
- .ReadInt32( xSrc )
- .ReadInt32( ySrc )
- .ReadInt32( cxSrc )
- .ReadInt32( cySrc )
- .ReadUInt32( offBmiSrc )
- .ReadUInt32( cbBmiSrc )
- .ReadUInt32( offBitsSrc )
- .ReadUInt32( cbBitsSrc )
- .ReadUInt32( iUsageSrc )
- .ReadUInt32( dwRop )
- .ReadInt32( cxDest )
- .ReadInt32( cyDest );
-
- Bitmap aBitmap;
- tools::Rectangle aRect( Point( xDest, yDest ), Size( cxDest, cyDest ) );
-
- if ( ((SAL_MAX_UINT32 - 14) < cbBitsSrc)
- || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc )
- )
- {
- bStatus = false;
- }
- else
- {
- sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14;
- if ( nSize <= ( nEndPos - nStartPos ) )
- {
- char* pBuf = new char[ nSize ];
- SvMemoryStream aTmp( pBuf, nSize, StreamMode::READ | StreamMode::WRITE );
- aTmp.ObjectOwnsMemory( true );
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list