Files
core/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp
2026-04-02 08:10:57 +03:00

3886 lines
119 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 "xlsx_conversion_context.h"
#include "../../Common/Utils/simple_xml_writer.h"
#include "../../../OOXML/Base/Unit.h"
#include "../Format/Auxiliary/HelpFunc.h"
#include "../../../DesktopEditor/raster/BgraFrame.h"
#include "../../../OOXML/PPTXFormat/Logic/SpTreeElem.h"
#include "../../../OOXML/PPTXFormat/Logic/Shape.h"
#include "../../../OOXML/PPTXFormat/Logic/SpTree.h"
#include "../../Common/Vml/PPTShape/PptShape.h"
#include "../../Common/Vml/PPTShape/Ppt2PptxShapeConverter.h"
namespace oox {
//-----------------------------------------------------------------------------------------------------------
const static std::wstring shemeColor[18] =
{L"accent1",L"accent2",L"accent3",L"accent4",L"accent5",L"accent6",L"bk1",L"bk2",L"dk1",L"dk2",L"folHlink",L"hlink",L"lt1",L"lt2",L"none", L"tx1",L"tx2",L"phClr"};
const static int shemeDefaultColor[] =
{
0x00000000, 0x00FFFFFF, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00FFFF00, 0x00FF00FF, 0x0000FFFF,
0x00000000, 0x00FFFFFF, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00FFFF00, 0x00FF00FF, 0x0000FFFF,
0x00800000, 0x00008000, 0x00000080, 0x00808000, 0x00800080, 0x00008080, 0x00C0C0C0, 0x00808080,
0x009999FF, 0x00993366, 0x00FFFFCC, 0x00CCFFFF, 0x00660066, 0x00FF8080, 0x000066CC, 0x00CCCCFF,
0x00000080, 0x00FF00FF, 0x00FFFF00, 0x0000FFFF, 0x00800080, 0x00800000, 0x00008080, 0x000000FF,
0x0000CCFF, 0x00CCFFFF, 0x00CCFFCC, 0x00FFFF99, 0x0099CCFF, 0x00FF99CC, 0x00CC99FF, 0x00FFCC99,
0x003366FF, 0x0033CCCC, 0x0099CC00, 0x00FFCC00, 0x00FF9900, 0x00FF6600, 0x00666699, 0x00969696,
0x00003366, 0x00339966, 0x00003300, 0x00333300, 0x00993300, 0x00993366, 0x00333399, 0x00333333
};
const static int controlPanelColors2[] =
{
0x00000000, 0x00FFFFFF, 0x00000000, 0x00FFFFFF,
0x00000000, 0x00000000, 0x00000000, 0x00FFFFFF,
0x00FFFFFF, 0x00000000, 0x00FFFFFF, 0x00FFFFFF,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00FFFFFF, 0x00FFFFFF, 0x00FFFFFF, 0x00000000,
0x00FFFFFF, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00FFFFFF, 0x00FFFFFF
};
const static int controlPanelColors1[] =
{
0x00FFFFFF, 0x00CCCCCC, 0x00FFFFFF, 0x006363CE,
0x00DDDDDD, 0x00DDDDDD, 0x00888888, 0x00000000,
0x00000000, 0x00808080, 0x00B5D5FF, 0x00000000,
0x00FFFFFF, 0x00FFFFFF, 0x007F7F7F, 0x00FBFCC5,
0x00000000, 0x00F7F7F7, 0x00000000, 0x00FFFFFF,
0x00666666, 0x00C0C0C0, 0x00DDDDDD, 0x00C0C0C0,
0x00888888, 0x00FFFFFF, 0x00CCCCCC, 0x00000000
};
//-----------------------------------------------------------------------------------------------------
class xlsx_drawing_context_handle::Impl
{
public:
Impl(size_t & next_vml_file_id, external_items & items)
: next_vml_file_id_(next_vml_file_id), items_(items), next_rId_(1), next_drawing_id_(1)
{
}
external_items & get_mediaitems() { return items_; }
size_t next_rId()
{
return next_rId_++;
}
std::pair<std::wstring, std::wstring> add_drawing_xml(std::wstring const & content, xlsx_drawings_rels_ptr rels)
{// todo file number counters separately
const std::wstring id = std::to_wstring(next_drawing_id_++);
const std::wstring fileName = std::wstring(L"drawing") + id + L".xml";
drawings_.push_back(drawing_elm(fileName, content, rels));
const std::wstring rId = std::wstring(L"rId") + id;
return std::pair<std::wstring, std::wstring>(fileName, rId);
}
std::pair<std::wstring, std::wstring> add_drawing_vml(std::wstring const & content, xlsx_drawings_rels_ptr rels)
{
const std::wstring drawing_id = std::to_wstring(next_drawing_id_++);
const std::wstring file_vml_id = std::to_wstring(next_vml_file_id_++);
const std::wstring fileName = std::wstring(L"vmlDrawing") + file_vml_id + L".vml";
drawings_vml_.push_back(drawing_elm(fileName, content, rels));
const std::wstring rId = std::wstring(L"rId") + drawing_id;
return std::pair<std::wstring, std::wstring>(fileName, rId);
}
const std::vector<drawing_elm> & content() const
{
return drawings_;
}
const std::vector<drawing_elm> & content_vml() const
{
return drawings_vml_;
}
xlsx_drawings_rels_ptr get_drawings_rels();
private:
external_items & items_;
size_t next_rId_;
std::vector<drawing_elm> drawings_;
std::vector<drawing_elm> drawings_vml_;
size_t next_drawing_id_;
size_t & next_vml_file_id_;
};
xlsx_drawing_context_handle::xlsx_drawing_context_handle(size_t & next_vml_file_id, external_items & items)
: impl_(new xlsx_drawing_context_handle::Impl(next_vml_file_id, items))
{
}
xlsx_drawing_context_handle::~xlsx_drawing_context_handle()
{
}
std::pair<std::wstring, std::wstring> xlsx_drawing_context_handle::add_drawing_xml(std::wstring const & content, xlsx_drawings_rels_ptr rels )
{
return impl_->add_drawing_xml(content, rels);
}
std::pair<std::wstring, std::wstring> xlsx_drawing_context_handle::add_drawing_vml(std::wstring const & content, xlsx_drawings_rels_ptr rels )
{
return impl_->add_drawing_vml(content, rels);
}
const std::vector<drawing_elm> & xlsx_drawing_context_handle::content() const
{
return impl_->content();
}
const std::vector<drawing_elm> & xlsx_drawing_context_handle::content_vml() const
{
return impl_->content_vml();
}
//---------------------------------------------------------------------------------------
_color xlsx_drawing_context::CorrectSysColor(int nColorCode, _drawing_state_ptr & drawing_state)
{
_color color;
unsigned short nParameter = (unsigned short)(( nColorCode >> 16 ) & 0x00ff); // the HiByte of nParameter is not zero, an exclusive AND is helping :o
unsigned short nFunctionBits = (unsigned short)(( nColorCode & 0x00000f00 ) >> 8 );
unsigned short nAdditionalFlags = (unsigned short)(( nColorCode & 0x0000f000) >> 8 );
unsigned short nColorIndex = (unsigned short) ( nColorCode & 0x00ff);
unsigned short nPropColor = 0;
switch (nColorIndex)
{
case 0xF0: color = drawing_state->fill.color; break;
case 0xF1:
{
if (drawing_state->line.fill.type != fillNone) color = drawing_state->line.fill.color;
else color = drawing_state->fill.color;
}break;
case 0xF2: color = drawing_state->line.fill.color; break;
case 0xF3: color = drawing_state->shadow.color; break;
case 0xF4: break; ///this
case 0xF5: color = drawing_state->fill.color2; break;
case 0xF6: break; //lineBackColor
case 0xF7: //FillThenLine
case 0xF8: //colorIndexMask
color = drawing_state->shadow.color; break;
default:
//from table
break;
}
if (color.index != -1)
{
// extract color
// todo make themes !!!!!
color.nRGB = shemeDefaultColor[color.index];
color.index = -1;
color.sRGB = STR::toRGB(color.nRGB);
}
//if ( nCProp && ( nPropColor & 0x10000000 ) == 0 ) // beware of looping recursive
// color = CorrectSysColor( nPropColor, pElement);
if( nAdditionalFlags & 0x80 ) // make color gray
{
BYTE nZwi = 0x7f;//= aColor.GetLuminance();
color.SetRGB(nZwi, nZwi, nZwi);
}
switch( nFunctionBits )
{
case 0x01 : // darken color by parameter
{
BYTE R = static_cast<BYTE> ( ( nParameter * color.GetR() ) >> 8 );
BYTE G = static_cast<BYTE> ( ( nParameter * color.GetG() ) >> 8 );
BYTE B = static_cast<BYTE> ( ( nParameter * color.GetB() ) >> 8 );
color.SetRGB(R, G, B);
}
break;
case 0x02 : // lighten color by parameter
{
unsigned short nInvParameter = ( 0x00ff - nParameter ) * 0xff;
BYTE R = static_cast<BYTE>( ( nInvParameter + ( nParameter * color.GetR() ) ) >> 8 );
BYTE G = static_cast<BYTE>( ( nInvParameter + ( nParameter * color.GetG() ) ) >> 8 );
BYTE B = static_cast<BYTE>( ( nInvParameter + ( nParameter * color.GetB() ) ) >> 8 );
color.SetRGB(R, G, B);
}
break;
case 0x03 : // add grey level RGB(p,p,p)
{
short nR = (short)color.GetR() + (short)nParameter;
short nG = (short)color.GetG() + (short)nParameter;
short nB = (short)color.GetB() + (short)nParameter;
if ( nR > 0x00ff ) nR = 0x00ff;
if ( nG > 0x00ff ) nG = 0x00ff;
if ( nB > 0x00ff ) nB = 0x00ff;
color.SetRGB( (BYTE)nR, (BYTE)nG, (BYTE)nB );
}
break;
case 0x04 : // substract grey level RGB(p,p,p)
{
short nR = (short)color.GetR() - (short)nParameter;
short nG = (short)color.GetG() - (short)nParameter;
short nB = (short)color.GetB() - (short)nParameter;
if ( nR < 0 ) nR = 0;
if ( nG < 0 ) nG = 0;
if ( nB < 0 ) nB = 0;
color.SetRGB( (BYTE)nR, (BYTE)nG, (BYTE)nB );
}
break;
case 0x05 : // substract from gray level RGB(p,p,p)
{
short nR = (short)nParameter - (short)color.GetR();
short nG = (short)nParameter - (short)color.GetG();
short nB = (short)nParameter - (short)color.GetB();
if ( nR < 0 ) nR = 0;
if ( nG < 0 ) nG = 0;
if ( nB < 0 ) nB = 0;
color.SetRGB( (BYTE)nR, (BYTE)nG, (BYTE)nB );
}
break;
case 0x06 : // per component: black if < p, white if >= p
{
BYTE R = color.GetR() < nParameter ? 0x00 : 0xff ;
BYTE G = color.GetG() < nParameter ? 0x00 : 0xff ;
BYTE B = color.GetB() < nParameter ? 0x00 : 0xff ;
color.SetRGB(R, G, B);
}
break;
}
if ( nAdditionalFlags & 0x40 ) // top-bit invert
color.SetRGB( color.GetR() ^ 0x80, color.GetG() ^ 0x80, color.GetB() ^ 0x80 );
if ( nAdditionalFlags & 0x20 ) // invert color
color.SetRGB(0xff - color.GetR(), 0xff - color.GetG(), 0xff - color.GetB());
//if (color.sRGB.empty())
// {incorrect
// color.nRGB = shemeDefaultColor[nColorIndex];
// color.index = -1;
// color.sRGB = STR::toRGB(color.nRGB);
//}
return color;
}
//-----------------------------------------------------------------------------------------------------------
xlsx_drawing_context::xlsx_drawing_context(xlsx_conversion_context & Context) : context_(Context), handle_(Context.get_drawing_context_handle())
, rels_ (xlsx_drawings_rels::create())
, vml_HF_rels_ (xlsx_drawings_rels::create())
, vml_rels_(xlsx_drawings_rels::create())
, sheet_rels_ (xlsx_drawings_rels::create())
{
in_chart_ = false;
count_object = 0;
current_level = 0;
current_drawing_states = &drawing_states ;
}
bool xlsx_drawing_context::start_drawing(int type)
{
switch(type)
{
case 0x0000: // Group
start_group(); return true;
case 0x0001: // Line
case 0x0002: // Rectangle
case 0x0003: // Oval
case 0x0004: // Arc
case 0x0006: // Text
case 0x001E: // OfficeArt object
case 0x0009: // Polygon:
start_shape(type); return true;
case 0x0008: // Picture
start_image(); return true;
case 0x0005: // Chart
//start_shape(2); return true;
start_chart(); return true;
case 0x0007: // Button
case 0x000B: // Checkbox
case 0x000C: // Radio button
case 0x000D: // Edit box
case 0x000E: // Label
case 0x000F: // Dialog box
case 0x0010: // Spin control
case 0x0012: // List
case 0x0013: // Group box
case 0x0011: // Scrollbar
case 0x0014: // Dropdown list
start_control(type); return true;
case 0x0019: // Note
start_comment(); return true;
break;
}
return false;
}
external_items::Type xlsx_drawing_context::getType()
{
if (current_drawing_states == NULL) return external_items::typeUnknown;
if (current_drawing_states->empty()) return external_items::typeUnknown;
return current_drawing_states->back()->type;
}
int xlsx_drawing_context::getLevel()
{
if (current_drawing_states == NULL) return -1;
if (current_drawing_states->empty()) return -1;
return current_level;
}
_drawing_state_ptr create_drawing_state()
{
return _drawing_state_ptr(new _drawing_state());
}
void xlsx_drawing_context::start_image()
{
if (current_drawing_states == NULL) return;
current_drawing_states->push_back(create_drawing_state());
current_drawing_states->back()->type = external_items::typeImage;
current_drawing_states->back()->type_control = 0x0008;
count_object++;
}
void xlsx_drawing_context::start_comment()
{
if (current_drawing_states == NULL) return;
current_drawing_states->push_back(create_drawing_state());
current_drawing_states->back()->type = external_items::typeComment;
current_drawing_states->back()->shape_id = MSOSPT::msosptRectangle;
current_drawing_states->back()->type_control = 0x0019;
current_drawing_states->back()->object.bVisible = false;
count_object++;
context_.get_comments_context().start_comment();
}
void xlsx_drawing_context::start_group()
{
_drawing_state_ptr newState = create_drawing_state();
current_drawing_states->push_back(newState);
current_level++;
current_drawing_states->back()->parent_drawing_states = current_drawing_states;
current_drawing_states = &newState->drawing_states;
current_drawing_states->push_back(newState);
current_drawing_states->back()->type = external_items::typeGroup;
current_drawing_states->back()->type_control = 0x0000;
}
void xlsx_drawing_context::end_group()
{
if (current_level < 1) return;
//std::vector<_drawing_state_ptr>* cur_states = NULL;
//for (size_t i = 0; i < current_drawing_states->size(); i++)
//{
// if (!current_drawing_states->empty())
// {
// int level = current_level;
// cur_states = current_drawing_states;
// while (level > 0)
// {
// _drawing_state_ptr & drawing_state = cur_states->front();
// if (i != 0 || level != current_level) // group refers to itself
// {
// double kf_x = (double)drawing_state->child_anchor.cx / drawing_state->group_anchor.cx;
// double kf_y = (double)drawing_state->child_anchor.cy / drawing_state->group_anchor.cy;
// current_drawing_states->at(i)->child_anchor.cx *= kf_x;
// current_drawing_states->at(i)->child_anchor.cy *= kf_y;
//
// current_drawing_states->at(i)->child_anchor.x = current_drawing_states->at(i)->child_anchor.x * kf_x + drawing_state->child_anchor.x;
// current_drawing_states->at(i)->child_anchor.y = current_drawing_states->at(i)->child_anchor.y * kf_y + drawing_state->child_anchor.y;
// }
// level--;
// cur_states = cur_states->front()->parent_drawing_states;
// }
// }
//}
serialize_group();
current_drawing_states = current_drawing_states->front()->parent_drawing_states;
current_level--;
}
void xlsx_drawing_context::start_chart()
{
if (current_drawing_states == NULL) return;
context_.start_chart();
current_drawing_states->push_back(create_drawing_state());
current_drawing_states->back()->type = external_items::typeChart;
in_chart_ = true;
count_object++;
}
void xlsx_drawing_context::start_control(int type)
{
if (current_drawing_states == NULL) return;
current_drawing_states->push_back(create_drawing_state());
current_drawing_states->back()->type = external_items::typeControl;
current_drawing_states->back()->shape_id = MSOSPT::msosptRectangle;
current_drawing_states->back()->type_control = type;
count_object++;
}
void xlsx_drawing_context::start_shape(int type)
{
if (current_drawing_states == NULL) return;
current_drawing_states->push_back(create_drawing_state());
current_drawing_states->back()->type = external_items::typeShape;
current_drawing_states->back()->type_control = type;
switch(type)
{
case 0x0001: current_drawing_states->back()->shape_id = MSOSPT::msosptLine; break;
case 0x0002: current_drawing_states->back()->shape_id = MSOSPT::msosptRectangle; break;
case 0x0003: current_drawing_states->back()->shape_id = MSOSPT::msosptEllipse; break;
case 0x0004: current_drawing_states->back()->shape_id = MSOSPT::msosptArc; break;
case 0x0006: current_drawing_states->back()->shape_id = MSOSPT::msosptTextBox; break;
case 0x001E: current_drawing_states->back()->shape_id = MSOSPT::msosptRectangle; break;// OfficeArt object
case 0x0009: current_drawing_states->back()->shape_id = MSOSPT::msosptNotPrimitive; break;// Polygon:
}
count_object++;
}
void xlsx_drawing_context::set_id(int id)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->id = id;
}
void xlsx_drawing_context::set_FlipH()
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->flipH = true;
}
void xlsx_drawing_context::set_FlipV()
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->flipV = true;
}
void xlsx_drawing_context::set_shape_id(int id)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
if (current_drawing_states->back()->bTextBox) return;
current_drawing_states->back()->shape_id = (MSOSPT)id;
}
void xlsx_drawing_context::set_alternative_drawing(const std::wstring & xml_data)
{
if (xml_data.empty()) return;
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->xmlAlternative = xml_data;
}
void xlsx_drawing_context::reset_alternative_drawing()
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
std::wstring xml_data = current_drawing_states->back()->xmlAlternative;
current_drawing_states->back()->xmlAlternative.clear();
XmlUtils::CXmlLiteReader oReader;
if ( !oReader.FromString( xml_data ) )
return;
if ( !oReader.ReadNextNode() ) //anchor or object(sp in group)
return;
std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName());
nullable<PPTX::Logic::SpTreeElem> oElement;
int nCurDepth = oReader.GetDepth();
while ( oReader.ReadNextSiblingNode( nCurDepth ) )
{
sName = XmlUtils::GetNameNoNS(oReader.GetName());
if (L"AlternateContent" == sName || L"Choice" == sName ||
L"twoCellAnchor" == sName || L"oneCellAnchor" == sName || L"absoluteAnchor" == sName)
{
nCurDepth++;
continue;
}
else if ( L"graphicFrame" == sName || L"pic" == sName || L"sp" == sName || L"grpSp" == sName || L"cxnSp" == sName || L"spTree" == sName)
{
oElement = oReader;
}
}
if (oElement.IsInit())
{
NSBinPptxRW::CXmlWriter writer(XMLWRITER_DOC_TYPE_XLSX);
smart_ptr<PPTX::Logic::Shape> shape = oElement->GetElem().smart_dynamic_cast<PPTX::Logic::Shape>();
if (shape.IsInit())
{
shape->spPr.Geometry.toXmlWriter(&writer);
if (shape->spPr.scene3d.IsInit())
shape->spPr.scene3d->toXmlWriter(&writer);
if (shape->spPr.sp3d.IsInit())
shape->spPr.sp3d->toXmlWriter(&writer);
current_drawing_states->back()->xmlGeomAlternative = writer.GetXmlString();
writer.ClearNoAttack();
if (shape->style.IsInit())
shape->style->toXmlWriter(&writer);
current_drawing_states->back()->xmlStyleAlternative = writer.GetXmlString();
writer.ClearNoAttack();
if ((shape->txBody.IsInit()) && (shape->txBody->bodyPr.IsInit()))
{
bool bWordArt = shape->txBody->bodyPr->prstTxWarp.IsInit();
if (bWordArt || (false == shape->txBody->Paragrs.empty()) && (false == shape->txBody->Paragrs[0].RunElems.empty()))
{
shape->txBody->toXmlWriter(&writer);
current_drawing_states->back()->xmlTxBodyAlternative = writer.GetXmlString();
writer.ClearNoAttack();
}
}
if (shape->spPr.Fill.is_init())
{
shape->spPr.Fill.toXmlWriter(&writer);
current_drawing_states->back()->xmlFillAlternative = writer.GetXmlString();
writer.ClearNoAttack();
}
if (shape->spPr.EffectList.is_init())
{
shape->spPr.EffectList.toXmlWriter(&writer);
current_drawing_states->back()->xmlEffectAlternative = writer.GetXmlString();
writer.ClearNoAttack();
}
}
smart_ptr<PPTX::Logic::SpTree> groupShape = oElement->GetElem().smart_dynamic_cast<PPTX::Logic::SpTree>();
if (groupShape.IsInit())
{//smartArt or group
if (groupShape->grpSpPr.Fill.is_init())
{
groupShape->grpSpPr.Fill.toXmlWriter(&writer);
current_drawing_states->back()->xmlFillAlternative = writer.GetXmlString();
writer.ClearNoAttack();
}
if (false == groupShape->SpTreeElems.empty()) // smartArt
{
if (false == groupShape->grpSpPr.xfrm.IsInit())
{
groupShape->grpSpPr.xfrm.Init();
set_xfrm_from_anchor(groupShape->grpSpPr.xfrm.GetPointer(), current_drawing_states->back());
}
groupShape->toXmlWriter(&writer);
current_drawing_states->back()->xmlAlternative = writer.GetXmlString();
writer.ClearNoAttack();
}
}
}
//std::wstring sName = oReader.GetName();
//if ( (L"xdr:anchor" == sName || L"xdr:object" == sName) && !oReader.IsEmptyNode() ) //object -
//{
// current_drawing_states->back()->xmlAlternative = oReader.GetInnerXml();
// //fill(color index???) ??? prst ???
//}
}
void xlsx_drawing_context::set_xfrm_from_anchor(PPTX::Logic::Xfrm *xfrm, _drawing_state_ptr state)
{
if (!xfrm) return;
if (!state) return;
if (state->type_anchor == 1)
{
xfrm->offX = (int)(state->sheet_anchor.absolute.x);
xfrm->offY = (int)(state->sheet_anchor.absolute.y);
xfrm->extX = (int)(state->sheet_anchor.absolute.cx);
xfrm->extY = (int)(state->sheet_anchor.absolute.cy);
xfrm->chExtX = (int)(state->sheet_anchor.absolute.cx);
xfrm->chExtY = (int)(state->sheet_anchor.absolute.cy);
}
if (state->type_anchor == 3)
{
xfrm->offX = (int)(state->absolute_anchor.x * 12700);
xfrm->offY = (int)(state->absolute_anchor.y * 12700);
xfrm->extX = (int)(state->absolute_anchor.cx * 12700);
xfrm->extY = (int)(state->absolute_anchor.cy * 12700);
xfrm->chExtX = (int)(state->absolute_anchor.cx * 12700);
xfrm->chExtY = (int)(state->absolute_anchor.cy * 12700);
}
}
void xlsx_drawing_context::set_hidden(bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->hidden = val;
}
void xlsx_drawing_context::set_object_visible(bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.bVisible = val;
}
void xlsx_drawing_context::set_object_anchor(int col, int row)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.col = col;
current_drawing_states->back()->object.row = row;
}
void xlsx_drawing_context::set_object_id(int val)
{
}
void xlsx_drawing_context::set_object_link(const std::wstring & formula)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.link = formula;
}
void xlsx_drawing_context::set_object_x_val(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.x_val = val;
}
void xlsx_drawing_context::set_object_x_min(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.x_min = val;
}
void xlsx_drawing_context::set_object_x_max(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.x_max = val;
}
void xlsx_drawing_context::set_object_x_inc(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.x_inc = val;
}
void xlsx_drawing_context::set_object_x_page(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.x_page = val;
}
void xlsx_drawing_context::set_object_x_sel(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.x_sel = val;
}
void xlsx_drawing_context::set_object_x_sel_type(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.x_sel_type = val;
}
void xlsx_drawing_context::set_object_lct(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.lct = val;
}
void xlsx_drawing_context::set_object_fmlaRange(const std::wstring & fmla)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.fmlaRange = fmla;
}
void xlsx_drawing_context::set_object_drop_style(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.drop_style = val;
}
void xlsx_drawing_context::set_object_drop_lines(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.drop_lines = val;
}
void xlsx_drawing_context::set_object_dx(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.dx = val;
}
void xlsx_drawing_context::set_object_checked(bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.checked = val;
}
void xlsx_drawing_context::set_object_multiLine(bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.multiLine = val;
}
void xlsx_drawing_context::set_object_vscroll(bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.vscroll = val;
}
void xlsx_drawing_context::set_object_hscroll(bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.hscroll = val;
}
void xlsx_drawing_context::set_object_3D(bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object._3D = val;
}
void xlsx_drawing_context::end_drawing()
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
reset_alternative_drawing();
if (current_drawing_states->back()->type == external_items::typeGroup) return;
//std::vector<_drawing_state_ptr>* cur_states = current_drawing_states;;
//
//int level = current_level;
//while (level > 0)
//{
// _drawing_state_ptr & drawing_state = cur_states->front();
// double kf_x = (double)drawing_state->child_anchor.cx / drawing_state->group_anchor.cx;
// double kf_y = (double)drawing_state->child_anchor.cy / drawing_state->group_anchor.cy;
// current_drawing_states->back()->child_anchor.cx *= kf_x;
// current_drawing_states->back()->child_anchor.cy *= kf_y;
//
// current_drawing_states->back()->child_anchor.x = drawing_state->group_anchor.x +
// (long)(kf_x * (current_drawing_states->back()->child_anchor.x - drawing_state->group_anchor.x));
// current_drawing_states->back()->child_anchor.y = drawing_state->group_anchor.y +
// (long)(kf_y * (current_drawing_states->back()->child_anchor.y - drawing_state->group_anchor.y));
// level--;
// cur_states = cur_states->front()->parent_drawing_states;
//}
end_drawing(current_drawing_states->back());
if ( current_drawing_states->back()->type == external_items::typeComment ||
current_drawing_states->back()->type == external_items::typeControl )
{
drawing_states_vml.push_back(current_drawing_states->back());
if (current_drawing_states->back()->type == external_items::typeComment)
current_drawing_states->pop_back();
}
else if (!current_drawing_states->back()->vml_shape.empty())
{ // && current_drawing_states->back()->vml_HF_mode_
drawing_states_vml_HF.push_back(current_drawing_states->back());
current_drawing_states->pop_back();
}
}
void xlsx_drawing_context::end_drawing(_drawing_state_ptr & drawing_state)
{
if (!drawing_state) return;
if (drawing_state->id < 0)
drawing_state->id = count_object + 0x20000;
if (((drawing_state->rotation >= 45.0 && drawing_state->rotation <= 135.0) ||
(drawing_state->rotation >= 225.0 && drawing_state->rotation <= 315.0) ||
(drawing_state->rotation <= -45.0 && drawing_state->rotation >= -135.0) ||
(drawing_state->rotation <= -225.0 && drawing_state->rotation >= -315.0)) && current_level > 0)
{
int left = current_drawing_states->back()->child_anchor.x;
int top = current_drawing_states->back()->child_anchor.y;
int right = current_drawing_states->back()->child_anchor.x + current_drawing_states->back()->child_anchor.cx;
int bottom = current_drawing_states->back()->child_anchor.y + current_drawing_states->back()->child_anchor.cy;
left = (right + current_drawing_states->back()->child_anchor.x) * 0.5 - (bottom - current_drawing_states->back()->child_anchor.y) * 0.5;
top = (bottom + current_drawing_states->back()->child_anchor.y) * 0.5 - (right - current_drawing_states->back()->child_anchor.x) * 0.5;
right = left + current_drawing_states->back()->child_anchor.cy;
bottom = top + current_drawing_states->back()->child_anchor.cx;
current_drawing_states->back()->child_anchor.x = left;
current_drawing_states->back()->child_anchor.y = top;
current_drawing_states->back()->child_anchor.cx = right - left;
current_drawing_states->back()->child_anchor.cy = bottom - top;
}
if ( drawing_state->type == external_items::typeImage || drawing_state->type == external_items::typeShape )
{
if (drawing_state->shape_id == msosptPictureFrame)
{
drawing_state->type = external_items::typeImage;
}
if (!drawing_state->fill.picture_target.empty())
drawing_state->fill.texture_target = drawing_state->fill.picture_target;
bool isIternal = false;
if (!drawing_state->fill.texture_target.empty())
{
drawing_state->objectId = handle_.impl_->get_mediaitems().find_image(drawing_state->fill.texture_target, isIternal);
}
if (drawing_state->type == external_items::typeImage)
{
serialize_pic(drawing_state);
}
else
{
serialize_shape(drawing_state);
}
if (!drawing_state->fill.texture_target.empty())
{
if (drawing_state->vml_HF_mode_)
{
vml_HF_rels_->add(isIternal, drawing_state->objectId, drawing_state->fill.texture_target, drawing_state->type);
}
else
{
rels_->add(isIternal, drawing_state->objectId, drawing_state->fill.texture_target, drawing_state->type);
}
}
}
if ( drawing_state->type == external_items::typeChart )
{
context_.end_chart();
in_chart_ = false;
std::wstring target;
drawing_state->objectId = handle_.impl_->get_mediaitems().add_chart(target);
serialize_chart(drawing_state);
rels_->add( true, drawing_state->objectId, target, drawing_state->type);
}
if ( drawing_state->type == external_items::typeComment )
{
context_.get_comments_context().set_content(drawing_state->text.content);
serialize_vml_shape(drawing_state);
context_.get_comments_context().end_comment();
}
//if ( drawing_state->type == external_items::typeShape)
//{
// serialize_shape(drawing_state);
//}
if ( drawing_state->type == external_items::typeOleObject )
{
serialize_shape(drawing_state);
drawing_states_objects.push_back(drawing_state); // for serialize in sheet
}
if ( drawing_state->type == external_items::typeActiveX) // control objects with binary properties
{
context_.end_activeX();
serialize_shape(drawing_state);
drawing_states_controls.push_back(drawing_state); // for serialize in sheet
}
if ( drawing_state->type == external_items::typeControl)// control objects with xml properties
{
serialize_control(drawing_state);
if (drawing_state->objectId.empty())
{
std::wstring target;
drawing_state->objectId = context_.get_mediaitems().add_control_props(target);
sheet_rels_->add(true, drawing_state->objectId, L"ctrlProps/" + target, external_items::typeControlProps);
std::wstringstream strm;
serialize_control_props(strm, drawing_state);
context_.add_control_props(target, strm.str());
}
drawing_states_controls.push_back(drawing_state); // for serialize in sheet
}
}
void xlsx_drawing_context::serialize_group()
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
_drawing_state_ptr & drawing_state = current_drawing_states->front();
std::wstringstream strm;
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"xdr:grpSp")
{
CP_XML_NODE(L"xdr:nvGrpSpPr")
{
CP_XML_NODE(L"xdr:cNvPr")
{
CP_XML_ATTR(L"id", drawing_state->id);
if (drawing_state->name.empty())
{
drawing_state->name = L"Group_" + std::to_wstring(count_object);
}
CP_XML_ATTR(L"name", drawing_state->name);
if (!drawing_state->description.empty())
{
CP_XML_ATTR(L"descr", XmlUtils::EncodeXmlString(drawing_state->description));
}
if (drawing_state->hidden)
{
CP_XML_ATTR(L"hidden", 1);
}
if (!drawing_state->hyperlink.empty())
{
CP_XML_NODE(L"a:hlinkClick")
{
CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships");
CP_XML_ATTR(L"r:id", drawing_state->hyperlink);
}
}
}
CP_XML_NODE(L"xdr:cNvGrpSpPr")
{
CP_XML_NODE(L"a:grpSpLocks")
{
CP_XML_ATTR(L"noChangeAspect", 1);
}
}
}
CP_XML_NODE(L"xdr:grpSpPr")
{
CP_XML_ATTR(L"bwMode", L"auto");
serialize_xfrm(CP_XML_STREAM(), drawing_state);
if (false == drawing_state->xmlFillAlternative.empty()) //Family budget (monthly)1.xls
{
CP_XML_STREAM() << drawing_state->xmlFillAlternative;
}
//serialize_fill(CP_XML_STREAM(), drawing_state); ???? white //Family budget (monthly)1.xls
//serialize_line(CP_XML_STREAM(), drawing_state);
}
for (size_t i = 1; i < current_drawing_states->size(); i++)
{
CP_XML_STREAM() << current_drawing_states->at(i)->shape;
//todo current_drawing_states->at(i).shape.erase(); // save memory
}
}
}
drawing_state->shape = strm.str();
}
void xlsx_drawing_context::serialize_vml_shape(_drawing_state_ptr & drawing_state)
{
std::wstringstream strm;
CP_XML_WRITER(strm)
{
std::wstringstream strmStyle;
strmStyle << L"position:absolute;";
strmStyle << L"margin-left:" << std::to_wstring(drawing_state->sheet_anchor.absolute.x / 12700.) << L"pt;"; //in pt (1 pt = 12700 emu)
strmStyle << L"margin-top:" << std::to_wstring(drawing_state->sheet_anchor.absolute.y / 12700.) << L"pt;";
strmStyle << L"width:" << std::to_wstring(drawing_state->sheet_anchor.absolute.cx / 12700.) << L"pt;";
strmStyle << L"height:" << std::to_wstring(drawing_state->sheet_anchor.absolute.cy / 12700.) << L"pt;";
strmStyle << L"z-index:" << std::to_wstring(drawing_state->id) << L";";
if (drawing_state->object.bVisible == false)
strmStyle << L"visibility:hidden;";
CP_XML_NODE(L"v:shape")
{
CP_XML_ATTR(L"id", L"_x0000_s" + std::to_wstring(drawing_state->id));
if (drawing_state->shape_id != msosptNotPrimitive)
{
CP_XML_ATTR(L"type", L"#_x0000_t" + std::to_wstring(drawing_state->shape_id));
CP_XML_ATTR(L"o:spt", drawing_state->shape_id);
}
CP_XML_ATTR(L"fillcolor", L"#" + drawing_state->fill.color.sRGB);
if (drawing_state->line.width > 0)
{
CP_XML_ATTR(L"strokeweight", std::to_wstring(drawing_state->line.width) +L"pt");
}
CP_XML_ATTR(L"style", strmStyle.str());
if (!current_drawing_states->back()->custom_verticles.empty() &&
!current_drawing_states->back()->custom_segments.empty())
{
ODRAW::PathParser oParser ( current_drawing_states->back()->custom_segments,
current_drawing_states->back()->custom_verticles,
current_drawing_states->back()->custom_guides,
current_drawing_states->back()->custom_x_limo,
current_drawing_states->back()->custom_y_limo);
std::wstring path = oParser.GetVmlPath();
if (false == path.empty())
CP_XML_ATTR(L"path", path);
}
if (drawing_state->type == external_items::typeControl)
{
CP_XML_ATTR(L"o:button", L"t");
}
if (drawing_state->line.fill.type == fillNone)
{
CP_XML_ATTR(L"stroked", L"f");
}
if (drawing_state->fill.type == fillNone)
{
CP_XML_ATTR(L"filled", L"f");
}
//----------------------------------------------------------------------------------------------
CP_XML_NODE(L"v:shadow")
{
CP_XML_ATTR(L"color", L"black");
CP_XML_ATTR(L"obscured", L"t");
CP_XML_ATTR(L"on", L"t");
}
//CP_XML_NODE(L"v:wrap")
//{
// CP_XML_ATTR(L"v:type", L"none");
//}
CP_XML_NODE(L"v:fill")
{
CP_XML_ATTR(L"color", std::wstring(L"#") + drawing_state->fill.color.sRGB);
if (drawing_state->fill.color.opacity > 0.00001)
{
CP_XML_ATTR(L"opacity", drawing_state->fill.color.opacity * 65536);
}
bool isIternal = false;
std::wstring rId = handle_.impl_->get_mediaitems().find_image( drawing_state->fill.texture_target, isIternal);
if (!rId.empty())
{
CP_XML_ATTR(L"o:relid" , rId);
CP_XML_ATTR(L"type" , L"tile");
if (current_drawing_states->back()->vml_HF_mode_ )
{
vml_HF_rels_->add(isIternal, rId , drawing_state->fill.texture_target, external_items::typeImage);
}
else
{
vml_rels_->add(isIternal, rId , drawing_state->fill.texture_target, external_items::typeImage);
}
}
else if (drawing_state->fill.type == fillGradient || drawing_state->fill.type == fillGradientOne)
{
CP_XML_ATTR(L"color2", std::wstring(L"#") + drawing_state->fill.color2.sRGB);
if (drawing_state->fill.color2.opacity > 0.00001)
{
CP_XML_ATTR(L"opacity2", drawing_state->fill.color2.opacity * 65536);
}
CP_XML_ATTR(L"type", L"gradient");
}
else
{
CP_XML_ATTR(L"type", L"solid");
}
}
CP_XML_NODE(L"v:stroke")
{
CP_XML_ATTR(L"color", std::wstring(L"#") + drawing_state->line.fill.color.sRGB);
//CP_XML_ATTR(L"opacity",(100.-dVal.get())/100.);
switch(drawing_state->line.typeDash)
{
case lineDash: CP_XML_ATTR(L"dashstyle", L"dash"); break;
case lineDot: CP_XML_ATTR(L"dashstyle", L"dot"); break;
case lineDashDot: CP_XML_ATTR(L"dashstyle", L"dashDot"); break;
case lineDashDotDot:CP_XML_ATTR(L"dashstyle", L"lgDashDotDot"); break;
}
}
if (!drawing_state->text.vml_content.empty())
{
CP_XML_NODE(L"v:textbox")
{
//style='mso-direction-alt:auto'
//o:singleclick="f"
CP_XML_STREAM() << drawing_state->text.vml_content;
}
}
if (drawing_state->type_control == 0x000b)
{
CP_XML_NODE(L"v:textbox")
{
CP_XML_ATTR(L"o:singleclick", L"f");
CP_XML_NODE(L"div")
{
CP_XML_ATTR(L"style", L"text-align:left");
}
}
}
CP_XML_NODE(L"x:ClientData")
{
switch(drawing_state->type_control)
{
case 0x0000: CP_XML_ATTR(L"ObjectType", L"Group"); break;
case 0x0001: CP_XML_ATTR(L"ObjectType", L"Shape"); break; // Line
case 0x0002: CP_XML_ATTR(L"ObjectType", L"Rect"); break;
case 0x0003: CP_XML_ATTR(L"ObjectType", L"Shape"); break; // Oval
case 0x0004: CP_XML_ATTR(L"ObjectType", L"Shape"); break; // Arc
case 0x0006: CP_XML_ATTR(L"ObjectType", L"Shape"); break; // Text
case 0x0007: CP_XML_ATTR(L"ObjectType", L"Button"); break;
case 0x0008: CP_XML_ATTR(L"ObjectType", L"Pict"); break;
case 0x0009: CP_XML_ATTR(L"ObjectType", L"Shape"); break; // Polygon:
case 0x000B: CP_XML_ATTR(L"ObjectType", L"Checkbox"); break;
case 0x000C: CP_XML_ATTR(L"ObjectType", L"Radio"); break;
case 0x000D: CP_XML_ATTR(L"ObjectType", L"Edit"); break;
case 0x000E: CP_XML_ATTR(L"ObjectType", L"Label"); break;
case 0x000F: CP_XML_ATTR(L"ObjectType", L"Dialog"); break;
case 0x0010: CP_XML_ATTR(L"ObjectType", L"Spin"); break;
case 0x0012: CP_XML_ATTR(L"ObjectType", L"List"); break;
case 0x0013: CP_XML_ATTR(L"ObjectType", L"GBox"); break;
case 0x0011: CP_XML_ATTR(L"ObjectType", L"Scroll"); break;
case 0x0014: CP_XML_ATTR(L"ObjectType", L"Drop"); break;
case 0x001E: CP_XML_ATTR(L"ObjectType", L"Shape"); break; // OfficeArt object
case 0x0019: CP_XML_ATTR(L"ObjectType", L"Note"); break;
default: break;
}
CP_XML_NODE(L"x:MoveWithCells"){}
CP_XML_NODE(L"x:SizeWithCells"){}
if (drawing_state->sheet_anchor.xFrom >= 0 && drawing_state->sheet_anchor.xTo > 0)
{//old xls don't have this
std::wstringstream strmAnchor;
strmAnchor
<< drawing_state->sheet_anchor.colFrom << L", " << (int)(2 * drawing_state->sheet_anchor.xFrom / 12700.) << L", "
<< drawing_state->sheet_anchor.rwFrom << L", " << (int)(2 * drawing_state->sheet_anchor.yFrom / 12700.) << L", "
<< drawing_state->sheet_anchor.colTo << L", " << (int)(2 * drawing_state->sheet_anchor.xTo / 12700.) << L", "
<< drawing_state->sheet_anchor.rwTo << L", " << (int)(2 * drawing_state->sheet_anchor.yTo / 12700.);
if (!strmAnchor.str().empty())
{
CP_XML_NODE(L"x:Anchor"){CP_XML_CONTENT(strmAnchor.str());}
}
}
CP_XML_NODE(L"x:AutoFill") {CP_XML_CONTENT("False");}
//if (drawing_state->type_control != 0x000b)
{
CP_XML_NODE(L"x:Row") {CP_XML_CONTENT(drawing_state->object.row);}
CP_XML_NODE(L"x:Column") {CP_XML_CONTENT(drawing_state->object.col);}
}
if (drawing_state->object.bVisible) CP_XML_NODE(L"x:Visible");
if (!drawing_state->object.macro.empty())
{
CP_XML_NODE(L"x:FmlaMacro"){CP_XML_CONTENT(drawing_state->object.macro);}
}
if (!drawing_state->object.link.empty() )
{
CP_XML_NODE(L"x:FmlaLink"){CP_XML_CONTENT(drawing_state->object.link);}
}
if (drawing_state->object.x_val)
{
CP_XML_NODE(L"x:Val"){CP_XML_CONTENT(*drawing_state->object.x_val);}
}
if (drawing_state->object.x_min)
{
CP_XML_NODE(L"x:Min"){CP_XML_CONTENT(*drawing_state->object.x_min);}
}
if (drawing_state->object.x_max)
{
CP_XML_NODE(L"x:Max"){CP_XML_CONTENT(*drawing_state->object.x_max);}
}
if (drawing_state->object.x_inc)
{
CP_XML_NODE(L"x:Inc"){CP_XML_CONTENT(*drawing_state->object.x_inc);}
}
if (drawing_state->object.x_page)
{
CP_XML_NODE(L"x:Page"){CP_XML_CONTENT(*drawing_state->object.x_page);}
}
if (!drawing_state->object.fmlaRange.empty() )
{
CP_XML_NODE(L"x:FmlaRange"){CP_XML_CONTENT(drawing_state->object.fmlaRange);}
}
if (drawing_state->object.x_sel)
{
CP_XML_NODE(L"x:Sel"){CP_XML_CONTENT(*drawing_state->object.x_sel);}
}
if (drawing_state->object.x_sel_type)
{
switch(*drawing_state->object.x_sel_type)
{
case 0:
default:
CP_XML_NODE(L"x:SelType"){CP_XML_CONTENT(L"Single");}
}
}
if (drawing_state->object.lct)
{
switch(*drawing_state->object.lct)
{
case 0:
default:
CP_XML_NODE(L"x:LCT"){CP_XML_CONTENT(L"Normal");}
}
}
if (drawing_state->object.drop_style)
{
switch(*drawing_state->object.drop_style)
{
case 0:
default:
CP_XML_NODE(L"x:DropStyle"){CP_XML_CONTENT(L"Combo");}
}
}
if (drawing_state->object.drop_lines)
{
CP_XML_NODE(L"x:DropLines"){CP_XML_CONTENT(*drawing_state->object.drop_lines);}
}
if (drawing_state->object.dx)
{
CP_XML_NODE(L"x:Dx") { CP_XML_CONTENT(*drawing_state->object.dx); }
}
if (drawing_state->object.checked)
{
CP_XML_NODE(L"x:Checked") { CP_XML_CONTENT(*drawing_state->object.checked); }
}
if (drawing_state->object._3D)
{
CP_XML_NODE(L"x:NoThreeD") { CP_XML_CONTENT(*drawing_state->object._3D ? L"False" : L"True"); }
}
if (drawing_state->object.multiLine)
{
CP_XML_NODE(L"x:Multiline") { CP_XML_CONTENT(*drawing_state->object.multiLine ? L"True" : L"False"); }
}
if (drawing_state->object.vscroll)
{
CP_XML_NODE(L"x:VScroll") { CP_XML_CONTENT(*drawing_state->object.vscroll ? L"True" : L"False"); }
}
if (drawing_state->object.hscroll)
{
CP_XML_NODE(L"x:Horiz") { CP_XML_CONTENT(*drawing_state->object.hscroll ? L"True" : L"False"); }
}
}
}
}
drawing_state->vml_shape = strm.str();
}
void xlsx_drawing_context::serialize_vml_pic(_drawing_state_ptr & drawing_state)
{
std::wstringstream strm;
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"v:shape")
{
CP_XML_ATTR( L"id" , drawing_state->name);
CP_XML_ATTR( L"o:spt" , L"75" );
CP_XML_ATTR( L"o:preferrelative", "t" );
CP_XML_ATTR( L"filled" , "f" );
CP_XML_ATTR( L"stroked" , "f" );
CP_XML_ATTR( L"type" , L"#_x0000_t75" );
CP_XML_ATTR( L"coordsize" , L"21600,21600" );
std::wstring style = std::wstring(L"position:absolute;margin-left:0;margin-top:0;");
// todo make values "shorter" .. 2 decimal places is enough
style += std::wstring(L"width:") + std::to_wstring(drawing_state->child_anchor.cx) + std::wstring(L"pt;");
style += std::wstring(L"height:") + std::to_wstring(drawing_state->child_anchor.cy) + std::wstring(L"pt;");
style += std::wstring(L"z-index:") + std::to_wstring(drawing_state->id) + std::wstring(L";");
CP_XML_ATTR(L"style",style);
CP_XML_NODE(L"v:imagedata")
{
CP_XML_ATTR(L"o:relid", drawing_state->objectId);
}
}
}
drawing_state->vml_shape = strm.str();
}
void xlsx_drawing_context::serialize_pic(_drawing_state_ptr & drawing_state)
{
if (drawing_state->vml_HF_mode_)
return serialize_vml_pic(drawing_state);
std::wstringstream strm;
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"xdr:pic")
{
CP_XML_ATTR(L"macro", drawing_state->object.macro);
CP_XML_NODE(L"xdr:nvPicPr")
{
CP_XML_NODE(L"xdr:cNvPr")
{
CP_XML_ATTR(L"id", drawing_state->id);
if (drawing_state->name.empty())
drawing_state->name = L"Picture_" + (drawing_state->objectId.size() > 5 ? drawing_state->objectId.substr(5) : std::to_wstring(drawing_state->id));
CP_XML_ATTR(L"name", drawing_state->name);
if (!drawing_state->description.empty())
{
CP_XML_ATTR(L"descr", XmlUtils::EncodeXmlString(drawing_state->description));
}
if (drawing_state->hidden)
{
CP_XML_ATTR(L"hidden", 1);
}
if (!drawing_state->hyperlink.empty())
{
CP_XML_NODE(L"a:hlinkClick")
{
CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships");
CP_XML_ATTR(L"r:id", drawing_state->hyperlink);
}
}
}
CP_XML_NODE(L"xdr:cNvPicPr")
{
CP_XML_NODE(L"a:picLocks")
{
CP_XML_ATTR(L"noChangeAspect", 1);
}
}
}
drawing_state->fill.texture_mode = textureStretch;
serialize_bitmap_fill(CP_XML_STREAM(), drawing_state->fill, drawing_state->objectId, L"xdr:");
CP_XML_NODE(L"xdr:spPr")
{
serialize_xfrm(CP_XML_STREAM(), drawing_state);
CP_XML_NODE(L"a:prstGeom")
{
CP_XML_ATTR(L"prst", "rect");
CP_XML_NODE(L"a:avLst");
}
CP_XML_NODE(L"a:noFill");
if (false == drawing_state->xmlEffectAlternative.empty())
{
CP_XML_STREAM() << drawing_state->xmlEffectAlternative;
}
else
{
//serialize_effect(CP_XML_STREAM(), drawing_state);
}
}
}
}
drawing_state->shape = strm.str();
}
void xlsx_drawing_context::serialize_chart(_drawing_state_ptr & drawing_state)
{
std::wstringstream strm;
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"xdr:graphicFrame")
{
CP_XML_NODE(L"xdr:nvGraphicFramePr")
{
CP_XML_NODE(L"xdr:cNvPr")
{
CP_XML_ATTR(L"id", drawing_state->id);
if (drawing_state->name.empty())
drawing_state->name = L"Chart_" + std::to_wstring(count_object);
CP_XML_ATTR(L"name", drawing_state->name);
if (!drawing_state->description.empty())
{
CP_XML_ATTR(L"descr", XmlUtils::EncodeXmlString(drawing_state->description));
}
if (drawing_state->hidden)
{
CP_XML_ATTR(L"hidden", 1);
}
}
CP_XML_NODE(L"xdr:cNvGraphicFramePr");
}
serialize_xfrm(CP_XML_STREAM(), drawing_state);
//serialize_fill(CP_XML_STREAM());
//serialize_line(CP_XML_STREAM());
CP_XML_NODE(L"a:graphic")
{
CP_XML_NODE(L"a:graphicData")
{
CP_XML_ATTR(L"uri", L"http://schemas.openxmlformats.org/drawingml/2006/chart");
CP_XML_NODE(L"c:chart")
{
CP_XML_ATTR(L"xmlns:c", L"http://schemas.openxmlformats.org/drawingml/2006/chart");
CP_XML_ATTR(L"r:id", drawing_state->objectId);
}
}
}
}
}
drawing_state->shape = strm.str();
}
void xlsx_drawing_context::serialize_control(_drawing_state_ptr & drawing_state)
{
std::wstringstream strm;
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"xdr:sp")
{
CP_XML_NODE(L"xdr:nvSpPr")
{
CP_XML_NODE(L"xdr:cNvPr")
{
CP_XML_ATTR(L"id", drawing_state->id);
if (drawing_state->name.empty())
{
drawing_state->name = L"Control_" + std::to_wstring(count_object);
}
CP_XML_ATTR(L"name", drawing_state->name);
if (!drawing_state->description.empty())
{
CP_XML_ATTR(L"descr", XmlUtils::EncodeXmlString(drawing_state->description));
}
CP_XML_ATTR(L"hidden", 1);
CP_XML_NODE(L"a:extLst")
{
CP_XML_NODE(L"a:ext")
{
CP_XML_ATTR(L"uri", L"{63B3BB69-23CF-44E3-9099-C40C66FF867C}");
CP_XML_NODE(L"a14:compatExt")
{
CP_XML_ATTR(L"xmlns:a14", L"http://schemas.microsoft.com/office/drawing/2010/main");
CP_XML_ATTR(L"spid", L"_x0000_s" + std::to_wstring(drawing_state->id));
}
}
}
}
CP_XML_NODE(L"xdr:cNvSpPr");
}
CP_XML_NODE(L"xdr:spPr")
{
serialize_xfrm(CP_XML_STREAM(), drawing_state);
CP_XML_NODE(L"a:prstGeom")
{
CP_XML_ATTR(L"prst", L"rect");
if (!drawing_state->wordart.is) CP_XML_NODE(L"a:avLst");
}
CP_XML_NODE(L"a:noFill");
CP_XML_NODE(L"a:ln")
{
CP_XML_NODE(L"a:noFill");
}
}
serialize_text(CP_XML_STREAM(), drawing_state);
}
}
drawing_state->shape = strm.str();
serialize_vml_shape(drawing_state);
}
void xlsx_drawing_context::serialize_shape(_drawing_state_ptr & drawing_state)
{
if (drawing_state->vml_HF_mode_)
return serialize_vml_shape(drawing_state);
std::wstringstream strm;
std::wstring prstTxWarp;
std::wstring prstGeom = Spt2ShapeType(drawing_state->shape_id);
std::wstring customGeom;
if (prstGeom.empty())
{
prstTxWarp = Spt2WordArtShapeType(drawing_state->shape_id);
if (prstTxWarp.empty() == false)
{
drawing_state->wordart.is = true;
drawing_state->bTextBox = true;
prstGeom = L"rect";
}
else
{
customGeom = convert_custom_shape(drawing_state);
drawing_state->bCustom = true;
}
}
else
{
if (drawing_state->shape_id == msosptTextBox) drawing_state->bTextBox = true;
}
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"xdr:sp")
{
CP_XML_ATTR(L"macro", drawing_state->object.macro);
CP_XML_NODE(L"xdr:nvSpPr")
{
CP_XML_NODE(L"xdr:cNvPr")
{
CP_XML_ATTR(L"id", drawing_state->id);
if (drawing_state->name.empty())
{
if (drawing_state->wordart.is)
drawing_state->name = L"WordArt_" + std::to_wstring(count_object);
else if ( drawing_state->type == external_items::typeOleObject )
drawing_state->name = L"Object_" + std::to_wstring(count_object);
else if ( drawing_state->type == external_items::typeActiveX )
drawing_state->name = L"ActiveX_" + std::to_wstring(count_object);
else
drawing_state->name = L"Shape_" + std::to_wstring(count_object);
}
CP_XML_ATTR(L"name", drawing_state->name);
if (!drawing_state->description.empty())
{
CP_XML_ATTR(L"descr", XmlUtils::EncodeXmlString(drawing_state->description));
}
if (drawing_state->hidden)
{
CP_XML_ATTR(L"hidden", 1);
}
if (!drawing_state->hyperlink.empty())
{
CP_XML_NODE(L"a:hlinkClick")
{
CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships");
CP_XML_ATTR(L"r:id", drawing_state->hyperlink);
}
}
//if ( drawing_state->type == external_items::typeOleObject ) + VmlDrawing
//{
// CP_XML_NODE(L"a:extLst")
// {
// CP_XML_NODE(L"a:ext")
// {
// CP_XML_ATTR(L"uri", L"{63B3BB69-23CF-44E3-9099-C40C66FF867C}");
// CP_XML_ATTR(L"xmlns:a14", L"http://schemas.microsoft.com/office/drawing/2010/main");
// CP_XML_NODE(L"a14:compatExt")
// {
// CP_XML_ATTR(L"spid", L"_x0000_s" + std::to_wstring(drawing_state->id));
// }
// }
// }
//}
}
CP_XML_NODE(L"xdr:cNvSpPr")
{
if (drawing_state->bTextBox)CP_XML_ATTR(L"txBox", 1);
//CP_XML_NODE(L"a:spLocks")
//{
// CP_XML_ATTR(L"noGrp", 1);
// CP_XML_ATTR(L"noChangeArrowheads", 1);
//}
}
}
CP_XML_NODE(L"xdr:spPr")
{
serialize_xfrm(CP_XML_STREAM(), drawing_state);
if (false == drawing_state->xmlGeomAlternative.empty())
{
CP_XML_STREAM() << drawing_state->xmlGeomAlternative;
}
else
{
if (prstGeom.empty() == false)
{
CP_XML_NODE(L"a:prstGeom")
{
CP_XML_ATTR(L"prst", prstGeom);
if (false == drawing_state->wordart.is)
{
CP_XML_NODE(L"a:avLst")
{
// recalculation needed
//for (size_t i = 0; i < drawing_state->custom_adjustValues.size(); i++)
//{
// if (drawing_state->custom_adjustValues[i])
// {
// CP_XML_NODE(L"a:gd")
// {
// CP_XML_ATTR(L"name", L"adj" + std::to_wstring(i + 1));
// CP_XML_ATTR(L"fmla", L"val " + std::to_wstring(*drawing_state->custom_adjustValues[i]));
// }
// }
//}
}
}
}
}
else if (customGeom.empty() == false)
{
CP_XML_NODE(L"a:custGeom")
{
CP_XML_STREAM() << customGeom;
}
}
else
{
CP_XML_NODE(L"a:prstGeom")
{
CP_XML_ATTR(L"prst", L"rect");
}
}
}
if (!is_lined_shape(drawing_state))
{
if (false == drawing_state->xmlFillAlternative.empty() &&
std::wstring::npos == drawing_state->xmlFillAlternative.find(L"r:emb")) //Family budget (monthly)1.xls
{
CP_XML_STREAM() << drawing_state->xmlFillAlternative;
}
else
{
serialize_fill(CP_XML_STREAM(), drawing_state);
}
}
serialize_line(CP_XML_STREAM(), drawing_state);
if (false == drawing_state->xmlEffectAlternative.empty())
{
CP_XML_STREAM() << drawing_state->xmlEffectAlternative;
}
else
{
if (drawing_state->shadow.enabled && drawing_state->shadow.offsetX != 0)
{
double dist = sqrt(drawing_state->shadow.offsetX * drawing_state->shadow.offsetX +
drawing_state->shadow.offsetY * drawing_state->shadow.offsetY);
double dir = atan(abs(drawing_state->shadow.offsetY / drawing_state->shadow.offsetX)) * 180. / 3.1415926;
if (drawing_state->shadow.offsetX < 0 && drawing_state->shadow.offsetY < 0)
dir += 180;
else if (drawing_state->shadow.offsetX < 0)
dir = 180 - dir;
else if (drawing_state->shadow.offsetY < 0)
dir = 360 - dir;
CP_XML_NODE(L"a:effectLst")
{
CP_XML_NODE(L"a:outerShdw")
{
CP_XML_ATTR(L"dist", (int)(dist));
CP_XML_ATTR(L"dir", (int)(dir * 60000));
CP_XML_ATTR(L"sx", (int)(drawing_state->shadow.scaleX2X * 100000 + 0.5));
CP_XML_ATTR(L"sy", (int)(drawing_state->shadow.scaleY2Y * 100000 + 0.5));
CP_XML_ATTR(L"rotWithShape", 0);
serialize_color(CP_XML_STREAM(), drawing_state->shadow.color, drawing_state->shadow.opacity);
}
}
}
//serialize_effect(CP_XML_STREAM(), drawing_state);
}
}
if (false == drawing_state->xmlStyleAlternative.empty())
{
CP_XML_STREAM() << drawing_state->xmlStyleAlternative;
}
serialize_text(CP_XML_STREAM(), drawing_state);
}
}
drawing_state->shape = strm.str();
}
bool xlsx_drawing_context::is_lined_shape(_drawing_state_ptr & drawing_state)
{
if (drawing_state->shape_id == msosptStraightConnector1 ||
drawing_state->shape_id == msosptLine ||
drawing_state->shape_id == msosptBentConnector2 ||
drawing_state->shape_id == msosptBentConnector3 ||
drawing_state->shape_id == msosptBentConnector4 ||
drawing_state->shape_id == msosptBentConnector5 ||
drawing_state->shape_id == msosptCurvedConnector2 ||
drawing_state->shape_id == msosptCurvedConnector3 ||
drawing_state->shape_id == msosptCurvedConnector4 ||
drawing_state->shape_id == msosptCurvedConnector5 )return true;
return false;
}
std::wstring xlsx_drawing_context::convert_custom_shape(_drawing_state_ptr & drawing_state)
{
CBaseShapePtr shapePtr = CPPTShape::CreateByType(static_cast<PPTShapes::ShapeType>(drawing_state->shape_id));
CPPTShape *shape = dynamic_cast<CPPTShape*>(shapePtr.get());
if (shape == NULL) return L"";
std::wstring strResult;
std::wstringstream strm;
shape->m_oCustomVML.SetAdjusts(&shape->m_arAdjustments);
for (size_t i = 0 ; i < drawing_state->custom_verticles.size(); i++)
{
Aggplus::POINT p;
p.x = drawing_state->custom_verticles[i].x;
p.y = drawing_state->custom_verticles[i].y;
shape->m_oCustomVML.m_arVertices.push_back(p);
}
for (size_t i = 0 ; i < drawing_state->custom_guides.size(); i++)
{// todo merge/combine !!
NSCustomVML::CGuide guid;
guid.m_eType = drawing_state->custom_guides[i].m_eType;
guid.m_param_type1 = drawing_state->custom_guides[i].m_param_type1;
guid.m_param_type2 = drawing_state->custom_guides[i].m_param_type2;
guid.m_param_type3 = drawing_state->custom_guides[i].m_param_type3;
guid.m_param_value1 = drawing_state->custom_guides[i].m_param_value1;
guid.m_param_value2 = drawing_state->custom_guides[i].m_param_value2;
guid.m_param_value3 = drawing_state->custom_guides[i].m_param_value3;
shape->m_oCustomVML.addGuide(guid);
}
for (size_t i = 0 ; i < drawing_state->custom_segments.size(); i++)
{
if (0 == drawing_state->custom_segments[i].m_nCount)
{
if ((ODRAW::rtEnd != drawing_state->custom_segments[i].m_eRuler) &&
(ODRAW::rtNoFill != drawing_state->custom_segments[i].m_eRuler) &&
(ODRAW::rtNoStroke != drawing_state->custom_segments[i].m_eRuler) &&
(ODRAW::rtClose != drawing_state->custom_segments[i].m_eRuler))
{
continue;
}
}
shape->m_oCustomVML.addSegment(drawing_state->custom_segments[i].m_eRuler , drawing_state->custom_segments[i].m_nCount);
}
//for (int i = 0; i < drawing_state->custom_adjustHandles.size(); i++)
//{// todo - this wasn't here before ?????
// shape->m_oCustomVML.addHandle(i, *drawing_state->custom_adjustHandles[i]);
//}
for (size_t i = 0; i < drawing_state->custom_adjustValues.size(); i++)
{
if (drawing_state->custom_adjustValues[i])
{
shape->m_oCustomVML.addAdjust(i, *drawing_state->custom_adjustValues[i]);
}
}
if (drawing_state->custom_path >= 0)
shape->m_oCustomVML.SetPath((ODRAW::RulesType)drawing_state->custom_path);
shape->m_oCustomVML.ToCustomShape(shape, shape->m_oManager);
shape->ReCalculate();
//-------------------------------------------------------------------------------------
if (drawing_state->custom_rect.cx > 0 && drawing_state->custom_rect.cy > 0)
{
shape->m_oPath.SetCoordsize(drawing_state->custom_rect.cx, drawing_state->custom_rect.cy);
}
NSGuidesVML::CFormParam pParamCoef;
pParamCoef.m_eType = NSGuidesVML::ptValue;
pParamCoef.m_lParam = 65536;
pParamCoef.m_lCoef = 65536;
NSGuidesVML::CFormulaConverter pFormulaConverter;
//coeff
pFormulaConverter.ConvertCoef(pParamCoef);
//guids----------------------------------------
int nGuidCount = shape->m_oManager.m_arFormulas.size();
if (0 != nGuidCount)
{
pFormulaConverter.ConvertFormula(shape->m_oManager.m_arFormulas);
}
//path------------------------------------------
int nPathCount = shape->m_strPath.length();
if (0 != nPathCount && shape->m_eType != 1)
{
pFormulaConverter.ConvertPath(shape->m_strPath, shape->m_oPath);
//string rect
int nRectCount = (int)shape->m_arStringTextRects.size();
if (0 != nRectCount)
{
pFormulaConverter.ConvertTextRect(shape->m_arStringTextRects[0]);
}
int nHandlesCount = shape->m_arHandles.size();
int nAdjCount = shape->m_arAdjustments.size();
//handles
if (0 != nHandlesCount || 0 != nAdjCount)
{
pFormulaConverter.ConvertHandle(shape->m_arHandles, shape->m_arAdjustments, shape->m_eType);
}
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"a:avLst")
{
CP_XML_STREAM() << pFormulaConverter.m_oAdjRes.GetXmlString();
}
CP_XML_NODE(L"a:gdLst")
{
CP_XML_STREAM() << pFormulaConverter.m_oCoef.GetXmlString();
CP_XML_STREAM() << pFormulaConverter.m_oGuidsRes.GetXmlString();
}
CP_XML_NODE(L"a:ahLst")
{
CP_XML_STREAM() << pFormulaConverter.m_oHandleRes.GetXmlString();
}
//connectors-------------------------
CP_XML_NODE(L"a:cxnLst");
////textRect---------------------------
//if (pFormulaConverter.m_oTextRect.GetSize() != 0)
strm << pFormulaConverter.m_oTextRect.GetXmlString();
CP_XML_NODE(L"a:pathLst")
{
CP_XML_STREAM() << pFormulaConverter.m_oPathRes.GetXmlString();
}
}
strResult = strm.str();
}
//delete shape;
//shapePtr.reset();
return strResult;
}
void xlsx_drawing_context::reset_fill_pattern (_drawing_state_ptr & drawing_state)
{
if (drawing_state->fill.type == fillPattern)
{
std::wstring rgbColor1 = drawing_state->fill.color.sRGB;
std::wstring rgbColor2 = drawing_state->fill.color2.sRGB;
if (rgbColor1.empty())
{
if (drawing_state->fill.color.index >= 8)
rgbColor1 = standart_color[drawing_state->fill.color.index - 8];
else
rgbColor1 = L"0";
}
if (rgbColor2.empty() )
{
if ( drawing_state->fill.color2.index >= 8)
rgbColor2 = standart_color[drawing_state->fill.color2.index - 8];
else
rgbColor2 = L"0";
}
ChangeBlack2ColorImage( rgbColor2, rgbColor1, drawing_state );
drawing_state->fill.type = fillTexture;
drawing_state->fill.texture_mode = textureTill;
}
}
void xlsx_drawing_context::serialize_fill(std::wostream & stream, _drawing_state::_fill & fill)
{
if (fill.type == fillNone)
{
serialize_none_fill(stream);
return;
}
if (!fill.texture_target.empty() && fill.type == fillTexture)
{
bool isIternal = false;
std::wstring rId = handle_.impl_->get_mediaitems().find_image( fill.texture_target, isIternal);
if (!rId.empty())
{
if (in_chart_ == true)
{
context_.current_chart().add_rels( isIternal, rId , fill.texture_target, external_items::typeImage);
}
else
{
rels_->add(isIternal, rId , fill.texture_target, external_items::typeImage);
}
serialize_bitmap_fill(stream, fill, rId);
return;
}
}
if (fill.type == fillGradient || fill.type == fillGradientOne)
{
serialize_gradient_fill(stream, fill);
return;
}
//------------
if (fill.color.index >= 0 || !fill.color.sRGB.empty())
{
serialize_solid_fill(stream, fill.color, fill.color.opacity);
}
else serialize_none_fill(stream);
}
void xlsx_drawing_context::clear_fill()
{
if (!current_drawing_states) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->clear_fill();
}
int xlsx_drawing_context::get_fill_type()
{
if (!current_drawing_states) return 0;
if (current_drawing_states->empty()) return 0;
return current_drawing_states->back()->fill.type;
}
void xlsx_drawing_context::serialize_fill(std::wostream & stream)
{
serialize_fill(stream, current_drawing_states->back());
}
void xlsx_drawing_context::serialize_fill(std::wostream & stream, _drawing_state_ptr & drawing_state)
{
if (drawing_state->fill.type == fillPattern)
reset_fill_pattern(drawing_state);
if (drawing_state->wordart.is)
serialize_none_fill(stream);
else
serialize_fill(stream, drawing_state->fill);
}
void xlsx_drawing_context::serialize_line(std::wostream & stream, _drawing_state_ptr & drawing_state)
{
if (drawing_state->wordart.is) return;
serialize_line(stream, drawing_state->line);
}
void xlsx_drawing_context::serialize_none_fill(std::wostream & stream)
{
CP_XML_WRITER(stream)
{
CP_XML_NODE(L"a:noFill");
}
}
void xlsx_drawing_context::serialize_solid_fill(std::wostream & stream, const _color & color, double opacity)
{
CP_XML_WRITER(stream)
{
CP_XML_NODE(L"a:solidFill")
{
serialize_color(CP_XML_STREAM(), color, opacity);
}
}
}
void xlsx_drawing_context::serialize_gradient_fill(std::wostream & stream, _drawing_state::_fill & fill)
{
CP_XML_WRITER(stream)
{
CP_XML_NODE(L"a:gradFill")
{
CP_XML_ATTR(L"rotWithShape", 0);
CP_XML_NODE(L"a:gsLst")
{
if (fill.colorsPosition.empty() && fill.focus != 0)
{
if (fill.focus > 0)
{
fill.colorsPosition.push_back(std::pair<double, _color>(0., fill.color));
fill.colorsPosition.push_back(std::pair<double, _color>(fill.focus/100., fill.color2));
fill.colorsPosition.push_back(std::pair<double, _color>(1., fill.color));
}
else if (fill.focus < 0)
{
fill.colorsPosition.push_back(std::pair<double, _color>(0., fill.color2));
fill.colorsPosition.push_back(std::pair<double, _color>(-fill.focus/100., fill.color));
fill.colorsPosition.push_back(std::pair<double, _color>(1., fill.color2));
}
}
if ( !fill.colorsPosition.empty() )
{
for (size_t i = 0; i < fill.colorsPosition.size(); i++)
{
CP_XML_NODE(L"a:gs")
{
CP_XML_ATTR(L"pos", (int)(fill.colorsPosition[i].first * 100000));
serialize_color(CP_XML_STREAM(), fill.colorsPosition[i].second, fill.colorsPosition[i].second.opacity);
// check that if there are indices here, they are taken from programmatic ones not user ones (see below)
}
}
}
else
{
CP_XML_NODE(L"a:gs")
{
fill.color.bScheme = false; // by common indices
CP_XML_ATTR(L"pos", 0);
serialize_color(CP_XML_STREAM(), fill.color, fill.color.opacity);
}
CP_XML_NODE(L"a:gs")
{
fill.color2.bScheme = false; // by common indices
CP_XML_ATTR(L"pos", 100000);
serialize_color(CP_XML_STREAM(), fill.color2, fill.color2.opacity);
}
}
}
CP_XML_NODE(L"a:lin")
{
int val = 90 - fill.angle;
if (val < 0) val = 0;
CP_XML_ATTR(L"ang", val * 60000);
CP_XML_ATTR(L"scaled", 1);
}
}
}
}
void xlsx_drawing_context::serialize_anchor (std::wostream & stream, _drawing_state_ptr & drawing_state, std::wstring ns)
{
CP_XML_WRITER(stream)
{
if (drawing_state->type_anchor == 1)
{
if (drawing_state->sheet_anchor.colFrom < 0) drawing_state->sheet_anchor.colFrom = 0;
if (drawing_state->sheet_anchor.rwFrom < 0) drawing_state->sheet_anchor.rwFrom = 0;
CP_XML_NODE(ns + L"from")
{
CP_XML_NODE(L"xdr:col") { CP_XML_CONTENT (drawing_state->sheet_anchor.colFrom); }
CP_XML_NODE(L"xdr:colOff") { CP_XML_CONTENT (drawing_state->sheet_anchor.xFrom) ; }
CP_XML_NODE(L"xdr:row") { CP_XML_CONTENT (drawing_state->sheet_anchor.rwFrom); }
CP_XML_NODE(L"xdr:rowOff") { CP_XML_CONTENT (drawing_state->sheet_anchor.yFrom) ; }
}
CP_XML_NODE(ns + L"to")
{
CP_XML_NODE(L"xdr:col") { CP_XML_CONTENT (drawing_state->sheet_anchor.colTo); }
CP_XML_NODE(L"xdr:colOff") { CP_XML_CONTENT (drawing_state->sheet_anchor.xTo); }
CP_XML_NODE(L"xdr:row") { CP_XML_CONTENT (drawing_state->sheet_anchor.rwTo); }
CP_XML_NODE(L"xdr:rowOff") { CP_XML_CONTENT (drawing_state->sheet_anchor.yTo); }
}
}
if (drawing_state->type_anchor == 3)
{
CP_XML_NODE(ns + L"pos")//in emu (1 pt = 12700)
{
CP_XML_ATTR(L"x", (int)(drawing_state->absolute_anchor.x * 12700));
CP_XML_ATTR(L"y", (int)(drawing_state->absolute_anchor.y * 12700));
}
CP_XML_NODE(ns + L"ext") //in emu (1 pt = 12700)
{
CP_XML_ATTR(L"cx", (int)(drawing_state->absolute_anchor.cx * 12700));
CP_XML_ATTR(L"cy", (int)(drawing_state->absolute_anchor.cy * 12700));
}
}
}
}
void xlsx_drawing_context::serialize_xfrm(std::wostream & stream, _drawing_state_ptr & drawing_state)
{
std::wstring nameXfrm = L"a:xfrm";
if (drawing_state->type == external_items::typeChart)
nameXfrm = L"xdr:xfrm";
CP_XML_WRITER(stream)
{
CP_XML_NODE(nameXfrm)
{
if (drawing_state->flipV) CP_XML_ATTR(L"flipV", true);
if (drawing_state->flipH) CP_XML_ATTR(L"flipH", true);
if (drawing_state->rotation != 0)
{
if (drawing_state->rotation > 180)
{
drawing_state->rotation -= 360.;
}
CP_XML_ATTR(L"rot", (int)(drawing_state->rotation * 60000));
}
CP_XML_NODE(L"a:off")
{
CP_XML_ATTR(L"x", drawing_state->child_anchor.x);
CP_XML_ATTR(L"y", drawing_state->child_anchor.y);
}
CP_XML_NODE(L"a:ext")
{
CP_XML_ATTR(L"cx", drawing_state->child_anchor.cx);
CP_XML_ATTR(L"cy", drawing_state->child_anchor.cy);
}
if (drawing_state->type == external_items::typeGroup)
{
CP_XML_NODE(L"a:chOff")
{
CP_XML_ATTR(L"x", drawing_state->group_anchor.x);
CP_XML_ATTR(L"y", drawing_state->group_anchor.y);
}
CP_XML_NODE(L"a:chExt")
{
CP_XML_ATTR(L"cx", drawing_state->group_anchor.cx);
CP_XML_ATTR(L"cy", drawing_state->group_anchor.cy);
}
}
}
}
}
void xlsx_drawing_context::serialize_color (std::wostream & stream, const _color &color, double opacity)
{
CP_XML_WRITER(stream)
{
if (!color.sRGB.empty())
{
CP_XML_NODE(L"a:srgbClr")
{
CP_XML_ATTR(L"val", color.sRGB);
if (opacity > 0.00001)
{
CP_XML_NODE(L"a:alpha")
{
CP_XML_ATTR(L"val", (int)(opacity * 100000));
}
}
}
}
else if (color.index >=0 && color.index < 17 && color.bScheme && color.index != 14)
{
CP_XML_NODE(L"a:schemeClr")
{
CP_XML_ATTR(L"val", shemeColor[color.index]);
if (opacity > 0.00001)
{
CP_XML_NODE(L"a:alpha")
{
CP_XML_ATTR(L"val", (int)(opacity * 100000));
}
}
}
}
else if (color.index >= 8 && color.index < 57)
{
CP_XML_NODE(L"a:srgbClr")
{
CP_XML_ATTR(L"val", standart_color[color.index - 8]);
if (opacity > 0.00001)
{
CP_XML_NODE(L"a:alpha")
{
CP_XML_ATTR(L"val", (int)(opacity * 100000));
}
}
}
}
else
{
CP_XML_NODE(L"a:schemeClr")
{
CP_XML_ATTR(L"val", L"lt1");
}
}
}
}
void xlsx_drawing_context::serialize_text(std::wostream & stream, _drawing_state_ptr & drawing_state)
{
if (!drawing_state) return;
if (drawing_state->text.content.empty() && drawing_state->wordart.text.empty()) return;
if (false == drawing_state->xmlTxBodyAlternative.empty())
{
stream << drawing_state->xmlTxBodyAlternative;
return;
}
CP_XML_WRITER(stream)
{
CP_XML_NODE(L"xdr:txBody")
{
CP_XML_NODE(L"a:bodyPr")//todooo rtl
{
if (drawing_state->text.wrap == 2 || drawing_state->wordart.is)
CP_XML_ATTR(L"wrap", L"none" );
else if (drawing_state->bCustom)
CP_XML_ATTR(L"wrap", L"square");
if (false == drawing_state->text.fit_shape)
{
CP_XML_ATTR(L"horzOverflow", L"clip");
CP_XML_ATTR(L"vertOverflow", L"clip");
}
if (drawing_state->wordart.is)
{
CP_XML_ATTR(L"fromWordArt", 1);
if (drawing_state->wordart.vertical)
CP_XML_ATTR(L"vert", L"wordArtVert");
std::wstring prstTxWarp = Spt2WordArtShapeType(drawing_state->shape_id);
CP_XML_NODE(L"a:prstTxWarp")
{
CP_XML_ATTR(L"prst", prstTxWarp);
CP_XML_NODE(L"a:avLst");// modifiers
}
}
else
{
CP_XML_ATTR(L"lIns", drawing_state->text.margins.left);
CP_XML_ATTR(L"tIns", drawing_state->text.margins.top);
CP_XML_ATTR(L"rIns", drawing_state->text.margins.right);
CP_XML_ATTR(L"bIns", drawing_state->text.margins.bottom);
switch (drawing_state->text.vert_align)
{
case 1: CP_XML_ATTR(L"anchor", L"t"); break;
case 2: CP_XML_ATTR(L"anchor", L"ctr"); break;
case 3: CP_XML_ATTR(L"anchor", L"b"); break;
}
switch(drawing_state->text.vertical)
{
case 1:
case 3: CP_XML_ATTR(L"vert", L"vert"); break;
case 2: CP_XML_ATTR(L"vert", L"vert270"); break;
case 5: CP_XML_ATTR(L"vert", L"wordArtVert"); break;
}
}
//text margins
}
CP_XML_NODE(L"a:lstStyle");
CP_XML_NODE(L"a:p")
{
CP_XML_NODE(L"a:pPr")
{
switch(drawing_state->text.align)
{
case 1: CP_XML_ATTR(L"algn", L"l"); break;
case 2: CP_XML_ATTR(L"algn", L"ctr"); break;
case 3: CP_XML_ATTR(L"algn", L"r"); break;
case 4: CP_XML_ATTR(L"algn", L"just"); break;
case 5: CP_XML_ATTR(L"algn", L"dist"); break;
}
}
if (drawing_state->wordart.is)
{
CP_XML_NODE(L"a:r")
{
CP_XML_NODE(L"a:rPr")
{
if (drawing_state->wordart.size < 1) drawing_state->wordart.size = 36;
CP_XML_ATTR(L"sz", (int)(drawing_state->wordart.size * 100));
if (drawing_state->wordart.bold) CP_XML_ATTR(L"b", 1);
if (drawing_state->wordart.italic) CP_XML_ATTR(L"i", 1);
if (drawing_state->wordart.underline) CP_XML_ATTR(L"u", L"sng");
if (drawing_state->wordart.strike) CP_XML_ATTR(L"strike", L"sngStrike");
//if (drawing_state->wordart.cap) CP_XML_ATTR(L"cap", *cap);
CP_XML_ATTR(L"kern", 10);
if (drawing_state->wordart.spacing > 1)
CP_XML_ATTR(L"spc", (int) ((drawing_state->wordart.spacing - 1 ) * 3600.));
else if (drawing_state->wordart.spacing < 1)
CP_XML_ATTR(L"spc", (int) ((drawing_state->wordart.spacing - 1 ) * 1800.));
else
CP_XML_ATTR(L"spc", 0);
serialize_line(CP_XML_STREAM(), drawing_state->line);
serialize_fill(CP_XML_STREAM(), drawing_state->fill);
if (!drawing_state->wordart.font.empty())
{
CP_XML_NODE(L"a:latin") {CP_XML_ATTR(L"typeface", drawing_state->wordart.font);}
CP_XML_NODE(L"a:cs") {CP_XML_ATTR(L"typeface", drawing_state->wordart.font);}
}
}
CP_XML_NODE(L"a:t")
{
CP_XML_STREAM() << drawing_state->wordart.text;
}
}
}
else
{
CP_XML_STREAM() << drawing_state->text.content;
}
}
}
}
}
void xlsx_drawing_context::serialize_line(std::wostream & stream, _drawing_state::_line & line)
{
if (line.fill.type == fillNone) return;
CP_XML_WRITER(stream)
{
CP_XML_NODE(L"a:ln")
{
if (line.width > 0)
CP_XML_ATTR(L"w", line.width);//in emu (1 pt = 12700) ???
else
CP_XML_ATTR(L"w", 9525); //default
switch(line.endcap)
{
case 0: CP_XML_ATTR(L"cap", L"rnd"); break;
case 1: CP_XML_ATTR(L"cap", L"sq"); break;
case 2: CP_XML_ATTR(L"cap", L"flat"); break;
}
serialize_fill(CP_XML_STREAM(), line.fill);
CP_XML_NODE(L"a:prstDash")
{
switch(line.typeDash)
{
case lineSolid: CP_XML_ATTR(L"val", L"solid"); break;
case lineDash: CP_XML_ATTR(L"val", L"dash"); break;
case lineDot: CP_XML_ATTR(L"val", L"dot"); break;
case lineDashDot: CP_XML_ATTR(L"val", L"dashDot"); break;
case lineDashDotDot:CP_XML_ATTR(L"val", L"lgDashDotDot"); break;
}
}
switch(line.join)
{
case 0: CP_XML_NODE(L"a:bevel"); break;
case 1:
CP_XML_NODE(L"a:miter")
{
if (line.miter > 0)
CP_XML_ATTR(L"lim", line.miter * 1000);
}break;
case 2: CP_XML_NODE(L"a:round"); break;
}
if (line.arrow.enabled)
{
serialize_arrow(CP_XML_STREAM(), L"a:headEnd", line.arrow.start, line.arrow.start_width, line.arrow.start_length);
serialize_arrow(CP_XML_STREAM(), L"a:tailEnd", line.arrow.end, line.arrow.end_width, line.arrow.end_length);
}
}
}
}
void xlsx_drawing_context::serialize_arrow(std::wostream & stream, std::wstring name, int type, int width, int length)
{
if (type < 1) return;
CP_XML_WRITER(stream)
{
CP_XML_NODE(name)
{
switch(type)
{
case 1: CP_XML_ATTR(L"type", L"triangle"); break;
case 2: CP_XML_ATTR(L"type", L"stealth"); break;
case 3: CP_XML_ATTR(L"type", L"diamond"); break;
case 4: CP_XML_ATTR(L"type", L"oval"); break;
case 5: CP_XML_ATTR(L"type", L"arrow"); break;
}
switch(width)
{
case 1: CP_XML_ATTR(L"w", L"lg"); break;
case 2: CP_XML_ATTR(L"w", L"med"); break;
case 3: CP_XML_ATTR(L"w", L"sm"); break;
}
switch(length)
{
case 1: CP_XML_ATTR(L"len", L"lg"); break;
case 2: CP_XML_ATTR(L"len", L"med");break;
case 3: CP_XML_ATTR(L"len", L"sm"); break;
}
}
}
}
void xlsx_drawing_context::serialize_bitmap_fill(std::wostream & stream, _drawing_state::_fill & fill, std::wstring rId, const std::wstring ns)
{
CP_XML_WRITER(stream)
{
CP_XML_NODE(ns + L"blipFill")
{
CP_XML_NODE(L"a:blip")
{
CP_XML_ATTR(L"r:embed", rId);
if (fill.grayscale)
{
CP_XML_NODE(L"a:grayscl");
}
if (fill.brightness || fill.contrast)
{
CP_XML_NODE(L"a:lum")
{
if (fill.brightness)CP_XML_ATTR(L"bright", *fill.brightness * 1000);
if (fill.contrast) CP_XML_ATTR(L"contrast", *fill.contrast * 1000);
}
}
if (fill.biLevel)
{
CP_XML_NODE(L"a:biLevel")
{
CP_XML_ATTR(L"thresh", *fill.biLevel * 1000);
}
}
if (fill.color.opacity > 0.00001)
{
CP_XML_NODE(L"a:alphaModFix")
{
CP_XML_ATTR(L"amt", (int)(fill.color.opacity * 100000));
}
}
}
CP_XML_NODE(L"a:srcRect")
{
if (fill.texture_crop_enabled)
{
CP_XML_ATTR(L"l", static_cast<long>(fill.texture_crop[0] * 10000));
CP_XML_ATTR(L"t", static_cast<long>(fill.texture_crop[1] * 10000));
CP_XML_ATTR(L"r", static_cast<long>(fill.texture_crop[2] * 10000));
CP_XML_ATTR(L"b", static_cast<long>(fill.texture_crop[3] * 10000));
}
}
if (fill.texture_mode == textureStretch)
{
CP_XML_NODE(L"a:stretch")
{
CP_XML_NODE(L"a:fillRect");
}
}
if (fill.texture_mode == textureTill)
{
CP_XML_NODE(L"a:tile");
}
}
}
}
void xlsx_drawing_context::serialize(std::wostream & stream, _drawing_state_ptr & drawing_state)
{
if (drawing_state->type_anchor == 0) return;
std::wstring sNodeAnchor;
if (drawing_state->type_anchor == 1) sNodeAnchor = L"xdr:twoCellAnchor";
else if (drawing_state->type_anchor == 2) sNodeAnchor = L"xdr:oneCellAnchor";
else if (drawing_state->type_anchor == 3) sNodeAnchor = L"xdr:absoluteAnchor";
if (sNodeAnchor.empty()) return;
CP_XML_WRITER(stream)
{
CP_XML_NODE(sNodeAnchor)
{
//if (drawing_state->anchor.type == 1) CP_XML_ATTR(L"editAs", L"oneCell");
serialize_anchor(CP_XML_STREAM(), drawing_state);
if (!drawing_state->xmlAlternative.empty())
{
CP_XML_STREAM() << drawing_state->xmlAlternative;
}
else
{
CP_XML_STREAM() << drawing_state->shape;
}
CP_XML_NODE(L"xdr:clientData");
}
}
}
void xlsx_drawing_context::serialize_control(std::wostream & strm, _drawing_state_ptr & drawing_state)
{
if (drawing_state->type != external_items::typeActiveX &&
drawing_state->type != external_items::typeControl) return;
if (drawing_state->type_anchor == 3)
{//absolute
drawing_state->sheet_anchor.colFrom = 1;
drawing_state->sheet_anchor.colTo = 1;
drawing_state->sheet_anchor.rwFrom = 0;
drawing_state->sheet_anchor.rwTo = 0;
drawing_state->sheet_anchor.xFrom = drawing_state->absolute_anchor.x;
drawing_state->sheet_anchor.yFrom = drawing_state->absolute_anchor.y;
drawing_state->sheet_anchor.xTo = drawing_state->absolute_anchor.x + drawing_state->absolute_anchor.cx;
drawing_state->sheet_anchor.yTo = drawing_state->absolute_anchor.y + drawing_state->absolute_anchor.cy;
drawing_state->type_anchor = 1;
}
else if (drawing_state->type_anchor == 0)
{//child in group
drawing_state->sheet_anchor.colFrom = 1;
drawing_state->sheet_anchor.colTo = 1;
drawing_state->sheet_anchor.rwFrom = 0;
drawing_state->sheet_anchor.rwTo = 0;
drawing_state->sheet_anchor.xFrom = drawing_state->child_anchor.x;
drawing_state->sheet_anchor.yFrom = drawing_state->child_anchor.y;
drawing_state->sheet_anchor.xTo = drawing_state->child_anchor.x + drawing_state->child_anchor.cx;
drawing_state->sheet_anchor.yTo = drawing_state->child_anchor.y + drawing_state->child_anchor.cy;
drawing_state->type_anchor = 1;
}
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"control")
{
CP_XML_ATTR(L"shapeId", drawing_state->id);
CP_XML_ATTR(L"r:id", drawing_state->objectId);
if (!drawing_state->name.empty())
{
CP_XML_ATTR(L"name", drawing_state->name);
}
CP_XML_NODE(L"controlPr")
{
CP_XML_ATTR(L"defaultSize", 0);
CP_XML_ATTR(L"autoLine", drawing_state->object.bAutoLine);
CP_XML_ATTR(L"autoPict", drawing_state->object.bAutoPict);
if (!drawing_state->object.link.empty())
{
CP_XML_ATTR(L"linkedCell", drawing_state->object.link);
}
if (!drawing_state->object.fmlaRange.empty())
{
CP_XML_ATTR(L"listFillRange", drawing_state->object.fmlaRange);
}
if (!drawing_state->fill.picture_target.empty())
drawing_state->fill.texture_target = drawing_state->fill.picture_target;
if (!drawing_state->fill.texture_target.empty())
{
bool isIternal = false;
std::wstring rId = handle_.impl_->get_mediaitems().find_image( drawing_state->fill.texture_target, isIternal);
CP_XML_ATTR(L"r:id", rId);
sheet_rels_->add(isIternal, rId , drawing_state->fill.texture_target, external_items::typeImage);
}
CP_XML_NODE(L"anchor")
{
CP_XML_ATTR(L"moveWithCells", 1);
serialize_anchor(CP_XML_STREAM(), drawing_state, L"");
}
}
}
}
}
void xlsx_drawing_context::serialize_control_props(std::wostream & strm, _drawing_state_ptr & drawing_state)
{
if (drawing_state == NULL) return;
if (drawing_state->type != external_items::typeActiveX &&
drawing_state->type != external_items::typeControl) return;
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"formControlPr")
{
CP_XML_ATTR(L"xmlns", L"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main" );
switch(drawing_state->type_control)
{
case 0x0000: CP_XML_ATTR(L"objectType", L"Group"); break;
case 0x0001: CP_XML_ATTR(L"objectType", L"Shape"); break; // Line
case 0x0002: CP_XML_ATTR(L"objectType", L"Rect"); break;
case 0x0003: CP_XML_ATTR(L"objectType", L"Shape"); break; // Oval
case 0x0004: CP_XML_ATTR(L"objectType", L"Shape"); break; // Arc
case 0x0006: CP_XML_ATTR(L"objectType", L"Shape"); break; // Text
case 0x0007: CP_XML_ATTR(L"objectType", L"Button"); break;
case 0x0008: CP_XML_ATTR(L"objectType", L"Pict"); break;
case 0x0009: CP_XML_ATTR(L"objectType", L"Shape"); break; // Polygon:
case 0x000B: CP_XML_ATTR(L"objectType", L"CheckBox"); break;
case 0x000C: CP_XML_ATTR(L"objectType", L"Radio"); break;
case 0x000D: CP_XML_ATTR(L"objectType", L"Edit"); break;
case 0x000E: CP_XML_ATTR(L"objectType", L"Label"); break;
case 0x000F: CP_XML_ATTR(L"objectType", L"Dialog"); break;
case 0x0010: CP_XML_ATTR(L"objectType", L"Spin"); break;
case 0x0012: CP_XML_ATTR(L"objectType", L"List"); break;
case 0x0013: CP_XML_ATTR(L"objectType", L"GBox"); break;
case 0x0011: CP_XML_ATTR(L"objectType", L"Scroll"); break;
case 0x0014: CP_XML_ATTR(L"objectType", L"Drop"); break;
case 0x001E: CP_XML_ATTR(L"objectType", L"Shape"); break; // OfficeArt object
case 0x0019: CP_XML_ATTR(L"objectType", L"Note"); break;
default: break;
}
if (drawing_state->object.drop_style)
{
switch(*drawing_state->object.drop_style)
{
case 0:
default:
CP_XML_ATTR(L"dropStyle", L"combo");
}
}
if (!drawing_state->object.link.empty() )
{
CP_XML_ATTR(L"fmlaLink", drawing_state->object.link);
}
if (!drawing_state->object.fmlaRange.empty() )
{
CP_XML_ATTR(L"fmlaRange", drawing_state->object.fmlaRange);
}
if (drawing_state->object.x_min)
{
CP_XML_ATTR(L"min", *drawing_state->object.x_min);
}
if (drawing_state->object.x_max)
{
CP_XML_ATTR(L"max", *drawing_state->object.x_max);
}
if (drawing_state->object.x_inc)
{
CP_XML_ATTR(L"inc", *drawing_state->object.x_inc);
}
if (drawing_state->object.x_page)
{
CP_XML_ATTR(L"page", *drawing_state->object.x_page);
}
if (drawing_state->object.x_sel)
{
CP_XML_ATTR(L"sel", *drawing_state->object.x_sel);
}
if (drawing_state->object.x_val)
{
CP_XML_ATTR(L"val", *drawing_state->object.x_val);
}
if (drawing_state->object.drop_lines)
{
CP_XML_ATTR(L"dropLines", *drawing_state->object.drop_lines);
}
if (drawing_state->object.dx)
{
CP_XML_ATTR(L"dx", *drawing_state->object.dx);
}
if (drawing_state->object.checked && (*drawing_state->object.checked))
{
CP_XML_ATTR(L"checked", L"Checked");
}
if (drawing_state->object._3D)
{
CP_XML_ATTR(L"noThreeD", !(*drawing_state->object._3D));
}
if (drawing_state->object.vscroll)
{
CP_XML_ATTR(L"verticalBar", *drawing_state->object.vscroll);
}
if (drawing_state->object.hscroll)
{
CP_XML_ATTR(L"horiz", *drawing_state->object.hscroll);
}
if (drawing_state->object.multiLine)
{
CP_XML_ATTR(L"multiLine", *drawing_state->object.multiLine);
}
}
}
}
void xlsx_drawing_context::serialize_object(std::wostream & stream, _drawing_state_ptr & drawing_state)
{
if (drawing_state->type != external_items::typeOleObject) return;
if (drawing_state->type_anchor == 3)
{//absolute
drawing_state->sheet_anchor.colFrom = 1;
drawing_state->sheet_anchor.colTo = 1;
drawing_state->sheet_anchor.rwFrom = 0;
drawing_state->sheet_anchor.rwTo = 0;
drawing_state->sheet_anchor.xFrom = drawing_state->absolute_anchor.x;
drawing_state->sheet_anchor.yFrom = drawing_state->absolute_anchor.y;
drawing_state->sheet_anchor.xTo = drawing_state->absolute_anchor.x + drawing_state->absolute_anchor.cx;
drawing_state->sheet_anchor.yTo = drawing_state->absolute_anchor.y + drawing_state->absolute_anchor.cy;
drawing_state->type_anchor = 1;
}
else if (drawing_state->type_anchor == 0)
{//child in group
drawing_state->sheet_anchor.colFrom = 1;
drawing_state->sheet_anchor.colTo = 1;
drawing_state->sheet_anchor.rwFrom = 0;
drawing_state->sheet_anchor.rwTo = 0;
drawing_state->sheet_anchor.xFrom = drawing_state->child_anchor.x;
drawing_state->sheet_anchor.yFrom = drawing_state->child_anchor.y;
drawing_state->sheet_anchor.xTo = drawing_state->child_anchor.x + drawing_state->child_anchor.cx;
drawing_state->sheet_anchor.yTo = drawing_state->child_anchor.y + drawing_state->child_anchor.cy;
drawing_state->type_anchor = 1;
}
CP_XML_WRITER(stream)
{
CP_XML_NODE(L"oleObject")
{
if (!drawing_state->objectProgId.empty())
{
CP_XML_ATTR(L"progId", drawing_state->objectProgId);
}
CP_XML_ATTR(L"shapeId", drawing_state->id);
CP_XML_ATTR(L"r:id", drawing_state->objectId);
CP_XML_NODE(L"objectPr")
{
CP_XML_ATTR(L"defaultSize", 0);
//CP_XML_ATTR(L"autoPict", 0);
if (!drawing_state->fill.picture_target.empty())
drawing_state->fill.texture_target = drawing_state->fill.picture_target;
if (!drawing_state->fill.texture_target.empty())
{
bool isIternal = false;
std::wstring rId = handle_.impl_->get_mediaitems().find_image( drawing_state->fill.texture_target, isIternal);
CP_XML_ATTR(L"r:id", rId);
sheet_rels_->add(isIternal, rId , drawing_state->fill.texture_target, external_items::typeImage);
}
CP_XML_NODE(L"anchor")
{
CP_XML_ATTR(L"moveWithCells", 1);
serialize_anchor(CP_XML_STREAM(), drawing_state, L"");
}
}
}
}
}
//-------------------------------------------------------------------------------------------------------------------------------
void xlsx_drawing_context::set_name(const std::wstring & str)
{
if (current_drawing_states == NULL) return;
if (str.empty()) return;
current_drawing_states->back()->name = str;
}
void xlsx_drawing_context::set_description(const std::wstring & str)
{
if (current_drawing_states == NULL) return;
if (str.empty()) return;
current_drawing_states->back()->description = str;
}
void xlsx_drawing_context::set_macro(const std::wstring & str)
{
if (current_drawing_states == NULL) return;
current_drawing_states->back()->object.macro = str;
}
void xlsx_drawing_context::set_ole_object(const std::wstring & id, const std::wstring & info)
{
if (current_drawing_states == NULL) return;
current_drawing_states->back()->type = external_items::typeOleObject;
current_drawing_states->back()->objectId = id;
current_drawing_states->back()->objectProgId = info;
}
void xlsx_drawing_context::set_control_activeX(const std::wstring & rid)
{
if (current_drawing_states == NULL) return;
current_drawing_states->back()->type = external_items::typeActiveX;
current_drawing_states->back()->objectId = rid;
}
void xlsx_drawing_context::set_sheet_anchor(int colFrom, int xFrom, int rwFrom, int yFrom, int colTo, int xTo, int rwTo, int yTo,
double x, double y, double cx, double cy)
{
if (current_drawing_states == NULL) return;
if (colTo > 0 || xTo > 0 || rwTo > 0 || yTo > 0)
{// 0 in comment old versions
current_drawing_states->back()->sheet_anchor.colFrom = colFrom;
current_drawing_states->back()->sheet_anchor.colTo = colTo;
current_drawing_states->back()->sheet_anchor.rwFrom = rwFrom;
current_drawing_states->back()->sheet_anchor.rwTo = rwTo;
current_drawing_states->back()->sheet_anchor.xFrom = xFrom;
current_drawing_states->back()->sheet_anchor.yFrom = yFrom;
current_drawing_states->back()->sheet_anchor.xTo = xTo;
current_drawing_states->back()->sheet_anchor.yTo = yTo;
}
current_drawing_states->back()->sheet_anchor.absolute.x = x;
current_drawing_states->back()->sheet_anchor.absolute.y = y;
current_drawing_states->back()->sheet_anchor.absolute.cx = cx;
current_drawing_states->back()->sheet_anchor.absolute.cy = cy;
current_drawing_states->back()->type_anchor = 1;
}
void xlsx_drawing_context::set_child_anchor(int x, int y, int cx, int cy)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->child_anchor.x = x;
current_drawing_states->back()->child_anchor.y = y;
current_drawing_states->back()->child_anchor.cx = cx;
current_drawing_states->back()->child_anchor.cy = cy;
}
void xlsx_drawing_context::set_group_anchor(int x, int y, int cx, int cy)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->group_anchor.x = x;
current_drawing_states->back()->group_anchor.y = y;
current_drawing_states->back()->group_anchor.cx = cx;
current_drawing_states->back()->group_anchor.cy = cy;
}
void xlsx_drawing_context::set_absolute_anchor(double x, double y, double cx, double cy)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
if (current_drawing_states->back()->type_anchor != 0) return;
current_drawing_states->back()->absolute_anchor.x = (int)x;
current_drawing_states->back()->absolute_anchor.y = (int)y;
current_drawing_states->back()->absolute_anchor.cx = (int)cx;
current_drawing_states->back()->absolute_anchor.cy = (int)cy;
current_drawing_states->back()->type_anchor = 3;
}
void xlsx_drawing_context::set_fill_texture_mode(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->fill.texture_mode = (_texture_mode)val;
}
void xlsx_drawing_context::set_fill_texture(const std::wstring & str)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
if (str.empty()) return;
if (false == current_drawing_states->back()->fill.texture_target.empty()) return;
current_drawing_states->back()->fill.texture_target = str;
if (current_drawing_states->back()->fill.type == fillUndefined)
{
current_drawing_states->back()->fill.type = fillTexture;
current_drawing_states->back()->fill.texture_mode = textureStretch;
}
}
void xlsx_drawing_context::set_picture(const std::wstring & str)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
if (str.empty()) return;
if (false == current_drawing_states->back()->fill.picture_target.empty()) return;
current_drawing_states->back()->fill.picture_target = str;
if (current_drawing_states->back()->fill.type == fillUndefined)
{
current_drawing_states->back()->fill.type = fillTexture;
current_drawing_states->back()->fill.texture_mode = textureStretch;
}
}
void xlsx_drawing_context::set_picture_crop_top (double val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->fill.texture_crop[1] = val;
current_drawing_states->back()->fill.texture_crop_enabled = true;
}
void xlsx_drawing_context::set_picture_crop_bottom(double val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->fill.texture_crop[3] = val;
current_drawing_states->back()->fill.texture_crop_enabled = true;
}
void xlsx_drawing_context::set_picture_crop_left (double val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->fill.texture_crop[0] = val;
current_drawing_states->back()->fill.texture_crop_enabled = true;
}
void xlsx_drawing_context::set_picture_crop_right (double val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->fill.texture_crop[2] = val;
current_drawing_states->back()->fill.texture_crop_enabled = true;
}
void xlsx_drawing_context::set_picture_name(const std::wstring & str)
{
current_drawing_states->back()->fill.name = str;
}
void xlsx_drawing_context::set_picture_grayscale(bool val)
{
current_drawing_states->back()->fill.grayscale = val;
}
void xlsx_drawing_context::set_picture_brightness(int val)
{
current_drawing_states->back()->fill.brightness = val;
}
void xlsx_drawing_context::set_picture_contrast(int val)
{
current_drawing_states->back()->fill.contrast = val;
}
void xlsx_drawing_context::set_picture_biLevel(int val)
{
current_drawing_states->back()->fill.biLevel = val;
}
void xlsx_drawing_context::set_picture_transparent(int nColor, const std::wstring & sColor)
{
//....
}
void xlsx_drawing_context::set_shadow_enabled(bool val)
{
current_drawing_states->back()->shadow.enabled = val;
}
void xlsx_drawing_context::set_shadow_type(int val)
{
current_drawing_states->back()->shadow.type = val;
}
void xlsx_drawing_context::set_shadow_opacity(double val)
{
current_drawing_states->back()->shadow.opacity = val;
}
void xlsx_drawing_context::set_shadow_color(int nColor, const std::wstring & sColor)
{
current_drawing_states->back()->shadow.color.sRGB = sColor;
current_drawing_states->back()->shadow.color.nRGB = nColor;
}
void xlsx_drawing_context::set_shadow_highlight(int nColor, const std::wstring & sColor)
{
current_drawing_states->back()->shadow.highlight.sRGB = sColor;
current_drawing_states->back()->shadow.highlight.nRGB = nColor;
}
void xlsx_drawing_context::set_shadow_originX(double val)
{
current_drawing_states->back()->shadow.originX = val;
}
void xlsx_drawing_context::set_shadow_originY(double val)
{
current_drawing_states->back()->shadow.originY = val;
}
void xlsx_drawing_context::set_shadow_offsetX(int val)
{
current_drawing_states->back()->shadow.offsetX = val;
}
void xlsx_drawing_context::set_shadow_offsetY(int val)
{
current_drawing_states->back()->shadow.offsetY = val;
}
void xlsx_drawing_context::set_shadow_scaleX2X(double val)
{
current_drawing_states->back()->shadow.scaleX2X = val;
}
void xlsx_drawing_context::set_shadow_scaleY2Y(double val)
{
current_drawing_states->back()->shadow.scaleY2Y = val;
}
void xlsx_drawing_context::set_rotation (double val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
val -= (int)(val / 360.) * 360;
if (current_drawing_states->back()->flipH && current_drawing_states->back()->flipV/* && current_level > 0*/)
{
val = 180 - val;
}
else if (current_drawing_states->back()->flipH/* && current_level > 0*/)
{
val = 180 + val;
}
else if (current_drawing_states->back()->flipV/* && current_level > 0*/)
{
val = 360 - val;
}
val -= (int)(val / 360.) * 360;
//if (val > 360) val -= 360;
current_drawing_states->back()->rotation = val;
}
void xlsx_drawing_context::set_line_color (int nColor, const std::wstring & sColor)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->line.fill.color.sRGB = sColor;
current_drawing_states->back()->line.fill.color.nRGB = nColor;
}
void xlsx_drawing_context::set_line_color (int index, int type)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
_color color;
if (type == 3)
{
color = CorrectSysColor(index, current_drawing_states->back());
}
else
{
if (index < 64)
{
color.nRGB = shemeDefaultColor[index];
color.sRGB = STR::toRGB(color.nRGB);
}
else if (index > 64 && index < 92)
{
color.nRGB = controlPanelColors1[index - 65];
color.sRGB = STR::toRGB(color.nRGB);
}
color.index = -1;
}
if (color.sRGB.empty())
return;
current_drawing_states->back()->line.fill.color = color;
}
void xlsx_drawing_context::set_fill_angle (double val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->fill.angle = val;
}
void xlsx_drawing_context::set_fill_focus (int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->fill.focus = val;
}
void xlsx_drawing_context::set_fill_color (int nColor, const std::wstring & sColor, bool background)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
if (background)
{
current_drawing_states->back()->fill.color2.sRGB = sColor;
current_drawing_states->back()->fill.color2.nRGB = nColor;
}
else
{
current_drawing_states->back()->fill.color.sRGB = sColor;
current_drawing_states->back()->fill.color.nRGB = nColor;
}
}
void xlsx_drawing_context::set_fill_color (int index, int type, bool background)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
_color color;
if (type == 3)
{
color = CorrectSysColor(index, current_drawing_states->back());
}
else
{
if (index < 64)
{
color.nRGB = shemeDefaultColor[index];
color.sRGB = STR::toRGB(color.nRGB);
}
else if (index > 64 && index < 92)
{
color.nRGB = background ? controlPanelColors2[index - 65] : controlPanelColors1[index - 65];
color.sRGB = STR::toRGB(color.nRGB);
}
color.index = -1;
}
if (color.sRGB.empty())
return;
if (background) current_drawing_states->back()->fill.color2 = color;
else current_drawing_states->back()->fill.color = color;
}
void xlsx_drawing_context::set_fill_opacity (double val, bool background)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
if (background) current_drawing_states->back()->fill.color2.opacity = val;
else current_drawing_states->back()->fill.color.opacity = val;
}
void xlsx_drawing_context::add_fill_colors(double position, const std::wstring & col)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
_color color;
color.sRGB = col;
current_drawing_states->back()->fill.colorsPosition.push_back(std::pair<double, _color>(position, color));
}
void xlsx_drawing_context::add_fill_colors(double position, int index, int type)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
_color color;
color.index = index;
if (type == 1) color.bScheme = true;
current_drawing_states->back()->fill.colorsPosition.push_back(std::pair<double, _color>(position, color));
}
void xlsx_drawing_context::set_fill_type (_fill_type val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->fill.type = val;
}
//---------------------------------------------------------
void xlsx_drawing_context::set_line_dash(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
switch (val)
{
case 0: current_drawing_states->back()->line.typeDash = lineSolid; break;
case 1:
case 6:
case 7: current_drawing_states->back()->line.typeDash = lineDash; break;
case 2:
case 5: current_drawing_states->back()->line.typeDash = lineDot; break;
case 3:
case 8:
case 9: current_drawing_states->back()->line.typeDash = lineDashDot; break;
case 4:
case 10:current_drawing_states->back()->line.typeDash = lineDashDotDot; break;
}
}
void xlsx_drawing_context::set_line_type (int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
switch(val)
{
case 0: current_drawing_states->back()->line.fill.type = fillSolid; break;
case 1: current_drawing_states->back()->line.fill.type = fillPattern; break;
case 2: current_drawing_states->back()->line.fill.type = fillTexture; break;
case 5: current_drawing_states->back()->line.fill.type = fillNone; break;
}
}
void xlsx_drawing_context::set_line_style (int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
switch(val)
{
case 0: current_drawing_states->back()->line.style = L"simple"; break;
case 1: current_drawing_states->back()->line.style = L"double"; break;
case 2: current_drawing_states->back()->line.style = L"thickThin"; break;
case 3: current_drawing_states->back()->line.style = L"thinThick"; break;
case 4: current_drawing_states->back()->line.style = L"triple"; break;
}
}
void xlsx_drawing_context::set_line_width (int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->line.width = val;
}
void xlsx_drawing_context::set_line_miter(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->line.miter = val;
}
void xlsx_drawing_context::set_line_join(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->line.join = val;
}
void xlsx_drawing_context::set_line_endcap(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->line.endcap = val;
}
void xlsx_drawing_context::set_line_arrow(bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->line.arrow.enabled = val;
}
void xlsx_drawing_context::set_arrow_start (int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->line.arrow.start = val;
current_drawing_states->back()->line.arrow.enabled = true;
}
void xlsx_drawing_context::set_arrow_end (int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->line.arrow.end = val;
current_drawing_states->back()->line.arrow.enabled = true;
}
void xlsx_drawing_context::set_arrow_start_width (int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->line.arrow.start_width = val;
}
void xlsx_drawing_context::set_arrow_end_width (int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->line.arrow.end_width = val;
}
void xlsx_drawing_context::set_arrow_start_length (int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->line.arrow.start_length = val;
}
void xlsx_drawing_context::set_arrow_end_length (int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->line.arrow.end_length = val;
}
//----------------------------------------------------------------------
void xlsx_drawing_context::set_fill_old_version (_UINT32 val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
unsigned char backColorIdx = GETBITS(val, 0, 7);
unsigned char patternColorIdx = GETBITS(val, 8,15);
unsigned char pattern = GETBITS(val,16,23);
unsigned char auto_ = GETBITS(val,24,31);
if (auto_)
{
if (current_drawing_states->back()->shape_id == MSOSPT::msosptTextBox)
set_fill_type(oox::fillNone);
}
else if (pattern)
{
set_fill_color(patternColorIdx, 2);
}
else
{
set_fill_color(backColorIdx, 2);
}
}
void xlsx_drawing_context::set_line_old_version (_UINT32 val)
{
unsigned char colorIdx = GETBITS(val, 0, 7);
unsigned char style = GETBITS(val, 8, 15);
unsigned char width = GETBITS(val, 16, 23);
unsigned char auto_ = GETBITS(val, 24, 31);
if (auto_)
return;
set_line_color(colorIdx, 2);
if (style < 5) set_line_dash(style);
else if (style == 0xff)
set_line_type(5);
//switch( style )
//{
//case 5: med;
//case 6: dark;
//case 7: light;
//}
switch( width )
{
case 0: break; //hair
case 1: break; //single
case 2: set_line_style(1); break;
case 3: set_line_style(44); break;
}
}
void xlsx_drawing_context::set_flag_old_version(_UINT16 val, _UINT16 val2)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
unsigned short flips_flag = 0;
if (current_drawing_states->back()->shape_id == MSOSPT::msosptArc)
{
flips_flag = val;
}
if (current_drawing_states->back()->shape_id == MSOSPT::msosptTextBox)
{
}
if (current_drawing_states->back()->shape_id == MSOSPT::msosptLine)
{
unsigned char nArrowType = GETBITS(val, 0, 3);
bool bLineStart = false;
bool bLineEnd = false;
bool bFilled = false;
switch( nArrowType )
{
case 0: bLineStart = false; bLineEnd = true; bFilled = false; break;
case 1: bLineStart = true; bLineEnd = true; bFilled = false; break;
case 2: bLineStart = false; bLineEnd = true; bFilled = true; break;
case 3: bLineStart = true; bLineEnd = true; bFilled = true; break;
}
if( bLineStart || bLineEnd )
{
unsigned char nArrowWidth = GETBITS(val, 4, 7);
double fArrowWidth = 3.0;
switch( nArrowWidth )
{
case 0: fArrowWidth = 2.0; break;
case 1: fArrowWidth = 3.0; break;
case 2: fArrowWidth = 5.0; break;
}
unsigned char nArrowLength = GETBITS(val, 8, 11 );
double fArrowLength = 3.0;
switch( nArrowLength )
{
case 0: fArrowLength = 2.5; break;
case 1: fArrowLength = 3.5; break;
case 2: fArrowLength = 6.0; break;
}
}
flips_flag = val2;
}
switch( flips_flag )
{
case 1:
current_drawing_states->back()->flipH = true;
current_drawing_states->back()->flipV = true; break;
case 2:
current_drawing_states->back()->flipH = true; break;
case 3:
current_drawing_states->back()->flipV = true; break;
}
}
//-------------------------------------------------------------------------------------------------------------------
void xlsx_drawing_context::set_hyperlink(const std::wstring & link, const std::wstring & display, bool is_external)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
std::wstring sId = std::wstring(L"hId") + std::to_wstring(hlinks_.size()+1);
std::wstring link_correct = link;
if (!is_external) link_correct = std::wstring(L"#") + link_correct;
_hlink_desc desc = {sId, link_correct, display, is_external};
hlinks_.push_back(desc);
current_drawing_states->back()->hyperlink = sId;
rels_->add( !is_external, sId , link_correct, external_items::typeHyperlink);
}
void xlsx_drawing_context::set_wordart_text(const std::wstring & text)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->wordart.text = text;
}
void xlsx_drawing_context::set_wordart_font(const std::wstring & val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->wordart.font = val;
}
void xlsx_drawing_context::set_wordart_size (int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->wordart.size = val;
}
void xlsx_drawing_context::set_text_align (int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->text.align = val;
}
void xlsx_drawing_context::set_text_vert_align (int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->text.vert_align = val;
}
void xlsx_drawing_context::set_text_vertical (int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->text.vertical = val;
}
void xlsx_drawing_context::set_text_margin(RECT & val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->text.margins = val;
}
void xlsx_drawing_context::set_text_fit_shape(bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->text.fit_shape = val;
}
void xlsx_drawing_context::set_wordart_bold (bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->wordart.bold = val;
}
void xlsx_drawing_context::set_wordart_italic (bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->wordart.italic = val;
}
void xlsx_drawing_context::set_wordart_underline (bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->wordart.underline = val;
}
void xlsx_drawing_context::set_wordart_strike(bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->wordart.strike = val;
}
void xlsx_drawing_context::set_wordart_vertical (bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->wordart.vertical = val;
}
void xlsx_drawing_context::set_wordart_spacing (double val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->wordart.spacing = val;
}
void xlsx_drawing_context::set_text (const std::wstring & text)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->text.content = text;
}
void xlsx_drawing_context::set_text_vml (const std::wstring & text)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->text.vml_content = text;
}
void xlsx_drawing_context::set_text_wrap (int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->text.wrap = val;
}
void xlsx_drawing_context::set_custom_rect(_rect & rect)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->custom_rect = rect;
}
void xlsx_drawing_context::set_properties(const std::wstring & str)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->shape = str;
}
void xlsx_drawing_context::set_custom_verticles (std::vector<ODRAW::MSOPOINT> & points)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->custom_verticles = points;
}
void xlsx_drawing_context::set_custom_guides (std::vector<ODRAW::MSOSG> & guides)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
if (current_drawing_states->back()->shape_id == MSOSPT::msosptNotchedCircularArrow) return;
current_drawing_states->back()->custom_guides = guides;
}
void xlsx_drawing_context::set_custom_segments (std::vector<ODRAW::MSOPATHINFO> & segments)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->custom_segments = segments;
}
void xlsx_drawing_context::set_custom_adjustHandles(std::vector<ODRAW::ADJH> & handles)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->custom_adjustHandles = handles;
}
void xlsx_drawing_context::set_custom_adjustValues(std::vector<_CP_OPT(int)> & values)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->custom_adjustValues = values;
}
void xlsx_drawing_context::set_custom_path (int type_path)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->custom_path = type_path;
}
void xlsx_drawing_context::set_custom_connection(std::vector<ODRAW::MSOPOINT>& points)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->custom_connection = points;
}
void xlsx_drawing_context::set_custom_connectionDir(std::vector<OSHARED::FixedPoint>& points)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->custom_connectionDir = points;
}
void xlsx_drawing_context::set_custom_inscribe(std::vector<ODRAW::MSORECT>& rects)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->custom_inscribe = rects;
}
void xlsx_drawing_context::set_custom_x_limo(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->custom_x_limo = val;
}
void xlsx_drawing_context::set_custom_y_limo(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->custom_y_limo = val;
}
//----------------------------------------------------------------------------------------------------------
bool xlsx_drawing_context::get_mode_HF ()
{//comment, shapes in header/footer, ....
if (current_drawing_states == NULL) return false;
if (current_drawing_states->empty()) return false;
return current_drawing_states->back()->vml_HF_mode_;
}
void xlsx_drawing_context::set_mode_HF (bool val)
{//comment, shapes in header/footer, ....
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->vml_HF_mode_ = val;
}
//----------------------------------------------------------------------------------------------------------
bool xlsx_drawing_context::empty()
{
return drawing_states.empty();
}
bool xlsx_drawing_context::empty_vml()
{
return drawing_states_vml.empty();
}
bool xlsx_drawing_context::empty_vml_HF()
{
return drawing_states_vml_HF.empty();
}
xlsx_drawings_rels_ptr xlsx_drawing_context::get_rels()
{
return rels_;
}
xlsx_drawings_rels_ptr xlsx_drawing_context::get_vml_HF_rels()
{
return vml_HF_rels_;
}
xlsx_drawings_rels_ptr xlsx_drawing_context::get_vml_rels()
{
return vml_rels_;
}
xlsx_drawings_rels_ptr xlsx_drawing_context::get_sheet_rels()
{
return sheet_rels_;
}
bool xlsx_drawing_context::ChangeBlack2ColorImage(std::wstring sRgbColor1, std::wstring sRgbColor2, _drawing_state_ptr & drawing_state)
{
if (drawing_state->fill.texture_target.length() < 6) return false;
std::wstring image_path = context_.get_mediaitems().media_path() + drawing_state->fill.texture_target.substr(6);
size_t rgbColor1 = STR::hex_str2int(sRgbColor1);
size_t rgbColor2 = STR::hex_str2int(sRgbColor2);
CBgraFrame bgraFrame;
return bgraFrame.ReColorPatternImage(image_path, rgbColor1, rgbColor2);
}
void xlsx_drawing_context::serialize_objects(std::wostream & strm)
{
for (size_t i = 0; i < drawing_states_objects.size(); i++)
{
serialize_object(strm, drawing_states_objects[i]);
}
drawing_states_objects.clear();
}
void xlsx_drawing_context::serialize_controls(std::wostream & strm)
{
for (size_t i = 0; i < drawing_states_controls.size(); i++)
{
serialize_control(strm, drawing_states_controls[i]);
}
drawing_states_controls.clear();
}
//-------------------------------------------------------------------------------------------------------------------
void xlsx_drawing_context::serialize_vml_HF(std::wostream & strm)
{
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"xml")
{
CP_XML_ATTR(L"xmlns:v" , L"urn:schemas-microsoft-com:vml");
CP_XML_ATTR(L"xmlns:o" , L"urn:schemas-microsoft-com:office:office");
CP_XML_ATTR(L"xmlns:x" , L"urn:schemas-microsoft-com:office:excel");
for (size_t i = 0 ; i < drawing_states_vml_HF.size(); i++)
{
CP_XML_STREAM() << drawing_states_vml_HF[i]->vml_shape;
}
}
}
}
void xlsx_drawing_context::serialize_vml(std::wostream & strm)
{
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"xml")
{
CP_XML_ATTR(L"xmlns:v" , L"urn:schemas-microsoft-com:vml");
CP_XML_ATTR(L"xmlns:o" , L"urn:schemas-microsoft-com:office:office");
CP_XML_ATTR(L"xmlns:x" , L"urn:schemas-microsoft-com:office:excel");
for (size_t i = 0 ; i < drawing_states_vml.size(); i++)
{
CP_XML_STREAM() << drawing_states_vml[i]->vml_shape;
}
}
}
}
void xlsx_drawing_context::serialize(std::wostream & strm)
{
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"xdr:wsDr")
{
CP_XML_ATTR(L"xmlns:xdr", L"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing");
CP_XML_ATTR(L"xmlns:a" , L"http://schemas.openxmlformats.org/drawingml/2006/main");
CP_XML_ATTR(L"xmlns:r" , L"http://schemas.openxmlformats.org/officeDocument/2006/relationships");
CP_XML_ATTR(L"xmlns:mc" , L"http://schemas.openxmlformats.org/markup-compatibility/2006");
CP_XML_ATTR(L"xmlns:a14", L"http://schemas.microsoft.com/office/drawing/2010/main");
for (size_t i = 0 ; i < drawing_states.size(); i++)
{
serialize(CP_XML_STREAM(), drawing_states[i]);
}
}
}
}
}