diff --git a/ASCOfficeOdfFile/formulasconvert/formulasconvert_oox.cpp b/ASCOfficeOdfFile/formulasconvert/formulasconvert_oox.cpp index 8d4bad7863..875cf21235 100644 --- a/ASCOfficeOdfFile/formulasconvert/formulasconvert_oox.cpp +++ b/ASCOfficeOdfFile/formulasconvert/formulasconvert_oox.cpp @@ -465,6 +465,10 @@ std::wstring oox2odf_converter::Impl::convert_formula(const std::wstring & expr) boost::wregex(L"(?!([a-zA-Z]+\\d*\\())(([a-zA-Z]+\\!)?\\$?[a-zA-Z]*\\$?\\d*(\\:\\$?[a-zA-Z]*\\$?\\d*){0,1})"), &oox2odf_converter::Impl::replace_arguments, boost::match_default | boost::format_all); + //SUBTOTAL(109,Expense31[Amount]) + XmlUtils::replace_all( res, L"[", L"KVADRATIN"); + XmlUtils::replace_all( res, L"]", L"KVADRATOUT"); + if (res1 == res) { XmlUtils::replace_all( res1, L"KAVYCHKA", L"\""); //IMCONJUGATE_emb.xlsx diff --git a/ASCOfficeOdfFile/src/odf/draw_frame_docx.cpp b/ASCOfficeOdfFile/src/odf/draw_frame_docx.cpp index 0f439a440f..77a9a59b7d 100644 --- a/ASCOfficeOdfFile/src/odf/draw_frame_docx.cpp +++ b/ASCOfficeOdfFile/src/odf/draw_frame_docx.cpp @@ -838,12 +838,20 @@ void common_draw_docx_convert(oox::docx_conversion_context & Context, union_comm } if (!drawing->isInline) { + drawing->relativeHeight = L"2"; + drawing->behindDoc = L"0"; + + if (((drawing->styleWrap && drawing->styleWrap->get_type() == style_wrap::RunThrough) || + !drawing->styleWrap) && styleRunThrough && styleRunThrough->get_type() == run_through::Background) + { + drawing->behindDoc = L"1"; + if (!drawing->styleWrap) + drawing->styleWrap = style_wrap(style_wrap::RunThrough); + + } if (!drawing->styleWrap) drawing->styleWrap = style_wrap(style_wrap::Parallel);//у опен офис и мс разные дефолты - drawing->relativeHeight = L"2"; - drawing->behindDoc = L"0"; - _CP_OPT(int) zIndex = attlists_.shape_with_text_and_styles_.common_shape_draw_attlist_.draw_z_index_; if (zIndex)//порядок отрисовки объектов @@ -853,13 +861,6 @@ void common_draw_docx_convert(oox::docx_conversion_context & Context, union_comm else drawing->relativeHeight = std::to_wstring( 2 + *zIndex ); } - - if (drawing->styleWrap && drawing->styleWrap->get_type() == style_wrap::RunThrough - && styleRunThrough && styleRunThrough->get_type() == run_through::Background) - { - drawing-> behindDoc = L"1"; - } - drawing->margin_rect[0] = GetMargin(graphicProperties, sideLeft); drawing->margin_rect[1] = GetMargin(graphicProperties, sideTop); drawing->margin_rect[2] = GetMargin(graphicProperties, sideRight); diff --git a/ASCOfficeOdfFile/src/odf/draw_shapes_docx.cpp b/ASCOfficeOdfFile/src/odf/draw_shapes_docx.cpp index e770b93d64..890d284ab8 100644 --- a/ASCOfficeOdfFile/src/odf/draw_shapes_docx.cpp +++ b/ASCOfficeOdfFile/src/odf/draw_shapes_docx.cpp @@ -103,6 +103,7 @@ void draw_shape::common_docx_convert(oox::docx_conversion_context & Context) { std::wstring href = fill.bitmap->xlink_href_; fill.bitmap->rId = Context.get_mediaitems().add_or_find(href, oox::typeImage, fill.bitmap->isInternal, href); + fill.bitmap->name_space = L"w14"; } std::wstringstream strm_fill, strm_ln; diff --git a/ASCOfficeOdfFileW/OdfFileWTest/OdfFileWTest.cpp b/ASCOfficeOdfFileW/OdfFileWTest/OdfFileWTest.cpp index 4a1e0d0ee3..7ac18dca03 100644 --- a/ASCOfficeOdfFileW/OdfFileWTest/OdfFileWTest.cpp +++ b/ASCOfficeOdfFileW/OdfFileWTest/OdfFileWTest.cpp @@ -96,7 +96,7 @@ HRESULT convert_single(std::wstring srcFileName) Oox2Odf::Converter converter(srcTempPath, type, L"C:\\Windows\\Fonts", NULL); - std::wstring sPassword = L"password"; + std::wstring sPassword;// = L"password"; converter.convert(); converter.write(dstTempPath, srcTempPath, sPassword, L"hiuh56f56tfy7g"); diff --git a/ASCOfficeOdfFileW/source/OdfFormat/odf_chart_context.cpp b/ASCOfficeOdfFileW/source/OdfFormat/odf_chart_context.cpp index 136b6621eb..31986b54d3 100644 --- a/ASCOfficeOdfFileW/source/OdfFormat/odf_chart_context.cpp +++ b/ASCOfficeOdfFileW/source/OdfFormat/odf_chart_context.cpp @@ -230,10 +230,11 @@ std::wstring odf_chart_context::Impl::convert_formula(std::wstring oox_formula) else { //open office dont support defined names in chart formula + // 7501214.xlsx - частичное заполнение local-table int col = -1, row = -1; utils::parsing_ref( refs[0], col, row); - if (col < 0 && row < 0) + if (col < 0 && row < 0 && (odf_context_->type != SpreadsheetDocument)) { local_table_enabled_ = true; //find defined name ???? @@ -1587,7 +1588,9 @@ void odf_chart_context::set_cash(std::wstring format, std::vector int col1 = -1, col2 = -1, row1 = -1, row2 = -1; - if (refs.size() < 1) return; + if (refs.size() < 1) return; + if (refs[0].empty()) return; + utils::parsing_ref( refs[0], col1, row1); if (refs.size() > 1) @@ -1694,7 +1697,7 @@ int odf_chart_context::Impl::create_local_table_rows(int curr_row, ods_table_sta add = false; - if (cells[i].row > curr_row + 1 && !header) + if (cells[i].row > curr_row + 1/* && !header*/) { office_element_ptr row_elm; diff --git a/ASCOfficeOdfFileW/source/OdfFormat/odf_drawing_context.cpp b/ASCOfficeOdfFileW/source/OdfFormat/odf_drawing_context.cpp index f2bdce2cb0..8c76a2f315 100644 --- a/ASCOfficeOdfFileW/source/OdfFormat/odf_drawing_context.cpp +++ b/ASCOfficeOdfFileW/source/OdfFormat/odf_drawing_context.cpp @@ -346,7 +346,7 @@ void odf_drawing_context::set_background_state(bool Val) void odf_drawing_context::check_anchor() { return; - if ((impl_->is_footer_ || impl_->is_header_ || impl_->is_background_) && (impl_->anchor_settings_.run_through_) && (impl_->anchor_settings_.run_through_->get_type() == run_through::Background)) + if ((/*impl_->is_footer_ || impl_->is_header_ ||*/ impl_->is_background_) && (impl_->anchor_settings_.run_through_) && (impl_->anchor_settings_.run_through_->get_type() == run_through::Background)) { set_anchor(anchor_type::Char); //подозрительно на подложку страницы @@ -1317,7 +1317,7 @@ void odf_drawing_context::set_no_fill() switch(impl_->current_drawing_part_) { case Area: - if ((impl_->is_footer_ || impl_->is_header_ || impl_->is_background_) && + if ((/*impl_->is_footer_ || impl_->is_header_ ||*/ impl_->is_background_) && (impl_->current_graphic_properties->common_draw_fill_attlist_.draw_fill_) && (impl_->current_graphic_properties->common_draw_fill_attlist_.draw_fill_->get_type() == draw_fill::bitmap)) { @@ -1367,7 +1367,7 @@ void odf_drawing_context::set_solid_fill(std::wstring hexColor) //impl_->current_graphic_properties->common_background_color_attlist_.fo_background_color_ = color(hexColor); - default transparent //последнее нужно - что если будут вводить текст - под текстом будет цвет фона (или он поменяется в полях текста) - if ((impl_->is_footer_ || impl_->is_header_ || impl_->is_background_) && + if ((/*impl_->is_footer_ || impl_->is_header_ ||*/ impl_->is_background_) && (impl_->current_graphic_properties->common_draw_fill_attlist_.draw_fill_) && (impl_->current_graphic_properties->common_draw_fill_attlist_.draw_fill_->get_type() == draw_fill::bitmap)) { @@ -2391,7 +2391,7 @@ void odf_drawing_context::set_textarea_padding(_CP_OPT(double) & left, _CP_OPT(d //------------------------------------------------------------------------------------------------------------------ void odf_drawing_context::start_image(std::wstring odf_path) { - if (impl_->is_footer_ || impl_->is_header_ || impl_->is_background_) + if (/*impl_->is_footer_ || impl_->is_header_ ||*/ impl_->is_background_)//AstraIntlCaseStudyFinal0.docx { start_shape(142/*SimpleTypes::shapetypeRect*/); start_bitmap_style(); @@ -2514,7 +2514,10 @@ void odf_drawing_context::set_text_box_min_size(bool val) if (impl_->current_graphic_properties) { impl_->current_graphic_properties->draw_auto_grow_height_ = true; - impl_->current_graphic_properties->draw_auto_grow_width_ = true; + //impl_->current_graphic_properties->draw_auto_grow_width_ = true; //Example_2.xlsx + + impl_->current_graphic_properties->draw_fit_to_size_ = false; + impl_->current_graphic_properties->style_shrink_to_fit_ = false; } if (impl_->current_drawing_state_.elements_.empty()) return; @@ -2675,7 +2678,7 @@ void odf_drawing_context::set_text_box_parent_style(std::wstring style_name) void odf_drawing_context::end_image() { - if (impl_->is_footer_ || impl_->is_header_ || impl_->is_background_) + if (/*impl_->is_footer_ || impl_->is_header_ ||*/ impl_->is_background_) { end_bitmap_style(); end_shape(); diff --git a/ASCOfficeOdfFileW/source/OdfFormat/ods_table_state.cpp b/ASCOfficeOdfFileW/source/OdfFormat/ods_table_state.cpp index 46bb6f0d35..8bfd519e9c 100644 --- a/ASCOfficeOdfFileW/source/OdfFormat/ods_table_state.cpp +++ b/ASCOfficeOdfFileW/source/OdfFormat/ods_table_state.cpp @@ -80,11 +80,20 @@ std::wstring convert_date(const std::wstring & oox_date) boost::gregorian::date date_ = boost::gregorian::date(1900, 1, 1) + boost::gregorian::date_duration(iDate-2); ////to for example, "1899-12-31T05:37:46.66569 - std::wstring date_str = boost::lexical_cast(date_.year()) + std::wstring date_str; + + try + { + date_str = boost::lexical_cast(date_.year()) + L"-" + (date_.month() < 10 ? L"0": L"") + boost::lexical_cast(date_.month().as_number()) + L"-" + (date_.day() < 10 ? L"0": L"") + boost::lexical_cast(date_.day()); + } + catch(...) + { + date_str = oox_date; + } return date_str; } @@ -471,21 +480,21 @@ void ods_table_state::set_row_default_cell_style(std::wstring & style_name) office_element_ptr & ods_table_state::current_row_element() { - if (rows_.size()>0) + if (false == rows_.empty()) return rows_.back().elm; else throw; } office_element_ptr & ods_table_state::current_cell_element() { - if (cells_size_ >0) + if (cells_size_ > 0) return cells_.back().elm; else throw; } ods_hyperlink_state & ods_table_state::current_hyperlink() { - if ((cells_size_ >0 && hyperlinks_.size()>0) && (cells_.back().hyperlink_idx>=0) ) + if ((cells_size_ >0 && !hyperlinks_.empty()) && (cells_.back().hyperlink_idx >= 0) ) { return hyperlinks_[cells_.back().hyperlink_idx]; } diff --git a/ASCOfficeOdfFileW/source/OdfFormat/odt_conversion_context.cpp b/ASCOfficeOdfFileW/source/OdfFormat/odt_conversion_context.cpp index 2bdfde67c3..9f1bd13c71 100644 --- a/ASCOfficeOdfFileW/source/OdfFormat/odt_conversion_context.cpp +++ b/ASCOfficeOdfFileW/source/OdfFormat/odt_conversion_context.cpp @@ -658,6 +658,7 @@ std::map odt_conversion_context::parse_instr_options void odt_conversion_context::add_field_instr(const std::wstring &instr) { + if (current_fields.empty()) return; current_fields.back().instrText += instr; } void odt_conversion_context::set_field_instr() @@ -824,7 +825,7 @@ void odt_conversion_context::set_field_instr() } void odt_conversion_context::start_field(bool in_span) { - if (false == current_fields.empty() && current_fields.back().status == 0) + if (false == current_fields.empty() && current_fields.back().status == 0 && current_fields.back().instrText.empty() ) return; //start_field из sdt _field_state field; diff --git a/ASCOfficeOdfFileW/source/OdfFormat/style_graphic_properties.cpp b/ASCOfficeOdfFileW/source/OdfFormat/style_graphic_properties.cpp index ba10c9f596..a342ae92a1 100644 --- a/ASCOfficeOdfFileW/source/OdfFormat/style_graphic_properties.cpp +++ b/ASCOfficeOdfFileW/source/OdfFormat/style_graphic_properties.cpp @@ -125,6 +125,7 @@ void graphic_format_properties::serialize(std::wostream & _Wostream ,const wchar CP_XML_ATTR_OPT(L"draw:fit-to-size", draw_fit_to_size_); CP_XML_ATTR_OPT(L"draw:fit-to-contour", draw_fit_to_contour_); CP_XML_ATTR_OPT(L"draw:ole-draw-aspect", draw_ole_draw_aspect_); + CP_XML_ATTR_OPT(L"style:shrink-to-fit", style_shrink_to_fit_); CP_XML_ATTR_OPT(L"draw:stroke", draw_stroke_); CP_XML_ATTR_OPT(L"draw:stroke-dash", draw_stroke_dash_); diff --git a/ASCOfficeOdfFileW/source/OdfFormat/style_graphic_properties.h b/ASCOfficeOdfFileW/source/OdfFormat/style_graphic_properties.h index d71b81c3d3..eebbc72f7a 100644 --- a/ASCOfficeOdfFileW/source/OdfFormat/style_graphic_properties.h +++ b/ASCOfficeOdfFileW/source/OdfFormat/style_graphic_properties.h @@ -93,6 +93,7 @@ public: _CP_OPT(odf_types::Bool) draw_auto_grow_height_; _CP_OPT(odf_types::Bool) draw_auto_grow_width_; + _CP_OPT(odf_types::Bool) style_shrink_to_fit_; _CP_OPT(odf_types::Bool) draw_fit_to_size_; _CP_OPT(odf_types::Bool) draw_fit_to_contour_; _CP_OPT(std::wstring) draw_wrap_influence_on_position_; diff --git a/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConvertDrawing.cpp b/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConvertDrawing.cpp index e156b42bd8..0d28b8e8b0 100644 --- a/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConvertDrawing.cpp +++ b/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConvertDrawing.cpp @@ -688,8 +688,8 @@ void OoxConverter::convert(PPTX::Logic::SpPr *oox_spPr, PPTX::Logic::ShapeStyle* bool bLine = odf_context()->drawing_context()->isLineShape(); - if (custGeom && !custGeom->cxnLst.empty()) - bLine = true; + //if (custGeom && !custGeom->cxnLst.empty()) + // bLine = true; odf_context()->drawing_context()->start_area_properties(); { @@ -2293,7 +2293,7 @@ void OoxConverter::convert(PPTX::Logic::StyleRef *style_ref, int type) if (index < 1000) { index -= 1; - if ((index >= 0) || (index < (int)theme->themeElements.fmtScheme.fillStyleLst.size())) + if (index >= 0 && index < (int)theme->themeElements.fmtScheme.fillStyleLst.size()) { fill = &theme->themeElements.fmtScheme.fillStyleLst[index]; } @@ -2301,7 +2301,7 @@ void OoxConverter::convert(PPTX::Logic::StyleRef *style_ref, int type) else if (index > 1000) { index -= 1001; - if ((index >= 0) || (index < (int)theme->themeElements.fmtScheme.bgFillStyleLst.size())) + if (index >= 0 && index < (int)theme->themeElements.fmtScheme.bgFillStyleLst.size()) { fill = &theme->themeElements.fmtScheme.bgFillStyleLst[index]; } @@ -2312,15 +2312,15 @@ void OoxConverter::convert(PPTX::Logic::StyleRef *style_ref, int type) else if (type == 2) { index -= 1; - if (index >= 0 || index < (int)theme->themeElements.fmtScheme.lnStyleLst.size()) + if (index >= 0 && index < (int)theme->themeElements.fmtScheme.lnStyleLst.size()) { convert(&theme->themeElements.fmtScheme.lnStyleLst[index], nARGB); } } - else if (type == 3) + else if (type == 3) { index -= 1; - if ((index >= 0) || (index < (int)theme->themeElements.fmtScheme.effectStyleLst.size())) + if (index >= 0 && index < (int)theme->themeElements.fmtScheme.effectStyleLst.size()) { convert(&theme->themeElements.fmtScheme.effectStyleLst[index]); } diff --git a/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConvertVml.cpp b/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConvertVml.cpp index 4e75bb278c..df80a8b026 100644 --- a/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConvertVml.cpp +++ b/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConvertVml.cpp @@ -483,9 +483,17 @@ void OoxConverter::convert(OOX::Vml::CFill *vml_fill) odf_context()->drawing_context()->set_gradient_start(*sRgbColor1, no_set); if (sRgbColor2) odf_context()->drawing_context()->set_gradient_end(*sRgbColor2, no_set); + else + odf_context()->drawing_context()->set_gradient_end(L"#ffffff", no_set); + if (vml_fill->m_oAngle.IsInit()) + { + odf_context()->drawing_context()->set_gradient_angle(vml_fill->m_oAngle->GetValue() + 90); + } if (vml_fill->m_oFocusPosition.IsInit()) + { odf_context()->drawing_context()->set_gradient_center(vml_fill->m_oFocusPosition->GetX(), vml_fill->m_oFocusPosition->GetY()); + } odf_context()->drawing_context()->end_gradient_style(); }break; @@ -952,9 +960,9 @@ void OoxConverter::convert(OOX::Vml::CVmlCommonElements *vml_common) delete oRgbColor; } } - for (std::vector::iterator it = vml_common->m_arrItems.begin(); it != vml_common->m_arrItems.end(); ++it) + for (size_t i = 0; i < vml_common->m_arrItems.size(); ++i) { - convert(*it); + convert(vml_common->m_arrItems[i]); } if (vml_common->m_oFilled.IsInit() && vml_common->m_oFilled->GetValue() == SimpleTypes::booleanFalse) diff --git a/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConverterChart.cpp b/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConverterChart.cpp index f0dcb6e5ae..55e86a0cec 100644 --- a/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConverterChart.cpp +++ b/ASCOfficeOdfFileW/source/Oox2OdfConverter/ConverterChart.cpp @@ -1205,7 +1205,8 @@ void OoxConverter::convert(OOX::Spreadsheet::CT_NumDataSource* val) } else if (val->m_numRef) { - if (val->m_numRef->m_f)odf_context()->chart_context()->set_series_value_formula(*val->m_numRef->m_f); + if (val->m_numRef->m_f) + odf_context()->chart_context()->set_series_value_formula(*val->m_numRef->m_f); convert(val->m_numRef->m_numCache, false, false); } diff --git a/ASCOfficeOdfFileW/source/Oox2OdfConverter/DocxConverter.cpp b/ASCOfficeOdfFileW/source/Oox2OdfConverter/DocxConverter.cpp index e5cc7486d5..fd1cadbc88 100644 --- a/ASCOfficeOdfFileW/source/Oox2OdfConverter/DocxConverter.cpp +++ b/ASCOfficeOdfFileW/source/Oox2OdfConverter/DocxConverter.cpp @@ -3001,6 +3001,11 @@ void DocxConverter::convert(OOX::Drawing::CAnchor *oox_anchor) odt_context->drawing_context()->set_wrap_style(odf_types::style_wrap::Parallel); wrap_set = true; } + else if (oox_anchor->m_oWrapNone.IsInit()) + { + odt_context->drawing_context()->set_wrap_style(odf_types::style_wrap::None); + wrap_set = true; + } else if (oox_anchor->m_oAllowOverlap.IsInit()) { odt_context->drawing_context()->set_overlap(oox_anchor->m_oAllowOverlap->ToBool()); @@ -4364,13 +4369,22 @@ bool DocxConverter::convert(OOX::Logic::CTableProperty *oox_table_pr, odf_writer } else if (oox_table_pr->m_oTblLayout.IsInit() && oox_table_pr->m_oTblLayout->m_oType.IsInit()) { - table_properties->table_format_properties_.common_horizontal_margin_attlist_.fo_margin_left_ = odf_types::length(0,odf_types::length::cm); + table_properties->table_format_properties_.common_horizontal_margin_attlist_.fo_margin_left_ = odf_types::length(0, odf_types::length::cm); table_properties->table_format_properties_.table_align_ = odf_types::table_align(odf_types::table_align::Left); } - //if(oox_table_pr->m_oJc.IsInit() && oox_table_pr->m_oJc->m_oVal.IsInit()) - //{ - //} + if(oox_table_pr->m_oJc.IsInit() && oox_table_pr->m_oJc->m_oVal.IsInit()) + { + switch(oox_table_pr->m_oJc->m_oVal->GetValue()) + { + case 0: table_properties->table_format_properties_.table_align_ = odf_types::table_align(odf_types::table_align::Center); break; + case 2: + case 3: table_properties->table_format_properties_.table_align_ = odf_types::table_align(odf_types::table_align::Left); break; + case 1: + case 4: table_properties->table_format_properties_.table_align_ = odf_types::table_align(odf_types::table_align::Right); break; + default: break; + } + } //nullable > m_oBidiVisual; //nullable m_oShade; //nullable m_oTblCaption; diff --git a/ASCOfficeOdfFileW/source/Oox2OdfConverter/XlsxConverter.cpp b/ASCOfficeOdfFileW/source/Oox2OdfConverter/XlsxConverter.cpp index 01b027b32d..700014ec22 100644 --- a/ASCOfficeOdfFileW/source/Oox2OdfConverter/XlsxConverter.cpp +++ b/ASCOfficeOdfFileW/source/Oox2OdfConverter/XlsxConverter.cpp @@ -1115,10 +1115,10 @@ void XlsxConverter::convert(OOX::Spreadsheet::CSheetViews *oox_sheet_views) std::wstring ref(selection->m_oActiveCell.get()); odf_writer::utils::parsing_ref (ref, ActiveCellX, ActiveCellY); - if (ActiveCellX >= 0 && ActiveCellY >= 0) + if (ActiveCellX > 0 && ActiveCellY > 0) { - ods_context->settings_context()->add_property(L"CursorPositionX", L"int", std::to_wstring(ActiveCellX)); - ods_context->settings_context()->add_property(L"CursorPositionY", L"int", std::to_wstring(ActiveCellY)); + ods_context->settings_context()->add_property(L"CursorPositionX", L"int", std::to_wstring(ActiveCellX - 1)); + ods_context->settings_context()->add_property(L"CursorPositionY", L"int", std::to_wstring(ActiveCellY - 1)); } } if (selection->m_oSqref.IsInit()) @@ -1983,16 +1983,37 @@ void XlsxConverter::convert(OOX::Spreadsheet::CCellAnchor *oox_anchor) if (!oox_anchor) return; ////////////////// - if (oox_anchor->m_oFrom.IsInit() || oox_anchor->m_oTo.IsInit()) + if (oox_anchor->m_oFrom.IsInit() || oox_anchor->m_oTo.IsInit() || + oox_anchor->m_oPos.IsInit() || oox_anchor->m_oExt.IsInit()) { oox_table_position from={}, to={}; - convert(oox_anchor->m_oFrom.GetPointer(), &from); - convert(oox_anchor->m_oTo.GetPointer(), &to); + double x1 = 0, y1 = 0, x2 = 0, y2 = 0; - double x1=0, y1=0, x2=0, y2=0; - ods_context->current_table().convert_position(from, x1, y1); - ods_context->current_table().convert_position(to, x2, y2); + if (oox_anchor->m_oFrom.IsInit()) + { + convert(oox_anchor->m_oFrom.GetPointer(), &from); + ods_context->current_table().convert_position(from, x1, y1); + } + else if (oox_anchor->m_oPos.IsInit()) + { + if (oox_anchor->m_oPos->m_oX.IsInit()) + x1 = oox_anchor->m_oPos->m_oX->GetValue(); + if (oox_anchor->m_oPos->m_oY.IsInit()) + y1 = oox_anchor->m_oPos->m_oY->GetValue(); + } + if (oox_anchor->m_oTo.IsInit()) + { + convert(oox_anchor->m_oTo.GetPointer(), &to); + ods_context->current_table().convert_position(to, x2, y2); + } + else if (oox_anchor->m_oExt.IsInit()) + { + if (oox_anchor->m_oExt->m_oCx.IsInit()) + x2 = x1 + oox_anchor->m_oExt->m_oCx->GetValue(); + if (oox_anchor->m_oExt->m_oCy.IsInit()) + y2 = y1 + oox_anchor->m_oExt->m_oCy->GetValue(); + } ods_context->drawing_context()->set_drawings_rect(x1, y1, x2 - x1, y2 - y1); } diff --git a/ASCOfficePPTXFile/PPTXFormat/Logic/GraphicFrame.cpp b/ASCOfficePPTXFile/PPTXFormat/Logic/GraphicFrame.cpp index bff45133e3..03e97e552a 100755 --- a/ASCOfficePPTXFile/PPTXFormat/Logic/GraphicFrame.cpp +++ b/ASCOfficePPTXFile/PPTXFormat/Logic/GraphicFrame.cpp @@ -751,7 +751,11 @@ namespace PPTX olePic.Init(); olePic->blipFill.blip.Init(); + olePic->blipFill.stretch.Init(); + olePic->blipFill.stretch->fillRect.Init(); + + olePic->blipFill.srcRect.Init(); olePic->blipFill.blip->oleFilepathImage = NSDirectory::CreateTempFileWithUniqueName(sTempDirectory, L"img"); diff --git a/ASCOfficePPTXFile/PPTXFormat/Logic/Pic.cpp b/ASCOfficePPTXFile/PPTXFormat/Logic/Pic.cpp index bd6bb4af4d..554e6e6d0d 100644 --- a/ASCOfficePPTXFile/PPTXFormat/Logic/Pic.cpp +++ b/ASCOfficePPTXFile/PPTXFormat/Logic/Pic.cpp @@ -1498,7 +1498,11 @@ namespace PPTX if(oleObject->m_oId.IsInit()) { if (blipFill.blip.IsInit() == false) + { blipFill.blip.Init(); + blipFill.stretch.Init(); + blipFill.stretch->fillRect.Init(); + } blipFill.blip->oleRid = oleObject->m_oId->get(); } XmlMacroReadAttributeBase(node, L"spid", oleObject->m_sShapeId); diff --git a/ASCOfficePPTXFile/PPTXFormat/Logic/UniEffect.cpp b/ASCOfficePPTXFile/PPTXFormat/Logic/UniEffect.cpp index e9f5fe9f65..e145be6237 100644 --- a/ASCOfficePPTXFile/PPTXFormat/Logic/UniEffect.cpp +++ b/ASCOfficePPTXFile/PPTXFormat/Logic/UniEffect.cpp @@ -82,6 +82,7 @@ namespace PPTX } void UniEffect::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) { + LONG pos = pReader->GetPos(); ULONG rec_len = pReader->GetULong(); if (0 == rec_len) return; @@ -92,11 +93,43 @@ namespace PPTX { case EFFECT_TYPE_ALPHAMODFIX: Effect = new PPTX::Logic::AlphaModFix(); break; case EFFECT_TYPE_DUOTONE: Effect = new PPTX::Logic::Duotone(); break; + case EFFECT_TYPE_OUTERSHDW: Effect = new PPTX::Logic::OuterShdw(); break; + case EFFECT_TYPE_GLOW: Effect = new PPTX::Logic::Glow(); break; + case EFFECT_TYPE_XFRM: Effect = new PPTX::Logic::XfrmEffect(); break; + case EFFECT_TYPE_BLUR: Effect = new PPTX::Logic::Blur(); break; + case EFFECT_TYPE_PRSTSHDW: Effect = new PPTX::Logic::PrstShdw(); break; + case EFFECT_TYPE_INNERSHDW: Effect = new PPTX::Logic::InnerShdw(); break; + case EFFECT_TYPE_REFLECTION: Effect = new PPTX::Logic::Reflection(); break; + case EFFECT_TYPE_SOFTEDGE: Effect = new PPTX::Logic::SoftEdge(); break; + case EFFECT_TYPE_FILLOVERLAY: Effect = new PPTX::Logic::FillOverlay(); break; + case EFFECT_TYPE_ALPHACEILING: Effect = new PPTX::Logic::AlphaCeiling(); break; + case EFFECT_TYPE_ALPHAFLOOR: Effect = new PPTX::Logic::AlphaFloor(); break; + case EFFECT_TYPE_TINTEFFECT: Effect = new PPTX::Logic::TintEffect(); break; + case EFFECT_TYPE_RELOFF: Effect = new PPTX::Logic::RelOff(); break; + case EFFECT_TYPE_LUM: Effect = new PPTX::Logic::LumEffect(); break; + case EFFECT_TYPE_HSL: Effect = new PPTX::Logic::HslEffect(); break; + case EFFECT_TYPE_GRAYSCL: Effect = new PPTX::Logic::Grayscl(); break; + case EFFECT_TYPE_ALPHAREPL: Effect = new PPTX::Logic::AlphaRepl(); break; + case EFFECT_TYPE_ALPHAOUTSET: Effect = new PPTX::Logic::AlphaOutset(); break; + case EFFECT_TYPE_ALPHABILEVEL: Effect = new PPTX::Logic::AlphaBiLevel(); break; + case EFFECT_TYPE_BILEVEL: Effect = new PPTX::Logic::BiLevel(); break; + case EFFECT_TYPE_FILL: Effect = new PPTX::Logic::FillEffect(); break; + case EFFECT_TYPE_CLRREPL: Effect = new PPTX::Logic::ClrRepl(); break; + case EFFECT_TYPE_CLRCHANGE: Effect = new PPTX::Logic::ClrChange(); break; + case EFFECT_TYPE_ALPHAINV: Effect = new PPTX::Logic::AlphaInv(); break; + case EFFECT_TYPE_ALPHAMOD: Effect = new PPTX::Logic::AlphaMod(); break; + case EFFECT_TYPE_BLEND: Effect = new PPTX::Logic::Blend(); break; } + + pReader->Seek(pos); if (Effect.is_init()) + { Effect->fromPPTY(pReader); + } else + { pReader->SkipRecord(); + } } UniEffect::UniEffect(XmlUtils::CXmlNode& node) { diff --git a/ASCOfficeRtfFile/RtfFormatLib/source/DestinationCommand.cpp b/ASCOfficeRtfFile/RtfFormatLib/source/DestinationCommand.cpp index 7e7501eebf..27f361b9d5 100644 --- a/ASCOfficeRtfFile/RtfFormatLib/source/DestinationCommand.cpp +++ b/ASCOfficeRtfFile/RtfFormatLib/source/DestinationCommand.cpp @@ -1094,11 +1094,10 @@ bool RtfParagraphPropsCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& else { paragraphProps->m_bInTable = 1; - if ( PROP_DEF == paragraphProps->m_nItap ) + if ( PROP_DEF == paragraphProps->m_nItap) paragraphProps->m_nItap = 1; } } - COMMAND_RTF_BOOL( "intbl", paragraphProps->m_bInTable, sCommand, hasParameter, parameter ) else if ( "itap" == sCommand && hasParameter) { //if (parameter == 0 && paragraphProps->m_bInTable && paragraphProps->m_nItap > 0) @@ -2340,6 +2339,32 @@ bool RtfOldListReader::ExecuteCommand( RtfDocument& oDocument, RtfReader& oReade return false; return true; } +void RtfParagraphPropDestination::EndRows(RtfReader& oReader) +{ + RtfTableRowPtr oNewTableRow ( new RtfTableRow() ); + oNewTableRow->m_oProperty = oReader.m_oState->m_oRowProperty; + + for( int k = (int)aCells.size() - 1; k >= 0 ; k-- ) + { + if ( aCellItaps[k] == nCurItap ) + { + oNewTableRow->InsertItem( aCells[k], 0 ); + + aCells.erase(aCells.begin() + k); + aCellItaps.erase(aCellItaps.begin() + k); + } + else + break; + } + //для каждого cell в row добавляем их свойства + for( int i = 0; i < oNewTableRow->GetCount() && i < oNewTableRow->m_oProperty.GetCount() ; i++ ) + { + oNewTableRow->operator [](i)->m_oProperty = oNewTableRow->m_oProperty[i]; + } + //Добавляем временный row + aRows.push_back( oNewTableRow ); + aRowItaps.push_back( nCurItap ); +} //------------------------------------------------------------------------------------------------------------------------------------------- void RtfParagraphPropDestination::AddItem( RtfParagraphPtr oItem, RtfReader& oReader, bool bEndCell, bool bEndRow ) @@ -2351,6 +2376,8 @@ void RtfParagraphPropDestination::AddItem( RtfParagraphPtr oItem, RtfReader& oRe { if ( nCurItap > 0 ) //Если до этого были только параграфы в таблицах - завершаем таблицу { + if (bEndRow) EndRows(oReader); //ê¡ñ¿ó¿ñπá½∞¡á∩ »α«úαá¼¼á.rtf + RtfTablePtr oNewTable ( new RtfTable() ); oNewTable->m_oProperty = oCurRowProperty; @@ -2416,30 +2443,10 @@ void RtfParagraphPropDestination::AddItem( RtfParagraphPtr oItem, RtfReader& oRe aItaps.push_back( oItem->m_oProperty.m_nItap ); } nCurItap = oItem->m_oProperty.m_nItap; - //закончилась строка + if ( bEndRow ) { - RtfTableRowPtr oNewTableRow ( new RtfTableRow() ); - oNewTableRow->m_oProperty = oReader.m_oState->m_oRowProperty; - - for( int k = (int)aCells.size() - 1; k >= 0 ; k-- ) - { - if ( aCellItaps[k] == nCurItap ) - { - oNewTableRow->InsertItem( aCells[k], 0 ); - - aCells.erase(aCells.begin() + k); - aCellItaps.erase(aCellItaps.begin() + k); - } - else - break; - } - //для каждого cell в row добавляем их свойства - for( int i = 0; i < (int)oNewTableRow->GetCount() && i < oNewTableRow->m_oProperty.GetCount() ; i++ ) - oNewTableRow->operator [](i)->m_oProperty = oNewTableRow->m_oProperty[i]; - //Добавляем временный row - aRows.push_back( oNewTableRow ); - aRowItaps.push_back( nCurItap ); + EndRows(oReader); } else { diff --git a/ASCOfficeRtfFile/RtfFormatLib/source/DestinationCommand.h b/ASCOfficeRtfFile/RtfFormatLib/source/DestinationCommand.h index 6bd5af9f0e..9885293188 100644 --- a/ASCOfficeRtfFile/RtfFormatLib/source/DestinationCommand.h +++ b/ASCOfficeRtfFile/RtfFormatLib/source/DestinationCommand.h @@ -1656,6 +1656,7 @@ public: void Finalize( RtfReader& oReader); + void EndRows(RtfReader& oReader); void ExecuteNumberChar( RtfDocument& oDocument, RtfReader& oReader, RtfAbstractReader& oAbstrReader, int nWinChar, int nMacChar ) { RtfFont oFont; diff --git a/Common/DocxFormat/Source/Common/ComplexTypes.h b/Common/DocxFormat/Source/Common/ComplexTypes.h index 70cd2d94cb..d95721018c 100644 --- a/Common/DocxFormat/Source/Common/ComplexTypes.h +++ b/Common/DocxFormat/Source/Common/ComplexTypes.h @@ -704,7 +704,7 @@ namespace ComplexTypes std::wstring sResult; if ( m_sVal.IsInit() ) - sResult += XmlUtils::EncodeXmlString(m_sVal.get(), false); + sResult += m_sVal.get(); return sResult; } diff --git a/Common/DocxFormat/Source/Common/SimpleTypes_Vml.h b/Common/DocxFormat/Source/Common/SimpleTypes_Vml.h index 1535397b50..d532f2d620 100644 --- a/Common/DocxFormat/Source/Common/SimpleTypes_Vml.h +++ b/Common/DocxFormat/Source/Common/SimpleTypes_Vml.h @@ -4106,10 +4106,16 @@ namespace SimpleTypes void ReadValue_Rotation(std::wstring& sValue) { - m_oValue.dValue = sValue.empty() ? 0 : _wtof(sValue.c_str() ); + m_oValue.dValue = sValue.empty() ? 0 : _wtof(sValue.c_str() ); - if (sValue.find(_T("fd")) != -1) - m_oValue.dValue /= 6000; + if (sValue.find(_T("fd")) != std::wstring::npos) + { + m_oValue.dValue /= 6000.; + } + else if (sValue.find(_T("f")) == sValue.length() - 1) + { + m_oValue.dValue /= 65536.; + } } void ReadValue_Double(std::wstring& sValue) diff --git a/Common/version.txt b/Common/version.txt index 671e0dd22e..b6cdfd3b71 100644 --- a/Common/version.txt +++ b/Common/version.txt @@ -1 +1 @@ -2.4.550.0 +2.4.551.0 diff --git a/DesktopEditor/graphics/Graphics.cpp b/DesktopEditor/graphics/Graphics.cpp index c65d3deb89..ebb7a5c022 100644 --- a/DesktopEditor/graphics/Graphics.cpp +++ b/DesktopEditor/graphics/Graphics.cpp @@ -618,6 +618,12 @@ namespace Aggplus c_c_path.approximation_method(agg::curve_inc); DashStyle eStyle = (DashStyle)pPen->DashStyle; + if (DashStyleCustom == eStyle) + { + if (0 == pPen->Count) + eStyle = DashStyleSolid; + } + agg::trans_affine* pAffine = &m_oFullTransform.m_internal->m_agg_mtx; if (m_bIntegerGrid) pAffine = new agg::trans_affine(); diff --git a/DesktopEditor/graphics/MetafileToGraphicsRenderer.cpp b/DesktopEditor/graphics/MetafileToGraphicsRenderer.cpp index 4599e2f676..463d204cb2 100644 --- a/DesktopEditor/graphics/MetafileToGraphicsRenderer.cpp +++ b/DesktopEditor/graphics/MetafileToGraphicsRenderer.cpp @@ -51,6 +51,9 @@ namespace NSOnlineOfficeBinToPdf int m_nRasterW; int m_nRasterH; + double m_dDpiX; + double m_dDpiY; + std::vector m_arTempFiles; public: @@ -70,6 +73,9 @@ namespace NSOnlineOfficeBinToPdf m_nRasterW = 100; m_nRasterH = 100; + + m_dDpiX = 96.0; + m_dDpiY = 96.0; } ~CMetafileToRenderterRaster_private() @@ -228,6 +234,14 @@ namespace NSOnlineOfficeBinToPdf nRasterW = (int)(w * dKoef1 + 0.5); nRasterH = (int)(h * dKoef1 + 0.5); } + else if (2 == m_internal->m_nSaveType) + { + double w = oInfo.arSizes[nPageIndex].width; + double h = oInfo.arSizes[nPageIndex].height; + + nRasterW = (int)((w * m_internal->m_dDpiX / 25.4) + 0.5); + nRasterH = (int)((h * m_internal->m_dDpiY / 25.4) + 0.5); + } oFrame.put_Width(nRasterW); oFrame.put_Height(nRasterH); @@ -347,4 +361,9 @@ namespace NSOnlineOfficeBinToPdf { m_internal->m_bIsOnlyFirst = value; } + void CMetafileToRenderterRaster::SetOutputDpi(const double& dDpiX, const double& dDpiY) + { + m_internal->m_dDpiX = dDpiX; + m_internal->m_dDpiY = dDpiY; + } } diff --git a/DesktopEditor/graphics/MetafileToGraphicsRenderer.h b/DesktopEditor/graphics/MetafileToGraphicsRenderer.h index b0e9b502c3..46fd60802d 100644 --- a/DesktopEditor/graphics/MetafileToGraphicsRenderer.h +++ b/DesktopEditor/graphics/MetafileToGraphicsRenderer.h @@ -81,6 +81,8 @@ namespace NSOnlineOfficeBinToPdf bool GetIsOnlyFirst(); void SetIsOnlyFirst(const bool& value); + + void SetOutputDpi(const double& dDpiX, const double& dDpiY); }; } diff --git a/DesktopEditor/graphics/pro/graphics.pro b/DesktopEditor/graphics/pro/graphics.pro index 28b8b9ef2a..5123a84d96 100644 --- a/DesktopEditor/graphics/pro/graphics.pro +++ b/DesktopEditor/graphics/pro/graphics.pro @@ -60,9 +60,12 @@ core_windows { LIB_GRAPHICS_PRI_PATH = $$PWD/../.. +FREETYPE_VERSION=2.5.2 + INCLUDEPATH += \ $$LIB_GRAPHICS_PRI_PATH/agg-2.4/include \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/include \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/include \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/include/freetype \ $$LIB_GRAPHICS_PRI_PATH/cximage/jasper/include \ $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg \ $$LIB_GRAPHICS_PRI_PATH/cximage/png \ @@ -134,45 +137,46 @@ SOURCES += \ SOURCES += $$PWD/graphics_pri.cpp -SOURCES += $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftbbox.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftgxval.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftlcdfil.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftmm.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftotval.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftpatent.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftpfr.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftsynth.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/fttype1.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftwinfnt.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftxf86.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/pcf/pcf.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/pfr/pfr.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/psaux/psaux.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/pshinter/pshinter.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/psnames/psmodule.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/raster/raster.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/sfnt/sfnt.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/truetype/truetype.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/type1/type1.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/cid/type1cid.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/type42/type42.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/winfonts/winfnt.c \ +SOURCES += \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftbbox.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftgxval.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftlcdfil.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftmm.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftotval.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftpatent.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftpfr.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftsynth.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/fttype1.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftwinfnt.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftxf86.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/pcf/pcf.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/pfr/pfr.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/psaux/psaux.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/pshinter/pshinter.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/psnames/psmodule.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/raster/raster.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/sfnt/sfnt.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/truetype/truetype.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/type1/type1.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/cid/type1cid.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/type42/type42.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/winfonts/winfnt.c \ \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/autofit/autofit.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/bdf/bdf.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/cff/cff.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftbase.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftbitmap.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/cache/ftcache.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftfstype.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftgasp.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftglyph.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/gzip/ftgzip.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftinit.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/lzw/ftlzw.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftstroke.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/base/ftsystem.c \ - $$LIB_GRAPHICS_PRI_PATH/freetype-2.5.2/src/smooth/smooth.c + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/autofit/autofit.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/bdf/bdf.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/cff/cff.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftbase.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftbitmap.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/cache/ftcache.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftfstype.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftgasp.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftglyph.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/gzip/ftgzip.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftinit.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/lzw/ftlzw.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftstroke.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/base/ftsystem.c \ + $$LIB_GRAPHICS_PRI_PATH/freetype-$$FREETYPE_VERSION/src/smooth/smooth.c SOURCES += \ $$LIB_GRAPHICS_PRI_PATH/cximage/jasper/base/jas_cm.c \ diff --git a/HtmlRenderer/src/Text.h b/HtmlRenderer/src/Text.h index 77742a9c53..0dc9957ef4 100644 --- a/HtmlRenderer/src/Text.h +++ b/HtmlRenderer/src/Text.h @@ -450,7 +450,7 @@ namespace NSHtmlRenderer m_oCurrentInfo.m_lAscent = (USHORT)(lA); m_oCurrentInfo.m_lDescent = (USHORT)(lD); m_oCurrentInfo.m_lLineHeight = (USHORT)(lL); - m_oCurrentInfo.m_lUnitsPerEm = (USHORT)(lD); + m_oCurrentInfo.m_lUnitsPerEm = (USHORT)(lU); } }; diff --git a/HtmlRenderer/src/Writer.h b/HtmlRenderer/src/Writer.h index 3511c1f14a..3d1ab9a677 100644 --- a/HtmlRenderer/src/Writer.h +++ b/HtmlRenderer/src/Writer.h @@ -1143,6 +1143,8 @@ namespace NSHtmlRenderer int symbolsCount = 0; oCur.GenerateArray(symbols, symbolsCount); + // есть проблема с композитными глифами (буква ё). пока отключу конвертацию + lFontConverterFlag = 0; oFontConverter.ToOTF(oCur.m_strFontPath, strTempFont, (unsigned int*)symbols, symbolsCount, sName, lFontConverterFlag); // TRUETYPE only RELEASEARRAYOBJECTS(symbols); diff --git a/Test/Applications/StandardTester/StandardTester.pro b/Test/Applications/StandardTester/StandardTester.pro new file mode 100644 index 0000000000..3406854ec9 --- /dev/null +++ b/Test/Applications/StandardTester/StandardTester.pro @@ -0,0 +1,19 @@ +TEMPLATE = app +CONFIG += console c++11 +CONFIG -= app_bundle +CONFIG -= qt + +SOURCES += \ + $$PWD/../../../../core/Common/OfficeFileFormatChecker2.cpp \ + $$PWD/../../../../core/Common/3dParty/pole/pole.cpp \ + $$PWD/../../../../core/Common/DocxFormat/Source/Base/unicode_util.cpp + +SOURCES += main.cpp + +CORE_ROOT_DIR = $$PWD/../../../../core +PWD_ROOT_DIR = $$PWD +include($$PWD/../../../Common/base.pri) + +LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lkernel -lgraphics + +DESTDIR = $$PWD/build diff --git a/Test/Applications/StandardTester/main.cpp b/Test/Applications/StandardTester/main.cpp new file mode 100644 index 0000000000..c3044c0b80 --- /dev/null +++ b/Test/Applications/StandardTester/main.cpp @@ -0,0 +1,801 @@ +#include + +#include "../../../Common/OfficeFileFormats.h" +#include "../../../Common/OfficeFileFormatChecker.h" + +#include "../../../DesktopEditor/graphics/Timer.h" +#include "../../../DesktopEditor/graphics/TemporaryCS.h" +#include "../../../DesktopEditor/common/File.h" +#include "../../../DesktopEditor/common/Directory.h" +#include "../../../DesktopEditor/common/StringBuilder.h" + +#include "../../../OfficeUtils/src/OfficeUtils.h" + +#include "../../../DesktopEditor/fontengine/application_generate_fonts.h" + +class CConverter; +class CInternalWorker +{ +public: + std::map m_formats; + std::vector m_files; + + int m_nCount; + int m_nCurrent; + int m_nCurrentComplete; + + std::wstring m_sInputFolder; + std::wstring m_sOutputFolder; + + bool m_bIsStandard; + + NSCriticalSection::CRITICAL_SECTION m_oCS; + NSCriticalSection::CRITICAL_SECTION m_oCS_OfficeUtils; + +public: + CInternalWorker() + { + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_RTF, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_DOCUMENT_TXT, true)); + + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPSX, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP, true)); + + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLS, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_SPREADSHEET_ODS, true)); + m_formats.insert(std::make_pair(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV, true)); + + m_nCount = 0; + m_nCurrent = 0; + m_nCurrentComplete = 0; + + m_oCS.InitializeCriticalSection(); + m_oCS_OfficeUtils.InitializeCriticalSection(); + } + ~CInternalWorker() + { + m_oCS.DeleteCriticalSection(); + m_oCS_OfficeUtils.DeleteCriticalSection(); + } + + CConverter* GetNextConverter(); + void OnConvertFile(CConverter* pConverter, int nCode); + void Start(int nCores); + void Cancel(); + + void OpenDir(std::wstring sDir) + { + m_sInputFolder = sDir; + std::vector arFiles = NSDirectory::GetFiles(sDir, true); + for (std::vector::iterator iter = arFiles.begin(); iter != arFiles.end(); iter++) + { + std::wstring sExt = NSFile::GetFileExtention(*iter); + if (sExt == L"docx" || sExt == L"pptx" || sExt == L"xlsx") + m_files.push_back(*iter); + } + m_nCount = (int)m_files.size(); + } + + bool IsWork() + { + CTemporaryCS oCS(&m_oCS); + return (m_nCurrentComplete < m_nCount); + } +}; + +namespace NSX2T +{ + int Convert(const std::wstring& sConverterPath, const std::wstring sXmlPath) + { + int nReturnCode = 0; + std::wstring sConverterExe = sConverterPath; + +#ifdef WIN32 + NSCommon::string_replace(sConverterExe, L"/", L"\\"); + + sConverterExe += L".exe"; + std::wstring sApp = L"x2t "; + + STARTUPINFO sturtupinfo; + ZeroMemory(&sturtupinfo,sizeof(STARTUPINFO)); + sturtupinfo.cb = sizeof(STARTUPINFO); + + sApp += (L"\"" + sXmlPath + L"\""); + wchar_t* pCommandLine = NULL; + if (true) + { + pCommandLine = new wchar_t[sApp.length() + 1]; + memcpy(pCommandLine, sApp.c_str(), sApp.length() * sizeof(wchar_t)); + pCommandLine[sApp.length()] = (wchar_t)'\0'; + } + + HANDLE ghJob = CreateJobObject(NULL, NULL); + + if (ghJob) + { + JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 }; + + // Configure all child processes associated with the job to terminate when the + jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + if ( 0 == SetInformationJobObject( ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli))) + { + CloseHandle(ghJob); + ghJob = NULL; + } + } + + PROCESS_INFORMATION processinfo; + ZeroMemory(&processinfo,sizeof(PROCESS_INFORMATION)); + BOOL bResult = CreateProcessW(sConverterExe.c_str(), pCommandLine, + NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &sturtupinfo, &processinfo); + + if (bResult && ghJob) + { + AssignProcessToJobObject(ghJob, processinfo.hProcess); + } + + ::WaitForSingleObject(processinfo.hProcess, INFINITE); + + RELEASEARRAYOBJECTS(pCommandLine); + + //get exit code + DWORD dwExitCode = 0; + if (GetExitCodeProcess(processinfo.hProcess, &dwExitCode)) + { + nReturnCode = (int)dwExitCode; + } + + CloseHandle(processinfo.hProcess); + CloseHandle(processinfo.hThread); + + if (ghJob) + { + CloseHandle(ghJob); + ghJob = NULL; + } + +#endif + +#ifdef LINUX + pid_t pid = fork(); // create child process + int status; + + std::string sProgramm = U_TO_UTF8(sConverterExe); + std::string sXmlA = U_TO_UTF8(sXmlPath); + + switch (pid) + { + case -1: // error + break; + + case 0: // child process + { + std::string sLibraryDir = sProgramm; + std::string sPATH = sProgramm; + if (std::string::npos != sProgramm.find_last_of('/')) + { + sLibraryDir = "LD_LIBRARY_PATH=" + sProgramm.substr(0, sProgramm.find_last_of('/')); + sPATH = "PATH=" + sProgramm.substr(0, sProgramm.find_last_of('/')); + } + +#ifdef _MAC + sLibraryDir = "DY" + sLibraryDir; +#endif + + const char* nargs[3]; + nargs[0] = sProgramm.c_str(); + nargs[1] = sXmlA.c_str(); + nargs[2] = NULL; + +#ifndef _MAC + const char* nenv[2]; + nenv[0] = sLibraryDir.c_str(); + nenv[1] = NULL; +#else + const char* nenv[3]; + nenv[0] = sLibraryDir.c_str(); + nenv[1] = sPATH.c_str(); + nenv[2] = NULL; +#endif + + execve(sProgramm.c_str(), + (char * const *)nargs, + (char * const *)nenv); + exit(EXIT_SUCCESS); + break; + } + default: // parent process, pid now contains the child pid + while (-1 == waitpid(pid, &status, 0)); // wait for child to complete + if (WIFEXITED(status)) + { + nReturnCode = WEXITSTATUS(status); + } + break; + } +#endif + + return nReturnCode; + } +} + +class CConverter : public NSThreads::CBaseThread +{ +public: + CInternalWorker* m_pInternal; + std::wstring m_file; + std::wstring m_folder_dst; + int m_format; + +public: + CConverter(CInternalWorker* pWorker) : NSThreads::CBaseThread() + { + m_pInternal = pWorker; + } + virtual ~CConverter() + { + Stop(); + } + + virtual DWORD ThreadProc() + { + COfficeFileFormatChecker oChecker; + if (!oChecker.isOfficeFile(m_file)) + { + m_bRunThread = FALSE; + m_pInternal->OnConvertFile(this, -1); + return 0; + } + + m_format = oChecker.nFileType; + +#if 0 + std::map::iterator find = m_pInternal->m_formats.find(m_format); + if ((find == m_pInternal->m_formats.end()) || (find->second == false)) + { + m_bRunThread = FALSE; + m_pInternal->OnConvertFile(this, -1); + return 0; + } +#endif + + std::wstring sProcess = NSFile::GetProcessDirectory(); + + NSCommon::string_replace(sProcess, L"\\", L"/"); + NSCommon::string_replace(m_file, L"\\", L"/"); + + std::wstring sDirectoryDst = m_folder_dst; + NSCommon::string_replace(sDirectoryDst, L"\\", L"/"); + +#ifdef WIN32 + NSCommon::string_replace(m_file, L"//", L"\\\\"); +#endif + + NSDirectory::CreateDirectory(sDirectoryDst); + + NSStringUtils::CStringBuilder oBuilder; + oBuilder.WriteString(L""); + + std::wstring sFileDst = sDirectoryDst + L"/page.zip"; + + oBuilder.WriteEncodeXmlString(m_file); + oBuilder.WriteString(L""); + + oBuilder.WriteEncodeXmlString(sFileDst); + oBuilder.WriteString(L""); + oBuilder.WriteString(std::to_wstring(AVS_OFFICESTUDIO_FILE_IMAGE)); + oBuilder.WriteString(L"./true"); + oBuilder.WriteString(sProcess + L"/fonts"); + oBuilder.WriteString(L"/AllFonts.js464"); + + oBuilder.WriteString(L""); + oBuilder.WriteEncodeXmlString(sProcess + L"/fonts"); + oBuilder.WriteString(L""); + + oBuilder.WriteString(L"42false10001000"); + + oBuilder.WriteString(L""); + + std::wstring sXmlConvert = oBuilder.GetData(); + + std::wstring sTempFileForParams = sDirectoryDst + L"/params.xml"; + NSFile::CFileBinary::SaveToFile(sTempFileForParams, sXmlConvert, true); + + if (NSDirectory::Exists(sProcess + L"/converter")) + sProcess += L"/converter"; + + std::wstring sExe = sProcess + L"/x2t"; + int nReturnCode = NSX2T::Convert(sExe, sTempFileForParams); + + NSFile::CFileBinary::Remove(sTempFileForParams); + + if (0 == nReturnCode) + { + CTemporaryCS oCS(&m_pInternal->m_oCS_OfficeUtils); + + COfficeUtils oUtils; + if (S_OK == oUtils.ExtractToDirectory(sFileDst, sDirectoryDst, NULL, 0)) + NSFile::CFileBinary::Remove(sFileDst); + } + + if (!m_pInternal->m_bIsStandard) + { + // смотрим разницу + std::wstring strDirIn = NSFile::GetDirectoryName(m_file); + std::wstring strDirOut = sDirectoryDst; + + std::wstring strDiffsMain = NSFile::GetDirectoryName(strDirOut) + L"/DIFF"; + std::wstring strDiffs = strDiffsMain + L"/" + NSFile::GetFileName(m_file); + + int nCountInPages = GetPagesCount(strDirIn); + int nCountOutPages = GetPagesCount(strDirOut); + + if (nCountInPages != nCountOutPages) + { + if (!NSDirectory::Exists(strDiffsMain)) + NSDirectory::CreateDirectory(strDiffsMain); + if (!NSDirectory::Exists(strDiffs)) + NSDirectory::CreateDirectory(strDiffs); + + if (nCountInPages > nCountOutPages) + nCountInPages = nCountOutPages; + + std::wstring sFilePagesDiff = strDiffs + L"/pages_count"; + NSFile::CFileBinary oFile; + oFile.CreateFileW(sFilePagesDiff); + oFile.CloseFile(); + + std::cout << "file (page count) : " << U_TO_UTF8(strDiffs) << std::endl; + } + + for (int nPage = 0; nPage < nCountInPages; ++nPage) + { + std::wstring sPageI = strDirIn + L"/image" + std::to_wstring(nPage + 1) + L".png"; + std::wstring sPageO = strDirOut + L"/image" + std::to_wstring(nPage + 1) + L".png"; + std::wstring sPageDiff = strDiffs + L"/image" + std::to_wstring(nPage + 1) + L".png"; + + CBgraFrame frameI; + frameI.OpenFile(sPageI); + + CBgraFrame frameO; + frameO.OpenFile(sPageO); + + int nW_I = frameI.get_Width(); + int nH_I = frameI.get_Height(); + + int nW_O = frameO.get_Width(); + int nH_O = frameO.get_Height(); + + if (nW_I != nW_O || nH_I != nH_O) + { + if (!NSDirectory::Exists(strDiffsMain)) + NSDirectory::CreateDirectory(strDiffsMain); + if (!NSDirectory::Exists(strDiffs)) + NSDirectory::CreateDirectory(strDiffs); + + std::wstring sFilePagesDiff = sPageDiff; + NSFile::CFileBinary oFile; + oFile.CreateFileW(sPageDiff); + oFile.WriteStringUTF8(L"sizes!"); + oFile.CloseFile(); + + std::cout << "file (sizes) : " << U_TO_UTF8(sPageDiff) << ", (" << nW_I << ", " << nH_I << "), (" << nW_O << ", " << nH_O << ")" << std::endl; + continue; + } + + BYTE* pDataI = frameI.get_Data(); + BYTE* pDataO = frameO.get_Data(); + size_t sizeMemory = 4 * nW_I * nH_I; + + if (0 == memcmp(pDataI, pDataO, sizeMemory)) + continue; + + sizeMemory = nW_I * nH_I; + + for (size_t pix = 0; pix < sizeMemory; ++pix) + { + if (pDataI[0] != pDataO[0] || pDataI[1] != pDataO[1] || pDataI[2] != pDataO[2]) + { + if (pDataO[0] == 0x00 && pDataO[1] == 0x00 && pDataO[2] == 0xFF) + { + pDataO[0] = 0xFF; + pDataO[1] = 0x00; + pDataO[2] = 0x00; + } + else + { + pDataO[0] = 0x00; + pDataO[1] = 0x00; + pDataO[2] = 0xFF; + } + } + pDataI += 4; + pDataO += 4; + } + + if (!NSDirectory::Exists(strDiffsMain)) + NSDirectory::CreateDirectory(strDiffsMain); + if (!NSDirectory::Exists(strDiffs)) + NSDirectory::CreateDirectory(strDiffs); + + frameO.SaveFile(sPageDiff, 4); + + std::cout << "file (diffs) : " << U_TO_UTF8(sPageDiff) << std::endl; + } + } + + m_bRunThread = FALSE; + + m_pInternal->OnConvertFile(this, nReturnCode); + return 0; + } + + int GetPagesCount(const std::wstring& dir) + { + int nCount = 0; + std::vector files = NSDirectory::GetFiles(dir, false); + for (std::vector::iterator i = files.begin(); i != files.end(); i++) + { + std::wstring sExt = NSFile::GetFileExtention(*i); + if (sExt == L"png") + ++nCount; + } + return nCount; + } +}; + +CConverter* CInternalWorker::GetNextConverter() +{ + if (m_nCurrent >= m_nCount) + return NULL; + + CConverter* pConverter = new CConverter(this); + pConverter->m_file = m_files[m_nCurrent]; + ++m_nCurrent; + std::wstring sName = NSFile::GetFileName(pConverter->m_file); + + pConverter->m_folder_dst = m_sOutputFolder + L"/" + sName; + NSDirectory::CreateDirectory(pConverter->m_folder_dst); + + if (m_bIsStandard) + NSFile::CFileBinary::Copy(pConverter->m_file, pConverter->m_folder_dst + L"/" + sName); + + pConverter->Start(0); + return pConverter; +} + +void CInternalWorker::OnConvertFile(CConverter* pConverter, int nCode) +{ + CTemporaryCS oCS(&m_oCS); + + std::cout << "file (complete) : " << U_TO_UTF8(m_files[m_nCurrentComplete]) << ", code : " << nCode << std::endl; + + ++m_nCurrentComplete; + + RELEASEOBJECT(pConverter); + GetNextConverter(); +} + +void CInternalWorker::Start(int nCores) +{ + CTemporaryCS oCS(&m_oCS); + + int nSizeInit = nCores; + if (nSizeInit > m_nCount) + nSizeInit = m_nCount; + + for (int i = 0; i < nSizeInit; ++i) + GetNextConverter(); +} + +void CInternalWorker::Cancel() +{ + CTemporaryCS oCS(&m_oCS); + m_nCount = m_nCurrent; +} + +#define ONLYOFFICE_FONTS_VERSION_ 1 +void CheckFonts(const bool& bIsUseSystemFonts, std::vector& arDirs) +{ + std::vector strFonts; + std::wstring strDirectory = NSFile::GetProcessDirectory() + L"/fonts"; + + if (!NSDirectory::Exists(strDirectory)) + NSDirectory::CreateDirectory(strDirectory); + + std::wstring strAllFontsJSPath = strDirectory + L"/AllFonts.js"; + std::wstring strThumbnailsFolder = strDirectory; + std::wstring strFontsSelectionBin = strDirectory + L"/font_selection.bin"; + + if (true) + { + NSFile::CFileBinary oFile; + if (oFile.OpenFile(strDirectory + L"/fonts.log")) + { + int nSize = oFile.GetFileSize(); + char* pBuffer = new char[nSize]; + DWORD dwReaden = 0; + oFile.ReadFile((BYTE*)pBuffer, nSize, dwReaden); + oFile.CloseFile(); + + int nStart = 0; + int nCur = nStart; + for (; nCur < nSize; ++nCur) + { + if (pBuffer[nCur] == '\n') + { + int nEnd = nCur - 1; + if (nEnd > nStart) + { + std::string s(pBuffer + nStart, nEnd - nStart + 1); + strFonts.push_back(s); + } + nStart = nCur + 1; + } + } + + delete[] pBuffer; + } + + if (0 != strFonts.size()) + { + // check version!!! + std::string sOO_Version = strFonts[0]; + if (0 != sOO_Version.find("ONLYOFFICE_FONTS_VERSION_")) + { + strFonts.clear(); + } + else + { + std::string sVersion = sOO_Version.substr(25); + int nVersion = std::stoi(sVersion); + if (nVersion != ONLYOFFICE_FONTS_VERSION_) + strFonts.clear(); + else + strFonts.erase(strFonts.begin()); + } + } + } + + NSFonts::IApplicationFonts* oApplicationF = NSFonts::NSApplication::Create(); + std::vector strFontsW_Cur; + + if (bIsUseSystemFonts) + strFontsW_Cur = oApplicationF->GetSetupFontFiles(); + + for (std::vector::iterator i = arDirs.begin(); i != arDirs.end(); i++) + { + NSDirectory::GetFiles2(*i, strFontsW_Cur, true); + } + +#if defined(_LINUX) + std::wstring sHome = GetHomeDirectory(); + if (!sHome.empty()) + { +#ifdef _MAC + NSDirectory::GetFiles2(sHome + L"/Library/Fonts", strFontsW_Cur, true); +#else + NSDirectory::GetFiles2(sHome + L"/.fonts", strFontsW_Cur, true); + NSDirectory::GetFiles2(sHome + L"/.local/share/fonts", strFontsW_Cur, true); +#endif + } +#endif + + bool bIsEqual = true; + if (strFonts.size() != strFontsW_Cur.size()) + bIsEqual = false; + + if (bIsEqual) + { + int nCount = (int)strFonts.size(); + for (int i = 0; i < nCount; ++i) + { + if (strFonts[i] != NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(strFontsW_Cur[i].c_str(), strFontsW_Cur[i].length())) + { + bIsEqual = false; + break; + } + } + } + + if (bIsEqual) + { + if (!NSFile::CFileBinary::Exists(strFontsSelectionBin)) + bIsEqual = false; + } + + if (!bIsEqual) + { + if (NSFile::CFileBinary::Exists(strAllFontsJSPath)) + NSFile::CFileBinary::Remove(strAllFontsJSPath); + if (NSFile::CFileBinary::Exists(strFontsSelectionBin)) + NSFile::CFileBinary::Remove(strFontsSelectionBin); + + if (strFonts.size() != 0) + NSFile::CFileBinary::Remove(strDirectory + L"/fonts.log"); + + NSFile::CFileBinary oFile; + oFile.CreateFileW(strDirectory + L"/fonts.log"); + oFile.WriteStringUTF8(L"ONLYOFFICE_FONTS_VERSION_"); + oFile.WriteStringUTF8(std::to_wstring(ONLYOFFICE_FONTS_VERSION_)); + oFile.WriteFile((BYTE*)"\n", 1); + int nCount = (int)strFontsW_Cur.size(); + for (int i = 0; i < nCount; ++i) + { + oFile.WriteStringUTF8(strFontsW_Cur[i]); + oFile.WriteFile((BYTE*)"\n", 1); + } + oFile.CloseFile(); + + int nFlag = 3; + oApplicationF->InitializeFromArrayFiles(strFontsW_Cur, nFlag); + + NSCommon::SaveAllFontsJS(oApplicationF, strAllFontsJSPath, strThumbnailsFolder, strFontsSelectionBin); + } + + oApplicationF->Release(); +} + +std::wstring CorrectDir(const std::wstring& sDir) +{ + if (sDir.empty()) + return L""; + + const wchar_t* data = sDir.c_str(); + + std::wstring::size_type pos1 = (data[0] == '\"') ? 1 : 0; + std::wstring::size_type pos2 = sDir.length(); + + if (data[pos2 - 1] == '\"') + --pos2; + + if (pos2 > 0 && ((data[pos2 - 1] == '\\') || (data[pos2 - 1] == '/'))) + --pos2; + + return sDir.substr(pos1, pos2 - pos1); +} + +/* + * + * --input="input-standard-files-dir" + * --output="output-dir" + * --standard // generate standarts + * --use-system-fonts="0/1/false/true" + * --font-dirs="C:\\Windows\\Fonts;/usr/share/fonts;" + * --cores=4 + * + */ + +#ifdef WIN32 +int wmain(int argc, wchar_t** argv) +#else +int main(int argc, char** argv) +#endif +{ + std::vector arFontsDirs; + bool bIsStandard = false; + std::wstring strInputFolder = L""; + std::wstring strOutputFolder = L""; + bool bIsUseSystemFonts = true; + int nCores = 1; + + for (int i = 0; i < argc; ++i) + { +#ifdef WIN32 + std::wstring sParam(argv[i]); +#else + std::string sParamA(argv[i]); + std::wstring sParam = UTF8_TO_U(sParamA); +#endif + + if (sParam.find(L"--") == 0) + { + std::wstring sKey = L""; + std::wstring sValue = L""; + + std::wstring::size_type _pos = sParam.find('='); + if (std::wstring::npos == _pos) + { + sKey = sParam; + } + else + { + sKey = sParam.substr(0, _pos); + sValue = sParam.substr(_pos + 1); + } + + if (sKey == L"--input") + { + strInputFolder = CorrectDir(sValue); + } + else if (sKey == L"--output") + { + strOutputFolder = CorrectDir(sValue); + } + else if (sKey == L"--standard") + { + bIsStandard = true; + } + else if (sKey == L"--use-system-fonts") + { + if (sValue == L"0" || sValue == L"false") + bIsUseSystemFonts = false; + } + else if (sKey == L"--font-dirs") + { + const wchar_t* src = sValue.c_str(); + const wchar_t* limit = src + sValue.length(); + + const wchar_t* srcPrev = src; + while (src < limit) + { + if (*src == ';') + { + if (srcPrev != src) + { + arFontsDirs.push_back(std::wstring(srcPrev, src - srcPrev)); + } + src++; + srcPrev = src; + } + else + src++; + } + + if (src > srcPrev) + { + arFontsDirs.push_back(std::wstring(srcPrev, src - srcPrev)); + } + } + else if (sKey == L"--cores") + { + nCores = std::stoi(sValue); + if (nCores < 1) + nCores = 1; + } + } + } + + DWORD dwTime1 = NSTimers::GetTickCount(); + + CheckFonts(bIsUseSystemFonts, arFontsDirs); + +#if 0 + if (true) + { + strInputFolder = L"D:\\standard"; + strOutputFolder = L"D:\\standard\\out"; + bIsStandard = true; + } + else + { + strInputFolder = L"D:\\standard\\out"; + strOutputFolder = L"D:\\standard\\check"; + bIsStandard = false; + } +#endif + + CInternalWorker oWorker; + oWorker.OpenDir(strInputFolder); + oWorker.m_sOutputFolder = strOutputFolder; + oWorker.m_bIsStandard = bIsStandard; + + if (!NSDirectory::Exists(strOutputFolder)) + NSDirectory::CreateDirectories(strOutputFolder); + + oWorker.Start(nCores); + while (oWorker.IsWork()) + NSThreads::Sleep(500); + + DWORD dwTime2 = NSTimers::GetTickCount(); + + DWORD dwTimeDelta = (dwTime2 - dwTime1) / 1000; + std::cout << "time: " << dwTimeDelta << std::endl; + + return 0; +}