From db2660a1a3a2ba39868b6869ccb9b4e58501ee6d Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 25 Oct 2024 10:44:39 +0300 Subject: [PATCH] Text Widget write --- .../graphics/commands/AnnotField.cpp | 16 +- DesktopEditor/graphics/commands/AnnotField.h | 6 +- PdfFile/PdfWriter.cpp | 198 +++++++++++++++++- PdfFile/PdfWriter.h | 1 + 4 files changed, 215 insertions(+), 6 deletions(-) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index 75583ae581..7bb61a5d5c 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -933,7 +933,8 @@ void CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::Read(NSOnlineOfficeBinToP int CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetMaxLen() const { return m_nMaxLen; } const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetV() { return m_wsV; } const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetRV() { return m_wsRV; } -const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetAPV() { return m_wsAPV; } +const std::vector& CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetGID() { return m_arrGID; } +const std::vector< std::pair >& CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetUnicode() { return m_arrUnicode; } void CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags, int nWidgetFlag) { if (nFlags & (1 << 9)) @@ -943,7 +944,18 @@ void CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::Read(NSOnlineOfficeBinToPdf if (nWidgetFlag & (1 << 25)) m_wsRV = pReader->ReadString(); if (nFlags & (1 << 12)) - m_wsAPV = pReader->ReadString(); + { + int nLen = pReader->ReadInt(); + for (int i = 0; i < nLen; ++i) + { + int nGID = pReader->ReadInt(); + m_arrGID.push_back(nGID); + int nLen2 = pReader->ReadInt(); + m_arrUnicode.push_back(std::make_pair(nLen2, new unsigned int[nLen2])); + for (int j = 0; j < nLen2; ++j) + m_arrUnicode.back().second[j] = pReader->ReadInt(); + } + } } int CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetTI() const { return m_nTI; } diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index 9f7b8b1978..4a65f7d31d 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -85,7 +85,8 @@ public: int GetMaxLen() const; const std::wstring& GetV(); const std::wstring& GetRV(); - const std::wstring& GetAPV(); + const std::vector& GetGID(); + const std::vector< std::pair >& GetUnicode(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags, int nWidgetFlag); @@ -93,7 +94,8 @@ public: int m_nMaxLen; std::wstring m_wsV; std::wstring m_wsRV; - std::wstring m_wsAPV; + std::vector m_arrGID; + std::vector< std::pair > m_arrUnicode; }; class GRAPHICS_DECL CChoiceWidgetPr diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 9424325664..19d9ed976d 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2376,13 +2376,14 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF if (nFlags & (1 << 12)) { bAPValue = true; - wsValue = pPr->GetAPV(); pTextWidget->SetAPV(); } // ВНЕШНИЙ ВИД pTextWidget->SetFont(m_pFont, dFontSize, isBold, isItalic); - if ((bValue && pTextWidget->Get("T")) || bAPValue) + if (bAPValue) + DrawTextWidget(pAppFonts, pTextWidget, pPr->GetGID(), pPr->GetUnicode()); + else if (bValue && pTextWidget->Get("T")) DrawTextWidget(pAppFonts, pTextWidget, wsValue); } else if (oInfo.IsChoiceWidget()) @@ -3591,6 +3592,199 @@ void CPdfWriter::DrawAP(PdfWriter::CAnnotation* pAnnot, BYTE* pRender, LONG nLen m_pDocument->SetCurPage(pCurPage); RELEASEOBJECT(pFakePage); } +void CPdfWriter::DrawTextWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::vector& arrGID, const std::vector< std::pair >& arrUnicode) +{ + if (!pAppFonts || !pTextWidget) + return; + PdfWriter::CFontCidTrueType* pFont = pTextWidget->GetFont(); + if (!pFont) + return; + PdfWriter::CFontTrueType* pFontTT = m_pDocument->CreateTrueTypeFont(pFont); + double dFontSize = pTextWidget->GetFontSize(); + bool isBold = pTextWidget->GetFontIsBold(); + bool isItalic = pTextWidget->GetFontIsItalic(); + bool isComb = pTextWidget->IsCombFlag(); + double dWidth = pTextWidget->GetWidth(); + double dHeight = pTextWidget->GetHeight(); + BYTE nAlign = pTextWidget->GetQ(); + + if (!pTextWidget->HaveBorder() && pTextWidget->HaveBC()) + pTextWidget->SetBorder(0, 1, {}); + double dShiftBorder = pTextWidget->GetBorderWidth(); + BYTE nType = pTextWidget->GetBorderType(); + if (nType == 1 || nType == 3) + dShiftBorder *= 2; + + // Коды, шрифты, количество + unsigned int unLen = arrGID.size(); + unsigned int* pUnicodes = new unsigned int[unLen]; + unsigned short* pCodes = new unsigned short[unLen]; + PdfWriter::CFontCidTrueType** ppFonts = new PdfWriter::CFontCidTrueType*[unLen]; + + for (unsigned int i = 0; i < unLen; ++i) + { + //unsigned char* pCodes = new unsigned char[2]; + unsigned short ushCode = pFont->EncodeGID(arrGID[i], arrUnicode[i].second, arrUnicode[i].first); + //pCodes[0] = (ushCode >> 8) & 0xFF; + //pCodes[1] = ushCode & 0xFF; + + //unsigned char* pCodes = EncodeGID(arrGID->at(i).first, pUnicodes, unUnicodeCount); + + /* + unsigned int unUnicode = pUnicodes[unIndex]; + + if (!pFont->HaveChar(unUnicode)) + { + std::wstring wsFontFamily = pAppFonts->GetFontBySymbol(unUnicode); + PdfWriter::CFontCidTrueType* pTempFont = GetFont(wsFontFamily, bBold, bItalic); + if (pTempFont) + { + pCodes[unIndex] = pTempFont->EncodeUnicode(unUnicode); + ppFonts[unIndex] = pTempFont; + continue; + } + } + */ + pCodes[i] = ushCode; + ppFonts[i] = pFont; + + pUnicodes[i] = arrUnicode[i].second[0]; + } + + bool bFont = true; + //GetFontData(pAppFonts, wsValue, pFont, isBold, isItalic, pUnicodes, unLen, pCodes, ppFonts); + if (!bFont) + { + pTextWidget->SetEmptyAP(); + RELEASEARRAYOBJECTS(pUnicodes); + RELEASEARRAYOBJECTS(pCodes); + RELEASEARRAYOBJECTS(ppFonts); + return; + } + + if (!isComb && pTextWidget->IsMultiLine() && pFontTT) + { + unsigned short* pCodes2 = new unsigned short[unLen]; + unsigned int* pWidths = new unsigned int[unLen]; + + unsigned short ushSpaceCode = 0xFFFF; + unsigned short ushNewLineCode = 0xFFFE; + for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) + { + unsigned short ushCode = 0; + if (0x0020 == pUnicodes[unIndex]) + ushCode = ushSpaceCode; + else if (0x000D == pUnicodes[unIndex] || 0x000A == pUnicodes[unIndex]) + ushCode = ushNewLineCode; + + pCodes2[unIndex] = ushCode; + pWidths[unIndex] = ppFonts[unIndex]->GetWidth(pCodes[unIndex]); + } + + m_oLinesManager.Init(pCodes2, pWidths, unLen, ushSpaceCode, ushNewLineCode, pFontTT->GetLineHeight(), pFontTT->GetAscent()); + + double dKoef = dFontSize / pFontTT->m_dUnitsPerEm; + double dLineHeight = (pFontTT->m_dAscent + std::abs(pFontTT->m_dDescent)) * dKoef; + + m_oLinesManager.CalculateLines(dFontSize, dWidth - dShiftBorder * 4); + + pTextWidget->StartAP(); + + unsigned int unLinesCount = m_oLinesManager.GetLinesCount(); + double dLineShiftY = dHeight - dShiftBorder * 2 - dLineHeight; + for (unsigned int unIndex = 0; unIndex < unLinesCount; ++unIndex) + { + unsigned int unLineStart = m_oLinesManager.GetLineStartPos(unIndex); + double dLineShiftX = dShiftBorder * 2; + double dLineWidth = m_oLinesManager.GetLineWidth(unIndex, dFontSize); + if (2 == nAlign) + dLineShiftX = dWidth - dLineWidth - dShiftBorder * 2; + else if (1 == nAlign) + dLineShiftX = (dWidth - dLineWidth) / 2; + + int nInLineCount = m_oLinesManager.GetLineEndPos(unIndex) - m_oLinesManager.GetLineStartPos(unIndex); + if (nInLineCount > 0) + pTextWidget->AddLineToAP(dLineShiftX, dLineShiftY, pCodes + unLineStart, nInLineCount, ppFonts + unLineStart, NULL); + + dLineShiftY -= dLineHeight; + } + + pTextWidget->EndAP(); + + m_oLinesManager.Clear(); + + RELEASEARRAYOBJECTS(pCodes2); + RELEASEARRAYOBJECTS(pWidths); + } + else + { + double* pShifts = NULL; + unsigned int unShiftsCount = 0; + double dShiftX = dShiftBorder * 2; + if (dShiftX == 0) + dShiftX = 2; + + if (isComb) + { + unShiftsCount = unLen; + pShifts = new double[unShiftsCount]; + if (pShifts && unShiftsCount) + { + dShiftX = 0; + unsigned int unCellsCount = std::max(unShiftsCount, pTextWidget->GetMaxLen()); + double dPrevW = 0; + double dCellW = dWidth / unCellsCount; + + if (1 == nAlign) + { + unsigned int unCells = (unCellsCount - unShiftsCount) / 2; + dPrevW = unCells * dCellW; + } + if (2 == nAlign) + dPrevW = (unCellsCount - unShiftsCount) * dCellW; + + for (unsigned int unIndex = 0; unIndex < unShiftsCount; ++unIndex) + { + unsigned short ushCode = pCodes[unIndex]; + double dGlyphWidth = ppFonts[unIndex]->GetGlyphWidth(ushCode) / 1000.0 * dFontSize; + double dTempShift = (dCellW - dGlyphWidth) / 2; + pShifts[unIndex] = dPrevW + dTempShift; + dPrevW = dCellW - dTempShift; + } + } + } + else if (1 == nAlign || 2 == nAlign) + { + double dLineWidth = 0; + for (unsigned int unIndex = 0; unIndex < unLen; ++unIndex) + { + unsigned short ushCode = pCodes[unIndex]; + double dLetterWidth = ppFonts[unIndex]->GetWidth(ushCode) / 1000.0 * dFontSize; + dLineWidth += dLetterWidth; + } + + if (2 == nAlign) + dShiftX = dWidth - dLineWidth - dShiftBorder * 2; + else if (1 == nAlign) + dShiftX = (dWidth - dLineWidth) / 2; + } + + double dBaseLine = (dHeight - dFontSize) / 2.0 - dShiftBorder; + if (pFontTT) + { + double dKoef = dFontSize / pFontTT->m_dUnitsPerEm; + double dLineHeight = (pFontTT->m_dAscent + std::abs(pFontTT->m_dDescent)) * dKoef;; + dBaseLine = (dHeight - dLineHeight) / 2.0 + std::abs(pFontTT->m_dDescent * dKoef); + } + + pTextWidget->SetAP(L"", pCodes, unLen, dShiftX, dBaseLine, ppFonts, pShifts); + RELEASEARRAYOBJECTS(pShifts); + } + + RELEASEARRAYOBJECTS(pUnicodes); + RELEASEARRAYOBJECTS(pCodes); + RELEASEARRAYOBJECTS(ppFonts); +} void CPdfWriter::DrawTextWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::wstring& wsValue) { if (!pAppFonts || !pTextWidget) diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index ddb97e0a46..dba43df6d9 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -248,6 +248,7 @@ private: std::wstring GetDownloadFile(const std::wstring& sUrl, const std::wstring& wsTempDirectory); void DrawAP(PdfWriter::CAnnotation* pAnnot, BYTE* pRender, LONG nLenRender); void DrawTextWidget (NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::wstring& wsValue); + void DrawTextWidget (NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::vector& arrGID, const std::vector< std::pair >& arrUnicode); void DrawChoiceWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CChoiceWidget* pChoiceWidget, const std::vector& arrValue); void DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CPushButtonWidget* pButtonWidget, BYTE nAP, PdfWriter::CXObject* pForm);