Compare commits

...

53 Commits

Author SHA1 Message Date
ce1763501b Optimization 2025-02-25 10:59:19 +03:00
896427db83 For bug 72964 2025-02-08 21:59:52 +03:00
2f4b7442c7 Fix CJSContext::GetCurrent method for jsc version 2025-02-06 12:44:39 +03:00
45da53e9ae Refactoring standarttester 2025-02-04 20:12:07 +03:00
a33743cff2 fix bug #73052 2025-02-04 13:44:41 +06:00
a83e19cbdf fix bug #72176 2025-02-03 16:35:23 +00:00
8a991ae24a Merge pull request 'Fix bug #72857' (#208) from fix/bug72857 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/208
2025-02-03 14:35:21 +00:00
6caca87b64 Merge pull request 'For bug #72496' (#207) from fix/bug72496 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/207
2025-02-03 14:35:10 +00:00
9ab884ae24 Merge pull request 'Fix hwp conversion' (#217) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/217
2025-02-03 14:15:54 +00:00
e493d976e3 Fix bug #73036 2025-02-03 16:59:47 +03:00
d75e7342cf Fix bug #73042 2025-02-03 15:45:09 +03:00
ddd750be9c Merge pull request 'Fix write base fonts' (#216) from fix/pdf-standart-fonts into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/216
2025-02-03 12:40:28 +00:00
79a4434583 Fix bug #73040 2025-02-03 15:35:39 +03:00
44ff2aff3c Fix empty FreeText AP 2025-02-03 15:32:41 +03:00
2f4b3e41b3 Fix write base fonts 2025-02-03 15:24:08 +03:00
fe208f5243 Merge pull request 'Fix bug #72961' (#215) from fix/bug-72961 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/215
2025-02-03 11:15:35 +00:00
e41c1d9703 Fix bug #72961 2025-02-03 14:12:29 +03:00
5c5f98a6e3 Fix bug 73014 2025-02-03 10:45:38 +03:00
f9dd82ad47 Merge pull request 'Fix HWP conversion' (#211) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/211
2025-02-03 06:43:31 +00:00
084c8f4b94 Fix bug #72999 2025-02-03 07:17:39 +03:00
bf15325a9e Fix bug #73000 2025-02-03 05:25:55 +03:00
1b50b3a53a Fix bug 72868 2025-02-01 17:39:08 +03:00
70b40c46d2 Fix bug #72721 2025-02-01 11:36:52 +03:00
23798f3c96 Fix ios build 2025-01-31 17:14:07 +03:00
1e8d22080d Merge pull request 'Fix hwp bugs' (#209) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/209
2025-01-31 05:08:55 +00:00
90bcd47fb7 The conversion of the character spacing to hwp has been removed 2025-01-31 03:15:19 +03:00
c1adf0b30c Fix bug #72685 2025-01-31 03:15:12 +03:00
81a4d9ccd0 Fix bug 72936 2025-01-30 16:51:25 +03:00
a97014c173 Disable use filesystem in metafiles (js module) 2025-01-30 14:26:57 +03:00
b3951d083a Fix elements align in html conversion 2025-01-30 10:37:42 +00:00
7d78b37540 Fix bug #72932 2025-01-30 10:37:42 +00:00
ff162d451e Merge pull request 'Fix hwp bug' (#205) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/205
2025-01-30 10:33:13 +00:00
5dc6402006 Fix test file 2025-01-30 13:12:27 +03:00
fae17d9bfc Merge pull request 'For bug #72694' (#204) from fix/bug72694 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/204
2025-01-30 08:02:28 +00:00
931f4edae4 For bug #72694 2025-01-30 13:36:42 +06:00
3609cf1237 Fix bug #72933 2025-01-30 00:49:49 +03:00
cc8fa641aa Merge pull request 'Fix bug 72811' (#203) from fix/bug-72811 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/203
2025-01-29 16:20:19 +00:00
3b9a865d77 Fix bug 72811 2025-01-29 19:07:58 +03:00
f3b0a992bd Fix typo 2025-01-29 18:57:35 +03:00
74f3e7f279 Merge pull request 'Fix hwp conversion' (#202) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/202
2025-01-29 15:45:08 +00:00
d195aa4a79 Fix build 2025-01-29 18:31:12 +03:00
4a384edf08 For bug #72496 2025-01-29 20:23:33 +05:00
30f96cbc6c Fix bug #72705 2025-01-29 18:15:29 +03:00
007362d8be Fix bug #72780 2025-01-29 17:57:54 +03:00
f4aac048ea fix bug #72012 2025-01-29 17:44:17 +03:00
f815fec8ed Fix bug #72714 2025-01-29 17:14:53 +03:00
4ec217226d Fix bug #72721 2025-01-29 16:32:43 +03:00
3cef41e876 Added bookmark conversion, fix bugs, refactoring in hwp format 2025-01-29 16:22:03 +03:00
20bff1d6fe for bug #72794 2025-01-29 11:17:21 +00:00
8da1a109de Fix bug #72857 2025-01-29 02:28:47 +05:00
7e4fe558f4 Fix bug #72847 2025-01-28 15:17:08 +03:00
d3d9c8df94 Added text indent in hwp conversion 2025-01-27 22:14:25 +03:00
01b582c4b9 Added BorderFill in hwp conversion 2025-01-27 22:01:41 +03:00
64 changed files with 942 additions and 525 deletions

View File

@ -316,7 +316,7 @@ namespace NSCSS
std::wstring wsTextAlign{oStyle.m_oText.GetAlign().ToWString()};
if (wsTextAlign.empty() && bInTable)
if (wsTextAlign.empty())
wsTextAlign = oStyle.m_oDisplay.GetHAlign().ToWString();
oXmlElement.AddPropertiesInP(PProperties::P_Jc, wsTextAlign);

View File

@ -240,6 +240,14 @@ bool CV8RealTimeWorker::InitVariables()
if (try_catch->Check())
return false;
}
if (!m_sJSCodeStart.empty())
{
m_context->runScript(m_sJSCodeStart, try_catch);
if (try_catch->Check())
return false;
}
return true;
}

View File

@ -422,6 +422,7 @@ public:
int m_nFileType;
std::string m_sUtf8ArgumentJSON;
std::string m_sGlobalVariable;
std::string m_sJSCodeStart;
CJSContextData m_oContextData;
@ -455,7 +456,8 @@ namespace NSDoctRenderer
std::wstring m_sTmpFolder;
std::wstring m_sFileDir;
int m_nFileType;
bool m_bJavascriptBeforeEditor;
std::wstring m_sCommandsBeforeContextCreated;
std::wstring m_sX2tPath;
@ -478,7 +480,7 @@ namespace NSDoctRenderer
public:
CDocBuilder_Private() : CDoctRendererConfig(), m_sTmpFolder(NSFile::CFileBinary::GetTempPath()), m_nFileType(-1),
m_pWorker(NULL), m_pAdditionalData(NULL), m_bIsInit(false), m_bIsServerSafeVersion(false),
m_sGlobalVariable(""), m_bIsGlobalVariableUse(false), m_pParent(NULL), m_bJavascriptBeforeEditor(false)
m_sGlobalVariable(""), m_bIsGlobalVariableUse(false), m_pParent(NULL), m_sCommandsBeforeContextCreated(L"")
{
}
@ -639,9 +641,6 @@ namespace NSDoctRenderer
NSDirectory::CreateDirectory(m_sFileDir + L"/changes");
}
if (m_bJavascriptBeforeEditor)
CheckWorkerAfterOpen();
return bRet;
#else
std::wstring sPath = m_sX2tPath + L"/empty/new.";
@ -930,11 +929,7 @@ namespace NSDoctRenderer
LOGGER_SPEED_LAP("open_convert");
if (0 == nReturnCode)
{
if (m_bJavascriptBeforeEditor)
CheckWorkerAfterOpen();
return 0;
}
NSDirectory::DeleteDirectory(m_sFileDir);
m_sFileDir = L"";
@ -1220,36 +1215,27 @@ namespace NSDoctRenderer
{
if (NULL == m_pWorker)
{
m_pWorker = new CV8RealTimeWorker(m_pParent, GetEditorType(), this);
NSDoctRenderer::DoctRendererEditorType editorType = GetEditorType();
if (NSDoctRenderer::DoctRendererEditorType::INVALID == editorType)
return false;
m_pWorker = new CV8RealTimeWorker(m_pParent, editorType, this);
m_pWorker->m_sUtf8ArgumentJSON = m_oParams.m_sArgumentJSON;
m_pWorker->m_sGlobalVariable = m_sGlobalVariable;
m_pWorker->m_sJSCodeStart = U_TO_UTF8(m_sCommandsBeforeContextCreated);
m_sCommandsBeforeContextCreated = L"";
return CheckWorkerAfterOpen();
m_pWorker->m_nFileType = m_nFileType;
CV8Params oParams;
oParams.IsServerSaveVersion = m_bIsServerSafeVersion;
oParams.DocumentDirectory = m_sFileDir;
return m_pWorker->OpenFile(m_sX2tPath, m_sFileDir, editorType, this, &oParams);
}
return true;
}
bool CheckWorkerAfterOpen()
{
if (!m_pWorker)
return false;
m_pWorker->m_nFileType = m_nFileType;
if (-1 == m_nFileType)
{
m_bJavascriptBeforeEditor = true;
return false;
}
m_bJavascriptBeforeEditor = false;
CV8Params oParams;
oParams.IsServerSaveVersion = m_bIsServerSafeVersion;
oParams.DocumentDirectory = m_sFileDir;
return m_pWorker->OpenFile(m_sX2tPath, m_sFileDir, GetEditorType(), this, &oParams);
}
int SaveFile(const std::wstring& ext, const std::wstring& path, const wchar_t* params = NULL)
{
int nType = GetFormatByTexExtention(ext);
@ -1261,21 +1247,26 @@ namespace NSDoctRenderer
if (command.length() < 7 && !retValue) // minimum command (!!!)
return true;
if (m_nFileType == -1)
{
m_sCommandsBeforeContextCreated += command;
return true;
}
Init();
bool bRes = CheckWorker();
if (CheckWorker())
return m_pWorker->ExecuteCommand(command, retValue);
if (!bRes && m_pWorker && m_bJavascriptBeforeEditor)
m_pWorker->InitVariables();
return m_pWorker->ExecuteCommand(command, retValue);
return false;
}
CDocBuilderContext GetContext(bool enterContext)
{
CDocBuilderContext ctx;
CheckWorker();
if (!CheckWorker())
return ctx;
ctx.m_internal->m_context = m_pWorker->m_context;
ctx.m_internal->m_context_data = &m_pWorker->m_oContextData;

View File

@ -125,10 +125,6 @@ namespace NSDoctRenderer
AppendScript(builder, config->m_strSdkPath + L"/pdf/src/engine/drawingfile_native.js");
AppendScript(builder, config->m_strSdkPath + L"/pdf/src/annotations/stamps.json", "window[\"native_pdf_stamps\"]=", ";");
sCachePath = config->m_strSdkPath + L"/pdf/sdk-all";
std::string ss = builder->GetData();
NSFile::CFileBinary::SaveToFile(L"D:\\222.js", UTF8_TO_U(ss));
break;
}
default:

View File

@ -160,16 +160,30 @@ void CGraphicsEmbed::SetAppImage(CGraphicsAppImage* appImage)
JSSmart<CJSValue> CGraphicsEmbed::create(JSSmart<CJSValue> Native, JSSmart<CJSValue> width_px, JSSmart<CJSValue> height_px, JSSmart<CJSValue> width_mm, JSSmart<CJSValue> height_mm)
{
NSNativeControl::CNativeControl* pControl = NULL;
if (!Native->isNull())
{
pControl = (NSNativeControl::CNativeControl*)Native->toObject()->getNative()->getObject();
JSSmart<CJSObject> pNativeObject = Native->toObject();
CJSEmbedObject* pNativeEmbedObject = pNativeObject->getNative();
if (m_pInternal->m_pAppImage)
delete m_pInternal->m_pAppImage;
m_pInternal->m_pAppImage = new CGraphicsAppImage();
m_pInternal->m_pAppImage->SetFontsDirectory(pControl->m_strFontsDirectory);
m_pInternal->m_pAppImage->SetImagesDirectory(pControl->m_strImagesDirectory);
if (pNativeEmbedObject)
{
NSNativeControl::CNativeControl* pControl = (NSNativeControl::CNativeControl*)pNativeEmbedObject->getObject();
m_pInternal->m_pAppImage->SetFontsDirectory(pControl->m_strFontsDirectory);
m_pInternal->m_pAppImage->SetImagesDirectory(pControl->m_strImagesDirectory);
}
else
{
JSSmart<CJSValue> checkResources = pNativeObject->get("isResourcesObject");
if (checkResources->isBool() && true == checkResources->toBool())
{
m_pInternal->m_pAppImage->SetFontsDirectory(pNativeObject->get("fontsDirectory")->toStringW());
m_pInternal->m_pAppImage->SetImagesDirectory(pNativeObject->get("imagesDirectory")->toStringW());
}
}
}
m_pInternal->init(width_px->toDouble(), height_px->toDouble(), width_mm->toDouble(), height_mm->toDouble());

View File

@ -374,7 +374,7 @@ namespace NSJSBase
JSSmart<CJSContext> CJSContext::GetCurrent()
{
CJSContext* ret = new CJSContext();
CJSContext* ret = new CJSContext(false);
ret->m_internal->context = NSJSBase::CJSContextPrivate::GetCurrentContext();
return ret;
}

View File

@ -100,6 +100,7 @@
"FT_CONFIG_OPTION_SYSTEM_ZLIB",
"GRAPHICS_NO_USE_DYNAMIC_LIBRARY",
"HYPHEN_ENGINE_DISABLE_FILESYSTEM",
"METAFILE_DISABLE_FILESYSTEM",
"HAVE_UNISTD_H", "HAVE_FCNTL_H", "_ARM_ALIGN_",
"METAFILE_SUPPORT_WMF_EMF",

View File

@ -730,14 +730,14 @@ bool Location::IsTouching() noexcept
PointD pt;
bool straight = C.IsStraight() && Inters->C.IsStraight();
return !straight || !intersect({C.Segment1.P.X,
C.Segment1.P.Y,
C.Segment2.P.X,
C.Segment2.P.Y,
Inters->C.Segment1.P.X,
Inters->C.Segment1.P.Y,
Inters->C.Segment2.P.X,
Inters->C.Segment2.P.Y}, pt);
return !straight || !intersect(C.Segment1.P.X,
C.Segment1.P.Y,
C.Segment2.P.X,
C.Segment2.P.Y,
Inters->C.Segment1.P.X,
Inters->C.Segment1.P.Y,
Inters->C.Segment2.P.X,
Inters->C.Segment2.P.Y, pt);
}
CBooleanOperations::CBooleanOperations(const CGraphicsPath& path1,
@ -943,7 +943,7 @@ void CBooleanOperations::TraceAllOverlap()
{
int touchCount = 0;
for (const auto& c : OriginCurves2)
count1 += CheckInters(MIN_POINT, s, c, touchCount);
count1 += CheckInters(s, c, touchCount);
break;
}
}
@ -954,7 +954,7 @@ void CBooleanOperations::TraceAllOverlap()
{
int touchCount = 0;
for (const auto& c : OriginCurves1)
count2 += CheckInters(MIN_POINT, s, c, touchCount);
count2 += CheckInters(s, c, touchCount);
break;
}
}
@ -1255,20 +1255,26 @@ void CBooleanOperations::SetVisited(const Segment& segment)
std::vector<std::vector<int>> CBooleanOperations::FindBoundsCollisions()
{
int length1 = static_cast<int>(Curves1.size()),
length2 = static_cast<int>(Curves2.size());
std::vector<std::vector<double>> allBounds, bounds2;
allBounds.reserve(length1 + length2);
bounds2.reserve(length2);
for (const auto& c : Curves1)
allBounds.push_back(c.GetBound());
allBounds.emplace_back(c.GetBound());
for (const auto& c : Curves2)
bounds2.push_back(c.GetBound());
bounds2.emplace_back(c.GetBound());
bool self = allBounds == bounds2;
if (!self)
for (auto it = bounds2.begin(); it != bounds2.end(); ++it)
allBounds.push_back(*it);
{
allBounds.resize(length1 + length2);
for (size_t i = 0; i < length2; i++)
allBounds[i + length1] = std::move(bounds2[i]);
}
int allLength = static_cast<int>(allBounds.size()),
length1 = static_cast<int>(Curves1.size());
int allLength = static_cast<int>(allBounds.size());
std::vector<int> allIdicesByPri1(allLength);
for (int i = 0; i < allLength; i++)
@ -1502,8 +1508,8 @@ void CBooleanOperations::LinkIntersection(std::shared_ptr<Location> from,
void CBooleanOperations::AddLineIntersection(const Curve& curve1, const Curve& curve2)
{
PointD pt;
if (intersect({curve1.Segment1.P.X, curve1.Segment1.P.Y, curve1.Segment2.P.X, curve1.Segment2.P.Y,
curve2.Segment1.P.X, curve2.Segment1.P.Y, curve2.Segment2.P.X, curve2.Segment2.P.Y}, pt))
if (intersect(curve1.Segment1.P.X, curve1.Segment1.P.Y, curve1.Segment2.P.X, curve1.Segment2.P.Y,
curve2.Segment1.P.X, curve2.Segment1.P.Y, curve2.Segment2.P.X, curve2.Segment2.P.Y, pt))
AddLocation(curve1, curve2, curve1.GetTimeOf(pt), curve2.GetTimeOf(pt));
}
@ -1626,10 +1632,10 @@ int CBooleanOperations::AddCurveIntersection(const Curve& curve1, const Curve& c
return calls;
}
int CBooleanOperations::CheckInters(const PointD& point, const Segment& segment, const Curve& curve, int& touchCount) const
int CBooleanOperations::CheckInters(const Segment& segment, const Curve& curve, int& touchCount) const
{
PointD pt{};
if (intersect({point.X, point.Y, segment.P.X, segment.P.Y, curve.Segment1.P.X, curve.Segment1.P.Y, curve.Segment2.P.X, curve.Segment2.P.Y}, pt))
if (intersect(MIN_POINT.X, MIN_POINT.Y, segment.P.X, segment.P.Y, curve.Segment1.P.X, curve.Segment1.P.Y, curve.Segment2.P.X, curve.Segment2.P.Y, pt))
{
if (getDistance(segment.P, pt) <= GEOMETRIC_EPSILON) return (touchCount + 1) % 2;
if (getDistance(curve.Segment1.P, pt) <= GEOMETRIC_EPSILON || getDistance(curve.Segment2.P, pt) <= GEOMETRIC_EPSILON)
@ -1642,8 +1648,8 @@ int CBooleanOperations::CheckInters(const PointD& point, const Segment& segment,
}
if (!curve.IsStraight())
{
std::vector<double> roots = curve.GetCurveLineIntersection(segment.P.X,segment.P.Y, point.X - segment.P.X, point.Y - segment.P.Y);
Curve line(segment, Segment(point));
std::vector<double> roots = curve.GetCurveLineIntersection(segment.P.X,segment.P.Y, MIN_POINT.X - segment.P.X, MIN_POINT.Y - segment.P.Y);
Curve line(segment, Segment(MIN_POINT));
int count = 0;
for (const auto& r : roots)
@ -1672,7 +1678,7 @@ void CBooleanOperations::SetWinding()
int count = 0,
touchCount = 0;
for (const auto& c : OriginCurves2)
count += CheckInters(MIN_POINT, s1, c, touchCount);
count += CheckInters(s1, c, touchCount);
for (auto& s : Segments1)
s.Winding = count % 2;
@ -1680,7 +1686,7 @@ void CBooleanOperations::SetWinding()
count = 0;
touchCount = 0;
for (const auto& c : OriginCurves1)
count += CheckInters(MIN_POINT, s2, c, touchCount);
count += CheckInters(s2, c, touchCount);
for (auto& s : Segments2)
s.Winding = count % 2;
@ -1698,7 +1704,7 @@ void CBooleanOperations::SetWinding()
int count = 0,
touchCount = 0;
for (const auto& c : (s.Id == 1 ? OriginCurves2 : OriginCurves1))
count += CheckInters(MIN_POINT, s, c, touchCount);
count += CheckInters(s, c, touchCount);
do
{

View File

@ -140,7 +140,7 @@ namespace Aggplus
void AddCurveLineIntersection(const Curve& curve1, const Curve& curve2, bool flip);
int AddCurveIntersection(const Curve& curve1, const Curve& curve2, const Curve& startCurve1, const Curve& startCurve2, bool flip,
int recursion = 0, int calls = 0, double tMin = 0.0, double tMax = 1.0, double uMin = 0.0, double uMax = 1.0);
int CheckInters(const PointD& point, const Segment& segment, const Curve& curve, int& touchCount) const;
int CheckInters(const Segment& segment, const Curve& curve, int& touchCount) const;
void SetWinding();
// Location

View File

@ -837,12 +837,13 @@ namespace Aggplus
{
std::vector<PointD> points;
unsigned length = m_internal->m_agg_ps.total_vertices();
points.resize(count);
for (unsigned i = 0; i < count; i++)
{
double x,y;
if (idx + i > length) break;
this->m_internal->m_agg_ps.vertex(idx + i, &x, &y);
points.push_back(PointD(x, y));
points[i] = PointD(x, y);
}
return points;
@ -885,37 +886,37 @@ namespace Aggplus
{
std::vector<CGraphicsPath> result;
CGraphicsPath subPath;
bool close = true;
CGraphicsPath sub_path;
for (unsigned i = 0; i < m_internal->m_agg_ps.total_vertices(); i++)
{
if (IsMovePoint(i))
{
if (!close)
{
PointD firstPoint = subPath.GetPoints(0, 1)[0];
PointD firstPoint = sub_path.GetPoints(0, 1)[0];
double x, y;
subPath.GetLastPoint(x, y);
sub_path.GetLastPoint(x, y);
if ((abs(firstPoint.X - x) <= 1e-2 && abs(firstPoint.Y - y) <= 1e-2) ||
subPath.GetPointCount() == 1)
sub_path.GetPointCount() == 1)
{
if (!firstPoint.Equals(PointD(x, y)) || subPath.GetPointCount() == 1)
subPath.LineTo(firstPoint.X, firstPoint.Y);
subPath.CloseFigure();
if (!firstPoint.Equals(PointD(x, y)) || sub_path.GetPointCount() == 1)
sub_path.LineTo(firstPoint.X, firstPoint.Y);
sub_path.CloseFigure();
}
result.push_back(subPath);
subPath.Reset();
result.push_back(sub_path);
sub_path.Reset();
}
subPath.StartFigure();
sub_path.StartFigure();
PointD point = GetPoints(i, 1)[0];
subPath.MoveTo(point.X, point.Y);
sub_path.MoveTo(point.X, point.Y);
close = false;
}
else if (IsCurvePoint(i))
{
std::vector<PointD> points = GetPoints(i, 3);
subPath.CurveTo(points[0].X, points[0].Y,
sub_path.CurveTo(points[0].X, points[0].Y,
points[1].X, points[1].Y,
points[2].X, points[2].Y);
i += 2;
@ -923,40 +924,40 @@ namespace Aggplus
else if (IsLinePoint(i))
{
PointD point = GetPoints(i, 1)[0];
subPath.LineTo(point.X, point.Y);
sub_path.LineTo(point.X, point.Y);
}
else if (IsClosePoint(i))
{
PointD firstPoint = subPath.GetPoints(0, 1)[0];
PointD firstPoint = sub_path.GetPoints(0, 1)[0];
double x, y;
subPath.GetLastPoint(x, y);
sub_path.GetLastPoint(x, y);
if (!firstPoint.Equals(PointD(x, y)) || subPath.GetPointCount() == 1)
subPath.LineTo(firstPoint.X, firstPoint.Y);
if (!firstPoint.Equals(PointD(x, y)) || sub_path.GetPointCount() == 1)
sub_path.LineTo(firstPoint.X, firstPoint.Y);
subPath.CloseFigure();
result.push_back(subPath);
subPath.Reset();
sub_path.CloseFigure();
result.push_back(sub_path);
sub_path.Reset();
close = true;
}
}
if (!close)
{
PointD firstPoint = subPath.GetPoints(0, 1)[0];
PointD firstPoint = sub_path.GetPoints(0, 1)[0];
double x, y;
subPath.GetLastPoint(x, y);
sub_path.GetLastPoint(x, y);
if ((abs(firstPoint.X - x) <= 1e-2 && abs(firstPoint.Y - y) <= 1e-2) ||
subPath.GetPointCount() == 1)
sub_path.GetPointCount() == 1)
{
if (!firstPoint.Equals(PointD(x, y)) ||
subPath.GetPointCount() == 1)
subPath.LineTo(firstPoint.X, firstPoint.Y);
subPath.CloseFigure();
sub_path.GetPointCount() == 1)
sub_path.LineTo(firstPoint.X, firstPoint.Y);
sub_path.CloseFigure();
}
result.push_back(subPath);
result.push_back(sub_path);
}
return result;

View File

@ -153,13 +153,6 @@ IMetafileToRenderter::IMetafileToRenderter(IRenderer* pRenderer)
}
IMetafileToRenderter::~IMetafileToRenderter()
{
for (std::vector<std::wstring>::iterator i = m_arTempFiles.begin(); i != m_arTempFiles.end(); i++)
{
std::wstring sPath = *i;
if (NSFile::CFileBinary::Exists(sPath))
NSFile::CFileBinary::Remove(sPath);
}
if (m_pPicker)
{
CMetafileFontPicker* pPicker = (CMetafileFontPicker*)m_pPicker;
@ -234,8 +227,6 @@ std::wstring IMetafileToRenderter::GetImagePath(const std::wstring& sPath)
oFrame.put_Data(NULL);
sImagePath = sTempFile;
}
m_arTempFiles.push_back(sTempFile);
}
RELEASEARRAYOBJECTS(pImageBuffer);

View File

@ -49,7 +49,6 @@ public:
protected:
std::wstring m_sTempDir;
std::vector<std::wstring> m_arTempFiles;
std::wstring m_sThemesDir;
std::wstring m_sMediaDir;

View File

@ -151,27 +151,28 @@ inline double integrate(const double& ax, const double& bx, const double& cx, co
return A * sum;
}
inline bool intersect(std::vector<double> v, Aggplus::PointD& res)
inline bool intersect(double v0, double v1, double v2, double v3, double v4,
double v5, double v6, double v7, Aggplus::PointD& res)
{
v[2] -= v[0];
v[3] -= v[1];
v[6] -= v[4];
v[7] -= v[5];
v2 -= v0;
v3 -= v1;
v6 -= v4;
v7 -= v5;
double cross = v[2] * v[7] - v[3] * v[6];
double cross = v2 * v7 - v3 * v6;
if (!isMachineZero(cross))
{
double dx = v[0] - v[4],
dy = v[1] - v[5],
u1 = (v[6] * dy - v[7] * dx) / cross,
u2 = (v[2] * dy - v[3] * dx) / cross,
double dx = v0 - v4,
dy = v1 - v5,
u1 = (v6 * dy - v7 * dx) / cross,
u2 = (v2 * dy - v3 * dx) / cross,
uMin = -EPSILON,
uMax = 1 + EPSILON;
if (uMin < u1 && u1 < uMax && uMin < u2 && u2 < uMax)
{
u1 = u1 <= 0 ? 0 : u1 >= 1 ? 1 : u1;
res = Aggplus::PointD(v[0] + u1 * v[2], v[1] + u1 * v[3]);
res = Aggplus::PointD(v0 + u1 * v2, v1 + u1 * v3);
return true;
}

View File

@ -147,6 +147,10 @@ namespace MetaFile
if (BI_JPEG != unCompression || BI_PNG != unCompression)
return false;
#ifdef METAFILE_DISABLE_FILESYSTEM
return false;
#endif
std::wstring wsTempFileName = GetTempFilename();
if (wsTempFileName.empty())
return false;

View File

@ -664,6 +664,9 @@ namespace MetaFile
for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex)
m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].first;
pEmfPlusBrush->oColor = pEmfPlusBrush->arGradientColors[unPositionCount - 1].first;
pEmfPlusBrush->oColorBack = pEmfPlusBrush->arGradientColors[0].first;
}
}

View File

@ -9,6 +9,15 @@ namespace NSDocxRenderer
{
UINT CShape::m_gRelativeHeight = c_iStandartRelativeHeight;
unsigned int ClampUIntSign(const double& value)
{
if (value < 0)
return 0;
if (value > 0x7FFFFFFF)
return 0x7FFFFFFF;
return (unsigned int)value;
}
CShape::CShape()
{
m_nRelativeHeight = m_gRelativeHeight;
@ -881,10 +890,10 @@ namespace NSDocxRenderer
{
double to_percentage = 100.0 * 1000.0 / m_oPen.Size;
oWriter.WriteString(L"<a:ds d=\"");
oWriter.AddUInt(dash_pattern[i] * to_percentage);
oWriter.AddUInt(ClampUIntSign(dash_pattern[i] * to_percentage));
oWriter.WriteString(L"\" ");
oWriter.WriteString(L"sp=\"");
oWriter.AddUInt(dash_pattern[i + 1] * to_percentage);
oWriter.AddUInt(ClampUIntSign(dash_pattern[i + 1] * to_percentage));
oWriter.WriteString(L"\" />");
}
oWriter.WriteString(L"</a:custDash>");

View File

@ -2381,6 +2381,8 @@ private:
if (oTS.bAddSpaces && m_oState.m_bInP && !m_oState.m_bInR && !iswspace(sText.front()) && !m_oState.m_bWasSpace && CTextSettings::Normal == oTS.eTextMode)
WriteSpace(pXml);
OpenP(pXml);
NSStringUtils::CStringBuilder oPPr;
std::wstring sPStyle = wrP(&oPPr, arSelectors, oTS);

View File

@ -12,6 +12,8 @@ PWD_ROOT_DIR = $$PWD
include($$CORE_ROOT_DIR/Common/base.pri)
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib
ADD_DEPENDENCY(kernel, UnicodeConverter, graphics)
DEFINES += HWPFILE_USE_DYNAMIC_LIBRARY
@ -50,7 +52,6 @@ SOURCES += \
HwpDoc/HwpFileHeader.cpp \
HwpDoc/OLEdoc/CompoundFile.cpp \
HwpDoc/OLEdoc/DirectoryEntry.cpp \
HwpDoc/Paragraph/CCtrlField.cpp \
HwpDoc/Paragraph/CapParagraph.cpp \
HwpDoc/Paragraph/CellParagraph.cpp \
HwpDoc/Paragraph/CharShape.cpp \
@ -63,6 +64,7 @@ SOURCES += \
HwpDoc/Paragraph/CtrlContainer.cpp \
HwpDoc/Paragraph/CtrlEmpty.cpp \
HwpDoc/Paragraph/CtrlEqEdit.cpp \
HwpDoc/Paragraph/CtrlField.cpp \
HwpDoc/Paragraph/CtrlForm.cpp \
HwpDoc/Paragraph/CtrlGeneralShape.cpp \
HwpDoc/Paragraph/CtrlHeadFoot.cpp \
@ -135,7 +137,6 @@ HEADERS += \
HwpDoc/OLEdoc/DirectoryEntry.h \
HwpDoc/OLEdoc/Sector.h \
HwpDoc/OLEdoc/SectorType.h \
HwpDoc/Paragraph/CCtrlField.h \
HwpDoc/Paragraph/CapParagraph.h \
HwpDoc/Paragraph/CellParagraph.h \
HwpDoc/Paragraph/CharShape.h \
@ -149,6 +150,7 @@ HEADERS += \
HwpDoc/Paragraph/CtrlContainer.h \
HwpDoc/Paragraph/CtrlEmpty.h \
HwpDoc/Paragraph/CtrlEqEdit.h \
HwpDoc/Paragraph/CtrlField.h \
HwpDoc/Paragraph/CtrlForm.h \
HwpDoc/Paragraph/CtrlGeneralShape.h \
HwpDoc/Paragraph/CtrlHeadFoot.h \

View File

@ -30,7 +30,7 @@
namespace HWP
{
static std::vector<std::pair<THWPColor, std::wstring>> arHighlightColors
static const std::vector<std::pair<THWPColor, std::wstring>> arHighlightColors
{{{{0, 0, 0}, L"black"}, {{0, 0, 255}, L"blue"}, {{0, 255, 255}, L"cyan"},
{{0, 255, 0}, L"green"}, {{255, 0, 255}, L"magenta"}, {{255, 0, 0}, L"red"},
{{255, 255, 0}, L"yellow"}, {{255, 255, 255}, L"white"}, {{0, 0, 139}, L"darkBlue"},
@ -74,7 +74,8 @@ EShapeObjectType GetShapeObjectType(const std::wstring& wsID)
}
CConverter2OOXML::CConverter2OOXML()
: m_pContext(nullptr), m_ushShapeCount(0), m_ushPageCount(1), m_ushTableCount(0), m_ushEquationCount(0)
: m_pContext(nullptr), m_ushShapeCount(0), m_ushPageCount(1), m_ushTableCount(0),
m_ushEquationCount(0), m_ushBookmarkCount(0)
{}
CConverter2OOXML::~CConverter2OOXML()
@ -331,13 +332,11 @@ void CConverter2OOXML::WriteCharacter(const CCtrlCharacter* pCharacter, short sh
{
case ECtrlCharType::PARAGRAPH_BREAK:
{
if (oState.m_bOpenedP)
{
oState.m_bOpenedP = false;
oBuilder.WriteString(L"</w:p>");
}
else
WriteText(L"", shParaShapeID, pCharacter->GetCharShapeId(), oBuilder, oState);
if (!oState.m_bOpenedP)
break;
oState.m_bOpenedP = false;
oBuilder.WriteString(L"</w:p>");
break;
}
@ -352,9 +351,9 @@ void CConverter2OOXML::WriteCharacter(const CCtrlCharacter* pCharacter, short sh
}
}
void CConverter2OOXML::WriteShape(const CCtrlGeneralShape* pShape, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)
void CConverter2OOXML::WriteShape(const CCtrlGeneralShape* pShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)
{
if (nullptr == pShape)
if (nullptr == pShape || oState.m_bInTextBox)
return;
switch (pShape->GetShapeType())
@ -366,27 +365,27 @@ void CConverter2OOXML::WriteShape(const CCtrlGeneralShape* pShape, NSStringUtils
case EShapeType::Polygon:
case EShapeType::Curve:
{
WriteGeometryShape(pShape, oBuilder, oState);
WriteGeometryShape(pShape, shParaShapeID, oBuilder, oState);
break;
}
case EShapeType::Pic:
{
WritePicture((const CCtrlShapePic*)pShape, oBuilder, oState);
WritePicture((const CCtrlShapePic*)pShape, shParaShapeID, oBuilder, oState);
break;
}
case EShapeType::EqEdit:
{
WriteEqEditShape((const CCtrlEqEdit*)pShape, oBuilder, oState);
WriteEqEditShape((const CCtrlEqEdit*)pShape, shParaShapeID, oBuilder, oState);
break;
}
case EShapeType::Ole:
{
WriteOleShape((const CCtrlShapeOle*)pShape, oBuilder, oState);
WriteOleShape((const CCtrlShapeOle*)pShape, shParaShapeID, oBuilder, oState);
break;
}
case EShapeType::Video:
{
WriteVideo((const CCtrlShapeVideo*)pShape, oBuilder, oState);
WriteVideo((const CCtrlShapeVideo*)pShape, shParaShapeID, oBuilder, oState);
break;
}
case EShapeType::GeneralShape:
@ -417,22 +416,32 @@ void CConverter2OOXML::WriteField(const CCtrlField* pShape, short shParaShapeID,
{
case EFieldType::Hyperlink:
{
HWP_STRING sCommand = pShape->GetCommand();
HWP_STRING wsHref = pShape->GetStringParam(L"Path");
if (sCommand.empty())
break;
sCommand = sCommand.substr(0, sCommand.find(L';'));
size_t unFound = sCommand.find(L'\\');
while (HWP_STRING::npos != unFound)
if(wsHref.empty())
{
sCommand.erase(unFound, 1);
unFound = sCommand.find(L'\\', unFound);
HWP_STRING sCommand = pShape->GetStringParam(L"Command");
if (sCommand.empty())
sCommand = pShape->GetCommand();
sCommand = sCommand.substr(0, sCommand.find(L';'));
size_t unFound = sCommand.find(L'\\');
while (HWP_STRING::npos != unFound)
{
sCommand.erase(unFound, 1);
unFound = sCommand.find(L'\\', unFound);
}
wsHref = sCommand;
}
const HWP_STRING wsID = AddRelationship(L"hyperlink", sCommand);
if (wsHref.empty())
break;
const HWP_STRING wsID = AddRelationship(L"hyperlink", wsHref);
OpenParagraph(shParaShapeID, oBuilder, oState);
oBuilder.WriteString(L"<w:hyperlink r:id=\"" + wsID + L"\">");
@ -446,6 +455,26 @@ void CConverter2OOXML::WriteField(const CCtrlField* pShape, short shParaShapeID,
oBuilder.WriteString(L"</w:hyperlink>");
break;
}
case EFieldType::Bookmark:
{
oBuilder.WriteString(L"<w:bookmarkStart w:id=\"" + std::to_wstring(m_ushBookmarkCount) + L"\" w:name=\"");
oBuilder.WriteEncodeXmlString(pShape->GetStringParam(L"bookmarkname"));
oBuilder.WriteString(L"\"/>");
oState.m_arOpenedBookmarks.push(m_ushBookmarkCount++);
oState.m_mOpenField.insert(std::make_pair(pShape->GetInstanceID(), pShape));
break;
}
case EFieldType::BookmarkClosing:
{
if (oState.m_arOpenedBookmarks.empty())
break;
oBuilder.WriteString(L"<w:bookmarkEnd w:id=\"" + std::to_wstring(oState.m_arOpenedBookmarks.top()) + L"\"/>");
oState.m_arOpenedBookmarks.pop();
break;
}
//TODO:: как-будто хочется определить тип закрывающей field на этапе парса hwpx
case EFieldType::Unknown:
{
@ -460,6 +489,15 @@ void CConverter2OOXML::WriteField(const CCtrlField* pShape, short shParaShapeID,
oBuilder.WriteString(L"</w:hyperlink>");
break;
}
case EFieldType::Bookmark:
{
if (oState.m_arOpenedBookmarks.empty())
break;
oBuilder.WriteString(L"<w:bookmarkEnd w:id=\"" + std::to_wstring(oState.m_arOpenedBookmarks.top()) + L"\"/>");
oState.m_arOpenedBookmarks.pop();
break;
}
default:
break;
}
@ -485,23 +523,22 @@ void CConverter2OOXML::WriteParagraph(const CHWPPargraph* pParagraph, NSStringUt
return;
CloseParagraph(oBuilder, oState);
OpenParagraph(pParagraph->GetShapeID(), oBuilder, oState);
if (0 < pParagraph->GetBreakType())
{
if ((0x04 == (pParagraph->GetBreakType() & 0x04)) && (0 < oState.m_unParaIndex))
{
oBuilder.WriteString(L"<w:r><w:br w:type=\"page\"/></w:r>");
oState.m_eBreakType = TConversionState::EBreakType::Page;
// oBuilder.WriteString(L"<w:r><w:br w:type=\"page\"/></w:r>");
++m_ushPageCount;
}
else if (0x08 == (pParagraph->GetBreakType() & 0x08))
oBuilder.WriteString(L"<w:r><w:br w:type=\"column\"/></w:r>");
oState.m_eBreakType = TConversionState::EBreakType::Column;
// oBuilder.WriteString(L"<w:r><w:br w:type=\"column\"/></w:r>");
}
++oState.m_unParaIndex;
std::vector<const CCtrlNote*> arNotes;
for (const CCtrl* pCtrl : pParagraph->GetCtrls())
{
switch (pCtrl->GetCtrlType())
@ -519,7 +556,7 @@ void CConverter2OOXML::WriteParagraph(const CHWPPargraph* pParagraph, NSStringUt
}
case ECtrlObjectType::Shape:
{
WriteShape((const CCtrlGeneralShape*)pCtrl, oBuilder, oState);
WriteShape((const CCtrlGeneralShape*)pCtrl, pParagraph->GetShapeID(), oBuilder, oState);
break;
}
case ECtrlObjectType::Table:
@ -529,7 +566,7 @@ void CConverter2OOXML::WriteParagraph(const CHWPPargraph* pParagraph, NSStringUt
}
case ECtrlObjectType::Note:
{
arNotes.push_back((const CCtrlNote*)pCtrl);
WriteNote((const CCtrlNote*)pCtrl, pParagraph->GetShapeID(), oBuilder, oState);
break;
}
case ECtrlObjectType::SectionDef:
@ -544,7 +581,7 @@ void CConverter2OOXML::WriteParagraph(const CHWPPargraph* pParagraph, NSStringUt
}
case ECtrlObjectType::AutoNumber:
{
WriteAutoNumber((const CCtrlAutoNumber*)pCtrl, pParagraph->GetShapeID(), ((const CParaText*)pCtrl)->GetCharShapeID(), oBuilder, oState);
WriteAutoNumber((const CCtrlAutoNumber*)pCtrl, pParagraph->GetShapeID(), oState.m_ushLastCharShapeId, oBuilder, oState);
break;
}
case ECtrlObjectType::Field:
@ -561,20 +598,6 @@ void CConverter2OOXML::WriteParagraph(const CHWPPargraph* pParagraph, NSStringUt
default:
break;
}
if (!arNotes.empty() && ECtrlObjectType::Note != pCtrl->GetCtrlType() && oState.m_bOpenedP)
{
for (const CCtrlNote* pNote: arNotes)
WriteNote(pNote, pParagraph->GetShapeID(), oBuilder, oState);
arNotes.clear();
}
}
if (oState.m_bOpenedP && !arNotes.empty())
{
for (const CCtrlNote* pNote: arNotes)
WriteNote(pNote, pParagraph->GetShapeID(), oBuilder, oState);
}
CloseParagraph(oBuilder, oState);
@ -604,6 +627,11 @@ void CConverter2OOXML::WriteParaShapeProperties(short shParaShapeID, NSStringUti
oBuilder.WriteString(L"<w:keepNext w:val=\"" + HWP_STRING((pParaShape->KeepWithNext()) ? L"true" : L"false") + L"\"/>");
const int nIndent = pParaShape->GetIndent();
if (0 != nIndent)
oBuilder.WriteString(L"<w:ind w:firstLine=\"" + std::to_wstring(static_cast<int>(std::ceil(nIndent / 10.))) + L"\"/>");
switch(pParaShape->GetHorizantalAlign())
{
case EHorizontalAlign::JUSTIFY: oBuilder.WriteString(L"<w:jc w:val=\"both\"/>"); break;
@ -667,7 +695,7 @@ void CConverter2OOXML::WriteParaShapeProperties(short shParaShapeID, NSStringUti
oBuilder.WriteString(L"<w:numPr>");
oBuilder.WriteString(L"<w:ilvl w:val=\"0\"/>");
oBuilder.WriteString(L"<w:ilvl w:val=\"" + std::to_wstring((int)pParaShape->GetHeadingLevel()) + L"\"/>");
oBuilder.WriteString(L"<w:numId w:val=\"" + std::to_wstring(nNumId) + L"\"/>");
oBuilder.WriteString(L"</w:numPr>");
@ -685,6 +713,8 @@ void CConverter2OOXML::WriteTable(const CCtrlTable* pTable, short shParaShapeID,
if (nullptr == pTable || pTable->Empty())
return;
CloseParagraph(oBuilder, oState);
++m_ushTableCount;
oBuilder.WriteString(L"<w:tbl>");
@ -825,8 +855,18 @@ void CConverter2OOXML::WriteCell(const CTblCell* pCell, NSStringUtils::CStringBu
{
for (const CHWPPargraph* pParagraph : pCell->GetParagraphs())
{
NSStringUtils::CStringBuilder oCellBuilder;
TConversionState oCellState;
WriteParagraph(pParagraph, oBuilder, oCellState);
WriteParagraph(pParagraph, oCellBuilder, oCellState);
if (0 == oCellBuilder.GetCurSize())
{
OpenParagraph(pParagraph->GetShapeID(), oBuilder, oCellState);
CloseParagraph(oBuilder, oCellState);
}
else
oBuilder.Write(oCellBuilder);
}
}
else
@ -850,15 +890,15 @@ void CConverter2OOXML::WriteCellProperties(short shBorderFillID, NSStringUtils::
oBuilder.WriteString(L"<w:tcBorders>");
WriteCellBorder(pBorderFill->GetTopBorder(), L"top", oBuilder);
WriteCellBorder(pBorderFill->GetLeftBorder(), L"left", oBuilder);
WriteCellBorder(pBorderFill->GetBottomBorder(), L"bottom", oBuilder);
WriteCellBorder(pBorderFill->GetRightBorder(), L"right", oBuilder);
WriteBorder(pBorderFill->GetTopBorder(), L"top", oBuilder);
WriteBorder(pBorderFill->GetLeftBorder(), L"left", oBuilder);
WriteBorder(pBorderFill->GetBottomBorder(), L"bottom", oBuilder);
WriteBorder(pBorderFill->GetRightBorder(), L"right", oBuilder);
oBuilder.WriteString(L"</w:tcBorders>");
}
void CConverter2OOXML::WriteCellBorder(const TBorder& oBorder, const HWP_STRING& sBorderName, NSStringUtils::CStringBuilder& oBuilder)
void CConverter2OOXML::WriteBorder(const TBorder& oBorder, const HWP_STRING& sBorderName, NSStringUtils::CStringBuilder& oBuilder)
{
if (0x00 == oBorder.m_chWidth || sBorderName.empty())
return;
@ -904,7 +944,7 @@ VECTOR<TPoint> ArcToBezier(const TPoint& oStart, const TPoint& oEnd, const TPoin
return {oStart, oControl1, oControl2, oEnd};
}
void CConverter2OOXML::WriteGeometryShape(const CCtrlGeneralShape* pGeneralShape, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)
void CConverter2OOXML::WriteGeometryShape(const CCtrlGeneralShape* pGeneralShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)
{
if (nullptr == pGeneralShape)
return;
@ -914,17 +954,18 @@ void CConverter2OOXML::WriteGeometryShape(const CCtrlGeneralShape* pGeneralShape
if (EShapeObjectType::Unknown == eShapeType)
return;
++m_ushShapeCount;
WriteCaption((const CCtrlCommon*)pGeneralShape, oBuilder, oState);
OpenParagraph(shParaShapeID, oBuilder, oState);
const int nWidth = Transform::HWPUINT2OOXML(pGeneralShape->GetWidth());
const int nHeight = Transform::HWPUINT2OOXML(pGeneralShape->GetHeight());
const std::wstring wsWidth = std::to_wstring(nWidth);
const std::wstring wsHeight = std::to_wstring(nHeight);
if (!oState.m_bOpenedP)
oBuilder.WriteString(L"<w:p>");
oBuilder.WriteString(L"<w:r><w:rPr><w:noProof/></w:rPr>");
oBuilder.WriteString(L"<mc:AlternateContent><mc:Choice Requires=\"wps\">");
@ -1053,6 +1094,7 @@ void CConverter2OOXML::WriteGeometryShape(const CCtrlGeneralShape* pGeneralShape
oBuilder.WriteString(L"<wps:txbx><w:txbxContent>");
TConversionState oShapeState;
oShapeState.m_bInTextBox = true;
for (unsigned int unParaIndex = 0; unParaIndex < nCountParagraphs; ++unParaIndex)
WriteParagraph(pGeneralShape->GetParagraphs(unParaIndex), oBuilder, oShapeState);
@ -1065,21 +1107,16 @@ void CConverter2OOXML::WriteGeometryShape(const CCtrlGeneralShape* pGeneralShape
oBuilder.WriteString(L"</wps:wsp></a:graphicData></a:graphic>");
CloseDrawingNode(pGeneralShape, oBuilder);
oBuilder.WriteString(L"</mc:Choice></mc:AlternateContent></w:r>");
if (!oState.m_bOpenedP)
oBuilder.WriteString(L"</w:p>");
}
void CConverter2OOXML::WriteEqEditShape(const CCtrlEqEdit* pEqEditShape, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)
void CConverter2OOXML::WriteEqEditShape(const CCtrlEqEdit* pEqEditShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)
{
//TODO:: добавить конвертацию eqn формулы в ooxml
++m_ushEquationCount;
if (!oState.m_bOpenedP)
{
oBuilder.WriteString(L"<w:p>");
oState.m_bOpenedP = true;
}
WriteCaption((const CCtrlCommon*)pEqEditShape, oBuilder, oState);
OpenParagraph(shParaShapeID, oBuilder, oState);
oBuilder.WriteString(L"<w:r>");
@ -1088,7 +1125,7 @@ void CConverter2OOXML::WriteEqEditShape(const CCtrlEqEdit* pEqEditShape, NSStrin
oBuilder.WriteString(L"</w:t></w:r>");
}
void CConverter2OOXML::WriteOleShape(const CCtrlShapeOle* pOleShape, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)
void CConverter2OOXML::WriteOleShape(const CCtrlShapeOle* pOleShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)
{
//TODO:: добавить конвертацию hwp ole -> ooxml chart
//TODO:: необходимо добавить поддержку формата "Hwp Document File Formats - Charts" (для случаев, когда нет ooxml представления)
@ -1111,12 +1148,15 @@ void CConverter2OOXML::WriteOleShape(const CCtrlShapeOle* pOleShape, NSStringUti
if (0 == unChartIndex)
return;
++m_ushShapeCount;
WriteCaption((const CCtrlCommon*)pOleShape, oBuilder, oState);
const std::wstring wsWidth = std::to_wstring(Transform::HWPUINT2OOXML(pOleShape->GetWidth()));
const std::wstring wsHeight = std::to_wstring(Transform::HWPUINT2OOXML(pOleShape->GetHeight()));
const std::wstring wsRelID = AddRelationship(L"chart", L"charts/chart" + std::to_wstring(unChartIndex) + L".xml");
if (!oState.m_bOpenedP)
oBuilder.WriteString(L"<w:p>");
OpenParagraph(shParaShapeID, oBuilder, oState);
oBuilder.WriteString(L"<w:r><w:rPr><w:noProof/></w:rPr>");
@ -1129,9 +1169,6 @@ void CConverter2OOXML::WriteOleShape(const CCtrlShapeOle* pOleShape, NSStringUti
CloseDrawingNode(pOleShape, oBuilder);
oBuilder.WriteString(L"</w:r>");
if (!oState.m_bOpenedP)
oBuilder.WriteString(L"</w:p>");
AddContentType(L"charts/chart" + std::to_wstring(unChartIndex) + L".xml", L"application/vnd.openxmlformats-officedocument.drawingml.chart+xml");
AddContentType(L"charts/style" + std::to_wstring(unChartIndex) + L".xml", L"application/vnd.ms-office.chartstyle+xml");
AddContentType(L"charts/colors" + std::to_wstring(unChartIndex) + L".xml", L"application/vnd.ms-office.chartcolorstyle+xml");
@ -1168,17 +1205,6 @@ void CConverter2OOXML::WriteSectionSettings(TConversionState& oState)
}
}
if (nullptr != oState.m_pColumnDef && 1 < oState.m_pColumnDef->GetColCount())
{
//TODO:: Добавить поддержку остальный свойств
m_oDocXml.WriteString(L"<w:cols w:num=\"" + std::to_wstring(oState.m_pColumnDef->GetColCount()) + L"\" w:space=\"454\" w:equalWidth=\"true\"");
if (ELineStyle2::NONE != oState.m_pColumnDef->GetColLineStyle())
m_oDocXml.WriteString(L" w:sep=\"true\"");
m_oDocXml.WriteString(L"/>");
}
const CPage *pPage = (nullptr != oState.m_pSectionDef) ? oState.m_pSectionDef->GetPage() : nullptr;
if (nullptr == pPage)
@ -1195,12 +1221,24 @@ void CConverter2OOXML::WriteSectionSettings(TConversionState& oState)
std::to_wstring(Transform::HWPUINT2Twips(pPage->GetMarginHeader())) + L"\" w:footer=\"" + std::to_wstring(Transform::HWPUINT2Twips(pPage->GetMarginFooter())) + L"\" w:gutter=\"" +
std::to_wstring(Transform::HWPUINT2Twips(pPage->GetMarginGutter())) + L"\"/>");
}
m_oDocXml.WriteString(L"<w:cols w:space=\"708\"/>");
m_oDocXml.WriteString(L"<w:docGrid w:linePitch=\"360\"/>");
if (nullptr != oState.m_pColumnDef && 1 < oState.m_pColumnDef->GetColCount())
{
//TODO:: Добавить поддержку остальный свойств
m_oDocXml.WriteString(L"<w:cols w:num=\"" + std::to_wstring(oState.m_pColumnDef->GetColCount()) + L"\" w:space=\"454\"");
if (ELineStyle2::NONE != oState.m_pColumnDef->GetColLineStyle())
m_oDocXml.WriteString(L" w:sep=\"true\"");
m_oDocXml.WriteString(L"/>");
}
else
m_oDocXml.WriteString(L"<w:cols w:space=\"708\"/>");
m_oDocXml.WriteString(L"</w:sectPr>");
}
void CConverter2OOXML::WritePicture(const CCtrlShapePic* pCtrlPic, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)
void CConverter2OOXML::WritePicture(const CCtrlShapePic* pCtrlPic, short shParaShapeId, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)
{
if (nullptr == pCtrlPic)
return;
@ -1210,10 +1248,11 @@ void CConverter2OOXML::WritePicture(const CCtrlShapePic* pCtrlPic, NSStringUtils
if (sPictureID.empty())
return;
++m_ushShapeCount;
WriteCaption((const CCtrlCommon*)pCtrlPic, oBuilder, oState);
if (!oState.m_bOpenedP)
oBuilder.WriteString(L"<w:p>");
OpenParagraph(shParaShapeId, oBuilder, oState);
oBuilder.WriteString(L"<w:r><w:rPr><w:noProof/></w:rPr>");
@ -1231,12 +1270,9 @@ void CConverter2OOXML::WritePicture(const CCtrlShapePic* pCtrlPic, NSStringUtils
oBuilder.WriteString(L"</pic:spPr></pic:pic></a:graphicData></a:graphic>");
CloseDrawingNode(pCtrlPic, oBuilder);
oBuilder.WriteString(L"</w:r>");
if (!oState.m_bOpenedP)
oBuilder.WriteString(L"</w:p>");
}
void CConverter2OOXML::WriteVideo(const CCtrlShapeVideo* pCtrlVideo, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)
void CConverter2OOXML::WriteVideo(const CCtrlShapeVideo* pCtrlVideo, short shParaShapeId, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)
{
if (nullptr == pCtrlVideo || 1 != pCtrlVideo->GetVideoType())
return;
@ -1246,10 +1282,11 @@ void CConverter2OOXML::WriteVideo(const CCtrlShapeVideo* pCtrlVideo, NSStringUti
if (sPictureID.empty())
return;
++m_ushShapeCount;
WriteCaption((const CCtrlCommon*)pCtrlVideo, oBuilder, oState);
if (!oState.m_bOpenedP)
oBuilder.WriteString(L"<w:p>");
OpenParagraph(shParaShapeId, oBuilder, oState);
oBuilder.WriteString(L"<w:r><w:rPr><w:noProof/></w:rPr>");
@ -1279,9 +1316,6 @@ void CConverter2OOXML::WriteVideo(const CCtrlShapeVideo* pCtrlVideo, NSStringUti
CloseDrawingNode(pCtrlVideo, oBuilder);
oBuilder.WriteString(L"</w:r>");
if (!oState.m_bOpenedP)
oBuilder.WriteString(L"</w:p>");
}
bool CConverter2OOXML::SaveSVGFile(const HWP_STRING& sSVG, HWP_STRING& sFileName)
@ -1532,14 +1566,17 @@ void CConverter2OOXML::WriteRunnerStyle(short shCharShapeID, NSStringUtils::CStr
if (!bStrike && pCharShape->StrikeOut())
oBuilder.WriteString(L"<w:strike/>");
double dSpacing = ((double)pCharShape->GetHeight() / 100.) * ((double)pCharShape->GetSpacing(ELang::HANGUL) / 100) * 0.8 + 0.4;
dSpacing *= 20; // pt to twips (20 = 1440 / 72)
//TODO:: на данный момент вычисляется не правильно. Необходимо более точно разобраться
// double dSpacing = ((double)pCharShape->GetHeight() / 100.) * ((double)pCharShape->GetSpacing(ELang::HANGUL) / 100) * 0.8 + 0.4;
// dSpacing *= 20; // pt to twips (20 = 1440 / 72)
oBuilder.WriteString(L"<w:spacing w:val=\"" + std::to_wstring((int)std::round(dSpacing)) + L"\"/>");
// oBuilder.WriteString(L"<w:spacing w:val=\"" + std::to_wstring((int)std::round(dSpacing)) + L"\"/>");
if (nullptr != oState.m_pHighlightColor)
oBuilder.WriteString(L"<w:highlight w:val=\"" + ConvertIntRgbToStr(*oState.m_pHighlightColor) + L"\"/>");
WriteTextBorderStyle(pCharShape->GetBorderFillID(), oBuilder, oState);
oBuilder.WriteString(sExternStyles);
oBuilder.WriteString(L"</w:rPr>");
@ -1559,13 +1596,26 @@ void CConverter2OOXML::WriteRunnerStyle(short shCharShapeID, NSStringUtils::CStr
oState.m_eBreakType = TConversionState::EBreakType::None;
}
void CConverter2OOXML::WriteTextBorderStyle(short shBorderFillId, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)
{
const CHWPRecordBorderFill* pBorderFill = dynamic_cast<const CHWPRecordBorderFill*>(m_pContext->GetBorderFill(shBorderFillId));
if (nullptr == pBorderFill)
return;
TBorder oBorder{pBorderFill->GetLeftBorder()};
if (ELineStyle2::NONE == oBorder.m_eStyle)
return;
WriteBorder(pBorderFill->GetLeftBorder(), L"bdr", oBuilder);
}
void CConverter2OOXML::OpenDrawingNode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder)
{
if (nullptr == pCtrlShape)
return;
++m_ushShapeCount;
oBuilder.WriteString(L"<w:drawing>");
if (pCtrlShape->GetTreatAsChar())
@ -1742,8 +1792,8 @@ void CConverter2OOXML::WriteText(const CParaText* pParaText, const std::vector<T
{
if (unTextPosition + nParaTextPosition == oRangeTag.m_nStartPos)
{
WriteText(wsText.substr(unStartText, unTextPosition - unStartText - 1), shParaShapeID, pParaText->GetCharShapeID(), oBuilder, oState);
unStartText = unTextPosition - 1;
WriteText(wsText.substr(unStartText, unTextPosition - unStartText), shParaShapeID, pParaText->GetCharShapeID(), oBuilder, oState);
unStartText = unTextPosition;
switch (oRangeTag.m_chType)
{
@ -1758,8 +1808,8 @@ void CConverter2OOXML::WriteText(const CParaText* pParaText, const std::vector<T
}
else if (unTextPosition + nParaTextPosition == oRangeTag.m_nEndPos)
{
WriteText(wsText.substr(unStartText, unTextPosition - unStartText - 1), shParaShapeID, pParaText->GetCharShapeID(), oBuilder, oState);
unStartText = unTextPosition - 1;
WriteText(wsText.substr(unStartText, unTextPosition - unStartText), shParaShapeID, pParaText->GetCharShapeID(), oBuilder, oState);
unStartText = unTextPosition;
switch (oRangeTag.m_chType)
{
@ -1830,7 +1880,22 @@ void CConverter2OOXML::WriteText(const HWP_STRING& wsText, short shParaShapeID,
WriteRunnerStyle(shCharShapeID, oBuilder, oState);
oBuilder.WriteString(L"<w:t>");
oBuilder.WriteString(L"<w:t");
bool bNeedPreserve = (wsText.cend() != std::find_if(wsText.cbegin(), wsText.cend(), [](wchar_t wChar){ return iswspace(wChar); }));
bool bNeedAddSpace = false;
if (oState.m_bIsNote && !iswspace(wsText[0]))
bNeedAddSpace = true;
if (bNeedPreserve || bNeedAddSpace)
oBuilder.WriteString(L" xml:space=\"preserve\">");
else
oBuilder.WriteString(L">");
if (bNeedAddSpace)
oBuilder.WriteString(L" ");
oBuilder.WriteEncodeXmlString(wsText);
oBuilder.WriteString(L"</w:t></w:r>");
@ -1985,12 +2050,29 @@ void CConverter2OOXML::WriteAutoNumber(const CCtrlAutoNumber* pAutoNumber,short
switch (pAutoNumber->GetNumType())
{
case ENumType::PAGE:
{
OpenParagraph(shParaShapeID, oBuilder, oState);
oBuilder.WriteString(L"<w:fldSimple w:instr=\"PAGE \\* ARABIC\"><w:r><w:t>1</w:t></w:r></w:fldSimple>");
return;
}
case ENumType::TOTAL_PAGE:
ushValue = m_ushPageCount; break;
case ENumType::FOOTNOTE:
ushValue = m_oFootnoteConverter.GetFootnoteCount(); break;
{
OpenParagraph(shParaShapeID, oBuilder, oState);
oBuilder.WriteString(L"<w:r>");
WriteRunnerStyle(shCharShapeID, oBuilder, oState, L"<w:vertAlign w:val=\"superscript\"/>");
oBuilder.WriteString(L"<w:footnoteRef/></w:r>");
return;
}
case ENumType::ENDNOTE:
ushValue = m_oFootnoteConverter.GetEndnoteCount(); break;
{
OpenParagraph(shParaShapeID, oBuilder, oState);
oBuilder.WriteString(L"<w:r>");
WriteRunnerStyle(shCharShapeID, oBuilder, oState, L"<w:vertAlign w:val=\"superscript\"/>");
oBuilder.WriteString(L"<w:endnoteRef/></w:r>");
return;
}
case ENumType::FIGURE:
{
wsType = L"Figure";
@ -2030,7 +2112,15 @@ HWP_STRING CConverter2OOXML::AddRelationship(const HWP_STRING& wsType, const HWP
if (m_arRelationships.cend() != itFound)
return itFound->m_wsID;
m_arRelationships.push_back({L"rId" + std::to_wstring(m_arRelationships.size() + 1), wsType, wsTarget});
if (L"hyperlink" == wsType)
{
NSStringUtils::CStringBuilder oBuilder;
oBuilder.WriteEncodeXmlString(wsTarget);
m_arRelationships.push_back({L"rId" + std::to_wstring(m_arRelationships.size() + 1), wsType, oBuilder.GetData()});
}
else
m_arRelationships.push_back({L"rId" + std::to_wstring(m_arRelationships.size() + 1), wsType, wsTarget});
return m_arRelationships.back().m_wsID;
}
@ -2105,7 +2195,7 @@ HWP_STRING CConverter2OOXML::GetTempDirectory() const
}
TConversionState::TConversionState()
: m_bOpenedP(false), m_bOpenedR(false), m_ushLastCharShapeId(-1), m_ushSecdIndex(0), m_unParaIndex(0), m_pHighlightColor(nullptr),
: m_bOpenedP(false), m_bOpenedR(false), m_bIsNote(false), m_bInTextBox(false), m_ushLastCharShapeId(-1), m_ushSecdIndex(0), m_unParaIndex(0), m_pHighlightColor(nullptr),
m_pSectionDef(nullptr), m_pColumnDef(nullptr), m_eBreakType(EBreakType::None)
{}

View File

@ -3,7 +3,7 @@
#include "../../../DesktopEditor/common/StringBuilder.h"
#include "../Paragraph/CCtrlField.h"
#include "../Paragraph/CtrlField.h"
#include "../Paragraph/CtrlAutoNumber.h"
#include "../Paragraph/CtrlSectionDef.h"
#include "../Paragraph/CtrlShapeVideo.h"
@ -37,6 +37,9 @@ struct TConversionState
{
bool m_bOpenedP;
bool m_bOpenedR;
bool m_bIsNote;
bool m_bInTextBox; // TODO:: используется, чтобы в wps:txbx не появилась новая фигура (посмотреть этот момент нужно подробнее)
unsigned short m_ushLastCharShapeId;
@ -46,6 +49,7 @@ struct TConversionState
THWPColor *m_pHighlightColor;
VECTOR<const CCtrlHeadFoot*> m_arCtrlsHeadFoot; //only for hwpx
std::stack<int> m_arOpenedBookmarks;
const CCtrlSectionDef* m_pSectionDef;
const CCtrlColumnDef* m_pColumnDef;
@ -106,6 +110,8 @@ class CConverter2OOXML
unsigned short m_ushTableCount;
unsigned short m_ushEquationCount;
unsigned short m_ushBookmarkCount;
void CreateEmptyFiles();
void FillDefaultData();
void Close();
@ -118,20 +124,21 @@ class CConverter2OOXML
void WriteTableProperties(const CCtrlTable* pTable, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteCell(const CTblCell* pCell, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState, ECellCreator eCellCreator);
void WriteCellProperties(short shBorderFillID, NSStringUtils::CStringBuilder& oBuilder);
void WriteCellBorder(const TBorder& oBorder, const HWP_STRING& sBorderName, NSStringUtils::CStringBuilder& oBuilder);
void WriteBorder(const TBorder& oBorder, const HWP_STRING& sBorderName, NSStringUtils::CStringBuilder& oBuilder);
void WriteGeometryShape(const CCtrlGeneralShape* pGeneralShape, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteEqEditShape(const CCtrlEqEdit* pEqEditShape, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteOleShape(const CCtrlShapeOle* pOleShape, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteGeometryShape(const CCtrlGeneralShape* pGeneralShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteEqEditShape(const CCtrlEqEdit* pEqEditShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteOleShape(const CCtrlShapeOle* pOleShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteSectionSettings(TConversionState& oState);
void WritePicture(const CCtrlShapePic* pCtrlPic, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteVideo(const CCtrlShapeVideo* pCtrlVideo, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WritePicture(const CCtrlShapePic* pCtrlPic, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteVideo(const CCtrlShapeVideo* pCtrlVideo, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
bool SaveSVGFile(const HWP_STRING& sSVG, HWP_STRING& sFileName);
HWP_STRING SavePicture(const HWP_STRING& sBinItemId);
void WriteParaShapeProperties(short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteRunnerStyle(short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState, const HWP_STRING& sExternStyles = L"");
void WriteTextBorderStyle(short shBorderFillId, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void OpenDrawingNode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
void CloseDrawingNode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
@ -152,7 +159,7 @@ class CConverter2OOXML
void WriteAutoNumber(const CCtrlAutoNumber* pAutoNumber, short shParaShapeID, short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteCharacter(const CCtrlCharacter* pCharacter, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteShape(const CCtrlGeneralShape* pShape, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteShape(const CCtrlGeneralShape* pShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
void WriteNote(const CCtrlNote* pNote, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);

View File

@ -35,6 +35,7 @@ std::wstring CFootnoteConverter::CreateNote(const CCtrlNote* pNote, CConverter2O
pXMLBuilder->WriteString(L"<w:" + wsPrefix + L"note w:id=\"" + wsIndex + L"\">");
TConversionState oState;
oState.m_bIsNote = true;
for (const CHWPPargraph* pParagraph : pNote->GetParagraphs())
oConverter.WriteParagraph(pParagraph, *pXMLBuilder, oState);

View File

@ -27,12 +27,14 @@ int CNumberingConverter::CreateNumbering(const CHWPRecordNumbering* pNumbering,
if (nullptr == pNumbering || eHeadingType == EHeadingType::NONE || EHeadingType::OUTLINE == eHeadingType)
return 0;
std::vector<const CHWPRecordNumbering*>::const_iterator itFound = std::find(m_arUsedNumbering.cbegin(), m_arUsedNumbering.cend(), pNumbering);
std::vector<std::pair<EHeadingType, const CHWPRecordNumbering*>>::const_iterator itFound = std::find_if(m_arUsedNumbering.cbegin(), m_arUsedNumbering.cend(),
[pNumbering, eHeadingType](const std::pair<EHeadingType, const CHWPRecordNumbering*>& oValue)
{ return eHeadingType == oValue.first && pNumbering == oValue.second;});
if (m_arUsedNumbering.cend() != itFound)
return itFound - m_arUsedNumbering.cbegin() + 1;
m_arUsedNumbering.push_back(pNumbering);
m_arUsedNumbering.push_back(std::make_pair(eHeadingType, pNumbering));
m_oNumberXml.WriteString(L"<w:abstractNum w:abstractNumId=\"" + std::to_wstring(m_arUsedNumbering.size()) + L"\">");
@ -51,7 +53,15 @@ int CNumberingConverter::CreateNumbering(const CHWPRecordNumbering* pNumbering,
m_oNumberXml.WriteString(L"<w:suff w:val=\"space\"/>");
wsLvlText = pNumbering->GetNumFormat(shIndex);
std::replace(wsLvlText.begin(), wsLvlText.end(), L'^', L'%');
if (wsLvlText.empty())
{
for (short shLvl = 0; shLvl <= shIndex; ++shLvl)
wsLvlText += L'%' + std::to_wstring(shLvl + 1) + L'.';
}
else
std::replace(wsLvlText.begin(), wsLvlText.end(), L'^', L'%');
m_oNumberXml.WriteString(L"<w:lvlText w:val=\"" + wsLvlText + L"\"/>");
m_oNumberXml.WriteString(L"<w:lvlJc w:val=\"");
@ -73,9 +83,8 @@ int CNumberingConverter::CreateNumbering(const CHWPRecordNumbering* pNumbering,
{
m_oNumberXml.WriteString(L"<w:lvl w:ilvl=\"" + std::to_wstring(shIndex) + L"\">");
m_oNumberXml.WriteString(L"<w:start w:val=\"1\"/>");
m_oNumberXml.WriteString(L"<w:numFmt w:val=\"" + wsNumFormat + L"\"/>");
m_oNumberXml.WriteString(L"<w:suff w:val=\"space\"/>");
m_oNumberXml.WriteString(L"<w:isLgl w:val=\"false\"/>");
m_oNumberXml.WriteString(L"<w:lvlJc w:val=\"");
switch(pNumbering->GetAlign(shIndex))
@ -174,7 +183,7 @@ bool CNumberingConverter::SaveToFile(const std::wstring& wsDirectory)
else
{
for (unsigned short ushIndex = 1; ushIndex <= m_arUsedNumbering.size(); ++ushIndex)
m_oNumberXml.WriteString(L"<w:num w:numId=\"" + std::to_wstring(ushIndex) + L"\"><w:abstractNumId w:val=\"" + std::to_wstring(ushIndex) + L"\"/></w:num>");
oNumberingData.WriteString(L"<w:num w:numId=\"" + std::to_wstring(ushIndex) + L"\"><w:abstractNumId w:val=\"" + std::to_wstring(ushIndex) + L"\"/></w:num>");
}
oNumberingData.WriteString(L"</w:numbering>");

View File

@ -11,7 +11,7 @@ namespace HWP
class CNumberingConverter
{
NSStringUtils::CStringBuilder m_oNumberXml;
std::vector<const CHWPRecordNumbering*> m_arUsedNumbering;
std::vector<std::pair<EHeadingType, const CHWPRecordNumbering*>> m_arUsedNumbering;
public:
CNumberingConverter();

View File

@ -123,8 +123,8 @@ void COleConverter::CreateChart(CHWPStream& oOleStream)
NSStringUtils::CStringBuilder oRelsData;
oRelsData.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
oRelsData.WriteString(L"<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">");
oRelsData.WriteString(L"<Relationship Id=\"rId1\" Type=\"http://schemas.microsoft.com/office/2011/relationships/chartStyle\" Target=\"style1.xml\"/>");
oRelsData.WriteString(L"<Relationship Id=\"rId2\" Type=\"http://schemas.microsoft.com/office/2011/relationships/chartColorStyle\" Target=\"colors1.xml\"/>");
oRelsData.WriteString(L"<Relationship Id=\"rId1\" Type=\"http://schemas.microsoft.com/office/2011/relationships/chartStyle\" Target=\"style" + std::to_wstring(m_unCountCharts) + L".xml\"/>");
oRelsData.WriteString(L"<Relationship Id=\"rId2\" Type=\"http://schemas.microsoft.com/office/2011/relationships/chartColorStyle\" Target=\"colors" + std::to_wstring(m_unCountCharts) + L".xml\"/>");
oRelsData.WriteString(L"</Relationships>");
NSFile::CFileBinary oRelsFile;

View File

@ -288,7 +288,7 @@ const CHWPRecord* CHWPDocInfo::GetCharShape(int nIndex) const
const CHWPRecord* CHWPDocInfo::GetNumbering(int nIndex) const
{
GET_RECORD(m_arNumberings, nIndex - 1);
GET_RECORD(m_arNumberings, nIndex);
}
const CHWPRecord* CHWPDocInfo::GetBullet(int nIndex) const
@ -318,10 +318,33 @@ CHWPFile* CHWPDocInfo::GetParentHWP()
const CHWPRecord* CHWPDocInfo::GetBinData(const HWP_STRING& sID) const
{
if (m_mBinDatas.end() == m_mBinDatas.find(sID))
return nullptr;
switch (m_eHanType)
{
case EHanType::HWP:
{
short shID = std::stoi(sID) - 1;
return m_mBinDatas.at(sID);
if (shID >= m_mBinDatas.size())
return nullptr;
std::map<HWP_STRING, CHWPRecord*>::const_iterator itElement = m_mBinDatas.cbegin();
for (unsigned short ushIndex = 0; ushIndex < shID; ++ushIndex)
++itElement;
return itElement->second;
}
case EHanType::HWPX:
{
if (m_mBinDatas.end() == m_mBinDatas.find(sID))
return nullptr;
return m_mBinDatas.at(sID);
break;
}
default:
return nullptr;
}
}
EHanType CHWPDocInfo::GetHanType() const

View File

@ -43,12 +43,6 @@ EState GetState(int nValue)
CHWPRecordBinData::CHWPRecordBinData(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion)
: CHWPRecord(nTagNum, nLevel, nSize)
{
if (EHanType::HWP == oDocInfo.GetHanType())
{
if (oDocInfo.GetParentHWP()->GetBinData().empty())
oDocInfo.GetParentHWP()->SetBinData(oDocInfo.GetParentHWP()->GetOleFile()->GetChildEntries(L"BinData"));
}
oBuffer.SavePosition();
short shTypeBits;

View File

@ -372,4 +372,9 @@ int CHWPRecordCharShape::GetTextColor() const
{
return m_nTextColor;
}
short CHWPRecordCharShape::GetBorderFillID() const
{
return m_shBorderFillIDRef;
}
}

View File

@ -123,6 +123,8 @@ public:
HWP_STRING GetFontName(ELang eLang) const;
short GetSpacing(ELang eLang) const;
int GetTextColor() const;
short GetBorderFillID() const;
};
}

View File

@ -1,4 +1,5 @@
#include "HWPRecordCtrlData.h"
#include "../Paragraph/CtrlField.h"
namespace HWP
{
@ -35,7 +36,53 @@ int CHWPRecordCtrlData::ParseCtrl(CCtrl& oCtrl, int nSize, CHWPStream& oBuffer,
// TODO:: Вернуться к этому моменту
// Само по себе содержание документа Hankom не позволяет понять, как его интерпретировать.
oBuffer.Skip(nSize);
oBuffer.SavePosition();
if (ECtrlObjectType::Field == oCtrl.GetCtrlType())
{
short shSetID, shNumberItems;
oBuffer.ReadShort(shSetID);
oBuffer.ReadShort(shNumberItems);
short shItemID, shItemType;
for (unsigned short ushIndex = 0; ushIndex < shNumberItems; ++ushIndex)
{
oBuffer.ReadShort(shItemID);
short shUnknownValue;
oBuffer.ReadShort(shUnknownValue); // Unknown Data
oBuffer.ReadShort(shItemType);
switch (GetParamItemType(shItemType))
{
case EParamItemType::PIT_NULL: oBuffer.Skip(4); break;
case EParamItemType::PIT_BSTR:
{
HWP_STRING sValue;
oBuffer.ReadString(sValue, EStringCharacter::UTF16);
if (EFieldType::Bookmark == ((CCtrlField&)oCtrl).GetType())
((CCtrlField&)oCtrl).AddStringParam(L"bookmarkname", sValue);
break;
}
case EParamItemType::PIT_I1: oBuffer.Skip(1); break;
case EParamItemType::PIT_I2: oBuffer.Skip(2); break;
case EParamItemType::PIT_I4: oBuffer.Skip(4); break;
case EParamItemType::PIT_I: oBuffer.Skip(4); break;
case EParamItemType::PIT_UI1: oBuffer.Skip(1); break;
case EParamItemType::PIT_UI2: oBuffer.Skip(2); break;
case EParamItemType::PIT_UI4: oBuffer.Skip(4); break;
case EParamItemType::PIT_UI: oBuffer.Skip(4); break;
case EParamItemType::PIT_SET:
case EParamItemType::PIT_ARRAY:
case EParamItemType::PIT_BINDATA:
break;
}
}
}
oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true));
return nSize;
}
}

View File

@ -13,7 +13,7 @@
#include "../Paragraph/CtrlSectionDef.h"
#include "../Paragraph/CtrlTable.h"
#include "../Paragraph/CtrlEmpty.h"
#include "../Paragraph/CCtrlField.h"
#include "../Paragraph/CtrlField.h"
namespace HWP
{
@ -78,7 +78,8 @@ CCtrl* CHWPRecordCtrlHeader::Parse(int nTagNum, int nLevel, int nSize, CHWPStrea
pCtrl = new CCtrlPageNumPos(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion);
pCtrl->SetFullFilled();
}
else if (L"klh%" == sCtrlID)
else if (L"klh%" == sCtrlID ||
L"kmb%" == sCtrlID)
{
pCtrl = new CCtrlField(sCtrlID, nSize - oBuffer.GetDistanceToLastPos(), oBuffer, 0, nVersion);
pCtrl->SetFullFilled();

View File

@ -44,19 +44,6 @@ CHWPRecordIDMaping::CHWPRecordIDMaping(CHWPDocInfo& oDocInfo, int nTagNum, int n
m_arIdMappingNum.push_back(nCount);
m_arCounts[nIndex] = nCount;
switch (GetIndex(nIndex))
{
case EIndex::BIN_DATA:
{
// TODO:: проверить
if (nullptr != m_pParent && m_pParent->GetParentHWP()->GetBinData().empty())
m_pParent->GetParentHWP()->SetBinData(m_pParent->GetParentHWP()->GetOleFile()->GetChildEntries(L"BinData"));
break;
}
default: break;
}
}
}
}

View File

@ -218,4 +218,12 @@ int CHWPRecordNumbering::GetStartNumber(unsigned short ushIndex) const
return m_arNumbering[ushIndex].m_nStartNumber;
}
int CHWPRecordNumbering::GetCharShape(unsigned short ushIndex) const
{
if (ushIndex >= 7)
return 0;
return m_arNumbering[ushIndex].m_nCharShape;
}
}

View File

@ -42,6 +42,7 @@ public:
HWP_STRING GetNumFormat(unsigned short ushIndex) const;
HWP_BYTE GetAlign(unsigned short ushIndex) const;
int GetStartNumber(unsigned short ushIndex) const;
int GetCharShape(unsigned short ushIndex) const;
};
}

View File

@ -13,6 +13,14 @@ EHeadingType GetHeadingType(int nValue)
}
}
EHeadingType GetHeadingType(const HWP_STRING& sValue)
{
IF_STRING_IN_ENUM(OUTLINE, sValue, EHeadingType);
ELSE_IF_STRING_IN_ENUM(NUMBER, sValue, EHeadingType);
ELSE_IF_STRING_IN_ENUM(BULLET, sValue, EHeadingType);
ELSE_STRING_IN_ENUM(NONE, EHeadingType);
}
EHorizontalAlign GetHorizontalAlign(int nValue)
{
SWITCH(EHorizontalAlign, nValue)
@ -26,6 +34,16 @@ EHorizontalAlign GetHorizontalAlign(int nValue)
}
}
EHorizontalAlign GetHorizontalAlign(const HWP_STRING& sValue)
{
IF_STRING_IN_ENUM(RIGHT, sValue, EHorizontalAlign);
ELSE_IF_STRING_IN_ENUM(CENTER, sValue, EHorizontalAlign);
ELSE_IF_STRING_IN_ENUM(DISTRIBUTE, sValue, EHorizontalAlign);
ELSE_IF_STRING_IN_ENUM(DISTRIBUTE_SPACE, sValue, EHorizontalAlign);
ELSE_IF_STRING_IN_ENUM(JUSTIFY, sValue, EHorizontalAlign);
ELSE_STRING_IN_ENUM(LEFT, EHorizontalAlign);
}
EVerticalAlign GetVerticalAlign(int nValue)
{
SWITCH(EVerticalAlign, nValue)
@ -37,6 +55,14 @@ EVerticalAlign GetVerticalAlign(int nValue)
}
}
EVerticalAlign GetVerticalAlign(const HWP_STRING& sValue)
{
IF_STRING_IN_ENUM(CENTER, sValue, EVerticalAlign);
ELSE_IF_STRING_IN_ENUM(BOTTOM, sValue, EVerticalAlign);
ELSE_IF_STRING_IN_ENUM(BASELINE, sValue, EVerticalAlign);
ELSE_STRING_IN_ENUM(TOP, EVerticalAlign);
}
CHWPRecordParaShape::CHWPRecordParaShape(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion)
: CHWPRecord(nTagNum, nLevel, nSize), m_pParent(&oDocInfo)
{
@ -125,12 +151,12 @@ void CHWPRecordParaShape::RecursiveParaShape(CXMLNode& oNode)
{
if (L"hh:align" == oNode.GetName())
{
m_eAlign = ::HWP::GetHorizontalAlign(oNode.GetAttributeInt(L"horizontal"));
m_eVertAlign = ::HWP::GetVerticalAlign(oNode.GetAttributeInt(L"vertical"));
m_eAlign = ::HWP::GetHorizontalAlign(oNode.GetAttribute(L"horizontal"));
m_eVertAlign = ::HWP::GetVerticalAlign(oNode.GetAttribute(L"vertical"));
}
else if (L"hh:heading" == oNode.GetName())
{
m_eHeadingType = ::HWP::GetHeadingType(oNode.GetAttributeInt(L"type"));
m_eHeadingType = ::HWP::GetHeadingType(oNode.GetAttribute(L"type"));
m_shHeadingIdRef = oNode.GetAttributeInt(L"idRef");
m_chHeadingLevel = (HWP_BYTE)oNode.GetAttributeInt(L"level");
}
@ -262,6 +288,11 @@ int CHWPRecordParaShape::GetMarginNext() const
return m_nMarginNext;
}
int CHWPRecordParaShape::GetIndent() const
{
return m_nIndent;
}
bool CHWPRecordParaShape::KeepWithNext() const
{
return m_bKeepWithNext;

View File

@ -90,6 +90,8 @@ public:
int GetMarginPrev() const;
int GetMarginNext() const;
int GetIndent() const;
bool KeepWithNext() const;
};
}

View File

@ -12,7 +12,7 @@
#include "../Paragraph/CtrlGeneralShape.h"
#include "../Paragraph/CtrlTable.h"
#include "../Paragraph/CtrlEqEdit.h"
#include "../Paragraph/CCtrlField.h"
#include "../Paragraph/CtrlField.h"
#include <regex>
@ -38,7 +38,7 @@ LIST<CCtrl*> CHWPRecordParaText::Parse(int nTagNum, int nLevel, int nSize, CHWPS
}
//TODO:: перейти на обычный проход по символам
std::wregex oRegex(L"([\\u0000-\\u001f]|.{2}[\\u0000-\u0017]{4})"); // [\\u0000\\u000a\\u000d\\u0018-\\u001f]|[\\u0001\\u0002-\\u0009\\u000b-\\u000c\\u000e-\\u0017].{6}[\\u0001\\u0002-\\u0009\\u000b-\\u000c\\u000e-\\u0017]
std::wregex oRegex(L"([\\u0000-\\u001f]|.{2}[\\u0000-\\u0017]{4})"); // [\\u0000\\u000a\\u000d\\u0018-\\u001f]|[\\u0001\\u0002-\\u0009\\u000b-\\u000c\\u000e-\\u0017].{6}[\\u0001\\u0002-\\u0009\\u000b-\\u000c\\u000e-\\u0017]
std::wsregex_iterator itCurrent(sText.begin(), sText.end(), oRegex);
std::wsregex_iterator itEnd = std::wsregex_iterator();
@ -51,7 +51,7 @@ LIST<CCtrl*> CHWPRecordParaText::Parse(int nTagNum, int nLevel, int nSize, CHWPS
#define UPDATE_CURRENT_TEXT() \
do { \
if (!sCurrentText.empty()) \
if (!sCurrentText.empty() && (unsigned int)sCurrentText[0] > 0x001f) \
{ \
arParas.push_back(new CParaText(L"____", sCurrentText, nPrevIndex + 1)); \
sCurrentText.clear(); \
@ -133,7 +133,7 @@ LIST<CCtrl*> CHWPRecordParaText::Parse(int nTagNum, int nLevel, int nSize, CHWPS
//TODO:: Проверить
HWP_STRING sInfo = sText.substr(itCurrent->position(), 2);
std::wregex wrReplaceRegex(L"[\\x00-\\x20]+$");
std::wregex wrReplaceRegex(L"[\\u0000-\\u0017]+$");
sInfo = std::regex_replace(sInfo, wrReplaceRegex, L"");
HWP_STRING sType;
@ -144,7 +144,7 @@ LIST<CCtrl*> CHWPRecordParaText::Parse(int nTagNum, int nLevel, int nSize, CHWPS
sType[2] = (sInfo[1] & 0xFF);
sType[3] = ((sInfo[1] >> 8) & 0xFF);
if (0x00 == sType[3])
if (0x17 >= sType[3])
sType[3] = L' ';
//TODO:: более подробно разобраться в данном моменте
@ -170,8 +170,10 @@ LIST<CCtrl*> CHWPRecordParaText::Parse(int nTagNum, int nLevel, int nSize, CHWPS
arParas.push_back(new CCtrlTable(sType));
else if (L"deqe" == sType)
arParas.push_back(new CCtrlEqEdit(sType));
else if (L"klh%" == sType ||
L"klh " == sType)
else if (L"klh%" == sType || // hyperlink start
L"klh " == sType || // hyperlink end
L"kmb%" == sType || // bookmark start
L"kmb " == sType) // bookmark end
arParas.push_back(new CCtrlField(sType));
}
@ -183,7 +185,7 @@ LIST<CCtrl*> CHWPRecordParaText::Parse(int nTagNum, int nLevel, int nSize, CHWPS
sCurrentText += sText.substr(nPrevIndex);
if (!sCurrentText.empty())
arParas.push_back(new CParaText(L"____", sCurrentText, nPrevIndex));
arParas.push_back(new CParaText(L"____", sCurrentText, nPrevIndex + 1));
oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true));
return arParas;

View File

@ -4,6 +4,12 @@
#include "../OfficeUtils/src/OfficeUtils.h"
#include "../DesktopEditor/common/Directory.h"
// For decrypt
#include "../../Common/3dParty/cryptopp/modes.h"
#include "../../Common/3dParty/cryptopp/aes.h"
#include "../../Common/3dParty/cryptopp/filters.h"
// ----------
#define DEFAULT_BUFFER_SIZE 8096
namespace HWP
@ -67,7 +73,7 @@ bool CHWPFile::Open()
if (!m_oFileHeader.Distributable() && !GetBodyText(m_nVersion))
return false;
if (!m_oFileHeader.Distributable() && !GetViewText(m_nVersion))
if (m_oFileHeader.Distributable() && !GetViewText(m_nVersion))
return false;
return true;
@ -115,35 +121,7 @@ bool CHWPFile::GetComponent(const HWP_STRING& sEntryName, CHWPStream& oBuffer)
{
return m_oOleFile.GetComponent(sEntryName, oBuffer);
}
//TODO:: написанно, что данные методы используются только для отображения в LibbreOffice
// проверить и если нужны будут, то реализовать
VECTOR<CDirectoryEntry*> CHWPFile::GetBinData()
{
return VECTOR<CDirectoryEntry*>();
}
void CHWPFile::SetBinData(const std::vector<CDirectoryEntry*>& arBinData)
{
}
VECTOR<CHWPPargraph*> CHWPFile::GetParas()
{
return VECTOR<CHWPPargraph*>();
}
void CHWPFile::AddParas(const std::vector<CHWPPargraph*>& arParas)
{
}
//------------
void CHWPFile::SaveChildEntries(const HWP_STRING& sBasePath, const HWP_STRING& sStorageName, ECompressed eCompressed)
{
// TODO:: перенести
}
CDirectoryEntry* CHWPFile::FindChildEntry(const HWP_STRING& sBasePath, const CDirectoryEntry& oBaseEntry, const HWP_STRING& sEntryName) const
{
for (CDirectoryEntry* pEntry : m_oOleFile.GetChildEntries(&oBaseEntry))
@ -303,6 +281,24 @@ bool CHWPFile::Unzip(CHWPStream& oInput, CHWPStream& oBuffer)
return DEFLATE_OK == nRes || DEFLATE_STREAM_END == nRes;
}
// Так как на всех ОС необходимо одинаковое поведение,
// то используем свой рандомайзер
class CRandomizer
{
uint32_t m_unSeed;
public:
CRandomizer(uint32_t unSeed)
: m_unSeed(unSeed)
{}
int rand()
{
m_unSeed = m_unSeed * 214013L + 2531011L;
return (m_unSeed >> 16) & 0x7fff;
}
};
bool CHWPFile::Decrypt(CHWPStream& oInput, CHWPStream& oBuffer)
{
int nHeader;
@ -320,8 +316,43 @@ bool CHWPFile::Decrypt(CHWPStream& oInput, CHWPStream& oBuffer)
if (256 != nSize)
return false;
//TODO:: реализовать
return false;
CHWPStream oDocData(256);
oDocData.Copy(oInput, 256);
oInput.Skip(256);
int nSeed;
oDocData.ReadInt(nSeed);
oDocData.Skip(-4);
CRandomizer oRandomizer(nSeed);
unsigned char chKey;
for (unsigned int unIndex = 0, unCount = 0; unIndex < 256; ++unIndex)
{
if (0 == unCount)
{
chKey = oRandomizer.rand() & 0xFF;
unCount = (oRandomizer.rand() & 0xF) + 1;
}
if (unIndex >= 4)
*(oDocData.GetCurPtr() + unIndex) = oDocData[unIndex] ^ chKey;
--unCount;
}
int nHashOffset = (nSeed & 0x0f) + 4;
oBuffer.Expand(oInput.SizeToEnd());
using namespace CryptoPP;
ECB_Mode<AES>::Decryption oDecryptor;
oDecryptor.SetKey((byte*)(oDocData.GetCurPtr() + nHashOffset), 16);
ArraySource((byte*)oInput.GetCurPtr(), oInput.SizeToEnd(), true, new StreamTransformationFilter(oDecryptor, new ArraySink( (byte*)oBuffer.GetCurPtr(), oBuffer.GetSize()), StreamTransformationFilter::NO_PADDING));
return true;
}
bool CHWPFile::GetBodyText(int nVersion)

View File

@ -32,13 +32,8 @@ public:
const CHWPDocInfo* GetDocInfo() const;
bool GetDocInfo(int nVersion);
bool GetComponent(const HWP_STRING& sEntryName, CHWPStream& oBuffer);
VECTOR<CDirectoryEntry*> GetBinData();
void SetBinData(const VECTOR<CDirectoryEntry*>& arBinData);
VECTOR<CHWPPargraph*> GetParas();
void AddParas(const VECTOR<CHWPPargraph*>& arParas);
bool GetChildStream(const HWP_STRING& sEntryName, ECompressed eCompressed, CHWPStream& oBuffer);
private:
void SaveChildEntries(const HWP_STRING& sBasePath, const HWP_STRING& sStorageName, ECompressed eCompressed);
CDirectoryEntry* FindChildEntry(const HWP_STRING& sBasePath, const CDirectoryEntry& oBaseEntry, const HWP_STRING& sEntryName) const;
HWP_STRING SaveChildEntry(const HWP_STRING& sRootPath, const HWP_STRING& sEntryName, ECompressed eCompressed);

View File

@ -529,8 +529,6 @@ int CHWPSection::ParseCtrlRecurse(CCtrl* pCurrCtrl, int nRunLevel, CHWPStream& o
ParseRecurse(pNewPara, nLevel, oBuffer, 0, nVersion);
}
else if (ECtrlObjectType::Shape == pCtrl->GetCtrlType())
// else if (nullptr != dynamic_cast<CCtrlShapeRect*>(pCtrl) ||
// nullptr != dynamic_cast<CCtrlGeneralShape*>(pCtrl))
{
CCtrlCommon* pCtrlCommon = (CCtrlCommon*)pCtrl;
oBuffer.Skip(-6);
@ -573,7 +571,6 @@ int CHWPSection::ParseCtrlRecurse(CCtrl* pCurrCtrl, int nRunLevel, CHWPStream& o
case HWPTAG_SHAPE_COMPONENT_TEXTART:
case HWPTAG_SHAPE_COMPONENT_UNKNOWN:
{
// if (nullptr != dynamic_cast<CCtrlGeneralShape*>(pCtrl))
if (ECtrlObjectType::Shape == pCtrl->GetCtrlType())
ParseCtrlRecurse((CCtrlGeneralShape*)pCtrl, nLevel, oBuffer, 0, nVersion);
else
@ -856,6 +853,8 @@ int CHWPSection::ParseCtrlRecurse(CCtrl* pCurrCtrl, int nRunLevel, CHWPStream& o
}
}
oBuffer.RemoveLastSavedPos();
return 0;
}
@ -895,6 +894,7 @@ int CHWPSection::ParseContainerRecurse(CCtrlContainer* pContainer, int nRunLevel
while (oBuffer.CanRead())
{
oBuffer.ReadInt(nHeader);
oBuffer.Skip(-4);
nTagNum = nHeader & 0x3FF; // 10 bits (0 - 9 bit)
nLevel = (nHeader & 0xFFC00) >> 10; // 10 bits (10-19 bit)
nSize = (nHeader & 0xFFF00000) >> 20; // 12 bits (20-31 bit)
@ -979,7 +979,6 @@ int CHWPSection::ParseContainerRecurse(CCtrlContainer* pContainer, int nRunLevel
{
CCtrlGeneralShape* pCtrl = pContainer->GetLastShape();
int nSubParaCount = CHWPRecordListHeader::GetCount(nTagNum, nLevel, nSize, oBuffer, 0, nVersion);
oBuffer.Skip(6);
if (EShapeType::Rect == pCtrl->GetShapeType() || EShapeType::Polygon == pCtrl->GetShapeType())
{

View File

@ -36,6 +36,11 @@ void CHWPStream::Clear()
m_arSavedPositions.pop();
}
void CHWPStream::Copy(CHWPStream& oStream, unsigned long ulSize)
{
memcpy(m_pCur, oStream.GetCurPtr(), (std::min)(SizeToEnd(), (unsigned long)(std::min)(ulSize, oStream.SizeToEnd())));
}
void CHWPStream::SetStream(HWP_BYTE* pBuffer, unsigned long ulSize, bool bExternalBuffer)
{
m_pBegin = pBuffer;

View File

@ -28,6 +28,7 @@ public:
~CHWPStream();
void Clear();
void Copy(CHWPStream& oStream, unsigned long ulSize);
void SetStream(HWP_BYTE* pBuffer, unsigned long ulSize, bool bExternalBuffer = true);

View File

@ -1,78 +0,0 @@
#include "CCtrlField.h"
namespace HWP
{
CCtrlField::CCtrlField(const HWP_STRING& sCtrlID)
: CCtrl(sCtrlID), m_eType(EFieldType::Unknown)
{
if (L"klh%" == sCtrlID)
m_eType = EFieldType::Hyperlink;
else if (L"klh " == sCtrlID)
m_eType = EFieldType::HyperlinkClosing;
}
CCtrlField::CCtrlField(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion)
: CCtrl(sCtrlID), m_eType(EFieldType::Unknown)
{
if (L"klh%" == sCtrlID)
m_eType = EFieldType::Hyperlink;
else if (L"klh " == sCtrlID)
m_eType = EFieldType::HyperlinkClosing;
oBuffer.ReadInt(m_nProperty);
oBuffer.ReadByte(m_chEtcProperty);
oBuffer.ReadString(m_sCommand, EStringCharacter::UTF16);
oBuffer.ReadInt(m_nInstanceID);
}
CCtrlField::CCtrlField(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion)
: CCtrl(sCtrlID), m_eType(EFieldType::Unknown)
{
if (L"hp:fieldBegin" == oNode.GetName())
{
HWP_STRING sType = oNode.GetAttribute(L"type");
if (sType == L"HYPERLINK")
m_eType = EFieldType::Hyperlink;
m_nInstanceID = oNode.GetAttributeInt(L"fieldid");
for (CXMLNode& oChild : oNode.GetChild(L"hp:parameters").GetChilds(L"hp:stringParam"))
{
if (L"Command" == oChild.GetAttribute(L"name"))
m_sCommand = oChild.GetText();
}
for (CXMLNode& oChild : oNode.GetChild(L"hp:parameters").GetChilds(L"hp:integerParam"))
{
if (L"Prop" == oChild.GetAttribute(L"name"))
m_chEtcProperty = stoi(oChild.GetText());
}
}
else if (L"hp:fieldEnd" == oNode.GetName())
{
m_nInstanceID = oNode.GetAttributeInt(L"fieldid");
}
}
ECtrlObjectType CCtrlField::GetCtrlType() const
{
return ECtrlObjectType::Field;
}
int CCtrlField::GetInstanceID() const
{
return m_nInstanceID;
}
EFieldType CCtrlField::GetType() const
{
return m_eType;
}
HWP_STRING CCtrlField::GetCommand() const
{
return m_sCommand;
}
}

View File

@ -1,5 +1,6 @@
#include "CharShape.h"
#include "CtrlCharacter.h"
#include "CtrlAutoNumber.h"
#include "ParaText.h"
#include <algorithm>

View File

@ -6,7 +6,7 @@
#include "CtrlNewNumber.h"
#include "CtrlNote.h"
#include "CtrlPageNumPos.h"
#include "CCtrlField.h"
#include "CtrlField.h"
namespace HWP
{

View File

@ -0,0 +1,113 @@
#include "CtrlField.h"
#include <iostream>
#include <ostream>
namespace HWP
{
CCtrlField::CCtrlField(const HWP_STRING& sCtrlID)
: CCtrl(sCtrlID), m_eType(EFieldType::Unknown)
{
UpdateType(sCtrlID);
}
CCtrlField::CCtrlField(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion)
: CCtrl(sCtrlID), m_eType(EFieldType::Unknown)
{
UpdateType(sCtrlID);
oBuffer.ReadInt(m_nProperty);
oBuffer.ReadByte(m_chEtcProperty);
oBuffer.ReadString(m_sCommand, EStringCharacter::UTF16);
oBuffer.ReadInt(m_nInstanceID);
}
void CCtrlField::UpdateType(const HWP_STRING& sCtrlID)
{
if (L"klh%" == sCtrlID)
m_eType = EFieldType::Hyperlink;
else if (L"klh " == sCtrlID)
m_eType = EFieldType::HyperlinkClosing;
else if (L"kmb%" == sCtrlID)
m_eType = EFieldType::Bookmark;
else if (L"kmb " == sCtrlID)
m_eType = EFieldType::BookmarkClosing;
}
CCtrlField::CCtrlField(const HWP_STRING& sCtrlID, CXMLNode& oNode, int nVersion)
: CCtrl(sCtrlID), m_eType(EFieldType::Unknown)
{
if (L"hp:fieldBegin" == oNode.GetName())
{
HWP_STRING sType = oNode.GetAttribute(L"type");
if (L"HYPERLINK" == sType)
m_eType = EFieldType::Hyperlink;
else if (L"BOOKMARK" == sType)
m_eType = EFieldType::Bookmark;
m_nInstanceID = oNode.GetAttributeInt(L"fieldid");
HWP_STRING sName = oNode.GetAttribute(L"name");
if (!sName.empty() && EFieldType::Bookmark == m_eType)
AddStringParam(L"bookmarkname", sName);
for (CXMLNode& oChild : oNode.GetChild(L"hp:parameters").GetChilds())
{
if (L"hp:stringParam" == oChild.GetName())
AddStringParam(oChild.GetAttribute(L"name"), oChild.GetText());
else if (L"hp:integerParam" == oChild.GetName())
AddIntegerParam(oChild.GetAttribute(L"name"), std::stoi(oChild.GetText()));
}
}
else if (L"hp:fieldEnd" == oNode.GetName())
{
m_nInstanceID = oNode.GetAttributeInt(L"fieldid");
}
}
ECtrlObjectType CCtrlField::GetCtrlType() const
{
return ECtrlObjectType::Field;
}
void CCtrlField::AddStringParam(const HWP_STRING& wsName, const HWP_STRING& wsValue)
{
m_mStringParams.insert(std::make_pair(wsName, wsValue));
}
void CCtrlField::AddIntegerParam(const HWP_STRING& wsName, int nValue)
{
m_mIntegerParam.insert(std::make_pair(wsName, nValue));
}
HWP_STRING CCtrlField::GetStringParam(const HWP_STRING& wsName) const
{
std::map<HWP_STRING, HWP_STRING>::const_iterator itFound = m_mStringParams.find(wsName);
return ((m_mStringParams.cend() != itFound) ? itFound->second : HWP_STRING());
}
int CCtrlField::GetIntegerParam(const HWP_STRING& wsName) const
{
std::map<HWP_STRING, int>::const_iterator itFound = m_mIntegerParam.find(wsName);
return ((m_mIntegerParam.cend() != itFound) ? itFound->second : 0);
}
int CCtrlField::GetInstanceID() const
{
return m_nInstanceID;
}
EFieldType CCtrlField::GetType() const
{
return m_eType;
}
HWP_STRING CCtrlField::GetCommand() const
{
return m_sCommand;
}
}

View File

@ -1,5 +1,5 @@
#ifndef CCTRLFIELD_H
#define CCTRLFIELD_H
#ifndef CTRLFIELD_H
#define CTRLFIELD_H
#include "Ctrl.h"
#include "../HWPStream.h"
@ -10,6 +10,8 @@ enum class EFieldType
{
Hyperlink,
HyperlinkClosing,
Bookmark,
BookmarkClosing,
Unknown
};
@ -22,6 +24,11 @@ class CCtrlField : public CCtrl
int m_nInstanceID;
EFieldType m_eType;
std::map<HWP_STRING, HWP_STRING> m_mStringParams;
std::map<HWP_STRING, int> m_mIntegerParam;
void UpdateType(const HWP_STRING& sCtrlID);
public:
CCtrlField(const HWP_STRING& sCtrlID);
CCtrlField(const HWP_STRING& sCtrlID, int nSize, CHWPStream& oBuffer, int nOff, int nVersion);
@ -29,10 +36,16 @@ public:
ECtrlObjectType GetCtrlType() const override;
void AddStringParam(const HWP_STRING& wsName, const HWP_STRING& wsValue);
void AddIntegerParam(const HWP_STRING& wsName, int nValue);
HWP_STRING GetStringParam(const HWP_STRING& wsName) const;
int GetIntegerParam(const HWP_STRING& wsName) const;
int GetInstanceID() const;
EFieldType GetType() const;
HWP_STRING GetCommand() const;
};
}
#endif // CCTRLFIELD_H
#endif // CTRLFIELD_H

View File

@ -6,8 +6,8 @@ int main()
{
CHWPFile oFile;
if (oFile.OpenHWPX(L"C:/ONLYOFFICE/Files/hwpx/test_multiple_elements.hwpx"))
// if (oFile.OpenHWP(L"C:/ONLYOFFICE/Files/hwp/Examples/test_rect.hwp"))
// if (oFile.OpenHWPX(L"YOUR_PATH"))
if (oFile.OpenHWP(L"YOUR_PATH"))
{
std::cout << "Successful" << std::endl;
}
@ -23,4 +23,5 @@ int main()
NSDirectory::CreateDirectory(wsTempDir);
oFile.SetTempDirectory(wsTempDir);
oFile.ConvertToOOXML(L"result.docx");
oFile.Close();
}

View File

@ -60,6 +60,8 @@ BiffStructurePtr PtgExtraArray::clone()
void PtgExtraArray::load(CFRecord& record)
{
auto tempcols = 0;
auto temprows = 0;
if (record.getGlobalWorkbookInfo()->Version < 0x0800)
{
DColunByteU cols_xls;
@ -67,17 +69,41 @@ void PtgExtraArray::load(CFRecord& record)
record >> cols_xls >> rows_xls;
cols = cols_xls;
rows = rows_xls;
tempcols = cols_xls+1;
temprows = rows_xls+1;
}
else
{
record >> cols >> rows;
tempcols = cols;
temprows = rows;
}
for(int i = 0; i < (cols + 1) * (rows + 1); ++i)
for(int i = 0; i < (tempcols) * (temprows); ++i)
{
if (record.getRdPtr() >= record.getDataSize())
break;
unsigned char rec_type;
record >> rec_type;
if (record.getGlobalWorkbookInfo()->Version >= 0x0800)
{
switch(rec_type)
{
case 0:
rec_type = SerAr::SerType::typeSerNum;
break;
case 1:
rec_type = SerAr::SerType::typeSerStr;
break;
case 2:
rec_type = SerAr::SerType::typeSerBool;
case 4:
rec_type = SerAr::SerType::typeSerErr;
break;
default:
rec_type = SerAr::SerType::typeSerNil;
break;
}
}
SerArPtr ser(SerAr::createSerAr(rec_type));
if(ser.get())
{
@ -112,7 +138,7 @@ void PtgExtraArray::save(CFRecord& record)
const std::wstring PtgExtraArray::toString() const
{
std::wstring ret_val;
unsigned char col_cnt = cols + 1;
unsigned char col_cnt = cols + 1;
if (array_.empty()) return L"";
@ -126,7 +152,7 @@ const std::wstring PtgExtraArray::toString() const
else
{
ret_val += L';';
col_cnt = cols + 1;
col_cnt = cols + 1;
}
}
ret_val += array_.back()->toString();

View File

@ -94,7 +94,7 @@ void SerStr::save(CFRecord& record)
const std::wstring SerStr::toString() const
{
return L"\"" + boost::algorithm::replace_all_copy(std::wstring(string_), L"\"", L"\"\"") + L"\"";
return L"\"" + boost::algorithm::replace_all_copy(std::wstring(rgch), L"\"", L"\"\"") + L"\"";
}

View File

@ -1,4 +1,4 @@
/*
/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
@ -191,22 +191,24 @@ namespace PPTX
pWriter->StartNode(namespace_ + L":cNvCxnSpPr");
pWriter->EndAttributes();
pWriter->StartNode(_T("a:cxnSpLocks"));
pWriter->StartAttributes();
pWriter->WriteAttribute(_T("noAdjustHandles"), noAdjustHandles);
pWriter->WriteAttribute(_T("noChangeArrowheads"), noChangeArrowheads);
pWriter->WriteAttribute(_T("noChangeAspect"), noChangeAspect);
pWriter->WriteAttribute(_T("noChangeShapeType"), noChangeShapeType);
pWriter->WriteAttribute(_T("noEditPoints"), noEditPoints);
pWriter->WriteAttribute(_T("noGrp"), noGrp);
pWriter->WriteAttribute(_T("noMove"), noMove);
pWriter->WriteAttribute(_T("noResize"), noResize);
pWriter->WriteAttribute(_T("noRot"), noRot);
pWriter->WriteAttribute(_T("noSelect"), noSelect);
pWriter->EndAttributes();
pWriter->EndNode(_T("a:cxnSpLocks"));
if(noAdjustHandles.IsInit() || noChangeArrowheads.IsInit() || noChangeAspect.IsInit() || noChangeShapeType.IsInit() || noEditPoints.IsInit()
|| noGrp.IsInit() || noMove.IsInit() || noResize.IsInit() || noRot.IsInit() || noRot.IsInit())
{
pWriter->StartNode(_T("a:cxnSpLocks"));
pWriter->StartAttributes();
pWriter->WriteAttribute(_T("noAdjustHandles"), noAdjustHandles);
pWriter->WriteAttribute(_T("noChangeArrowheads"), noChangeArrowheads);
pWriter->WriteAttribute(_T("noChangeAspect"), noChangeAspect);
pWriter->WriteAttribute(_T("noChangeShapeType"), noChangeShapeType);
pWriter->WriteAttribute(_T("noEditPoints"), noEditPoints);
pWriter->WriteAttribute(_T("noGrp"), noGrp);
pWriter->WriteAttribute(_T("noMove"), noMove);
pWriter->WriteAttribute(_T("noResize"), noResize);
pWriter->WriteAttribute(_T("noRot"), noRot);
pWriter->WriteAttribute(_T("noSelect"), noSelect);
pWriter->EndAttributes();
pWriter->EndNode(_T("a:cxnSpLocks"));
}
if (stCxn_id.is_init() || stCxn_idx.is_init())
{
pWriter->StartNode(_T("a:stCxn"));

View File

@ -1,4 +1,4 @@
/*
/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
@ -113,7 +113,7 @@ namespace PPTX
cNvCxnSpPr.toXmlWriter(pWriter);
if (pWriter->m_lDocType != XMLWRITER_DOC_TYPE_GRAPHICS &&
pWriter->m_lDocType != XMLWRITER_DOC_TYPE_CHART_DRAWING)
pWriter->m_lDocType != XMLWRITER_DOC_TYPE_CHART_DRAWING && pWriter->m_lDocType != XMLWRITER_DOC_TYPE_XLSX)
{
nvPr.toXmlWriter2(namespace_, pWriter);
}

View File

@ -1,4 +1,4 @@
/*
/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
@ -2682,10 +2682,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\"
else if(ptr->sxaxis.bRw)
m_oAxis = SimpleTypes::Spreadsheet::EPivotAxisType::axisRow;
else if(ptr->sxaxis.bData)
{
m_oAxis = SimpleTypes::Spreadsheet::EPivotAxisType::axisValues;
if(ptr->sxaxis.bData)
m_oDataField = ptr->sxaxis.bData;
}
if(!ptr->fCompact)
m_oCompact = ptr->fCompact;

View File

@ -1286,7 +1286,7 @@ namespace StarMath
StValuePr stBarPr;
if(pBarPr == nullptr)
return stBarPr;
if(pBarPr->m_oPos.IsInit() && pBarPr->m_oPos->m_val.IsInit())
if(pBarPr->m_oPos.GetPointer() != nullptr && pBarPr->m_oPos->m_val.GetPointer() != nullptr)
stBarPr.m_enPos = pBarPr->m_oPos->m_val->GetValue();
stStyle = ConversionCtrlPr(pBarPr->m_oCtrlPr.GetPointer());
return stBarPr;
@ -2042,31 +2042,36 @@ namespace StarMath
}
void CRelationsAndOperationsOnSets::Conversion(XmlUtils::CXmlWriter *pXmlWrite, std::wstring &wsAnnotation)
{
pXmlWrite->WriteNodeBegin(L"mrow",false);
if(m_pLeftArg!= nullptr)
{
if(GetAttribute() != nullptr)
{
GetAttribute()->AddRef();
m_pLeftArg->SetAttribute(GetAttribute());
}
m_pLeftArg->Conversion(pXmlWrite,wsAnnotation);
}
if(m_wsAnnotationSymbol == L"\u0026lt;" || m_wsAnnotationSymbol == L"\u0026gt;")
COOXml2Odf::RecordingMoNode(m_wsAnnotationSymbol,pXmlWrite);
if(m_pLeftArg == nullptr && m_pRightArg == nullptr)
COOXml2Odf::MTextRecording(pXmlWrite,wsAnnotation,m_wsSymbol);
else
COOXml2Odf::RecordingMoNode(m_wsSymbol,pXmlWrite);
wsAnnotation += m_wsAnnotationSymbol + L" ";
if(m_pRightArg != nullptr)
{
if(GetAttribute() != nullptr)
pXmlWrite->WriteNodeBegin(L"mrow",false);
if(m_pLeftArg!= nullptr)
{
GetAttribute()->AddRef();
m_pRightArg->SetAttribute(GetAttribute());
if(GetAttribute() != nullptr)
{
GetAttribute()->AddRef();
m_pLeftArg->SetAttribute(GetAttribute());
}
m_pLeftArg->Conversion(pXmlWrite,wsAnnotation);
}
m_pRightArg->Conversion(pXmlWrite,wsAnnotation);
if(m_wsAnnotationSymbol == L"\u0026lt;" || m_wsAnnotationSymbol == L"\u0026gt;")
COOXml2Odf::RecordingMoNode(m_wsAnnotationSymbol,pXmlWrite);
else
COOXml2Odf::RecordingMoNode(m_wsSymbol,pXmlWrite);
wsAnnotation += m_wsAnnotationSymbol + L" ";
if(m_pRightArg != nullptr)
{
if(GetAttribute() != nullptr)
{
GetAttribute()->AddRef();
m_pRightArg->SetAttribute(GetAttribute());
}
m_pRightArg->Conversion(pXmlWrite,wsAnnotation);
}
pXmlWrite->WriteNodeEnd(L"mrow",false,false);
}
pXmlWrite->WriteNodeEnd(L"mrow",false,false);
}
void CRelationsAndOperationsOnSets::SetLeftArg(COneElement *pElement)
{

View File

@ -3240,12 +3240,6 @@ namespace StarMath
m_enGlobalType = TypeElement::Operation;
return;
}
m_enUnderType = CElementString::GetWord(m_wsLowerCaseToken);
if(m_enUnderType != TypeElement::undefine)
{
m_enGlobalType = TypeElement::String;
return;
}
if(m_enUnderType == TypeElement::undefine && !m_wsLowerCaseToken.empty())
{
m_enGlobalType = TypeElement::String;
@ -3332,10 +3326,8 @@ namespace StarMath
m_itStart++;
break;
}
else if(!m_wsElement.empty() && (CheckTokenForGetElement(*m_itStart)||(m_wsElement.back() == L'<' && (L'-' != *m_itStart && L'?' != *m_itStart && L'=' != *m_itStart && L'<' != *m_itStart && L'>' != *m_itStart)) || *m_itStart == L'(' || L')' == *m_itStart || L'%' == *m_itStart||(L'#' == *m_itStart && L'#' != m_wsElement.back()) ||(L'-' == *m_itStart && L'+' != m_wsElement.back() && L'<' != m_wsElement.back()) || (L'+' == *m_itStart && L'-' != m_wsElement.back()) || (L'.' == *m_itStart && !iswdigit(m_wsElement.back())) || (iswdigit(*m_itStart) && !iswdigit(m_wsElement.back()) && L'.' != m_wsElement.back()) || (CheckIsalhpaForGetElement(*m_itStart,m_wsElement.back())) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *m_itStart || (L'>' == *m_itStart && L'-' !=m_wsElement.back() && L'?' != m_wsElement.back()) || L'=' == *m_itStart))))
{
else if(!m_wsElement.empty() && (CheckTokenForGetElement(*m_itStart) ||(m_wsElement.back() == L'<' && (L'-' != *m_itStart && L'?' != *m_itStart && L'=' != *m_itStart && L'<' != *m_itStart && L'>' != *m_itStart)) || *m_itStart == L'(' || L')' == *m_itStart || L'(' == m_wsElement.back() || L')' == m_wsElement.back() || L'%' == *m_itStart||(L'#' == *m_itStart && L'#' != m_wsElement.back()) ||( L'+' == m_wsElement.back() && L'-' != *m_itStart ) || (L'-' == *m_itStart && L'+' != m_wsElement.back()) || (L'-' == m_wsElement.back() && L'+' != *m_itStart && L'>' != *m_itStart) || (L'+' == *m_itStart && L'-' != m_wsElement.back()) || (L'.' == *m_itStart && !iswdigit(m_wsElement.back())) || (iswdigit(*m_itStart) && !iswdigit(m_wsElement.back()) && L'.' != m_wsElement.back())|| (iswdigit(m_wsElement.back()) && !iswdigit(*m_itStart)) || ((m_wsElement.back() != L'<' && m_wsElement.back() != L'>') && (L'<' == *m_itStart || (L'>' == *m_itStart && L'-' !=m_wsElement.back() && L'?' != m_wsElement.back()) || L'=' == *m_itStart))))
return m_wsElement;
}
else if((( CheckTokenForGetElement(*m_itStart) || L'=' == *m_itStart) && m_wsElement.empty()) || (!m_wsElement.empty() && ((L'#' == m_wsElement.back() && L'#' == *m_itStart) || (L'-' == *m_itStart && L'+' == m_wsElement.back()) || ((L'+' == *m_itStart || L'>' == *m_itStart) && L'-' == m_wsElement.back()) || (m_wsElement.back() == L'<' && (L'=' == *m_itStart || L'<' == *m_itStart || L'>' == *m_itStart || L'-' == *m_itStart)) ||(L'?' == m_wsElement.back() && L'>' == *m_itStart) || (m_wsElement.back() == L'>' && (L'>' == *m_itStart || L'=' == *m_itStart )) ) ) )
{
m_wsElement.push_back(*m_itStart);

View File

@ -135,6 +135,7 @@ namespace oox {
{
type = -1;
opacity = boost::none;
image_opacity = boost::none;
gradient.reset();
hatch.reset();

View File

@ -259,6 +259,7 @@ void object_odf_context::docx_convert(oox::docx_conversion_context & Context)
}
else if (object_type_ == 3 && office_math_)
{
bool in_draw_frame = Context.get_drawing_state_content();
oox::StreamsManPtr prev = Context.get_stream_man();
std::wstringstream temp_stream(Context.get_drawing_context().get_text_stream_frame());
@ -268,7 +269,7 @@ void object_odf_context::docx_convert(oox::docx_conversion_context & Context)
Context.get_math_context().base_font_size_ = baseFontHeight_;
Context.get_math_context().base_font_name_ = baseFontName_;
Context.get_math_context().base_alignment_ = baseAlignment_;
Context.get_math_context().base_alignment_ = in_draw_frame ? 0 : baseAlignment_;
Context.get_math_context().base_font_italic_ = baseFontItalic_;
Context.get_math_context().base_font_bold_ = baseFontBold_;

View File

@ -305,7 +305,12 @@ void Compute_GradientFill(draw_gradient* gradient_style, oox::oox_gradient_fill_
fill->angle = -90 - gradient_style->draw_angle_->get_value();
if (fill->angle < 0)
fill->angle += 360;
{
int fullRotations = std::ceil(-fill->angle / 360.0f);
fill->angle += 360 * fullRotations;
}
for (size_t i = 0; i < gradient_style->content_.size(); ++i)
{

View File

@ -1731,7 +1731,12 @@ void draw_object::docx_convert(oox::docx_conversion_context & Context)
objectBuild.userShapes = drawingName;
}
bool state = Context.get_drawing_state_content();
Context.set_drawing_state_content(!drawing->isInline || drawing->inFrame);
objectBuild.docx_convert(Context);
Context.set_drawing_state_content(state);
}
//------------------------------------------------------------------------------------------------------------
if (!frame || !drawing)
@ -1766,8 +1771,11 @@ void draw_object::docx_convert(oox::docx_conversion_context & Context)
{
drawing->type = oox::typeShape;
drawing->additional.push_back(_property(L"fit-to-size", true));
drawing->additional.push_back(_property(L"text-content", std::wstring(L"<w:p>") + content + std::wstring(L"</w:p>")));
//drawing->additional.push_back(_property(L"auto-grow-width", true));
drawing->additional.push_back(_property(L"auto-grow-height", true));
//drawing->additional.push_back(_property(L"fit-to-size", true));
drawing->additional.push_back(_property(L"text-content", std::wstring(L"<w:p>") + content + std::wstring(L"</w:p>")));
}
else
{//in text

View File

@ -101,14 +101,23 @@ void draw_frame::pptx_convert(oox::pptx_conversion_context & Context)
const _CP_OPT(length) svg_heightVal = common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_height_;
double width_pt = 0, height_pt = 0;
if (svg_widthVal && svg_heightVal)
{
const double width_pt = svg_widthVal.get_value_or(length(0)).get_value_unit(length::pt);
const double height_pt = svg_heightVal.get_value_or(length(0)).get_value_unit(length::pt);
double width_pt = svg_widthVal.get_value_or(length(0)).get_value_unit(length::pt);
double height_pt = svg_heightVal.get_value_or(length(0)).get_value_unit(length::pt);
double x_pt = common_draw_attlists_.position_.svg_x_.get_value_or(length(0)).get_value_unit(length::pt);
double y_pt = common_draw_attlists_.position_.svg_y_.get_value_or(length(0)).get_value_unit(length::pt);
if (width_pt <= 0)
{
width_pt = 1;
Context.get_slide_context().set_property(_property(L"auto-grow-width", true));
}
if (height_pt <= 0)
{
height_pt = 1;
Context.get_slide_context().set_property(_property(L"auto-grow-height", true));
}
if (x_pt < 0) x_pt = 0;
if (y_pt < 0) y_pt = 0;

View File

@ -85,7 +85,7 @@ void table_table_row::pptx_convert(oox::pptx_conversion_context & Context)
{
int height = 0;
const style_instance * inst = Context.root()->odf_context().styleContainer().style_by_name( styleName , style_family::TableRow,false);
const style_instance * inst = Context.root()->odf_context().styleContainer().style_by_name( styleName , style_family::TableRow,true);
if ((inst) && (inst->content()) && (inst->content()->get_style_table_row_properties()))
{
@ -244,7 +244,7 @@ void table_table::pptx_convert(oox::pptx_conversion_context & Context)
_Wostream << L" firstCol=\"1\"";
_Wostream << ">";
style_instance * inst = Context.root()->odf_context().styleContainer().style_by_name( tableStyleName , style_family::Table,false);
style_instance * inst = Context.root()->odf_context().styleContainer().style_by_name( tableStyleName , style_family::Table,true);
if ((inst) && (inst->content()))
{
@ -352,7 +352,8 @@ void table_table_column::pptx_convert(oox::pptx_conversion_context & Context)
{
const std::wstring colStyleName = attlist_.table_style_name_.get();
style_instance * inst = Context.root()->odf_context().styleContainer().style_by_name( colStyleName , style_family::TableColumn,false );
style_instance * inst = Context.root()->odf_context().styleContainer().style_by_name(colStyleName, style_family::TableColumn, true);
if ((inst) && (inst->content()))
{
//column properies
@ -395,20 +396,20 @@ void table_table_cell::pptx_convert(oox::pptx_conversion_context & Context)
style_name = Context.get_table_context().get_default_cell_style();
if (!style_name.empty())
{
style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false);
style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, true);
if (style_inst) style_instances.push_back(style_inst);
}
style_name = Context.get_table_context().get_default_cell_style_col(Context.get_table_context().current_column());
if (!style_name.empty())
{
style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false);
style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, true);
if (style_inst)style_instances.push_back(style_inst);
}
style_name = Context.get_table_context().get_template_row_style_name();
if (!style_name.empty() && !Context.get_table_context().template_is_first_column() && !Context.get_table_context().template_is_last_column())
{
style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false);
style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, true);
if (style_inst)style_instances.push_back(style_inst);
}
@ -417,7 +418,7 @@ void table_table_cell::pptx_convert(oox::pptx_conversion_context & Context)
style_name = Context.get_table_context().get_default_cell_style_row();
if (!style_name.empty())
{
style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false);
style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, true);
if (style_inst) style_instances.push_back(style_inst);
}
}
@ -425,7 +426,7 @@ void table_table_cell::pptx_convert(oox::pptx_conversion_context & Context)
style_name = attlist_.table_style_name_.get_value_or(L"");
if (!style_name.empty())
{
style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, false);
style_inst = Context.root()->odf_context().styleContainer().style_by_name(style_name, style_family::TableCell, true);
if (style_inst) style_instances.push_back(style_inst);
}

View File

@ -1080,15 +1080,6 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID)
if (!pPDFDocument || !pDoc)
return false;
PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex);
if (!pEditPage)
{
pEditPage = pDoc->GetCurPage();
EditPage(nPageIndex);
pDoc->SetCurPage(pEditPage);
pWriter->EditPage(pEditPage);
}
XRef* xref = pPDFDocument->getXRef();
std::pair<int, int> pPageRef = pDoc->GetPageRef(nPageIndex);
if (!xref || pPageRef.first == 0)
@ -1118,6 +1109,15 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID)
return false;
}
PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex);
if (!pEditPage)
{
pEditPage = pDoc->GetCurPage();
EditPage(nPageIndex);
pDoc->SetCurPage(pEditPage);
pWriter->EditPage(pEditPage);
}
// Воспроизведение словаря аннотации из reader для writer
PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, oAnnotRef.getRefNum());
if (!pXref)
@ -1505,10 +1505,13 @@ bool CPdfEditor::IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bIt
std::map<std::wstring, std::wstring>::iterator it = m_mFonts.find(wsFontName);
if (it != m_mFonts.end())
wsFontPath = it->second;
std::map<std::wstring, std::wstring> mFonts = pReader->GetFonts();
std::map<std::wstring, std::wstring>::iterator it2 = mFonts.find(wsFontName);
if (it2 != mFonts.end())
wsFontPath = it2->second;
if (wsFontPath.empty())
{
std::map<std::wstring, std::wstring> mFonts = pReader->GetFonts();
std::map<std::wstring, std::wstring>::iterator it2 = mFonts.find(wsFontName);
if (it2 != mFonts.end())
wsFontPath = it2->second;
}
if (wsFontPath.empty())
return false;
if (wsFontName == L"Helvetica")

View File

@ -42,6 +42,7 @@
#include "OnlineOfficeBinToPdf.h"
#include "SrcWriter/Document.h"
#include "Resources/BaseFonts.h"
#else
class CPdfEditor
@ -329,9 +330,7 @@ OfficeDrawingFileType CPdfFile::GetType()
}
std::wstring CPdfFile::GetTempDirectory()
{
if (!m_pInternal->pReader)
return std::wstring();
return m_pInternal->pReader->GetTempDirectory();
return m_pInternal->wsTempFolder;
}
void CPdfFile::SetTempDirectory(const std::wstring& wsPath)
{
@ -910,6 +909,28 @@ HRESULT CPdfFile::put_FontName(const std::wstring& wsName)
lStyle |= 2;
put_FontStyle(lStyle);
}
NSFonts::IFontsMemoryStorage* pMemoryStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage();
if (wsFontPath == sSub && (!pMemoryStorage || !pMemoryStorage->Get(wsFontPath)))
{
const BYTE* pData14 = NULL;
unsigned int nSize14 = 0;
std::wstring wsTempFileName = m_pInternal->wsTempFolder + L"/" + wsFontPath + L".base";
if (NSFile::CFileBinary::Exists(wsTempFileName))
wsFontPath = wsTempFileName;
else if (PdfReader::GetBaseFont(sSub, pData14, nSize14))
{
NSFile::CFileBinary oFile;
if (oFile.CreateFileW(wsTempFileName))
{
oFile.WriteFile((BYTE*)pData14, nSize14);
wsFontPath = wsTempFileName;
}
else if (!wsTempFileName.empty())
NSFile::CFileBinary::Remove(wsTempFileName);
oFile.CloseFile();
}
}
}
else
wsFont = sSub;

View File

@ -142,12 +142,6 @@ public:
void OpenDir(std::wstring sDir)
{
m_sInputFolder = sDir;
if (m_bDiffOnly)
{
m_files = NSDirectory::GetDirectories(m_sInputFolder);
m_nCount = (int)m_files.size();
return;
}
std::vector<std::wstring> arFiles = NSDirectory::GetFiles(sDir, true);
for (std::vector<std::wstring>::iterator iter = arFiles.begin(); iter != arFiles.end(); iter++)
@ -298,7 +292,6 @@ public:
NSFile::CFileBinary::SaveToFile(sLogFile, sLogContent, true);
}
int GenerateDiff(const std::wstring strDirIn, const std::wstring strDirOut, const std::wstring strDiffs)
{
int nCountInPages = GetPagesCount(strDirIn);
@ -521,6 +514,10 @@ class CConverter : public NSThreads::CBaseThread
{
public:
CInternalWorker* m_pInternal;
std::wstring m_input_dir;
std::wstring m_output_dir;
std::wstring m_file;
std::wstring m_folder_dst;
int m_format;
@ -537,15 +534,40 @@ public:
Stop();
}
std::wstring GetOutputFile(const std::wstring& sFolderAddon = L"", const bool& isStandart = false)
{
std::wstring input_dir = m_input_dir;
NSStringUtils::string_replace(input_dir, L"\\", L"/");
std::wstring input_file = m_file;
NSStringUtils::string_replace(input_file, L"\\", L"/");
std::wstring output_dir = isStandart ? (m_input_dir + L"/../out/master") : (m_output_dir + L"/");
if (!sFolderAddon.empty())
output_dir += (sFolderAddon + L"/");
NSStringUtils::string_replace(output_dir, L"\\", L"/");
NSStringUtils::string_replace(output_dir, L"//", L"/");
std::wstring output_file = output_dir + input_file.substr(input_dir.length());
NSStringUtils::string_replace(output_file, L"//", L"/");
#ifdef _WIN32
NSStringUtils::string_replace(output_file, L"/", L"\\");
#endif
return output_file;
}
virtual DWORD ThreadProc()
{
if (m_bDiffOnly)
{
std::wstring strDirIn = m_file;
std::wstring strDirIn = GetOutputFile(L"", true);
std::wstring strDirOut = m_folder_dst;
std::wstring strDiffsMain = NSFile::GetDirectoryName(strDirOut) + L"/DIFF";
std::wstring strDiffs = strDiffsMain + L"/" + NSFile::GetFileName(m_file);
std::wstring strDiffs = GetOutputFile(L"DIFF");
int checkCode = m_pInternal->GenerateDiff(strDirIn, strDirOut, strDiffs);
@ -650,12 +672,10 @@ public:
if (!m_pInternal->m_bIsStandard)
{
// смотрим разницу
std::wstring strDirIn = NSFile::GetDirectoryName(m_file);
std::wstring strDirIn = GetOutputFile(L"", true);
std::wstring strDirOut = sDirectoryDst;
std::wstring strDiffsMain = NSFile::GetDirectoryName(strDirOut) + L"/DIFF";
std::wstring strDiffs = strDiffsMain + L"/" + NSFile::GetFileName(m_file);
std::wstring strDiffs = GetOutputFile(L"DIFF");
checkCode = m_pInternal->GenerateDiff(strDirIn, strDirOut, strDiffs);
}
@ -673,13 +693,18 @@ CConverter* CInternalWorker::GetNextConverter()
CConverter* pConverter = new CConverter(this);
pConverter->DestroyOnFinish();
pConverter->m_input_dir = m_sInputFolder;
pConverter->m_output_dir = m_sOutputFolder;
pConverter->m_file = m_files[m_nCurrent];
pConverter->m_bDiffOnly = m_bDiffOnly;
++m_nCurrent;
std::wstring sName = NSFile::GetFileName(pConverter->m_file);
pConverter->m_folder_dst = m_sOutputFolder + L"/" + sName;
NSDirectory::CreateDirectory(pConverter->m_folder_dst);
pConverter->m_folder_dst = pConverter->GetOutputFile();
NSDirectory::CreateDirectories(pConverter->m_folder_dst);
if (m_bIsStandard)
NSFile::CFileBinary::Copy(pConverter->m_file, pConverter->m_folder_dst + L"/" + sName);

View File

@ -450,7 +450,7 @@ TEST(OOXml2OdfTest,Example1)
pElement->fromXML(oReader);
StarMath::COOXml2Odf oTest;
oTest.StartConversion(pElement);
std::wstring wsOdf = L"<math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"block\"><semantics><mrow><msup><mrow><mo fence=\"true\" form=\"prefix\" stretchy=\"true\" />(<mrow><mrow><mi mathvariant=\"italic\">x</mi><mo stretchy=\"false\">+</mo><mi mathvariant=\"italic\">a</mi></mrow></mrow><mo fence=\"true\" form=\"postfix\" stretchy=\"true\" />)</mrow><mi mathvariant=\"italic\">n</mi></msup><mrow><mo stretchy=\"false\">=</mo></mrow><munderover><mo stretchy=\"false\">\u2211</mo><mrow><mi mathvariant=\"italic\">k</mi><mo stretchy=\"false\">=</mo><mn>0</mn></mrow><mi mathvariant=\"italic\">n</mi></munderover><mrow><mo fence=\"true\" form=\"prefix\" stretchy=\"true\" />(<mrow><mtable><mtr><mtd><mi mathvariant=\"italic\">n</mi></mtd></mtr><mtr><mtd><mi mathvariant=\"italic\">k</mi></mtd></mtr></mtable></mrow><mo fence=\"true\" form=\"postfix\" stretchy=\"true\" />)</mrow><msup><mi mathvariant=\"italic\">x</mi><mi mathvariant=\"italic\">k</mi></msup><msup><mi mathvariant=\"italic\">a</mi><mrow><mi mathvariant=\"italic\">n</mi><mo stretchy=\"false\">-</mo><mi mathvariant=\"italic\">k</mi></mrow></msup></mrow><annotation encoding=\"StarMath 5.0\">left ( x + a right ) ^ {n } = sum from {k = 0 } to {n } left ( binom { n } { k } right ) x ^ {k } a ^ {n - k } </annotation></semantics></math>";
std::wstring wsOdf = L"<math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"block\"><semantics><mrow><msup><mrow><mo fence=\"true\" form=\"prefix\" stretchy=\"true\" />(<mrow><mrow><mi mathvariant=\"italic\">x</mi><mo stretchy=\"false\">+</mo><mi mathvariant=\"italic\">a</mi></mrow></mrow><mo fence=\"true\" form=\"postfix\" stretchy=\"true\" />)</mrow><mi mathvariant=\"italic\">n</mi></msup><mtext>=</mtext><munderover><mo stretchy=\"false\">\x2211</mo><mrow><mi mathvariant=\"italic\">k</mi><mo stretchy=\"false\">=</mo><mn>0</mn></mrow><mi mathvariant=\"italic\">n</mi></munderover><mrow><mo fence=\"true\" form=\"prefix\" stretchy=\"true\" />(<mrow><mtable><mtr><mtd><mi mathvariant=\"italic\">n</mi></mtd></mtr><mtr><mtd><mi mathvariant=\"italic\">k</mi></mtd></mtr></mtable></mrow><mo fence=\"true\" form=\"postfix\" stretchy=\"true\" />)</mrow><msup><mi mathvariant=\"italic\">x</mi><mi mathvariant=\"italic\">k</mi></msup><msup><mi mathvariant=\"italic\">a</mi><mrow><mi mathvariant=\"italic\">n</mi><mo stretchy=\"false\">-</mo><mi mathvariant=\"italic\">k</mi></mrow></msup></mrow><annotation encoding=\"StarMath 5.0\">left ( x + a right ) ^ {n } &quot;=&quot; sum from {k = 0 } to {n } left ( binom { n } { k } right ) x ^ {k } a ^ {n - k } </annotation></semantics></math>";
EXPECT_EQ(oTest.GetOdf(),wsOdf);
}
TEST(OOXml2OdfTest,Example3)
@ -505,7 +505,7 @@ TEST(OOXml2OdfTest,Example7)
pElement->fromXML(oReader);
StarMath::COOXml2Odf oTest;
oTest.StartConversion(pElement);
std::wstring wsOdf = L"<math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"block\"><semantics><mrow><msup><mi mathvariant=\"italic\">a</mi><mn>2</mn></msup><mrow><mo stretchy=\"false\">+</mo></mrow><msup><mi mathvariant=\"italic\">b</mi><mn>2</mn></msup><mrow><mo stretchy=\"false\">=</mo></mrow><msup><mi mathvariant=\"italic\">c</mi><mn>2</mn></msup></mrow><annotation encoding=\"StarMath 5.0\">a ^ {2 } + b ^ {2 } = c ^ {2 } </annotation></semantics></math>";
std::wstring wsOdf = L"<math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"block\"><semantics><mrow><msup><mi mathvariant=\"italic\">a</mi><mn>2</mn></msup><mrow><mo stretchy=\"false\">+</mo></mrow><msup><mi mathvariant=\"italic\">b</mi><mn>2</mn></msup><mtext>=</mtext><msup><mi mathvariant=\"italic\">c</mi><mn>2</mn></msup></mrow><annotation encoding=\"StarMath 5.0\">a ^ {2 } + b ^ {2 } &quot;=&quot; c ^ {2 } </annotation></semantics></math>";
EXPECT_EQ(oTest.GetOdf(),wsOdf);
}
TEST(OOXml2OdfTest,Example9)