From 2d758b155d9bd76b2abc8fca4cdc5dcb2f462ce7 Mon Sep 17 00:00:00 2001 From: Elena Subbotina Date: Tue, 3 Jun 2025 14:20:09 +0300 Subject: [PATCH] fix bug #74747 --- .../Reader/Converter/oox_drawing_fills.cpp | 15 ++++--- OdfFile/Reader/Converter/oox_drawing_fills.h | 12 +++++- .../Reader/Converter/pptx_slide_context.cpp | 37 +++++++++++++++-- .../Reader/Converter/xlsx_drawing_context.cpp | 15 ++++++- OdfFile/Reader/Format/draw_common.cpp | 41 ++++++++++--------- OdfFile/Reader/Format/draw_common.h | 4 +- OdfFile/Reader/Format/draw_frame_docx.cpp | 24 +++++++---- 7 files changed, 106 insertions(+), 42 deletions(-) diff --git a/OdfFile/Reader/Converter/oox_drawing_fills.cpp b/OdfFile/Reader/Converter/oox_drawing_fills.cpp index 18701ae8b9..0b6b037e70 100644 --- a/OdfFile/Reader/Converter/oox_drawing_fills.cpp +++ b/OdfFile/Reader/Converter/oox_drawing_fills.cpp @@ -163,10 +163,9 @@ void oox_serialize_bitmap_fill(std::wostream & strm, const _oox_fill & val, cons CP_XML_WRITER(strm) { - CP_XML_NODE(std::wstring(val.bitmap->name_space + L":blipFill")) + CP_XML_NODE(val.bitmap->name_space + L":blipFill") { - //if (val.bitmap->rotate) CP_XML_ATTR(ns + L":rotWithShape",*(val.bitmap->rotate)); - //else CP_XML_ATTR(ns + L":rotWithShape",1); + CP_XML_ATTR2(ns_att + L"rotWithShape", false); if (val.bitmap->dpi) { @@ -241,10 +240,16 @@ void oox_serialize_bitmap_fill(std::wostream & strm, const _oox_fill & val, cons } if (val.bitmap->bTile) { + if (!val.bitmap->bCrop) + { + CP_XML_NODE(ns + L":srcRect"); + } CP_XML_NODE(ns + L":tile") { - //tx="0" ty="0" sx="100000" sy="100000" - CP_XML_ATTR2(ns_att + L"flip", "none"); + CP_XML_ATTR2(ns_att + L"tx", 0); + CP_XML_ATTR2(ns_att + L"ty", 0); + CP_XML_ATTR2(ns_att + L"sx", (int)(val.bitmap->sx.get_value_or(100) * 1000)); + CP_XML_ATTR2(ns_att + L"sy", (int)(val.bitmap->sy.get_value_or(100) * 1000)); CP_XML_ATTR2(ns_att + L"algn", L"ctr"); } } diff --git a/OdfFile/Reader/Converter/oox_drawing_fills.h b/OdfFile/Reader/Converter/oox_drawing_fills.h index bd6ee4e1dd..f9268cc638 100644 --- a/OdfFile/Reader/Converter/oox_drawing_fills.h +++ b/OdfFile/Reader/Converter/oox_drawing_fills.h @@ -66,9 +66,17 @@ namespace oox { bool bStretch; bool bCrop; bool bTile; - - double cropRect[4];//0-left, 1 -top, 2- right, 3 - bottom + _CP_OPT(double) sx; + _CP_OPT(double) sy; + _CP_OPT(double) sx_pt; + _CP_OPT(double) sy_pt; + + double cropRect[4]; //0-left, 1 -top, 2- right, 3 - bottom + + _CP_OPT(int) width; + _CP_OPT(int) height; + _CP_OPT(int) dpi; _CP_OPT(bool) rotate; diff --git a/OdfFile/Reader/Converter/pptx_slide_context.cpp b/OdfFile/Reader/Converter/pptx_slide_context.cpp index 5ff30d2630..3f4c5c4f8c 100644 --- a/OdfFile/Reader/Converter/pptx_slide_context.cpp +++ b/OdfFile/Reader/Converter/pptx_slide_context.cpp @@ -474,7 +474,21 @@ void pptx_slide_context::add_background(_oox_fill & fill) fill.bitmap->rId = get_mediaitems()->add_or_find(fill.bitmap->xlink_href_, typeImage, isMediaInternal, ref, oox::document_place); add_rels(isMediaInternal, fill.bitmap->rId, ref, typeImage); - } + + std::wstring fileName = impl_->odfPacket_ + FILE_SEPARATOR_STR + fill.bitmap->xlink_href_; + _image_file_::GetResolution(fileName.c_str(), fill.bitmap->width, fill.bitmap->height, get_mediaitems()->applicationFonts()); + + if (fill.bitmap->width && fill.bitmap->height) + { + //fill.bitmap->bCrop = odf_reader::parse_clipping(clipping_string_, *fill.bitmap->width, *fill.bitmap->height, fill.bitmap->cropRect); + + if (fill.bitmap->sx_pt && fill.bitmap->sy_pt) + { + fill.bitmap->sx = (*fill.bitmap->sx_pt * 100. / *fill.bitmap->width) * 4 / 3; + fill.bitmap->sy = (*fill.bitmap->sy_pt * 100. / *fill.bitmap->height) * 4 / 3; + } + } + } impl_->background_fill_ = fill; } @@ -897,9 +911,24 @@ void pptx_slide_context::Impl::process_common_properties(drawing_object_descript } void pptx_slide_context::Impl::process_crop(const drawing_object_description& obj, _pptx_drawing& drawing, const std::wstring& filename) -{ - drawing.fill.bitmap->bCrop = odf_reader::parse_clipping(obj.clipping_string_, filename, drawing.fill.bitmap->cropRect, get_mediaitems()->applicationFonts()); - drawing.fill.bitmap->bStretch = true; +{ + if (!drawing.fill.bitmap) return; + + _image_file_::GetResolution(filename.c_str(), drawing.fill.bitmap->width, drawing.fill.bitmap->height, get_mediaitems()->applicationFonts()); + + if (drawing.fill.bitmap->width && drawing.fill.bitmap->height) + { + drawing.fill.bitmap->bCrop = odf_reader::parse_clipping(obj.clipping_string_, *drawing.fill.bitmap->width, *drawing.fill.bitmap->height, drawing.fill.bitmap->cropRect); + + if (drawing.fill.bitmap->sx_pt && drawing.fill.bitmap->sy_pt) + { + drawing.fill.bitmap->sx = (*drawing.fill.bitmap->sx_pt * 100. / *drawing.fill.bitmap->width) * 4 / 3; + drawing.fill.bitmap->sy = (*drawing.fill.bitmap->sy_pt * 100. / *drawing.fill.bitmap->height) * 4 / 3; + } + } + + if (!drawing.fill.bitmap->bTile) + drawing.fill.bitmap->bStretch = true; } void pptx_slide_context::dump_rels(rels & Rels) diff --git a/OdfFile/Reader/Converter/xlsx_drawing_context.cpp b/OdfFile/Reader/Converter/xlsx_drawing_context.cpp index 6d4f781849..65be591cd8 100644 --- a/OdfFile/Reader/Converter/xlsx_drawing_context.cpp +++ b/OdfFile/Reader/Converter/xlsx_drawing_context.cpp @@ -666,8 +666,19 @@ void xlsx_drawing_context::process_image(drawing_object_description & obj, _xlsx } std::wstring fileName = odf_packet_path_ + FILE_SEPARATOR_STR + obj.xlink_href_; - drawing.fill.bitmap->bCrop = odf_reader::parse_clipping(obj.clipping_string_, fileName, drawing.fill.bitmap->cropRect, impl_->get_mediaitems()->applicationFonts()); - drawing.fill.bitmap->bStretch = true; + _image_file_::GetResolution(fileName.c_str(), drawing.fill.bitmap->width, drawing.fill.bitmap->height, impl_->get_mediaitems()->applicationFonts()); + + if (drawing.fill.bitmap->width && drawing.fill.bitmap->height) + { + drawing.fill.bitmap->bCrop = odf_reader::parse_clipping(obj.clipping_string_, *drawing.fill.bitmap->width, *drawing.fill.bitmap->height, drawing.fill.bitmap->cropRect); + + if (drawing.fill.bitmap->sx_pt && drawing.fill.bitmap->sy_pt) + { + drawing.fill.bitmap->sx = (*drawing.fill.bitmap->sx_pt * 100. / *drawing.fill.bitmap->width) * 4 / 3; + drawing.fill.bitmap->sy = (*drawing.fill.bitmap->sy_pt * 100. / *drawing.fill.bitmap->height) * 4 / 3; + } + } + drawing.fill.bitmap->bStretch = true; std::wstring ref;/// это ссылка на выходной внешний объект bool isMediaInternal = false; diff --git a/OdfFile/Reader/Format/draw_common.cpp b/OdfFile/Reader/Format/draw_common.cpp index 44661eff30..aa57576858 100644 --- a/OdfFile/Reader/Format/draw_common.cpp +++ b/OdfFile/Reader/Format/draw_common.cpp @@ -55,7 +55,7 @@ namespace _image_file_ { - bool GetResolution(const wchar_t* fileName, int & Width, int &Height, NSFonts::IApplicationFonts* appFonts) + bool GetResolution(const wchar_t* fileName, _CP_OPT(int)& Width, _CP_OPT(int)&Height, NSFonts::IApplicationFonts* appFonts) { CBgraFrame image; MetaFile::IMetaFile* meta_file = MetaFile::Create(appFonts); @@ -120,11 +120,11 @@ int get_value_emu(double pt) { return static_cast((pt* 360000 * 2.54) / 72); } -bool parse_clipping(std::wstring strClipping,std::wstring fileName, double_4 & clip_rect, NSFonts::IApplicationFonts *appFonts) +bool parse_clipping(std::wstring strClipping, int fileWidth, int fileHeight, double_4& clip_rect) { memset(clip_rect, 0, 4*sizeof(double)); - if (strClipping.empty() || fileName.empty()) return false; + if (strClipping.empty()) return false; //, , , - http://www.w3.org/TR/2001/REC-xsl-20011015/xslspec.html#clip @@ -144,10 +144,6 @@ bool parse_clipping(std::wstring strClipping,std::wstring fileName, double_4 & c if (!bEnableCrop) return false; - int fileWidth = 0,fileHeight = 0; - - if (!_image_file_::GetResolution(fileName.data(), fileWidth, fileHeight, appFonts) || fileWidth < 1 || fileHeight < 1) return false; - if (Points_pt.size() > 3)//если другое количество точек .. попозже { float dpi_ = 96.; @@ -548,23 +544,28 @@ void Compute_GraphicFill(const common_draw_fill_attlist & props, const office_el break; } } - else + if (props.draw_fill_image_width_ && props.draw_fill_image_height_) { - if (props.draw_fill_image_width_ && props.draw_fill_image_height_) + if (props.draw_fill_image_width_->get_type() == odf_types::length_or_percent::Percent && + props.draw_fill_image_height_->get_type() == odf_types::length_or_percent::Percent) { - if (props.draw_fill_image_width_->get_type() == odf_types::length_or_percent::Percent && - props.draw_fill_image_height_->get_type() == odf_types::length_or_percent::Percent) + fill.bitmap->sx = props.draw_fill_image_width_->get_percent().get_value(); + fill.bitmap->sy = props.draw_fill_image_height_->get_percent().get_value(); + + if ( !props.style_repeat_ && props.draw_fill_image_width_->get_percent().get_value() > 99.9 && + props.draw_fill_image_height_->get_percent().get_value() > 99.9 && + props.draw_fill_image_width_->get_percent().get_value() < 100.1 && + props.draw_fill_image_height_->get_percent().get_value() < 100.1) { - if (props.draw_fill_image_width_->get_percent().get_value() > 99.9 && - props.draw_fill_image_height_->get_percent().get_value() > 99.9 && - props.draw_fill_image_width_->get_percent().get_value() < 100.1 && - props.draw_fill_image_height_->get_percent().get_value() < 100.1 ) - { - fill.bitmap->bStretch = true; - fill.bitmap->bTile = false; - } + fill.bitmap->bStretch = true; + fill.bitmap->bTile = false; } } + else + { + fill.bitmap->sx_pt = props.draw_fill_image_width_->get_length().get_value_unit(length::pt); + fill.bitmap->sy_pt = props.draw_fill_image_height_->get_length().get_value_unit(length::pt); + } } } if (props.draw_fill_gradient_name_) @@ -735,7 +736,7 @@ void docx_convert_transforms(std::wstring transformStr,std::vector1) y_pt = Points[1].get_value_unit(length::pt); //ее может не быть + if (Points.size() > 1) y_pt = Points[1].get_value_unit(length::pt); //ее может не быть //Context.get_drawing_context().set_translate(x_pt,y_pt); additional.push_back(_property(L"svg:translate_x", x_pt)); diff --git a/OdfFile/Reader/Format/draw_common.h b/OdfFile/Reader/Format/draw_common.h index a1d73409db..9e0d7d198a 100644 --- a/OdfFile/Reader/Format/draw_common.h +++ b/OdfFile/Reader/Format/draw_common.h @@ -49,7 +49,7 @@ namespace _image_file_ { - bool GetResolution(const wchar_t* fileName, int & Width, int &Height, NSFonts::IApplicationFonts *appFonts); + bool GetResolution(const wchar_t* fileName, _CP_OPT(int) &Width, _CP_OPT(int) &Height, NSFonts::IApplicationFonts *appFonts); void GenerateZeroImage(const std::wstring & fileName); } @@ -72,7 +72,7 @@ void Compute_GraphicFill(const odf_types::common_draw_fill_attlist & props, const office_element_ptr & style_image, odf_document *document, oox::_oox_fill & fill, bool txbx = false, bool reset_fill = true); typedef double double_4[4]; -bool parse_clipping(std::wstring strClipping, std::wstring fileName, double_4 & clip_rect, NSFonts::IApplicationFonts *appFonts); +bool parse_clipping(std::wstring strClipping, int width, int height, double_4 & clip_rect); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class draw_a : public office_element_impl { diff --git a/OdfFile/Reader/Format/draw_frame_docx.cpp b/OdfFile/Reader/Format/draw_frame_docx.cpp index 66b02b9150..b56ceaca8e 100644 --- a/OdfFile/Reader/Format/draw_frame_docx.cpp +++ b/OdfFile/Reader/Format/draw_frame_docx.cpp @@ -1289,14 +1289,24 @@ void draw_image::docx_convert(oox::docx_conversion_context & Context) //////////////// if (properties) { - if (properties->fo_clip_ && drawing->fill.bitmap) + std::wstring fileName = Context.root()->get_folder() + FILE_SEPARATOR_STR + xlink_attlist_.href_.get_value_or(L""); + _image_file_::GetResolution(fileName.c_str(), drawing->fill.bitmap->width, drawing->fill.bitmap->height, Context.get_mediaitems()->applicationFonts()); + + if (drawing->fill.bitmap->width && drawing->fill.bitmap->height) { - std::wstring strRectClip = properties->fo_clip_.get(); - strRectClip = strRectClip.substr(5, strRectClip.length() - 6); - - std::wstring fileName = Context.root()->get_folder() + FILE_SEPARATOR_STR + xlink_attlist_.href_.get_value_or(L""); - - drawing->fill.bitmap->bCrop = parse_clipping(strRectClip, fileName, drawing->fill.bitmap->cropRect, Context.get_mediaitems()->applicationFonts()); + if (properties->fo_clip_) + { + std::wstring strRectClip = properties->fo_clip_.get(); + strRectClip = strRectClip.substr(5, strRectClip.length() - 6); + + drawing->fill.bitmap->bCrop = odf_reader::parse_clipping(strRectClip, *drawing->fill.bitmap->width, *drawing->fill.bitmap->height, drawing->fill.bitmap->cropRect); + } + + if (drawing->fill.bitmap->sx_pt && drawing->fill.bitmap->sy_pt) + { + drawing->fill.bitmap->sx = (*drawing->fill.bitmap->sx_pt * 100. / *drawing->fill.bitmap->width) * 4 /3; + drawing->fill.bitmap->sy = (*drawing->fill.bitmap->sy_pt * 100. / *drawing->fill.bitmap->height) * 4 / 3; + } } if (properties->common_draw_fill_attlist_.draw_luminance_) {