From ce0f8251d3625ab9aff25a3cc15f7b00e3c24969 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Fri, 22 Nov 2024 17:32:40 +0500 Subject: [PATCH] Fix bug #69238 --- OOXML/PPTXFormat/Logic/EffectLst.cpp | 20 +++++ OOXML/PPTXFormat/Logic/EffectLst.h | 3 + OOXML/PPTXFormat/Logic/EffectProperties.h | 9 +++ OOXML/PPTXFormat/Logic/SpPr.cpp | 2 + OdfFile/Writer/Converter/ConvertDrawing.cpp | 80 ++++++++++++------- .../Writer/Format/Shapes/odf_shape_mapping.h | 14 ++-- OdfFile/Writer/Format/odf_drawing_context.cpp | 18 ++--- 7 files changed, 103 insertions(+), 43 deletions(-) diff --git a/OOXML/PPTXFormat/Logic/EffectLst.cpp b/OOXML/PPTXFormat/Logic/EffectLst.cpp index f3b7e6f325..e54ccad18b 100644 --- a/OOXML/PPTXFormat/Logic/EffectLst.cpp +++ b/OOXML/PPTXFormat/Logic/EffectLst.cpp @@ -198,6 +198,26 @@ namespace PPTX pReader->Seek(_end_rec); } + void EffectLst::Merge(EffectLst& effectLst) const + { + if (blur.IsInit()) + effectLst.blur = blur; + if (fillOverlay.IsInit()) + effectLst.fillOverlay = fillOverlay; + if (glow.IsInit()) + effectLst.glow = glow; + if (innerShdw.IsInit()) + effectLst.innerShdw = innerShdw; + if (outerShdw.IsInit()) + effectLst.outerShdw = outerShdw; + if (prstShdw.IsInit()) + effectLst.prstShdw = prstShdw; + if (reflection.IsInit()) + effectLst.reflection = reflection; + if (softEdge.IsInit()) + effectLst.softEdge = softEdge; + } + void EffectLst::FillParentPointersForChilds() { if(blur.IsInit()) diff --git a/OOXML/PPTXFormat/Logic/EffectLst.h b/OOXML/PPTXFormat/Logic/EffectLst.h index e1095262be..d57314d62b 100644 --- a/OOXML/PPTXFormat/Logic/EffectLst.h +++ b/OOXML/PPTXFormat/Logic/EffectLst.h @@ -72,6 +72,9 @@ namespace PPTX virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + void Merge(EffectLst& effectLst) const; + public: nullable blur; nullable fillOverlay; diff --git a/OOXML/PPTXFormat/Logic/EffectProperties.h b/OOXML/PPTXFormat/Logic/EffectProperties.h index 42446a965f..da3c773ad2 100644 --- a/OOXML/PPTXFormat/Logic/EffectProperties.h +++ b/OOXML/PPTXFormat/Logic/EffectProperties.h @@ -145,6 +145,15 @@ namespace PPTX List->toXmlWriter(pWriter); } + void Merge(EffectProperties& effectProperties) const + { + if (List.IsInit() && List.is()) + { + effectProperties.List.reset(new EffectLst()); + List.as().Merge(effectProperties.List.as()); + } + } + nullable List; protected: virtual void FillParentPointersForChilds(){}; diff --git a/OOXML/PPTXFormat/Logic/SpPr.cpp b/OOXML/PPTXFormat/Logic/SpPr.cpp index bd8f71c5f3..e67a10f515 100644 --- a/OOXML/PPTXFormat/Logic/SpPr.cpp +++ b/OOXML/PPTXFormat/Logic/SpPr.cpp @@ -181,6 +181,8 @@ namespace PPTX spPr.Fill = Fill;//.fromXML(Fill.toXML()); if(ln.IsInit()) ln->Merge(spPr.ln); + + EffectList.Merge(spPr.EffectList); } void SpPr::FillParentPointersForChilds() { diff --git a/OdfFile/Writer/Converter/ConvertDrawing.cpp b/OdfFile/Writer/Converter/ConvertDrawing.cpp index 6576ee1b69..ecbd8a6aac 100644 --- a/OdfFile/Writer/Converter/ConvertDrawing.cpp +++ b/OdfFile/Writer/Converter/ConvertDrawing.cpp @@ -239,8 +239,8 @@ void OoxConverter::convert(PPTX::Logic::Xfrm *oox_xfrm) if (oox_xfrm->flipH.get_value_or(false)) odf_context()->drawing_context()->set_flip_H(true); if (oox_xfrm->flipV.get_value_or(false)) odf_context()->drawing_context()->set_flip_V(true); - if (oox_xfrm->rot.get_value_or(0) > 0) - odf_context()->drawing_context()->set_rotate(360. - oox_xfrm->rot.get_value_or(0)/60000.); + if (oox_xfrm->rot.IsInit()) + odf_context()->drawing_context()->set_rotate(oox_xfrm->rot.get_value_or(0)/60000.); } void OoxConverter::convert(PPTX::Logic::Xfrm *oox_txbx, PPTX::Logic::Xfrm *oox_xfrm) { @@ -1091,14 +1091,60 @@ void OoxConverter::convert(PPTX::Logic::PrstGeom *oox_geom) odf_context()->drawing_context()->add_modifier(oox_geom->avLst[i].fmla.get_value_or(L"0")); } } + +static std::wstring process_gd_formula(const PPTX::Logic::Gd& gd, std::vector>& deferred_formulas, size_t& last_gd_index) +{ + std::vector args; + boost::algorithm::split(args, gd.fmla.get_value_or(L""), boost::is_any_of("\t "), boost::token_compress_on); + + std::wstring fmla = gd.fmla.get_value_or(L""); + + if (args.size() >= 4 && gd.GetFormulaType(args.front()) == 0) // if formula is "('*/') - Multiply Divide Formula" + { + if (boost::algorithm::starts_with(args[3], L"gd")) + { + const std::wstring abs_name = std::wstring(L"gd") + std::to_wstring(last_gd_index + 1); + const std::wstring abs_fmla = L"abs " + args[3]; + + const std::wstring cmp_name = std::wstring(L"gd") + std::to_wstring(last_gd_index + 2); + const std::wstring cmp_fmla = L"?: " + abs_name + L" " + args[3] + L" 1"; + + last_gd_index += 2; + + deferred_formulas.push_back(std::make_pair(abs_name, abs_fmla)); + deferred_formulas.push_back(std::make_pair(cmp_name, cmp_fmla)); + + args[3] = cmp_name; + + fmla = boost::algorithm::join(args, L" "); + } + } + + return fmla; +} + void OoxConverter::convert(PPTX::Logic::CustGeom *oox_cust_geom) { if (!oox_cust_geom) return; - for (size_t i = 0; i < oox_cust_geom->gdLst.size(); i++) + if (oox_cust_geom->gdLst.size()) { - odf_context()->drawing_context()->add_formula(oox_cust_geom->gdLst[i].name.get_value_or(L""), oox_cust_geom->gdLst[i].fmla.get_value_or(L"")); + std::vector> deferred_formulas; + size_t last_gd_index = oox_cust_geom->gdLst.size() - 1; + + for (size_t i = 0; i < oox_cust_geom->gdLst.size(); i++) + { + const PPTX::Logic::Gd& gd = oox_cust_geom->gdLst[i]; + + const std::wstring fmla = process_gd_formula(gd, deferred_formulas, last_gd_index); + + odf_context()->drawing_context()->add_formula(gd.name.get_value_or(L""), fmla); + } + + for (const auto& gd : deferred_formulas) + odf_context()->drawing_context()->add_formula(gd.first, gd.second); } + for (size_t i = 0; i < oox_cust_geom->pathLst.size(); i++) { convert(&oox_cust_geom->pathLst[i]); @@ -1285,35 +1331,17 @@ void OoxConverter::convert(PPTX::Logic::Path2D *oox_geom_path) odf_context()->drawing_context()->set_viewBox(oox_geom_path->w.get_value_or(0), oox_geom_path->h.get_value_or(0)); - if (oox_geom_path->fill.IsInit()) - { - odf_context()->drawing_context()->start_area_properties(); - switch(oox_geom_path->fill->GetBYTECode()) - { - case 0://darken - case 1://darkenLess - case 2://lighten - case 3://lightenLess - break; - case 4: - odf_context()->drawing_context()->set_no_fill(); - break; - case 5: - default: - break; - } - odf_context()->drawing_context()->end_area_properties(); - } for (size_t i = 0 ; i < oox_geom_path->Paths.size(); i++) { if (oox_geom_path->Paths[i].Path2D.is()) - { convert(&oox_geom_path->Paths[i].Path2D.as()); - } } if (oox_geom_path->stroke.IsInit() && *oox_geom_path->stroke == false) odf_context()->drawing_context()->add_path_element(std::wstring(L"S"), L""); + + if(oox_geom_path->fill.IsInit() && oox_geom_path->fill->GetBYTECode() == 4) // fill == "none" + odf_context()->drawing_context()->add_path_element(std::wstring(L"F"), L""); odf_context()->drawing_context()->add_path_element(std::wstring(L"N"), L""); } @@ -1335,8 +1363,6 @@ void OoxConverter::convert(PPTX::Logic::PathBase *oox_path) if (quadBezTo) convert(quadBezTo); if (arcTo) convert(arcTo); if (close) convert(close); - - } void OoxConverter::convert(PPTX::Logic::BlipFill *oox_bitmap_fill) diff --git a/OdfFile/Writer/Format/Shapes/odf_shape_mapping.h b/OdfFile/Writer/Format/Shapes/odf_shape_mapping.h index d68c7d66ff..8500188608 100644 --- a/OdfFile/Writer/Format/Shapes/odf_shape_mapping.h +++ b/OdfFile/Writer/Format/Shapes/odf_shape_mapping.h @@ -62,7 +62,7 @@ namespace cpdoccore { L"" , drawCustom}, // shapetypeAccentCallout1, { L"" , drawCustom}, // shapetypeAccentCallout2, { L"" , drawCustom}, // shapetypeAccentCallout3, - { L"actionButtonBackPrevious" , drawCustom}, // shapetypeActionButtonBackPrevious, //mso-spt194 + { L"mso-spt194" , drawCustom}, // shapetypeActionButtonBackPrevious, { L"mso-spt196" , drawCustom}, // shapetypeActionButtonBeginning, { L"mso-spt189" , drawCustom}, // shapetypeActionButtonBlank, { L"mso-spt198" , drawCustom}, // shapetypeActionButtonDocument, @@ -72,7 +72,7 @@ namespace cpdoccore { L"mso-spt190" , drawCustom}, // shapetypeActionButtonHome, { L"mso-spt192" , drawCustom}, // shapetypeActionButtonInformation, { L"mso-spt200" , drawCustom}, // shapetypeActionButtonMovie, - { L"mso-spt19drawCustom" , drawCustom}, // shapetypeActionButtonReturn, + { L"mso-spt197" , drawCustom}, // shapetypeActionButtonReturn, { L"mso-spt199" , drawCustom}, // shapetypeActionButtonSound, { L"" , drawCustom}, // shapetypeArc, { L"" , drawCustom}, // shapetypeBentArrow, @@ -243,19 +243,19 @@ namespace cpdoccore { L"" , drawCustom}, // shapetypeWedgeEllipseCallout, { L"" , drawCustom}, // shapetypeWedgeRectCallout, { L"" , drawCustom}, // shapetypeWedgeRoundRectCallout, - { L"mso-spt1drawCustom" , drawCustom}, // shapetypeBallon, + { L"mso-spt17" , drawCustom}, // shapetypeBallon, { L"up-right-arrow" , drawCustom}, // shapetypeRightUpArrow, { L"fontwork-arch-down-pour" , drawCustom}, // shapetypeTextArchDownPour, { L"fontwork-arch-up-pour" , drawCustom}, // shapetypeTextArchUpPour, - { L"mso-spt1drawCustom5" , drawCustom}, // shapetypeTextCanDown, - { L"mso-spt1drawCustom4" , drawCustom}, // shapetypeTextCanUp, + { L"mso-spt175" , drawCustom}, // shapetypeTextCanDown, + { L"mso-spt174" , drawCustom}, // shapetypeTextCanUp, { L"fontwork-circle-pour" , drawCustom}, // shapetypeTextCirclePour, { L"fontwork-curve-down" , drawCustom}, // shapetypeTextCurveDown, { L"fontwork-curve-up" , drawCustom}, // shapetypeTextCurveUp, { L"mso-spt161" , drawCustom}, // shapetypeTextDeflate, { L"mso-spt163" , drawCustom}, // shapetypeTextDeflateBottom, { L"mso-spt166" , drawCustom}, // shapetypeTextDeflateInflate, - { L"mso-spt16drawCustom" , drawCustom}, // shapetypeTextDeflateInflateDeflat, + { L"mso-spt167" , drawCustom}, // shapetypeTextDeflateInflateDeflat, { L"mso-spt165" , drawCustom}, // shapetypeTextDeflateTop, { L"mso-spt158" , drawCustom}, // shapetypeTextDoubleWave1, { L"fontwork-fade-down" , drawCustom}, // shapetypeTextFadeDown, @@ -267,7 +267,7 @@ namespace cpdoccore { L"mso-spt142" , drawCustom}, // shapetypeTextRingInside, { L"mso-spt143" , drawCustom}, // shapetypeTextRingOutside, { L"fontwork-wave" , drawCustom}, // shapetypeTextWave1, - { L"mso-spt15drawCustom" , drawCustom}, // shapetypeTextWave2, + { L"mso-spt157" , drawCustom}, // shapetypeTextWave2, { L"mso-spt159" , drawCustom}, // shapetypeTextWave4, { L"mso-spt14" , drawCustom} // shapetypeThickArrow }; diff --git a/OdfFile/Writer/Format/odf_drawing_context.cpp b/OdfFile/Writer/Format/odf_drawing_context.cpp index a22f37de09..fb1a87307b 100644 --- a/OdfFile/Writer/Format/odf_drawing_context.cpp +++ b/OdfFile/Writer/Format/odf_drawing_context.cpp @@ -1663,7 +1663,8 @@ void odf_drawing_context::add_path_element(std::wstring command, std::wstring st { XmlUtils::replace_all(strE, L"gd", L"?f"); - if (command != impl_->current_drawing_state_.path_last_command_) + if (command != impl_->current_drawing_state_.path_last_command_ + || command == L"M") // NOTE: Две последовательые команды "Move" должны быть записаны без сокращений (включая команду "M" для каждого мува) { impl_->current_drawing_state_.path_ += command; if (!strE.empty()) @@ -1712,10 +1713,10 @@ int GetFormulaType2(const WCHAR& c1, const WCHAR& c2) static std::wstring replace_textarea(std::wstring textarea_coord) { - XmlUtils::replace_all(textarea_coord, L"t", L"top"); - XmlUtils::replace_all(textarea_coord, L"l", L"left"); - XmlUtils::replace_all(textarea_coord, L"r", L"right"); - XmlUtils::replace_all(textarea_coord, L"b", L"bottom"); + XmlUtils::replace_all(textarea_coord, L"t", L"0"); + XmlUtils::replace_all(textarea_coord, L"l", L"0"); + XmlUtils::replace_all(textarea_coord, L"r", L"logwidth"); + XmlUtils::replace_all(textarea_coord, L"b", L"logheight"); return textarea_coord; } @@ -1861,8 +1862,8 @@ void odf_drawing_context::add_formula (std::wstring name, std::wstring fmla) } XmlUtils::replace_all(odf_fmla, L"gd", L"?f"); - XmlUtils::replace_all(odf_fmla, L"h", L"(bottom-top)"); - XmlUtils::replace_all(odf_fmla, L"w", L"(right-left)"); + XmlUtils::replace_all(odf_fmla, L"h", L"logheight"); + XmlUtils::replace_all(odf_fmla, L"w", L"logwidth"); XmlUtils::replace_all(odf_fmla, L"adj", L"$"); //XmlUtils::replace_all(name, L"gd", L"f"); @@ -1904,8 +1905,7 @@ void odf_drawing_context::set_flip_V(bool bVal) void odf_drawing_context::set_rotate(double dVal) { - if (dVal > 180) dVal = dVal - 360; - double dRotate = dVal / 180. * 3.14159265358979323846; + double dRotate = -dVal / 180. * 3.14159265358979323846; impl_->current_drawing_state_.rotateAngle_ = dRotate; }