diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 71794dec59..d1c432d6a0 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -110,7 +110,7 @@ bool CPdfFile::EditPdf(const std::wstring& wsDstFile) return false; RELEASEOBJECT(m_pInternal->pWriter); - m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this); + m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this, true, m_pInternal->wsTempFolder); RELEASEOBJECT(m_pInternal->pEditor); m_pInternal->pEditor = new CPdfEditor(m_pInternal->wsSrcFile, m_pInternal->wsPassword, wsDstFile, m_pInternal->pReader, m_pInternal->pWriter); @@ -151,7 +151,7 @@ bool CPdfFile::MovePage(int nPageIndex, int nPos) HRESULT CPdfFile::ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword) { RELEASEOBJECT(m_pInternal->pWriter); - m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this, false); + m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this, false, m_pInternal->wsTempFolder); return _ChangePassword(wsPath, wsPassword, m_pInternal->pReader, m_pInternal->pWriter); } @@ -313,6 +313,8 @@ void CPdfFile::SetTempDirectory(const std::wstring& wsPath) m_pInternal->wsTempFolder = wsPath; if (m_pInternal->pReader) m_pInternal->pReader->SetTempDirectory(wsPath); + if (m_pInternal->pWriter) + m_pInternal->pWriter->SetTempDirectory(wsPath); } int CPdfFile::GetPagesCount() { @@ -491,7 +493,7 @@ BYTE* CPdfFile::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, in void CPdfFile::CreatePdf(bool isPDFA) { RELEASEOBJECT(m_pInternal->pWriter); - m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, isPDFA, this); + m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, isPDFA, this, true, m_pInternal->wsTempFolder); } int CPdfFile::SaveToFile(const std::wstring& wsPath) { diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 520ce4c05c..67d0d6eb27 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -45,6 +45,7 @@ #include "SrcWriter/Field.h" #include "SrcWriter/Outline.h" +#include "Resources/BaseFonts.h" #include "../DesktopEditor/graphics/Image.h" #include "../DesktopEditor/graphics/structures.h" #include "../DesktopEditor/raster/BgraFrame.h" @@ -134,7 +135,7 @@ Aggplus::CImage* ConvertMetafile(NSFonts::IApplicationFonts* pAppFonts, const st // CPdfRenderer // //---------------------------------------------------------------------------------------- -CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRenderer* pRenderer, bool bCreate) : m_oCommandManager(this) +CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRenderer* pRenderer, bool bCreate, const std::wstring& wsTempDirectory) : m_oCommandManager(this) { // Создаем менеджер шрифтов с собственным кэшем m_pFontManager = pAppFonts->GenerateFontManager(); @@ -143,6 +144,7 @@ CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRend m_pFontManager->SetOwnerCache(pMeasurerCache); m_pRenderer = pRenderer; m_bNeedAddHelvetica = true; + m_wsTempDirectory = wsTempDirectory; m_pDocument = new PdfWriter::CDocument(); @@ -242,6 +244,10 @@ std::wstring CPdfWriter::GetTempFile(const std::wstring& wsDirectory) { return NSFile::CFileBinary::CreateTempFileWithUniqueName(wsDirectory, L"PDF"); } +void CPdfWriter::SetTempDirectory(const std::wstring& wsTempDirectory) +{ + m_wsTempDirectory = wsTempDirectory; +} //---------------------------------------------------------------------------------------- // Функции для работы со страницей //---------------------------------------------------------------------------------------- @@ -2357,6 +2363,34 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pButtonWidget->SetStyle(pPrB->GetStyle()); + if (!pButtonWidget->Get("DA")) + { + PdfWriter::CFontDict* pFont = pFontTT; + if (!wsFontName.empty()) + { + put_FontName(wsFontName); + put_FontStyle(nStyle); + put_FontSize(dFontSize); + + if (m_bNeedUpdateTextFont) + UpdateFont(); + if (m_pFont) + pFont = m_pDocument->CreateTrueTypeFont(m_pFont); + } + else + { + put_FontName(L"Embedded: ZapfDingbats"); + put_FontStyle(0); + put_FontSize(dFontSize); + + if (m_bNeedUpdateTextFont) + UpdateFont(); + if (m_pFont14) + pFont = m_pFont14; + } + pButtonWidget->SetDA(pFont, oInfo.GetWidgetAnnotPr()->GetFontSize(), dFontSize, oInfo.GetWidgetAnnotPr()->GetTC()); + } + // ВНЕШНИЙ ВИД if (!pButtonWidget->Get("AP")) pButtonWidget->SetAP(); @@ -3181,7 +3215,38 @@ bool CPdfWriter::GetBaseFont14(const std::wstring& wsFontName, int nBase14) std::wstring wsFontPath = m_oFont.GetPath(); LONG lFaceIndex = m_oFont.GetFaceIndex(); if (!FindFontPath(wsFontName, m_oFont.IsBold(), m_oFont.IsItalic(), wsFontPath, lFaceIndex)) - return false; + { + std::wstring sSub = wsFontName.substr(10); + const BYTE* pData14 = NULL; + unsigned int nSize14 = 0; + PdfReader::GetBaseFont(sSub, pData14, nSize14); + NSFonts::IFontsMemoryStorage* pMemoryStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage(); + if (pMemoryStorage) + { + if (!pMemoryStorage->Get(sSub)) + pMemoryStorage->Add(sSub, (BYTE*)pData14, nSize14); + AddFont(wsFontName, false, false, sSub, 0); + } + else + { + std::wstring wsTempFileName = m_wsTempDirectory + L"/" + sSub + L".base"; + if (NSFile::CFileBinary::Exists(wsTempFileName)) + wsFontPath = wsTempFileName; + else + { + NSFile::CFileBinary oFile; + if (oFile.CreateFileW(wsTempFileName)) + { + oFile.WriteFile((BYTE*)pData14, nSize14); + wsFontPath = wsTempFileName; + } + oFile.CloseFile(); + } + AddFont(wsFontName, false, false, wsFontPath, 0); + } + if (!FindFontPath(wsFontName, m_oFont.IsBold(), m_oFont.IsItalic(), wsFontPath, lFaceIndex)) + return false; + } if (!m_pFontManager->LoadFontFromFile(wsFontPath, lFaceIndex, m_oFont.GetSize(), 72, 72)) return false; PdfWriter::EStandard14Fonts nType = (PdfWriter::EStandard14Fonts)nBase14; diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 3ca2de790d..eb3f211de5 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -64,7 +64,7 @@ namespace Aggplus class CPdfWriter { public: - CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA = false, IRenderer* pRenderer = NULL, bool bCreate = true); + CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA = false, IRenderer* pRenderer = NULL, bool bCreate = true, const std::wstring& wsTempDirectory = L""); ~CPdfWriter(); int SaveToFile(const std::wstring& wsPath); int SaveToMemory(BYTE** pData, int* pLength); @@ -72,6 +72,7 @@ public: void SetDocumentID(const std::wstring& wsDocumentID); void SetDocumentInfo(const std::wstring& wsTitle, const std::wstring& wsCreator, const std::wstring& wsSubject, const std::wstring& wsKeywords); std::wstring GetTempFile(const std::wstring& wsDirectory); + void SetTempDirectory(const std::wstring& wsTempDirectory); //---------------------------------------------------------------------------------------- // Функции для работы со страницей //---------------------------------------------------------------------------------------- @@ -264,6 +265,7 @@ private: PdfWriter::CShading* m_pShading; PdfWriter::CExtGrState* m_pShadingExtGrState; + std::wstring m_wsTempDirectory; CCommandManager m_oCommandManager; CPenState m_oPen; CBrushState m_oBrush; diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 5fff8ad417..f1c4046c08 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -833,11 +833,11 @@ namespace PdfWriter { sDA.append(" /"); sDA.append(sFontName); - } - sDA.append(" "); - sDA.append(std::to_string(dFontSize)); - sDA.append(" Tf"); + sDA.append(" "); + sDA.append(std::to_string(dFontSize)); + sDA.append(" Tf"); + } Add("DA", new CStringObject(sDA.c_str())); } @@ -1236,11 +1236,11 @@ namespace PdfWriter { sDA.append(" /"); sDA.append(sFontName); - } - sDA.append(" "); - sDA.append(std::to_string(dFontSize)); - sDA.append(" Tf"); + sDA.append(" "); + sDA.append(std::to_string(dFontSize)); + sDA.append(" Tf"); + } CDictObject* pOwner = GetObjOwnValue("DA"); if (pOwner) @@ -1448,11 +1448,11 @@ namespace PdfWriter { sDA.append(" /"); sDA.append(sFontName); - } - sDA.append(" "); - sDA.append(std::to_string(m_dFontSizeAP)); - sDA.append(" Tf\012"); + sDA.append(" "); + sDA.append(std::to_string(m_dFontSizeAP)); + sDA.append(" Tf\012"); + } return sDA; } @@ -2011,6 +2011,14 @@ namespace PdfWriter m_nSubtype = WidgetRadiobutton; CWidgetAnnotation::SetFlag(nFlags); } + std::string CCheckBoxWidget::GetTC(bool bCAPS) + { + std::string sDA = GetColor(m_arrTC, bCAPS); + if (sDA.empty()) + sDA = bCAPS ? "0 G" : "0 g"; + sDA += "\012"; + return sDA; + } //---------------------------------------------------------------------------------------- // CTextWidget //---------------------------------------------------------------------------------------- diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index 73ae2077f1..4d2edad790 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -548,6 +548,7 @@ namespace PdfWriter virtual void SetFlag (const int& nFlag); void SetAP(); void SwitchAP(const std::string& sV, int nI = -1); + std::string GetTC(bool bCAPS); std::string Yes(); void Off(); diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index c4ee5bf86e..edb9eb055d 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -3264,12 +3264,13 @@ namespace PdfWriter double dShift = dBorder / 2.0; if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset) dShift *= 2.0; - m_pStream->WriteStr("0 g\012q\012"); + m_pStream->WriteStr("q\012"); m_pStream->WriteStr("1 0 0 1 "); m_pStream->WriteReal(dCX); m_pStream->WriteChar(' '); m_pStream->WriteReal(dCY); m_pStream->WriteStr(" cm\012"); + m_pStream->WriteStr(pAnnot->GetTC(false).c_str()); StreamWriteCircle(m_pStream, 0, 0, dR / 2.0 - dShift); m_pStream->WriteStr("f\012Q\012"); } @@ -3375,12 +3376,13 @@ namespace PdfWriter { case ECheckBoxStyle::Check: { - m_pStream->WriteStr("0 g\012q\012"); + m_pStream->WriteStr("q\012"); m_pStream->WriteStr("1 0 0 1 "); m_pStream->WriteReal((bW ? dDiff : 0) + dShift); m_pStream->WriteChar(' '); m_pStream->WriteReal((bW ? 0 : dDiff) + dShift); m_pStream->WriteStr(" cm\012"); + m_pStream->WriteStr(pAnnot->GetTC(false).c_str()); double dScale = (std::min(dW, dH) - dShift * 2.0) / 20.0; StreamWriteXYMove(m_pStream, 5.2381 * dScale, 11.2 * dScale); @@ -3400,7 +3402,8 @@ namespace PdfWriter dCross *= 2; m_pStream->WriteStr("q\012"); StreamWriteRect(m_pStream, dCross, dCross, dW - dCross, dH - dCross); - m_pStream->WriteStr("W\012n\0120 G\0121 w\012"); + m_pStream->WriteStr("W\012n\0121 w\012"); + m_pStream->WriteStr(pAnnot->GetTC(true).c_str()); double x1 = dShift + 1 + (bW ? dDiff : 0); double y1 = dShift + 1 + (bW ? 0 : dDiff); @@ -3417,12 +3420,13 @@ namespace PdfWriter case ECheckBoxStyle::Diamond: { double dSq = dC - dShift * 2.0 - 1; - m_pStream->WriteStr("0 g\012q\012"); + m_pStream->WriteStr("q\012"); m_pStream->WriteStr("1 0 0 1 "); m_pStream->WriteReal(dCX); m_pStream->WriteChar(' '); m_pStream->WriteReal(dCY); m_pStream->WriteStr(" cm\012"); + m_pStream->WriteStr(pAnnot->GetTC(false).c_str()); StreamWriteXYMove(m_pStream, -dSq, 0); StreamWriteXYLine(m_pStream, 0, dSq); StreamWriteXYLine(m_pStream, dSq, 0); @@ -3434,12 +3438,13 @@ namespace PdfWriter { double dR = dC - dShift * 2.0 - 1; - m_pStream->WriteStr("0 g\012q\012"); + m_pStream->WriteStr("q\012"); m_pStream->WriteStr("1 0 0 1 "); m_pStream->WriteReal(dCX); m_pStream->WriteChar(' '); m_pStream->WriteReal(dCY); m_pStream->WriteStr(" cm\012"); + m_pStream->WriteStr(pAnnot->GetTC(false).c_str()); StreamWriteCircle(m_pStream, 0, 0, dR); m_pStream->WriteStr("f\012Q\012"); break; @@ -3450,7 +3455,8 @@ namespace PdfWriter double dRInner = dROuter / 2.5; int nPoints = 5; - m_pStream->WriteStr("0 g\012q\012"); + m_pStream->WriteStr("q\012"); + m_pStream->WriteStr(pAnnot->GetTC(false).c_str()); for (int i = 0; i < nPoints * 2; ++i) { double dR = i % 2 == 0 ? dROuter : dRInner; @@ -3469,7 +3475,8 @@ namespace PdfWriter { double dSq = std::min(dW, dH) * 2.0 / 3.0 - dShift * 2.0 - 1; - m_pStream->WriteStr("0 g\012q\012"); + m_pStream->WriteStr("q\012"); + m_pStream->WriteStr(pAnnot->GetTC(false).c_str()); StreamWriteRect(m_pStream, dCX - dSq / 2.0, dCY - dSq / 2.0, dSq, dSq); m_pStream->WriteStr("f\012Q\012"); break;