File indexing completed on 2025-01-19 10:49:18
0001 /* 0002 * This file is part of Office 2007 Filters for Calligra 0003 * 0004 * SPDX-FileCopyrightText: 2009 Nokia Corporation and /or its subsidiary(-ies). 0005 * Contact: Suresh Chande suresh.chande@nokia.com 0006 * 0007 * SPDX-FileCopyrightText: 2012 Matus Uzak (matus.uzak@gmail.com). 0008 * 0009 * SPDX-License-Identifier: LGPL-2.1-only 0010 * 0011 */ 0012 0013 #ifndef MSOOXML_DRAWINGML_SHARED_IMPL_H 0014 #define MSOOXML_DRAWINGML_SHARED_IMPL_H 0015 0016 #undef CURRENT_EL 0017 #define CURRENT_EL extLst 0018 //! extLst (Extension List) 0019 //! DrawingML ECMA-376 20.1.2.2.15, p.3034 0020 /*! 0021 This element specifies the extension list within which all future 0022 extensions of element type ext is defined. The extension list along 0023 with corresponding future extensions is used to extend the storage 0024 capabilities of the DrawingML framework. This allows for various new 0025 types of data to be stored natively within the framework. 0026 */ 0027 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_extLst() 0028 { 0029 READ_PROLOGUE 0030 // NO support atm, skipping 0031 skipCurrentElement(); 0032 0033 READ_EPILOGUE 0034 } 0035 0036 #undef CURRENT_EL 0037 #define CURRENT_EL lnL 0038 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_Table_lnL() 0039 { 0040 READ_PROLOGUE2(Table_lnL) 0041 0042 return read_Table_generic("lnL"); 0043 0044 READ_EPILOGUE 0045 } 0046 0047 #undef CURRENT_EL 0048 #define CURRENT_EL lnR 0049 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_Table_lnR() 0050 { 0051 READ_PROLOGUE2(Table_lnR) 0052 0053 return read_Table_generic("lnR"); 0054 0055 READ_EPILOGUE 0056 } 0057 0058 #undef CURRENT_EL 0059 #define CURRENT_EL lnT 0060 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_Table_lnT() 0061 { 0062 READ_PROLOGUE2(Table_lnT) 0063 0064 return read_Table_generic("lnT"); 0065 0066 READ_EPILOGUE 0067 } 0068 0069 #undef CURRENT_EL 0070 #define CURRENT_EL lnB 0071 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_Table_lnB() 0072 { 0073 READ_PROLOGUE2(Table_lnB) 0074 0075 return read_Table_generic("lnB"); 0076 0077 READ_EPILOGUE 0078 } 0079 0080 #undef CURRENT_EL 0081 #define CURRENT_EL ln 0082 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_Table_ln() 0083 { 0084 READ_PROLOGUE2(Table_ln) 0085 0086 return read_Table_generic("ln"); 0087 0088 READ_EPILOGUE 0089 } 0090 0091 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_Table_generic(const QString& endElement) 0092 { 0093 QXmlStreamAttributes attrs = attributes(); 0094 0095 m_currentBorder = KoBorder::BorderData(); 0096 0097 //compound line type 0098 TRY_READ_ATTR_WITHOUT_NS(cmpd) 0099 //double lines 0100 if( cmpd.isEmpty() || cmpd == "sng" ) { 0101 m_currentBorder.style = KoBorder::BorderSolid; 0102 } 0103 //single line 0104 else if (cmpd == "dbl") { 0105 m_currentBorder.style = KoBorder::BorderDouble; 0106 } 0107 //thick thin double lines 0108 else if (cmpd == "thickThin") { 0109 //FIXME it seem we don't support this properly. Use solid for now. 0110 m_currentBorder.style = KoBorder::BorderDouble; 0111 } 0112 //thin thick double lines 0113 else if (cmpd == "thinThick") { 0114 //FIXME it doesn't seem we support this properly. 0115 m_currentBorder.style = KoBorder::BorderDouble; 0116 } 0117 //thin thick thin triple lines 0118 else if (cmpd == "tri") { 0119 //NOTE: There is not triple in ODF 0120 m_currentBorder.style = KoBorder::BorderSolid; 0121 } 0122 0123 TRY_READ_ATTR_WITHOUT_NS(w) //width 0124 m_currentBorder.outerPen.setWidthF(EMU_TO_POINT(w.toDouble())); 0125 0126 while (!atEnd()) { 0127 readNext(); 0128 if (isEndElement() && name() == endElement) { 0129 break; 0130 } 0131 if(isStartElement()) { 0132 if(QUALIFIED_NAME_IS(solidFill)) { 0133 TRY_READ(solidFill); 0134 m_currentBorder.style = KoBorder::BorderSolid; 0135 m_currentBorder.innerPen.setColor(m_currentColor); 0136 m_currentBorder.outerPen.setColor(m_currentColor); 0137 } 0138 else if (QUALIFIED_NAME_IS(prstDash)) { 0139 attrs = attributes(); 0140 //TODO find out how other colors are handled 0141 m_currentBorder.innerPen.setColor(Qt::black); 0142 m_currentBorder.outerPen.setColor(Qt::black); 0143 TRY_READ_ATTR_WITHOUT_NS(val) 0144 //TODO support other dash types. Make it its own function. 0145 if (val == "dash") { 0146 m_currentBorder.style = KoBorder::BorderDashed; 0147 } 0148 else if(val == "dashDot") { 0149 m_currentBorder.style = KoBorder::BorderDashDot; 0150 } 0151 else if(val == "dot") { 0152 m_currentBorder.style = KoBorder::BorderDotted; 0153 } 0154 } 0155 SKIP_UNKNOWN 0156 // ELSE_WRONG_FORMAT 0157 } 0158 } 0159 return KoFilter::OK; 0160 } 0161 0162 #undef CURRENT_EL 0163 #define CURRENT_EL ln 0164 //! ln (Outline) 0165 //! DrawingML ECMA-376, 20.1.2.2.24, p. 3048. 0166 /*! 0167 This element specifies an outline style that can be applied to a 0168 number of different objects such as shapes and text. The line allows 0169 for the specifying of many different types of outlines including 0170 even line dashes and bevels. 0171 0172 Parent Elements: 0173 0174 Child Elements: 0175 - [done] bevel (Line Join Bevel) §20.1.8.9 0176 - custDash (Custom Dash) §20.1.8.21 0177 - extLst (Extension List) §20.1.2.2.15 0178 - gradFill (Gradient Fill) §20.1.8.33 0179 - [done] headEnd (Line Head/End Style) §20.1.8.38 0180 - [done] miter (Miter Line Join) §20.1.8.43 0181 - [done] noFill (No Fill) §20.1.8.44 0182 - pattFill (Pattern Fill) §20.1.8.47 0183 - [done] prstDash (Preset Dash) §20.1.8.48 0184 - [done] round (Round Line Join) §20.1.8.52 0185 - [done] solidFill (Solid Fill) §20.1.8.54 0186 - [done] tailEnd (Tail line end style) §20.1.8.57 0187 0188 Attributes: 0189 - algn (Stroke Alignment) 0190 - [done] cap (Line Ending Cap Style) 0191 - cmpd (Compound Line Type) 0192 - [done] w (Line Width) 0193 */ 0194 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_ln() 0195 { 0196 READ_PROLOGUE 0197 QXmlStreamAttributes attrs(attributes()); 0198 0199 //TODO: align 0200 TRY_READ_ATTR_WITHOUT_NS(algn) 0201 //center 0202 if (algn.isEmpty() || algn == "ctr") { 0203 } 0204 //inset 0205 else if (algn == "in") { 0206 } 0207 0208 //line ending cap 0209 TRY_READ_ATTR_WITHOUT_NS(cap) 0210 if (cap.isEmpty() || cap == "sq") { 0211 m_currentDrawStyle->addProperty("svg:stroke-linecap", "square"); 0212 } 0213 else if (cap == "rnd") { 0214 m_currentDrawStyle->addProperty("svg:stroke-linecap", "round"); 0215 } 0216 else if (cap == "flat") { 0217 m_currentDrawStyle->addProperty("svg:stroke-linecap", "butt"); 0218 } 0219 0220 //TODO: compound line type 0221 TRY_READ_ATTR_WITHOUT_NS(cmpd) 0222 0223 //single line 0224 if( cmpd.isEmpty() || cmpd == "sng" ) { 0225 } 0226 //double lines 0227 else if (cmpd == "dbl") { 0228 } 0229 //thick thin double lines 0230 else if (cmpd == "thickThin") { 0231 } 0232 //thin thick double lines 0233 else if (cmpd == "thinThick") { 0234 } 0235 //thin thick thin triple lines 0236 else if (cmpd == "tri") { 0237 } 0238 0239 TRY_READ_ATTR_WITHOUT_NS(w) 0240 0241 if (!w.isEmpty()) { 0242 m_currentLineWidth = EMU_TO_POINT(w.toDouble()); 0243 m_currentDrawStyle->addPropertyPt("svg:stroke-width", m_currentLineWidth); 0244 m_currentDrawStyle->addProperty("draw:stroke", "solid"); 0245 } 0246 0247 while (!atEnd()) { 0248 readNext(); 0249 BREAK_IF_END_OF(CURRENT_EL) 0250 if ( isStartElement() ) { 0251 0252 // line head/tail end 0253 TRY_READ_IF(headEnd) 0254 ELSE_TRY_READ_IF(tailEnd) 0255 0256 // linejoin 0257 else if (qualifiedName() == QLatin1String("a:bevel")) { 0258 m_currentDrawStyle->addProperty("draw:stroke-linejoin", "bevel"); 0259 } 0260 else if (qualifiedName() == QLatin1String("a:miter")) { 0261 m_currentDrawStyle->addProperty("draw:stroke-linejoin", "miter"); 0262 } 0263 else if (qualifiedName() == QLatin1String("a:round")) { 0264 m_currentDrawStyle->addProperty("draw:stroke-linejoin", "round"); 0265 } 0266 0267 // //custom dash 0268 // else if(qualifiedName() == QLatin1String("a:custDash")) { 0269 // } 0270 // //extension list 0271 // else if(qualifiedName() == QLatin1String("a:extLst")) { 0272 // } 0273 // //gradient fill 0274 // else if(qualifiedName() == QLatin1String("a:gradFill")) { 0275 // } 0276 0277 // //pattern fill 0278 // else if(qualifiedName() == QLatin1String("a:pattFill")) { 0279 // } 0280 0281 //solid fill 0282 else if (qualifiedName() == QLatin1String("a:solidFill")) { 0283 TRY_READ(solidFill) 0284 m_currentDrawStyle->addProperty("svg:stroke-color", m_currentColor.name()); 0285 0286 // Opacity is disabled because there's a bug somewhere 0287 // which makes even 1% opacity hide lines. 0288 0289 // if (m_currentAlpha > 0) { 0290 // m_currentDrawStyle->addProperty("svg:stroke-opacity", 0291 // QString("%1%").arg(m_currentAlpha/100.0)); 0292 // } 0293 } 0294 else if (qualifiedName() == QLatin1String("a:noFill")) { 0295 m_currentDrawStyle->addProperty("draw:stroke", "none"); 0296 } 0297 else if (qualifiedName() == QLatin1String("a:prstDash")) { 0298 attrs = attributes(); 0299 TRY_READ_ATTR_WITHOUT_NS(val) 0300 QPen pen; 0301 pen.setWidthF(m_currentLineWidth); 0302 if (val == "dash") { 0303 pen.setStyle(Qt::DashLine); 0304 m_currentDrawStyle->addProperty("draw:stroke", "dash"); 0305 KoGenStyle dashStyle(KoGenStyle::StrokeDashStyle); 0306 dashStyle.addAttribute("draw:style", "rect"); 0307 QVector<qreal> dashes = pen.dashPattern(); 0308 dashStyle.addAttribute("draw:dots1", static_cast<int>(1)); 0309 dashStyle.addAttributePt("draw:dots1-length", dashes[0]*pen.widthF()); 0310 dashStyle.addAttributePt("draw:distance", dashes[1]*pen.widthF()); 0311 if (dashes.size() > 2) { 0312 dashStyle.addAttribute("draw:dots2", static_cast<int>(1)); 0313 dashStyle.addAttributePt("draw:dots2-length", dashes[2]*pen.widthF()); 0314 } 0315 QString dashStyleName = mainStyles->insert(dashStyle, "dash"); 0316 m_currentDrawStyle->addProperty("draw:stroke-dash", dashStyleName); 0317 // NOTE: A "dash" looks wrong in Calligra/LO when 0318 // svg:stroke-linecap is applied. 0319 m_currentDrawStyle->removeProperty("svg:stroke-linecap"); 0320 } 0321 } 0322 SKIP_UNKNOWN 0323 } 0324 } 0325 0326 READ_EPILOGUE 0327 } 0328 0329 #undef CURRENT_EL 0330 #define CURRENT_EL solidFill 0331 //! solidFill - Solid Fill 0332 /*! DrawingML ECMA-376 20.1.8.54, p. 3234. 0333 0334 This element specifies a solid color fill. The shape is filled entirely with 0335 the specified color. 0336 0337 Parents: 0338 - bg (§21.4.3.1) 0339 - bgFillStyleLst (§20.1.4.1.7) 0340 - bgPr (§19.3.1.2) 0341 - defRPr (§21.1.2.3.2) 0342 - endParaRPr (§21.1.2.2.3) 0343 - fill (§20.1.8.28) 0344 - fill (§20.1.4.2.9) 0345 - fillOverlay (§20.1.8.29) 0346 - fillStyleLst (§20.1.4.1.13) 0347 - grpSpPr (§21.3.2.14) 0348 - grpSpPr (§20.1.2.2.22) 0349 - grpSpPr (§20.5.2.18) 0350 - grpSpPr (§19.3.1.23) 0351 - ln (§20.1.2.2.24) 0352 - lnB (§21.1.3.5) 0353 - lnBlToTr (§21.1.3.6) 0354 - lnL (§21.1.3.7) 0355 - lnR (§21.1.3.8) 0356 - lnT (§21.1.3.9) 0357 - lnTlToBr (§21.1.3.10) 0358 - [done] rPr (§21.1.2.3.9) 0359 - spPr (§21.2.2.197) 0360 - spPr (§21.3.2.23) 0361 - spPr (§21.4.3.7) 0362 - [done] spPr (§20.1.2.2.35) 0363 - spPr (§20.2.2.6) 0364 - spPr (§20.5.2.30) 0365 - [done] spPr (§19.3.1.44) 0366 - tblPr (§21.1.3.15) 0367 - tcPr (§21.1.3.17) 0368 - uFill (§21.1.2.3.12) 0369 - uLn (§21.1.2.3.14) 0370 0371 Child elements: 0372 - [done] hslClr (Hue, Saturation, Luminance Color Model) §20.1.2.3.13 0373 - [done] prstClr (Preset Color) §20.1.2.3.22 0374 - [done] schemeClr (Scheme Color) §20.1.2.3.29 0375 - [done] scrgbClr (RGB Color Model - Percentage Variant) §20.1.2.3.30 0376 - [done] srgbClr (RGB Color Model - Hex Variant) §20.1.2.3.32 0377 - [done] sysClr (System Color) §20.1.2.3.33 0378 0379 Attributes: 0380 None. 0381 */ 0382 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_solidFill() 0383 { 0384 READ_PROLOGUE 0385 0386 while (!atEnd()) { 0387 readNext(); 0388 debugMsooXml << *this; 0389 BREAK_IF_END_OF(CURRENT_EL) 0390 if (isStartElement()) { 0391 TRY_READ_IF(scrgbClr) 0392 ELSE_TRY_READ_IF(schemeClr) 0393 ELSE_TRY_READ_IF(srgbClr) 0394 ELSE_TRY_READ_IF(sysClr) 0395 ELSE_TRY_READ_IF(prstClr) 0396 ELSE_TRY_READ_IF(hslClr) 0397 ELSE_WRONG_FORMAT 0398 } 0399 } 0400 READ_EPILOGUE 0401 } 0402 0403 //! fillREf handler (Fill reference) 0404 /* 0405 Parent elements: 0406 - [done] style (§21.3.2.24); 0407 - [done] style (§21.4.2.28); 0408 - [done] style (§20.1.2.2.37); 0409 - [done] style (§20.5.2.31); 0410 - [done] style (§19.3.1.46); 0411 - [done] tblBg (§20.1.4.2.25); 0412 - [done] tcStyle (§20.1.4.2.29) 0413 0414 Child elements: 0415 - [done] hslClr (Hue, Saturation, Luminance Color Model) §20.1.2.3.13 0416 - [done] prstClr (Preset Color) §20.1.2.3.22 0417 - [done] schemeClr (Scheme Color) §20.1.2.3.29 0418 - [done] scrgbClr (RGB Color Model - Percentage Variant) §20.1.2.3.30 0419 - [done] srgbClr (RGB Color Model - Hex Variant) §20.1.2.3.32 0420 - [done] sysClr (System Color) §20.1.2.3.33 0421 0422 */ 0423 #if !defined MSOOXML_THEMESREADER_CPP 0424 #undef CURRENT_EL 0425 #define CURRENT_EL fillRef 0426 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_fillRef() 0427 { 0428 READ_PROLOGUE 0429 const QXmlStreamAttributes attrs(attributes()); 0430 TRY_READ_ATTR_WITHOUT_NS(idx) 0431 int index = idx.toInt(); 0432 0433 // If it has draw:fill it means that the style has already been defined 0434 if (!m_currentDrawStyle->property("draw:fill").isEmpty()) { 0435 skipCurrentElement(); 0436 READ_EPILOGUE 0437 } 0438 0439 while (!atEnd()) { 0440 readNext(); 0441 debugMsooXml << *this; 0442 BREAK_IF_END_OF(CURRENT_EL) 0443 if (isStartElement()) { 0444 TRY_READ_IF(schemeClr) 0445 ELSE_TRY_READ_IF(scrgbClr) 0446 ELSE_TRY_READ_IF(sysClr) 0447 ELSE_TRY_READ_IF(srgbClr) 0448 ELSE_TRY_READ_IF(prstClr) 0449 ELSE_TRY_READ_IF(hslClr) 0450 ELSE_WRONG_FORMAT 0451 } 0452 } 0453 0454 MSOOXML::DrawingMLFillBase *fillBase = m_context->themes->formatScheme.fillStyles.value(index); 0455 if (fillBase) { 0456 fillBase->writeStyles(*mainStyles, m_currentDrawStyle, m_currentColor); 0457 } 0458 0459 READ_EPILOGUE 0460 } 0461 0462 #undef CURRENT_EL 0463 #define CURRENT_EL fontRef 0464 //! fontRef handler (Font reference) 0465 /* 0466 Parent elements: 0467 - [done] style (§21.3.2.24); 0468 - [done] style (§21.4.2.28); 0469 - [done] style (§20.1.2.2.37); 0470 - [done] style (§20.5.2.31); 0471 - [done] style (§19.3.1.46); 0472 - [done] tcTxStyle (§20.1.4.2.30) 0473 0474 Child elements: 0475 - [done] hslClr (Hue, Saturation, Luminance Color Model) §20.1.2.3.13 0476 - [done] prstClr (Preset Color) §20.1.2.3.22 0477 - [done] schemeClr (Scheme Color) §20.1.2.3.29 0478 - [done] scrgbClr (RGB Color Model - Percentage Variant) §20.1.2.3.30 0479 - [done] srgbClr (RGB Color Model - Hex Variant) §20.1.2.3.32 0480 - [done] sysClr (System Color) §20.1.2.3.33 0481 */ 0482 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_fontRef() 0483 { 0484 READ_PROLOGUE 0485 0486 const QXmlStreamAttributes attrs(attributes()); 0487 0488 TRY_READ_ATTR_WITHOUT_NS(idx) 0489 0490 if (!idx.isEmpty()) { 0491 if (idx.startsWith("major")) { 0492 m_referredFontName = m_context->themes->fontScheme.majorFonts.latinTypeface; 0493 } 0494 else if (idx.startsWith("minor")) { 0495 m_referredFontName = m_context->themes->fontScheme.minorFonts.latinTypeface; 0496 } 0497 } 0498 0499 while (!atEnd()) { 0500 readNext(); 0501 BREAK_IF_END_OF(CURRENT_EL) 0502 if (isStartElement()) { 0503 TRY_READ_IF(schemeClr) 0504 ELSE_TRY_READ_IF(srgbClr) 0505 ELSE_TRY_READ_IF(sysClr) 0506 ELSE_TRY_READ_IF(scrgbClr) 0507 ELSE_TRY_READ_IF(prstClr) 0508 ELSE_TRY_READ_IF(hslClr) 0509 ELSE_WRONG_FORMAT 0510 } 0511 } 0512 0513 READ_EPILOGUE 0514 } 0515 #endif //!defined MSOOXML_THEMESREADER_CPP 0516 0517 #undef CURRENT_EL 0518 #define CURRENT_EL hslClr 0519 //! hslClr (hue saturation luminance color) 0520 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_hslClr() 0521 { 0522 READ_PROLOGUE 0523 const QXmlStreamAttributes attrs(attributes()); 0524 0525 READ_ATTR_WITHOUT_NS(hue) 0526 READ_ATTR_WITHOUT_NS(sat) 0527 READ_ATTR_WITHOUT_NS(lum) 0528 0529 qreal trueHue = hue.toDouble() / 6000.0 / 360; 0530 qreal trueSat = sat.leftRef(sat.size() - 1).toDouble() / 100.0; 0531 qreal trueLum = lum.leftRef(lum.size() - 1).toDouble() / 100.0; 0532 0533 m_currentColor.setHslF(trueHue, trueSat, trueLum); 0534 0535 //TODO: all the color transformations 0536 while (!atEnd()) { 0537 readNext(); 0538 BREAK_IF_END_OF(CURRENT_EL) 0539 if (isStartElement()) { 0540 TRY_READ_IF(tint) 0541 ELSE_TRY_READ_IF(shade) 0542 ELSE_TRY_READ_IF(satMod) 0543 ELSE_TRY_READ_IF(alpha) 0544 SKIP_UNKNOWN 0545 } 0546 } 0547 0548 MSOOXML::Utils::modifyColor(m_currentColor, m_currentTint, m_currentShadeLevel, m_currentSatMod); 0549 0550 READ_EPILOGUE 0551 } 0552 0553 0554 #undef CURRENT_EL 0555 #define CURRENT_EL prstClr 0556 //! prstClr (preset color) 0557 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_prstClr() 0558 { 0559 READ_PROLOGUE 0560 const QXmlStreamAttributes attrs(attributes()); 0561 0562 TRY_READ_ATTR_WITHOUT_NS(val) 0563 0564 // TODO: support all of them.. 0565 if (!val.isEmpty()) { 0566 if (val == "aliceBlue") { 0567 m_currentColor = QColor(240, 248, 255); 0568 } 0569 else if (val == "antiqueWhite") { 0570 m_currentColor = QColor(250, 235, 215); 0571 } 0572 else if (val == "aqua") { 0573 m_currentColor = QColor(0, 255, 255); 0574 } 0575 else if (val == "aquamarine") { 0576 m_currentColor = QColor(127, 255, 212); 0577 } 0578 else if (val == "azure") { 0579 m_currentColor = QColor(240, 255, 255); 0580 } 0581 else if (val == "beige") { 0582 m_currentColor = QColor(245, 245, 220); 0583 } 0584 else if (val == "bisque") { 0585 m_currentColor = QColor(255, 228, 196); 0586 } 0587 else if (val == "black") { 0588 m_currentColor = QColor(0, 0, 0); 0589 } 0590 else if (val == "blue") { 0591 m_currentColor = QColor(0, 0, 215); 0592 } 0593 else if (val == "green") { 0594 m_currentColor = QColor(0, 255, 0); 0595 } 0596 else if (val == "red") { 0597 m_currentColor = QColor(255, 0, 0); 0598 } 0599 else if (val == "violet") { 0600 m_currentColor = QColor(238, 130, 238); 0601 } 0602 else if (val == "wheat") { 0603 m_currentColor = QColor(245, 222, 179); 0604 } 0605 else if (val == "white") { 0606 m_currentColor = QColor(255, 255, 255); 0607 } 0608 else if (val == "whiteSmoke") { 0609 m_currentColor = QColor(245, 245, 245); 0610 } 0611 else if (val == "yellow") { 0612 m_currentColor = QColor(255, 255, 0); 0613 } 0614 else if (val == "yellowGreen") { 0615 m_currentColor = QColor(154, 205, 50); 0616 } 0617 } 0618 0619 m_currentTint = 0; 0620 m_currentShadeLevel = 0; 0621 m_currentSatMod = 0; 0622 m_currentAlpha = 0; 0623 0624 //TODO: all the color transformations 0625 while (!atEnd()) { 0626 readNext(); 0627 BREAK_IF_END_OF(CURRENT_EL) 0628 if (isStartElement()) { 0629 TRY_READ_IF(tint) 0630 ELSE_TRY_READ_IF(shade) 0631 ELSE_TRY_READ_IF(satMod) 0632 ELSE_TRY_READ_IF(alpha) 0633 SKIP_UNKNOWN 0634 } 0635 } 0636 0637 MSOOXML::Utils::modifyColor(m_currentColor, m_currentTint, m_currentShadeLevel, m_currentSatMod); 0638 0639 READ_EPILOGUE 0640 } 0641 0642 /* 0643 This element specifies a color bound to a user's theme. As with all 0644 elements which define a color, it is possible to apply a list of color 0645 transforms to the base color defined. 0646 0647 Parent Elements 0648 - accent1 (§20.1.4.1.1) 0649 - accent2 (§20.1.4.1.2) 0650 - accent3 (§20.1.4.1.3) 0651 - accent4 (§20.1.4.1.4) 0652 - accent5 (§20.1.4.1.5) 0653 - accent6 (§20.1.4.1.6) 0654 - alphaInv (§20.1.8.4) 0655 - bgClr (§20.1.8.10) 0656 - bgRef (§19.3.1.3) 0657 - buClr (§21.1.2.4.4) 0658 - clrFrom (§20.1.8.17) 0659 - clrMru (§19.2.1.4) 0660 - clrRepl (§20.1.8.18) 0661 - clrTo (§20.1.8.19) 0662 - clrVal (§19.5.27) 0663 - contourClr (§20.1.5.6) 0664 - custClr (§20.1.4.1.8) 0665 - dk1 (§20.1.4.1.9) 0666 - dk2 (§20.1.4.1.10) 0667 - duotone (§20.1.8.23) 0668 - effectClrLst (§21.4.4.7) 0669 - effectRef (§20.1.4.2.8) 0670 - extrusionClr (§20.1.5.7) 0671 - fgClr (§20.1.8.27) 0672 - fillClrLst (§21.4.4.8) 0673 - fillRef (§20.1.4.2.10) 0674 - folHlink (§20.1.4.1.15) 0675 - fontRef (§20.1.4.1.17) 0676 - from (§19.5.43) 0677 - glow (§20.1.8.32) 0678 - gs (§20.1.8.36) 0679 - highlight (§21.1.2.3.4) 0680 - hlink (§20.1.4.1.19) 0681 - innerShdw (§20.1.8.40) 0682 - linClrLst (§21.4.4.9) 0683 - lnRef (§20.1.4.2.19) 0684 - lt1 (§20.1.4.1.22) 0685 - lt2 (§20.1.4.1.23) 0686 - outerShdw (§20.1.8.45) 0687 - penClr (§19.2.1.23) 0688 - prstShdw (§20.1.8.49) 0689 - [done] solidFill (§20.1.8.54) 0690 - tcTxStyle (§20.1.4.2.30) 0691 - to (§19.5.90) 0692 - txEffectClrLst (§21.4.4.12) 0693 - txFillClrLst (§21.4.4.13) 0694 - txLinClrLst (§21.4.4.14) 0695 0696 Child elements: 0697 - [done] alpha (Alpha) §20.1.2.3.1 0698 - alphaMod (Alpha Modulation) §20.1.2.3.2 0699 - alphaOff (Alpha Offset) §20.1.2.3.3 0700 - blue (Blue) §20.1.2.3.4 0701 - blueMod (Blue Modification) §20.1.2.3.5 0702 - blueOff (Blue Offset) §20.1.2.3.6 0703 - comp (Complement) §20.1.2.3.7 0704 - gamma (Gamma) §20.1.2.3.8 0705 - gray (Gray) §20.1.2.3.9 0706 - green (Green) §20.1.2.3.10 0707 - greenMod (Green Modification) §20.1.2.3.11 0708 - greenOff (Green Offset) §20.1.2.3.12 0709 - hue (Hue) §20.1.2.3.14 0710 - hueMod (Hue Modulate) §20.1.2.3.15 0711 - hueOff (Hue Offset) §20.1.2.3.16 0712 - inv (Inverse) §20.1.2.3.17 0713 - invGamma (Inverse Gamma) §20.1.2.3.18 0714 - lum (Luminance) §20.1.2.3.19 0715 - [done] lumMod (Luminance Modulation) §20.1.2.3.20 0716 - [done] lumOff (Luminance Offset) §20.1.2.3.21 0717 - red (Red) §20.1.2.3.23 0718 - redMod (Red Modulation) §20.1.2.3.24 0719 - redOff (Red Offset) §20.1.2.3.25 0720 - sat (Saturation) §20.1.2.3.26 0721 - [done] satMod (Saturation Modulation) §20.1.2.3.27 0722 - satOff (Saturation Offset) §20.1.2.3.28 0723 - shade (Shade) §20.1.2.3.31 0724 - [done] tint (Tint) §20.1.2.3.34 0725 0726 Attributes 0727 - val (Value) Specifies the desired scheme. 0728 */ 0729 #undef CURRENT_EL 0730 #define CURRENT_EL schemeClr 0731 //! @todo support all child elements 0732 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_schemeClr() 0733 { 0734 READ_PROLOGUE 0735 0736 const QXmlStreamAttributes attrs(attributes()); 0737 READ_ATTR_WITHOUT_NS(val) 0738 0739 #ifdef PPTXXMLDOCUMENTREADER_CPP 0740 // Skip the rest of the code, the color scheme map (clrMap) is unknown at 0741 // time of reading. 0742 if (m_colorState == PptxXmlDocumentReader::defRPrState) { 0743 defaultTextColors[defaultTextColors.size() - 1] = val; 0744 } 0745 else { 0746 defaultBulletColors[defaultBulletColors.size() - 1] = val; 0747 } 0748 skipCurrentElement(); 0749 READ_EPILOGUE 0750 #endif 0751 0752 m_currentTint = 0; 0753 m_currentShadeLevel = 0; 0754 m_currentSatMod = 0; 0755 m_currentAlpha = 0; 0756 0757 MSOOXML::DrawingMLColorSchemeItemBase *colorItem = 0; 0758 0759 #if !defined MSOOXML_THEMESREADER_CPP 0760 QString valTransformed = m_context->colorMap.value(val); 0761 if (valTransformed.isEmpty()) { 0762 // In some cases, such as fontRef, mapping is bypassed 0763 colorItem = m_context->themes->colorScheme.value(val); 0764 } else { 0765 colorItem = m_context->themes->colorScheme.value(valTransformed); 0766 } 0767 #endif 0768 0769 // Parse the child elements 0770 MSOOXML::Utils::DoubleModifier lumMod; 0771 MSOOXML::Utils::DoubleModifier lumOff; 0772 while (!atEnd()) { 0773 readNext(); 0774 BREAK_IF_END_OF(CURRENT_EL) 0775 if (isStartElement()) { 0776 // @todo: Hmm, are these color modifications only available for pptx? 0777 if (QUALIFIED_NAME_IS(lumMod)) { 0778 m_currentDoubleValue = &lumMod.value; 0779 TRY_READ(lumMod) 0780 lumMod.valid = true; 0781 } else if (QUALIFIED_NAME_IS(lumOff)) { 0782 m_currentDoubleValue = &lumOff.value; 0783 TRY_READ(lumOff) 0784 lumOff.valid = true; 0785 } 0786 ELSE_TRY_READ_IF(shade) 0787 ELSE_TRY_READ_IF(tint) 0788 ELSE_TRY_READ_IF(satMod) 0789 ELSE_TRY_READ_IF(alpha) 0790 SKIP_UNKNOWN 0791 } 0792 } 0793 0794 QColor col = Qt::white; 0795 if (colorItem) { 0796 col = colorItem->value(); 0797 } 0798 0799 col = MSOOXML::Utils::colorForLuminance(col, lumMod, lumOff); 0800 m_currentColor = col; 0801 0802 MSOOXML::Utils::modifyColor(m_currentColor, m_currentTint, m_currentShadeLevel, m_currentSatMod); 0803 0804 READ_EPILOGUE 0805 } 0806 0807 #undef CURRENT_EL 0808 #define CURRENT_EL sysClr 0809 //! sysClr handler 0810 // SysClr is bit controversial, it is supposed to use 0811 // color defined by the system at the moment, the document is read 0812 // however, it often means that when reading the document, it is not 0813 // using the same colors, the creator wished. 0814 // Sometimes sysclr saves attribute lastClr which tells which color 0815 // the creator was using, the current implementation uses that 0816 // and ignores real system colors. 0817 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_sysClr() 0818 { 0819 READ_PROLOGUE 0820 const QXmlStreamAttributes attrs(attributes()); 0821 0822 m_currentTint = 0; 0823 m_currentShadeLevel = 0; 0824 m_currentSatMod = 0; 0825 m_currentAlpha = 0; 0826 0827 TRY_READ_ATTR_WITHOUT_NS(lastClr) 0828 0829 if (!lastClr.isEmpty()) { 0830 m_currentColor = QColor( QLatin1Char('#') + lastClr ); 0831 } 0832 0833 //TODO: all the color transformations 0834 while (!atEnd()) { 0835 readNext(); 0836 BREAK_IF_END_OF(CURRENT_EL) 0837 if (isStartElement()) { 0838 TRY_READ_IF(tint) 0839 ELSE_TRY_READ_IF(shade) 0840 ELSE_TRY_READ_IF(satMod) 0841 ELSE_TRY_READ_IF(alpha) 0842 SKIP_UNKNOWN 0843 } 0844 } 0845 0846 MSOOXML::Utils::modifyColor(m_currentColor, m_currentTint, m_currentShadeLevel, m_currentSatMod); 0847 0848 READ_EPILOGUE 0849 } 0850 0851 #undef CURRENT_EL 0852 #define CURRENT_EL scrgbClr 0853 //! RGB Color Model - Percentage Variant 0854 //! DrawingML ECMA-376 20.1.2.3.30, p. 3074. 0855 /*! 0856 This element specifies a solid color fill. 0857 0858 Child elements: 0859 - [done] alpha (Alpha) §20.1.2.3.1 0860 - alphaMod (Alpha Modulation) §20.1.2.3.2 0861 - alphaOff (Alpha Offset) §20.1.2.3.3 0862 - blue (Blue) §20.1.2.3.4 0863 - blueMod (Blue Modification) §20.1.2.3.5 0864 - blueOff (Blue Offset) §20.1.2.3.6 0865 - comp (Complement) §20.1.2.3.7 0866 - gamma (Gamma) §20.1.2.3.8 0867 - gray (Gray) §20.1.2.3.9 0868 - green (Green) §20.1.2.3.10 0869 - greenMod (Green Modification) §20.1.2.3.11 0870 - greenOff (Green Offset) §20.1.2.3.12 0871 - hue (Hue) §20.1.2.3.14 0872 - hueMod (Hue Modulate) §20.1.2.3.15 0873 - hueOff (Hue Offset) §20.1.2.3.16 0874 - [done] inv (Inverse) §20.1.2.3.17 0875 - invGamma (Inverse Gamma) §20.1.2.3.18 0876 - lum (Luminance) §20.1.2.3.19 0877 - lumMod (Luminance Modulation) §20.1.2.3.20 0878 - lumOff (Luminance Offset) §20.1.2.3.21 0879 - red (Red) §20.1.2.3.23 0880 - redMod (Red Modulation) §20.1.2.3.24 0881 - redOff (Red Offset) §20.1.2.3.25 0882 0883 Attributes: 0884 - [done] b (blue) 0885 - [done] g (green) 0886 - [done] r (red) 0887 */ 0888 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_scrgbClr() 0889 { 0890 READ_PROLOGUE 0891 0892 const QXmlStreamAttributes attrs(attributes()); 0893 0894 m_currentTint = 0; 0895 m_currentShadeLevel = 0; 0896 m_currentSatMod = 0; 0897 m_currentAlpha = 0; 0898 0899 READ_ATTR_WITHOUT_NS(r) 0900 READ_ATTR_WITHOUT_NS(g) 0901 READ_ATTR_WITHOUT_NS(b) 0902 0903 bool okR, okG, okB; 0904 0905 m_currentColor = QColor::fromRgbF(qreal(MSOOXML::Utils::ST_Percentage_to_double(r, okR)), 0906 qreal(MSOOXML::Utils::ST_Percentage_to_double(g, okG)), 0907 qreal(MSOOXML::Utils::ST_Percentage_to_double(b, okB))); 0908 0909 //TODO: all the color transformations 0910 while (!atEnd()) { 0911 readNext(); 0912 BREAK_IF_END_OF(CURRENT_EL) 0913 if (isStartElement()) { 0914 TRY_READ_IF(tint) 0915 ELSE_TRY_READ_IF(alpha) 0916 SKIP_UNKNOWN 0917 } 0918 } 0919 0920 MSOOXML::Utils::modifyColor(m_currentColor, m_currentTint, m_currentShadeLevel, m_currentSatMod); 0921 0922 READ_EPILOGUE 0923 } 0924 0925 #undef CURRENT_EL 0926 #define CURRENT_EL srgbClr 0927 //! srgbClr (RGB Color Model - Hex Variant) 0928 //! DrawingML ECMA-376 20.1.2.3.32, p. 3085. 0929 /*! 0930 This element specifies a color in RGB notation. 0931 0932 Child elements: 0933 - alpha (Alpha) §20.1.2.3.1 0934 - alphaMod (Alpha Modulation) §20.1.2.3.2 0935 - alphaOff (Alpha Offset) §20.1.2.3.3 0936 - blue (Blue) §20.1.2.3.4 0937 - blueMod (Blue Modification) §20.1.2.3.5 0938 - blueOff (Blue Offset) §20.1.2.3.6 0939 - comp (Complement) §20.1.2.3.7 0940 - gamma (Gamma) §20.1.2.3.8 0941 - gray (Gray) §20.1.2.3.9 0942 - green (Green) §20.1.2.3.10 0943 - greenMod (Green Modification) §20.1.2.3.11 0944 - greenOff (Green Offset) §20.1.2.3.12 0945 - hue (Hue) §20.1.2.3.14 0946 - hueMod (Hue Modulate) §20.1.2.3.15 0947 - hueOff (Hue Offset) §20.1.2.3.16 0948 - inv (Inverse) §20.1.2.3.17 0949 - invGamma (Inverse Gamma) §20.1.2.3.18 0950 - lum (Luminance) §20.1.2.3.19 0951 - lumMod (Luminance Modulation) §20.1.2.3.20 0952 - lumOff (Luminance Offset) §20.1.2.3.21 0953 - red (Red) §20.1.2.3.23 0954 - redMod (Red Modulation) §20.1.2.3.24 0955 - redOff (Red Offset) §20.1.2.3.25 0956 - sat (Saturation) §20.1.2.3.26 0957 - [done] satMod (Saturation Modulation) §20.1.2.3.27 0958 - satOff (Saturation Offset) §20.1.2.3.28 0959 - [done] shade (Shade) §20.1.2.3.31 0960 - [done] tint (Tint) §20.1.2.3.34 0961 0962 Attributes: 0963 - [done] val ("RRGGBB" hex digits) 0964 */ 0965 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_srgbClr() 0966 { 0967 READ_PROLOGUE 0968 0969 const QXmlStreamAttributes attrs(attributes()); 0970 0971 m_currentTint = 0; 0972 m_currentShadeLevel = 0; 0973 m_currentSatMod = 0; 0974 m_currentAlpha = 0; 0975 0976 READ_ATTR_WITHOUT_NS(val) 0977 0978 m_currentColor = QColor( QLatin1Char('#') + val ); 0979 0980 //TODO: all the color transformations 0981 while (!atEnd()) { 0982 readNext(); 0983 BREAK_IF_END_OF(CURRENT_EL) 0984 if (isStartElement()) { 0985 TRY_READ_IF(tint) 0986 ELSE_TRY_READ_IF(shade) 0987 ELSE_TRY_READ_IF(satMod) 0988 ELSE_TRY_READ_IF(alpha) 0989 SKIP_UNKNOWN 0990 } 0991 } 0992 0993 MSOOXML::Utils::modifyColor(m_currentColor, m_currentTint, m_currentShadeLevel, m_currentSatMod); 0994 0995 READ_EPILOGUE 0996 } 0997 0998 #undef CURRENT_EL 0999 #define CURRENT_EL shade 1000 //! shade (shade value) 1001 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_shade() 1002 { 1003 READ_PROLOGUE 1004 const QXmlStreamAttributes attrs(attributes()); 1005 TRY_READ_ATTR_WITHOUT_NS(val) 1006 1007 if (!val.isEmpty()) { 1008 bool ok = false; 1009 int value = val.toInt(&ok); 1010 if (!ok) { 1011 value = 0; 1012 } 1013 m_currentShadeLevel = value/100000.0; // To get percentage (form 0.x) 1014 } 1015 1016 readNext(); 1017 READ_EPILOGUE 1018 } 1019 1020 #undef CURRENT_EL 1021 #define CURRENT_EL tint 1022 //! tint (tint value) 1023 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tint() 1024 { 1025 READ_PROLOGUE 1026 const QXmlStreamAttributes attrs(attributes()); 1027 TRY_READ_ATTR_WITHOUT_NS(val) 1028 1029 if (!val.isEmpty()) { 1030 bool ok = false; 1031 int value = val.toInt(&ok); 1032 if (!ok) { 1033 value = 0; 1034 } 1035 m_currentTint = value/100000.0; // To get percentage (form 0.x) 1036 } 1037 1038 readNext(); 1039 READ_EPILOGUE 1040 } 1041 1042 #undef CURRENT_EL 1043 #define CURRENT_EL alpha 1044 //! alpha (alpha value) 1045 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_alpha() 1046 { 1047 READ_PROLOGUE 1048 const QXmlStreamAttributes attrs(attributes()); 1049 TRY_READ_ATTR_WITHOUT_NS(val) 1050 1051 if (!val.isEmpty()) { 1052 bool ok = false; 1053 int value = val.toInt(&ok); 1054 if (!ok) { 1055 value = 0; 1056 } 1057 m_currentAlpha = value/1000; // To get percentage 1058 } 1059 1060 readNext(); 1061 READ_EPILOGUE 1062 } 1063 1064 #undef CURRENT_EL 1065 #define CURRENT_EL lumMod 1066 //! 20.1.2.3.20 lumMod (Luminance Modulation) 1067 //! This element specifies the input color with its luminance modulated by the given percentage. 1068 //! @todo support all child elements 1069 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lumMod() 1070 { 1071 READ_PROLOGUE 1072 const QXmlStreamAttributes attrs(attributes()); 1073 READ_ATTR_WITHOUT_NS(val) 1074 1075 bool ok; 1076 Q_ASSERT(m_currentDoubleValue); 1077 *m_currentDoubleValue = MSOOXML::Utils::ST_Percentage_withMsooxmlFix_to_double(val, ok); 1078 if (!ok) 1079 return KoFilter::WrongFormat; 1080 1081 readNext(); 1082 READ_EPILOGUE 1083 } 1084 1085 #undef CURRENT_EL 1086 #define CURRENT_EL satMod 1087 //! satMod (Saturation modulation value) 1088 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_satMod() 1089 { 1090 READ_PROLOGUE 1091 const QXmlStreamAttributes attrs(attributes()); 1092 TRY_READ_ATTR_WITHOUT_NS(val) 1093 1094 if (!val.isEmpty()) { 1095 bool ok = false; 1096 int value = val.toInt(&ok); 1097 if (!ok) { 1098 value = 0; 1099 } 1100 m_currentSatMod = value/100000.0; // To get percentage in from 0.x 1101 } 1102 1103 readNext(); 1104 READ_EPILOGUE 1105 } 1106 1107 #undef CURRENT_EL 1108 #define CURRENT_EL lumOff 1109 //! 20.1.2.3.21 lumOff (Luminance Offset) 1110 //! This element specifies the input color with its luminance shifted, but with its hue and saturation unchanged. 1111 //! @todo support all child elements 1112 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lumOff() 1113 { 1114 READ_PROLOGUE 1115 const QXmlStreamAttributes attrs(attributes()); 1116 READ_ATTR_WITHOUT_NS(val) 1117 1118 bool ok; 1119 Q_ASSERT(m_currentDoubleValue); 1120 *m_currentDoubleValue = MSOOXML::Utils::ST_Percentage_withMsooxmlFix_to_double(val, ok); 1121 if (!ok) 1122 return KoFilter::WrongFormat; 1123 1124 readNext(); 1125 READ_EPILOGUE 1126 } 1127 1128 //! tailEnd (Tail line end style) 1129 //! DrawingML ECMA-376 20.1.8.57, p.3232 1130 /*! 1131 This element specifies decorations which can be added to the tail of 1132 a line. 1133 1134 Parent Elements: 1135 - [done] ln (§20.1.2.2.24); 1136 - lnB (§21.1.3.5); 1137 - lnBlToTr (§21.1.3.6); 1138 - lnL (§21.1.3.7); 1139 - lnR (§21.1.3.8); 1140 - lnT (§21.1.3.9); 1141 - lnTlToBr (§21.1.3.10); 1142 - uLn (§21.1.2.3.14) 1143 1144 Attributes: 1145 - len (Length of Head/End) 1146 - [done] type (Line Head/End Type) 1147 - w (Width of Head/End) 1148 1149 TODO: merge the following two readers 1150 */ 1151 #undef CURRENT_EL 1152 #define CURRENT_EL tailEnd 1153 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tailEnd() 1154 { 1155 READ_PROLOGUE 1156 const QXmlStreamAttributes attrs(attributes()); 1157 TRY_READ_ATTR_WITHOUT_NS(type) 1158 TRY_READ_ATTR_WITHOUT_NS(w) 1159 1160 if (!type.isEmpty() && type != "none") { 1161 // draw:marker-end 1162 m_currentDrawStyle->addProperty("draw:marker-end", MSOOXML::Utils::defineMarkerStyle(*mainStyles, type)); 1163 // draw:marker-end-center 1164 m_currentDrawStyle->addProperty("draw:marker-end-center", "false"); 1165 // draw:marker-end-width 1166 m_currentDrawStyle->addPropertyPt("draw:marker-end-width", 1167 MSOOXML::Utils::defineMarkerWidth(w, m_currentLineWidth)); 1168 } 1169 1170 readNext(); 1171 READ_EPILOGUE 1172 } 1173 1174 #undef CURRENT_EL 1175 #define CURRENT_EL headEnd 1176 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_headEnd() 1177 { 1178 READ_PROLOGUE 1179 const QXmlStreamAttributes attrs(attributes()); 1180 TRY_READ_ATTR_WITHOUT_NS(type) 1181 TRY_READ_ATTR_WITHOUT_NS(w) 1182 1183 if (!type.isEmpty() && type != "none") { 1184 // draw:marker-start 1185 m_currentDrawStyle->addProperty("draw:marker-start", MSOOXML::Utils::defineMarkerStyle(*mainStyles, type)); 1186 // draw:marker-start-center 1187 m_currentDrawStyle->addProperty("draw:marker-start-center", "false"); 1188 // draw:marker-start-width 1189 m_currentDrawStyle->addPropertyPt("draw:marker-start-width", 1190 MSOOXML::Utils::defineMarkerWidth(w, m_currentLineWidth)); 1191 } 1192 1193 readNext(); 1194 READ_EPILOGUE 1195 } 1196 1197 #endif