mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-03-25 11:31:15 +08:00
Compare commits
18 Commits
feature/pd
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| 23e736051f | |||
| 8870516a8a | |||
| dbe56878b1 | |||
| 84aa409b1e | |||
| 8fa5f8944e | |||
| 27dc6403d7 | |||
| ecaef0fbed | |||
| 2addc5a3d8 | |||
| 4e1afe5c55 | |||
| 9ae5855ed0 | |||
| bb97d00ae7 | |||
| 2074785963 | |||
| ed697edba2 | |||
| 95d6c6c927 | |||
| da769a642b | |||
| 12083ae8c9 | |||
| 6819a41452 | |||
| 5d5732161a |
@ -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()
|
||||
{
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
};
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -60,8 +60,6 @@
|
||||
"_UndoRedact",
|
||||
"_CheckOwnerPassword",
|
||||
"_CheckPerm",
|
||||
"_IsXFA",
|
||||
"_GetXFA",
|
||||
"_GetImageBase64",
|
||||
"_GetImageBase64Len",
|
||||
"_GetImageBase64Ptr",
|
||||
|
||||
@ -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()
|
||||
{
|
||||
|
||||
@ -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()
|
||||
{
|
||||
|
||||
@ -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()
|
||||
{
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
};
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -48,6 +48,7 @@ public:
|
||||
BaseObjectPtr clone();
|
||||
|
||||
virtual const bool loadContent(BinProcessor& proc);
|
||||
virtual const bool saveContent(BinProcessor& proc);
|
||||
|
||||
static const ElementType type = typeMSODRAWINGGROUP;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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();
|
||||
};
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user