Developing DocxRenderer

- pptx shapes (in progress)
- no br logic
This commit is contained in:
Alexey
2024-03-12 11:51:47 +03:00
parent 448156c905
commit 9ffc34b7e2
15 changed files with 356 additions and 85 deletions

View File

@ -128,6 +128,29 @@ std::vector<std::wstring> CDocxRenderer::ScanPage(IOfficeDrawingFile* pFile, siz
return xml_shapes; return xml_shapes;
} }
std::vector<std::wstring> CDocxRenderer::ScanPagePptx(IOfficeDrawingFile* pFile, size_t nPage)
{
m_pInternal->m_oDocument.Clear();
m_pInternal->m_oDocument.Init(false);
m_pInternal->m_oDocument.m_oCurrentPage.m_bUseDefaultFont = true;
m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = true;
DrawPage(pFile, nPage);
std::vector<std::wstring> xml_shapes;
for (const auto& shape : m_pInternal->m_oDocument.m_oCurrentPage.m_arShapes)
{
if (!shape) continue;
auto writer = new NSStringUtils::CStringBuilder();
shape->ToXmlPptx(*writer);
xml_shapes.push_back(writer->GetData());
delete writer;
}
m_pInternal->m_oDocument.Clear();
return xml_shapes;
}
void CDocxRenderer::DrawPage(IOfficeDrawingFile* pFile, size_t nPage) void CDocxRenderer::DrawPage(IOfficeDrawingFile* pFile, size_t nPage)
{ {
//std::cout << "Page " << i + 1 << "/" << nPagesCount << std::endl; //std::cout << "Page " << i + 1 << "/" << nPagesCount << std::endl;

View File

@ -194,6 +194,7 @@ public:
HRESULT SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType); HRESULT SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType);
int Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress = true); int Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress = true);
std::vector<std::wstring> ScanPage(IOfficeDrawingFile* pFile, size_t nPage); std::vector<std::wstring> ScanPage(IOfficeDrawingFile* pFile, size_t nPage);
std::vector<std::wstring> ScanPagePptx(IOfficeDrawingFile* pFile, size_t nPage);
private: private:
CDocxRenderer_Private* m_pInternal; CDocxRenderer_Private* m_pInternal;

View File

@ -1407,16 +1407,13 @@ namespace NSDocxRenderer
// alignment check // alignment check
bool is_first_line = false; bool is_first_line = false;
std::shared_ptr<CTextLine> gap_check_line = m_arTextLines[0];
for (size_t index = 0; index < ar_positions.size() - 1; ++index) for (size_t index = 0; index < ar_positions.size() - 1; ++index)
{ {
Position position_top; Position position_bot = ar_positions[index];
Position position_bot;
position_bot = ar_positions[index]; auto& line_top = m_arTextLines[index];
if (index == 0) auto& line_bot = m_arTextLines[index + 1];
position_top = position_bot;
else
position_top = ar_positions[index - 1];
if (index == 0 || ar_delims[index - 1]) if (index == 0 || ar_delims[index - 1])
is_first_line = true; is_first_line = true;
@ -1424,7 +1421,7 @@ namespace NSDocxRenderer
is_first_line = false; is_first_line = false;
// первая строка может быть с отступом // первая строка может быть с отступом
if (is_first_line && m_arTextLines[index + 1]->m_dLeft < m_arTextLines[index]->m_dLeft) if (is_first_line && line_bot->m_dLeft < line_top->m_dLeft)
{ {
// если больше трех линий - проверим третью // если больше трех линий - проверим третью
if (index < ar_positions.size() - 2) if (index < ar_positions.size() - 2)
@ -1441,15 +1438,48 @@ namespace NSDocxRenderer
bool is_unknown = !(position_bot.left || position_bot.right || position_bot.center); bool is_unknown = !(position_bot.left || position_bot.right || position_bot.center);
if (is_unknown) if (is_unknown)
ar_delims[index] = true; ar_delims[index] = true;
}
// отдельно просмотрим возможные параграфы по две строки if (ar_delims[index])
for (size_t index = 0; index < ar_delims.size() - 1; ++index) gap_check_line = line_bot;
{
if (!ar_delims[index] && ar_delims[index + 1]) // bla-bla-bla
// text bla-bla-bla-bla
//
// bla-bla-bla text
// bla-bla-bla-bla
else if (!ar_delims[index])
{ {
// ширина верхней строчки сильно меньше нижней double gap = 0;
if (m_arTextLines[index]->m_dWidth * 3 < m_arTextLines[index + 1]->m_dWidth) std::shared_ptr<CContText> cont = nullptr;
if (position_bot.left)
{
gap = line_bot->m_dRight - gap_check_line->m_dRight;
cont = line_bot->m_arConts[0];
}
else if (position_bot.right)
{
gap = line_bot->m_dLeft - gap_check_line->m_dLeft;
cont = line_bot->m_arConts[line_bot->m_arConts.size() - 1];
}
else
continue;
if (gap < 0)
{
gap_check_line = line_bot;
continue;
}
size_t cont_len = cont->m_oText.length();
size_t space_pos = cont->m_oText.ToStdWString().find_first_of(L' ');
if (space_pos == std::wstring::npos)
space_pos = cont_len;
// to save time doing it roughly
double rough_width = cont->m_dWidth / cont_len * space_pos;
if (gap > rough_width * 1.2)
ar_delims[index] = true; ar_delims[index] = true;
} }
} }

View File

@ -54,6 +54,7 @@ namespace NSDocxRenderer
virtual void Clear() = 0; virtual void Clear() = 0;
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const = 0; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const = 0;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const = 0;
virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) const; virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) const;
virtual eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc) const; virtual eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc) const;

View File

@ -176,7 +176,7 @@ namespace NSDocxRenderer
oWriter.WriteString(L"\"/>"); oWriter.WriteString(L"\"/>");
} }
if(m_bIsEmbossPresent) if (m_bIsEmbossPresent)
oWriter.WriteString(L"<w:emboss/>"); oWriter.WriteString(L"<w:emboss/>");
else if(m_bIsEngravePresent) else if(m_bIsEngravePresent)
oWriter.WriteString(L"<w:imprint/>"); oWriter.WriteString(L"<w:imprint/>");
@ -196,7 +196,132 @@ namespace NSDocxRenderer
oWriter.WriteString(L"<w:strike/>"); oWriter.WriteString(L"<w:strike/>");
} }
if(m_bIsUnderlinePresent) if (m_bIsUnderlinePresent)
{
oWriter.WriteString(L"<w:u w:val=");
oWriter.WriteString(SingletonInstance<LinesTable>().ConvertLineToString(m_eUnderlineType));
if (m_lUnderlineColor != m_pFontStyle->oBrush.Color1)
{
oWriter.WriteString(L" w:color=\"");
oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lUnderlineColor));
oWriter.WriteString(L"\"");
}
oWriter.WriteString(L"/>");
}
if (m_bIsHighlightPresent)
{
//note В <w:style это не работает
ColorTable& colorTable = SingletonInstance<ColorTable>();
if (colorTable.IsStandardColor(m_lHighlightColor))
{
oWriter.WriteString(L"<w:highlight w:val=\"");
oWriter.WriteString(colorTable.ConverColorToString(ConvertColorBGRToRGB(m_lHighlightColor)));
}
else
{
oWriter.WriteString(L"<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"");
oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lHighlightColor));
}
oWriter.WriteString(L"\"/>");
}
if (m_eVertAlignType == eVertAlignType::vatSubscript || m_eVertAlignType == eVertAlignType::vatSuperscript)
{
int lSize = static_cast<int>(3.0 * m_pFontStyle->dFontSize);
oWriter.WriteString(L"<w:sz w:val=\"");
oWriter.AddInt(lSize);
oWriter.WriteString(L"\"/><w:szCs w:val=\"");
oWriter.AddInt(lSize);
oWriter.WriteString(L"\"/>");
}
else if (m_bWriteStyleRaw)
{
int lSize = static_cast<int>(2.0 * m_pFontStyle->dFontSize);
oWriter.WriteString(L"<w:sz w:val=\"");
oWriter.AddInt(lSize);
oWriter.WriteString(L"\"/><w:szCs w:val=\"");
oWriter.AddInt(lSize);
oWriter.WriteString(L"\"/>");
}
if (m_bWriteStyleRaw)
{
oWriter.WriteString(L"<w:rFonts w:ascii=\"");
oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName);
oWriter.WriteString(L"\" w:hAnsi=\"");
oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName);
oWriter.WriteString(L"\" w:cs=\"");
oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName);
oWriter.WriteString(L"\" w:hint=\"default\"/>");
if (m_pFontStyle->bBold)
{
oWriter.WriteString(L"<w:b/>");
oWriter.WriteString(L"<w:bCs/>");
}
if (m_pFontStyle->bItalic)
{
oWriter.WriteString(L"<w:i/>");
oWriter.WriteString(L"<w:iCs/>");
}
if (ConvertColorBGRToRGB(m_pFontStyle->oBrush.Color1) != c_iBlackColor2)
{
oWriter.WriteString(L"<w:color w:val=\"");
oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_pFontStyle->oBrush.Color1));
oWriter.WriteString(L"\"/>");
}
}
if (m_eVertAlignType == eVertAlignType::vatSubscript)
oWriter.WriteString(L"<w:vertAlign w:val=\"subscript\"/>");
else if (m_eVertAlignType == eVertAlignType::vatSuperscript)
oWriter.WriteString(L"<w:vertAlign w:val=\"superscript\"/>");
oWriter.WriteString(L"</w:rPr>");
oWriter.WriteString(L"<w:t xml:space=\"preserve\">");
oWriter.WriteEncodeXmlString(m_oText.ToStdWString());
oWriter.WriteString(L"</w:t>");
if (m_bIsAddBrEnd) oWriter.WriteString(L"<w:br/>");
oWriter.WriteString(L"</w:r>");
}
void CContText::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const
{
oWriter.WriteString(L"<a:r>");
oWriter.WriteString(L"<w:rPr noProof=\"1\" ");
LONG lCalculatedSpacing = 0;
if (!m_oText.empty())
{
double dSpacing = (m_dWidth - m_oSelectedSizes.dWidth) / (m_oText.length());
dSpacing *= c_dMMToDx;
//mm to points * 20
lCalculatedSpacing = static_cast<LONG>(dSpacing);
}
// принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу
lCalculatedSpacing -= 1;
oWriter.WriteString(L" spc=\"");
oWriter.AddInt(lCalculatedSpacing * 100);
oWriter.WriteString(L"\"");
//////////////////////////////////////////////////////////////////////
if (m_bIsOutlinePresent)
oWriter.WriteString(L"<w:outline/>");
if (m_bIsShadowPresent)
oWriter.WriteString(L"<w:shadow/>");
if (m_bIsStrikeoutPresent)
{
if (m_bIsDoubleStrikeout)
oWriter.WriteString(L"<w:dstrike/>");
else
oWriter.WriteString(L"<w:strike/>");
}
if (m_bIsUnderlinePresent)
{ {
oWriter.WriteString(L"<w:u w:val="); oWriter.WriteString(L"<w:u w:val=");
oWriter.WriteString(SingletonInstance<LinesTable>().ConvertLineToString(m_eUnderlineType)); oWriter.WriteString(SingletonInstance<LinesTable>().ConvertLineToString(m_eUnderlineType));

View File

@ -80,6 +80,7 @@ namespace NSDocxRenderer
virtual void Clear() override final; virtual void Clear() override final;
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual eVerticalCrossingType GetVerticalCrossingType(const CContText* pItem) const noexcept; virtual eVerticalCrossingType GetVerticalCrossingType(const CContText* pItem) const noexcept;
// calc sizes in selected font (uses m_pFontStyle & m_pManager) // calc sizes in selected font (uses m_pFontStyle & m_pManager)

View File

@ -3,29 +3,37 @@
namespace NSDocxRenderer namespace NSDocxRenderer
{ {
void CDropCap::ToXml(NSStringUtils::CStringBuilder& oWriter) const void CDropCap::BuildXml(NSStringUtils::CStringBuilder& oWriter, const std::wstring& wsTag) const
{ {
oWriter.WriteString(L"<w:p>"); oWriter.WriteString(L"<" + wsTag + L":p>");
oWriter.WriteString(L"<w:pPr>"); oWriter.WriteString(L"<" + wsTag + L":pPr>");
oWriter.WriteString(L"<w:spacing w:after=\"0\""); oWriter.WriteString(L"<" + wsTag + L":spacing " + wsTag + L":after=\"0\"");
oWriter.WriteString(L" w:line=\""); oWriter.WriteString(L" " + wsTag + L":line=\"");
oWriter.AddInt(static_cast<LONG>((m_dBaselinePos - m_dTop) * c_dMMToDx)); oWriter.AddInt(static_cast<LONG>((m_dBaselinePos - m_dTop) * c_dMMToDx));
oWriter.WriteString(L"\" "); oWriter.WriteString(L"\" ");
oWriter.WriteString(L"w:lineRule=\"exact\" />"); oWriter.WriteString(wsTag + L":lineRule=\"exact\" />");
oWriter.WriteString(L"</w:pPr>"); oWriter.WriteString(L"</" + wsTag + L":pPr>");
oWriter.WriteString(L"<w:r>"); oWriter.WriteString(L"<" + wsTag + L":r>");
oWriter.WriteString(L"<w:rPr>"); oWriter.WriteString(L"<" + wsTag + L":rPr>");
oWriter.WriteString(L"<w:rFonts w:ascii=\"" + wsFont + oWriter.WriteString(L"<" + wsTag + L":rFonts " + wsTag + L":ascii=\"" + wsFont +
L"\" w:hAnsi=\"" + wsFont + L"\" " + wsTag + L":hAnsi=\"" + wsFont +
L"\" w:eastAsia=\"" + wsFont + L"\" " + wsTag + L":eastAsia=\"" + wsFont +
L"\" w:cs=\"" + wsFont + L"\" />"); L"\" " + wsTag + L":cs=\"" + wsFont + L"\" />");
oWriter.WriteString(L"<w:sz w:val=\""); oWriter.WriteString(L"<" + wsTag + L":sz " + wsTag + L":val=\"");
oWriter.AddInt(nFontSize); oWriter.AddInt(nFontSize);
oWriter.WriteString(L"\" />"); oWriter.WriteString(L"\" />");
oWriter.WriteString(L"</w:rPr>"); oWriter.WriteString(L"</" + wsTag + L":rPr>");
oWriter.WriteString(L"<w:t xml:space=\"preserve\">" + wsText + L"</w:t>"); oWriter.WriteString(L"<" + wsTag + L":t xml:space=\"preserve\">" + wsText + L"</" + wsTag + L":t>");
oWriter.WriteString(L"</w:r>"); oWriter.WriteString(L"</" + wsTag + L":r>");
oWriter.WriteString(L"</w:p>"); oWriter.WriteString(L"</" + wsTag + L":p>");
}
void CDropCap::ToXml(NSStringUtils::CStringBuilder& oWriter) const
{
BuildXml(oWriter, L"w");
}
void CDropCap::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const
{
BuildXml(oWriter, L"a");
} }
} }

View File

@ -18,8 +18,12 @@ namespace NSDocxRenderer
CDropCap() = default; CDropCap() = default;
~CDropCap() = default; ~CDropCap() = default;
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void Clear() override {} virtual void Clear() override {}
private:
void BuildXml(NSStringUtils::CStringBuilder& oWriter, const std::wstring& wsTag) const;
}; };
} }

View File

@ -22,5 +22,7 @@ namespace NSDocxRenderer
CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia); CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia);
void Clear() override final {}; void Clear() override final {};
void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final
{}
}; };
} }

View File

@ -14,54 +14,54 @@ namespace NSDocxRenderer
m_arLines.clear(); m_arLines.clear();
} }
void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter) const void CParagraph::BuildXml(NSStringUtils::CStringBuilder& oWriter, const std::wstring& wsTag) const
{ {
oWriter.WriteString(L"<w:p>"); oWriter.WriteString(L"<" + wsTag + L":p>");
oWriter.WriteString(L"<w:pPr>"); oWriter.WriteString(L"<" + wsTag + L":pPr>");
// styles // styles
if(!m_wsStyleId.empty()) oWriter.WriteString(L"<w:pStyle w:val=\"" + m_wsStyleId + L"\"/>"); if(!m_wsStyleId.empty()) oWriter.WriteString(L"<" + wsTag + L":pStyle " + wsTag + L":val=\"" + m_wsStyleId + L"\"/>");
oWriter.WriteString(L"<w:spacing"); oWriter.WriteString(L"<" + wsTag + L":spacing");
if (m_dSpaceBefore > 0) if (m_dSpaceBefore > 0)
{ {
oWriter.WriteString(L" w:before=\""); oWriter.WriteString(L" " + wsTag + L":before=\"");
oWriter.AddInt(static_cast<int>(m_dSpaceBefore * c_dMMToDx)); oWriter.AddInt(static_cast<int>(m_dSpaceBefore * c_dMMToDx));
oWriter.WriteString(L"\""); oWriter.WriteString(L"\"");
} }
if (m_dSpaceAfter > 0) if (m_dSpaceAfter > 0)
{ {
oWriter.WriteString(L" w:after=\""); oWriter.WriteString(L" " + wsTag + L":after=\"");
oWriter.AddInt(static_cast<int>(m_dSpaceAfter * c_dMMToDx)); oWriter.AddInt(static_cast<int>(m_dSpaceAfter * c_dMMToDx));
oWriter.WriteString(L"\""); oWriter.WriteString(L"\"");
} }
if (m_dLineHeight > 0) if (m_dLineHeight > 0)
{ {
oWriter.WriteString(L" w:line=\""); oWriter.WriteString(L" " + wsTag + L":line=\"");
oWriter.AddInt(static_cast<int>(m_dLineHeight * c_dMMToDx)); oWriter.AddInt(static_cast<int>(m_dLineHeight * c_dMMToDx));
oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки oWriter.WriteString(L"\" " + wsTag + L":lineRule=\"exact\""); // exact - точный размер строки
} }
oWriter.WriteString(L"/>"); //конец w:spacing oWriter.WriteString(L"/>"); //конец w:spacing
oWriter.WriteString(L"<w:ind"); oWriter.WriteString(L"<" + wsTag + L":ind");
if (m_dLeftBorder > 0) if (m_dLeftBorder > 0)
{ {
oWriter.WriteString(L" w:left=\""); oWriter.WriteString(L" " + wsTag + L":left=\"");
oWriter.AddInt(static_cast<int>(m_dLeftBorder * c_dMMToDx)); oWriter.AddInt(static_cast<int>(m_dLeftBorder * c_dMMToDx));
oWriter.WriteString(L"\""); oWriter.WriteString(L"\"");
} }
if (m_dRightBorder > 0) if (m_dRightBorder > 0)
{ {
oWriter.WriteString(L" w:right=\""); oWriter.WriteString(L" " + wsTag + L":right=\"");
oWriter.AddInt(static_cast<int>(m_dRightBorder * c_dMMToDx)); //здесь m_dRight - расстояние от правого края oWriter.AddInt(static_cast<int>(m_dRightBorder * c_dMMToDx)); //здесь m_dRight - расстояние от правого края
oWriter.WriteString(L"\""); oWriter.WriteString(L"\"");
} }
if (m_bIsNeedFirstLineIndent) if (m_bIsNeedFirstLineIndent)
{ {
oWriter.WriteString(L" w:firstLine=\""); oWriter.WriteString(L" " + wsTag + L":firstLine=\"");
oWriter.AddInt(static_cast<int>(m_dFirstLine * c_dMMToDx)); oWriter.AddInt(static_cast<int>(m_dFirstLine * c_dMMToDx));
oWriter.WriteString(L"\""); oWriter.WriteString(L"\"");
} }
@ -70,16 +70,16 @@ namespace NSDocxRenderer
switch (m_eTextAlignmentType) switch (m_eTextAlignmentType)
{ {
case tatByCenter: case tatByCenter:
oWriter.WriteString(L"<w:jc w:val=\"center\"/>"); oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"center\"/>");
break; break;
case tatByRight: case tatByRight:
oWriter.WriteString(L"<w:jc w:val=\"end\"/>"); oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"end\"/>");
break; break;
case tatByWidth: case tatByWidth:
oWriter.WriteString(L"<w:jc w:val=\"both\"/>"); oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"both\"/>");
break; break;
case tatByLeft: case tatByLeft:
oWriter.WriteString(L"<w:jc w:val=\"begin\"/>"); oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"begin\"/>");
break; break;
case tatUnknown: case tatUnknown:
default: //по умолчанию выравнивание по левому краю - можно ничего не добавлять default: //по умолчанию выравнивание по левому краю - можно ничего не добавлять
@ -88,20 +88,34 @@ namespace NSDocxRenderer
if (m_bIsShadingPresent) if (m_bIsShadingPresent)
{ {
oWriter.WriteString(L"<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\""); oWriter.WriteString(L"<" + wsTag + L":shd " + wsTag + L":val=\"clear\" " + wsTag + L":color=\"auto\" " + wsTag + L":fill=\"");
oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lColorOfShadingFill)); oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lColorOfShadingFill));
oWriter.WriteString(L"\"/>"); oWriter.WriteString(L"\"/>");
} }
}
void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter) const
{
BuildXml(oWriter, L"w");
oWriter.WriteString(L"</w:pPr>"); oWriter.WriteString(L"</w:pPr>");
for(const auto& line : m_arLines) for(const auto& line : m_arLines)
if(line) if(line)
line->ToXml(oWriter); line->ToXml(oWriter);
oWriter.WriteString(L"</w:p>"); oWriter.WriteString(L"</w:p>");
} }
void CParagraph::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const
{
BuildXml(oWriter, L"a");
oWriter.WriteString(L"</a:pPr>");
for(const auto& line : m_arLines)
if(line)
line->ToXmlPptx(oWriter);
oWriter.WriteString(L"</a:p>");
}
void CParagraph::RemoveHighlightColor() void CParagraph::RemoveHighlightColor()
{ {
if (!m_bIsShadingPresent) if (!m_bIsShadingPresent)
@ -134,8 +148,7 @@ namespace NSDocxRenderer
while(!pLastCont) while(!pLastCont)
pLastCont = pLine->m_arConts[--iNumConts]; pLastCont = pLine->m_arConts[--iNumConts];
// добавляем br в конец каждой строки pLastCont->m_oText += L" ";
pLastCont->m_bIsAddBrEnd = true;
} }
} }
} }

View File

@ -40,8 +40,12 @@ namespace NSDocxRenderer
virtual ~CParagraph(); virtual ~CParagraph();
virtual void Clear() override final; virtual void Clear() override final;
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
void RemoveHighlightColor(); void RemoveHighlightColor();
void MergeLines(); void MergeLines();
private:
void BuildXml(NSStringUtils::CStringBuilder& oWriter, const std::wstring& wsTag) const;
}; };
} }

View File

@ -781,13 +781,20 @@ namespace NSDocxRenderer
oWriter.WriteString(L"\""); oWriter.WriteString(L"\"");
} }
oWriter.WriteString(L">"); oWriter.WriteString(L">");
oWriter.WriteString(L"<a:off x=\"0\" y=\"0\"/>");
oWriter.WriteString(L"<a:off x=\"");
oWriter.AddInt(static_cast<int>(m_dLeft * c_dMMToEMU));
oWriter.WriteString(L"\" y=\"");
oWriter.AddInt(static_cast<int>(m_dTop * c_dMMToEMU));
oWriter.WriteString(L"\"/>");
oWriter.WriteString(L"<a:ext"); oWriter.WriteString(L"<a:ext");
oWriter.WriteString(L" cx=\""); oWriter.WriteString(L" cx=\"");
oWriter.AddInt(static_cast<int>(m_dWidth * c_dMMToEMU)); oWriter.AddInt(static_cast<int>(m_dWidth * c_dMMToEMU));
oWriter.WriteString(L"\" cy=\""); oWriter.WriteString(L"\" cy=\"");
oWriter.AddInt(static_cast<int>(m_dHeight * c_dMMToEMU)); oWriter.AddInt(static_cast<int>(m_dHeight * c_dMMToEMU));
oWriter.WriteString(L"\"/>"); oWriter.WriteString(L"\"/>");
oWriter.WriteString(L"</a:xfrm>"); oWriter.WriteString(L"</a:xfrm>");
//Если просто текст без графики //Если просто текст без графики
@ -869,6 +876,36 @@ namespace NSDocxRenderer
} }
} }
void CShape::BuildTextBoxParams(NSStringUtils::CStringBuilder &oWriter) const
{
oWriter.WriteString(L" rot=\"0\""); //Определяет поворот, который применяется к тексту в пределах ограничивающей рамки.
oWriter.WriteString(L" spcFirstLastPara=\"0\""); //должен ли соблюдаться интервал между абзацами до и после, заданный пользователем.
oWriter.WriteString(L" vertOverflow=\"overflow\""); //может ли текст выходить за пределы ограничительной рамки по вертикали
oWriter.WriteString(L" horzOverflow=\"overflow\""); //может ли текст выходить за пределы ограничительной рамки по горизонтали.
oWriter.WriteString(L" vert=\"horz\"");
//oWriter.WriteString(L" wrap=\"none\""); //граница шейпа по ширине текста
oWriter.WriteString(L" wrap=\"square\""); //Определяет параметры обертки, которые будут использоваться для данного текстового тела.
//на сколько граница текста отступает от границы шейпа
oWriter.WriteString(L" lIns=\"0\""); //left по умолчанию 0.25см = 91440
oWriter.WriteString(L" tIns=\"0\""); //top по умолчанию 0.13см = 45720
oWriter.WriteString(L" rIns=\"0\""); //right по умолчанию 0.25см
oWriter.WriteString(L" bIns=\"0\""); //bottom по умолчанию 0.13см
oWriter.WriteString(L" numCol=\"1\""); //Определяет количество колонок текста в ограничивающем прямоугольнике.
oWriter.WriteString(L" spcCol=\"0\""); //Определяет пространство между колонками текста в текстовой области (только если numCol >1)
oWriter.WriteString(L" rtlCol=\"0\""); //используются ли столбцы в порядке справа налево (true) или слева направо (false).
oWriter.WriteString(L" fromWordArt=\"0\""); //true/1 текст в этом текстовом поле является преобразованным текстом из объекта WordArt.
oWriter.WriteString(L" anchor=\"t\""); //Вертикальное выравнивание текста в шейпе (t - top, b - bottom, ctr - middle) по умолчанию top
oWriter.WriteString(L" anchorCtr=\"0\""); //true/1 Определяет центрирование текстового поля.
oWriter.WriteString(L" forceAA=\"0\""); //true/1 Заставляет текст отображаться сглаженным независимо от размера шрифта.
oWriter.WriteString(L" compatLnSpc=\"1\""); //межстрочный интервал для данного текста определяется упрощенным способом с помощью сцены шрифта.
oWriter.WriteString(L">");
oWriter.WriteString(L"<a:prstTxWarp prst=\"textNoShape\">");
oWriter.WriteString(L"<a:avLst/>");
oWriter.WriteString(L"</a:prstTxWarp>");
oWriter.WriteString(L"<a:noAutofit/>");
}
void CShape::BuildTextBox(NSStringUtils::CStringBuilder &oWriter) const void CShape::BuildTextBox(NSStringUtils::CStringBuilder &oWriter) const
{ {
if (m_eType == eShapeType::stTextBox && !m_arOutputObjects.empty()) if (m_eType == eShapeType::stTextBox && !m_arOutputObjects.empty())
@ -884,32 +921,7 @@ namespace NSDocxRenderer
oWriter.WriteString(L"</wps:txbx>"); oWriter.WriteString(L"</wps:txbx>");
oWriter.WriteString(L"<wps:bodyPr"); //определяет свойства тела текста внутри фигуры oWriter.WriteString(L"<wps:bodyPr"); //определяет свойства тела текста внутри фигуры
oWriter.WriteString(L" rot=\"0\""); //Определяет поворот, который применяется к тексту в пределах ограничивающей рамки. BuildTextBoxParams(oWriter);
oWriter.WriteString(L" spcFirstLastPara=\"0\""); //должен ли соблюдаться интервал между абзацами до и после, заданный пользователем.
oWriter.WriteString(L" vertOverflow=\"overflow\""); //может ли текст выходить за пределы ограничительной рамки по вертикали
oWriter.WriteString(L" horzOverflow=\"overflow\""); //может ли текст выходить за пределы ограничительной рамки по горизонтали.
oWriter.WriteString(L" vert=\"horz\"");
//oWriter.WriteString(L" wrap=\"none\""); //граница шейпа по ширине текста
oWriter.WriteString(L" wrap=\"square\""); //Определяет параметры обертки, которые будут использоваться для данного текстового тела.
//на сколько граница текста отступает от границы шейпа
oWriter.WriteString(L" lIns=\"0\""); //left по умолчанию 0.25см = 91440
oWriter.WriteString(L" tIns=\"0\""); //top по умолчанию 0.13см = 45720
oWriter.WriteString(L" rIns=\"0\""); //right по умолчанию 0.25см
oWriter.WriteString(L" bIns=\"0\""); //bottom по умолчанию 0.13см
oWriter.WriteString(L" numCol=\"1\""); //Определяет количество колонок текста в ограничивающем прямоугольнике.
oWriter.WriteString(L" spcCol=\"0\""); //Определяет пространство между колонками текста в текстовой области (только если numCol >1)
oWriter.WriteString(L" rtlCol=\"0\""); //используются ли столбцы в порядке справа налево (true) или слева направо (false).
oWriter.WriteString(L" fromWordArt=\"0\""); //true/1 текст в этом текстовом поле является преобразованным текстом из объекта WordArt.
oWriter.WriteString(L" anchor=\"t\""); //Вертикальное выравнивание текста в шейпе (t - top, b - bottom, ctr - middle) по умолчанию top
oWriter.WriteString(L" anchorCtr=\"0\""); //true/1 Определяет центрирование текстового поля.
oWriter.WriteString(L" forceAA=\"0\""); //true/1 Заставляет текст отображаться сглаженным независимо от размера шрифта.
oWriter.WriteString(L" compatLnSpc=\"1\""); //межстрочный интервал для данного текста определяется упрощенным способом с помощью сцены шрифта.
oWriter.WriteString(L">");
oWriter.WriteString(L"<a:prstTxWarp prst=\"textNoShape\">");
oWriter.WriteString(L"<a:avLst/>");
oWriter.WriteString(L"</a:prstTxWarp>");
oWriter.WriteString(L"<a:noAutofit/>");
oWriter.WriteString(L"</wps:bodyPr>"); oWriter.WriteString(L"</wps:bodyPr>");
} }
else else
@ -917,4 +929,27 @@ namespace NSDocxRenderer
oWriter.WriteString(L"<wps:bodyPr/>"); oWriter.WriteString(L"<wps:bodyPr/>");
} }
} }
void CShape::ToXmlPptx(NSStringUtils::CStringBuilder &oWriter) const
{
oWriter.WriteString(L"<p:sp>");
oWriter.WriteString(L"<p:spPr>");
BuildGraphicProperties(oWriter);
oWriter.WriteString(L"</p:spPr>");
if (m_eType == eShapeType::stTextBox && !m_arOutputObjects.empty())
{
oWriter.WriteString(L"<a:txBody>");
oWriter.WriteString(L"<a:bodyPr");
BuildTextBoxParams(oWriter);
oWriter.WriteString(L"</a:bodyPr>");
for (const auto& obj : m_arOutputObjects)
obj->ToXmlPptx(oWriter);
oWriter.WriteString(L"</a:txBody>");
}
oWriter.WriteString(L"</p:sp>");
}
}; // namespace NSDocxRenderer }; // namespace NSDocxRenderer

View File

@ -62,6 +62,7 @@ namespace NSDocxRenderer
virtual ~CShape(); virtual ~CShape();
virtual void Clear() override final; virtual void Clear() override final;
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter)const override final;
void SetVector(CVectorGraphics&& oVector); void SetVector(CVectorGraphics&& oVector);
@ -85,6 +86,7 @@ namespace NSDocxRenderer
void BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter) const; void BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter) const;
void BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) const; void BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) const;
void BuildTextBox(NSStringUtils::CStringBuilder &oWriter) const; void BuildTextBox(NSStringUtils::CStringBuilder &oWriter) const;
void BuildTextBoxParams(NSStringUtils::CStringBuilder &oWriter) const;
static void ResetRelativeHeight(); static void ResetRelativeHeight();

View File

@ -75,6 +75,8 @@ namespace NSDocxRenderer
wide_space->m_pFontStyle = pFirst->m_pFontStyle; wide_space->m_pFontStyle = pFirst->m_pFontStyle;
wide_space->m_pShape = nullptr; wide_space->m_pShape = nullptr;
wide_space->m_iNumDuplicates = 0; wide_space->m_iNumDuplicates = 0;
// cache that value? (calls rarely)
wide_space->CalcSelected(); wide_space->CalcSelected();
}; };
@ -245,4 +247,21 @@ namespace NSDocxRenderer
if(cont) if(cont)
cont->ToXml(oWriter); cont->ToXml(oWriter);
} }
void CTextLine::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const
{
for (const auto& cont : m_arConts)
if(cont)
cont->ToXmlPptx(oWriter);
}
size_t CTextLine::GetLength() const
{
size_t len = 0;
for (const auto& cont : m_arConts)
if (cont)
len += cont->m_oText.length();
return len;
}
} }

View File

@ -35,6 +35,7 @@ namespace NSDocxRenderer
virtual ~CTextLine(); virtual ~CTextLine();
virtual void Clear() override final; virtual void Clear() override final;
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void RecalcWithNewItem(const CContText* pCont); virtual void RecalcWithNewItem(const CContText* pCont);
virtual eVerticalCrossingType GetVerticalCrossingType(const CTextLine* pLine) const noexcept; virtual eVerticalCrossingType GetVerticalCrossingType(const CTextLine* pLine) const noexcept;
@ -45,5 +46,7 @@ namespace NSDocxRenderer
bool IsShadingPresent(const CTextLine* pLine) const noexcept; bool IsShadingPresent(const CTextLine* pLine) const noexcept;
bool IsCanBeDeleted() const; bool IsCanBeDeleted() const;
size_t GetLength() const;
}; };
} }