Compare commits

..

18 Commits

Author SHA1 Message Date
23e736051f Merge remote-tracking branch 'origin/feature/add-xls-writing' into develop 2026-03-24 15:06:48 +03:00
8870516a8a Fix bug 68012 2026-03-23 16:07:38 +03:00
dbe56878b1 fix drawing conversion 2026-03-23 18:18:23 +06:00
84aa409b1e Merge branch 'develop' into feature/add-xls-writing 2026-03-23 13:06:49 +06:00
8fa5f8944e Fix bug 56081 2026-03-20 14:56:53 +03:00
27dc6403d7 add several image conversion 2026-03-20 17:50:25 +06:00
ecaef0fbed fix drawing group pict conversion 2026-03-19 20:48:49 +06:00
2addc5a3d8 fix bstoreContainer size 2026-03-19 18:21:34 +06:00
4e1afe5c55 add file blip store entry writin 2026-03-19 16:49:36 +06:00
9ae5855ed0 refactor drawing generation methods 2026-03-18 16:26:40 +06:00
bb97d00ae7 add imageWriting 2026-03-17 18:51:26 +06:00
2074785963 add cell anchor writing for pics 2026-03-13 21:55:00 +06:00
ed697edba2 add pic conversion method 2026-03-13 20:43:39 +06:00
95d6c6c927 Merge branch 'release/v9.4.0' into feature/add-xls-writing 2026-03-13 14:22:03 +06:00
da769a642b Merge branch hotfix/v9.3.1 into release/v9.4.0 2026-03-12 15:19:51 +00:00
12083ae8c9 Merge pull request 'Fix bugs 75897, 80163' (#722) from fix/pdf-bug into release/v9.4.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/722
2026-03-12 12:29:03 +00:00
6819a41452 Fix bug 75897 2026-03-12 14:06:57 +03:00
5d5732161a Fix bug 80163 2026-03-12 11:11:32 +03:00
47 changed files with 1116 additions and 764 deletions

View File

@ -617,19 +617,6 @@ public:
return ((CPdfFile*)m_pFile)->GetEmbeddedFontPath(sName);
}
bool isXFA()
{
if (0 != m_nType)
return false;
return ((CPdfFile*)m_pFile)->IsXFA();
}
BYTE* getXFA()
{
if (0 != m_nType)
return NULL;
return ((CPdfFile*)m_pFile)->GetXFA();
}
private:
int GetPagesCount()
{

View File

@ -263,15 +263,6 @@ JSSmart<CJSValue> CDrawingFileEmbed::CheckPerm(JSSmart<CJSValue> nPerm)
return CJSContext::createBool(m_pFile->CheckPerm(nPerm->toInt32()));
}
JSSmart<CJSValue> CDrawingFileEmbed::IsXFA()
{
return CJSContext::createBool(m_pFile->isXFA());
}
JSSmart<CJSValue> CDrawingFileEmbed::GetXFA()
{
return WasmMemoryToJS(m_pFile->getXFA());
}
bool EmbedDrawingFile(JSSmart<NSJSBase::CJSContext>& context, IOfficeDrawingFile* pFile)
{
CJSContext::Embed<CDrawingFileEmbed>(false);

View File

@ -62,9 +62,6 @@ public:
JSSmart<CJSValue> CheckOwnerPassword(JSSmart<CJSValue> sPassword);
JSSmart<CJSValue> CheckPerm(JSSmart<CJSValue> nPerm);
JSSmart<CJSValue> IsXFA();
JSSmart<CJSValue> GetXFA();
DECLARE_EMBED_METHODS
};

View File

@ -36,8 +36,6 @@
-(JSValue*) UndoRedact;
-(JSValue*) CheckOwnerPassword : (JSValue*)sPassword;
-(JSValue*) CheckPerm : (JSValue*)nPerm;
-(JSValue*) IsXFA;
-(JSValue*) GetXFA;
@end
@interface CJSCDrawingFileEmbed : NSObject<IJSCDrawingFileEmbed, JSEmbedObjectProtocol>
@ -81,8 +79,6 @@ FUNCTION_WRAPPER_JS_3(RedactPage, RedactPage)
FUNCTION_WRAPPER_JS_0(UndoRedact, UndoRedact)
FUNCTION_WRAPPER_JS_1(CheckOwnerPassword, CheckOwnerPassword)
FUNCTION_WRAPPER_JS_1(CheckPerm, CheckPerm)
FUNCTION_WRAPPER_JS_0(IsXFA, IsXFA)
FUNCTION_WRAPPER_JS_0(GetXFA, GetXFA)
@end
class CDrawingFileEmbedAdapter : public CJSEmbedObjectAdapterJSC

View File

@ -39,8 +39,6 @@ namespace NSDrawingFileEmbed
FUNCTION_WRAPPER_V8_0(_UndoRedact, UndoRedact)
FUNCTION_WRAPPER_V8_1(_CheckOwnerPassword, CheckOwnerPassword)
FUNCTION_WRAPPER_V8_1(_CheckPerm, CheckPerm)
FUNCTION_WRAPPER_V8_0(_IsXFA, IsXFA)
FUNCTION_WRAPPER_V8_0(_GetXFA, GetXFA)
v8::Handle<v8::ObjectTemplate> CreateTemplate(v8::Isolate* isolate)
{
@ -79,8 +77,6 @@ namespace NSDrawingFileEmbed
NSV8Objects::Template_Set(result, "UndoRedact", _UndoRedact);
NSV8Objects::Template_Set(result, "CheckOwnerPassword", _CheckOwnerPassword);
NSV8Objects::Template_Set(result, "CheckPerm", _CheckPerm);
NSV8Objects::Template_Set(result, "IsXFA", _IsXFA);
NSV8Objects::Template_Set(result, "GetXFA", _GetXFA);
return handle_scope.Escape(result);
}

View File

@ -1374,6 +1374,25 @@ namespace Aggplus
}
}
template<class span_gen_type>
void CGraphics::render_blendmode(span_gen_type& sg, span_alloc_type& span_allocator, BYTE Alpha)
{
if (m_nBlendMode != agg::comp_op_src_over)
{
typedef agg::renderer_scanline_aa<comp_renderer_type, span_alloc_type, span_gen_type> aa_renderer_type;
pixfmt_type_comp pixfmt(m_frame_buffer.ren_buf(), m_nBlendMode);
comp_renderer_type ren_base(pixfmt);
aa_renderer_type ri(ren_base, span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
}
else
{
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
}
}
template<class Renderer>
void CGraphics::render_scanlines(Renderer& ren)
{
@ -1417,12 +1436,9 @@ namespace Aggplus
if (m_nBlendMode != agg::comp_op_src_over)
{
typedef agg::renderer_scanline_aa_solid<comp_renderer_type> solid_comp_renderer_type;
solid_comp_renderer_type ren_solid;
comp_renderer_type ren_base;
pixfmt_type_comp pixfmt(m_frame_buffer.ren_buf(), m_nBlendMode);
ren_base.attach(pixfmt);
ren_solid.attach(ren_base);
comp_renderer_type ren_base(pixfmt);
solid_comp_renderer_type ren_solid(ren_base);
ren_solid.color(dwColor.GetAggColor());
render_scanlines(ren_solid);
@ -1727,6 +1743,70 @@ namespace Aggplus
}
}
template<typename pixfmt>
void CGraphics::DoFillPathTextureClampSz2_Impl(agg::rendering_buffer& PatRendBuff, interpolator_type_linear& interpolator, span_alloc_type& span_allocator, int nCurrentMode, BYTE Alpha)
{
typedef agg::image_accessor_clone<pixfmt> img_source_type;
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
switch (nCurrentMode)
{
case 0:
{
typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type_linear> span_gen_type;
span_gen_type sg(img_src, interpolator);
render_blendmode(sg, span_allocator, Alpha);
break;
}
case 1:
{
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
span_gen_type sg(img_src, interpolator);
render_blendmode(sg, span_allocator, Alpha);
break;
}
case 2:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bicubic(), false);
span_gen_type sg(img_src, interpolator, filter);
render_blendmode(sg, span_allocator, Alpha);
break;
}
case 3:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_spline16(), false);
span_gen_type sg(img_src, interpolator, filter);
render_blendmode(sg, span_allocator, Alpha);
break;
}
case 4:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_blackman256(), false);
span_gen_type sg(img_src, interpolator, filter);
render_blendmode(sg, span_allocator, Alpha);
break;
}
case 255:
{
typedef agg::span_image_resample_rgba_affine_for_draw<img_source_type> span_gen_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bilinear(), false);
span_gen_type sg(img_src, interpolator, filter);
render_blendmode(sg, span_allocator, Alpha);
break;
}
default:
break;
}
}
void CGraphics::DoFillPathTextureClampSz2(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride, BYTE Alpha)
{
span_alloc_type span_allocator;
@ -1738,158 +1818,11 @@ namespace Aggplus
PatRendBuff.attach((BYTE*)pImgBuff, dwImgWidth, dwImgHeight, nImgStride);
int nCurrentMode = 255;
if (!m_bSwapRGB)
{
typedef agg::pixfmt_bgra32 pixfmt;
typedef agg::image_accessor_clone<pixfmt> img_source_type;
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
switch (nCurrentMode)
{
case 0:
{
typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 1:
{
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 2:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bicubic(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 3:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_spline16(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 4:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_blackman256(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 255:
{
typedef agg::span_image_resample_rgba_affine_for_draw<img_source_type> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bilinear(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
default:
break;
}
}
DoFillPathTextureClampSz2_Impl<agg::pixfmt_bgra32>(PatRendBuff, interpolator, span_allocator, nCurrentMode, Alpha);
else
{
typedef agg::pixfmt_rgba32 pixfmt;
typedef agg::image_accessor_clone<pixfmt> img_source_type;
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
switch (nCurrentMode)
{
case 0:
{
typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 1:
{
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 2:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bicubic(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 3:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_spline16(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 4:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_blackman256(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 255:
{
typedef agg::span_image_resample_rgba_affine_for_draw<img_source_type> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bilinear(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
default:
break;
}
}
DoFillPathTextureClampSz2_Impl<agg::pixfmt_rgba32>(PatRendBuff, interpolator, span_allocator, nCurrentMode, Alpha);
}
template<class ColorSpacePix>

View File

@ -430,6 +430,9 @@ public:
protected:
template<class span_gen_type>
void render_blendmode(span_gen_type& sg, span_alloc_type& span_allocator, BYTE Alpha);
template<class Renderer>
void render_scanlines(Renderer& ren);
template<class Rasterizer, class Renderer>
@ -447,6 +450,9 @@ protected:
//--test
void DoFillPathHatch(CBrushHatch *pBrush);
void DoFillPathTextureClampSz(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride);
template<typename pixfmt>
void DoFillPathTextureClampSz2_Impl(agg::rendering_buffer& PatRendBuff, interpolator_type_linear& interpolator, span_alloc_type& span_allocator, int nCurrentMode, BYTE Alpha);
void DoFillPathTextureClampSz2(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride, BYTE Alpha = 255);
template<class ColorSpacePix>

View File

@ -60,8 +60,6 @@
"_UndoRedact",
"_CheckOwnerPassword",
"_CheckPerm",
"_IsXFA",
"_GetXFA",
"_GetImageBase64",
"_GetImageBase64Len",
"_GetImageBase64Ptr",

View File

@ -177,30 +177,6 @@ CFile.prototype["UndoRedact"] = function()
return this._UndoRedact();
};
// XFA
CFile.prototype["isXFA"] = function()
{
if (!this.nativeFile)
return false;
return this._isXFA();
};
CFile.prototype["getXFA"] = function()
{
if (!this.nativeFile)
return {};
let ptr = this._getXFA();
let reader = ptr.getReader();
if (!reader) return {};
let res = {};
res["dynamic"] = reader.readByte() ? true : false;
res["xfa"] = reader.readString();
ptr.free();
return res;
};
// INFO DOCUMENT
CFile.prototype.getInfo = function()
{

View File

@ -184,17 +184,6 @@ CFile.prototype._getInteractiveFormsFonts = function(type)
return g_module_pointer;
};
// XFA
CFile.prototype._isXFA = function()
{
return g_native_drawing_file["IsXFA"]();
};
CFile.prototype._getXFA = function()
{
g_module_pointer.ptr = g_native_drawing_file["GetXFA"]();
return g_module_pointer;
};
// INFO DOCUMENT
CFile.prototype._getInfo = function()
{

View File

@ -305,17 +305,6 @@ CFile.prototype._getInteractiveFormsFonts = function(type)
return g_module_pointer;
};
// XFA
CFile.prototype._isXFA = function()
{
return Module["_IsXFA"](this.nativeFile) ? true : false;
};
CFile.prototype._getXFA = function()
{
g_module_pointer.ptr = Module["_GetXFA"](this.nativeFile);
return g_module_pointer;
};
// INFO DOCUMENT
CFile.prototype._getInfo = function()
{

View File

@ -210,14 +210,6 @@ WASM_EXPORT int CheckPerm(CDrawingFile* pFile, int nPermFlag)
{
return pFile->CheckPerm(nPermFlag) ? 1 : 0;
}
WASM_EXPORT int IsXFA(CDrawingFile* pFile)
{
return pFile->isXFA() ? 1 : 0;
}
WASM_EXPORT BYTE* GetXFA(CDrawingFile* pFile)
{
return pFile->getXFA();
}
WASM_EXPORT void* GetImageBase64(CDrawingFile* pFile, int rId)
{

View File

@ -1194,7 +1194,7 @@ int main(int argc, char* argv[])
}
// RASTER
if (true)
if (false)
{
int i = nTestPage;
//for (int i = 0; i < nPagesCount; ++i)
@ -2333,29 +2333,6 @@ int main(int argc, char* argv[])
ReadInteractiveFormsFonts(pGrFile, 2);
}
// XFA
if (true && IsXFA(pGrFile))
{
BYTE* pXFA = GetXFA(pGrFile);
nLength = READ_INT(pXFA);
int i = 4;
nLength -= 4;
BYTE bD = READ_BYTE(pXFA + i);
i += 1;
std::cout << " XFA: Dynamic " << (bool)bD << std::endl;
int nPathLength = READ_INT(pXFA + i);
i += 4;
NSFile::CFileBinary oFile;
if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/XFA.xml"))
oFile.WriteFile(pXFA + i, nPathLength);
oFile.CloseFile();
i += nPathLength;
std::cout << std::endl;
}
Close(pGrFile);
return 0;

View File

@ -312,7 +312,7 @@ void CFRecord::appendRawData(const char* raw_data, const size_t size)
void CFRecord::appendRawDataToStatic(const unsigned char *raw_data, const size_t size)
{
if(MAX_RECORD_SIZE - rdPtr > size)
if(MAX_RECORD_SIZE - rdPtr >= size)
{
memcpy(&intData[rdPtr], raw_data, size);
rdPtr += size;

View File

@ -137,137 +137,39 @@ const bool MsoDrawing::isEndingRecord(CFRecord& record)
return ODRAW::OfficeArtDgContainer::CheckIfContainerSizeOK(record);
}
void MsoDrawing::prepareComment(const unsigned int CommentId, const unsigned int row, const unsigned int col)
void MsoDrawing::prepareDrawing(const DrawingType Type, const unsigned int DrawingtId, const unsigned int row1, const unsigned int col1,
const unsigned int row2, const unsigned int col2, const unsigned int param)
{
if(rgChildRec.first)
{
auto fdgPtr = new ODRAW::OfficeArtFDG;
fdgPtr->rh_own.recInstance = DrawingtId;
fdgPtr->spidCur = DrawingtId;
rgChildRec.m_OfficeArtFDG = ODRAW::OfficeArtRecordPtr(fdgPtr);
auto spgrContainer = new ODRAW::OfficeArtSpgrContainer(ODRAW::OfficeArtRecord::CA_Sheet);
rgChildRec.m_OfficeArtSpgrContainer = ODRAW::OfficeArtRecordPtr(spgrContainer);
auto ShapeGroup = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Sheet);
auto groupFsp = new ODRAW::OfficeArtFSP;
ShapeGroup->m_OfficeArtFSP = ODRAW::OfficeArtRecordPtr(groupFsp);
groupFsp->shape_id = 0;
groupFsp->fGroup = true;
groupFsp->fPatriarch = true;
groupFsp->spid = CommentId;
auto groupFSPGR = new ODRAW::OfficeArtFSPGR;
ShapeGroup->m_OfficeArtFSPGR = ODRAW::OfficeArtRecordPtr(groupFSPGR);
auto fdgPtr = new ODRAW::OfficeArtFDG;
fdgPtr->rh_own.recInstance = CommentId;
rgChildRec.m_OfficeArtFDG = ODRAW::OfficeArtRecordPtr(fdgPtr);
spgrContainer->m_OfficeArtSpgrContainerFileBlock.push_back(ODRAW::OfficeArtContainerPtr(ShapeGroup));
}
auto TextboxContainer = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Sheet);
TextboxContainer->extraSize += 8;
if(rgChildRec.first)
{
auto spgrContainer = static_cast<ODRAW::OfficeArtSpgrContainer*>(rgChildRec.m_OfficeArtSpgrContainer.get());
spgrContainer->m_OfficeArtSpgrContainerFileBlock.push_back(ODRAW::OfficeArtContainerPtr(TextboxContainer));
}
else
rgChildRec.m_OfficeArtSpContainer.push_back(ODRAW::OfficeArtContainerPtr(TextboxContainer));
auto fsprPtr = new ODRAW::OfficeArtFSP;
TextboxContainer->m_OfficeArtFSP = ODRAW::OfficeArtRecordPtr(fsprPtr);
fsprPtr->shape_id = 0xCA;
fsprPtr->spid = CommentId+1;
fsprPtr->fHaveAnchor = true;
fsprPtr->fHaveSpt = true;
auto clientAnchor = new ODRAW::OfficeArtClientAnchorSheet;
clientAnchor->colL = col+1;
clientAnchor->colR = col+3;
clientAnchor->rwT = row;
clientAnchor->rwB = row+4;
{
auto commentOptions = new ODRAW::OfficeArtFOPT;
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x0080;
txId->op = CommentId;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x008B;
txId->op = 2;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x00BF;
txId->op = 0x00080008;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x0158;
txId->op = 0x0000;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x0181;
txId->op = 0x08000050;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x03BF;
txId->op = 0x00020002;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
commentOptions->fopt.options_count += 6;
TextboxContainer->m_oOfficeArtFOPT = ODRAW::OfficeArtRecordPtr(commentOptions);
}
TextboxContainer->m_OfficeArtAnchor = ODRAW::OfficeArtRecordPtr(clientAnchor);
auto clientData = new ODRAW::OfficeArtClientData;
TextboxContainer->m_oOfficeArtClientData = ODRAW::OfficeArtRecordPtr(clientData);
}
void MsoDrawing::prepareChart(const unsigned int chartId, const unsigned int x1, const unsigned int x2,
const unsigned int y1, const unsigned int y2, const unsigned int x1Offset, const unsigned int x2Offset,
const unsigned int y1Offset,const unsigned int y2Offset)
{
if(rgChildRec.first)
{
auto fdgPtr = new ODRAW::OfficeArtFDG;
fdgPtr->rh_own.recInstance = chartId;
fdgPtr->spidCur = chartId;
rgChildRec.m_OfficeArtFDG = ODRAW::OfficeArtRecordPtr(fdgPtr);
auto spgrContainer = new ODRAW::OfficeArtSpgrContainer(ODRAW::OfficeArtRecord::CA_Chart);
rgChildRec.m_OfficeArtSpgrContainer = ODRAW::OfficeArtRecordPtr(spgrContainer);
{
auto SpContainer = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Chart);
auto SpContainer = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Sheet);
spgrContainer->m_OfficeArtSpgrContainerFileBlock.push_back(ODRAW::OfficeArtContainerPtr(SpContainer));
auto groupFSPGR = new ODRAW::OfficeArtFSPGR;
groupFSPGR->xLeft = x1;
groupFSPGR->xRight = x2;
groupFSPGR->yTop = y1;
groupFSPGR->yBottom = y2;
groupFSPGR->xLeft = col1;
groupFSPGR->xRight = col2;
groupFSPGR->yTop = row1;
groupFSPGR->yBottom = row2;
SpContainer->m_OfficeArtFSPGR = ODRAW::OfficeArtRecordPtr(groupFSPGR);
auto fsprPtr = new ODRAW::OfficeArtFSP;
SpContainer->m_OfficeArtFSP = ODRAW::OfficeArtRecordPtr(fsprPtr);
fsprPtr->shape_id = 0;
fsprPtr->spid = chartId-1;
fsprPtr->spid = DrawingtId;
fsprPtr->fGroup = true;
fsprPtr->fPatriarch = true;
}
}
{
auto SpContainer = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Chart);
auto SpContainer = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Sheet);
if(rgChildRec.first && rgChildRec.m_OfficeArtSpgrContainer != nullptr)
{
auto spgrContainer = static_cast<ODRAW::OfficeArtSpgrContainer*>(rgChildRec.m_OfficeArtSpgrContainer.get());
@ -278,24 +180,81 @@ void MsoDrawing::prepareChart(const unsigned int chartId, const unsigned int x1,
auto fsprPtr = new ODRAW::OfficeArtFSP;
SpContainer->m_OfficeArtFSP = ODRAW::OfficeArtRecordPtr(fsprPtr);
fsprPtr->shape_id = 1;
fsprPtr->spid = chartId;
if(Type == DrawingType::comment)
fsprPtr->shape_id = 0xCA;
else
fsprPtr->shape_id = 1;
fsprPtr->spid = DrawingtId+1;
fsprPtr->fHaveMaster = true;
auto clientAnchor = new ODRAW::OfficeArtClientAnchorSheet;
clientAnchor->colL = x1;
clientAnchor->dxL = x1Offset;
clientAnchor->colR = x2;
clientAnchor->dxR = x2Offset;
clientAnchor->rwT = y1;
clientAnchor->dyT = y1Offset;
clientAnchor->rwB = y2;
clientAnchor->dyB = y2Offset;
clientAnchor->colL = col1;
clientAnchor->colR = col2;
clientAnchor->rwT = row1;
clientAnchor->rwB = row2;
SpContainer->m_OfficeArtAnchor = ODRAW::OfficeArtRecordPtr(clientAnchor);
auto clientData = new ODRAW::OfficeArtClientData;
SpContainer->m_oOfficeArtClientData = ODRAW::OfficeArtRecordPtr(clientData);
if(Type == DrawingType::comment)
{
auto commentOptions = new ODRAW::OfficeArtFOPT;
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x0080;
txId->op = DrawingtId;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x008B;
txId->op = 2;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x00BF;
txId->op = 0x00080008;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x0158;
txId->op = 0x0000;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x0181;
txId->op = 0x08000050;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x03BF;
txId->op = 0x00020002;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
commentOptions->fopt.options_count += 6;
SpContainer->m_oOfficeArtFOPT = ODRAW::OfficeArtRecordPtr(commentOptions);
SpContainer->extraSize += 8;
}
else if(Type == DrawingType::pic)
{
auto commentOptions = new ODRAW::OfficeArtFOPT;
{
auto PicOp = new ODRAW::OfficeArtFOPTE;//pib
PicOp->opid = 0x0104;
PicOp->fComplex = false;
PicOp->fBid = true;
PicOp->op = param;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(PicOp));
}
SpContainer->m_oOfficeArtFOPT = ODRAW::OfficeArtRecordPtr(commentOptions);
commentOptions->fopt.options_count += 1;
}
}
}
} // namespace XLS

View File

@ -60,19 +60,22 @@ public:
virtual const bool isStartingRecord (CFRecord& record);
virtual const bool isEndingRecord (CFRecord& record);
virtual void useContinueRecords (CFRecord& record);
void prepareComment (const unsigned int CommentId, const unsigned int row, const unsigned int col);
void prepareChart (const unsigned int chartId, const unsigned int x1, const unsigned int x2,
const unsigned int y1, const unsigned int y2, const unsigned int x1Offset = 0, const unsigned int x2Offset = 0,
const unsigned int y1Offset = 0,const unsigned int y2Offset = 0);
//-----------------------------
ODRAW::OfficeArtDgContainer rgChildRec;
bool isReading;
enum DrawingType
{
chart,
comment,
pic
};
DrawingType xlsDrawingType;
void prepareDrawing(const DrawingType DrawingType, const unsigned int DrawingtId, const unsigned int row1, const unsigned int col1,
const unsigned int row2, const unsigned int col2, const unsigned int param = 1);
};
typedef boost::shared_ptr<MsoDrawing> MsoDrawingPtr;
} // namespace XLS

View File

@ -33,6 +33,7 @@
#include "MsoDrawingGroup.h"
#include "../Biff_structures/ODRAW/SimpleOfficeArtContainers.h"
#include "../Biff_structures/ODRAW/OfficeArtFDGGBlock.h"
#include "../Biff_structures/ODRAW/OfficeArtBStoreContainer.h"
namespace XLS
{
@ -88,5 +89,35 @@ void MsoDrawingGroup::prepareChart(unsigned int count)
}
}
int MsoDrawingGroup::AddPict(const std::wstring& picPath)
{
int pictNum = -1;
ODRAW::OfficeArtBStoreContainer *bstore;
if(rgChildRec.m_OfficeArtBStoreContainer == nullptr)
{
bstore = new ODRAW::OfficeArtBStoreContainer;
rgChildRec.m_OfficeArtBStoreContainer = ODRAW::OfficeArtRecordPtr(bstore);
}
else
bstore = static_cast<ODRAW::OfficeArtBStoreContainer*>(rgChildRec.m_OfficeArtBStoreContainer.get());
if(!drawingNames.IsInit())
drawingNames.Init();
if(drawingNames->find(picPath) == drawingNames->end())
{
auto fileBlock = new ODRAW::OfficeArtBStoreContainerFileBlock;
bstore->rgfb.push_back(fileBlock);
pictNum = bstore->rgfb.size();
drawingNames->emplace(picPath, pictNum);
DWORD fileSize = 0;
auto result = NSFile::CFileBinary::ReadAllBytes(picPath, (BYTE**)&fileBlock->pict_data, fileSize);
fileBlock->pict_size = fileSize;
}
else
pictNum = drawingNames->find(picPath)->second;
return pictNum;
}
} // namespace XLS

View File

@ -33,6 +33,7 @@
#include "BiffRecordContinued.h"
#include "../Biff_structures/ODRAW/SimpleOfficeArtContainers.h"
#include "../../../../../OOXML/Base/Nullable.h"
namespace XLS
{
@ -54,9 +55,11 @@ public:
void writeFields(CFRecord& record);
void prepareChart(unsigned int count);
int AddPict(const std::wstring& pictPath);
ODRAW::OfficeArtDggContainer rgChildRec;
unsigned int drawingCount = 0;
nullable<std::map<std::wstring, unsigned int>> drawingNames;
};

View File

@ -52,7 +52,7 @@ public:
virtual void load(CFRecord& record);
virtual void save(CFRecord& record);
bool fAutoPict = false;
bool fAutoPict = true;
bool fDde = false;
bool fPrintCalc = false;
bool fIcon = false;

View File

@ -80,6 +80,23 @@ void OfficeArtBStoreContainer::loadFields(XLS::CFRecord& record)
}
}
void OfficeArtBStoreContainer::save(XLS::CFRecord& record)
{
rh_own.recVer = 0xF;
rh_own.recInstance = rgfb.size();
rh_own.recType = 0xF001;
for(auto i : rgfb)
{
rh_own.recLen += 44; //OfficeArtFBSE
if(!i->nameData.empty())
rh_own.recLen += i->nameData.size()+1;
rh_own.recLen += 25; //blipHeader
rh_own.recLen += i->pict_size;
}
record << rh_own;
}
const unsigned short OfficeArtBStoreContainer::GetInstanceToStore()
{
return rgfb.size();

View File

@ -61,6 +61,7 @@ public:
static const XLS::ElementType type = XLS::typeOfficeArtBStoreContainer;
virtual void loadFields(XLS::CFRecord& record);
virtual void save(XLS::CFRecord& record);
// overriden
const unsigned short GetInstanceToStore();

View File

@ -269,4 +269,71 @@ void OfficeArtBStoreContainerFileBlock::load(XLS::CFRecord& record)
}
const void WriteMD4Digest(std::wstring UidStr, XLS::CFRecord& record)
{
if(UidStr.size() < 16 )
UidStr = L"0000000000000000";
for(int i = 0; i < 16; i++)
{
unsigned char hex_data = UidStr.at(i);
record << hex_data;
}
}
void OfficeArtBStoreContainerFileBlock::save(XLS::CFRecord& record)
{
//fbse
{
OfficeArtRecordHeader FbseHeader;
FbseHeader.recVer = 2;
FbseHeader.recInstance = 5;
FbseHeader.recType = 0xF007;
FbseHeader.recLen = pict_size + 36 + 25;
if(!nameData.empty())
FbseHeader.recLen += nameData.size()+1;
record << FbseHeader;
BYTE btOs = FbseHeader.recInstance;
record << btOs << btOs;
WriteMD4Digest(rgbUid1, record);
unsigned short tag = 0xFF;
record << tag;
unsigned int Size = pict_size + 17 + 8;
record << Size;
unsigned int Cref = 1;
record << Cref;
unsigned int foDelay = 0;
record << foDelay;
record.reserveNunBytes(1);
BYTE cbName = 0;
if(!nameData.empty())
cbName = nameData.size()+1;
record << cbName;
record.reserveNunBytes(2);
if(cbName)
{
for(auto i : nameData)
{
record << i;
}
BYTE terminal = L'\0';
record << terminal;
}
}
OfficeArtRecordHeader rc_header;
rc_header.recVer = 0;
rc_header.recInstance = 0x46A;
rc_header.recType = 0xF01D;
rc_header.recLen = pict_size + 17;
record << rc_header;
record.reserveNunBytes(16);
BYTE tag = 0xFF;
record << tag;
//record.appendRawDataToStatic((BYTE*)pict_data, pict_size);
}
} // namespace XLS

View File

@ -71,6 +71,7 @@ public:
}
virtual void load(XLS::CFRecord& record);
virtual void save(XLS::CFRecord& record);
static const XLS::ElementType type = XLS::typeOfficeArtBStoreContainerFileBlock;
@ -86,6 +87,7 @@ public:
size_t recType;
std::wstring rgbUid1;
std::wstring rgbUid2;
std::wstring nameData;
bool result;
const std::wstring ReadMD4Digest(XLS::CFRecord& record)

View File

@ -31,6 +31,7 @@
*/
#include "SimpleOfficeArtContainers.h"
#include "OfficeArtBStoreContainer.h"
namespace ODRAW
{
@ -144,10 +145,18 @@ void OfficeArtDggContainer::save(XLS::CFRecord& record)
if(m_OfficeArtFDGGBlock != nullptr)
m_OfficeArtFDGGBlock->save(record);
if(m_OfficeArtBStoreContainer != nullptr)
m_OfficeArtBStoreContainer->save(record);
//calculating size
rh_own.recLen = record.getRdPtr() - sizePos;
record.RollRdPtrBack(rh_own.recLen + 4);
auto recLen = rh_own.recLen;
if(m_OfficeArtBStoreContainer != nullptr)
{
//recLen+=8;//container Header
auto bstore = static_cast<ODRAW::OfficeArtBStoreContainer*>(m_OfficeArtBStoreContainer.get());
recLen+= bstore->rh_own.recLen;
}
record << recLen;
record.skipNunBytes(rh_own.recLen);
}

View File

@ -290,9 +290,10 @@ const bool CHARTFORMATS::loadContent(BinProcessor& proc)
const bool CHARTFORMATS::saveContent(BinProcessor& proc)
{
if(m_ChartRect == nullptr)
return false;
proc.mandatory(*m_ChartRect);
if(m_ChartRect != nullptr)
proc.mandatory(*m_ChartRect);
else
proc.mandatory<Chart>();
proc.mandatory<Begin>();
for(auto i : m_arFONTLIST)
{

View File

@ -48,6 +48,7 @@ public:
BaseObjectPtr clone();
virtual const bool loadContent(BinProcessor& proc);
virtual const bool saveContent(BinProcessor& proc);
static const ElementType type = typeMSODRAWINGGROUP;

View File

@ -33,6 +33,8 @@
#include "MSODRAWINGGROUP.h"
#include "../Biff_records/MsoDrawingGroup.h"
#include "../Biff_records/Continue.h"
#include "../Biff_structures/ODRAW/OfficeArtBStoreContainer.h"
#include "../Biff_structures/ODRAW/OfficeArtBStoreContainerFileBlock.h"
namespace XLS
{
@ -71,5 +73,79 @@ const bool MSODRAWINGGROUP::loadContent(BinProcessor& proc)
return true;
}
const bool MSODRAWINGGROUP::saveContent(BinProcessor& proc)
{
auto MaxRecSize = 8224;
proc.mandatory(*m_MsoDrawingGroup);
auto castedGroup = static_cast<MsoDrawingGroup*>(m_MsoDrawingGroup.get());
if(castedGroup->rgChildRec.m_OfficeArtBStoreContainer)
{
auto bstore = static_cast<ODRAW::OfficeArtBStoreContainer*>(castedGroup->rgChildRec.m_OfficeArtBStoreContainer.get());
for (auto* block : bstore->rgfb)
{
CFRecord continueRecord(60, proc.getGlobalWorkbookInfo());
block->save(continueRecord);
size_t headerSize = continueRecord.getRdPtr();
size_t filePtr = 0;
const BYTE* data = (BYTE*)block->pict_data;
size_t dataSize = block->pict_size;
while (filePtr < dataSize)
{
size_t freeSpace;
if (filePtr == 0)
freeSpace = MaxRecSize - headerSize;
else
freeSpace = MaxRecSize;
size_t chunkSize = std::min(freeSpace, dataSize - filePtr);
XLS::Continue continueRec;
size_t recSize = (filePtr == 0)
? headerSize + chunkSize
: chunkSize;
continueRec.m_iDataSize = recSize;
continueRec.m_pData = new char[recSize];
if (filePtr == 0)
{
memcpy(
continueRec.m_pData,
continueRecord.getCurStaticData<BYTE>() - headerSize,
headerSize
);
memcpy(
continueRec.m_pData + headerSize,
data + filePtr,
chunkSize
);
}
else
{
auto datPtr = data + filePtr;
memcpy(
continueRec.m_pData,
datPtr,
chunkSize
);
auto testPt = datPtr;
auto test2 = testPt;
}
proc.mandatory(continueRec);
filePtr += chunkSize;
}
}
}
return true;
}
} // namespace XLS

View File

@ -733,9 +733,10 @@ const bool GlobalsSubstream::saveContent(BinProcessor& proc)
proc.mandatory(*i);
for(auto i : m_arMSODRAWINGGROUP)
{
auto drawingGroup = static_cast<MsoDrawingGroup*>(i.get());
auto drawingGroupUnion = static_cast<MSODRAWINGGROUP*>(i.get());
auto drawingGroup = static_cast<MsoDrawingGroup*>(drawingGroupUnion->m_MsoDrawingGroup.get());
drawingGroup->prepareChart(drawingGroup->drawingCount);
proc.mandatory(*drawingGroup);
proc.mandatory(*drawingGroupUnion);
}
if(m_SHAREDSTRINGS != nullptr)
proc.mandatory(*m_SHAREDSTRINGS);

View File

@ -34,6 +34,8 @@
#include "ChartSerialize.h"
#include "../../../DesktopEditor/common/StringExt.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/ChartSheetSubstream.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SERIESFORMAT.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SS.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/IVAXIS.h"
@ -41,7 +43,11 @@
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CRT.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CHARTFOMATS.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/LD.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/AXISPARENT.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/AXES.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/AXS.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/ATTACHEDLABEL.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/AI.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Series.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/DataFormat.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/BRAI.h"
@ -64,6 +70,12 @@
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/AxisLine.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/LineFormat.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Tick.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Pos.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Text.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/ObjectLink.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/BRAI.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/SeriesText.h"
namespace OOX
@ -1163,6 +1175,160 @@ xmlns:c16r2=\"http://schemas.microsoft.com/office/drawing/2015/06/chart\"");
writer.WriteString(sNodeName);
writer.WriteString(L">");
}
XLS::BaseObjectPtr CT_ChartSpace::toXLS()
{
auto ptr = new XLS::ChartSheetSubstream(0);
ptr->separate = false;
auto pageSetup = new XLS::PAGESETUP;
ptr->m_PAGESETUP = XLS::BaseObjectPtr(pageSetup);
auto ChartFormatsPtr = new XLS::CHARTFORMATS;
ptr->m_CHARTFORMATS = XLS::BaseObjectPtr(ChartFormatsPtr);
if(m_spPr.IsInit())
{
ChartFormatsPtr->m_FRAME = m_spPr->toXLSFrame();
}
if(m_chart->m_plotArea != nullptr)
{
auto AxisParentUnion = new XLS::AXISPARENT;
auto axes = new XLS::AXES;
AxisParentUnion->m_AXES = XLS::BaseObjectPtr(axes);
ChartFormatsPtr->m_arAXISPARENT.push_back(XLS::BaseObjectPtr(AxisParentUnion));
auto axisPos = new XLS::Pos;
axisPos->x1 = 0;
axisPos->y1 = 200;
axisPos->x2 = 4000;
axisPos->y2 = 3800;
AxisParentUnion->m_Pos = XLS::BaseObjectPtr(axisPos);
for(auto chartIndex = 0; chartIndex < m_chart->m_plotArea->m_Items.size(); chartIndex ++)
{
if(*m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5BARCHART)
{
auto barChart = static_cast<CT_BarChart*>(m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(barChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5BAR3DCHART)
{
auto barChart = static_cast<CT_Bar3DChart*>(m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(barChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5PIECHART)
{
auto PieChart = static_cast<CT_PieChart*>(m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(PieChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5PIE3DCHART)
{
auto PieChart = static_cast<CT_Pie3DChart*>(m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(PieChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5LINECHART)
{
auto LineChart = static_cast<CT_LineChart*>(m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(LineChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5LINE3DCHART)
{
auto LineChart = static_cast<CT_Line3DChart*>(m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(LineChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5AREACHART)
{
auto AreaChart = static_cast<CT_AreaChart*>(m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(AreaChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5AREA3DCHART)
{
auto AreaChart = static_cast<CT_Area3DChart*>(m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(AreaChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5SURFACECHART)
{
auto SurfaceChart = static_cast<CT_SurfaceChart*>(m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(SurfaceChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5SCATTERCHART)
{
auto ScatterChart = static_cast<CT_ScatterChart*>(m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(ScatterChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5RADARCHART)
{
auto ScatterChart = static_cast<CT_RadarChart*>(m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(ScatterChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
if(ChartFormatsPtr->m_arAXISPARENT.size() < 2)
{
for(auto axPose = 0; axPose < m_chart->m_plotArea->m_ItemsElementName1.size(); axPose++)
{
if(m_chart->m_plotArea->m_ItemsElementName1[axPose] != nullptr && m_chart->m_plotArea->m_Items1.size() > axPose)
{
auto AxType = *m_chart->m_plotArea->m_ItemsElementName1[axPose];
switch (AxType)
{
case ItemsChoiceType6::itemschoicetype6CATAX:
{
auto ivAx = static_cast<CT_CatAx*>(m_chart->m_plotArea->m_Items1.at(axPose));
axes->m_arAxes.push_back(ivAx->toXLS());
break;
}
case ItemsChoiceType6::itemschoicetype6VALAX:
{
auto dvAx = static_cast<CT_ValAx*>(m_chart->m_plotArea->m_Items1.at(axPose));
axes->m_arAxes.push_back(dvAx->toXLS());
break;
}
default:
break;
}
}
}
}
if(m_chart->m_legend != nullptr && !AxisParentUnion->m_arCRT.empty())
{
auto crtPtr = static_cast<XLS::CRT*>(AxisParentUnion->m_arCRT.back().get());
crtPtr->m_LD = m_chart->m_legend->toXLS();
}
}
}
{
auto labelUnion = new XLS::ATTACHEDLABEL;
auto textRecord = new XLS::Text;
textRecord->wBkgMode = 1;
textRecord->at = 2;
textRecord->vat = 1;
auto textPos = new XLS::Pos;
textPos->mdBotRt = 2;
textPos->mdTopLt = 2;
textPos->x1 = 150;
textPos->y1 = 25;
labelUnion->m_Pos = XLS::BaseObjectPtr(textPos);
auto objLink = new XLS::ObjectLink;
objLink->wLinkObj = 1;
auto seriesText = new XLS::SeriesText;
if(m_chart->m_title != nullptr && m_chart->m_title->m_tx != nullptr)
seriesText->stText = m_chart->m_title->m_tx->m_oRich->GetText();
else
{
textRecord->fAutoText = true;
}
auto aiUnion = new XLS::AI;
auto brai = new XLS::BRAI;
brai->rt = 1;
aiUnion->m_BRAI = XLS::BaseObjectPtr(brai);
aiUnion->m_SeriesText = XLS::BaseObjectPtr(seriesText);
labelUnion->m_AI = XLS::BaseObjectPtr(aiUnion);
labelUnion->m_ObjectLink = XLS::BaseObjectPtr(objLink);
labelUnion->m_TextProperties = XLS::BaseObjectPtr(textRecord);
ChartFormatsPtr->m_arATTACHEDLABEL.push_back(XLS::BaseObjectPtr(labelUnion));
}
return XLS::BaseObjectPtr(ptr);
}
EElementType CT_ChartSpace::getType() { return et_ct_ChartSpace; }
CT_RelId::CT_RelId()

View File

@ -2100,6 +2100,7 @@ namespace OOX
void fromXML(XmlUtils::CXmlLiteReader& oReader);
void toXML(const std::wstring& sNodeName, NSStringUtils::CStringBuilder& writer) const;
XLS::BaseObjectPtr toXLS();
EElementType getType();
};

View File

@ -292,8 +292,7 @@ namespace OOX
drawingPtr->rgChildRec.first = false;
objPair.first = XLS::MsoDrawingPtr(drawingPtr);
}
drawingPtr->prepareComment(id, ptr->note_sh.row, ptr->note_sh.col);
drawingPtr->prepareDrawing(XLS::MsoDrawing::DrawingType::comment, id, ptr->note_sh.row, ptr->note_sh.col+1, ptr->note_sh.row+4, ptr->note_sh.col+3);
objectsPtr->m_arrObject.push_back(objPair);
}

View File

@ -85,7 +85,7 @@ namespace OOX
virtual void read(const CPath& oRootPath, const CPath& oPath);
virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const;
void toXLSChart(std::vector<XLS::BaseObjectPtr> &chartVector);
void toXls(XLS::BaseObjectPtr GlobalsSubstream, XLS::BaseObjectPtr WorksheetStream);
virtual const OOX::FileType type() const;
@ -94,7 +94,6 @@ namespace OOX
const CPath& GetReadPath();
bool IsEmpty();
bool IsChart();
private:
CPath m_oReadPath;

View File

@ -33,23 +33,14 @@
#include "Drawing.h"
#include "Pos.h"
#include "../../../MsBinaryFile/XlsFile/Format/Binary/CFStreamCacheWriter.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/ChartSheetSubstream.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/OBJECTS.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CHARTFOMATS.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/AXISPARENT.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/AXES.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/ATTACHEDLABEL.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/AI.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CRT.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/MSODRAWINGGROUP.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/OBJ.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/MsoDrawing.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Chart.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/AxisParent.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Pos.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Text.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/ObjectLink.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/BRAI.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/SeriesText.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/MsoDrawingGroup.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Obj.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/WorksheetSubstream.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.h"
#include "../../PPTXFormat/Logic/Shape.h"
#include "../Chart/Chart.h"
@ -269,35 +260,71 @@ namespace OOX
oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() );
IFileContainer::Write(oPath, oDirectory, oContent);
}
void CDrawing::toXLSChart(std::vector<XLS::BaseObjectPtr> &chartVector)
void CDrawing::toXls(XLS::BaseObjectPtr GlobalsSubstream, XLS::BaseObjectPtr WorksheetStream)
{
auto worksheet = static_cast<XLS::WorksheetSubstream*>(WorksheetStream.get());
auto workbook = static_cast<XLS::GlobalsSubstream*>(GlobalsSubstream.get());
XLS::OBJECTS *wsObjects;
XLS::MsoDrawingGroup* drawingGroupPtr;
if(workbook->m_arMSODRAWINGGROUP.empty())
{
drawingGroupPtr = new XLS::MsoDrawingGroup;
auto drawingGroupUnion = new XLS::MSODRAWINGGROUP(false);
drawingGroupUnion->m_MsoDrawingGroup = XLS::BaseObjectPtr(drawingGroupPtr);
workbook->m_arMSODRAWINGGROUP.push_back(XLS::BaseObjectPtr(drawingGroupUnion));
}
else
{
auto drawingGroupUnion = static_cast<XLS::MSODRAWINGGROUP*>(workbook->m_arMSODRAWINGGROUP.back().get());
drawingGroupPtr = static_cast<XLS::MsoDrawingGroup*>(drawingGroupUnion->m_MsoDrawingGroup.get());
}
if(worksheet->m_OBJECTS == nullptr)
{
wsObjects = new XLS::OBJECTS(false);
worksheet->m_OBJECTS = XLS::BaseObjectPtr(wsObjects);
}
else
wsObjects = static_cast<XLS::OBJECTS*>(worksheet->m_OBJECTS.get());
for(auto anchor : m_arrItems)
{
auto ptr = new XLS::ChartSheetSubstream(0);
ptr->separate = false;
auto pageSetup = new XLS::PAGESETUP;
ptr->m_PAGESETUP = XLS::BaseObjectPtr(pageSetup);
auto ChartFormatsPtr = new XLS::CHARTFORMATS;
ptr->m_CHARTFORMATS = XLS::BaseObjectPtr(ChartFormatsPtr);
if(anchor->m_oElement.IsInit())
auto drawing = new XLS::MsoDrawing(false);
auto drawingPtr = XLS::MsoDrawingPtr(drawing);
if(!wsObjects->m_arrObject.empty())
drawing->rgChildRec.first = false;
else
wsObjects->m_MsoDrawing = drawingPtr;
if(anchor->m_oElement->is<PPTX::Logic::Pic>())
{
auto anchorElem = anchor->m_oElement->GetElem();
auto graphicFrame = static_cast<PPTX::Logic::GraphicFrame*>(anchorElem.GetPointer());
{
auto chartRect = new XLS::Chart;
if(anchor->m_oPos.IsInit() && anchor->m_oPos->m_oX.IsInit())
chartRect->x.dVal = anchor->m_oPos->m_oX->GetValue();
if(anchor->m_oPos.IsInit() && anchor->m_oPos->m_oY.IsInit())
chartRect->y.dVal = anchor->m_oPos->m_oY->GetValue();
if(anchor->m_oExt.IsInit() && anchor->m_oExt->m_oCx.IsInit())
chartRect->dx.dVal = anchor->m_oExt->m_oCx->GetValue();
if(anchor->m_oExt.IsInit() && anchor->m_oExt->m_oCy->GetValue())
chartRect->dy.dVal = anchor->m_oExt->m_oCy->GetValue();
ChartFormatsPtr->m_ChartRect = XLS::BaseObjectPtr(chartRect);
}
auto anchorElem = anchor->m_oElement->GetElem();
auto picElem = static_cast<PPTX::Logic::Pic*>(anchorElem.GetPointer());
auto picRid = picElem->blipFill.blip->embed->get();
auto castedPic = Get<OOX::Media>(picRid);
auto pictName = castedPic->filename().GetPath();
auto PicNumber = drawingGroupPtr->AddPict(pictName);
auto shapeCount = drawingGroupPtr->drawingCount+1;
auto left = 0, leftOff = 0, right = 0, righOff = 0, top = 0, topOff = 0, bot = 0, botOff = 0;
anchor->getAnchorPos(left, leftOff, top, topOff, right, righOff, bot, botOff);
drawing->prepareDrawing(XLS::MsoDrawing::DrawingType::pic, shapeCount, top, left, bot, right, PicNumber);
std::pair<XLS::BaseObjectPtr, std::vector<XLS::BaseObjectPtr>> objPair;
auto objPt = new XLS::Obj(drawingPtr);
objPt->cmo.ot = 0x8;
objPt->cmo.id = drawingGroupPtr->drawingCount+1;
objPt->cmo.fPrint = true;
objPair.first = drawingPtr;
objPair.second.push_back(XLS::BaseObjectPtr(objPt));
wsObjects->m_arrObject.push_back(objPair);
drawingGroupPtr->drawingCount++;
}
else if(anchor->m_oElement->is<PPTX::Logic::GraphicFrame>())
{
auto graphicFrame = static_cast<PPTX::Logic::GraphicFrame*>(anchor->m_oElement->GetElem().GetPointer());
if(graphicFrame->chartRec.IsInit() && graphicFrame->chartRec->id_data.IsInit())
{
auto chartRid = graphicFrame->chartRec->id_data.get();
@ -305,152 +332,41 @@ namespace OOX
auto ChartFile = static_cast<OOX::Spreadsheet::CChartFile*>(castedChart.GetPointer());
if(ChartFile->m_oChartSpace.m_chart == nullptr)
continue;
if(ChartFile->m_oChartSpace.m_spPr.IsInit())
{
ChartFormatsPtr->m_FRAME = ChartFile->m_oChartSpace.m_spPr->toXLSFrame();
}
if(ChartFile->m_oChartSpace.m_chart->m_plotArea != nullptr)
{
auto AxisParentUnion = new XLS::AXISPARENT;
auto axes = new XLS::AXES;
AxisParentUnion->m_AXES = XLS::BaseObjectPtr(axes);
ChartFormatsPtr->m_arAXISPARENT.push_back(XLS::BaseObjectPtr(AxisParentUnion));
auto axisPos = new XLS::Pos;
axisPos->x1 = 0;
axisPos->y1 = 200;
axisPos->x2 = 4000;
axisPos->y2 = 3800;
AxisParentUnion->m_Pos = XLS::BaseObjectPtr(axisPos);
auto xlsChart = ChartFile->m_oChartSpace.toXLS();
auto shapeCount = drawingGroupPtr->drawingCount+1;
for(auto chartIndex = 0; chartIndex < ChartFile->m_oChartSpace.m_chart->m_plotArea->m_Items.size(); chartIndex ++)
{
if(*ChartFile->m_oChartSpace.m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5BARCHART)
{
auto barChart = static_cast<CT_BarChart*>(ChartFile->m_oChartSpace.m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(barChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*ChartFile->m_oChartSpace.m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5BAR3DCHART)
{
auto barChart = static_cast<CT_Bar3DChart*>(ChartFile->m_oChartSpace.m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(barChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*ChartFile->m_oChartSpace.m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5PIECHART)
{
auto PieChart = static_cast<CT_PieChart*>(ChartFile->m_oChartSpace.m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(PieChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*ChartFile->m_oChartSpace.m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5PIE3DCHART)
{
auto PieChart = static_cast<CT_Pie3DChart*>(ChartFile->m_oChartSpace.m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(PieChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*ChartFile->m_oChartSpace.m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5LINECHART)
{
auto LineChart = static_cast<CT_LineChart*>(ChartFile->m_oChartSpace.m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(LineChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*ChartFile->m_oChartSpace.m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5LINE3DCHART)
{
auto LineChart = static_cast<CT_Line3DChart*>(ChartFile->m_oChartSpace.m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(LineChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*ChartFile->m_oChartSpace.m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5AREACHART)
{
auto AreaChart = static_cast<CT_AreaChart*>(ChartFile->m_oChartSpace.m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(AreaChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*ChartFile->m_oChartSpace.m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5AREA3DCHART)
{
auto AreaChart = static_cast<CT_Area3DChart*>(ChartFile->m_oChartSpace.m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(AreaChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*ChartFile->m_oChartSpace.m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5SURFACECHART)
{
auto SurfaceChart = static_cast<CT_SurfaceChart*>(ChartFile->m_oChartSpace.m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(SurfaceChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*ChartFile->m_oChartSpace.m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5SCATTERCHART)
{
auto ScatterChart = static_cast<CT_ScatterChart*>(ChartFile->m_oChartSpace.m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(ScatterChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
else if(*ChartFile->m_oChartSpace.m_chart->m_plotArea->m_ItemsElementName0.at(chartIndex) == OOX::Spreadsheet::itemschoicetype5RADARCHART)
{
auto ScatterChart = static_cast<CT_RadarChart*>(ChartFile->m_oChartSpace.m_chart->m_plotArea->m_Items.at(chartIndex));
AxisParentUnion->m_arCRT.push_back(ScatterChart->toXLS(chartIndex, ptr->m_CHARTFORMATS));
}
if(ChartFormatsPtr->m_arAXISPARENT.size() < 2)
{
for(auto axPose = 0; axPose < ChartFile->m_oChartSpace.m_chart->m_plotArea->m_ItemsElementName1.size(); axPose++)
{
if(ChartFile->m_oChartSpace.m_chart->m_plotArea->m_ItemsElementName1[axPose] != nullptr && ChartFile->m_oChartSpace.m_chart->m_plotArea->m_Items1.size() > axPose)
{
auto AxType = *ChartFile->m_oChartSpace.m_chart->m_plotArea->m_ItemsElementName1[axPose];
switch (AxType)
{
case ItemsChoiceType6::itemschoicetype6CATAX:
{
auto ivAx = static_cast<CT_CatAx*>(ChartFile->m_oChartSpace.m_chart->m_plotArea->m_Items1.at(axPose));
axes->m_arAxes.push_back(ivAx->toXLS());
break;
}
case ItemsChoiceType6::itemschoicetype6VALAX:
{
auto dvAx = static_cast<CT_ValAx*>(ChartFile->m_oChartSpace.m_chart->m_plotArea->m_Items1.at(axPose));
axes->m_arAxes.push_back(dvAx->toXLS());
break;
}
default:
break;
}
}
}
}
if(ChartFile->m_oChartSpace.m_chart->m_legend != nullptr && !AxisParentUnion->m_arCRT.empty())
{
auto crtPtr = static_cast<XLS::CRT*>(AxisParentUnion->m_arCRT.back().get());
crtPtr->m_LD = ChartFile->m_oChartSpace.m_chart->m_legend->toXLS();
}
}
auto drawingObj = new XLS::MsoDrawing(false);
{
auto left = 0, leftOff = 0, right = 0, righOff = 0, top = 0, topOff = 0, bot = 0, botOff = 0;
anchor->getAnchorPos(left, leftOff, top, topOff, right, righOff, bot, botOff);
if(!wsObjects->m_arrObject.empty())
drawingObj->rgChildRec.first = false;
drawingObj->prepareDrawing(XLS::MsoDrawing::DrawingType::chart, shapeCount, top, left, bot, right);
}
std::pair<XLS::BaseObjectPtr, std::vector<XLS::BaseObjectPtr>> objPair;
{
auto labelUnion = new XLS::ATTACHEDLABEL;
auto textRecord = new XLS::Text;
textRecord->wBkgMode = 1;
textRecord->at = 2;
textRecord->vat = 1;
auto textPos = new XLS::Pos;
textPos->mdBotRt = 2;
textPos->mdTopLt = 2;
textPos->x1 = 150;
textPos->y1 = 25;
auto drawingObjPtr = XLS::MsoDrawingPtr(drawingObj);
objPair.first = drawingObjPtr;
labelUnion->m_Pos = XLS::BaseObjectPtr(textPos);
auto objLink = new XLS::ObjectLink;
objLink->wLinkObj = 1;
auto seriesText = new XLS::SeriesText;
if(ChartFile->m_oChartSpace.m_chart->m_title != nullptr && ChartFile->m_oChartSpace.m_chart->m_title->m_tx != nullptr)
seriesText->stText = ChartFile->m_oChartSpace.m_chart->m_title->m_tx->m_oRich->GetText();
else
{
textRecord->fAutoText = true;
}
auto aiUnion = new XLS::AI;
auto brai = new XLS::BRAI;
brai->rt = 1;
aiUnion->m_BRAI = XLS::BaseObjectPtr(brai);
aiUnion->m_SeriesText = XLS::BaseObjectPtr(seriesText);
labelUnion->m_AI = XLS::BaseObjectPtr(aiUnion);
labelUnion->m_ObjectLink = XLS::BaseObjectPtr(objLink);
labelUnion->m_TextProperties = XLS::BaseObjectPtr(textRecord);
ChartFormatsPtr->m_arATTACHEDLABEL.push_back(XLS::BaseObjectPtr(labelUnion));
if(drawingObj->rgChildRec.first)
wsObjects->m_MsoDrawing = drawingObjPtr;
}
auto objPt = new XLS::Obj(wsObjects->m_MsoDrawing);
objPt->cmo.ot = 5;
objPt->cmo.fPrint = true;
objPt->cmo.fRecalcObj = true;
objPt->cmo.id = drawingGroupPtr->drawingCount;
auto objUnion = new XLS::OBJ(wsObjects->m_MsoDrawing);
objUnion->m_Obj = XLS::BaseObjectPtr(objPt);
objUnion->m_arrChart.push_back(xlsChart);
objPair.second.push_back(XLS::BaseObjectPtr(objUnion));
wsObjects->m_arrObject.push_back(objPair);
drawingGroupPtr->drawingCount++;
}
}
chartVector.push_back(XLS::BaseObjectPtr(ptr));
}
}
const OOX::FileType CDrawing::type() const
@ -473,10 +389,6 @@ namespace OOX
{
return m_arrItems.empty();
}
bool CDrawing::IsChart()
{
return (!IsEmpty() && m_arrItems.back()->m_oElement.IsInit() && m_arrItems.back()->m_oElement->is<PPTX::Logic::GraphicFrame>());
}
void CDrawing::ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
{
}

View File

@ -54,18 +54,16 @@
#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h"
#include "../../../MsBinaryFile/XlsFile/Format/Binary/CFStreamCacheWriter.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/WorksheetSubstream.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/ChartSheetSubstream.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SORTANDFILTER.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMTS.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CONDFMT12.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/OBJECTS.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FEAT11.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/OBJ.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/MSODRAWINGGROUP.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/CondFmt12.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/MsoDrawing.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Obj.h"
#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/MsoDrawingGroup.h"
#include "../../../OdfFile/Common/logging.h"
@ -435,77 +433,6 @@ namespace OOX
worksheetPtr->m_CELLTABLE = m_oSheetData->toXLS();
if(m_oDataConsolidate.IsInit())
worksheetPtr->m_DCON = m_oDataConsolidate->toXLS();
if(m_oDrawing.IsInit() && m_oDrawing->m_oId.IsInit())
{
RId drawingId = m_oDrawing->m_oId->GetValue();
auto castedDrawing = Get<OOX::File>(drawingId);
auto drawingPtr = static_cast<OOX::Spreadsheet::CDrawing*>(castedDrawing.GetPointer());
if(drawingPtr->IsChart())
{
XLS::MsoDrawingGroup* drawingGroupPtr;
auto Objects = new XLS::OBJECTS(false);
auto objectsPtr = XLS::BaseObjectPtr(Objects);
{
auto workbookStream = static_cast<XLS::GlobalsSubstream*>(globalsPtr.get());
if(workbookStream->m_arMSODRAWINGGROUP.empty())
{
drawingGroupPtr = new XLS::MsoDrawingGroup;
workbookStream->m_arMSODRAWINGGROUP.push_back(XLS::BaseObjectPtr(drawingGroupPtr));
}
else
{
drawingGroupPtr = static_cast<XLS::MsoDrawingGroup*>(workbookStream->m_arMSODRAWINGGROUP.back().get());
}
}
std::vector<XLS::BaseObjectPtr> charts;
drawingPtr->toXLSChart(charts);
auto chartIndex = 0;
auto shapeCount = drawingGroupPtr->drawingCount+1;
if(!charts.empty())
{
for(auto anchor : drawingPtr->m_arrItems)
{
auto drawingObj = new XLS::MsoDrawing(false);
{
auto left = 0, leftOff = 0, right = 0, righOff = 0, top = 0, topOff = 0, bot = 0, botOff = 0;
anchor->getAnchorPos(left, leftOff, top, topOff, right, righOff, bot, botOff);
if(anchor != *drawingPtr->m_arrItems.begin())
drawingObj->rgChildRec.first = false;
drawingObj->prepareChart(shapeCount, left, right, top, bot, leftOff, righOff, topOff, botOff);
}
std::pair<XLS::BaseObjectPtr, std::vector<XLS::BaseObjectPtr>> objPair;
{
auto drawingObjPtr = XLS::MsoDrawingPtr(drawingObj);
objPair.first = drawingObjPtr;
if(drawingObj->rgChildRec.first)
Objects->m_MsoDrawing = drawingObjPtr;
}
auto objPt = new XLS::Obj(Objects->m_MsoDrawing);
objPt->cmo.ot = 5;
objPt->cmo.fPrint = true;
objPt->cmo.fRecalcObj = true;
objPt->cmo.id = drawingGroupPtr->drawingCount;
auto objUnion = new XLS::OBJ(Objects->m_MsoDrawing);
objUnion->m_Obj = XLS::BaseObjectPtr(objPt);
if(charts.size() > chartIndex)
objUnion->m_arrChart.push_back(charts.at(chartIndex));
objPair.second.push_back(XLS::BaseObjectPtr(objUnion));
Objects->m_arrObject.push_back(objPair);
chartIndex++;
drawingGroupPtr->drawingCount++;
shapeCount += 1;
}
worksheetPtr->m_OBJECTS = objectsPtr;
}
}
}
if(m_pComments != nullptr)
{
if(worksheetPtr->m_OBJECTS == nullptr)
@ -517,14 +444,26 @@ namespace OOX
if(workbookStream->m_arMSODRAWINGGROUP.empty())
{
drawingGroupPtr = new XLS::MsoDrawingGroup;
workbookStream->m_arMSODRAWINGGROUP.push_back(XLS::BaseObjectPtr(drawingGroupPtr));
auto drawingGroupUnion = new XLS::MSODRAWINGGROUP(false);
drawingGroupUnion->m_MsoDrawingGroup = XLS::BaseObjectPtr(drawingGroupPtr);
workbookStream->m_arMSODRAWINGGROUP.push_back(XLS::BaseObjectPtr(drawingGroupUnion));
}
else
{
drawingGroupPtr = static_cast<XLS::MsoDrawingGroup*>(workbookStream->m_arMSODRAWINGGROUP.back().get());
auto drawingGroupUnion = static_cast<XLS::MSODRAWINGGROUP*>(workbookStream->m_arMSODRAWINGGROUP.back().get());
drawingGroupPtr = static_cast<XLS::MsoDrawingGroup*>(drawingGroupUnion->m_MsoDrawingGroup.get());
}
drawingGroupPtr->drawingCount++;
}//will be later
}
if(m_oDrawing.IsInit() && m_oDrawing->m_oId.IsInit())
{
RId drawingId = m_oDrawing->m_oId->GetValue();
auto castedDrawing = Get<OOX::File>(drawingId);
auto drawingPtr = static_cast<OOX::Spreadsheet::CDrawing*>(castedDrawing.GetPointer());
drawingPtr->toXls(globalsPtr, sheetPtr);
}
if(m_oTableParts.IsInit())
{
auto feat11 = new XLS::FEAT11;

View File

@ -453,12 +453,6 @@ bool CPdfFile::CheckPerm(int nPerm)
return false;
return m_pInternal->pReader->CheckPerm(nPerm);
}
bool CPdfFile::IsXFA()
{
if (!m_pInternal->pReader)
return false;
return m_pInternal->pReader->isXFA();
}
int CPdfFile::GetRotate(int nPageIndex)
{
if (!m_pInternal->pReader)
@ -505,12 +499,6 @@ BYTE* CPdfFile::GetLinks(int nPageIndex)
return NULL;
return m_pInternal->pReader->GetLinks(nPageIndex);
}
BYTE* CPdfFile::GetXFA()
{
if (!m_pInternal->pReader)
return NULL;
return m_pInternal->pReader->GetXFA();
}
BYTE* CPdfFile::GetWidgets()
{
if (!m_pInternal->pReader)

View File

@ -145,11 +145,9 @@ public:
bool UndoRedact();
bool CheckOwnerPassword(const wchar_t* sPassword);
bool CheckPerm(int nPerm);
bool IsXFA();
int GetRotate(int nPageIndex);
int GetMaxRefID();
void SetPageFonts(int nPageIndex);
BYTE* GetXFA();
BYTE* GetWidgets();
BYTE* GetAnnotEmbeddedFonts();
BYTE* GetAnnotStandardFonts();

View File

@ -56,7 +56,6 @@
#include "lib/xpdf/TextOutputDev.h"
#include "lib/xpdf/AcroForm.h"
#include "lib/xpdf/SecurityHandler.h"
#include "lib/xpdf/XFAScanner.h"
#include "lib/goo/GList.h"
NSFonts::IFontManager* InitFontManager(NSFonts::IApplicationFonts* pAppFonts)
@ -653,20 +652,6 @@ bool CPdfReader::CheckPerm(int nPerm)
return ownerPasswordOk || (permFlags & (1 << --nPerm));
}
bool CPdfReader::isXFA()
{
PDFDoc* pDoc = m_vPDFContext.front()->m_pDocument;
AcroForm* pAcroForms = pDoc->getCatalog()->getForm();
if (!pAcroForms)
return false;
Object* oAcroForm = pAcroForms->getAcroFormObj();
Object oXFA;
bool bRes = !oAcroForm->dictLookup("XFA", &oXFA)->isNull();
oXFA.free();
return bRes;
}
void CPdfReader::DrawPageOnRenderer(IRenderer* pRenderer, int _nPageIndex, bool* pbBreak)
{
PDFDoc* pDoc = NULL;
@ -1088,40 +1073,6 @@ void getBookmarks(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out,
}
pOutlineItem->close();
}
BYTE* CPdfReader::GetXFA()
{
PDFDoc* pDoc = m_vPDFContext.front()->m_pDocument;
XRef* xref = pDoc->getXRef();
AcroForm* pAcroForms = pDoc->getCatalog()->getForm();
if (!pAcroForms)
return NULL;
Object* oAcroForm = pAcroForms->getAcroFormObj();
Object oXFA, oCatDict, oNR;
NSWasm::CData oRes;
oRes.SkipLen();
bool bNR = false;
if (xref->getCatalog(&oCatDict)->isDict() && oCatDict.dictLookup("NeedsRendering", &oNR)->isBool())
bNR = !!oNR.getBool();
oRes.WriteBool(bNR);
oCatDict.free(); oNR.free();
if (!oAcroForm->dictLookup("XFA", &oXFA)->isNull())
{
GString* sXFA = XFAScanner::readXFAStreams(&oXFA);
oRes.WriteString((BYTE*)sXFA->getCString(), sXFA->getLength());
}
else
oRes.AddInt(0);
oXFA.free();
oRes.WriteLen();
BYTE* bRes = oRes.GetBuffer();
oRes.ClearWithoutAttack();
return bRes;
}
BYTE* CPdfReader::GetStructure()
{
if (m_vPDFContext.empty())

View File

@ -97,7 +97,6 @@ public:
bool UndoRedact();
bool CheckOwnerPassword(const wchar_t* sPassword);
bool CheckPerm(int nPerm);
bool isXFA();
void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY);
void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak);
std::wstring GetInfo();
@ -116,7 +115,6 @@ public:
int GetPageIndex(int nPageIndex, PDFDoc** pDoc = NULL, PdfReader::CPdfFontList** pFontList = NULL, int* nStartRefID = NULL);
void SetFonts(int nPageIndex);
BYTE* GetXFA();
BYTE* GetStructure();
BYTE* GetLinks(int nPageIndex);
BYTE* GetWidgets();

View File

@ -597,8 +597,9 @@ std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CP
}
else
{
double dStretch = 1.0;
std::wstring wsFBN = wsFontBaseName;
NSFonts::CFontInfo* pFontInfo = RendererOutputDev::GetFontByParams(xref, pFontManager, gfxFont, wsFBN);
NSFonts::CFontInfo* pFontInfo = RendererOutputDev::GetFontByParams(xref, pFontManager, gfxFont, wsFBN, dStretch);
if (pFontInfo && !pFontInfo->m_wsFontPath.empty())
{
EraseSubsetTag(wsFontBaseName);
@ -1064,7 +1065,7 @@ void CollectFontWidths(GfxFont* gfxFont, Dict* pFontDict, std::map<unsigned int,
}
oDescendantFonts.free();
}
void CheckFontStylePDF(std::wstring& sName, bool& bBold, bool& bItalic)
double CheckFontStylePDF(std::wstring& sName, bool& bBold, bool& bItalic)
{
EraseSubsetTag(sName);
@ -1072,16 +1073,18 @@ void CheckFontStylePDF(std::wstring& sName, bool& bBold, bool& bItalic)
CheckFontNameStyle(sName, L"semibold");
CheckFontNameStyle(sName, L"regular");
CheckFontNameStyle(sName, L"ultraexpanded");
CheckFontNameStyle(sName, L"extraexpanded");
CheckFontNameStyle(sName, L"semiexpanded");
CheckFontNameStyle(sName, L"expanded");
double dStretch = 1.0;
CheckFontNameStyle(sName, L"ultracondensed");
CheckFontNameStyle(sName, L"extracondensed");
CheckFontNameStyle(sName, L"semicondensed");
CheckFontNameStyle(sName, L"condensedlight");
CheckFontNameStyle(sName, L"condensed");
if (CheckFontNameStyle(sName, L"ultraexpanded")) dStretch = 2.0;
if (CheckFontNameStyle(sName, L"extraexpanded")) dStretch = 1.5;
if (CheckFontNameStyle(sName, L"semiexpanded")) dStretch = 1.125;
if (CheckFontNameStyle(sName, L"expanded")) dStretch = 1.25;
if (CheckFontNameStyle(sName, L"ultracondensed")) dStretch = 0.5;
if (CheckFontNameStyle(sName, L"extracondensed")) dStretch = 0.625;
if (CheckFontNameStyle(sName, L"semicondensed")) dStretch = 0.875;
if (CheckFontNameStyle(sName, L"condensedlight")) dStretch = 0.75;
if (CheckFontNameStyle(sName, L"condensed")) dStretch = 0.75;
//CheckFontNameStyle(sName, L"light");
if (CheckFontNameStyle(sName, L"bold_italic")) { bBold = true; bItalic = true; }
@ -1097,6 +1100,8 @@ void CheckFontStylePDF(std::wstring& sName, bool& bBold, bool& bItalic)
//if (CheckFontNameStyle(sName, L"bolditalicmt")) { bBold = true; bItalic = true; }
//if (CheckFontNameStyle(sName, L"bolditalic")) { bBold = true; bItalic = true; }
//if (CheckFontNameStyle(sName, L"boldoblique")) { bBold = true; bItalic = true; }
return dStretch;
}
bool EraseSubsetTag(std::wstring& sFontName)
{

View File

@ -65,7 +65,7 @@ std::vector<CAnnotFontInfo> GetAnnotFontInfos(PDFDoc* pdfDoc, NSFonts::IFontMana
std::map<std::wstring, std::wstring> GetFreeTextFont(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, Object* oAnnotRef, std::vector<CAnnotMarkup::CFontData*>& arrRC);
bool FindFonts(Object* oStream, int nDepth, Object* oResFonts);
void CollectFontWidths(GfxFont* gfxFont, Dict* pFontDict, std::map<unsigned int, unsigned int>& mGIDToWidth);
void CheckFontStylePDF(std::wstring& sName, bool& bBold, bool& bItalic);
double CheckFontStylePDF(std::wstring& sName, bool& bBold, bool& bItalic);
bool EraseSubsetTag(std::wstring& sFontName);
}

View File

@ -77,12 +77,12 @@
namespace PdfReader
{
void CheckFontNamePDF(std::wstring& sName, NSFonts::CFontSelectFormat* format)
double CheckFontNamePDF(std::wstring& sName, NSFonts::CFontSelectFormat* format)
{
bool bBold = false;
bool bItalic = false;
CheckFontStylePDF(sName, bBold, bItalic);
double dStretch = CheckFontStylePDF(sName, bBold, bItalic);
if (format)
{
@ -91,6 +91,20 @@ namespace PdfReader
if (bItalic)
format->bItalic = new INT(1);
}
return dStretch;
}
USHORT StretchToWidthClass(double fStretch)
{
if (fStretch <= 0.50) return 1; // Ultra-condensed
if (fStretch <= 0.625) return 2; // Extra-condensed
if (fStretch <= 0.75) return 3; // Condensed
if (fStretch <= 0.875) return 4; // Semi-condensed
if (fStretch <= 1.0) return 5; // Normal
if (fStretch <= 1.125) return 6; // Semi-expanded
if (fStretch <= 1.25) return 7; // Expanded
if (fStretch <= 1.50) return 8; // Extra-expanded
return 9; // Ultra-expanded
}
void Transform(double* pMatrix, double dUserX, double dUserY, double* pdDeviceX, double* pdDeviceY)
@ -738,7 +752,7 @@ namespace PdfReader
{
}
NSFonts::CFontInfo* RendererOutputDev::GetFontByParams(XRef* pXref, NSFonts::IFontManager* pFontManager, GfxFont* pFont, std::wstring& wsFontBaseName)
NSFonts::CFontInfo* RendererOutputDev::GetFontByParams(XRef* pXref, NSFonts::IFontManager* pFontManager, GfxFont* pFont, std::wstring& wsFontBaseName, double& dStretch)
{
NSFonts::CFontInfo* pFontInfo = NULL;
if (!pFontManager)
@ -751,7 +765,9 @@ namespace PdfReader
oRefObject.free();
NSFonts::CFontSelectFormat oFontSelect;
CheckFontNamePDF(wsFontBaseName, &oFontSelect);
dStretch = CheckFontNamePDF(wsFontBaseName, &oFontSelect);
if (std::abs(dStretch - 1.0f) > 1e-5f)
oFontSelect.usWidth = new USHORT(StretchToWidthClass(dStretch));
if (oFontObject.isDict())
{
Dict* pFontDict = oFontObject.getDict();
@ -825,7 +841,7 @@ namespace PdfReader
oDictItem.free();
oFontDescriptor.dictLookup("StemV", &oDictItem);
if (oDictItem.isNum())
if (oDictItem.isNum() && !oFontSelect.usWidth)
{
double dStemV = oDictItem.getNum();
if (dStemV > 50.5)
@ -884,6 +900,7 @@ namespace PdfReader
wsFontBaseName = L"Helvetica";
const BYTE* pData14 = NULL;
unsigned int nSize14 = 0;
double dStretch = 1.0;
#ifdef FONTS_USE_ONLY_MEMORY_STREAMS
CMemoryFontStream oMemoryFontStream;
#endif
@ -1194,7 +1211,7 @@ namespace PdfReader
else if (!pFont->locateFont(pXref, false) ||
(wsFileName = NSStrings::GetStringFromUTF32(pFont->locateFont(pXref, false)->path)).length() == 0)
{
NSFonts::CFontInfo* pFontInfo = GetFontByParams(pXref, pFontManager, pFont, wsFontBaseName);
NSFonts::CFontInfo* pFontInfo = GetFontByParams(pXref, pFontManager, pFont, wsFontBaseName, dStretch);
if (pFontInfo && L"" != pFontInfo->m_wsFontPath)
{
@ -1593,6 +1610,7 @@ namespace PdfReader
pEntry->unLenGID = (unsigned int)nLen;
pEntry->unLenUnicode = (unsigned int)nToUnicodeLen;
pEntry->bAvailable = true;
pEntry->dStretch = dStretch;
pEntry->bFontSubstitution = bFontSubstitution;
pEntry->bIsIdentity = pFont->isCIDFont() == gTrue ? ((GfxCIDFont*)pFont)->usesIdentityEncoding() || ((GfxCIDFont*)pFont)->usesIdentityCIDToGID() || ((GfxCIDFont*)pFont)->ctuUsesCharCodeToUnicode() || pFont->getType() == fontCIDType0C : false;
}
@ -2493,6 +2511,12 @@ namespace PdfReader
}
}
if (oEntry.dStretch != 1.0 && oEntry.bFontSubstitution)
{
arrMatrix[0] *= oEntry.dStretch;
arrMatrix[1] *= oEntry.dStretch;
}
double dShiftX = 0, dShiftY = 0;
DoTransform(arrMatrix, &dShiftX, &dShiftY, true);

View File

@ -57,6 +57,7 @@ namespace PdfReader
bool bAvailable; // Доступен ли шрифт. Сделано для многопотоковости
bool bFontSubstitution = false;
bool bIsIdentity = false;
double dStretch = 1.0;
};
@ -244,7 +245,7 @@ namespace PdfReader
{
m_pbBreak = pbBreak;
}
static NSFonts::CFontInfo* GetFontByParams(XRef* pXref, NSFonts::IFontManager* pFontManager, GfxFont* pFont, std::wstring& wsFontBaseName);
static NSFonts::CFontInfo* GetFontByParams(XRef* pXref, NSFonts::IFontManager* pFontManager, GfxFont* pFont, std::wstring& wsFontBaseName, double& dStretch);
static void GetFont(XRef* pXref, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, GfxFont* pFont, std::wstring& wsFileName, std::wstring& wsFontName, bool bNotFullName = true);
private:

View File

@ -2022,7 +2022,7 @@ namespace PdfWriter
}
if (!m_pAppearance)
if (!m_pAppearance && !bNoAP)
{
m_pAppearance = new CAnnotAppearance(m_pXref, this);
CObjectBase* pAP = Get("AP");
@ -2055,6 +2055,8 @@ namespace PdfWriter
if (bNoAP)
{
RemoveAP();
if (pForm)
{
CheckMK();

View File

@ -343,15 +343,13 @@ AcroForm *AcroForm::load(PDFDoc *docA, Catalog *catalog, Object *acroFormObjA) {
AcroFormField *field;
Object xfaObj, fieldsObj, annotsObj, annotRef, annotObj, obj1, obj2;
int pageNum, i, j;
GString* sXFA = NULL;
// this is the normal case: acroFormObj is a dictionary, as expected
if (acroFormObjA->isDict()) {
acroForm = new AcroForm(docA, acroFormObjA);
if (!acroFormObjA->dictLookup("XFA", &xfaObj)->isNull()) {
sXFA = XFAScanner::readXFAStreams(&xfaObj);
acroForm->xfaScanner = NULL;
if (!acroFormObjA->dictLookup("XFA", &xfaObj)->isNull()) {
acroForm->xfaScanner = XFAScanner::load(&xfaObj);
if (!catalog->getNeedsRendering()) {
acroForm->isStaticXFA = gTrue;
}
@ -721,7 +719,7 @@ AcroFormField *AcroFormField::load(AcroForm *acroFormA, Object *fieldRefA) {
i0 = i1;
}
}
xfaFieldA = acroFormA->xfaScanner->findField(xfaName);
xfaFieldA = acroFormA->xfaScanner->findField(xfaName);
delete xfaName;
}
@ -745,9 +743,9 @@ AcroFormField *AcroFormField::load(AcroForm *acroFormA, Object *fieldRefA) {
typeA = acroFormFieldCheckbox;
}
} else if (!typeStr->cmp("Tx")) {
if (xfaFieldA && xfaFieldA->getBarcodeInfo()) {
typeA = acroFormFieldBarcode;
} else if (flagsA & acroFormFlagFileSelect) {
if (xfaFieldA && xfaFieldA->getBarcodeInfo()) {
typeA = acroFormFieldBarcode;
} else if (flagsA & acroFormFlagFileSelect) {
typeA = acroFormFieldFileSelect;
} else if (flagsA & acroFormFlagMultiline) {
typeA = acroFormFieldMultilineText;
@ -862,9 +860,9 @@ Unicode *AcroFormField::getValue(int *length) {
// from the XFA field (NB: an XFA field with no value overrides the
// AcroForm value)
if (xfaField) {
if (xfaField->getValue()) {
u = utf8ToUnicode(xfaField->getValue(), length);
}
if (xfaField->getValue()) {
u = utf8ToUnicode(xfaField->getValue(), length);
}
// no XFA form - take the AcroForm value
} else {
@ -1223,7 +1221,7 @@ void AcroFormField::drawAnnot(int pageNum, Gfx *gfx, GBool printing,
if (acroForm->needAppearances) {
render = gTrue;
} else if (xfaField && xfaField->getValue()) {
render = gTrue;
render = gTrue;
} else {
if (!annotObj->dictLookup("AP", &obj1)->isDict()) {
render = gTrue;

View File

@ -125,7 +125,6 @@ class XFAScanner {
public:
static XFAScanner *load(Object *xfaObj);
static GString *readXFAStreams(Object *xfaObj);
virtual ~XFAScanner();
@ -136,6 +135,7 @@ public:
private:
XFAScanner();
static GString *readXFAStreams(Object *xfaObj);
GHash *scanFormValues(ZxElement *xmlRoot);
void scanFormNode(ZxElement *elem, GString *fullName,
GHash *formValues);

View File

@ -293,7 +293,7 @@ Object *ObjectStream::getObject(int objIdx, int objNum, Object *obj) {
XRef::XRef(BaseStream *strA, GBool repair) {
GFileOffset pos;
Object obj;
Object obj, root, rootType;
XRefPosSet *posSet;
int i;
@ -370,6 +370,17 @@ XRef::XRef(BaseStream *strA, GBool repair) {
if (obj.isRef()) {
rootNum = obj.getRefNum();
rootGen = obj.getRefGen();
fetch(rootNum, rootGen, &root);
if (!root.isDict() || !root.dictLookup("Type", &rootType)->isName("Catalog"))
{
root.free(); rootType.free();
errCode = errDamaged;
ok = gFalse;
return;
}
root.free(); rootType.free();
obj.free();
} else {
obj.free();
@ -972,6 +983,39 @@ GBool XRef::constructXRef() {
error(errSyntaxError, -1, "Couldn't find trailer dictionary");
return gFalse;
}
// validate the catalog object found by the initial xref scan
if (!quickCheckCatalog(str, entries[rootNum].offset + start)) {
error(errSyntaxWarning, -1, "invalid Catalog, trying repair scan");
// reset state before repair scan
rootNum = -1;
rootGen = -1;
gfree(entries);
entries = NULL;
size = 0;
last = -1;
for (int i = 0; i < xrefCacheSize; ++i) {
if (cache[i].num >= 0) {
cache[i].num = -1;
cache[i].obj.free();
}
}
for (int i = 0; i < objStrCacheLength; ++i) {
delete objStrs[i];
objStrs[i] = NULL;
}
objStrCacheLength = 0;
gfree(xrefTablePos);
xrefTablePos = NULL;
xrefTablePosLen = 0;
if (!trailerDict.isNone()) trailerDict.free();
return constructXRefRepair();
}
return gTrue;
}
@ -1016,6 +1060,316 @@ GBool XRef::saveTrailerDict(Dict *dict, GBool isXRefStream) {
return bRes;
}
// quick check: is the object at the given offset a /Type /Catalog dict?
GBool XRef::quickCheckCatalog(BaseStream *str, GFileOffset pos) {
if (pos < 0) return gFalse;
char buf[512];
str->setPos(pos);
int n = str->getBlock(buf, sizeof(buf) - 1);
if (n <= 0) return gFalse;
buf[n] = '\0';
// skip "N G obj"
char *p = strstr(buf, " obj");
if (!p) return gFalse;
p += 4;
// look for /Type key
char *t = strstr(p, "/Type");
if (!t || t - buf > 450) return gFalse;
t += 5;
// skip whitespace between /Type and its value
while (*t == ' ' || *t == '\t' || *t == '\r' || *t == '\n') ++t;
// value may be "/Catalog" or "/ Catalog" — skip the slash
if (*t == '/') ++t;
while (*t == ' ' || *t == '\t') ++t;
return strncmp(t, "Catalog", 7) == 0;
}
GFileOffset XRef::findValidCutoff(XRefTempEntry *tempEntries, int tempSize, std::vector<XRefTrailerCandidate> &candidates) {
for (auto it = candidates.rbegin(); it != candidates.rend(); ++it) {
XRefTrailerCandidate &c = *it;
GFileOffset rootPos = c.rootObjPos;
if (rootPos < 0 && c.rootNum < tempSize && tempEntries[c.rootNum].used)
rootPos = tempEntries[c.rootNum].offset;
if (rootPos < 0) continue;
if (quickCheckCatalog(str, rootPos + start)) {
return (c.sectionEnd >= 0) ? c.sectionEnd : c.trailerPos;
}
}
return -1;
}
GBool XRef::constructXRefRepair() {
int tempSize = 0;
XRefTempEntry *tempEntries = NULL;
auto ensureTemp = [&](int num) {
if (num >= tempSize) {
int newSize = num + 256;
tempEntries = (XRefTempEntry *)greallocn(
tempEntries, newSize, sizeof(XRefTempEntry));
for (int i = tempSize; i < newSize; ++i) {
tempEntries[i].offset = -1;
tempEntries[i].gen = 0;
tempEntries[i].used = gFalse;
}
tempSize = newSize;
}
};
std::vector<XRefTrailerCandidate> candidates;
int tmpStreamEndsSize = 0;
int tmpStreamEndsLen = 0;
GFileOffset *tmpStreamEnds = NULL;
// ---------- PASS 1 ----------
{
char buf[4096 + 1];
str->reset();
GFileOffset bufPos = start;
char *p = buf;
char *end = buf;
GBool startOfLine = gTrue;
GBool eof = gFalse;
GFileOffset sectionStart = start;
while (1) {
if (end - p < 256 && !eof) {
memmove(buf, p, end - p);
bufPos += p - buf;
p = buf + (end - p);
int n = (int)(buf + 4096 - p);
int m = str->getBlock(p, n);
end = p + m;
*end = '\0';
p = buf;
eof = m < n;
}
if (p == end && eof) break;
GFileOffset curPos = (GFileOffset)(bufPos + (p - buf));
// %%EOF — close current section
if (startOfLine && p[0] == '%' && !strncmp(p, "%%EOF", 5)) {
for (auto &c : candidates)
if (c.sectionEnd < 0 && c.sectionStart == sectionStart)
c.sectionEnd = curPos;
sectionStart = curPos + 5;
p += 5;
startOfLine = gFalse;
continue;
}
if (startOfLine && !strncmp(p, "endstream", 9)) {
if (tmpStreamEndsLen == tmpStreamEndsSize) {
tmpStreamEndsSize += 64;
tmpStreamEnds = (GFileOffset *)greallocn(
tmpStreamEnds, tmpStreamEndsSize, sizeof(GFileOffset));
}
tmpStreamEnds[tmpStreamEndsLen++] = curPos;
p += 9;
startOfLine = gFalse;
continue;
}
if (startOfLine && !strncmp(p, "trailer", 7)) {
GFileOffset tPos = (GFileOffset)(bufPos + (p + 7 - buf));
Object tDict, obj;
obj.initNull();
Parser *parser = new Parser(
NULL,
new Lexer(NULL, str->makeSubStream(tPos, gFalse, 0, &obj)),
gFalse);
parser->getObj(&tDict);
if (tDict.isDict()) {
Object rootRef;
tDict.getDict()->lookupNF("Root", &rootRef);
if (rootRef.isRef()) {
int rNum = rootRef.getRefNum();
ensureTemp(rNum);
XRefTrailerCandidate c;
c.trailerPos = tPos;
c.sectionStart = sectionStart;
c.sectionEnd = -1;
c.rootNum = rNum;
c.rootGen = rootRef.getRefGen();
// rootObjPos — берём то что уже видели к этому моменту
c.rootObjPos = tempEntries[rNum].used
? tempEntries[rNum].offset
: -1;
candidates.push_back(c);
}
rootRef.free();
}
tDict.free();
delete parser;
p += 7;
startOfLine = gFalse;
continue;
}
// N G obj — write to tempEntries only
if (startOfLine && *p >= '0' && *p <= '9') {
char *q = p;
int num = 0, gen = 0;
do { num = num * 10 + (*q - '0'); ++q; }
while (*q >= '0' && *q <= '9' && num < 100000000);
if (*q == '\t' || *q == '\x0c' || *q == ' ') {
do { ++q; } while (*q == '\t' || *q == '\x0c' || *q == ' ');
if (*q >= '0' && *q <= '9') {
do { gen = gen * 10 + (*q - '0'); ++q; }
while (*q >= '0' && *q <= '9' && gen < 100000000);
if ((*q == '\t' || *q == '\x0c' || *q == ' ') &&
!strncmp(q + 1, "obj", 3)) {
ensureTemp(num);
// will be overwritten — pass 2 is bounded by cutoff
tempEntries[num].offset = curPos - start;
tempEntries[num].gen = gen;
tempEntries[num].used = gTrue;
}
}
}
while (*p && *p != '\n' && *p != '\r') ++p;
startOfLine = gFalse;
continue;
}
startOfLine = (*p == '\n' || *p == '\r');
++p;
}
} // end of pass 1
// ---------- VALIDATION ----------
GFileOffset cutoffPos = findValidCutoff(tempEntries, tempSize, candidates);
gfree(tempEntries);
gfree(tmpStreamEnds);
if (cutoffPos < 0) {
error(errSyntaxWarning, -1, "no valid Catalog found, scanning entire file");
cutoffPos = str->getPos();
}
// ---------- PASS 2 ----------
// identical to original constructXRef, but stops at curPos >= cutoffPos
int streamObjNumsSize = 0;
int streamObjNumsLen = 0;
int *streamObjNums = NULL;
int lastObjNum = -1;
rootNum = -1;
gfree(streamEnds);
streamEnds = NULL;
streamEndsLen = 0;
int streamEndsSize = 0;
{
char buf[4096 + 1];
str->reset();
GFileOffset bufPos = start;
char *p = buf;
char *end = buf;
GBool startOfLine = gTrue;
GBool eof = gFalse;
while (1) {
if (end - p < 256 && !eof) {
memmove(buf, p, end - p);
bufPos += p - buf;
p = buf + (end - p);
int n = (int)(buf + 4096 - p);
int m = str->getBlock(p, n);
end = p + m;
*end = '\0';
p = buf;
eof = m < n;
}
if (p == end && eof) break;
GFileOffset curPos = (GFileOffset)(bufPos + (p - buf));
if (curPos - start >= cutoffPos)
break;
if (startOfLine && !strncmp(p, "trailer", 7)) {
constructTrailerDict((GFileOffset)(bufPos + (p + 7 - buf)));
p += 7;
startOfLine = gFalse;
} else if (startOfLine && !strncmp(p, "endstream", 9)) {
if (streamEndsLen == streamEndsSize) {
streamEndsSize += 64;
streamEnds = (GFileOffset *)greallocn(
streamEnds, streamEndsSize, sizeof(GFileOffset));
}
streamEnds[streamEndsLen++] = curPos;
p += 9;
startOfLine = gFalse;
} else if (startOfLine && *p >= '0' && *p <= '9') {
p = constructObjectEntry(p, (GFileOffset)(bufPos + (p - buf)),
&lastObjNum);
startOfLine = gFalse;
} else if (p[0] == '>' && p[1] == '>') {
p += 2;
startOfLine = gFalse;
while (*p == '\t' || *p == '\n' || *p == '\x0c' ||
*p == '\r' || *p == ' ') {
startOfLine = (*p == '\n' || *p == '\r');
++p;
}
if (!strncmp(p, "stream", 6)) {
if (lastObjNum >= 0) {
if (streamObjNumsLen == streamObjNumsSize) {
streamObjNumsSize += 64;
streamObjNums = (int *)greallocn(
streamObjNums, streamObjNumsSize, sizeof(int));
}
streamObjNums[streamObjNumsLen++] = lastObjNum;
}
p += 6;
startOfLine = gFalse;
}
} else {
startOfLine = (*p == '\n' || *p == '\r');
++p;
}
}
} // end of pass 2
GBool bRoot = gFalse;
for (int i = 0; i < streamObjNumsLen; ++i) {
Object obj;
fetch(streamObjNums[i], entries[streamObjNums[i]].gen, &obj);
if (obj.isStream()) {
Dict *dict = obj.streamGetDict();
Object type;
dict->lookup("Type", &type);
if (type.isName("XRef") && !bRoot) {
bRoot = saveTrailerDict(dict, gTrue);
} else if (type.isName("ObjStm")) {
constructObjectStreamEntries(&obj, streamObjNums[i]);
}
type.free();
}
obj.free();
}
gfree(streamObjNums);
if (rootNum < 0) {
error(errSyntaxError, -1, "Couldn't find trailer dictionary");
return gFalse;
}
return gTrue;
}
// Look for an object header ("nnn ggg obj") at [p]. The first
// character at *[p] is a digit. [pos] is the position of *[p].
char *XRef::constructObjectEntry(char *p, GFileOffset pos, int *objNum) {

View File

@ -10,6 +10,7 @@
#define XREF_H
#include <aconf.h>
#include <vector>
#ifdef USE_GCC_PRAGMAS
#pragma interface
@ -50,6 +51,21 @@ struct XRefCacheEntry {
Object obj;
};
struct XRefTempEntry {
GFileOffset offset;
int gen;
GBool used;
};
struct XRefTrailerCandidate {
GFileOffset trailerPos;
GFileOffset sectionStart;
GFileOffset sectionEnd;
GFileOffset rootObjPos; // Root object offset at the time the trailer was encountered
int rootNum;
int rootGen;
};
#define xrefCacheSize 16
#define objStrCacheSize 128
@ -179,6 +195,9 @@ private:
void constructObjectStreamEntries(Object *objStr, int objStrObjNum);
GBool constructXRefEntry(int num, int gen, GFileOffset pos,
XRefEntryType type);
GBool constructXRefRepair();
GFileOffset findValidCutoff(XRefTempEntry *tempEntries, int tempSize, std::vector<XRefTrailerCandidate> &candidates);
static GBool quickCheckCatalog(BaseStream *str, GFileOffset pos);
GBool getObjectStreamObject(int objStrNum, int objIdx,
int objNum, Object *obj);
ObjectStream *getObjectStream(int objStrNum);