Files
Yajbir Singh f1b860b25c
Some checks failed
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

720 lines
24 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* (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 "NumberingMapping.h"
namespace DocFileFormat
{
NumberingMapping::NumberingMapping(ConversionContext* context) : AbstractOpenXmlMapping(new XMLTools::CStringXmlWriter()), m_context(context), m_document(NULL), m_xmldocument(NULL)
{
if (m_context)
{
m_document = m_context->_doc;
m_xmldocument = m_context->_docx;
}
}
NumberingMapping::~NumberingMapping()
{
RELEASEOBJECT(m_pXmlWriter);
}
}
namespace DocFileFormat
{
void NumberingMapping::Apply(IVisitable* visited)
{
if ((NULL == m_document) || (NULL == m_xmldocument))
return;
ListTable* rglst = static_cast<ListTable*>(visited);
if ((rglst != NULL) && (!rglst->listData.empty() || !rglst->listNumbering.empty()))
{
m_xmldocument->RegisterNumbering();
//start the document
m_pXmlWriter->WriteNodeBegin( L"w:numbering", TRUE );
//write namespaces
m_pXmlWriter->WriteAttribute( L"xmlns:w", OpenXmlNamespaces::WordprocessingML );
m_pXmlWriter->WriteAttribute( L"xmlns:v", OpenXmlNamespaces::VectorML );
m_pXmlWriter->WriteAttribute( L"xmlns:o", OpenXmlNamespaces::Office );
m_pXmlWriter->WriteAttribute( L"xmlns:w10", OpenXmlNamespaces::OfficeWord );
m_pXmlWriter->WriteAttribute( L"xmlns:r", OpenXmlNamespaces::Relationships );
m_pXmlWriter->WriteAttribute( L"xmlns:wpc", L"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" );
m_pXmlWriter->WriteAttribute( L"xmlns:mc", L"http://schemas.openxmlformats.org/markup-compatibility/2006");
m_pXmlWriter->WriteAttribute( L"xmlns:wp14", L"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing");
m_pXmlWriter->WriteAttribute( L"xmlns:wp", L"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing");
m_pXmlWriter->WriteAttribute( L"xmlns:w14", L"http://schemas.microsoft.com/office/word/2010/wordml" );
m_pXmlWriter->WriteAttribute( L"xmlns:wpg", L"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" );
m_pXmlWriter->WriteAttribute( L"xmlns:wpi", L"http://schemas.microsoft.com/office/word/2010/wordprocessingInk" );
m_pXmlWriter->WriteAttribute( L"xmlns:wne", L"http://schemas.microsoft.com/office/word/2006/wordml" );
m_pXmlWriter->WriteAttribute( L"xmlns:wps", L"http://schemas.microsoft.com/office/word/2010/wordprocessingShape" );
m_pXmlWriter->WriteAttribute( L"xmlns:a", L"http://schemas.openxmlformats.org/drawingml/2006/main" );
m_pXmlWriter->WriteAttribute( L"xmlns:m", L"http://schemas.openxmlformats.org/officeDocument/2006/math" );
m_pXmlWriter->WriteAttribute( L"mc:Ignorable", L"w14 wp14" );
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
PictureBulletsMapping();
for (size_t i = 0; i < rglst->listData.size(); ++i)
{
//start abstractNum
m_pXmlWriter->WriteNodeBegin( L"w:abstractNum", TRUE );
m_pXmlWriter->WriteAttribute( L"w:abstractNumId", FormatUtils::SizeTToWideString( i /*+ 1 */));
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
//nsid
m_pXmlWriter->WriteNodeBegin( L"w:nsid", TRUE );
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::IntToFormattedWideString( rglst->listData[i]->lsid, L"%08X" ));
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
//multiLevelType
m_pXmlWriter->WriteNodeBegin( L"w:multiLevelType", TRUE );
if ( rglst->listData[i]->fHybrid )
{
m_pXmlWriter->WriteAttribute( L"w:val", L"hybridMultilevel" );
}
else if ( rglst->listData[i]->fSimpleList )
{
m_pXmlWriter->WriteAttribute( L"w:val", L"singleLevel" );
}
else
{
m_pXmlWriter->WriteAttribute( L"w:val", L"multilevel" );
}
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
//template
m_pXmlWriter->WriteNodeBegin( L"w:tmpl", TRUE );
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::IntToFormattedWideString( rglst->listData[i]->tplc, L"%08X"));
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
// writes the levels
size_t length = rglst->listData[i]->rglvl->size();
for (size_t j = 0; j < length; ++j)
{
ListLevel* lvl = rglst->listData[i]->rglvl->at(j);
LevelMapping(lvl, j, rglst->listData[i]->rgistd[j]);
}
//end abstractNum
m_pXmlWriter->WriteNodeEnd( L"w:abstractNum" );
}
//write old style numbering (сложносоставных не сущестует)
for (size_t i = 0; i < rglst->listNumbering.size(); ++i)
{
//start abstractNum
m_pXmlWriter->WriteNodeBegin( L"w:abstractNum", TRUE );
m_pXmlWriter->WriteAttribute( L"w:abstractNumId", FormatUtils::SizeTToWideString( rglst->listNumbering[i]->id ));
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
////nsid
//m_pXmlWriter->WriteNodeBegin( L"w:nsid", TRUE );
//m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::IntToFormattedWideString( rglst->listNumbering[i]->lsid, L"%08x" ) ));
//m_pXmlWriter->WriteNodeEnd( L"", TRUE );
//multiLevelType
m_pXmlWriter->WriteNodeBegin( L"w:multiLevelType", TRUE );
{
m_pXmlWriter->WriteAttribute( L"w:val", L"singleLevel" );
}
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
LevelMapping(rglst->listNumbering[i], 0);
//end abstractNum
m_pXmlWriter->WriteNodeEnd( L"w:abstractNum" );
}
//write the overrides
for (size_t i = 0; i < m_document->listFormatOverrideTable->size(); ++i)
{
ListFormatOverride* lfo = m_document->listFormatOverrideTable->at(i);
//start num
m_pXmlWriter->WriteNodeBegin( L"w:num", TRUE );
m_pXmlWriter->WriteAttribute( L"w:numId", FormatUtils::SizeTToWideString(i + 1));
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
int index = FindIndexbyId( rglst->listData, lfo->lsid );
m_pXmlWriter->WriteNodeBegin( L"w:abstractNumId", TRUE );
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::IntToWideString( index ) );
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
for (std::vector<ListFormatOverrideLevel*>::const_iterator iter = lfo->rgLfoLvl.begin(); iter != lfo->rgLfoLvl.end(); ++iter)
{
m_pXmlWriter->WriteNodeBegin( L"w:lvlOverride", TRUE );
m_pXmlWriter->WriteAttribute( L"w:ilvl", FormatUtils::IntToWideString( (*iter)->ilvl ));
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
if ( ( (*iter)->fStartAt ) && ( !(*iter)->fFormatting ) )
{
m_pXmlWriter->WriteNodeBegin( L"w:startOverride", TRUE );
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::IntToWideString( (*iter)->iStartAt ));
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
}
LevelMapping((*iter)->lvl, 0, ListData::ISTD_NIL);
m_pXmlWriter->WriteNodeEnd(L"w:lvlOverride");
}
m_pXmlWriter->WriteNodeEnd(L"w:num");
}
if (m_document->listFormatOverrideTable->empty() && !rglst->listNumbering.empty())
{
for (size_t i = 0; i < rglst->listNumbering.size(); ++i)
{
m_pXmlWriter->WriteNodeBegin( L"w:num", TRUE );
m_pXmlWriter->WriteAttribute( L"w:numId", FormatUtils::SizeTToWideString(rglst->listNumbering[i]->id));
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
m_pXmlWriter->WriteNodeBegin( L"w:abstractNumId", TRUE );
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::SizeTToWideString( rglst->listNumbering[i]->id ));
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
m_pXmlWriter->WriteNodeEnd(L"w:num");
}
}
m_pXmlWriter->WriteNodeEnd(L"w:numbering");
m_xmldocument->NumberingXML = std::wstring(m_pXmlWriter->GetXmlString());
}
}
int NumberingMapping::FindIndexbyId(std::vector<ListDataPtr>& listData, int lsid)
{
int ret = -1;
int i = 0;
for (size_t i = 0; i < listData.size(); ++i)
{
if (listData[i]->lsid == lsid)
{
return i;
}
}
return -1;
}
// Converts the number text of the binary format to the number text of OOXML.
// OOXML uses different placeholders for the numbers.
std::wstring NumberingMapping::GetLvlText(const ListLevel* lvl, bool bIsSymbol) const
{
std::wstring ret;
if (lvl != NULL)
{
if (lvl->nfc == 0x17)
{
if (!lvl->xst.empty())
{
wchar_t xchBullet = lvl->xst[0];
// В символьном шрифте обрезать надо, в других случаях - нет
if (true == bIsSymbol && (xchBullet & 0xF000) != 0)
{
xchBullet &= 0x0FFF;
}
if (!FormatUtils::IsControlSymbol(xchBullet))
{
ret.push_back(lvl->xst[0]);//??? xchBullet
}
else
{
}
}
}
else
{
ret = lvl->xst;
std::wstring::const_iterator result = lvl->xst.begin();
std::wstring::const_iterator newResult = lvl->xst.begin();
newResult = find_if(lvl->xst.begin(), lvl->xst.end(), &NumberingMapping::IsPlaceholder);
ret = std::wstring(lvl->xst.begin(), newResult);
result = newResult;
while (result != lvl->xst.end())
{
newResult = find_if((result + 1), lvl->xst.end(), &NumberingMapping::IsPlaceholder);
ret += L"%";
ret += FormatUtils::SizeTToWideString(*result + 1);
ret += std::wstring((result + 1), newResult);
result = newResult;
}
}
}
return ret;
}
std::wstring NumberingMapping::GetLvlText(NumberingDescriptorPtr& lvl, bool bIsSymbol, int Before, int After) const
{
if (!lvl)return L"";
std::wstring ret;
if (lvl->nfc == 0xff)
{
if (!lvl->xst.empty())
{
wchar_t xchBullet = lvl->xst[0];
// В символьном шрифте обрезать надо, в других случаях - нет
if (bIsSymbol && (xchBullet & 0xF000) != 0)
{
xchBullet &= 0x0FFF;
}
if (!FormatUtils::IsControlSymbol(xchBullet))
{
ret.push_back(lvl->xst[0]);
}
}
else
{
ret.push_back(L'\xF0B7');
}
}
else
{
std::wstring strBefore = lvl->xst.substr(0, Before);
std::wstring strAfter = lvl->xst.substr(Before, After);
ret = strBefore + L"%1" + strAfter ;
}
return ret;
}
bool NumberingMapping::IsPlaceholder(wchar_t symbol)
{
if ((symbol == (wchar_t)0x0000) || (symbol == (wchar_t)0x0001) || (symbol == (wchar_t)0x0002) ||
(symbol == (wchar_t)0x0003) || (symbol == (wchar_t)0x0004) || (symbol == (wchar_t)0x0005) ||
(symbol == (wchar_t)0x0006) || (symbol == (wchar_t)0x0007) || (symbol == (wchar_t)0x0008))
{
return true;
}
return false;
}
std::wstring NumberingMapping::GetNumberFormatWideString(int nfc, int nWordVersion)
{
if (nWordVersion > 0 && nfc > 5)
{
if (nfc == 0xff) return std::wstring( L"bullet");
else return std::wstring( L"none");
}
switch ( nfc )
{
case 0:
return std::wstring( L"decimal" );
case 1:
return std::wstring( L"upperRoman" );
case 2:
return std::wstring( L"lowerRoman" );
case 3:
return std::wstring( L"upperLetter");
case 4:
return std::wstring( L"lowerLetter");
case 5:
return std::wstring( L"ordinal" );
case 6:
return std::wstring( L"cardinalText" );
case 7:
return std::wstring( L"ordinalText" );
case 8:
return std::wstring( L"hex" );
case 9:
return std::wstring( L"chicago" );
case 10:
return std::wstring( L"ideographDigital" );
case 11:
return std::wstring( L"japaneseCounting" );
case 12:
return std::wstring( L"aiueo" );
case 13:
return std::wstring( L"iroha" );
case 14:
return std::wstring( L"decimalFullWidth" );
case 15:
return std::wstring( L"decimalHalfWidth" );
case 16:
return std::wstring( L"japaneseLegal" );
case 17:
return std::wstring( L"japaneseDigitalTenThousand" );
case 18:
return std::wstring( L"decimalEnclosedCircle" );
case 19:
return std::wstring( L"decimalFullWidth2" );
case 20:
return std::wstring( L"aiueoFullWidth" );
case 21:
return std::wstring( L"irohaFullWidth" );
case 22:
return std::wstring( L"decimalZero" );
case 23:
return std::wstring( L"bullet" );
case 24:
return std::wstring( L"ganada" );
case 25:
return std::wstring( L"chosung" );
case 26:
return std::wstring( L"decimalEnclosedFullstop" );
case 27:
return std::wstring( L"decimalEnclosedParen" );
case 28:
return std::wstring( L"decimalEnclosedCircleChinese" );
case 29:
return std::wstring( L"ideographEnclosedCircle" );
case 30:
return std::wstring( L"ideographTraditional" );
case 31:
return std::wstring( L"ideographZodiac" );
case 32:
return std::wstring( L"ideographZodiacTraditional" );
case 33:
return std::wstring( L"taiwaneseCounting" );
case 34:
return std::wstring( L"ideographLegalTraditional" );
case 35:
return std::wstring( L"taiwaneseCountingThousand" );
case 36:
return std::wstring( L"taiwaneseDigital" );
case 37:
return std::wstring( L"chineseCounting" );
case 38:
return std::wstring( L"chineseLegalSimplified" );
case 39:
return std::wstring( L"chineseCountingThousand" );
case 40:
return std::wstring( L"koreanDigital" );
case 41:
return std::wstring( L"koreanCounting" );
case 42:
return std::wstring( L"koreanLegal" );
case 43:
return std::wstring( L"koreanDigital2" );
case 44:
return std::wstring( L"vietnameseCounting" );
case 45:
return std::wstring( L"russianLower" );
case 46:
return std::wstring( L"russianUpper" );
case 47:
return std::wstring( L"none" );
case 48:
return std::wstring( L"numberInDash" );
case 49:
return std::wstring( L"hebrew1" );
case 50:
return std::wstring( L"hebrew2" );
case 51:
return std::wstring( L"arabicAlpha" );
case 52:
return std::wstring( L"arabicAbjad" );
case 53:
return std::wstring( L"hindiVowels" );
case 54:
return std::wstring( L"hindiConsonants" );
case 55:
return std::wstring( L"hindiNumbers" );
case 56:
return std::wstring( L"hindiCounting" );
case 57:
return std::wstring( L"thaiLetters" );
case 58:
return std::wstring( L"thaiNumbers" );
case 59:
return std::wstring( L"thaiCounting" );
default:
return std::wstring( L"decimal" );
}
}
void NumberingMapping::LevelMapping(NumberingDescriptorPtr & lvl, unsigned int level)
{
if (!lvl) return;
std::wstring fontFamily;
bool isSymbol = false;
if( lvl->ftc < m_document->FontTable->Data.size() )
{
FontFamilyName* ffn = static_cast<FontFamilyName*>( m_document->FontTable->operator [] ( lvl->ftc ) );
isSymbol = (ffn->chs == 2);
fontFamily = FormatUtils::XmlEncode(ffn->xszFtn);
}
//--------------------------------------------------------------------------------
m_pXmlWriter->WriteNodeBegin( L"w:lvl", TRUE );
m_pXmlWriter->WriteAttribute( L"w:ilvl", FormatUtils::IntToWideString(level));
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
m_pXmlWriter->WriteNodeBegin( L"w:start", TRUE );
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::IntToWideString(lvl->iStartAt));
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
m_pXmlWriter->WriteNodeBegin( L"w:numFmt", TRUE );
m_pXmlWriter->WriteAttribute( L"w:val", GetNumberFormatWideString(lvl->nfc, true));
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
//// suffix
// m_pXmlWriter->WriteNodeBegin( L"w:suff", TRUE );
// m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::MapValueToWideString(lvl->ixchFollow, &FollowingCharMap[0][0], 3, 8));
// m_pXmlWriter->WriteNodeEnd( L"", TRUE );
// Number level text
std::wstring lvlText = GetLvlText(lvl, isSymbol, lvl->cbTextBefore, lvl->cbTextAfter);
//if (lvlText.empty() && lvl->ftc == 0)//auto
//{
// lvlText.push_back(L'\xF0B7');
// lvlText.push_back(L'\0');
// fontFamily = L"Wingdings";
//}
if (!lvlText.empty())
{
m_pXmlWriter->WriteNodeBegin(L"w:lvlText",TRUE);
m_pXmlWriter->WriteAttribute(L"w:val",lvlText);
m_pXmlWriter->WriteNodeEnd(L"", TRUE);
}
// jc
m_pXmlWriter->WriteNodeBegin( L"w:lvlJc", TRUE );
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::MapValueToWideString(lvl->jc, &LevelJustificationMap[0][0], 3, 7));
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
// pPr
m_pXmlWriter->WriteNodeBegin( L"w:pPr", FALSE );
m_pXmlWriter->WriteNodeEnd(L"w:pPr");
// rPr
if (false == lvl->rPr.empty())
{
m_pXmlWriter->WriteString( lvl->rPr );
}
else
{
m_pXmlWriter->WriteNodeBegin( L"w:rPr", FALSE );
if (!fontFamily.empty())
{
m_pXmlWriter->WriteNodeBegin( L"w:rFonts", TRUE );
// w:hint="default"
m_pXmlWriter->WriteAttribute(L"w:hAnsi", fontFamily);
m_pXmlWriter->WriteAttribute(L"w:ascii", fontFamily);
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
}
m_pXmlWriter->WriteNodeEnd(L"w:rPr");
}
m_pXmlWriter->WriteNodeEnd(L"w:lvl");
}
void NumberingMapping::LevelMapping(const ListLevel* lvl, unsigned int level, short styleIndex)
{
if (!lvl) return;
XMLTools::CStringXmlWriter oWriterTemp; //Временный writer,что не нарушать последовательность записи
//rPr
RevisionData rev(lvl->grpprlChpx);
CharacterPropertiesMapping cpMapping(&oWriterTemp, m_document, &rev, lvl->grpprlPapx, false);
lvl->grpprlChpx->Convert(&cpMapping);
// Проверяем шрифт
m_pXmlWriter->WriteNodeBegin( L"w:lvl", TRUE );
m_pXmlWriter->WriteAttribute( L"w:ilvl", FormatUtils::IntToWideString(level));
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
// starts at
m_pXmlWriter->WriteNodeBegin( L"w:start", TRUE );
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::IntToWideString(lvl->iStartAt));
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
// number format
m_pXmlWriter->WriteNodeBegin( L"w:numFmt", TRUE );
m_pXmlWriter->WriteAttribute( L"w:val", GetNumberFormatWideString(lvl->nfc));
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
// suffix
m_pXmlWriter->WriteNodeBegin( L"w:suff", TRUE );
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::MapValueToWideString(lvl->ixchFollow, &FollowingCharMap[0][0], 3, 8));
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
// style
// The style id is used for a reverse reference.
// It can happen that the reference points to the wrong style.
if (styleIndex != ListData::ISTD_NIL && styleIndex < m_document->Styles->Styles->size())
{
m_pXmlWriter->WriteNodeBegin( L"w:pStyle", TRUE );
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::XmlEncode(StyleSheetMapping::MakeStyleId(m_document->Styles->Styles->at(styleIndex))));
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
}
// Number level text
m_pXmlWriter->WriteNodeBegin(L"w:lvlText",TRUE);
m_pXmlWriter->WriteAttribute(L"w:val",GetLvlText(lvl, cpMapping.CheckIsSymbolFont()));
m_pXmlWriter->WriteNodeEnd(L"",TRUE);
WriteLevelPictureBullet(lvl->grpprlChpx);
// legacy
if (lvl->fWord6)
{
m_pXmlWriter->WriteNodeBegin( L"w:legacy", TRUE );
m_pXmlWriter->WriteAttribute( L"w:legacy", L"1" );
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
}
// jc
m_pXmlWriter->WriteNodeBegin( L"w:lvlJc", TRUE );
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::MapValueToWideString(lvl->jc, &LevelJustificationMap[0][0], 3, 7));
m_pXmlWriter->WriteNodeEnd( L"", TRUE );
// pPr
bool isBidi = false;
ParagraphPropertiesMapping oppMapping(m_pXmlWriter, m_context, m_document, NULL, isBidi, NULL, -1, false);
lvl->grpprlPapx->Convert(&oppMapping);
// пишем rPr
m_pXmlWriter->WriteString(oWriterTemp.GetXmlString());
m_pXmlWriter->WriteNodeEnd(L"w:lvl");
}
void NumberingMapping::PictureBulletsMapping()
{
for (std::map<int, int>::const_iterator iter = m_document->PictureBulletsCPsMap.begin(); iter != m_document->PictureBulletsCPsMap.end(); ++iter)
{
int fc = m_document->FindFileCharPos(iter->second);
int fcEnd = m_document->FindFileCharPos(iter->second + 1);
if (fc < 0 || fcEnd < 0 ) break;
std::vector<CharacterPropertyExceptions*>* chpxs = m_document->GetCharacterPropertyExceptions(fc, fcEnd);
if ((chpxs != NULL) && (!chpxs->empty()))
{
PictureDescriptor pict(chpxs->front(), m_document->DataStream, fcEnd - fc, m_document->nWordVersion);
if ((pict.mfp.mm > 98) && (pict.shapeContainer != NULL))
{
m_pXmlWriter->WriteNodeBegin( L"w:numPicBullet", TRUE );
m_pXmlWriter->WriteAttribute( L"w:numPicBulletId", FormatUtils::IntToWideString( iter->first ));
m_pXmlWriter->WriteNodeEnd( L"", TRUE, FALSE );
m_pXmlWriter->WriteNodeBegin( L"w:pict" );
//inline picture + bullete props
if (pict.blipStoreEntry != NULL)
{
VMLPictureMapping oPicture(m_context, m_pXmlWriter, false, this, true);
oPicture.m_isBullete = true;
pict.Convert(&oPicture);
}
else
{
VMLShapeMapping oShape (m_context, m_pXmlWriter, NULL, &pict, this, true);
oShape.m_isBullete = true;
pict.shapeContainer->Convert(&oShape);
}
m_pXmlWriter->WriteNodeEnd(L"w:pict");
m_pXmlWriter->WriteNodeEnd(L"w:numPicBullet");
}
}
RELEASEOBJECT( chpxs );
}
}
void NumberingMapping::WriteLevelPictureBullet(const CharacterPropertyExceptions* grpprlChpx)
{
if (grpprlChpx)
{
unsigned int index = 0;
bool isPictureBullet = false;
for (std::vector<SinglePropertyModifier>::const_iterator iter = grpprlChpx->grpprl->begin(); iter != grpprlChpx->grpprl->end(); ++iter)
{
switch(iter->OpCode)
{
case sprmCPbiIBullet:
{
index = FormatUtils::BytesToUInt32(iter->Arguments, 0, iter->argumentsSize);
}break;
case sprmCPbiGrf:
{
isPictureBullet = FormatUtils::BitmaskToBool(FormatUtils::BytesToUInt16(iter->Arguments, 0, iter->argumentsSize), 0x1);
}break;
default:
break;
}
}
if (isPictureBullet && false == m_document->PictureBulletsCPsMap.empty())
{
m_pXmlWriter->WriteNodeBegin(L"w:lvlPicBulletId",TRUE);
m_pXmlWriter->WriteAttribute(L"w:val",FormatUtils::IntToWideString(index));
m_pXmlWriter->WriteNodeEnd(L"",TRUE);
}
}
}
}