summaryrefslogtreecommitdiffstats
path: root/drawinglayer/source/tools/emfphelperdata.hxx
blob: ef870f31e6879e7512a7700a4a4473310997c6de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#pragma once

#include <wmfemfhelper.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <drawinglayer/attribute/linestartendattribute.hxx>
#include <tools/stream.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <map>

// predefines
class SvStream;
namespace basegfx { class B2DPolyPolygon; }

namespace emfplushelper
{
    // EMF+ commands
    #define EmfPlusRecordTypeHeader 0x4001
    #define EmfPlusRecordTypeEndOfFile 0x4002
    #define EmfPlusRecordTypeComment 0x4003
    #define EmfPlusRecordTypeGetDC 0x4004
    //TODO EmfPlusRecordTypeMultiFormatStart 0x4005
    //TODO EmfPlusRecordTypeMultiFormatSection 0x4006
    //TODO EmfPlusRecordTypeMultiFormatEnd 0x4007
    #define EmfPlusRecordTypeObject 0x4008
    //TODO EmfPlusRecordTypeClear 0x4009
    #define EmfPlusRecordTypeFillRects 0x400A
    #define EmfPlusRecordTypeDrawRects 0x400B
    #define EmfPlusRecordTypeFillPolygon 0x400C
    #define EmfPlusRecordTypeDrawLines 0x400D
    #define EmfPlusRecordTypeFillEllipse 0x400E
    #define EmfPlusRecordTypeDrawEllipse 0x400F
    #define EmfPlusRecordTypeFillPie 0x4010
    #define EmfPlusRecordTypeDrawPie 0x4011
    #define EmfPlusRecordTypeDrawArc 0x4012
    #define EmfPlusRecordTypeFillRegion 0x4013
    #define EmfPlusRecordTypeFillPath 0x4014
    #define EmfPlusRecordTypeDrawPath 0x4015
    #define EmfPlusRecordTypeFillClosedCurve 0x4016
    #define EmfPlusRecordTypeDrawClosedCurve 0x4017
    //TODO EmfPlusRecordTypeDrawCurve 0x4018
    #define EmfPlusRecordTypeDrawBeziers 0x4019
    #define EmfPlusRecordTypeDrawImage 0x401A
    #define EmfPlusRecordTypeDrawImagePoints 0x401B
    #define EmfPlusRecordTypeDrawString 0x401C
    #define EmfPlusRecordTypeSetRenderingOrigin 0x401D
    #define EmfPlusRecordTypeSetAntiAliasMode 0x401E
    #define EmfPlusRecordTypeSetTextRenderingHint 0x401F
    #define EmfPlusRecordTypeSetTextContrast 0x4020
    #define EmfPlusRecordTypeSetInterpolationMode 0x4021
    #define EmfPlusRecordTypeSetPixelOffsetMode 0x4022
    //TODO EmfPlusRecordTypeSetCompositingMode 0x4023
    #define EmfPlusRecordTypeSetCompositingQuality 0x4024
    #define EmfPlusRecordTypeSave 0x4025
    #define EmfPlusRecordTypeRestore 0x4026
    #define EmfPlusRecordTypeBeginContainer 0x4027
    #define EmfPlusRecordTypeBeginContainerNoParams 0x4028
    #define EmfPlusRecordTypeEndContainer 0x4029
    #define EmfPlusRecordTypeSetWorldTransform 0x402A
    #define EmfPlusRecordTypeResetWorldTransform 0x402B
    #define EmfPlusRecordTypeMultiplyWorldTransform 0x402C
    #define EmfPlusRecordTypeTranslateWorldTransform 0x402D
    #define EmfPlusRecordTypeScaleWorldTransform 0x402E
    #define EmfPlusRecordTypeRotateWorldTransform 0x402F
    #define EmfPlusRecordTypeSetPageTransform 0x4030
    #define EmfPlusRecordTypeResetClip 0x4031
    #define EmfPlusRecordTypeSetClipRect 0x4032
    #define EmfPlusRecordTypeSetClipPath 0x4033
    #define EmfPlusRecordTypeSetClipRegion 0x4034
    #define EmfPlusRecordTypeOffsetClip 0x4035
    #define EmfPlusRecordTypeDrawDriverString 0x4036
    //TODO EmfPlusRecordTypeStrokeFillPath 0x4037
    //TODO EmfPlusRecordTypeSerializableObject 0x4038
    //TODO EmfPlusRecordTypeSetTSGraphics 0x4039
    //TODO EmfPlusRecordTypeSetTSClip 0x403A

    // EMF+object types
    #define EmfPlusObjectTypeBrush 0x100
    #define EmfPlusObjectTypePen 0x200
    #define EmfPlusObjectTypePath 0x300
    #define EmfPlusObjectTypeRegion 0x400
    #define EmfPlusObjectTypeImage 0x500
    #define EmfPlusObjectTypeFont 0x600
    #define EmfPlusObjectTypeStringFormat 0x700
    #define EmfPlusObjectTypeImageAttributes 0x800
    #define EmfPlusObjectTypeCustomLineCap 0x900

    enum PixelOffsetMode
    {
        PixelOffsetModeDefault = 0x00,
        PixelOffsetModeHighSpeed = 0x01,
        PixelOffsetModeHighQuality = 0x02,
        PixelOffsetModeNone = 0x03,
        PixelOffsetModeHalf = 0x04
    };

    enum SmoothingMode
    {
        SmoothingModeDefault = 0x00,
        SmoothingModeHighSpeed = 0x01,
        SmoothingModeHighQuality = 0x02,
        SmoothingModeNone = 0x03,
        SmoothingModeAntiAlias8x4 = 0x04,
        SmoothingModeAntiAlias8x8 = 0x05
    };

    enum InterpolationMode
    {
        InterpolationModeDefault = 0x00,
        InterpolationModeLowQuality = 0x01,
        InterpolationModeHighQuality = 0x02,
        InterpolationModeBilinear = 0x03,
        InterpolationModeBicubic = 0x04,
        InterpolationModeNearestNeighbor = 0x05,
        InterpolationModeHighQualityBilinear = 0x06,
        InterpolationModeHighQualityBicubic = 0x07
    };

    enum TextRenderingHint
    {
        TextRenderingHintSystemDefault = 0x00,
        TextRenderingHintSingleBitPerPixelGridFit = 0x01,
        TextRenderingHintSingleBitPerPixel = 0x02,
        TextRenderingHintAntialiasGridFit = 0x03,
        TextRenderingHintAntialias = 0x04,
        TextRenderingHintClearTypeGridFit = 0x05
    };

    enum UnitType
    {
        UnitTypeWorld = 0x00,
        UnitTypeDisplay = 0x01,
        UnitTypePixel = 0x02,
        UnitTypePoint = 0x03,
        UnitTypeInch = 0x04,
        UnitTypeDocument = 0x05,
        UnitTypeMillimeter = 0x06
    };

    enum EmfPlusCombineMode
    {
        EmfPlusCombineModeReplace = 0x00000000,
        EmfPlusCombineModeIntersect = 0x00000001,
        EmfPlusCombineModeUnion = 0x00000002,
        EmfPlusCombineModeXOR = 0x00000003,
        EmfPlusCombineModeExclude = 0x00000004,
        EmfPlusCombineModeComplement = 0x00000005
    };

    const char* emfTypeToName(sal_uInt16 type);
    OUString UnitTypeToString(sal_uInt16 nType);

    struct EMFPObject
    {
        virtual ~EMFPObject();
    };

    typedef std::map<int, wmfemfhelper::PropertyHolder> GraphicStateMap;

    struct EmfPlusHelperData
    {
    private:
        /* EMF+ */
        basegfx::B2DHomMatrix       maBaseTransform;
        basegfx::B2DHomMatrix       maWorldTransform;
        basegfx::B2DHomMatrix       maMapTransform;

        std::unique_ptr<EMFPObject> maEMFPObjects[256];
        float                       mfPageScale;
        sal_Int32                   mnOriginX;
        sal_Int32                   mnOriginY;
        sal_uInt32                  mnHDPI;
        sal_uInt32                  mnVDPI;
        bool                        mbSetTextContrast;
        sal_uInt16                  mnTextContrast;

        /* EMF+ emf header info */
        sal_Int32                   mnFrameLeft;
        sal_Int32                   mnFrameTop;
        sal_Int32                   mnFrameRight;
        sal_Int32                   mnFrameBottom;
        sal_Int32                   mnPixX;
        sal_Int32                   mnPixY;
        sal_Int32                   mnMmX;
        sal_Int32                   mnMmY;

        /* multipart object data */
        bool                        mbMultipart;
        sal_uInt16                  mMFlags;
        SvMemoryStream              mMStream;

        /* emf+ graphic state stack */
        GraphicStateMap             mGSStack;
        GraphicStateMap             mGSContainerStack;

        /* Performance optimizators */
        /* Extracted Scale values from Transformation Matrix */
        double mdExtractedXScale;
        double mdExtractedYScale;

        /// data holders
        wmfemfhelper::TargetHolders&    mrTargetHolders;
        wmfemfhelper::PropertyHolders&  mrPropertyHolders;
        wmfemfhelper::PropertyHolder    aGetDCState;
        bool                            bIsGetDCProcessing;

        // readers
        void processObjectRecord(SvMemoryStream& rObjectStream, sal_uInt16 flags, sal_uInt32 dataSize, bool bUseWholeStream = false);
        static void ReadPoint(SvStream& s, float& x, float& y, sal_uInt32 flags);

        // internal mapper
        void mappingChanged();

        // stack actions
        void GraphicStatePush(GraphicStateMap& map, sal_Int32 index);
        void GraphicStatePop(GraphicStateMap& map, sal_Int32 index);

        drawinglayer::attribute::LineStartEndAttribute CreateLineEnd(const sal_Int32 aCap,
                                                                     const float aPenWidth) const;

        // primitive creators
        void EMFPPlusDrawPolygon(const ::basegfx::B2DPolyPolygon& polygon, sal_uInt32 penIndex);
        void EMFPPlusFillPolygon(const ::basegfx::B2DPolyPolygon& polygon, const bool isColor, const sal_uInt32 brushIndexOrColor);
        void EMFPPlusFillPolygonSolidColor(const ::basegfx::B2DPolyPolygon& polygon, Color const& color);

        // helper functions
        Color EMFPGetBrushColorOrARGBColor(const sal_uInt16 flags, const sal_uInt32 brushIndexOrColor) const;

    public:
        EmfPlusHelperData(
            SvMemoryStream& rMS,
            wmfemfhelper::TargetHolders& rTargetHolders,
            wmfemfhelper::PropertyHolders& rPropertyHolders);
        ~EmfPlusHelperData();

        void processEmfPlusData(
            SvMemoryStream& rMS,
            const drawinglayer::geometry::ViewInformation2D& rViewInformation);

        // mappers
        ::basegfx::B2DPoint Map(double ix, double iy) const;

        // readers
        static void ReadRectangle(SvStream& s, float& x, float& y, float &width, float& height, bool bCompressed = false);
        static bool readXForm(SvStream& rIn, basegfx::B2DHomMatrix& rTarget);
        static ::basegfx::B2DPolyPolygon combineClip(::basegfx::B2DPolyPolygon const & leftPolygon, int combineMode, ::basegfx::B2DPolyPolygon const & rightPolygon);

        static float getUnitToPixelMultiplier(const UnitType aUnitType, const sal_uInt32 aDPI);
    };
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */