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 #ifndef INCLUDED_OOX_EXPORT_DRAWINGML_HXX
21 #define INCLUDED_OOX_EXPORT_DRAWINGML_HXX
22 
23 #include <map>
24 #include <string_view>
25 #include <vector>
26 
27 #include <com/sun/star/beans/PropertyState.hpp>
28 #include <com/sun/star/uno/Any.hxx>
29 #include <com/sun/star/uno/Reference.hxx>
30 #include <com/sun/star/uno/Sequence.hxx>
31 #include <com/sun/star/style/ParagraphAdjust.hpp>
32 #include <com/sun/star/drawing/Hatch.hpp>
33 #include <com/sun/star/i18n/ScriptType.hpp>
34 #include <oox/dllapi.h>
35 #include <oox/drawingml/drawingmltypes.hxx>
36 #include <oox/token/tokens.hxx>
37 #include <oox/export/utils.hxx>
38 #include <rtl/string.hxx>
39 #include <rtl/ustring.hxx>
40 #include <sal/types.h>
41 #include <sax/fshelper.hxx>
42 #include <svx/msdffdef.hxx>
43 #include <vcl/checksum.hxx>
44 #include <tools/gen.hxx>
45 #include <vcl/mapmod.hxx>
46 
47 class Graphic;
48 class SdrObjCustomShape;
49 
50 namespace com::sun::star {
51 namespace awt {
52     struct FontDescriptor;
53     struct Gradient;
54 }
55 namespace beans {
56     struct PropertyValue;
57     class XPropertySet;
58     class XPropertyState;
59 }
60 namespace drawing {
61     class XShape;
62     struct EnhancedCustomShapeParameterPair;
63     struct EnhancedCustomShapeParameter;
64 }
65 namespace graphic {
66     class XGraphic;
67 }
68 namespace style {
69     struct LineSpacing;
70 }
71 namespace text {
72     class XTextContent;
73     class XTextRange;
74     class XTextFrame;
75 }
76 namespace io {
77     class XOutputStream;
78 }
79 namespace uno {
80     class XInterface;
81 }
82 namespace frame {
83     class XModel;
84 }
85 }
86 
87 struct EscherConnectorListEntry;
88 class OutlinerParaObject;
89 namespace tools { class Rectangle; }
90 
91 namespace tools {
92     class PolyPolygon;
93 }
94 
95 namespace oox {
96 namespace core {
97     class XmlFilterBase;
98 }
99 
100 namespace drawingml {
101 
102 class OOX_DLLPUBLIC URLTransformer
103 {
104 public:
105     virtual ~URLTransformer();
106 
107     virtual OUString getTransformedString(const OUString& rURL) const;
108 
109     virtual bool isExternalURL(const OUString& rURL) const;
110 };
111 
112 // Our rotation is counter-clockwise and is in 100ths of a degree.
113 // drawingML rotation is clockwise and is in 60000ths of a degree.
ExportRotateClockwisify(Degree100 input)114 inline sal_Int32 ExportRotateClockwisify(Degree100 input)
115 {
116     return ((21600000 - input.get() * 600) % 21600000);
117 }
118 
119 /// Interface to be implemented by the parent exporter that knows how to handle shape text.
120 class OOX_DLLPUBLIC DMLTextExport
121 {
122 public:
123     virtual void WriteOutliner(const OutlinerParaObject& rParaObj) = 0;
124     /// Write the contents of the textbox that is associated to this shape.
125     virtual void WriteTextBox(css::uno::Reference<css::drawing::XShape> xShape) = 0;
126     /// Look up the RelId of a graphic based on its checksum.
127     virtual OUString FindRelId(BitmapChecksum nChecksum) = 0;
128     /// Look up the filename of a graphic based on its checksum.
129     virtual OUString FindFileName(BitmapChecksum nChecksum) = 0;
130     /// Store the RelId and filename of a graphic based on its checksum.
131     virtual void CacheRelId(BitmapChecksum nChecksum, const OUString& rRelId, const OUString& rFileName) = 0;
132     ///  Get textbox which belongs to the shape.
133     virtual css::uno::Reference<css::text::XTextFrame> GetUnoTextFrame(
134         css::uno::Reference<css::drawing::XShape> xShape) = 0;
135 protected:
DMLTextExport()136     DMLTextExport() {}
~DMLTextExport()137     virtual ~DMLTextExport() {}
138 };
139 
140 class OOX_DLLPUBLIC DrawingML
141 {
142 
143 private:
144     static int mnImageCounter;
145     static int mnWdpImageCounter;
146     static std::map<OUString, OUString> maWdpCache;
147     static sal_Int32 mnDrawingMLCount;
148     static sal_Int32 mnVmlCount;
149 
150     /// To specify where write eg. the images to (like 'ppt', or 'word' - according to the OPC).
151     DocumentType meDocumentType;
152     /// Parent exporter, used for text callback.
153     DMLTextExport* mpTextExport;
154 
155 
156 protected:
157     css::uno::Any                             mAny;
158     ::sax_fastparser::FSHelperPtr             mpFS;
159     ::oox::core::XmlFilterBase*               mpFB;
160     /// If set, this is the parent of the currently handled shape.
161     css::uno::Reference<css::drawing::XShape> m_xParent;
162     bool                                      mbIsBackgroundDark;
163 
164     bool GetProperty( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet, const OUString& aName );
165     bool GetPropertyAndState( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet,
166                   const css::uno::Reference< css::beans::XPropertyState >& rXPropState,
167                   const OUString& aName, css::beans::PropertyState& eState );
168     OUString GetFieldValue( const css::uno::Reference< css::text::XTextRange >& rRun, bool& bIsURLField );
169 
170     /// Output the media (including copying a video from vnd.sun.star.Package: to the output if necessary).
171     void WriteMediaNonVisualProperties(const css::uno::Reference<css::drawing::XShape>& xShape);
172 
173     void WriteStyleProperties( sal_Int32 nTokenId, const css::uno::Sequence< css::beans::PropertyValue >& aProperties );
174 
175     const char* GetComponentDir() const;
176     const char* GetRelationCompPrefix() const;
177 
178     static bool EqualGradients( css::awt::Gradient aGradient1, css::awt::Gradient aGradient2 );
179     bool IsFontworkShape(const css::uno::Reference< css::beans::XPropertySet >& rXShapePropSet);
180 
181     void WriteGlowEffect(const css::uno::Reference<css::beans::XPropertySet>& rXPropSet);
182     void WriteSoftEdgeEffect(const css::uno::Reference<css::beans::XPropertySet>& rXPropSet);
183     bool HasEnhancedCustomShapeSegmentCommand(const css::uno::Reference<css::drawing::XShape>& rXShape, const sal_Int16 nCommand);
184 
185 public:
DrawingML(::sax_fastparser::FSHelperPtr pFS,::oox::core::XmlFilterBase * pFB,DocumentType eDocumentType=DOCUMENT_PPTX,DMLTextExport * pTextExport=nullptr)186     DrawingML( ::sax_fastparser::FSHelperPtr pFS, ::oox::core::XmlFilterBase* pFB, DocumentType eDocumentType = DOCUMENT_PPTX, DMLTextExport* pTextExport = nullptr )
187         : meDocumentType( eDocumentType ), mpTextExport(pTextExport), mpFS( pFS ), mpFB( pFB ), mbIsBackgroundDark( false ) {}
SetFS(::sax_fastparser::FSHelperPtr pFS)188     void SetFS( ::sax_fastparser::FSHelperPtr pFS ) { mpFS = pFS; }
GetFS() const189     const ::sax_fastparser::FSHelperPtr& GetFS() const { return mpFS; }
GetFB()190     ::oox::core::XmlFilterBase* GetFB() { return mpFB; }
GetDocumentType() const191     DocumentType GetDocumentType() const { return meDocumentType; }
192     /// The application-specific text exporter callback, if there is one.
GetTextExport()193     DMLTextExport* GetTextExport() { return mpTextExport; }
194 
SetBackgroundDark(bool bIsDark)195     void SetBackgroundDark(bool bIsDark) { mbIsBackgroundDark = bIsDark; }
196     /// If bRelPathToMedia is true add "../" to image folder path while adding the image relationship
197     OUString WriteImage( const Graphic &rGraphic , bool bRelPathToMedia = false, OUString* pFileName = nullptr );
198 
199     void WriteColor( ::Color nColor, sal_Int32 nAlpha = MAX_PERCENT );
200     void WriteColor( const OUString& sColorSchemeName, const css::uno::Sequence< css::beans::PropertyValue >& aTransformations, sal_Int32 nAlpha = MAX_PERCENT );
201     void WriteColor( const ::Color nColor, const css::uno::Sequence< css::beans::PropertyValue >& aTransformations, sal_Int32 nAlpha = MAX_PERCENT );
202     void WriteColorTransformations( const css::uno::Sequence< css::beans::PropertyValue >& aTransformations, sal_Int32 nAlpha = MAX_PERCENT );
203     void WriteGradientStop(sal_uInt16 nStop, ::Color nColor, sal_Int32 nAlpha = MAX_PERCENT);
204     void WriteLineArrow( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet, bool bLineStart );
205     void WriteConnectorConnections( EscherConnectorListEntry& rConnectorEntry, sal_Int32 nStartID, sal_Int32 nEndID );
206 
207     void WriteSolidFill( ::Color nColor, sal_Int32 nAlpha = MAX_PERCENT );
208     void WriteSolidFill( const OUString& sSchemeName, const css::uno::Sequence< css::beans::PropertyValue >& aTransformations, sal_Int32 nAlpha = MAX_PERCENT );
209     void WriteSolidFill( const ::Color nColor, const css::uno::Sequence< css::beans::PropertyValue >& aTransformations, sal_Int32 nAlpha = MAX_PERCENT );
210     void WriteSolidFill( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet );
211     void WriteGradientFill( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet );
212 
213     void WriteGradientFill( css::awt::Gradient rGradient, css::awt::Gradient rTransparenceGradient,
214                             const css::uno::Reference<css::beans::XPropertySet>& rXPropSet = css::uno::Reference<css::beans::XPropertySet>());
215 
216     void WriteGrabBagGradientFill( const css::uno::Sequence< css::beans::PropertyValue >& aGradientStops, css::awt::Gradient rGradient);
217 
218     void WriteBlipOrNormalFill( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet,
219             const OUString& rURLPropName );
220     void WriteBlipFill( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet,
221             const OUString& sURLPropName );
222     void WriteBlipFill( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet,
223                          const OUString& sURLPropName, sal_Int32 nXmlNamespace );
224 
225     void WriteXGraphicBlipFill(css::uno::Reference<css::beans::XPropertySet> const & rXPropSet,
226                                css::uno::Reference<css::graphic::XGraphic> const & rxGraphic,
227                                sal_Int32 nXmlNamespace, bool bWriteMode, bool bRelPathToMedia = false);
228 
229     void WritePattFill( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet );
230     void WritePattFill(const css::uno::Reference<css::beans::XPropertySet>& rXPropSet,
231             const css::drawing::Hatch& rHatch);
232 
233     void WriteGraphicCropProperties(css::uno::Reference<css::beans::XPropertySet> const & rxPropertySet,
234                                     Size const & rOriginalSize, MapMode const & rMapMode);
235 
236     void WriteSrcRectXGraphic(css::uno::Reference<css::beans::XPropertySet> const & rxPropertySet,
237                               css::uno::Reference<css::graphic::XGraphic> const & rxGraphic);
238 
239     void WriteOutline( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet,
240                               css::uno::Reference< css::frame::XModel> const & xModel = nullptr );
241 
242     void WriteXGraphicStretch(css::uno::Reference<css::beans::XPropertySet> const & rXPropSet,
243                               css::uno::Reference<css::graphic::XGraphic> const & rxGraphic);
244 
245     void WriteLinespacing( const css::style::LineSpacing& rLineSpacing );
246 
247     OUString WriteXGraphicBlip(css::uno::Reference<css::beans::XPropertySet> const & rXPropSet,
248                                css::uno::Reference<css::graphic::XGraphic> const & rxGraphic,
249                                bool bRelPathToMedia);
250 
251     void WriteImageBrightnessContrastTransparence(css::uno::Reference<css::beans::XPropertySet> const & rXPropSet);
252 
253     void WriteXGraphicBlipMode(css::uno::Reference<css::beans::XPropertySet> const & rXPropSet,
254                                css::uno::Reference<css::graphic::XGraphic> const & rxGraphic);
255 
256     void WriteShapeTransformation(const css::uno::Reference< css::drawing::XShape >& rXShape,
257                   sal_Int32 nXmlNamespace, bool bFlipH = false, bool bFlipV = false, bool bSuppressRotation = false, bool bSuppressFlipping = false, bool bFlippedBeforeRotation = false);
258     void WriteTransformation(const css::uno::Reference< css::drawing::XShape >& xShape, const tools::Rectangle& rRectangle,
259                   sal_Int32 nXmlNamespace, bool bFlipH = false, bool bFlipV = false, sal_Int32 nRotation = 0, bool bIsGroupShape = false);
260 
261     void WriteText( const css::uno::Reference< css::uno::XInterface >& rXIface, bool bBodyPr, bool bText = true, sal_Int32 nXmlNamespace = 0);
262     void WriteParagraph( const css::uno::Reference< css::text::XTextContent >& rParagraph,
263                          bool& rbOverridingCharHeight, sal_Int32& rnCharHeight, const css::uno::Reference< css::beans::XPropertySet >& rXShapePropSet);
264     void WriteParagraphProperties(const css::uno::Reference< css::text::XTextContent >& rParagraph, float fFirstCharHeight);
265     void WriteParagraphNumbering(const css::uno::Reference< css::beans::XPropertySet >& rXPropSet, float fFirstCharHeight,
266                                   sal_Int16 nLevel );
267     void WriteParagraphTabStops(const css::uno::Reference<css::beans::XPropertySet>& rXPropSet);
268     void WriteRun( const css::uno::Reference< css::text::XTextRange >& rRun,
269                    bool& rbOverridingCharHeight, sal_Int32& rnCharHeight,
270                    const css::uno::Reference< css::beans::XPropertySet >& rXShapePropSet);
271     void WriteRunProperties( const css::uno::Reference< css::beans::XPropertySet >& rRun, bool bIsField, sal_Int32 nElement, bool bCheckDirect,
272                              bool& rbOverridingCharHeight, sal_Int32& rnCharHeight,
273                              sal_Int16 nScriptType = css::i18n::ScriptType::LATIN,
274                              const css::uno::Reference< css::beans::XPropertySet >& rXShapePropSet = {});
275 
276     void WritePresetShape( const char* pShape , std::vector< std::pair<sal_Int32,sal_Int32>> & rAvList );
277     void WritePresetShape( const char* pShape );
278     void WritePresetShape( const char* pShape, MSO_SPT eShapeType, bool bPredefinedHandlesUsed, const css::beans::PropertyValue& rProp );
279     bool WriteCustomGeometry(
280         const css::uno::Reference<css::drawing::XShape>& rXShape,
281         const SdrObjCustomShape& rSdrObjCustomShape);
282     void WriteCustomGeometryPoint(
283         const css::drawing::EnhancedCustomShapeParameterPair& rParamPair,
284         const SdrObjCustomShape& rSdrObjCustomShape);
285     static sal_Int32 GetCustomGeometryPointValue(
286         const css::drawing::EnhancedCustomShapeParameter& rParam,
287         const SdrObjCustomShape& rSdrObjCustomShape);
288     void WritePolyPolygon(const css::uno::Reference<css::drawing::XShape>& rXShape,
289                           const tools::PolyPolygon& rPolyPolygon, const bool bClosed);
290     void WriteFill( const css::uno::Reference< css::beans::XPropertySet >& xPropSet );
291     void WriteShapeStyle( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet );
292     void WriteShapeEffects( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet );
293     void WriteShapeEffect( std::u16string_view sName, const css::uno::Sequence< css::beans::PropertyValue >& aEffectProps );
294     void WriteShape3DEffects( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet );
295     void WriteArtisticEffect( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet );
296     OString WriteWdpPicture( const OUString& rFileId, const css::uno::Sequence< sal_Int8 >& rPictureData );
297     void WriteDiagram(const css::uno::Reference<css::drawing::XShape>& rXShape, int nDiagramId);
298     void writeDiagramRels(const css::uno::Sequence<css::uno::Sequence<css::uno::Any>>& xRelSeq,
299                           const css::uno::Reference<css::io::XOutputStream>& xOutStream,
300                           std::u16string_view sGrabBagProperyName, int nDiagramId);
301     static void WriteFromTo(const css::uno::Reference<css::drawing::XShape>& rXShape, const css::awt::Size& aPageSize,
302                             const sax_fastparser::FSHelperPtr& pDrawing);
303 
304     static bool IsGroupShape( const css::uno::Reference< css::drawing::XShape >& rXShape );
305     static bool IsDiagram(const css::uno::Reference<css::drawing::XShape>& rXShape);
306     sal_Int32 getBulletMarginIndentation (const css::uno::Reference< css::beans::XPropertySet >& rXPropSet,sal_Int16 nLevel, std::u16string_view propName);
307 
308     static void ResetCounters();
309 
310     static void ResetMlCounters();
311 
getNewDrawingUniqueId()312     static sal_Int32 getNewDrawingUniqueId() { return ++mnDrawingMLCount; }
getNewVMLUniqueId()313     static sal_Int32 getNewVMLUniqueId() { return ++mnVmlCount; }
314 
315     // A Helper to decide the script type for given text in order to call WriteRunProperties.
316     static sal_Int16 GetScriptType(const OUString& rStr);
317 
318     static sal_Unicode SubstituteBullet( sal_Unicode cBulletId, css::awt::FontDescriptor& rFontDesc );
319 
320     static ::Color ColorWithIntensity( sal_uInt32 nColor, sal_uInt32 nIntensity );
321 
322     static const char* GetAlignment( css::style::ParagraphAdjust nAlignment );
323 
324     sax_fastparser::FSHelperPtr     CreateOutputStream (
325                                         const OUString& sFullStream,
326                                         std::u16string_view sRelativeStream,
327                                         const css::uno::Reference< css::io::XOutputStream >& xParentRelation,
328                                         const char* sContentType,
329                                         const char* sRelationshipType,
330                                         OUString* pRelationshipId );
331 
332 };
333 
334 }
335 }
336 
337 #endif
338 
339 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
340