1 /*
2 * This file is part of Office 2007 Filters for Calligra
3 *
4 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
5 * Contact: Suresh Chande suresh.chande@nokia.com
6 *
7 * Copyright (C) 2012 Matus Uzak (matus.uzak@gmail.com).
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * version 2.1 as published by the Free Software Foundation.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25 #ifndef MSOOXML_DRAWINGML_SHARED_IMPL_H
26 #define MSOOXML_DRAWINGML_SHARED_IMPL_H
27
28 #undef CURRENT_EL
29 #define CURRENT_EL extLst
30 //! extLst (Extension List)
31 //! DrawingML ECMA-376 20.1.2.2.15, p.3034
32 /*!
33 This element specifies the extension list within which all future
34 extensions of element type ext is defined. The extension list along
35 with corresponding future extensions is used to extend the storage
36 capabilities of the DrawingML framework. This allows for various new
37 types of data to be stored natively within the framework.
38 */
read_extLst()39 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_extLst()
40 {
41 READ_PROLOGUE
42 // NO support atm, skipping
43 skipCurrentElement();
44
45 READ_EPILOGUE
46 }
47
48 #undef CURRENT_EL
49 #define CURRENT_EL lnL
read_Table_lnL()50 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_Table_lnL()
51 {
52 READ_PROLOGUE2(Table_lnL)
53
54 return read_Table_generic("lnL");
55
56 READ_EPILOGUE
57 }
58
59 #undef CURRENT_EL
60 #define CURRENT_EL lnR
read_Table_lnR()61 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_Table_lnR()
62 {
63 READ_PROLOGUE2(Table_lnR)
64
65 return read_Table_generic("lnR");
66
67 READ_EPILOGUE
68 }
69
70 #undef CURRENT_EL
71 #define CURRENT_EL lnT
read_Table_lnT()72 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_Table_lnT()
73 {
74 READ_PROLOGUE2(Table_lnT)
75
76 return read_Table_generic("lnT");
77
78 READ_EPILOGUE
79 }
80
81 #undef CURRENT_EL
82 #define CURRENT_EL lnB
read_Table_lnB()83 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_Table_lnB()
84 {
85 READ_PROLOGUE2(Table_lnB)
86
87 return read_Table_generic("lnB");
88
89 READ_EPILOGUE
90 }
91
92 #undef CURRENT_EL
93 #define CURRENT_EL ln
read_Table_ln()94 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_Table_ln()
95 {
96 READ_PROLOGUE2(Table_ln)
97
98 return read_Table_generic("ln");
99
100 READ_EPILOGUE
101 }
102
read_Table_generic(const QString & endElement)103 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_Table_generic(const QString& endElement)
104 {
105 QXmlStreamAttributes attrs = attributes();
106
107 m_currentBorder = KoBorder::BorderData();
108
109 //compound line type
110 TRY_READ_ATTR_WITHOUT_NS(cmpd)
111 //double lines
112 if( cmpd.isEmpty() || cmpd == "sng" ) {
113 m_currentBorder.style = KoBorder::BorderSolid;
114 }
115 //single line
116 else if (cmpd == "dbl") {
117 m_currentBorder.style = KoBorder::BorderDouble;
118 }
119 //thick thin double lines
120 else if (cmpd == "thickThin") {
121 //FIXME it seem we don't support this properly. Use solid for now.
122 m_currentBorder.style = KoBorder::BorderDouble;
123 }
124 //thin thick double lines
125 else if (cmpd == "thinThick") {
126 //FIXME it doesn't seem we support this properly.
127 m_currentBorder.style = KoBorder::BorderDouble;
128 }
129 //thin thick thin triple lines
130 else if (cmpd == "tri") {
131 //NOTE: There is not triple in ODF
132 m_currentBorder.style = KoBorder::BorderSolid;
133 }
134
135 TRY_READ_ATTR_WITHOUT_NS(w) //width
136 m_currentBorder.outerPen.setWidthF(EMU_TO_POINT(w.toDouble()));
137
138 while (!atEnd()) {
139 readNext();
140 if (isEndElement() && name() == endElement) {
141 break;
142 }
143 if(isStartElement()) {
144 if(QUALIFIED_NAME_IS(solidFill)) {
145 TRY_READ(solidFill);
146 m_currentBorder.style = KoBorder::BorderSolid;
147 m_currentBorder.innerPen.setColor(m_currentColor);
148 m_currentBorder.outerPen.setColor(m_currentColor);
149 }
150 else if (QUALIFIED_NAME_IS(prstDash)) {
151 attrs = attributes();
152 //TODO find out how other colors are handled
153 m_currentBorder.innerPen.setColor(Qt::black);
154 m_currentBorder.outerPen.setColor(Qt::black);
155 TRY_READ_ATTR_WITHOUT_NS(val)
156 //TODO support other dash types. Make it its own function.
157 if (val == "dash") {
158 m_currentBorder.style = KoBorder::BorderDashed;
159 }
160 else if(val == "dashDot") {
161 m_currentBorder.style = KoBorder::BorderDashDot;
162 }
163 else if(val == "dot") {
164 m_currentBorder.style = KoBorder::BorderDotted;
165 }
166 }
167 SKIP_UNKNOWN
168 // ELSE_WRONG_FORMAT
169 }
170 }
171 return KoFilter::OK;
172 }
173
174 #undef CURRENT_EL
175 #define CURRENT_EL ln
176 //! ln (Outline)
177 //! DrawingML ECMA-376, 20.1.2.2.24, p. 3048.
178 /*!
179 This element specifies an outline style that can be applied to a
180 number of different objects such as shapes and text. The line allows
181 for the specifying of many different types of outlines including
182 even line dashes and bevels.
183
184 Parent Elements:
185
186 Child Elements:
187 - [done] bevel (Line Join Bevel) §20.1.8.9
188 - custDash (Custom Dash) §20.1.8.21
189 - extLst (Extension List) §20.1.2.2.15
190 - gradFill (Gradient Fill) §20.1.8.33
191 - [done] headEnd (Line Head/End Style) §20.1.8.38
192 - [done] miter (Miter Line Join) §20.1.8.43
193 - [done] noFill (No Fill) §20.1.8.44
194 - pattFill (Pattern Fill) §20.1.8.47
195 - [done] prstDash (Preset Dash) §20.1.8.48
196 - [done] round (Round Line Join) §20.1.8.52
197 - [done] solidFill (Solid Fill) §20.1.8.54
198 - [done] tailEnd (Tail line end style) §20.1.8.57
199
200 Attributes:
201 - algn (Stroke Alignment)
202 - [done] cap (Line Ending Cap Style)
203 - cmpd (Compound Line Type)
204 - [done] w (Line Width)
205 */
read_ln()206 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_ln()
207 {
208 READ_PROLOGUE
209 QXmlStreamAttributes attrs(attributes());
210
211 //TODO: align
212 TRY_READ_ATTR_WITHOUT_NS(algn)
213 //center
214 if (algn.isEmpty() || algn == "ctr") {
215 }
216 //inset
217 else if (algn == "in") {
218 }
219
220 //line ending cap
221 TRY_READ_ATTR_WITHOUT_NS(cap)
222 if (cap.isEmpty() || cap == "sq") {
223 m_currentDrawStyle->addProperty("svg:stroke-linecap", "square");
224 }
225 else if (cap == "rnd") {
226 m_currentDrawStyle->addProperty("svg:stroke-linecap", "round");
227 }
228 else if (cap == "flat") {
229 m_currentDrawStyle->addProperty("svg:stroke-linecap", "butt");
230 }
231
232 //TODO: compound line type
233 TRY_READ_ATTR_WITHOUT_NS(cmpd)
234
235 //single line
236 if( cmpd.isEmpty() || cmpd == "sng" ) {
237 }
238 //double lines
239 else if (cmpd == "dbl") {
240 }
241 //thick thin double lines
242 else if (cmpd == "thickThin") {
243 }
244 //thin thick double lines
245 else if (cmpd == "thinThick") {
246 }
247 //thin thick thin triple lines
248 else if (cmpd == "tri") {
249 }
250
251 TRY_READ_ATTR_WITHOUT_NS(w)
252
253 if (!w.isEmpty()) {
254 m_currentLineWidth = EMU_TO_POINT(w.toDouble());
255 m_currentDrawStyle->addPropertyPt("svg:stroke-width", m_currentLineWidth);
256 m_currentDrawStyle->addProperty("draw:stroke", "solid");
257 }
258
259 while (!atEnd()) {
260 readNext();
261 BREAK_IF_END_OF(CURRENT_EL)
262 if ( isStartElement() ) {
263
264 // line head/tail end
265 TRY_READ_IF(headEnd)
266 ELSE_TRY_READ_IF(tailEnd)
267
268 // linejoin
269 else if (qualifiedName() == QLatin1String("a:bevel")) {
270 m_currentDrawStyle->addProperty("draw:stroke-linejoin", "bevel");
271 }
272 else if (qualifiedName() == QLatin1String("a:miter")) {
273 m_currentDrawStyle->addProperty("draw:stroke-linejoin", "miter");
274 }
275 else if (qualifiedName() == QLatin1String("a:round")) {
276 m_currentDrawStyle->addProperty("draw:stroke-linejoin", "round");
277 }
278
279 // //custom dash
280 // else if(qualifiedName() == QLatin1String("a:custDash")) {
281 // }
282 // //extension list
283 // else if(qualifiedName() == QLatin1String("a:extLst")) {
284 // }
285 // //gradient fill
286 // else if(qualifiedName() == QLatin1String("a:gradFill")) {
287 // }
288
289 // //pattern fill
290 // else if(qualifiedName() == QLatin1String("a:pattFill")) {
291 // }
292
293 //solid fill
294 else if (qualifiedName() == QLatin1String("a:solidFill")) {
295 TRY_READ(solidFill)
296 m_currentDrawStyle->addProperty("svg:stroke-color", m_currentColor.name());
297
298 // Opacity is disabled because there's a bug somewhere
299 // which makes even 1% opacity hide lines.
300
301 // if (m_currentAlpha > 0) {
302 // m_currentDrawStyle->addProperty("svg:stroke-opacity",
303 // QString("%1%").arg(m_currentAlpha/100.0));
304 // }
305 }
306 else if (qualifiedName() == QLatin1String("a:noFill")) {
307 m_currentDrawStyle->addProperty("draw:stroke", "none");
308 }
309 else if (qualifiedName() == QLatin1String("a:prstDash")) {
310 attrs = attributes();
311 TRY_READ_ATTR_WITHOUT_NS(val)
312 QPen pen;
313 pen.setWidthF(m_currentLineWidth);
314 if (val == "dash") {
315 pen.setStyle(Qt::DashLine);
316 m_currentDrawStyle->addProperty("draw:stroke", "dash");
317 KoGenStyle dashStyle(KoGenStyle::StrokeDashStyle);
318 dashStyle.addAttribute("draw:style", "rect");
319 QVector<qreal> dashes = pen.dashPattern();
320 dashStyle.addAttribute("draw:dots1", static_cast<int>(1));
321 dashStyle.addAttributePt("draw:dots1-length", dashes[0]*pen.widthF());
322 dashStyle.addAttributePt("draw:distance", dashes[1]*pen.widthF());
323 if (dashes.size() > 2) {
324 dashStyle.addAttribute("draw:dots2", static_cast<int>(1));
325 dashStyle.addAttributePt("draw:dots2-length", dashes[2]*pen.widthF());
326 }
327 QString dashStyleName = mainStyles->insert(dashStyle, "dash");
328 m_currentDrawStyle->addProperty("draw:stroke-dash", dashStyleName);
329 // NOTE: A "dash" looks wrong in Calligra/LO when
330 // svg:stroke-linecap is applied.
331 m_currentDrawStyle->removeProperty("svg:stroke-linecap");
332 }
333 }
334 SKIP_UNKNOWN
335 }
336 }
337
338 READ_EPILOGUE
339 }
340
341 #undef CURRENT_EL
342 #define CURRENT_EL solidFill
343 //! solidFill - Solid Fill
344 /*! DrawingML ECMA-376 20.1.8.54, p. 3234.
345
346 This element specifies a solid color fill. The shape is filled entirely with
347 the specified color.
348
349 Parents:
350 - bg (§21.4.3.1)
351 - bgFillStyleLst (§20.1.4.1.7)
352 - bgPr (§19.3.1.2)
353 - defRPr (§21.1.2.3.2)
354 - endParaRPr (§21.1.2.2.3)
355 - fill (§20.1.8.28)
356 - fill (§20.1.4.2.9)
357 - fillOverlay (§20.1.8.29)
358 - fillStyleLst (§20.1.4.1.13)
359 - grpSpPr (§21.3.2.14)
360 - grpSpPr (§20.1.2.2.22)
361 - grpSpPr (§20.5.2.18)
362 - grpSpPr (§19.3.1.23)
363 - ln (§20.1.2.2.24)
364 - lnB (§21.1.3.5)
365 - lnBlToTr (§21.1.3.6)
366 - lnL (§21.1.3.7)
367 - lnR (§21.1.3.8)
368 - lnT (§21.1.3.9)
369 - lnTlToBr (§21.1.3.10)
370 - [done] rPr (§21.1.2.3.9)
371 - spPr (§21.2.2.197)
372 - spPr (§21.3.2.23)
373 - spPr (§21.4.3.7)
374 - [done] spPr (§20.1.2.2.35)
375 - spPr (§20.2.2.6)
376 - spPr (§20.5.2.30)
377 - [done] spPr (§19.3.1.44)
378 - tblPr (§21.1.3.15)
379 - tcPr (§21.1.3.17)
380 - uFill (§21.1.2.3.12)
381 - uLn (§21.1.2.3.14)
382
383 Child elements:
384 - [done] hslClr (Hue, Saturation, Luminance Color Model) §20.1.2.3.13
385 - [done] prstClr (Preset Color) §20.1.2.3.22
386 - [done] schemeClr (Scheme Color) §20.1.2.3.29
387 - [done] scrgbClr (RGB Color Model - Percentage Variant) §20.1.2.3.30
388 - [done] srgbClr (RGB Color Model - Hex Variant) §20.1.2.3.32
389 - [done] sysClr (System Color) §20.1.2.3.33
390
391 Attributes:
392 None.
393 */
read_solidFill()394 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_solidFill()
395 {
396 READ_PROLOGUE
397
398 while (!atEnd()) {
399 readNext();
400 debugMsooXml << *this;
401 BREAK_IF_END_OF(CURRENT_EL)
402 if (isStartElement()) {
403 TRY_READ_IF(scrgbClr)
404 ELSE_TRY_READ_IF(schemeClr)
405 ELSE_TRY_READ_IF(srgbClr)
406 ELSE_TRY_READ_IF(sysClr)
407 ELSE_TRY_READ_IF(prstClr)
408 ELSE_TRY_READ_IF(hslClr)
409 ELSE_WRONG_FORMAT
410 }
411 }
412 READ_EPILOGUE
413 }
414
415 //! fillREf handler (Fill reference)
416 /*
417 Parent elements:
418 - [done] style (§21.3.2.24);
419 - [done] style (§21.4.2.28);
420 - [done] style (§20.1.2.2.37);
421 - [done] style (§20.5.2.31);
422 - [done] style (§19.3.1.46);
423 - [done] tblBg (§20.1.4.2.25);
424 - [done] tcStyle (§20.1.4.2.29)
425
426 Child elements:
427 - [done] hslClr (Hue, Saturation, Luminance Color Model) §20.1.2.3.13
428 - [done] prstClr (Preset Color) §20.1.2.3.22
429 - [done] schemeClr (Scheme Color) §20.1.2.3.29
430 - [done] scrgbClr (RGB Color Model - Percentage Variant) §20.1.2.3.30
431 - [done] srgbClr (RGB Color Model - Hex Variant) §20.1.2.3.32
432 - [done] sysClr (System Color) §20.1.2.3.33
433
434 */
435 #if !defined MSOOXML_THEMESREADER_CPP
436 #undef CURRENT_EL
437 #define CURRENT_EL fillRef
read_fillRef()438 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_fillRef()
439 {
440 READ_PROLOGUE
441 const QXmlStreamAttributes attrs(attributes());
442 TRY_READ_ATTR_WITHOUT_NS(idx)
443 int index = idx.toInt();
444
445 // If it has draw:fill it means that the style has already been defined
446 if (!m_currentDrawStyle->property("draw:fill").isEmpty()) {
447 skipCurrentElement();
448 READ_EPILOGUE
449 }
450
451 while (!atEnd()) {
452 readNext();
453 debugMsooXml << *this;
454 BREAK_IF_END_OF(CURRENT_EL)
455 if (isStartElement()) {
456 TRY_READ_IF(schemeClr)
457 ELSE_TRY_READ_IF(scrgbClr)
458 ELSE_TRY_READ_IF(sysClr)
459 ELSE_TRY_READ_IF(srgbClr)
460 ELSE_TRY_READ_IF(prstClr)
461 ELSE_TRY_READ_IF(hslClr)
462 ELSE_WRONG_FORMAT
463 }
464 }
465
466 MSOOXML::DrawingMLFillBase *fillBase = m_context->themes->formatScheme.fillStyles.value(index);
467 if (fillBase) {
468 fillBase->writeStyles(*mainStyles, m_currentDrawStyle, m_currentColor);
469 }
470
471 READ_EPILOGUE
472 }
473
474 #undef CURRENT_EL
475 #define CURRENT_EL fontRef
476 //! fontRef handler (Font reference)
477 /*
478 Parent elements:
479 - [done] style (§21.3.2.24);
480 - [done] style (§21.4.2.28);
481 - [done] style (§20.1.2.2.37);
482 - [done] style (§20.5.2.31);
483 - [done] style (§19.3.1.46);
484 - [done] tcTxStyle (§20.1.4.2.30)
485
486 Child elements:
487 - [done] hslClr (Hue, Saturation, Luminance Color Model) §20.1.2.3.13
488 - [done] prstClr (Preset Color) §20.1.2.3.22
489 - [done] schemeClr (Scheme Color) §20.1.2.3.29
490 - [done] scrgbClr (RGB Color Model - Percentage Variant) §20.1.2.3.30
491 - [done] srgbClr (RGB Color Model - Hex Variant) §20.1.2.3.32
492 - [done] sysClr (System Color) §20.1.2.3.33
493 */
read_fontRef()494 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_fontRef()
495 {
496 READ_PROLOGUE
497
498 const QXmlStreamAttributes attrs(attributes());
499
500 TRY_READ_ATTR_WITHOUT_NS(idx)
501
502 if (!idx.isEmpty()) {
503 if (idx.startsWith("major")) {
504 m_referredFontName = m_context->themes->fontScheme.majorFonts.latinTypeface;
505 }
506 else if (idx.startsWith("minor")) {
507 m_referredFontName = m_context->themes->fontScheme.minorFonts.latinTypeface;
508 }
509 }
510
511 while (!atEnd()) {
512 readNext();
513 BREAK_IF_END_OF(CURRENT_EL)
514 if (isStartElement()) {
515 TRY_READ_IF(schemeClr)
516 ELSE_TRY_READ_IF(srgbClr)
517 ELSE_TRY_READ_IF(sysClr)
518 ELSE_TRY_READ_IF(scrgbClr)
519 ELSE_TRY_READ_IF(prstClr)
520 ELSE_TRY_READ_IF(hslClr)
521 ELSE_WRONG_FORMAT
522 }
523 }
524
525 READ_EPILOGUE
526 }
527 #endif //!defined MSOOXML_THEMESREADER_CPP
528
529 #undef CURRENT_EL
530 #define CURRENT_EL hslClr
531 //! hslClr (hue saturation luminance color)
read_hslClr()532 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_hslClr()
533 {
534 READ_PROLOGUE
535 const QXmlStreamAttributes attrs(attributes());
536
537 READ_ATTR_WITHOUT_NS(hue)
538 READ_ATTR_WITHOUT_NS(sat)
539 READ_ATTR_WITHOUT_NS(lum)
540
541 qreal trueHue = hue.toDouble() / 6000.0 / 360;
542 qreal trueSat = sat.left(sat.size() - 1).toDouble() / 100.0;
543 qreal trueLum = lum.left(lum.size() - 1).toDouble() / 100.0;
544
545 m_currentColor.setHslF(trueHue, trueSat, trueLum);
546
547 //TODO: all the color transformations
548 while (!atEnd()) {
549 readNext();
550 BREAK_IF_END_OF(CURRENT_EL)
551 if (isStartElement()) {
552 TRY_READ_IF(tint)
553 ELSE_TRY_READ_IF(shade)
554 ELSE_TRY_READ_IF(satMod)
555 ELSE_TRY_READ_IF(alpha)
556 SKIP_UNKNOWN
557 }
558 }
559
560 MSOOXML::Utils::modifyColor(m_currentColor, m_currentTint, m_currentShadeLevel, m_currentSatMod);
561
562 READ_EPILOGUE
563 }
564
565
566 #undef CURRENT_EL
567 #define CURRENT_EL prstClr
568 //! prstClr (preset color)
read_prstClr()569 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_prstClr()
570 {
571 READ_PROLOGUE
572 const QXmlStreamAttributes attrs(attributes());
573
574 TRY_READ_ATTR_WITHOUT_NS(val)
575
576 // TODO: support all of them..
577 if (!val.isEmpty()) {
578 if (val == "aliceBlue") {
579 m_currentColor = QColor(240, 248, 255);
580 }
581 else if (val == "antiqueWhite") {
582 m_currentColor = QColor(250, 235, 215);
583 }
584 else if (val == "aqua") {
585 m_currentColor = QColor(0, 255, 255);
586 }
587 else if (val == "aquamarine") {
588 m_currentColor = QColor(127, 255, 212);
589 }
590 else if (val == "azure") {
591 m_currentColor = QColor(240, 255, 255);
592 }
593 else if (val == "beige") {
594 m_currentColor = QColor(245, 245, 220);
595 }
596 else if (val == "bisque") {
597 m_currentColor = QColor(255, 228, 196);
598 }
599 else if (val == "black") {
600 m_currentColor = QColor(0, 0, 0);
601 }
602 else if (val == "blue") {
603 m_currentColor = QColor(0, 0, 215);
604 }
605 else if (val == "green") {
606 m_currentColor = QColor(0, 255, 0);
607 }
608 else if (val == "red") {
609 m_currentColor = QColor(255, 0, 0);
610 }
611 else if (val == "violet") {
612 m_currentColor = QColor(238, 130, 238);
613 }
614 else if (val == "wheat") {
615 m_currentColor = QColor(245, 222, 179);
616 }
617 else if (val == "white") {
618 m_currentColor = QColor(255, 255, 255);
619 }
620 else if (val == "whiteSmoke") {
621 m_currentColor = QColor(245, 245, 245);
622 }
623 else if (val == "yellow") {
624 m_currentColor = QColor(255, 255, 0);
625 }
626 else if (val == "yellowGreen") {
627 m_currentColor = QColor(154, 205, 50);
628 }
629 }
630
631 m_currentTint = 0;
632 m_currentShadeLevel = 0;
633 m_currentSatMod = 0;
634 m_currentAlpha = 0;
635
636 //TODO: all the color transformations
637 while (!atEnd()) {
638 readNext();
639 BREAK_IF_END_OF(CURRENT_EL)
640 if (isStartElement()) {
641 TRY_READ_IF(tint)
642 ELSE_TRY_READ_IF(shade)
643 ELSE_TRY_READ_IF(satMod)
644 ELSE_TRY_READ_IF(alpha)
645 SKIP_UNKNOWN
646 }
647 }
648
649 MSOOXML::Utils::modifyColor(m_currentColor, m_currentTint, m_currentShadeLevel, m_currentSatMod);
650
651 READ_EPILOGUE
652 }
653
654 /*
655 This element specifies a color bound to a user's theme. As with all
656 elements which define a color, it is possible to apply a list of color
657 transforms to the base color defined.
658
659 Parent Elements
660 - accent1 (§20.1.4.1.1)
661 - accent2 (§20.1.4.1.2)
662 - accent3 (§20.1.4.1.3)
663 - accent4 (§20.1.4.1.4)
664 - accent5 (§20.1.4.1.5)
665 - accent6 (§20.1.4.1.6)
666 - alphaInv (§20.1.8.4)
667 - bgClr (§20.1.8.10)
668 - bgRef (§19.3.1.3)
669 - buClr (§21.1.2.4.4)
670 - clrFrom (§20.1.8.17)
671 - clrMru (§19.2.1.4)
672 - clrRepl (§20.1.8.18)
673 - clrTo (§20.1.8.19)
674 - clrVal (§19.5.27)
675 - contourClr (§20.1.5.6)
676 - custClr (§20.1.4.1.8)
677 - dk1 (§20.1.4.1.9)
678 - dk2 (§20.1.4.1.10)
679 - duotone (§20.1.8.23)
680 - effectClrLst (§21.4.4.7)
681 - effectRef (§20.1.4.2.8)
682 - extrusionClr (§20.1.5.7)
683 - fgClr (§20.1.8.27)
684 - fillClrLst (§21.4.4.8)
685 - fillRef (§20.1.4.2.10)
686 - folHlink (§20.1.4.1.15)
687 - fontRef (§20.1.4.1.17)
688 - from (§19.5.43)
689 - glow (§20.1.8.32)
690 - gs (§20.1.8.36)
691 - highlight (§21.1.2.3.4)
692 - hlink (§20.1.4.1.19)
693 - innerShdw (§20.1.8.40)
694 - linClrLst (§21.4.4.9)
695 - lnRef (§20.1.4.2.19)
696 - lt1 (§20.1.4.1.22)
697 - lt2 (§20.1.4.1.23)
698 - outerShdw (§20.1.8.45)
699 - penClr (§19.2.1.23)
700 - prstShdw (§20.1.8.49)
701 - [done] solidFill (§20.1.8.54)
702 - tcTxStyle (§20.1.4.2.30)
703 - to (§19.5.90)
704 - txEffectClrLst (§21.4.4.12)
705 - txFillClrLst (§21.4.4.13)
706 - txLinClrLst (§21.4.4.14)
707
708 Child elements:
709 - [done] alpha (Alpha) §20.1.2.3.1
710 - alphaMod (Alpha Modulation) §20.1.2.3.2
711 - alphaOff (Alpha Offset) §20.1.2.3.3
712 - blue (Blue) §20.1.2.3.4
713 - blueMod (Blue Modification) §20.1.2.3.5
714 - blueOff (Blue Offset) §20.1.2.3.6
715 - comp (Complement) §20.1.2.3.7
716 - gamma (Gamma) §20.1.2.3.8
717 - gray (Gray) §20.1.2.3.9
718 - green (Green) §20.1.2.3.10
719 - greenMod (Green Modification) §20.1.2.3.11
720 - greenOff (Green Offset) §20.1.2.3.12
721 - hue (Hue) §20.1.2.3.14
722 - hueMod (Hue Modulate) §20.1.2.3.15
723 - hueOff (Hue Offset) §20.1.2.3.16
724 - inv (Inverse) §20.1.2.3.17
725 - invGamma (Inverse Gamma) §20.1.2.3.18
726 - lum (Luminance) §20.1.2.3.19
727 - [done] lumMod (Luminance Modulation) §20.1.2.3.20
728 - [done] lumOff (Luminance Offset) §20.1.2.3.21
729 - red (Red) §20.1.2.3.23
730 - redMod (Red Modulation) §20.1.2.3.24
731 - redOff (Red Offset) §20.1.2.3.25
732 - sat (Saturation) §20.1.2.3.26
733 - [done] satMod (Saturation Modulation) §20.1.2.3.27
734 - satOff (Saturation Offset) §20.1.2.3.28
735 - shade (Shade) §20.1.2.3.31
736 - [done] tint (Tint) §20.1.2.3.34
737
738 Attributes
739 - val (Value) Specifies the desired scheme.
740 */
741 #undef CURRENT_EL
742 #define CURRENT_EL schemeClr
743 //! @todo support all child elements
read_schemeClr()744 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_schemeClr()
745 {
746 READ_PROLOGUE
747
748 const QXmlStreamAttributes attrs(attributes());
749 READ_ATTR_WITHOUT_NS(val)
750
751 #ifdef PPTXXMLDOCUMENTREADER_CPP
752 // Skip the rest of the code, the color scheme map (clrMap) is unknown at
753 // time of reading.
754 if (m_colorState == PptxXmlDocumentReader::defRPrState) {
755 defaultTextColors[defaultTextColors.size() - 1] = val;
756 }
757 else {
758 defaultBulletColors[defaultBulletColors.size() - 1] = val;
759 }
760 skipCurrentElement();
761 READ_EPILOGUE
762 #endif
763
764 m_currentTint = 0;
765 m_currentShadeLevel = 0;
766 m_currentSatMod = 0;
767 m_currentAlpha = 0;
768
769 MSOOXML::DrawingMLColorSchemeItemBase *colorItem = 0;
770
771 #if !defined MSOOXML_THEMESREADER_CPP
772 QString valTransformed = m_context->colorMap.value(val);
773 if (valTransformed.isEmpty()) {
774 // In some cases, such as fontRef, mapping is bypassed
775 colorItem = m_context->themes->colorScheme.value(val);
776 } else {
777 colorItem = m_context->themes->colorScheme.value(valTransformed);
778 }
779 #endif
780
781 // Parse the child elements
782 MSOOXML::Utils::DoubleModifier lumMod;
783 MSOOXML::Utils::DoubleModifier lumOff;
784 while (!atEnd()) {
785 readNext();
786 BREAK_IF_END_OF(CURRENT_EL)
787 if (isStartElement()) {
788 // @todo: Hmm, are these color modifications only available for pptx?
789 if (QUALIFIED_NAME_IS(lumMod)) {
790 m_currentDoubleValue = &lumMod.value;
791 TRY_READ(lumMod)
792 lumMod.valid = true;
793 } else if (QUALIFIED_NAME_IS(lumOff)) {
794 m_currentDoubleValue = &lumOff.value;
795 TRY_READ(lumOff)
796 lumOff.valid = true;
797 }
798 ELSE_TRY_READ_IF(shade)
799 ELSE_TRY_READ_IF(tint)
800 ELSE_TRY_READ_IF(satMod)
801 ELSE_TRY_READ_IF(alpha)
802 SKIP_UNKNOWN
803 }
804 }
805
806 QColor col = Qt::white;
807 if (colorItem) {
808 col = colorItem->value();
809 }
810
811 col = MSOOXML::Utils::colorForLuminance(col, lumMod, lumOff);
812 m_currentColor = col;
813
814 MSOOXML::Utils::modifyColor(m_currentColor, m_currentTint, m_currentShadeLevel, m_currentSatMod);
815
816 READ_EPILOGUE
817 }
818
819 #undef CURRENT_EL
820 #define CURRENT_EL sysClr
821 //! sysClr handler
822 // SysClr is bit controversial, it is supposed to use
823 // color defined by the system at the moment, the document is read
824 // however, it often means that when reading the document, it is not
825 // using the same colors, the creator wished.
826 // Sometimes sysclr saves attribute lastClr which tells which color
827 // the creator was using, the current implementation uses that
828 // and ignores real system colors.
read_sysClr()829 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_sysClr()
830 {
831 READ_PROLOGUE
832 const QXmlStreamAttributes attrs(attributes());
833
834 m_currentTint = 0;
835 m_currentShadeLevel = 0;
836 m_currentSatMod = 0;
837 m_currentAlpha = 0;
838
839 TRY_READ_ATTR_WITHOUT_NS(lastClr)
840
841 if (!lastClr.isEmpty()) {
842 m_currentColor = QColor( QLatin1Char('#') + lastClr );
843 }
844
845 //TODO: all the color transformations
846 while (!atEnd()) {
847 readNext();
848 BREAK_IF_END_OF(CURRENT_EL)
849 if (isStartElement()) {
850 TRY_READ_IF(tint)
851 ELSE_TRY_READ_IF(shade)
852 ELSE_TRY_READ_IF(satMod)
853 ELSE_TRY_READ_IF(alpha)
854 SKIP_UNKNOWN
855 }
856 }
857
858 MSOOXML::Utils::modifyColor(m_currentColor, m_currentTint, m_currentShadeLevel, m_currentSatMod);
859
860 READ_EPILOGUE
861 }
862
863 #undef CURRENT_EL
864 #define CURRENT_EL scrgbClr
865 //! RGB Color Model - Percentage Variant
866 //! DrawingML ECMA-376 20.1.2.3.30, p. 3074.
867 /*!
868 This element specifies a solid color fill.
869
870 Child elements:
871 - [done] alpha (Alpha) §20.1.2.3.1
872 - alphaMod (Alpha Modulation) §20.1.2.3.2
873 - alphaOff (Alpha Offset) §20.1.2.3.3
874 - blue (Blue) §20.1.2.3.4
875 - blueMod (Blue Modification) §20.1.2.3.5
876 - blueOff (Blue Offset) §20.1.2.3.6
877 - comp (Complement) §20.1.2.3.7
878 - gamma (Gamma) §20.1.2.3.8
879 - gray (Gray) §20.1.2.3.9
880 - green (Green) §20.1.2.3.10
881 - greenMod (Green Modification) §20.1.2.3.11
882 - greenOff (Green Offset) §20.1.2.3.12
883 - hue (Hue) §20.1.2.3.14
884 - hueMod (Hue Modulate) §20.1.2.3.15
885 - hueOff (Hue Offset) §20.1.2.3.16
886 - [done] inv (Inverse) §20.1.2.3.17
887 - invGamma (Inverse Gamma) §20.1.2.3.18
888 - lum (Luminance) §20.1.2.3.19
889 - lumMod (Luminance Modulation) §20.1.2.3.20
890 - lumOff (Luminance Offset) §20.1.2.3.21
891 - red (Red) §20.1.2.3.23
892 - redMod (Red Modulation) §20.1.2.3.24
893 - redOff (Red Offset) §20.1.2.3.25
894
895 Attributes:
896 - [done] b (blue)
897 - [done] g (green)
898 - [done] r (red)
899 */
read_scrgbClr()900 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_scrgbClr()
901 {
902 READ_PROLOGUE
903
904 const QXmlStreamAttributes attrs(attributes());
905
906 m_currentTint = 0;
907 m_currentShadeLevel = 0;
908 m_currentSatMod = 0;
909 m_currentAlpha = 0;
910
911 READ_ATTR_WITHOUT_NS(r)
912 READ_ATTR_WITHOUT_NS(g)
913 READ_ATTR_WITHOUT_NS(b)
914
915 bool okR, okG, okB;
916
917 m_currentColor = QColor::fromRgbF(qreal(MSOOXML::Utils::ST_Percentage_to_double(r, okR)),
918 qreal(MSOOXML::Utils::ST_Percentage_to_double(g, okG)),
919 qreal(MSOOXML::Utils::ST_Percentage_to_double(b, okB)));
920
921 //TODO: all the color transformations
922 while (!atEnd()) {
923 readNext();
924 BREAK_IF_END_OF(CURRENT_EL)
925 if (isStartElement()) {
926 TRY_READ_IF(tint)
927 ELSE_TRY_READ_IF(alpha)
928 SKIP_UNKNOWN
929 }
930 }
931
932 MSOOXML::Utils::modifyColor(m_currentColor, m_currentTint, m_currentShadeLevel, m_currentSatMod);
933
934 READ_EPILOGUE
935 }
936
937 #undef CURRENT_EL
938 #define CURRENT_EL srgbClr
939 //! srgbClr (RGB Color Model - Hex Variant)
940 //! DrawingML ECMA-376 20.1.2.3.32, p. 3085.
941 /*!
942 This element specifies a color in RGB notation.
943
944 Child elements:
945 - alpha (Alpha) §20.1.2.3.1
946 - alphaMod (Alpha Modulation) §20.1.2.3.2
947 - alphaOff (Alpha Offset) §20.1.2.3.3
948 - blue (Blue) §20.1.2.3.4
949 - blueMod (Blue Modification) §20.1.2.3.5
950 - blueOff (Blue Offset) §20.1.2.3.6
951 - comp (Complement) §20.1.2.3.7
952 - gamma (Gamma) §20.1.2.3.8
953 - gray (Gray) §20.1.2.3.9
954 - green (Green) §20.1.2.3.10
955 - greenMod (Green Modification) §20.1.2.3.11
956 - greenOff (Green Offset) §20.1.2.3.12
957 - hue (Hue) §20.1.2.3.14
958 - hueMod (Hue Modulate) §20.1.2.3.15
959 - hueOff (Hue Offset) §20.1.2.3.16
960 - inv (Inverse) §20.1.2.3.17
961 - invGamma (Inverse Gamma) §20.1.2.3.18
962 - lum (Luminance) §20.1.2.3.19
963 - lumMod (Luminance Modulation) §20.1.2.3.20
964 - lumOff (Luminance Offset) §20.1.2.3.21
965 - red (Red) §20.1.2.3.23
966 - redMod (Red Modulation) §20.1.2.3.24
967 - redOff (Red Offset) §20.1.2.3.25
968 - sat (Saturation) §20.1.2.3.26
969 - [done] satMod (Saturation Modulation) §20.1.2.3.27
970 - satOff (Saturation Offset) §20.1.2.3.28
971 - [done] shade (Shade) §20.1.2.3.31
972 - [done] tint (Tint) §20.1.2.3.34
973
974 Attributes:
975 - [done] val ("RRGGBB" hex digits)
976 */
read_srgbClr()977 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_srgbClr()
978 {
979 READ_PROLOGUE
980
981 const QXmlStreamAttributes attrs(attributes());
982
983 m_currentTint = 0;
984 m_currentShadeLevel = 0;
985 m_currentSatMod = 0;
986 m_currentAlpha = 0;
987
988 READ_ATTR_WITHOUT_NS(val)
989
990 m_currentColor = QColor( QLatin1Char('#') + val );
991
992 //TODO: all the color transformations
993 while (!atEnd()) {
994 readNext();
995 BREAK_IF_END_OF(CURRENT_EL)
996 if (isStartElement()) {
997 TRY_READ_IF(tint)
998 ELSE_TRY_READ_IF(shade)
999 ELSE_TRY_READ_IF(satMod)
1000 ELSE_TRY_READ_IF(alpha)
1001 SKIP_UNKNOWN
1002 }
1003 }
1004
1005 MSOOXML::Utils::modifyColor(m_currentColor, m_currentTint, m_currentShadeLevel, m_currentSatMod);
1006
1007 READ_EPILOGUE
1008 }
1009
1010 #undef CURRENT_EL
1011 #define CURRENT_EL shade
1012 //! shade (shade value)
read_shade()1013 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_shade()
1014 {
1015 READ_PROLOGUE
1016 const QXmlStreamAttributes attrs(attributes());
1017 TRY_READ_ATTR_WITHOUT_NS(val)
1018
1019 if (!val.isEmpty()) {
1020 bool ok = false;
1021 int value = val.toInt(&ok);
1022 if (!ok) {
1023 value = 0;
1024 }
1025 m_currentShadeLevel = value/100000.0; // To get percentage (form 0.x)
1026 }
1027
1028 readNext();
1029 READ_EPILOGUE
1030 }
1031
1032 #undef CURRENT_EL
1033 #define CURRENT_EL tint
1034 //! tint (tint value)
read_tint()1035 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tint()
1036 {
1037 READ_PROLOGUE
1038 const QXmlStreamAttributes attrs(attributes());
1039 TRY_READ_ATTR_WITHOUT_NS(val)
1040
1041 if (!val.isEmpty()) {
1042 bool ok = false;
1043 int value = val.toInt(&ok);
1044 if (!ok) {
1045 value = 0;
1046 }
1047 m_currentTint = value/100000.0; // To get percentage (form 0.x)
1048 }
1049
1050 readNext();
1051 READ_EPILOGUE
1052 }
1053
1054 #undef CURRENT_EL
1055 #define CURRENT_EL alpha
1056 //! alpha (alpha value)
read_alpha()1057 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_alpha()
1058 {
1059 READ_PROLOGUE
1060 const QXmlStreamAttributes attrs(attributes());
1061 TRY_READ_ATTR_WITHOUT_NS(val)
1062
1063 if (!val.isEmpty()) {
1064 bool ok = false;
1065 int value = val.toInt(&ok);
1066 if (!ok) {
1067 value = 0;
1068 }
1069 m_currentAlpha = value/1000; // To get percentage
1070 }
1071
1072 readNext();
1073 READ_EPILOGUE
1074 }
1075
1076 #undef CURRENT_EL
1077 #define CURRENT_EL lumMod
1078 //! 20.1.2.3.20 lumMod (Luminance Modulation)
1079 //! This element specifies the input color with its luminance modulated by the given percentage.
1080 //! @todo support all child elements
read_lumMod()1081 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lumMod()
1082 {
1083 READ_PROLOGUE
1084 const QXmlStreamAttributes attrs(attributes());
1085 READ_ATTR_WITHOUT_NS(val)
1086
1087 bool ok;
1088 Q_ASSERT(m_currentDoubleValue);
1089 *m_currentDoubleValue = MSOOXML::Utils::ST_Percentage_withMsooxmlFix_to_double(val, ok);
1090 if (!ok)
1091 return KoFilter::WrongFormat;
1092
1093 readNext();
1094 READ_EPILOGUE
1095 }
1096
1097 #undef CURRENT_EL
1098 #define CURRENT_EL satMod
1099 //! satMod (Saturation modulation value)
read_satMod()1100 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_satMod()
1101 {
1102 READ_PROLOGUE
1103 const QXmlStreamAttributes attrs(attributes());
1104 TRY_READ_ATTR_WITHOUT_NS(val)
1105
1106 if (!val.isEmpty()) {
1107 bool ok = false;
1108 int value = val.toInt(&ok);
1109 if (!ok) {
1110 value = 0;
1111 }
1112 m_currentSatMod = value/100000.0; // To get percentage in from 0.x
1113 }
1114
1115 readNext();
1116 READ_EPILOGUE
1117 }
1118
1119 #undef CURRENT_EL
1120 #define CURRENT_EL lumOff
1121 //! 20.1.2.3.21 lumOff (Luminance Offset)
1122 //! This element specifies the input color with its luminance shifted, but with its hue and saturation unchanged.
1123 //! @todo support all child elements
read_lumOff()1124 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lumOff()
1125 {
1126 READ_PROLOGUE
1127 const QXmlStreamAttributes attrs(attributes());
1128 READ_ATTR_WITHOUT_NS(val)
1129
1130 bool ok;
1131 Q_ASSERT(m_currentDoubleValue);
1132 *m_currentDoubleValue = MSOOXML::Utils::ST_Percentage_withMsooxmlFix_to_double(val, ok);
1133 if (!ok)
1134 return KoFilter::WrongFormat;
1135
1136 readNext();
1137 READ_EPILOGUE
1138 }
1139
1140 //! tailEnd (Tail line end style)
1141 //! DrawingML ECMA-376 20.1.8.57, p.3232
1142 /*!
1143 This element specifies decorations which can be added to the tail of
1144 a line.
1145
1146 Parent Elements:
1147 - [done] ln (§20.1.2.2.24);
1148 - lnB (§21.1.3.5);
1149 - lnBlToTr (§21.1.3.6);
1150 - lnL (§21.1.3.7);
1151 - lnR (§21.1.3.8);
1152 - lnT (§21.1.3.9);
1153 - lnTlToBr (§21.1.3.10);
1154 - uLn (§21.1.2.3.14)
1155
1156 Attributes:
1157 - len (Length of Head/End)
1158 - [done] type (Line Head/End Type)
1159 - w (Width of Head/End)
1160
1161 TODO: merge the following two readers
1162 */
1163 #undef CURRENT_EL
1164 #define CURRENT_EL tailEnd
read_tailEnd()1165 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tailEnd()
1166 {
1167 READ_PROLOGUE
1168 const QXmlStreamAttributes attrs(attributes());
1169 TRY_READ_ATTR_WITHOUT_NS(type)
1170 TRY_READ_ATTR_WITHOUT_NS(w)
1171
1172 if (!type.isEmpty() && type != "none") {
1173 // draw:marker-end
1174 m_currentDrawStyle->addProperty("draw:marker-end", MSOOXML::Utils::defineMarkerStyle(*mainStyles, type));
1175 // draw:marker-end-center
1176 m_currentDrawStyle->addProperty("draw:marker-end-center", "false");
1177 // draw:marker-end-width
1178 m_currentDrawStyle->addPropertyPt("draw:marker-end-width",
1179 MSOOXML::Utils::defineMarkerWidth(w, m_currentLineWidth));
1180 }
1181
1182 readNext();
1183 READ_EPILOGUE
1184 }
1185
1186 #undef CURRENT_EL
1187 #define CURRENT_EL headEnd
read_headEnd()1188 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_headEnd()
1189 {
1190 READ_PROLOGUE
1191 const QXmlStreamAttributes attrs(attributes());
1192 TRY_READ_ATTR_WITHOUT_NS(type)
1193 TRY_READ_ATTR_WITHOUT_NS(w)
1194
1195 if (!type.isEmpty() && type != "none") {
1196 // draw:marker-start
1197 m_currentDrawStyle->addProperty("draw:marker-start", MSOOXML::Utils::defineMarkerStyle(*mainStyles, type));
1198 // draw:marker-start-center
1199 m_currentDrawStyle->addProperty("draw:marker-start-center", "false");
1200 // draw:marker-start-width
1201 m_currentDrawStyle->addPropertyPt("draw:marker-start-width",
1202 MSOOXML::Utils::defineMarkerWidth(w, m_currentLineWidth));
1203 }
1204
1205 readNext();
1206 READ_EPILOGUE
1207 }
1208
1209 #endif
1210