Coverage Report

Created: 2026-04-29 07:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwpg/src/lib/WPG2Parser.h
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2
/* libwpg
3
 * Version: MPL 2.0 / LGPLv2.1+
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
 * Major Contributor(s):
10
 * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
11
 * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch)
12
 * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)
13
 *
14
 * For minor contributions see the git repository.
15
 *
16
 * Alternatively, the contents of this file may be used under the terms
17
 * of the GNU Lesser General Public License Version 2.1 or later
18
 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
19
 * applicable instead of those above.
20
 *
21
 * For further information visit http://libwpg.sourceforge.net
22
 */
23
24
/* "This product is not manufactured, approved, or supported by
25
 * Corel Corporation or Corel Corporation Limited."
26
 */
27
28
#ifndef __WPG2PARSER_H__
29
#define __WPG2PARSER_H__
30
31
#include <limits>
32
#include <map>
33
#include <stack>
34
#include <vector>
35
36
#include <librevenge/librevenge.h>
37
38
#include "WPGBitmap.h"
39
#include "WPGDashArray.h"
40
#include "WPGXParser.h"
41
42
class WPG2TransformMatrix
43
{
44
public:
45
  double element[3][3];
46
47
  WPG2TransformMatrix()
48
995k
  {
49
    // identity transformation
50
995k
    element[0][0] = element[1][1] = 1;
51
995k
    element[2][2] = 1;
52
995k
    element[0][1] = element[0][2] = 0;
53
995k
    element[1][0] = element[1][2] = 0;
54
995k
    element[2][0] = element[2][1] = 0;
55
995k
  }
56
57
  void transform(long &x, long &y) const
58
1.32M
  {
59
1.32M
    const double rx = element[0][0]*x + element[1][0]*y + element[2][0];
60
1.32M
    const double ry = element[0][1]*x + element[1][1]*y + element[2][1];
61
1.32M
    x = toLong(rx);
62
1.32M
    y = toLong(ry);
63
1.32M
  }
64
65
  librevenge::RVNGPropertyList transformPoint(const ::librevenge::RVNGPropertyList &p) const
66
0
  {
67
0
    librevenge::RVNGPropertyList propList;
68
0
    propList.insert("svg:x", (element[0][0]*p["svg:x"]->getDouble() + element[1][0]*p["svg:y"]->getDouble() + element[2][0]));
69
0
    propList.insert("svg:y", (element[0][1]*p["svg:x"]->getDouble() + element[1][1]*p["svg:y"]->getDouble() + element[2][1]));
70
0
    return propList;
71
0
  }
72
73
  librevenge::RVNGPropertyList transformRect(const ::librevenge::RVNGPropertyList &r) const
74
0
  {
75
0
    librevenge::RVNGPropertyList propList;
76
0
    double oldx1 = r["svg:x"]->getDouble();
77
0
    double oldy1 = r["svg:y"]->getDouble();
78
0
    double oldx2 = r["svg:x"]->getDouble() + r["svg:width"]->getDouble();
79
0
    double oldy2 = r["svg:y"]->getDouble() + r["svg:height"]->getDouble();
80
0
81
0
    double newx1 = element[0][0]*oldx1 + element[1][0]*oldy1 + element[2][0];
82
0
    double newy1 = element[0][1]*oldx1 + element[1][1]*oldy1 + element[2][1];
83
0
    double newx2 = element[0][0]*oldx2 + element[1][0]*oldy2 + element[2][0];
84
0
    double newy2 = element[0][1]*oldx2 + element[1][1]*oldy2 + element[2][1];
85
0
86
0
    propList.insert("svg:x", (double)newx1);
87
0
    propList.insert("svg:y", (double)newy1);
88
0
    propList.insert("svg:width", (newx2-newx1));
89
0
    propList.insert("svg:height", (newy2-newy1));
90
0
    return propList;
91
0
  }
92
93
  WPG2TransformMatrix &transformBy(const WPG2TransformMatrix &m)
94
8.80k
  {
95
8.80k
    double result[3][3];
96
97
35.2k
    for (int i = 0; i < 3; i++)
98
105k
      for (int j = 0; j < 3; j++)
99
79.2k
      {
100
79.2k
        result[i][j] = 0;
101
316k
        for (int k = 0; k < 3; k++)
102
237k
          result[i][j] += m.element[i][k]*element[k][j];
103
79.2k
      }
104
105
35.2k
    for (int x = 0; x < 3; x++)
106
105k
      for (int y = 0; y < 3; y++)
107
79.2k
        element[x][y] = result[x][y];
108
109
8.80k
    return *this;
110
8.80k
  }
111
112
private:
113
  static long toLong(double d)
114
2.65M
  {
115
2.65M
    if (d > double(std::numeric_limits<long>::max()))
116
33.0k
      return std::numeric_limits<long>::max();
117
2.62M
    else if (d < double(std::numeric_limits<long>::min()))
118
14.6k
      return std::numeric_limits<long>::min();
119
2.61M
    else
120
2.61M
      return long(d);
121
2.65M
  }
122
};
123
124
class WPGCompoundPolygon
125
{
126
public:
127
  WPG2TransformMatrix matrix;
128
  bool isFilled;
129
  bool isFramed;
130
  bool isClosed;
131
132
0
  WPGCompoundPolygon(): matrix(), isFilled(true), isFramed(true), isClosed(true) {}
133
};
134
135
class WPGGroupContext
136
{
137
public:
138
  unsigned subIndex;
139
  int parentType;
140
  librevenge::RVNGPropertyListVector compoundPath;
141
  WPG2TransformMatrix compoundMatrix;
142
  bool compoundWindingRule;
143
  bool compoundFilled;
144
  bool compoundFramed;
145
  bool compoundClosed;
146
147
689k
  WPGGroupContext(): subIndex(0), parentType(0),
148
689k
    compoundPath(), compoundMatrix(), compoundWindingRule(false),
149
689k
    compoundFilled(false), compoundFramed(true), compoundClosed(false) {}
150
151
  bool isCompoundPolygon() const
152
919k
  {
153
919k
    return parentType == 0x1a;
154
919k
  }
155
};
156
157
class WPGBitmapContext
158
{
159
public:
160
  double x1, y1, x2, y2;
161
  long hres, vres;
162
13.7k
  WPGBitmapContext(): x1(0), y1(0), x2(0), y2(0), hres(100), vres(100) {}
163
};
164
165
class WPGBinaryDataContext
166
{
167
public:
168
  double x1, y1, x2, y2;
169
  int numObjects, objectIndex;
170
  std::vector<librevenge::RVNGString> mimeTypes;
171
13.7k
  WPGBinaryDataContext(): x1(0), y1(0), x2(0), y2(0), numObjects(0), objectIndex(0), mimeTypes() {}
172
};
173
174
class WPGTextDataContext
175
{
176
public:
177
  double x1, y1, x2, y2;
178
  unsigned short flags;
179
  unsigned char vertAlign;
180
  unsigned char horAlign;
181
  double baseLineAngle;
182
13.7k
  WPGTextDataContext(): x1(0), y1(0), x2(0), y2(0), flags(), vertAlign(), horAlign(), baseLineAngle(0.0) {}
183
};
184
185
class WPG2Parser : public WPGXParser
186
{
187
public:
188
  WPG2Parser(librevenge::RVNGInputStream *input, librevenge::RVNGDrawingInterface *painter, bool isEmbedded = false);
189
  bool parse() override;
190
191
private:
192
  void handleStartWPG();
193
  void handleEndWPG();
194
  void handleFormSettings();
195
  void handleLayer();
196
  void handleCompoundPolygon();
197
198
  void handlePenStyleDefinition();
199
  void handlePatternDefinition();
200
  void handleColorPalette();
201
  void handleDPColorPalette();
202
  void handlePenForeColor();
203
  void handleDPPenForeColor();
204
  void handlePenBackColor();
205
  void handleDPPenBackColor();
206
  void handlePenStyle();
207
  void handlePenSize();
208
  void handleDPPenSize();
209
  void handleLineCap();
210
  void handleLineJoin();
211
  void handleBrushGradient();
212
  void handleDPBrushGradient();
213
  void handleBrushForeColor();
214
  void handleDPBrushForeColor();
215
  void handleBrushBackColor();
216
  void handleDPBrushBackColor();
217
  void handleBrushPattern();
218
219
  void handlePolyline();
220
  void handlePolyspline();
221
  void handlePolycurve();
222
  void handleRectangle();
223
  void handleArc();
224
225
  void handleBitmap();
226
  void handleBitmapData();
227
228
  void handleTextData();
229
  void handleTextLine();
230
  void handleTextBlock();
231
  void handleTextPath();
232
233
  void handleObjectCapsule();
234
  void handleObjectImage();
235
236
  void resetPalette();
237
  void flushCompoundPolygon();
238
  void setPenStyle();
239
240
  unsigned int getRemainingRecordLength() const;
241
  bool checkRLESize(unsigned bytes) const;
242
243
  double toDouble(long x) const;
244
  void transformXY(long &x, long &y) const;
245
246
  // parsing context
247
  int m_recordLength;
248
  long m_recordEnd;
249
  bool m_success;
250
  bool m_exit;
251
  bool m_graphicsStarted;
252
  unsigned int m_xres;
253
  unsigned int m_yres;
254
  long m_xofs;
255
  long m_yofs;
256
  long m_width;
257
  long m_height;
258
  bool m_doublePrecision;
259
  librevenge::RVNGPropertyList m_style;
260
  libwpg::WPGColor m_penForeColor;
261
  libwpg::WPGColor m_penBackColor;
262
  libwpg::WPGColor m_brushForeColor;
263
  libwpg::WPGColor m_brushBackColor;
264
  libwpg::WPGDashArray m_dashArray;
265
  librevenge::RVNGPropertyListVector m_gradient;
266
  std::map<unsigned int,libwpg::WPGDashArray> m_dashArrayStyles;
267
  bool m_layerOpened;
268
#ifdef DEBUG
269
  unsigned int m_layerId;
270
#endif
271
  WPG2TransformMatrix m_matrix;
272
  double m_gradientAngle;
273
  librevenge::RVNGPropertyList m_gradientRef;
274
  std::stack<WPGGroupContext> m_groupStack;
275
  WPG2TransformMatrix m_compoundMatrix;
276
  bool m_compoundWindingRule;
277
  bool m_compoundFilled;
278
  bool m_compoundFramed;
279
  bool m_compoundClosed;
280
  WPGBitmapContext m_bitmap;
281
  WPGBinaryDataContext m_binaryData;
282
  bool m_hFlipped, m_vFlipped;
283
  WPGTextDataContext m_textData;
284
  bool m_drawTextData;
285
286
  class ObjectCharacterization;
287
  void parseCharacterization(ObjectCharacterization *);
288
#if DUMP_BINARY_DATA
289
  unsigned m_binaryId;
290
#endif
291
};
292
293
#endif // __WPG2PARSER_H__
294
/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */