From 42466cf648fdd04ea584c5583124f7072839fa10 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Thu, 31 Oct 2024 18:08:36 +0500 Subject: [PATCH 01/51] Fix atan2 custom shape formula conversion --- OdfFile/Writer/Format/odf_drawing_context.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OdfFile/Writer/Format/odf_drawing_context.cpp b/OdfFile/Writer/Format/odf_drawing_context.cpp index 586c9da949..a22f37de09 100644 --- a/OdfFile/Writer/Format/odf_drawing_context.cpp +++ b/OdfFile/Writer/Format/odf_drawing_context.cpp @@ -1840,6 +1840,9 @@ void odf_drawing_context::add_formula (std::wstring name, std::wstring fmla) case 4: odf_fmla = L"abs(" + val[0] + L")"; break; + case 5: + odf_fmla = L"(10800000 * atan2(" + val[1] + L", " + val[0] + L"))/pi"; + break; case 7: odf_fmla = val[0] + L"*cos(pi*(" + val[1] + L")/10800000)"; break; From ce0f8251d3625ab9aff25a3cc15f7b00e3c24969 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Fri, 22 Nov 2024 17:32:40 +0500 Subject: [PATCH 02/51] 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; } From 8918b7fae07cb45eb7978701d88fdb7eff099347 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Tue, 3 Dec 2024 13:26:51 +0500 Subject: [PATCH 03/51] Fix formula conversion order --- OdfFile/Reader/Converter/oox_drawing.cpp | 12 +-- OdfFile/Reader/Format/draw_shapes.cpp | 83 ++++++++++++++++++++- OdfFile/Reader/Format/svg_parser.cpp | 2 +- OdfFile/Writer/Converter/ConvertDrawing.cpp | 12 +-- 4 files changed, 91 insertions(+), 18 deletions(-) diff --git a/OdfFile/Reader/Converter/oox_drawing.cpp b/OdfFile/Reader/Converter/oox_drawing.cpp index 8618c84101..56987f4762 100644 --- a/OdfFile/Reader/Converter/oox_drawing.cpp +++ b/OdfFile/Reader/Converter/oox_drawing.cpp @@ -75,18 +75,18 @@ namespace svg_path { CP_XML_NODE(val.command) { - if (val.command == L"a:ArcTo") + if (val.command == L"a:arcTo") { if (val.points.size() > 0) { CP_XML_ATTR(L"wR", val.points[0].x.get()); CP_XML_ATTR(L"hR", val.points[0].y.get()); } - //if (val.points.size() > 1) - //{ - // CP_XML_ATTR(L"stAng", (int)(val.points[1].x.get() * 60000)); - // CP_XML_ATTR(L"swAng", (int)(val.points[1].y.get() * 60000)); - //} + if (val.points.size() > 1) + { + CP_XML_ATTR(L"stAng", val.points[1].x.get()); + CP_XML_ATTR(L"swAng", val.points[1].y.get()); + } } else { diff --git a/OdfFile/Reader/Format/draw_shapes.cpp b/OdfFile/Reader/Format/draw_shapes.cpp index f93d4841f4..eed6d603cb 100644 --- a/OdfFile/Reader/Format/draw_shapes.cpp +++ b/OdfFile/Reader/Format/draw_shapes.cpp @@ -530,23 +530,38 @@ void draw_enhanced_geometry::add_child_element( xml::sax * Reader, const std::ws } } -bool convert_equation(const std::wstring& formula, std::wstring &result) +bool convert_equation(std::wstring formula, std::wstring &result) { std::wstring operators; std::wstring function; std::vector values; + boost::erase_all(formula, L" "); + + bool next_negative = false; + size_t pos = 0; while (pos < formula.size()) { - if ((formula[pos] == L'+' || formula[pos] == L'/' || formula[pos] == L'*' || formula[pos] == L'-') && pos > 0) + if ((formula[pos] == L'+' || formula[pos] == L'/' || formula[pos] == L'*') && pos > 0) { if (operators.size() > 1 && !function.empty()) { return false; // ? todooo } + operators += formula[pos++]; } + else if (formula[pos] == L'-') + { + if (pos > 0 && (formula[pos-1] == L'+' || formula[pos-1] == L'/' || formula[pos - 1] == L'*' || formula[pos - 1] == L',')) + { + next_negative = true; + pos++; + } + else + operators += formula[pos++]; + } else if (formula[pos] == L'i' && formula[pos + 1] == L'f') { if (false == operators.empty()) @@ -577,6 +592,16 @@ bool convert_equation(const std::wstring& formula, std::wstring &result) } else pos++; } + else if (formula[pos] == 'a') + { + if (false == operators.empty()) + return false; + + if (pos + 2 < formula.size() && formula[pos + 1] == L'b' && formula[pos + 2] == L's') + { + function = L"abs"; pos += 3; + } + } else if (formula[pos] == L'b') {//bottom values.emplace_back(); @@ -661,6 +686,13 @@ bool convert_equation(const std::wstring& formula, std::wstring &result) else if (formula[pos] >= L'0' && formula[pos] <= L'9' || formula[pos] == L'-' || formula[pos] == L'w' || formula[pos] == L'h') { values.emplace_back(); + + if (next_negative) + { + values.back() += L'-'; + next_negative = false; + } + size_t pos_start = pos; while (pos < formula.size() && formula[pos] >= L'0' && formula[pos] <= L'9' || ((formula[pos] == L'-' || formula[pos] == L'w' || formula[pos] == L'h') && pos_start == pos)) { @@ -780,6 +812,49 @@ void draw_enhanced_geometry::find_draw_type_oox() if (attlist_.drawooo_enhanced_path_) odf_path_ = attlist_.drawooo_enhanced_path_.get(); else if (attlist_.draw_enhanced_path_) odf_path_ = attlist_.draw_enhanced_path_.get(); } + +static void process_polylines(std::vector<::svg_path::_polylineS>& polylines, const std::vector>& equations) +{ + using namespace ::svg_path; + + for (size_t i = 0; i < polylines.size(); i++) + { + _polylineS& p = polylines[i]; + + if (p.command == L"a:arcTo" && p.points.size() > 1) + { + ::svg_path::_pointS& pt = p.points[1]; + + auto x_it = std::find_if(equations.begin(), equations.end(), + [&pt](const std::pair& eq) {return pt.x && eq.first == *pt.x;}); + auto y_it = std::find_if(equations.begin(), equations.end(), + [&pt](const std::pair& eq) {return pt.y && eq.first == *pt.y; }); + + if (x_it != equations.end()) + { + const std::wstring& formula = x_it->second; + + std::vector split; + boost::split(split, formula, boost::is_any_of("\t "), boost::token_compress_on); + + if (split.size() == 4 && split[0] == L"*/" && split[1] == L"1" && boost::starts_with(split[2], L"gd") && split[3] == L"60000") + pt.x = split[2]; + } + + if (y_it != equations.end()) + { + const std::wstring& formula = y_it->second; + + std::vector split; + boost::split(split, formula, boost::is_any_of("\t "), boost::token_compress_on); + + if (split.size() == 4 && split[0] == L"*/" && split[1] == L"1" && boost::starts_with(split[2], L"gd") && split[3] == L"60000") + pt.y = split[2]; + } + } + } +} + bool draw_enhanced_geometry::oox_convert(std::vector& props) { find_draw_type_oox(); @@ -826,7 +901,7 @@ bool draw_enhanced_geometry::oox_convert(std::vector& pro XmlUtils::replace_all(name, L"f", L"gd"); XmlUtils::replace_all(value, L"(bottom-top)", L"h"); - XmlUtils::replace_all(value, L"(right-left)", L"w"); ; + XmlUtils::replace_all(value, L"(right-left)", L"w"); std::wstring value_conv; if (convert_equation(value, value_conv)) @@ -874,6 +949,8 @@ bool draw_enhanced_geometry::oox_convert(std::vector& pro { set_shape = true; + process_polylines(o_Polyline, equations); + std::wstringstream output_; ::svg_path::oox_serialize(output_, o_Polyline); props.push_back(odf_reader::_property(L"custom_path", output_.str())); diff --git a/OdfFile/Reader/Format/svg_parser.cpp b/OdfFile/Reader/Format/svg_parser.cpp index 7ae6135e8a..e3495fb5fa 100644 --- a/OdfFile/Reader/Format/svg_parser.cpp +++ b/OdfFile/Reader/Format/svg_parser.cpp @@ -1100,7 +1100,7 @@ namespace svg_path nY += L"+" + nLastY; } - aCurrPoly.command = L"a:ArcTo"; + aCurrPoly.command = L"a:arcTo"; // append curved edge aCurrPoly.points.push_back(_pointS(nX, nY)); aCurrPoly.points.push_back(_pointS(A1, A2)); diff --git a/OdfFile/Writer/Converter/ConvertDrawing.cpp b/OdfFile/Writer/Converter/ConvertDrawing.cpp index ecbd8a6aac..ec4d5ddf7f 100644 --- a/OdfFile/Writer/Converter/ConvertDrawing.cpp +++ b/OdfFile/Writer/Converter/ConvertDrawing.cpp @@ -1092,7 +1092,7 @@ void OoxConverter::convert(PPTX::Logic::PrstGeom *oox_geom) } } -static std::wstring process_gd_formula(const PPTX::Logic::Gd& gd, std::vector>& deferred_formulas, size_t& last_gd_index) +static std::wstring process_gd_formula(const PPTX::Logic::Gd& gd, odf_writer::odf_drawing_context* drawing_context, 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); @@ -1111,8 +1111,8 @@ static std::wstring process_gd_formula(const PPTX::Logic::Gd& gd, std::vectoradd_formula(abs_name, abs_fmla); + drawing_context->add_formula(cmp_name, cmp_fmla); args[3] = cmp_name; @@ -1129,20 +1129,16 @@ void OoxConverter::convert(PPTX::Logic::CustGeom *oox_cust_geom) if (oox_cust_geom->gdLst.size()) { - 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); + const std::wstring fmla = process_gd_formula(gd, odf_context()->drawing_context(), 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++) From 36b0cc524e3e3f096883dc4b9510f84771efb654 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Mon, 23 Dec 2024 17:33:13 +0500 Subject: [PATCH 04/51] Fix bug #72039 --- OdfFile/Reader/Format/draw_shapes_docx.cpp | 6 ++++ OdfFile/Reader/Format/svg_parser.cpp | 33 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/OdfFile/Reader/Format/draw_shapes_docx.cpp b/OdfFile/Reader/Format/draw_shapes_docx.cpp index 7107433a8b..fd94b4f8a7 100644 --- a/OdfFile/Reader/Format/draw_shapes_docx.cpp +++ b/OdfFile/Reader/Format/draw_shapes_docx.cpp @@ -198,6 +198,9 @@ void draw_line::docx_convert(oox::docx_conversion_context & Context) void draw_path::docx_convert(oox::docx_conversion_context & Context) { + Context.start_paragraph(); + Context.add_new_run(); + //if (Context.get_drawing_context().get_current_level() >0 )return; if (Context.get_drawing_context().get_current_level() > 0 && !Context.get_drawing_context().in_group() ) { @@ -209,6 +212,9 @@ void draw_path::docx_convert(oox::docx_conversion_context & Context) //... reset_svg_path(); draw_shape::docx_convert(Context); + + Context.finish_run(); + Context.finish_paragraph(); } void draw_connector::docx_convert(oox::docx_conversion_context & Context) diff --git a/OdfFile/Reader/Format/svg_parser.cpp b/OdfFile/Reader/Format/svg_parser.cpp index 7ae6135e8a..7cc5a61ffd 100644 --- a/OdfFile/Reader/Format/svg_parser.cpp +++ b/OdfFile/Reader/Format/svg_parser.cpp @@ -567,6 +567,39 @@ namespace svg_path } }break; + case 'Q': + { + nPos++; + skipSpaces(nPos, rSvgDStatement, nLen); + + while (nPos < nLen && isOnNumberChar(rSvgDStatement, nPos)) + { + double nX, nY; + double nX1, nY1; + + if (!importDoubleAndSpaces(nX1, nPos, rSvgDStatement, nLen)) return false; + if (!importDoubleAndSpaces(nY1, nPos, rSvgDStatement, nLen)) return false; + if (!importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; + if (!importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; + + aCurrPoly.command = L"a:quadBezTo"; + + aCurrPoly.points.push_back(_point(nX1, nY1)); + aCurrPoly.points.push_back(_point(nX, nY)); + + Polyline.push_back(aCurrPoly); + aCurrPoly.points.clear(); + + // set last position + nLastX = nX; + nLastY = nY; + + //keep control point + nLastControlX = nX1; + nLastControlY = nY1; + } + }break; + case 'G': { nPos++; From 5b8d2660aa4ae419354280418dc84ece23ef97d3 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Mon, 23 Dec 2024 17:33:13 +0500 Subject: [PATCH 05/51] Fix bug #72039 --- OdfFile/Reader/Format/draw_shapes_docx.cpp | 14 +++++++++ OdfFile/Reader/Format/svg_parser.cpp | 33 ++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/OdfFile/Reader/Format/draw_shapes_docx.cpp b/OdfFile/Reader/Format/draw_shapes_docx.cpp index 7107433a8b..e5778bd9ac 100644 --- a/OdfFile/Reader/Format/draw_shapes_docx.cpp +++ b/OdfFile/Reader/Format/draw_shapes_docx.cpp @@ -198,6 +198,14 @@ void draw_line::docx_convert(oox::docx_conversion_context & Context) void draw_path::docx_convert(oox::docx_conversion_context & Context) { + bool in_paragraph = !Context.get_paragraph_state(); + + if (in_paragraph) + { + Context.start_paragraph(); + Context.add_new_run(); + } + //if (Context.get_drawing_context().get_current_level() >0 )return; if (Context.get_drawing_context().get_current_level() > 0 && !Context.get_drawing_context().in_group() ) { @@ -209,6 +217,12 @@ void draw_path::docx_convert(oox::docx_conversion_context & Context) //... reset_svg_path(); draw_shape::docx_convert(Context); + + if (in_paragraph) + { + Context.finish_run(); + Context.finish_paragraph(); + } } void draw_connector::docx_convert(oox::docx_conversion_context & Context) diff --git a/OdfFile/Reader/Format/svg_parser.cpp b/OdfFile/Reader/Format/svg_parser.cpp index 7ae6135e8a..7cc5a61ffd 100644 --- a/OdfFile/Reader/Format/svg_parser.cpp +++ b/OdfFile/Reader/Format/svg_parser.cpp @@ -567,6 +567,39 @@ namespace svg_path } }break; + case 'Q': + { + nPos++; + skipSpaces(nPos, rSvgDStatement, nLen); + + while (nPos < nLen && isOnNumberChar(rSvgDStatement, nPos)) + { + double nX, nY; + double nX1, nY1; + + if (!importDoubleAndSpaces(nX1, nPos, rSvgDStatement, nLen)) return false; + if (!importDoubleAndSpaces(nY1, nPos, rSvgDStatement, nLen)) return false; + if (!importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false; + if (!importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false; + + aCurrPoly.command = L"a:quadBezTo"; + + aCurrPoly.points.push_back(_point(nX1, nY1)); + aCurrPoly.points.push_back(_point(nX, nY)); + + Polyline.push_back(aCurrPoly); + aCurrPoly.points.clear(); + + // set last position + nLastX = nX; + nLastY = nY; + + //keep control point + nLastControlX = nX1; + nLastControlY = nY1; + } + }break; + case 'G': { nPos++; From 00abbab370538b70d289abc56ed58f42bc39a6a1 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Thu, 26 Dec 2024 17:52:59 +0500 Subject: [PATCH 06/51] Fix bug #72264 --- OdfFile/Reader/Format/styles.cpp | 9 ++++++++- OdfFile/Reader/Format/styles.h | 1 + OdfFile/Reader/Format/text_elements.cpp | 19 ++++++++++++++----- OdfFile/Reader/Format/text_elements.h | 2 ++ 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/OdfFile/Reader/Format/styles.cpp b/OdfFile/Reader/Format/styles.cpp index a9fcf5afb6..574acb2aac 100644 --- a/OdfFile/Reader/Format/styles.cpp +++ b/OdfFile/Reader/Format/styles.cpp @@ -138,7 +138,14 @@ std::wstring process_margin(const _CP_OPT(length_or_percent) & margin, double Mu style_text_properties * style_content::get_style_text_properties() const { - return dynamic_cast(style_text_properties_.get()); + return dynamic_cast(style_text_properties_.get()); +} + +style_text_properties* style_content::get_style_text_properties(bool create) +{ + if (!style_text_properties_ && create) + style_text_properties_ = boost::make_shared(); + return dynamic_cast(style_text_properties_.get()); } style_paragraph_properties * style_content::get_style_paragraph_properties() const diff --git a/OdfFile/Reader/Format/styles.h b/OdfFile/Reader/Format/styles.h index 4cf374d9dc..46a935ba77 100644 --- a/OdfFile/Reader/Format/styles.h +++ b/OdfFile/Reader/Format/styles.h @@ -93,6 +93,7 @@ public: graphic_format_properties* get_graphic_properties()const; style_text_properties* get_style_text_properties() const; + style_text_properties* get_style_text_properties(bool create); style_paragraph_properties* get_style_paragraph_properties()const; style_table_properties* get_style_table_properties()const; style_section_properties* get_style_section_properties()const; diff --git a/OdfFile/Reader/Format/text_elements.cpp b/OdfFile/Reader/Format/text_elements.cpp index 4e4657d6e4..8e4677f9d7 100644 --- a/OdfFile/Reader/Format/text_elements.cpp +++ b/OdfFile/Reader/Format/text_elements.cpp @@ -253,12 +253,12 @@ size_t paragraph::drop_cap_docx_convert(oox::docx_conversion_context & Context) return index; } -void static process_list_bullet_style(oox::docx_conversion_context& Context, office_element_ptr_array& content) +void paragraph::process_list_bullet_style(oox::docx_conversion_context& Context) { - if (content.size() <= 0) + if (content_.size() <= 0) return; - span* first_span = dynamic_cast(content[0].get()); + span* first_span = dynamic_cast(content_[0].get()); if (!first_span) return; @@ -275,6 +275,15 @@ void static process_list_bullet_style(oox::docx_conversion_context& Context, off if (text_props) { + if (!attrs_.text_style_name_.empty()) + { + style_instance* paragraph_style = Context.root()->odf_context().styleContainer().style_by_name(attrs_.text_style_name_, style_family::Paragraph, false); + if (paragraph_style && paragraph_style->content()) + { + paragraph_style->content()->get_style_text_properties(true)->content_.apply_from(text_props->content_); + } + } + const _CP_OPT(odf_types::font_weight)& font_weight = text_props->content_.fo_font_weight_; const _CP_OPT(odf_types::font_style)& font_style = text_props->content_.fo_font_style_; @@ -283,7 +292,7 @@ void static process_list_bullet_style(oox::docx_conversion_context& Context, off if (font_style && font_style->get_type() == odf_types::font_style::Italic) ss << ""; } - + Context.get_text_tracked_context().dumpRPrInsDel_ = ss.str(); } @@ -383,7 +392,7 @@ void paragraph::docx_convert(oox::docx_conversion_context & Context, _CP_OPT(std } Context.start_paragraph_style(styleName); - process_list_bullet_style(Context, content_); + process_list_bullet_style(Context); int textStyle = Context.process_paragraph_attr(&attrs_); diff --git a/OdfFile/Reader/Format/text_elements.h b/OdfFile/Reader/Format/text_elements.h index f8b2a7678a..7d35a74579 100644 --- a/OdfFile/Reader/Format/text_elements.h +++ b/OdfFile/Reader/Format/text_elements.h @@ -73,6 +73,8 @@ public: void pptx_convert (oox::pptx_conversion_context & Context) ; size_t drop_cap_docx_convert(oox::docx_conversion_context & Context); + + void process_list_bullet_style(oox::docx_conversion_context& Context); paragraph_attrs attrs_; From 3365ca15d6e3c54732b0a56f6d5c367fa28b27a5 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 9 Jan 2025 15:47:22 +0600 Subject: [PATCH 07/51] Fix scientific numbers csv reading --- .../CellFormatController/DigitReader.cpp | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/DigitReader.cpp b/OOXML/Binary/Sheets/Reader/CellFormatController/DigitReader.cpp index e714841316..65ae59396e 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/DigitReader.cpp +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/DigitReader.cpp @@ -177,16 +177,31 @@ bool DigitReader::ReadScientific(const std::wstring &value, std::wstring &digit, std::wregex scientificRegex(L"(^[+-]?(\\d+\\.?\\d*)([eE][+-]?\\d+))$"); if(std::regex_search(value, scientificRegex)) { - auto doubleVal = std::stod(value); - - std::wstringstream ss; - ss.precision(14); // Установить точность - ss.setf(std::ios::scientific); - ss << doubleVal; - digit = ss.str(); + try + { + auto doubleVal = std::stod(value); + + std::wstringstream ss; + _INT32 MainPartSize = value.find(L"E"); + if(MainPartSize < 1) + MainPartSize = value.find(L"e"); + ss.precision(MainPartSize); // Установить точность + ss.setf(std::ios::scientific); + ss << doubleVal; + digit = ss.str(); + + format = L"0.0"; + if(MainPartSize > 3) + format += std::wstring(MainPartSize - 3, L'0'); + format +=L"E+00"; + return true; + + } + catch (std::exception) + { + return false; + } - format = L"0.00000E+00"; - return true; } return false; } From e230fa1d4384c648a80c8cda7288fa2da27d9b83 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Thu, 9 Jan 2025 14:02:46 +0300 Subject: [PATCH 08/51] fix bug #53173 --- MsBinaryFile/DocFile/DocumentProperties.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MsBinaryFile/DocFile/DocumentProperties.cpp b/MsBinaryFile/DocFile/DocumentProperties.cpp index aaaf5725cf..8b5c19185b 100644 --- a/MsBinaryFile/DocFile/DocumentProperties.cpp +++ b/MsBinaryFile/DocFile/DocumentProperties.cpp @@ -574,7 +574,6 @@ namespace DocFileFormat } else if ( nFib < Fib1997 ) { - //throw new UnspportedFileVersionException(); } } @@ -749,7 +748,7 @@ namespace DocFileFormat fAutofitLikeWW11 = false; fUnderlineTabInNumList = false; fHangulWidthLikeWW11 = false; - fSplitPgBreakAndParaMark = false; + fSplitPgBreakAndParaMark = true; fDontVertAlignCellWithSp = false; fDontBreakConstrainedForcedTables = false; fDontVertAlignInTxbx = false; From a7774a6bc33dcfb8c9f2a10464f76902077a95e0 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Fri, 10 Jan 2025 17:10:46 +0300 Subject: [PATCH 09/51] fix bug #72395 --- MsBinaryFile/DocFile/TableCellPropertiesMapping.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MsBinaryFile/DocFile/TableCellPropertiesMapping.cpp b/MsBinaryFile/DocFile/TableCellPropertiesMapping.cpp index d02d70edca..4945e1e5d2 100644 --- a/MsBinaryFile/DocFile/TableCellPropertiesMapping.cpp +++ b/MsBinaryFile/DocFile/TableCellPropertiesMapping.cpp @@ -114,7 +114,7 @@ namespace DocFileFormat // Технические_Требования_1_287_ДИТ.DOC if (tdef.rgTc80[j].horzMerge == 0 && tdef.rgTc80[j].wWidth < 1) { - bUseWidth = false; + //bUseWidth = false; break; } } From 07bf7a44aaa543e5f1c8900d43bfaa520889f18e Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Mon, 13 Jan 2025 17:08:46 +0500 Subject: [PATCH 10/51] Fix bug #72375 --- OdfFile/Reader/Format/draw_frame_docx.cpp | 9 +++++++++ OdfFile/Writer/Format/odf_drawing_context.cpp | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/OdfFile/Reader/Format/draw_frame_docx.cpp b/OdfFile/Reader/Format/draw_frame_docx.cpp index cdc27029ce..6ed7cfef51 100644 --- a/OdfFile/Reader/Format/draw_frame_docx.cpp +++ b/OdfFile/Reader/Format/draw_frame_docx.cpp @@ -851,6 +851,15 @@ void common_draw_docx_convert(oox::docx_conversion_context & Context, union_comm drawing->styleHorizontalPos = graphicProperties->common_horizontal_pos_attlist_.style_horizontal_pos_; drawing->styleVerticalPos = graphicProperties->common_vertical_pos_attlist_.style_vertical_pos_; drawing->styleVerticalRel = graphicProperties->common_vertical_rel_attlist_.style_vertical_rel_; + + if (graphicProperties->style_mirror_) + { + bool flipV = graphicProperties->style_mirror_->find(L"vertical") != std::wstring::npos; + bool flipH = graphicProperties->style_mirror_->find(L"horizontal") != std::wstring::npos; + + drawing->additional.push_back(odf_reader::_property(L"flipV", flipV)); + drawing->additional.push_back(odf_reader::_property(L"flipH", flipH)); + } } if (!drawing->styleVerticalRel && anchor) { diff --git a/OdfFile/Writer/Format/odf_drawing_context.cpp b/OdfFile/Writer/Format/odf_drawing_context.cpp index 6545f16250..7ad2c05e59 100644 --- a/OdfFile/Writer/Format/odf_drawing_context.cpp +++ b/OdfFile/Writer/Format/odf_drawing_context.cpp @@ -3325,6 +3325,13 @@ void odf_drawing_context::end_image() else impl_->current_graphic_properties->style_mirror_ = std::wstring(L"horizontal"); } + if (impl_->current_drawing_state_.flipV_) + { + if (impl_->current_graphic_properties->style_mirror_) + impl_->current_graphic_properties->style_mirror_ = *impl_->current_graphic_properties->style_mirror_ + std::wstring(L" vertical"); + else + impl_->current_graphic_properties->style_mirror_ = std::wstring(L"vertical"); + } end_element(); end_frame(); } From fdcb2cf7ba97ce118224d7c81d2479d7cef42494 Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Mon, 13 Jan 2025 18:19:42 +0500 Subject: [PATCH 11/51] Fix bug #72432 --- OdfFile/Reader/Format/draw_common.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/OdfFile/Reader/Format/draw_common.cpp b/OdfFile/Reader/Format/draw_common.cpp index 0e650cea50..ace4d962c2 100644 --- a/OdfFile/Reader/Format/draw_common.cpp +++ b/OdfFile/Reader/Format/draw_common.cpp @@ -298,10 +298,14 @@ void Compute_HatchFill(draw_hatch * image_style,oox::oox_hatch_fill_ptr fill) void Compute_GradientFill(draw_gradient* gradient_style, oox::oox_gradient_fill_ptr fill) { int style = 0; - if (gradient_style->draw_style_) style = gradient_style->draw_style_->get_type(); + if (gradient_style->draw_style_) + style = gradient_style->draw_style_->get_type(); - if (gradient_style->draw_angle_) fill->angle = 90 - gradient_style->draw_angle_->get_value(); - if (fill->angle < 0) fill->angle += 360; + if (gradient_style->draw_angle_) + fill->angle = -90 - gradient_style->draw_angle_->get_value(); + + if (fill->angle < 0) + fill->angle += 360; for (size_t i = 0; i < gradient_style->content_.size(); ++i) { From be2f142fd33f76d67e8291e14bc21bf86985e823 Mon Sep 17 00:00:00 2001 From: Green Date: Mon, 13 Jan 2025 16:52:45 +0300 Subject: [PATCH 12/51] Fix build --- HwpFile/HWPFile.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HwpFile/HWPFile.h b/HwpFile/HWPFile.h index 1af81c2f82..018192344e 100644 --- a/HwpFile/HWPFile.h +++ b/HwpFile/HWPFile.h @@ -6,7 +6,7 @@ #ifndef HWPFILE_USE_DYNAMIC_LIBRARY #define HWP_FILE_DECL_EXPORT #else -#include "../../DesktopEditor/common/base_export.h" +#include "../DesktopEditor/common/base_export.h" #define HWP_FILE_DECL_EXPORT Q_DECL_EXPORT #endif From 17762b71dbac24a887682417c3478ca647b55f1f Mon Sep 17 00:00:00 2001 From: Green Date: Mon, 13 Jan 2025 16:53:14 +0300 Subject: [PATCH 13/51] Unused files have been deleted --- HwpFile/HWPFile.pro | 2 - HwpFile/HwpDoc/Conversion/WriterContext.cpp | 212 -------------------- HwpFile/HwpDoc/Conversion/WriterContext.h | 47 ----- 3 files changed, 261 deletions(-) delete mode 100644 HwpFile/HwpDoc/Conversion/WriterContext.cpp delete mode 100644 HwpFile/HwpDoc/Conversion/WriterContext.h diff --git a/HwpFile/HWPFile.pro b/HwpFile/HWPFile.pro index d03bafe9e7..fdb9d410cf 100644 --- a/HwpFile/HWPFile.pro +++ b/HwpFile/HWPFile.pro @@ -22,7 +22,6 @@ SOURCES += \ HwpDoc/Conversion/FootnoteConverter.cpp \ HwpDoc/Conversion/NumberingConverter.cpp \ HwpDoc/Conversion/OleConverter.cpp \ - HwpDoc/Conversion/WriterContext.cpp \ HwpDoc/HWPDocInfo.cpp \ HwpDoc/HWPElements/HWPRecord.cpp \ HwpDoc/HWPElements/HWPRecordBinData.cpp \ @@ -97,7 +96,6 @@ HEADERS += \ HwpDoc/Conversion/OleConverter.h \ HwpDoc/Conversion/Transform.h \ HwpDoc/Conversion/Types.h \ - HwpDoc/Conversion/WriterContext.h \ HwpDoc/Errors.h \ HwpDoc/HWPDocInfo.h \ HwpDoc/HWPElements/HWPRecord.h \ diff --git a/HwpFile/HwpDoc/Conversion/WriterContext.cpp b/HwpFile/HwpDoc/Conversion/WriterContext.cpp deleted file mode 100644 index 9b95b9c995..0000000000 --- a/HwpFile/HwpDoc/Conversion/WriterContext.cpp +++ /dev/null @@ -1,212 +0,0 @@ -#include "WriterContext.h" -#include "../HWPFile_Private.h" - -namespace HWP -{ -CWriterContext::CWriterContext() - : m_eType(EHanType::NONE), m_pHWPFile(nullptr) -{} - -CWriterContext::~CWriterContext() -{ - if (nullptr != m_pHWPFile) - delete m_pHWPFile; -} - -VECTOR CWriterContext::GetSections() -{ - switch(m_eType) - { - case EHanType::NONE: break; - case EHanType::HWP: - { - if (nullptr != m_pHWPFile) - return m_pHWPFile->GetSections(); - - break; - } - case EHanType::HWPX: - break; - } - - return VECTOR(); -} - -HWP_STRING CWriterContext::DetectHancom(const HWP_STRING& sPathToFile) -{ - HWP_STRING sDetectingType; - - CHWPFile_Private* pHwpTemp = new CHWPFile_Private(sPathToFile); - if (nullptr != pHwpTemp) - { - if (pHwpTemp->Detect()) - { - sDetectingType = L"HWP"; - pHwpTemp->Close(); - } - - delete pHwpTemp; - } - - if (!sDetectingType.empty()) - return sDetectingType; - - //TODO:: добавить HWPX - - return sDetectingType; -} - -bool CWriterContext::Detect() -{ - switch(m_eType) - { - case EHanType::HWP: - { - if (nullptr == m_pHWPFile) - return false; - - return m_pHWPFile->Detect(); - } - case EHanType::NONE: - case EHanType::HWPX: - return false; - } -} - -bool CWriterContext::Open(const HWP_STRING& sPathToFile, const HWP_STRING& sHanType) -{ - if (L"HWP" == sHanType) - { - m_eType = EHanType::HWP; - m_pHWPFile = new CHWPFile_Private(sPathToFile); - - if (nullptr == m_pHWPFile) - return false; - - return m_pHWPFile->Open(); - } - - return false; -} - -void CWriterContext::Close() -{ - switch (m_eType) - { - case EHanType::HWP: - { - if (nullptr != m_pHWPFile) - m_pHWPFile->Close(); - break; - } - case EHanType::NONE: - case EHanType::HWPX: - break; - } -} - -const CHWPDocInfo* CWriterContext::GetDocInfo() -{ - switch (m_eType) - { - case EHanType::HWP: - { - if (nullptr == m_pHWPFile) - return nullptr; - - return m_pHWPFile->GetDocInfo(); - } - case EHanType::NONE: - case EHanType::HWPX: - return nullptr; - } -} - -const CHWPRecordBorderFill* CWriterContext::GetBorderFill(short shId) -{ - const CHWPDocInfo* pDocInfo = GetDocInfo(); - - if (nullptr == pDocInfo || 0 >= shId) - return nullptr; - - return (CHWPRecordBorderFill*)pDocInfo->GetBorderFill(shId - 1); -} - -const CHWPRecordParaShape* CWriterContext::GetParaShape(int nId) -{ - const CHWPDocInfo* pDocInfo = GetDocInfo(); - - if (nullptr == pDocInfo || 0 >= nId) - return nullptr; - - return (CHWPRecordParaShape*)pDocInfo->GetParaShape(nId); -} - -const CHWPRecordStyle* CWriterContext::GetParaStyle(short shId) -{ - const CHWPDocInfo* pDocInfo = GetDocInfo(); - - if (nullptr == pDocInfo || 0 >= shId) - return nullptr; - - return (CHWPRecordStyle*)pDocInfo->GetStyle(shId); -} - -const CHWPRecordCharShape* CWriterContext::GetCharShape(int nId) -{ - const CHWPDocInfo* pDocInfo = GetDocInfo(); - - if (nullptr == pDocInfo || 0 >= nId) - return nullptr; - - return (CHWPRecordCharShape*)pDocInfo->GetCharShape(nId); -} - -const CHWPRecordNumbering* CWriterContext::GetNumbering(short shId) -{ - const CHWPDocInfo* pDocInfo = GetDocInfo(); - - if (nullptr == pDocInfo || 0 >= shId) - return nullptr; - - return (CHWPRecordNumbering*)pDocInfo->GetNumbering(shId); -} - -const CHWPRecordBullet* CWriterContext::GetBullet(short shId) -{ - const CHWPDocInfo* pDocInfo = GetDocInfo(); - - if (nullptr == pDocInfo || 0 >= shId) - return nullptr; - - return (CHWPRecordBullet*)pDocInfo->GetBullet(shId - 1); -} - -const CHwpRecordTabDef* CWriterContext::GetTabDef(short shId) -{ - const CHWPDocInfo* pDocInfo = GetDocInfo(); - - if (nullptr == pDocInfo || 0 >= shId) - return nullptr; - - return (CHwpRecordTabDef*)pDocInfo->GetTabDef(shId); -} - -HWP_STRING CWriterContext::GetBinFilename(const HWP_STRING& sId) -{ - //TODO::реализовать - return HWP_STRING(); -} - -bool CWriterContext::GetBinBytes(const HWP_STRING& sId, CHWPStream& oBuffer) -{ - //TODO::реализовать - return false; -} - -HWP_STRING CWriterContext::GetBinFormat(const HWP_STRING& sId) -{ - //TODO::реализовать - return HWP_STRING(); -} -} diff --git a/HwpFile/HwpDoc/Conversion/WriterContext.h b/HwpFile/HwpDoc/Conversion/WriterContext.h deleted file mode 100644 index a203c25034..0000000000 --- a/HwpFile/HwpDoc/Conversion/WriterContext.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef WRITERCONTEXT_H -#define WRITERCONTEXT_H - -#include "../HWPFile.h" -#include "../HanType.h" -#include "../HWPSection.h" - -#include "../HWPElements/HWPRecordParaShape.h" -#include "../HWPElements/HWPRecordStyle.h" -#include "../HWPElements/HWPRecordCharShape.h" -#include "../HWPElements/HWPRecordNumbering.h" -#include "../HWPElements/HWPRecordBullet.h" -#include "../HWPElements/HwpRecordTabDef.h" - -namespace HWP -{ -class CWriterContext -{ - EHanType m_eType; - CHWPFile_Private* m_pHWPFile; - int m_nVersion; -public: - CWriterContext(); - ~CWriterContext(); - - VECTOR GetSections(); - HWP_STRING DetectHancom(const HWP_STRING& sPathToFile); - bool Detect(); - bool Open(const HWP_STRING& sPathToFile, const HWP_STRING& sHanType); - void Close(); - - const CHWPDocInfo* GetDocInfo(); - const CHWPRecordBorderFill* GetBorderFill(short shId); - const CHWPRecordParaShape* GetParaShape(int nId); - const CHWPRecordStyle* GetParaStyle(short shId); - const CHWPRecordCharShape* GetCharShape(int nId); - const CHWPRecordNumbering* GetNumbering(short shId); - const CHWPRecordBullet* GetBullet(short shId); - const CHwpRecordTabDef* GetTabDef(short shId); - - HWP_STRING GetBinFilename(const HWP_STRING& sId); - bool GetBinBytes(const HWP_STRING& sId, CHWPStream& oBuffer); - HWP_STRING GetBinFormat(const HWP_STRING& sId); -}; -} - -#endif // WRITERCONTEXT_H From a9d8cbbc574922f6d3ad5e94a6f34dea620b4ef3 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 13 Jan 2025 17:27:54 +0300 Subject: [PATCH 14/51] Fix bug 71493 Also fix bug 57854, 55429 --- DesktopEditor/graphics/Clip.cpp | 54 +-- DesktopEditor/graphics/Clip.h | 12 +- DesktopEditor/graphics/Graphics.cpp | 394 +++++++++++--------- DesktopEditor/graphics/Graphics.h | 6 +- DesktopEditor/graphics/GraphicsRenderer.cpp | 3 +- DesktopEditor/graphics/IRenderer.h | 3 + PdfFile/SrcReader/GfxClip.h | 13 +- PdfFile/SrcReader/RendererOutputDev.cpp | 13 +- 8 files changed, 270 insertions(+), 228 deletions(-) diff --git a/DesktopEditor/graphics/Clip.cpp b/DesktopEditor/graphics/Clip.cpp index 4c4e51e95a..b755d3c49e 100644 --- a/DesktopEditor/graphics/Clip.cpp +++ b/DesktopEditor/graphics/Clip.cpp @@ -191,6 +191,16 @@ namespace Aggplus { } + CClipMulti::clip_rasterizer* CClipMulti::GetRasterizer() + { + if (!m_bIsClip) + { + m_rasterizer.reset(); + return &m_rasterizer; + } + return NULL; + } + void CClipMulti::Create(LONG width, LONG height) { m_lWidth = width; @@ -212,62 +222,52 @@ namespace Aggplus typedef agg::conv_curve conv_crv_type; conv_crv_type c_c_path(trans); - + m_rasterizer.add_path(c_c_path); - m_rasterizer.filling_rule(pPath->m_internal->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero); + + GenerateClip2(pPath->m_internal->m_bEvenOdd); + } + + void CClipMulti::GenerateClip2(bool bEvenOdd) + { + m_rasterizer.filling_rule(bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero); m_bIsClip = true; m_bIsClip2 = false; } - void CClipMulti::Combine(CGraphicsPath* pPath, CMatrix* pMatrix, agg::sbool_op_e op) + void CClipMulti::Combine(bool bEvenOdd, agg::sbool_op_e op, clip_rasterizer* pRasterizer) { + if (!pRasterizer) + return; + if (!m_bIsClip) - return GenerateClip(pPath, pMatrix); + return GenerateClip2(bEvenOdd); if (!m_bIsClip2) { // смешивать надо с растерайзером - agg::rasterizer_scanline_aa rasterizer; - rasterizer.clip_box(0, 0, m_lWidth, m_lHeight); - - typedef agg::conv_transform trans_type; - trans_type trans(pPath->m_internal->m_agg_ps, pMatrix->m_internal->m_agg_mtx); - - typedef agg::conv_curve conv_crv_type; - conv_crv_type c_c_path(trans); - - rasterizer.add_path(c_c_path); - rasterizer.filling_rule(pPath->m_internal->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero); + pRasterizer->filling_rule(bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero); scanline_type sl1; scanline_type sl2; scanline_type sl; - agg::sbool_combine_shapes_aa(op, m_rasterizer, rasterizer, sl1, sl2, sl, m_storage1); + agg::sbool_combine_shapes_aa(op, m_rasterizer, *pRasterizer, sl1, sl2, sl, m_storage1); m_lCurStorage = 1; } else { // надо смешивать со стораджем - agg::rasterizer_scanline_aa rasterizer; - rasterizer.clip_box(0, 0, m_lWidth, m_lHeight); - typedef agg::conv_transform trans_type; - trans_type trans(pPath->m_internal->m_agg_ps, pMatrix->m_internal->m_agg_mtx); - - typedef agg::conv_curve conv_crv_type; - conv_crv_type c_c_path(trans); - - rasterizer.add_path(c_c_path); - rasterizer.filling_rule(pPath->m_internal->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero); + pRasterizer->filling_rule(op ? agg::fill_even_odd : agg::fill_non_zero); scanline_type sl1; scanline_type sl2; scanline_type sl; - agg::sbool_combine_shapes_aa(op, rasterizer, (m_lCurStorage == 1) ? m_storage1 : m_storage2, sl1, sl2, sl, + agg::sbool_combine_shapes_aa(op, *pRasterizer, (m_lCurStorage == 1) ? m_storage1 : m_storage2, sl1, sl2, sl, (m_lCurStorage == 1) ? m_storage2 : m_storage1); if (1 == m_lCurStorage) diff --git a/DesktopEditor/graphics/Clip.h b/DesktopEditor/graphics/Clip.h index 034fe01c67..d5c4d4be0b 100644 --- a/DesktopEditor/graphics/Clip.h +++ b/DesktopEditor/graphics/Clip.h @@ -138,10 +138,11 @@ public: class CClipMulti { - typedef agg::scanline_p8 scanline_type; - public: - agg::rasterizer_scanline_aa m_rasterizer; + typedef agg::scanline_p8 scanline_type; + typedef agg::rasterizer_scanline_aa clip_rasterizer; + + clip_rasterizer m_rasterizer; agg::scanline_storage_aa8 m_storage1; agg::scanline_storage_aa8 m_storage2; @@ -158,10 +159,13 @@ public: CClipMulti(); ~CClipMulti(); + clip_rasterizer* GetRasterizer(); + void Create(LONG width, LONG height); void GenerateClip(CGraphicsPath* pPath, CMatrix* pMatrix); + void GenerateClip2(bool bEvenOdd); - void Combine(CGraphicsPath* pPath, CMatrix* pMatrix, agg::sbool_op_e op); + void Combine(bool bEvenOdd, agg::sbool_op_e op, clip_rasterizer* pRasterizer); bool IsClip(); bool IsClip2(); diff --git a/DesktopEditor/graphics/Graphics.cpp b/DesktopEditor/graphics/Graphics.cpp index a6d6ce2d7b..2ffd835aff 100644 --- a/DesktopEditor/graphics/Graphics.cpp +++ b/DesktopEditor/graphics/Graphics.cpp @@ -502,18 +502,41 @@ namespace Aggplus return Ok; } - Status CGraphics::CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op) + Status CGraphics::CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op, NSStructures::CPen* pPen) { Aggplus::CMatrix m; - return InternalClip(pPath, (m_bIntegerGrid || pPath->m_internal->m_pTransform != NULL) ? &m : &m_oFullTransform, op); + return InternalClip(pPath, (m_bIntegerGrid || pPath->m_internal->m_pTransform != NULL) ? &m : &m_oFullTransform, op, pPen); } - Status CGraphics::InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op) + Status CGraphics::InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op, NSStructures::CPen* pPen) { if (NULL == pPath) return InvalidParameter; - m_oClip.Combine(pPath, pTransform, op); + bool bTempRasterizer = false; + CClipMulti::clip_rasterizer* pRasterizer = m_oClip.GetRasterizer(); + if (!pRasterizer) + { + pRasterizer = new CClipMulti::clip_rasterizer(); + pRasterizer->clip_box(0, 0, m_oClip.m_lWidth, m_oClip.m_lHeight); + bTempRasterizer = true; + } + + agg::trans_affine* pAffine = NULL; + if (pPen) + pAffine = DoStrokePath(pPen, pPath, pRasterizer); + else + { + typedef agg::conv_transform trans_type; + trans_type trans(pPath->m_internal->m_agg_ps, pTransform->m_internal->m_agg_mtx); + + typedef agg::conv_curve conv_crv_type; + conv_crv_type c_c_path(trans); + + pRasterizer->add_path(c_c_path); + } + + m_oClip.Combine(pPath->m_internal->m_bEvenOdd, op, pRasterizer); // write to clips history CGraphics_ClipStateRecord* pRecord = new CGraphics_ClipStateRecord(); @@ -522,6 +545,11 @@ namespace Aggplus pRecord->Operation = op; m_oClipState.AddRecord(pRecord); + if (pAffine) + delete pAffine; + if (bTempRasterizer) + delete pRasterizer; + return Ok; } @@ -610,180 +638,7 @@ namespace Aggplus m_rasterizer.get_rasterizer().reset(); - agg::line_join_e LineJoin = agg::round_join; - switch(pPen->LineJoin) - { - case LineJoinMiter : LineJoin = agg::miter_join_revert; break; - case LineJoinBevel : LineJoin = agg::bevel_join; break; - case LineJoinRound : LineJoin = agg::round_join; break; - case LineJoinMiterClipped : LineJoin = agg::miter_join_revert; break; - default: break; - } - agg::line_cap_e LineCap = agg::round_cap; - switch(pPen->LineStartCap) - { - case LineCapFlat : LineCap = agg::butt_cap; break; - case LineCapRound : LineCap = agg::round_cap; break; - case LineCapSquare : LineCap = agg::square_cap; break; - default: break; - } - - double dWidth = pPen->Size; - if (!m_bIntegerGrid && m_bIs0PenWidthAs1px) - { - double dWidthMinSize, dSqrtDet = sqrt(abs(m_oFullTransform.m_internal->m_agg_mtx.determinant())); - if (0 == dWidth) - { - double dX = 0.72, dY = 0.72; - agg::trans_affine invert = ~m_oFullTransform.m_internal->m_agg_mtx; - invert.transform_2x2(&dX, &dY); - dWidth = std::min(abs(dX), abs(dY)); - } - else if (0 != dSqrtDet && dWidth < (dWidthMinSize = 1.0 / dSqrtDet)) - dWidth = dWidthMinSize; - } - - double dblMiterLimit = pPen->MiterLimit; - - agg::path_storage path_copy(pPath->m_internal->m_agg_ps); - bool bIsUseIdentity = m_bIntegerGrid; - if (!bIsUseIdentity) - { - agg::trans_affine* full_trans = &m_oFullTransform.m_internal->m_agg_mtx; - double dDet = full_trans->determinant(); - - if (fabs(dDet) < 0.0001) - { - path_copy.transform_all_paths(m_oFullTransform.m_internal->m_agg_mtx); - dWidth *= sqrt(fabs(dDet)); - - bIsUseIdentity = true; - } - } - - typedef agg::conv_curve conv_crv_type; - - conv_crv_type c_c_path(path_copy); - c_c_path.approximation_scale(25.0); - c_c_path.approximation_method(agg::curve_inc); - DashStyle eStyle = (DashStyle)pPen->DashStyle; - - if (DashStyleCustom == eStyle) - { - if (0 == pPen->Count || NULL == pPen->DashPattern) - { - eStyle = DashStyleSolid; - } - else - { - bool bFoundNormal = false; - for (int i = 0; i < pPen->Count; i++) - { - if (fabs(pPen->DashPattern[i]) > 0.0001) - { - bFoundNormal = true; - break; - } - } - if (!bFoundNormal) - eStyle = DashStyleSolid; - } - } - - agg::trans_affine* pAffine = &m_oFullTransform.m_internal->m_agg_mtx; - if (bIsUseIdentity) - pAffine = new agg::trans_affine(); - - if (DashStyleSolid == eStyle) - { - typedef agg::conv_stroke Path_Conv_StrokeN; - Path_Conv_StrokeN pgN(c_c_path); - - //pgN.line_join(agg::miter_join_revert); - - pgN.line_cap(LineCap); - - pgN.line_join(LineJoin); - pgN.inner_join(agg::inner_round); - - pgN.miter_limit(dblMiterLimit); - pgN.width(dWidth); - - pgN.approximation_scale(25.0); - - typedef agg::conv_transform transStroke; - - transStroke trans(pgN, *pAffine); - m_rasterizer.get_rasterizer().add_path(trans); - } - else - { - typedef agg::conv_dash Path_Conv_Dash; - Path_Conv_Dash poly2_dash(c_c_path); - - typedef agg::conv_stroke Path_Conv_StrokeD; - Path_Conv_StrokeD pgD(poly2_dash); - - switch (eStyle) - { - case DashStyleDash: - poly2_dash.add_dash(3.00*dWidth, dWidth); - break; - case DashStyleDot: - poly2_dash.add_dash(dWidth, dWidth); - break; - case DashStyleDashDot: - poly2_dash.add_dash(3.00*dWidth, dWidth); - poly2_dash.add_dash(dWidth, dWidth); - break; - case DashStyleDashDotDot: - poly2_dash.add_dash(3.00*dWidth, dWidth); - poly2_dash.add_dash(dWidth, dWidth); - poly2_dash.add_dash(dWidth, dWidth); - break; - default: - case DashStyleCustom: - { - double offset = pPen->DashOffset; - double* params = pPen->DashPattern; - LONG lCount = pPen->Count; - LONG lCount2 = lCount / 2; - - double dKoef = 1.0; - - for (LONG i = 0; i < lCount2; ++i) - { - if (0 == i) - { - poly2_dash.add_dash((params[i * 2]) * dKoef, params[i * 2 + 1] * dKoef); - } - else - { - poly2_dash.add_dash(params[i * 2] * dKoef, params[i * 2 + 1] * dKoef); - } - } - if (1 == (lCount % 2)) - { - poly2_dash.add_dash(params[lCount - 1] * dKoef, 0); - } - poly2_dash.dash_start(offset * dKoef); - - break; - } - } - - double dWidthMinSize = 1.0 / sqrt(abs(m_oCoordTransform.m_internal->m_agg_mtx.determinant())); - if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize) - dWidth = dWidthMinSize; - - pgD.line_cap(LineCap); - pgD.line_join(LineJoin); - pgD.miter_limit(dblMiterLimit); - pgD.width(dWidth); - - agg::conv_transform trans(pgD, *pAffine); - m_rasterizer.get_rasterizer().add_path(trans); - } + agg::trans_affine* pAffine = DoStrokePath(pPen, pPath, &m_rasterizer.get_rasterizer()); CColor oColor((BYTE)(pPen->Alpha * m_dGlobalAlpha), pPen->Color, m_bSwapRGB); CBrushSolid oBrush(oColor); @@ -798,8 +653,7 @@ namespace Aggplus if (gamma >= 0) m_rasterizer.gamma(1.0); - if (bIsUseIdentity) - RELEASEOBJECT(pAffine); + RELEASEOBJECT(pAffine); return Ok; } @@ -2243,6 +2097,186 @@ namespace Aggplus break; } } + template + agg::trans_affine* CGraphics::DoStrokePath(NSStructures::CPen* pPen, CGraphicsPath* pPath, Rasterizer* pRasterizer) + { + agg::line_join_e LineJoin = agg::round_join; + switch(pPen->LineJoin) + { + case LineJoinMiter : LineJoin = agg::miter_join_revert; break; + case LineJoinBevel : LineJoin = agg::bevel_join; break; + case LineJoinRound : LineJoin = agg::round_join; break; + case LineJoinMiterClipped : LineJoin = agg::miter_join_revert; break; + default: break; + } + agg::line_cap_e LineCap = agg::round_cap; + switch(pPen->LineStartCap) + { + case LineCapFlat : LineCap = agg::butt_cap; break; + case LineCapRound : LineCap = agg::round_cap; break; + case LineCapSquare : LineCap = agg::square_cap; break; + default: break; + } + + double dWidth = pPen->Size; + if (!m_bIntegerGrid && m_bIs0PenWidthAs1px) + { + double dWidthMinSize, dSqrtDet = sqrt(abs(m_oFullTransform.m_internal->m_agg_mtx.determinant())); + if (0 == dWidth) + { + double dX = 0.72, dY = 0.72; + agg::trans_affine invert = ~m_oFullTransform.m_internal->m_agg_mtx; + invert.transform_2x2(&dX, &dY); + dWidth = std::min(abs(dX), abs(dY)); + } + else if (0 != dSqrtDet && dWidth < (dWidthMinSize = 1.0 / dSqrtDet)) + dWidth = dWidthMinSize; + } + + double dblMiterLimit = pPen->MiterLimit; + + agg::path_storage path_copy(pPath->m_internal->m_agg_ps); + bool bIsUseIdentity = m_bIntegerGrid; + if (!bIsUseIdentity) + { + agg::trans_affine* full_trans = &m_oFullTransform.m_internal->m_agg_mtx; + double dDet = full_trans->determinant(); + + if (fabs(dDet) < 0.0001) + { + path_copy.transform_all_paths(m_oFullTransform.m_internal->m_agg_mtx); + dWidth *= sqrt(fabs(dDet)); + + bIsUseIdentity = true; + } + } + + typedef agg::conv_curve conv_crv_type; + + conv_crv_type c_c_path(path_copy); + c_c_path.approximation_scale(25.0); + c_c_path.approximation_method(agg::curve_inc); + DashStyle eStyle = (DashStyle)pPen->DashStyle; + + if (DashStyleCustom == eStyle) + { + if (0 == pPen->Count || NULL == pPen->DashPattern) + { + eStyle = DashStyleSolid; + } + else + { + bool bFoundNormal = false; + for (int i = 0; i < pPen->Count; i++) + { + if (fabs(pPen->DashPattern[i]) > 0.0001) + { + bFoundNormal = true; + break; + } + } + if (!bFoundNormal) + eStyle = DashStyleSolid; + } + } + + agg::trans_affine* pAffine = &m_oFullTransform.m_internal->m_agg_mtx; + if (bIsUseIdentity) + pAffine = new agg::trans_affine(); + + if (DashStyleSolid == eStyle) + { + typedef agg::conv_stroke Path_Conv_StrokeN; + Path_Conv_StrokeN pgN(c_c_path); + + //pgN.line_join(agg::miter_join_revert); + + pgN.line_cap(LineCap); + + pgN.line_join(LineJoin); + pgN.inner_join(agg::inner_round); + + pgN.miter_limit(dblMiterLimit); + pgN.width(dWidth); + + pgN.approximation_scale(25.0); + + typedef agg::conv_transform transStroke; + + transStroke trans(pgN, *pAffine); + pRasterizer->add_path(trans); + } + else + { + typedef agg::conv_dash Path_Conv_Dash; + Path_Conv_Dash poly2_dash(c_c_path); + + typedef agg::conv_stroke Path_Conv_StrokeD; + Path_Conv_StrokeD pgD(poly2_dash); + + switch (eStyle) + { + case DashStyleDash: + poly2_dash.add_dash(3.00*dWidth, dWidth); + break; + case DashStyleDot: + poly2_dash.add_dash(dWidth, dWidth); + break; + case DashStyleDashDot: + poly2_dash.add_dash(3.00*dWidth, dWidth); + poly2_dash.add_dash(dWidth, dWidth); + break; + case DashStyleDashDotDot: + poly2_dash.add_dash(3.00*dWidth, dWidth); + poly2_dash.add_dash(dWidth, dWidth); + poly2_dash.add_dash(dWidth, dWidth); + break; + default: + case DashStyleCustom: + { + double offset = pPen->DashOffset; + double* params = pPen->DashPattern; + LONG lCount = pPen->Count; + LONG lCount2 = lCount / 2; + + double dKoef = 1.0; + + for (LONG i = 0; i < lCount2; ++i) + { + if (0 == i) + { + poly2_dash.add_dash((params[i * 2]) * dKoef, params[i * 2 + 1] * dKoef); + } + else + { + poly2_dash.add_dash(params[i * 2] * dKoef, params[i * 2 + 1] * dKoef); + } + } + if (1 == (lCount % 2)) + { + poly2_dash.add_dash(params[lCount - 1] * dKoef, 0); + } + poly2_dash.dash_start(offset * dKoef); + + break; + } + } + + double dWidthMinSize = 1.0 / sqrt(abs(m_oCoordTransform.m_internal->m_agg_mtx.determinant())); + if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize) + dWidth = dWidthMinSize; + + pgD.line_cap(LineCap); + pgD.line_join(LineJoin); + pgD.miter_limit(dblMiterLimit); + pgD.width(dWidth); + + agg::conv_transform trans(pgD, *pAffine); + pRasterizer->add_path(trans); + } + + return bIsUseIdentity ? pAffine : NULL; + } // text methods int CGraphics::FillGlyph2(int nX, int nY, TGlyph* pGlyph, Aggplus::CBrush* pBrush) { diff --git a/DesktopEditor/graphics/Graphics.h b/DesktopEditor/graphics/Graphics.h index fdeb9135cd..5bb709688d 100644 --- a/DesktopEditor/graphics/Graphics.h +++ b/DesktopEditor/graphics/Graphics.h @@ -360,8 +360,8 @@ public: Status SetClip(CGraphicsPath* pPath); Status ResetClip(); Status ExclugeClip(CGraphicsPath* pPath); - Status CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op); - Status InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op); + Status CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op, NSStructures::CPen* pPen = NULL); + Status InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op, NSStructures::CPen* pPen = NULL); // измерение текста INT MeasureString(const std::wstring& strText, CFontManager* pManager, double* lWidth, double* lHeight); @@ -453,6 +453,8 @@ protected: void DoFillPathTextureClampSz3(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride, Aggplus::WrapMode wrapmode, BYTE Alpha = 255); void DoFillPath(const CBrush* Brush); + template + agg::trans_affine* DoStrokePath(NSStructures::CPen* pPen, CGraphicsPath* pPath, Rasterizer* ras); // text methods int FillGlyph2(int nX, int nY, TGlyph* pGlyph, Aggplus::CBrush* pBrush); diff --git a/DesktopEditor/graphics/GraphicsRenderer.cpp b/DesktopEditor/graphics/GraphicsRenderer.cpp index f2fe7443e4..9b0c684e55 100644 --- a/DesktopEditor/graphics/GraphicsRenderer.cpp +++ b/DesktopEditor/graphics/GraphicsRenderer.cpp @@ -822,7 +822,8 @@ HRESULT CGraphicsRenderer::EndCommand(const DWORD& lType) m_pPath->SetRuler(bIsIn ? false : true); INT bIsIntersect = (c_nClipRegionIntersect == (0x0100 & m_lCurrentClipMode)); - m_pRenderer->CombineClip(m_pPath, bIsIntersect ? agg::sbool_and : agg::sbool_or); + INT bIsStrokePath = (c_nClipToStrokePath == (0x0010 & m_lCurrentClipMode)); + m_pRenderer->CombineClip(m_pPath, bIsIntersect ? agg::sbool_and : agg::sbool_or, bIsStrokePath ? &m_oPen : NULL); //m_pRenderer->SetClip(m_pPath); break; diff --git a/DesktopEditor/graphics/IRenderer.h b/DesktopEditor/graphics/IRenderer.h index e387ed6e3b..0f46a733e7 100644 --- a/DesktopEditor/graphics/IRenderer.h +++ b/DesktopEditor/graphics/IRenderer.h @@ -96,6 +96,9 @@ const long c_nBaselineShift = 0xa041; // типы клипа const long c_nClipRegionTypeWinding = 0x0000; const long c_nClipRegionTypeEvenOdd = 0x0001; +// тип преобразования пути для клипов +const long c_nClipToPath = 0x0000; +const long c_nClipToStrokePath = 0x0010; // тип объединения клипов const long c_nClipRegionIntersect = 0x0000; const long c_nClipRegionUnion = 0x0100; diff --git a/PdfFile/SrcReader/GfxClip.h b/PdfFile/SrcReader/GfxClip.h index 68f83e6b01..60fb159cac 100644 --- a/PdfFile/SrcReader/GfxClip.h +++ b/PdfFile/SrcReader/GfxClip.h @@ -354,16 +354,15 @@ public: RELEASEOBJECT(m_vPaths[i]); } - void AddPath(GfxPath *pPath, double *Matrix, bool bEo) + void AddPath(GfxPath *pPath, double *Matrix, int nFlag) { if (pPath && Matrix) { m_vPaths.push_back(pPath->copy()); m_vMatrix.push_back(GfxClipMatrix()); m_vMatrix.back().FromDoublePointer(Matrix); - m_vPathsClipEo.push_back(bEo); + m_vPathsClipFlag.push_back(nFlag); } - } size_t GetPathNum() @@ -376,9 +375,9 @@ public: return m_vPaths[i]; } - bool GetClipEo(int i) + int GetClipFlag(int i) { - return m_vPathsClipEo[i]; + return m_vPathsClipFlag[i]; } bool IsChanged() @@ -393,10 +392,8 @@ public: std::vector m_vMatrix; private: - - std::vector m_vPaths; - std::vector m_vPathsClipEo; + std::vector m_vPathsClipFlag; bool m_bChanged; }; diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 843e39ea01..409ece809c 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -2173,7 +2173,8 @@ namespace PdfReader if (!m_sStates.back().pClip) m_sStates.back().pClip = new GfxClip(); - m_sStates.back().pClip->AddPath(pGState->getPath(), pGState->getCTM(), false); + int nClipFlag = c_nClipRegionIntersect | c_nClipRegionTypeWinding; + m_sStates.back().pClip->AddPath(pGState->getPath(), pGState->getCTM(), nClipFlag); AddClip(pGState, &m_sStates.back(), m_sStates.back().pClip->GetPathNum() - 1); } void RendererOutputDev::eoClip(GfxState* pGState) @@ -2183,7 +2184,8 @@ namespace PdfReader if (!m_sStates.back().pClip) m_sStates.back().pClip = new GfxClip(); - m_sStates.back().pClip->AddPath(pGState->getPath(), pGState->getCTM(), true); + int nClipFlag = c_nClipRegionIntersect | c_nClipRegionTypeEvenOdd; + m_sStates.back().pClip->AddPath(pGState->getPath(), pGState->getCTM(), nClipFlag); AddClip(pGState, &m_sStates.back(), m_sStates.back().pClip->GetPathNum() - 1); } void RendererOutputDev::clipToStrokePath(GfxState* pGState) @@ -2193,7 +2195,8 @@ namespace PdfReader if (!m_sStates.back().pClip) m_sStates.back().pClip = new GfxClip(); - m_sStates.back().pClip->AddPath(pGState->getPath(), pGState->getCTM(), false); + int nClipFlag = c_nClipRegionIntersect | c_nClipRegionTypeWinding | c_nClipToStrokePath; + m_sStates.back().pClip->AddPath(pGState->getPath(), pGState->getCTM(), nClipFlag); AddClip(pGState, &m_sStates.back(), m_sStates.back().pClip->GetPathNum() - 1); } void RendererOutputDev::clipToPath(GfxState* pGState, GfxPath* pPath, double* pMatrix, bool bEO) @@ -3496,9 +3499,7 @@ namespace PdfReader GfxClip* pClip = pState->pClip; GfxPath* pPath = pClip->GetPath(nIndex); - bool bFlag = pClip->GetClipEo(nIndex); - int nClipFlag = bFlag ? c_nClipRegionTypeEvenOdd : c_nClipRegionTypeWinding; - nClipFlag |= c_nClipRegionIntersect; + int nClipFlag = pClip->GetClipFlag(nIndex);; m_pRenderer->BeginCommand(c_nClipType); m_pRenderer->put_ClipMode(nClipFlag); From a5fed4af708c53cc1f26e6daa5e6af4cf111ff36 Mon Sep 17 00:00:00 2001 From: Green Date: Tue, 14 Jan 2025 00:21:29 +0300 Subject: [PATCH 15/51] Fix build and refactoring --- HwpFile/HwpDoc/Conversion/Converter2OOXML.h | 2 + HwpFile/HwpDoc/OLEdoc/CompoundFile.cpp | 71 +++++++++++---------- HwpFile/HwpDoc/OLEdoc/CompoundFile.h | 4 +- HwpFile/HwpDoc/Paragraph/CharShape.cpp | 1 + HwpFile/HwpDoc/Paragraph/CharShape.h | 1 - HwpFile/HwpDoc/Paragraph/HWPPargraph.cpp | 1 + 6 files changed, 45 insertions(+), 35 deletions(-) diff --git a/HwpFile/HwpDoc/Conversion/Converter2OOXML.h b/HwpFile/HwpDoc/Conversion/Converter2OOXML.h index 539204a68e..8674f1ad7e 100644 --- a/HwpFile/HwpDoc/Conversion/Converter2OOXML.h +++ b/HwpFile/HwpDoc/Conversion/Converter2OOXML.h @@ -11,6 +11,8 @@ #include "../Paragraph/CtrlColumnDef.h" #include "../Paragraph/CtrlShapePic.h" #include "../Paragraph/CtrlShapeOle.h" +#include "../Paragraph/CtrlEqEdit.h" +#include "../Paragraph/CtrlTable.h" #include "../Paragraph/TblCell.h" #include "FootnoteConverter.h" diff --git a/HwpFile/HwpDoc/OLEdoc/CompoundFile.cpp b/HwpFile/HwpDoc/OLEdoc/CompoundFile.cpp index 647c9e5a82..680bcf0fa7 100644 --- a/HwpFile/HwpDoc/OLEdoc/CompoundFile.cpp +++ b/HwpFile/HwpDoc/OLEdoc/CompoundFile.cpp @@ -1,10 +1,14 @@ #include "CompoundFile.h" +#include +#include namespace HWP { CCompoundFile::CCompoundFile(const HWP_STRING& sFileName) - : m_fFile(sFileName, std::ios::in | std::ios::binary), m_nSectorSize(512) -{} + : m_nSectorSize(512) +{ + m_oFile.OpenFile(sFileName); +} CCompoundFile::~CCompoundFile() { @@ -104,11 +108,12 @@ bool CCompoundFile::Read(const CDirectoryEntry& oEntry, CHWPStream& oBuffer) int nSatID = arStreamContainerSectors.at(nStreamIndex); - m_fFile.seekg((nSatID + 1) * m_nSectorSize + nStreamOffset * 64); - m_fFile.read(oBuffer.GetCurPtr(), nRemainSize >= 64 ? 64 : nRemainSize); + DWORD dwSizeRead; + m_oFile.SeekFile((nSatID + 1) * m_nSectorSize + nStreamOffset * 64); + m_oFile.ReadFile((BYTE*)oBuffer.GetCurPtr(), nRemainSize >= 64 ? 64 : nRemainSize, dwSizeRead); - oBuffer.Skip(m_fFile.gcount()); - nRemainSize -= m_fFile.gcount(); + oBuffer.Skip(dwSizeRead); + nRemainSize -= dwSizeRead; } } else @@ -119,11 +124,12 @@ bool CCompoundFile::Read(const CDirectoryEntry& oEntry, CHWPStream& oBuffer) continue; // readStream - m_fFile.seekg((nSecNum + 1) * m_nSectorSize); - m_fFile.read(oBuffer.GetCurPtr(), nRemainSize >= m_nSectorSize ? m_nSectorSize : nRemainSize); + DWORD dwSizeRead; + m_oFile.SeekFile((nSecNum + 1) * m_nSectorSize); + m_oFile.ReadFile((BYTE*)oBuffer.GetCurPtr(), nRemainSize >= m_nSectorSize ? m_nSectorSize : nRemainSize, dwSizeRead); - oBuffer.Skip(m_fFile.gcount()); - nRemainSize -= m_fFile.gcount(); + oBuffer.Skip(dwSizeRead); + nRemainSize -= dwSizeRead; } } @@ -134,22 +140,20 @@ bool CCompoundFile::Read(const CDirectoryEntry& oEntry, CHWPStream& oBuffer) bool CCompoundFile::Open() { - if (m_fFile.bad()) - return false; - CHWPStream oBuffer(m_nSectorSize); if (!oBuffer.IsValid()) return false; - m_fFile.read(oBuffer.GetCurPtr(), m_nSectorSize); + DWORD dwSizeRead; + m_oFile.ReadFile((BYTE*)oBuffer.GetCurPtr(), m_nSectorSize, dwSizeRead); - if (m_fFile.gcount() != m_nSectorSize || !ParseHeader(oBuffer)) + if (dwSizeRead != m_nSectorSize || !ParseHeader(oBuffer)) return false; if (0x0004 == m_nMajorVersion) { - m_fFile.seekg(4096); + m_oFile.SeekFile(4096); m_nSectorSize = 4096; } @@ -323,8 +327,7 @@ bool CCompoundFile::Open() void CCompoundFile::Close() { - if (m_fFile.is_open()) - m_fFile.close(); + m_oFile.CloseFile(); } void CCompoundFile::AddSiblings(VECTOR& arIndexs, int nCurrentIndex) const @@ -367,10 +370,11 @@ VECTOR CCompoundFile::GetSecIDsFromSAT(int nSecID, int nSatIndex, int nSecI if (!oBuffer.IsValid()) return VECTOR(); - m_fFile.seekg((nSecID + 1) * m_nSectorSize); - m_fFile.read(oBuffer.GetCurPtr(), m_nSectorSize); + DWORD dwSizeRead; + m_oFile.SeekFile((nSecID + 1) * m_nSectorSize); + m_oFile.ReadFile((BYTE*)oBuffer.GetCurPtr(), m_nSectorSize, dwSizeRead); - if (m_fFile.gcount() != m_nSectorSize) + if (dwSizeRead != m_nSectorSize) return VECTOR(); int nCurrSecID = nSecIDSSAT; @@ -399,10 +403,11 @@ void CCompoundFile::ReadDirectorySector(int nSecID) if (!oBuffer.IsValid()) return; - m_fFile.seekg((nSecID + 1) * m_nSectorSize); - m_fFile.read(oBuffer.GetCurPtr(), m_nSectorSize); + DWORD dwSizeRead; + m_oFile.SeekFile((nSecID + 1) * m_nSectorSize); + m_oFile.ReadFile((BYTE*)oBuffer.GetCurPtr(), m_nSectorSize, dwSizeRead); - if (m_fFile.gcount() == m_nSectorSize) + if (dwSizeRead == m_nSectorSize) ParseDirectorySector(oBuffer); } @@ -413,10 +418,11 @@ void CCompoundFile::ReadSSATSector(int nSecID) if (!oBuffer.IsValid()) return; - m_fFile.seekg((nSecID + 1) * m_nSectorSize); - m_fFile.read(oBuffer.GetCurPtr(), m_nSectorSize); + DWORD dwSizeRead; + m_oFile.SeekFile((nSecID + 1) * m_nSectorSize); + m_oFile.ReadFile((BYTE*)oBuffer.GetCurPtr(), m_nSectorSize, dwSizeRead); - if (m_fFile.gcount() == m_nSectorSize) + if (dwSizeRead == m_nSectorSize) ParseSSATSector(oBuffer); } @@ -427,10 +433,11 @@ void CCompoundFile::ReadMSATSector(int nSecID) if (!oBuffer.IsValid()) return; - m_fFile.seekg((nSecID + 1) * m_nSectorSize); - m_fFile.read(oBuffer.GetCurPtr(), m_nSectorSize); + DWORD dwSizeRead; + m_oFile.SeekFile((nSecID + 1) * m_nSectorSize); + m_oFile.ReadFile((BYTE*)oBuffer.GetCurPtr(), m_nSectorSize, dwSizeRead); - if (m_fFile.gcount() == m_nSectorSize) + if (dwSizeRead == m_nSectorSize) ParseMSATSector(oBuffer); } @@ -618,14 +625,14 @@ bool CCompoundFile::ParseHeader(CHWPStream& oBuffer) int nSectorShift = oBuffer.ReadShort(); - m_nSectorSize = std::pow(2., (double)nSectorShift); + m_nSectorSize = pow(2., (double)nSectorShift); if ((0x0003 == m_nMajorVersion && 0x0009 != nSectorShift) || (0x0004 == m_nMajorVersion && 0x000C != nSectorShift)) return false; nSectorShift = oBuffer.ReadShort(); - m_nShortSectorSize = std::pow(2., (double)nSectorShift); + m_nShortSectorSize = pow(2., (double)nSectorShift); if (0x0006 != nSectorShift) return false; diff --git a/HwpFile/HwpDoc/OLEdoc/CompoundFile.h b/HwpFile/HwpDoc/OLEdoc/CompoundFile.h index b4ff688e04..7db0875cf9 100644 --- a/HwpFile/HwpDoc/OLEdoc/CompoundFile.h +++ b/HwpFile/HwpDoc/OLEdoc/CompoundFile.h @@ -4,13 +4,13 @@ #include "Sector.h" #include "DirectoryEntry.h" #include "../HWPStream.h" -#include +#include "../../DesktopEditor/common/File.h" namespace HWP { class CCompoundFile { - std::ifstream m_fFile; + NSFile::CFileBinary m_oFile; int m_nMinorVersion; int m_nMajorVersion; int m_nSectorSize; diff --git a/HwpFile/HwpDoc/Paragraph/CharShape.cpp b/HwpFile/HwpDoc/Paragraph/CharShape.cpp index 5edd51f2ac..789066bd48 100644 --- a/HwpFile/HwpDoc/Paragraph/CharShape.cpp +++ b/HwpFile/HwpDoc/Paragraph/CharShape.cpp @@ -1,6 +1,7 @@ #include "CharShape.h" #include "CtrlCharacter.h" #include "ParaText.h" +#include namespace HWP { diff --git a/HwpFile/HwpDoc/Paragraph/CharShape.h b/HwpFile/HwpDoc/Paragraph/CharShape.h index 172991f26e..e0ccfa5ff8 100644 --- a/HwpFile/HwpDoc/Paragraph/CharShape.h +++ b/HwpFile/HwpDoc/Paragraph/CharShape.h @@ -1,7 +1,6 @@ #ifndef CHARSHAPE_H #define CHARSHAPE_H -#include #include "../HWPStream.h" #include "Ctrl.h" diff --git a/HwpFile/HwpDoc/Paragraph/HWPPargraph.cpp b/HwpFile/HwpDoc/Paragraph/HWPPargraph.cpp index 1effd8275a..a40699eb36 100644 --- a/HwpFile/HwpDoc/Paragraph/HWPPargraph.cpp +++ b/HwpFile/HwpDoc/Paragraph/HWPPargraph.cpp @@ -1,4 +1,5 @@ #include "HWPPargraph.h" +#include namespace HWP { From 4003a39ef9991dc79168d087abb41d0554808700 Mon Sep 17 00:00:00 2001 From: Green Date: Tue, 14 Jan 2025 01:42:46 +0300 Subject: [PATCH 16/51] Fix typo --- HwpFile/HwpDoc/OLEdoc/CompoundFile.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HwpFile/HwpDoc/OLEdoc/CompoundFile.h b/HwpFile/HwpDoc/OLEdoc/CompoundFile.h index 7db0875cf9..50a52288aa 100644 --- a/HwpFile/HwpDoc/OLEdoc/CompoundFile.h +++ b/HwpFile/HwpDoc/OLEdoc/CompoundFile.h @@ -4,7 +4,7 @@ #include "Sector.h" #include "DirectoryEntry.h" #include "../HWPStream.h" -#include "../../DesktopEditor/common/File.h" +#include "../../../DesktopEditor/common/File.h" namespace HWP { From 9aaa24152316b656f0a4f2b577e264cfd4e79304 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Tue, 14 Jan 2025 11:01:03 +0300 Subject: [PATCH 17/51] fix bug #72328 --- OdfFile/Reader/Converter/docx_drawing.cpp | 3 +- OdfFile/Reader/Converter/mediaitems.cpp | 105 ++++++++++++- OdfFile/Reader/Converter/mediaitems.h | 3 + OdfFile/Reader/Converter/oox_package.cpp | 151 +++++++++++++++++-- OdfFile/Reader/Converter/oox_rels.h | 3 +- OdfFile/Reader/Format/draw_frame.cpp | 33 ++-- OdfFile/Reader/Format/draw_frame.h | 36 ++--- OdfFile/Reader/Format/draw_frame_docx.cpp | 24 ++- OdfFile/Reader/Format/office_binary_data.cpp | 23 ++- OdfFile/Reader/Format/office_binary_data.h | 1 + 10 files changed, 322 insertions(+), 60 deletions(-) diff --git a/OdfFile/Reader/Converter/docx_drawing.cpp b/OdfFile/Reader/Converter/docx_drawing.cpp index 4499362aed..84c9f51a3c 100644 --- a/OdfFile/Reader/Converter/docx_drawing.cpp +++ b/OdfFile/Reader/Converter/docx_drawing.cpp @@ -754,7 +754,8 @@ void _docx_drawing::serialize(std::wostream & strm/*, bool insideOtherDrawing*/) return docx_serialize_child(strm, *this); if (type == typeMsObject || - type == typeOleObject) + type == typeOleObject || + type == typePDF) { docx_serialize_object(strm, *this); } diff --git a/OdfFile/Reader/Converter/mediaitems.cpp b/OdfFile/Reader/Converter/mediaitems.cpp index 01e4e350bb..5de91800ed 100644 --- a/OdfFile/Reader/Converter/mediaitems.cpp +++ b/OdfFile/Reader/Converter/mediaitems.cpp @@ -43,8 +43,13 @@ #include "../../../DesktopEditor/common/Directory.h" #include "../../../DesktopEditor/raster/ImageFileFormatChecker.h" +#include "../../../Common/OfficeFileFormatChecker.h" #include "../../../DesktopEditor/graphics/pro/Fonts.h" +#include "../../../DesktopEditor/graphics/MetafileToGraphicsRenderer.h" +#include "../../../DesktopEditor/graphics/Image.h" +#include "../../../PdfFile/PdfFile.h" + namespace cpdoccore { namespace oox { @@ -89,7 +94,7 @@ mediaitems::mediaitems(const std::wstring & odfPacket) : odf_packet_(odfPacket) count_activeX = 0; count_control = 0; - applicationFonts_ = NSFonts::NSApplication::Create(); + applicationFonts_ = NSFonts::NSApplication::Create(); } mediaitems::~mediaitems() { @@ -98,8 +103,13 @@ mediaitems::~mediaitems() } void mediaitems::set_font_directory(std::wstring pathFonts) { - if (applicationFonts_) - applicationFonts_->InitializeFromFolder(pathFonts); + if (applicationFonts_) + { + if (pathFonts.empty()) + applicationFonts_->Initialize(); + else + applicationFonts_->InitializeFromFolder(pathFonts); + } } bool mediaitems::is_internal_path(const std::wstring& uri, const std::wstring& packetRoot) { @@ -171,6 +181,7 @@ std::wstring static get_default_file_name(_rels_type type) case typeMsObject: return L"msObject"; case typeOleObject: + case typePDF: return L"oleObject"; case typeMedia: return L"media"; @@ -183,7 +194,7 @@ std::wstring static get_default_file_name(_rels_type type) case typeControl: return L"control"; case typeControlProps: - return L"controlProps"; + return L"controlProps"; default: return L""; } @@ -227,6 +238,8 @@ std::wstring mediaitems::create_file_name(const std::wstring & uri, _rels_type t sExt = L".bin"; else if ( type == typeChart) sExt = L".xml"; + else if ( type == typePDF) + sExt = L".bin"; return get_default_file_name(type) + std::to_wstring(Num) + sExt; } @@ -246,6 +259,16 @@ std::wstring mediaitems::detectImageFileExtension(const std::wstring &fileName) CImageFileFormatChecker image_checker; sExt = image_checker.DetectFormatByData(buffer, buffer_size); + if (sExt.empty()) + { + std::wstring documentID; + COfficeFileFormatChecker office_checker; + + if (office_checker.isPdfFormatFile(buffer, buffer_size, documentID)) + { + sExt = L"pdf"; + } + } if (sExt.empty()) { size_t n = fileName.rfind(L"."); @@ -268,7 +291,7 @@ std::wstring mediaitems::add_or_find(const std::wstring & href, _rels_type type, { sub_path = L"charts/"; } - else if ( type == typeMsObject || type == typeOleObject) + else if ( type == typeMsObject || type == typeOleObject || type == typePDF) { isMediaInternal = is_internal(href, odf_packet_); sub_path = L"embeddings/"; @@ -293,8 +316,9 @@ std::wstring mediaitems::add_or_find(const std::wstring & href, _rels_type type, else if ( type == typeAudio) number = count_audio + 1; else if ( type == typeVideo) number = count_video + 1; else if ( type == typeSlide) number = count_slide + 1; - else if ( type == typeMsObject || - type == typeOleObject) number = count_object + 1; + else if ( type == typeMsObject || + type == typeOleObject || + type == typePDF) number = count_object + 1; else if ( type == typeControl) number = count_control + 1; else number = items_.size() + 1; @@ -342,7 +366,7 @@ std::wstring mediaitems::add_or_find(const std::wstring & href, _rels_type type, id = std::wstring(L"picId") + std::to_wstring(count_image + 1); count_image++; } - else if ( type == typeMsObject || type == typeOleObject) + else if ( type == typeMsObject || type == typeOleObject || type == typePDF) { id = std::wstring(L"objId") + std::to_wstring(count_object + 1); count_object++; @@ -414,6 +438,71 @@ void mediaitems::dump_rels(rels & Rels, _rels_type_place type_place) items_[i].count_used++; } } +bool mediaitems::pdf2image(const std::wstring& pdf_file_name, const std::wstring& image_file_name) +{ + _UINT32 nRes = 0; + IOfficeDrawingFile* pReader = new CPdfFile(applicationFonts_); + if (!pReader) return false; + + bool bResult = pReader->LoadFromFile(pdf_file_name.c_str(), L""); + + if (bResult) + { + // default as in CMetafileToRenderterRaster + int nRasterFormat = 4; + int nSaveType = 2; + bool bIsOnlyFirst = true; + bool bIsZip = true; + int nRasterW = 100; + int nRasterH = 100; + + int nSaveFlags = (nSaveType & 0xF0) >> 4; + nSaveType = nSaveType & 0x0F; + + int nPagesCount = 1; + + { + int nRasterWCur = nRasterW; + int nRasterHCur = nRasterH; + + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + pReader->GetPageInfo(0, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + + if (nSaveFlags & 0x0F) + { + if (((dWidth < dHeight) && (nRasterWCur > nRasterHCur)) || + ((dWidth > dHeight) && (nRasterWCur < nRasterHCur))) + { + int nTmp = nRasterWCur; + nRasterWCur = nRasterHCur; + nRasterHCur = nTmp; + } + } + + if (1 == nSaveType) + { + double dKoef1 = nRasterWCur / dWidth; + double dKoef2 = nRasterHCur / dHeight; + if (dKoef1 > dKoef2) + dKoef1 = dKoef2; + + nRasterWCur = (int)(dWidth * dKoef1 + 0.5); + nRasterHCur = (int)(dHeight * dKoef1 + 0.5); + } + else if (2 == nSaveType) + { + nRasterWCur = -1; + nRasterHCur = -1; + } + + pReader->ConvertToRaster(0, image_file_name, nRasterFormat, nRasterWCur, nRasterHCur); + } + } + + delete pReader; + return bResult; +} } diff --git a/OdfFile/Reader/Converter/mediaitems.h b/OdfFile/Reader/Converter/mediaitems.h index d0f953d9db..ac40bf2d6f 100644 --- a/OdfFile/Reader/Converter/mediaitems.h +++ b/OdfFile/Reader/Converter/mediaitems.h @@ -106,6 +106,7 @@ public: case typeImage: return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"; case typeChart: return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"; case typeMsObject: return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/package"; + case typePDF: case typeOleObject: return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject"; case typeHyperlink: return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"; case typeMedia: return L"http://schemas.microsoft.com/office/2007/relationships/media"; @@ -146,6 +147,8 @@ public: return typeMedia; } + bool pdf2image(const std::wstring& pdf_file_name, const std::wstring& image_file_name); + private: std::wstring create_file_name (const std::wstring & uri, _rels_type type, bool & isInternal, size_t Num); std::wstring detectImageFileExtension (const std::wstring &fileName); diff --git a/OdfFile/Reader/Converter/oox_package.cpp b/OdfFile/Reader/Converter/oox_package.cpp index 0461de45b7..bae9856174 100644 --- a/OdfFile/Reader/Converter/oox_package.cpp +++ b/OdfFile/Reader/Converter/oox_package.cpp @@ -43,6 +43,8 @@ #include "../../../DesktopEditor/raster/Metafile/MetaFileCommon.h" #include "../../../DesktopEditor/raster/ImageFileFormatChecker.h" #include "../../../OOXML/Base/Base.h" +#include "../../../Common/cfcpp/compoundfile.h" +#include "../../../Common/3dParty/pole/pole.h" namespace cpdoccore { namespace oox { @@ -387,9 +389,9 @@ void media::write(const std::wstring & RootPath) for (size_t i = 0; i < items.size(); i++ ) { if (items[i].valid && ( items[i].type == typeImage || - items[i].type == typeMedia || - items[i].type == typeAudio || - items[i].type == typeVideo )) + items[i].type == typeMedia || + items[i].type == typeAudio || + items[i].type == typeVideo )) { std::wstring &file_name = items[i].href; std::wstring file_name_out = RootPath + FILE_SEPARATOR_STR + items[i].outputName; @@ -431,18 +433,143 @@ void embeddings::write(const std::wstring & RootPath) for (size_t i = 0; i < items.size(); i++ ) { - if ( items[i].mediaInternal && items[i].valid && - (items[i].type == typeMsObject || items[i].type == typeOleObject)) - { - int pos = items[i].outputName.rfind(L"."); - std::wstring extension = pos >= 0 ? items[i].outputName.substr(pos + 1) : L""; - - content_types.add_or_find_default(extension); + int pos = items[i].outputName.rfind(L"."); + std::wstring extension = pos >= 0 ? items[i].outputName.substr(pos + 1) : L""; - std::wstring file_name_out = RootPath + FILE_SEPARATOR_STR + items[i].outputName; - + content_types.add_or_find_default(extension); + + std::wstring file_name_out = RootPath + FILE_SEPARATOR_STR + items[i].outputName; + + if ( items[i].mediaInternal && items[i].valid && + (items[i].type == typeMsObject || items[i].type == typeOleObject )) + { NSFile::CFileBinary::Copy(items[i].href, file_name_out); } + else if (items[i].type == typePDF) + { + std::string name = "Acrobat Document"; + std::string class_name = "Acrobat Document"; + std::string class_name2 = "Acrobat.Document.DC"; + + _UINT32 name_size = (_UINT32)name.length() + 1; + _UINT32 class_name_size = class_name.size() + 1; + _UINT32 class_name2_size = class_name2.size() + 1; + + DWORD nativeDataSize = 0; + BYTE* nativeData = NULL; + + NSFile::CFileBinary file; + file.ReadAllBytes(items[i].href, &nativeData, nativeDataSize); + + CFCPP::CompoundFile* storageOut = new CFCPP::CompoundFile(CFCPP::Ver_3, CFCPP::Default); + if (storageOut && nativeData) + { + _UINT32 tmp = 0; + //CompObj + BYTE dataCompObjHeader[28] = { 0x01, 0x00, 0xfe, 0xff, 0x03, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x65, 0xca, 0x01, 0xb8, 0xfc, 0xa1, 0xd0, 0x11, 0x85, 0xad, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 }; + + std::shared_ptr oStreamCompObj = storageOut->RootStorage()->AddStream(L"\001CompObj"); + long long posStreamCompObj = 0; + oStreamCompObj->Write((char*)dataCompObjHeader, 0, 28); posStreamCompObj += 28; + + oStreamCompObj->Write((char*)&class_name_size, posStreamCompObj, 4); posStreamCompObj += 4; + oStreamCompObj->Write((char*)class_name.c_str(), posStreamCompObj, class_name_size); posStreamCompObj += class_name_size; + + tmp = 0; + oStreamCompObj->Write((char*)&tmp, posStreamCompObj, 4); posStreamCompObj += 4; + + oStreamCompObj->Write((char*)&class_name2_size, posStreamCompObj, 4); posStreamCompObj += 4; + oStreamCompObj->Write((char*)class_name2.c_str(), posStreamCompObj, class_name2_size); posStreamCompObj += class_name2_size; + + tmp = 0x71B239F4; + oStreamCompObj->Write((char*)&tmp, posStreamCompObj, 4); posStreamCompObj += 4;// UnicodeMarker + + tmp = 0; + oStreamCompObj->Write((char*)&tmp, posStreamCompObj, 4); posStreamCompObj += 4;// UnicodeUserType + oStreamCompObj->Write((char*)&tmp, posStreamCompObj, 4); posStreamCompObj += 4;// UnicodeClipboardFormat + oStreamCompObj->Write((char*)&tmp, posStreamCompObj, 4); posStreamCompObj += 4;// + + //Ole + BYTE dataOleInfo[] = { 0x01, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; + + std::shared_ptr oStreamOle = storageOut->RootStorage()->AddStream(L"\001Ole"); + oStreamOle->Write((char*)dataOleInfo, 0, 20); + + //CONTENTS + std::shared_ptr oStreamCONTENTS = storageOut->RootStorage()->AddStream(L"CONTENTS"); + oStreamCONTENTS->Write((char*)nativeData, 0, nativeDataSize); + + //ObjInfo + std::shared_ptr oStreamObjInfo = storageOut->RootStorage()->AddStream(L"\003ObjInfo"); + + BYTE dataObjInfo[] = { 0x00, 0x00, 0x03, 0x00, 0x0D, 0x00 }; + oStreamObjInfo->Write((char*)dataObjInfo, 0, 6); + + bool result = storageOut->Save(file_name_out); + storageOut->Close(); + } + if (storageOut) delete storageOut; + + //POLE::Storage* storageOut = new POLE::Storage(file_name_out.c_str()); + //if ((storageOut) && (storageOut->open(true, true))) + //{ + // _UINT32 tmp = 0; + // std::string name = class_name; + // _UINT32 name_size = (_UINT32)name.length() + 1; + ////Ole + // BYTE dataOleInfo[] = { 0x01, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; + // POLE::Stream oStream3(storageOut, L"\001Ole", true, 20); + // oStream3.write(dataOleInfo, 20); + // oStream3.flush(); + ////CompObj + // BYTE dataCompObjHeader[28] = { 0x01, 0x00, 0xfe, 0xff, 0x03, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + // 0x65, 0xca, 0x01, 0xb8, 0xfc, 0xa1, 0xd0, 0x11, 0x85, 0xad, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 }; + + // POLE::Stream oStream1(storageOut, L"\001CompObj", true, 28 + (class_name_size + 4) + (class_name2_size + 4) + 4 * 4); + // oStream1.write(dataCompObjHeader, 28); + + // oStream1.write((BYTE*)&class_name_size, 4); + // oStream1.write((BYTE*)class_name.c_str(), class_name_size); + + // tmp = 0; + // oStream1.write((BYTE*)&tmp, 4); + + // oStream1.write((BYTE*)&class_name2_size, 4); + // oStream1.write((BYTE*)class_name2.c_str(), class_name2_size); + + // tmp = 0x71B239F4; + // oStream1.write((BYTE*)&tmp, 4); // UnicodeMarker + + // tmp = 0; + // oStream1.write((BYTE*)&tmp, 4); // UnicodeUserType + // oStream1.write((BYTE*)&tmp, 4); // UnicodeClipboardFormat + // oStream1.write((BYTE*)&tmp, 4); // + // oStream1.flush(); + + // //ObjInfo + // BYTE dataObjInfo[] = { 0x00,0x00,0x03,0x00,0x0D,0x00 }; + // POLE::Stream oStream2(storageOut, L"\003ObjInfo", true, 6); + // oStream2.write(dataObjInfo, 6); + // oStream2.flush(); + + // POLE::Stream streamData(storageOut, L"CONTENTS", true, nativeDataSize); + // _UINT32 sz_write = 0; + // _UINT32 sz = 4096; + // while (sz_write < nativeDataSize) + // { + // if (sz_write + sz > nativeDataSize) + // sz = nativeDataSize - sz_write; + // streamData.write(nativeData + sz_write, sz); + // sz_write += sz; + // } + // streamData.flush(); + + // storageOut->close(); + // delete storageOut; + //} + if (nativeData) delete[]nativeData; + } } } diff --git a/OdfFile/Reader/Converter/oox_rels.h b/OdfFile/Reader/Converter/oox_rels.h index be4c1c4903..7ed7f65650 100644 --- a/OdfFile/Reader/Converter/oox_rels.h +++ b/OdfFile/Reader/Converter/oox_rels.h @@ -61,7 +61,8 @@ enum _rels_type typeActiveX, typeControl, typeControlProps, - typeChartUserShapes + typeChartUserShapes, + typePDF }; enum _rels_type_place { diff --git a/OdfFile/Reader/Format/draw_frame.cpp b/OdfFile/Reader/Format/draw_frame.cpp index d595634c86..ea19a7edbb 100644 --- a/OdfFile/Reader/Format/draw_frame.cpp +++ b/OdfFile/Reader/Format/draw_frame.cpp @@ -82,8 +82,9 @@ void draw_chart_attlist::add_attributes( const xml::attributes_wc_ptr & Attribut { //CP_APPLY_ATTR(L"draw:filter-name", draw_filter_name_); } +//------------------------------------------------------------------------------------------------------------ // draw:image -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_image::ns = L"draw"; const wchar_t * draw_image::name = L"image"; @@ -100,7 +101,6 @@ void draw_image::add_attributes( const xml::attributes_wc_ptr & Attributes ) draw_image_attlist_.add_attributes(Attributes); xlink_attlist_.add_attributes(Attributes); } - void draw_image::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) { if CP_CHECK_NAME(L"office", L"binary-data") @@ -116,8 +116,9 @@ std::wostream & draw_image::text_to_stream(std::wostream & _Wostream, bool bXmlE { return _Wostream; } +//------------------------------------------------------------------------------------------------------------ // draw:chart -//////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_chart::ns = L"draw"; const wchar_t * draw_chart::name = L"chart"; @@ -145,8 +146,9 @@ void draw_chart::add_child_element( xml::sax * Reader, const std::wstring & Ns, } +//------------------------------------------------------------------------------------------------------------ // draw:g -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_g::ns = L"draw"; const wchar_t * draw_g::name = L"g"; void draw_g::add_attributes( const xml::attributes_wc_ptr & Attributes ) @@ -242,8 +244,9 @@ std::wostream & draw_g::text_to_stream(std::wostream & _Wostream, bool bXmlEncod return _Wostream; } +//------------------------------------------------------------------------------------------------------------ // draw:frame -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_frame::ns = L"draw"; const wchar_t * draw_frame::name = L"frame"; @@ -252,7 +255,6 @@ std::wostream & draw_frame::text_to_stream(std::wostream & _Wostream, bool bXmlE CP_SERIALIZE_TEXT(content_, bXmlEncode); return _Wostream; } - void draw_frame::add_attributes( const xml::attributes_wc_ptr & Attributes ) { idx_in_owner = -1; @@ -263,7 +265,6 @@ void draw_frame::add_attributes( const xml::attributes_wc_ptr & Attributes ) draw_frame_attlist_.add_attributes(Attributes); } - void draw_frame::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) { if (CP_CHECK_NAME(L"draw", L"text-box") || @@ -325,8 +326,9 @@ void draw_text_box_attlist::add_attributes( const xml::attributes_wc_ptr & Attri CP_APPLY_ATTR(L"fo:max-height", fo_max_height_); } +//------------------------------------------------------------------------------------------------------------ // draw:text-box -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_text_box::ns = L"draw"; const wchar_t * draw_text_box::name = L"text-box"; @@ -352,8 +354,9 @@ void draw_text_box::add_child_element( xml::sax * Reader, const std::wstring & N CP_CREATE_ELEMENT(content_); } +//------------------------------------------------------------------------------------------------------------ // draw:object -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_object::ns = L"draw"; const wchar_t * draw_object::name = L"object"; @@ -379,8 +382,9 @@ void draw_object::add_child_element( xml::sax * Reader, const std::wstring & Ns, } } +//------------------------------------------------------------------------------------------------------------ // draw:object-ole -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_object_ole::ns = L"draw"; const wchar_t * draw_object_ole::name = L"object-ole"; @@ -444,7 +448,8 @@ void draw_object_ole::detectObject(const std::wstring &fileName, std::wstring &p COfficeFileFormatChecker checker(fileName); switch(checker.nFileType) { - case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC: extension = L".doc"; prog = L"Word"; rels = oox::typeOleObject; break; + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC: + case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC_FLAT: extension = L".doc"; prog = L"Word"; rels = oox::typeOleObject; break; case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX: extension = L".docx"; prog = L"Word"; rels = oox::typeMsObject; break; case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS: extension = L".xls"; prog = L"Excel"; rels = oox::typeOleObject; break; @@ -517,8 +522,9 @@ std::wstring draw_object::office_convert(odf_document_ptr odfDocument, int type) return href_result; } +//------------------------------------------------------------------------------------------------------------ // draw:param -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_param::ns = L"draw"; const wchar_t * draw_param::name = L"param"; @@ -532,8 +538,9 @@ void draw_param::add_child_element( xml::sax * Reader, const std::wstring & Ns, { CP_NOT_APPLICABLE_ELM(); } +//------------------------------------------------------------------------------------------------------------ // draw:plugin -////////////////////////////////////////////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------------------------------------ const wchar_t * draw_plugin::ns = L"draw"; const wchar_t * draw_plugin::name = L"plugin"; diff --git a/OdfFile/Reader/Format/draw_frame.h b/OdfFile/Reader/Format/draw_frame.h index 30ff4f0de7..1a17dfc805 100644 --- a/OdfFile/Reader/Format/draw_frame.h +++ b/OdfFile/Reader/Format/draw_frame.h @@ -85,6 +85,8 @@ private: office_element_ptr office_binary_data_; office_element_ptr draw_frame_ptr; //openoffice xml 1.0 + + bool convert_pdf2image(NSFonts::IApplicationFonts* applicationFonts, const std::wstring& pdf_file_name, const std::wstring& image_file_name); }; CP_REGISTER_OFFICE_ELEMENT2(draw_image); @@ -146,10 +148,10 @@ public: class draw_frame : public office_element_impl { public: - static const wchar_t * ns; - static const wchar_t * name; - static const xml::NodeType xml_type = xml::typeElement; - static const ElementType type = typeDrawFrame; + static const wchar_t *ns; + static const wchar_t *name; + static const xml::NodeType xml_type = xml::typeElement; + static const ElementType type = typeDrawFrame; CPDOCCORE_DEFINE_VISITABLE(); draw_frame() : oox_drawing_(), idx_in_owner(-1), is_object_(false) {} @@ -165,33 +167,33 @@ public: int idx_in_owner ; - odf_types::union_common_draw_attlists common_draw_attlists_; + odf_types::union_common_draw_attlists common_draw_attlists_; - draw_frame_attlist draw_frame_attlist_; + draw_frame_attlist draw_frame_attlist_; // draw-text-box, draw-image, draw-object, draw-object-ole, draw-applet, draw-floating-frame, draw-plugin - office_element_ptr_array content_; + office_element_ptr_array content_; - office_element_ptr office_event_listeners_; + office_element_ptr office_event_listeners_; - office_element_ptr draw_glue_point_; - office_element_ptr draw_image_map_; + office_element_ptr draw_glue_point_; + office_element_ptr draw_image_map_; - office_element_ptr draw_contour_; // draw-contour-polygon or draw-contour-path + office_element_ptr draw_contour_; // draw-contour-polygon or draw-contour-path - office_element_ptr svg_title_; - office_element_ptr svg_desc_; + office_element_ptr svg_title_; + office_element_ptr svg_desc_; friend class odf_document; friend class draw_image; friend class draw_chart; - oox_drawing_ptr oox_drawing_; + oox_drawing_ptr oox_drawing_; - bool is_object_; + bool is_object_; private: - virtual void add_attributes ( const xml::attributes_wc_ptr & Attributes ); - virtual void add_child_element ( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); + virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); + virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); void docx_convert_start(oox::docx_conversion_context & Context); void docx_convert_end(oox::docx_conversion_context & Context); diff --git a/OdfFile/Reader/Format/draw_frame_docx.cpp b/OdfFile/Reader/Format/draw_frame_docx.cpp index cdc27029ce..f0cd798e64 100644 --- a/OdfFile/Reader/Format/draw_frame_docx.cpp +++ b/OdfFile/Reader/Format/draw_frame_docx.cpp @@ -1200,6 +1200,7 @@ void draw_image::docx_convert(oox::docx_conversion_context & Context) std::wstring href = xlink_attlist_.href_.get_value_or(L""); + oox::_rels_type type = oox::typeImage; if (true == href.empty()) { office_binary_data* binary_data = dynamic_cast(office_binary_data_.get()); @@ -1207,6 +1208,7 @@ void draw_image::docx_convert(oox::docx_conversion_context & Context) if (binary_data) { href = binary_data->write_to(Context.root()->get_folder()); + type = (oox::_rels_type)binary_data->type_binary_data; } } else @@ -1229,7 +1231,7 @@ void draw_image::docx_convert(oox::docx_conversion_context & Context) if (href[0] == L'#') href = href.substr(1); if (drawing->type == oox::typeUnknown) - drawing->type = oox::typeImage; + drawing->type = type; oox::StreamsManPtr prev = Context.get_stream_man(); @@ -1264,10 +1266,26 @@ void draw_image::docx_convert(oox::docx_conversion_context & Context) drawing->fill.bitmap = oox::oox_bitmap_fill::create(); drawing->fill.type = 2; drawing->fill.bitmap->isInternal = false; - drawing->fill.bitmap->rId = Context.get_mediaitems()->add_or_find(href, oox::typeImage, drawing->fill.bitmap->isInternal, href, Context.get_type_place()); drawing->fill.bitmap->bStretch = true; - const std::wstring styleName = frame->common_draw_attlists_.shape_with_text_and_styles_. + std::wstring href_out; + if (drawing->type == oox::typePDF) + { + drawing->objectProgId = L"Acrobat.Document.DC"; + drawing->objectId = Context.get_mediaitems()->add_or_find(href, type, drawing->fill.bitmap->isInternal, href_out, Context.get_type_place()); + + std::wstring image_file = NSFile::CFileBinary::CreateTempFileWithUniqueName(Context.root()->get_folder() + FILE_SEPARATOR_STR, L"img"); + + if (Context.get_mediaitems()->pdf2image(Context.root()->get_folder() + FILE_SEPARATOR_STR + href, image_file)) + { + int pos = image_file.rfind(FILE_SEPARATOR_STR); + href = image_file.substr(pos + 1); + } + } + + drawing->fill.bitmap->rId = Context.get_mediaitems()->add_or_find(href, oox::typeImage, drawing->fill.bitmap->isInternal, href_out, Context.get_type_place()); + + const std::wstring styleName = frame->common_draw_attlists_.shape_with_text_and_styles_. common_shape_draw_attlist_.draw_style_name_.get_value_or(L""); odf_reader::style_instance* styleInst = Context.root()->odf_context().styleContainer().style_by_name(styleName, odf_types::style_family::Graphic,Context.process_headers_footers_); diff --git a/OdfFile/Reader/Format/office_binary_data.cpp b/OdfFile/Reader/Format/office_binary_data.cpp index 94752673b7..4538a028ae 100644 --- a/OdfFile/Reader/Format/office_binary_data.cpp +++ b/OdfFile/Reader/Format/office_binary_data.cpp @@ -31,14 +31,12 @@ */ #include "office_binary_data.h" - -#include +#include "../../../DesktopEditor/raster/ImageFileFormatChecker.h" +#include "../../../Common/OfficeFileFormatChecker.h" namespace cpdoccore { namespace odf_reader { - - // office:binary-data ////////////////////////////////////////////////////////////////////////////////////////////////// const wchar_t * office_binary_data::ns = L"office"; @@ -72,9 +70,24 @@ std::wstring office_binary_data::write_to(const std::wstring & path) NSFile::CBase64Converter::Decode(base64Binary_.c_str(), base64Binary_.length(), pData, nLength); if (pData) { + CImageFileFormatChecker image_checker; + std::wstring sExt = image_checker.DetectFormatByData(pData, nLength); + + if (sExt.empty()) + { + std::wstring documentID; + COfficeFileFormatChecker office_checker; + + if (office_checker.isPdfFormatFile(pData, nLength, documentID)) + { + type_binary_data = 20; // oox::_rels_type = typePDF; + sExt = L"pdf"; + } + } + NSFile::CFileBinary file; - std::wstring bin_file = file.CreateTempFileWithUniqueName(path + FILE_SEPARATOR_STR, L"bin"); + std::wstring bin_file = file.CreateTempFileWithUniqueName(path + FILE_SEPARATOR_STR, sExt); if (file.CreateFileW(bin_file)) { file.WriteFile(pData, nLength); diff --git a/OdfFile/Reader/Format/office_binary_data.h b/OdfFile/Reader/Format/office_binary_data.h index d3a18e1c7b..42a3725598 100644 --- a/OdfFile/Reader/Format/office_binary_data.h +++ b/OdfFile/Reader/Format/office_binary_data.h @@ -53,6 +53,7 @@ public: virtual std::wostream & text_to_stream(std::wostream & _Wostream, bool bXmlEncode = true) const; std::wstring write_to(const std::wstring & path); + int type_binary_data = 2; //_rels_type type = Image; private: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); From 89d7242d2155f6834d30dbc44742ad3dd330ccd6 Mon Sep 17 00:00:00 2001 From: Green Date: Wed, 8 Jan 2025 19:04:29 +0300 Subject: [PATCH 18/51] Fix bug #72386 --- .../3dParty/html/css/src/StyleProperties.cpp | 42 +++++++++++++++++++ Common/3dParty/html/css/src/StyleProperties.h | 2 + 2 files changed, 44 insertions(+) diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index eff2556758..69481e53de 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -513,6 +513,9 @@ namespace NSCSS return (*static_cast(m_oValue)) == (*static_cast(oColor.m_oValue)); case ColorUrl: return (*static_cast(m_oValue)) == (*static_cast(oColor.m_oValue)); + case ColorContextStroke: + case ColorContextFill: + return false; } } @@ -532,6 +535,9 @@ namespace NSCSS return (*static_cast(m_oValue)) != (*static_cast(oColor.m_oValue)); case ColorUrl: return (*static_cast(m_oValue)) != (*static_cast(oColor.m_oValue)); + case ColorContextStroke: + case ColorContextFill: + return false; } } @@ -561,6 +567,9 @@ namespace NSCSS m_oValue = new CURL(*static_cast(oColor.m_oValue)); break; } + case ColorContextStroke: + case ColorContextFill: + break; } return *this; @@ -580,6 +589,39 @@ namespace NSCSS : CValue(NULL, 0, false), m_oOpacity(1.), m_enType(ColorEmpty) {} + CColor::CColor(const CColor& oColor) + : CValue(NULL, 0, false), m_oOpacity(oColor.m_oOpacity), m_enType(oColor.m_enType) + { + switch (m_enType) + { + case ColorRGB: + { + TRGB *pRGB = static_cast(oColor.m_oValue); + m_oValue = new TRGB(*pRGB); + break; + } + case ColorHEX: + { + std::wstring* pValue = static_cast(oColor.m_oValue); + m_oValue = new std::wstring(*pValue); + break; + } + case ColorUrl: + { + CURL *pURL = static_cast(oColor.m_oValue); + m_oValue = new CURL(*pURL); + break; + } + default: + break; + } + } + + CColor::~CColor() + { + Clear(); + } + void CColor::SetEmpty(unsigned int unLevel) { Clear(); diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 92713238c2..7a0be6b03b 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -224,6 +224,8 @@ namespace NSCSS { public: CColor(); + CColor(const CColor& oColor); + ~CColor(); bool SetValue(const std::wstring& wsValue, unsigned int unLevel = 0, bool bHardMode = true) override; bool SetOpacity(const std::wstring& wsValue, unsigned int unLevel = 0, bool bHardMode = true); From 8f448d3842ff20a95db0aaa11d1c52d339b4bade Mon Sep 17 00:00:00 2001 From: Green Date: Sat, 11 Jan 2025 22:06:48 +0300 Subject: [PATCH 19/51] For bug #72318 --- .../EmfInterpretator/CEmfInterpretatorSvg.cpp | 17 ++++++++++++----- .../Metafile/Emf/EmfParser/CEmfParserBase.cpp | 16 ++++++++++++---- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp index db78257382..0083d483d0 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp @@ -380,16 +380,23 @@ namespace MetaFile void CEmfInterpretatorSvg::HANDLE_EMR_PIE(const TRectL &oBox, const TPointL &oStart, const TPointL &oEnd) { - short shCenterX = (oBox.Left + oBox.Right) / 2; - short shCenterY = (oBox.Top + oBox.Bottom) / 2; + int nCenterX = (oBox.Left + oBox.Right) / 2; + int nCenterY = (oBox.Top + oBox.Bottom) / 2; short shRadiusX = std::abs(oBox.Right - oBox.Left) / 2; short shRadiusY = std::abs(oBox.Bottom - oBox.Top) / 2; - std::wstring wsPath = L'M' + ConvertToWString(shCenterX) + L' ' + ConvertToWString(shCenterY) + L' ' + + double dStartAngle = std::atan2(oStart.Y - nCenterY, oStart.X - nCenterX); + double dEndAngle = std::atan2(oEnd.Y - nCenterY, oEnd.X - nCenterX); + + if (dEndAngle > dStartAngle) + dEndAngle -= 2 * M_PI; + + std::wstring wsPath = L'M' + ConvertToWString(nCenterX) + L' ' + ConvertToWString(nCenterY) + L' ' + L'L' + ConvertToWString(oStart.X)+ L' ' + ConvertToWString(oStart.Y)+ L' ' + - L'A' + ConvertToWString(shRadiusX) + L' ' + ConvertToWString(shRadiusY) + L" 0, 0, 0, " + ConvertToWString(oEnd.X) + L' ' + ConvertToWString(oEnd.Y) + L' ' + - L'L' + ConvertToWString(shCenterX) + L' ' + ConvertToWString(shCenterY) + L" Z"; + L'A' + ConvertToWString(shRadiusX) + L' ' + ConvertToWString(shRadiusY) + L" 0 " + + ((std::abs(dEndAngle - dStartAngle) > M_PI) ? L'1' : L'0') + L" 0 " + ConvertToWString(oEnd.X) + L' ' + ConvertToWString(oEnd.Y) + L' ' + + L'L' + ConvertToWString(nCenterX) + L' ' + ConvertToWString(nCenterY) + L" Z"; NodeAttributes arAttributes = {{L"d", wsPath}}; diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.cpp index 51811de570..cffcbabb82 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParserBase.cpp @@ -1509,11 +1509,19 @@ namespace MetaFile if (NULL != m_pInterpretator && (NULL == m_pPath || Svg != m_pInterpretator->GetType())) m_pInterpretator->HANDLE_EMR_PIE(oBox, oStart, oEnd); - double dStartAngle = GetEllipseAngle(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, oStart.X, oStart.Y); - double dSweepAngle = GetEllipseAngle(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, oEnd.X, oEnd.Y) - dStartAngle; + const int nCenterX = (oBox.Left + oBox.Right) / 2; + const int nCenterY = (oBox.Top + oBox.Bottom) / 2; - ArcTo(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, dStartAngle, dSweepAngle); - LineTo((oBox.Left + oBox.Right) / 2, (oBox.Top + oBox.Bottom) / 2); + double dStartAngle = std::atan2(oStart.Y - nCenterY, oStart.X - nCenterX); + double dEndAngle = std::atan2(oEnd.Y - nCenterY, oEnd.X - nCenterX); + + if (dEndAngle > dStartAngle) + dEndAngle -= 2 * M_PI; + + MoveTo(nCenterX, nCenterY); + LineTo(oStart.X, oStart.Y); + ArcTo(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, dStartAngle * 180. / M_PI, (dEndAngle - dStartAngle) * 180. / M_PI); + LineTo(nCenterX, nCenterY); ClosePath(); DrawPath(true, true); } From b9e1d77038adf4b25523bed5e0cd054fde959d5e Mon Sep 17 00:00:00 2001 From: Green Date: Sat, 11 Jan 2025 14:53:41 +0300 Subject: [PATCH 20/51] Fix bug #72353 --- .../raster/Metafile/Common/MetaFileObjects.h | 3 ++ .../raster/Metafile/Common/MetaFileRenderer.h | 16 ++++-- .../raster/Metafile/Emf/EmfObjects.cpp | 9 ++++ .../raster/Metafile/Emf/EmfObjects.h | 2 + .../Metafile/Emf/EmfParser/CEmfPlusParser.cpp | 50 +++++++++++++------ .../raster/Metafile/Emf/EmfPlusObjects.cpp | 23 +++++++++ .../raster/Metafile/Emf/EmfPlusObjects.h | 3 ++ .../raster/Metafile/StarView/SvmObjects.cpp | 10 ++++ .../raster/Metafile/StarView/SvmObjects.h | 1 + .../CInterpretatorSvgBase.cpp | 25 +++++++--- .../WmfInterpretator/CInterpretatorSvgBase.h | 1 + .../raster/Metafile/Wmf/WmfObjects.cpp | 10 ++++ .../raster/Metafile/Wmf/WmfObjects.h | 2 + 13 files changed, 129 insertions(+), 26 deletions(-) diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileObjects.h b/DesktopEditor/raster/Metafile/Common/MetaFileObjects.h index 4f11b6c8c2..1c96b94266 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileObjects.h +++ b/DesktopEditor/raster/Metafile/Common/MetaFileObjects.h @@ -33,6 +33,7 @@ #define _METAFILE_COMMON_METAFILEOBJECTS_H #include +#include namespace MetaFile { @@ -70,6 +71,8 @@ namespace MetaFile virtual void GetBounds(double& left, double& top, double& width, double& height) const = 0; virtual void GetCenterPoint(double& dX, double& dY) const = 0; + virtual std::vector> GetGradientColors() const = 0; + virtual void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const = 0; }; diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileRenderer.h b/DesktopEditor/raster/Metafile/Common/MetaFileRenderer.h index 389a90df7e..20b41a82de 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileRenderer.h +++ b/DesktopEditor/raster/Metafile/Common/MetaFileRenderer.h @@ -1109,12 +1109,18 @@ namespace MetaFile m_pRenderer->put_BrushLinearAngle(pBrush->GetStyleEx()); - long Colors[2]; - Colors[0] = pBrush->GetColor() + (pBrush->GetAlpha() << 24); - Colors[1] = pBrush->GetColor2() + (pBrush->GetAlpha2() << 24); - double Position[2] = {0, 1}; + std::vector> arColors{pBrush->GetGradientColors()}; - m_pRenderer->put_BrushGradientColors(Colors,Position,2); + std::vector arLColors(arColors.size()); + std::vector arDPositions(arColors.size()); + + for (unsigned int unIndex = 0; unIndex < arColors.size(); ++unIndex) + { + arLColors[unIndex] = arColors[unIndex].first; + arDPositions[unIndex] = arColors[unIndex].second; + } + + m_pRenderer->put_BrushGradientColors(arLColors.data(), arDPositions.data(), arColors.size()); } else if ( BS_RADIALGRADIENT == unBrushStyle || diff --git a/DesktopEditor/raster/Metafile/Emf/EmfObjects.cpp b/DesktopEditor/raster/Metafile/Emf/EmfObjects.cpp index 485cdbc437..78bcbdb27e 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfObjects.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfObjects.cpp @@ -155,6 +155,15 @@ namespace MetaFile unHeight = unDibHeigth; } + std::vector > CEmfLogBrushEx::GetGradientColors() const + { + std::vector> arColors(2); + + arColors[0] = std::make_pair(GetColor() + (GetAlpha() << 24), 0.); + arColors[1] = std::make_pair(GetColor2() + (GetAlpha2() << 24), 0.); + + return arColors; + } CEmfLogFont::CEmfLogFont(bool bFixedLength) : m_bFixedLength(bFixedLength) diff --git a/DesktopEditor/raster/Metafile/Emf/EmfObjects.h b/DesktopEditor/raster/Metafile/Emf/EmfObjects.h index b2ba5d7e22..495e51524d 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfObjects.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfObjects.h @@ -77,6 +77,8 @@ namespace MetaFile void GetBounds(double& left, double& top, double& width, double& height) const override; void GetCenterPoint(double& dX, double& dY) const override; void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override; + + std::vector> GetGradientColors() const override; public: unsigned int unBrushStyle; TRGBA oColor; diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp index b8b83d6c65..84249fdcee 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp @@ -655,20 +655,15 @@ namespace MetaFile m_oStream >> unPositionCount; - std::vector arBlendPositions(unPositionCount); - - for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex) - m_oStream >> arBlendPositions[unIndex]; - - std::vector arBlendColors(unPositionCount); - - for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex) - m_oStream >> arBlendColors[unIndex]; - - if (1 < unPositionCount) + if (unPositionCount > 1) { - pEmfPlusBrush->oColorBack = arBlendColors[0]; - pEmfPlusBrush->oColor = arBlendColors.back(); + pEmfPlusBrush->arGradientColors.resize(unPositionCount); + + for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex) + m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].second; + + for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex) + m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].first; } } @@ -679,13 +674,40 @@ namespace MetaFile //TODO: реализовать pEmfPlusBrush->unStyle = BS_LINEARGRADIENT; - m_oStream.Skip(8); // BrushDataFlags, WrapMode + int nBrushDataFlags; + m_oStream >> nBrushDataFlags; + + m_oStream.Skip(4); // WrapMode // m_oStream >> pEmfPlusBrush->RectF; m_oStream.Skip(16); m_oStream >> pEmfPlusBrush->oColor; m_oStream >> pEmfPlusBrush->oColorBack; + m_oStream.Skip(8); // Reserved1, Reserved2 + + if (BrushDataTransform & nBrushDataFlags) + { + m_oStream.Skip(24); + } + + if (BrushDataPresetColors & nBrushDataFlags) + { + int nPositionCount; + m_oStream >> nPositionCount; + + if (nPositionCount > 1) + { + pEmfPlusBrush->arGradientColors.resize(nPositionCount); + + for (unsigned int unIndex = 0; unIndex < nPositionCount; ++unIndex) + m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].second; + + for (unsigned int unIndex = 0; unIndex < nPositionCount; ++unIndex) + m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].first; + } + } + break; } default: diff --git a/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.cpp b/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.cpp index 27459c7405..35e4baf05b 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.cpp @@ -79,6 +79,29 @@ namespace MetaFile height = oRectF.dHeight; } + std::vector > CEmfPlusBrush::GetGradientColors() const + { + if (arGradientColors.empty()) + { + std::vector> arColors(2); + + arColors[0] = std::make_pair(GetColor() + (GetAlpha() << 24), 0.); + arColors[1] = std::make_pair(GetColor2() + (GetAlpha2() << 24), 0.); + + return arColors; + } + + std::vector> arColors(arGradientColors.size()); + + for (unsigned int unIndex = 0; unIndex < arGradientColors.size(); ++unIndex) + { + arColors[unIndex].first = METAFILE_RGBA(arGradientColors[unIndex].first.chRed, arGradientColors[unIndex].first.chGreen, arGradientColors[unIndex].first.chBlue, arGradientColors[unIndex].first.chAlpha); + arColors[unIndex].second = arGradientColors[unIndex].second; + } + + return arColors; + } + CEmfPlusPen::CEmfPlusPen() : unStyle(PS_SOLID | PS_GEOMETRIC | PS_STARTCAP_FLAT | PS_ENDCAP_FLAT | PS_JOIN_MITER), dWidth(1), oColor(0, 0, 0), pBrush(NULL), dMiterLimit(0), dDashOffset(0), diff --git a/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.h b/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.h index 351eb8320e..f473584354 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.h @@ -189,6 +189,7 @@ namespace MetaFile void GetCenterPoint(double& dX, double& dY) const override; void GetBounds(double& left, double& top, double& width, double& height) const override; + std::vector> GetGradientColors() const override; public: TEmfPlusARGB oColor; TEmfPlusARGB oColorBack; @@ -198,6 +199,8 @@ namespace MetaFile TEmfPlusPointF oCenterPoint; unsigned int unAngle; std::wstring wsDibPatternPath; + + std::vector> arGradientColors; }; class CEmfPlusPen: public CEmfPlusObject, public IPen diff --git a/DesktopEditor/raster/Metafile/StarView/SvmObjects.cpp b/DesktopEditor/raster/Metafile/StarView/SvmObjects.cpp index 4654c35218..99ecfb38aa 100644 --- a/DesktopEditor/raster/Metafile/StarView/SvmObjects.cpp +++ b/DesktopEditor/raster/Metafile/StarView/SvmObjects.cpp @@ -358,6 +358,16 @@ void CSvmBrush::GetBounds(double& left, double& top, double& width, double& heig void CSvmBrush::GetDibPattern(unsigned char **pBuffer, unsigned int &unWidth, unsigned int &unHeight) const {} +std::vector > CSvmBrush::GetGradientColors() const +{ + std::vector> arColors(2); + + arColors[0] = std::make_pair(GetColor() + (GetAlpha() << 24), 0.); + arColors[1] = std::make_pair(GetColor2() + (GetAlpha2() << 24), 0.); + + return arColors; +} + int CSvmPen::GetColor() const { return METAFILE_RGBA(Color.r, Color.g, Color.b, 0); diff --git a/DesktopEditor/raster/Metafile/StarView/SvmObjects.h b/DesktopEditor/raster/Metafile/StarView/SvmObjects.h index ed4dc0fed9..71382438ec 100644 --- a/DesktopEditor/raster/Metafile/StarView/SvmObjects.h +++ b/DesktopEditor/raster/Metafile/StarView/SvmObjects.h @@ -300,6 +300,7 @@ public: void GetBounds(double& left, double& top, double& width, double& height) const override; void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override; + std::vector> GetGradientColors() const override; public: unsigned short BrushStyleEx; //angle, or .... unsigned short BrushStyle; diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp index a7a3da0b28..809b254256 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp @@ -1276,16 +1276,19 @@ namespace MetaFile std::wstring wsStyleId; - if (BS_LINEARGRADIENT == pBrush->GetStyle() || - BS_RECTGRADIENT == pBrush->GetStyle() || - BS_PATHGRADIENT == pBrush->GetStyle()) + if (BS_LINEARGRADIENT == pBrush->GetStyle() || + BS_RECTGRADIENT == pBrush->GetStyle() || + BS_PATHGRADIENT == pBrush->GetStyle()) { wsStyleId = L"LINEARGRADIENT_" + ConvertToWString(++m_unNumberDefs, 0); - m_wsDefs += L"" + - L"GetColor(), pBrush->GetAlpha()) + L"\"/>" + - L"GetColor2(), pBrush->GetAlpha2()) + L"\"/>" + - L""; + m_wsDefs += L""; + + for (const std::pair parColorData : pBrush->GetGradientColors()) + m_wsDefs += L""; + + m_wsDefs += L""; return wsStyleId; } @@ -2065,4 +2068,12 @@ namespace MetaFile return L"rgba(" + std::to_wstring(uchRed) + L", " + std::to_wstring(uchGreen) + L", " + std::to_wstring(uchBlue) + L", " + ConvertToWString((double)uchAlpha / 255., 3) + L')'; } + + std::wstring CalculateColor(unsigned int unColor) + { + BYTE chAlpha = unColor >> 24; + + return CalculateColor(unColor, chAlpha); + } + } diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.h b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.h index 5063f58f03..d9779d345c 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.h +++ b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.h @@ -158,6 +158,7 @@ namespace MetaFile friend class CWmfInterpretatorSvg; }; + std::wstring CalculateColor(unsigned int unColor); std::wstring CalculateColor(unsigned int unColor, BYTE uchAlpha); std::wstring CalculateColor(BYTE uchRed, BYTE uchGreen, BYTE uchBlue, BYTE uchAlpha); } diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp index babf1854ad..24b65c198f 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp @@ -162,6 +162,16 @@ namespace MetaFile unHeight = unDibHeigth; } + std::vector > CWmfBrush::GetGradientColors() const + { + std::vector> arColors(2); + + arColors[0] = std::make_pair(GetColor() + (GetAlpha() << 24), 0.); + arColors[1] = std::make_pair(GetColor2() + (GetAlpha2() << 24), 0.); + + return arColors; + } + CWmfFont::CWmfFont() : shHeight(DEFAULT_FONT_SIZE), shWidth(0), shEscapement(0), shOrientation(0), shWeight(400), uchItalic(0x00), uchUnderline(0x00), uchStrikeOut(0x00), uchCharSet(0x01), uchOutPrecision(0x00), diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfObjects.h b/DesktopEditor/raster/Metafile/Wmf/WmfObjects.h index 3c8c9f681b..8b113dccc0 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfObjects.h +++ b/DesktopEditor/raster/Metafile/Wmf/WmfObjects.h @@ -82,6 +82,8 @@ namespace MetaFile void GetBounds(double& left, double& top, double& width, double& height) const override; void GetCenterPoint(double& dX, double& dY) const override; void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override; + + std::vector> GetGradientColors() const override; public: unsigned short ushBrushStyle; From b76235d4fc41d95b9031cb60b99932ee45dc6523 Mon Sep 17 00:00:00 2001 From: Green Date: Fri, 10 Jan 2025 22:26:55 +0300 Subject: [PATCH 21/51] For bug #72413 --- DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp index aa3a67b8fb..af4dcf1291 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp @@ -442,14 +442,14 @@ namespace SVG if (!Equals(0., dFontHeight) && dFontHeight < MIN_FONT_SIZE) { - dXScale *= MIN_FONT_SIZE / dFontHeight; - dYScale *= MIN_FONT_SIZE / dFontHeight; + dXScale *= dFontHeight / MIN_FONT_SIZE; + dYScale *= dFontHeight / MIN_FONT_SIZE; dFontHeight = MIN_FONT_SIZE; } else if (!Equals(0., dFontHeight) && dFontHeight > MAX_FONT_SIZE) { - dXScale *= dFontHeight / MAX_FONT_SIZE; - dYScale *= dFontHeight / MAX_FONT_SIZE; + dXScale *= MAX_FONT_SIZE / dFontHeight; + dYScale *= MAX_FONT_SIZE / dFontHeight; dFontHeight = MAX_FONT_SIZE; } From cbd7e8ee7bed53baca91374cbb70536df9bd7b52 Mon Sep 17 00:00:00 2001 From: Green Date: Tue, 14 Jan 2025 12:35:26 +0300 Subject: [PATCH 22/51] Refactoring --- .../raster/Metafile/Common/MetaFileObjects.h | 2 +- .../raster/Metafile/Common/MetaFileRenderer.h | 15 ++++----------- .../raster/Metafile/Emf/EmfObjects.cpp | 10 +++------- .../raster/Metafile/Emf/EmfObjects.h | 2 +- .../raster/Metafile/Emf/EmfPlusObjects.cpp | 19 ++++++++----------- .../raster/Metafile/Emf/EmfPlusObjects.h | 2 +- .../raster/Metafile/StarView/SvmObjects.cpp | 10 +++------- .../raster/Metafile/StarView/SvmObjects.h | 2 +- .../CInterpretatorSvgBase.cpp | 10 +++++++--- .../raster/Metafile/Wmf/WmfObjects.cpp | 10 +++------- .../raster/Metafile/Wmf/WmfObjects.h | 2 +- 11 files changed, 33 insertions(+), 51 deletions(-) diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileObjects.h b/DesktopEditor/raster/Metafile/Common/MetaFileObjects.h index 1c96b94266..58b9c94e7a 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileObjects.h +++ b/DesktopEditor/raster/Metafile/Common/MetaFileObjects.h @@ -71,7 +71,7 @@ namespace MetaFile virtual void GetBounds(double& left, double& top, double& width, double& height) const = 0; virtual void GetCenterPoint(double& dX, double& dY) const = 0; - virtual std::vector> GetGradientColors() const = 0; + virtual void GetGradientColors(std::vector& arColors, std::vector& arPositions) const = 0; virtual void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const = 0; }; diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileRenderer.h b/DesktopEditor/raster/Metafile/Common/MetaFileRenderer.h index 20b41a82de..507ee0082f 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileRenderer.h +++ b/DesktopEditor/raster/Metafile/Common/MetaFileRenderer.h @@ -1109,18 +1109,11 @@ namespace MetaFile m_pRenderer->put_BrushLinearAngle(pBrush->GetStyleEx()); - std::vector> arColors{pBrush->GetGradientColors()}; + std::vector arColors; + std::vector arPositions; - std::vector arLColors(arColors.size()); - std::vector arDPositions(arColors.size()); - - for (unsigned int unIndex = 0; unIndex < arColors.size(); ++unIndex) - { - arLColors[unIndex] = arColors[unIndex].first; - arDPositions[unIndex] = arColors[unIndex].second; - } - - m_pRenderer->put_BrushGradientColors(arLColors.data(), arDPositions.data(), arColors.size()); + pBrush->GetGradientColors(arColors, arPositions); + m_pRenderer->put_BrushGradientColors(arColors.data(), arPositions.data(), arColors.size()); } else if ( BS_RADIALGRADIENT == unBrushStyle || diff --git a/DesktopEditor/raster/Metafile/Emf/EmfObjects.cpp b/DesktopEditor/raster/Metafile/Emf/EmfObjects.cpp index 78bcbdb27e..09f8874ced 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfObjects.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfObjects.cpp @@ -155,14 +155,10 @@ namespace MetaFile unHeight = unDibHeigth; } - std::vector > CEmfLogBrushEx::GetGradientColors() const + void CEmfLogBrushEx::GetGradientColors(std::vector& arColors, std::vector& arPositions) const { - std::vector> arColors(2); - - arColors[0] = std::make_pair(GetColor() + (GetAlpha() << 24), 0.); - arColors[1] = std::make_pair(GetColor2() + (GetAlpha2() << 24), 0.); - - return arColors; + arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))}; + arPositions = {0., 1.}; } CEmfLogFont::CEmfLogFont(bool bFixedLength) diff --git a/DesktopEditor/raster/Metafile/Emf/EmfObjects.h b/DesktopEditor/raster/Metafile/Emf/EmfObjects.h index 495e51524d..e077f2c8fe 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfObjects.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfObjects.h @@ -78,7 +78,7 @@ namespace MetaFile void GetCenterPoint(double& dX, double& dY) const override; void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override; - std::vector> GetGradientColors() const override; + void GetGradientColors(std::vector& arColors, std::vector& arPositions) const override; public: unsigned int unBrushStyle; TRGBA oColor; diff --git a/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.cpp b/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.cpp index 35e4baf05b..13b17d54ff 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.cpp @@ -79,27 +79,24 @@ namespace MetaFile height = oRectF.dHeight; } - std::vector > CEmfPlusBrush::GetGradientColors() const + void CEmfPlusBrush::GetGradientColors(std::vector& arColors, std::vector& arPositions) const { if (arGradientColors.empty()) { - std::vector> arColors(2); + arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))}; + arPositions = {0., 1.}; - arColors[0] = std::make_pair(GetColor() + (GetAlpha() << 24), 0.); - arColors[1] = std::make_pair(GetColor2() + (GetAlpha2() << 24), 0.); - - return arColors; + return; } - std::vector> arColors(arGradientColors.size()); + arColors.resize(arGradientColors.size()); + arPositions.resize(arGradientColors.size()); for (unsigned int unIndex = 0; unIndex < arGradientColors.size(); ++unIndex) { - arColors[unIndex].first = METAFILE_RGBA(arGradientColors[unIndex].first.chRed, arGradientColors[unIndex].first.chGreen, arGradientColors[unIndex].first.chBlue, arGradientColors[unIndex].first.chAlpha); - arColors[unIndex].second = arGradientColors[unIndex].second; + arColors[unIndex] = METAFILE_RGBA(arGradientColors[unIndex].first.chRed, arGradientColors[unIndex].first.chGreen, arGradientColors[unIndex].first.chBlue, arGradientColors[unIndex].first.chAlpha); + arPositions[unIndex] = arGradientColors[unIndex].second; } - - return arColors; } CEmfPlusPen::CEmfPlusPen() diff --git a/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.h b/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.h index f473584354..3b61cd0f4b 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.h +++ b/DesktopEditor/raster/Metafile/Emf/EmfPlusObjects.h @@ -189,7 +189,7 @@ namespace MetaFile void GetCenterPoint(double& dX, double& dY) const override; void GetBounds(double& left, double& top, double& width, double& height) const override; - std::vector> GetGradientColors() const override; + void GetGradientColors(std::vector& arColors, std::vector& arPositions) const override; public: TEmfPlusARGB oColor; TEmfPlusARGB oColorBack; diff --git a/DesktopEditor/raster/Metafile/StarView/SvmObjects.cpp b/DesktopEditor/raster/Metafile/StarView/SvmObjects.cpp index 99ecfb38aa..2c774bcbf9 100644 --- a/DesktopEditor/raster/Metafile/StarView/SvmObjects.cpp +++ b/DesktopEditor/raster/Metafile/StarView/SvmObjects.cpp @@ -358,14 +358,10 @@ void CSvmBrush::GetBounds(double& left, double& top, double& width, double& heig void CSvmBrush::GetDibPattern(unsigned char **pBuffer, unsigned int &unWidth, unsigned int &unHeight) const {} -std::vector > CSvmBrush::GetGradientColors() const +void CSvmBrush::GetGradientColors(std::vector& arColors, std::vector& arPositions) const { - std::vector> arColors(2); - - arColors[0] = std::make_pair(GetColor() + (GetAlpha() << 24), 0.); - arColors[1] = std::make_pair(GetColor2() + (GetAlpha2() << 24), 0.); - - return arColors; + arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))}; + arPositions = {0., 1.}; } int CSvmPen::GetColor() const diff --git a/DesktopEditor/raster/Metafile/StarView/SvmObjects.h b/DesktopEditor/raster/Metafile/StarView/SvmObjects.h index 71382438ec..c2aefa243e 100644 --- a/DesktopEditor/raster/Metafile/StarView/SvmObjects.h +++ b/DesktopEditor/raster/Metafile/StarView/SvmObjects.h @@ -300,7 +300,7 @@ public: void GetBounds(double& left, double& top, double& width, double& height) const override; void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override; - std::vector> GetGradientColors() const override; + void GetGradientColors(std::vector& arColors, std::vector& arPositions) const override; public: unsigned short BrushStyleEx; //angle, or .... unsigned short BrushStyle; diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp index 809b254256..8f21404175 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp @@ -1284,9 +1284,13 @@ namespace MetaFile m_wsDefs += L""; - for (const std::pair parColorData : pBrush->GetGradientColors()) - m_wsDefs += L""; + std::vector arColors; + std::vector arPositions; + pBrush->GetGradientColors(arColors, arPositions); + + for (unsigned int unIndex = 0; unIndex < arColors.size(); ++unIndex) + m_wsDefs += L""; m_wsDefs += L""; diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp index 24b65c198f..b697d0843a 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfObjects.cpp @@ -162,14 +162,10 @@ namespace MetaFile unHeight = unDibHeigth; } - std::vector > CWmfBrush::GetGradientColors() const + void CWmfBrush::GetGradientColors(std::vector& arColors, std::vector& arPositions) const { - std::vector> arColors(2); - - arColors[0] = std::make_pair(GetColor() + (GetAlpha() << 24), 0.); - arColors[1] = std::make_pair(GetColor2() + (GetAlpha2() << 24), 0.); - - return arColors; + arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))}; + arPositions = {0., 1.}; } CWmfFont::CWmfFont() diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfObjects.h b/DesktopEditor/raster/Metafile/Wmf/WmfObjects.h index 8b113dccc0..a3a31b3d1a 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfObjects.h +++ b/DesktopEditor/raster/Metafile/Wmf/WmfObjects.h @@ -83,7 +83,7 @@ namespace MetaFile void GetCenterPoint(double& dX, double& dY) const override; void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override; - std::vector> GetGradientColors() const override; + void GetGradientColors(std::vector& arColors, std::vector& arPositions) const override; public: unsigned short ushBrushStyle; From aa90104b18d3694d8c36123722677e48f682f4c4 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 14 Jan 2025 13:03:28 +0300 Subject: [PATCH 23/51] Fix build --- DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp index cf6435762c..e47a686cef 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp @@ -42,6 +42,7 @@ namespace MetaFile virtual void SetImageSize(int nWidth, int nHeight) {} virtual bool LoadFromFile(const wchar_t* wsFilePath) { return false; } virtual bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize) { return false; } + virtual bool LoadFromString(const std::wstring& data) { return false; } virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) { return false; } virtual void Close() {} virtual void GetBounds(double* pdX, double* pdY, double* pdW, double* pdH) {} @@ -50,6 +51,7 @@ namespace MetaFile virtual NSFonts::IFontManager* get_FontManager() { return NULL; } virtual std::wstring ConvertToSvg(unsigned int unWidth = 0, unsigned int unHeight = 0) { return L""; } + virtual void SetTempDirectory(const std::wstring& dir) {} virtual void ConvertToXml(const wchar_t* wsFilePath) {} virtual void ConvertToXmlAndRaster(const wchar_t *wsXmlFilePath, const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight = -1) {} From 7b56d56c0e221420c1c9e4327faf2377dc416486 Mon Sep 17 00:00:00 2001 From: michael-efremov Date: Tue, 14 Jan 2025 15:17:17 +0300 Subject: [PATCH 24/51] [android] Add new formats --- X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp b/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp index dfe40d20b8..1d5d8986df 100644 --- a/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp +++ b/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp @@ -127,6 +127,9 @@ extern "C" { jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION", AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_CANVAS_PDF", AVS_OFFICESTUDIO_FILE_CANVAS_PDF); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF", AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF); + jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES", AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES); + jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_DOCUMENT_HWP", AVS_OFFICESTUDIO_FILE_DOCUMENT_HWP); + jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_DOCUMENT_HWPX", AVS_OFFICESTUDIO_FILE_DOCUMENT_HWPX); jobject res = jjniHashMap.toJniObject(env); jjniHashMap.destroy(env); From 2098c72a351ebe1d274b19447f966b26b1fbcc8d Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 14 Jan 2025 17:11:23 +0300 Subject: [PATCH 25/51] Fix bug 72489 --- PdfFile/PdfWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 7393f75ad2..c09956180c 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -190,7 +190,7 @@ int CPdfWriter::SaveToFile(const std::wstring& wsPath) if (!IsValid()) return 1; - if (!m_pFont && !m_pFont14) + if (!m_pFont && !m_pFont14 && !m_pDocument->IsPDFA()) { m_bNeedUpdateTextFont = false; m_pFont14 = m_pDocument->CreateFont14(L"Helvetica", 0, PdfWriter::EStandard14Fonts::standard14fonts_Helvetica); From ca77113e79e7fe727c15e7420d263cc96ed37c8d Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Tue, 14 Jan 2025 17:21:16 +0300 Subject: [PATCH 26/51] . --- X2tConverter/test/win32Test/X2tTest.cpp | 4 ++++ X2tConverter/test/win32Test/X2tTest.vcxproj | 1 + X2tConverter/test/win32Test/X2tTest.vcxproj.filters | 3 +++ 3 files changed, 8 insertions(+) diff --git a/X2tConverter/test/win32Test/X2tTest.cpp b/X2tConverter/test/win32Test/X2tTest.cpp index e96954d734..81cbfb02f2 100644 --- a/X2tConverter/test/win32Test/X2tTest.cpp +++ b/X2tConverter/test/win32Test/X2tTest.cpp @@ -42,6 +42,7 @@ #pragma comment(lib, "../../../build/lib/win_64/DEBUG/HtmlFile2.lib") #pragma comment(lib, "../../../build/lib/win_64/DEBUG/graphics.lib") #pragma comment(lib, "../../../build/lib/win_64/DEBUG/IWorkFile.lib") + #pragma comment(lib, "../../../build/lib/win_64/DEBUG/HWPFile.lib") #pragma comment(lib, "../../../build/lib/win_64/DEBUG/kernel_network.lib") #pragma comment(lib, "../../../build/lib/win_64/DEBUG/kernel.lib") #pragma comment(lib, "../../../build/lib/win_64/DEBUG/UnicodeConverter.lib") @@ -56,6 +57,7 @@ #pragma comment(lib, "../../../build/lib/win_64/HtmlFile2.lib") #pragma comment(lib, "../../../build/lib/win_64/graphics.lib") #pragma comment(lib, "../../../build/lib/win_64/IWorkFile.lib") + #pragma comment(lib, "../../../build/lib/win_64/HWPFile.lib") #pragma comment(lib, "../../../build/lib/win_64/kernel_network.lib") #pragma comment(lib, "../../../build/lib/win_64/kernel.lib") #pragma comment(lib, "../../../build/lib/win_64/UnicodeConverter.lib") @@ -74,6 +76,7 @@ #pragma comment(lib, "../../../build/lib/win_32/DEBUG/HtmlFile2.lib") #pragma comment(lib, "../../../build/lib/win_32/DEBUG/graphics.lib") #pragma comment(lib, "../../../build/lib/win_32/DEBUG/IWorkFile.lib") + #pragma comment(lib, "../../../build/lib/win_32/DEBUG/HWPFile.lib") #pragma comment(lib, "../../../build/lib/win_32/DEBUG/kernel.lib") #pragma comment(lib, "../../../build/lib/win_32/DEBUG/kernel_network.lib") #pragma comment(lib, "../../../build/lib/win_32/DEBUG/UnicodeConverter.lib") @@ -89,6 +92,7 @@ #pragma comment(lib, "../../../build/lib/win_32/HtmlFile2.lib") #pragma comment(lib, "../../../build/lib/win_32/graphics.lib") #pragma comment(lib, "../../../build/lib/win_32/IWorkFile.lib") + #pragma comment(lib, "../../../build/lib/win_32/HWPFile.lib") #pragma comment(lib, "../../../build/lib/win_32/kernel_network.lib") #pragma comment(lib, "../../../build/lib/win_32/kernel.lib") #pragma comment(lib, "../../../build/lib/win_32/UnicodeConverter.lib") diff --git a/X2tConverter/test/win32Test/X2tTest.vcxproj b/X2tConverter/test/win32Test/X2tTest.vcxproj index 04bd792159..e21180ad19 100644 --- a/X2tConverter/test/win32Test/X2tTest.vcxproj +++ b/X2tConverter/test/win32Test/X2tTest.vcxproj @@ -183,6 +183,7 @@ + diff --git a/X2tConverter/test/win32Test/X2tTest.vcxproj.filters b/X2tConverter/test/win32Test/X2tTest.vcxproj.filters index 67d982e5db..4bf78a3029 100644 --- a/X2tConverter/test/win32Test/X2tTest.vcxproj.filters +++ b/X2tConverter/test/win32Test/X2tTest.vcxproj.filters @@ -58,6 +58,9 @@ libs + + libs + From f51b58c92724db4997e46f382d09caf68cb8aeea Mon Sep 17 00:00:00 2001 From: michael-efremov Date: Wed, 15 Jan 2025 09:36:16 +0300 Subject: [PATCH 27/51] [android] Add HWPFile --- X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt b/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt index 01debe28f3..05c0cb1709 100644 --- a/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt +++ b/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt @@ -70,7 +70,7 @@ set(CORE_DIR ${ARG_PATH_SRC_CORE}) set(X2T_CONVERTER_LIBS ${ARG_PATH_LIB_BUILD_TOOLS}/${ANDROID_ABI}) message(STATUS "Prebuild libraries path: ${X2T_CONVERTER_LIBS}") -SET(new_list libUnicodeConverter.so libkernel.so libkernel_network.so libgraphics.so libPdfFile.so libDjVuFile.so libXpsFile.so libHtmlFile2.so libFb2File.so libEpubFile.so libIWorkFile.so libDocxRenderer.so libdoctrenderer.so libx2t.so) +SET(new_list libUnicodeConverter.so libkernel.so libkernel_network.so libgraphics.so libPdfFile.so libDjVuFile.so libXpsFile.so libHtmlFile2.so libFb2File.so libEpubFile.so libIWorkFile.so libDocxRenderer.so libdoctrenderer.so libx2t.so libHWPFile.so) SET(libs_list "") FOREACH(file_path ${new_list}) From dde69ba65f9de428ddc222fecce95b263a99a917 Mon Sep 17 00:00:00 2001 From: Green Date: Wed, 15 Jan 2025 13:09:45 +0300 Subject: [PATCH 28/51] Fix typo --- HwpFile/HwpDoc/Paragraph/CtrlContainer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HwpFile/HwpDoc/Paragraph/CtrlContainer.cpp b/HwpFile/HwpDoc/Paragraph/CtrlContainer.cpp index 05b5c16f48..51c3180ed6 100644 --- a/HwpFile/HwpDoc/Paragraph/CtrlContainer.cpp +++ b/HwpFile/HwpDoc/Paragraph/CtrlContainer.cpp @@ -122,7 +122,7 @@ int CCtrlContainer::ParseCtrl(CCtrlContainer& oObj, int nSize, CHWPStream& oBuff oBuffer.ReadShort(oObj.m_shNElement); - oObj.m_arCtrlIdList.reserve(oObj.m_shNElement); + oObj.m_arCtrlIdList.resize(oObj.m_shNElement); for (unsigned int unIndex = 0; unIndex < oObj.m_shNElement; ++unIndex) oBuffer.ReadString(oObj.m_arCtrlIdList[unIndex], 4, EStringCharacter::ASCII); From aa2af5d280843afa24eeff9e0d2bd64e13dcdb22 Mon Sep 17 00:00:00 2001 From: michael-efremov Date: Wed, 15 Jan 2025 14:29:38 +0300 Subject: [PATCH 29/51] [android] Add new formats --- X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp b/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp index 1d5d8986df..fa05caa4fc 100644 --- a/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp +++ b/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp @@ -67,6 +67,7 @@ extern "C" { jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM", AVS_OFFICESTUDIO_FILE_PRESENTATION_POTM); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP_FLAT", AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP_FLAT); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP", AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP); + jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY", AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_SPREADSHEET", AVS_OFFICESTUDIO_FILE_SPREADSHEET); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX", AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX); @@ -78,6 +79,7 @@ extern "C" { jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM", AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLTM); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS_FLAT", AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS_FLAT); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_SPREADSHEET_OTS", AVS_OFFICESTUDIO_FILE_SPREADSHEET_OTS); + jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS", AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_CROSSPLATFORM", AVS_OFFICESTUDIO_FILE_CROSSPLATFORM); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF", AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF); From f18b50cd4f8e33bde88063688190f9d921faccd4 Mon Sep 17 00:00:00 2001 From: Green Date: Wed, 15 Jan 2025 14:37:45 +0300 Subject: [PATCH 30/51] Fix typo --- HwpFile/HwpDoc/Paragraph/CtrlColumnDef.cpp | 4 ++-- HwpFile/HwpDoc/Paragraph/CtrlContainer.cpp | 4 ++-- HwpFile/HwpDoc/Paragraph/CtrlShapeCurve.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/HwpFile/HwpDoc/Paragraph/CtrlColumnDef.cpp b/HwpFile/HwpDoc/Paragraph/CtrlColumnDef.cpp index 6862a792fa..9811e4e530 100644 --- a/HwpFile/HwpDoc/Paragraph/CtrlColumnDef.cpp +++ b/HwpFile/HwpDoc/Paragraph/CtrlColumnDef.cpp @@ -18,8 +18,8 @@ CCtrlColumnDef::CCtrlColumnDef(const HWP_STRING& sCtrlID, int nSize, CHWPStream& if (!m_bSameSz) { - m_arColSzWidths.reserve(m_shColCount); - m_arColSzGaps.reserve(m_shColCount - 1); + m_arColSzWidths.resize(m_shColCount); + m_arColSzGaps.resize(m_shColCount - 1); for (int nIndex = 0; nIndex < m_shColCount; ++nIndex) { diff --git a/HwpFile/HwpDoc/Paragraph/CtrlContainer.cpp b/HwpFile/HwpDoc/Paragraph/CtrlContainer.cpp index 51c3180ed6..ceb15f514e 100644 --- a/HwpFile/HwpDoc/Paragraph/CtrlContainer.cpp +++ b/HwpFile/HwpDoc/Paragraph/CtrlContainer.cpp @@ -67,12 +67,12 @@ int CCtrlContainer::ParseElement(CCtrlContainer& oObj, int nSize, CHWPStream& oB if (oObj.m_shNElement <= 0) return oBuffer.GetDistanceToLastPos(true); - oObj.m_arCtrlIdList.reserve(oObj.m_shNElement); + oObj.m_arCtrlIdList.resize(oObj.m_shNElement); for (unsigned int unIndex = 0; unIndex < oObj.m_shNElement; ++unIndex) oBuffer.ReadString(oObj.m_arCtrlIdList[unIndex], 4, EStringCharacter::ASCII); - oObj.m_arShapes.reserve(oObj.m_shNElement); + oObj.m_arShapes.resize(oObj.m_shNElement); HWP_STRING sCtrlId; diff --git a/HwpFile/HwpDoc/Paragraph/CtrlShapeCurve.cpp b/HwpFile/HwpDoc/Paragraph/CtrlShapeCurve.cpp index 36c88738f3..10509ae11e 100644 --- a/HwpFile/HwpDoc/Paragraph/CtrlShapeCurve.cpp +++ b/HwpFile/HwpDoc/Paragraph/CtrlShapeCurve.cpp @@ -30,7 +30,7 @@ int CCtrlShapeCurve::ParseElement(CCtrlShapeCurve& oObj, int nSize, CHWPStream& if (0 < oObj.m_nPoints) { - oObj.m_arPoints.reserve(oObj.m_nPoints); + oObj.m_arPoints.resize(oObj.m_nPoints); for (unsigned int unIndex = 0; unIndex < oObj.m_nPoints; ++unIndex) { oBuffer.ReadInt(oObj.m_arPoints[unIndex].m_nX); @@ -40,7 +40,7 @@ int CCtrlShapeCurve::ParseElement(CCtrlShapeCurve& oObj, int nSize, CHWPStream& if (1 < oObj.m_nPoints) { - oObj.m_arSegmentType.reserve(oObj.m_nPoints - 1); + oObj.m_arSegmentType.resize(oObj.m_nPoints - 1); for (unsigned int unIndex = 0; unIndex < oObj.m_nPoints - 1; ++unIndex) oBuffer.ReadByte(oObj.m_arSegmentType[unIndex]); } From 2c9e58280bcfb25b5634b3e06dee8ba6aafd7216 Mon Sep 17 00:00:00 2001 From: Green Date: Wed, 15 Jan 2025 15:09:24 +0300 Subject: [PATCH 31/51] Fixed the bug of missing bmp images in hwp format --- HwpFile/HwpDoc/Conversion/Converter2OOXML.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/HwpFile/HwpDoc/Conversion/Converter2OOXML.cpp b/HwpFile/HwpDoc/Conversion/Converter2OOXML.cpp index 4b703afc6e..58047b2b2a 100644 --- a/HwpFile/HwpDoc/Conversion/Converter2OOXML.cpp +++ b/HwpFile/HwpDoc/Conversion/Converter2OOXML.cpp @@ -296,7 +296,7 @@ void CConverter2OOXML::Convert() bool CConverter2OOXML::IsRasterFormat(const HWP_STRING& sFormat) { - return L"png" == sFormat || L"jpg" == sFormat || L"jpeg" == sFormat; + return L"png" == sFormat || L"jpg" == sFormat || L"jpeg" == sFormat || L"bmp" == sFormat; } void CConverter2OOXML::WriteCharacter(const CCtrlCharacter* pCharacter, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState) @@ -364,6 +364,7 @@ void CConverter2OOXML::WriteShape(const CCtrlGeneralShape* pShape, NSStringUtils } case EShapeType::GeneralShape: case EShapeType::ConnectLine: + case EShapeType::Container: case EShapeType::Polygon: case EShapeType::TextArt: case EShapeType::Curve: From a6940c42acf5bb3c68b6834686e3d190f575fa5a Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Wed, 15 Jan 2025 17:02:31 +0400 Subject: [PATCH 32/51] Obtain builder's version from INTVER --- DesktopEditor/doctrenderer/config.h | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/DesktopEditor/doctrenderer/config.h b/DesktopEditor/doctrenderer/config.h index 0ffe06655a..1f04514b3c 100644 --- a/DesktopEditor/doctrenderer/config.h +++ b/DesktopEditor/doctrenderer/config.h @@ -38,6 +38,9 @@ #include "../xml/include/xmlutils.h" #include "../fontengine/TextHyphen.h" +#define VALUE_TO_STRING(x) #x +#define VALUE(x) VALUE_TO_STRING(x) + namespace NSDoctRenderer { class CAdditionalData @@ -203,28 +206,14 @@ namespace NSDoctRenderer char* GetVersion() { - std::wstring sFile = m_strSdkPath + L"/word/sdk-all-min.js"; + std::string sVersion = VALUE(INTVER); - std::string sData; - if (!NSFile::CFileBinary::ReadAllTextUtf8A(sFile, sData)) - return NULL; - - std::string::size_type startPos = sData.find("Version:"); - if (std::string::npos == startPos) - return NULL; - - startPos += 8; - - std::string::size_type endPos = sData.find(')', startPos); - if (std::string::npos == endPos) - return NULL; - - size_t sSrcLen = endPos - startPos + 1; + size_t sSrcLen = sVersion.size(); if (sSrcLen == 0) return NULL; char* sRet = new char[sSrcLen + 1]; - memcpy(sRet, sData.c_str() + startPos, sSrcLen); + memcpy(sRet, sVersion.c_str(), sSrcLen); sRet[sSrcLen] = '\0'; return sRet; } From 2ea586ec6f2679c6800f9cb8fe827f96dbd88f7d Mon Sep 17 00:00:00 2001 From: Kamil Kerimov Date: Wed, 15 Jan 2025 20:13:21 +0500 Subject: [PATCH 33/51] Fix bug #72414 --- .../style_paragraph_properties_docx.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/OdfFile/Reader/Format/style_paragraph_properties_docx.cpp b/OdfFile/Reader/Format/style_paragraph_properties_docx.cpp index c3696f7f63..0e6166a87c 100644 --- a/OdfFile/Reader/Format/style_paragraph_properties_docx.cpp +++ b/OdfFile/Reader/Format/style_paragraph_properties_docx.cpp @@ -405,6 +405,7 @@ void paragraph_format_properties::docx_convert(oox::docx_conversion_context & Co { // TODO auto indent +#if 0 if (Context.get_list_style_level() > 0) { int lvl = Context.get_list_style_stack().size() - 1; @@ -421,26 +422,24 @@ void paragraph_format_properties::docx_convert(oox::docx_conversion_context & Co } } } - std::wstring w_left, w_right, w_hanging, w_firstLine; +#endif + std::wstring w_left, w_right, w_hanging; - w_left = docx_process_margin(curr_margin_left_, 20.0); + w_left = docx_process_margin(fo_margin_left_, 20.0); w_right = docx_process_margin(fo_margin_right_, 20.0); - w_firstLine = docx_process_margin(fo_text_indent_, 20.0); + w_hanging = docx_process_margin(fo_text_indent_, -20.0); if (w_left.empty()) w_left = L"0"; if (w_right.empty()) w_right = L"0"; - if (w_firstLine.empty()) w_hanging = L"0"; + if (w_hanging.empty()) w_hanging = L"0"; CP_XML_NODE(L"w:ind") { - CP_XML_ATTR(L"w:left", w_left); - CP_XML_ATTR(L"w:right", w_right); + CP_XML_ATTR(L"w:start", w_left); + CP_XML_ATTR(L"w:end", w_right); if (Context.get_drop_cap_context().state() != 1 )//состояние сразу после добавления буквицы - не нужны ни отступы, ни висячие { - if (!w_firstLine.empty()) - CP_XML_ATTR(L"w:firstLine", w_firstLine); - if (!w_hanging.empty()) CP_XML_ATTR(L"w:hanging", w_hanging); } @@ -518,7 +517,7 @@ void style_tab_stop::docx_convert(oox::docx_conversion_context & Context, bool c length def_tab = length(1.0, length::cm);// в ms значение 0.8 не корректно оО - double tab_pos = 20.0 * style_position_.get_value_unit(length::pt) + margin_left ; + double tab_pos = 20.0 * style_position_.get_value_unit(length::pt); double min_tab_pos = 20.0 * def_tab.get_value_unit(length::pt) ; if (tab_pos < min_tab_pos) From 8e1810697f360167bc842903c1cde86d09c7d7b7 Mon Sep 17 00:00:00 2001 From: Green Date: Wed, 15 Jan 2025 20:34:02 +0300 Subject: [PATCH 34/51] Fix bug #72519 --- DesktopEditor/raster/Metafile/svg/SvgObjects/CUse.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CUse.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CUse.cpp index a2ae8aa6aa..73f33188a8 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CUse.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CUse.cpp @@ -45,21 +45,23 @@ namespace SVG const CRenderedObject *pFoundObj = dynamic_cast(pFile->GetMarkedObject(m_wsHref)); - if (NULL != pFoundObj) + bool bResult = false; + + if (NULL != pFoundObj && this != pFoundObj) { if (NULL != pOtherStyles) { TSvgStyles oNewStyles(m_oStyles); oNewStyles += *pOtherStyles; - pFoundObj->Draw(pRenderer, pFile, oMode, &oNewStyles, this); + bResult = pFoundObj->Draw(pRenderer, pFile, oMode, &oNewStyles, this); } else - pFoundObj->Draw(pRenderer, pFile, oMode, &m_oStyles, this); + bResult = pFoundObj->Draw(pRenderer, pFile, oMode, &m_oStyles, this); } EndPath(pRenderer, pFile, oOldTransform); - return true; + return bResult; } TBounds CUse::GetBounds() const From 3adf33638493815806892b99990c54eb63b7a332 Mon Sep 17 00:00:00 2001 From: Green Date: Wed, 15 Jan 2025 22:42:28 +0300 Subject: [PATCH 35/51] For bug #72519 --- .../3dParty/html/css/src/StyleProperties.cpp | 19 ++++++++ Common/3dParty/html/css/src/StyleProperties.h | 1 + HtmlFile2/htmlfile2.cpp | 44 +++++++++++++++---- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index 69481e53de..69426ca486 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -917,6 +917,25 @@ namespace NSCSS } } + std::wstring CColor::ToHEX() const + { + switch(m_enType) + { + case ColorRGB: + { + TRGB* pRGB = static_cast(m_oValue); + return ConvertRGBtoHEX(*pRGB); + } + case ColorHEX: + { + std::wstring *pValue = static_cast(m_oValue); + return *pValue; + } + default: + return std::wstring(); + } + } + std::wstring CColor::EquateToColor(const std::vector> &arColors) const { if (arColors.empty()) diff --git a/Common/3dParty/html/css/src/StyleProperties.h b/Common/3dParty/html/css/src/StyleProperties.h index 7a0be6b03b..2fa1ce1935 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -242,6 +242,7 @@ namespace NSCSS int ToInt() const override; double ToDouble() const override; std::wstring ToWString() const override; + std::wstring ToHEX() const; std::wstring EquateToColor(const std::vector>& arColors) const; TRGB ToRGB() const; diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 1fd8b087a1..3a0b628788 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -1561,7 +1561,7 @@ public: } // settings.xml - std::wstring sSettings = L""; + std::wstring sSettings = L""; NSFile::CFileBinary oSettingsWriter; if (oSettingsWriter.CreateFileW(m_sDst + L"/word/settings.xml")) { @@ -2178,10 +2178,12 @@ private: NSCSS::CCompiledStyle oStyle; m_oStylesCalculator.GetCompiledStyle(oStyle, sSelectors); - INT nMarLeft = 720; - INT nMarRight = 720; - INT nMarTop = 100; - INT nMarBottom = 100; + const bool bInTable = ElementInTable(sSelectors); + + INT nMarLeft = (!bInTable) ? 720 : 0; + INT nMarRight = (!bInTable) ? 720 : 0; + INT nMarTop = (!bInTable) ? 100 : 0; + INT nMarBottom = (!bInTable) ? 100 : 0; if (!oStyle.m_oMargin.GetLeft().Empty() && !oStyle.m_oMargin.GetLeft().Zero()) nMarLeft = oStyle.m_oMargin.GetLeft().ToInt(NSCSS::Twips, m_oPageData.GetWidth().ToInt(NSCSS::Twips)); @@ -2294,6 +2296,28 @@ private: m_oDocXml.WriteString(L"\"/>"); */ + if (!sSelectors.back().m_mAttributes.empty()) + { + std::map::iterator itFound = sSelectors.back().m_mAttributes.find(L"bgcolor"); + + if (sSelectors.back().m_mAttributes.end() != itFound) + { + NSCSS::NSProperties::CColor oColor; + oColor.SetValue(itFound->second); + + if (!oColor.Empty() && !oColor.None()) + { + const std::wstring wsHEXColor{oColor.ToHEX()}; + + if (!wsHEXColor.empty()) + m_oDocXml.WriteString(L""); + + sSelectors.back().m_mAttributes.erase(itFound); + } + } + } + m_oLightReader.MoveToElement(); + CTextSettings oTS; readStream(&m_oDocXml, sSelectors, oTS); } @@ -3627,12 +3651,14 @@ private: return true; } - bool ParseTable(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, CTextSettings& oTS) + bool ParseTable(NSStringUtils::CStringBuilder* oXml, std::vector& sSelectors, const CTextSettings& oTS) { if(m_oLightReader.IsEmptyNode()) return false; CTable oTable; + CTextSettings oTextSettings{oTS}; + oTextSettings.sPStyle.clear(); NSCSS::CCompiledStyle oStyle; m_oStylesCalculator.GetCompiledStyle(oStyle, sSelectors); @@ -3729,11 +3755,11 @@ private: if(sName == L"caption") ParseTableCaption(oTable, sSelectors, oTS); if(sName == L"thead") - ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeHeader); + ParseTableRows(oTable, sSelectors, oTextSettings, ERowParseMode::ParseModeHeader); if(sName == L"tbody") - ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeBody); + ParseTableRows(oTable, sSelectors, oTextSettings, ERowParseMode::ParseModeBody); else if(sName == L"tfoot") - ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeFoother); + ParseTableRows(oTable, sSelectors, oTextSettings, ERowParseMode::ParseModeFoother); else if (sName == L"colgroup") ParseTableColspan(oTable); From 8239d6f51dae8acb083b6918bdc7f3447d2a719e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 16 Jan 2025 10:42:07 +0300 Subject: [PATCH 36/51] Fix bug 72529 --- PdfFile/PdfWriter.cpp | 8 ++++---- PdfFile/SrcWriter/Annotation.cpp | 31 ++++++++++++------------------- PdfFile/SrcWriter/Annotation.h | 2 +- 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index c09956180c..bebc960063 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -1985,13 +1985,13 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF { pMarkupAnnot->RemoveAP(); - CAnnotFieldInfo::CTextMarkupAnnotPr* pPr = oInfo.GetTextMarkupAnnotPr(); + CAnnotFieldInfo::CTextMarkupAnnotPr* pTMPr = oInfo.GetTextMarkupAnnotPr(); PdfWriter::CTextMarkupAnnotation* pTextMarkupAnnot = (PdfWriter::CTextMarkupAnnotation*)pAnnot; - pTextMarkupAnnot->SetSubtype(pPr->GetSubtype()); - pTextMarkupAnnot->SetQuadPoints(pPr->GetQuadPoints()); + pTextMarkupAnnot->SetSubtype(pTMPr->GetSubtype()); + pTextMarkupAnnot->SetQuadPoints(pTMPr->GetQuadPoints()); - pTextMarkupAnnot->SetAP(pPr->GetQuadPoints()); + pTextMarkupAnnot->SetAP(pTMPr->GetQuadPoints(), pPr->GetCA()); } else if (oInfo.IsSquareCircle()) { diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index fd7fc00ce6..2cf08c0312 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1188,7 +1188,7 @@ namespace PdfWriter for (int i = 0; i < arrQuadPoints.size(); ++i) pArray->Add(i % 2 == 0 ? (arrQuadPoints[i] + m_dPageX) : (m_dPageH - arrQuadPoints[i])); } - void CTextMarkupAnnotation::SetAP(const std::vector& arrQuadPoints) + void CTextMarkupAnnotation::SetAP(const std::vector& arrQuadPoints, const double& dCA) { CAnnotAppearance* pAP = new CAnnotAppearance(m_pXref, this); Add("AP", pAP); @@ -1198,20 +1198,21 @@ namespace PdfWriter pN->AddBBox(GetRect().fLeft, GetRect().fBottom, GetRect().fRight, GetRect().fTop); pN->AddMatrix(1, 0, 0, 1, -GetRect().fLeft, -GetRect().fBottom); + CExtGrState* pExtGrState = m_pDocument->GetExtGState(dCA, dCA, m_nSubtype == AnnotHighLight ? blendmode_Multiply : blendmode_Unknown); + const char* sExtGrStateName = m_pDocument->GetFieldsResources()->GetExtGrStateName(pExtGrState); + if (sExtGrStateName) + { + pStream->WriteEscapeName(sExtGrStateName); + pStream->WriteStr(" gs\012"); + } + std::string sColor = GetColor(dynamic_cast(Get("C")), m_nSubtype != AnnotHighLight); + pStream->WriteStr(sColor.c_str()); + pStream->WriteChar('\012'); + switch (m_nSubtype) { case AnnotHighLight: { - CExtGrState* pExtGrState = m_pDocument->GetExtGState(-1, -1, blendmode_Multiply); - const char* sExtGrStateName = m_pDocument->GetFieldsResources()->GetExtGrStateName(pExtGrState); - if (sExtGrStateName) - { - pStream->WriteEscapeName(sExtGrStateName); - pStream->WriteStr(" gs\012"); - } - std::string sColor = GetColor(dynamic_cast(Get("C")), false); - pStream->WriteStr(sColor.c_str()); - pStream->WriteChar('\012'); pStream->WriteStr("1 w\012"); for (int i = 0; i < arrQuadPoints.size(); i += 8) @@ -1241,10 +1242,6 @@ namespace PdfWriter case AnnotSquiggly: case AnnotUnderline: { - std::string sColor = GetColor(dynamic_cast(Get("C")), true); - pStream->WriteStr(sColor.c_str()); - pStream->WriteChar('\012'); - for (int i = 0; i < arrQuadPoints.size(); i += 8) { double dX = arrQuadPoints[i + 2] - arrQuadPoints[i]; @@ -1273,10 +1270,6 @@ namespace PdfWriter case AnnotStrikeOut: default: { - std::string sColor = GetColor(dynamic_cast(Get("C")), true); - pStream->WriteStr(sColor.c_str()); - pStream->WriteChar('\012'); - for (int i = 0; i < arrQuadPoints.size(); i += 8) { double dX1 = arrQuadPoints[i] + (arrQuadPoints[i + 4] - arrQuadPoints[i]) / 2.0; diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index 070faffaea..890249a9de 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -321,7 +321,7 @@ namespace PdfWriter void SetSubtype(BYTE nSubtype); void SetQuadPoints(const std::vector& arrQuadPoints); - void SetAP(const std::vector& arrQuadPoints); + void SetAP(const std::vector& arrQuadPoints, const double& dCA); }; class CSquareCircleAnnotation : public CMarkupAnnotation { From 23ac269339e9cb1ef3206e2ce974b943f46b054b Mon Sep 17 00:00:00 2001 From: Green Date: Thu, 16 Jan 2025 15:02:32 +0300 Subject: [PATCH 37/51] Fix bug #72533 --- HtmlFile2/htmlfile2.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 3a0b628788..38d09bd156 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -599,6 +599,11 @@ public: return m_bIsEmpty; } + bool Merged() + { + return m_bIsMerged; + } + CTableCell* Copy() { return new CTableCell(*this); @@ -756,7 +761,7 @@ public: if (nPosition < 0) { - std::vector::iterator itFoundEmpty = std::find_if(m_arCells.begin(), m_arCells.end(), [](CTableCell* pCell) { return pCell->Empty(); }); + std::vector::iterator itFoundEmpty = std::find_if(m_arCells.begin(), m_arCells.end(), [](CTableCell* pCell) { return pCell->Empty() && !pCell->Merged(); }); if (m_arCells.end() != itFoundEmpty) { @@ -3666,9 +3671,9 @@ private: //Table styles std::wstring wsFrame; - for (const std::pair oArgument : sSelectors.back().m_mAttributes) + for (const std::pair& oArgument : sSelectors.back().m_mAttributes) { - if (L"border" == oArgument.first) + if (oStyle.m_oBorder.Empty() && L"border" == oArgument.first) { const int nWidth = NSStringFinder::ToInt(oArgument.second); @@ -3676,7 +3681,7 @@ private: { oStyle.m_oBorder.SetStyle(L"outset", 0, true); oStyle.m_oBorder.SetWidth(nWidth, 0, true); - oStyle.m_oBorder.SetColor(L"auto", 0, true); + oStyle.m_oBorder.SetColor(L"auto", 0, true); oTable.SetRules(L"all"); } else From ecd80408e28ffc3ce726454f5ac30306a03f32af Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 17 Jan 2025 15:23:28 +0600 Subject: [PATCH 38/51] for bug #72486 --- OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp index 224e4ef2e4..26b91ddbf5 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp @@ -208,7 +208,7 @@ bool DateReader::parseLocalDate(const std::wstring &date, tm &result, bool &Hasd { auto charElement = cutteddateStr.at(i); DateElemTypes elementType; - if(charElement == L' ') + if(charElement == L' ' || charElement == L' ') elementType = DateElemTypes::space; else if(charElement >= L'0' && charElement<= L'9') elementType = DateElemTypes::digit; From fb934ef527148907bc68d619ebb249086d9d3bb5 Mon Sep 17 00:00:00 2001 From: Green Date: Fri, 17 Jan 2025 15:18:52 +0300 Subject: [PATCH 39/51] Fix bug #72558 --- Common/3dParty/html/css/src/CCompiledStyle.cpp | 14 ++++++++++++-- Common/3dParty/html/css/src/CCompiledStyle.h | 3 ++- .../3dParty/html/css/src/xhtml/CDocumentStyle.cpp | 2 +- HtmlFile2/htmlfile2.cpp | 3 ++- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Common/3dParty/html/css/src/CCompiledStyle.cpp b/Common/3dParty/html/css/src/CCompiledStyle.cpp index 059140bc77..1d5d8d355e 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.cpp +++ b/Common/3dParty/html/css/src/CCompiledStyle.cpp @@ -25,7 +25,7 @@ namespace NSCSS m_arParentsStyles(oStyle.m_arParentsStyles), m_sId(oStyle.m_sId), m_nDpi(oStyle.m_nDpi), m_UnitMeasure(oStyle.m_UnitMeasure), m_dCoreFontSize(oStyle.m_dCoreFontSize), m_oFont(oStyle.m_oFont), m_oMargin(oStyle.m_oMargin), m_oPadding(oStyle.m_oPadding), m_oBackground(oStyle.m_oBackground), - m_oText(oStyle.m_oText), m_oBorder(oStyle.m_oBorder), m_oDisplay(oStyle.m_oDisplay){} + m_oText(oStyle.m_oText), m_oBorder(oStyle.m_oBorder), m_oDisplay(oStyle.m_oDisplay), m_oTransform(oStyle.m_oTransform){} CCompiledStyle::~CCompiledStyle() { @@ -44,6 +44,7 @@ namespace NSCSS m_oPadding += oElement.m_oPadding; m_oText += oElement.m_oText; m_oDisplay += oElement.m_oDisplay; + m_oTransform += oElement.m_oTransform; if (!oElement.m_sId.empty()) m_sId += L'+' + oElement.m_sId; @@ -66,6 +67,7 @@ namespace NSCSS m_oPadding = oElement.m_oPadding; m_oText = oElement.m_oText; m_oDisplay = oElement.m_oDisplay; + m_oTransform = oElement.m_oTransform; return *this; } @@ -78,7 +80,8 @@ namespace NSCSS m_oMargin == oStyle.m_oMargin && m_oPadding == oStyle.m_oPadding && m_oText == oStyle.m_oText && - m_oDisplay == oStyle.m_oDisplay; + m_oDisplay == oStyle.m_oDisplay && + m_oTransform == oStyle.m_oTransform; } void CCompiledStyle::StyleEquation(CCompiledStyle &oFirstStyle, CCompiledStyle &oSecondStyle) @@ -90,6 +93,7 @@ namespace NSCSS NSProperties::CText ::Equation(oFirstStyle.m_oText, oSecondStyle.m_oText); NSProperties::CBorder ::Equation(oFirstStyle.m_oBorder, oSecondStyle.m_oBorder); NSProperties::CDisplay ::Equation(oFirstStyle.m_oDisplay, oSecondStyle.m_oDisplay); + NSProperties::CTransform ::Equation(oFirstStyle.m_oTransform, oSecondStyle.m_oTransform); } void CCompiledStyle::SetDpi(const unsigned short &uiDpi) @@ -431,6 +435,12 @@ namespace NSCSS m_oDisplay.SetVAlign(pPropertie.second, unLevel, bHardMode); break; } + //TRANSFORM + CASE(L"transform"): + { + m_oTransform.SetMatrix(pPropertie.second, unLevel, bHardMode); + break; + } default: AddOtherStyle(pPropertie, unLevel, bHardMode); } } diff --git a/Common/3dParty/html/css/src/CCompiledStyle.h b/Common/3dParty/html/css/src/CCompiledStyle.h index 530e41b4a3..2a597c58c9 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.h +++ b/Common/3dParty/html/css/src/CCompiledStyle.h @@ -31,11 +31,12 @@ namespace NSCSS NSProperties::CText m_oText; NSProperties::CBorder m_oBorder; NSProperties::CDisplay m_oDisplay; + NSProperties::CTransform m_oTransform; CCompiledStyle(); CCompiledStyle(const CCompiledStyle& oStyle); - ~CCompiledStyle(); + virtual ~CCompiledStyle(); void SetDpi(const unsigned short& uiDpi); void SetUnitMeasure(const UnitMeasure& enUnitMeasure); diff --git a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp index c69d7ffa9c..37c3e91f09 100644 --- a/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp +++ b/Common/3dParty/html/css/src/xhtml/CDocumentStyle.cpp @@ -485,7 +485,7 @@ namespace NSCSS return; if (!oStyle.m_oFont.GetSize().Empty()) - oXmlElement.AddPropertiesInR(RProperties::R_Sz, std::to_wstring(static_cast(oStyle.m_oFont.GetSize().ToDouble(NSCSS::Point) * 2. + 0.5))); // Значения шрифта увеличивает на 2 + oXmlElement.AddPropertiesInR(RProperties::R_Sz, std::to_wstring(static_cast(oStyle.m_oFont.GetSize().ToDouble(NSCSS::Point) * 2. * oStyle.m_oTransform.GetMatrix().GetFinalValue().sy() + 0.5))); // Значения шрифта увеличивает на 2 if (oStyle.m_oText.GetDecoration().m_oLine.Underline()) oXmlElement.AddPropertiesInR(RProperties::R_U, (!oStyle.m_oText.GetDecoration().m_oStyle.Empty()) ? oStyle.m_oText.GetDecoration().m_oStyle.ToWString() : L"single"); diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index 38d09bd156..b52356b2c9 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -4766,7 +4766,8 @@ HRESULT CHtmlFile2::OpenBatchHtml(const std::vector& sSrc, const s m_internal->m_oLightReader.Clear(); m_internal->m_sBase.clear(); } - m_internal->m_oStylesCalculator.Clear(); + //Если очищать, то каждый раз при использовании внешнего css файла он заново парсится + // m_internal->m_oStylesCalculator.Clear(); } m_internal->write(); From aa0ba83d327e5572b275e3ef2848e84e6b03b81c Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 17 Jan 2025 18:44:27 +0300 Subject: [PATCH 40/51] Fix bug#72189 --- .../Converter/StarMath2OOXML/cstarmathpars.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp index 19dc6b0f0e..9873eec91e 100644 --- a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -1251,7 +1251,10 @@ namespace StarMath { pReader->ReadingTheNextToken(); enOpen = GetBracketOpen(pReader->GetLowerCaseString()); - enClose = GetBracketClose(pReader->GetLowerCaseString()); + if(pReader->GetLowerCaseString() == L"none") + enOpen = TypeElement::none; + else + enClose = GetBracketClose(pReader->GetLowerCaseString()); if(enOpen != TypeElement::undefine) { m_enLeftBracket = enOpen; @@ -3410,7 +3413,13 @@ namespace StarMath if(CElementBracket::GetBracketOpen(m_wsLowerCaseToken) != TypeElement::undefine) { if(CElementBracket::GetBracketOpen(m_wsLowerCaseToken) == TypeElement::left) - continue; + { + if(GetToken() && (m_wsLowerCaseToken == L"none" || (m_wsLowerCaseToken != L"left" && CElementBracket::GetBracketOpen(m_wsLowerCaseToken) != TypeElement::undefine))) + { + inBracketInside += 1; + continue; + } + } else inBracketInside +=1; } @@ -3421,7 +3430,6 @@ namespace StarMath m_stBracket.push(m_itEnd); m_stCloseBracket.push(m_itStart); m_itEnd = itStartBracketClose; -// m_itEnd = m_itStart; break; } else if(CElementBracket::GetBracketClose(m_wsLowerCaseToken) != TypeElement::undefine && inBracketInside != 0) From 172bb09305768185bcf67a156ae956e8b577790f Mon Sep 17 00:00:00 2001 From: Alexey Nagaev Date: Fri, 17 Jan 2025 20:07:45 +0300 Subject: [PATCH 41/51] Fix bug 72484 --- Test/Applications/x2tTester/x2tTester.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Test/Applications/x2tTester/x2tTester.cpp b/Test/Applications/x2tTester/x2tTester.cpp index 0233b5cb15..6e5b613386 100644 --- a/Test/Applications/x2tTester/x2tTester.cpp +++ b/Test/Applications/x2tTester/x2tTester.cpp @@ -5,6 +5,14 @@ class CFormatsList; class Cx2tTester; class CConverter; +std::wstring GetFileExtLower(const std::wstring& file) +{ + std::wstring input_ext = NSFile::GetFileExtention(file); + for (auto& c : input_ext) + c = std::tolower(c); + return input_ext; +} + CFormatsList::CFormatsList() { } @@ -522,7 +530,7 @@ void Cx2tTester::Start() { std::wstring& input_file = files[i]; std::wstring input_filename = NSFile::GetFileName(input_file); - std::wstring input_ext = NSFile::GetFileExtention(input_file); + std::wstring input_ext = GetFileExtLower(input_file); // if no format in input formats - skip if(std::find(m_inputExts.begin(), m_inputExts.end(), input_ext) == m_inputExts.end() @@ -619,7 +627,7 @@ void Cx2tTester::Convert(const std::vector& files, bool bNoDirecto { const std::wstring& input_file = files[i]; std::wstring input_filename = NSFile::GetFileName(input_file); - std::wstring input_ext = NSFile::GetFileExtention(input_file); + std::wstring input_ext = GetFileExtLower(input_file); std::wstring input_file_directory = NSFile::GetDirectoryName(input_file); // takes full directory after input folder @@ -865,6 +873,8 @@ std::vector Cx2tTester::ParseExtensionsString(std::wstring extensi while ((pos = extensions.find(' ')) != std::wstring::npos) { std::wstring ext = extensions.substr(0, pos); + for (auto& c : ext) + c = std::tolower(c); if(ext == L"documents") exts = fl.GetDocuments(); @@ -1145,7 +1155,7 @@ DWORD CConverter::ThreadProc() Cx2tTester::Report report; report.inputFile = input_filename; report.outputFile = output_filename; - report.direction = input_ext.substr(1, input_ext.size() - 1) + L"-" + output_ext.substr(1, output_ext.size() - 1); + report.direction = m_inputExt + L"-" + output_ext.substr(1, output_ext.size() - 1); report.time = NSTimers::GetTickCount() - time_file_start; report.inputSize = input_size; report.outputSize = output_size; From df76ff3778145a41c68cb9bb64e2f6cf5648e77c Mon Sep 17 00:00:00 2001 From: Alexey Nagaev Date: Fri, 17 Jan 2025 20:11:47 +0300 Subject: [PATCH 42/51] Fix bug 72537 --- Test/Applications/x2tTester/x2tTester.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Test/Applications/x2tTester/x2tTester.cpp b/Test/Applications/x2tTester/x2tTester.cpp index 6e5b613386..fb2f38c161 100644 --- a/Test/Applications/x2tTester/x2tTester.cpp +++ b/Test/Applications/x2tTester/x2tTester.cpp @@ -183,6 +183,10 @@ CFormatsList CFormatsList::GetDefaultExts() list.m_documents.push_back(L"fodt"); list.m_documents.push_back(L"htm"); list.m_documents.push_back(L"html"); + + list.m_documents.push_back(L"hwp"); + list.m_documents.push_back(L"hwpx"); + list.m_documents.push_back(L"mht"); list.m_documents.push_back(L"odt"); list.m_documents.push_back(L"ott"); From 0c2b49af11e04c37ab5579e5763594e66e47bfff Mon Sep 17 00:00:00 2001 From: Alexey Nagaev Date: Mon, 20 Jan 2025 10:53:51 +0300 Subject: [PATCH 43/51] Fix build for win XP --- Test/Applications/x2tTester/x2tTester.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Test/Applications/x2tTester/x2tTester.cpp b/Test/Applications/x2tTester/x2tTester.cpp index fb2f38c161..50fd098819 100644 --- a/Test/Applications/x2tTester/x2tTester.cpp +++ b/Test/Applications/x2tTester/x2tTester.cpp @@ -1,4 +1,7 @@ #include "x2tTester.h" + +#include + #include "../../../X2tConverter/src/run.h" class CFormatsList; From 34627ff1c56d056a4fd95c27abdf50e5bf76c79c Mon Sep 17 00:00:00 2001 From: Green Date: Sun, 19 Jan 2025 00:23:39 +0300 Subject: [PATCH 44/51] Fix bug #72519 --- HtmlFile2/htmlfile2.cpp | 127 ++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 51 deletions(-) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index b52356b2c9..a24e75048d 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -63,6 +63,8 @@ const static double HTML_FONTS[7] = {7.5, 10, 12, 13.5, 18, 24, 36}; #define HtmlTag GumboTag +#define MAX_STRING_BLOCK_SIZE (size_t)10485760 + const std::map m_HTML_TAGS { ADD_TAG(L"a", A), @@ -217,6 +219,27 @@ static inline HtmlTag GetHtmlTag(const std::wstring& wsStrTag) return oFound->second; } +static inline void WriteToStringBuilder(NSStringUtils::CStringBuilder& oSrcStringBuilder, NSStringUtils::CStringBuilder& oDstStringBuilder) +{ + if (oSrcStringBuilder.GetCurSize() < MAX_STRING_BLOCK_SIZE) + { + oDstStringBuilder.Write(oSrcStringBuilder); + return; + } + + size_t ulSize = oSrcStringBuilder.GetCurSize(); + size_t ulCurrentBlockSize = 0, ulPosition = 0; + + while (ulSize > 0) + { + ulCurrentBlockSize = std::min(ulSize, MAX_STRING_BLOCK_SIZE); + oDstStringBuilder.WriteString(oSrcStringBuilder.GetSubData(ulPosition, ulCurrentBlockSize)); + + ulSize -= ulCurrentBlockSize; + ulPosition += ulCurrentBlockSize; + } +} + // Ячейка таблицы struct CTc { @@ -591,7 +614,7 @@ public: : m_unColspan(oCell.m_unColspan), m_unRowSpan(oCell.m_unRowSpan), m_bIsMerged(oCell.m_bIsMerged), m_bIsEmpty(oCell.m_bIsEmpty), m_oStyles(oCell.m_oStyles) { - m_oData.SetText(oCell.m_oData.GetData()); + WriteToStringBuilder(oCell.m_oData, m_oData); } bool Empty() @@ -1082,7 +1105,7 @@ public: void AddCaption(NSStringUtils::CStringBuilder& oCaption) { - m_oCaption += oCaption.GetData(); + WriteToStringBuilder(oCaption, m_oCaption); } void SetPadding(const NSCSS::NSProperties::CIndent& oPadding) @@ -1220,42 +1243,40 @@ public: RecalculateMaxColumns(); } - std::wstring ConvertToOOXML() + bool ConvertToOOXML(NSStringUtils::CStringBuilder& oStringBuilder) { if (m_arRows.empty()) - return std::wstring(); + return false; - NSStringUtils::CStringBuilder oTable; - - oTable.WriteNodeBegin(L"w:tbl"); - oTable.WriteNodeBegin(L"w:tblPr"); + oStringBuilder.WriteNodeBegin(L"w:tbl"); + oStringBuilder.WriteNodeBegin(L"w:tblPr"); if (!m_oStyles.m_oWidth.Empty() && !m_oStyles.m_oWidth.Zero()) { if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oWidth.GetUnitMeasure()) - oTable += L""; + oStringBuilder += L""; else - oTable += L""; + oStringBuilder += L""; } else - oTable += L""; + oStringBuilder += L""; if (!m_oStyles.m_oMargin.GetLeft().Empty() && !m_oStyles.m_oMargin.GetLeft().Zero()) { if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oMargin.GetLeft().GetUnitMeasure()) - oTable += L""; + oStringBuilder += L""; else - oTable += L""; + oStringBuilder += L""; } if (!m_oStyles.m_wsAlign.empty()) - oTable += L""; + oStringBuilder += L""; if (0 < m_oStyles.m_nCellSpacing && m_oStyles.m_oBorder.GetCollapse() != NSCSS::NSProperties::BorderCollapse::Collapse) - oTable += L""; + oStringBuilder += L""; if (!m_oStyles.m_oBorder.Empty() && !m_oStyles.m_oBorder.Zero()) - oTable += L"" + CreateBorders(m_oStyles.m_oBorder, NULL, true, (TTableStyles::ETableRules::Groups == m_oStyles.m_enRules && !m_arColgroups.empty()) ? TTableStyles::ETableRules::Cols : m_oStyles.m_enRules) + L""; + oStringBuilder += L"" + CreateBorders(m_oStyles.m_oBorder, NULL, true, (TTableStyles::ETableRules::Groups == m_oStyles.m_enRules && !m_arColgroups.empty()) ? TTableStyles::ETableRules::Cols : m_oStyles.m_enRules) + L""; if (!m_oStyles.m_oPadding.Empty() && !m_oStyles.m_oPadding.Zero()) { @@ -1264,42 +1285,42 @@ public: const int nBottomPadding = std::max(0, m_oStyles.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT)); const int nRightPadding = std::max(0, m_oStyles.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH )); - oTable.WriteNodeBegin(L"w:tblCellMar"); + oStringBuilder.WriteNodeBegin(L"w:tblCellMar"); if (0 != nTopPadding) - oTable += L""; + oStringBuilder += L""; if (0 != nLeftPadding) - oTable += L""; + oStringBuilder += L""; if (0 != nBottomPadding) - oTable += L""; + oStringBuilder += L""; if (0 != nRightPadding) - oTable += L""; + oStringBuilder += L""; - oTable.WriteNodeEnd(L"w:tblCellMar"); + oStringBuilder.WriteNodeEnd(L"w:tblCellMar"); } else - oTable += L""; + oStringBuilder += L""; - oTable += L""; - oTable.WriteNodeEnd(L"w:tblPr"); + oStringBuilder += L""; + oStringBuilder.WriteNodeEnd(L"w:tblPr"); if (HaveCaption()) { - oTable.WriteNodeBegin(L"w:tr"); - oTable.WriteNodeBegin(L"w:tc"); - oTable.WriteNodeBegin(L"w:tcPr"); - oTable += L""; - oTable += L""; - oTable += L""; - oTable += L""; - oTable += L""; - oTable.WriteNodeEnd(L"w:tcPr"); - oTable.WriteString(m_oCaption.GetData()); - oTable.WriteNodeEnd(L"w:tc"); - oTable.WriteNodeEnd(L"w:tr"); + oStringBuilder.WriteNodeBegin(L"w:tr"); + oStringBuilder.WriteNodeBegin(L"w:tc"); + oStringBuilder.WriteNodeBegin(L"w:tcPr"); + oStringBuilder += L""; + oStringBuilder += L""; + oStringBuilder += L""; + oStringBuilder += L""; + oStringBuilder += L""; + oStringBuilder.WriteNodeEnd(L"w:tcPr"); + WriteToStringBuilder(m_oCaption, oStringBuilder); + oStringBuilder.WriteNodeEnd(L"w:tc"); + oStringBuilder.WriteNodeEnd(L"w:tr"); } #define CONVERT_ROWS(rows, mode) \ @@ -1314,7 +1335,7 @@ public: else if (0 != unRowIndex) \ nInstruction |= MID_ELEMENT << 4; \ nInstruction |= mode; \ - oTable += rows[unRowIndex]->ConvertToOOXML(*this, nInstruction); \ + oStringBuilder += rows[unRowIndex]->ConvertToOOXML(*this, nInstruction); \ } \ } @@ -1324,9 +1345,9 @@ public: CONVERT_ROWS(m_arRows, PARSE_MODE_BODY) CONVERT_ROWS(m_arFoother, PARSE_MODE_FOOTHER) - oTable.WriteNodeEnd(L"w:tbl"); + oStringBuilder.WriteNodeEnd(L"w:tbl"); - return oTable.GetData(); + return true; } private: std::vector> m_arHeaders; @@ -2357,7 +2378,7 @@ private: std::wstring sPStyle = wrP(&oPPr, arSelectors, oTS); - pXml->WriteString(oPPr.GetData()); + WriteToStringBuilder(oPPr, *pXml); NSStringUtils::CStringBuilder oRPr; std::wstring sRStyle; @@ -2366,7 +2387,7 @@ private: { sRStyle = wrRPr(&oRPr, arSelectors, oTS); - pXml->WriteString(oRPr.GetData()); + WriteToStringBuilder(oRPr, *pXml); if (oTS.bQ) pXml->WriteString(L"""); @@ -2411,12 +2432,12 @@ private: { CloseP(pXml, arSelectors); OpenP(pXml); - pXml->WriteString(oPPr.GetData()); + WriteToStringBuilder(oPPr, *pXml); sText.erase(0, nAfter + 1); nAfter = 0; } OpenR(pXml); - pXml->WriteString(oRPr.GetData()); + WriteToStringBuilder(oRPr, *pXml); nAfter = sText.find_first_of(L"\n\r\t", nAfter); } @@ -2966,12 +2987,12 @@ private: } } while (m_oLightReader.ReadNextSiblingNode2(nDeath)); - pXml->WriteString(oSummary.GetData()); + WriteToStringBuilder(oSummary, *pXml); if (bOpened) { m_oState = oBodyState; - pXml->WriteString(oBody.GetData()); + WriteToStringBuilder(oBody, *pXml); } return true; @@ -3277,7 +3298,7 @@ private: CloseP(&oXmlData, sSelectors); if (bResult) - oXml->WriteString(oXmlData.GetData()); + WriteToStringBuilder(oXmlData, *oXml); else m_oState = oCurentState; } @@ -3643,13 +3664,17 @@ private: OpenR(oXml); oXml->WriteString(L""); - oXml->WriteString(L"" + oRT.GetData() + L""); - oXml->WriteString(L"" + oBase.GetData() + L""); + oXml->WriteString(L""); + WriteToStringBuilder(oRT, *oXml); + oXml->WriteString(L""); + oXml->WriteString(L""); + WriteToStringBuilder(oBase, *oXml); + oXml->WriteString(L""); oXml->WriteString(L""); CloseR(oXml); } else - oXml->WriteString(oBase.GetData()); + WriteToStringBuilder(oBase, *oXml); CloseP(oXml, sSelectors); @@ -3773,7 +3798,7 @@ private: oTable.Shorten(); oTable.CompleteTable(); - oXml->WriteString(oTable.ConvertToOOXML()); + oTable.ConvertToOOXML(*oXml); WriteEmptyParagraph(oXml, true); return true; From 3af549a1580bf1216bd091f01d5f4e16b924090a Mon Sep 17 00:00:00 2001 From: Green Date: Sat, 18 Jan 2025 17:56:34 +0300 Subject: [PATCH 45/51] Fix bug #72586 --- EpubFile/src/CEpubFile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EpubFile/src/CEpubFile.cpp b/EpubFile/src/CEpubFile.cpp index 0ee795bb15..eeb91f6e74 100644 --- a/EpubFile/src/CEpubFile.cpp +++ b/EpubFile/src/CEpubFile.cpp @@ -80,7 +80,7 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s if (nContent != std::wstring::npos) { nContent += 11; - sContent = sFileContent.substr(nContent, sFileContent.find(L'\"', nContent) - nContent); + sContent = sFileContent.substr(nContent, sFileContent.find_first_of(L"\"'", nContent) - nContent); } std::wstring sContentPath; From c9ce68eab3c82667abe171bd8fb10d5808e380d6 Mon Sep 17 00:00:00 2001 From: Green Date: Sat, 18 Jan 2025 17:57:48 +0300 Subject: [PATCH 46/51] Improved work with external style files in html --- .../3dParty/html/css/src/CCssCalculator.cpp | 20 + Common/3dParty/html/css/src/CCssCalculator.h | 4 + .../html/css/src/CCssCalculator_Private.cpp | 803 +++++++++++------- .../html/css/src/CCssCalculator_Private.h | 92 +- Common/3dParty/html/css/src/CElement.cpp | 8 +- Common/3dParty/html/css/src/CElement.h | 3 +- .../3dParty/html/css/src/StaticFunctions.cpp | 1 - HtmlFile2/htmlfile2.cpp | 13 +- 8 files changed, 587 insertions(+), 357 deletions(-) diff --git a/Common/3dParty/html/css/src/CCssCalculator.cpp b/Common/3dParty/html/css/src/CCssCalculator.cpp index dee295f56c..86dabcf7ca 100644 --- a/Common/3dParty/html/css/src/CCssCalculator.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator.cpp @@ -63,6 +63,26 @@ namespace NSCSS return m_pInternal->GetDpi(); } + void CCssCalculator::ClearPageData() + { + m_pInternal->ClearPageData(); + } + + void CCssCalculator::ClearEmbeddedStyles() + { + m_pInternal->ClearEmbeddedStyles(); + } + + void CCssCalculator::ClearAllowedStyleFiles() + { + m_pInternal->ClearAllowedStyleFiles(); + } + + void CCssCalculator::ClearStylesFromFile(const std::wstring& wsFilePath) + { + m_pInternal->ClearStylesFromFile(wsFilePath); + } + void CCssCalculator::Clear() { m_pInternal->Clear(); diff --git a/Common/3dParty/html/css/src/CCssCalculator.h b/Common/3dParty/html/css/src/CCssCalculator.h index a6a0103e02..d5410e5e35 100644 --- a/Common/3dParty/html/css/src/CCssCalculator.h +++ b/Common/3dParty/html/css/src/CCssCalculator.h @@ -35,6 +35,10 @@ namespace NSCSS std::wstring GetEncoding() const; unsigned short int GetDpi() const; + void ClearPageData(); + void ClearEmbeddedStyles(); + void ClearAllowedStyleFiles(); + void ClearStylesFromFile(const std::wstring& wsFilePath); void Clear(); }; } diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index 9850a43162..0e1773048a 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -5,12 +5,9 @@ #include #include #include -#include #include #include "../../katana-parser/src/selector.h" -#include "../../../../../UnicodeConverter/UnicodeConverter.h" -#include "ConstValues.h" #include "../../../../../DesktopEditor/common/File.h" #include "StaticFunctions.h" @@ -41,58 +38,109 @@ bool operator<(const std::vector &arLeftSelectors, const std::vect namespace NSCSS { - CCssCalculator_Private::CCssCalculator_Private() : m_nDpi(96), m_nCountNodes(0), m_sEncoding(L"UTF-8"){} + CStyleStorage::CStyleStorage() + {} - CCssCalculator_Private::~CCssCalculator_Private() + CStyleStorage::~CStyleStorage() { - m_arFiles.clear(); - - for (std::map::iterator oIter = m_mData.begin(); oIter != m_mData.end(); ++oIter) - if (oIter->second != NULL) - delete oIter->second; - - m_mData.clear(); + Clear(); } - inline void CCssCalculator_Private::GetOutputData(KatanaOutput *oOutput) + void CStyleStorage::Clear() { - if ( NULL == oOutput ) + for (TStyleFileData* pStyleFileData : m_arStyleFiles) + { + if (nullptr == pStyleFileData) + continue; + + for (std::map::iterator oIter = pStyleFileData->m_mStyleData.begin(); oIter != pStyleFileData->m_mStyleData.end(); ++oIter) + if (oIter->second != nullptr) + delete oIter->second; + + delete pStyleFileData; + } + + m_arStyleFiles.clear(); + m_arEmptyStyleFiles.clear(); + + ClearPageData(); + ClearEmbeddedStyles(); + ClearAllowedStyleFiles(); + } + + void CStyleStorage::AddStyles(const std::string& sStyle) + { + if (sStyle.empty()) return; - switch (oOutput->mode) { - case KatanaParserModeStylesheet: - GetStylesheet(oOutput->stylesheet); - break; - case KatanaParserModeRule: - GetRule(oOutput->rule); - break; - case KatanaParserModeKeyframeRule: - case KatanaParserModeKeyframeKeyList: - case KatanaParserModeMediaList: - case KatanaParserModeValue: - case KatanaParserModeSelector: - case KatanaParserModeDeclarationList: - break; - } - + KatanaOutput *output = katana_parse(sStyle.c_str(), sStyle.length(), KatanaParserModeStylesheet); + this->GetOutputData(output, m_mEmbeddedStyleData); + katana_destroy_output(output); } - #ifdef CSS_CALCULATOR_WITH_XHTML - std::map CCssCalculator_Private::GetPageData(const std::wstring &wsPageName) + void CStyleStorage::AddStyles(const std::wstring& wsStyle) { - if (m_arPageDatas.empty()) - return {}; + if (wsStyle.empty()) + return; - for (const TPageData& oPageData : m_arPageDatas) + std::wregex oRegex(L"@page\\s*([^{]*)(\\{[^}]*\\})"); + std::wsmatch oMatch; + std::wstring::const_iterator oSearchStart(wsStyle.cbegin()); + + while (std::regex_search(oSearchStart, wsStyle.cend(), oMatch, oRegex)) { - if (std::find(oPageData.m_wsNames.begin(), oPageData.m_wsNames.end(), wsPageName) != oPageData.m_wsNames.end()) - return oPageData.m_mData; + AddPageData(oMatch[1].str(), oMatch[2].str()); + oSearchStart = oMatch.suffix().first; } - return {}; + AddStyles(U_TO_UTF8(wsStyle)); } - - void CCssCalculator_Private::SetPageData(NSProperties::CPage &oPage, const std::map &mData, unsigned int unLevel, bool bHardMode) + + void CStyleStorage::AddStylesFromFile(const std::wstring& wsFileName) + { + std::set::const_iterator itEmptyFileFound = m_arEmptyStyleFiles.find(wsFileName); + + if (m_arEmptyStyleFiles.cend() != itEmptyFileFound) + return; + + std::vector::const_iterator itFound = std::find_if(m_arStyleFiles.cbegin(), m_arStyleFiles.cend(), + [wsFileName](const TStyleFileData* pStyleFileData) + { return wsFileName == pStyleFileData->m_wsStyleFilepath; }); + + m_arAllowedStyleFiles.insert(wsFileName); + + if (m_arStyleFiles.cend() != itFound) + return; + + TStyleFileData *pStyleFileData = new TStyleFileData(); + + pStyleFileData->m_wsStyleFilepath = wsFileName; + + AddStyles(NS_STATIC_FUNCTIONS::GetContentAsUTF8(wsFileName), pStyleFileData->m_mStyleData); + + if (!pStyleFileData->m_mStyleData.empty()) + m_arStyleFiles.push_back(pStyleFileData); + else + { + m_arEmptyStyleFiles.insert(wsFileName); + delete pStyleFileData; + } + } + + void CStyleStorage::ClearStylesFromFile(const std::wstring& wsFileName) + { + std::vector::const_iterator itFound = std::find_if(m_arStyleFiles.cbegin(), m_arStyleFiles.cend(), + [wsFileName](const TStyleFileData* pStyleFileData) + { return wsFileName == pStyleFileData->m_wsStyleFilepath; }); + + if (m_arStyleFiles.cend() != itFound) + { + m_arStyleFiles.erase(itFound); + delete *itFound; + } + } + + void CStyleStorage::SetPageData(NSProperties::CPage& oPage, const std::map& mData, unsigned int unLevel, bool bHardMode) { for (const std::pair &oData : mData) { @@ -107,6 +155,343 @@ namespace NSCSS } } + std::map CStyleStorage::GetPageData(const std::wstring& wsPageName) + { + if (m_arPageDatas.empty()) + return {}; + + for (const TPageData& oPageData : m_arPageDatas) + { + if (std::find(oPageData.m_wsNames.begin(), oPageData.m_wsNames.end(), wsPageName) != oPageData.m_wsNames.end()) + return oPageData.m_mData; + } + + return {}; + } + + const CElement* CStyleStorage::FindElement(const std::wstring& wsSelector) + { + if (wsSelector.empty()) + return nullptr; + + const CElement* pFoundElement = FindSelectorFromStyleData(wsSelector, m_mEmbeddedStyleData); + + if (nullptr != pFoundElement) + return pFoundElement; + + for (std::vector::const_reverse_iterator itIter = m_arStyleFiles.crbegin(); itIter < m_arStyleFiles.crend(); ++itIter) + { + if (m_arAllowedStyleFiles.cend() == std::find(m_arAllowedStyleFiles.cbegin(), m_arAllowedStyleFiles.cend(), (*itIter)->m_wsStyleFilepath)) + continue; + + pFoundElement = FindSelectorFromStyleData(wsSelector, (*itIter)->m_mStyleData); + + if (nullptr != pFoundElement) + return pFoundElement; + } + + return nullptr; + } + + void CStyleStorage::AddStyles(const std::string& sStyle, std::map& mStyleData) + { + if (sStyle.empty()) + return; + + KatanaOutput *output = katana_parse(sStyle.c_str(), sStyle.length(), KatanaParserModeStylesheet); + this->GetOutputData(output, mStyleData); + katana_destroy_output(output); + } + + void CStyleStorage::AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles) + { + m_arPageDatas.push_back({NS_STATIC_FUNCTIONS::GetWordsW(wsPageName), NS_STATIC_FUNCTIONS::GetRules(wsStyles)}); + } + + void CStyleStorage::ClearPageData() + { + m_arPageDatas.clear(); + } + + void CStyleStorage::ClearEmbeddedStyles() + { + for (std::map::iterator oIter = m_mEmbeddedStyleData.begin(); oIter != m_mEmbeddedStyleData.end(); ++oIter) + if (oIter->second != nullptr) + delete oIter->second; + + m_mEmbeddedStyleData.clear(); + } + + void CStyleStorage::ClearAllowedStyleFiles() + { + m_arAllowedStyleFiles.clear(); + } + + void CStyleStorage::GetStylesheet(const KatanaStylesheet* oStylesheet, std::map& mStyleData) + { + for (size_t i = 0; i < oStylesheet->imports.length; ++i) + GetRule((KatanaRule*)oStylesheet->imports.data[i], mStyleData); + + for (size_t i = 0; i < oStylesheet->rules.length; ++i) + GetRule((KatanaRule*)oStylesheet->rules.data[i], mStyleData); + } + + void CStyleStorage::GetRule(const KatanaRule* oRule, std::map& mStyleData) + { + if ( NULL == oRule ) + return; + + switch (oRule->type) { + case KatanaRuleStyle: + { + GetStyleRule((KatanaStyleRule*)oRule, mStyleData); + break; + } + default: + break; + } + } + + void CStyleStorage::GetStyleRule(const KatanaStyleRule* oRule, std::map& mStyleData) + { + if (oRule->declarations->length == 0) + return; + + const std::map mStyle = GetDeclarationList(oRule->declarations); + for (const std::wstring &wsSelector : GetSelectorList(oRule->selectors)) + { + std::vector arWords = NS_STATIC_FUNCTIONS::GetWordsW(wsSelector, false, L" "); + + CElement* oLastElement = NULL; + CElement* oFirstElement = NULL; + bool bCreateFirst = true; + + for (std::vector::reverse_iterator oWord = arWords.rbegin(); oWord != arWords.rend(); ++oWord) + { + const size_t posPoint = oWord->find(L'.'); + const size_t posLattice = oWord->find(L'#'); + + const std::wstring sName = (posPoint != std::wstring::npos) ? oWord->substr(0, posPoint) : (posLattice != std::wstring::npos) ? oWord->substr(0, posLattice) : *oWord; + const std::wstring sClass = (posPoint != std::wstring::npos) ? (posLattice == std::wstring::npos) ? oWord->substr(posPoint, oWord->length()) : oWord->substr(posPoint, posLattice - posPoint) : L""; + const std::wstring sId = (posLattice != std::wstring::npos) ? oWord->substr(posLattice, oWord->length()) : L""; + + CElement* oNameElement = NULL; + CElement* oClassElement = NULL; + CElement* oIdElement = NULL; + bool bIsNewElement = true; + + if (!sId.empty()) + { + if (NULL == oFirstElement && bCreateFirst) + { + const std::map::const_iterator& oFindId = mStyleData.find(sId); + if (oFindId != mStyleData.end()) + { + oIdElement = oFindId->second; + bCreateFirst = false; + } + else + { + oIdElement = new CElement; + oIdElement->SetSelector(sId); + if (bCreateFirst) + oFirstElement = oIdElement; + } + } + else + { + oIdElement = new CElement; + oIdElement->SetSelector(sId); + + oLastElement->AddPrevElement(oIdElement); + } + bIsNewElement = false; + oLastElement = oIdElement; + } + + if (!sClass.empty()) + { + if (NULL == oFirstElement && bCreateFirst) + { + const std::map::const_iterator& oFindClass = mStyleData.find(sClass); + if (oFindClass != mStyleData.end()) + { + oClassElement = oFindClass->second; + bCreateFirst = false; + } + else + { + oClassElement = new CElement; + oClassElement->SetSelector(sClass); + if (bCreateFirst) + oFirstElement = oClassElement; + } + } + else + { + oClassElement = new CElement; + oClassElement->SetSelector(sClass); + + if (bIsNewElement) + oLastElement->AddPrevElement(oClassElement); + else + oLastElement->AddKinElement(oClassElement); + } + + bIsNewElement = false; + oLastElement = oClassElement; + } + + if (!sName.empty()) + { + if (NULL == oFirstElement && bCreateFirst) + { + const std::map::const_iterator& oFindName = mStyleData.find(sName); + if (oFindName != mStyleData.end()) + { + oNameElement = oFindName->second; + bCreateFirst = false; + } + else + { + oNameElement = new CElement; + oNameElement->SetSelector(sName); + if (bCreateFirst) + oFirstElement = oNameElement; + } + } + else + { + oNameElement = new CElement; + oNameElement->SetSelector(sName); + + if (bIsNewElement) + oLastElement->AddPrevElement(oNameElement); + else + oLastElement->AddKinElement(oNameElement); + + } + oLastElement = oNameElement; + } + } + + if (NULL != oLastElement) + oLastElement->AddProperties(mStyle); + + if (NULL != oFirstElement) + mStyleData[oFirstElement->GetSelector()] = oFirstElement; + } + } + + std::wstring CStyleStorage::GetValueList(const KatanaArray* oValues) + { + return StringifyValueList(oValues); + } + + std::vector CStyleStorage::GetSelectorList(const KatanaArray* oSelectors) const + { + if (oSelectors->length == 0) + return std::vector(); + + std::vector arSelectors; + + for (unsigned int i = 0; i < oSelectors->length; ++i) + arSelectors.push_back(GetSelector((KatanaSelector*)oSelectors->data[i])); + + return arSelectors; + } + + std::wstring CStyleStorage::GetSelector(const KatanaSelector* oSelector) const + { + KatanaParser oParser; + oParser.options = &kKatanaDefaultOptions; + + std::wstring wsText; + const KatanaParserString* string = katana_selector_to_string(&oParser, const_cast(oSelector), NULL); + const char* text = katana_string_to_characters(&oParser, string); + + katana_parser_deallocate(&oParser, (void*) string->data); + katana_parser_deallocate(&oParser, (void*) string); + + wsText = UTF8_TO_U(std::string(text)); + + katana_parser_deallocate(&oParser, (void*)text); + + return wsText; + } + + std::map CStyleStorage::GetDeclarationList(const KatanaArray* oDeclarations) const + { + if(oDeclarations->length == 0) + return std::map(); + + std::map arDeclarations; + + for (size_t i = 0; i < oDeclarations->length; ++i) + arDeclarations.insert(GetDeclaration((KatanaDeclaration*)oDeclarations->data[i])); + + return arDeclarations; + } + + std::pair CStyleStorage::GetDeclaration(const KatanaDeclaration* oDecl) const + { + std::wstring sValueList = StringifyValueList(oDecl->values); + + if (oDecl->important) + sValueList += L" !important"; + + return std::make_pair(UTF8_TO_U(std::string(oDecl->property)), sValueList); + } + + void CStyleStorage::GetOutputData(KatanaOutput* oOutput, std::map& mStyleData) + { + if ( NULL == oOutput ) + return; + + switch (oOutput->mode) { + case KatanaParserModeStylesheet: + GetStylesheet(oOutput->stylesheet, mStyleData); + break; + case KatanaParserModeRule: + GetRule(oOutput->rule, mStyleData); + break; + case KatanaParserModeKeyframeRule: + case KatanaParserModeKeyframeKeyList: + case KatanaParserModeMediaList: + case KatanaParserModeValue: + case KatanaParserModeSelector: + case KatanaParserModeDeclarationList: + break; + } + } + + const CElement* CStyleStorage::FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map& mStyleData) + { + std::map::const_iterator itFound = mStyleData.find(wsSelector); + + if (mStyleData.cend() != itFound) + return itFound->second; + + return nullptr; + } + + CCssCalculator_Private::CCssCalculator_Private() : m_nDpi(96), m_nCountNodes(0), m_sEncoding(L"UTF-8"){} + + CCssCalculator_Private::~CCssCalculator_Private() + {} + + #ifdef CSS_CALCULATOR_WITH_XHTML + std::map CCssCalculator_Private::GetPageData(const std::wstring &wsPageName) + { + return m_oStyleStorage.GetPageData(wsPageName); + } + + void CCssCalculator_Private::SetPageData(NSProperties::CPage &oPage, const std::map &mData, unsigned int unLevel, bool bHardMode) + { + //TODO:: пересмотреть данный метод + m_oStyleStorage.SetPageData(oPage, mData, unLevel, bHardMode); + } + std::vector CCssCalculator_Private::CalculateAllNodes(const std::vector &arSelectors) { std::vector arNodes; @@ -137,7 +522,7 @@ namespace NSCSS return arNodes; } - void CCssCalculator_Private::FindPrevAndKindElements(const CElement *pElement, const std::vector &arNextNodes, std::vector& arFindedElements, const std::wstring &wsName, const std::vector &arClasses) + void CCssCalculator_Private::FindPrevAndKindElements(const CElement *pElement, const std::vector &arNextNodes, std::vector& arFindedElements, const std::wstring &wsName, const std::vector &arClasses) { if (arNextNodes.empty()) return; @@ -152,12 +537,12 @@ namespace NSCSS arFindedElements.insert(arFindedElements.end(), arTempKins.begin(), arTempKins.end()); } - std::vector CCssCalculator_Private::FindElements(std::vector &arNodes, std::vector &arNextNodes) + std::vector CCssCalculator_Private::FindElements(std::vector &arNodes, std::vector &arNextNodes) { if (arNodes.empty()) return {}; - std::vector arFindedElements; + std::vector arFindedElements; std::wstring wsName, wsId; std::vector arClasses; @@ -183,19 +568,16 @@ namespace NSCSS arNextNodes.push_back(wsName); } - const std::map::const_iterator oFindName = m_mData.find(wsName); - std::map::const_iterator oFindId; - if (!wsId.empty()) { - oFindId = m_mData.find(wsId); + const CElement* pFoundId = m_oStyleStorage.FindElement(wsId); - if (m_mData.cend() != oFindId) + if(nullptr != pFoundId) { - if (!oFindId->second->Empty()) - arFindedElements.push_back(oFindId->second); + if (!pFoundId->Empty()) + arFindedElements.push_back(pFoundId); - FindPrevAndKindElements(oFindId->second, arNextNodes, arFindedElements, wsName); + FindPrevAndKindElements(pFoundId, arNextNodes, arFindedElements, wsName); } } @@ -203,260 +585,38 @@ namespace NSCSS { for (std::vector::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass) { - const std::map::const_iterator oFindClass = m_mData.find(*iClass); - if (oFindClass != m_mData.cend()) - { - if (!oFindClass->second->Empty()) - arFindedElements.push_back(oFindClass->second); + const CElement* pFoundClass = m_oStyleStorage.FindElement(*iClass); - FindPrevAndKindElements(oFindClass->second, arNextNodes, arFindedElements, wsName); + if (nullptr != pFoundClass) + { + if (!pFoundClass->Empty()) + arFindedElements.push_back(pFoundClass); + + FindPrevAndKindElements(pFoundClass, arNextNodes, arFindedElements, wsName); } } } - if (oFindName != m_mData.cend()) - { - if (!oFindName->second->Empty()) - arFindedElements.push_back(oFindName->second); + const CElement* pFoundName = m_oStyleStorage.FindElement(wsName); - FindPrevAndKindElements(oFindName->second, arNextNodes, arFindedElements, wsName, arClasses); + if (nullptr != pFoundName) + { + if (!pFoundName->Empty()) + arFindedElements.push_back(pFoundName); + + FindPrevAndKindElements(pFoundName, arNextNodes, arFindedElements, wsName, arClasses); } if (arFindedElements.size() > 1) { std::sort(arFindedElements.rbegin(), arFindedElements.rend(), - [](CElement* oFirstElement, CElement* oSecondElement) - { - return oFirstElement->GetWeight() > oSecondElement->GetWeight(); - }); + [](const CElement* oFirstElement, const CElement* oSecondElement) + { return oFirstElement->GetWeight() > oSecondElement->GetWeight(); }); } return arFindedElements; } - #endif - void CCssCalculator_Private::AddPageData(const std::wstring &wsPageNames, const std::wstring &wsStyles) - { - m_arPageDatas.push_back({NS_STATIC_FUNCTIONS::GetWordsW(wsPageNames), NS_STATIC_FUNCTIONS::GetRules(wsStyles)}); - } - - inline void CCssCalculator_Private::GetStylesheet(const KatanaStylesheet *oStylesheet) - { - for (size_t i = 0; i < oStylesheet->imports.length; ++i) - GetRule((KatanaRule*)oStylesheet->imports.data[i]); - - for (size_t i = 0; i < oStylesheet->rules.length; ++i) - GetRule((KatanaRule*)oStylesheet->rules.data[i]); - } - - inline void CCssCalculator_Private::GetRule(const KatanaRule *oRule) - { - if ( NULL == oRule ) - return; - - switch (oRule->type) { - case KatanaRuleStyle: - { - GetStyleRule((KatanaStyleRule*)oRule); - break; - } - default: - break; - } - } - - inline void CCssCalculator_Private::GetStyleRule(const KatanaStyleRule *oRule) - { - if (oRule->declarations->length == 0) - return; - - const std::map mStyle = GetDeclarationList(oRule->declarations); - for (const std::wstring &wsSelector : GetSelectorList(oRule->selectors)) - { - std::vector arWords = NS_STATIC_FUNCTIONS::GetWordsW(wsSelector, false, L" "); - - CElement* oLastElement = NULL; - CElement* oFirstElement = NULL; - bool bCreateFirst = true; - - for (std::vector::reverse_iterator oWord = arWords.rbegin(); oWord != arWords.rend(); ++oWord) - { - const size_t posPoint = oWord->find(L'.'); - const size_t posLattice = oWord->find(L'#'); - - const std::wstring sName = (posPoint != std::wstring::npos) ? oWord->substr(0, posPoint) : (posLattice != std::wstring::npos) ? oWord->substr(0, posLattice) : *oWord; - const std::wstring sClass = (posPoint != std::wstring::npos) ? (posLattice == std::wstring::npos) ? oWord->substr(posPoint, oWord->length()) : oWord->substr(posPoint, posLattice - posPoint) : L""; - const std::wstring sId = (posLattice != std::wstring::npos) ? oWord->substr(posLattice, oWord->length()) : L""; - - CElement* oNameElement = NULL; - CElement* oClassElement = NULL; - CElement* oIdElement = NULL; - bool bIsNewElement = true; - - if (!sId.empty()) - { - if (NULL == oFirstElement && bCreateFirst) - { - const std::map::const_iterator& oFindId = m_mData.find(sId); - if (oFindId != m_mData.end()) - { - oIdElement = oFindId->second; - bCreateFirst = false; - } - else - { - oIdElement = new CElement; - oIdElement->SetSelector(sId); - if (bCreateFirst) - oFirstElement = oIdElement; - } - } - else - { - oIdElement = new CElement; - oIdElement->SetSelector(sId); - - oLastElement->AddPrevElement(oIdElement); - } - bIsNewElement = false; - oLastElement = oIdElement; - } - - if (!sClass.empty()) - { - if (NULL == oFirstElement && bCreateFirst) - { - const std::map::const_iterator& oFindClass = m_mData.find(sClass); - if (oFindClass != m_mData.end()) - { - oClassElement = oFindClass->second; - bCreateFirst = false; - } - else - { - oClassElement = new CElement; - oClassElement->SetSelector(sClass); - if (bCreateFirst) - oFirstElement = oClassElement; - } - } - else - { - oClassElement = new CElement; - oClassElement->SetSelector(sClass); - - if (bIsNewElement) - oLastElement->AddPrevElement(oClassElement); - else - oLastElement->AddKinElement(oClassElement); - } - - bIsNewElement = false; - oLastElement = oClassElement; - } - - if (!sName.empty()) - { - if (NULL == oFirstElement && bCreateFirst) - { - const std::map::const_iterator& oFindName = m_mData.find(sName); - if (oFindName != m_mData.end()) - { - oNameElement = oFindName->second; - bCreateFirst = false; - } - else - { - oNameElement = new CElement; - oNameElement->SetSelector(sName); - if (bCreateFirst) - oFirstElement = oNameElement; - } - } - else - { - oNameElement = new CElement; - oNameElement->SetSelector(sName); - - if (bIsNewElement) - oLastElement->AddPrevElement(oNameElement); - else - oLastElement->AddKinElement(oNameElement); - - } - oLastElement = oNameElement; - } - } - - if (NULL != oLastElement) - oLastElement->AddProperties(mStyle); - - if (NULL != oFirstElement) - m_mData[oFirstElement->GetSelector()] = oFirstElement; - } - } - - inline std::vector CCssCalculator_Private::GetSelectorList(const KatanaArray* oSelectors) const - { - if (oSelectors->length == 0) - return std::vector(); - - std::vector arSelectors; - - for (unsigned int i = 0; i < oSelectors->length; ++i) - arSelectors.push_back(GetSelector((KatanaSelector*)oSelectors->data[i])); - - return arSelectors; - } - - inline std::wstring CCssCalculator_Private::GetSelector(const KatanaSelector *oSelector) const - { - KatanaParser oParser; - oParser.options = &kKatanaDefaultOptions; - - std::wstring wsText; - const KatanaParserString* string = katana_selector_to_string(&oParser, const_cast(oSelector), NULL); - const char* text = katana_string_to_characters(&oParser, string); - - katana_parser_deallocate(&oParser, (void*) string->data); - katana_parser_deallocate(&oParser, (void*) string); - - wsText = UTF8_TO_U(std::string(text)); - - katana_parser_deallocate(&oParser, (void*)text); - - return wsText; - } - - inline std::map CCssCalculator_Private::GetDeclarationList(const KatanaArray* oDeclarations) const - { - if(oDeclarations->length == 0) - return std::map(); - - std::map arDeclarations; - - for (size_t i = 0; i < oDeclarations->length; ++i) - arDeclarations.insert(GetDeclaration((KatanaDeclaration*)oDeclarations->data[i])); - - return arDeclarations; - } - - inline std::pair CCssCalculator_Private::GetDeclaration(const KatanaDeclaration* oDecl) const - { - std::wstring sValueList = StringifyValueList(oDecl->values); - - if (oDecl->important) - sValueList += L" !important"; - - return std::make_pair(UTF8_TO_U(std::string(oDecl->property)), sValueList); - } - - inline std::wstring CCssCalculator_Private::GetValueList(const KatanaArray *oValues) - { - return StringifyValueList(oValues); - } - - #ifdef CSS_CALCULATOR_WITH_XHTML CCompiledStyle CCssCalculator_Private::GetCompiledStyle(const std::vector& arSelectors) { if (arSelectors.empty()) @@ -566,42 +726,20 @@ namespace NSCSS return true; } #endif - void CCssCalculator_Private::AddStyles(const std::string &sStyle) - { - if (sStyle.empty()) - return; - KatanaOutput *output = katana_parse(sStyle.c_str(), sStyle.length(), KatanaParserModeStylesheet); - this->GetOutputData(output); - katana_destroy_output(output); + void CCssCalculator_Private::AddStyles(const std::string& sStyle) + { + m_oStyleStorage.AddStyles(sStyle); } - void CCssCalculator_Private::AddStyles(const std::wstring &wsStyle) + void CCssCalculator_Private::AddStyles(const std::wstring& wsStyle) { - if (wsStyle.empty()) - return; - - std::wregex oRegex(L"@page\\s*([^{]*)(\\{[^}]*\\})"); - std::wsmatch oMatch; - std::wstring::const_iterator oSearchStart(wsStyle.cbegin()); - - while (std::regex_search(oSearchStart, wsStyle.cend(), oMatch, oRegex)) - { - AddPageData(oMatch[1].str(), oMatch[2].str()); - oSearchStart = oMatch.suffix().first; - } - - AddStyles(U_TO_UTF8(wsStyle)); + m_oStyleStorage.AddStyles(wsStyle); } void CCssCalculator_Private::AddStylesFromFile(const std::wstring& wsFileName) { - if (std::find(m_arFiles.begin(), m_arFiles.end(), wsFileName) != m_arFiles.end()) - return; - - m_arFiles.push_back(wsFileName); - - AddStyles(NS_STATIC_FUNCTIONS::GetContentAsUTF8(wsFileName)); + m_oStyleStorage.AddStylesFromFile(wsFileName); } void CCssCalculator_Private::SetDpi(unsigned short int nValue) @@ -614,9 +752,28 @@ namespace NSCSS return m_nDpi; } - const std::map *CCssCalculator_Private::GetData() const + void CCssCalculator_Private::ClearPageData() { - return &m_mData; + m_oStyleStorage.ClearPageData(); + } + + void CCssCalculator_Private::ClearEmbeddedStyles() + { + m_oStyleStorage.ClearEmbeddedStyles(); + + #ifdef CSS_CALCULATOR_WITH_XHTML + m_mUsedStyles.clear(); + #endif + } + + void CCssCalculator_Private::ClearAllowedStyleFiles() + { + m_oStyleStorage.ClearAllowedStyleFiles(); + } + + void CCssCalculator_Private::ClearStylesFromFile(const std::wstring& wsFilePath) + { + m_oStyleStorage.ClearStylesFromFile(wsFilePath); } std::wstring CCssCalculator_Private::GetEncoding() const @@ -629,10 +786,14 @@ namespace NSCSS m_sEncoding = L"UTF-8"; m_nDpi = 96; - m_mData.clear(); - m_arFiles.clear(); + m_oStyleStorage.Clear(); + + #ifdef CSS_CALCULATOR_WITH_XHTML + m_mUsedStyles.clear(); + #endif } } + inline static std::wstring StringifyValueList(const KatanaArray* oValues) { if (NULL == oValues) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.h b/Common/3dParty/html/css/src/CCssCalculator_Private.h index f4837f9df7..55067586db 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.h +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.h @@ -16,14 +16,40 @@ namespace NSCSS { - class CCssCalculator_Private + class CStyleStorage { - unsigned short int m_nDpi; - unsigned short int m_nCountNodes; + public: + CStyleStorage(); + ~CStyleStorage(); - std::list m_arFiles; + void Clear(); - std::map m_mData; + void AddStyles(const std::string& sStyle); + void AddStyles(const std::wstring& wsStyle); + void AddStylesFromFile(const std::wstring& wsFileName); + void AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles); + + void ClearPageData(); + void ClearEmbeddedStyles(); + void ClearAllowedStyleFiles(); + void ClearStylesFromFile(const std::wstring& wsFileName); + + void SetPageData(NSProperties::CPage& oPage, const std::map& mData, unsigned int unLevel, bool bHardMode = false); + + std::map GetPageData(const std::wstring& wsPageName); + + const CElement* FindElement(const std::wstring& wsSelector); + private: + typedef struct + { + std::wstring m_wsStyleFilepath; + std::map m_mStyleData; + } TStyleFileData; + + std::set m_arEmptyStyleFiles; + std::set m_arAllowedStyleFiles; + std::vector m_arStyleFiles; + std::map m_mEmbeddedStyleData; typedef struct { @@ -32,27 +58,13 @@ namespace NSCSS } TPageData; std::vector m_arPageDatas; + private: + void AddStyles(const std::string& sStyle, std::map& mStyleData); - #ifdef CSS_CALCULATOR_WITH_XHTML - std::map, CCompiledStyle> m_mUsedStyles; - - std::map GetPageData(const std::wstring& wsPageName); - void SetPageData(NSProperties::CPage& oPage, const std::map& mData, unsigned int unLevel, bool bHardMode = false); + void GetStylesheet(const KatanaStylesheet* oStylesheet, std::map& mStyleData); + void GetRule(const KatanaRule* oRule, std::map& mStyleData); - std::vector CalculateAllNodes(const std::vector& arSelectors); - - void FindPrevAndKindElements(const CElement* pElement, const std::vector& arNextNodes, std::vector& arFindedElements, const std::wstring& wsName, const std::vector& arClasses = {}); - std::vector FindElements(std::vector& arNodes, std::vector& arNextNodes); - #endif - - std::wstring m_sEncoding; - - void AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles); - - void GetStylesheet(const KatanaStylesheet* oStylesheet); - void GetRule(const KatanaRule* oRule); - - void GetStyleRule(const KatanaStyleRule* oRule); + void GetStyleRule(const KatanaStyleRule* oRule, std::map& mStyleData); std::wstring GetValueList(const KatanaArray* oValues); @@ -62,7 +74,31 @@ namespace NSCSS std::map GetDeclarationList(const KatanaArray* oDeclarations) const; std::pair GetDeclaration(const KatanaDeclaration* oDecl) const; - void GetOutputData(KatanaOutput* oOutput); + void GetOutputData(KatanaOutput* oOutput, std::map& mStyleData); + + const CElement* FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map& mStyleData); + }; + + class CCssCalculator_Private + { + unsigned short int m_nDpi; + unsigned short int m_nCountNodes; + + CStyleStorage m_oStyleStorage; + + #ifdef CSS_CALCULATOR_WITH_XHTML + std::map, CCompiledStyle> m_mUsedStyles; + + std::map GetPageData(const std::wstring& wsPageName); + void SetPageData(NSProperties::CPage& oPage, const std::map& mData, unsigned int unLevel, bool bHardMode = false); + + std::vector CalculateAllNodes(const std::vector& arSelectors); + + void FindPrevAndKindElements(const CElement* pElement, const std::vector& arNextNodes, std::vector& arFindedElements, const std::wstring& wsName, const std::vector& arClasses = {}); + std::vector FindElements(std::vector& arNodes, std::vector& arNextNodes); + #endif + + std::wstring m_sEncoding; public: CCssCalculator_Private(); @@ -85,8 +121,10 @@ namespace NSCSS std::wstring GetEncoding() const; unsigned short int GetDpi() const; - const std::map* GetData() const; - + void ClearPageData(); + void ClearEmbeddedStyles(); + void ClearAllowedStyleFiles(); + void ClearStylesFromFile(const std::wstring& wsFilePath); void Clear(); }; diff --git a/Common/3dParty/html/css/src/CElement.cpp b/Common/3dParty/html/css/src/CElement.cpp index c6144ee26f..1ceda93ff4 100644 --- a/Common/3dParty/html/css/src/CElement.cpp +++ b/Common/3dParty/html/css/src/CElement.cpp @@ -40,6 +40,7 @@ namespace NSCSS { m_sSelector = sSelector; m_sFullSelector = m_sSelector; + UpdateWeight(); } void NSCSS::CElement::AddPropertie(const std::wstring &sName, const std::wstring& sValue) @@ -67,6 +68,7 @@ namespace NSCSS m_arPrevElements.push_back(oPrevElement); oPrevElement->m_sFullSelector += L' ' + m_sFullSelector; + UpdateWeight(); } void CElement::AddKinElement(CElement *oKinElement) @@ -76,6 +78,7 @@ namespace NSCSS m_arKinElements.push_back(oKinElement); oKinElement->m_sFullSelector += m_sFullSelector; + oKinElement->UpdateWeight(); } std::map CElement::GetStyle() const @@ -230,11 +233,14 @@ namespace NSCSS return NULL; } - std::vector CElement::GetWeight() + void CElement::UpdateWeight() { if (m_arWeight.empty()) m_arWeight = NS_STATIC_FUNCTIONS::GetWeightSelector(m_sFullSelector); + } + std::vector CElement::GetWeight() const + { return m_arWeight; } diff --git a/Common/3dParty/html/css/src/CElement.h b/Common/3dParty/html/css/src/CElement.h index 0cb32d7935..9844b27cc6 100644 --- a/Common/3dParty/html/css/src/CElement.h +++ b/Common/3dParty/html/css/src/CElement.h @@ -44,7 +44,8 @@ namespace NSCSS CElement *FindPrevElement(const std::wstring& sSelector) const; - std::vector GetWeight(); + void UpdateWeight(); + std::vector GetWeight() const; void IncreasedWeight(); }; } diff --git a/Common/3dParty/html/css/src/StaticFunctions.cpp b/Common/3dParty/html/css/src/StaticFunctions.cpp index 6eee504aa0..4ef042783b 100644 --- a/Common/3dParty/html/css/src/StaticFunctions.cpp +++ b/Common/3dParty/html/css/src/StaticFunctions.cpp @@ -48,7 +48,6 @@ namespace NS_STATIC_FUNCTIONS if (sEncoding.empty()) sEncoding = "utf-8"; - if (!sEncoding.empty() && sEncoding != "utf-8" && sEncoding != "UTF-8") { NSUnicodeConverter::CUnicodeConverter oConverter; diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index a24e75048d..f9798caaa2 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -6,8 +6,6 @@ #include #include #include -#include -#include #include "../Common/3dParty/html/htmltoxhtml.h" #include "../Common/3dParty/html/css/src/CCssCalculator.h" @@ -2372,8 +2370,6 @@ private: if (oTS.bAddSpaces && m_oState.m_bInP && !m_oState.m_bInR && !iswspace(sText.front()) && !m_oState.m_bWasSpace && CTextSettings::Normal == oTS.eTextMode) WriteSpace(pXml); - OpenP(pXml); - NSStringUtils::CStringBuilder oPPr; std::wstring sPStyle = wrP(&oPPr, arSelectors, oTS); @@ -4791,8 +4787,13 @@ HRESULT CHtmlFile2::OpenBatchHtml(const std::vector& sSrc, const s m_internal->m_oLightReader.Clear(); m_internal->m_sBase.clear(); } - //Если очищать, то каждый раз при использовании внешнего css файла он заново парсится - // m_internal->m_oStylesCalculator.Clear(); + + // Очищаем разрешенные файлы стилей + // Это необходимо, чтобы мы не могли взять стили из не подключенного файла, но при этом, чтобы данные оставались, + // т.к. ко многим файлам может быть подключен один и тот же файл (проблема возникает когда он большой) + // и подключать (в нашем случае заново парсить) его будет долго + m_internal->m_oStylesCalculator.ClearAllowedStyleFiles(); + m_internal->m_oStylesCalculator.ClearEmbeddedStyles(); } m_internal->write(); From da252bfa5ec2ccf31efc5ee5e1a786c1297c074e Mon Sep 17 00:00:00 2001 From: Green Date: Sun, 19 Jan 2025 16:41:47 +0300 Subject: [PATCH 47/51] Fix bug #72589 --- HtmlFile2/htmlfile2.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/HtmlFile2/htmlfile2.cpp b/HtmlFile2/htmlfile2.cpp index f9798caaa2..6534a46072 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -792,6 +792,7 @@ public: if (1 != pCell->GetColspan()) { + ++itFoundEmpty; UINT unColspan = pCell->GetColspan() - 1; while (m_arCells.end() != itFoundEmpty && (*itFoundEmpty)->Empty() && unColspan > 0) @@ -824,12 +825,13 @@ public: { delete m_arCells[nPosition]; --m_oStyles.m_unMaxIndex; - m_arCells[nPosition++] = pCell; + m_arCells[nPosition] = pCell; if (1 != pCell->GetColspan()) { + ++nPosition; UINT unDeleteCount = pCell->GetColspan() - 1; - while (m_arCells[nPosition]->Empty() && nPosition < m_arCells.size() && unDeleteCount > 0) + while (nPosition < m_arCells.size() && m_arCells[nPosition]->Empty() && !m_arCells[nPosition]->Merged() && unDeleteCount > 0) { delete m_arCells[nPosition]; --m_oStyles.m_unMaxIndex; From 024efd2e35794333f7922eb4d57d8229829d8a4b Mon Sep 17 00:00:00 2001 From: Green Date: Thu, 16 Jan 2025 17:35:11 +0300 Subject: [PATCH 48/51] Fix bug #72535 --- HwpFile/HwpDoc/HWPStream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HwpFile/HwpDoc/HWPStream.cpp b/HwpFile/HwpDoc/HWPStream.cpp index bd4bc15182..4e35ffce05 100644 --- a/HwpFile/HwpDoc/HWPStream.cpp +++ b/HwpFile/HwpDoc/HWPStream.cpp @@ -193,7 +193,7 @@ void Trim(HWP_STRING& sValue) HWP_STRING::const_reverse_iterator itEnd = std::find_if(sValue.crbegin(), sValue.crend(), [](wchar_t wChar){ return !iswcntrl(wChar); }); - if (itEnd != sValue.crend()) + if (itEnd != sValue.crbegin()) sValue.erase(itEnd.base()); } From 70c98eb9f34f28c568416c4364fee6541b34fe6c Mon Sep 17 00:00:00 2001 From: Green Date: Mon, 20 Jan 2025 15:13:33 +0300 Subject: [PATCH 49/51] Fix build --- .../html/css/src/CCssCalculator_Private.cpp | 65 +++++---- .../html/css/src/CCssCalculator_Private.h | 36 ++--- .../raster/Metafile/svg/SvgObjects/CStyle.cpp | 133 ++---------------- 3 files changed, 64 insertions(+), 170 deletions(-) diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index 0e1773048a..ea30b49502 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -63,9 +63,12 @@ namespace NSCSS m_arStyleFiles.clear(); m_arEmptyStyleFiles.clear(); - ClearPageData(); ClearEmbeddedStyles(); ClearAllowedStyleFiles(); + + #ifdef CSS_CALCULATOR_WITH_XHTML + ClearPageData(); + #endif } void CStyleStorage::AddStyles(const std::string& sStyle) @@ -83,6 +86,7 @@ namespace NSCSS if (wsStyle.empty()) return; + #ifdef CSS_CALCULATOR_WITH_XHTML std::wregex oRegex(L"@page\\s*([^{]*)(\\{[^}]*\\})"); std::wsmatch oMatch; std::wstring::const_iterator oSearchStart(wsStyle.cbegin()); @@ -92,6 +96,7 @@ namespace NSCSS AddPageData(oMatch[1].str(), oMatch[2].str()); oSearchStart = oMatch.suffix().first; } + #endif AddStyles(U_TO_UTF8(wsStyle)); } @@ -140,6 +145,12 @@ namespace NSCSS } } + #ifdef CSS_CALCULATOR_WITH_XHTML + void CStyleStorage::AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles) + { + m_arPageDatas.push_back({NS_STATIC_FUNCTIONS::GetWordsW(wsPageName), NS_STATIC_FUNCTIONS::GetRules(wsStyles)}); + } + void CStyleStorage::SetPageData(NSProperties::CPage& oPage, const std::map& mData, unsigned int unLevel, bool bHardMode) { for (const std::pair &oData : mData) @@ -169,6 +180,12 @@ namespace NSCSS return {}; } + void CStyleStorage::ClearPageData() + { + m_arPageDatas.clear(); + } + #endif + const CElement* CStyleStorage::FindElement(const std::wstring& wsSelector) { if (wsSelector.empty()) @@ -203,16 +220,6 @@ namespace NSCSS katana_destroy_output(output); } - void CStyleStorage::AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles) - { - m_arPageDatas.push_back({NS_STATIC_FUNCTIONS::GetWordsW(wsPageName), NS_STATIC_FUNCTIONS::GetRules(wsStyles)}); - } - - void CStyleStorage::ClearPageData() - { - m_arPageDatas.clear(); - } - void CStyleStorage::ClearEmbeddedStyles() { for (std::map::iterator oIter = m_mEmbeddedStyleData.begin(); oIter != m_mEmbeddedStyleData.end(); ++oIter) @@ -481,17 +488,23 @@ namespace NSCSS {} #ifdef CSS_CALCULATOR_WITH_XHTML - std::map CCssCalculator_Private::GetPageData(const std::wstring &wsPageName) - { - return m_oStyleStorage.GetPageData(wsPageName); - } - void CCssCalculator_Private::SetPageData(NSProperties::CPage &oPage, const std::map &mData, unsigned int unLevel, bool bHardMode) { //TODO:: пересмотреть данный метод m_oStyleStorage.SetPageData(oPage, mData, unLevel, bHardMode); } + std::map CCssCalculator_Private::GetPageData(const std::wstring &wsPageName) + { + return m_oStyleStorage.GetPageData(wsPageName); + } + + void CCssCalculator_Private::ClearPageData() + { + m_oStyleStorage.ClearPageData(); + } + #endif + std::vector CCssCalculator_Private::CalculateAllNodes(const std::vector &arSelectors) { std::vector arNodes; @@ -617,6 +630,7 @@ namespace NSCSS return arFindedElements; } + #ifdef CSS_CALCULATOR_WITH_XHTML CCompiledStyle CCssCalculator_Private::GetCompiledStyle(const std::vector& arSelectors) { if (arSelectors.empty()) @@ -752,11 +766,6 @@ namespace NSCSS return m_nDpi; } - void CCssCalculator_Private::ClearPageData() - { - m_oStyleStorage.ClearPageData(); - } - void CCssCalculator_Private::ClearEmbeddedStyles() { m_oStyleStorage.ClearEmbeddedStyles(); @@ -792,6 +801,13 @@ namespace NSCSS m_mUsedStyles.clear(); #endif } + + bool IsTableElement(const std::wstring& wsNameTag) + { + return L"td" == wsNameTag || L"tr" == wsNameTag || L"table" == wsNameTag || + L"tbody" == wsNameTag || L"thead" == wsNameTag || L"tfoot" == wsNameTag || + L"th" == wsNameTag; + } } inline static std::wstring StringifyValueList(const KatanaArray* oValues) @@ -894,11 +910,4 @@ inline static std::wstring StringifyValue(const KatanaValue* oValue) return str; } -inline static bool IsTableElement(const std::wstring& wsNameTag) -{ - return L"td" == wsNameTag || L"tr" == wsNameTag || L"table" == wsNameTag || - L"tbody" == wsNameTag || L"thead" == wsNameTag || L"tfoot" == wsNameTag || - L"th" == wsNameTag; -} - diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.h b/Common/3dParty/html/css/src/CCssCalculator_Private.h index 55067586db..617812e067 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.h +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.h @@ -3,11 +3,9 @@ #include #include -#include -#include +#include #include "CElement.h" -#include "ConstValues.h" -#include "CUnitMeasureConverter.h" +#include "StyleProperties.h" #include "../../katana-parser/src/katana.h" #ifdef CSS_CALCULATOR_WITH_XHTML @@ -27,16 +25,17 @@ namespace NSCSS void AddStyles(const std::string& sStyle); void AddStyles(const std::wstring& wsStyle); void AddStylesFromFile(const std::wstring& wsFileName); - void AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles); - void ClearPageData(); void ClearEmbeddedStyles(); void ClearAllowedStyleFiles(); void ClearStylesFromFile(const std::wstring& wsFileName); + #ifdef CSS_CALCULATOR_WITH_XHTML + void AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles); void SetPageData(NSProperties::CPage& oPage, const std::map& mData, unsigned int unLevel, bool bHardMode = false); - std::map GetPageData(const std::wstring& wsPageName); + void ClearPageData(); + #endif const CElement* FindElement(const std::wstring& wsSelector); private: @@ -51,6 +50,7 @@ namespace NSCSS std::vector m_arStyleFiles; std::map m_mEmbeddedStyleData; + #ifdef CSS_CALCULATOR_WITH_XHTML typedef struct { std::vector m_wsNames; @@ -58,6 +58,7 @@ namespace NSCSS } TPageData; std::vector m_arPageDatas; + #endif private: void AddStyles(const std::string& sStyle, std::map& mStyleData); @@ -88,18 +89,14 @@ namespace NSCSS #ifdef CSS_CALCULATOR_WITH_XHTML std::map, CCompiledStyle> m_mUsedStyles; - - std::map GetPageData(const std::wstring& wsPageName); + void SetPageData(NSProperties::CPage& oPage, const std::map& mData, unsigned int unLevel, bool bHardMode = false); - - std::vector CalculateAllNodes(const std::vector& arSelectors); - - void FindPrevAndKindElements(const CElement* pElement, const std::vector& arNextNodes, std::vector& arFindedElements, const std::wstring& wsName, const std::vector& arClasses = {}); - std::vector FindElements(std::vector& arNodes, std::vector& arNextNodes); + std::map GetPageData(const std::wstring &wsPageName); #endif - std::wstring m_sEncoding; + void FindPrevAndKindElements(const CElement* pElement, const std::vector& arNextNodes, std::vector& arFindedElements, const std::wstring& wsName, const std::vector& arClasses = {}); + std::wstring m_sEncoding; public: CCssCalculator_Private(); ~CCssCalculator_Private(); @@ -110,8 +107,13 @@ namespace NSCSS std::wstring CalculateStyleId(const CNode& oNode); bool CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector &arSelectors); + + void ClearPageData(); #endif + std::vector CalculateAllNodes(const std::vector& arSelectors); + std::vector FindElements(std::vector& arNodes, std::vector& arNextNodes); + void AddStyles(const std::string& sStyle); void AddStyles(const std::wstring& wsStyle); void AddStylesFromFile(const std::wstring& wsFileName); @@ -121,12 +123,12 @@ namespace NSCSS std::wstring GetEncoding() const; unsigned short int GetDpi() const; - void ClearPageData(); void ClearEmbeddedStyles(); void ClearAllowedStyleFiles(); void ClearStylesFromFile(const std::wstring& wsFilePath); void Clear(); - }; + + inline bool IsTableElement(const std::wstring& wsNameTag); } #endif // CCSSCALCULATOR_PRIVATE_H diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp index a99dffa81d..98c64d9d55 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp @@ -29,139 +29,22 @@ namespace SVG if (NULL == pSvgObject) return; - const std::map *pData = m_pInternal->GetData(); const std::vector arSelectors = pSvgObject->GetFullPath(); - if ((NULL == pData || pData->empty()) && arSelectors.empty()) - return; - - std::vector arWords; - arWords.reserve(arSelectors.size() * 2); - - std::vector arNextNodes; - arNextNodes.reserve(arSelectors.size() * 2); - - for (std::vector::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode) - { - arWords.push_back(oNode->m_wsName); - - if (!oNode->m_wsClass.empty()) - { - if (oNode->m_wsClass.find(L' ') != std::wstring::npos) - { - std::vector arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" "); - - if (arClasses.size() > 1) - arClasses.resize(unique(arClasses.begin(),arClasses.end()) - arClasses.begin()); - - arWords.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(), - [](std::wstring sRes, const std::wstring& sClass) - {return sRes += L'.' + sClass + L' ';})); - } - else - arWords.push_back(L'.' + oNode->m_wsClass); - } - if (!oNode->m_wsId.empty()) - arWords.push_back(L'#' + oNode->m_wsId); - } - - std::vector arElements; + std::vector arNodes = m_pInternal->CalculateAllNodes(arSelectors); + std::vector arPrevNodes; for (size_t i = 0; i < arSelectors.size(); ++i) { - std::wstring sName, sId; - std::vector arClasses; - - if (arWords.back()[0] == L'#') - { - sId = arWords.back(); - arWords.pop_back(); - arNextNodes.push_back(sId); - } - - if (arWords.back()[0] == L'.') - { - arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), false, L" "); - arNextNodes.push_back(arWords.back()); - arWords.pop_back(); - } - - sName = arWords.back(); - arWords.pop_back(); - arNextNodes.push_back(sName); - - const std::map::const_iterator oFindName = pData->find(sName); - std::map::const_iterator oFindId; - std::vector arFindElements; - - if (!sId.empty()) - { - oFindId = pData->find(sId); - - if (oFindId != std::end(*pData)) - { - if (!oFindId->second->Empty()) - arFindElements.push_back(oFindId->second); - - const std::vector arTempPrev = oFindId->second->GetPrevElements(arNextNodes.rbegin() + ((arClasses.empty()) ? 1 : 2), arNextNodes.rend()); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - } - } - - if (!arClasses.empty()) - { - for (std::vector::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass) - { - const std::map::const_iterator oFindClass = pData->find(*iClass); - if (oFindClass != std::end(*pData)) - { - if (!oFindClass->second->Empty()) - arFindElements.push_back(oFindClass->second); - - const std::vector arTempPrev = oFindClass->second->GetPrevElements(arNextNodes.rbegin() + 2, arNextNodes.rend()); - const std::vector arTempKins = oFindClass->second->GetNextOfKin(sName); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - - if (!arTempKins.empty()) - arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); - } - } - } - - if (oFindName != std::end(*pData)) - { - if (!oFindName->second->Empty()) - arFindElements.push_back(oFindName->second); - - const std::vector arTempPrev = oFindName->second->GetPrevElements(arNextNodes.rbegin() + 1, arNextNodes.rend()); - const std::vector arTempKins = oFindName->second->GetNextOfKin(sName, arClasses); - - if (!arTempPrev.empty()) - arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end()); - - if (!arTempKins.empty()) - arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end()); - } - - - if (arFindElements.size() > 1) - { - std::sort(arFindElements.rbegin(), arFindElements.rend(), - [](NSCSS::CElement* oFirstElement, NSCSS::CElement* oSecondElement) - { - return oFirstElement->GetWeight() > oSecondElement->GetWeight(); - }); - } - pSvgObject->SetData(arSelectors[i].m_mAttributes, i + 1); - pSvgObject->SetData(arSelectors[i].m_wsStyle, i + 1, true); - for (const NSCSS::CElement* oElement : arFindElements) + for (const NSCSS::CElement* oElement : m_pInternal->FindElements(arNodes, arPrevNodes)) pSvgObject->SetData(oElement->GetStyle(), i + 1); + + if (!arSelectors[i].m_wsStyle.empty()) + pSvgObject->SetData(arSelectors[i].m_wsStyle, i + 1, true); } + + return; } } From 8bd655dd17e220da14a0955c3adc712052a5f4f6 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Mon, 20 Jan 2025 21:22:45 +0300 Subject: [PATCH 50/51] fix bug #72611 --- .../Common/SummaryInformation/PropertySetStream.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MsBinaryFile/Common/SummaryInformation/PropertySetStream.cpp b/MsBinaryFile/Common/SummaryInformation/PropertySetStream.cpp index f03c893830..dca3d412ab 100644 --- a/MsBinaryFile/Common/SummaryInformation/PropertySetStream.cpp +++ b/MsBinaryFile/Common/SummaryInformation/PropertySetStream.cpp @@ -64,6 +64,15 @@ namespace OLEPS *stream >> NumPropertySets; + if (SystemIdentifier == NumPropertySets) + {//oops + _GUID_ Clsid2 = {}; + _UINT32 reserved1 = 0, reserved2 = 0; + + *stream >> Clsid2 >> reserved1 >> reserved2; // ??? ReportBuilder + *stream >> NumPropertySets; + } + if (NumPropertySets != 0x01 && NumPropertySets != 0x02) { NumPropertySets = 0x01; From 8a8a6e78eb307855f8b42e7628d1bee7cef86e74 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Mon, 20 Jan 2025 21:49:25 +0300 Subject: [PATCH 51/51] fix bug #72578 --- OdfFile/Reader/Converter/oox_package.cpp | 33 ++++++++++++++---------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/OdfFile/Reader/Converter/oox_package.cpp b/OdfFile/Reader/Converter/oox_package.cpp index bae9856174..daa36fa87d 100644 --- a/OdfFile/Reader/Converter/oox_package.cpp +++ b/OdfFile/Reader/Converter/oox_package.cpp @@ -135,6 +135,8 @@ content_type * content_types_file::content() bool content_types_file::add_or_find_default(const std::wstring & extension) { + if (extension.empty()) return true; + std::vector & defaults = content_type_content_.get_default(); for (size_t i = 0 ; i < defaults.size(); i++) @@ -433,6 +435,10 @@ void embeddings::write(const std::wstring & RootPath) for (size_t i = 0; i < items.size(); i++ ) { + if (items[i].type == typeUnknown) continue; + if (items[i].type == typeShape) continue; + if (items[i].type == typeGroupShape) continue; + int pos = items[i].outputName.rfind(L"."); std::wstring extension = pos >= 0 ? items[i].outputName.substr(pos + 1) : L""; @@ -448,12 +454,10 @@ void embeddings::write(const std::wstring & RootPath) else if (items[i].type == typePDF) { std::string name = "Acrobat Document"; - std::string class_name = "Acrobat Document"; - std::string class_name2 = "Acrobat.Document.DC"; + std::string class_name = "Acrobat.Document.DC"; - _UINT32 name_size = (_UINT32)name.length() + 1; + _UINT32 name_size = name.size() + 1; _UINT32 class_name_size = class_name.size() + 1; - _UINT32 class_name2_size = class_name2.size() + 1; DWORD nativeDataSize = 0; BYTE* nativeData = NULL; @@ -473,14 +477,14 @@ void embeddings::write(const std::wstring & RootPath) long long posStreamCompObj = 0; oStreamCompObj->Write((char*)dataCompObjHeader, 0, 28); posStreamCompObj += 28; - oStreamCompObj->Write((char*)&class_name_size, posStreamCompObj, 4); posStreamCompObj += 4; - oStreamCompObj->Write((char*)class_name.c_str(), posStreamCompObj, class_name_size); posStreamCompObj += class_name_size; + oStreamCompObj->Write((char*)&name_size, posStreamCompObj, 4); posStreamCompObj += 4; + oStreamCompObj->Write((char*)name.c_str(), posStreamCompObj, name_size); posStreamCompObj += name_size; tmp = 0; oStreamCompObj->Write((char*)&tmp, posStreamCompObj, 4); posStreamCompObj += 4; - oStreamCompObj->Write((char*)&class_name2_size, posStreamCompObj, 4); posStreamCompObj += 4; - oStreamCompObj->Write((char*)class_name2.c_str(), posStreamCompObj, class_name2_size); posStreamCompObj += class_name2_size; + oStreamCompObj->Write((char*)&class_name_size, posStreamCompObj, 4); posStreamCompObj += 4; + oStreamCompObj->Write((char*)class_name.c_str(), posStreamCompObj, class_name_size); posStreamCompObj += class_name_size; tmp = 0x71B239F4; oStreamCompObj->Write((char*)&tmp, posStreamCompObj, 4); posStreamCompObj += 4;// UnicodeMarker @@ -496,18 +500,19 @@ void embeddings::write(const std::wstring & RootPath) std::shared_ptr oStreamOle = storageOut->RootStorage()->AddStream(L"\001Ole"); oStreamOle->Write((char*)dataOleInfo, 0, 20); + //ObjInfo + std::shared_ptr oStreamObjInfo = storageOut->RootStorage()->AddStream(L"\003ObjInfo"); + + BYTE dataObjInfo[] = { 0x00, 0x00, 0x03, 0x00, 0x01, 0x00 }; + oStreamObjInfo->Write((char*)dataObjInfo, 0, 6); + //CONTENTS std::shared_ptr oStreamCONTENTS = storageOut->RootStorage()->AddStream(L"CONTENTS"); oStreamCONTENTS->Write((char*)nativeData, 0, nativeDataSize); - //ObjInfo - std::shared_ptr oStreamObjInfo = storageOut->RootStorage()->AddStream(L"\003ObjInfo"); - - BYTE dataObjInfo[] = { 0x00, 0x00, 0x03, 0x00, 0x0D, 0x00 }; - oStreamObjInfo->Write((char*)dataObjInfo, 0, 6); - bool result = storageOut->Save(file_name_out); storageOut->Close(); + } if (storageOut) delete storageOut;