Coverage Report

Created: 2026-05-16 09:25

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