LibreOffice Module vcl (master)  1
wmf.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include "emfwr.hxx"
21 #include "wmfwr.hxx"
22 #include <vcl/wmf.hxx>
23 #include <vcl/gdimetafiletools.hxx>
24 #include <vcl/graph.hxx>
25 
26 using namespace com::sun::star;
27 
28 bool ReadWindowMetafile( SvStream& rStream, GDIMetaFile& rMTF )
29 {
30  // tdf#111484 Use new method to import Metafile. Take current StreamPos
31  // into account (used by SwWW8ImplReader::ReadGrafFile and by
32  // SwWw6ReadMetaStream, so do *not* ignore. OTOH XclImpDrawing::ReadWmf
33  // is nice enough to copy to an own MemStream to avoid that indirect
34  // parameter passing...)
35  const sal_uInt32 nStreamStart(rStream.Tell());
36  const sal_uInt32 nStreamEnd(rStream.TellEnd());
37 
38  if (nStreamStart >= nStreamEnd)
39  {
40  return false;
41  }
42 
43  // Read binary data to mem array
44  const sal_uInt32 nStreamLength(nStreamEnd - nStreamStart);
45  auto rData = std::make_unique<std::vector<sal_uInt8>>(nStreamLength);
46  rStream.ReadBytes(rData->data(), rData->size());
47  BinaryDataContainer aDataContainer(std::move(rData));
48  rStream.Seek(nStreamStart);
49 
50  if (rStream.good())
51  {
52  // Throw into VectorGraphicData to get the import. Do not care
53  // too much for type, this will be checked there. Also no path
54  // needed, it is a temporary object
55  auto aVectorGraphicDataPtr =
56  std::make_shared<VectorGraphicData>(aDataContainer, VectorGraphicDataType::Emf);
57 
58  // create a Graphic and grep Metafile from it
59  const Graphic aGraphic(aVectorGraphicDataPtr);
60 
61  // get the Metafile from it, done
62  rMTF = aGraphic.GetGDIMetaFile();
63  return true;
64  }
65 
66  return rStream.good();
67 }
68 
69 bool ConvertGDIMetaFileToWMF( const GDIMetaFile & rMTF, SvStream & rTargetStream,
70  FilterConfigItem const * pConfigItem, bool bPlaceable)
71 {
72  WMFWriter aWMFWriter;
73  GDIMetaFile aGdiMetaFile(rMTF);
74 
75  if(usesClipActions(aGdiMetaFile))
76  {
77  // #i121267# It is necessary to prepare the metafile since the export does *not* support
78  // clip regions. This tooling method clips the geometry content of the metafile internally
79  // against its own clip regions, so that the export is safe to ignore clip regions
81  }
82 
83  bool bRet = aWMFWriter.WriteWMF(aGdiMetaFile, rTargetStream, pConfigItem, bPlaceable);
84  return bRet;
85 }
86 
87 bool ConvertGraphicToWMF(const Graphic& rGraphic, SvStream& rTargetStream,
88  FilterConfigItem const* pConfigItem, bool bPlaceable)
89 {
90  GfxLink aLink = rGraphic.GetGfxLink();
91  if (aLink.GetType() == GfxLinkType::NativeWmf && aLink.GetData() && aLink.GetDataSize())
92  {
93  if(!aLink.IsEMF()) // If WMF, just write directly.
94  return rTargetStream.WriteBytes(aLink.GetData(), aLink.GetDataSize()) == aLink.GetDataSize();
95 
96  // This may be an EMF+ file. In EmfReader::ReadEnhWMF() we normally drop non-EMF commands
97  // when reading EMF+, so converting that to WMF is better done by re-parsing with EMF+ disabled.
98  auto & rDataContainer = aLink.getDataContainer();
99  auto aVectorGraphicData
100  = std::make_shared<VectorGraphicData>(rDataContainer, VectorGraphicDataType::Emf);
101  aVectorGraphicData->setEnableEMFPlus(false);
102  Graphic aGraphic(aVectorGraphicData);
103  bool bRet = ConvertGDIMetaFileToWMF(aGraphic.GetGDIMetaFile(), rTargetStream, pConfigItem,
104  bPlaceable);
105  return bRet;
106  }
107 
108  bool bRet = ConvertGDIMetaFileToWMF(rGraphic.GetGDIMetaFile(), rTargetStream, pConfigItem,
109  bPlaceable);
110  return bRet;
111 }
112 
113 bool ConvertGDIMetaFileToEMF(const GDIMetaFile & rMTF, SvStream & rTargetStream)
114 {
115  EMFWriter aEMFWriter(rTargetStream);
116  GDIMetaFile aGdiMetaFile(rMTF);
117 
118  if(usesClipActions(aGdiMetaFile))
119  {
120  // #i121267# It is necessary to prepare the metafile since the export does *not* support
121  // clip regions. This tooling method clips the geometry content of the metafile internally
122  // against its own clip regions, so that the export is safe to ignore clip regions
124  }
125 
126  return aEMFWriter.WriteEMF(aGdiMetaFile);
127 }
128 
129 bool WriteWindowMetafileBits( SvStream& rStream, const GDIMetaFile& rMTF )
130 {
131  return WMFWriter().WriteWMF( rMTF, rStream, nullptr, false );
132 }
133 
134 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool WriteWMF(const GDIMetaFile &rMTF, SvStream &rTargetStream, FilterConfigItem const *pFilterConfigItem, bool bPlaceable)
Definition: wmfwr.cxx:1679
bool ReadWindowMetafile(SvStream &rStream, GDIMetaFile &rMTF)
Definition: wmf.cxx:28
virtual sal_uInt64 TellEnd()
bool ConvertGDIMetaFileToWMF(const GDIMetaFile &rMTF, SvStream &rTargetStream, FilterConfigItem const *pConfigItem, bool bPlaceable)
Definition: wmf.cxx:69
bool usesClipActions(const GDIMetaFile &rSource)
const ContentProperties & rData
sal_uInt64 Seek(sal_uInt64 nPos)
bool WriteWindowMetafileBits(SvStream &rStream, const GDIMetaFile &rMTF)
Definition: wmf.cxx:129
Container for the binary data, whose responsibility is to manage the make it as simple as possible to...
bool ConvertGDIMetaFileToEMF(const GDIMetaFile &rMTF, SvStream &rTargetStream)
Definition: wmf.cxx:113
const GDIMetaFile & GetGDIMetaFile() const
Definition: graph.cxx:339
void clipMetafileContentAgainstOwnRegions(GDIMetaFile &rSource)
bool ConvertGraphicToWMF(const Graphic &rGraphic, SvStream &rTargetStream, FilterConfigItem const *pConfigItem, bool bPlaceable)
Definition: wmf.cxx:87
std::size_t WriteBytes(const void *pData, std::size_t nSize)
bool WriteEMF(const GDIMetaFile &rMtf)
Definition: emfwr.cxx:239
GfxLink GetGfxLink() const
Definition: graph.cxx:509
std::size_t ReadBytes(void *pData, std::size_t nSize)
sal_uInt64 Tell() const
bool good() const