Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/emfio/inc/mtftools.hxx
Line
Count
Source
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
#pragma once
20
21
#include <basegfx/utils/b2dclipstate.hxx>
22
#include <basegfx/vector/b2enums.hxx>
23
#include <tools/poly.hxx>
24
#include <vcl/font.hxx>
25
#include <vcl/bitmap.hxx>
26
#include <vcl/lineinfo.hxx>
27
#include <vcl/rendercontext/State.hxx>
28
#include <vcl/metaact.hxx>
29
#include <rtl/ref.hxx>
30
31
#include <com/sun/star/drawing/LineCap.hpp>
32
33
#include "emfiodllapi.h"
34
35
namespace emfio
36
{
37
    /* [MS-EMF] - v20210625 - pages 43, 107 */
38
    enum class RegionMode : sal_uInt32
39
    {
40
        RGN_AND  = 0x01,
41
        RGN_OR   = 0x02,
42
        RGN_XOR  = 0x03,
43
        RGN_DIFF = 0x04,
44
        RGN_COPY = 0x05
45
    };
46
47
    /* [MS-EMF] - v20210625 - pages 40, 198 */
48
    enum class BackgroundMode : sal_uInt32
49
    {
50
        NONE = 0,
51
        Transparent = 1,
52
        OPAQUE = 2,
53
    };
54
55
    /* [MS-EMF] - v20210625 - pages 40, 210 */
56
    /* xform stuff */
57
    enum class ModifyWorldTransformMode : sal_uInt32
58
    {
59
        MWT_IDENTITY      = 0x01,
60
        MWT_LEFTMULTIPLY  = 0x02,
61
        MWT_RIGHTMULTIPLY = 0x03,
62
        MWT_SET           = 0x04
63
    };
64
65
    constexpr sal_uInt32 ENHMETA_STOCK_OBJECT = 0x80000000;
66
67
    /* [MS-EMF] - v20210625 - pages 44, 45, 182 */
68
    /* Stock Logical Objects */
69
    enum class StockObject : sal_uInt32
70
    {
71
        WHITE_BRUSH       = 0,
72
        LTGRAY_BRUSH      = 1,
73
        GRAY_BRUSH        = 2,
74
        DKGRAY_BRUSH      = 3,
75
        BLACK_BRUSH       = 4,
76
        NULL_BRUSH        = 5,
77
        WHITE_PEN         = 6,
78
        BLACK_PEN         = 7,
79
        NULL_PEN          = 8,
80
        ANSI_FIXED_FONT   = 11,
81
        ANSI_VAR_FONT     = 12,
82
        SYSTEM_FIXED_FONT = 16
83
    };
84
85
    /* Note: This enum is incomplete compared to the specification */
86
    /* [MS-WMF] - v20210625 - pages 25-26 */
87
    enum class WMFRasterOp : sal_uInt16
88
    {
89
        NONE = 0,
90
        Black = 1,
91
        Not = 6,
92
        XorPen = 7,
93
        Nop = 11,
94
        CopyPen = 13
95
    };
96
97
    /* Note: We have MapMode elsewhere, so we use MappingMode instead */
98
    /* [MS-EMF] - v20210625 - pages 38-50, 202 */
99
    /* Mapping modes */
100
    enum MappingMode : sal_uInt32
101
    {
102
        MM_TEXT        = 0x01,
103
        MM_LOMETRIC    = 0x02,
104
        MM_HIMETRIC    = 0x03,
105
        MM_LOENGLISH   = 0x04,
106
        MM_HIENGLISH   = 0x05,
107
        MM_TWIPS       = 0x06,
108
        MM_ISOTROPIC   = 0x07,
109
        MM_ANISOTROPIC = 0x08
110
    };
111
112
    /* Note: No type is specified, but 32-bit unsigned is used to provide
113
     * to match the number of bits in the binary literal, and also the
114
     * previous definition of SetGfxMode() and GetGfxMode() functions */
115
    /* [MS-EMF] - v20210625 - pages 35 */
116
    /* Graphics modes */
117
    enum class GraphicsMode : sal_uInt32
118
    {
119
        GM_COMPATIBLE = 0x00000001,
120
        GM_ADVANCED   = 0x00000002
121
    } ;
122
123
    /* [MS-WMF] - v20210625 - pages 46 */
124
    /* StretchBlt() modes */
125
    enum class StretchMode : sal_uInt16
126
    {
127
        BLACKONWHITE        = 0x0001,
128
        WHITEONBLACK        = 0x0002,
129
        COLORONCOLOR        = 0x0003,
130
        HALFTONE            = 0x0004,
131
        STRETCH_ANDSCANS    = BLACKONWHITE,
132
        STRETCH_ORSCANS     = WHITEONBLACK,
133
        STRETCH_DELETESCANS = COLORONCOLOR
134
    };
135
136
    constexpr sal_Int32 LF_FACESIZE = 32;
137
138
    struct LOGFONTW
139
    {
140
        sal_Int32       lfHeight;
141
        sal_Int32       lfWidth;
142
        sal_Int32       lfEscapement;
143
        sal_Int32       lfOrientation;
144
        sal_Int32       lfWeight;
145
        sal_uInt8       lfItalic;
146
        sal_uInt8       lfUnderline;
147
        sal_uInt8       lfStrikeOut;
148
        sal_uInt8       lfCharSet;
149
        sal_uInt8       lfOutPrecision;
150
        sal_uInt8       lfClipPrecision;
151
        sal_uInt8       lfQuality;
152
        sal_uInt8       lfPitchAndFamily;
153
        OUString        alfFaceName;
154
        LOGFONTW()
155
21.0k
            : lfHeight(0)
156
21.0k
            , lfWidth(0)
157
21.0k
            , lfEscapement(0)
158
21.0k
            , lfOrientation(0)
159
21.0k
            , lfWeight(0)
160
21.0k
            , lfItalic(0)
161
21.0k
            , lfUnderline(0)
162
21.0k
            , lfStrikeOut(0)
163
21.0k
            , lfCharSet(0)
164
21.0k
            , lfOutPrecision(0)
165
21.0k
            , lfClipPrecision(0)
166
21.0k
            , lfQuality(0)
167
21.0k
            , lfPitchAndFamily(0)
168
21.0k
        {
169
21.0k
        }
170
    };
171
172
    /* [MS-WMF] - v20210625 - pages 153 */
173
    enum TextAlignmentMode : sal_uInt16
174
    {
175
        TA_NOUPDATECP   = 0x0000,
176
        TA_UPDATECP     = 0x0001,
177
        TA_LEFT         = 0x0000,
178
        TA_RIGHT        = 0x0002,
179
        TA_CENTER       = 0x0006,
180
        TA_RIGHT_CENTER = (TA_RIGHT | TA_CENTER),
181
        TA_TOP          = 0x0000,
182
        TA_BOTTOM       = 0x0008,
183
        // In [MS-WMF] 2.1.2.3, TA_BASELINE value is wrong.
184
        // It is 0x0018 and it should be 0x0010.
185
        TA_BASELINE     = 0x0010,
186
        TA_RTLREADING   = 0x0100
187
    };
188
189
    /* Note: This enum is incomplete compared to the specification */
190
    /* [MS-EMF] - v20210625 - pages 47-50, 126 */
191
    /* Ternary raster operations */
192
    enum TernaryRasterOperation : sal_uInt32
193
    {
194
        SRCCOPY   = 0x00CC0020L,
195
        SRCPAINT  = 0x00EE0086L,
196
        SRCAND    = 0x008800C6L,
197
        SRCINVERT = 0x00660046L,
198
        SRCERASE  = 0x00440328L,
199
        PATCOPY   = 0x00F00021L,
200
        PATINVERT = 0x005A0049L,
201
        BLACKNESS = 0x00000042L,
202
        WHITENESS = 0x00FF0062L
203
    };
204
205
    /* [MS-EMF] - v20210625 - pages 40, 41, 65 */
206
    enum PenStyle : sal_uInt32
207
    {
208
        PS_COSMETIC          = 0x00000000,
209
        PS_GEOMETRIC         = 0x00010000,
210
211
        PS_SOLID             = 0x00000000,
212
        PS_DASH              = 0x00000001,
213
        PS_DOT               = 0x00000002,
214
        PS_DASHDOT           = 0x00000003,
215
        PS_DASHDOTDOT        = 0x00000004,
216
        PS_NULL              = 0x00000005,
217
        PS_INSIDEFRAME       = 0x00000006,
218
        PS_USERSTYLE         = 0x00000007,
219
        PS_ALTERNATE         = 0x00000008,
220
        PS_STYLE_MASK        = 0x0000000F,
221
222
        PS_ENDCAP_ROUND      = 0x00000000,
223
        PS_ENDCAP_SQUARE     = 0x00000100,
224
        PS_ENDCAP_FLAT       = 0x00000200,
225
        PS_ENDCAP_STYLE_MASK = 0x00000F00,
226
227
        PS_JOIN_ROUND        = 0x00000000,
228
        PS_JOIN_BEVEL        = 0x00001000,
229
        PS_JOIN_MITER        = 0x00002000,
230
        PS_JOIN_STYLE_MASK   = 0x0000F000
231
    };
232
233
    /* [MS-WMF] - v20210625 - pages 30, 82 */
234
    /* Character Sets */
235
    enum CharacterSet : sal_uInt8
236
    {
237
        ANSI_CHARSET        = 0x00000000,
238
        DEFAULT_CHARSET     = 0x00000001,
239
        SYMBOL_CHARSET      = 0x00000002,
240
        SHIFTJIS_CHARSET    = 0x00000080,
241
        HANGUL_CHARSET      = 0x00000081,
242
        GB2312_CHARSET      = 0x00000086,
243
        CHINESEBIG5_CHARSET = 0x00000088,
244
        OEM_CHARSET         = 0x000000FF,
245
        /* WINVER >= 0x0400 */
246
        MAC_CHARSET         = 0x0000004D,
247
        JOHAB_CHARSET       = 0x00000082,
248
        GREEK_CHARSET       = 0x000000A1,
249
        TURKISH_CHARSET     = 0x000000A2,
250
        VIETNAMESE_CHARSET  = 0x000000A3,
251
        HEBREW_CHARSET      = 0x000000B1,
252
        ARABIC_CHARSET      = 0x000000B2,
253
        BALTIC_CHARSET      = 0x000000BA,
254
        RUSSIAN_CHARSET     = 0x000000CC,
255
        THAI_CHARSET        = 0x000000DE,
256
        EASTEUROPE_CHARSET  = 0x000000EE
257
    };
258
259
    /* Note: This enum is incomplete compared to the specification */
260
    /* [MS-EMF] - v20210625 - pages 32, 283 */
261
    enum ExtTextOutOptions : sal_uInt32
262
    {
263
        ETO_OPAQUE      = 0x0002,
264
        ETO_CLIPPED     = 0x0004,
265
        /* WINVER >= 0x0400 */
266
        ETO_GLYPH_INDEX = 0x0010,
267
        ETO_RTLREADING  = 0x0080,
268
        /* _WIN32_WINNT >= 0x0500 */
269
        ETO_NO_RECT     = 0x0100,
270
        ETO_SMALL_CHARS = 0x0200,
271
        ETO_PDY         = 0x2000
272
    };
273
274
    /* [MS-WMF] - v20210625 - pages 44, 96 */
275
    /* This is packed into a byte as 2 bits */
276
    enum PitchFont : sal_uInt8
277
    {
278
        DEFAULT_PITCH  = 0,
279
        FIXED_PITCH    = 1,
280
        VARIABLE_PITCH = 2
281
    };
282
283
    /* [MS-WMF] - v20210625 - pages 33,  */
284
    enum FamilyFont : sal_uInt8
285
    {
286
        FF_DONTCARE   = 0x00,
287
        FF_ROMAN      = 0x01,
288
        FF_SWISS      = 0x02,
289
        FF_MODERN     = 0x03,
290
        FF_SCRIPT     = 0x04,
291
        FF_DECORATIVE = 0x05
292
    };
293
294
    enum WeightFont
295
    {
296
        FW_THIN       = 100,
297
        FW_EXTRALIGHT = 200,
298
        FW_LIGHT      = 300,
299
        FW_NORMAL     = 400,
300
        FW_MEDIUM     = 500,
301
        FW_SEMIBOLD   = 600,
302
        FW_BOLD       = 700,
303
        FW_EXTRABOLD  = 800,
304
        FW_ULTRALIGHT = 200,
305
        FW_ULTRABOLD  = 800,
306
        FW_BLACK      = 900
307
    };
308
309
    /* [MS-WMF] - v20210625 - pages 29, 30, 182 */
310
    enum class BrushStyle : sal_uInt16
311
    {
312
        BS_SOLID         = 0,
313
        BS_NULL          = 1,
314
        BS_HOLLOW        = 1,
315
        BS_HATCHED       = 2,
316
        BS_PATTERN       = 3,
317
        BS_INDEXED       = 4,
318
        BS_DIBPATTERN    = 5,
319
        BS_DIBPATTERNPT  = 6,
320
        BS_PATTERN8X8    = 7,
321
        BS_DIBPATTERN8X8 = 8,
322
        BS_MONOPATTERN   = 9
323
    };
324
325
    constexpr sal_Int32 RDH_RECTANGLES = 1;
326
    constexpr sal_Int32 W_MFCOMMENT = 15;
327
    constexpr sal_Int32 PRIVATE_ESCAPE_UNICODE = 2;
328
329
    //Scalar constants
330
    constexpr sal_Int32 UNDOCUMENTED_WIN_RCL_RELATION = 32;
331
    constexpr sal_Int32 MS_FIXPOINT_BITCOUNT_28_4 = 4;
332
}
333
334
//============================ WmfReader ==================================
335
336
namespace emfio
337
{
338
    class WinMtfClipPath
339
    {
340
        basegfx::utils::B2DClipState maClip;
341
342
    public:
343
110k
        WinMtfClipPath() : maClip() {};
344
345
        void        setClipPath(const basegfx::B2DPolyPolygon&, RegionMode nClippingMode);
346
        void        intersectClip(const basegfx::B2DPolyPolygon& rPolyPolygon);
347
        void        excludeClip(const basegfx::B2DPolyPolygon& rPolyPolygon);
348
        void        moveClipRegion(const Size& rSize);
349
        void        setDefaultClipPath();
350
351
13.1k
        bool        isEmpty() const { return maClip.isCleared(); }
352
353
0
        basegfx::utils::B2DClipState const & getClip() const { return maClip; }
354
        basegfx::B2DPolyPolygon const & getClipPath() const;
355
356
        bool        operator==(const WinMtfClipPath& rPath) const
357
70.5k
        {
358
70.5k
            return maClip == rPath.maClip;
359
70.5k
        };
360
    };
361
362
    class WinMtfPathObj : public tools::PolyPolygon
363
    {
364
        bool    bClosed;
365
366
    public:
367
368
        WinMtfPathObj() :
369
110k
            bClosed(true)
370
110k
        {}
371
372
        void        Init()
373
8.46k
        {
374
8.46k
            Clear();
375
8.46k
            bClosed = true;
376
8.46k
        }
377
378
        void        ClosePath();
379
        void        AddPoint(const Point& rPoint);
380
        void        AddPolygon(const tools::Polygon& rPoly);
381
        void        AddPolyLine(const tools::Polygon& rPoly);
382
        void        AddPolyPolygon(const tools::PolyPolygon& rPolyPolygon);
383
    };
384
385
    struct EMFIO_DLLPUBLIC GDIObj
386
    {
387
596k
        GDIObj() = default;
388
3.11k
        GDIObj(GDIObj const &) = default;
389
599k
        virtual ~GDIObj() = default; // Polymorphic base class
390
540k
        GDIObj & operator =(GDIObj const &) = default;
391
    };
392
393
    struct EMFIO_DLLPUBLIC WinMtfFontStyle final : GDIObj
394
    {
395
        vcl::Font    aFont;
396
397
        explicit WinMtfFontStyle(LOGFONTW const & rLogFont);
398
399
        ~WinMtfFontStyle() override;
400
    };
401
402
    enum class WinMtfFillStyleType
403
    {
404
        Solid, Pattern
405
    };
406
407
    struct WinMtfFillStyle final : GDIObj
408
    {
409
        Color               aFillColor;
410
        bool                bTransparent;
411
        WinMtfFillStyleType aType;
412
        Bitmap              aBmp;
413
414
        WinMtfFillStyle()
415
154k
            : aFillColor(COL_BLACK)
416
154k
            , bTransparent(false)
417
154k
            , aType(WinMtfFillStyleType::Solid)
418
154k
        {}
419
420
        WinMtfFillStyle(const Color& rColor, bool bTrans = false)
421
154k
            : aFillColor(rColor)
422
154k
            , bTransparent(bTrans)
423
154k
            , aType(WinMtfFillStyleType::Solid)
424
154k
        {}
425
426
        explicit WinMtfFillStyle(Bitmap const & rBmp)
427
17.6k
            : bTransparent(false)
428
17.6k
            , aType(WinMtfFillStyleType::Pattern)
429
17.6k
            , aBmp(rBmp)
430
17.6k
        {}
431
432
        bool operator==(const WinMtfFillStyle& rStyle) const
433
125k
        {
434
125k
            return aFillColor == rStyle.aFillColor
435
116k
                && bTransparent == rStyle.bTransparent
436
116k
                && aType == rStyle.aType;
437
125k
        }
438
    };
439
440
441
    struct WinMtfPalette final : GDIObj
442
    {
443
        std::vector< Color > aPaletteColors;
444
445
        WinMtfPalette()
446
21.7k
            : aPaletteColors(std::vector< Color >{})
447
21.7k
        {}
448
449
        WinMtfPalette(std::vector<Color> paletteColors)
450
4.03k
            : aPaletteColors(std::move(paletteColors))
451
4.03k
        {}
452
453
    };
454
455
456
    struct WinMtfLineStyle final : GDIObj
457
    {
458
        Color       aLineColor;
459
        LineInfo    aLineInfo;
460
        bool        bTransparent;
461
462
        WinMtfLineStyle()
463
154k
            : aLineColor(COL_BLACK)
464
154k
            , bTransparent(false)
465
154k
        {}
466
467
        WinMtfLineStyle(const Color& rColor, bool bTrans = false)
468
57.3k
            : aLineColor(rColor)
469
57.3k
            , bTransparent(bTrans)
470
57.3k
        {}
471
472
        WinMtfLineStyle(const Color& rColor, const sal_uInt32 nStyle, const sal_uInt32 nPenWidth)
473
10.3k
            : aLineColor(rColor)
474
10.3k
        {
475
            // According to documentation: nStyle = PS_COSMETIC = 0x0 - line with a width of one logical unit and a style that is a solid color
476
            // tdf#140271 Based on observed behaviour the line width is not constant with PS_COSMETIC
477
478
            // Width 0 means default width for LineInfo (HairLine) with 1 pixel wide
479
10.3k
            aLineInfo.SetWidth(nPenWidth);
480
10.3k
            switch (nStyle & PS_STYLE_MASK)
481
10.3k
            {
482
808
                case PS_DASHDOTDOT:
483
808
                    aLineInfo.SetStyle(LineStyle::Dash);
484
808
                    aLineInfo.SetDashCount(1);
485
808
                    aLineInfo.SetDotCount(2);
486
808
                    break;
487
496
                case PS_DASHDOT:
488
496
                    aLineInfo.SetStyle(LineStyle::Dash);
489
496
                    aLineInfo.SetDashCount(1);
490
496
                    aLineInfo.SetDotCount(1);
491
496
                    break;
492
339
                case PS_DOT:
493
339
                    aLineInfo.SetStyle(LineStyle::Dash);
494
339
                    aLineInfo.SetDashCount(0);
495
339
                    aLineInfo.SetDotCount(1);
496
339
                    break;
497
745
                case PS_DASH:
498
745
                    aLineInfo.SetStyle(LineStyle::Dash);
499
745
                    aLineInfo.SetDashCount(1);
500
745
                    aLineInfo.SetDotCount(0);
501
745
                    break;
502
238
                case PS_NULL:
503
238
                    aLineInfo.SetStyle(LineStyle::NONE);
504
238
                    break;
505
280
                case PS_INSIDEFRAME: // TODO Implement PS_INSIDEFRAME
506
7.48k
                case PS_SOLID:
507
7.73k
                default:
508
7.73k
                    aLineInfo.SetStyle(LineStyle::Solid);
509
10.3k
            }
510
10.3k
            if (nPenWidth)
511
7.49k
                switch (nStyle & PS_ENDCAP_STYLE_MASK)
512
7.49k
                {
513
5.93k
                    case PS_ENDCAP_ROUND:
514
5.93k
                        aLineInfo.SetLineCap(css::drawing::LineCap_ROUND);
515
5.93k
                        break;
516
65
                    case PS_ENDCAP_SQUARE:
517
65
                        aLineInfo.SetLineCap(css::drawing::LineCap_SQUARE);
518
65
                        break;
519
121
                    case PS_ENDCAP_FLAT:
520
1.49k
                    default:
521
1.49k
                        aLineInfo.SetLineCap(css::drawing::LineCap_BUTT);
522
7.49k
                }
523
2.86k
            else
524
2.86k
                aLineInfo.SetLineCap(css::drawing::LineCap_BUTT);
525
10.3k
            switch (nStyle & PS_JOIN_STYLE_MASK)
526
10.3k
            {
527
8.37k
                case PS_JOIN_ROUND:
528
8.37k
                    aLineInfo.SetLineJoin(basegfx::B2DLineJoin::Round);
529
8.37k
                    break;
530
312
                case PS_JOIN_BEVEL:
531
312
                    aLineInfo.SetLineJoin(basegfx::B2DLineJoin::Bevel);
532
312
                    break;
533
                // Undocumented but based on experiments with MS Paint and MS Word,
534
                // the default Join Style is PS_JOIN_MITER
535
805
                case PS_JOIN_MITER:
536
1.68k
                default:
537
1.68k
                    aLineInfo.SetLineJoin(basegfx::B2DLineJoin::Miter);
538
10.3k
            }
539
10.3k
            bTransparent = aLineInfo.GetStyle() == LineStyle::NONE;
540
10.3k
        }
541
542
        bool operator==(const WinMtfLineStyle& rStyle) const
543
113k
        {
544
113k
            return aLineColor == rStyle.aLineColor
545
86.2k
                && bTransparent == rStyle.bTransparent
546
85.8k
                && aLineInfo == rStyle.aLineInfo;
547
113k
        }
548
    };
549
550
    struct XForm
551
    {
552
        float   eM11;
553
        float   eM12;
554
        float   eM21;
555
        float   eM22;
556
        float   eDx;
557
        float   eDy;
558
559
        XForm()
560
179k
            : eM11(1.0f)
561
179k
            , eM12(0.0f)
562
179k
            , eM21(0.0f)
563
179k
            , eM22(1.0f)
564
179k
            , eDx(0.0f)
565
179k
            , eDy(0.0f)
566
179k
        {}
567
    };
568
569
    SvStream& operator >> (SvStream& rInStream, XForm& rXForm);
570
571
    struct SaveStruct
572
    {
573
        BackgroundMode              nBkMode;
574
        MappingMode         eMapMode;
575
        GraphicsMode        eGfxMode;
576
        vcl::text::ComplexTextLayoutFlags nTextLayoutMode;
577
        sal_Int32           nWinOrgX, nWinOrgY, nWinExtX, nWinExtY;
578
        sal_Int32           nDevOrgX, nDevOrgY, nDevWidth, nDevHeight;
579
580
        WinMtfLineStyle     aLineStyle;
581
        WinMtfFillStyle     aFillStyle;
582
583
        vcl::Font           aFont;
584
        Color               aBkColor;
585
        Color               aTextColor;
586
        sal_uInt32          nTextAlign;
587
        RasterOp            eRasterOp;
588
589
        Point               aActPos;
590
        WinMtfPathObj       maPathObj;
591
        WinMtfClipPath      maClipPath;
592
        XForm               aXForm;
593
594
        bool                bClockWiseArcDirection;
595
        bool                bFillStyleSelected;
596
    };
597
598
    struct BSaveStruct
599
    {
600
        Bitmap              aBmp;
601
        tools::Rectangle    aOutRect;
602
        sal_uInt32          nWinRop;
603
        bool m_bForceAlpha = false;
604
605
        BSaveStruct(const Bitmap& rBmp, const tools::Rectangle& rOutRect, sal_uInt32 nRop,
606
                    bool bForceAlpha = false)
607
65.9k
            : aBmp(rBmp)
608
65.9k
            , aOutRect(rOutRect)
609
65.9k
            , nWinRop(nRop)
610
65.9k
            , m_bForceAlpha(bForceAlpha)
611
65.9k
        {}
612
    };
613
614
    // tdf#127471 implement detection and correction of wrongly scaled
615
    // fonts in own-written, old (before this fix) EMF/WMF files
616
    class ScaledFontDetectCorrectHelper
617
    {
618
    private:
619
        rtl::Reference<MetaFontAction>                                  maCurrentMetaFontAction;
620
        std::vector<double>                                             maAlternativeFontScales;
621
        std::vector<std::pair<rtl::Reference<MetaFontAction>, double>>  maPositiveIdentifiedCases;
622
        std::vector<std::pair<rtl::Reference<MetaFontAction>, double>>  maNegativeIdentifiedCases;
623
624
    public:
625
        ScaledFontDetectCorrectHelper();
626
        void endCurrentMetaFontAction();
627
        void newCurrentMetaFontAction(const rtl::Reference<MetaFontAction>& rNewMetaFontAction);
628
        void evaluateAlternativeFontScale(OUString const & rText, tools::Long nImportedTextLength);
629
        void applyAlternativeFontScale();
630
    };
631
632
    class MtfTools
633
    {
634
        MtfTools(MtfTools const &) = delete;
635
        MtfTools& operator =(MtfTools const &) = delete;
636
637
    protected:
638
        WinMtfPathObj       maPathObj;
639
        WinMtfClipPath      maClipPath;
640
641
        WinMtfLineStyle     maLatestLineStyle;
642
        WinMtfLineStyle     maLineStyle;
643
        WinMtfLineStyle     maNopLineStyle;
644
        WinMtfFillStyle     maLatestFillStyle;
645
        WinMtfFillStyle     maFillStyle;
646
        WinMtfFillStyle     maNopFillStyle;
647
        WinMtfPalette       maPalette;
648
649
        vcl::Font           maLatestFont;
650
        vcl::Font           maFont;
651
        sal_uInt32          mnLatestTextAlign;
652
        sal_uInt32          mnTextAlign;
653
        Color               maLatestTextColor;
654
        Color               maTextColor;
655
        Color               maLatestBkColor;
656
        Color               maBkColor;
657
        vcl::text::ComplexTextLayoutFlags  mnLatestTextLayoutMode;
658
        vcl::text::ComplexTextLayoutFlags  mnTextLayoutMode;
659
        BackgroundMode      mnLatestBkMode;
660
        BackgroundMode      mnBkMode;
661
        RasterOp            meLatestRasterOp;
662
        RasterOp            meRasterOp;
663
664
        std::vector< std::unique_ptr<GDIObj> > mvGDIObj;
665
        Point               maActPos;
666
        WMFRasterOp         mnRop;
667
        std::vector< std::shared_ptr<SaveStruct> > mvSaveStack;
668
669
        GraphicsMode        meGfxMode;
670
        MappingMode         meMapMode;
671
672
        XForm               maXForm;
673
        sal_Int32           mnDevOrgX;
674
        sal_Int32           mnDevOrgY;
675
        sal_Int32           mnDevWidth;
676
        sal_Int32           mnDevHeight;
677
        sal_Int32           mnWinOrgX;
678
        sal_Int32           mnWinOrgY;
679
        sal_Int32           mnWinExtX;
680
        sal_Int32           mnWinExtY;
681
682
        sal_Int32           mnPixX;            // Reference Device in pixel
683
        sal_Int32           mnPixY;            // Reference Device in pixel
684
        sal_Int32           mnMillX;           // Reference Device in Mill
685
        sal_Int32           mnMillY;           // Reference Device in Mill
686
        tools::Rectangle    mrclFrame;
687
        tools::Rectangle    mrclBounds;
688
689
        GDIMetaFile*        mpGDIMetaFile;
690
691
        SvStream*           mpInputStream;               // the WMF/EMF file to be read
692
        sal_uInt32          mnStartPos;
693
        sal_uInt32          mnEndPos;
694
        std::vector<BSaveStruct> maBmpSaveList;
695
696
        // tdf#127471 always try to detect - only used with ScaledText
697
        ScaledFontDetectCorrectHelper maScaledFontHelper;
698
699
        bool                mbNopMode : 1;
700
        bool                mbClockWiseArcDirection : 1;
701
        bool                mbFillStyleSelected : 1;
702
        bool                mbClipNeedsUpdate : 1;
703
        bool                mbComplexClip : 1;
704
        bool                mbIsMapWinSet : 1;
705
        bool                mbIsMapDevSet : 1;
706
707
        void                ResetInternalState();
708
        void                UpdateLineStyle();
709
        void                UpdateFillStyle();
710
711
        Point               ImplMap(const Point& rPt);
712
        Point               ImplScale(const Point& rPt);
713
        Size                ImplMap(const Size& rSize, bool bDoWorldTransform = true);
714
        tools::Rectangle    ImplMap(const tools::Rectangle& rRectangle);
715
        void                ImplMap(vcl::Font& rFont);
716
        tools::Polygon&     ImplMap(tools::Polygon& rPolygon);
717
        tools::PolyPolygon& ImplMap(tools::PolyPolygon& rPolyPolygon);
718
        void                ImplScale(tools::Polygon& rPolygon);
719
        tools::PolyPolygon& ImplScale(tools::PolyPolygon& rPolyPolygon);
720
        void                ImplResizeObjectArry(sal_uInt32 nNewEntry);
721
        void                ImplSetNonPersistentLineColorTransparenz();
722
        void                ImplDrawClippedPolyPolygon(const tools::PolyPolygon& rPolyPoly);
723
        void                ImplDrawBitmap(const Point& rPos, const Size& rSize, const Bitmap& rBitmap);
724
725
    public:
726
727
        void                SetDevByWin(); //Hack to set varying defaults for incompletely defined files.
728
        void                SetDevOrg(const Point& rPoint);
729
        void                SetDevOrgOffset(sal_Int32 nXAdd, sal_Int32 nYAdd);
730
        void                SetDevExt(const Size& rSize, bool regular = true);
731
        void                ScaleDevExt(double fX, double fY);
732
733
        void                SetWinOrg(const Point& rPoint, bool bIsEMF = false);
734
2.18k
        Point               GetWinOrg() { return Point(mnWinOrgX, mnWinOrgY); }
735
        void                SetWinOrgOffset(sal_Int32 nX, sal_Int32 nY);
736
        void                SetWinExt(const Size& rSize, bool bIsEMF = false);
737
        void                ScaleWinExt(double fX, double fY);
738
739
        void                SetrclBounds(const tools::Rectangle& rRect);
740
        void                SetrclFrame(const tools::Rectangle& rRect);
741
        void                SetRefPix(const Size& rSize);
742
        void                SetRefMill(const Size& rSize);
743
744
        void                SetMapMode(MappingMode mnMapMode);
745
        void                SetWorldTransform(const XForm& rXForm);
746
        void                ModifyWorldTransform(const XForm& rXForm, ModifyWorldTransformMode nMode);
747
748
        void                Push();
749
        void                Pop( const sal_Int32 nSavedDC = -1 );
750
751
        WMFRasterOp         SetRasterOp(WMFRasterOp nRasterOp);
752
        void                StrokeAndFillPath(bool bStroke, bool bFill);
753
754
        void                SetArcDirection(bool bCounterClockWise);
755
8.48k
        bool                IsArcDirectionClockWise() { return mbClockWiseArcDirection; };
756
80.6k
        void                SetGfxMode(GraphicsMode nGfxMode) { meGfxMode = nGfxMode; };
757
27.0k
        GraphicsMode        GetGfxMode() const { return meGfxMode; };
758
        void                SetBkMode(BackgroundMode nMode);
759
        void                SetBkColor(const Color& rColor);
760
        void                SetTextColor(const Color& rColor);
761
        void                SetTextAlign(sal_uInt32 nAlign);
762
763
        void                CreateObject(std::unique_ptr<GDIObj> pObject);
764
        void                CreateObjectIndexed(sal_uInt32 nIndex, std::unique_ptr<GDIObj> pObject);
765
        void                CreateObject();
766
767
        void                DeleteObject(sal_uInt32 nIndex);
768
        void                SelectObject(sal_uInt32 nIndex);
769
26.3k
        rtl_TextEncoding    GetCharSet() const { return maFont.GetCharSet(); };
770
0
        const vcl::Font&    GetFont() const { return maFont; }
771
        void                SetTextLayoutMode(vcl::text::ComplexTextLayoutFlags nLayoutMode);
772
773
8.46k
        void                ClearPath() { maPathObj.Init(); };
774
28.9k
        void                ClosePath() { maPathObj.ClosePath(); };
775
69
        const tools::PolyPolygon& GetPathObj() const { return maPathObj; };
776
777
        void                MoveTo(const Point& rPoint, bool bRecordPath = false);
778
        void                LineTo(const Point& rPoint, bool bRecordPath = false);
779
        void                DrawPixel(const Point& rSource, const Color& rColor);
780
        void                DrawRect(const tools::Rectangle& rRect, bool bEdge = true);
781
        void                DrawRectWithBGColor(const tools::Rectangle& rRect);
782
        void                DrawRoundRect(const tools::Rectangle& rRect, const Size& rSize);
783
        void                DrawEllipse(const tools::Rectangle& rRect);
784
        void                DrawArc(
785
            const tools::Rectangle& rRect,
786
            const Point& rStartAngle,
787
            const Point& rEndAngle,
788
            bool bDrawTo = false
789
        );
790
        void                DrawPie(
791
            const tools::Rectangle& rRect,
792
            const Point& rStartAngle,
793
            const Point& rEndAngle
794
        );
795
        void                DrawChord(
796
            const tools::Rectangle& rRect,
797
            const Point& rStartAngle,
798
            const Point& rEndAngle
799
        );
800
        void                DrawPolygon(tools::Polygon rPolygon, bool bRecordPath);
801
        void                DrawPolyPolygon(tools::PolyPolygon& rPolyPolygon, bool bRecordPath = false);
802
        void                DrawPolyLine(tools::Polygon rPolygon,
803
            bool bDrawTo = false,
804
            bool bRecordPath = false
805
        );
806
        void                DrawPolyBezier(tools::Polygon rPolygon,
807
            bool bDrawTo,
808
            bool bRecordPath
809
        );
810
        void                DrawText(Point& rPosition,
811
            OUString const & rString,
812
            KernArray* pDXArry = nullptr,
813
            tools::Long* pDYArry = nullptr,
814
            const float fXScale = 1.0,
815
            const float fYScale = 1.0,
816
            bool bRecordPath = false,
817
            GraphicsMode nGraphicsMode = GraphicsMode::GM_COMPATIBLE);
818
819
        void                ResolveBitmapActions(std::vector<BSaveStruct>& rSaveList);
820
821
        void                IntersectClipRect(const tools::Rectangle& rRect);
822
        void                ExcludeClipRect(const tools::Rectangle& rRect);
823
        void                MoveClipRegion(const Size& rSize);
824
        void                SetClipPath(
825
            const tools::PolyPolygon& rPolyPoly,
826
            RegionMode nClippingMode,
827
            bool bIsMapped
828
        );
829
        void                SetDefaultClipPath();
830
        void                UpdateClipRegion();
831
        void                AddFromGDIMetaFile(GDIMetaFile& rGDIMetaFile);
832
833
        void                PassEMFPlus(void const * pBuffer, sal_uInt32 nLength);
834
        void                PassEMFPlusHeaderInfo();
835
836
        Color               ReadColor();
837
838
        explicit            MtfTools(GDIMetaFile& rGDIMetaFile, SvStream& rStreamWMF);
839
        ~MtfTools();
840
    };
841
}
842
843
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */