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;
}
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)
{
//std::cout << "Page " << i + 1 << "/" << nPagesCount << std::endl;

View File

@ -194,6 +194,7 @@ public:
HRESULT SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType);
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> ScanPagePptx(IOfficeDrawingFile* pFile, size_t nPage);
private:
CDocxRenderer_Private* m_pInternal;

View File

@ -1407,16 +1407,13 @@ namespace NSDocxRenderer
// alignment check
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)
{
Position position_top;
Position position_bot;
Position position_bot = ar_positions[index];
position_bot = ar_positions[index];
if (index == 0)
position_top = position_bot;
else
position_top = ar_positions[index - 1];
auto& line_top = m_arTextLines[index];
auto& line_bot = m_arTextLines[index + 1];
if (index == 0 || ar_delims[index - 1])
is_first_line = true;
@ -1424,7 +1421,7 @@ namespace NSDocxRenderer
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)
@ -1441,15 +1438,48 @@ namespace NSDocxRenderer
bool is_unknown = !(position_bot.left || position_bot.right || position_bot.center);
if (is_unknown)
ar_delims[index] = true;
}
// отдельно просмотрим возможные параграфы по две строки
for (size_t index = 0; index < ar_delims.size() - 1; ++index)
{
if (!ar_delims[index] && ar_delims[index + 1])
if (ar_delims[index])
gap_check_line = line_bot;
// bla-bla-bla
// text bla-bla-bla-bla
//
// bla-bla-bla text
// bla-bla-bla-bla
else if (!ar_delims[index])
{
// ширина верхней строчки сильно меньше нижней
if (m_arTextLines[index]->m_dWidth * 3 < m_arTextLines[index + 1]->m_dWidth)
double gap = 0;
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;
}
}

View File

@ -54,6 +54,7 @@ namespace NSDocxRenderer
virtual void Clear() = 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 eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc) const;

View File

@ -176,7 +176,7 @@ namespace NSDocxRenderer
oWriter.WriteString(L"\"/>");
}
if(m_bIsEmbossPresent)
if (m_bIsEmbossPresent)
oWriter.WriteString(L"<w:emboss/>");
else if(m_bIsEngravePresent)
oWriter.WriteString(L"<w:imprint/>");
@ -196,7 +196,132 @@ namespace NSDocxRenderer
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(SingletonInstance<LinesTable>().ConvertLineToString(m_eUnderlineType));

View File

@ -80,6 +80,7 @@ namespace NSDocxRenderer
virtual void Clear() 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;
// calc sizes in selected font (uses m_pFontStyle & m_pManager)

View File

@ -3,29 +3,37 @@
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"<w:pPr>");
oWriter.WriteString(L"<w:spacing w:after=\"0\"");
oWriter.WriteString(L" w:line=\"");
oWriter.WriteString(L"<" + wsTag + L":p>");
oWriter.WriteString(L"<" + wsTag + L":pPr>");
oWriter.WriteString(L"<" + wsTag + L":spacing " + wsTag + L":after=\"0\"");
oWriter.WriteString(L" " + wsTag + L":line=\"");
oWriter.AddInt(static_cast<LONG>((m_dBaselinePos - m_dTop) * c_dMMToDx));
oWriter.WriteString(L"\" ");
oWriter.WriteString(L"w:lineRule=\"exact\" />");
oWriter.WriteString(L"</w:pPr>");
oWriter.WriteString(L"<w:r>");
oWriter.WriteString(L"<w:rPr>");
oWriter.WriteString(L"<w:rFonts w:ascii=\"" + wsFont +
L"\" w:hAnsi=\"" + wsFont +
L"\" w:eastAsia=\"" + wsFont +
L"\" w:cs=\"" + wsFont + L"\" />");
oWriter.WriteString(wsTag + L":lineRule=\"exact\" />");
oWriter.WriteString(L"</" + wsTag + L":pPr>");
oWriter.WriteString(L"<" + wsTag + L":r>");
oWriter.WriteString(L"<" + wsTag + L":rPr>");
oWriter.WriteString(L"<" + wsTag + L":rFonts " + wsTag + L":ascii=\"" + wsFont +
L"\" " + wsTag + L":hAnsi=\"" + wsFont +
L"\" " + wsTag + L":eastAsia=\"" + wsFont +
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.WriteString(L"\" />");
oWriter.WriteString(L"</w:rPr>");
oWriter.WriteString(L"<w:t xml:space=\"preserve\">" + wsText + L"</w:t>");
oWriter.WriteString(L"</w:r>");
oWriter.WriteString(L"</w:p>");
oWriter.WriteString(L"</" + wsTag + L":rPr>");
oWriter.WriteString(L"<" + wsTag + L":t xml:space=\"preserve\">" + wsText + L"</" + wsTag + L":t>");
oWriter.WriteString(L"</" + wsTag + L":r>");
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;
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 {}
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);
void Clear() 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();
}
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"<w:pPr>");
oWriter.WriteString(L"<" + wsTag + L":p>");
oWriter.WriteString(L"<" + wsTag + L":pPr>");
// 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)
{
oWriter.WriteString(L" w:before=\"");
oWriter.WriteString(L" " + wsTag + L":before=\"");
oWriter.AddInt(static_cast<int>(m_dSpaceBefore * c_dMMToDx));
oWriter.WriteString(L"\"");
}
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.WriteString(L"\"");
}
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.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки
oWriter.WriteString(L"\" " + wsTag + L":lineRule=\"exact\""); // exact - точный размер строки
}
oWriter.WriteString(L"/>"); //конец w:spacing
oWriter.WriteString(L"<w:ind");
oWriter.WriteString(L"<" + wsTag + L":ind");
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.WriteString(L"\"");
}
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.WriteString(L"\"");
}
if (m_bIsNeedFirstLineIndent)
{
oWriter.WriteString(L" w:firstLine=\"");
oWriter.WriteString(L" " + wsTag + L":firstLine=\"");
oWriter.AddInt(static_cast<int>(m_dFirstLine * c_dMMToDx));
oWriter.WriteString(L"\"");
}
@ -70,16 +70,16 @@ namespace NSDocxRenderer
switch (m_eTextAlignmentType)
{
case tatByCenter:
oWriter.WriteString(L"<w:jc w:val=\"center\"/>");
oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"center\"/>");
break;
case tatByRight:
oWriter.WriteString(L"<w:jc w:val=\"end\"/>");
oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"end\"/>");
break;
case tatByWidth:
oWriter.WriteString(L"<w:jc w:val=\"both\"/>");
oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"both\"/>");
break;
case tatByLeft:
oWriter.WriteString(L"<w:jc w:val=\"begin\"/>");
oWriter.WriteString(L"<" + wsTag + L":jc " + wsTag + L":val=\"begin\"/>");
break;
case tatUnknown:
default: //по умолчанию выравнивание по левому краю - можно ничего не добавлять
@ -88,20 +88,34 @@ namespace NSDocxRenderer
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.WriteString(L"\"/>");
}
}
void CParagraph::ToXml(NSStringUtils::CStringBuilder& oWriter) const
{
BuildXml(oWriter, L"w");
oWriter.WriteString(L"</w:pPr>");
for(const auto& line : m_arLines)
if(line)
line->ToXml(oWriter);
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()
{
if (!m_bIsShadingPresent)
@ -134,8 +148,7 @@ namespace NSDocxRenderer
while(!pLastCont)
pLastCont = pLine->m_arConts[--iNumConts];
// добавляем br в конец каждой строки
pLastCont->m_bIsAddBrEnd = true;
pLastCont->m_oText += L" ";
}
}
}

View File

@ -40,8 +40,12 @@ namespace NSDocxRenderer
virtual ~CParagraph();
virtual void Clear() override final;
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
void RemoveHighlightColor();
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"<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" cx=\"");
oWriter.AddInt(static_cast<int>(m_dWidth * c_dMMToEMU));
oWriter.WriteString(L"\" cy=\"");
oWriter.AddInt(static_cast<int>(m_dHeight * c_dMMToEMU));
oWriter.WriteString(L"\"/>");
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
{
if (m_eType == eShapeType::stTextBox && !m_arOutputObjects.empty())
@ -884,32 +921,7 @@ namespace NSDocxRenderer
oWriter.WriteString(L"</wps:txbx>");
oWriter.WriteString(L"<wps:bodyPr"); //определяет свойства тела текста внутри фигуры
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/>");
BuildTextBoxParams(oWriter);
oWriter.WriteString(L"</wps:bodyPr>");
}
else
@ -917,4 +929,27 @@ namespace NSDocxRenderer
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

View File

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

View File

@ -75,6 +75,8 @@ namespace NSDocxRenderer
wide_space->m_pFontStyle = pFirst->m_pFontStyle;
wide_space->m_pShape = nullptr;
wide_space->m_iNumDuplicates = 0;
// cache that value? (calls rarely)
wide_space->CalcSelected();
};
@ -245,4 +247,21 @@ namespace NSDocxRenderer
if(cont)
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 void Clear() 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 eVerticalCrossingType GetVerticalCrossingType(const CTextLine* pLine) const noexcept;
@ -45,5 +46,7 @@ namespace NSDocxRenderer
bool IsShadingPresent(const CTextLine* pLine) const noexcept;
bool IsCanBeDeleted() const;
size_t GetLength() const;
};
}