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