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_FILTER_MSFILTER_ESCHEREX_HXX
21 #define INCLUDED_FILTER_MSFILTER_ESCHEREX_HXX
22 
23 #include <memory>
24 #include <vector>
25 
26 #include <com/sun/star/awt/Point.hpp>
27 #include <com/sun/star/beans/PropertyState.hpp>
28 #include <com/sun/star/drawing/BitmapMode.hpp>
29 #include <com/sun/star/awt/XBitmap.hpp>
30 #include <com/sun/star/uno/Any.hxx>
31 #include <com/sun/star/uno/Reference.hxx>
32 #include <filter/msfilter/msfilterdllapi.h>
33 #include <rtl/string.hxx>
34 #include <rtl/ustring.hxx>
35 #include <sal/types.h>
36 #include <vcl/GraphicObject.hxx>
37 #include <svx/svdtypes.hxx>
38 #include <svx/msdffdef.hxx>
39 #include <tools/gen.hxx>
40 #include <tools/solar.h>
41 #include <tools/stream.hxx>
42 #include <vcl/mapmod.hxx>
43 #include <o3tl/typed_flags_set.hxx>
44 
45 class Color;
46 
47 namespace com { namespace sun { namespace star {
48     namespace awt { struct Rectangle; }
49     namespace beans { class XPropertySet; }
50     namespace drawing { struct EnhancedCustomShapeParameter; }
51     namespace drawing { struct Hatch; }
52 } } }
53 
54 namespace tools {
55     class Polygon;
56     class PolyPolygon;
57 }
58 
59         /*Record Name       FBT-Value   Instance                  Contents                                                          Wrd Exl PPT Ver*/
60 // In the Microsoft documentation the naming scheme is msofbt... instead of ESCHER_...
61 #define ESCHER_DggContainer     0xF000u /*                           per-document data                                                  X   X   X     */
62 #define ESCHER_Dgg              0xF006u /*                           an FDGG and several FIDCLs                                         X   X   X   0 */
63 #define ESCHER_OPT              0xF00Bu /* count of properties       the document-wide default shape properties                         X   X   X   3 */
64 #define ESCHER_SplitMenuColors  0xF11Eu /* count of colors           the colors in the top-level split menus                            X   X   X   0 */
65 #define ESCHER_BstoreContainer  0xF001u /* count of BLIPs            all images in the document (JPEGs, metafiles, etc.)                X   X   X     */
66 #define ESCHER_BSE              0xF007u /* BLIP type                 an FBSE (one per BLIP)                                             X   X   X   2 */
67 #define ESCHER_BlipFirst        0xF018u /*                           range of fbts reserved for various kinds of BLIPs                  X   X   X     */
68 
69 #define ESCHER_DgContainer      0xF002u /*                           per-sheet/page/slide data                                          X   X   X     */
70 #define ESCHER_Dg               0xF008u /* drawing ID                an FDG                                                             X   X   X   0 */
71 #define ESCHER_SpgrContainer    0xF003u /*                           several SpContainers, the first of which is the group shape itself X   X   X     */
72 #define ESCHER_SpContainer      0xF004u /*                           a shape                                                            X   X   X     */
73 #define ESCHER_Spgr             0xF009u /*                           an FSPGR; only present if the shape is a group shape               X   X   X   1 */
74 #define ESCHER_Sp               0xF00Au /* shape type                an FSP                                                             X   X   X   2 */
75 //#define     ESCHER_OPT           0xF00Bu /* count of properties       a shape property table                                             X   X   X   3 */
76 #define ESCHER_ClientTextbox    0xF00Du /* host-defined              the text in the textbox, in host-defined format                    X   X   X     */
77 #define ESCHER_ChildAnchor      0xF00Fu /*                           a RECT, in units relative to the parent group                      X   X   X   0 */
78 #define ESCHER_ClientAnchor     0xF010u /* host-defined              the location of the shape, in a host-defined format                X   X   X     */
79 #define ESCHER_ClientData       0xF011u /* host-defined              host-specific data                                                 X   X   X     */
80 #define ESCHER_SolverContainer  0xF005u /* count of rules            the rules governing shapes                                         X   X   X     */
81 #define ESCHER_ConnectorRule    0xF012u /*                           an FConnectorRule                                                      X   X   1 */
82 #define ESCHER_UDefProp         0xF122u
83 
84 enum class ShapeFlag : sal_uInt32
85 {
86     NONE                = 0x000,
87     Group               = 0x001,   /* shape is a group shape */
88     Child               = 0x002,   /* shape is a child shape */
89     Patriarch           = 0x004,   /* shape is the topmost group shape.
90                                       Exactly one of these per drawing. */
91     Deleted             = 0x008,   /* shape has been deleted */
92     OLEShape            = 0x010,   /* shape is an OLE object */
93     HaveMaster          = 0x020,   /* shape has a valid master in hspMaster property */
94     FlipH               = 0x040,   /* shape is flipped horizontally */
95     FlipV               = 0x080,   /* shape is flipped vertically */
96     Connector           = 0x100,   /* shape is a connector shape */
97     HaveAnchor          = 0x200,   /* shape has an anchor of some kind */
98     Background          = 0x400,   /* shape is a background shape */
99     HaveShapeProperty   = 0x800    /* shape has a shape type property */
100 };  /* 20 bits unused */
101 namespace o3tl {
102     template<> struct typed_flags<ShapeFlag> : is_typed_flags<ShapeFlag, 0x00000FFF> {};
103 }
104 
105 #define ESCHER_ShpInst_Min                          0
106 #define ESCHER_ShpInst_NotPrimitive                 ESCHER_ShpInst_Min
107 #define ESCHER_ShpInst_Rectangle                    1
108 #define ESCHER_ShpInst_RoundRectangle               2
109 #define ESCHER_ShpInst_Ellipse                      3
110 #define ESCHER_ShpInst_Arc                          19
111 #define ESCHER_ShpInst_Line                         20
112 #define ESCHER_ShpInst_StraightConnector1           32
113 #define ESCHER_ShpInst_BentConnector2               33
114 #define ESCHER_ShpInst_BentConnector3               34
115 #define ESCHER_ShpInst_CurvedConnector3             38
116 #define ESCHER_ShpInst_PictureFrame                 75
117 #define ESCHER_ShpInst_TextPlainText                136
118 #define ESCHER_ShpInst_TextDeflateInflateDeflate    167
119 #define ESCHER_ShpInst_TextSlantUp                  172
120 #define ESCHER_ShpInst_HostControl                  201
121 #define ESCHER_ShpInst_TextBox                      202
122 #define ESCHER_ShpInst_COUNT                        203
123 #define ESCHER_ShpInst_Max                          0x0FFF
124 #define ESCHER_ShpInst_Nil                          ESCHER_ShpInst_Max
125 
126 enum ESCHER_BlibType
127 {                           // GEL provided types...
128    ERROR = 0,               // An error occurred during loading
129    UNKNOWN,                 // An unknown blip type
130    EMF,                     // Windows Enhanced Metafile
131    WMF,                     // Windows Metafile
132    PICT,                    // Macintosh PICT
133    PEG,                     // JFIF
134    PNG,                     // PNG
135    DIB,                     // Windows DIB
136    FirstClient = 32,        // First client defined blip type
137    LastClient  = 255        // Last client defined blip type
138 };
139 
140 
141 enum ESCHER_FillStyle
142 {
143     ESCHER_FillSolid,       // Fill with a solid color
144     ESCHER_FillPattern,     // Fill with a pattern (bitmap)
145     ESCHER_FillTexture,     // A texture (pattern with its own color map)
146     ESCHER_FillPicture,     // Center a picture in the shape
147     ESCHER_FillShade,       // Shade from start to end points
148     ESCHER_FillShadeCenter, // Shade from bounding rectangle to end point
149     ESCHER_FillShadeShape,  // Shade from shape outline to end point
150     ESCHER_FillShadeScale,
151     ESCHER_FillShadeTitle,
152     ESCHER_FillBackground
153 };
154 
155 enum ESCHER_wMode
156 {
157     ESCHER_wColor,          // only used for predefined shades
158     ESCHER_wAutomatic,      // depends on object type
159     ESCHER_wGrayScale,      // shades of gray only
160     ESCHER_wLightGrayScale, // shades of light gray only
161     ESCHER_wInverseGray,    // dark gray mapped to light gray, etc.
162     ESCHER_wGrayOutline,    // pure gray and white
163     ESCHER_wBlackTextLine,  // black text and lines, all else grayscale
164     ESCHER_wHighContrast,   // pure black and white mode (no grays)
165     ESCHER_wBlack,          // solid black   msobwWhite,          // solid white
166     ESCHER_wDontShow,       // object not drawn
167     ESCHER_wNumModes        // number of Black and white modes
168 };
169 
170 
171 enum ESCHER_ShapePath
172 {
173     ESCHER_ShapeLines,          // A line of straight segments
174     ESCHER_ShapeLinesClosed,    // A closed polygonal object
175     ESCHER_ShapeCurves,         // A line of Bezier curve segments
176     ESCHER_ShapeCurvesClosed,   // A closed shape with curved edges
177     ESCHER_ShapeComplex         // pSegmentInfo must be non-empty
178 };
179 
180 
181 enum ESCHER_WrapMode
182 {
183     ESCHER_WrapSquare,
184     ESCHER_WrapByPoints,
185     ESCHER_WrapNone,
186     ESCHER_WrapTopBottom,
187     ESCHER_WrapThrough
188 };
189 
190 
191 enum ESCHER_bwMode
192 {
193     ESCHER_bwColor,             // only used for predefined shades
194     ESCHER_bwAutomatic,         // depends on object type
195     ESCHER_bwGrayScale,         // shades of gray only
196     ESCHER_bwLightGrayScale,    // shades of light gray only
197     ESCHER_bwInverseGray,       // dark gray mapped to light gray, etc.
198     ESCHER_bwGrayOutline,       // pure gray and white
199     ESCHER_bwBlackTextLine,     // black text and lines, all else grayscale
200     ESCHER_bwHighContrast,      // pure black and white mode (no grays)
201     ESCHER_bwBlack,             // solid black
202     ESCHER_bwWhite,             // solid white
203     ESCHER_bwDontShow,          // object not drawn
204     ESCHER_bwNumModes           // number of Black and white modes
205 };
206 
207 
208 enum ESCHER_AnchorText
209 {
210     ESCHER_AnchorTop,
211     ESCHER_AnchorMiddle,
212     ESCHER_AnchorBottom,
213     ESCHER_AnchorTopCentered,
214     ESCHER_AnchorMiddleCentered,
215     ESCHER_AnchorBottomCentered,
216     ESCHER_AnchorTopBaseline,
217     ESCHER_AnchorBottomBaseline,
218     ESCHER_AnchorTopCenteredBaseline,
219     ESCHER_AnchorBottomCenteredBaseline
220 };
221 
222 //  connector style
223 enum ESCHER_cxSTYLE
224 {
225     ESCHER_cxstyleStraight = 0,
226     ESCHER_cxstyleBent,
227     ESCHER_cxstyleCurved,
228     ESCHER_cxstyleNone
229 };
230 
231 //  text flow
232 enum ESCHER_txfl
233 {
234     ESCHER_txflHorzN,           // Horizontal non-@
235     ESCHER_txflTtoBA,           // Top to Bottom @-font
236     ESCHER_txflBtoT,            // Bottom to Top non-@
237     ESCHER_txflTtoBN,           // Top to Bottom non-@
238     ESCHER_txflHorzA,           // Horizontal @-font
239     ESCHER_txflVertN            // Vertical, non-@
240 };
241 
242 
243 //  flags for pictures
244 enum ESCHER_BlipFlags
245 {
246     ESCHER_BlipFlagDefault = 0,
247     ESCHER_BlipFlagComment = 0,     // Blip name is a comment
248     ESCHER_BlipFlagFile,            // Blip name is a file name
249     ESCHER_BlipFlagURL,             // Blip name is a full URL
250     ESCHER_BlipFlagType = 3,        // Mask to extract type
251    /* Or the following flags with any of the above. */
252     ESCHER_BlipFlagDoNotSave = 4,
253     ESCHER_BlipFlagLinkToFile = 8
254 };
255 
256 // dashed line style
257 enum ESCHER_LineDashing
258 {
259     ESCHER_LineSolid,               // Solid (continuous) pen
260     ESCHER_LineDashSys,             // PS_DASH system   dash style
261     ESCHER_LineDotSys,              // PS_DOT system   dash style
262     ESCHER_LineDashDotSys,          // PS_DASHDOT system dash style
263     ESCHER_LineDashDotDotSys,       // PS_DASHDOTDOT system dash style
264     ESCHER_LineDotGEL,              // square dot style
265     ESCHER_LineDashGEL,             // dash style
266     ESCHER_LineLongDashGEL,         // long dash style
267     ESCHER_LineDashDotGEL,          // dash short dash
268     ESCHER_LineLongDashDotGEL,      // long dash short dash
269     ESCHER_LineLongDashDotDotGEL    // long dash short dash short dash
270 };
271 
272 // line end effect
273 enum ESCHER_LineEnd
274 {
275     ESCHER_LineNoEnd,
276     ESCHER_LineArrowEnd,
277     ESCHER_LineArrowStealthEnd,
278     ESCHER_LineArrowDiamondEnd,
279     ESCHER_LineArrowOvalEnd,
280     ESCHER_LineArrowOpenEnd
281 };
282 
283 // size of arrowhead
284 enum ESCHER_LineWidth
285 {
286     ESCHER_LineNarrowArrow,
287     ESCHER_LineMediumWidthArrow,
288     ESCHER_LineWideArrow
289 };
290 
291 // size of arrowhead
292 enum ESCHER_LineEndLength
293 {
294     ESCHER_LineShortArrow,
295     ESCHER_LineMediumLenArrow,
296     ESCHER_LineLongArrow
297 };
298 
299 // line join style.
300 enum ESCHER_LineJoin
301 {
302     ESCHER_LineJoinBevel,     // Join edges by a straight line
303     ESCHER_LineJoinMiter,     // Extend edges until they join
304     ESCHER_LineJoinRound      // Draw an arc between the two edges
305 };
306 
307 // line cap style (applies to ends of dash segments too).
308 enum ESCHER_LineCap
309 {
310     ESCHER_LineEndCapRound,   // Rounded ends - the default
311     ESCHER_LineEndCapSquare,  // Square protrudes by half line width
312     ESCHER_LineEndCapFlat     // Line ends at end point
313 };
314 
315 enum MSOPATHTYPE
316 {
317     msopathLineTo,        // Draw a straight line (one point)
318     msopathCurveTo,       // Draw a cubic Bezier curve (three points)
319     msopathMoveTo,        // Move to a new point (one point)
320     msopathClose,         // Close a sub - path (no points)
321     msopathEnd,           // End a path (no points)
322     msopathEscape,        // Escape code
323     msopathClientEscape,  // Escape code interpreted by the client
324     msopathInvalid        // Invalid - should never be found
325 };
326 
327 // Shape Properties
328 // 1pt = 12700 EMU (English Metric Units)
329 // 1pt = 20 Twip = 20/1440" = 1/72"
330 // 1twip=635 EMU
331 // 1" = 12700*72 = 914400 EMU
332 // 1" = 25.4mm
333 // 1mm = 36000 EMU
334 // Transform
335 #define ESCHER_Prop_Rotation                      4  /*  Fixed Point 16.16 degrees                  */
336 // Protection
337 #define ESCHER_Prop_LockAgainstGrouping         127  /*  bool              Do not group this shape             */
338 // Text
339 #define ESCHER_Prop_lTxid                       128  /*  LONG              id for the text, value determined by the host            */
340 #define ESCHER_Prop_dxTextLeft                  129  /*  LONG              margins relative to shape's inscribed                    */
341 #define ESCHER_Prop_dyTextTop                   130  /*  LONG                text rectangle (in EMUs)                               */
342 #define ESCHER_Prop_dxTextRight                 131  /*  LONG                                                                       */
343 #define ESCHER_Prop_dyTextBottom                132  /*  LONG                                                                       */
344 #define ESCHER_Prop_WrapText                    133  /*  MSOWRAPMODE       Wrap text at shape margins                               */
345 #define ESCHER_Prop_AnchorText                  135  /*  ESCHER_AnchorText How to anchor the text                                   */
346 #define ESCHER_Prop_txflTextFlow                136  /*  MSOTXFL           Text flow                                                */
347 #define ESCHER_Prop_hspNext                     138  /*  MSOHSP            ID of the next shape (used by Word for linked textboxes) */
348 #define ESCHER_Prop_FitTextToShape              191  /*  bool              Size text to fit shape size                              */
349 // GeoText
350 #define ESCHER_Prop_gtextUNICODE                192  /*  WCHAR*            UNICODE text string       */
351 #define ESCHER_Prop_gtextSize                   195  /*  LONG              default point size        */
352 #define ESCHER_Prop_gtextFont                   197  /*  WCHAR*            font family name          */
353 // Blip
354 #define ESCHER_Prop_cropFromTop                 256  /*  LONG              16.16 fraction times total                          */
355 #define ESCHER_Prop_cropFromBottom              257  /*  LONG                image width or height,                            */
356 #define ESCHER_Prop_cropFromLeft                258  /*  LONG                as appropriate.                                   */
357 #define ESCHER_Prop_cropFromRight               259  /*  LONG                                                                  */
358 #define ESCHER_Prop_pib                         260  /*  IMsoBlip*         Blip to display                                     */
359 #define ESCHER_Prop_pibName                     261  /*  WCHAR*            Blip file name                                      */
360 #define ESCHER_Prop_pibFlags                    262  /*  MSOBLIPFLAGS      Blip flags                                          */
361 #define ESCHER_Prop_pictureContrast             264  /*  LONG              contrast setting                                    */
362 #define ESCHER_Prop_pictureBrightness           265  /*  LONG              brightness setting                                  */
363 #define ESCHER_Prop_pictureId                   267  /*  LONG              Host-defined ID for OLE objects (usually a pointer) */
364 #define ESCHER_Prop_pictureActive               319  /*  bool              Server is active (OLE objects only)                 */
365 // Geometry
366 #define ESCHER_Prop_geoLeft                     320  /*  LONG              Defines the G (geometry) coordinate space.  */
367 #define ESCHER_Prop_geoTop                      321  /*  LONG                                                          */
368 #define ESCHER_Prop_geoRight                    322  /*  LONG                                                          */
369 #define ESCHER_Prop_geoBottom                   323  /*  LONG                                                          */
370 #define ESCHER_Prop_shapePath                   324  /*  MSOSHAPEPATH                                                  */
371 #define ESCHER_Prop_pVertices                   325  /*  IMsoArray         An array of points, in G units.             */
372 #define ESCHER_Prop_pSegmentInfo                326  /*  IMsoArray                                                     */
373 #define ESCHER_Prop_adjustValue                 327  /*  LONG              Adjustment values corresponding to          */
374 #define ESCHER_Prop_adjust2Value                328  /*  LONG                the positions of the adjust handles       */
375 #define ESCHER_Prop_fFillOK                     383  /*  bool              OK to fill the shape through the UI or VBA? */
376 // FillStyle
377 #define ESCHER_Prop_fillType                    384  /*  ESCHER_FillStyle  Type of fill                                  */
378 #define ESCHER_Prop_fillColor                   385  /*  MSOCLR            Foreground color                              */
379 #define ESCHER_Prop_fillOpacity                 386  /*  LONG              Fixed 16.16                                   */
380 #define ESCHER_Prop_fillBackColor               387  /*  MSOCLR            Background color                              */
381 #define ESCHER_Prop_fillBackOpacity             388  /*  LONG              Shades only                                   */
382 #define ESCHER_Prop_fillBlip                    390  /*  IMsoBlip*         Pattern/texture                               */
383 #define ESCHER_Prop_fillAngle                   395  /*  LONG              Fade angle - degrees in 16.16                 */
384 #define ESCHER_Prop_fillFocus                   396  /*  LONG              Linear shaded fill focus percent              */
385 #define ESCHER_Prop_fillToLeft                  397  /*  LONG              Fraction 16.16                                */
386 #define ESCHER_Prop_fillToTop                   398  /*  LONG              Fraction 16.16                                */
387 #define ESCHER_Prop_fillToRight                 399  /*  LONG              Fraction 16.16                                */
388 #define ESCHER_Prop_fillToBottom                400  /*  LONG              Fraction 16.16                                */
389 #define ESCHER_Prop_fillRectRight               403  /*  LONG                define how large the fade is going to be.   */
390 #define ESCHER_Prop_fillRectBottom              404  /*  LONG                                                            */
391 #define ESCHER_Prop_fNoFillHitTest              447  /*  bool              Hit test a shape as though filled             */
392 // LineStyle
393 #define ESCHER_Prop_lineColor                   448  /*  MSOCLR            Color of line                              */
394 #define ESCHER_Prop_lineOpacity                 449  /*  LONG              Not implemented                            */
395 #define ESCHER_Prop_lineBackColor               450  /*  MSOCLR            Background color                           */
396 #define ESCHER_Prop_lineWidth                   459  /*  LONG              A units; 1pt == 12700 EMUs                 */
397 #define ESCHER_Prop_lineStyle                   461  /*  MSOLINESTYLE      Draw parallel lines?                       */
398 #define ESCHER_Prop_lineDashing                 462  /*  MSOLINEDASHING    Can be overridden by:                      */
399 #define ESCHER_Prop_lineStartArrowhead          464  /*  MSOLINEEND        Arrow at start                             */
400 #define ESCHER_Prop_lineEndArrowhead            465  /*  MSOLINEEND        Arrow at end                               */
401 #define ESCHER_Prop_lineStartArrowWidth         466  /*  MSOLINEENDWIDTH   Arrow at start                             */
402 #define ESCHER_Prop_lineStartArrowLength        467  /*  MSOLINEENDLENGTH  Arrow at end                               */
403 #define ESCHER_Prop_lineEndArrowWidth           468  /*  MSOLINEENDWIDTH   Arrow at start                             */
404 #define ESCHER_Prop_lineEndArrowLength          469  /*  MSOLINEENDLENGTH  Arrow at end                               */
405 #define ESCHER_Prop_lineJoinStyle               470  /*  MSOLINEJOIN       How to join lines                          */
406 #define ESCHER_Prop_lineEndCapStyle             471  /*  MSOLINECAP        How to end lines                           */
407 #define ESCHER_Prop_fNoLineDrawDash             511  /*  bool              Draw a dashed line if no line              */
408 // ShadowStyle
409 #define ESCHER_Prop_shadowColor                 513  /*  MSOCLR            Foreground color          */
410 #define ESCHER_Prop_shadowOpacity               516  /*  LONG              Fixed 16.16               */
411 #define ESCHER_Prop_shadowOffsetX               517  /*  LONG              Offset shadow             */
412 #define ESCHER_Prop_shadowOffsetY               518  /*  LONG              Offset shadow             */
413 #define ESCHER_Prop_fshadowObscured             575  /*  bool              Excel5-style shadow       */
414 // 3D Object
415 #define ESCHER_Prop_fc3DLightFace               703  /*  bool                                                                                                                             */
416 // Shape
417 #define ESCHER_Prop_hspMaster                   769  /*  MSOHSP          master shape                                        */
418 #define ESCHER_Prop_cxstyle                     771  /*  MSOCXSTYLE      Type of connector                                   */
419 #define ESCHER_Prop_bWMode                      772  /*  ESCHERwMode     Settings for modifications to                       */
420 #define ESCHER_Prop_fBackground                 831  /*  bool            If sal_True, this is the background shape.              */
421 // GroupShape
422 #define ESCHER_Prop_wzName                      896  /*  WCHAR*          Shape Name (present only if explicitly set)                                                            */
423 #define ESCHER_Prop_wzDescription               897  /*  WCHAR*          alternate text                                                                                         */
424 #define ESCHER_Prop_pihlShape                   898  /*  IHlink*         The hyperlink in the shape.                                                                            */
425 #define ESCHER_Prop_dxWrapDistLeft              900  /*  LONG            Left wrapping distance from text (Word)                                                                */
426 #define ESCHER_Prop_dyWrapDistTop               901  /*  LONG            Top wrapping distance from text (Word)                                                                 */
427 #define ESCHER_Prop_dxWrapDistRight             902  /*  LONG            Right wrapping distance from text (Word)                                                               */
428 #define ESCHER_Prop_dyWrapDistBottom            903  /*  LONG            Bottom wrapping distance from text (Word)                                                              */
429 #define ESCHER_Prop_tableProperties             927
430 #define ESCHER_Prop_tableRowProperties          928
431 #define ESCHER_Prop_fHidden                     958  /*  bool            Do not display                                                                                         */
432 #define ESCHER_Prop_fPrint                      959  /*  bool            Print this shape                                                                                       */
433 
434 
435 #define ESCHER_Persist_PrivateEntry         0x80000000
436 #define ESCHER_Persist_Dgg                  0x00010000
437 #define ESCHER_Persist_Dg                   0x00020000
438 #define ESCHER_Persist_CurrentPosition      0x00040000
439 #define ESCHER_Persist_Grouping_Snap        0x00050000
440 #define ESCHER_Persist_Grouping_Logic       0x00060000
441 
442 const sal_uInt32 DFF_DGG_CLUSTER_SIZE       = 0x00000400;   /// Shape IDs per cluster in DGG atom.
443 
444 namespace com { namespace sun { namespace star {
445     namespace awt {
446         struct Gradient;
447     }
448     namespace drawing {
449         struct EnhancedCustomShapeAdjustmentValue;
450         class XShape;
451         class XShapes;
452     }
453 }}}
454 
455 struct MSFILTER_DLLPUBLIC EscherConnectorListEntry
456 {
457     css::uno::Reference< css::drawing::XShape >   mXConnector;
458     css::awt::Point                               maPointA;
459     css::uno::Reference< css::drawing::XShape >   mXConnectToA;
460     css::awt::Point                               maPointB;
461     css::uno::Reference< css::drawing::XShape >   mXConnectToB;
462 
463     sal_uInt32      GetConnectorRule( bool bFirst );
464 
EscherConnectorListEntryEscherConnectorListEntry465                     EscherConnectorListEntry( const css::uno::Reference< css::drawing::XShape > & rC,
466                                         const css::awt::Point& rPA,
467                                         css::uno::Reference< css::drawing::XShape > const & rSA ,
468                                         const css::awt::Point& rPB,
469                                         css::uno::Reference< css::drawing::XShape > const & rSB ) :
470                                             mXConnector ( rC ),
471                                             maPointA    ( rPA ),
472                                             mXConnectToA( rSA ),
473                                             maPointB    ( rPB ),
474                                             mXConnectToB( rSB ) {}
475 
476                     static sal_uInt32 GetClosestPoint( const tools::Polygon& rPoly, const css::awt::Point& rP );
477 };
478 
479 struct MSFILTER_DLLPUBLIC EscherExContainer
480 {
481     sal_uInt32  nContPos;
482     SvStream&   rStrm;
483 
484     EscherExContainer( SvStream& rSt, const sal_uInt16 nRecType, const sal_uInt16 nInstance = 0 );
485     ~EscherExContainer();
486 };
487 
488 struct MSFILTER_DLLPUBLIC EscherExAtom
489 {
490     sal_uInt32  nContPos;
491     SvStream&   rStrm;
492 
493     EscherExAtom( SvStream& rSt, const sal_uInt16 nRecType, const sal_uInt16 nInstance = 0, const sal_uInt8 nVersion = 0 );
494     ~EscherExAtom();
495 };
496 
497 struct EscherPropertyValueHelper
498 {
499     static bool GetPropertyValue(
500         css::uno::Any& rAny,
501         const css::uno::Reference< css::beans::XPropertySet > &,
502         const OUString& rPropertyName,
503         bool bTestPropertyAvailability = false
504     );
505 
506     static css::beans::PropertyState GetPropertyState(
507         const css::uno::Reference < css::beans::XPropertySet > &,
508         const OUString& rPropertyName
509     );
510 };
511 
512 
513 struct EscherPersistEntry
514 {
515     sal_uInt32  mnID;
516     sal_uInt32  mnOffset;
517 
EscherPersistEntryEscherPersistEntry518     EscherPersistEntry( sal_uInt32 nId, sal_uInt32 nOffset ) { mnID = nId; mnOffset = nOffset; };
519 
520 };
521 
522 
523 class EscherBlibEntry
524 {
525     friend class EscherGraphicProvider;
526     friend class EscherEx;
527 
528     sal_uInt32      mnIdentifier[ 4 ];
529     sal_uInt32      mnPictureOffset;        // offset to the graphic in PictureStreams
530     sal_uInt32      mnSize;                 // size of real graphic
531 
532     sal_uInt32      mnRefCount;             // !! reference count
533     sal_uInt32      mnSizeExtra;            // !! size of preceding header
534 
535     ESCHER_BlibType meBlibType;
536 
537     Size            maPrefSize;
538     MapMode         maPrefMapMode;
539 
540     bool            mbIsEmpty;
541     bool            mbIsNativeGraphicPossible;
542 
543 public:
544 
545                     EscherBlibEntry(
546                         sal_uInt32 nPictureOffset,
547                         const GraphicObject& rObj,
548                         const OString& rId,
549                         const GraphicAttr* pAttr
550                     );
551 
552                     ~EscherBlibEntry();
553 
554     void            WriteBlibEntry( SvStream& rSt, bool bWritePictureOffset, sal_uInt32 nResize = 0 );
IsEmpty() const555     bool            IsEmpty() const { return mbIsEmpty; };
556 
557     bool            operator==( const EscherBlibEntry& ) const;
558 };
559 
560 
561 enum class EscherGraphicProviderFlags {
562     NONE                    = 0,
563     UseInstances            = 1,
564 };
565 namespace o3tl {
566     template<> struct typed_flags<EscherGraphicProviderFlags> : is_typed_flags<EscherGraphicProviderFlags, 0x01> {};
567 }
568 
569 class MSFILTER_DLLPUBLIC EscherGraphicProvider
570 {
571     EscherGraphicProviderFlags
572                             mnFlags;
573     std::vector<std::unique_ptr<EscherBlibEntry>>
574                             mvBlibEntrys;
575     OUString                maBaseURI;
576 
577 protected:
578 
579     sal_uInt32              ImplInsertBlib( EscherBlibEntry* p_EscherBlibEntry );
580 
581 public:
582 
583     sal_uInt32  GetBlibStoreContainerSize( SvStream const * pMergePicStreamBSE = nullptr ) const;
584     void        WriteBlibStoreContainer( SvStream& rStrm, SvStream* pMergePicStreamBSE = nullptr  );
585     void        WriteBlibStoreEntry(SvStream& rStrm, sal_uInt32 nBlipId, sal_uInt32 nResize);
586     sal_uInt32  GetBlibID(
587                     SvStream& rPicOutStream,
588                     GraphicObject const & pGraphicObject,
589                     const css::awt::Rectangle* pVisArea = nullptr,
590                     const GraphicAttr* pGrafikAttr = nullptr,
591                     const bool ooxmlExport = false
592                 );
HasGraphics() const593     bool        HasGraphics() const { return !mvBlibEntrys.empty(); };
594 
595     void        SetNewBlipStreamOffset( sal_Int32 nOffset );
596 
597     bool        GetPrefSize( const sal_uInt32 nBlibId, Size& rSize, MapMode& rMapMode );
598 
SetBaseURI(const OUString & rBaseURI)599     void        SetBaseURI( const OUString& rBaseURI ) { maBaseURI = rBaseURI; };
GetBaseURI() const600     const OUString& GetBaseURI() const { return maBaseURI; };
601 
602     EscherGraphicProvider( EscherGraphicProviderFlags nFlags  = EscherGraphicProviderFlags::NONE );
603     virtual ~EscherGraphicProvider();
604 
605     EscherGraphicProvider& operator=( EscherGraphicProvider const & ) = delete; // MSVC2015 workaround
606     EscherGraphicProvider( EscherGraphicProvider const & ) = delete; // MSVC2015 workaround
607 };
608 
609 struct EscherShapeListEntry;
610 
611 class MSFILTER_DLLPUBLIC EscherSolverContainer
612 {
613     ::std::vector< std::unique_ptr<EscherShapeListEntry> >     maShapeList;
614     ::std::vector< std::unique_ptr<EscherConnectorListEntry> > maConnectorList;
615 
616 public:
617 
618     sal_uInt32      GetShapeId(
619                         const css::uno::Reference< css::drawing::XShape > & rShape
620                     ) const;
621 
622     void            AddShape(
623                         const css::uno::Reference< css::drawing::XShape > &,
624                         sal_uInt32 nId
625                     );
626 
627     void            AddConnector(
628                         const css::uno::Reference< css::drawing::XShape > &,
629                         const css::awt::Point& rA,
630                         css::uno::Reference< css::drawing::XShape > const &,
631                         const css::awt::Point& rB,
632                         css::uno::Reference< css::drawing::XShape > const & rConB
633                     );
634 
635     void            WriteSolver( SvStream& );
636 
637                     EscherSolverContainer();
638                     ~EscherSolverContainer();
639 
640     EscherSolverContainer& operator=( EscherSolverContainer const & ) = delete; // MSVC2015 workaround
641     EscherSolverContainer( EscherSolverContainer const & ) = delete; // MSVC2015 workaround
642 };
643 
644 
645 #define ESCHER_CREATEPOLYGON_LINE           1
646 #define ESCHER_CREATEPOLYGON_POLYLINE       2
647 #define ESCHER_CREATEPOLYGON_POLYPOLYGON    4
648 
649 class SdrObjCustomShape;
650 
651 struct EscherPropSortStruct
652 {
653     std::vector<sal_uInt8>    nProp;
654     sal_uInt32  nPropValue;
655     sal_uInt16  nPropId;
656 };
657 
658 typedef std::vector< EscherPropSortStruct > EscherProperties;
659 
660 class MSFILTER_DLLPUBLIC EscherPropertyContainer
661 {
662     EscherGraphicProvider*  pGraphicProvider;
663     SvStream*               pPicOutStrm;
664     tools::Rectangle*              pShapeBoundRect;
665 
666     sal_uInt32              nCountCount;
667     sal_uInt32              nCountSize;
668 
669     std::vector<EscherPropSortStruct>
670                             pSortStruct;
671 
672     bool                    bHasComplexData;
673 
674 
675     static sal_uInt32 ImplGetColor( const sal_uInt32 rColor, bool bSwap = true );
676     void        ImplCreateGraphicAttributes(
677                     const css::uno::Reference< css::beans::XPropertySet > & rXPropSet,
678                     sal_uInt32 nBlibId,
679                     bool bCreateCroppingAttributes
680                 );
681     bool        ImplCreateEmbeddedBmp(GraphicObject const & rGraphicObject);
682 
683     SAL_DLLPRIVATE explicit EscherPropertyContainer(
684         EscherGraphicProvider * pGraphProv, SvStream * pPiOutStrm,
685         tools::Rectangle * pBoundRect);
686 
687 public:
688 
689     EscherPropertyContainer();
690     EscherPropertyContainer(
691         EscherGraphicProvider& rGraphicProvider,    // the PropertyContainer needs to know
692         SvStream* pPicOutStrm,                      // the GraphicProvider to be able to write
693         tools::Rectangle& rShapeBoundRect                  // FillBitmaps or GraphicObjects.
694     );                                              // under some circumstances the ShapeBoundRect
695                                                     // is adjusted this will happen when rotated
696                                                     // GraphicObjects are saved to PowerPoint
697     ~EscherPropertyContainer();
698 
699     void AddOpt(
700         sal_uInt16 nPropID,
701         bool bBlib,
702         sal_uInt32 nSizeReduction,
703         SvMemoryStream& rStream);
704 
705     void AddOpt(
706         sal_uInt16 nPropertyID,
707         const OUString& rString);
708 
709     void AddOpt(
710         sal_uInt16 nPropertyID,
711         sal_uInt32 nPropValue,
712         bool bBlib = false);
713 
714     void AddOpt(
715         sal_uInt16 nPropertyID,
716         bool bBlib,
717         sal_uInt32 nPropValue,
718         const std::vector<sal_uInt8>& rProp);
719 
720     bool        GetOpt( sal_uInt16 nPropertyID, sal_uInt32& rPropValue ) const;
721 
722     bool        GetOpt( sal_uInt16 nPropertyID, EscherPropSortStruct& rPropValue ) const;
723 
724     EscherProperties GetOpts() const;
725 
726     void        Commit( SvStream& rSt, sal_uInt16 nVersion = 3, sal_uInt16 nRecType = ESCHER_OPT );
727 
728     void        CreateShapeProperties(
729                     const css::uno::Reference< css::drawing::XShape > & rXShape
730                 );
731     bool        CreateOLEGraphicProperties(
732                     const css::uno::Reference< css::drawing::XShape > & rXOleObject
733                 );
734     bool        CreateGraphicProperties(
735                     const css::uno::Reference< css::drawing::XShape > & rXShape,
736                     const GraphicObject& rGraphicObj
737                 );
738     bool        CreateMediaGraphicProperties(
739                     const css::uno::Reference< css::drawing::XShape > & rXMediaObject
740                 );
741 
742     /** Creates a complex ESCHER_Prop_fillBlip containing the BLIP directly (for Excel charts). */
743     void        CreateEmbeddedBitmapProperties(
744                     css::uno::Reference<css::awt::XBitmap> const & rxBitmap,
745                     css::drawing::BitmapMode eBitmapMode
746                 );
747     /** Creates a complex ESCHER_Prop_fillBlip containing a hatch style (for Excel charts). */
748     void        CreateEmbeddedHatchProperties(
749                     const css::drawing::Hatch& rHatch,
750                     const Color& rBackColor,
751                     bool bFillBackground
752                 );
753 
754                     // the GraphicProperties will only be created if a GraphicProvider and PicOutStrm is known
755                     // DR: #99897# if no GraphicProvider is present, a complex ESCHER_Prop_fillBlip
756                     //             will be created, containing the BLIP directly (e.g. for Excel charts).
757     bool        CreateGraphicProperties(
758                     const css::uno::Reference< css::beans::XPropertySet > & rXPropSet,
759                     const OUString& rSource,
760                     const bool bCreateFillBitmap,
761                     const bool bCreateCroppingAttributes = false,
762                     const bool bFillBitmapModeAllowed = true,
763                     const bool bOOxmlExport = false
764                 );
765 
766     bool        CreateBlipPropertiesforOLEControl( const css::uno::Reference< css::beans::XPropertySet > & rXPropSet, const css::uno::Reference< css::drawing::XShape > & rXShape);
767 
768     bool        CreatePolygonProperties(
769                     const css::uno::Reference< css::beans::XPropertySet > & rXPropSet,
770                     sal_uInt32 nFlags,
771                     bool bBezier,
772                     css::awt::Rectangle& rGeoRect,
773                     tools::Polygon const * pPolygon = nullptr
774                 );
775 
776     static sal_uInt32 GetGradientColor(
777                     const css::awt::Gradient* pGradient,
778                     sal_uInt32 nStartColor
779                 );
780 
781     void        CreateGradientProperties( const css::awt::Gradient & rGradient );
782     void        CreateGradientProperties(
783                     const css::uno::Reference< css::beans::XPropertySet > &,
784                     bool bTransparentGradient = false
785                 );
786 
787     void        CreateLineProperties(
788                     const css::uno::Reference< css::beans::XPropertySet > &,
789                     bool bEdge
790                 );
791     void        CreateFillProperties(
792                     const css::uno::Reference< css::beans::XPropertySet > &,
793                     bool bEdge,
794                     bool bTransparentGradient = false );
795     void        CreateFillProperties(
796                     const css::uno::Reference< css::beans::XPropertySet > &,
797                     bool bEdge,
798                     const css::uno::Reference< css::drawing::XShape > & rXShape );
799     void        CreateTextProperties(
800                     const css::uno::Reference< css::beans::XPropertySet > &,
801                     sal_uInt32 nText,
802                     const bool bIsCustomShape = false,
803                     const bool bIsTextFrame = true
804                 );
805 
806     bool        CreateConnectorProperties(
807                     const css::uno::Reference< css::drawing::XShape > & rXShape,
808                     EscherSolverContainer& rSolver,
809                     css::awt::Rectangle& rGeoRect,
810                     sal_uInt16& rShapeType,
811                     ShapeFlag& rShapeFlags
812                 );
813 
814                 // Because shadow properties depends to the line and fillstyle, the CreateShadowProperties method should be called at last.
815                 // It's active only when at least a FillStyle or LineStyle is set.
816     void        CreateShadowProperties(
817                     const css::uno::Reference< css::beans::XPropertySet > &
818                 );
819 
820     sal_Int32   GetValueForEnhancedCustomShapeParameter( const css::drawing::EnhancedCustomShapeParameter& rParameter,
821                             const std::vector< sal_Int32 >& rEquationOrder, bool bAdjustTrans = false );
822         // creates all necessary CustomShape properties, this includes also Text-, Shadow-, Fill-, and LineProperties
823     void        CreateCustomShapeProperties(
824                     const MSO_SPT eShapeType,
825                     const css::uno::Reference< css::drawing::XShape > &
826                 );
827     bool        IsFontWork() const;
828 
829     // helper functions which are also used by the escher import
830     static tools::PolyPolygon  GetPolyPolygon(
831                             const css::uno::Reference< css::drawing::XShape > & rXShape
832                         );
833     static tools::PolyPolygon  GetPolyPolygon( const css::uno::Any& rSource );
834     static MSO_SPT      GetCustomShapeType(
835                             const css::uno::Reference< css::drawing::XShape > & rXShape,
836                             ShapeFlag& nMirrorFlags,
837                             OUString& rShapeType,
838                             bool bOOXML = false
839                         );
840 
841     // helper functions which are also used in ooxml export
842     static bool         GetLineArrow(
843                             const bool bLineStart,
844                             const css::uno::Reference< css::beans::XPropertySet > & rXPropSet,
845                             ESCHER_LineEnd& reLineEnd,
846                             sal_Int32& rnArrowLength,
847                             sal_Int32& rnArrowWidth
848                         );
849 
850     static bool IsDefaultObject(
851         const SdrObjCustomShape& rSdrObjCustomShape,
852         const MSO_SPT eShapeType);
853 
854     static void         LookForPolarHandles(
855                             const MSO_SPT eShapeType,
856                             sal_Int32& nAdjustmentsWhichNeedsToBeConverted
857                         );
858     static bool         GetAdjustmentValue( const css::drawing::EnhancedCustomShapeAdjustmentValue & rkProp, sal_Int32 nIndex, sal_Int32 nAdjustmentsWhichNeedsToBeConverted, sal_Int32& nValue );
859 };
860 
861 
862 class MSFILTER_DLLPUBLIC EscherPersistTable
863 {
864 
865 public:
866     ::std::vector< std::unique_ptr<EscherPersistEntry> > maPersistTable;
867 
868     bool        PtIsID( sal_uInt32 nID );
869     void        PtInsert( sal_uInt32 nID, sal_uInt32 nOfs );
870     void        PtDelete( sal_uInt32 nID );
871     sal_uInt32  PtGetOffsetByID( sal_uInt32 nID );
872     void        PtReplace( sal_uInt32 nID, sal_uInt32 nOfs );
873     void        PtReplaceOrInsert( sal_uInt32 nID, sal_uInt32 nOfs );
874 
875                 EscherPersistTable();
876     virtual     ~EscherPersistTable();
877 
878     EscherPersistTable& operator=( EscherPersistTable const & ) = delete; // MSVC2015 workaround
879     EscherPersistTable( EscherPersistTable const & ) = delete; // MSVC2015 workaround
880 };
881 
882 
883 class EscherEx;
884 
885 /// abstract base class for ESCHER_ClientTextbox, ESCHER_ClientData
886 class MSFILTER_DLLPUBLIC EscherExClientRecord_Base
887 {
888 public:
EscherExClientRecord_Base()889                                 EscherExClientRecord_Base() {}
890     virtual                     ~EscherExClientRecord_Base();
891 
892                                 /// Application writes the record header
893                                 /// using rEx.AddAtom(...) followed by
894                                 /// record data written to rEx.GetStream()
895     virtual void                WriteData( EscherEx& rEx ) const = 0;
896 };
897 
898 
899 /// abstract base class for ESCHER_ClientAnchor
900 class MSFILTER_DLLPUBLIC EscherExClientAnchor_Base
901 {
902 public:
EscherExClientAnchor_Base()903                                 EscherExClientAnchor_Base() {}
904     virtual                     ~EscherExClientAnchor_Base();
905 
906                                 /// Application writes the record header
907                                 /// using rEx.AddAtom(...) followed by
908                                 /// record data written to rEx.GetStream()
909     virtual void                WriteData( EscherEx& rEx,
910                                     const tools::Rectangle& rRect ) = 0;
911 };
912 
913 class InteractionInfo
914 {
915     std::unique_ptr<SvMemoryStream>       mpHyperlinkRecord;
916 
917 public:
InteractionInfo(SvMemoryStream * pStream)918     InteractionInfo( SvMemoryStream* pStream )
919     {
920         mpHyperlinkRecord.reset( pStream );
921     }
getHyperlinkRecord() const922     const std::unique_ptr< SvMemoryStream >&  getHyperlinkRecord() const { return mpHyperlinkRecord; }
923 };
924 
925 class EscherExHostAppData
926 {
927 private:
928         EscherExClientAnchor_Base*  pClientAnchor;
929         EscherExClientRecord_Base*  pClientData;
930         EscherExClientRecord_Base*  pClientTextbox;
931         InteractionInfo*            pInteractionInfo;
932         // ignore single shape if entire pages are written
933         bool                        bDontWriteShape;
934 
935 public:
EscherExHostAppData()936         EscherExHostAppData() : pClientAnchor(nullptr), pClientData(nullptr),
937                 pClientTextbox(nullptr), pInteractionInfo(nullptr), bDontWriteShape(false)
938         {}
939 
SetInteractionInfo(InteractionInfo * p)940         void SetInteractionInfo( InteractionInfo* p )
941             { pInteractionInfo = p; }
SetClientAnchor(EscherExClientAnchor_Base * p)942         void SetClientAnchor( EscherExClientAnchor_Base* p )
943             { pClientAnchor = p; }
SetClientData(EscherExClientRecord_Base * p)944         void SetClientData( EscherExClientRecord_Base* p )
945             { pClientData = p; }
SetClientTextbox(EscherExClientRecord_Base * p)946         void SetClientTextbox( EscherExClientRecord_Base* p )
947             { pClientTextbox = p; }
SetDontWriteShape(bool b)948         void SetDontWriteShape( bool b )
949             { bDontWriteShape = b; }
GetInteractionInfo() const950         InteractionInfo* GetInteractionInfo() const
951             { return pInteractionInfo; }
GetClientAnchor() const952         EscherExClientAnchor_Base* GetClientAnchor() const
953             { return pClientAnchor; }
GetClientTextbox() const954         EscherExClientRecord_Base* GetClientTextbox() const
955             { return pClientTextbox; }
956 
WriteClientAnchor(EscherEx & rEx,const tools::Rectangle & rRect)957         void WriteClientAnchor( EscherEx& rEx, const tools::Rectangle& rRect )
958             { if( pClientAnchor )  pClientAnchor->WriteData( rEx, rRect ); }
WriteClientData(EscherEx & rEx)959         void WriteClientData( EscherEx& rEx )
960             { if( pClientData ) pClientData->WriteData( rEx ); }
WriteClientTextbox(EscherEx & rEx)961         void WriteClientTextbox( EscherEx& rEx )
962             { if( pClientTextbox ) pClientTextbox->WriteData( rEx ); }
963 
DontWriteShape() const964         bool DontWriteShape() const { return bDontWriteShape; }
965 };
966 
967 
968 /** Instance for global DFF data, shared through various instances of EscherEx. */
969 class MSFILTER_DLLPUBLIC EscherExGlobal : public EscherGraphicProvider
970 {
971 public:
972     explicit            EscherExGlobal();
973     virtual             ~EscherExGlobal() override;
974 
975     /** Returns a new drawing ID for a new drawing container (DGCONTAINER). */
976     sal_uInt32          GenerateDrawingId();
977     /** Creates and returns a new shape identifier, updates the internal shape
978         counters and registers the identifier in the DGG cluster table.
979         @param nDrawingId  Drawing identifier has to be passed to be able to
980             generate shape identifiers for multiple drawings simultaneously. */
981     sal_uInt32          GenerateShapeId( sal_uInt32 nDrawingId, bool bIsInSpgr );
982     /** Returns the number of shapes in the current drawing, based on number of
983         calls to the GenerateShapeId() function. */
984     sal_uInt32          GetDrawingShapeCount( sal_uInt32 nDrawingId ) const;
985     /** Returns the last shape identifier generated by the GenerateShapeId()
986         function. */
987     sal_uInt32          GetLastShapeId( sal_uInt32 nDrawingId ) const;
988 
989     /** Sets the flag indicating that the DGGCONTAINER exists. */
SetDggContainer()990     void         SetDggContainer() { mbHasDggCont = true; }
991     /** Sets the flag indicating that the DGGCONTAINER exists. */
HasDggContainer() const992     bool         HasDggContainer() const { return mbHasDggCont; }
993     /** Returns the total size of the DGG atom (including header). */
994     sal_uInt32          GetDggAtomSize() const;
995     /** Writes the complete DGG atom to the passed stream (overwrites existing data!). */
996     void                WriteDggAtom( SvStream& rStrm ) const;
997 
998     /** Called if a picture shall be written and no picture stream is set at
999         class ImplEESdrWriter.
1000 
1001         On first invocation, this function calls the virtual member function
1002         ImplQueryPictureStream(). The return value will be cached internally
1003         for subsequent calls and for the GetPictureStream() function.
1004      */
1005     SvStream*           QueryPictureStream();
1006 
1007     /** Returns the picture stream if existing (queried), otherwise null. */
GetPictureStream()1008     SvStream*    GetPictureStream() { return mpPicStrm; }
1009 
1010 private:
1011     /** Derived classes may implement to create a new stream used to store the
1012         picture data.
1013 
1014         The implementation has to take care about lifetime of the returned
1015         stream (it will not be destructed automatically). This function is
1016         called exactly once. The return value will be cached internally for
1017         repeated calls of the public QueryPictureStream() function.
1018      */
1019     virtual SvStream*   ImplQueryPictureStream();
1020 
1021 private:
1022     struct ClusterEntry
1023     {
1024         sal_uInt32          mnDrawingId;        /// Identifier of drawing this cluster belongs to (one-based index into maDrawingInfos).
1025         sal_uInt32          mnNextShapeId;      /// Next free shape identifier in this cluster.
ClusterEntryEscherExGlobal::ClusterEntry1026         explicit     ClusterEntry( sal_uInt32 nDrawingId ) : mnDrawingId( nDrawingId ), mnNextShapeId( 0 ) {}
1027     };
1028     typedef ::std::vector< ClusterEntry > ClusterTable;
1029 
1030     struct DrawingInfo
1031     {
1032         sal_uInt32          mnClusterId;        /// Currently used cluster (one-based index into maClusterTable).
1033         sal_uInt32          mnShapeCount;       /// Current number of shapes in this drawing.
1034         sal_uInt32          mnLastShapeId;      /// Last shape identifier generated for this drawing.
DrawingInfoEscherExGlobal::DrawingInfo1035         explicit     DrawingInfo( sal_uInt32 nClusterId ) : mnClusterId( nClusterId ), mnShapeCount( 0 ), mnLastShapeId( 0 ) {}
1036     };
1037     typedef ::std::vector< DrawingInfo > DrawingInfoVector;
1038 
1039     ClusterTable        maClusterTable;     /// List with cluster IDs (used object IDs in drawings).
1040     DrawingInfoVector   maDrawingInfos;     /// Data about all used drawings.
1041     SvStream*           mpPicStrm;          /// Cached result of ImplQueryPictureStream().
1042     bool                mbHasDggCont;       /// True = the DGGCONTAINER has been initialized.
1043     bool                mbPicStrmQueried;   /// True = ImplQueryPictureStream() has been called.
1044 };
1045 
1046 class SdrObject;
1047 class SdrPage;
1048 class ImplEESdrWriter;
1049 
1050 class MSFILTER_DLLPUBLIC EscherEx : public EscherPersistTable
1051 {
1052     protected:
1053         std::shared_ptr<EscherExGlobal>           mxGlobal;
1054         ::std::unique_ptr< ImplEESdrWriter > mpImplEESdrWriter;
1055         SvStream*                   mpOutStrm;
1056         bool                        mbOwnsStrm;
1057         sal_uInt32                  mnStrmStartOfs;
1058         std::vector< sal_uInt32 >   mOffsets;
1059         std::vector< sal_uInt16 >   mRecTypes;
1060 
1061         sal_uInt32                  mnCurrentDg;
1062         sal_uInt32                  mnCountOfs;
1063 
1064         sal_uInt32                  mnGroupLevel;
1065         SdrLayerID                  mnHellLayerId;
1066 
1067         bool                        mbEscherSpgr;
1068         bool                        mbEscherDg;
1069         bool                        mbOOXML;
1070         OUString                    mEditAs;
1071 
1072 
1073         bool DoSeek( sal_uInt32 nKey );
1074 
1075 public:
1076     explicit            EscherEx( const std::shared_ptr<EscherExGlobal>& rxGlobal, SvStream* pOutStrm, bool bOOXML = false );
1077     virtual             ~EscherEx() override;
1078 
1079     /** Creates and returns a new shape identifier, updates the internal shape
1080         counters and registers the identifier in the DGG cluster table. */
GenerateShapeId()1081     virtual sal_uInt32   GenerateShapeId() { return mxGlobal->GenerateShapeId( mnCurrentDg, mbEscherSpgr ); }
1082 
1083     /** Returns the graphic provider from the global object that has been
1084         passed to the constructor.
1085      */
GetGraphicProvider()1086     EscherGraphicProvider& GetGraphicProvider() { return *mxGlobal; }
1087 
1088     /** Called if a picture shall be written and no picture stream is set at
1089         class ImplEESdrWriter.
1090      */
QueryPictureStream()1091     SvStream*    QueryPictureStream() { return mxGlobal->QueryPictureStream(); }
1092 
1093                 /// Inserts internal data into the EscherStream, this process
1094                 /// may and has to be executed only once
1095                 /// If pPicStreamMergeBSE is known, the BLIPs from this stream are being
1096                 /// merged into the MsofbtBSE Records of the EscherStream like it's
1097                 /// required for Excel (and maybe Word?)
1098         void Flush( SvStream* pPicStreamMergeBSE = nullptr );
1099 
1100     /** Inserts the passed number of bytes at the current position of the
1101         output stream.
1102 
1103         Inserts dummy bytes and moves all following stream data, and updates
1104         all internal stream offsets stored in the PersistTable and the affected
1105         container sizes, which makes this operation very expensive. (!)
1106 
1107         @param nBytes  The number of bytes to be inserted into the stream.
1108 
1109         An atom that currently ends
1110         exactly at the current stream position will not be expanded to
1111         include the inserted data (used to insert e.g. a new atom after an
1112         existing atom). Note that containers that end exactly at the
1113         current stream position are always expanded to include the inserted
1114         data.
1115      */
1116     void            InsertAtCurrentPos( sal_uInt32 nBytes );
1117 
1118     void            InsertPersistOffset( sal_uInt32 nKey, sal_uInt32 nOffset ); // It is not being checked if this key is already in the PersistantTable
1119     void            ReplacePersistOffset( sal_uInt32 nKey, sal_uInt32 nOffset );
1120     sal_uInt32      GetPersistOffset( sal_uInt32 nKey );
1121     bool            SeekToPersistOffset( sal_uInt32 nKey );
1122     void            InsertAtPersistOffset( sal_uInt32 nKey, sal_uInt32 nValue );   // nValue is being inserted into the Stream where it's appropriate (overwrite mode), without that the
1123                                                                                     // current StreamPosition changes
1124     void            SetEditAs( const OUString& rEditAs );
GetEditAs() const1125     const OUString& GetEditAs() const { return mEditAs; }
GetStream() const1126     SvStream&       GetStream() const   { return *mpOutStrm; }
GetStreamPos() const1127     sal_uLong       GetStreamPos() const    { return mpOutStrm->Tell(); }
1128 
1129                 // features during the creation of the following Containers:
1130 
1131                 //      ESCHER_DggContainer:    an EscherDgg Atom is automatically being created and managed
1132                 //      ESCHER_DgContainer:     an EscherDg Atom is automatically being created and managed
1133                 //      ESCHER_SpgrContainer:
1134                 //      ESCHER_SpContainer:
1135 
1136     virtual void OpenContainer( sal_uInt16 nEscherContainer, int nRecInstance = 0 );
1137     virtual void CloseContainer();
1138 
1139     void BeginAtom();
1140     void EndAtom( sal_uInt16 nRecType, int nRecVersion = 0, int nRecInstance = 0 );
1141     void AddAtom( sal_uInt32 nAtomSitze, sal_uInt16 nRecType, int nRecVersion = 0, int nRecInstance = 0 );
1142     void AddChildAnchor( const tools::Rectangle& rRectangle );
1143     void AddClientAnchor( const tools::Rectangle& rRectangle );
1144 
1145     virtual sal_uInt32 EnterGroup( const OUString& rShapeName, const tools::Rectangle* pBoundRect );
1146     sal_uInt32  EnterGroup( const tools::Rectangle* pBoundRect = nullptr );
GetGroupLevel() const1147     sal_uInt32  GetGroupLevel() const { return mnGroupLevel; };
1148     void SetGroupSnapRect( sal_uInt32 nGroupLevel, const tools::Rectangle& rRect );
1149     void SetGroupLogicRect( sal_uInt32 nGroupLevel, const tools::Rectangle& rRect );
1150     virtual void LeaveGroup();
1151 
1152                 // a ESCHER_Sp is being written ( a ESCHER_DgContainer has to be opened for this purpose!)
1153     virtual void AddShape( sal_uInt32 nShpInstance, ShapeFlag nFlagIds, sal_uInt32 nShapeID = 0 );
1154 
1155     virtual void Commit( EscherPropertyContainer& rProps, const tools::Rectangle& rRect);
1156 
1157     static sal_uInt32  GetColor( const sal_uInt32 nColor );
1158     static sal_uInt32  GetColor( const Color& rColor );
1159 
1160                 // ...Sdr... implemented in eschesdo.cxx
1161 
1162     void    AddSdrPage( const SdrPage& rPage );
1163     void    AddUnoShapes( const css::uno::Reference< css::drawing::XShapes >& rxShapes );
1164 
1165                 /// returns the ShapeID
1166     sal_uInt32  AddSdrObject( const SdrObject& rObj, bool ooxmlExport = false );
AddSdrObjectVMLObject(const SdrObject &)1167     virtual void  AddSdrObjectVMLObject( const SdrObject& /*rObj*/)
1168     {
1169         // Required for Exporting VML shape
1170     }
1171 
1172                 /// If objects are written through AddSdrObject the
1173                 /// SolverContainer has to be written, and maybe some
1174                 /// maintenance to be done.
1175     void    EndSdrObjectPage();
1176 
1177                 /// Called before a shape is written, application supplies
1178                 /// ClientRecords. May set AppData::bDontWriteShape so the
1179                 /// shape is ignored.
1180     virtual EscherExHostAppData* StartShape(
1181                             const css::uno::Reference< css::drawing::XShape >& rShape,
1182                             const tools::Rectangle* pChildAnchor );
1183 
1184                 /// Called after a shape is written to inform the application
1185                 /// of the resulted shape type and ID.
1186     virtual void    EndShape( sal_uInt16 nShapeType, sal_uInt32 nShapeID );
1187 
1188                 /// Called before an AdditionalText EnterGroup occurs.
1189                 /// The current shape will be written in three parts:
1190                 /// a group shape, the shape itself, and an extra textbox shape.
1191                 /// The complete flow is:
1192                 /// StartShape sets HostData1.
1193                 /// EnterAdditionalTextGroup sets HostData2, App may modify
1194                 ///   HostData1 and keep track of the change.
1195                 /// The group shape is written with HostData2.
1196                 /// Another StartShape with the same (!) object sets HostData3.
1197                 /// The current shape is written with HostData3.
1198                 /// EndShape is called for the current shape.
1199                 /// Another StartShape with the same (!) object sets HostData4.
1200                 /// The textbox shape is written with HostData4.
1201                 /// EndShape is called for the textbox shape.
1202                 /// EndShape is called for the group shape, this provides
1203                 ///   the same functionality as an ordinary recursive group.
1204     virtual EscherExHostAppData*    EnterAdditionalTextGroup();
1205 
1206                 /// Called if an ESCHER_Prop_lTxid shall be written
1207     virtual sal_uInt32  QueryTextID( const css::uno::Reference< css::drawing::XShape >&, sal_uInt32 nShapeId );
1208             // add a dummy rectangle shape into the escher stream
1209         sal_uInt32  AddDummyShape();
1210 
1211     static const SdrObject* GetSdrObject( const css::uno::Reference< css::drawing::XShape >& rXShape );
1212 
SetHellLayerId(SdrLayerID nId)1213     void SetHellLayerId( SdrLayerID nId )       { mnHellLayerId = nId; }
GetHellLayerId() const1214     SdrLayerID GetHellLayerId() const           { return mnHellLayerId; }
1215 
1216 private:
1217                         EscherEx( const EscherEx& ) = delete;
1218     EscherEx&           operator=( const EscherEx& ) = delete;
1219 };
1220 
1221 
1222 #endif
1223 
1224 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1225