Compare commits

..

1 Commits

Author SHA1 Message Date
64c7b7a3fd handout binary 2026-02-02 22:36:39 +03:00
56 changed files with 823 additions and 837 deletions

View File

@ -600,6 +600,12 @@ namespace NSCSS
return true;
}
void CColor::SetNone()
{
Clear();
m_oValue.reset();
}
char NormalizeNegativeColorValue(INT nValue)
{
@ -641,21 +647,18 @@ namespace NSCSS
}
else if (L"none" == wsNewValue || wsNewValue == L"transparent")
{
Clear();
m_oValue = CColorValue();
SetNone();
bResult = true;
}
else if (L"context-stroke" == wsNewValue)
{
Clear();
m_oValue = CColorValueContextStroke();
bResult = true;
}
else if (L"context-fill" == wsNewValue)
{
Clear();
m_oValue = CColorValueContextFill();
bResult = true;
}
else if (10 <= wsNewValue.length() && wsNewValue.substr(0, 3) == L"rgb")
{

View File

@ -343,6 +343,7 @@ namespace NSCSS
void SetRGB(const TRGB& oRGB);
void SetHEX(const std::wstring& wsValue);
bool SetUrl(const std::wstring& wsValue);
void SetNone();
};
typedef enum

View File

@ -85,13 +85,6 @@ bool Segment::IsEmpty() const noexcept
return Id == 0 && Index == -1 && P.IsZero() && HI.IsZero() && HO.IsZero();
}
bool Segment::Equals(const Segment& other) const noexcept
{
return isZero(P.X - other.P.X) && isZero(P.Y - other.P.Y) &&
isZero(HI.X - other.HI.X) && isZero(HI.Y - other.HI.Y) &&
isZero(HO.X - other.HO.X) && isZero(HO.Y - other.HO.Y);
}
bool Segment::operator==(const Segment& other) const noexcept
{
return (Index == other.Index) && (Id == other.Id);
@ -697,12 +690,6 @@ bool Curve::IsStraight() const noexcept
return !Segment2.IsCurve;
}
bool Curve::Equals(const Curve& other) const noexcept
{
return Segment1.Equals(other.Segment1) &&
Segment2.Equals(other.Segment2);
}
bool Curve::operator==(const Curve& other) const noexcept
{
return Segment1 == other.Segment1 &&
@ -843,7 +830,7 @@ void CBooleanOperations::TraceBoolean()
return;
}
if (!Locations.empty() && !IsOnlyEnds())
if (!Locations.empty())
{
int length = static_cast<int>(Locations.size());
for (int i = 0; i < length; i++)
@ -1858,7 +1845,7 @@ void CBooleanOperations::GetCurveIntersection(const Curve& curve1, const Curve&
AddCurveIntersection(flip ? curve2 : curve1, flip ? curve1 : curve2,
flip ? curve2 : curve1, flip ? curve1 : curve2, flip);
if (Locations.size() == before && (!straight /*|| Locations.empty()*/))
if (Locations.size() == before && (!straight || Locations.empty()))
{
double t = curve2.GetTimeOf(curve1.Segment1.P);
if (t != -1.0)
@ -2071,27 +2058,17 @@ bool CBooleanOperations::IsInside(const Segment& segment) const
void CBooleanOperations::SetWinding()
{
if (Locations.empty() || (Locations.size() == 2 && Locations[0]->Ends) || IsOnlyEnds())
if (Locations.empty() || (Locations.size() == 2 && Locations[0]->Ends))
{
Segment s1 = Segments1[0], s2 = Segments2[0];
Segment s1, s2;
for (const auto& s : Segments1)
{
bool skip = false;
for (const auto& ss : Segments2)
skip = skip || !s.Equals(ss);
if (!s.Inters && !skip)
if (!s.Inters)
s1 = s;
}
for (const auto& s : Segments2)
{
bool skip = false;
for (const auto& ss : Segments1)
skip = skip || !s.Equals(ss);
if (!s.Inters && !skip)
if (!s.Inters)
s2 = s;
}
bool winding = IsInside(s1);
@ -2308,8 +2285,8 @@ bool CBooleanOperations::IsOneCurvePath(int pathIndex) const noexcept
void CBooleanOperations::AddLocation(Curve curve1, Curve curve2, double t1,
double t2, bool overlap, bool filter, bool ends)
{
bool excludeStart = !overlap && GetPreviousCurve(curve1).Equals(curve2),
excludeEnd = !overlap && curve1 != curve2 && GetNextCurve(curve1).Equals(curve2);
bool excludeStart = !overlap && GetPreviousCurve(curve1) == curve2,
excludeEnd = !overlap && curve1 != curve2 && GetNextCurve(curve1) == curve2;
double tMin = CURVETIME_EPSILON,
tMax = 1 - tMin;
@ -2368,18 +2345,6 @@ bool CBooleanOperations::CheckLocation(std::shared_ptr<Location> loc, bool start
return false;
}
bool CBooleanOperations::IsOnlyEnds() const noexcept
{
bool onlyEnds1 = true;
bool onlyEnds2 = true;
for (const auto& l : Locations)
{
onlyEnds1 = onlyEnds1 && l->Ends;
onlyEnds2 = onlyEnds2 && l->Inters->Ends;
}
return onlyEnds1 || onlyEnds2;
}
CGraphicsPath CalcBooleanOperation(const CGraphicsPath& path1,
const CGraphicsPath& path2,
BooleanOpType op,

View File

@ -37,7 +37,6 @@ namespace Aggplus
bool IsValid(const BooleanOpType& op) const noexcept;
bool IsEmpty() const noexcept;
bool Equals(const Segment& other) const noexcept;
bool operator==(const Segment& other) const noexcept;
bool operator!=(const Segment& other) const noexcept;
};
@ -83,7 +82,6 @@ namespace Aggplus
void Flip() noexcept;
bool IsStraight() const noexcept;
bool Equals(const Curve& other) const noexcept;
bool operator==(const Curve& other) const noexcept;
bool operator!=(const Curve& other) const noexcept;
};
@ -161,7 +159,6 @@ namespace Aggplus
bool IsOneCurvePath(int pathIndex) const noexcept;
void AddOffsets(std::vector<double>& offsets, const Curve& curve, bool end);
bool CheckLocation(std::shared_ptr<Location> loc, bool start) const noexcept;
bool IsOnlyEnds() const noexcept;
private:
BooleanOpType Op = Intersection;

View File

@ -498,10 +498,7 @@ namespace NSOnlineOfficeBinToPdf
bIsEnableBrushRect = oReader.ReadBool();
if (!bIsEnableBrushRect)
{
pRenderer->BrushRect(bIsEnableBrushRect ? 1 : 0, 0, 0, 1, 1);
clipRect = Aggplus::RectF_T<double>();
}
break;
}
case ctBrushTexturePathOld:
@ -773,6 +770,7 @@ namespace NSOnlineOfficeBinToPdf
clipPath.AddRectangle(clipRect.X, clipRect.Y, clipRect.Width, clipRect.Height);
path = Aggplus::CalcBooleanOperation(drawPath, clipPath, Aggplus::Intersection);
clipRect = Aggplus::RectF_T<double>();
}
pRenderer->AddPath(path);

View File

@ -349,7 +349,7 @@ bool CImageFileFormatChecker::isSvgFile(BYTE* pBuffer,DWORD dwBytes)
{
if (eFileType)return false;
if ( (6 <= dwBytes) && (0x3C == pBuffer[0] && 0x3F == pBuffer[1] && 0x78 == pBuffer[2] && 0x6D == pBuffer[3]
if ( (6 <= dwBytes) &&(0x3C == pBuffer[0] && 0x3F == pBuffer[1] && 0x78 == pBuffer[2] && 0x6D == pBuffer[3]
&& 0x6C == pBuffer[4] && 0x20 == pBuffer[5]))
{
std::string sXml_part = std::string((char*)pBuffer, dwBytes);
@ -358,11 +358,6 @@ bool CImageFileFormatChecker::isSvgFile(BYTE* pBuffer,DWORD dwBytes)
return true;
}
}
else if ( (6 <= dwBytes) && (0x3C == pBuffer[0] && 's' == pBuffer[1] && 'v' == pBuffer[2] && 'g' == pBuffer[3]
&& 0x20 == pBuffer[4]))
{
return true;
}
return false;
}

View File

@ -74,7 +74,7 @@ namespace MetaFile
virtual void EndClipPath(unsigned int unMode) = 0;
virtual void UpdateDC() = 0;
virtual void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) = 0;
virtual void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) = 0;
virtual void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) = 0;
};

View File

@ -863,17 +863,12 @@ namespace MetaFile
void PathClip(const CPath& oPath, int nClipMode, TXForm *pTransform = NULL)
{
double dM11, dM12, dM21, dM22, dX, dY;
GetTransform(&dM11, &dM12, &dM21, &dM22, &dX, &dY);
if (NULL != pTransform)
SetTransform(pTransform->M11, pTransform->M12,
pTransform->M21, pTransform->M22,
pTransform->Dx - m_pFile->GetDCBounds().Left,
pTransform->Dy - m_pFile->GetDCBounds().Top);
else
SetTransform(dM11, dM12, dM21, dM22,
dX - m_pFile->GetDCBounds().Left,
dY - m_pFile->GetDCBounds().Top);
{
GetTransform(&dM11, &dM12, &dM21, &dM22, &dX, &dY);
SetTransform(pTransform->M11, pTransform->M12, pTransform->M21, pTransform->M22, pTransform->Dx, pTransform->Dy);
}
oPath.DrawOn(this, false, false, nClipMode);
@ -919,7 +914,7 @@ namespace MetaFile
m_bStartedPath = false;
}
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY)
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY)
{
double dKoefX = m_dScaleX;
double dKoefY = m_dScaleY;
@ -1275,6 +1270,19 @@ namespace MetaFile
if ((NULL != pDataDash && 0 != unSizeDash) || PS_SOLID != ulPenStyle)
{
// Дублированный код из Graphics
// Без этого используется оригинальный код в Graphics, который отрисовывает уже неверно
double dDashWidth{dWidth};
if (!Equals(dWidthMinSize, dWidth))
{
double dDet = oMatrix.Determinant();
if (fabs(dDet) < 0.0001)
dDashWidth *= dSqrtDet;
}
// -----------------------------
if (NULL != pDataDash && 0 != unSizeDash)
{
m_pRenderer->put_PenDashOffset(pPen->GetDashOffset());
@ -1282,7 +1290,7 @@ namespace MetaFile
std::vector<double> arDashes(unSizeDash);
for (unsigned int unIndex = 0; unIndex < unSizeDash; ++unIndex)
arDashes[unIndex] = pDataDash[unIndex] * dWidth;
arDashes[unIndex] = pDataDash[unIndex] * dDashWidth;
m_pRenderer->PenDashPattern(arDashes.data(), unSizeDash);
@ -1296,35 +1304,35 @@ namespace MetaFile
{
case PS_DASH:
{
arDashPattern.push_back(9 * dWidth);
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(9 * dDashWidth);
arDashPattern.push_back(3 * dDashWidth);
break;
}
case PS_DOT:
{
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(3 * dDashWidth);
arDashPattern.push_back(3 * dDashWidth);
break;
}
case PS_DASHDOT:
{
arDashPattern.push_back(9 * dWidth);
arDashPattern.push_back(6 * dWidth);
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(6 * dWidth);
arDashPattern.push_back(9 * dDashWidth);
arDashPattern.push_back(6 * dDashWidth);
arDashPattern.push_back(3 * dDashWidth);
arDashPattern.push_back(6 * dDashWidth);
break;
}
case PS_DASHDOTDOT:
{
arDashPattern.push_back(9 * dWidth);
arDashPattern.push_back(6 * dWidth);
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(6 * dWidth);
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(6 * dWidth);
arDashPattern.push_back(9 * dDashWidth);
arDashPattern.push_back(6 * dDashWidth);
arDashPattern.push_back(3 * dDashWidth);
arDashPattern.push_back(6 * dDashWidth);
arDashPattern.push_back(3 * dDashWidth);
arDashPattern.push_back(6 * dDashWidth);
break;
}

View File

@ -239,7 +239,7 @@ namespace MetaFile
void EndClipPath(unsigned int unMode) override {};
void UpdateDC() override {};
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) override {};
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override {};
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override {};
};
}

View File

@ -182,7 +182,7 @@ namespace MetaFile
pInterpretator->UpdateDC();
}
void CEmfInterpretatorArray::SetTransform(const double &dM11, const double &dM12, const double &dM21, const double &dM22, const double &dX, const double &dY)
void CEmfInterpretatorArray::SetTransform(double &dM11, double &dM12, double &dM21, double &dM22, double &dX, double &dY)
{
for (CEmfInterpretatorBase* pInterpretator : m_arInterpretators)
pInterpretator->SetTransform(dM11, dM12, dM21, dM22, dX, dY);

View File

@ -57,7 +57,7 @@ namespace MetaFile
void EndClipPath(unsigned int unMode) override;
void UpdateDC() override;
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) override;
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override;
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override;
void HANDLE_EMR_HEADER(const TEmfHeader& oTEmfHeader) override;

View File

@ -143,7 +143,7 @@ namespace MetaFile
m_pMetaFileRenderer->UpdateDC();
}
void CEmfInterpretatorRender::SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY)
void CEmfInterpretatorRender::SetTransform(double &dM11, double &dM12, double &dM21, double &dM22, double &dX, double &dY)
{
if (NULL != m_pMetaFileRenderer)
m_pMetaFileRenderer->SetTransform(dM11, dM12, dM21, dM22, dX, dY);

View File

@ -43,7 +43,7 @@ namespace MetaFile
void EndClipPath(unsigned int unMode) override;
void UpdateDC() override;
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) override;
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override;
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override;
CMetaFileRenderer* GetRenderer() const;

View File

@ -223,7 +223,7 @@ namespace MetaFile
void EndPath() override {};
void UpdateDC() override {};
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) override {};
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override {};
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override {};
void SwapClips(CSvgClip& oFirstClip, CSvgClip& oSecondClip);

View File

@ -237,7 +237,7 @@ namespace MetaFile
void EndClipPath(unsigned int unMode) override {};
void UpdateDC() override {};
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) override {};
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override {};
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override {};
};
}

View File

@ -627,21 +627,13 @@ namespace MetaFile
void CInterpretatorSvgBase::PathClip(const CPath &oPath, int nClipMode, TXForm *pTransform)
{
const std::wstring wsPath = CreatePath(oPath, pTransform);
std::wstring wsPath = CreatePath(oPath, pTransform);
if (wsPath.empty())
return;
const std::wstring wsClipId = L"PATHCLIP_" + ConvertToWString(++m_unNumberDefs, 0);
std::wstring wsValue = L"<path d=\"" + wsPath + L"\"";
const int nOffsetLeft{-m_pParser->GetDCBounds().Left};
const int nOffsetTop {-m_pParser->GetDCBounds().Top};
if (0 != nOffsetLeft || 0 != nOffsetTop)
wsValue += L" transform=\"translate(" + std::to_wstring(nOffsetLeft) + L',' + std::to_wstring(nOffsetTop) + L")\"";
wsValue += L"/>";
const std::wstring wsValue = L"<path d=\"" + wsPath + L"\"/>";
m_oClip.AddClipValue(wsClipId, wsValue, nClipMode);
}

View File

@ -131,7 +131,7 @@ namespace MetaFile
m_pMetaFileRenderer->UpdateDC();
}
void CWmfInterpretatorRender::SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY)
void CWmfInterpretatorRender::SetTransform(double &dM11, double &dM12, double &dM21, double &dM22, double &dX, double &dY)
{
if (NULL != m_pMetaFileRenderer)
m_pMetaFileRenderer->SetTransform(dM11, dM12, dM21, dM22, dX, dY);

View File

@ -40,7 +40,7 @@ namespace MetaFile
void EndClipPath(unsigned int unMode) override;
void UpdateDC() override;
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) override;
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override;
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override;
CMetaFileRenderer* GetRenderer() const;

View File

@ -130,7 +130,7 @@ namespace MetaFile
void EndClipPath(unsigned int unMode) override {};
void UpdateDC() override {};
void SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY) override {};
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override {};
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override {};
};

View File

@ -40,14 +40,13 @@
CPictFile::CPictFile()
{
m_pRenderer = NSGraphics::Create();
m_pFontManager = NSFonts::NSFontManager::Create();
m_pRenderer->SetFontManager(m_pFontManager);
}
CPictFile::~CPictFile()
{
if (m_pAppFonts)
RELEASEINTERFACE(m_pAppFonts);
if (m_pFontManager)
RELEASEINTERFACE(m_pFontManager);
RELEASEINTERFACE(m_pFontManager);
RELEASEINTERFACE(m_pRenderer);
}
@ -1672,7 +1671,6 @@ void CPictFile::DrawArc()
void CPictFile::ReadAndDrawText(int x, int y)
{
InitializeRenderer();
InitializeFonts();
char text[256];
char byte_len = fgetc(m_pFile);
@ -1697,20 +1695,6 @@ void CPictFile::ReadAndDrawText(int x, int y)
m_pRenderer->EndCommand(c_nTextGraphicType);
}
void CPictFile::InitializeFonts()
{
if (m_pAppFonts)
return;
m_pAppFonts = NSFonts::NSApplication::Create();
m_pAppFonts->Initialize();
m_pFontManager = m_pAppFonts->GenerateFontManager();
NSFonts::IFontsCache* fonts_cache = NSFonts::NSFontCache::Create();
fonts_cache->SetStreams(m_pAppFonts->GetStreams());
m_pFontManager->SetOwnerCache(fonts_cache);
m_pRenderer->SetFontManager(m_pFontManager);
}
void CPictFile::InitializeRenderer()
{
if (m_pFrameData)

View File

@ -247,7 +247,6 @@ private:
void DrawArc();
void ReadAndDrawText(int x, int y);
void InitializeFonts();
void InitializeRenderer();
private:
@ -258,8 +257,8 @@ private:
CBgraFrame m_oFrame{};
BYTE* m_pFrameData{nullptr};
size_t m_nPenHeight{1};
size_t m_nPenWidth{1};
size_t m_nPenHeight{0};
size_t m_nPenWidth{0};
int m_nFontStyle{0};
int m_nFontSize{0};
@ -276,7 +275,6 @@ private:
std::vector<Aggplus::Point> m_arLastPolygon{};
NSGraphics::IGraphicsRenderer* m_pRenderer{nullptr};
NSFonts::IApplicationFonts* m_pAppFonts{nullptr};
NSFonts::IFontManager* m_pFontManager{nullptr};
};

View File

@ -105,13 +105,13 @@ namespace NSHeif {
inline bool CHeifFile::Decode(heif_context* ctx, CBgraFrame* frame, bool isRGBA)
{
heif_image_handle* handle = nullptr;
heif_image_handle* handle;
defer(heif_image_handle_release(handle););
if (IsError(heif_context_get_primary_image_handle(ctx, &handle)))
return false;
heif_image* img = nullptr;
heif_image* img;
defer(heif_image_release(img););
if (IsError(heif_decode_image(handle, &img, heif_colorspace_RGB, heif_chroma_444, nullptr)))

View File

@ -1261,10 +1261,12 @@ void CConverter2OOXML::WriteEqEditShape(const CCtrlEqEdit* pEqEditShape, short s
OpenParagraph(shParaShapeID, shParaStyleID, oBuilder, oState);
oBuilder.WriteString(L"<w:r/>");
oBuilder.WriteString(L"<w:r><w:t xml:space=\"preserve\">");
StarMath::CStarMathConverter oConverterStarMath;
oBuilder.WriteString(oConverterStarMath.ConvertEQNToOOXml(pEqEditShape->GetEqn()));
oBuilder.WriteString(L"</w:t></w:r>");
}
void CConverter2OOXML::WriteOleShape(const CCtrlShapeOle* pOleShape, short shParaShapeID, short shParaStyleID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState)

View File

@ -91,7 +91,9 @@ namespace NSBinPptxRW
SlideNotesRels = 45,
NotesRels = 46,
NotesMastersRels= 47,
CustomProperties= 48
CustomProperties= 48,
HandoutMastersRels = 49
};
}
}

View File

@ -1581,6 +1581,16 @@ namespace NSBinPptxRW
std::to_wstring(nIndexTheme + 1) + L".xml\"/>";
m_pWriter->WriteString(s);
}
void CRelsGenerator::StartThemeHandoutMaster(int nIndexTheme)
{
m_pWriter->WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
m_pWriter->WriteString(L"<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">");
std::wstring s = L"<Relationship Id=\"rId" + std::to_wstring(m_lNextRelsID++) +
L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\" Target=\"../theme/theme" +
std::to_wstring(nIndexTheme + 1) + L".xml\"/>";
m_pWriter->WriteString(s);
}
void CRelsGenerator::StartLayout(int nIndexTheme)
{
m_pWriter->WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
@ -1653,13 +1663,18 @@ namespace NSBinPptxRW
return rid;
}
void CRelsGenerator::WriteNotesMaster()
{
std::wstring strRels0 = L"<Relationship Id=\"rId" + std::to_wstring(m_lNextRelsID++) +
L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster\" Target=\"notesMasters/notesMaster1.xml\"/>";
m_pWriter->WriteString(strRels0);
L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster\" Target=\"notesMasters/notesMaster1.xml\"/>";
m_pWriter->WriteString(strRels0);
}
void CRelsGenerator::WriteHandoutMaster()
{
std::wstring strRels0 = L"<Relationship Id=\"rId" + std::to_wstring(m_lNextRelsID++) +
L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/handoutMaster\" Target=\"handoutMasters/handoutMaster1.xml\"/>";
m_pWriter->WriteString(strRels0);
}
std::wstring CRelsGenerator::WriteCustom(const std::wstring & file_name)
{
std::wstring rid = L"rId" + std::to_wstring(m_lNextRelsID++);

View File

@ -162,12 +162,14 @@ namespace NSBinPptxRW
std::map<size_t, LONG> layouts;
std::map<size_t, LONG> notes;
std::map<size_t, LONG> notesMasters;
std::map<size_t, LONG> handoutMasters;
std::vector<_masterSlideInfo> m_oRels;
std::vector<LONG> m_oSlide_Layout_Rels;
std::vector<LONG> m_oSlide_Notes_Rels;
std::vector<LONG> m_oNote_Rels;
std::vector<LONG> m_oNotesMasters_Rels;
std::vector<LONG> m_oHandoutMasters_Rels;
NSShapeImageGen::CMediaManager* m_pMediaManager;
@ -488,10 +490,13 @@ namespace NSBinPptxRW
void StartLayout (int nIndexTheme);
void StartSlide (int nIndexSlide, int nIndexLayout, int nIndexNotes);
void StartNotes (int nIndexSlide);
void StartThemeNotesMaster(int nIndexTheme);
void WriteThemes (int nCount);
void WriteNotesMaster();
void WriteHandoutMaster();
void StartThemeNotesMaster(int nIndexTheme);
void StartThemeHandoutMaster(int nIndexTheme);
std::wstring WriteCustom(const std::wstring& file_name);
std::wstring WriteMaster(int nIndex);

View File

@ -33,12 +33,12 @@
#include "Converter.h"
#include "../../PPTXFormat/Presentation/PresentationChildElements.h"
#include "../../PPTXFormat/NotesSlide.h"
#include "../../PPTXFormat/HandoutMaster.h"
namespace PPTX2EditorAdvanced
{
DWORD Convert(NSBinPptxRW::CBinaryFileWriter& oBinaryWriter, PPTX::Document& oFolder, const std::wstring& strSourceDirectory, const std::wstring& strDstFile, bool bIsNoBase64)
{
// сначала соберем все объекты для конвертации и сформируем main-таблицы
NSBinPptxRW::CCommonWriter* pCommon = oBinaryWriter.m_pCommon;
std::vector<smart_ptr<PPTX::Theme>> _themes;
@ -47,6 +47,7 @@ namespace PPTX2EditorAdvanced
std::vector<smart_ptr<PPTX::SlideLayout>> _layouts;
std::vector<smart_ptr<PPTX::NotesSlide>> _notes;
std::vector<smart_ptr<PPTX::NotesMaster>> _notesMasters;
std::vector<smart_ptr<PPTX::HandoutMaster>> _handoutMasters;
smart_ptr<PPTX::Presentation> presentation = oFolder.Get(OOX::Presentation::FileTypes::Presentation).smart_dynamic_cast<PPTX::Presentation>();
@ -55,7 +56,6 @@ namespace PPTX2EditorAdvanced
int cy = presentation->sldSz->cy;
#endif
// записываем все темы
size_t nCountMasters = presentation->sldMasterIdLst.size();
for (size_t nMaster = 0; nMaster < nCountMasters; ++nMaster)
{
@ -167,6 +167,47 @@ namespace PPTX2EditorAdvanced
oBinaryWriter.m_pCommon->m_oNotesMasters_Rels.push_back(nNotesMastersRelsIndex);
}
// записываем все handoutMasters
size_t nCountHandoutMasters = presentation->handoutMasterIdLst.size();
for (size_t nHandout = 0; nHandout < nCountHandoutMasters; ++nHandout)
{
smart_ptr<PPTX::HandoutMaster> handoutMaster = ((*presentation)[presentation->handoutMasterIdLst[nHandout].rid.get()]).smart_dynamic_cast<PPTX::HandoutMaster>();
if (false == handoutMaster.IsInit())
{
// такого быть не должно
continue;
}
size_t pPointerNM = (size_t)(handoutMaster.operator ->());
std::map<size_t, LONG>::const_iterator pSearchNM = pCommon->handoutMasters.find(pPointerNM);
if (pSearchNM != pCommon->handoutMasters.end())
{
// такого быть не должно
continue;
}
// записываем mainMaster
LONG lCountNM = (LONG)_handoutMasters.size();
pCommon->handoutMasters[pPointerNM] = lCountNM;
_handoutMasters.push_back(handoutMaster);
// проверяем theme
size_t pPointerTh = (size_t)(handoutMaster->theme_.operator ->());
LONG nHandoutMastersRelsIndex = -1;
std::map<size_t, LONG>::const_iterator pSearchTh = pCommon->themes.find(pPointerTh);
if (pSearchTh == pCommon->themes.end())
{
LONG lCountTh = (LONG)_themes.size();
pCommon->themes[pPointerTh] = lCountTh;
_themes.push_back(handoutMaster->theme_);
nHandoutMastersRelsIndex = lCountTh;
}
else {
nHandoutMastersRelsIndex = pSearchTh->second;
}
oBinaryWriter.m_pCommon->m_oHandoutMasters_Rels.push_back(nHandoutMastersRelsIndex);
}
// записываем все слайды
for (size_t i = 0; i < presentation->sldIdLst.size(); ++i)
{
@ -407,6 +448,14 @@ namespace PPTX2EditorAdvanced
{
_notesMasters[i]->toPPTY(&oBinaryWriter);
}
// handoutmasters
oBinaryWriter.StartMainRecord(NSBinPptxRW::NSMainTables::HandoutMasters);
ULONG nCountHM = (ULONG)_handoutMasters.size();
oBinaryWriter.WriteULONG(nCountHM);
for (ULONG i = 0; i < nCountHM; ++i)
{
_handoutMasters[i]->toPPTY(&oBinaryWriter);
}
// ImageMap ---------------------------------------
oBinaryWriter.StartMainRecord(NSBinPptxRW::NSMainTables::ImageMap);
oBinaryWriter.StartRecord(NSBinPptxRW::NSMainTables::ImageMap);
@ -529,13 +578,25 @@ namespace PPTX2EditorAdvanced
oBinaryWriter.WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd);
oBinaryWriter.EndRecord();
// HandoutMastersRels --------------------------------------
oBinaryWriter.StartMainRecord(NSBinPptxRW::NSMainTables::HandoutMastersRels);
oBinaryWriter.StartRecord(NSBinPptxRW::NSMainTables::HandoutMastersRels);
oBinaryWriter.WriteBYTE(NSBinPptxRW::g_nodeAttributeStart);
_s_rels = oBinaryWriter.m_pCommon->m_oHandoutMasters_Rels.size();
for (size_t i = 0; i < _s_rels; ++i)
{
oBinaryWriter.WriteInt1(0, oBinaryWriter.m_pCommon->m_oHandoutMasters_Rels[i]);
}
oBinaryWriter.WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd);
oBinaryWriter.EndRecord();
oBinaryWriter.EndRecord();
// ------------------------------------------------
oBinaryWriter.WriteEmbeddedFonts();
oBinaryWriter.WriteMainPart(nStartPos);
// все записалось нормально. осталось скинуть на диск
BYTE* pbBinBuffer = oBinaryWriter.GetBuffer();
int nBinBufferLen = (int)oBinaryWriter.GetPosition();
if (bIsNoBase64)

View File

@ -39,9 +39,9 @@ namespace Writers
}
void DefaultNotesMasterWriter::Write(std::wstring fileName)
{
std::wstring s_Common = _T("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
std::wstring s_Common = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
s_Common += _T("<p:notesMaster xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">\
s_Common += L"<p:notesMaster xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">\
<p:cSld>\
<p:bg>\
<p:bgPr>\
@ -224,7 +224,54 @@ namespace Writers
</a:defRPr>\
</a:lvl9pPr>\
</p:notesStyle>\
</p:notesMaster>");
</p:notesMaster>";
OOX::CPath pathFile = fileName;
NSFile::CFileBinary oFile;
oFile.CreateFile(pathFile.GetPath());
oFile.WriteStringUTF8(s_Common);
oFile.CloseFile();
}
DefaultHandoutMasterWriter::DefaultHandoutMasterWriter()
{
}
void DefaultHandoutMasterWriter::Write(std::wstring fileName)
{
std::wstring s_Common = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
s_Common += L"<p:handoutMaster xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" \
xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" \
xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">\
<p:cSld><p:bg><p:bgRef idx=\"1001\"><a:schemeClr val=\"bg1\"/></p:bgRef></p:bg><p:spTree><p:nvGrpSpPr><p:cNvPr id=\"1\" name=""/>\
<p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"0\" cy=\"0\"/><a:chOff x=\"0\" y=\"0\"/><a:chExt cx=\"0\" cy=\"0\"/>\
</a:xfrm></p:grpSpPr><p:sp><p:nvSpPr><p:cNvPr id=\"2\" name=\"Header Placeholder 1\"><a:extLst><a:ext uri=\"{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}\">\
<a16:creationId xmlns:a16=\"http://schemas.microsoft.com/office/drawing/2014/main\" id=\"{F67C4017-3E03-D994-D007-4D4D5EBE9CE9}\"/></a:ext></a:extLst>\
</p:cNvPr><p:cNvSpPr><a:spLocks noGrp=\"1\"/></p:cNvSpPr><p:nvPr><p:ph type=\"hdr\" sz=\"quarter\"/></p:nvPr></p:nvSpPr><p:spPr>\
<a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"2971800\" cy=\"458788\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></p:spPr>\
<p:txBody><a:bodyPr vert=\"horz\" lIns=\"91440\" tIns=\"45720\" rIns=\"91440\" bIns=\"45720\" rtlCol=\"0\"/><a:lstStyle><a:lvl1pPr algn=\"l\"><a:defRPr sz=\"1200\"/>\
</a:lvl1pPr></a:lstStyle><a:p><a:endParaRPr/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id=\"3\" name=\"Date Placeholder 2\">\
<a:extLst><a:ext uri=\"{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}\"><a16:creationId xmlns:a16=\"http://schemas.microsoft.com/office/drawing/2014/main\" \
id=\"{749FF9CD-FA8A-BCBD-7746-C502D224F9D4}\"/></a:ext></a:extLst></p:cNvPr><p:cNvSpPr><a:spLocks noGrp=\"1\"/></p:cNvSpPr><p:nvPr><p:ph type=\"dt\" sz=\"quarter\" \
idx=\"1\"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x=\"3884613\" y=\"0\"/><a:ext cx=\"2971800\" cy=\"458788\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/>\
</a:prstGeom></p:spPr><p:txBody><a:bodyPr vert=\"horz\" lIns=\"91440\" tIns=\"45720\" rIns=\"91440\" bIns=\"45720\" rtlCol=\"0\"/><a:lstStyle><a:lvl1pPr algn=\"r\">\
<a:defRPr sz=\"1200\"/></a:lvl1pPr></a:lstStyle><a:p><a:fld id=\"{DBDFD766-57CE-4B91-8DD2-37F0838B984D}\" type=\"datetimeFigureOut\"><a:rPr smtClean=\"0\"/>\
<a:t></a:t></a:fld><a:endParaRPr/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr><p:cNvPr id=\"4\" name=\"Footer Placeholder 3\"><a:extLst>\
<a:ext uri=\"{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}\"><a16:creationId xmlns:a16=\"http://schemas.microsoft.com/office/drawing/2014/main\" \
id=\"{942A17DF-8C78-FA66-4CE3-783B1C5D3A5A}\"/></a:ext></a:extLst></p:cNvPr><p:cNvSpPr><a:spLocks noGrp=\"1\"/></p:cNvSpPr><p:nvPr>\
<p:ph type=\"ftr\" sz=\"quarter\" idx=\"2\"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x=\"0\" y=\"8685213\"/><a:ext cx=\"2971800\" cy=\"458787\"/>\
</a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></p:spPr><p:txBody><a:bodyPr vert=\"horz\" lIns=\"91440\" tIns=\"45720\" rIns=\"91440\" bIns=\"45720\" rtlCol=\"0\" \
anchor=\"b\"/><a:lstStyle><a:lvl1pPr algn=\"l\"><a:defRPr sz=\"1200\"/></a:lvl1pPr></a:lstStyle><a:p><a:endParaRPr/></a:p></p:txBody></p:sp><p:sp><p:nvSpPr>\
<p:cNvPr id=\"5\" name=\"Slide Number Placeholder 4\"><a:extLst><a:ext uri=\"{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}\">\
<a16:creationId xmlns:a16=\"http://schemas.microsoft.com/office/drawing/2014/main\" id=\"{54E6FC8D-4D60-9D7A-1320-C69919607B49}\"/></a:ext></a:extLst>\
</p:cNvPr><p:cNvSpPr><a:spLocks noGrp=\"1\"/></p:cNvSpPr><p:nvPr><p:ph type=\"sldNum\" sz=\"quarter\" idx=\"3\"/></p:nvPr></p:nvSpPr><p:spPr><a:xfrm>\
<a:off x=\"3884613\" y=\"8685213\"/><a:ext cx=\"2971800\" cy=\"458787\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></p:spPr><p:txBody>\
<a:bodyPr vert=\"horz\" lIns=\"91440\" tIns=\"45720\" rIns=\"91440\" bIns=\"45720\" rtlCol=\"0\" anchor=\"b\"/><a:lstStyle><a:lvl1pPr algn=\"r\"><a:defRPr sz=\"1200\"/>\
</a:lvl1pPr></a:lstStyle><a:p><a:fld id=\"{D7F4AEF4-93E6-4B70-916A-B30E3EBEE0F3}\" type=\"slidenum\"><a:rPr smtClean=\"0\"/><a:t><3E>#<23></a:t></a:fld><a:endParaRPr/>\
</a:p></p:txBody></p:sp></p:spTree><p:extLst><p:ext uri=\"{BB962C8B-B14F-4D97-AF65-F5344CB8AC3E}\">\
<p14:creationId xmlns:p14=\"http://schemas.microsoft.com/office/powerpoint/2010/main\" val=\"2429687043\"/></p:ext></p:extLst></p:cSld>\
<p:clrMap bg1=\"lt1\" tx1=\"dk1\" bg2=\"lt2\" tx2=\"dk2\" accent1=\"accent1\" accent2=\"accent2\" accent3=\"accent3\" accent4=\"accent4\" accent5=\"accent5\" accent6=\"accent6\" \
hlink=\"hlink\" folHlink=\"folHlink\"/></p:handoutMaster>";
OOX::CPath pathFile = fileName;

View File

@ -42,5 +42,11 @@ namespace Writers
DefaultNotesMasterWriter();
void Write(std::wstring fileName);
};
class DefaultHandoutMasterWriter
{
public:
DefaultHandoutMasterWriter();
void Write(std::wstring fileName);
};
}

View File

@ -66,8 +66,8 @@ namespace NSBinPptxRW
{
m_strDstFolder = strFolder;
OOX::CPath pathPPT = m_strDstFolder + FILE_SEPARATOR_STR + _T("ppt");
OOX::CPath pathDocProps = m_strDstFolder + FILE_SEPARATOR_STR + _T("docProps");
OOX::CPath pathPPT = m_strDstFolder + FILE_SEPARATOR_STR + L"ppt";
OOX::CPath pathDocProps = m_strDstFolder + FILE_SEPARATOR_STR + L"docProps";
NSDirectory::CreateDirectory(m_strDstFolder);
NSDirectory::CreateDirectory(pathDocProps.GetPath());
@ -77,19 +77,19 @@ namespace NSBinPptxRW
m_oImageManager.SetDstFolder(pathPPT.GetPath());
OOX::CPath pathMedia = pathPPT / _T("media");
OOX::CPath pathMedia = pathPPT / L"media";
m_oImageManager.SetDstMedia(pathMedia.GetPath());
NSDirectory::CreateDirectory(pathMedia.GetPath());
OOX::CPath pathCharts = pathPPT / _T("charts");
OOX::CPath pathCharts = pathPPT / L"charts";
m_oImageManager.SetDstCharts(pathCharts.GetPath());
OOX::CPath pathEmbeddings = pathPPT / _T("embeddings");
OOX::CPath pathEmbeddings = pathPPT / L"embeddings";
m_oImageManager.SetDstEmbed(pathEmbeddings.GetPath());
m_oReader.m_pRels->m_pManager = &m_oImageManager;
OOX::CPath pathTheme = pathPPT / _T("theme");
OOX::CPath pathTheme = pathPPT / L"theme";
NSDirectory::CreateDirectory(pathTheme.GetPath());
m_oReader.m_strFolderThemes = pathTheme.GetPath();
@ -186,6 +186,7 @@ namespace NSBinPptxRW
LONG nCountLayouts = 0;
LONG nCountSlides = 0;
bool bNotesMasterPresent = false;
bool bHandoutMasterPresent = false;
pPair = m_mainTables.find(NSBinPptxRW::NSMainTables::Themes);
if (m_mainTables.end() != pPair)
@ -317,6 +318,23 @@ namespace NSBinPptxRW
m_arNotesMasters_Theme.push_back(m_oReader.GetULong());
}
}
pPair = m_mainTables.find(NSBinPptxRW::NSMainTables::HandoutMastersRels);
if (m_mainTables.end() != pPair)
{
m_oReader.Seek(pPair->second);
m_oReader.Skip(6); // type + len + start attr
size_t index = 0;
while (true)
{
BYTE _at = m_oReader.GetUChar_TypeNode();
if (_at == NSBinPptxRW::g_nodeAttributeEnd)
break;
m_arHandoutMasters_Theme.push_back(m_oReader.GetULong());
}
}
// теперь нужно удалить все themes, которые не ведут на мастерслайды
std::vector<LONG> arThemes;
std::vector<LONG> arThemesDst;
@ -336,7 +354,6 @@ namespace NSBinPptxRW
arThemesSave[ind] = true;
}
}
for (size_t i = 0; i < m_arNotesMasters_Theme.size(); i++)
{
int index = m_arNotesMasters_Theme[i];
@ -345,6 +362,14 @@ namespace NSBinPptxRW
arThemesSave[index] = true;
}
}
for (size_t i = 0; i < m_arHandoutMasters_Theme.size(); i++)
{
int index = m_arHandoutMasters_Theme[i];
if (index >= 0 && index < (int)arThemesSave.size())
{
arThemesSave[index] = true;
}
}
LONG lCurrectTheme = 0;
for (LONG i = 0; i < nCountMasters && i < arThemesSave.size(); ++i)
{
@ -363,7 +388,7 @@ namespace NSBinPptxRW
if (m_mainTables.end() != pPair)
{
OOX::CPath pathFolder = m_oReader.m_strFolderThemes;
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + _T("_rels");
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + L"_rels";
NSDirectory::CreateDirectory(pathFolder.GetPath());
NSDirectory::CreateDirectory(pathFolderRels.GetPath());
@ -402,7 +427,7 @@ namespace NSBinPptxRW
OOX::CPath pathFile = pathFolder + FILE_SEPARATOR_STR + strMasterXml;
oXmlWriter.SaveToFile(pathFile.GetPath());
OOX::CPath pathFileRels = pathFolderRels + FILE_SEPARATOR_STR + strMasterXml + _T(".rels");
OOX::CPath pathFileRels = pathFolderRels + FILE_SEPARATOR_STR + strMasterXml + L".rels";
m_oReader.m_pRels->SaveRels(pathFileRels.GetPath());
}
}
@ -410,8 +435,8 @@ namespace NSBinPptxRW
pPair = m_mainTables.find(NSBinPptxRW::NSMainTables::SlideMasters);
if (m_mainTables.end() != pPair)
{
OOX::CPath pathFolder = m_strDstFolder + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("slideMasters");
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + _T("_rels");
OOX::CPath pathFolder = m_strDstFolder + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"slideMasters";
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + L"_rels";
NSDirectory::CreateDirectory(pathFolder.GetPath());
NSDirectory::CreateDirectory(pathFolderRels.GetPath());
@ -459,7 +484,7 @@ namespace NSBinPptxRW
OOX::CPath pathFile = pathFolder + FILE_SEPARATOR_STR + strMasterXml;
oXmlWriter.SaveToFile(pathFile.GetPath());
OOX::CPath pathFileRels = pathFolderRels + FILE_SEPARATOR_STR + strMasterXml + _T(".rels");
OOX::CPath pathFileRels = pathFolderRels + FILE_SEPARATOR_STR + strMasterXml + L".rels";
m_oReader.m_pRels->SaveRels(pathFileRels.GetPath());
}
}
@ -467,8 +492,8 @@ namespace NSBinPptxRW
pPair = m_mainTables.find(NSBinPptxRW::NSMainTables::SlideLayouts);
if (m_mainTables.end() != pPair)
{
OOX::CPath pathFolder = m_strDstFolder + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("slideLayouts");
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + _T("_rels");
OOX::CPath pathFolder = m_strDstFolder + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"slideLayouts";
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + L"_rels";
NSDirectory::CreateDirectory(pathFolder.GetPath());
NSDirectory::CreateDirectory(pathFolderRels.GetPath());
@ -501,7 +526,7 @@ namespace NSBinPptxRW
OOX::CPath pathFile = pathFolder + FILE_SEPARATOR_STR + strMasterXml;
oXmlWriter.SaveToFile(pathFile.GetPath());
OOX::CPath pathFileRels = pathFolderRels + FILE_SEPARATOR_STR + strMasterXml + _T(".rels");
OOX::CPath pathFileRels = pathFolderRels + FILE_SEPARATOR_STR + strMasterXml + L".rels";
m_oReader.m_pRels->SaveRels(pathFileRels.GetPath());
}
}
@ -514,8 +539,8 @@ namespace NSBinPptxRW
if (lCount > 0)
{
OOX::CPath pathFolder = m_strDstFolder + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("notesSlides");
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + _T("_rels");
OOX::CPath pathFolder = m_strDstFolder + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"notesSlides";
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + L"_rels";
NSDirectory::CreateDirectory(pathFolder.GetPath());
NSDirectory::CreateDirectory(pathFolderRels.GetPath());
@ -555,7 +580,7 @@ namespace NSBinPptxRW
OOX::CPath pathFile = pathFolder + FILE_SEPARATOR_STR + strNotesXml;
oXmlWriter.SaveToFile(pathFile.GetPath());
OOX::CPath pathFileRels = pathFolderRels + FILE_SEPARATOR_STR + strNotesXml + _T(".rels");
OOX::CPath pathFileRels = pathFolderRels + FILE_SEPARATOR_STR + strNotesXml + L".rels";
m_oReader.m_pRels->SaveRels(pathFileRels.GetPath());
}
}
@ -569,8 +594,8 @@ namespace NSBinPptxRW
if (lCount > 0 || m_arNotesSlides.size() > 0)//один элемент
{
OOX::CPath pathFolder = m_strDstFolder + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("notesMasters");
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + _T("_rels");
OOX::CPath pathFolder = m_strDstFolder + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"notesMasters";
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + L"_rels";
NSDirectory::CreateDirectory(pathFolder.GetPath());
NSDirectory::CreateDirectory(pathFolderRels.GetPath());
@ -579,7 +604,7 @@ namespace NSBinPptxRW
m_arNotesMasters.push_back(elm);
m_oReader.m_pRels->Clear();
m_oReader.m_pRels->StartThemeNotesMaster((int)m_arSlideMasters_Theme.size());
m_oReader.m_pRels->StartThemeNotesMaster(m_arNotesMasters_Theme[0]);
bNotesMasterPresent = true;
if (lCount > 0)
@ -601,22 +626,73 @@ namespace NSBinPptxRW
OOX::CPath pathFile = pathFolder + FILE_SEPARATOR_STR + strMasterNotesXml;
oXmlWriter.SaveToFile(pathFile.GetPath());
OOX::CPath pathFileRels = pathFolderRels + FILE_SEPARATOR_STR + strMasterNotesXml + _T(".rels");
OOX::CPath pathFileRels = pathFolderRels + FILE_SEPARATOR_STR + strMasterNotesXml + L".rels";
m_oReader.m_pRels->SaveRels(pathFileRels.GetPath());
}
else
{
CreateDefaultNotesMasters((int)m_arSlideMasters_Theme.size());
CreateDefaultNotesMasters(m_arNotesMasters_Theme[0]);
}
}
}
// handoutMasters
pPair = m_mainTables.find(NSBinPptxRW::NSMainTables::HandoutMasters);
if (m_mainTables.end() != pPair)
{
m_oReader.Seek(pPair->second);
LONG lCount = m_oReader.GetLong();
if (lCount > 0)
{
bHandoutMasterPresent = true;
OOX::CPath pathFolder = m_strDstFolder + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"handoutMasters";
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + L"_rels";
NSDirectory::CreateDirectory(pathFolder.GetPath());
NSDirectory::CreateDirectory(pathFolderRels.GetPath());
PPTX::HandoutMaster elm(&m_oDocument);
m_arHandoutMasters.push_back(elm);
m_oReader.m_pRels->Clear();
m_oReader.m_pRels->StartThemeHandoutMaster(m_arHandoutMasters_Theme[0]);
if (lCount > 0)
{
try
{
m_arHandoutMasters.back().fromPPTY(&m_oReader);
}
catch (...)
{
}
m_oReader.m_pRels->CloseRels();
std::wstring strMasterHandoutXml = L"handoutMaster1.xml";
oXmlWriter.ClearNoAttack();
m_arHandoutMasters.back().toXmlWriter(&oXmlWriter);
OOX::CPath pathFile = pathFolder + FILE_SEPARATOR_STR + strMasterHandoutXml;
oXmlWriter.SaveToFile(pathFile.GetPath());
OOX::CPath pathFileRels = pathFolderRels + FILE_SEPARATOR_STR + strMasterHandoutXml + L".rels";
m_oReader.m_pRels->SaveRels(pathFileRels.GetPath());
}
}
else
{
CreateDefaultHandoutMasters(m_arHandoutMasters_Theme[0]);
}
}
// slides
int nComment = 1;
pPair = m_mainTables.find(NSBinPptxRW::NSMainTables::Slides);
if (m_mainTables.end() != pPair)
{
OOX::CPath pathFolder = m_strDstFolder + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("slides");
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + _T("_rels");
OOX::CPath pathFolder = m_strDstFolder + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"slides";
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + L"_rels";
NSDirectory::CreateDirectory(pathFolder.GetPath());
NSDirectory::CreateDirectory(pathFolderRels.GetPath());
@ -642,7 +718,7 @@ namespace NSBinPptxRW
if (m_arSlides[i].comments.is_init())
{
OOX::CPath pathFolderCommentDir = m_strDstFolder + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("comments");
OOX::CPath pathFolderCommentDir = m_strDstFolder + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"comments";
if (1 == nComment)
{
NSDirectory::CreateDirectory(pathFolderCommentDir.GetPath());
@ -679,7 +755,7 @@ namespace NSBinPptxRW
OOX::CPath pathFile = pathFolder + FILE_SEPARATOR_STR + strMasterXml;
oXmlWriter.SaveToFile(pathFile.GetPath());
OOX::CPath pathFileRels = pathFolderRels + FILE_SEPARATOR_STR + strMasterXml + _T(".rels");
OOX::CPath pathFileRels = pathFolderRels + FILE_SEPARATOR_STR + strMasterXml + L".rels";
m_oReader.m_pRels->SaveRels(pathFileRels.GetPath());
}
}
@ -770,28 +846,28 @@ namespace NSBinPptxRW
oXmlWriter.ClearNoAttack();
m_oApp.toXmlWriter(&oXmlWriter);
OOX::CPath pathApp = m_strDstFolder + FILE_SEPARATOR_STR + _T("docProps") + FILE_SEPARATOR_STR + _T("app.xml");
OOX::CPath pathApp = m_strDstFolder + FILE_SEPARATOR_STR + L"docProps" + FILE_SEPARATOR_STR + L"app.xml";
oXmlWriter.SaveToFile(pathApp.GetPath());
// core
oXmlWriter.ClearNoAttack();
m_oCore.toXmlWriter(&oXmlWriter);
OOX::CPath pathCore = m_strDstFolder + FILE_SEPARATOR_STR + _T("docProps") + FILE_SEPARATOR_STR + _T("core.xml");
OOX::CPath pathCore = m_strDstFolder + FILE_SEPARATOR_STR + L"docProps" + FILE_SEPARATOR_STR + L"core.xml";
oXmlWriter.SaveToFile(pathCore.GetPath());
// presProps
oXmlWriter.ClearNoAttack();
m_oPresProps.toXmlWriter(&oXmlWriter);
OOX::CPath pathPresProps = m_strDstFolder + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("presProps.xml");
OOX::CPath pathPresProps = m_strDstFolder + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"presProps.xml";
oXmlWriter.SaveToFile(pathPresProps.GetPath());
// viewProps
oXmlWriter.ClearNoAttack();
m_oViewProps.toXmlWriter(&oXmlWriter);
OOX::CPath pathViewProps = m_strDstFolder + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("viewProps.xml");
OOX::CPath pathViewProps = m_strDstFolder + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"viewProps.xml";
oXmlWriter.SaveToFile(pathViewProps.GetPath());
m_oReader.m_pRels->Clear();
@ -816,15 +892,15 @@ namespace NSBinPptxRW
oXmlWriter.ClearNoAttack();
m_oCustomProperties->toXmlWriter(&oXmlWriter);
OOX::CPath pathCore = m_strDstFolder + FILE_SEPARATOR_STR + _T("docProps") + FILE_SEPARATOR_STR + OOX::FileTypes::CustomProperties.DefaultFileName().GetPath();
OOX::CPath pathCore = m_strDstFolder + FILE_SEPARATOR_STR + L"docProps" + FILE_SEPARATOR_STR + OOX::FileTypes::CustomProperties.DefaultFileName().GetPath();
oXmlWriter.SaveToFile(pathCore.GetPath());
}
// customs
pPair = m_mainTables.find(NSBinPptxRW::NSMainTables::Customs);
if (m_mainTables.end() != pPair)
{
OOX::CPath pathFolder = m_strDstFolder + FILE_SEPARATOR_STR + _T("customXml");
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + _T("_rels");
OOX::CPath pathFolder = m_strDstFolder + FILE_SEPARATOR_STR + L"customXml";
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + L"_rels";
NSDirectory::CreateDirectory(pathFolder.GetPath());
NSDirectory::CreateDirectory(pathFolderRels.GetPath());
@ -849,15 +925,15 @@ namespace NSBinPptxRW
oXmlWriter.ClearNoAttack();
m_oTableStyles.toXmlWriter(&oXmlWriter);
OOX::CPath pathTableStyles = m_strDstFolder + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("tableStyles.xml");
OOX::CPath pathTableStyles = m_strDstFolder + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"tableStyles.xml";
oXmlWriter.SaveToFile(pathTableStyles.GetPath());
// presentation
pPair = m_mainTables.find(NSBinPptxRW::NSMainTables::Presentation);
if (m_mainTables.end() != pPair)
{
OOX::CPath pathFolder = m_strDstFolder + FILE_SEPARATOR_STR + _T("ppt");
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + _T("_rels");
OOX::CPath pathFolder = m_strDstFolder + FILE_SEPARATOR_STR + L"ppt";
OOX::CPath pathFolderRels = pathFolder + FILE_SEPARATOR_STR + L"_rels";
NSDirectory::CreateDirectory(pathFolderRels.GetPath());
@ -904,9 +980,16 @@ namespace NSBinPptxRW
m_oPresentation.notesMasterIdLst[0].rid = m_oReader.m_pRels->m_lNextRelsID;
m_oReader.m_pRels->WriteNotesMaster();
}
if (bHandoutMasterPresent)
{
m_oPresentation.handoutMasterIdLst.push_back(PPTX::Logic::XmlId(L"p:handoutMasterId"));
m_oPresentation.handoutMasterIdLst[0].rid = m_oReader.m_pRels->m_lNextRelsID;
m_oReader.m_pRels->WriteHandoutMaster();
}
if (m_oPresentation.comments.is_init())
{
OOX::CPath pathFolderCommentDir = m_strDstFolder + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("comments");
OOX::CPath pathFolderCommentDir = m_strDstFolder + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"comments";
if (1 == nComment)
{
NSDirectory::CreateDirectory(pathFolderCommentDir.GetPath());
@ -989,7 +1072,11 @@ namespace NSBinPptxRW
{
pContentTypes->Registration(L"application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml", L"/ppt/notesMasters", L"notesMaster1.xml");
}
// handout master
if (!m_arHandoutMasters.empty())
{
pContentTypes->Registration(L"application/vnd.openxmlformats-officedocument.presentationml.handoutMaster+xml", L"/ppt/handoutMasters", L"handoutMaster1.xml");
}
// masters
for (LONG i = 0; i < nCountMasters; ++i)
{
@ -1017,21 +1104,21 @@ namespace NSBinPptxRW
pContentTypes->Write(m_strDstFolder);
std::wstring strRELS = _T("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\
std::wstring strRELS = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\
<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\
<Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\" Target=\"docProps/core.xml\"/>\
<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"ppt/presentation.xml\"/>\
<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\" Target=\"docProps/app.xml\"/>");
<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\" Target=\"docProps/app.xml\"/>";
if (m_oCustomProperties.IsInit())
{
strRELS += L"<Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties\" Target=\"docProps/custom.xml\"/>";
}
strRELS += L"</Relationships>";
OOX::CPath filePathRels = m_strDstFolder + FILE_SEPARATOR_STR + _T("_rels");
OOX::CPath filePathRels = m_strDstFolder + FILE_SEPARATOR_STR + L"_rels";
NSDirectory::CreateDirectory(filePathRels.GetPath());
filePathRels = filePathRels + FILE_SEPARATOR_STR + _T(".rels");
filePathRels = filePathRels + FILE_SEPARATOR_STR + L".rels";
NSFile::CFileBinary oFile;
oFile.CreateFileW(filePathRels.GetPath());
@ -1131,16 +1218,16 @@ namespace NSBinPptxRW
int nCountSlides = (int)m_arSlides.size();
m_oApp.HeadingPairs.push_back(PPTX::Logic::HeadingVariant());
m_oApp.HeadingPairs[0].m_type = _T("lpstr");
m_oApp.HeadingPairs[0].m_strContent = _T("Theme");
m_oApp.HeadingPairs[0].m_type = L"lpstr";
m_oApp.HeadingPairs[0].m_strContent = L"Theme";
m_oApp.HeadingPairs.push_back(PPTX::Logic::HeadingVariant());
m_oApp.HeadingPairs[1].m_type = _T("i4");
m_oApp.HeadingPairs[1].m_type = L"i4";
m_oApp.HeadingPairs[1].m_iContent = nCountThemes;
m_oApp.HeadingPairs.push_back(PPTX::Logic::HeadingVariant());
m_oApp.HeadingPairs[2].m_type = _T("lpstr");
m_oApp.HeadingPairs[2].m_strContent = _T("Slide Titles");
m_oApp.HeadingPairs[2].m_type = L"lpstr";
m_oApp.HeadingPairs[2].m_strContent = L"Slide Titles";
m_oApp.HeadingPairs.push_back(PPTX::Logic::HeadingVariant());
m_oApp.HeadingPairs[3].m_type = _T("i4");
m_oApp.HeadingPairs[3].m_type = L"i4";
m_oApp.HeadingPairs[3].m_iContent = nCountSlides;
for (int i = 0; i < nCountThemes; ++i)
@ -1184,8 +1271,7 @@ namespace NSBinPptxRW
}
void CPPTXWriter::CreateDefaultCore()
{
// m_oCore.creator = _T("");
m_oCore.m_sLastModifiedBy = _T("");
m_oCore.m_sLastModifiedBy = L"";
}
void CPPTXWriter::CreateDefaultViewProps()
{
@ -1203,7 +1289,7 @@ namespace NSBinPptxRW
m_oViewProps.SlideViewPr->CSldViewPr.CViewPr.Origin.y = -90;
m_oViewProps.SlideViewPr->CSldViewPr.GuideLst.push_back(PPTX::nsViewProps::Guide());
m_oViewProps.SlideViewPr->CSldViewPr.GuideLst[0].orient = _T("horz");
m_oViewProps.SlideViewPr->CSldViewPr.GuideLst[0].orient = L"horz";
m_oViewProps.SlideViewPr->CSldViewPr.GuideLst[0].pos = 2160;
m_oViewProps.SlideViewPr->CSldViewPr.GuideLst.push_back(PPTX::nsViewProps::Guide());
m_oViewProps.SlideViewPr->CSldViewPr.GuideLst[1].pos = 2880;
@ -1222,7 +1308,7 @@ namespace NSBinPptxRW
}
void CPPTXWriter::CreateDefaultTableStyles()
{
m_oTableStyles.def = _T("{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}");
m_oTableStyles.def = L"{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}";
}
void CPPTXWriter::CreateDefaultPresProps()
{
@ -1230,38 +1316,65 @@ namespace NSBinPptxRW
}
void CPPTXWriter::CreateDefaultNotesMasters(int nIndexTheme)
{
std::wstring strThemeNotes = L"theme" + std::to_wstring( nIndexTheme ) + L".xml";
std::wstring strThemeNotes = L"theme" + std::to_wstring(nIndexTheme) + L".xml";
OOX::CPath pathNotesTheme = m_oReader.m_strFolderThemes + FILE_SEPARATOR_STR + strThemeNotes;
Writers::DefaultNotesThemeWriter notesTheme;
notesTheme.Write(pathNotesTheme.GetPath());
/////////////////////
OOX::CPath pathNotesMasters = m_strDstFolder + FILE_SEPARATOR_STR + _T("ppt") + FILE_SEPARATOR_STR + _T("notesMasters");
/////////////////////
OOX::CPath pathNotesMasters = m_strDstFolder + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"notesMasters";
NSDirectory::CreateDirectory(pathNotesMasters.GetPath());
OOX::CPath pathNotesMaster1 = pathNotesMasters / _T("notesMaster1.xml");
OOX::CPath pathNotesMaster1 = pathNotesMasters / L"notesMaster1.xml";
Writers::DefaultNotesMasterWriter notesMaster;
notesMaster.Write(pathNotesMaster1.GetPath());
OOX::CPath pathNotesMasterRels = pathNotesMasters / _T("_rels");
OOX::CPath pathNotesMasterRels = pathNotesMasters / L"_rels";
NSDirectory::CreateDirectory(pathNotesMasterRels.GetPath());
std::wstring strThemeNotesNum = std::to_wstring(nIndexTheme);
std::wstring strVal = _T("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\
std::wstring strVal = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\
<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\
<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\" Target=\"../theme/theme") + strThemeNotesNum + _T(".xml\"/></Relationships>");
<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\" Target=\"../theme/theme" + strThemeNotesNum + L".xml\"/></Relationships>";
NSFile::CFileBinary oFileRels;
oFileRels.CreateFile(pathNotesMasterRels.GetPath() + FILE_SEPARATOR_STR + _T("notesMaster1.xml.rels"));
oFileRels.CreateFile(pathNotesMasterRels.GetPath() + FILE_SEPARATOR_STR + L"notesMaster1.xml.rels");
oFileRels.WriteStringUTF8(strVal);
oFileRels.CloseFile();
}
void CPPTXWriter::CreateDefaultHandoutMasters(int nIndexTheme)
{
std::wstring strThemeNotes = L"theme" + std::to_wstring(nIndexTheme) + L".xml";
OOX::CPath pathNotesTheme = m_oReader.m_strFolderThemes + FILE_SEPARATOR_STR + strThemeNotes;
Writers::DefaultNotesThemeWriter notesTheme;
notesTheme.Write(pathNotesTheme.GetPath());
/////////////////////
OOX::CPath pathHandoutMasters = m_strDstFolder + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"handoutMasters";
NSDirectory::CreateDirectory(pathHandoutMasters.GetPath());
OOX::CPath pathNotesMaster1 = pathHandoutMasters / L"handoutMaster1.xml";
Writers::DefaultHandoutMasterWriter handoutMaster;
handoutMaster.Write(pathHandoutMasters.GetPath());
OOX::CPath pathHandoutMasterRels = pathHandoutMasters / L"_rels";
NSDirectory::CreateDirectory(pathHandoutMasterRels.GetPath());
std::wstring strThemeHandoutNum = std::to_wstring(nIndexTheme);
std::wstring strVal = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\
<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\
<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\" Target=\"../theme/theme" + strThemeHandoutNum + L".xml\"/></Relationships>";
NSFile::CFileBinary oFileRels;
oFileRels.CreateFile(pathHandoutMasterRels.GetPath() + FILE_SEPARATOR_STR + L"handoutMaster1.xml.rels");
oFileRels.WriteStringUTF8(strVal);
oFileRels.CloseFile();
}
void CPPTXWriter::CreateDefaultNote()
{
PPTX::Logic::NvGrpSpPr& nvGrpSpPr = m_oDefaultNote.cSld.spTree.nvGrpSpPr;
nvGrpSpPr.cNvPr.id = 1;
nvGrpSpPr.cNvPr.name = _T("");
nvGrpSpPr.cNvPr.name = L"";
PPTX::Logic::Xfrm* xfrm = new PPTX::Logic::Xfrm();
xfrm->offX = 0;
@ -1278,22 +1391,22 @@ namespace NSBinPptxRW
// shape comment !!! (TODO:)
PPTX::Logic::Shape* pShape = new PPTX::Logic::Shape();
pShape->nvSpPr.cNvPr.id = 100000;
pShape->nvSpPr.cNvPr.name = _T("");
pShape->nvSpPr.cNvPr.name = L"";
pShape->nvSpPr.cNvSpPr.noGrp = true;
pShape->nvSpPr.cNvSpPr.noChangeArrowheads = true;
pShape->nvSpPr.nvPr.ph = new PPTX::Logic::Ph();
pShape->nvSpPr.nvPr.ph->type = _T("body");
pShape->nvSpPr.nvPr.ph->idx = _T("1");
pShape->nvSpPr.nvPr.ph->type = L"body";
pShape->nvSpPr.nvPr.ph->idx = L"1";
PPTX::Logic::TxBody* pTxBody = new PPTX::Logic::TxBody();
pTxBody->Paragrs.push_back(PPTX::Logic::Paragraph());
PPTX::Logic::Run* pTxRun = new PPTX::Logic::Run();
PPTX::Logic::Run* pTxRun = new PPTX::Logic::Run();
pTxRun->rPr = new PPTX::Logic::RunProperties();
pTxRun->rPr->smtClean = false;
pTxRun->SetText(_T("")); // enter simple comment here
pTxRun->SetText(L""); // enter simple comment here
pShape->txBody = pTxBody;
if (pShape->txBody.IsInit())

View File

@ -39,6 +39,7 @@
#include "../../PPTXFormat/NotesSlide.h"
#include "../../DocxFormat/VmlDrawing.h"
#include "../../PPTXFormat/HandoutMaster.h"
namespace NSBinPptxRW
{
@ -68,6 +69,10 @@ namespace NSBinPptxRW
std::vector<LONG> m_arNotesSlides_Master;
std::vector<LONG> m_arNotesMasters_Theme;
std::vector<PPTX::HandoutMaster> m_arHandoutMasters;
std::vector<LONG> m_arHandoutSlides_Master;
std::vector<LONG> m_arHandoutMasters_Theme;
PPTX::Document m_oDocument;
PPTX::Presentation m_oPresentation;
PPTX::TableStyles m_oTableStyles;
@ -100,6 +105,7 @@ namespace NSBinPptxRW
void CreateDefaultTableStyles();
void CreateDefaultPresProps();
void CreateDefaultNotesMasters(int nIndexTheme);
void CreateDefaultHandoutMasters(int nIndexTheme);
void CreateDefaultNote();
};
}

View File

@ -192,7 +192,7 @@ namespace OOX
L"diagrams/data", true, true);
const FileType DiagramQuickStyle(L"diagrams", L"quickStyle.xml",
L"application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml",
L"application/vnd.openxmlformats-officedocument.drawingml.diagramQuickStyle+xml",
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramQuickStyle",
L"diagrams/quickStyle", true, true);

View File

@ -43,6 +43,7 @@
#include "Slide.h"
#include "NotesMaster.h"
#include "NotesSlide.h"
#include "HandoutMaster.h"
#include <map>
@ -152,6 +153,18 @@ namespace PPTX
}
}
for (std::map<std::wstring, smart_ptr<OOX::File>>::const_iterator pPair = map.m_map.begin(); pPair != map.m_map.end(); ++pPair)
{
const OOX::FileType& curType = pPair->second->type();
if (OOX::Presentation::FileTypes::HandoutMaster == curType)
{
smart_ptr<PPTX::HandoutMaster> pointer = pPair->second.smart_dynamic_cast<PPTX::HandoutMaster>();
if (pointer.is_init())
pointer->ApplyRels();
}
}
for (std::map<std::wstring, smart_ptr<OOX::File>>::const_iterator pPair = map.m_map.begin(); pPair != map.m_map.end(); ++pPair)
{
const OOX::FileType& curType = pPair->second->type();

View File

@ -51,17 +51,90 @@ namespace PPTX
XmlUtils::CXmlNode oNode;
oNode.FromXmlFile(filename.m_strFilename);
cSld = oNode.ReadNode(_T("p:cSld"));
cSld = oNode.ReadNode(L"p:cSld");
cSld.SetParentFilePointer(this);
clrMap = oNode.ReadNode(_T("p:clrMap"));
clrMap = oNode.ReadNode(L"p:clrMap");
clrMap.SetParentFilePointer(this);
hf = oNode.ReadNode(_T("p:hf"));
hf = oNode.ReadNode(L"p:hf");
if (hf.is_init())
hf->SetParentFilePointer(this);
}
void HandoutMaster::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const
{
pWriter->StartRecord(NSBinPptxRW::NSMainTables::HandoutMasters);
pWriter->WriteRecord1(0, cSld);
pWriter->WriteRecord1(1, clrMap);
pWriter->WriteRecord2(2, hf);
pWriter->EndRecord();
}
void HandoutMaster::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const
{
pWriter->StartNode(L"p:handoutMaster");
pWriter->StartAttributes();
pWriter->WriteAttribute(L"xmlns:a", PPTX::g_Namespaces.a.m_strLink);
pWriter->WriteAttribute(L"xmlns:r", PPTX::g_Namespaces.r.m_strLink);
pWriter->WriteAttribute(L"xmlns:p", PPTX::g_Namespaces.p.m_strLink);
pWriter->EndAttributes();
cSld.toXmlWriter(pWriter);
clrMap.toXmlWriter(pWriter);
pWriter->Write(hf);
pWriter->EndNode(L"p:handoutMaster");
}
void HandoutMaster::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader)
{
pReader->Skip(1); // type
LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4;
while (pReader->GetPos() < end)
{
BYTE _rec = pReader->GetUChar();
switch (_rec)
{
case 0:
{
cSld.fromPPTY(pReader);
break;
}
case 1:
{
clrMap.fromPPTY(pReader);
break;
}
case 2:
{
hf = new Logic::HF();
hf->fromPPTY(pReader);
break;
}
default:
{
pReader->SkipRecord();
break;
}
}
}
pReader->Seek(end);
}
void HandoutMaster::ApplyRels()
{
theme_ = (FileContainer::Get(OOX::FileTypes::Theme)).smart_dynamic_cast<PPTX::Theme>();
if (theme_.IsInit())
{
theme_->SetColorMap(clrMap);
}
}
void HandoutMaster::write(const OOX::CPath& filename, const OOX::CPath& directory, OOX::CContentTypes& content)const
{
WrapperFile::write(filename, directory, content);

View File

@ -52,19 +52,24 @@ namespace PPTX
HandoutMaster(OOX::Document* pMain, const OOX::CPath& filename, FileMap& map);
virtual ~HandoutMaster();
public:
virtual void read(const OOX::CPath& filename, FileMap& map);
virtual void write(const OOX::CPath& filename, const OOX::CPath& directory, OOX::CContentTypes& content) const;
public:
virtual const OOX::FileType type() const;
virtual const OOX::CPath DefaultDirectory() const;
virtual const OOX::CPath DefaultFileName() const;
public:
Logic::CSld cSld;
Logic::ClrMap clrMap;
virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const;
virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const;
virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader);
void ApplyRels();
Logic::CSld cSld;
Logic::ClrMap clrMap;
nullable<Logic::HF> hf;
smart_ptr<Theme> theme_;
};
} // namespace PPTX

View File

@ -56,17 +56,17 @@ namespace PPTX
XmlUtils::CXmlNode oNode;
oNode.FromXmlFile(filename.m_strFilename);
cSld = oNode.ReadNode(_T("p:cSld"));
cSld = oNode.ReadNode(L"p:cSld");
cSld.SetParentFilePointer(this);
clrMap = oNode.ReadNode(_T("p:clrMap"));
clrMap = oNode.ReadNode(L"p:clrMap");
clrMap.SetParentFilePointer(this);
hf = oNode.ReadNode(_T("p:hf"));
hf = oNode.ReadNode(L"p:hf");
if (hf.IsInit())
hf->SetParentFilePointer(this);
notesStyle = oNode.ReadNode(_T("p:notesStyle"));
notesStyle = oNode.ReadNode(L"p:notesStyle");
if (notesStyle.is_init())
notesStyle->SetParentFilePointer(this);
}
@ -111,12 +111,12 @@ namespace PPTX
}
void NotesMaster::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const
{
pWriter->StartNode(_T("p:notesMaster"));
pWriter->StartNode(L"p:notesMaster");
pWriter->StartAttributes();
pWriter->WriteAttribute(_T("xmlns:a"), PPTX::g_Namespaces.a.m_strLink);
pWriter->WriteAttribute(_T("xmlns:r"), PPTX::g_Namespaces.r.m_strLink);
pWriter->WriteAttribute(_T("xmlns:p"), PPTX::g_Namespaces.p.m_strLink);
pWriter->WriteAttribute(L"xmlns:a", PPTX::g_Namespaces.a.m_strLink);
pWriter->WriteAttribute(L"xmlns:r", PPTX::g_Namespaces.r.m_strLink);
pWriter->WriteAttribute(L"xmlns:p", PPTX::g_Namespaces.p.m_strLink);
pWriter->EndAttributes();
cSld.toXmlWriter(pWriter);
@ -125,7 +125,7 @@ namespace PPTX
pWriter->Write(hf);
pWriter->Write(notesStyle);
pWriter->EndNode(_T("p:notesMaster"));
pWriter->EndNode(L"p:notesMaster");
}
void NotesMaster::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader)
{
@ -198,8 +198,8 @@ namespace PPTX
{
if (pMasterShape->nvSpPr.nvPr.ph.is_init())
{
std::wstring lIdx = pMasterShape->nvSpPr.nvPr.ph->idx.get_value_or(_T(""));
std::wstring lType = pMasterShape->nvSpPr.nvPr.ph->type.get_value_or(_T("body"));
std::wstring lIdx = pMasterShape->nvSpPr.nvPr.ph->idx.get_value_or(L"");
std::wstring lType = pMasterShape->nvSpPr.nvPr.ph->type.get_value_or(L"body");
if (lType == L"ctrTitle") lType = L"title";

View File

@ -30,8 +30,6 @@
*
*/
#pragma once
#ifndef PPTX_SLIDES_NOTESSLIDE_INCLUDE_H_
#define PPTX_SLIDES_NOTESSLIDE_INCLUDE_H_
#include "WrapperFile.h"
#include "FileContainer.h"
@ -79,5 +77,3 @@ namespace PPTX
smart_ptr<Theme> theme_;
};
} // namespace PPTX
#endif // PPTX_SLIDES_NOTESSLIDE_INCLUDE_H_

View File

@ -2083,7 +2083,7 @@ int docx_conversion_context::process_paragraph_style(_CP_OPT(std::wstring) style
else
{
const std::wstring id = styles_map_.get( styleInst->name(), styleInst->type() );
output_stream() << L"<w:pPr>";
output_stream() << L"<w:pPr>";
output_stream() << L"<w:pStyle w:val=\"" << id << L"\" />";
@ -2315,7 +2315,7 @@ void docx_conversion_context::process_page_break_after(const odf_reader::style_i
if (inst->content() && inst->content()->get_style_paragraph_properties())
{
_CP_OPT(odf_types::fo_break) fo_break_val = inst->content()->get_style_paragraph_properties()->content_.fo_break_after_;
if (fo_break_val)
if (fo_break_val)
{
set_page_break_after(fo_break_val->get_type());
break;

View File

@ -672,12 +672,8 @@ void _oox_drawing::serialize_bodyPr(std::wostream & strm, const std::wstring & n
_CP_OPT(int) iWrap;
odf_reader::GetProperty(prop, L"text-wrap", iWrap);
if (((iWrap) && (*iWrap == 0))) // для текста устанавливаем значение square. Так у нас визуальное соотвествие при конвертации
CP_XML_ATTR(L"wrap", L"square");
else if((is_math_formula) && (*is_math_formula))
{
if (((iWrap) && (*iWrap == 0)) || ((is_math_formula) && (*is_math_formula)))
CP_XML_ATTR(L"wrap", L"none");
}
}
}

View File

@ -366,7 +366,7 @@ void line_break::docx_convert(oox::docx_conversion_context & Context)
{
bool in_drawing = false;
if (Context.get_drawing_context().get_current_shape() || Context.get_drawing_context().get_current_frame())
if (Context.get_drawing_context().get_current_shape() || Context.get_drawing_context().get_current_frame())
{
in_drawing = true;

View File

@ -4350,14 +4350,14 @@ void CPdfEditor::ScanAndProcessFonts(PDFDoc* pPDFDocument, XRef* xref, Dict* pRe
{
Ref oEmbRef;
std::wstring wsFontBaseName = NSStrings::GetStringFromUTF32(gfxFont->getName());
GfxFontLoc* pFontLoc = NULL;
if (gfxFont->getEmbeddedFontID(&oEmbRef) || PdfReader::IsBaseFont(wsFontBaseName) || ((pFontLoc = gfxFont->locateFont(xref, false)) && NSStrings::GetStringFromUTF32(pFontLoc->path).length()))
if (gfxFont->getEmbeddedFontID(&oEmbRef) || PdfReader::IsBaseFont(wsFontBaseName))
{
std::wstring wsFileName, wsFontName;
PdfReader::RendererOutputDev::GetFont(xref, pFontManager, pFontList, gfxFont, wsFileName, wsFontName, false);
// Собираем информацию о встроенном шрифте
if (!PdfReader::IsBaseFont(wsFontBaseName))
if (gfxFont->getEmbeddedFontID(&oEmbRef) && !PdfReader::IsBaseFont(wsFontBaseName))
{
PdfReader::TFontEntry pFontEntry;
Ref nFontRef = oFontRef.getRef();
@ -4384,7 +4384,6 @@ void CPdfEditor::ScanAndProcessFonts(PDFDoc* pPDFDocument, XRef* xref, Dict* pRe
}
}
RELEASEOBJECT(pFontLoc);
RELEASEOBJECT(gfxFont);
}

View File

@ -102,23 +102,11 @@ void CPdfFile::Close()
else if (m_pInternal->pReader)
m_pInternal->pReader->Close();
}
void CPdfFile::Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath)
void CPdfFile::Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate)
{
if (!m_pInternal->pWriter)
return;
m_pInternal->pWriter->Sign(dX, dY, dW, dH, wsPicturePath);
}
bool CPdfFile::PrepareSignature(BYTE** pDataToSign, DWORD& dwDataLength)
{
if (!m_pInternal->pWriter)
return false;
return m_pInternal->pWriter->PrepareSignature(pDataToSign, dwDataLength);
}
bool CPdfFile::FinalizeSignature(BYTE* pSignedData, DWORD dwDataLength)
{
if (!m_pInternal->pWriter)
return false;
return m_pInternal->pWriter->FinalizeSignature(pSignedData, dwDataLength);
m_pInternal->pWriter->Sign(dX, dY, dW, dH, wsPicturePath, pCertificate);
}
void CPdfFile::SetDocumentInfo(const std::wstring& wsTitle, const std::wstring& wsCreator, const std::wstring& wsSubject, const std::wstring& wsKeywords)
{
@ -146,12 +134,6 @@ bool CPdfFile::EditPdf(const std::wstring& wsDstFile)
m_pInternal->pEditor = new CPdfEditor(m_pInternal->wsSrcFile, m_pInternal->wsPassword, wsDstFile, m_pInternal->pReader, m_pInternal->pWriter);
return m_pInternal->pEditor->GetError() == 0;
}
void CPdfFile::EditClose()
{
if (m_pInternal->pEditor)
m_pInternal->pEditor->Close();
RELEASEOBJECT(m_pInternal->pEditor);
}
void CPdfFile::SetEditType(int nType)
{
if (!m_pInternal->pEditor)
@ -1090,30 +1072,12 @@ HRESULT CPdfFile::put_FontName(const std::wstring& wsName)
}
m_pInternal->pWriter->AddFont(wsFont, bBold, bItalic, wsFontPath, 0);
}
else if (wsFontPath.empty())
else
{
size_t lastSpace = wsName.find_last_of(L' ');
if (lastSpace != std::wstring::npos)
{
std::wstring numberStr = wsName.substr(lastSpace + 1);
int nTargetCode = std::stoi(numberStr);
const std::map<std::wstring, std::wstring>& mFonts = m_pInternal->pReader->GetFonts();
auto it = std::find_if(mFonts.begin(), mFonts.end(), [nTargetCode](const std::pair<const std::wstring, std::wstring>& pair)
{
const std::wstring& key = pair.first;
size_t pos = key.rfind(L' ');
if (pos != std::wstring::npos)
{
int keyCode = std::stoi(key.substr(pos + 1));
return keyCode == nTargetCode;
}
return false;
});
if (it != mFonts.end())
wsFont = L"Embedded: " + it->first;
else
wsFont = wsName.substr(10, lastSpace - 10);
}
const std::map<std::wstring, std::wstring>& mFonts = m_pInternal->pReader->GetFonts();
auto it = mFonts.find(sSub);
if (it != mFonts.end())
wsFontPath = it->second;
else
wsFont = sSub;
}

View File

@ -92,7 +92,6 @@ public:
// --- EDIT ---
// Переходит в режим редактирования. Pdf уже должен быть открыт на чтение - LoadFromFile/LoadFromMemory
bool EditPdf(const std::wstring& wsDstFile = L"");
void EditClose();
void SetEditType(int nType);
// Манипуляции со страницами возможны в режиме редактирования
bool EditPage (int nPageIndex);
@ -160,9 +159,7 @@ public:
void RotatePage (int nRotate);
void SetPassword (const std::wstring& wsPassword);
void SetDocumentID(const std::wstring& wsDocumentID);
void Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath);
bool PrepareSignature(BYTE** pDataToSign, DWORD& dwDataLength);
bool FinalizeSignature(BYTE* pSignedData, DWORD dwDataLength);
void Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate);
void SetDocumentInfo(const std::wstring& wsTitle, const std::wstring& wsCreator, const std::wstring& wsSubject, const std::wstring& wsKeywords);
void AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength);

View File

@ -3238,13 +3238,7 @@ bool CPdfWriter::EditClose()
{
if (oInfo.pDest)
{
PdfWriter::CObjectBase* pDestPage = m_pDocument->GetPageObj(oInfo.unDestPage);
if (pDestPage->GetType() == PdfWriter::object_type_UNKNOWN)
{
PdfWriter::CObjectBase* pBase = new PdfWriter::CObjectBase();
pBase->SetRef(pDestPage->GetObjId(), pDestPage->GetGenNo());
pDestPage = new PdfWriter::CProxyObject(pBase, true);
}
PdfWriter::CPage* pDestPage = m_pDocument->GetPage(oInfo.unDestPage);
oInfo.pDest->ChangePage(pDestPage);
}
else
@ -3262,7 +3256,7 @@ void CPdfWriter::PageRotate(int nRotate)
if (m_pPage)
m_pPage->SetRotate(nRotate);
}
void CPdfWriter::Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath)
void CPdfWriter::Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate)
{
PdfWriter::CImageDict* pImage = NULL;
if (!wsPicturePath.empty())
@ -3271,21 +3265,9 @@ void CPdfWriter::Sign(const double& dX, const double& dY, const double& dW, cons
pImage = LoadImage(&oImage, 255);
}
m_pDocument->Sign(PdfWriter::TRect(MM_2_PT(dX), m_pPage->GetHeight() - MM_2_PT(dY), MM_2_PT(dX + dW), m_pPage->GetHeight() - MM_2_PT(dY + dH)), pImage);
m_pDocument->Sign(PdfWriter::TRect(MM_2_PT(dX), m_pPage->GetHeight() - MM_2_PT(dY), MM_2_PT(dX + dW), m_pPage->GetHeight() - MM_2_PT(dY + dH)),
pImage, pCertificate);
}
bool CPdfWriter::PrepareSignature(BYTE** pDataToSign, DWORD& dwDataLength)
{
if (!m_pDocument)
return false;
return m_pDocument->PrepareSignature(pDataToSign, dwDataLength);
}
bool CPdfWriter::FinalizeSignature(BYTE* pSignedData, DWORD dwDataLength)
{
if (!m_pDocument)
return false;
return m_pDocument->FinalizeSignature(pSignedData, dwDataLength);
}
//----------------------------------------------------------------------------------------
// Внутренние функции
//----------------------------------------------------------------------------------------

View File

@ -225,9 +225,7 @@ public:
bool AddPage(int nPageIndex);
bool EditClose();
void PageRotate(int nRotate);
void Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath);
bool PrepareSignature(BYTE** pDataToSign, DWORD& dwDataLength);
bool FinalizeSignature(BYTE* pSignedData, DWORD dwDataLength);
void Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate);
PdfWriter::CDocument* GetDocument();
PdfWriter::CPage* GetPage();
IRenderer* GetRenderer();

View File

@ -1461,8 +1461,6 @@ namespace PdfReader
wsFontName = wsFontBaseName;
if (bNotFullName)
EraseSubsetTag(wsFontName);
else
wsFontName += (L" " + std::to_wstring(pFont->getID()->num));
pEntry->wsFilePath = wsFileName;
pEntry->wsFontName = wsFontName;

View File

@ -232,7 +232,7 @@ namespace PdfWriter
SaveToStream((CStream*)pStream);
delete pStream;
Sign(wsPath, m_pXref->GetSizeXRef() + 1, true);
Sign(wsPath, m_pXref->GetSizeXRef());
return true;
}
@ -424,12 +424,6 @@ namespace PdfWriter
return m_pPageTree->GetPage(unPage);
}
CObjectBase* CDocument::GetPageObj(const unsigned int& unPage)
{
if (unPage >= m_pPageTree->GetCount())
return NULL;
return m_pPageTree->GetObj(unPage);
}
CPage* CDocument::GetEditPage(const unsigned int& unPage)
{
CPage* pRes = NULL;
@ -907,10 +901,7 @@ namespace PdfWriter
{
CFontEmbedded* pFont = FindFontEmbedded(wsFontPath, unIndex);
if (pFont)
{
pFont->UpdateKey(sFontKey);
return pFont;
}
pFont = new CFontEmbedded(m_pXref, this);
pFont->LoadFont(sFontKey, nType, mCodeToWidth, mCodeToUnicode, mCodeToGID);
m_vFontsEmbedded.push_back(TFontInfo(wsFontPath, unIndex, pFont));
@ -1956,210 +1947,96 @@ namespace PdfWriter
unsigned int nSizeXRef = m_pXref->GetSizeXRef() + (bNeedStreamXRef ? 1 : 0);
m_pXref = m_pLastXref;
Sign(wsPath, nSizeXRef, bNeedStreamXRef);
RELEASEOBJECT(m_pEncryptDict);
return true;
}
void CDocument::Sign(const TRect& oRect, CImageDict* pImage)
void CDocument::Sign(const TRect& oRect, CImageDict* pImage, ICertificate* pCertificate)
{
m_vSignatures.push_back(new TSignatureInfo(oRect, m_pCurPage ? m_pCurPage : m_pPageTree->GetPage(0), pImage));
m_vSignatures.push_back({ oRect, m_pCurPage ? m_pCurPage : m_pPageTree->GetPage(0), pImage, pCertificate });
}
bool CDocument::PrepareSignature(BYTE** pDataToSign, DWORD& dwDataLength)
void CDocument::Sign(const std::wstring& wsPath, unsigned int nSizeXRef, bool bNeedStreamXRef)
{
// Сначала нужно сохранить основной файл
// Это должно быть сделано в AddToFile или SaveToFile ПЕРЕД вызовом этого метода
if (m_vSignatures.empty())
return false;
TSignatureInfo* pSI = m_vSignatures[0];
std::wstring wsPath = pSI->wsPath;
if (wsPath.empty())
return false;
unsigned int nSizeXRef = pSI->nSizeXRef;
bool bNeedStreamXRef = pSI->bNeedStreamXRef;
// Создаем новый XRef для этой подписи
CXref* pXrefBefore = m_pXref;
m_pXref = new CXref(this, nSizeXRef);
if (!m_pXref)
unsigned int nPrevAddr = m_pXref->GetPrevAddr();
std::vector<CXref*> vXRefForWrite;
for (unsigned int i = 0; i < m_vSignatures.size(); i++)
{
m_pXref = pXrefBefore;
return false;
}
if (!pSI->nPrevAddr)
pSI->nPrevAddr = pXrefBefore->GetPrevAddr();
m_pXref->SetPrevAddr(pSI->nPrevAddr);
// Создаем поле подписи
CSignatureField* pField = CreateSignatureField();
if (!pField)
{
delete m_pXref;
m_pXref = pXrefBefore;
return false;
}
// Настраиваем поле
pSI->pField = pField;
m_pAcroForm->Add("SigFlags", 3);
pField->GetSignatureDict()->SetDate();
pField->AddPageRect(pSI->pPage, pSI->oRect);
pField->Add("F", 132);
pField->SetFieldName("Sig" + std::to_string(++m_unFormFields));
if (pSI->pImage)
pField->SetAppearance(pSI->pImage);
// Открываем файл для дозаписи
CFileStream* pStream = new CFileStream();
if (!pStream || !pStream->OpenFile(wsPath, false))
{
delete m_pXref;
m_pXref = pXrefBefore;
return false;
}
pSI->nFileSizeBefore = pStream->Size();
// Вычисляем размер для Contents
unsigned int nContentsSize = 7000 + pStream->Size() / 1000 + 1000;
if (nContentsSize < 5000)
nContentsSize = 5000;
if (nContentsSize > 20000)
nContentsSize = 20000;
pField->GetSignatureDict()->SetContentsSize(nContentsSize);
// Записываем XRef и получаем информацию о расположении
CXref* pXrefCatalog = new CXref(this, m_pCatalog->GetObjId());
if (pXrefCatalog)
{
pXrefCatalog->Add(m_pCatalog->Copy(), m_pCatalog->GetGenNo());
pXrefCatalog->SetPrev(m_pXref);
}
CXref* pXrefPage = new CXref(this, pSI->pPage->GetObjId());
if (pXrefPage)
{
pXrefPage->Add(pSI->pPage->Copy(), pSI->pPage->GetGenNo());
pXrefPage->SetPrev(pXrefCatalog);
}
CXref* pXref = new CXref(this, 0, 65535);
if (pXref)
{
pXref->SetPrev(pXrefPage);
CDictObject* pTrailer = pXref->GetTrailer();
m_pTrailer->Copy(pTrailer);
CEncrypt* pEncrypt = NULL;
if (m_pEncryptDict)
pEncrypt = m_pEncryptDict->GetEncrypt();
pXref->WriteToStream(pStream, pEncrypt, bNeedStreamXRef);
pSI->pXref = pXref;
}
pField->GetSignatureDict()->WriteToStream(pStream, pStream->Size(), pDataToSign, dwDataLength);
// Восстанавливаем XRef
m_pXref = pXrefBefore;
delete pStream;
return true;
}
bool CDocument::FinalizeSignature(BYTE* pSignedData, DWORD dwDataLength)
{
if (m_vSignatures.empty())
return false;
TSignatureInfo* pSI = m_vSignatures[0];
bool bNeedStreamXRef = pSI->bNeedStreamXRef;
std::wstring wsPath = pSI->wsPath;
if (wsPath.empty() || !pSI->pField)
return false;
// Если подписание не удалось
if (!pSignedData || dwDataLength == 0)
{
unsigned int nFileSizeBefore = pSI->nFileSizeBefore;
// Обрезаем файл
NSFile::CFileBinary::Truncate(wsPath, nFileSizeBefore);
CXref* pXref = pSI->pXref;
m_vSignatures.pop_front();
pSI->pPage->DeleteAnnotation(pSI->pField->GetObjId());
if (m_pAcroForm)
CXref* pXrefBefore = m_pXref;
m_pXref = new CXref(this, nSizeXRef);
if (!m_pXref)
{
CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields");
for (int i = 0; i < ppFields->GetCount(); ++i)
{
CObjectBase* pObj = ppFields->Get(i);
if (pObj->GetObjId() == pSI->pField->GetObjId())
{
CObjectBase* pDelete = ppFields->Remove(i);
if (pDelete->GetType() == object_type_UNKNOWN)
RELEASEOBJECT(pDelete);
break;
}
}
m_pXref = pXrefBefore;
continue;
}
m_pXref->SetPrevAddr(nPrevAddr);
CSignatureField* pField = CreateSignatureField();
if (!pField)
{
RELEASEOBJECT(m_pXref);
m_pXref = pXrefBefore;
continue;
}
// Продолжаем со следующей подписью
if (!m_vSignatures.empty())
m_pAcroForm->Add("SigFlags", 3);
pField->GetSignatureDict()->SetCert(m_vSignatures[i].pCertificate);
pField->GetSignatureDict()->SetDate();
pField->AddPageRect(m_vSignatures[i].pPage, m_vSignatures[i].oRect);
pField->Add("F", 132);
pField->SetFieldName("Sig" + std::to_string(i + m_unFormFields + 1));
if (m_vSignatures[i].pImage)
pField->SetAppearance(m_vSignatures[i].pImage);
CFileStream* pStream = new CFileStream();
if (!pStream || !pStream->OpenFile(wsPath, false))
{
CXref* pPrev = pXref;
while (pPrev->GetPrev())
pPrev = pPrev->GetPrev();
Sign(wsPath, pSI->nSizeXRef, bNeedStreamXRef, pSI->nPrevAddr);
RELEASEOBJECT(m_pXref);
m_pXref = pXrefBefore;
continue;
}
delete pSI;
delete pXref;
return true; // Успешно откатили
}
CFileStream* pStream = new CFileStream();
if (!pStream || !pStream->OpenFile(wsPath, false))
{
delete pStream;
return false;
}
if (!pSI->pField->GetSignatureDict() || !pSI->pField->GetSignatureDict()->FinalizeSignature(pStream, pSignedData, dwDataLength))
{
delete pStream;
return false;
}
CXref* pXref = pSI->pXref;
delete pStream;
delete pSI;
m_vSignatures.pop_front();
CXref* pPrev = pXref;
while (pPrev->GetPrev()) pPrev = pPrev->GetPrev();
Sign(wsPath, pPrev->GetSizeXRef() + (bNeedStreamXRef ? 1 : 0), bNeedStreamXRef, pXref->GetPrevAddr());
// delete pXref
pPrev->SetPrev(m_pXref);
m_pXref = pXref;
return true;
}
void CDocument::Sign(const std::wstring& wsPath, unsigned int nSizeXRef, bool bNeedStreamXRef, unsigned int nPrevAddr)
{
if (!m_vSignatures.empty())
{
m_vSignatures[0]->wsPath = wsPath;
m_vSignatures[0]->nSizeXRef = nSizeXRef;
m_vSignatures[0]->nPrevAddr = nPrevAddr;
m_vSignatures[0]->bNeedStreamXRef = bNeedStreamXRef;
CXref* pXrefCatalog = new CXref(this, m_pCatalog->GetObjId());
if (pXrefCatalog)
{
pXrefCatalog->Add(m_pCatalog->Copy(), m_pCatalog->GetGenNo());
pXrefCatalog->SetPrev(m_pXref);
}
CXref* pXrefPage = new CXref(this, m_vSignatures[i].pPage->GetObjId());
if (pXrefPage)
{
pXrefPage->Add(m_vSignatures[i].pPage->Copy(), m_vSignatures[i].pPage->GetGenNo());
pXrefPage->SetPrev(pXrefCatalog);
}
CXref* pXref = new CXref(this, 0, 65535);
if (pXref)
{
pXref->SetPrev(pXrefPage);
CDictObject* pTrailer = pXref->GetTrailer();
m_pTrailer->Copy(pTrailer);
CEncrypt* pEncrypt = NULL;
if (m_pEncryptDict)
pEncrypt = m_pEncryptDict->GetEncrypt();
pXref->WriteToStream(pStream, pEncrypt, bNeedStreamXRef);
nPrevAddr = pXref->GetPrevAddr();
nSizeXRef = m_pXref->GetSizeXRef();
vXRefForWrite.push_back(pXref);
}
RELEASEOBJECT(pStream);
pStream = new CFileStream();
if (pStream && pStream->OpenFile(wsPath, false))
pField->GetSignatureDict()->WriteToStream(pStream, pStream->Size());
m_pXref = pXrefBefore;
RELEASEOBJECT(pStream);
}
for (CXref* XRef : vXRefForWrite)
RELEASEOBJECT(XRef);
vXRefForWrite.clear();
}
void CDocument::AddShapeXML(const std::string& sXML)
{

View File

@ -33,7 +33,6 @@
#define _PDF_WRITER_SRC_DOCUMENT_H
#include <vector>
#include <deque>
#include <string>
#include "Types.h"
@ -127,7 +126,6 @@ namespace PdfWriter
CPage* AddPage();
CPage* GetPage (const unsigned int& unPage);
CObjectBase* GetPageObj (const unsigned int& unPage);
CPage* GetEditPage(const unsigned int& unPage);
int FindPage (CPage* pPage);
unsigned int GetPagesCount() const;
@ -197,9 +195,7 @@ namespace PdfWriter
bool AddToFile(const std::wstring& wsPath, CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo);
void AddObject(CObjectBase* pObj);
bool MovePage(int nPageIndex, int nPos);
void Sign(const TRect& oRect, CImageDict* pImage);
bool PrepareSignature(BYTE** pDataToSign, DWORD& dwDataLength);
bool FinalizeSignature(BYTE* pSignedData, DWORD dwDataLength);
void Sign(const TRect& oRect, CImageDict* pImage, ICertificate* pCert);
bool EditAnnot (CXref* pXref, CAnnotation* pAnnot, int nID);
void AddParent(int nID, CDictObject* pParent);
CDictObject* CreateParent(int nID);
@ -240,7 +236,7 @@ namespace PdfWriter
CShading* CreateRadialShading(double dX0, double dY0, double dR0, double dX1, double dY1, double dR1, unsigned char* pColors, double* pPoints, int nCount);
bool CheckAcroForm();
CRadioGroupField* FindRadioGroupField(const std::wstring& wsGroupName);
void Sign(const std::wstring& wsPath, unsigned int nSizeXRef, bool bNeedStreamXRef = false, unsigned int nPrevAddr = 0);
void Sign(const std::wstring& wsPath, unsigned int nSizeXRef, bool bNeedStreamXRef = false);
private:
@ -259,31 +255,18 @@ namespace PdfWriter
};
struct TSignatureInfo
{
TSignatureInfo(const TRect& _oRect, CPage* _pPage, CImageDict* _pImage)
TSignatureInfo(const TRect& _oRect, CPage* _pPage, CImageDict* _pImage, ICertificate* _pCertificate)
{
oRect = _oRect;
pPage = _pPage;
pImage = _pImage;
nSizeXRef = 0;
nPrevAddr = 0;
nFileSizeBefore = 0;
bNeedStreamXRef = false;
pField = NULL;
pXref = NULL;
pCertificate = _pCertificate;
}
TRect oRect;
CPage* pPage;
CImageDict* pImage;
std::wstring wsPath;
unsigned int nSizeXRef;
unsigned int nPrevAddr;
unsigned int nFileSizeBefore;
bool bNeedStreamXRef;
CSignatureField* pField;
CXref* pXref;
ICertificate* pCertificate;
};
struct TImageInfo
{
@ -313,7 +296,7 @@ namespace PdfWriter
CStreamData* m_pMetaData;
bool m_bEncrypt;
CEncryptDict* m_pEncryptDict;
std::deque<TSignatureInfo*> m_vSignatures;
std::vector<TSignatureInfo> m_vSignatures;
std::vector<TImageInfo> m_vImages;
unsigned int m_unFormFields;
unsigned int m_unCompressMode;

View File

@ -223,6 +223,32 @@ namespace PdfWriter
Add("Filter", "Adobe.PPKLite");
Add("SubFilter", "adbe.pkcs7.detached");
unsigned int unDigestLength = 15000;
BYTE* pDigest = new BYTE[unDigestLength];
memset(pDigest, 0, unDigestLength);
Add("Contents", new CBinaryObject(pDigest, unDigestLength));
RELEASEARRAYOBJECTS(pDigest);
CArrayObject* pByteRange = new CArrayObject();
if (!pByteRange)
return;
Add("ByteRange", pByteRange);
pByteRange->Add(0);
pByteRange->Add(1234567890);
pByteRange->Add(1234567890);
pByteRange->Add(1234567890);
// Reference - Массив справочных словарей сигнатур
// Changes - Массив из трех чисел, который указывает изменения в документе в порядке: количество измененных страниц,
// количество измененных полей и количество заполненных полей
// Порядок подписей определяется значением ByteRange. Поскольку каждая подпись приводит к добавочному сохранению,
// более поздние подписи имеют большее значение длины
// Prop_Build - Словарь, который может использоваться обработчиком подписи для записи информации о состоянии компьютерной среды,
// используемой для подписи, такой как имя обработчика, используемого для создания подписи, дата сборки программного обеспечения,
// версия, и операционная система. Спецификация словаря PDF Signature Build содержит рекомендации по использованию этого словаря
m_nLen1 = 0;
m_nOffset2 = 0;
m_nByteRangeBegin = 0;
@ -233,33 +259,40 @@ namespace PdfWriter
}
void CSignatureDict::WriteToStream(CStream* pStream, CEncrypt* pEncrypt)
{
for (std::map<std::string, CObjectBase*>::const_iterator oIter = m_mList.begin(); oIter != m_mList.end(); ++oIter)
for (auto const &oIter : m_mList)
{
CObjectBase* pObject = oIter->second;
if (!pObject || pObject->IsHidden())
CObjectBase* pObject = oIter.second;
if (!pObject)
continue;
int nBegin, nEnd;
pStream->WriteEscapeName(oIter->first.c_str());
pStream->WriteChar(' ');
nBegin = pStream->Tell();
// Цифровая подпись не шифруется
pStream->Write(pObject, oIter->first == "Contents" ? NULL : pEncrypt);
nEnd = pStream->Tell();
pStream->WriteStr("\012");
if (oIter->first == "Contents")
if (pObject->IsHidden())
{
m_nLen1 = nBegin;
m_nOffset2 = nEnd;
// ничего не делаем
}
if (oIter->first == "ByteRange")
else
{
m_nByteRangeBegin = nBegin;
m_nByteRangeEnd = nEnd;
int nBegin, nEnd;
pStream->WriteEscapeName(oIter.first.c_str());
pStream->WriteChar(' ');
nBegin = pStream->Tell();
// Цифровая подпись не шифруется
pStream->Write(pObject, oIter.first == "Contents" ? NULL : pEncrypt);
nEnd = pStream->Tell();
pStream->WriteStr("\012");
if (oIter.first == "Contents")
{
m_nLen1 = nBegin;
m_nOffset2 = nEnd;
}
if (oIter.first == "ByteRange")
{
m_nByteRangeBegin = nBegin;
m_nByteRangeEnd = nEnd;
}
}
}
}
void CSignatureDict::WriteToStream(CStream* pStream, int nFileEnd, BYTE** pDataForSignature, DWORD& dwLenDataForSignature)
void CSignatureDict::WriteToStream(CStream* pStream, int nFileEnd)
{
// Запись ByteRange
if (m_nByteRangeBegin > 0 && m_nByteRangeEnd > 0 && m_nByteRangeBegin < m_nByteRangeEnd && m_nByteRangeEnd < nFileEnd)
@ -272,7 +305,7 @@ namespace PdfWriter
pByteRange->Add(0);
pByteRange->Add(m_nLen1);
pByteRange->Add(m_nOffset2);
pByteRange->Add(nFileEnd - m_nOffset2);
pByteRange->Add(nFileEnd - m_nOffset2);
pStream->Seek(m_nByteRangeBegin, EWhenceMode::SeekSet);
pStream->Write(pByteRange, NULL);
@ -292,78 +325,58 @@ namespace PdfWriter
RELEASEOBJECT(pByteRange);
}
// Запись Contents
if (m_nLen1 > 0 && m_nOffset2 > 0 && m_nLen1 < m_nOffset2 && m_nOffset2 < nFileEnd)
if (m_pCertificate && m_nLen1 > 0 && m_nOffset2 > 0 && m_nLen1 < m_nOffset2 && m_nOffset2 < nFileEnd)
{
dwLenDataForSignature = m_nLen1 + nFileEnd - m_nOffset2;
*pDataForSignature = new BYTE[dwLenDataForSignature];
if (!*pDataForSignature)
DWORD dwLenDataForSignature = m_nLen1 + nFileEnd - m_nOffset2;
BYTE* pDataForSignature = new BYTE[dwLenDataForSignature];
if (!pDataForSignature)
return;
pStream->Seek(0, EWhenceMode::SeekSet);
unsigned int dwLenReadData = m_nLen1;
pStream->Read(*pDataForSignature, &dwLenReadData);
pStream->Read(pDataForSignature, &dwLenReadData);
if ((int)dwLenReadData != m_nLen1)
{
RELEASEARRAYOBJECTS(*pDataForSignature);
RELEASEARRAYOBJECTS(pDataForSignature);
return;
}
pStream->Seek(m_nOffset2, EWhenceMode::SeekSet);
dwLenReadData = nFileEnd - m_nOffset2;
pStream->Read(*pDataForSignature + m_nLen1, &dwLenReadData);
if ((int)dwLenReadData != nFileEnd - m_nOffset2)
dwLenReadData = nFileEnd - m_nOffset2;
pStream->Read(pDataForSignature + m_nLen1, &dwLenReadData);
if ((int)dwLenReadData != nFileEnd - m_nOffset2)
{
RELEASEARRAYOBJECTS(*pDataForSignature);
RELEASEARRAYOBJECTS(pDataForSignature);
return;
}
BYTE* pDatatoWrite = NULL;
unsigned int dwLenDatatoWrite;
m_pCertificate->SignPKCS7(pDataForSignature, dwLenDataForSignature, pDatatoWrite, dwLenDatatoWrite);
RELEASEARRAYOBJECTS(pDataForSignature);
if (!pDatatoWrite)
return;
pStream->Seek(m_nLen1, EWhenceMode::SeekSet);
CBinaryObject* pContents = new CBinaryObject(pDatatoWrite, dwLenDatatoWrite);
RELEASEARRAYOBJECTS(pDatatoWrite);
if (!pContents)
return;
// Цифровая подпись не шифруется
pStream->Write(pContents, NULL);
RELEASEOBJECT(pContents);
// Стереть лишний >
BYTE cChar = '0';
pStream->Seek(pStream->Tell() - 1, EWhenceMode::SeekSet);
pStream->Write(&cChar, 1);
}
}
bool CSignatureDict::FinalizeSignature(CStream* pStream, BYTE* pSignedData, DWORD dwDataLength)
{
if (!pSignedData)
return false;
// Записываем подписанные данные в Contents
if (dwDataLength > m_nContentsSize)
{
// Подпись не влезает! Ошибка расчета размера
return false;
}
pStream->Seek(m_nLen1, EWhenceMode::SeekSet);
CBinaryObject* pContents = new CBinaryObject(pSignedData, dwDataLength);
if (!pContents)
return false;
// Цифровая подпись не шифруется
pStream->Write(pContents, NULL);
delete pContents;
// Стираем лишний '>' если нужно
BYTE cChar = '0';
pStream->Seek(pStream->Tell() - 1, EWhenceMode::SeekSet);
pStream->Write(&cChar, 1);
return true;
}
void CSignatureDict::SetContentsSize(unsigned int nSize)
{
m_nContentsSize = nSize;
BYTE* pDigest = new BYTE[m_nContentsSize];
memset(pDigest, 0, m_nContentsSize);
Add("Contents", new CBinaryObject(pDigest, m_nContentsSize, false));
CArrayObject* pByteRange = new CArrayObject();
if (!pByteRange)
return;
Add("ByteRange", pByteRange);
pByteRange->Add(0);
pByteRange->Add(1234567890);
pByteRange->Add(1234567890);
pByteRange->Add(1234567890);
}
void CSignatureDict::SetName(const std::string& sName)
void CSignatureDict::SetCert(ICertificate* pCert)
{
m_pCertificate = pCert;
}
void CSignatureDict::SetName(const std::string& sName)
{
// Name - Cтрока, Имя лица или органа, подписавшего документ.
// Значение следует использовать когда невозможно извлечь имя из подписи или сертификата подписавшего.

View File

@ -34,6 +34,8 @@
#include "Objects.h"
#include "../../DesktopEditor/xmlsec/src/include/Certificate.h"
namespace PdfWriter
{
class CEncrypt;
@ -76,19 +78,18 @@ namespace PdfWriter
}
void WriteToStream(CStream* pStream, CEncrypt* pEncrypt) override;
void WriteToStream(CStream* pStream, int nFileEnd, BYTE** pDataToSign, DWORD& dwDataLength);
bool FinalizeSignature(CStream* pStream, BYTE* pSignedData, DWORD dwDataLength);
void WriteToStream(CStream* pStream, int nFileEnd);
void SetCert(ICertificate* pCert);
void SetContentsSize(unsigned int nSize);
void SetName(const std::string& sName);
void SetReason(const std::string& sReason);
void SetContact(const std::string& sContacts);
void SetDate();
private:
unsigned int m_nContentsSize; // Размер Contents
ICertificate* m_pCertificate;
int m_nLen1; // Длина первого интервала
int m_nOffset2; // Начало второго интервала
int m_nLen1; // Длина первого интервала сигнатуры
int m_nOffset2; // Начало второго интервала сигнатуры
int m_nByteRangeBegin; // Смещение начала массива ByteRange
int m_nByteRangeEnd; // Смещение конца массива ByteRange

View File

@ -3222,59 +3222,56 @@ namespace PdfWriter
}
// Граница
if (pAnnot->HaveBC())
if (dBorder != 1)
{
if (dBorder != 1)
{
m_pStream->WriteReal(dBorder);
m_pStream->WriteStr(" w\012");
}
if (nBorderType == EBorderType::Dashed)
m_pStream->WriteStr(m_pAnnot->GetBorderDash().c_str());
m_pStream->WriteStr(pAnnot->GetBCforAP().c_str());
m_pStream->WriteReal(dBorder);
m_pStream->WriteStr(" w\012");
}
if (nBorderType == EBorderType::Dashed)
m_pStream->WriteStr(m_pAnnot->GetBorderDash().c_str());
m_pStream->WriteStr(pAnnot->GetBCforAP().c_str());
m_pStream->WriteStr("\012q\012");
m_pStream->WriteStr("1 0 0 1 ");
m_pStream->WriteReal(dCX);
m_pStream->WriteChar(' ');
m_pStream->WriteReal(dCY);
m_pStream->WriteStr(" cm\012");
StreamWriteCircle(m_pStream, 0, 0, dR - dBorder / 2.0);
m_pStream->WriteStr("s\012Q\012");
if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset)
{
double ca = cos(45.0 / 180.0 * M_PI);
double cx = 0, cy = 0, r = dR - dBorder * 1.5;
double bezierCircle = 0.55228475 * r;
std::string sBG = pAnnot->GetBGforAP(-0.250977, true);
if (sBG.empty())
sBG = "0.749023 G";
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.501953 G" : "0 G");
else // Beveled
m_pStream->WriteStr(bN ? "1 G" : sBG.c_str());
m_pStream->WriteStr("\012q\012");
m_pStream->WriteStr("1 0 0 1 ");
m_pStream->WriteReal(dCX);
m_pStream->WriteChar(' ');
m_pStream->WriteReal(dCY);
m_pStream->WriteStr(" cm\012");
StreamWriteCM(m_pStream, ca, ca, -ca, ca, dCX, dCY);
StreamWriteXYMove(m_pStream, cx + r, cy);
StreamWriteXYCurve(m_pStream, cx + r, cy + bezierCircle, cx + bezierCircle, cy + r, cx, cy + r);
StreamWriteXYCurve(m_pStream, cx - bezierCircle, cy + r, cx - r, cy + bezierCircle, cx - r, cy);
m_pStream->WriteStr("S\012Q\012");
StreamWriteCircle(m_pStream, 0, 0, dR - dBorder / 2.0);
m_pStream->WriteStr("s\012Q\012");
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.75293 G" : "1 G");
else // Beveled
m_pStream->WriteStr(bN ? sBG.c_str() : "1 G");
if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset)
{
double ca = cos(45.0 / 180.0 * M_PI);
double cx = 0, cy = 0, r = dR - dBorder * 1.5;
double bezierCircle = 0.55228475 * r;
std::string sBG = pAnnot->GetBGforAP(-0.250977, true);
if (sBG.empty())
sBG = "0.749023 G";
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.501953 G" : "0 G");
else // Beveled
m_pStream->WriteStr(bN ? "1 G" : sBG.c_str());
m_pStream->WriteStr("\012q\012");
StreamWriteCM(m_pStream, ca, ca, -ca, ca, dCX, dCY);
StreamWriteXYMove(m_pStream, cx + r, cy);
StreamWriteXYCurve(m_pStream, cx + r, cy + bezierCircle, cx + bezierCircle, cy + r, cx, cy + r);
StreamWriteXYCurve(m_pStream, cx - bezierCircle, cy + r, cx - r, cy + bezierCircle, cx - r, cy);
m_pStream->WriteStr("S\012Q\012");
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.75293 G" : "1 G");
else // Beveled
m_pStream->WriteStr(bN ? sBG.c_str() : "1 G");
m_pStream->WriteStr("\012q\012");
StreamWriteCM(m_pStream, ca, ca, -ca, ca, dCX, dCY);
StreamWriteXYMove(m_pStream, cx - r, cy);
StreamWriteXYCurve(m_pStream, cx - r, cy - bezierCircle, cx - bezierCircle, cy - r, cx, cy - r);
StreamWriteXYCurve(m_pStream, cx + bezierCircle, cy - r, cx + r, cy - bezierCircle, cx + r, cy);
m_pStream->WriteStr("S\012Q\012");
}
m_pStream->WriteStr("\012q\012");
StreamWriteCM(m_pStream, ca, ca, -ca, ca, dCX, dCY);
StreamWriteXYMove(m_pStream, cx - r, cy);
StreamWriteXYCurve(m_pStream, cx - r, cy - bezierCircle, cx - bezierCircle, cy - r, cx, cy - r);
StreamWriteXYCurve(m_pStream, cx + bezierCircle, cy - r, cx + r, cy - bezierCircle, cx + r, cy);
m_pStream->WriteStr("S\012Q\012");
}
// Установлен
@ -3331,63 +3328,60 @@ namespace PdfWriter
}
// Граница
if (pAnnot->HaveBC())
if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset)
{
if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset)
{
std::string sBG = pAnnot->GetBGforAP(-0.250977);
if (sBG.empty())
sBG = "0.749023 g";
std::string sBG = pAnnot->GetBGforAP(-0.250977);
if (sBG.empty())
sBG = "0.749023 g";
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.501953 g" : "0 g");
else // Beveled
m_pStream->WriteStr(bN ? "1 g" : sBG.c_str());
m_pStream->WriteStr("\012");
StreamWriteXYMove(m_pStream, dBorder, dBorder);
StreamWriteXYLine(m_pStream, dBorder, dH - dBorder);
StreamWriteXYLine(m_pStream, dW - dBorder, dH - dBorder);
StreamWriteXYLine(m_pStream, dW - dBorder * 2.0, dH - dBorder * 2.0);
StreamWriteXYLine(m_pStream, dBorder * 2.0, dH - dBorder * 2.0);
StreamWriteXYLine(m_pStream, dBorder * 2.0, dBorder * 2.0);
m_pStream->WriteStr("f\012");
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.75293 g" : "1 g");
else // Beveled
m_pStream->WriteStr(bN ? sBG.c_str() : "1 g");
m_pStream->WriteStr("\012");
StreamWriteXYMove(m_pStream, dW - dBorder, dH - dBorder);
StreamWriteXYLine(m_pStream, dW - dBorder, dBorder);
StreamWriteXYLine(m_pStream, dBorder, dBorder);
StreamWriteXYLine(m_pStream, dBorder * 2.0, dBorder * 2.0);
StreamWriteXYLine(m_pStream, dW - dBorder * 2.0, dBorder * 2.0);
StreamWriteXYLine(m_pStream, dW - dBorder * 2.0, dH - dBorder * 2.0);
m_pStream->WriteStr("f\012");
}
if (dBorder != 1)
{
m_pStream->WriteReal(dBorder);
m_pStream->WriteStr(" w\012");
}
if (nBorderType == EBorderType::Dashed)
m_pStream->WriteStr(m_pAnnot->GetBorderDash().c_str());
m_pStream->WriteStr(pAnnot->GetBCforAP().c_str());
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.501953 g" : "0 g");
else // Beveled
m_pStream->WriteStr(bN ? "1 g" : sBG.c_str());
m_pStream->WriteStr("\012");
if (nBorderType == EBorderType::Underline)
{
StreamWriteXYMove(m_pStream, 0, dBorder / 2.0);
StreamWriteXYLine(m_pStream, dW, dBorder / 2.0);
}
else
StreamWriteRect(m_pStream, dBorder / 2.0, dBorder / 2.0, dW - dBorder, dH - dBorder);
m_pStream->WriteStr("s\012Q\012");
StreamWriteXYMove(m_pStream, dBorder, dBorder);
StreamWriteXYLine(m_pStream, dBorder, dH - dBorder);
StreamWriteXYLine(m_pStream, dW - dBorder, dH - dBorder);
StreamWriteXYLine(m_pStream, dW - dBorder * 2.0, dH - dBorder * 2.0);
StreamWriteXYLine(m_pStream, dBorder * 2.0, dH - dBorder * 2.0);
StreamWriteXYLine(m_pStream, dBorder * 2.0, dBorder * 2.0);
m_pStream->WriteStr("f\012");
if (nBorderType == EBorderType::Inset)
m_pStream->WriteStr(bN ? "0.75293 g" : "1 g");
else // Beveled
m_pStream->WriteStr(bN ? sBG.c_str() : "1 g");
m_pStream->WriteStr("\012");
StreamWriteXYMove(m_pStream, dW - dBorder, dH - dBorder);
StreamWriteXYLine(m_pStream, dW - dBorder, dBorder);
StreamWriteXYLine(m_pStream, dBorder, dBorder);
StreamWriteXYLine(m_pStream, dBorder * 2.0, dBorder * 2.0);
StreamWriteXYLine(m_pStream, dW - dBorder * 2.0, dBorder * 2.0);
StreamWriteXYLine(m_pStream, dW - dBorder * 2.0, dH - dBorder * 2.0);
m_pStream->WriteStr("f\012");
}
if (dBorder != 1)
{
m_pStream->WriteReal(dBorder);
m_pStream->WriteStr(" w\012");
}
if (nBorderType == EBorderType::Dashed)
m_pStream->WriteStr(m_pAnnot->GetBorderDash().c_str());
m_pStream->WriteStr(pAnnot->GetBCforAP().c_str());
m_pStream->WriteStr("\012");
if (nBorderType == EBorderType::Underline)
{
StreamWriteXYMove(m_pStream, 0, dBorder / 2.0);
StreamWriteXYLine(m_pStream, dW, dBorder / 2.0);
}
else
StreamWriteRect(m_pStream, dBorder / 2.0, dBorder / 2.0, dW - dBorder, dH - dBorder);
m_pStream->WriteStr("s\012Q\012");
// Установлен
if (!bSet)
return;

View File

@ -71,7 +71,6 @@ namespace PdfWriter
unsigned int EncodeUnicode(const unsigned int& unGID, const unsigned int& unUnicode);
unsigned int EncodeGID(const unsigned int& unGID);
const char* GetFontKey() const { return m_sFontKey.c_str(); }
void UpdateKey(const std::string& sFontKey) { m_sFontKey = sFontKey; }
private:
std::string m_sFontKey;

View File

@ -532,10 +532,6 @@ namespace PdfWriter
{
m_pPrev = pPrev;
}
CXref* GetPrev()
{
return m_pPrev;
}
void SetPrevAddr(unsigned int unAddr)
{
m_unAddr = unAddr;

View File

@ -1232,8 +1232,7 @@ namespace PdfWriter
if (pObj->GetObjId() == nID)
{
CObjectBase* pDelete = pArray->Remove(i);
if (pDelete->GetType() == object_type_UNKNOWN)
RELEASEOBJECT(pDelete);
RELEASEOBJECT(pDelete);
return true;
}
}

View File

@ -116,7 +116,7 @@ public:
}
ICertificate* GetCertificate()
{
std::wstring wsCertificateFile = NSFile::GetProcessDirectory() + L"/pfx.pfx";
std::wstring wsCertificateFile = NSFile::GetProcessDirectory() + L"/cert.pfx";
std::wstring wsPrivateKeyFile = L"";
std::string sCertificateFilePassword = "123456";
std::string sPrivateFilePassword = "";
@ -524,7 +524,7 @@ TEST_F(CPdfFileTest, EditPdf)
TEST_F(CPdfFileTest, EditPdfFromBase64)
{
GTEST_SKIP();
//GTEST_SKIP();
NSFonts::NSApplicationFontStream::SetGlobalMemoryStorage(NSFonts::NSApplicationFontStream::CreateDefaultGlobalMemoryStorage());
@ -602,97 +602,22 @@ TEST_F(CPdfFileTest, EditPdfFromBin)
TEST_F(CPdfFileTest, EditPdfSign)
{
//GTEST_SKIP();
GTEST_SKIP();
LoadFromFile();
ASSERT_TRUE(pdfFile->EditPdf(wsDstFile));
ICertificate* pCertificate = GetCertificate();
ASSERT_TRUE(pCertificate);
EXPECT_TRUE(pdfFile->EditPage(0));
{
pdfFile->Sign(10, 10, 100, 100, NSFile::GetProcessDirectory() + L"/test.jpeg");
pdfFile->Sign(10, 150, 100, 100, NSFile::GetProcessDirectory() + L"/test.jpeg");
pdfFile->Sign(10, 300, 100, 100, NSFile::GetProcessDirectory() + L"/test.jpeg");
}
// Для цифровой подписи важно предварительно pdfFile->EditClose, в остальных случаях pdfFile->Close() сделает тоже самое
pdfFile->EditClose();
// EditPdf & EditClose || CreatePdf & SaveToFile
// И только после подготовка данных для подписания, подписываем, запись подписи
for (int i = 0; i < 3; ++i)
{
BYTE* pDataToSign = NULL;
DWORD dwDataLength = 0;
// Получили данные для подписания
pdfFile->PrepareSignature(&pDataToSign, dwDataLength);
ICertificate* pCertificate = GetCertificate();
ASSERT_TRUE(pCertificate);
BYTE* pDatatoWrite = NULL;
unsigned int dwLenDatatoWrite = 0;
// Предположим, что для подписи 1 произошло не успешное подписание, и данные остались пустыми
if (i % 2 == 0)
pCertificate->SignPKCS7(pDataToSign, dwDataLength, pDatatoWrite, dwLenDatatoWrite);
RELEASEARRAYOBJECTS(pDataToSign);
// Обязательно FinalizeSignature - он либо заполнит данные, либо сделает подпись пустой
pdfFile->FinalizeSignature(pDatatoWrite, dwLenDatatoWrite);
RELEASEARRAYOBJECTS(pDatatoWrite);
RELEASEOBJECT(pCertificate);
pdfFile->Sign(10, 10, 100, 100, NSFile::GetProcessDirectory() + L"/test.jpeg", pCertificate);
}
pdfFile->Close();
}
TEST_F(CPdfFileTest, PdfToPdfSign)
{
GTEST_SKIP();
LoadFromFile();
pdfFile->CreatePdf();
double dPageDpiX, dPageDpiY, dW, dH;
int nPages = pdfFile->GetPagesCount();
for (int i = 0; i < nPages; i++)
{
pdfFile->NewPage();
pdfFile->GetPageInfo(i, &dW, &dH, &dPageDpiX, &dPageDpiY);
pdfFile->put_Width( dW / dPageDpiX * 25.4);
pdfFile->put_Height(dH / dPageDpiY * 25.4);
pdfFile->DrawPageOnRenderer(pdfFile, i, NULL);
pdfFile->Sign(10, 10, 100, 100, NSFile::GetProcessDirectory() + L"/test.jpeg");
}
// Сначала SaveToFile, затем подписание, потом Close
pdfFile->SaveToFile(wsDstFile);
for (int i = 0; i < nPages; ++i)
{
BYTE* pDataToSign = NULL;
DWORD dwDataLength = 0;
pdfFile->PrepareSignature(&pDataToSign, dwDataLength);
ICertificate* pCertificate = GetCertificate();
ASSERT_TRUE(pCertificate);
BYTE* pDatatoWrite = NULL;
unsigned int dwLenDatatoWrite = 0;
if (i % 2 == 0)
pCertificate->SignPKCS7(pDataToSign, dwDataLength, pDatatoWrite, dwLenDatatoWrite);
pdfFile->FinalizeSignature(pDatatoWrite, dwLenDatatoWrite);
RELEASEOBJECT(pCertificate);
}
pdfFile->Close();
RELEASEOBJECT(pCertificate);
}
TEST_F(CPdfFileTest, PrintPdf)

View File

@ -53,7 +53,7 @@ namespace NExtractTools
return 1;
std::wstring pdfTemp = combinePath(convertParams.m_sTempDir, L"pdf_sign.pdf");
NSFile::CFileBinary::Copy(file, pdfTemp);
NSFile::CFileBinary::Move(file, pdfTemp);
CPdfFile pdfFile(fonts);
pdfFile.SetTempDirectory(convertParams.m_sTempDir);
@ -68,29 +68,9 @@ namespace NExtractTools
if (!pdfFile.EditPage(0))
return 2;
pdfFile.Sign(0, 0, 0, 0, L"");
pdfFile.Sign(0, 0, 0, 0, L"", certificate);
pdfFile.Close();
BYTE* pDataToSign = NULL;
DWORD dwDataLength = 0;
if (!pdfFile.PrepareSignature(&pDataToSign, dwDataLength))
{
RELEASEARRAYOBJECTS(pDataToSign);
return 2;
}
BYTE* pDatatoWrite = NULL;
unsigned int dwLenDatatoWrite = 0;
certificate->SignPKCS7(pDataToSign, dwDataLength, pDatatoWrite, dwLenDatatoWrite);
RELEASEARRAYOBJECTS(pDataToSign);
if (!pdfFile.FinalizeSignature(pDatatoWrite, dwLenDatatoWrite))
{
RELEASEARRAYOBJECTS(pDatatoWrite);
return 2;
}
RELEASEARRAYOBJECTS(pDatatoWrite);
RELEASEOBJECT(certificate);
return 0;
}