/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) * version 3 as published by the Free Software Foundation. In accordance with * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect * that Ascensio System SIA expressly excludes the warranty of non-infringement * of any third-party rights. * * This program is distributed WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html * * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish * street, Riga, Latvia, EU, LV-1050. * * The interactive user interfaces in modified source and object code versions * of the Program must display Appropriate Legal Notices, as required under * Section 5 of the GNU AGPL version 3. * * Pursuant to Section 7(b) of the License you must retain the original Product * logo when distributing the program. Pursuant to Section 7(e) we decline to * grant you any rights under trademark law for use of our trademarks. * * All the Product's GUI elements, including illustrations and icon sets, as * well as technical writing content are licensed under the terms of the * Creative Commons Attribution-ShareAlike 4.0 International. See the License * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ #include "XlsxConverter.h" #include "PptxConverter.h" #include "DocxConverter.h" #include "../../Common/utils.h" #include "../../../OOXML/DocxFormat/VmlDrawing.h" #include "../../../OOXML/DocxFormat/Diagram/DiagramDrawing.h" #include "../../../OOXML/DocxFormat/Diagram/DiagramData.h" #include "../../../OOXML/DocxFormat/Drawing/DrawingExt.h" #include "../../../OOXML/DocxFormat/Logic/Vml.h" #include "../../../OOXML/XlsxFormat/Chart/ChartDrawing.h" #include "../../../OOXML/XlsxFormat/Chart/Chart.h" #include "../../../OOXML/PPTXFormat/Slide.h" #include "../../../OOXML/PPTXFormat/SlideMaster.h" #include "../../../OOXML/PPTXFormat/Logic/SpTreeElem.h" #include "../../../OOXML/PPTXFormat/Logic/GraphicFrame.h" #include "../../../OOXML/PPTXFormat/Logic/Shape.h" #include "../../../OOXML/PPTXFormat/Logic/Pic.h" #include "../../../OOXML/PPTXFormat/Logic/CxnSp.h" #include "../../../OOXML/PPTXFormat/Logic/SpTree.h" #include "../../../OOXML/PPTXFormat/Logic/Table/Table.h" #include "../../../OOXML/PPTXFormat/Logic/Effects/AlphaModFix.h" #include "../../../OOXML/PPTXFormat/Logic/Effects/Duotone.h" #include "../../../OOXML/PPTXFormat/Logic/Colors/SrgbClr.h" #include "../../../OOXML/PPTXFormat/Logic/Colors/PrstClr.h" #include "../../../OOXML/PPTXFormat/Logic/Colors/SchemeClr.h" #include "../../../OOXML/PPTXFormat/Logic/TextFont.h" #include "../../../OOXML/Common/SimpleTypes_Drawing.h" #include "../../../OOXML/Common/SimpleTypes_Word.h" #include "../Format/odf_conversion_context.h" #include "../Format/odp_conversion_context.h" #include "../Format/odf_text_context.h" #include "../Format/odf_drawing_context.h" #include "../Format/style_text_properties.h" #include "../Format/style_paragraph_properties.h" #include "../Format/style_graphic_properties.h" #include "../Format/styles_list.h" #define GETBITS(from, numL, numH) ((from & (((1 << (numH - numL + 1)) - 1) << numL)) >> numL) using namespace cpdoccore; namespace Oox2Odf { double Emu2Pt(int emu) { return (1.0 * emu / (635 * 20.0)); } const double c_d_1_6 = 1.0 / 6.0; const double c_d_1_3 = 1.0 / 3.0; const double c_d_2_3 = 2.0 / 3.0; inline double Hue2RGB(double dV1, double dV2, double dH) { if (dH < 0.0) dH += 1.0; if (dH > 1.0) dH -= 1.0; if (dH < c_d_1_6) return dV1 + (dV2 - dV1) * 6.0 * dH; if (dH < 0.5) return dV2; if (dH < c_d_2_3) return dV1 + (dV2 - dV1) * (c_d_2_3 - dH) * 6.0; return dV1; } //---------------------------------------------------------------------------------- void OoxConverter::convert(PPTX::Logic::SpTreeElem *oox_element) { if (!oox_element) return; if (!oox_element->is_init()) return; smart_ptr elem = oox_element->GetElem(); convert (elem.GetPointer()); } void OoxConverter::convert_font(PPTX::Theme *theme, std::wstring & font) { if (font == L"+mj-lt") font = theme ? theme->themeElements.fontScheme.majorFont.latin.typeface : L""; else if (font == L"+mn-lt") font = theme ? theme->themeElements.fontScheme.minorFont.latin.typeface : L""; else if (font == L"+mj-ea") font = theme ? theme->themeElements.fontScheme.majorFont.ea.typeface : L""; else if (font == L"+mn-ea") font = theme ? theme->themeElements.fontScheme.minorFont.ea.typeface : L""; else if (font == L"+mj-cs") font = theme ? theme->themeElements.fontScheme.majorFont.cs.typeface : L""; else if (font == L"+mn-cs") font = theme ? theme->themeElements.fontScheme.minorFont.cs.typeface : L""; } void OoxConverter::convert(PPTX::Logic::GraphicFrame *oox_graphic_frame) { if (!oox_graphic_frame)return; convert(oox_graphic_frame->nvGraphicFramePr.GetPointer()); convert(oox_graphic_frame->xfrm.GetPointer()); if ( oox_graphic_frame->chartRec.is_init()) { convert(oox_graphic_frame->chartRec.GetPointer()); } else if ( oox_graphic_frame->smartArt.is_init()) { OoxConverter::convert(oox_graphic_frame->smartArt.GetPointer()); } else if ( oox_graphic_frame->olePic.is_init()) { OoxConverter::convert(oox_graphic_frame->olePic.GetPointer()); } else if ( oox_graphic_frame->table.is_init()) { PptxConverter *pptx_converter = dynamic_cast(this); if (pptx_converter) pptx_converter->convert(oox_graphic_frame->table.GetPointer()); } else if ( oox_graphic_frame->element.is_init()) { OoxConverter::convert(oox_graphic_frame->element.GetElem().GetPointer()); } } void OoxConverter::convert(PPTX::Logic::NvGraphicFramePr *oox_framePr) { if (oox_framePr == NULL) return; convert(&oox_framePr->cNvPr); } void OoxConverter::RGB2HSL(DWORD argb, double& dH, double& dS, double& dL) { unsigned char unB = (argb & 0xFF); unsigned char unG = (argb & 0xFF00) >> 8; unsigned char unR = (argb & 0xFF0000) >> 16; int nmin = (std::min)(unR, (std::min)(unG, unB)); int nmax = (std::max)(unR, (std::max)(unG, unB)); int nDelta = nmax - nmin; double dmax = (nmax + nmin) / 255.0; double dDelta = nDelta / 255.0; dL = dmax / 2.0; if (0 == nDelta) //This is a gray, no chroma... { dH = 0.0; dS = 0.0; } else //Chromatic data... { if (dL < 0.5) dS = dDelta / dmax; else dS = dDelta / (2.0 - dmax); dDelta = dDelta * 1530.0; double dR = (nmax - unR) / dDelta; double dG = (nmax - unG) / dDelta; double dB = (nmax - unB) / dDelta; if (unR == nmax) dH = dB - dG; else if (unG == nmax) dH = c_d_1_3 + dR - dB; else if (unB == nmax) dH = c_d_2_3 + dG - dR; if (dH < 0.0) dH += 1.0; if (dH > 1.0) dH -= 1.0; } } DWORD OoxConverter::HSL2RGB(double dH, double dS, double dL) { unsigned char unR, unG, unB; if (0 == dS) { unR = static_cast(255 * dL); unG = static_cast(255 * dL); unB = static_cast(255 * dL); } else { double dV2; if (dL < 0.5) dV2 = dL * (1.0 + dS); else dV2 = dL + dS - dS * dL; double dV1 = 2.0 * dL - dV2; unR = static_cast(255 * Hue2RGB(dV1, dV2, dH + c_d_1_3)); unG = static_cast(255 * Hue2RGB(dV1, dV2, dH)); unB = static_cast(255 * Hue2RGB(dV1, dV2, dH - c_d_1_3)); } return (unR << 16) | (unG << 8) | unB; } void OoxConverter::convert(PPTX::Logic::Xfrm *oox_xfrm) { if (oox_xfrm == NULL) return; //CTransform2D _CP_OPT(double) x, y, width, height; if (oox_xfrm->offX.IsInit()) x = Emu2Pt(*oox_xfrm->offX); if (oox_xfrm->offY.IsInit()) y = Emu2Pt(*oox_xfrm->offY); if (oox_xfrm->extX.IsInit()) width = Emu2Pt(*oox_xfrm->extX); if (oox_xfrm->extY.IsInit()) height = Emu2Pt(*oox_xfrm->extY); odf_context()->drawing_context()->set_size( width, height); odf_context()->drawing_context()->set_position( x, y); if (oox_xfrm->flipH.get_value_or(false)) odf_context()->drawing_context()->set_flip_H(true); if (oox_xfrm->flipV.get_value_or(false)) odf_context()->drawing_context()->set_flip_V(true); if (oox_xfrm->rot.IsInit()) odf_context()->drawing_context()->set_rotate(oox_xfrm->rot.get_value_or(0)/60000.); } void OoxConverter::convert(PPTX::Logic::Xfrm *oox_txbx, PPTX::Logic::Xfrm *oox_xfrm) { if (oox_txbx == NULL) return; if (oox_xfrm == NULL) return; if (oox_txbx->rot.IsInit() && oox_xfrm->rot.IsInit()) { int angle1 = *oox_txbx->rot / 60000; int angle2 = *oox_xfrm->rot / 60000; oox_txbx->rot = (angle1 + angle2) * 60000; } convert(oox_txbx); } std::wstring OoxConverter::GetImageIdFromVmlShape(OOX::Vml::CVmlCommonElements* pShape) { if (!pShape) return L""; std::wstring sIdImageFileCache; for (size_t i = 0; i < pShape->m_arrItems.size(); ++i) { OOX::WritingElement* pChildElemShape = pShape->m_arrItems[i]; if (OOX::et_v_imagedata == pChildElemShape->getType()) { OOX::Vml::CImageData* pImageData = static_cast(pChildElemShape); if (pImageData->m_oRelId.IsInit()) sIdImageFileCache = pImageData->m_oRelId->GetValue(); else if (pImageData->m_rId.IsInit()) sIdImageFileCache = pImageData->m_rId->GetValue(); else if (pImageData->m_rPict.IsInit()) sIdImageFileCache = pImageData->m_rPict->GetValue(); if (!sIdImageFileCache.empty()) break; } } return sIdImageFileCache; } void OoxConverter::convert(PPTX::Logic::Pic *oox_picture) { if (!oox_picture) return; if (oox_picture->spPr.Geometry.is_init()) { int type = SimpleTypes::shapetypeRect; if ( oox_picture->spPr.Geometry.is() ) { type = 1000; } else if ( oox_picture->spPr.Geometry.is() ) { const PPTX::Logic::PrstGeom& prstGeom = oox_picture->spPr.Geometry.as(); SimpleTypes::CShapeType preset; preset.FromString(prstGeom.prst.get()); type = preset.GetValue(); } if (type != SimpleTypes::shapetypeRect) { odf_context()->drawing_context()->start_shape(type); convert(&oox_picture->spPr, oox_picture->style.GetPointer()); convert(&oox_picture->nvPicPr); odf_context()->drawing_context()->start_area_properties(); convert(&oox_picture->blipFill); odf_context()->drawing_context()->end_area_properties(); odf_context()->drawing_context()->end_shape(); return; } } //-------------------------------------------------------------------------------------- bool bExternal = false; std::wstring pathImage; if (oox_picture->blipFill.blip.IsInit()) { if (oox_picture->blipFill.blip->embed.IsInit()) { std::wstring sID = oox_picture->blipFill.blip->embed->get(); pathImage = find_link_by_id(sID, 1, bExternal); if (false == NSFile::CFileBinary::Exists(pathImage)) { pathImage.clear(); } } else if (oox_picture->blipFill.blip->link.IsInit()) { std::wstring sID = oox_picture->blipFill.blip->link->get(); pathImage = find_link_by_id(sID, 1, bExternal); if (pathImage.empty()) pathImage = sID; } } //-------------------------------------------------------------------------------------- std::wstring odf_ref_image; if (oox_picture->nvPicPr.nvPr.media.is_init()) { if (oox_picture->nvPicPr.nvPr.media.is()) { PPTX::Logic::MediaFile & media = oox_picture->nvPicPr.nvPr.media.as(); std::wstring sID = media.link.get(); std::wstring pathMedia = find_link_by_id(sID, 3, bExternal); double start = -1, end = -1; for (size_t i = 0; i < oox_picture->nvPicPr.nvPr.extLst.size(); i++) { PPTX::Logic::Ext & ext = oox_picture->nvPicPr.nvPr.extLst[i]; if (pathMedia.empty() && ext.link_media.IsInit()) { pathMedia = find_link_by_id(ext.link_media->get(), 3, bExternal); //например файлики mp3 } if (ext.st.IsInit()) start = *ext.st; if (ext.end.IsInit()) end = *ext.end; } std::wstring odf_ref_media = odf_context()->add_media(pathMedia, bExternal); if (!odf_ref_media.empty()) { odf_context()->drawing_context()->start_media(odf_ref_media); //... params OoxConverter::convert(&oox_picture->nvPicPr.cNvPr); OoxConverter::convert(&oox_picture->spPr, oox_picture->style.GetPointer()); odf_ref_image = bExternal ? pathImage : odf_context()->add_image(pathImage); odf_context()->drawing_context()->set_image_replacement(odf_ref_image); odf_context()->drawing_context()->end_media(); return; } } } if (oox_picture->oleObject.IsInit()) { if (pathImage.empty() && oox_picture->blipFill.blip.IsInit()) { pathImage = oox_picture->blipFill.blip->oleFilepathImage; } std::wstring pathOle; if (oox_picture->oleObject->m_oId.IsInit()) { pathOle = find_link_by_id(oox_picture->oleObject->m_oId->get(), 4, bExternal); } std::wstring odf_ref_ole = odf_context()->add_oleobject(pathOle, bExternal); if (!odf_ref_ole.empty()) { odf_context()->drawing_context()->start_object_ole(odf_ref_ole); if (oox_picture->oleObject->m_sProgId.IsInit()) { odf_context()->drawing_context()->set_program(*oox_picture->oleObject->m_sProgId); } if (pathImage.empty() && oox_picture->oleObject->m_sShapeId.IsInit()) { PPTX::Slide *pSlide = dynamic_cast(current_document()); PPTX::SlideMaster *pSlideMaster = dynamic_cast(current_document()); OOX::CVmlDrawing *pVml = pSlide ? pSlide->Vml.GetPointer() : (pSlideMaster ? pSlideMaster->Vml.GetPointer() : NULL); if (pVml) { std::wstring sShapeId = oox_picture->oleObject->m_sShapeId.get(); std::map::iterator pFind = pVml->m_mapShapes.find(sShapeId); if (pVml->m_mapShapes.end() != pFind) { OOX::Vml::CVmlCommonElements* pShape = dynamic_cast(pFind->second.pElement); std::wstring sIdImageFileCache = GetImageIdFromVmlShape(pShape); if (!sIdImageFileCache.empty()) { //ищем физический файл ( rId относительно vml_drawing) smart_ptr pFile = pVml->Find(sIdImageFileCache); if (pFile.IsInit() && (OOX::FileTypes::Image == pFile->type())) { smart_ptr pImageFileCache = pFile.smart_dynamic_cast(); pathImage = pImageFileCache->filename().GetPath(); } } } } } odf_ref_image = odf_context()->add_imageobject(pathImage, bExternal); odf_context()->drawing_context()->set_image_replacement(odf_ref_image); odf_context()->drawing_context()->end_object_ole(); return; } } //-------------------------------------------------------------------------------------- odf_ref_image = bExternal ? pathImage : odf_context()->add_image(pathImage); if (bExternal && std::wstring::npos == odf_ref_image.find(L"\\") && std::wstring::npos == odf_ref_image.find(L"/")) { odf_ref_image = L"../" + odf_ref_image; } odf_context()->drawing_context()->start_image(odf_ref_image); { double Width = 0, Height = 0; _graphics_utils_::GetResolution(pathImage.c_str(), Width, Height); //inch Width /= 96; Height /= 96; if (oox_picture->blipFill.tile.IsInit()) { odf_context()->drawing_context()->set_image_style_repeat(2); } if (oox_picture->blipFill.stretch.IsInit()) { odf_context()->drawing_context()->set_image_style_repeat(1); } if (oox_picture->blipFill.srcRect.IsInit() && Width > 0 && Height >0 ) { double l = XmlUtils::GetInteger( oox_picture->blipFill.srcRect->l.get_value_or(L"0")) /100000.; double t = XmlUtils::GetInteger( oox_picture->blipFill.srcRect->t.get_value_or(L"0")) /100000.; double r = XmlUtils::GetInteger( oox_picture->blipFill.srcRect->r.get_value_or(L"0")) /100000.; double b = XmlUtils::GetInteger( oox_picture->blipFill.srcRect->b.get_value_or(L"0")) /100000.; odf_context()->drawing_context()->set_image_client_rect_inch( l * Width, t * Height, r * Width, b * Height ); } odf_context()->drawing_context()->start_area_properties(); if (oox_picture->blipFill.blip.IsInit()) { for (size_t i = 0 ; i < oox_picture->blipFill.blip->Effects.size(); i++) { convert(oox_picture->blipFill.blip->Effects[i].Effect.GetPointer()); } } odf_context()->drawing_context()->end_area_properties(); OoxConverter::convert(&oox_picture->nvPicPr.cNvPr); OoxConverter::convert(&oox_picture->spPr, oox_picture->style.GetPointer()); } if (oox_picture->blipFill.blip.IsInit()) { for (size_t i = 0; i < oox_picture->blipFill.blip->ExtLst.size(); ++i) { if (oox_picture->blipFill.blip->ExtLst[i].link_svg.IsInit()) { std::wstring sID = oox_picture->blipFill.blip->ExtLst[i].link_svg->get(); pathImage = find_link_by_id(sID, 1, bExternal); if (NSFile::CFileBinary::Exists(pathImage)) { odf_ref_image = odf_context()->add_image(pathImage); odf_context()->drawing_context()->start_image2(odf_ref_image); } break; } } } odf_context()->drawing_context()->end_image(); } void OoxConverter::convert(PPTX::Logic::SmartArt *oox_smart_art) { if (oox_smart_art == NULL) return; if (oox_smart_art->id_data.IsInit() == false) return; oox_smart_art->LoadDrawing(current_document()); if (oox_smart_art->m_oDrawing.IsInit()) { _CP_OPT(double) x, y, width, height, cx = 1., cy= 1.; odf_context()->drawing_context()->get_size (width, height); odf_context()->drawing_context()->get_position (x, y); odf_context()->drawing_context()->start_group(); odf_context()->drawing_context()->set_group_size (width, height, width, height); odf_context()->drawing_context()->set_group_position (x, y, cx, cy); #if 0 odf_context()->drawing_context()->start_drawing(); odf_context()->drawing_context()->start_shape(SimpleTypes::shapetypeRect); odf_context()->drawing_context()->set_size( width, height); odf_context()->drawing_context()->set_position(x, y); if (oox_smart_art->m_oDataBg.IsInit()) { oox_current_child_document = oox_smart_art->m_pDataContainer.GetPointer(); if ((oox_smart_art->m_oDataBg->m_oFill.Fill.IsInit()) && (oox_smart_art->m_oDataBg->m_oFill.m_type != PPTX::Logic::UniFill::noFill)) { odf_context()->drawing_context()->start_area_properties(); { convert(&oox_smart_art->m_oDataBg->m_oFill); } odf_context()->drawing_context()->end_area_properties(); } } odf_context()->drawing_context()->end_shape(); odf_context()->drawing_context()->end_drawing(); #endif oox_current_child_document = oox_smart_art->m_pDrawingContainer.GetPointer(); for (size_t i = 0; i < oox_smart_art->m_oDrawing->SpTreeElems.size(); i++) { odf_context()->drawing_context()->start_drawing(); convert(&oox_smart_art->m_oDrawing->SpTreeElems[i]); odf_context()->drawing_context()->end_drawing(); } odf_context()->drawing_context()->end_group(); oox_current_child_document = NULL; } } void OoxConverter::convert(PPTX::Logic::ChartRec *oox_chart) { if (!oox_chart) return; if( !oox_chart->id_data.IsInit()) return; _CP_OPT(double) width, height, x, y, zero(0); odf_context()->drawing_context()->get_size (width, height); odf_context()->drawing_context()->get_position (x, y); smart_ptr oFile = find_file_by_id (oox_chart->id_data->get()); if (oFile.IsInit()) { OOX::Spreadsheet::CChartFile* pChart = dynamic_cast(oFile.GetPointer()); OOX::Spreadsheet::CChartExFile* pChartEx = dynamic_cast(oFile.GetPointer()); if (pChart || pChartEx) { oox_current_child_document = pChart ? dynamic_cast(pChart) : dynamic_cast(pChartEx); OOX::CChartDrawing* pChartDrawing = NULL; if ( (pChart) && ((pChart->m_oChartSpace.m_userShapes) && (pChart->m_oChartSpace.m_userShapes->m_id.IsInit())) ) { oFile = find_file_by_id (*pChart->m_oChartSpace.m_userShapes->m_id); pChartDrawing = dynamic_cast(oFile.GetPointer()); } if ((pChartDrawing) && (false == pChartDrawing->m_arrItems.empty())) { odf_context()->drawing_context()->start_group(); odf_context()->drawing_context()->set_group_size (width, height, width, height); odf_context()->drawing_context()->set_group_position (x, y, zero, zero); odf_context()->drawing_context()->start_drawing(); odf_context()->drawing_context()->set_position (zero, zero); odf_context()->drawing_context()->set_size (width, height); } odf_context()->drawing_context()->start_object(odf_context()->get_next_name_object()); { odf_context()->start_chart(); odf_context()->chart_context()->set_chart_size(width, height); if (pChart) { OoxConverter::convert(pChart->m_oChartSpace.m_spPr.GetPointer()); OoxConverter::convert(&pChart->m_oChartSpace); } else if (pChartEx) { OoxConverter::convert(pChartEx->m_oChartSpace.m_spPr.GetPointer()); OoxConverter::convert(&pChartEx->m_oChartSpace); } odf_context()->end_chart(); } odf_context()->drawing_context()->end_object(); if ((pChartDrawing) && (false == pChartDrawing->m_arrItems.empty())) { odf_context()->drawing_context()->end_drawing(); oox_current_child_document = dynamic_cast(pChartDrawing); for (size_t i = 0; i < pChartDrawing->m_arrItems.size(); i++) { convert(pChartDrawing->m_arrItems[i], 0, 0, width.get_value_or(0), height.get_value_or(0)); } odf_context()->drawing_context()->end_group(); } oox_current_child_document = NULL; } } } void OoxConverter::convert(OOX::CSizeAnchor *sz_anchor, double x0, double y0, double width, double height) { if (!sz_anchor) return; _CP_OPT(double) x, y, cx, cy; if (sz_anchor->m_oFrom.IsInit()) { if (sz_anchor->m_oFrom->m_oX.IsInit()) x = *sz_anchor->m_oFrom->m_oX * width + x0; if (sz_anchor->m_oFrom->m_oY.IsInit()) y = *sz_anchor->m_oFrom->m_oY * height + y0; } OOX::CRelSizeAnchor *relAnchor = dynamic_cast(sz_anchor); OOX::CAbsSizeAnchor *absAnchor = dynamic_cast(sz_anchor); if ((relAnchor) && (relAnchor->m_oTo.IsInit() && sz_anchor->m_oFrom.IsInit())) { if (relAnchor->m_oTo->m_oX.IsInit()) cx = (*relAnchor->m_oTo->m_oX - *sz_anchor->m_oFrom->m_oX) * width; if (relAnchor->m_oTo->m_oY.IsInit()) cy = (*relAnchor->m_oTo->m_oY - *sz_anchor->m_oFrom->m_oY) * height; } if ((absAnchor) && (absAnchor->m_oExt.IsInit())) { if (absAnchor->m_oExt->m_oCx.IsInit()) cx = *absAnchor->m_oExt->m_oCx * width; if (absAnchor->m_oExt->m_oCy.IsInit()) cy = *absAnchor->m_oExt->m_oCy * height; } odf_context()->drawing_context()->start_drawing(); odf_context()->drawing_context()->set_position (x, y); odf_context()->drawing_context()->set_size (cx, cy); convert(sz_anchor->m_oElement.GetPointer()); odf_context()->drawing_context()->end_drawing(); } void OoxConverter::convert(PPTX::Logic::CNvGrpSpPr *oox_cnvGrpSpPr) { if (!oox_cnvGrpSpPr) return; } void OoxConverter::convert(PPTX::Logic::NvGrpSpPr *oox_nvGrpSpPr) { if (!oox_nvGrpSpPr) return; odf_context()->drawing_context()->set_group_name(oox_nvGrpSpPr->cNvPr.name); odf_context()->drawing_context()->set_group_z_order(oox_nvGrpSpPr->cNvPr.id); if (oox_nvGrpSpPr->cNvPr.descr.IsInit()) odf_context()->drawing_context()->set_description(oox_nvGrpSpPr->cNvPr.descr.get()); if (oox_nvGrpSpPr->cNvPr.id != -1) { cpdoccore::odf_writer::odp_conversion_context* odp_context = dynamic_cast(odf_context()); if (odp_context) { const std::wstring xml_id = odp_context->map_indentifier(std::to_wstring(oox_nvGrpSpPr->cNvPr.id)); odf_context()->drawing_context()->set_group_xml_id(xml_id); } } convert(&oox_nvGrpSpPr->cNvGrpSpPr); convert(&oox_nvGrpSpPr->nvPr); } void OoxConverter::convert(PPTX::Logic::GrpSpPr *oox_grpSpPr) { if (!oox_grpSpPr) return; if (oox_grpSpPr->xfrm.IsInit()) { if (oox_grpSpPr->xfrm->flipH.IsInit()) odf_context()->drawing_context()->set_group_flip_H(oox_grpSpPr->xfrm->flipH.get()); if (oox_grpSpPr->xfrm->flipV.IsInit()) odf_context()->drawing_context()->set_group_flip_V(oox_grpSpPr->xfrm->flipV.get()); _CP_OPT(double) cx, cy, ch_cx, ch_cy; if (oox_grpSpPr->xfrm->extX.IsInit()) cx = oox_grpSpPr->xfrm->extX.get() / 12700.; if (oox_grpSpPr->xfrm->extY.IsInit()) cy = oox_grpSpPr->xfrm->extY.get() / 12700.; if (oox_grpSpPr->xfrm->chExtX.IsInit()) ch_cx = oox_grpSpPr->xfrm->chExtX.get() / 12700.; if (oox_grpSpPr->xfrm->chExtY.IsInit()) ch_cy = oox_grpSpPr->xfrm->chExtY.get() / 12700.; odf_context()->drawing_context()->set_group_size( cx, cy, ch_cx, ch_cy ); _CP_OPT(double) x, y, ch_x, ch_y, ext_x, ext_y; if (oox_grpSpPr->xfrm->offX.IsInit()) x = oox_grpSpPr->xfrm->offX.get() / 12700.; if (oox_grpSpPr->xfrm->offY.IsInit()) y = oox_grpSpPr->xfrm->offY.get() / 12700.; if (oox_grpSpPr->xfrm->chOffX.IsInit()) ch_x = oox_grpSpPr->xfrm->chOffX.get() / 12700.; if (oox_grpSpPr->xfrm->chOffY.IsInit()) ch_y = oox_grpSpPr->xfrm->chOffY.get() / 12700.; size_t group_level = odf_context()->drawing_context()->get_group_level(); odf_context()->drawing_context()->get_position(ext_x, ext_y); if (ext_x && ext_y && group_level < 2) { x = ext_x; y = ext_y; } odf_context()->drawing_context()->set_group_position( x, y, ch_x, ch_y ); if (oox_grpSpPr->xfrm->rot.IsInit()) odf_context()->drawing_context()->set_group_rotate(oox_grpSpPr->xfrm->rot.get() / 60000.); } if ((oox_grpSpPr->Fill.Fill.IsInit()) && (oox_grpSpPr->Fill.m_type != PPTX::Logic::UniFill::noFill)) { odf_context()->drawing_context()->start_area_properties(); { convert(&oox_grpSpPr->Fill); } odf_context()->drawing_context()->end_area_properties(); } convert(oox_grpSpPr->EffectList.List.GetPointer()); convert(oox_grpSpPr->scene3d.GetPointer()); } void OoxConverter::convert(PPTX::Logic::SpTree *oox_shape_tree) { if (oox_shape_tree == NULL) return; odf_context()->drawing_context()->start_group(); convert(&oox_shape_tree->nvGrpSpPr); convert(&oox_shape_tree->grpSpPr); //odf_context()->drawing_context()->set_group_size (width, height, width, height); //odf_context()->drawing_context()->set_group_position (x, y, cx, cy); for (size_t i = 0; i < oox_shape_tree->SpTreeElems.size(); i++) { odf_context()->drawing_context()->start_drawing(); convert(oox_shape_tree->SpTreeElems[i].GetElem().GetPointer()); odf_context()->drawing_context()->end_drawing(); } odf_context()->drawing_context()->end_group(); } void OoxConverter::convert(PPTX::Logic::CxnSp *oox_connect) { if (oox_connect == NULL) return; int type = SimpleTypes::shapetypeLine; if ( oox_connect->spPr.Geometry.is() ) { const PPTX::Logic::PrstGeom& prstGeom = oox_connect->spPr.Geometry.as(); SimpleTypes::CShapeType preset; preset.FromString(prstGeom.prst.get()); type = preset.GetValue(); } odf_context()->drawing_context()->start_shape(type); convert(&oox_connect->spPr, oox_connect->style.GetPointer()); convert(&oox_connect->nvCxnSpPr); odf_context()->drawing_context()->end_shape(); } void OoxConverter::convert(PPTX::Logic::Shape *oox_shape) { if (oox_shape == NULL) return; if (oox_shape->txXfrm.IsInit()) { odf_context()->drawing_context()->start_group(); odf_context()->drawing_context()->start_drawing(); } int type = 1000; //custom if (oox_shape->spPr.Geometry.is_init()) { if ( oox_shape->spPr.Geometry.is() ) { const PPTX::Logic::PrstGeom& prstGeom = oox_shape->spPr.Geometry.as(); SimpleTypes::CShapeType preset; preset.FromString(prstGeom.prst.get()); type = preset.GetValue(); } if (type == SimpleTypes::shapetypeRect && (oox_shape->txBody.IsInit() || oox_shape->oTextBoxShape.IsInit())) type = 2000; if (type == 63) // ellipse type = 1000; // custom if (type == 2000) { PPTX::Logic::BodyPr *bodyPr = NULL; if (oox_shape->txBody.IsInit()) bodyPr = oox_shape->txBody->bodyPr.GetPointer(); else bodyPr = oox_shape->oTextBoxBodyPr.GetPointer(); if ((bodyPr) && (bodyPr->prstTxWarp.IsInit())) { int wordart_type = convert(bodyPr->prstTxWarp.GetPointer()); if (wordart_type > 0) type = wordart_type; } } } else if (oox_shape->nvSpPr.nvPr.ph.is_init()) { type = 2000; } if (type < 0)return; //----------------------------------------------------------------------------- odf_context()->drawing_context()->start_shape(type); if (oox_shape->nvSpPr.nvPr.ph.is_init()) { _CP_PTR(cpdoccore::odf_writer::paragraph_format_properties) paragraph_properties = boost::make_shared(); _CP_PTR(cpdoccore::odf_writer::text_format_properties) text_properties = boost::make_shared(); _CP_PTR(cpdoccore::odf_writer::graphic_format_properties) graphic_properties = boost::make_shared(); if(oox_shape->txBody.is_init()) convert(oox_shape->txBody->lstStyle.GetPointer(), 0, paragraph_properties.get(), text_properties.get()); if (odf_context()->drawing_context()->placeholder_replacing()) { graphic_properties->draw_textarea_horizontal_align_ = odf_types::text_align(odf_types::text_align::Left); graphic_properties->draw_textarea_vertical_align_ = odf_types::vertical_align(odf_types::vertical_align::Top); } odf_context()->drawing_context()->set_text_properties(text_properties.get()); odf_context()->drawing_context()->set_paragraph_properties(paragraph_properties.get()); odf_context()->drawing_context()->set_graphic_properties(graphic_properties.get()); if (oox_shape->txBody.IsInit()) { odf_context()->start_text_context(); convert(oox_shape->txBody->bodyPr.GetPointer()); odf_context()->drawing_context()->set_text(odf_context()->text_context()); odf_context()->end_text_context(); } } convert(&oox_shape->spPr, oox_shape->style.GetPointer()); convert(&oox_shape->nvSpPr); if (oox_shape->txXfrm.IsInit() == false) { if (oox_shape->oTextBoxShape.IsInit()) //docx sdt { DocxConverter *docx_converter = dynamic_cast(this); if (docx_converter) { odf_context()->start_text_context(); //docx_converter->convert(oox_shape->oTextBoxShape.GetPointer()); convert(oox_shape->oTextBoxBodyPr.GetPointer()); if (oox_shape->style.IsInit()) convert(&oox_shape->style->fontRef); for (size_t i = 0; i < oox_shape->oTextBoxShape->m_arrItems.size(); i++) { docx_converter->convert(oox_shape->oTextBoxShape->m_arrItems[i]); convert(oox_shape->oTextBoxBodyPr.GetPointer()); if (oox_shape->style.IsInit()) convert(&oox_shape->style->fontRef); } odf_context()->drawing_context()->set_text( odf_context()->text_context()); odf_context()->end_text_context(); } } else convert(oox_shape->txBody.GetPointer(), oox_shape->style.GetPointer()); } odf_context()->drawing_context()->end_shape(); if (oox_shape->txXfrm.IsInit()) { odf_context()->drawing_context()->end_drawing(); odf_context()->drawing_context()->start_drawing(); odf_context()->drawing_context()->start_text_box(); convert(oox_shape->txXfrm.GetPointer(), oox_shape->spPr.xfrm.GetPointer()); convert(oox_shape->txBody.GetPointer(), oox_shape->style.GetPointer()); odf_context()->drawing_context()->start_line_properties(); odf_context()->drawing_context()->set_no_fill(); odf_context()->drawing_context()->end_line_properties(); odf_context()->drawing_context()->end_shape(); odf_context()->drawing_context()->end_drawing(); odf_context()->drawing_context()->end_group(); } } void OoxConverter::convert(PPTX::Logic::SpPr *oox_spPr, PPTX::Logic::ShapeStyle* oox_sp_style) { if (oox_spPr == NULL) return; convert(oox_spPr->xfrm.GetPointer()); PPTX::Logic::PrstGeom* prstGeom = NULL; PPTX::Logic::CustGeom* custGeom = NULL; if (oox_spPr->Geometry.is()) { prstGeom = &oox_spPr->Geometry.as(); } if (oox_spPr->Geometry.is()) { custGeom = &oox_spPr->Geometry.as(); } convert(prstGeom); convert(custGeom); bool bLine = odf_context()->drawing_context()->isLineShape(); if (custGeom && !custGeom->cxnLst.empty() && !odf_context()->drawing_context()->isCustomClosed()) bLine = true; odf_context()->drawing_context()->start_area_properties(); { if (bLine) { odf_context()->drawing_context()->set_no_fill(); } else { if (oox_spPr->Fill.is_init()) convert(&oox_spPr->Fill); else if (oox_sp_style) convert(&oox_sp_style->fillRef, 1); } } odf_context()->drawing_context()->end_area_properties(); odf_context()->drawing_context()->start_line_properties(); { convert(oox_spPr->ln.GetPointer(), 0, oox_sp_style); } odf_context()->drawing_context()->end_line_properties(); //----------------------------------------------------------------------------------------------------------------------------- PPTX::Logic::EffectLst* effectLst = dynamic_cast(oox_spPr->EffectList.List.GetPointer()); if (effectLst) convert(effectLst); else if (oox_sp_style) convert(&oox_sp_style->effectRef, 3); convert(oox_spPr->scene3d.GetPointer()); convert(oox_spPr->sp3d.GetPointer()); //----------------------------------------------------------------------------------------------------------------------------- } void OoxConverter::convert(OOX::Drawing::COfficeArtExtensionList *ext_list) { if (ext_list == NULL)return; for (size_t i = 0; i < ext_list->m_arrExt.size(); i++) { convert(ext_list->m_arrExt[i]); } } void OoxConverter::convert(OOX::Drawing::COfficeArtExtension *art_ext) { if (art_ext == NULL)return; if (art_ext->m_oSparklineGroups.IsInit() || art_ext->m_oAltTextTable.IsInit()) { XlsxConverter *xlsx_converter = dynamic_cast(this); if (xlsx_converter) { xlsx_converter->convert(art_ext->m_oSparklineGroups.GetPointer()); xlsx_converter->convert(art_ext->m_oAltTextTable.GetPointer()); } } convert(art_ext->m_oChartFiltering.GetPointer()); convert(art_ext->m_oChartDataLabel.GetPointer()); //convert(art_ext->m_oCompatExt.GetPointer()); //convert(art_ext->m_oDataModelExt.GetPointer()); } void OoxConverter::convert(PPTX::Logic::UniFill *oox_fill, DWORD nARGB) { if (oox_fill == NULL) return; if (oox_fill->is()) odf_context()->drawing_context()->set_group_fill(); if (oox_fill->is()) odf_context()->drawing_context()->set_no_fill(); if (oox_fill->is()) convert(&oox_fill->as()); if (oox_fill->is()) convert(&oox_fill->as(), nARGB); if (oox_fill->is()) convert(&oox_fill->as(),nARGB); if (oox_fill->is()) convert(&oox_fill->as(), nARGB); } int OoxConverter::convert(PPTX::Logic::PrstTxWarp *oox_text_preset) { if (oox_text_preset == NULL) return -1; if (oox_text_preset->prst.GetBYTECode() == SimpleTypes::textshapetypeTextNoShape || oox_text_preset->prst.GetBYTECode() == SimpleTypes::textshapetypeTextPlain) // в зависимости от других настроек { return 2000; } else { return 2001 + oox_text_preset->prst.GetBYTECode(); } } void OoxConverter::convert(PPTX::Logic::PrstGeom *oox_geom) { if (!oox_geom) return; if (oox_geom->prst.get() == L"ellipse") { odf_context()->drawing_context()->set_viewBox(21600, 21600); odf_context()->drawing_context()->set_path(L"U 10800 10800 10800 10800 0 360 Z N"); odf_context()->drawing_context()->set_draw_type(L"circle"); return; } for (size_t i = 0; i < oox_geom->avLst.size(); i++) { odf_context()->drawing_context()->add_modifier(oox_geom->avLst[i].fmla.get_value_or(L"0")); } } static std::wstring process_gd_formula(const PPTX::Logic::Gd& gd, odf_writer::odf_drawing_context* drawing_context, size_t& last_gd_index) { std::vector args; boost::algorithm::split(args, gd.fmla.get_value_or(L""), boost::is_any_of("\t "), boost::token_compress_on); std::wstring fmla = gd.fmla.get_value_or(L""); if (args.size() >= 4 && gd.GetFormulaType(args.front()) == 0) // if formula is "('*/') - Multiply Divide Formula" { if (boost::algorithm::starts_with(args[3], L"gd")) { const std::wstring abs_name = std::wstring(L"gd") + std::to_wstring(last_gd_index + 1); const std::wstring abs_fmla = L"abs " + args[3]; const std::wstring cmp_name = std::wstring(L"gd") + std::to_wstring(last_gd_index + 2); const std::wstring cmp_fmla = L"?: " + abs_name + L" " + args[3] + L" 1"; last_gd_index += 2; drawing_context->add_formula(abs_name, abs_fmla); drawing_context->add_formula(cmp_name, cmp_fmla); args[3] = cmp_name; fmla = boost::algorithm::join(args, L" "); } } return fmla; } void OoxConverter::convert(PPTX::Logic::CustGeom *oox_cust_geom) { if (!oox_cust_geom) return; if (oox_cust_geom->gdLst.size()) { size_t last_gd_index = oox_cust_geom->gdLst.size() - 1; for (size_t i = 0; i < oox_cust_geom->gdLst.size(); i++) { const PPTX::Logic::Gd& gd = oox_cust_geom->gdLst[i]; const std::wstring fmla = process_gd_formula(gd, odf_context()->drawing_context(), last_gd_index); odf_context()->drawing_context()->add_formula(gd.name.get_value_or(L""), fmla); } } for (size_t i = 0; i < oox_cust_geom->pathLst.size(); i++) { convert(&oox_cust_geom->pathLst[i]); } for (size_t i = 0; i < oox_cust_geom->avLst.size(); i++) { odf_context()->drawing_context()->add_modifier(oox_cust_geom->avLst[i].fmla.get_value_or(L"0")); } for (size_t i = 0; i < oox_cust_geom->ahLst.size(); i++) { convert(oox_cust_geom->ahLst[i].ah.GetPointer()); } if (oox_cust_geom->rect.IsInit()) { odf_context()->drawing_context()->set_textarea (oox_cust_geom->rect->l.get_value_or(L"0"), oox_cust_geom->rect->t.get_value_or(L"0"), oox_cust_geom->rect->r.get_value_or(L"0"), oox_cust_geom->rect->b.get_value_or(L"0")); } } void OoxConverter::convert(PPTX::Logic::AhXY *oox_handle) { if (!oox_handle) return; odf_context()->drawing_context()->add_handle(oox_handle->x, oox_handle->y, oox_handle->gdRefX.get_value_or(L""), oox_handle->gdRefY.get_value_or(L""), oox_handle->minX.get_value_or(L""), oox_handle->maxX.get_value_or(L""), oox_handle->minX.get_value_or(L""), oox_handle->maxY.get_value_or(L"")); } void OoxConverter::convert(PPTX::Logic::AhPolar *oox_handle) { if (!oox_handle) return; } void OoxConverter::convert(PPTX::Logic::EffectDag *oox_effect_dag, DWORD ARGB) { if (!oox_effect_dag) return; //type - sib, value for (size_t i = 0; i < oox_effect_dag->Effects.size(); ++i) { convert(oox_effect_dag->Effects[i].Effect.GetPointer()/*, ARGB*/); } } void OoxConverter::convert(PPTX::Logic::EffectLst *oox_effect_list, DWORD ARGB) { if (!oox_effect_list) return; convert(oox_effect_list->blur.GetPointer(), ARGB); convert(oox_effect_list->fillOverlay.GetPointer(), ARGB); convert(oox_effect_list->glow.GetPointer(), ARGB); convert(oox_effect_list->reflection.GetPointer(), ARGB); convert(oox_effect_list->softEdge.GetPointer(), ARGB); convert(oox_effect_list->innerShdw.GetPointer(), ARGB); convert(oox_effect_list->outerShdw.GetPointer(), ARGB); convert(oox_effect_list->prstShdw.GetPointer(), ARGB); } void OoxConverter::convert(PPTX::Logic::AlphaModFix *oox_alpha, DWORD ARGB) { if (oox_alpha == NULL) return; if (false == oox_alpha->amt.IsInit()) return; odf_context()->drawing_context()->set_opacity(oox_alpha->amt.get() / 1000.); } void OoxConverter::convert(PPTX::Logic::Blur *oox_effect, DWORD ARGB) { if (oox_effect == NULL) return; } void OoxConverter::convert(PPTX::Logic::FillOverlay *oox_effect, DWORD ARGBt) { if (oox_effect == NULL) return; } void OoxConverter::convert(PPTX::Logic::Reflection *oox_effect, DWORD ARGB) { if (oox_effect == NULL) return; } void OoxConverter::convert(PPTX::Logic::Glow *oox_effect, DWORD ARGB) { if (oox_effect == NULL) return; } void OoxConverter::convert(PPTX::Logic::SoftEdge *oox_effect, DWORD ARGB) { if (oox_effect == NULL) return; } void OoxConverter::convert(PPTX::Logic::Grayscl *oox_effect, DWORD ARGB) { if (oox_effect == NULL) return; odf_context()->drawing_context()->set_grayscale(); } void OoxConverter::convert(PPTX::Logic::Duotone *oox_effect, DWORD ARGB) { if (oox_effect == NULL) return; if (oox_effect->Colors.empty()) return; convert(&oox_effect->Colors[0], ARGB); if (ARGB != 0) { double blue = GETBITS(ARGB, 0, 7) * 100. / 255.; double green = GETBITS(ARGB, 8, 15) * 100. / 255.; double red = GETBITS(ARGB, 16, 23) * 100. / 255.; odf_context()->drawing_context()->set_white_balance(red, green, blue); } } void OoxConverter::convert(PPTX::Logic::InnerShdw *oox_shadow, DWORD ARGB) { if (oox_shadow == NULL) return; std::wstring hexColor; _CP_OPT(double) opacity; convert(&oox_shadow->Color, hexColor, opacity, ARGB); double dist = oox_shadow->dist.IsInit() ? oox_shadow->dist.get() / 12700. : 0; double dir = oox_shadow->dir.IsInit() ? oox_shadow->dir.get() / 60000. : 0; double offset_x = dist * cos(dir * M_PI / 180); double offset_y = dist * sin(dir * M_PI / 180); odf_context()->drawing_context()->set_shadow(2, hexColor, opacity, offset_x, offset_y); } void OoxConverter::convert(PPTX::Logic::OuterShdw *oox_shadow, DWORD ARGB) { if (oox_shadow == NULL) return; std::wstring hexColor; _CP_OPT(double) opacity; convert(&oox_shadow->Color, hexColor, opacity, ARGB); double dist = oox_shadow->dist.IsInit() ? oox_shadow->dist.get() / 12700. : 0; double dir = oox_shadow->dir.IsInit() ? oox_shadow->dir.get() / 60000. : 0; double offset_x = dist * cos(dir * M_PI / 180); double offset_y = dist * sin(dir * M_PI / 180); odf_context()->drawing_context()->set_shadow(1, hexColor, opacity, offset_x, offset_y); } void OoxConverter::convert(PPTX::Logic::PrstShdw *oox_shadow, DWORD ARGB) { if (oox_shadow == NULL) return; std::wstring hexColor; _CP_OPT(double) opacity; convert(&oox_shadow->Color, hexColor, opacity, ARGB); //odf_context()->drawing_context()->set_shadow(1, hexColor, opacity, oox_shadow->dist.IsInit() ? oox_shadow->dist.get() / 12700. : 0); } void OoxConverter::convert(PPTX::Logic::EffectStyle *oox_effects, DWORD ARGB) { if (!oox_effects) return; if (oox_effects->Effects.is_init()) { if (oox_effects->Effects.is()) { convert(dynamic_cast(oox_effects->Effects.List.GetPointer()), ARGB); } else if(oox_effects->Effects.is()) { convert(dynamic_cast(oox_effects->Effects.List.GetPointer()), ARGB); } } if (oox_effects->scene3d.IsInit()) { } if (oox_effects->sp3d.IsInit()) { } } void OoxConverter::convert(PPTX::Logic::Path2D *oox_geom_path) { if (!oox_geom_path) return; odf_context()->drawing_context()->set_viewBox(oox_geom_path->w.get_value_or(0), oox_geom_path->h.get_value_or(0)); for (size_t i = 0 ; i < oox_geom_path->Paths.size(); i++) { if (oox_geom_path->Paths[i].Path2D.is()) convert(&oox_geom_path->Paths[i].Path2D.as()); } if (oox_geom_path->stroke.IsInit() && *oox_geom_path->stroke == false) odf_context()->drawing_context()->add_path_element(std::wstring(L"S"), L""); if(oox_geom_path->fill.IsInit() && oox_geom_path->fill->GetBYTECode() == 4) // fill == "none" odf_context()->drawing_context()->add_path_element(std::wstring(L"F"), L""); odf_context()->drawing_context()->add_path_element(std::wstring(L"N"), L""); } void OoxConverter::convert(PPTX::Logic::PathBase *oox_path) { if (!oox_path) return; PPTX::Logic::MoveTo* moveTo = dynamic_cast (oox_path); PPTX::Logic::LineTo* lineTo = dynamic_cast (oox_path); PPTX::Logic::CubicBezTo* cubicBezTo = dynamic_cast(oox_path); PPTX::Logic::Close* close = dynamic_cast (oox_path); PPTX::Logic::ArcTo* arcTo = dynamic_cast (oox_path); PPTX::Logic::QuadBezTo* quadBezTo = dynamic_cast (oox_path); if (moveTo) convert(moveTo); if (lineTo) convert(lineTo); if (cubicBezTo) convert(cubicBezTo); if (quadBezTo) convert(quadBezTo); if (arcTo) convert(arcTo); if (close) convert(close); } void OoxConverter::convert(PPTX::Logic::BlipFill *oox_bitmap_fill) { if (oox_bitmap_fill == NULL)return; odf_context()->drawing_context()->start_bitmap_style(); odf_context()->drawing_context()->start_area_properties(); { double Width=0, Height = 0; if (oox_bitmap_fill->blip.IsInit()) { std::wstring sID, pathImage; bool bExternal = false; if (oox_bitmap_fill->blip->embed.IsInit()) { sID = oox_bitmap_fill->blip->embed->get(); pathImage = find_link_by_id(sID, 1, bExternal); if (!pathImage.empty()) { odf_context()->drawing_context()->set_bitmap_link(pathImage, bExternal); _graphics_utils_::GetResolution(pathImage.c_str(), Width, Height); Width /= 96; //to inch (current dpi file) Height /= 96; } } else if (oox_bitmap_fill->blip->link.IsInit()) { sID = oox_bitmap_fill->blip->link->get(); pathImage = find_link_by_id(sID, 1, bExternal); //reconstruction.pptx if (pathImage.empty()) pathImage = sID; odf_context()->drawing_context()->set_bitmap_link(pathImage, bExternal); } for (size_t i = 0 ; i < oox_bitmap_fill->blip->Effects.size(); i++) { convert(oox_bitmap_fill->blip->Effects[i].Effect.GetPointer()); } } if (oox_bitmap_fill->srcRect.IsInit() && Width > 0 && Height > 0)//часть изображения { odf_context()->drawing_context()->set_image_client_rect_inch( (oox_bitmap_fill->srcRect->l.IsInit() ? XmlUtils::GetInteger(oox_bitmap_fill->srcRect->l.get()) : 0 ) / 100000. * Width, (oox_bitmap_fill->srcRect->t.IsInit() ? XmlUtils::GetInteger(oox_bitmap_fill->srcRect->t.get()) : 0 ) / 100000. * Height, (oox_bitmap_fill->srcRect->r.IsInit() ? XmlUtils::GetInteger(oox_bitmap_fill->srcRect->r.get()) : 0 ) / 100000. * Width, (oox_bitmap_fill->srcRect->b.IsInit() ? XmlUtils::GetInteger(oox_bitmap_fill->srcRect->b.get()) : 0 ) / 100000. * Height); } if (oox_bitmap_fill->tile.IsInit()) { odf_context()->drawing_context()->set_image_style_repeat(2); if (oox_bitmap_fill->tile->algn.IsInit()) odf_context()->drawing_context()->set_bitmap_tile_align(oox_bitmap_fill->tile->algn->GetBYTECode()); if (oox_bitmap_fill->tile->flip.IsInit()) {} if (oox_bitmap_fill->tile->sx.IsInit() && Width > 0) { odf_context()->drawing_context()->set_bitmap_tile_scale_x(*oox_bitmap_fill->tile->sx / 100000. * Width); } if (oox_bitmap_fill->tile->sy.IsInit()&& Height > 0) { odf_context()->drawing_context()->set_bitmap_tile_scale_y(*oox_bitmap_fill->tile->sy / 100000. * Height); } if (oox_bitmap_fill->tile->tx.IsInit() && Width > 0) { odf_context()->drawing_context()->set_bitmap_tile_translate_x(*oox_bitmap_fill->tile->tx * 100000. / Width ); } if (oox_bitmap_fill->tile->ty.IsInit() && Height > 0) { odf_context()->drawing_context()->set_bitmap_tile_translate_y(*oox_bitmap_fill->tile->ty * 100000. / Height ); } } if (oox_bitmap_fill->stretch.IsInit()) { odf_context()->drawing_context()->set_image_style_repeat(1); if (oox_bitmap_fill->stretch->fillRect.IsInit()){} //заполнение неполного объема } } odf_context()->drawing_context()->end_area_properties(); odf_context()->drawing_context()->end_bitmap_style(); } void OoxConverter::convert(PPTX::Logic::GradFill *oox_grad_fill, DWORD nARGB) { if (!oox_grad_fill) return; odf_context()->drawing_context()->start_gradient_style(); { odf_types::gradient_style::type grad_style = odf_types::gradient_style::linear; if ( (oox_grad_fill->lin.IsInit()) && (oox_grad_fill->lin->ang.IsInit())) { odf_context()->drawing_context()->set_gradient_angle(oox_grad_fill->lin->ang.get()/60000.); } if ( (oox_grad_fill->path.IsInit()) && (oox_grad_fill->path->path.IsInit())) { grad_style = odf_types::gradient_style::linear; switch(oox_grad_fill->path->path->GetBYTECode()) { case SimpleTypes::pathshadetypeCircle: grad_style = odf_types::gradient_style::radial; break; case SimpleTypes::pathshadetypeRect: grad_style = odf_types::gradient_style::rectangular; break; case SimpleTypes::pathshadetypeShape: grad_style = odf_types::gradient_style::square; break; } if (oox_grad_fill->path->rect.IsInit()) { odf_context()->drawing_context()->set_gradient_rect( XmlUtils::GetInteger(oox_grad_fill->path->rect->l.get_value_or(L"")) / 1000., XmlUtils::GetInteger(oox_grad_fill->path->rect->t.get_value_or(L"")) / 1000., XmlUtils::GetInteger(oox_grad_fill->path->rect->r.get_value_or(L"")) / 1000., XmlUtils::GetInteger(oox_grad_fill->path->rect->b.get_value_or(L"")) / 1000.); } else if (grad_style == odf_types::gradient_style::radial) { odf_context()->drawing_context()->set_gradient_center(0.5, 0.5); } } odf_context()->drawing_context()->set_gradient_type(grad_style); bool bOpacity = false; std::vector hexColors; std::vector<_CP_OPT(double)> opacities; for (size_t i = 0; i < oox_grad_fill->GsLst.size(); ++i) { hexColors.emplace_back(); opacities.emplace_back(); convert(&oox_grad_fill->GsLst[i].color, hexColors.back(), opacities.back(), nARGB); if (opacities.back()) bOpacity = true; odf_context()->drawing_context()->set_gradient_stop(hexColors.back(), oox_grad_fill->GsLst[i].pos); } std::reverse(hexColors.begin(), hexColors.end()); std::reverse(opacities.begin(), opacities.end()); if (hexColors.size() > 0) odf_context()->drawing_context()->set_gradient_start(hexColors[0], opacities[0]); if (hexColors.size() > 1) odf_context()->drawing_context()->set_gradient_end (hexColors[hexColors.size() - 1], opacities[opacities.size() - 1]); odf_context()->drawing_context()->end_gradient_style(); if (bOpacity && opacities.size() > 1) { if (!opacities[0]) opacities[0] = 100; if (!opacities[opacities.size() - 1]) opacities[opacities.size() - 1] = 100; if (*opacities[0] == *opacities[opacities.size() - 1] && opacities.size() < 3) { odf_context()->drawing_context()->set_opacity(*opacities[0]); } else { odf_context()->drawing_context()->start_opacity_style(); odf_context()->drawing_context()->set_opacity_type(grad_style); odf_context()->drawing_context()->set_opacity_start(*opacities[0]); odf_context()->drawing_context()->set_opacity_end(*opacities[opacities.size() - 1]); for (size_t i = 0; i < oox_grad_fill->GsLst.size(); ++i) { odf_context()->drawing_context()->set_opacity_stop(opacities[i], oox_grad_fill->GsLst[i].pos); } if (oox_grad_fill->lin.is_init()) { odf_context()->drawing_context()->set_opacity_angle(oox_grad_fill->lin->ang.get() / 60000.); } else if (oox_grad_fill->path.is_init() && oox_grad_fill->path->rect.is_init()) { odf_context()->drawing_context()->set_opacity_rect(XmlUtils::GetInteger(oox_grad_fill->path->rect->l.get_value_or(L"")), XmlUtils::GetInteger(oox_grad_fill->path->rect->t.get_value_or(L"")), XmlUtils::GetInteger(oox_grad_fill->path->rect->r.get_value_or(L"")), XmlUtils::GetInteger(oox_grad_fill->path->rect->b.get_value_or(L""))); } odf_context()->drawing_context()->end_opacity_style(); } } } } void OoxConverter::convert(PPTX::Logic::UniColor * color, DWORD & nARGB) { if (!color) return; smart_ptr clrMap(oox_clrMap()); clrMap.AddRef(); smart_ptr theme(oox_theme()); theme.AddRef(); nARGB = color->GetRGBColor(theme, clrMap, nARGB); } void OoxConverter::convert(PPTX::Logic::UniColor * color, std::wstring & hexString, _CP_OPT(double) & opacity, DWORD nARGB) { if (!color) return; convert(color, nARGB); if (nARGB != 0) { hexString = XmlUtils::ToString((unsigned int)(nARGB & 0x00FFFFFF), L"#%06X"); if ((nARGB >> 24) != 0xff) { opacity = ((nARGB >> 24) /255.) * 100.; } } else { //not found in theme } } void OoxConverter::convert(PPTX::Logic::SolidFill *oox_fill, DWORD nARGB) { if (!oox_fill) return; std::wstring hexString; _CP_OPT(double) opacity; convert(&oox_fill->Color, hexString, opacity, nARGB); odf_context()->drawing_context()->set_solid_fill(hexString); if (opacity) { odf_context()->drawing_context()->set_opacity(*opacity); } } void OoxConverter::convert(PPTX::Logic::PattFill *oox_pattern_fill, DWORD nARGB) { if (!oox_pattern_fill) return; odf_context()->drawing_context()->start_hatch_style(); { if (oox_pattern_fill->prst.IsInit()) { odf_context()->drawing_context()->set_hatch_type(oox_pattern_fill->prst->GetBYTECode()); } if (oox_pattern_fill->fgClr.is_init()) { std::wstring hexColor; _CP_OPT(double) opacity; convert(&oox_pattern_fill->fgClr, hexColor, opacity, nARGB); odf_context()->drawing_context()->set_hatch_line_color(hexColor); } if (oox_pattern_fill->bgClr.is_init()) { std::wstring hexColor; _CP_OPT(double) opacity; convert(&oox_pattern_fill->bgClr, hexColor, opacity, nARGB); odf_context()->drawing_context()->set_hatch_area_color(hexColor); } } odf_context()->drawing_context()->end_hatch_style(); } void OoxConverter::convert(PPTX::Logic::Ln *oox_line_prop, DWORD ARGB, PPTX::Logic::ShapeStyle* oox_sp_style) { if (oox_sp_style) { convert(&oox_sp_style->lnRef, 2); } if (!oox_line_prop) return; if (oox_line_prop->Fill.is_init()) { convert (&oox_line_prop->Fill, ARGB); } if (oox_line_prop->w.IsInit()) { int width = oox_line_prop->w.get(); if (width == 12700 && false == oox_line_prop->Fill.is_init()) { width = 0; odf_context()->drawing_context()->set_no_fill(); } odf_context()->drawing_context()->set_line_width(width / 12700.); //pt } if (oox_line_prop->headEnd.IsInit()) { if (oox_line_prop->headEnd->len.IsInit() || oox_line_prop->headEnd->type.IsInit() || oox_line_prop->headEnd->w.IsInit()) { int type = 0, w = 1, len = 1;//medium arrow if (oox_line_prop->headEnd->len.IsInit()) len = oox_line_prop->headEnd->len->GetBYTECode(); if (oox_line_prop->headEnd->type.IsInit()) type = oox_line_prop->headEnd->type->GetBYTECode(); if (oox_line_prop->headEnd->w.IsInit()) w = oox_line_prop->headEnd->w->GetBYTECode(); odf_context()->drawing_context()->set_line_head(type, len, w); } } if (oox_line_prop->tailEnd.IsInit()) { if (oox_line_prop->tailEnd->len.IsInit() || oox_line_prop->tailEnd->type.IsInit() || oox_line_prop->tailEnd->w.IsInit()) { int type = 1, w = 1, len = 1;//medium arrow if (oox_line_prop->tailEnd->len.IsInit()) len = oox_line_prop->tailEnd->len->GetBYTECode(); if (oox_line_prop->tailEnd->type.IsInit()) type = oox_line_prop->tailEnd->type->GetBYTECode(); if (oox_line_prop->tailEnd->w.IsInit()) w = oox_line_prop->tailEnd->w->GetBYTECode(); odf_context()->drawing_context()->set_line_tail(type, len, w); } } //if (oox_line_prop->custDash.IsInit()) //{ // //через задание стиля и описание геометрии //} if (oox_line_prop->prstDash.IsInit() && oox_line_prop->prstDash->val.IsInit()) { odf_context()->drawing_context()->set_line_dash_preset(oox_line_prop->prstDash->val->GetBYTECode()); } //nullable> m_oAlgn; //nullable> m_oCap; //nullable> m_oCmpd; //ELineJoinType m_eJoinType; // Тип соединения линий //nullable m_oBevel; //nullable m_oMiter; //nullable m_oRound; } void OoxConverter::convert(PPTX::Logic::BodyPr *oox_bodyPr) { if (!oox_bodyPr) return; if ((oox_bodyPr->fromWordArt.IsInit() && (*oox_bodyPr->fromWordArt)) && oox_bodyPr->prstTxWarp.IsInit()) { for (size_t i = 0; i < oox_bodyPr->prstTxWarp->avLst.size(); i++) { if (oox_bodyPr->prstTxWarp->avLst[i].fmla.IsInit()) { odf_context()->drawing_context()->add_modifier(oox_bodyPr->prstTxWarp->avLst[i].fmla.get()); } } } if (oox_bodyPr->vert.IsInit()) { odf_context()->drawing_context()->set_textarea_writing_mode (oox_bodyPr->vert->GetBYTECode()); } if (oox_bodyPr->anchor.IsInit()) { odf_context()->drawing_context()->set_textarea_vertical_align (oox_bodyPr->anchor->GetBYTECode()); } _CP_OPT(double) lIns, tIns, rIns, bIns; if (oox_bodyPr->lIns.IsInit()) lIns = oox_bodyPr->lIns.get() / 12700.; //pt if (oox_bodyPr->tIns.IsInit()) tIns = oox_bodyPr->tIns.get() / 12700.; if (oox_bodyPr->rIns.IsInit()) rIns = oox_bodyPr->rIns.get() / 12700.; if (oox_bodyPr->bIns.IsInit()) bIns = oox_bodyPr->bIns.get() / 12700.; odf_context()->drawing_context()->set_textarea_padding (lIns, tIns, rIns, bIns); if (oox_bodyPr->wrap.IsInit()) odf_context()->drawing_context()->set_textarea_wrap(oox_bodyPr->wrap->GetBYTECode()); if ((oox_bodyPr->numCol.IsInit()) && (oox_bodyPr->numCol.get() > 1)) { int cols = oox_bodyPr->numCol.get(); int gap_cms = oox_bodyPr->spcCol.IsInit() ? oox_bodyPr->spcCol.get() / 360000 : 0; odf_context()->drawing_context()->start_style_columns(cols, gap_cms); odf_context()->drawing_context()->end_style_columns(); } if (oox_bodyPr->rot.IsInit()) { odf_context()->drawing_context()->set_textarea_rotation(oox_bodyPr->rot.get() / 60000); } switch(oox_bodyPr->Fit.type) { case PPTX::Logic::TextFit::FitSpAuto: {//изменяемы размеры шейпа под текст odf_context()->drawing_context()->set_text_box_min_size(true);//уже выставленые в min }break; case PPTX::Logic::TextFit::FitNo: { }break; case PPTX::Logic::TextFit::FitNormAuto: { }break; default: { } } } void OoxConverter::convert(PPTX::Logic::NvSpPr *oox_nvSpPr) { if (!oox_nvSpPr) return; convert (&oox_nvSpPr->cNvPr); convert (&oox_nvSpPr->cNvSpPr); convert (&oox_nvSpPr->nvPr); } static bool is_sound_hlink(const std::wstring& hlink) { const std::wstring ext = NSFile::GetFileExtention(hlink); if (ext == L"wav" || ext == L"wma" || ext == L"mp3" || ext == L"ogg") return true; return false; } static bool is_relative_path(const std::wstring& path) { if (path.size() <= 0) return false; if (path.find(L"://") != std::wstring::npos) return false; if (path[0] == '/') return false; return true; } void OoxConverter::convert(PPTX::Logic::CNvPr *oox_cnvPr) { if (!oox_cnvPr) return; odf_context()->drawing_context()->set_name(oox_cnvPr->name); if (oox_cnvPr->id != -1) { cpdoccore::odf_writer::odp_conversion_context* odp_context = dynamic_cast(odf_context()); if (odp_context) { const std::wstring xml_id = odp_context->map_indentifier(std::to_wstring(oox_cnvPr->id)); odf_context()->drawing_context()->set_xml_id(xml_id); } } if (oox_cnvPr->descr.IsInit()) { odf_context()->drawing_context()->set_description(oox_cnvPr->descr.get()); } if (oox_cnvPr->hidden.IsInit()) { odf_context()->drawing_context()->set_hidden(oox_cnvPr->hidden.get()); } if (oox_cnvPr->hlinkClick.IsInit()) { convert(oox_cnvPr->hlinkClick.GetPointer()); } //nullable_string title; //nullable hlinkHover; } void OoxConverter::convert(PPTX::Logic::CNvSpPr *oox_cnvSpPr) { if (!oox_cnvSpPr) return; } void OoxConverter::convert(PPTX::Logic::CNvCxnSpPr *oox_cnvSpPr) { if (!oox_cnvSpPr) return; } void OoxConverter::convert(PPTX::Logic::NvCxnSpPr *oox_nvSpPr) { if (!oox_nvSpPr) return; convert(&oox_nvSpPr->cNvPr); convert(&oox_nvSpPr->cNvCxnSpPr); convert(&oox_nvSpPr->nvPr); } void OoxConverter::convert(PPTX::Logic::NvPr *oox_nvPr) { if (!oox_nvPr) return; //ph уровнем выше } void OoxConverter::convert_list_level(PPTX::Logic::TextParagraphPr *oox_para_props, int level) {//одномерные списки тока //if (!oox_list)return; if (!oox_para_props) return; PPTX::Theme *theme = oox_theme(); PPTX::Logic::Bullet & bullet = oox_para_props->ParagraphBullet; if (bullet.is())return; int odf_list_type = 13; // 1, 2, 3 ... if (bullet.is()) { const PPTX::Logic::BuAutoNum & buAutoNum = bullet.as(); int pptx_type = buAutoNum.type.GetBYTECode(); if ( pptx_type < 3) odf_list_type = 46; if (pptx_type > 2 && pptx_type < 6) odf_list_type = 60; if (pptx_type > 28 && pptx_type < 32) odf_list_type = 47; if (pptx_type > 31 && pptx_type < 35) odf_list_type = 61; odf_context()->styles_context()->lists_styles().start_style_level(level, odf_list_type); if (buAutoNum.startAt.IsInit()) { int start_value = *buAutoNum.startAt; if (start_value > 1) odf_context()->styles_context()->lists_styles().set_start_number(start_value); } } if (bullet.is()) { odf_list_type = 5; const PPTX::Logic::BuChar & buChar = bullet.as(); odf_context()->styles_context()->lists_styles().start_style_level(level, odf_list_type); odf_context()->styles_context()->lists_styles().set_bullet_char(buChar.Char); } if (bullet.is()) { const PPTX::Logic::BuBlip & buBlip = bullet.as(); std::wstring odf_ref; bool bExternal = false; if (buBlip.blip.embed.IsInit()) { std::wstring sID = buBlip.blip.embed->get(); std::wstring pathImage = find_link_by_id(sID, 1, bExternal); if (pathImage.empty()) pathImage = buBlip.blip.GetFullPicName(); // only for presentation merge shapes !! odf_ref = odf_context()->add_image(pathImage, bExternal); } else if (buBlip.blip.link.IsInit()) { odf_ref = buBlip.blip.link->get(); bExternal = true; } if (!odf_ref.empty()) { odf_list_type = 1000; odf_context()->styles_context()->lists_styles().start_style_level(level, odf_list_type ); odf_context()->styles_context()->lists_styles().set_bullet_image(odf_ref); } else { odf_list_type = 5; odf_context()->styles_context()->lists_styles().start_style_level(level, odf_list_type ); odf_context()->styles_context()->lists_styles().set_bullet_char(L"\x2022"); } } //odf_writer::style_list_level_label_alignment * aligment_props = odf_context()->styles_context()->lists_styles().get_list_level_alignment_properties(); odf_writer::style_list_level_properties* level_props = odf_context()->styles_context()->lists_styles().get_list_level_properties(); odf_writer::text_format_properties* text_properties = odf_context()->styles_context()->lists_styles().get_text_properties(); convert(oox_para_props->defRPr.GetPointer(), text_properties); if (oox_para_props->indent.IsInit() && level_props) { level_props->text_min_label_width_ = odf_types::length(- oox_para_props->indent.get() / 12700., odf_types::length::pt); level_props->text_space_before_ = odf_types::length(1, odf_types::length::pt); }else { //aligment_props->fo_text_indent_ = odf_types::length(0, odf_types::length::cm); //aligment_props->fo_margin_left_ = odf_types::length(0, odf_types::length::cm); } if (oox_para_props->buColor.is()) { const PPTX::Logic::BuClrTx & buClrTx = oox_para_props->buColor.as(); } if (oox_para_props->buColor.is()) { PPTX::Logic::BuClr & buClr = oox_para_props->buColor.as(); std::wstring hexColor; _CP_OPT(double) opacity; convert(&buClr.Color, hexColor, opacity); if (!hexColor.empty()) { if (std::wstring::npos == hexColor.find(L"#")) hexColor = std::wstring(L"#") + hexColor; if (text_properties) text_properties->fo_color_ = odf_types::color(hexColor); } } //----------------------------------- if (oox_para_props->buSize.is()) { const PPTX::Logic::BuSzPts & buSzPts = oox_para_props->buSize.as(); if (buSzPts.val.IsInit()) { if (text_properties) text_properties->fo_font_size_ = odf_types::length(*buSzPts.val, odf_types::length::pt); else if (odf_list_type == 1000) odf_context()->styles_context()->lists_styles().set_bullet_image_size(*buSzPts.val); } } else { double size_pt = oox_para_props->defRPr.IsInit() ? (oox_para_props->defRPr->sz.IsInit() ? *oox_para_props->defRPr->sz /100. : 0) : 0; if (size_pt < 0.001 && odf_list_type == 1000) { odf_writer::odf_style_state_ptr state = odf_context()->styles_context()->last_state(odf_types::style_family::Paragraph); odf_writer::text_format_properties *text_props = state ? state->get_text_properties() : NULL; if (text_props && text_props->fo_font_size_) { size_pt = text_props->fo_font_size_->get_length().get_value_unit(odf_types::length::pt); } if (size_pt < 0.001) { odf_writer::odf_style_state_ptr style_state; odf_context()->styles_context()->find_odf_default_style_state(odf_types::style_family::Text, style_state); if (style_state) text_props = style_state->get_text_properties(); if (text_props && text_props->fo_font_size_) { size_pt = text_props->fo_font_size_->get_length().get_value_unit(odf_types::length::pt); } } } if (oox_para_props->buSize.is()) { //equal tet size } if (oox_para_props->buSize.is()) { const PPTX::Logic::BuSzPct & buSzPct = oox_para_props->buSize.as(); if (buSzPct.val.IsInit()) { if (text_properties) text_properties->fo_font_size_ = odf_types::percent(*buSzPct.val / 1000.); size_pt *= *buSzPct.val / 100000.; } } if (text_properties && !text_properties->fo_font_size_) text_properties->fo_font_size_ = odf_types::percent(100.); else if (odf_list_type == 1000) { odf_context()->styles_context()->lists_styles().set_bullet_image_size(size_pt); } } //---------------- if (oox_para_props->buTypeface.is()) { const PPTX::Logic::BuFontTx & buFontTx = oox_para_props->buTypeface.as(); } if (oox_para_props->buTypeface.is()) { const PPTX::Logic::TextFont & textFont = oox_para_props->buTypeface.as(); std::wstring font = textFont.typeface; convert_font(theme, font); if (!font.empty() && text_properties) text_properties->fo_font_family_ = font; } odf_context()->styles_context()->lists_styles().end_style_level(); } static bool is_empty_run_elems(const std::vector& runElems) { using namespace PPTX::Logic; auto runIt = std::find_if_not(runElems.begin(), runElems.end(), [](const RunElem& r) { return !r.is(); }); if (runIt != runElems.end()) { const Run& run = runIt->as(); if (!run.HasText()) return true; } else return true; return false; } void OoxConverter::convert(PPTX::Logic::Paragraph *oox_paragraph, PPTX::Logic::TextListStyle *oox_list_style) { if (!oox_paragraph)return; bool styled = false; bool list_local = false; bool list_present = false; std::wstring list_style_name; int list_level = 0;//-1; NSCommon::nullable paraPr; if (oox_paragraph->pPr.IsInit()) { if (oox_paragraph->pPr->lvl.IsInit()) list_level = *oox_paragraph->pPr->lvl; if (oox_paragraph->pPr->ParagraphBullet.is_init()) list_local = true; } if (oox_list_style) { int i = (list_level >= 0 && list_level < 10) ? list_level : 0; if (oox_list_style->levels[i].IsInit()) oox_list_style->levels[i]->Merge(paraPr); } if (oox_paragraph->pPr.IsInit()) oox_paragraph->pPr->Merge(paraPr); if (paraPr.IsInit()) { list_level = paraPr->lvl.IsInit() ? *paraPr->lvl : 0; if (list_level > 0) list_present = true; if (paraPr->ParagraphBullet.is_init()) { list_present = true; if (paraPr->ParagraphBullet.is()) list_present = false; } else list_present = false; //свойства могут быть приписаны не только к параграфу, но и к самому объекту odf_writer::paragraph_format_properties* paragraph_properties = odf_context()->text_context()->get_paragraph_properties(); odf_writer::text_format_properties* text_properties = odf_context()->text_context()->get_text_properties(); if (!paragraph_properties) { odf_context()->text_context()->get_styles_context()->create_style(L"", odf_types::style_family::Paragraph, true, false, -1); paragraph_properties = odf_context()->text_context()->get_styles_context()->last_state()->get_paragraph_properties(); text_properties = odf_context()->text_context()->get_styles_context()->last_state()->get_text_properties(); styled = true; } convert(paraPr.GetPointer(), paragraph_properties, text_properties); if (odf_context()->drawing_context()->is_wordart()) odf_context()->drawing_context()->set_paragraph_properties(paragraph_properties); if (styled && odf_context()->drawing_context()->is_placeholder()) { odf_writer::odf_style_state_ptr state = odf_context()->text_context()->get_styles_context()->last_state(odf_types::style_family::Paragraph); odf_context()->drawing_context()->set_placeholder_style(state->get_name()); } } if (is_empty_run_elems(oox_paragraph->RunElems)) list_present = false; //if (oox_paragraph->RunElems.empty() && list_present) list_present = false; // ms не обозначает присутствие списка, libra - показывает значек while ((int)odf_context()->text_context()->list_state_.levels.size() > list_level) { odf_context()->text_context()->end_list(); } if(list_present) { if (odf_context()->text_context()->list_state_.levels.empty()) { odf_context()->text_context()->list_state_.started_list = false; odf_context()->text_context()->list_state_.style_name = L""; } if (list_local) { _CP_OPT(int) inStyles = odf_context()->drawing_context()->get_presentation(); odf_context()->styles_context()->lists_styles().start_style(inStyles && *inStyles > 0); convert_list_level(oox_paragraph->pPr.GetPointer(), list_level /*- 1*/); odf_context()->styles_context()->lists_styles().end_style(); } list_style_name = odf_context()->styles_context()->lists_styles().get_style_name(); //last added list_level++; if ((int)odf_context()->text_context()->list_state_.levels.size() < list_level) { while ((int)odf_context()->text_context()->list_state_.levels.size() < list_level) { if (false == odf_context()->text_context()->start_list(list_style_name)) { break; } odf_context()->text_context()->start_list_item(); if (odf_context()->text_context()->list_state_.style_name == list_style_name) list_style_name = L""; } } else odf_context()->text_context()->start_list_item(); } else if (odf_context()->text_context()->list_state_.started_list == true) { odf_context()->text_context()->end_list(); } odf_context()->text_context()->start_paragraph(styled); if (oox_paragraph->RunElems.size() > 0) { for (size_t i = 0; i < oox_paragraph->RunElems.size(); i++) { convert(&oox_paragraph->RunElems[i].as()); } } else { bool styled = oox_paragraph->endParaRPr.IsInit() && oox_paragraph->endParaRPr->sz.IsInit(); odf_context()->text_context()->start_span(styled); odf_context()->text_context()->end_span(); } odf_context()->text_context()->end_paragraph(); //if(list_present) //{ // odf_context()->text_context()->end_list_item(); //} } void OoxConverter::convert(PPTX::Logic::TextListStyle *oox_list_style, int level, odf_writer::paragraph_format_properties * paragraph_properties , odf_writer::text_format_properties * text_properties) { if (!oox_list_style) return; if (!paragraph_properties) return; convert(oox_list_style->levels[9].GetPointer(), paragraph_properties, text_properties); if (level < 0 || level > 9) return; convert(oox_list_style->levels[level].GetPointer(), paragraph_properties, text_properties); } void OoxConverter::convert(PPTX::Logic::TextParagraphPr *oox_paragraph_pr , odf_writer::paragraph_format_properties * paragraph_properties , odf_writer::text_format_properties * text_properties) { if (!oox_paragraph_pr) return; if (paragraph_properties) { if (oox_paragraph_pr->lnSpc.IsInit()) { odf_types::length_or_percent length; convert(oox_paragraph_pr->lnSpc.GetPointer(), length); paragraph_properties->fo_line_height_ = odf_types::line_width(length); } if (oox_paragraph_pr->spcAft.IsInit()) { odf_types::length_or_percent length; convert(oox_paragraph_pr->spcAft.GetPointer(), length); paragraph_properties->fo_margin_bottom_ = length; } if (oox_paragraph_pr->spcBef.IsInit()) { odf_types::length_or_percent length; convert(oox_paragraph_pr->spcBef.GetPointer(), length); paragraph_properties->fo_margin_top_ = length; } if (oox_paragraph_pr->algn.IsInit()) { switch(oox_paragraph_pr->algn->GetBYTECode()) { case 0 : paragraph_properties->fo_text_align_ = odf_types::text_align(odf_types::text_align::Center); break; case 1 : case 2 : case 3 : paragraph_properties->fo_text_align_ = odf_types::text_align(odf_types::text_align::Justify); break; case 5 : paragraph_properties->fo_text_align_ = odf_types::text_align(odf_types::text_align::Right); break; case 4 : default: paragraph_properties->fo_text_align_ = odf_types::text_align(odf_types::text_align::Left); break; } } if (oox_paragraph_pr->marL.IsInit()) { paragraph_properties->fo_margin_left_ = odf_types::length_or_percent(odf_types::length(oox_paragraph_pr->marL.get() / 12700., odf_types::length::pt)); } if (oox_paragraph_pr->marR.IsInit()) { paragraph_properties->fo_margin_right_ = odf_types::length_or_percent(odf_types::length(oox_paragraph_pr->marR.get() / 12700., odf_types::length::pt)); } if (oox_paragraph_pr->indent.IsInit()) { paragraph_properties->fo_text_indent_ = odf_types::length_or_percent(odf_types::length(oox_paragraph_pr->indent.get() / 12700., odf_types::length::pt)); } if (oox_paragraph_pr->rtl.IsInit() && *oox_paragraph_pr->rtl) { paragraph_properties->style_writing_mode_= odf_types::writing_mode(odf_types::writing_mode::RlTb); } } //defTabSz; //fontAlgn; if (oox_paragraph_pr->defRPr.IsInit()) { convert(oox_paragraph_pr->defRPr.GetPointer(), text_properties); //надо подумать как брать последний по family !!! //convert(oox_paragraph_pr->m_oDefRunProperty.GetPointer()); //odf_context()->text_context()->set_parent_span_style(odf_context()->styles_context()->last_state().get_name()); } } void OoxConverter::convert(PPTX::Logic::TextSpacing *oox_spacing, cpdoccore::odf_types::length_or_percent & length_or_percent) { if (!oox_spacing) return; if ( oox_spacing->spcPct.IsInit() ) { odf_types::percent percent = odf_types::percent(oox_spacing->GetVal()); length_or_percent = odf_types::length_or_percent(percent); } if ( oox_spacing->spcPts.IsInit() ) { odf_types::length length = odf_types::length(-oox_spacing->GetVal() / 100., odf_types::length::pt); length_or_percent = odf_types::length_or_percent(length); } } void OoxConverter::convert(PPTX::Logic::RunProperties *oox_run_pr, odf_writer::text_format_properties * text_properties) { if (!oox_run_pr) return; if (!text_properties) return; PPTX::Theme *theme = oox_theme(); //------------------------------------------------------ odf_writer::odf_drawing_context *drawing = odf_context()->drawing_context(); if (drawing) //from styles drawing impossible( ... todoooo ??? { //if ((oox_run_pr->Fill.is()) || // (oox_run_pr->ln.IsInit() /*&& (oox_run_pr->ln->Fill.is_init() && oox_run_pr->ln->Fill.getType() != OOX::et_a_noFill)*/)) //{ // drawing->change_text_box_2_wordart(); //} if (drawing->is_wordart()) { if (oox_run_pr->Fill.is_init()) { drawing->start_area_properties(); convert(&oox_run_pr->Fill); drawing->end_area_properties(); } if (oox_run_pr->ln.is_init()) { drawing->start_line_properties(true); if (oox_run_pr->ln->Fill.is_init() && oox_run_pr->ln->Fill.getType() != OOX::et_a_noFill ) { drawing->set_line_dash_preset(6); convert(oox_run_pr->ln.GetPointer()); } else if (drawing->is_wordart()) drawing->set_no_fill(); drawing->end_line_properties(); } } } //--------------------------------------- _CP_OPT(double) opacityText; std::wstring hexColorText; PPTX::Logic::GradFill* gradFill = NULL; PPTX::Logic::SolidFill* solidFill = NULL; if (oox_run_pr->ln.is_init()) { if (drawing) drawing->start_line_properties(true); if (oox_run_pr->ln->Fill.is_init() && oox_run_pr->ln->Fill.getType() == OOX::et_a_solidFill ) { solidFill = &oox_run_pr->ln->Fill.as(); } } if (!solidFill && oox_run_pr->Fill.is()) { gradFill = &oox_run_pr->Fill.as(); } else if (!solidFill && oox_run_pr->Fill.is()) { solidFill = &oox_run_pr->Fill.as(); } if (gradFill && !gradFill->GsLst.empty()) { convert(&gradFill->GsLst[0].color, hexColorText, opacityText); } if (solidFill) { convert(&solidFill->Color, hexColorText, opacityText); } if (!hexColorText.empty()) { if (std::wstring::npos == hexColorText.find(L"#")) hexColorText = std::wstring(L"#") + hexColorText; text_properties->fo_color_ = odf_types::color(hexColorText); } //--------------------------------------- if (oox_run_pr->b.IsInit()) { if (oox_run_pr->b.get() == true) text_properties->fo_font_weight_ = odf_types::font_weight(odf_types::font_weight::WBold); else text_properties->fo_font_weight_ = odf_types::font_weight(odf_types::font_weight::WNormal); } if (oox_run_pr->i.IsInit()) { if (oox_run_pr->i.get() ==true) text_properties->fo_font_style_ = odf_types::font_style(odf_types::font_style::Italic); else text_properties->fo_font_style_ = odf_types::font_style(odf_types::font_style::Normal); } if (oox_run_pr->sz.IsInit()) { convert(oox_run_pr->sz.get()/100., text_properties->fo_font_size_); convert(oox_run_pr->sz.get()/100., text_properties->style_font_size_asian_); convert(oox_run_pr->sz.get()/100., text_properties->style_font_size_complex_); } if (oox_run_pr->latin.IsInit()) { if (!oox_run_pr->latin->typeface.empty()) { std::wstring font = oox_run_pr->latin->typeface; convert_font(theme, font); if (!font.empty()) text_properties->fo_font_family_ = font; } else { text_properties->fo_font_family_ = L"Calibri";//default_font; ???? } } if (oox_run_pr->ea.IsInit()) { if (!oox_run_pr->ea->typeface.empty()) { std::wstring font = oox_run_pr->ea->typeface; convert_font(theme, font); if (!font.empty()) text_properties->style_font_family_asian_ = font; } else { } } if (oox_run_pr->cs.IsInit()) { if (!oox_run_pr->cs->typeface.empty()) { std::wstring font = oox_run_pr->cs->typeface; convert_font(theme, font); if (!font.empty()) text_properties->style_font_family_complex_ = font; } else { } } if (oox_run_pr->lang.IsInit()) { std::wstring oox_language = oox_run_pr->lang.get(), oox_country; size_t res = oox_language.find(L"-"); if (res != std::wstring::npos) { oox_country = oox_language.substr(res + 1); oox_language = oox_language.substr(0, res); } text_properties->fo_language_ = oox_language; if (!oox_country.empty()) text_properties->fo_country_ = oox_country; } if (oox_run_pr->spc.IsInit()) { text_properties->fo_letter_spacing_ = odf_types::letter_spacing(odf_types::length(oox_run_pr->spc.get()/100., odf_types::length::pt)); } if (oox_run_pr->u.IsInit()) { text_properties->style_text_underline_style_ = odf_types::line_style (odf_types::line_style::Solid); text_properties->style_text_underline_type_ = odf_types::line_type (odf_types::line_type::Single); switch(oox_run_pr->u->GetBYTECode()) { case 12: text_properties->style_text_underline_style_ = boost::none; text_properties->style_text_underline_type_ = odf_types::line_type(odf_types::line_type::None);break; case 0: case 1: text_properties->style_text_underline_style_ = odf_types::line_style(odf_types::line_style::Dash);break; case 5: case 6: text_properties->style_text_underline_style_ = odf_types::line_style(odf_types::line_style::DotDash);break; case 2: case 3: text_properties->style_text_underline_style_ = odf_types::line_style(odf_types::line_style::LongDash);break; case 7: case 8: text_properties->style_text_underline_style_ = odf_types::line_style(odf_types::line_style::DotDotDash);break; case 9: case 10: text_properties->style_text_underline_style_ = odf_types::line_style(odf_types::line_style::Dotted);break; case 14: case 16: text_properties->style_text_underline_style_ = odf_types::line_style(odf_types::line_style::Wave);break; case 4: text_properties->style_text_underline_type_ = odf_types::line_type(odf_types::line_type::Double);break; case 15: text_properties->style_text_underline_type_ = odf_types::line_type(odf_types::line_type::Double); text_properties->style_text_underline_style_ = odf_types::line_style(odf_types::line_style::Wave);break; } PPTX::Logic::UniFill *fill = NULL; if (oox_run_pr->uFillTx.IsInit()) fill = &oox_run_pr->uFillTx->Fill; else if (oox_run_pr->uFill.IsInit()) fill = &oox_run_pr->uFill->Fill; if (fill && fill->is() ) { PPTX::Logic::SolidFill &solid = fill->as(); _CP_OPT(double) opacityText; std::wstring hexColorText; convert(&solid.Color, hexColorText, opacityText); if (!hexColorText.empty()) { text_properties->style_text_underline_color_ = odf_types::color(hexColorText); } } } if (oox_run_pr->highlight.IsInit()) { _CP_OPT(double) opacityText; std::wstring hexColorText; convert(&oox_run_pr->highlight->Color, hexColorText, opacityText); text_properties->fo_background_color_ = odf_types::color(hexColorText); } if (oox_run_pr->strike.IsInit()) { switch(oox_run_pr->strike->GetBYTECode()) { case 0: text_properties->style_text_line_through_style_ = odf_types::line_style (odf_types::line_style::Solid); text_properties->style_text_line_through_type_ = odf_types::line_type(odf_types::line_type::Double); break; case 1: text_properties->style_text_line_through_style_ = boost::none; text_properties->style_text_line_through_type_ = odf_types::line_type(odf_types::line_type::None); break; case 2: text_properties->style_text_line_through_style_ = odf_types::line_style (odf_types::line_style::Solid); text_properties->style_text_line_through_type_ = odf_types::line_type(odf_types::line_type::Single); break; } } if (oox_run_pr->baseline.IsInit()) { text_properties->style_text_position_ = odf_types::text_position(*oox_run_pr->baseline / 1000.); } if (oox_run_pr->cap.IsInit()) { switch(oox_run_pr->cap->GetBYTECode()) { case 0: text_properties->fo_text_transform_ = odf_types::text_transform(odf_types::text_transform::Uppercase); break; case 1: text_properties->fo_font_variant_ = odf_types::font_variant(odf_types::font_variant::SmallCaps); break; case 2: text_properties->fo_font_variant_ = odf_types::font_variant(odf_types::font_variant::Normal); break; } } if (oox_run_pr->normalizeH.IsInit() && *oox_run_pr->normalizeH) { text_properties->fo_text_transform_ = odf_types::text_transform(odf_types::text_transform::Capitalize); } } static std::vector split_tabs(const std::wstring& text) { std::vector result; std::wstringstream ss; const wchar_t tabChar = L'\t'; for (const auto& c : text) { if (c == tabChar) { if (!ss.str().empty()) { result.push_back(ss.str()); ss.str(std::wstring()); } result.push_back(L"\t"); } else ss << c; } if(!ss.str().empty()) result.push_back(ss.str()); return result; } void OoxConverter::convert(PPTX::Logic::Run *oox_run) { if (!oox_run) return; bool styled = false; odf_writer::odf_text_context* text_context = odf_context()->text_context(); if (oox_run->rPr.IsInit()) { odf_writer::text_format_properties * text_properties = text_context->get_text_properties(); if (!text_properties) { text_context->get_styles_context()->create_style(L"", odf_types::style_family::Text, true, false, -1); text_properties = text_context->get_styles_context()->last_state()->get_text_properties(); styled = true; } convert(oox_run->rPr.GetPointer(), text_properties); } text_context->start_span(styled); if ((oox_run->rPr.IsInit()) && (oox_run->rPr->hlinkClick.IsInit()) && (oox_run->rPr->hlinkClick->id.IsInit())) { odf_writer::text_format_properties* text_properties = text_context->get_text_properties(); if (!text_properties->fo_color_) { PPTX::Logic::UniColor colorLink; colorLink.Color.reset(new PPTX::Logic::SchemeClr()); PPTX::Logic::SchemeClr & clr = colorLink.as(); clr.val.set(L"hlink"); std::wstring strHexColor; _CP_OPT(double) opacity; convert(&colorLink, strHexColor, opacity); if (!strHexColor.empty()) text_properties->fo_color_ = strHexColor; } text_properties->style_text_underline_type_ = odf_types::line_type::Single; text_properties->style_text_underline_style_ = odf_types::line_style::Solid; bool bExternal = false; std::wstring hlink = find_link_by_id(oox_run->rPr->hlinkClick->id.get(), 2, bExternal); std::wstring location; smart_ptr file = find_file_by_id(oox_run->rPr->hlinkClick->id.get()); OOX::HyperLink* hyperlink = dynamic_cast(file.GetPointer()); if (hyperlink) location = hyperlink->Uri().GetBasename(); if (oox_run->rPr->hlinkClick->action.IsInit() && location.empty()) { const std::wstring& action = *oox_run->rPr->hlinkClick->action; if (std::wstring::npos != action.find(L"previousslide")) location = L"previous-page"; else if (std::wstring::npos != action.find(L"nextslide")) location = L"next-page"; else if (std::wstring::npos != action.find(L"firstslide")) location = L"first-page"; else if (std::wstring::npos != action.find(L"lastslide")) location = L"last-page"; else if (std::wstring::npos != action.find(L"endshow")) location = L"end"; } text_context->add_hyperlink(hlink, oox_run->GetText(), location); } else { const std::wstring& text = oox_run->GetText(); std::vector tabSplit = split_tabs(text); for (const std::wstring& str : tabSplit) { if (str == L"\t") text_context->add_tab(); else text_context->add_text_content(str); } } text_context->end_span(); } void OoxConverter::convert(PPTX::Logic::Fld *oox_fld) { if (!oox_fld) return; bool styled = false; if (oox_fld->rPr.IsInit()) { odf_writer::text_format_properties * text_properties = odf_context()->text_context()->get_text_properties(); if (!text_properties) { odf_context()->styles_context()->create_style(L"", odf_types::style_family::Text, true, false, -1); text_properties = odf_context()->styles_context()->last_state()->get_text_properties(); styled = true; } convert(oox_fld->rPr.GetPointer(), text_properties); } odf_context()->text_context()->start_span(styled); std::wstring fld_type = oox_fld->type.get_value_or(L""); if ((oox_fld->rPr.IsInit()) && (oox_fld->rPr->hlinkClick.IsInit()) && (oox_fld->rPr->hlinkClick->id.IsInit())) { bool bExternal = false; std::wstring hlink = find_link_by_id(oox_fld->rPr->hlinkClick->id.get(), 2, bExternal); std::wstring location; odf_context()->text_context()->add_hyperlink(hlink, oox_fld->GetText(), location); } else if (fld_type == L"slidenum") { odf_context()->text_context()->add_text_page_number( oox_fld->GetText()); } else if (fld_type == L"datetime1") { odf_context()->text_context()->add_text_date( oox_fld->GetText()); } else { odf_context()->text_context()->add_text_content( oox_fld->GetText()); } odf_context()->text_context()->end_span(); } void OoxConverter::convert(PPTX::Logic::Br *oox_br) { if (!oox_br) return; odf_context()->text_context()->set_type_break(2, true); } void OoxConverter::convert(PPTX::Logic::MathParaWrapper *oox_math) { if (!oox_math) return; odf_context()->math_context()->in_text_box_ = false; odf_context()->start_drawing_context(); convert(oox_math->m_oMathPara.GetPointer()); convert(oox_math->m_oMath.GetPointer()); odf_context()->end_drawing_context(); } void OoxConverter::convert(PPTX::Logic::LineTo *oox_geom_path) { if (!oox_geom_path) return; std::wstring path_elm = oox_geom_path->x + L" " + oox_geom_path->y; odf_context()->drawing_context()->add_path_element(std::wstring(L"L"), path_elm); } void OoxConverter::convert(PPTX::Logic::MoveTo *oox_geom_path) { if (!oox_geom_path) return; std::wstring path_elm = oox_geom_path->x + L" " + oox_geom_path->y; odf_context()->drawing_context()->add_path_element(std::wstring(L"M"), path_elm); } void OoxConverter::convert(PPTX::Logic::TextListStyle *oox_list_style) { if (!oox_list_style) return; _CP_OPT(int) inStyles = odf_context()->drawing_context()->get_presentation(); odf_context()->styles_context()->lists_styles().start_style(inStyles && *inStyles > 0); // masters for (int i = 0; i < 9; i++) { OoxConverter::convert_list_level(oox_list_style->levels[i].GetPointer(), i); } odf_context()->styles_context()->lists_styles().end_style(); } void OoxConverter::convert(PPTX::Logic::Hyperlink* oox_hyperlink) { if (!oox_hyperlink) return; bool bExternal = false; if (odf_context()->drawing_context()->is_current_empty()) { if (oox_hyperlink->id.IsInit()) { std::wstring hlink = find_link_by_id(oox_hyperlink->id.get(), 2, bExternal); odf_context()->drawing_context()->start_link_object(hlink); } } else { odf_context()->drawing_context()->start_action(oox_hyperlink->action.get_value_or(L"")); if (oox_hyperlink->snd.IsInit()) { std::wstring sound = find_link_by_id(oox_hyperlink->snd->embed.get(), 3, bExternal); std::wstring href = odf_context()->add_media(sound, bExternal); odf_context()->drawing_context()->add_sound(href); } if (oox_hyperlink->id.IsInit()) { std::wstring hlink = find_link_by_id(oox_hyperlink->id.get(), 2, bExternal); boost::replace_all(hlink, L"\\", L"/"); // NOTE(Kamil Kerimov): Always use forward slash in odf for filepaths if (is_sound_hlink(hlink)) { std::wstring href = odf_context()->add_media(hlink, bExternal); odf_context()->drawing_context()->add_sound(href); } else { if (is_relative_path(hlink)) hlink = L"../" + hlink; odf_context()->drawing_context()->add_link(hlink); } smart_ptr file = find_file_by_id(oox_hyperlink->id.get()); OOX::HyperLink* hyperlink = dynamic_cast(file.GetPointer()); if (hyperlink) { odf_context()->add_hyperlink( odf_context()->drawing_context()->get_current_element(), hyperlink->Uri().GetBasename() ); } } odf_context()->drawing_context()->end_action(); } } void OoxConverter::convert(PPTX::Logic::TxBody *oox_txBody, PPTX::Logic::ShapeStyle* oox_style) { if (!oox_txBody) return; if (oox_txBody->Paragrs.empty()) return; odf_context()->start_text_context(); convert(oox_txBody->lstStyle.GetPointer()); //single math - либра не тянет сложные вложенности bool bSingleMath = false; if (odf_context()->drawing_context()->is_text_box() && oox_txBody->Paragrs.size() == 1 && oox_txBody->Paragrs[0].RunElems.size() == 1 && oox_txBody->Paragrs[0].RunElems[0].getType() == OOX::et_p_MathPara) { bSingleMath = true; odf_context()->math_context()->in_text_box_ = true; PPTX::Logic::MathParaWrapper *oox_math = dynamic_cast(oox_txBody->Paragrs[0].RunElems[0].GetElem().GetPointer()); convert(oox_math->m_oMathPara.GetPointer()); convert(oox_math->m_oMath.GetPointer()); odf_context()->math_context()->in_text_box_ = false; } //---------------------------------------------------------------------------------------------- for (size_t i = 0; !bSingleMath && i < oox_txBody->Paragrs.size(); i++) { convert(&oox_txBody->Paragrs[i], oox_txBody->lstStyle.GetPointer()); //внешние настройки для текста convert(oox_txBody->bodyPr.GetPointer()); if (oox_style) { convert(&oox_style->fontRef); } } odf_context()->drawing_context()->set_text( odf_context()->text_context()); odf_context()->end_text_context(); } static std::wstring convert_arc_angle(const std::wstring& angle, odf_writer::odf_drawing_context* dc) { std::wstring result = L"0"; int angleInt = XmlUtils::GetInteger(angle); if (angleInt == 0 && angle != L"0") { result = std::wstring(L"gd") + std::to_wstring(dc->get_formulas_count()); dc->add_formula(result, L"*/ 1 " + angle + L" 60000"); } else result = std::to_wstring(angleInt / 60000); return result; } void OoxConverter::convert(PPTX::Logic::ArcTo *oox_geom_path) { if (!oox_geom_path) return; const std::wstring stAng = convert_arc_angle(oox_geom_path->stAng, odf_context()->drawing_context()); const std::wstring swAng = convert_arc_angle(oox_geom_path->swAng, odf_context()->drawing_context()); std::wstring path_elm = oox_geom_path->wR + L" " + oox_geom_path->hR + L" " + stAng + L" " + swAng; odf_context()->drawing_context()->add_path_element(std::wstring(L"G"), path_elm); } void OoxConverter::convert(PPTX::Logic::QuadBezTo *oox_geom_path) { if (!oox_geom_path) return; std::wstring path_elm = oox_geom_path->x[0] + L" " + oox_geom_path->y[0] + L" " + oox_geom_path->x[1] + L" " + oox_geom_path->y[1]; odf_context()->drawing_context()->add_path_element(std::wstring(L"S"), path_elm); } void OoxConverter::convert(PPTX::Logic::CubicBezTo *oox_geom_path) { if (!oox_geom_path) return; std::wstring path_elm = oox_geom_path->x[0] + L" " + oox_geom_path->y[0] + L" " + oox_geom_path->x[1] + L" " + oox_geom_path->y[1] + L" " + oox_geom_path->x[2] + L" " + oox_geom_path->y[2]; odf_context()->drawing_context()->add_path_element(std::wstring(L"C"), path_elm); } void OoxConverter::convert(PPTX::Logic::Close *oox_geom_path) { if (!oox_geom_path) return; std::wstring path_elm ; odf_context()->drawing_context()->add_path_element(std::wstring(L"Z"), path_elm); } void OoxConverter::convert(PPTX::Logic::StyleRef *style_ref, int type) { if (!style_ref) return; DWORD nARGB = 0; convert(&style_ref->Color, nARGB); if (style_ref->idx.IsInit() == false) { std::wstring hexColor = XmlUtils::ToString((unsigned int)(nARGB & 0x00FFFFFF), L"#%06X"); _CP_OPT(double) opacity; if ((nARGB >> 24) != 0xff) { opacity = ((nARGB >> 24) /255.) * 100.; } if (type != 3) //?? todooo { odf_context()->drawing_context()->set_solid_fill(hexColor); if (opacity) odf_context()->drawing_context()->set_opacity(*opacity); } return; } int index = *style_ref->idx; PPTX::Theme *theme = oox_theme(); if (!theme) return; OOX::IFileContainer* old = oox_current_child_document; oox_current_child_document = theme; if (type == 1) { PPTX::Logic::UniFill *fill = NULL; if (index < 1000) { index -= 1; if (index >= 0 && index < (int)theme->themeElements.fmtScheme.fillStyleLst.size()) { fill = &theme->themeElements.fmtScheme.fillStyleLst[index]; } } else if (index > 1000) { index -= 1001; if (index >= 0 && index < (int)theme->themeElements.fmtScheme.bgFillStyleLst.size()) { fill = &theme->themeElements.fmtScheme.bgFillStyleLst[index]; } } convert(fill, nARGB); } else if (type == 2) { index -= 1; if (index >= 0 && index < (int)theme->themeElements.fmtScheme.lnStyleLst.size()) { convert(&theme->themeElements.fmtScheme.lnStyleLst[index], nARGB); } } else if (type == 3) { index -= 1; if (index >= 0 && index < (int)theme->themeElements.fmtScheme.effectStyleLst.size()) { convert(&theme->themeElements.fmtScheme.effectStyleLst[index], nARGB); } } oox_current_child_document = old; } void OoxConverter::convert(PPTX::Logic::FontRef *style_font_ref) { if (!style_font_ref) return; PPTX::Theme *theme = oox_theme(); if (!theme) return; std::wstring hexColor; _CP_OPT(double) opacity; convert(&style_font_ref->Color, hexColor, opacity); odf_context()->drawing_context()->set_textarea_fontcolor(hexColor); if (style_font_ref->idx.IsInit()) { PPTX::Logic::FontCollection *style_font = NULL; if (style_font_ref->idx->GetBYTECode() == SimpleTypes::fontcollectionindexMajor) { style_font = &theme->themeElements.fontScheme.majorFont; } if (style_font_ref->idx->GetBYTECode() == SimpleTypes::fontcollectionindexMinor) { style_font = &theme->themeElements.fontScheme.minorFont; } if (style_font) { std::wstring latin = style_font->latin.typeface; std::wstring ea = style_font->ea.typeface; std::wstring cs = style_font->cs.typeface; //theme->themeElements.fontScheme odf_context()->drawing_context()->set_textarea_font(latin, ea, cs); } } } }