fix/bug79610

fix bug #79610
This commit is contained in:
Timofey Derevyankin
2026-02-13 22:34:41 +03:00
parent f7555af6b3
commit ab1dd7a48b
5 changed files with 283 additions and 8 deletions

View File

@ -2808,5 +2808,45 @@ void docx_conversion_context::add_jsaProject(const std::string &content)
output_document_->get_content_types_file().add_or_find_default(L"bin");
}
const std::wstring docx_conversion_context::get_current_fontName()
{
auto textProps = current_text_properties();
if( textProps )
{
if( textProps->content_.fo_font_family_ )
{
return *textProps->content_.fo_font_family_;
}
else if( textProps->content_.style_font_name_ )
{
return *textProps->content_.style_font_name_;
}
}
return L"";
}
const double docx_conversion_context::get_current_fontSize_from_default_style()
{
auto defaultStyle = root()->odf_context().styleContainer().style_default_by_type(odf_types::style_family::Paragraph);
if( defaultStyle )
{
const auto content = defaultStyle->content();
if( content )
{
const auto textProps = content->get_style_text_properties();
if( textProps && textProps->content_.fo_font_size_ )
{
return textProps->content_.fo_font_size_->get_length().get_value_unit(odf_types::length::pt);
}
}
}
return 0.0;
}
}
}

View File

@ -1024,6 +1024,10 @@ public:
int get_scale() const;
const std::wstring get_current_fontName();
const double get_current_fontSize_from_default_style();
private:
std::wstring temp_name;

View File

@ -33,6 +33,8 @@
#include "docx_drawing.h"
#include <xml/simple_xml_writer.h>
#include "../../DataTypes/custom_shape_types_convert.h"
#include <xml/utils.h>
#include "measuredigits.h"
namespace cpdoccore {
@ -54,6 +56,20 @@ void serialize_wrap_top_bottom(std::wostream & strm, _docx_drawing const & val)
}
}
static double convert_symbol_size(double val, double metrix, bool add_padding)
{
val = ((int)((val * metrix + 5) / metrix * 256)) / 256.;
double pixels = (int)(((256. * val + ((int)(128. / metrix))) / 256.) * metrix); //in pixels
return pixels * 0.75; //* 9525. * 72.0 / (360000.0 * 2.54);
}
int get_value_emu(double pt)
{
return static_cast<int>((pt* 360000 * 2.54) / 72);
}
void serialize_wrap_square(std::wostream & strm, _docx_drawing const & val)
{
std::wstring wrapText;
@ -499,7 +515,7 @@ void docx_serialize_child(std::wostream & strm, _docx_drawing & val)
}
}
void docx_serialize_wps(std::wostream & strm, _docx_drawing & val)
void docx_serialize_wps(std::wostream & strm, _docx_drawing & val, oox::docx_conversion_context & Context)
{
CP_XML_WRITER(strm)
{
@ -591,7 +607,7 @@ void docx_serialize_wps(std::wostream & strm, _docx_drawing & val)
}
}
}
if (val.cx > 0 || val.cy > 0)
if (val.cx > 0 && val.cy > 0)
{
CP_XML_NODE(L"wp:extent")
{
@ -599,6 +615,52 @@ void docx_serialize_wps(std::wostream & strm, _docx_drawing & val)
CP_XML_ATTR(L"cy", val.cy);
}
}
else
{
double fontSize = 0.0;
std::wstring fontName = Context.get_current_fontName();
if( Context.get_current_fontSize() > 0 )
{
fontSize = Context.get_current_fontSize();
}
else if( Context.get_drop_cap_context().FontSize > 0 )
{
fontSize = Context.get_drop_cap_context().FontSize;
}
else
{
fontSize = Context.get_current_fontSize_from_default_style();
}
if( fontName.empty() )
{
fontName = L"Times New Roman";
}
if( fontSize <= 0 )
{
fontSize = 12.0; // default
}
std::pair<double, double> maxDigitSize_ = utils::GetMaxDigitSizePixels(fontName, fontSize, 96., 0, Context.get_mediaitems()->applicationFonts());
double cx = get_value_emu(convert_symbol_size(1.76 * Context.get_math_context().width, maxDigitSize_.first, false));
double cy = get_value_emu(convert_symbol_size(1.76 * Context.get_math_context().height, maxDigitSize_.second, false));
if (cx > val.cx)
val.cx = cx;
if (cy > val.cy)
val.cy = cy;
CP_XML_NODE(L"wp:extent")
{
CP_XML_ATTR(L"cx", val.cx);
CP_XML_ATTR(L"cy", val.cy);
}
}
serialize_wrap(CP_XML_STREAM(), val);
}
@ -642,6 +704,149 @@ void docx_serialize_wps(std::wostream & strm, _docx_drawing & val)
}
}
void docx_serialize_wps(std::wostream & strm, _docx_drawing & val)
{
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"w:drawing")
{
std::wstring strWp = L"wp:anchor";
if (val.isInline)strWp = L"wp:inline";
CP_XML_NODE(strWp)
{
if (val.isInline)
{
CP_XML_NODE(L"wp:extent")
{
if (val.cx > 0 && val.cy > 0)
{
CP_XML_ATTR(L"cx", val.cx);
CP_XML_ATTR(L"cy", val.cy);
}
else
{
CP_XML_ATTR(L"cx", 180000);
CP_XML_ATTR(L"cy", 180000);
}
}
serialize_null_extent(CP_XML_STREAM());
}
else//anchor
{
CP_XML_ATTR(L"simplePos", 0);
CP_XML_ATTR(L"locked", 0);
CP_XML_ATTR(L"layoutInCell", 1);
CP_XML_ATTR(L"allowOverlap", 1);
CP_XML_ATTR(L"relativeHeight" ,val.relativeHeight);
CP_XML_ATTR(L"behindDoc" , val.behindDoc);
CP_XML_ATTR(L"distL", val.margin_rect[0]);
CP_XML_ATTR(L"distT", val.margin_rect[1]);
CP_XML_ATTR(L"distR", val.margin_rect[2]);
CP_XML_ATTR(L"distB", val.margin_rect[3]);
CP_XML_NODE(L"wp:simplePos")
{
CP_XML_ATTR(L"x",0);
CP_XML_ATTR(L"y",0);
}
CP_XML_NODE(L"wp:positionH")
{
std::wstring relativeFrom = L"margin";
if (val.styleHorizontalRel) relativeFrom =val.styleHorizontalRel->get_type_str();
CP_XML_ATTR(L"relativeFrom", relativeFrom);
if (val.styleHorizontalPos &&
val.styleHorizontalPos->get_type() != odf_types::horizontal_pos::FromLeft &&
val.styleHorizontalPos->get_type() != odf_types::horizontal_pos::Outside)
{
CP_XML_NODE(L"wp:align") {CP_XML_STREAM() << (*val.styleHorizontalPos);}
}
else
{
CP_XML_NODE(L"wp:posOffset") {CP_XML_STREAM() << val.posOffsetH;}
}
}
CP_XML_NODE(L"wp:positionV")
{
std::wstring relativeFrom = L"margin";
if (val.styleVerticalRel)relativeFrom = val.styleVerticalRel->get_type_str();
CP_XML_ATTR(L"relativeFrom", relativeFrom);
if (val.styleVerticalPos &&
val.styleVerticalPos->get_type() != odf_types::vertical_pos::FromTop &&
val.styleVerticalPos->get_type() != odf_types::vertical_pos::Below)
{
CP_XML_NODE(L"wp:align")
{
CP_XML_STREAM() << val.styleVerticalPos->get_type_str();
}
}
else
{
CP_XML_NODE(L"wp:posOffset")
{
CP_XML_STREAM() << val.posOffsetV;
}
}
}
if (val.cx > 0 && val.cy > 0)
{
CP_XML_NODE(L"wp:extent")
{
CP_XML_ATTR(L"cx", val.cx);
CP_XML_ATTR(L"cy", val.cy);
}
}
serialize_wrap(CP_XML_STREAM(), val);
}
docx_serialize_common(CP_XML_STREAM(), val);
if (val.pctWidth)
{
std::wstring relativeFrom = L"margin";
if (val.styleHorizontalRel) relativeFrom =val.styleHorizontalRel->get_type_str();
if (relativeFrom == L"column") relativeFrom = L"margin";
CP_XML_NODE(L"wp14:sizeRelH")
{
CP_XML_ATTR(L"relativeFrom", relativeFrom);
CP_XML_NODE(L"wp14:pctWidth")
{
CP_XML_STREAM() << (val.pctWidth.get() * 1000);
}
}
}
if (val.pctHeight)
{
std::wstring relativeFrom = L"paragraph";
if (val.styleVerticalRel)relativeFrom = val.styleVerticalRel->get_type_str();
if (relativeFrom == L"paragraph") relativeFrom = L"margin";
CP_XML_NODE(L"wp14:sizeRelV")
{
CP_XML_ATTR(L"relativeFrom", relativeFrom);
CP_XML_NODE(L"wp14:pctHeight")
{
CP_XML_STREAM() << (val.pctHeight.get() * 1000);
}
}
}
}
}
}
}
void docx_serialize_vml(std::wostream & strm, _docx_drawing & val)
{
CP_XML_WRITER(strm)
@ -768,7 +973,7 @@ void docx_serialize_control(std::wostream & strm, _docx_drawing & val)
}
}
void _docx_drawing::serialize(std::wostream & strm/*, bool insideOtherDrawing*/)
void _docx_drawing::serialize(std::wostream & strm/*, bool insideOtherDrawing*/, oox::docx_conversion_context & Context)
{
if (type == typeUnknown) return;
@ -788,7 +993,34 @@ void _docx_drawing::serialize(std::wostream & strm/*, bool insideOtherDrawing*/)
else
{
//if (insideOtherDrawing)
docx_serialize_wps(strm, *this);
docx_serialize_wps(strm, *this, Context);
//else
// docx_serialize_alt_content(strm, val);
}
}
void _docx_drawing::serialize(std::wostream & strm/*, bool insideOtherDrawing*/)
{
if (type == typeUnknown) return;
if (inGroup)
return docx_serialize_child(strm, *this);
if (type == typeMsObject ||
type == typeOleObject ||
type == typePDF)
{
docx_serialize_object(strm, *this);
}
else if (type == typeControl)
{
docx_serialize_control(strm, *this);
}
else
{
//if (insideOtherDrawing)
docx_serialize_wps(strm, *this);
//else
// docx_serialize_alt_content(strm, val);
}

View File

@ -79,7 +79,8 @@ public:
std::wstring content_group_;
void serialize_text (std::wostream & strm);
void serialize (std::wostream & strm/*, bool insideOtherDrawing*/);
void serialize (std::wostream & strm/*, bool insideOtherDrawing*/, oox::docx_conversion_context & Context);
void serialize (std::wostream & strm/*, bool insideOtherDrawing*/);
};
}
}

View File

@ -1663,9 +1663,7 @@ void draw_frame::docx_convert(oox::docx_conversion_context & Context)
}
Context.add_new_run(L"");
}
drawing->serialize(Context.output_stream()/*, Context.get_drawing_state_content()*/);
drawing->serialize(Context.output_stream()/*, Context.get_drawing_state_content()*/, Context);
if (!Context.get_drawing_context().in_group() && !runState)
{
Context.finish_run();