diff --git a/OdfFile/Reader/Converter/docx_conversion_context.cpp b/OdfFile/Reader/Converter/docx_conversion_context.cpp index 31674f9f1c..92448ac0f9 100644 --- a/OdfFile/Reader/Converter/docx_conversion_context.cpp +++ b/OdfFile/Reader/Converter/docx_conversion_context.cpp @@ -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; +} + } } diff --git a/OdfFile/Reader/Converter/docx_conversion_context.h b/OdfFile/Reader/Converter/docx_conversion_context.h index 4d52ca81a7..59ec52d60d 100644 --- a/OdfFile/Reader/Converter/docx_conversion_context.h +++ b/OdfFile/Reader/Converter/docx_conversion_context.h @@ -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; diff --git a/OdfFile/Reader/Converter/docx_drawing.cpp b/OdfFile/Reader/Converter/docx_drawing.cpp index 4af369a977..26a5179628 100644 --- a/OdfFile/Reader/Converter/docx_drawing.cpp +++ b/OdfFile/Reader/Converter/docx_drawing.cpp @@ -33,6 +33,8 @@ #include "docx_drawing.h" #include #include "../../DataTypes/custom_shape_types_convert.h" +#include +#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((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 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); } diff --git a/OdfFile/Reader/Converter/docx_drawing.h b/OdfFile/Reader/Converter/docx_drawing.h index 09d13c5f09..159ff3b362 100644 --- a/OdfFile/Reader/Converter/docx_drawing.h +++ b/OdfFile/Reader/Converter/docx_drawing.h @@ -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*/); }; } } diff --git a/OdfFile/Reader/Format/draw_frame_docx.cpp b/OdfFile/Reader/Format/draw_frame_docx.cpp index b230b91cb5..5b942bab73 100644 --- a/OdfFile/Reader/Format/draw_frame_docx.cpp +++ b/OdfFile/Reader/Format/draw_frame_docx.cpp @@ -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();