Files
DocumentServer-v-9.2.0/core/MsBinaryFile/DocFile/TablePropertiesMapping.cpp
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

445 lines
14 KiB
C++

/*
* (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 "TablePropertiesMapping.h"
namespace DocFileFormat
{
TablePropertiesMapping::TablePropertiesMapping(XMLTools::CStringXmlWriter* pWriter, StyleSheet* styles, std::vector<short>* grid, bool isTableStyleNeeded) :
PropertiesMapping(pWriter), _tblPr(NULL), _tblGrid(NULL), _tblBorders(NULL), _grid(grid),
brcLeft(NULL), brcTop(NULL), brcBottom(NULL), brcRight(NULL), brcHorz(NULL), brcVert(NULL), _styles(styles),
_isTableStyleNeeded(isTableStyleNeeded)
{
_tblPr = new XMLTools::XMLElement(L"w:tblPr");
_tblBorders = new XMLTools::XMLElement(L"w:tblBorders");
}
TablePropertiesMapping::~TablePropertiesMapping()
{
RELEASEOBJECT(_tblPr);
RELEASEOBJECT(_tblGrid);
RELEASEOBJECT(_tblBorders);
}
void TablePropertiesMapping::Apply(IVisitable* visited)
{
TablePropertyExceptions* tapx = static_cast<TablePropertyExceptions*>(visited);
XMLTools::XMLElement tblCellMar(L"w:tblCellMar");
XMLTools::XMLElement tblLayout(L"w:tblLayout");
XMLTools::XMLElement tblpPr(L"w:tblpPr");
XMLTools::XMLAttribute layoutType(L"w:type", L"fixed");
_CP_OPT(short) tblIndent;
_CP_OPT(short) gabHalf;
_CP_OPT(short) marginLeft;
_CP_OPT(short) marginRight;
short cellSpacing = 0;
BYTE itcFirst = 0;
BYTE itcLim = 0;
bool bTableW = false;
for (std::vector<SinglePropertyModifier>::iterator iter = tapx->grpprl->begin(); iter != tapx->grpprl->end(); iter++)
{
switch (iter->OpCode)
{
case sprmOldTDxaGapHalf:
case sprmTDxaGapHalf:
{
gabHalf = FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize);
}break;
case sprmOldTDefTable:
case sprmTDefTable:
{
//table definition
SprmTDefTable tDef(iter->Arguments, iter->argumentsSize);
//Workaround for retrieving the indent of the table:
//In some files there is a indent but no sprmTWidthIndent is set.
//For this cases we can calculate the indent of the table by getting the
//first boundary of the TDef and adding the padding of the cells
tblIndent = FormatUtils::BytesToInt16(iter->Arguments, 1, iter->argumentsSize);
//If there follows a real sprmTWidthIndent, this value will be overwritten
//tblIndent = (std::max)((int)tblIndent,0); //cerere.doc
}break;
case sprmTTableWidth:
{
//preferred table width
unsigned char fts = iter->Arguments[0];
if (fts == 0) fts = 1; //auto - 江苏领辉M5仪表_2号协议&5S协议说明书-V1.1 - EN.doc
short width = FormatUtils::BytesToInt16(iter->Arguments, 1, iter->argumentsSize);
XMLTools::XMLElement tblW(L"w:tblW");
XMLTools::XMLAttribute w(L"w:w", FormatUtils::IntToWideString(width));
XMLTools::XMLAttribute type(L"w:type", FormatUtils::MapValueToWideString(fts, &WidthType[0][0], 4, 5));
tblW.AppendAttribute(type);
tblW.AppendAttribute(w);
_tblPr->AppendChild(tblW);
bTableW = true;
}break;
case sprmTMerge:
{
itcFirst = iter->Arguments[0];
itcLim = iter->Arguments[1];
}break;
case sprmTSplit:
{
}break;
case sprmOldTJc:
case sprmTJc:
case sprmTJcRow:
{
appendValueElement(_tblPr, L"jc", FormatUtils::MapValueToWideString(iter->Arguments[0], &Global::JustificationCode[0][0], 10, 15), true);
}break;
case sprmTWidthIndent:
{
tblIndent = FtsWWidth_Indent(iter->Arguments).wWidth;
}break;
case sprmTIstd:
case sprmTIstdPermute:
{
if (_isTableStyleNeeded)
{
size_t ind = FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize);
std::wstring id = ind < _styles->Styles->size() ? StyleSheetMapping::MakeStyleId(_styles->Styles->at(ind)) : L"";
if (id != std::wstring(L"TableNormal") && !id.empty())
{
appendValueElement(_tblPr, L"tblStyle", id, true);
}
}
}break;
case sprmTFBiDi:
case sprmTFBiDi90:
{
appendValueElement(_tblPr, L"bidiVisual", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize), true);
}break;
case sprmOldTTlp:
case sprmTTlp:
{
appendValueElement(_tblPr, L"tblLook", FormatUtils::IntToFormattedWideString(FormatUtils::BytesToInt16(iter->Arguments, 2, iter->argumentsSize), L"%04x"), true);
}break;
case sprmTFAutofit:
{
if (iter->Arguments[0] == 1)
{
layoutType.SetValue(L"auto");
}
}break;
case sprmTCellSpacing:
case sprmTCellSpacingDefault:
{
unsigned char grfbrc = iter->Arguments[2];
short wSpc = FormatUtils::BytesToInt16(iter->Arguments, 4, iter->argumentsSize);
std::wstring strValue = FormatUtils::IntToWideString(wSpc);
if (FormatUtils::BitmaskToBool((int)grfbrc, 0x01))
{
appendDxaElement(_tblPr, L"tblCellSpacing", strValue, true);
}
if (FormatUtils::BitmaskToBool((int)grfbrc, 0x02))
{
cellSpacing = wSpc;
}
}break;
case sprmTCellPaddingDefault:
case sprmTCellPadding:
case sprmTCellPaddingOuter:
{//cell padding (margin)
unsigned char grfbrc = iter->Arguments[2];
short wMar = FormatUtils::BytesToInt16(iter->Arguments, 4, iter->argumentsSize);
std::wstring strValue = FormatUtils::IntToWideString(wMar);
if (FormatUtils::BitmaskToBool((int)grfbrc, 0x01))
{
appendDxaElement(&tblCellMar, L"top", strValue, true);
}
if (FormatUtils::BitmaskToBool((int)grfbrc, 0x02))
{
marginLeft = wMar;
}
if (FormatUtils::BitmaskToBool((int)grfbrc, 0x04))
{
appendDxaElement(&tblCellMar, L"bottom", strValue, true);
}
if (FormatUtils::BitmaskToBool((int)grfbrc, 0x08))
{
marginRight = wMar;
}
}break;
case sprmTCHorzBands:
{
appendValueElement(_tblPr, L"tblStyleRowBandSize", iter->Arguments[0], true);
}break;
case sprmTCVertBands:
{
appendValueElement(_tblPr, L"tblStyleColBandSize", iter->Arguments[0], true);
}break;
case sprmTFNoAllowOverlap:
{
std::wstring tblOverlapVal(L"overlap");
if (iter->Arguments[0])
{
tblOverlapVal = L"never";
}
appendValueElement(_tblPr, L"tblOverlap", tblOverlapVal, true);
}break;
case sprmOldTSetShd:
case sprmTSetShdTable:
{
appendShading(_tblPr, ShadingDescriptor(iter->Arguments, iter->argumentsSize));
}break;
case sprmTTableBorders80:
{
const int size = 4;
unsigned char brc80[size];
memcpy(brc80, iter->Arguments, size);
brcTop = std::shared_ptr<BorderCode>(new BorderCode(brc80, size));
memcpy(brc80, (iter->Arguments + 4), size);
brcLeft = std::shared_ptr<BorderCode>(new BorderCode(brc80, size));
memcpy(brc80, (iter->Arguments + 8), size);
brcBottom = std::shared_ptr<BorderCode>(new BorderCode(brc80, size));
memcpy(brc80, (iter->Arguments + 12), size);
brcRight = std::shared_ptr<BorderCode>(new BorderCode(brc80, size));
memcpy(brc80, (iter->Arguments + 16), size);
brcHorz = std::shared_ptr<BorderCode>(new BorderCode(brc80, size));
memcpy(brc80, (iter->Arguments + 20), size);
brcVert = std::shared_ptr<BorderCode>(new BorderCode(brc80, size));
}break;
case sprmOldTTableBorders:
case sprmTTableBorders:
{
const int size = 8;
unsigned char brc[size];
memcpy(brc, iter->Arguments, size);
brcTop = std::shared_ptr<BorderCode>(new BorderCode(brc, size));
memcpy(brc, (iter->Arguments + 8), size);
brcLeft = std::shared_ptr<BorderCode>(new BorderCode(brc, size));
memcpy(brc, (iter->Arguments + 16), size);
brcBottom = std::shared_ptr<BorderCode>(new BorderCode(brc, size));
memcpy(brc, (iter->Arguments + 24), size);
brcRight = std::shared_ptr<BorderCode>(new BorderCode(brc, size));
memcpy(brc, (iter->Arguments + 32), size);
brcHorz = std::shared_ptr<BorderCode>(new BorderCode(brc, size));
memcpy(brc, (iter->Arguments + 40), size);
brcVert = std::shared_ptr<BorderCode>(new BorderCode(brc, size));
}break;
case sprmTPc:
{
unsigned char flag = (iter->Arguments[0] & 0x30) >> 4;
appendValueAttribute(&tblpPr, L"w:vertAnchor", FormatUtils::MapValueToWideString(flag, &Global::VerticalPositionCode[0][0], 4, 7));
flag = (iter->Arguments[0] & 0xC0) >> 6;
appendValueAttribute(&tblpPr, L"w:horzAnchor", FormatUtils::MapValueToWideString(flag, &Global::HorizontalPositionCode[0][0], 4, 7));
}break;
case sprmTDxaFromText:
{
appendValueAttribute(&tblpPr, L"w:leftFromText", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize));
}break;
case sprmTDxaFromTextRight:
{
appendValueAttribute(&tblpPr, L"w:rightFromText", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize));
}break;
case sprmTDyaFromText:
{
appendValueAttribute(&tblpPr, L"w:topFromText", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize));
}break;
case sprmTDyaFromTextBottom:
{
appendValueAttribute(&tblpPr, L"w:bottomFromText", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize));
}break;
case sprmTDxaAbs:
{
appendValueAttribute(&tblpPr, L"w:tblpX", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize));
}break;
case sprmTDyaAbs:
{
appendValueAttribute(&tblpPr, L"w:tblpY", FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize));
}break;
}
}
if (false == bTableW)
{
XMLTools::XMLElement tblW(L"w:tblW");
XMLTools::XMLAttribute w(L"w:w", L"0");
XMLTools::XMLAttribute type(L"w:type", L"auto");
tblW.AppendAttribute(type);
tblW.AppendAttribute(w);
_tblPr->AppendChild(tblW);
}
if (tblIndent)
{
XMLTools::XMLElement tblInd(L"w:tblInd");
XMLTools::XMLAttribute tblIndW(L"w:w", FormatUtils::IntToWideString(*tblIndent));
tblInd.AppendAttribute(tblIndW);
XMLTools::XMLAttribute tblIndType(L"w:type", L"dxa");
tblInd.AppendAttribute(tblIndType);
_tblPr->AppendChild(tblInd);
}
if (tblpPr.GetAttributeCount() > 0)
{
_tblPr->AppendChild(tblpPr);
}
if (brcTop)
{
XMLTools::XMLElement topBorder(L"w:top");
appendBorderAttributes(brcTop.get(), &topBorder);
addOrSetBorder(_tblBorders, &topBorder);
}
if (brcLeft)
{
XMLTools::XMLElement leftBorder(L"w:left");
appendBorderAttributes(brcLeft.get(), &leftBorder);
addOrSetBorder(_tblBorders, &leftBorder);
}
if (brcBottom)
{
XMLTools::XMLElement bottomBorder(L"w:bottom");
appendBorderAttributes(brcBottom.get(), &bottomBorder);
addOrSetBorder(_tblBorders, &bottomBorder);
}
if (brcRight)
{
XMLTools::XMLElement rightBorder(L"w:right");
appendBorderAttributes(brcRight.get(), &rightBorder);
addOrSetBorder(_tblBorders, &rightBorder);
}
if (brcHorz)
{
XMLTools::XMLElement insideHBorder(L"w:insideH");
appendBorderAttributes(brcHorz.get(), &insideHBorder);
addOrSetBorder(_tblBorders, &insideHBorder);
}
if (brcVert)
{
XMLTools::XMLElement insideVBorder(L"w:insideV");
appendBorderAttributes(brcVert.get(), &insideVBorder);
addOrSetBorder(_tblBorders, &insideVBorder);
}
if (_tblBorders->GetChildCount() > 0)
{
_tblPr->AppendChild(*_tblBorders);
}
if (false == layoutType.GetValue().empty())
{
tblLayout.AppendAttribute(layoutType);
}
_tblPr->AppendChild(tblLayout);
if ((gabHalf) && (*gabHalf != 0))
{
appendDxaElement(&tblCellMar, L"left", FormatUtils::IntToWideString(*gabHalf), true);
}
else if (marginLeft)
{
appendDxaElement(&tblCellMar, L"left", FormatUtils::IntToWideString(*marginLeft), true);
}
if ((gabHalf) && (*gabHalf != 0))
{
appendDxaElement(&tblCellMar, L"right", FormatUtils::IntToWideString(*gabHalf), true);
}
else if (marginRight)
{
appendDxaElement(&tblCellMar, L"right", FormatUtils::IntToWideString(*marginRight), true);
}
if (tblCellMar.GetChildCount() > 0 || tblCellMar.GetAttributeCount() > 0)
{
_tblPr->AppendChild(tblCellMar);
}
if (_tblPr->GetChildCount() > 0 || _tblPr->GetAttributeCount() > 0)
{
m_pXmlWriter->WriteString(_tblPr->GetXMLString());
}
//append the grid
_tblGrid = new XMLTools::XMLElement(L"w:tblGrid");
for (size_t i = 0; i < _grid->size(); i++)
{
XMLTools::XMLElement gridCol(L"w:gridCol");
if (_grid->at(i) > 0)
{
XMLTools::XMLAttribute gridColW(L"w:w", FormatUtils::IntToWideString(_grid->at(i)));
gridCol.AppendAttribute(gridColW);
}
_tblGrid->AppendChild(gridCol);
}
m_pXmlWriter->WriteString(_tblGrid->GetXMLString());
}
}