~ubuntu-branches/ubuntu/precise/koffice/precise

« back to all changes in this revision

Viewing changes to filters/libmso/shapes.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2010-09-21 15:36:35 UTC
  • mfrom: (1.4.1 upstream) (60.2.11 maverick)
  • Revision ID: james.westby@ubuntu.com-20100921153635-6tejqkiro2u21ydi
Tags: 1:2.2.2-0ubuntu3
Add kubuntu_03_fix-crash-on-closing-sqlite-connection-2.2.2.diff and
kubuntu_04_support-large-memo-values-for-msaccess-2.2.2.diff as
recommended by upstream http://kexi-
project.org/wiki/wikiview/index.php@Kexi2.2_Patches.html#sqlite_stab
ility

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This file is part of the KDE project
 
2
   Copyright (C) 2010 KO GmbH <jos.van.den.oever@kogmbh.com>
 
3
 
 
4
   This library is free software; you can redistribute it and/or
 
5
   modify it under the terms of the GNU Library General Public
 
6
   License as published by the Free Software Foundation; either
 
7
   version 2 of the License, or (at your option) any later version.
 
8
 
 
9
   This library is distributed in the hope that it will be useful,
 
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
   Library General Public License for more details.
 
13
 
 
14
   You should have received a copy of the GNU Library General Public License
 
15
   along with this library; see the file COPYING.LIB.  If not, write to
 
16
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
17
 * Boston, MA 02110-1301, USA.
 
18
*/
 
19
#include "ODrawToOdf.h"
 
20
#include "drawstyle.h"
 
21
 
 
22
#include <KoXmlWriter.h>
 
23
#include <kdebug.h>
 
24
 
 
25
#include <QMatrix>
 
26
 
 
27
#include <cmath>
 
28
 
 
29
using namespace MSO;
 
30
 
 
31
namespace {
 
32
enum {
 
33
    msosptMin = 0,
 
34
    msosptNotPrimitive = msosptMin,
 
35
    msosptRectangle = 1,
 
36
    msosptRoundRectangle = 2,
 
37
    msosptEllipse = 3,
 
38
    msosptDiamond = 4,
 
39
    msosptIsoscelesTriangle = 5,
 
40
    msosptRightTriangle = 6,
 
41
    msosptParallelogram = 7,
 
42
    msosptTrapezoid = 8,
 
43
    msosptHexagon = 9,
 
44
    msosptOctagon = 10,
 
45
    msosptPlus = 11,
 
46
    msosptStar = 12,
 
47
    msosptArrow = 13,
 
48
    msosptThickArrow = 14,
 
49
    msosptHomePlate = 15,
 
50
    msosptCube = 16,
 
51
    msosptBalloon = 17,
 
52
    msosptSeal = 18,
 
53
    msosptArc = 19,
 
54
    msosptLine = 20,
 
55
    msosptPlaque = 21,
 
56
    msosptCan = 22,
 
57
    msosptDonut = 23,
 
58
    msosptTextSimple = 24,
 
59
    msosptTextOctagon = 25,
 
60
    msosptTextHexagon = 26,
 
61
    msosptTextCurve = 27,
 
62
    msosptTextWave = 28,
 
63
    msosptTextRing = 29,
 
64
    msosptTextOnCurve = 30,
 
65
    msosptTextOnRing = 31,
 
66
    msosptStraightConnector1 = 32,
 
67
    msosptBentConnector2 = 33,
 
68
    msosptBentConnector3 = 34,
 
69
    msosptBentConnector4 = 35,
 
70
    msosptBentConnector5 = 36,
 
71
    msosptCurvedConnector2 = 37,
 
72
    msosptCurvedConnector3 = 38,
 
73
    msosptCurvedConnector4 = 39,
 
74
    msosptCurvedConnector5 = 40,
 
75
    msosptCallout1 = 41,
 
76
    msosptCallout2 = 42,
 
77
    msosptCallout3 = 43,
 
78
    msosptAccentCallout1 = 44,
 
79
    msosptAccentCallout2 = 45,
 
80
    msosptAccentCallout3 = 46,
 
81
    msosptBorderCallout1 = 47,
 
82
    msosptBorderCallout2 = 48,
 
83
    msosptBorderCallout3 = 49,
 
84
    msosptAccentBorderCallout1 = 50,
 
85
    msosptAccentBorderCallout2 = 51,
 
86
    msosptAccentBorderCallout3 = 52,
 
87
    msosptRibbon = 53,
 
88
    msosptRibbon2 = 54,
 
89
    msosptChevron = 55,
 
90
    msosptPentagon = 56,
 
91
    msosptNoSmoking = 57,
 
92
    msosptSeal8 = 58,
 
93
    msosptSeal16 = 59,
 
94
    msosptSeal32 = 60,
 
95
    msosptWedgeRectCallout = 61,
 
96
    msosptWedgeRRectCallout = 62,
 
97
    msosptWedgeEllipseCallout = 63,
 
98
    msosptWave = 64,
 
99
    msosptFoldedCorner = 65,
 
100
    msosptLeftArrow = 66,
 
101
    msosptDownArrow = 67,
 
102
    msosptUpArrow = 68,
 
103
    msosptLeftRightArrow = 69,
 
104
    msosptUpDownArrow = 70,
 
105
    msosptIrregularSeal1 = 71,
 
106
    msosptIrregularSeal2 = 72,
 
107
    msosptLightningBolt = 73,
 
108
    msosptHeart = 74,
 
109
    msosptPictureFrame = 75,
 
110
    msosptQuadArrow = 76,
 
111
    msosptLeftArrowCallout = 77,
 
112
    msosptRightArrowCallout = 78,
 
113
    msosptUpArrowCallout = 79,
 
114
    msosptDownArrowCallout = 80,
 
115
    msosptLeftRightArrowCallout = 81,
 
116
    msosptUpDownArrowCallout = 82,
 
117
    msosptQuadArrowCallout = 83,
 
118
    msosptBevel = 84,
 
119
    msosptLeftBracket = 85,
 
120
    msosptRightBracket = 86,
 
121
    msosptLeftBrace = 87,
 
122
    msosptRightBrace = 88,
 
123
    msosptLeftUpArrow = 89,
 
124
    msosptBentUpArrow = 90,
 
125
    msosptBentArrow = 91,
 
126
    msosptSeal24 = 92,
 
127
    msosptStripedRightArrow = 93,
 
128
    msosptNotchedRightArrow = 94,
 
129
    msosptBlockArc = 95,
 
130
    msosptSmileyFace = 96,
 
131
    msosptVerticalScroll = 97,
 
132
    msosptHorizontalScroll = 98,
 
133
    msosptCircularArrow = 99,
 
134
    msosptNotchedCircularArrow = 100,
 
135
    msosptUturnArrow = 101,
 
136
    msosptCurvedRightArrow = 102,
 
137
    msosptCurvedLeftArrow = 103,
 
138
    msosptCurvedUpArrow = 104,
 
139
    msosptCurvedDownArrow = 105,
 
140
    msosptCloudCallout = 106,
 
141
    msosptEllipseRibbon = 107,
 
142
    msosptEllipseRibbon2 = 108,
 
143
    msosptFlowChartProcess = 109,
 
144
    msosptFlowChartDecision = 110,
 
145
    msosptFlowChartInputOutput = 111,
 
146
    msosptFlowChartPredefinedProcess = 112,
 
147
    msosptFlowChartInternalStorage = 113,
 
148
    msosptFlowChartDocument = 114,
 
149
    msosptFlowChartMultidocument = 115,
 
150
    msosptFlowChartTerminator = 116,
 
151
    msosptFlowChartPreparation = 117,
 
152
    msosptFlowChartManualInput = 118,
 
153
    msosptFlowChartManualOperation = 119,
 
154
    msosptFlowChartConnector = 120,
 
155
    msosptFlowChartPunchedCard = 121,
 
156
    msosptFlowChartPunchedTape = 122,
 
157
    msosptFlowChartSummingJunction = 123,
 
158
    msosptFlowChartOr = 124,
 
159
    msosptFlowChartCollate = 125,
 
160
    msosptFlowChartSort = 126,
 
161
    msosptFlowChartExtract = 127,
 
162
    msosptFlowChartMerge = 128,
 
163
    msosptFlowChartOfflineStorage = 129,
 
164
    msosptFlowChartOnlineStorage = 130,
 
165
    msosptFlowChartMagneticTape = 131,
 
166
    msosptFlowChartMagneticDisk = 132,
 
167
    msosptFlowChartMagneticDrum = 133,
 
168
    msosptFlowChartDisplay = 134,
 
169
    msosptFlowChartDelay = 135,
 
170
    msosptTextPlainText = 136,
 
171
    msosptTextStop = 137,
 
172
    msosptTextTriangle = 138,
 
173
    msosptTextTriangleInverted = 139,
 
174
    msosptTextChevron = 140,
 
175
    msosptTextChevronInverted = 141,
 
176
    msosptTextRingInside = 142,
 
177
    msosptTextRingOutside = 143,
 
178
    msosptTextArchUpCurve = 144,
 
179
    msosptTextArchDownCurve = 145,
 
180
    msosptTextCircleCurve = 146,
 
181
    msosptTextButtonCurve = 147,
 
182
    msosptTextArchUpPour = 148,
 
183
    msosptTextArchDownPour = 149,
 
184
    msosptTextCirclePour = 150,
 
185
    msosptTextButtonPour = 151,
 
186
    msosptTextCurveUp = 152,
 
187
    msosptTextCurveDown = 153,
 
188
    msosptTextCascadeUp = 154,
 
189
    msosptTextCascadeDown = 155,
 
190
    msosptTextWave1 = 156,
 
191
    msosptTextWave2 = 157,
 
192
    msosptTextWave3 = 158,
 
193
    msosptTextWave4 = 159,
 
194
    msosptTextInflate = 160,
 
195
    msosptTextDeflate = 161,
 
196
    msosptTextInflateBottom = 162,
 
197
    msosptTextDeflateBottom = 163,
 
198
    msosptTextInflateTop = 164,
 
199
    msosptTextDeflateTop = 165,
 
200
    msosptTextDeflateInflate = 166,
 
201
    msosptTextDeflateInflateDeflate = 167,
 
202
    msosptTextFadeRight = 168,
 
203
    msosptTextFadeLeft = 169,
 
204
    msosptTextFadeUp = 170,
 
205
    msosptTextFadeDown = 171,
 
206
    msosptTextSlantUp = 172,
 
207
    msosptTextSlantDown = 173,
 
208
    msosptTextCanUp = 174,
 
209
    msosptTextCanDown = 175,
 
210
    msosptFlowChartAlternateProcess = 176,
 
211
    msosptFlowChartOffpageConnector = 177,
 
212
    msosptCallout90 = 178,
 
213
    msosptAccentCallout90 = 179,
 
214
    msosptBorderCallout90 = 180,
 
215
    msosptAccentBorderCallout90 = 181,
 
216
    msosptLeftRightUpArrow = 182,
 
217
    msosptSun = 183,
 
218
    msosptMoon = 184,
 
219
    msosptBracketPair = 185,
 
220
    msosptBracePair = 186,
 
221
    msosptSeal4 = 187,
 
222
    msosptDoubleWave = 188,
 
223
    msosptActionButtonBlank = 189,
 
224
    msosptActionButtonHome = 190,
 
225
    msosptActionButtonHelp = 191,
 
226
    msosptActionButtonInformation = 192,
 
227
    msosptActionButtonForwardNext = 193,
 
228
    msosptActionButtonBackPrevious = 194,
 
229
    msosptActionButtonEnd = 195,
 
230
    msosptActionButtonBeginning = 196,
 
231
    msosptActionButtonReturn = 197,
 
232
    msosptActionButtonDocument = 198,
 
233
    msosptActionButtonSound = 199,
 
234
    msosptActionButtonMovie = 200,
 
235
    msosptHostControl = 201,
 
236
    msosptTextBox = 202,
 
237
    msosptMax,
 
238
    msosptNil = 0x0FFF
 
239
};
 
240
 
 
241
void equation(Writer& out, const char* name, const char* formula)
 
242
{
 
243
    out.xml.startElement("draw:equation");
 
244
    out.xml.addAttribute("draw:name", name);
 
245
    out.xml.addAttribute("draw:formula", formula);
 
246
    out.xml.endElement();
 
247
}
 
248
}
 
249
 
 
250
/**
 
251
 * Return the bounding rectangle for this object.
 
252
 **/
 
253
QRect
 
254
ODrawToOdf::getRect(const OfficeArtSpContainer &o)
 
255
{
 
256
    if (o.childAnchor) {
 
257
        const OfficeArtChildAnchor& r = *o.childAnchor;
 
258
        return QRect(r.xLeft, r.yTop, r.xRight - r.xLeft, r.yBottom - r.yTop);
 
259
    } else if (o.clientAnchor && client) {
 
260
        return client->getRect(*o.clientAnchor);
 
261
    }
 
262
    return QRect(0, 0, 1, 1);
 
263
}
 
264
 
 
265
void ODrawToOdf::processEllipse(const OfficeArtSpContainer& o, Writer& out)
 
266
{
 
267
    out.xml.startElement("draw:ellipse");
 
268
    processStyleAndText(o, out);
 
269
    out.xml.endElement(); // draw:ellipse
 
270
}
 
271
 
 
272
void ODrawToOdf::processRectangle(const OfficeArtSpContainer& o, Writer& out)
 
273
{
 
274
    out.xml.startElement("draw:frame");
 
275
    processStyle(o, out);
 
276
    out.xml.startElement("draw:text-box");
 
277
    processText(o, out);
 
278
    out.xml.endElement(); // draw:text-box
 
279
    out.xml.endElement(); // draw:frame
 
280
}
 
281
 
 
282
void ODrawToOdf::processRoundRectangle(const OfficeArtSpContainer& o, Writer& out)
 
283
{
 
284
    out.xml.startElement("draw:custom-shape");
 
285
    processStyleAndText(o, out);
 
286
 
 
287
    out.xml.startElement("draw:enhanced-geometry");
 
288
    out.xml.addAttribute("draw:type", "round-rectangle");
 
289
    equation(out, "f0", "$0 /3");
 
290
    equation(out, "f1", "right-?f0");
 
291
    equation(out, "f2", "bottom-?f0");
 
292
    equation(out, "f3", "left+?f0");
 
293
    equation(out, "f4", "top+?f0");
 
294
    out.xml.endElement(); // draw:enhanced-geometry
 
295
    out.xml.endElement(); // draw:custom-shape
 
296
}
 
297
 
 
298
void ODrawToOdf::processDiamond(const OfficeArtSpContainer& o, Writer& out)
 
299
{
 
300
    out.xml.startElement("draw:custom-shape");
 
301
    processStyleAndText(o, out);
 
302
 
 
303
    out.xml.startElement("draw:enhanced-geometry");
 
304
    out.xml.addAttribute("draw:type", "diamond");
 
305
    out.xml.addAttribute("draw:glue-points", "5 0 0 5 5 10 10 5");
 
306
    out.xml.endElement();
 
307
    out.xml.endElement();
 
308
}
 
309
 
 
310
void ODrawToOdf::processTriangle(const OfficeArtSpContainer& o, Writer& out)
 
311
{
 
312
    /* draw IsocelesTriangle or RightTriangle */
 
313
    out.xml.startElement("draw:custom-shape");
 
314
    processStyleAndText(o, out);
 
315
 
 
316
    out.xml.startElement("draw:enhanced-geometry");
 
317
    out.xml.addAttribute("draw:glue-points", "5 0 2.5 5 0 10 5 10 10 10 7.5 5");
 
318
 
 
319
    if (o.shapeProp.fFlipV) {
 
320
        out.xml.addAttribute("draw:mirror-vertical", "true");
 
321
    }
 
322
    if (o.shapeProp.fFlipH) {
 
323
        out.xml.addAttribute("draw:mirror-horizontal", "true");
 
324
    }
 
325
    if (o.shapeProp.rh.recInstance == msosptRightTriangle) {
 
326
        out.xml.addAttribute("draw:type", "right-triangle");
 
327
    } else if (o.shapeProp.rh.recInstance == msosptIsoscelesTriangle) {
 
328
        out.xml.addAttribute("draw:type", "isosceles-triangle");
 
329
        equation(out, "f0", "$0");
 
330
        equation(out, "f1", "$0 /2");
 
331
        equation(out, "f2", "?f1 +10800");
 
332
        equation(out, "f3", "$0 *2/3");
 
333
        equation(out, "f4", "?f3 +7200");
 
334
        equation(out, "f5", "21600-?f0");
 
335
        equation(out, "f6", "?f5 /2");
 
336
        equation(out, "f7", "21600-?f6");
 
337
        out.xml.startElement("draw:handle");
 
338
        out.xml.addAttribute("draw:handle-range-x-maximum", 21600);
 
339
        out.xml.addAttribute("draw:handle-range-x-minimum", 0);
 
340
        out.xml.addAttribute("draw:handle-position", "$0 top");
 
341
        out.xml.endElement();
 
342
    }
 
343
 
 
344
    out.xml.endElement();    // enhanced-geometry
 
345
    out.xml.endElement(); // custom-shape
 
346
}
 
347
 
 
348
void ODrawToOdf::processTrapezoid(const OfficeArtSpContainer& o, Writer& out)
 
349
{
 
350
    out.xml.startElement("draw:custom-shape");
 
351
    processStyleAndText(o, out);
 
352
 
 
353
    out.xml.startElement("draw:enhanced-geometry");
 
354
    out.xml.addAttribute("draw:type", "trapezoid");
 
355
    out.xml.addAttribute("draw:glue-points", "5 0 2.5 5 0 10 5 10");
 
356
    if (o.shapeProp.fFlipV) {
 
357
        out.xml.addAttribute("draw:mirror-vertical", "true");
 
358
    }
 
359
    if (o.shapeProp.fFlipH) {
 
360
        out.xml.addAttribute("draw:mirror-horizontal", "true");
 
361
    }
 
362
    equation(out, "f0", "21600-$0");
 
363
    equation(out, "f1", "$0");
 
364
    equation(out, "f2", "$0 *10/18");
 
365
    equation(out, "f3", "?f2 +1750");
 
366
    equation(out, "f4", "21600-?f3");
 
367
    equation(out, "f5", "$0 /2");
 
368
    equation(out, "f6", "21600-?f5");
 
369
    out.xml.startElement("draw:handle");
 
370
    out.xml.addAttribute("draw:handle-range-x-maximum", 10800);
 
371
    out.xml.addAttribute("draw:handle-range-x-minimum", 0);
 
372
    out.xml.addAttribute("draw:handle-position", "$0 bottom");
 
373
    out.xml.endElement();
 
374
    out.xml.endElement(); // enhanced-geometry
 
375
    out.xml.endElement(); // custom-shape
 
376
}
 
377
 
 
378
void ODrawToOdf::processParallelogram(const OfficeArtSpContainer& o, Writer& out)
 
379
{
 
380
    out.xml.startElement("draw:custom-shape");
 
381
    processStyleAndText(o, out);
 
382
 
 
383
    out.xml.startElement("draw:enhanced-geometry");
 
384
    out.xml.addAttribute("draw:type", "parallelogram");
 
385
    out.xml.addAttribute("draw:glue-points", "6.25 0 4.5 0 8.75 5 3.75 10 5 10 1.25 5");
 
386
    if (o.shapeProp.fFlipV) {
 
387
        out.xml.addAttribute("draw:mirror-vertical", "true");
 
388
    }
 
389
    if (o.shapeProp.fFlipH) {
 
390
        out.xml.addAttribute("draw:mirror-horizontal", "true");
 
391
    }
 
392
    equation(out, "f0", "$0");
 
393
    equation(out, "f1", "21600-$0");
 
394
    equation(out, "f2", "$0 *10/24");
 
395
    equation(out, "f3", "?f2 +1750");
 
396
    equation(out, "f4", "21600-?f3");
 
397
    equation(out, "f5", "?f0 /2");
 
398
    equation(out, "f6", "10800+?f5");
 
399
    equation(out, "f7", "?f0-10800");
 
400
    equation(out, "f8", "if(?f7,?f12,0");
 
401
    equation(out, "f9", "10800-?f5");
 
402
    equation(out, "f10", "if(?f7, ?f12, 21600");
 
403
    equation(out, "f11", "21600-?f5");
 
404
    equation(out, "f12", "21600*10800/?f0");
 
405
    equation(out, "f13", "21600-?f12");
 
406
    out.xml.startElement("draw:handle");
 
407
    out.xml.addAttribute("draw:handle-range-x-maximum", 21600);
 
408
    out.xml.addAttribute("draw:handle-range-x-minimum", 0);
 
409
    out.xml.addAttribute("draw:handle-position", "$0 top");
 
410
    out.xml.endElement();
 
411
    out.xml.endElement(); // enhanced-geometry
 
412
    out.xml.endElement(); // custom-shape
 
413
}
 
414
 
 
415
void ODrawToOdf::processHexagon(const OfficeArtSpContainer& o, Writer& out)
 
416
{
 
417
    out.xml.startElement("draw:custom-shape");
 
418
    processStyleAndText(o, out);
 
419
 
 
420
    out.xml.startElement("draw:enhanced-geometry");
 
421
    out.xml.addAttribute("draw:type", "hexagon");
 
422
    out.xml.addAttribute("draw:glue-points", "5 0 0 5 5 10 10 5");
 
423
    equation(out, "f0", "$0");
 
424
    equation(out, "f1", "21600-$0");
 
425
    equation(out, "f2", "$0 *100/234");
 
426
    equation(out, "f3", "?f2 +1700");
 
427
    equation(out, "f4", "21600-?f3");
 
428
    out.xml.startElement("draw:handle");
 
429
    out.xml.addAttribute("draw:handle-range-x-maximum", 10800);
 
430
    out.xml.addAttribute("draw:handle-range-x-minimum", 0);
 
431
    out.xml.addAttribute("draw:handle-position", "$0 top");
 
432
    out.xml.endElement();
 
433
    out.xml.endElement(); // enhanced-geometry
 
434
    out.xml.endElement(); // custom-shape
 
435
}
 
436
 
 
437
void ODrawToOdf::processOctagon(const OfficeArtSpContainer& o, Writer& out)
 
438
{
 
439
    out.xml.startElement("draw:custom-shape");
 
440
    processStyleAndText(o, out);
 
441
 
 
442
    out.xml.startElement("draw:enhanced-geometry");
 
443
    out.xml.addAttribute("draw:type", "octagon");
 
444
    out.xml.addAttribute("draw:glue-points", "5 0 0 4.782 5 10 10 4.782");
 
445
    equation(out, "f0", "left+$0");
 
446
    equation(out, "f1", "top+$0");
 
447
    equation(out, "f2", "right-$0");
 
448
    equation(out, "f3", "bottom-$0");
 
449
    equation(out, "f4", "$0 /2");
 
450
    equation(out, "f5", "left+?f4");
 
451
    equation(out, "f6", "top+?f4");
 
452
    equation(out, "f7", "right-?f4");
 
453
    equation(out, "f8", "bottom-?f4");
 
454
    out.xml.startElement("draw:handle");
 
455
    out.xml.addAttribute("draw:handle-range-x-maximum", 10800);
 
456
    out.xml.addAttribute("draw:handle-range-x-minimum", 0);
 
457
    out.xml.addAttribute("draw:handle-position", "$0 top");
 
458
    out.xml.endElement();
 
459
    out.xml.endElement(); // enhanced-geometry
 
460
    out.xml.endElement(); // custom-shape
 
461
}
 
462
 
 
463
void ODrawToOdf::processArrow(const OfficeArtSpContainer& o, Writer& out)
 
464
{
 
465
    out.xml.startElement("draw:custom-shape");
 
466
    processStyleAndText(o, out);
 
467
 
 
468
    out.xml.startElement("draw:enhanced-geometry");
 
469
 
 
470
    if (o.shapeProp.rh.recInstance == msosptLeftArrow) {
 
471
        if (o.shapeProp.fFlipH)
 
472
            out.xml.addAttribute("draw:type", "right-arrow");
 
473
        else
 
474
            out.xml.addAttribute("draw:type", "left-arrow");
 
475
    } else if (o.shapeProp.rh.recInstance == msosptUpArrow) {
 
476
        out.xml.addAttribute("draw:type", "up-arrow");
 
477
    } else if (o.shapeProp.rh.recInstance == msosptDownArrow) {
 
478
        out.xml.addAttribute("draw:type", "down-arrow");
 
479
    }
 
480
    equation(out, "f0", "$1");
 
481
    equation(out, "f1", "$0");
 
482
    equation(out, "f2", "21600-$1");
 
483
    equation(out, "f3", "21600-?f1");
 
484
    equation(out, "f4", "?f3 *?f0 /10800");
 
485
    equation(out, "f5", "?f1 +?f4");
 
486
    equation(out, "f6", "?f1 *?f0 /10800");
 
487
    equation(out, "f7", "?f1 -?f6");
 
488
    out.xml.startElement("draw:handle");
 
489
    if (o.shapeProp.rh.recInstance == msosptLeftRightArrow || o.shapeProp.rh.recInstance == msosptLeftArrow) {
 
490
        out.xml.addAttribute("draw:handle-range-x-maximum", 21600);
 
491
        out.xml.addAttribute("draw:handle-range-x-minimum", 0);
 
492
        out.xml.addAttribute("draw:handle-position", "$0 $1");
 
493
        out.xml.addAttribute("draw:handle-range-y-maximum", 10800);
 
494
        out.xml.addAttribute("draw:handle-range-y-minimum", 0);
 
495
    } else if (o.shapeProp.rh.recInstance == msosptUpArrow || o.shapeProp.rh.recInstance == msosptDownArrow) {
 
496
        out.xml.addAttribute("draw:handle-range-x-maximum", 10800);
 
497
        out.xml.addAttribute("draw:handle-range-x-minimum", 0);
 
498
        out.xml.addAttribute("draw:handle-position", "$1 $0");
 
499
        out.xml.addAttribute("draw:handle-range-y-maximum", 21600);
 
500
        out.xml.addAttribute("draw:handle-range-y-minimum", 0);
 
501
    }
 
502
    out.xml.endElement(); // draw:handle
 
503
    out.xml.endElement(); // draw:enhanced-geometry
 
504
    out.xml.endElement(); // draw:custom-shape
 
505
}
 
506
 
 
507
void ODrawToOdf::processLine(const OfficeArtSpContainer& o, Writer& out)
 
508
{
 
509
    const QRect rect = getRect(o);
 
510
    qreal x1 = rect.x();
 
511
    qreal y1 = rect.y();
 
512
    qreal x2 = rect.x() + rect.width();
 
513
    qreal y2 = rect.y() + rect.height();
 
514
 
 
515
    if (o.shapeProp.fFlipV) {
 
516
        qSwap(y1, y2);
 
517
    }
 
518
    if (o.shapeProp.fFlipH) {
 
519
        qSwap(x1, x2);
 
520
    }
 
521
 
 
522
    out.xml.startElement("draw:line");
 
523
    out.xml.addAttribute("svg:y1", out.vOffset(y1));
 
524
    out.xml.addAttribute("svg:y2", out.vOffset(y2));
 
525
    out.xml.addAttribute("svg:x1", out.hOffset(x1));
 
526
    out.xml.addAttribute("svg:x2", out.hOffset(x2));
 
527
    addGraphicStyleToDrawElement(out, o);
 
528
    out.xml.addAttribute("draw:layer", "layout");
 
529
    processText(o, out);
 
530
 
 
531
    out.xml.endElement();
 
532
}
 
533
 
 
534
void ODrawToOdf::processSmiley(const OfficeArtSpContainer& o, Writer& out)
 
535
{
 
536
    out.xml.startElement("draw:custom-shape");
 
537
    processStyleAndText(o, out);
 
538
 
 
539
    out.xml.startElement("draw:enhanced-geometry");
 
540
    out.xml.addAttribute("draw:type", "smiley");
 
541
    out.xml.addAttribute("draw:glue-points", "5 0 1.461 1.461 0 5 1.461 8.536 10 5 8.536 1.461");
 
542
    equation(out, "f0", "$0-15510");
 
543
    equation(out, "f1", "17520-?f0");
 
544
    equation(out, "f2", "15510+?f0");
 
545
    out.xml.startElement("draw:handle");
 
546
    out.xml.addAttribute("draw:position", 10800);
 
547
    out.xml.addAttribute("draw:handle-range-y-maximum", 17520);
 
548
    out.xml.addAttribute("draw:handle-range-y-minimum", 15510);
 
549
    out.xml.addAttribute("draw:handle-position", "$0 top");
 
550
    out.xml.endElement();
 
551
    out.xml.endElement(); // enhanced-geometry
 
552
    out.xml.endElement(); // custom-shape
 
553
}
 
554
 
 
555
void ODrawToOdf::processHeart(const OfficeArtSpContainer& o, Writer& out)
 
556
{
 
557
    out.xml.startElement("draw:custom-shape");
 
558
    processStyleAndText(o, out);
 
559
 
 
560
    out.xml.startElement("draw:enhanced-geometry");
 
561
    out.xml.addAttribute("draw:type", "heart");
 
562
    out.xml.addAttribute("draw:glue-points", "5 1 1.43 5 5 10 8.553 5");
 
563
 
 
564
    out.xml.endElement(); // enhanced-geometry
 
565
    out.xml.endElement(); // custom-shape
 
566
}
 
567
 
 
568
void ODrawToOdf::processWedgeRectCallout(const MSO::OfficeArtSpContainer& o, Writer& out)
 
569
{
 
570
    out.xml.startElement("draw:custom-shape");
 
571
    processStyleAndText(o, out);
 
572
 
 
573
    out.xml.startElement("draw:enhanced-geometry");
 
574
    out.xml.addAttribute("draw:type", "rectangular-callout");
 
575
    out.xml.addAttribute("svg:viewBox", "0 0 21600 21600");
 
576
    out.xml.addAttribute("draw:glue-points", "10800 0 0 10800 10800 21600 21600 10800 ?f40 ?f41");
 
577
    out.xml.addAttribute("draw:text-areas", "0 0 21600 21600");
 
578
    out.xml.addAttribute("draw:modifiers", "514 25920");
 
579
    out.xml.addAttribute("draw:enhanced-path", "M 0 0 L 0 3590 ?f2 ?f3 0 8970 0 12630 ?f4 ?f5 0 18010 0 21600 3590 21600 ?f6 ?f7 8970 21600 12630 21600 ?f8 ?f9 18010 21600 21600 21600 21600 18010 ?f10 ?f11 21600 12630 21600 8970 ?f12 ?f13 21600 3590 21600 0 18010 0 ?f14 ?f15 12630 0 8970 0 ?f16 ?f17 3590 0 0 0 Z N");
 
580
    equation(out, "f0", "$0 -10800");
 
581
    equation(out, "f1", "$1 -10800");
 
582
    equation(out, "f2", "if(?f18 ,$0 ,0)");
 
583
    equation(out, "f3", "if(?f18 ,$1 ,6280)");
 
584
    equation(out, "f4", "if(?f23 ,$0 ,0)");
 
585
    equation(out, "f5", "if(?f23 ,$1 ,15320)");
 
586
    equation(out, "f6", "if(?f26 ,$0 ,6280)");
 
587
    equation(out, "f7", "if(?f26 ,$1 ,21600)");
 
588
    equation(out, "f8", "if(?f29 ,$0 ,15320)");
 
589
    equation(out, "f9", "if(?f29 ,$1 ,21600)");
 
590
    equation(out, "f10", "if(?f32 ,$0 ,21600)");
 
591
    equation(out, "f11", "if(?f32 ,$1 ,15320)");
 
592
    equation(out, "f12", "if(?f34 ,$0 ,21600)");
 
593
    equation(out, "f13", "if(?f34 ,$1 ,6280)");
 
594
    equation(out, "f14", "if(?f36 ,$0 ,15320)");
 
595
    equation(out, "f15", "if(?f36 ,$1 ,0)");
 
596
    equation(out, "f16", "if(?f38 ,$0 ,6280)");
 
597
    equation(out, "f17", "if(?f38 ,$1 ,0)");
 
598
    equation(out, "f18", "if($0 ,-1,?f19 )");
 
599
    equation(out, "f19", "if(?f1 ,-1,?f22 )");
 
600
    equation(out, "f20", "abs(?f0 )");
 
601
    equation(out, "f21", "abs(?f1 )");
 
602
    equation(out, "f22", "?f20 -?f21");
 
603
    equation(out, "f23", "if($0 ,-1,?f24 )");
 
604
    equation(out, "f24", "if(?f1 ,?f22 ,-1)");
 
605
    equation(out, "f25", "$1 -21600");
 
606
    equation(out, "f26", "if(?f25 ,?f27 ,-1)");
 
607
    equation(out, "f27", "if(?f0 ,-1,?f28 )");
 
608
    equation(out, "f28", "?f21 -?f20 ");
 
609
    equation(out, "f29", "if(?f25 ,?f30 ,-1)");
 
610
    equation(out, "f30", "if(?f0 ,?f28 ,-1)");
 
611
    equation(out, "f31", "$0 -21600");
 
612
    equation(out, "f32", "if(?f31 ,?f33 ,-1)");
 
613
    equation(out, "f33", "if(?f1 ,?f22 ,-1)");
 
614
    equation(out, "f34", "if(?f31 ,?f35 ,-1)");
 
615
    equation(out, "f35", "if(?f1 ,-1,?f22 )");
 
616
    equation(out, "f36", "if($1 ,-1,?f37 )");
 
617
    equation(out, "f37", "if(?f0 ,?f28 ,-1)");
 
618
    equation(out, "f38", "if($1 ,-1,?f39 )");
 
619
    equation(out, "f39", "if(?f0 ,-1,?f28 )");
 
620
    equation(out, "f40", "$0");
 
621
    equation(out, "f41", "$1");
 
622
    out.xml.startElement("draw:handle");
 
623
    out.xml.addAttribute("draw:handle-position", "$0 $1");
 
624
    out.xml.endElement();
 
625
    out.xml.endElement();
 
626
    out.xml.endElement(); // custom-shape
 
627
}
 
628
 
 
629
void ODrawToOdf::processWedgeEllipseCallout(const MSO::OfficeArtSpContainer& o, Writer& out)
 
630
{
 
631
    out.xml.startElement("draw:custom-shape");
 
632
    processStyleAndText(o, out);
 
633
 
 
634
    out.xml.startElement("draw:enhanced-geometry");
 
635
    out.xml.addAttribute("draw:type", "round-callout");
 
636
    out.xml.addAttribute("svg:viewBox", "0 0 21600 21600");
 
637
    out.xml.addAttribute("draw:glue-points", "10800 0 3160 3160 0 10800 3160 18440 10800 21600 18440 18440 21600 10800 18440 3160 ?f14 ?f15");
 
638
    out.xml.addAttribute("draw:text-areas", "3200 3200 18400 18400");
 
639
    out.xml.addAttribute("draw:modifiers", "0 11500");
 
640
    out.xml.addAttribute("draw:enhanced-path", "W 0 0 21600 21600 ?f22 ?f23 ?f18 ?f19 L ?f14 ?f15 Z N");
 
641
    equation(out, "f0", "$0 -10800");
 
642
    equation(out, "f1", "$1 -10800");
 
643
    equation(out, "f2", "?f0 *?f0");
 
644
    equation(out, "f3", "?f1 *?f1");
 
645
    equation(out, "f4", "?f2 +?f3");
 
646
    equation(out, "f5", "sqrt(?f4 )");
 
647
    equation(out, "f6", "?f5 -10800");
 
648
    equation(out, "f7", "atan2(?f1 ,?f0 )/(pi/180)");
 
649
    equation(out, "f8", "?f7 -10");
 
650
    equation(out, "f9", "?f7 +10");
 
651
    equation(out, "f10", "10800*cos(?f7 *(pi/180))");
 
652
    equation(out, "f11", "10800*sin(?f7 *(pi/180))");
 
653
    equation(out, "f12", "?f10 +10800");
 
654
    equation(out, "f13", "?f11 +10800");
 
655
    equation(out, "f14", "if(?f6 ,$0 ,?f12 )");
 
656
    equation(out, "f15", "if(?f6 ,$1 ,?f13 )");
 
657
    equation(out, "f16", "10800*cos(?f8 *(pi/180))");
 
658
    equation(out, "f17", "10800*sin(?f8 *(pi/180))");
 
659
    equation(out, "f18", "?f16 +10800");
 
660
    equation(out, "f19", "?f17 +10800");
 
661
    equation(out, "f20", "10800*cos(?f9 *(pi/180))");
 
662
    equation(out, "f21", "10800*sin(?f9 *(pi/180))");
 
663
    equation(out, "f22", "?f20 +10800");
 
664
    equation(out, "f23", "?f21 +10800");
 
665
    out.xml.startElement("draw:handle");
 
666
    out.xml.addAttribute("draw:handle-position", "$0 $1");
 
667
    out.xml.endElement();
 
668
    out.xml.endElement();
 
669
    out.xml.endElement(); // custom-shape
 
670
}
 
671
 
 
672
void ODrawToOdf::processQuadArrow(const OfficeArtSpContainer& o, Writer& out)
 
673
{
 
674
    out.xml.startElement("draw:custom-shape");
 
675
    processStyleAndText(o, out);
 
676
 
 
677
    out.xml.startElement("draw:enhanced-geometry");
 
678
    out.xml.addAttribute("svg:viewBox", "0 0 21600 21600");
 
679
    out.xml.addAttribute("draw:text-areas", "0 0 21600 21600");
 
680
    out.xml.addAttribute("draw:type", "quad-arrow");
 
681
    out.xml.addAttribute("draw:modifiers", "6500 8600 4300");
 
682
    out.xml.addAttribute("draw:enhanced-path", "M 0 10800 L ?f0 ?f1 ?f0 ?f2 ?f2 ?f2 ?f2 ?f0 ?f1 ?f0 10800 0 ?f3 ?f0 ?f4 ?f0 ?f4 ?f2 ?f5 ?f2 ?f5 ?f1 21600 10800 ?f5 ?f3 ?f5 ?f4 ?f4 ?f4 ?f4 ?f5 ?f3 ?f5 10800 21600 ?f1 ?f5 ?f2 ?f5 ?f2 ?f4 ?f0 ?f4 ?f0 ?f3 Z N");
 
683
    out.xml.startElement("draw:equation");
 
684
    out.xml.addAttribute("draw:name", "f0");
 
685
    out.xml.addAttribute("draw:formula", "$2");
 
686
    out.xml.endElement();
 
687
    out.xml.startElement("draw:equation");
 
688
    out.xml.addAttribute("draw:name", "f1");
 
689
    out.xml.addAttribute("draw:formula", "$0");
 
690
    out.xml.endElement();
 
691
    out.xml.startElement("draw:equation");
 
692
    out.xml.addAttribute("draw:name", "f2");
 
693
    out.xml.addAttribute("draw:formula", "$1");
 
694
    out.xml.endElement();
 
695
    out.xml.startElement("draw:equation");
 
696
    out.xml.addAttribute("draw:name", "f3");
 
697
    out.xml.addAttribute("draw:formula", "21600-$0");
 
698
    out.xml.endElement();
 
699
    out.xml.startElement("draw:equation");
 
700
    out.xml.addAttribute("draw:name", "f4");
 
701
    out.xml.addAttribute("draw:formula", "21600-$1");
 
702
    out.xml.endElement();
 
703
    out.xml.startElement("draw:equation");
 
704
    out.xml.addAttribute("draw:name", "f5");
 
705
    out.xml.addAttribute("draw:formula", "21600-$2");
 
706
    out.xml.endElement();
 
707
    out.xml.startElement("draw:handle");
 
708
    out.xml.addAttribute("draw:handle-position", "$1 $2");
 
709
    out.xml.addAttribute("draw:handle-range-x-minimum", "$0");
 
710
    out.xml.addAttribute("draw:handle-range-x-maximum", "10800");
 
711
    out.xml.addAttribute("draw:handle-range-y-minimum", "0");
 
712
    out.xml.addAttribute("draw:handle-range-y-maximum", "$0");
 
713
    out.xml.endElement();
 
714
    out.xml.startElement("draw:handle");
 
715
    out.xml.addAttribute("draw:handle-position", "$0 top");
 
716
    out.xml.addAttribute("draw:handle-range-x-minimum", "$2");
 
717
    out.xml.addAttribute("draw:handle-range-x-maximum", "$1");
 
718
    out.xml.endElement();
 
719
    out.xml.endElement();
 
720
    out.xml.endElement(); // draw:custom-shape
 
721
}
 
722
 
 
723
void ODrawToOdf::processUturnArrow(const MSO::OfficeArtSpContainer& o, Writer& out)
 
724
{
 
725
    out.xml.startElement("draw:custom-shape");
 
726
    processStyleAndText(o, out);
 
727
 
 
728
    out.xml.startElement("draw:enhanced-geometry");
 
729
    out.xml.addAttribute("svg:viewBox", "0 0 21600 21600");
 
730
    out.xml.addAttribute("draw:text-areas", "0 8280 6110 21600");
 
731
    out.xml.addAttribute("draw:type", "mso-spt101");
 
732
    out.xml.addAttribute("draw:enhanced-path", "M 0 21600 L 0 8550 C 0 3540 4370 0 9270 0 13890 0 18570 3230 18600 8300 L 21600 8300 15680 14260 9700 8300 12500 8300 C 12320 6380 10870 5850 9320 5850 7770 5850 6040 6410 6110 8520 L 6110 21600 Z N");
 
733
    out.xml.endElement();
 
734
    out.xml.endElement(); // draw:custom-shape
 
735
}
 
736
 
 
737
void ODrawToOdf::processFreeLine(const OfficeArtSpContainer& o, Writer& out)
 
738
{
 
739
    out.xml.startElement("draw:path");
 
740
    processStyleAndText(o, out);
 
741
    out.xml.endElement(); // path
 
742
}
 
743
 
 
744
void ODrawToOdf::processPictureFrame(const OfficeArtSpContainer& o, Writer& out)
 
745
{
 
746
    QString url;
 
747
    const Pib* pib = get<Pib>(o);
 
748
    if (pib && client) {
 
749
        url = client->getPicturePath(pib->pib);
 
750
    }
 
751
    out.xml.startElement("draw:frame");
 
752
    processStyleAndText(o, out);
 
753
    if (url.isEmpty()) {
 
754
        // if the image cannot be found, just place an empty frame
 
755
        out.xml.endElement(); // frame
 
756
        return;
 
757
    }
 
758
    out.xml.startElement("draw:image");
 
759
    out.xml.addAttribute("xlink:href", url);
 
760
    out.xml.addAttribute("xlink:type", "simple");
 
761
    out.xml.addAttribute("xlink:show", "embed");
 
762
    out.xml.addAttribute("xlink:actuate", "onLoad");
 
763
    out.xml.endElement(); // image
 
764
    out.xml.endElement(); // frame
 
765
}
 
766
void ODrawToOdf::processDrawingObject(const OfficeArtSpContainer& o, Writer& out)
 
767
{
 
768
    quint16 shapeType = o.shapeProp.rh.recInstance;
 
769
    if (shapeType == msosptEllipse) {
 
770
        processEllipse(o, out);
 
771
    } else if (shapeType == msosptRectangle
 
772
               || shapeType == msosptTextBox) {
 
773
        processRectangle(o, out);
 
774
    } else if (shapeType == msosptRoundRectangle) {
 
775
        processRoundRectangle(o, out);
 
776
    } else  if (shapeType == msosptDiamond) {
 
777
        processDiamond(o, out);
 
778
    } else  if (shapeType == msosptIsoscelesTriangle ||
 
779
                shapeType == msosptRightTriangle) {
 
780
        processTriangle(o, out);
 
781
    } else if (shapeType == msosptTrapezoid) {
 
782
        processTrapezoid(o, out);
 
783
    } else if (shapeType == msosptParallelogram) {
 
784
        processParallelogram(o, out);
 
785
    } else if (shapeType == msosptHexagon) {
 
786
        processHexagon(o, out);
 
787
    } else if (shapeType == msosptOctagon) {
 
788
        processOctagon(o, out);
 
789
    } else if (shapeType == msosptLeftArrow ||
 
790
               shapeType == msosptUpArrow ||
 
791
               shapeType == msosptDownArrow) {
 
792
        processArrow(o, out);
 
793
    } else if (shapeType == msosptLine) {
 
794
        processLine(o, out);
 
795
    } else if (shapeType == msosptWedgeRectCallout) {
 
796
        processWedgeRectCallout(o, out);
 
797
    } else if (shapeType == msosptWedgeEllipseCallout) {
 
798
        processWedgeEllipseCallout(o, out);
 
799
    } else if (shapeType == msosptSmileyFace) {
 
800
        processSmiley(o, out);
 
801
    } else if (shapeType == msosptHeart) {
 
802
        processHeart(o, out);
 
803
    } else if (shapeType == msosptQuadArrow) {
 
804
        processQuadArrow(o, out);
 
805
    } else if (shapeType == msosptUturnArrow) {
 
806
        processUturnArrow(o, out);
 
807
        //} else if (shapeType == msosptMin) {
 
808
        //    processFreeLine(o, out);
 
809
    } else if (shapeType == msosptPictureFrame
 
810
               || shapeType == msosptHostControl) {
 
811
        processPictureFrame(o, out);
 
812
    } else {
 
813
        qDebug() << "cannot handle object of type " << shapeType;
 
814
    }
 
815
}
 
816
void ODrawToOdf::processStyleAndText(const MSO::OfficeArtSpContainer& o,
 
817
                                     Writer& out)
 
818
{
 
819
    processStyle(o, out);
 
820
    processText(o, out);
 
821
}
 
822
void ODrawToOdf::processStyle(const MSO::OfficeArtSpContainer& o,
 
823
                                     Writer& out)
 
824
{
 
825
    const QRect rect = getRect(o);
 
826
    addGraphicStyleToDrawElement(out, o);
 
827
    out.xml.addAttribute("draw:layer", "layout");
 
828
    set2dGeometry(o, out);
 
829
}
 
830
void ODrawToOdf::processText(const MSO::OfficeArtSpContainer& o,
 
831
                                         Writer& out)
 
832
{
 
833
    if (o.clientData && client && client->onlyClientData(*o.clientData)) {
 
834
        client->processClientData(*o.clientData, out);
 
835
    } else if (o.clientTextbox) {
 
836
        client->processClientTextBox(*o.clientTextbox,
 
837
                                 o.clientData.data(), out);
 
838
    }
 
839
}
 
840
 
 
841
void ODrawToOdf::set2dGeometry(const OfficeArtSpContainer& o, Writer& out)
 
842
{
 
843
    const QRect rect = getRect(o);
 
844
 
 
845
    out.xml.addAttribute("svg:width", out.hLength(rect.width()));
 
846
    out.xml.addAttribute("svg:height", out.vLength(rect.height()));
 
847
 
 
848
    const Rotation* rotation = get<Rotation>(o);
 
849
    if (rotation) {
 
850
        //FIXME: I get wrong angle values, aren't they in radians?
 
851
        //FIXME: check weather how the degrees are measured (might need a to multiply by -1)
 
852
        qreal rotationAngle = toQReal(rotation->rotation);
 
853
 
 
854
        QMatrix matrix(cos(rotationAngle), -sin(rotationAngle), sin(rotationAngle), cos(rotationAngle), 0, 0);
 
855
 
 
856
        QPointF figureCenter(rect.width()/2.0, rect.height()/2.0);
 
857
 
 
858
        QPointF origenInDocument( rect.x(), rect.y() );
 
859
 
 
860
        qreal rotX = 0.0;
 
861
        qreal rotY = 0.0;
 
862
 
 
863
        matrix.map( figureCenter.x(), figureCenter.y(), &rotX, &rotY);
 
864
 
 
865
        QPointF rotatedCenterPoint( rotX, rotY );
 
866
 
 
867
        QPointF translatedPoint( figureCenter - rotatedCenterPoint + origenInDocument );
 
868
 
 
869
        static const QString transformString("rotate(%1) translate(%2 %3)");
 
870
 
 
871
        out.xml.addAttribute("draw:transform", transformString.arg(rotationAngle).arg( out.hOffset(translatedPoint.x())).arg(out.vOffset(translatedPoint.y())));
 
872
    }
 
873
    else {
 
874
        out.xml.addAttribute("svg:x", out.hOffset(rect.x()));
 
875
        out.xml.addAttribute("svg:y", out.vOffset(rect.y()));
 
876
    }
 
877
}
 
878
void defineArrow(KoGenStyles& styles)
 
879
{
 
880
    KoGenStyle marker(KoGenStyle::MarkerStyle);
 
881
    marker.addAttribute("draw:display-name", "msArrowEnd 5");
 
882
    marker.addAttribute("svg:viewBox", "0 0 210 210");
 
883
    marker.addAttribute("svg:d", "m105 0 105 210h-210z");
 
884
    styles.insert(marker, "msArrowEnd_20_5", KoGenStyles::DontAddNumberToName);
 
885
    // TODO: define proper styles for these arrows
 
886
    KoGenStyles::InsertionFlags flags = KoGenStyles::DontAddNumberToName | KoGenStyles::AllowDuplicates;
 
887
    styles.insert(marker, "msArrowStealthEnd_20_5", flags);
 
888
    styles.insert(marker, "msArrowDiamondEnd_20_5", flags);
 
889
    styles.insert(marker, "msArrowOvalEnd_20_5", flags);
 
890
    styles.insert(marker, "msArrowOpenEnd_20_5", flags);
 
891
}