/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) * version 3 as published by the Free Software Foundation. In accordance with * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect * that Ascensio System SIA expressly excludes the warranty of non-infringement * of any third-party rights. * * This program is distributed WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html * * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish * street, Riga, Latvia, EU, LV-1050. * * The interactive user interfaces in modified source and object code versions * of the Program must display Appropriate Legal Notices, as required under * Section 5 of the GNU AGPL version 3. * * Pursuant to Section 7(b) of the License you must retain the original Product * logo when distributing the program. Pursuant to Section 7(e) we decline to * grant you any rights under trademark law for use of our trademarks. * * All the Product's GUI elements, including illustrations and icon sets, as * well as technical writing content are licensed under the terms of the * Creative Commons Attribution-ShareAlike 4.0 International. See the License * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ #include "Field.h" #include "Pages.h" #include "Streams.h" #include "Document.h" #include "ResourcesDictionary.h" #include "Types.h" #include "Image.h" #include "Font.h" #include "Info.h" #include "EncryptDictionary.h" #include "Annotation.h" #include #include #include "../../DesktopEditor/common/SystemUtils.h" #include "../../DesktopEditor/common/File.h" #ifndef BS_DEF_WIDTH #define BS_DEF_WIDTH 1 #endif namespace PdfWriter { void AdjustLineEndpoint(ELineEndType nType, double x, double y, double dx, double dy, double w, double& tx, double& ty) { tx = x; ty = y; switch (nType) { case ELineEndType::ClosedArrow: case ELineEndType::OpenArrow: case ELineEndType::Diamond: { tx += w * dx; if ((dx > 0.001 && dy > 0) || (dx < -0.001 && dy < 0)) ty += w * dy; break; } case ELineEndType::Square: case ELineEndType::Circle: { if ((dx > -0.02 && dy < 0.02) || (dx < 0.02 && dy > -0.02)) tx += w * dx; break; } case ELineEndType::Slash: case ELineEndType::Butt: case ELineEndType::ROpenArrow: case ELineEndType::RClosedArrow: case ELineEndType::None: default: break; } } void StreamWriteCM(CStream* pStream, double m11, double m12, double m21, double m22, double tx, double ty) { pStream->WriteReal(m11); pStream->WriteChar(' '); pStream->WriteReal(m12); pStream->WriteChar(' '); pStream->WriteReal(m21); pStream->WriteChar(' '); pStream->WriteReal(m22); pStream->WriteChar(' '); pStream->WriteReal(tx); pStream->WriteChar(' '); pStream->WriteReal(ty); pStream->WriteStr(" cm\012"); } void StreamWriteXYMove(CStream* pStream, double x, double y) { pStream->WriteReal(x); pStream->WriteChar(' '); pStream->WriteReal(y); pStream->WriteStr(" m\012"); } void StreamWriteXYLine(CStream* pStream, double x, double y) { pStream->WriteReal(x); pStream->WriteChar(' '); pStream->WriteReal(y); pStream->WriteStr(" l\012"); } void StreamWriteXYCurve(CStream* pStream, double x1, double y1, double x2, double y2, double x3, double y3) { pStream->WriteReal(x1); pStream->WriteChar(' '); pStream->WriteReal(y1); pStream->WriteChar(' '); pStream->WriteReal(x2); pStream->WriteChar(' '); pStream->WriteReal(y2); pStream->WriteChar(' '); pStream->WriteReal(x3); pStream->WriteChar(' '); pStream->WriteReal(y3); pStream->WriteStr(" c\012"); } void StreamWriteRect(CStream* pStream, double x1, double y1, double x2, double y2) { pStream->WriteReal(x1); pStream->WriteChar(' '); pStream->WriteReal(y1); pStream->WriteChar(' '); pStream->WriteReal(x2); pStream->WriteChar(' '); pStream->WriteReal(y2); pStream->WriteStr(" re\012"); } void StreamWriteCircle(CStream* pStream, double cx, double cy, double r) { double bezierCircle = 0.55228475 * r; StreamWriteXYMove(pStream, cx + r, cy); StreamWriteXYCurve(pStream, cx + r, cy + bezierCircle, cx + bezierCircle, cy + r, cx, cy + r); StreamWriteXYCurve(pStream, cx - bezierCircle, cy + r, cx - r, cy + bezierCircle, cx - r, cy); StreamWriteXYCurve(pStream, cx - r, cy - bezierCircle, cx - bezierCircle, cy - r, cx, cy - r); StreamWriteXYCurve(pStream, cx + bezierCircle, cy - r, cx + r, cy - bezierCircle, cx + r, cy); } void DrawArrow(CStream* pStream, ELineEndType nType, double x, double y, double dx, double dy, double w) { double lineEndSize1 = 3, pi = 3.14159265358979323846; switch (nType) { case ELineEndType::Butt: { w *= lineEndSize1; StreamWriteXYMove(pStream, x + w * dy, y - w * dx); StreamWriteXYLine(pStream, x - w * dy, y + w * dx); pStream->WriteStr("S\012"); break; } case ELineEndType::Circle: { StreamWriteCircle(pStream, x, y, w * lineEndSize1); pStream->WriteStr("h\012B\012"); break; } case ELineEndType::Diamond: { w *= lineEndSize1; StreamWriteXYMove(pStream, x - w, y); StreamWriteXYLine(pStream, x, y + w); StreamWriteXYLine(pStream, x + w, y); StreamWriteXYLine(pStream, x, y - w); pStream->WriteStr("b\012"); break; } case ELineEndType::OpenArrow: case ELineEndType::ClosedArrow: { w *= lineEndSize1 * lineEndSize1; double d32 = pi * 32.0 / 180.0; double d28 = pi * 28.0 / 180.0; if ((dx > 0.001 && dy < 0) || (dx < -0.001 && dy > 0)) { StreamWriteXYMove(pStream, x + w * cos(d32) * dx + w * sin(d32) * dy, y + w * cos(d32) * dy - w * sin(d32) * dx); StreamWriteXYLine(pStream, x, y); StreamWriteXYLine(pStream, x + w * cos(d28) * dx - w * sin(d28) * dy, y + w * cos(d28) * dy + w * sin(d28) * dx); } else { double dCos = w * cos(pi / 6.0); double dSin = w * sin(pi / 6.0); StreamWriteXYMove(pStream, x + dCos * dx + dSin * dy, y + dCos * dy - dSin * dx); StreamWriteXYLine(pStream, x, y); StreamWriteXYLine(pStream, x + dCos * dx - dSin * dy, y + dCos * dy + dSin * dx); } pStream->WriteStr(nType == ELineEndType::OpenArrow ? "S\012" : "b\012"); break; } case ELineEndType::ROpenArrow: case ELineEndType::RClosedArrow: { x -= cos(pi / 18.0) * dx * w; y -= cos(pi / 18.0) * dy * w; w *= lineEndSize1 * lineEndSize1; double dCos = w * cos(pi / 6.0); double dSin = w * sin(pi / 6.0); StreamWriteXYMove(pStream, x - dCos * dx + dSin * dy, y - dCos * dy - dSin * dx); StreamWriteXYLine(pStream, x, y); StreamWriteXYLine(pStream, x - dCos * dx - dSin * dy, y - dCos * dy + dSin * dx); pStream->WriteStr(nType == ELineEndType::ROpenArrow ? "S\012" : "b\012"); break; } case ELineEndType::Slash: { w *= lineEndSize1 * lineEndSize1; double dCos = w * cos(pi / 6.0); double dSin = w * sin(pi / 6.0); StreamWriteXYMove(pStream, x + dCos * dy - dSin * dx, y - dCos * dx - dSin * dy); StreamWriteXYLine(pStream, x - dCos * dy + dSin * dx, y + dCos * dx + dSin * dy); pStream->WriteStr("S\012"); break; } case ELineEndType::Square: { w *= lineEndSize1; pStream->WriteReal(x - w); pStream->WriteChar(' '); pStream->WriteReal(y - w); pStream->WriteChar(' '); pStream->WriteReal(w * 2); pStream->WriteChar(' '); pStream->WriteReal(w * 2); pStream->WriteStr(" re\012"); pStream->WriteStr("B\012"); break; } case ELineEndType::None: default: { break; } } } void DrawLineArrow(CStream* pStream, double dBorderSize, double x1, double y1, double x2, double y2, ELineEndType nLE1, ELineEndType nLE2, double dLL = 0, double dLLO = 0, double dLLE = 0) { double dDX = x2 - x1; double dDY = y2 - y1; double dLen = sqrt(dDX * dDX + dDY * dDY); if (dLen > 0) { dDX /= dLen; dDY /= dLen; } double lx1, ly1, lx2, ly2; double ax1, ay1, ax2, ay2; double bx1, by1, bx2, by2; if (dLL != 0) { ax1 = x1 + dLLO * dDY; ay1 = y1 - dLLO * dDX; lx1 = ax1 + dLL * dDY; ly1 = ay1 - dLL * dDX; bx1 = lx1 + dLLE * dDY; by1 = ly1 - dLLE * dDX; ax2 = x2 + dLLO * dDY; ay2 = y2 - dLLO * dDX; lx2 = ax2 + dLL * dDY; ly2 = ay2 - dLL * dDX; bx2 = lx2 + dLLE * dDY; by2 = ly2 - dLLE * dDX; } else { lx1 = x1; ly1 = y1; lx2 = x2; ly2 = y2; ax1 = ay1 = ax2 = ay2 = 0; bx1 = by1 = bx2 = by2 = 0; } double tx1, ty1, tx2, ty2; AdjustLineEndpoint(nLE1, lx1, ly1, dDX, dDY, dBorderSize, tx1, ty1); AdjustLineEndpoint(nLE2, lx2, ly2, -dDX, -dDY, dBorderSize, tx2, ty2); if (dLL) { StreamWriteXYMove(pStream, ax1, ay1); StreamWriteXYLine(pStream, bx1, by1); StreamWriteXYMove(pStream, ax2, ay2); StreamWriteXYLine(pStream, bx2, by2); } StreamWriteXYMove(pStream, tx1, ty1); StreamWriteXYLine(pStream, tx2, ty2); pStream->WriteStr("S\012"); DrawArrow(pStream, nLE1, tx1, ty1, dDX, dDY, dBorderSize); DrawArrow(pStream, nLE2, tx2, ty2, -dDX, -dDY, dBorderSize); } //---------------------------------------------------------------------------------------- // CFieldBase //---------------------------------------------------------------------------------------- CFieldBase::CFieldBase(CXref* pXref, CDocument* pDocument) { pXref->Add(this); Add("Ff", (unsigned int)0); m_pXref = pXref; m_pDocument = pDocument; m_nBorderType = 0; m_dBorderSize = 0; m_bAutoFit = false; m_bShd = false; m_pMK = NULL; m_pParent = NULL; m_pKids = NULL; m_pAppearance = NULL; m_pFocus = NULL; m_pBlur = NULL; m_pFont = NULL; } void CFieldBase::SetReadOnlyFlag(bool isReadOnly) { SetFlag(isReadOnly, 1 << 0); } void CFieldBase::SetRequiredFlag(bool isRequired) { SetFlag(isRequired, 1 << 1); } void CFieldBase::SetNoExportFlag(bool isNoExport) { SetFlag(isNoExport, 1 << 2); } void CFieldBase::SetFlag(bool isFlag, int nBit) { int nFlags = ((CNumberObject*)this->Get("Ff"))->Get(); if ((nFlags & nBit) && !isFlag) { nFlags &= 0xffffffff ^ nBit; } else if (!(nFlags & nBit) && isFlag) { nFlags |= nBit; } Add("Ff", nFlags); } CDictObject* CFieldBase::GetAA() { CDictObject* pAA = dynamic_cast(this->Get("AA")); if (pAA) return pAA; pAA = new CDictObject(); if (!pAA) return NULL; Add("AA", pAA); return pAA; } void CFieldBase::AddScriptToAA(const std::string& sKey, const std::string& sScript, CDictObject* pAA) { if (sScript.empty()) return; if (!pAA) pAA = GetAA(); if (!pAA) return; CDictObject* pKey = new CDictObject(); if (!pKey) return; m_pXref->Add(pKey); pAA->Add(sKey.c_str(), pKey); pKey->Add("S", "JavaScript"); pKey->Add("JS", new CStringObject(sScript.c_str(), true, true)); } void CFieldBase::AddPageRect(CPage* pPage, const TRect& oRect) { if (!pPage) return; pPage->AddAnnotation(this); Add("Type", "Annot"); Add("Subtype", "Widget"); Add("P", pPage); CArrayObject* pArray = new CArrayObject(); if (!pArray) return; Add("Rect", pArray); if (oRect.fTop < oRect.fBottom) { pArray->Add(oRect.fLeft); pArray->Add(oRect.fTop); pArray->Add(oRect.fRight); pArray->Add(oRect.fBottom); m_oRect.fLeft = oRect.fLeft; m_oRect.fTop = oRect.fTop; m_oRect.fRight = oRect.fRight; m_oRect.fBottom = oRect.fBottom; } else { pArray->Add(oRect.fLeft); pArray->Add(oRect.fBottom); pArray->Add(oRect.fRight); pArray->Add(oRect.fTop); m_oRect.fLeft = oRect.fLeft; m_oRect.fTop = oRect.fBottom; m_oRect.fRight = oRect.fRight; m_oRect.fBottom = oRect.fTop; } Add("F", 4); } void CFieldBase::SetFieldName(const std::string& sName, bool isSkipCheck) { if (isSkipCheck || !m_pDocument->CheckFieldName(this, sName)) Add("T", new CStringObject(sName.c_str())); } void CFieldBase::SetFieldName(const std::wstring& wsName, bool isSkipCheck) { std::string sName = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(wsName); if (isSkipCheck || !m_pDocument->CheckFieldName(this, sName)) Add("T", new CStringObject(sName.c_str(), true)); } void CFieldBase::ClearKidRecords() { Remove("T"); Remove("FT"); Remove("Ff"); Remove("V"); Remove("AA"); } void CFieldBase::SetFieldHint(const std::wstring& wsHint) { if (wsHint != L"") { std::string sHint = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(wsHint); Add("TU", new CStringObject(sHint.c_str(), true)); } else { Remove("TU"); } } TRect& CFieldBase::GetRect() { return m_oRect; } CResourcesDict* CFieldBase::GetResourcesDict() { return m_pDocument->GetFieldsResources(); } void CFieldBase::SetDefaultAppearance(CFontDict* pFont, const double& dFontSize, const TRgb& oColor) { CResourcesDict* pFieldsResources = m_pDocument->GetFieldsResources(); const char* sFontName = pFieldsResources->GetFontName(pFont); if (!sFontName) return; std::string sDA; sDA.append(std::to_string(oColor.r)); sDA.append(" "); sDA.append(std::to_string(oColor.g)); sDA.append(" "); sDA.append(std::to_string(oColor.b)); sDA.append(" rg /"); sDA.append(sFontName); if (IsAutoFit()) { sDA.append(" 0 Tf"); } else { sDA.append(" "); sDA.append(std::to_string(dFontSize)); sDA.append(" Tf"); } Add("DA", new CStringObject(sDA.c_str(), false, true)); } void CFieldBase::SetTextAppearance(const std::wstring& wsValue, unsigned short* pCodes, unsigned int unCount, CFontDict* pFont, const TRgb& oColor, const double& dAlpha, double dFontSize, double dX, double dY, CFontCidTrueType** ppFonts, double* pShifts) { CAnnotAppearance* pAppearance = new CAnnotAppearance(m_pXref, this); Add("AP", pAppearance); CAnnotAppearanceObject* pNormal = pAppearance->GetNormal(); CResourcesDict* pFieldsResources = m_pDocument->GetFieldsResources(); const char* sExtGrStateName = NULL; if (fabs(dAlpha - 1.0) > 0.001) { CExtGrState* pExtGrState = m_pDocument->GetFillAlpha(dAlpha); sExtGrStateName = pFieldsResources->GetExtGrStateName(pExtGrState); } pNormal->DrawSimpleText(wsValue, pCodes, unCount, pFont, dFontSize, dX, dY, oColor.r, oColor.g, oColor.b, sExtGrStateName, fabs(m_oRect.fRight - m_oRect.fLeft), fabs(m_oRect.fBottom - m_oRect.fTop), ppFonts, pShifts); m_pFont = pNormal->GetFont(); } void CFieldBase::StartTextAppearance(CFontDict* pFont, const double& dFontSize, const TRgb& oColor, const double& dAlpha) { m_pAppearance = new CAnnotAppearance(m_pXref, this); if (!m_pAppearance) return; Add("AP", m_pAppearance); CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); CResourcesDict* pFieldsResources = GetResourcesDict(); const char* sExtGrStateName = NULL; if (fabs(dAlpha - 1.0) > 0.001) { CExtGrState* pExtGrState = m_pDocument->GetFillAlpha(dAlpha); sExtGrStateName = pFieldsResources->GetExtGrStateName(pExtGrState); } pNormal->StartDrawText(pFont, dFontSize, oColor.r, oColor.g, oColor.b, sExtGrStateName, fabs(m_oRect.fRight - m_oRect.fLeft), fabs(m_oRect.fBottom - m_oRect.fTop)); m_pFont = pNormal->GetFont(); } void CFieldBase::AddLineToTextAppearance(const double& dX, const double& dY, unsigned short* pCodes, const unsigned int& unCodesCount, CFontCidTrueType** ppFonts, const double* pShifts) { if (!m_pAppearance) return; CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); pNormal->DrawTextLine(dX, dY, pCodes, unCodesCount, ppFonts, pShifts); m_pFont = pNormal->GetFont(); } void CFieldBase::EndTextAppearance() { if (!m_pAppearance) return; CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal(); pNormal->EndDrawText(); } void CFieldBase::SetTextValue(const std::wstring &wsValue) { std::string sValue = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(wsValue); Add("V", new CStringObject(sValue.c_str(), true)); } void CFieldBase::SetFieldBorder(const EBorderSubtype& eSubtype, const TRgb& oColor, const double& dWidth, const unsigned short& nDashOn, const unsigned short& nDashOff, const unsigned short& nDashPhase) { if (dWidth < 0.01) { m_nBorderType = 0; Remove("BS"); return; } CDictObject* pBorderStyleDict = new CDictObject(); if (!pBorderStyleDict) return; Add("BS", pBorderStyleDict); // PDF ридеры воспринимают только целочисленные значения толщины линии int nWidth = (int)(dWidth + 0.5); if (nWidth < 1) nWidth = 1; pBorderStyleDict->Add("W", nWidth); if (border_subtype_Dashed == eSubtype) { CArrayObject* pDash = new CArrayObject(); if (!pDash) return; pBorderStyleDict->Add("D", pDash); pBorderStyleDict->Add("Type", "Border"); pDash->Add(nDashOn); pDash->Add(nDashOff); if (0 != nDashPhase) pDash->Add(nDashOff); } switch (eSubtype) { case border_subtype_Solid: pBorderStyleDict->Add("S", "S"); break; case border_subtype_Dashed: pBorderStyleDict->Add("S", "D"); break; case border_subtype_Beveled: pBorderStyleDict->Add("S", "B"); break; case border_subtype_Inset: pBorderStyleDict->Add("S", "I"); break; case border_subtype_Underlined: pBorderStyleDict->Add("S", "U"); break; } if (!m_pMK) { m_pMK = new CDictObject(); Add("MK", m_pMK); } if (!m_pMK) return; CArrayObject* pColor = new CArrayObject(); pColor->Add(oColor.r); pColor->Add(oColor.g); pColor->Add(oColor.b); m_pMK->Add("BC", pColor); m_nBorderType = 1; m_dBorderSize = nWidth; m_oBorderColor = oColor; } bool CFieldBase::HaveBorder() const { return m_nBorderType == 1; } const double& CFieldBase::GetBorderSize() const { return m_dBorderSize; } const TRgb& CFieldBase::GetBorderColor() const { return m_oBorderColor; } const bool& CFieldBase::IsAutoFit() const { return m_bAutoFit; } void CFieldBase::SetAutoFit(const bool& isAutoFit) { m_bAutoFit = isAutoFit; } bool CFieldBase::HaveShd() const { return m_bShd; } void CFieldBase::SetShd(const TRgb& oRgb) { m_oShdColor = oRgb; if (!m_pMK) { m_pMK = new CDictObject(); Add("MK", m_pMK); } if (!m_pMK) return; CArrayObject* pBG = new CArrayObject(); if (pBG) { pBG->Add(oRgb.r); pBG->Add(oRgb.g); pBG->Add(oRgb.b); m_pMK->Add("BG", pBG); } m_bShd = true; } const TRgb& CFieldBase::GetShdColor() const { return m_oShdColor; } void CFieldBase::SetParent(CFieldBase* pParent) { m_pParent = pParent; Add("Parent", pParent); } void CFieldBase::AddKid(CFieldBase* pChild) { if (!m_pKids) { m_pKids = new CArrayObject(); Add("Kids", m_pKids); } m_pKids->Add(pChild); } int CFieldBase::GetKidsCount() const { if (!m_pKids) return 0; return m_pKids->GetCount(); } int CFieldBase::GetFieldFlag() const { return ((CNumberObject*)Get("Ff"))->Get(); } const char* CFieldBase::GetFieldType() const { return ((CNameObject*)Get("FT"))->Get(); } void CFieldBase::SetAlign(const EFieldAlignType& eType) { Add("Q", (int)eType); } void CFieldBase::SetPlaceHolderText(const std::wstring& wsText, const TRgb& oNormalColor, const TRgb& oPlaceHolderColor) { m_wsPlaceHolderText = wsText; m_oNormalColor = oNormalColor; m_oPlaceHolderColor = oPlaceHolderColor; SetPlaceHolderText(std::vector{wsText}, {oNormalColor}, {oPlaceHolderColor}); if (m_pParent) m_pParent->UpdateKidsPlaceHolder(); } void CFieldBase::SetPlaceHolderText(const std::vector& vPlaceHolders, const std::vector& vNormalColors, const std::vector& vPlaceHolderColors) { if (!vPlaceHolders.size() || !vNormalColors.size() || !vPlaceHolderColors.size()) return; std::string sFocus = "\nvar curColor = color.convert(event.target.textColor, \"RGB\");\nif (("; for (unsigned int unIndex = 0, unCount = vPlaceHolders.size(); unIndex < unCount; ++unIndex) { if (unIndex) sFocus += " || "; std::string sText = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(vPlaceHolders[unIndex]); sFocus += "event.target.value==\"" + sText + "\""; } sFocus += ") && ("; for (unsigned int unIndex = 0, unCount = vPlaceHolderColors.size(); unIndex < unCount; ++unIndex) { if (unIndex) sFocus += " || "; const TRgb& oColor = vPlaceHolderColors[unIndex]; sFocus += "(Math.abs(curColor[1] - " + std::to_string(oColor.r) + ") < 0.005 && Math.abs(curColor[2] - " + std::to_string(oColor.g) + ") < 0.005 && Math.abs(curColor[3] - " + std::to_string(oColor.b) + ") < 0.005)"; } sFocus += "))\n{ event.target.value = \"\";\n event.target.textColor =[\"RGB\", " + std::to_string(vNormalColors[vNormalColors.size() - 1].r) + ", " + std::to_string(vNormalColors[vNormalColors.size() - 1].g) + ", " + std::to_string(vNormalColors[vNormalColors.size() - 1].b) + "];\n}"; std::string sText = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(vPlaceHolders[vPlaceHolders.size() - 1]); const TRgb& oColor = vPlaceHolderColors[vPlaceHolderColors.size() - 1]; std::string sBlur = "\nif (event.target.value == \"\")\n{\n event.target.textColor =[\"RGB\", " + std::to_string(oColor.r) + ", " + std::to_string(oColor.g) + ", " + std::to_string(oColor.b) + "];\nevent.target.value = \"" + sText + "\";\n}"; if (!m_pFocus || !m_pBlur) { CDictObject* pAA = GetAA(); if (!pAA) return; CDictObject* pFocus = new CDictObject(); CDictObject* pBlur = new CDictObject(); if (!pFocus || !pBlur) return; m_pXref->Add(pFocus); m_pXref->Add(pBlur); m_pFocus = pFocus; m_pBlur = pBlur; pAA->Add("Bl", pBlur); pAA->Add("Fo", pFocus); } m_pFocus->Add("S", "JavaScript"); m_pFocus->Add("JS", new CStringObject(sFocus.c_str(), true, true)); m_pBlur->Add("S", "JavaScript"); m_pBlur->Add("JS", new CStringObject(sBlur.c_str(), true, true)); } void CFieldBase::UpdateKidsPlaceHolder() { std::vector vText; std::vector vPlaceHolderColor, vNormalColor; if (m_pKids) { for (unsigned int unKidIndex = 0, unKidsCount = GetKidsCount(); unKidIndex < unKidsCount; ++unKidIndex) { CFieldBase* pKid = (CFieldBase*)m_pKids->Get(unKidIndex); const std::wstring& wsText = pKid->GetPlaceHolderText(); if (wsText.empty()) continue; const TRgb& oPColor = pKid->GetPlaceHolderColor(); const TRgb& oNColor = pKid->GetNormalColor(); bool isAdd = true; for (unsigned int unIndex = 0, unCount = vText.size(); unIndex < unCount; ++unIndex) { if (vText[unIndex] == wsText) { isAdd = false; break; } } if (isAdd) vText.push_back(wsText); isAdd = true; for (unsigned int unIndex = 0, unCount = vPlaceHolderColor.size(); unIndex < unCount; ++unIndex) { if (vPlaceHolderColor[unIndex] == oPColor) { isAdd = false; break; } } if (isAdd) vPlaceHolderColor.push_back(oPColor); isAdd = true; for (unsigned int unIndex = 0, unCount = vNormalColor.size(); unIndex < unCount; ++unIndex) { if (vNormalColor[unIndex] == oNColor) { isAdd = false; break; } } if (isAdd) vNormalColor.push_back(oNColor); } for (unsigned int unKidIndex = 0, unKidsCount = GetKidsCount(); unKidIndex < unKidsCount; ++unKidIndex) { CFieldBase* pKid = (CFieldBase*)m_pKids->Get(unKidIndex); pKid->SetPlaceHolderText(vText, vNormalColor, vPlaceHolderColor); } } } const std::wstring& CFieldBase::GetPlaceHolderText() { return m_wsPlaceHolderText; } const TRgb& CFieldBase::GetNormalColor() { return m_oNormalColor; } const TRgb& CFieldBase::GetPlaceHolderColor() { return m_oPlaceHolderColor; } void CFieldBase::SetFormat(const CFormFieldInfo::CTextFormFormat* pFormat) { if (!pFormat || pFormat->IsEmpty()) return; std::string scriptK, scriptF, scriptV; const TRgb& oNormalColor = GetNormalColor(); const std::string prefix = "var curColor = color.convert(event.target.textColor, \"RGB\");\nif (Math.abs(curColor[1] - " + std::to_string(oNormalColor.r) + ") < 0.005 && Math.abs(curColor[2] - " + std::to_string(oNormalColor.g) + ") < 0.005 && Math.abs(curColor[3] - " + std::to_string(oNormalColor.b) + ") < 0.005)\n{"; const std::string postfix = "}"; if (pFormat->GetSymbolsCount()) { scriptK += "\nvar s=String.fromCharCode("; scriptV += "\nvar s=String.fromCharCode("; for (unsigned int unIndex = 0, unCount = pFormat->GetSymbolsCount(); unIndex < unCount; ++unIndex) { if (unIndex) { scriptK += ", "; scriptV += ", "; } scriptK += std::to_string(pFormat->GetSymbol(unIndex)); scriptV += std::to_string(pFormat->GetSymbol(unIndex)); } scriptK += ");"; scriptV += ");"; scriptK += "\nfor (var i = 0, l = event.change.length; i < l; ++i){\nvar c = event.change.charAt(i);\nif(-1 == s.indexOf(c)){\nevent.rc = false;\nbreak;\n}\n}"; scriptV += "\nfor (var i = 0, l = event.value.length; i < l; ++i){\nvar c = event.value.charAt(i);\nif(-1 == s.indexOf(c)){\nevent.rc = false;\nbreak;\n}\n}"; } if (pFormat->IsDigit()) { scriptK += "\nif(false !== event.rc)\n{for(var i = 0, l = event.change.length; i < l; ++i){var c = event.change.charCodeAt(i);if(c < 48 || c > 57){event.rc = false;break;}}}"; scriptV += "\nfor(var i = 0, l = event.value.length; i < l; ++i){var c = event.value.charCodeAt(i);if(c < 48 || c > 57){event.rc = false;break;}}"; } else if (pFormat->IsLetter()) { scriptK += "\nvar r=/^[^\\d.!?\\/\\\\+\\-\\x20'\":;\\(\\)\\[\\]\\{\\}=_@#$%^&*]+$/;\nif(false !== event.rc)\n{for(var i = 0, l = event.change.length; i < l; ++i){var c = event.change.charCodeAt(i);if(!r.test(String.fromCharCode(c))){event.rc = false;break;}}}"; scriptV += "\nvar r=/^[^\\d.!?\\/\\\\+\\-\\x20'\":;\\(\\)\\[\\]\\{\\}=_@#$%^&*]+$/;\nfor(var i = 0, l = event.value.length; i < l; ++i){var c = event.value.charCodeAt(i);if(!r.test(String.fromCharCode(c))){event.rc = false;break;}}"; } else if (pFormat->IsMask()) { scriptK += "\nAFSpecial_KeystrokeEx(\"" + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pFormat->GetMask()) + "\");"; } else if (pFormat->IsRegExp()) { scriptV += "\nvar r=/" + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(pFormat->GetRegExp()) + "/;"; scriptV += "\nif(event.value)event.rc=!!event.value.match(r);"; } CDictObject* pAA = GetAA(); if (!scriptK.empty()) { scriptK = prefix + scriptK + postfix; AddScriptToAA("K", scriptK, pAA); } if (!scriptV.empty()) { scriptV = prefix + scriptV + postfix; AddScriptToAA("V", scriptV, pAA); } if (!scriptF.empty()) { scriptV = prefix + scriptF + postfix; AddScriptToAA("F", scriptF, pAA); } } CFontDict* CFieldBase::GetFont() { return m_pFont; } //---------------------------------------------------------------------------------------- // CTextField //---------------------------------------------------------------------------------------- CTextField::CTextField(CXref* pXref, CDocument* pDocument) : CFieldBase(pXref, pDocument) { Add("FT", "Tx"); m_bAutoFit = false; } void CTextField::SetMultilineFlag(bool isMultiLine) { SetFlag(isMultiLine, 1 << 12); } void CTextField::SetPasswordFlag(bool isPassword) { SetFlag(isPassword, 1 << 13); } void CTextField::SetFileSelectFlag(bool isFileSelect) { SetFlag(isFileSelect, 1 << 20); } void CTextField::SetDoNotSpellCheckFlag(bool isDoNotSpellCheck) { SetFlag(isDoNotSpellCheck, 1 << 22); } void CTextField::SetDoNotScrollFlag(bool isDoNotScroll) { SetFlag(isDoNotScroll, 1 << 23); } void CTextField::SetCombFlag(bool isComb) { SetFlag(isComb, 1 << 24); } void CTextField::SetRichTextFlag(bool isRichText) { SetFlag(isRichText, 1 << 25); } void CTextField::SetMaxLen(int nMaxLen) { if (nMaxLen > 0) { if (m_pParent) m_pParent->Add("MaxLen", nMaxLen); else Add("MaxLen", nMaxLen); } } int CTextField::GetMaxLen() const { CNumberObject* oMaxLen = (CNumberObject*)Get("MaxLen"); if (oMaxLen) return oMaxLen->Get(); return 0; } bool CTextField::IsCombFlag() const { int nFlags = ((CNumberObject*)this->Get("Ff"))->Get(); return (nFlags & (1 << 24)); } //---------------------------------------------------------------------------------------- // CChoiceField //---------------------------------------------------------------------------------------- CChoiceField::CChoiceField(CXref* pXref, CDocument* pDocument) : CFieldBase(pXref, pDocument) { m_pOpt = NULL; Add("FT", "Ch"); } void CChoiceField::SetComboFlag(const bool& isCombo) { SetFlag(isCombo, 1 << 17); } void CChoiceField::SetEditFlag(const bool& isEdit) { SetFlag(isEdit, 1 << 18); } void CChoiceField::SetSortFlag(const bool& isSort) { SetFlag(isSort, 1 << 19); } void CChoiceField::SetMultiSelectFlag(const bool& isMultiSelect) { SetFlag(isMultiSelect, 1 << 21); } void CChoiceField::SetDoNotSpellCheck(const bool& isDoNotSpellCheck) { SetFlag(isDoNotSpellCheck, 1 << 22); } void CChoiceField::AddOption(const std::wstring& wsOption, const bool& bPushBack) { if (!m_pOpt) { m_pOpt = new CArrayObject(); Add("Opt", m_pOpt); } if (!m_pOpt) return; std::string sOption = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(wsOption); m_pOpt->Add(new CStringObject(sOption.c_str(), true), bPushBack); } void CChoiceField::SetSelectedIndex(const unsigned int& unSelectedIndex) { if (m_pParent) { CChoiceField* pParent = dynamic_cast(m_pParent); if (pParent) { pParent->SetSelectedIndex(unSelectedIndex); return; } } CArrayObject* pArray = new CArrayObject(); if (!pArray) return; pArray->Add(unSelectedIndex); Add("I", pArray); if (m_pKids) { for (unsigned int unIndex = 0, unCount = m_pKids->GetCount(); unIndex < unCount; ++unIndex) { CFieldBase* pKid = dynamic_cast(m_pKids->Get(unIndex)); if (pKid) pKid->Remove("I"); } } } void CChoiceField::UpdateSelectedIndexToParent() { if (m_pParent) { CObjectBase* pSelectedArray = Get("I"); if (pSelectedArray) m_pParent->Add("I", pSelectedArray->Copy()); Remove("I"); CObjectBase* pValue = Get("V"); if (pValue) m_pParent->Add("V", pValue->Copy()); Remove("V"); CObjectBase* pOpt = Get("Opt"); if (pOpt) m_pParent->Add("Opt", pOpt->Copy()); Remove("Opt"); } } void CChoiceField::SetPlaceHolderText(const std::wstring& wsText, const TRgb& oNormalColor, const TRgb& oPlaceHolderColor) { CDictObject* pAA = GetAA(); if (!pAA) return; CDictObject* pFocus = new CDictObject(); CDictObject* pBlur = new CDictObject(); if (!pFocus || !pBlur) return; bool bCanEdit = GetFieldFlag() & (1 << 18); std::string sText = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(wsText); std::string sFocus, sBlur; if (!bCanEdit) { CDictObject* pChange = new CDictObject(); if (!pChange) { delete pFocus; delete pBlur; return; } // Если текст плейсхолдера не добавить как опцию, тогда AdobeAcrobat не дает выставлять такое текстовое значение AddOption(wsText, false); sFocus = "event.target.textColor = [\"RGB\", " + std::to_string(oNormalColor.r) + ", " + std::to_string(oNormalColor.g) + ", " + std::to_string(oNormalColor.b) + "];"; sBlur = "\nif (event.target.value == \"" + sText + "\")\n event.target.textColor = [\"RGB\", " + std::to_string(oPlaceHolderColor.r) + ", " + std::to_string(oPlaceHolderColor.g) + ", " + std::to_string(oPlaceHolderColor.b) + "];\nelse\n event.target.textColor = [\"RGB\", " + std::to_string(oNormalColor.r) + ", " + std::to_string(oNormalColor.g) + ", " + std::to_string(oNormalColor.b) + "];"; std::string sChange = "\n if (event.value == \"" + sText + "\")\n event.target.textColor =[\"RGB\", " + std::to_string(oPlaceHolderColor.r) + ", " + std::to_string(oPlaceHolderColor.g) + ", " + std::to_string(oPlaceHolderColor.b) + "];\n else\n event.target.textColor = [\"RGB\", " + std::to_string(oNormalColor.r) + ", " + std::to_string(oNormalColor.g) + ", " + std::to_string(oNormalColor.b) + "];\n}"; m_pXref->Add(pChange); pChange->Add("S", "JavaScript"); pChange->Add("JS", new CStringObject(sChange.c_str(), true, true)); pAA->Add("K", pChange); } else { sFocus = "var curColor = color.convert(event.target.textColor, \"RGB\");\nevent.target.textColor = [\"RGB\", " + std::to_string(oNormalColor.r) + ", " + std::to_string(oNormalColor.g) + ", " + std::to_string(oNormalColor.b) + "];\nif (event.target.value == \"" + \ sText + "\" && Math.abs(curColor[1] - " + std::to_string(oPlaceHolderColor.r) + ") < 0.005 && Math.abs(curColor[2] - " + std::to_string(oPlaceHolderColor.g) + ") < 0.005 && Math.abs(curColor[3] - " + std::to_string(oPlaceHolderColor.b) + ") < 0.005)\n event.target.value = \"\";"; sBlur = "\nif (event.target.value == \"\")\n{\n event.target.textColor = [\"RGB\", " + std::to_string(oPlaceHolderColor.r) + ", " + std::to_string(oPlaceHolderColor.g) + ", " + std::to_string(oPlaceHolderColor.b) + "];\nevent.target.value = \"" + sText + "\";\n}"; } m_pXref->Add(pFocus); pFocus->Add("S", "JavaScript"); pFocus->Add("JS", new CStringObject(sFocus.c_str(), true, true)); pAA->Add("Fo", pFocus); m_pXref->Add(pBlur); pBlur->Add("S", "JavaScript"); pBlur->Add("JS", new CStringObject(sBlur.c_str(), true, true)); pAA->Add("Bl", pBlur); } //---------------------------------------------------------------------------------------- // CCheckBoxField //---------------------------------------------------------------------------------------- CCheckBoxField::CCheckBoxField(CXref* pXref, CDocument* pDocument, CRadioGroupField* pGroup, const char* sYesName) : CFieldBase(pXref, pDocument) { Add("FT", "Btn"); m_pGroup = pGroup; if (pGroup) Add("Parent", pGroup); m_sYesName = sYesName ? sYesName : "Yes"; Add("AS", "Off"); } void CCheckBoxField::SetAppearance(const std::wstring& wsYesValue, unsigned short* pYesCodes, unsigned int unYesCount, CFontDict* pYesFont, const std::wstring& wsOffValue, unsigned short* pOffCodes, unsigned int unOffCount, CFontDict* pOffFont, const TRgb& oColor, const double& dAlpha, double dFontSize, double dX, double dY) { CCheckBoxAnnotAppearance* pAppearance = new CCheckBoxAnnotAppearance(m_pXref, this, m_sYesName.c_str()); Add("AP", pAppearance); if (!m_pMK) { m_pMK = new CDictObject(); m_pXref->Add(m_pMK); Add("MK", m_pMK); } if (!m_nBorderType) { CArrayObject* pArray = new CArrayObject(); pArray->Add(0); m_pMK->Add("BC", pArray); } if (!m_bShd) { CArrayObject* pArray = new CArrayObject(); pArray->Add(1); m_pMK->Add("BG", pArray); } CResourcesDict* pFieldsResources = m_pDocument->GetFieldsResources(); const char* sFontName = pFieldsResources->GetFontName(pYesFont); if (!sFontName) return; std::string sDA; sDA.append(std::to_string(oColor.r)); sDA.append(" "); sDA.append(std::to_string(oColor.g)); sDA.append(" "); sDA.append(std::to_string(oColor.b)); sDA.append(" rg /"); sDA.append(sFontName); sDA.append(" "); sDA.append(std::to_string(0)); sDA.append(" Tf"); Add("DA", new CStringObject(sDA.c_str())); const char* sExtGrStateName = NULL; if (fabs(dAlpha - 1.0) > 0.001) { CExtGrState* pExtGrState = m_pDocument->GetFillAlpha(dAlpha); sExtGrStateName = pFieldsResources->GetExtGrStateName(pExtGrState); } pAppearance->GetYesN()->DrawSimpleText(wsYesValue, pYesCodes, unYesCount, pYesFont, dFontSize, dX, dY, oColor.r, oColor.g, oColor.b, sExtGrStateName, fabs(m_oRect.fRight - m_oRect.fLeft), fabs(m_oRect.fBottom - m_oRect.fTop)); pAppearance->GetOffN()->DrawSimpleText(wsOffValue, pOffCodes, unOffCount, pOffFont, dFontSize, dX, dY, oColor.r, oColor.g, oColor.b, sExtGrStateName, fabs(m_oRect.fRight - m_oRect.fLeft), fabs(m_oRect.fBottom - m_oRect.fTop)); pAppearance->GetYesD()->DrawSimpleText(wsYesValue, pYesCodes, unYesCount, pYesFont, dFontSize, dX, dY, oColor.r, oColor.g, oColor.b, sExtGrStateName, fabs(m_oRect.fRight - m_oRect.fLeft), fabs(m_oRect.fBottom - m_oRect.fTop)); pAppearance->GetOffD()->DrawSimpleText(wsOffValue, pOffCodes, unOffCount, pOffFont, dFontSize, dX, dY, oColor.r, oColor.g, oColor.b, sExtGrStateName, fabs(m_oRect.fRight - m_oRect.fLeft), fabs(m_oRect.fBottom - m_oRect.fTop)); } void CCheckBoxField::SetAppearance(const int& nType, const TRgb& oColor, const double& dAlpha, double dFontSize, double dX, double dY) { if (!m_pMK) { m_pMK = new CDictObject(); m_pXref->Add(m_pMK); Add("MK", m_pMK); } CArrayObject* pArray = new CArrayObject(); pArray->Add(3); m_pMK->Add("BC", pArray); pArray = new CArrayObject(); pArray->Add(1); pArray->Add(1); pArray->Add(1); m_pMK->Add("BG", pArray); CCheckBoxAnnotAppearance* pAppearance = new CCheckBoxAnnotAppearance(m_pXref, this, m_sYesName.c_str()); Add("AP", pAppearance); CFontDict* pFont = (CFontDict*)m_pDocument->GetDefaultCheckboxFont(); CResourcesDict* pFieldsResources = m_pDocument->GetFieldsResources(); const char* sFontName = pFieldsResources->GetFontName(pFont); if (!sFontName) return; std::string sDA; sDA.append(std::to_string(oColor.r)); sDA.append(" "); sDA.append(std::to_string(oColor.g)); sDA.append(" "); sDA.append(std::to_string(oColor.b)); sDA.append(" rg /"); sDA.append(sFontName); sDA.append(" "); sDA.append(std::to_string(0)); sDA.append(" Tf"); Add("DA", new CStringObject(sDA.c_str())); const char* sExtGrStateName = NULL; if (fabs(dAlpha - 1.0) > 0.001) { CExtGrState* pExtGrState = m_pDocument->GetFillAlpha(dAlpha); sExtGrStateName = pFieldsResources->GetExtGrStateName(pExtGrState); } double dW = fabs(m_oRect.fRight - m_oRect.fLeft); double dH = fabs(m_oRect.fBottom - m_oRect.fTop); dFontSize = dH * 31.014 / 33.8712; dX = 5.4407 * dW / 37.119000; dY = 6.4375 * dH / 33.8712; SetFieldBorder(border_subtype_Solid, TRgb(0.0, 0.0, 0.0), 1, 0, 0, 0); Remove("BS"); if (1 == nType) { m_pMK->Add("CA", new CStringObject("4")); pAppearance->GetYesN()->DrawSimpleText(L"4", NULL, 0, pFont, dFontSize, dX, dY, oColor.r, oColor.g, oColor.b, sExtGrStateName, dW, dH); pAppearance->GetOffN()->DrawSimpleText(L"", NULL, 0, pFont, dFontSize, dX, dY, oColor.r, oColor.g, oColor.b, sExtGrStateName, dW, dH); } else if (2 == nType) { m_pMK->Add("CA", new CStringObject("1")); pAppearance->GetYesN()->DrawSimpleText(L"1", NULL, 0, pFont, dFontSize, dX, dY, oColor.r, oColor.g, oColor.b, sExtGrStateName, dW, dH); pAppearance->GetOffN()->DrawSimpleText(L"", NULL, 0, pFont, dFontSize, dX, dY, oColor.r, oColor.g, oColor.b, sExtGrStateName, dW, dH); } } void CCheckBoxField::SetValue(const bool& isYes) { const char* sValue = (isYes ? m_sYesName.c_str() : "Off"); Add("AS", sValue); Add("V", sValue); } //---------------------------------------------------------------------------------------- // CRadioGroupField //---------------------------------------------------------------------------------------- CRadioGroupField::CRadioGroupField(CXref* pXref, CDocument* pDocument) : CFieldBase(pXref, pDocument) { Add("FT", "Btn"); SetFlag(true, 1 << 14); SetFlag(true, 1 << 15); m_pKids = new CArrayObject(); if (m_pKids) Add("Kids", m_pKids); } CCheckBoxField* CRadioGroupField::CreateKid(const wchar_t* wsChoiceName) { if (!m_pKids) return NULL; std::string sName = wsChoiceName ? NSFile::CUtf8Converter::GetUtf8StringFromUnicode(wsChoiceName) : "Choice" + std::to_string(m_pKids->GetCount() + 1); CCheckBoxField* pKid = new CCheckBoxField(m_pXref, m_pDocument, this, sName.c_str()); m_pKids->Add(pKid); return pKid; } void CRadioGroupField::SetFieldName(const std::wstring& wsFieldName, bool isSkipCheck) { m_wsFieldName = wsFieldName; CFieldBase::SetFieldName(wsFieldName, true); } const std::wstring& CRadioGroupField::GetFieldName() const { return m_wsFieldName; } //---------------------------------------------------------------------------------------- // CPictureField //---------------------------------------------------------------------------------------- CPictureField::CPictureField(CXref* pXref, CDocument* pDocument) : CFieldBase(pXref, pDocument) { m_pMK = NULL; m_pIF = NULL; Add("FT", "Btn"); SetFlag(true, 1 << 16); Add("H", "I"); CDictObject* pAction = new CDictObject(); if (pAction) { pXref->Add(pAction); Add("A", pAction); pAction->Add("Type", "Action"); pAction->Add("S", "JavaScript"); pAction->Add("JS", new CStringObject("event.target.buttonImportIcon();")); } m_pMK = new CDictObject(); if (!m_pMK) return; pXref->Add(m_pMK); Add("MK", m_pMK); m_pMK->Add("R", 0); m_pMK->Add("TP", 1); m_pIF = new CDictObject(); if (!m_pIF) return; m_pMK->Add("IF", m_pIF); SetScaleType(EScaleType::Always); SetRespectBorders(false); SetConstantProportions(true); SetShift(0.5, 0.5); m_pResources = NULL; } void CPictureField::SetFieldName(const std::string& sName, bool isSkipCheck) { std::string _sName = sName + "_af_image"; CFieldBase::SetFieldName(_sName, isSkipCheck); } void CPictureField::SetFieldName(const std::wstring& wsName, bool isSkipCheck) { std::string sName = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(wsName) + "_af_image"; CFieldBase::SetFieldName(sName, isSkipCheck); } void CPictureField::SetAppearance(CImageDict* pImage) { CAnnotAppearance* pAppearance = new CAnnotAppearance(m_pXref, this); Add("AP", pAppearance); CAnnotAppearanceObject* pNormal = pAppearance->GetNormal(); CResourcesDict* pFieldsResources = GetResourcesDict(); std::string sDA = "0.909 0.941 0.992 rg"; Add("DA", new CStringObject(sDA.c_str())); if (pImage) { TRect oRect = GetRect(); double dH = fabs(oRect.fTop - oRect.fBottom); double dW = fabs(oRect.fRight - oRect.fLeft); double dOriginW = pImage->GetWidth() * 72 / 96.0; double dOriginH = pImage->GetHeight() * 72 / 96.0; bool bNeedScale = (EScaleType::Always == m_eScaleType || (EScaleType::Bigger == m_eScaleType && (dOriginH > dH || dOriginW > dW)) || (EScaleType::Smaller == m_eScaleType && dOriginH < dH && dOriginW < dW)); double dDstW = dOriginW; double dDstH = dOriginH; double dDstX = 0; double dDstY = 0; if (m_bRespectBorders && HaveBorder()) { double dBorderSize = GetBorderSize(); dDstX += 2 * dBorderSize; dDstY += 2 * dBorderSize; dH -= 4 * dBorderSize; dW -= 4 * dBorderSize; } if (bNeedScale) { if (!m_bConstantProportions) { dDstH = dH; dDstW = dW; } else { double dScaleKoef = fmin(dW / dOriginW, dH / dOriginH); dDstW = dScaleKoef * dOriginW; dDstH = dScaleKoef * dOriginH; } } dDstX += (dW - dDstW) * m_dShiftX; dDstY += (dH - dDstH) * m_dShiftY; CXObject* pForm = new CXObject(); CStream* pStream = new CMemoryStream(); pForm->SetStream(m_pXref, pStream); #ifndef FILTER_FLATE_DECODE_DISABLED if (m_pDocument->GetCompressionMode() & COMP_TEXT) pForm->SetFilter(STREAM_FILTER_FLATE_DECODE); #endif CArrayObject* pBBox = new CArrayObject(); pForm->Add("BBox", pBBox); pBBox->Add(0); pBBox->Add(0); pBBox->Add(dOriginW); pBBox->Add(dOriginH); pForm->Add("FormType", 1); CArrayObject* pFormMatrix = new CArrayObject(); pForm->Add("Matrix", pFormMatrix); pFormMatrix->Add(1); pFormMatrix->Add(0); pFormMatrix->Add(0); pFormMatrix->Add(1); pFormMatrix->Add(0); pFormMatrix->Add(0); pForm->Add("Name", "FRM"); CDictObject* pFormRes = new CDictObject(); CArrayObject* pFormResProcset = new CArrayObject(); pFormRes->Add("ProcSet", pFormResProcset); pFormResProcset->Add(new CNameObject("PDF")); pFormResProcset->Add(new CNameObject("ImageC")); CDictObject* pFormResXObject = new CDictObject(); pFormRes->Add("XObject", pFormResXObject); pFormResXObject->Add("Img", pImage); pForm->Add("Resources", pFormRes); pForm->Add("Subtype", "Form"); pForm->Add("Type", "XObject"); pStream->WriteStr("q\012"); pStream->WriteReal(dOriginW); pStream->WriteStr(" 0 0 "); pStream->WriteReal(dOriginH); pStream->WriteStr(" 0 0 cm\012/Img Do\012Q"); pFieldsResources->AddXObjectWithName("FRM", pForm); pNormal->DrawPicture("FRM", dDstX, dDstY, dDstW / dOriginW, dDstH / dOriginH, m_bRespectBorders); } else { pNormal->DrawPicture(); } } void CPictureField::SetScaleType(const EScaleType& eType) { if (!m_pIF) return; switch (eType) { case EScaleType::Always: m_pIF->Add("SW", "A"); break; case EScaleType::Bigger: m_pIF->Add("SW", "B"); break; case EScaleType::Smaller: m_pIF->Add("SW", "S"); break; case EScaleType::Never: m_pIF->Add("SW", "N"); break; } m_eScaleType = eType; } void CPictureField::SetConstantProportions(const bool& bConstant) { if (!m_pIF) return; if (bConstant) m_pIF->Add("S", "P"); else m_pIF->Add("S", "A"); m_bConstantProportions = bConstant; } void CPictureField::SetRespectBorders(const bool& bRespectBorders) { if (!m_pIF) return; m_pIF->Add("FB", !bRespectBorders); m_bRespectBorders = bRespectBorders; } void CPictureField::SetShift(const double& dX, const double& dY) { if (!m_pIF) return; CArrayObject* pA = new CArrayObject(); if (pA) { m_pIF->Add("A", pA); pA->Add(dX); pA->Add(dY); } m_dShiftX = dX; m_dShiftY = dY; } CResourcesDict* CPictureField::GetResourcesDict() { if (!m_pResources) m_pResources = new CResourcesDict(m_pXref, false, true); return m_pResources; } //---------------------------------------------------------------------------------------- // CSignatureField //---------------------------------------------------------------------------------------- CSignatureField::CSignatureField(CXref* pXref, CDocument* pDocument) : CFieldBase(pXref, pDocument) { // Словарь сигнатур m_pSig = new CSignatureDict(pXref); if (!m_pSig) return; Add("V", m_pSig); Add("FT", "Sig"); m_pResources = NULL; } void CSignatureField::SetName(const std::wstring& wsValue) { if (!m_pSig || wsValue.empty()) return; m_pSig->SetName(U_TO_UTF8(wsValue)); } void CSignatureField::SetReason(const std::wstring &wsValue) { if (!m_pSig || wsValue.empty()) return; m_pSig->SetReason(U_TO_UTF8(wsValue)); } void CSignatureField::SetContact(const std::wstring &wsValue) { if (!m_pSig || wsValue.empty()) return; m_pSig->SetContact(U_TO_UTF8(wsValue)); } void CSignatureField::SetCert() { } void CSignatureField::SetDate(bool bDate) { if (!m_pSig || !bDate) return; m_pSig->SetDate(); } void CSignatureField::SetAppearance(CImageDict* pImage) { CAnnotAppearance* pAppearance = new CAnnotAppearance(m_pXref, this); Add("AP", pAppearance); CAnnotAppearanceObject* pNormal = pAppearance->GetNormal(); CResourcesDict* pFieldsResources = GetResourcesDict(); std::string sDA = "0.909 0.941 0.992 rg"; Add("DA", new CStringObject(sDA.c_str())); if (pImage) { TRect oRect = GetRect(); double dH = fabs(oRect.fTop - oRect.fBottom); double dW = fabs(oRect.fRight - oRect.fLeft); double dOriginW = pImage->GetWidth() * 72 / 96.0; double dOriginH = pImage->GetHeight() * 72 / 96.0; double dDstW = dOriginW; double dDstH = dOriginH; double dDstX = 0; double dDstY = 0; if (HaveBorder()) { double dBorderSize = GetBorderSize(); dDstX += 2 * dBorderSize; dDstY += 2 * dBorderSize; dH -= 4 * dBorderSize; dW -= 4 * dBorderSize; } double dScaleKoef = fmin(dW / dOriginW, dH / dOriginH); dDstW = dScaleKoef * dOriginW; dDstH = dScaleKoef * dOriginH; dDstX += (dW - dDstW) * 0.5; dDstY += (dH - dDstH) * 0.5; CXObject* pForm = new CXObject(); CStream* pStream = new CMemoryStream(); pForm->SetStream(m_pXref, pStream); #ifndef FILTER_FLATE_DECODE_DISABLED if (m_pDocument->GetCompressionMode() & COMP_TEXT) pForm->SetFilter(STREAM_FILTER_FLATE_DECODE); #endif CArrayObject* pBBox = new CArrayObject(); pForm->Add("BBox", pBBox); pBBox->Add(0); pBBox->Add(0); pBBox->Add(dOriginW); pBBox->Add(dOriginH); pForm->Add("FormType", 1); CArrayObject* pFormMatrix = new CArrayObject(); pForm->Add("Matrix", pFormMatrix); pFormMatrix->Add(1); pFormMatrix->Add(0); pFormMatrix->Add(0); pFormMatrix->Add(1); pFormMatrix->Add(0); pFormMatrix->Add(0); pForm->Add("Name", "FRM"); CDictObject* pFormRes = new CDictObject(); CArrayObject* pFormResProcset = new CArrayObject(); pFormRes->Add("ProcSet", pFormResProcset); pFormResProcset->Add(new CNameObject("PDF")); pFormResProcset->Add(new CNameObject("ImageC")); CDictObject* pFormResXObject = new CDictObject(); pFormRes->Add("XObject", pFormResXObject); pFormResXObject->Add("Img", pImage); pForm->Add("Resources", pFormRes); pForm->Add("Subtype", "Form"); pForm->Add("Type", "XObject"); pStream->WriteStr("q\012"); pStream->WriteReal(dOriginW); pStream->WriteStr(" 0 0 "); pStream->WriteReal(dOriginH); pStream->WriteStr(" 0 0 cm\012/Img Do\012Q"); pFieldsResources->AddXObjectWithName("FRM", pForm); pNormal->DrawPicture("FRM", dDstX, dDstY, dDstW / dOriginW, dDstH / dOriginH, true); } else { pNormal->DrawPicture(); } } CResourcesDict* CSignatureField::GetResourcesDict() { if (!m_pResources) m_pResources = new CResourcesDict(m_pXref, false, true); return m_pResources; } //---------------------------------------------------------------------------------------- // CDateTimeField //---------------------------------------------------------------------------------------- CDateTimeField::CDateTimeField(CXref* pXref, CDocument* pDocument) : CFieldBase(pXref, pDocument) { Add("FT", "Tx"); SetFormat("d-mmm-yyyy"); } void CDateTimeField::SetFormat(const std::wstring& wsFormat) { SetFormat(NSFile::CUtf8Converter::GetUtf8StringFromUnicode(wsFormat)); } std::string CorrectFormat(const std::string& s) { std::string sRes = s; NSStringUtils::string_replaceA(sRes, "am/pm", "tt"); NSStringUtils::string_replaceA(sRes, "AM/PM", "tt"); NSStringUtils::string_replaceA(sRes, "M", "m"); NSStringUtils::string_replaceA(sRes, "Y", "y"); NSStringUtils::string_replaceA(sRes, "D", "d"); NSStringUtils::string_replaceA(sRes, ":mm", ":MM"); NSStringUtils::string_replaceA(sRes, "m\xeb\xb6\x84", "M\xeb\xb6\x84"); NSStringUtils::string_replaceA(sRes, "m\xe5\x88\x86", "M\xe5\x88\x86"); return sRes; } void CDateTimeField::SetFormat(const std::string& sFormat) { std::string sCorrectFormat = CorrectFormat(sFormat); std::string script = "AFDate_FormatEx(\"" + sCorrectFormat + "\");"; AddScriptToAA("F", script); script = "AFDate_KeystrokeEx(\"" + sCorrectFormat + "\");"; AddScriptToAA("K", script); } //---------------------------------------------------------------------------------------- // CAnnotAppearance //---------------------------------------------------------------------------------------- CAnnotAppearance::CAnnotAppearance(CXref* pXref, CFieldBase* pField) { m_pXref = pXref; m_pField = pField; m_pAnnot = NULL; m_pNormal = new CAnnotAppearanceObject(pXref, pField); m_pRollover = NULL; m_pDown = NULL; Add("N", m_pNormal); } CAnnotAppearance::CAnnotAppearance(CXref* pXref, CAnnotation* pAnnot) { m_pXref = pXref; m_pAnnot = pAnnot; m_pField = NULL; m_pNormal = NULL; m_pRollover = NULL; m_pDown = NULL; } CAnnotAppearanceObject* CAnnotAppearance::GetNormal(CResourcesDict* pResources) { if (!m_pNormal) { if (m_pField) m_pNormal = new CAnnotAppearanceObject(m_pXref, m_pField); else if (m_pAnnot) m_pNormal = new CAnnotAppearanceObject(m_pXref, m_pAnnot, pResources); if (m_pXref) Add("N", m_pNormal); } return m_pNormal; } CAnnotAppearanceObject* CAnnotAppearance::GetRollover(CResourcesDict* pResources) { if (!m_pRollover) { if (m_pField) m_pRollover = new CAnnotAppearanceObject(m_pXref, m_pField); else if (m_pAnnot) m_pRollover = new CAnnotAppearanceObject(m_pXref, m_pAnnot, pResources); Add("R", m_pRollover); } return m_pRollover; } CAnnotAppearanceObject* CAnnotAppearance::GetDown(CResourcesDict* pResources) { if (!m_pDown) { if (m_pField) m_pDown = new CAnnotAppearanceObject(m_pXref, m_pField); else if (m_pAnnot) m_pDown = new CAnnotAppearanceObject(m_pXref, m_pAnnot, pResources); Add("D", m_pDown); } return m_pDown; } //---------------------------------------------------------------------------------------- // CCheckBoxAnnotAppearance //---------------------------------------------------------------------------------------- CCheckBoxAnnotAppearance::CCheckBoxAnnotAppearance(CXref* pXref, CFieldBase* pField, const char* sYesName) { m_pXref = pXref; m_pYesN = new CAnnotAppearanceObject(pXref, pField); m_pOffN = new CAnnotAppearanceObject(pXref, pField); m_pYesD = new CAnnotAppearanceObject(pXref, pField); m_pOffD = new CAnnotAppearanceObject(pXref, pField); CDictObject* pDictN = new CDictObject(); Add("N", pDictN); pDictN->Add(sYesName ? sYesName : "Yes", m_pYesN); pDictN->Add("Off", m_pOffN); CDictObject* pDictD = new CDictObject(); Add("D", pDictD); pDictD->Add(sYesName ? sYesName : "Yes", m_pYesD); pDictD->Add("Off", m_pOffD); } CCheckBoxAnnotAppearance::CCheckBoxAnnotAppearance(CXref* pXref, CAnnotation* pAnnot, const char* sYesName) { m_pXref = pXref; m_pYesN = new CAnnotAppearanceObject(pXref, pAnnot, new CResourcesDict(pXref, true, false)); m_pOffN = new CAnnotAppearanceObject(pXref, pAnnot, new CResourcesDict(pXref, true, false)); m_pYesD = new CAnnotAppearanceObject(pXref, pAnnot, new CResourcesDict(pXref, true, false)); m_pOffD = new CAnnotAppearanceObject(pXref, pAnnot, new CResourcesDict(pXref, true, false)); CDictObject* pDictN = new CDictObject(); Add("N", pDictN); pDictN->Add(sYesName ? sYesName : "Yes", m_pYesN); pDictN->Add("Off", m_pOffN); CDictObject* pDictD = new CDictObject(); Add("D", pDictD); pDictD->Add(sYesName ? sYesName : "Yes", m_pYesD); pDictD->Add("Off", m_pOffD); } CAnnotAppearanceObject* CCheckBoxAnnotAppearance::GetYesN() { return m_pYesN; } CAnnotAppearanceObject* CCheckBoxAnnotAppearance::GetOffN() { return m_pOffN; } CAnnotAppearanceObject* CCheckBoxAnnotAppearance::GetYesD() { return m_pYesD; } CAnnotAppearanceObject* CCheckBoxAnnotAppearance::GetOffD() { return m_pOffD; } //---------------------------------------------------------------------------------------- // CAnnotAppearanceObject //---------------------------------------------------------------------------------------- void CAnnotAppearanceObject::Init(CXref* pXref, CResourcesDict* pResources) { m_pXref = pXref ? pXref : NULL; m_pFont = NULL; m_dFontSize = 10.0; m_bStart = true; if (m_pXref) { m_pStream = new CMemoryStream(); SetStream(m_pXref, m_pStream); #ifndef FILTER_FLATE_DECODE_DISABLED SetFilter(STREAM_FILTER_FLATE_DECODE); #endif } Add("Type", "XObject"); Add("Subtype", "Form"); Add("Resources", pResources); } CAnnotAppearanceObject::CAnnotAppearanceObject(CXref* pXref, CFieldBase* pField) { Init(pXref, pField->GetResourcesDict()); m_pField = pField; m_pAnnot = NULL; CArrayObject* pArray = new CArrayObject(); if (!pArray) return; Add("BBox", pArray); pArray->Add(0); pArray->Add(0); pArray->Add(fabs(pField->GetRect().fRight - pField->GetRect().fLeft)); pArray->Add(fabs(pField->GetRect().fBottom - pField->GetRect().fTop)); } CAnnotAppearanceObject::CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot, CResourcesDict* pResources) { Init(pXRef, pResources ? pResources : pAnnot->GetDocument()->GetFieldsResources()); m_pAnnot = pAnnot; m_pField = NULL; if (pAnnot->GetAnnotationType() == EAnnotType::AnnotWidget) { CArrayObject* pArray = new CArrayObject(); if (!pArray) return; Add("BBox", pArray); pArray->Add(0); pArray->Add(0); pArray->Add(fabs(pAnnot->GetRect().fRight - pAnnot->GetRect().fLeft)); pArray->Add(fabs(pAnnot->GetRect().fBottom - pAnnot->GetRect().fTop)); } } void CAnnotAppearanceObject::DrawSimpleText(const std::wstring& wsText, unsigned short* pCodes, unsigned int unCount, CFontDict* pFont, double dFontSize, double dX, double dY, double dR, double dG, double dB, const char* sExtGStateName, double dWidth, double dHeight, CFontCidTrueType** ppFonts, double* pShifts) { if (!m_pStream || !pFont) return; StartDrawText(pFont, dFontSize, dR, dG, dB, sExtGStateName, dWidth, dHeight); if (pCodes) DrawTextLine(dX, dY, pCodes, unCount, ppFonts, pShifts); else DrawTextLine(dX, dY, wsText); EndDrawText(); } void CAnnotAppearanceObject::DrawPicture(const char* sImageName, const double& dX, const double& dY, const double& dImageW, const double& dImageH, const bool& bRespectBorder) { if (!m_pStream) return; CWidgetAnnotation* pAnnot = NULL; if (m_pAnnot) pAnnot = (CWidgetAnnotation*)m_pAnnot; double dW = 0, dH = 0; if (m_pField || pAnnot) { TRect oRect = m_pField ? m_pField->GetRect() : pAnnot->GetRect(); dW = fabs(oRect.fRight - oRect.fLeft); dH = fabs(oRect.fBottom - oRect.fTop); } m_pStream->WriteStr("q\012"); if ((m_pField && m_pField->HaveShd()) || (pAnnot && pAnnot->HaveBG())) { if (m_pField) { TRgb oColor = m_pField->GetShdColor(); m_pStream->WriteReal(oColor.r); m_pStream->WriteChar(' '); m_pStream->WriteReal(oColor.g); m_pStream->WriteChar(' '); m_pStream->WriteReal(oColor.b); m_pStream->WriteStr(" rg\012"); } else { m_pStream->WriteStr(pAnnot->GetBGforAP().c_str()); m_pStream->WriteStr("\012"); } m_pStream->WriteStr("1 0 0 1 0 0 cm\012"); m_pStream->WriteStr("0 0 "); m_pStream->WriteReal(fmax(dW, 0.0)); m_pStream->WriteChar(' '); m_pStream->WriteReal(fmax(dH, 0.0)); m_pStream->WriteStr(" re\012f\012"); } else if (!sImageName) { m_pStream->WriteStr("0.909 0.941 0.992 rg\0121 0 0 1 0 0 cm\012"); m_pStream->WriteStr("0 0 "); m_pStream->WriteReal(fmax(dW, 0.0)); m_pStream->WriteChar(' '); m_pStream->WriteReal(fmax(dH, 0.0)); m_pStream->WriteStr(" re\012f\012"); } if ((m_pField && m_pField->HaveBorder()) || (pAnnot && pAnnot->HaveBorder())) { double dBorderSize = m_pField ? m_pField->GetBorderSize() : pAnnot->GetBorderWidth(); BYTE nType = 0; if (pAnnot) { nType = (BYTE)pAnnot->GetBorderType(); switch (nType) { case 1: // Beveled case 3: // Inset { m_pStream->WriteStr(nType == 1 ? "1 g\012" : "0.501953 g\012"); m_pStream->WriteReal(dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" m\012"); m_pStream->WriteReal(dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dH - dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(dW - dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dH - dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(dW - 2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dH - 2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dH - 2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteStr("f\012"); if (nType == 1 && pAnnot->HaveBG()) { m_pStream->WriteStr(pAnnot->GetBGforAP(-0.25).c_str()); m_pStream->WriteStr("\012"); } else m_pStream->WriteStr("0.75293 g\012"); m_pStream->WriteReal(dW - dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dH - dBorderSize); m_pStream->WriteStr(" m\012"); m_pStream->WriteReal(dW - dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(dW - 2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(dW - 2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dH - 2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteStr("f\012"); break; } case 2: // Dashed { m_pStream->WriteStr(pAnnot->GetBorderDash().c_str()); break; } default: break; } } if (m_pField) { TRgb oColor = m_pField->GetBorderColor(); m_pStream->WriteReal(oColor.r); m_pStream->WriteChar(' '); m_pStream->WriteReal(oColor.g); m_pStream->WriteChar(' '); m_pStream->WriteReal(oColor.b); m_pStream->WriteStr(" RG\012"); } else { m_pStream->WriteStr(pAnnot->GetBCforAP().c_str()); m_pStream->WriteStr("\012"); } m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" w\0120 j\0120 J\012"); if (nType == 4) // Underline { m_pStream->WriteInt(0); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize / 2); m_pStream->WriteStr(" m\012"); m_pStream->WriteReal(dW); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize / 2); m_pStream->WriteStr(" l\012S\012"); } else { m_pStream->WriteReal(dBorderSize / 2); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize / 2); m_pStream->WriteChar(' '); m_pStream->WriteReal(std::max(dW - dBorderSize, 0.0)); m_pStream->WriteChar(' '); m_pStream->WriteReal(std::max(dH - dBorderSize, 0.0)); m_pStream->WriteStr(" re\012S\012"); } if (bRespectBorder && sImageName) { m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(fmax(dW - 4 * dBorderSize, 0.0)); m_pStream->WriteChar(' '); m_pStream->WriteReal(fmax(dH - 4 * dBorderSize, 0.0)); m_pStream->WriteStr(" re\012W\012n\012"); } } else if (!sImageName) { m_pStream->WriteStr("0.909 0.941 0.992 RG\012"); m_pStream->WriteStr("0.5 0.5 "); m_pStream->WriteReal(fmax(dW - 1, 0.0)); m_pStream->WriteChar(' '); m_pStream->WriteReal(fmax(dH - 1, 0.0)); m_pStream->WriteStr(" re\012s\012"); } if (sImageName) { m_pStream->WriteReal(dImageW); m_pStream->WriteStr(" 0 0 "); m_pStream->WriteReal(dImageH); m_pStream->WriteChar(' '); m_pStream->WriteReal(dX); m_pStream->WriteChar(' '); m_pStream->WriteReal(dY); m_pStream->WriteStr(" cm\012"); m_pStream->WriteEscapeName(sImageName); m_pStream->WriteStr(" Do\012"); } m_pStream->WriteStr("Q"); } void CAnnotAppearanceObject::StartDrawText(CFontDict* pFont, const double& dFontSize, const double& dR, const double& dG, const double& dB, const char* sExtGStateName, const double& dWidth, const double& dHeight) { CResourcesDict* pResources = dynamic_cast(Get("Resources")); if (!m_pStream || !pResources) return; CWidgetAnnotation* pAnnot = NULL; if (m_pAnnot) pAnnot = (CWidgetAnnotation*)m_pAnnot; m_pStream->WriteEscapeName("Tx"); m_pStream->WriteStr(" BMC\012"); if ((m_pField && m_pField->HaveShd()) || (pAnnot && pAnnot->HaveBG())) { m_pStream->WriteStr("q\012"); if (m_pField) { TRgb oColor = m_pField->GetShdColor(); m_pStream->WriteReal(oColor.r); m_pStream->WriteChar(' '); m_pStream->WriteReal(oColor.g); m_pStream->WriteChar(' '); m_pStream->WriteReal(oColor.b); m_pStream->WriteStr(" rg\012"); } else { m_pStream->WriteStr(pAnnot->GetBGforAP().c_str()); m_pStream->WriteStr("\012"); } m_pStream->WriteStr("1 0 0 1 0 0 cm\012"); m_pStream->WriteStr("0 0 "); m_pStream->WriteReal(fmax(dWidth, 0.0)); m_pStream->WriteChar(' '); m_pStream->WriteReal(fmax(dHeight, 0.0)); m_pStream->WriteStr(" re\012f\012"); m_pStream->WriteStr("Q\012"); } double dBorderSize = 0; double dBorderSizeStyle = 0; if (pAnnot && pAnnot->HaveBorder()) { dBorderSize = pAnnot->GetBorderWidth(); dBorderSizeStyle = dBorderSize; if (pAnnot->GetBorderType() == EBorderType::Beveled || pAnnot->GetBorderType() == EBorderType::Inset) dBorderSizeStyle *= 2; } if ((m_pField && m_pField->HaveBorder()) || (pAnnot && pAnnot->HaveBorder() && pAnnot->HaveBC())) { m_pStream->WriteStr("q\012"); dBorderSize = m_pField ? m_pField->GetBorderSize() : pAnnot->GetBorderWidth(); dBorderSizeStyle = dBorderSize; BYTE nType = 0; if (pAnnot) { nType = (BYTE)pAnnot->GetBorderType(); switch (nType) { case 1: // Beveled case 3: // Inset { dBorderSizeStyle *= 2; m_pStream->WriteStr(nType == 1 ? "1 g\012" : "0.501953 g\012"); m_pStream->WriteReal(dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" m\012"); m_pStream->WriteReal(dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dHeight - dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(dWidth - dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dHeight - dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(dWidth - 2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dHeight - 2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dHeight - 2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteStr("f\012"); if (nType == 1 && pAnnot->HaveBG()) { m_pStream->WriteStr(pAnnot->GetBGforAP(-0.25).c_str()); m_pStream->WriteStr("\012"); } else m_pStream->WriteStr("0.75293 g\012"); m_pStream->WriteReal(dWidth - dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dHeight - dBorderSize); m_pStream->WriteStr(" m\012"); m_pStream->WriteReal(dWidth - dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(dWidth - 2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(dWidth - 2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dHeight - 2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteStr("f\012"); break; } case 2: // Dashed { m_pStream->WriteStr(pAnnot->GetBorderDash().c_str()); break; } default: break; } } if (m_pField) { TRgb oColor = m_pField->GetBorderColor(); m_pStream->WriteReal(oColor.r); m_pStream->WriteChar(' '); m_pStream->WriteReal(oColor.g); m_pStream->WriteChar(' '); m_pStream->WriteReal(oColor.b); m_pStream->WriteStr(" RG\012"); } else { m_pStream->WriteStr(pAnnot->GetBCforAP().c_str()); m_pStream->WriteStr("\012"); } m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" w\0120 j\0120 J\012"); if (nType == 4) // Underline { m_pStream->WriteInt(0); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize / 2); m_pStream->WriteStr(" m\012"); m_pStream->WriteReal(dWidth); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize / 2); m_pStream->WriteStr(" l\012S\012"); } else { m_pStream->WriteReal(dBorderSize / 2); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize / 2); m_pStream->WriteChar(' '); m_pStream->WriteReal(std::max(dWidth - dBorderSize, 0.0)); m_pStream->WriteChar(' '); m_pStream->WriteReal(std::max(dHeight - dBorderSize, 0.0)); m_pStream->WriteStr(" re\012S\012"); } CTextField* pTextField = dynamic_cast(m_pField); CTextWidget* pAnnot = dynamic_cast(m_pAnnot); if ((pTextField && pTextField->IsCombFlag()) || (pAnnot && pAnnot->IsCombFlag() && (nType == 0 || nType == 2))) { int nMaxLen = pTextField ? pTextField->GetMaxLen() : pAnnot->GetMaxLen(); if (nMaxLen > 1) { double dStep = dWidth / nMaxLen; double dX = dStep; for (int nIndex = 0; nIndex < nMaxLen - 1; ++nIndex) { m_pStream->WriteReal(dX); m_pStream->WriteChar(' '); m_pStream->WriteInt(0); m_pStream->WriteChar(' '); m_pStream->WriteStr(" m\012"); m_pStream->WriteReal(dX); m_pStream->WriteChar(' '); m_pStream->WriteReal(dHeight); m_pStream->WriteChar(' '); m_pStream->WriteStr(" l\012S\012"); dX += dStep; } } } m_pStream->WriteStr("Q\012"); } m_pStream->WriteStr("q\012"); if (pAnnot && pAnnot->GetWidgetType() == WidgetPushbutton && !((CPushButtonWidget*)pAnnot)->GetRespectBorder()) { m_pStream->WriteStr("0 0 "); m_pStream->WriteReal(std::max(dWidth, 0.0)); m_pStream->WriteChar(' '); m_pStream->WriteReal(std::max(dHeight, 0.0)); } else { m_pStream->WriteReal(dBorderSizeStyle); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSizeStyle); m_pStream->WriteChar(' '); m_pStream->WriteReal(std::max(dWidth - dBorderSizeStyle * 2, 0.0)); m_pStream->WriteChar(' '); m_pStream->WriteReal(std::max(dHeight - dBorderSizeStyle * 2, 0.0)); } m_pStream->WriteStr(" re\012W\012n\012"); if (pAnnot && pAnnot->GetWidgetType() == WidgetListbox) { CChoiceWidget* pAnnot = dynamic_cast(m_pAnnot); double dBaseLine = pAnnot->GetListBoxHeight(); std::vector arrIndex = pAnnot->GetListBoxIndex(); m_pStream->WriteStr("0.60 0.75 0.85 rg\012"); for (int i = 0; i < arrIndex.size(); ++i) { double dH = dHeight - dBorderSizeStyle - dBaseLine * (double)(arrIndex[i] + 1); if (dH < 0) break; m_pStream->WriteReal(dBorderSizeStyle); m_pStream->WriteChar(' '); m_pStream->WriteReal(dH); m_pStream->WriteChar(' '); m_pStream->WriteReal(std::max(dWidth - dBorderSizeStyle * 2.0, 0.0)); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBaseLine); m_pStream->WriteStr(" re\012f\012"); } } m_pStream->WriteStr("BT\012"); m_dFontSize = std::min(1000.0, std::max(0.0, dFontSize)); if (m_pField) { m_pStream->WriteReal(dR); m_pStream->WriteChar(' '); m_pStream->WriteReal(dG); m_pStream->WriteChar(' '); m_pStream->WriteReal(dB); m_pStream->WriteStr(" rg\012"); if (sExtGStateName) { m_pStream->WriteEscapeName(sExtGStateName); m_pStream->WriteStr(" gs\012"); } m_pStream->WriteEscapeName(pResources->GetFontName(pFont)); m_pStream->WriteChar(' '); m_pStream->WriteReal(m_dFontSize); m_pStream->WriteStr(" Tf\012"); } else if (pFont) m_pStream->WriteStr(pAnnot->GetDAforAP(pFont).c_str()); m_bStart = true; m_pFont = pFont; } void CAnnotAppearanceObject::StartDraw(const double& dWidth, const double& dHeight) { CWidgetAnnotation* pAnnot = dynamic_cast(m_pAnnot); if (!m_pStream || !pAnnot) return; DrawBackground(dWidth, dHeight); DrawBorder(dWidth, dHeight); m_pStream->WriteStr("q\012"); double dBorderSize = pAnnot->GetBorderWidth(); EBorderType nType = pAnnot->GetBorderType(); if (nType == EBorderType::Beveled || nType == EBorderType::Inset) dBorderSize *= 2; if (pAnnot->GetWidgetType() == WidgetPushbutton && !((CPushButtonWidget*)pAnnot)->GetRespectBorder()) dBorderSize = 0; m_pStream->WriteReal(dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(std::max(dWidth - dBorderSize * 2, 0.0)); m_pStream->WriteChar(' '); m_pStream->WriteReal(std::max(dHeight - dBorderSize * 2, 0.0)); m_pStream->WriteStr(" re\012W\012n\012"); if (pAnnot && pAnnot->GetWidgetType() == WidgetListbox) { CChoiceWidget* pAnnot = dynamic_cast(m_pAnnot); double dBaseLine = pAnnot->GetListBoxHeight(); std::vector arrIndex = pAnnot->GetListBoxIndex(); m_pStream->WriteStr("0.60 0.75 0.85 rg\012"); for (int i = 0; i < arrIndex.size(); ++i) { double dH = dHeight - dBorderSize - dBaseLine * (double)(arrIndex[i] + 1); if (dH < 0) break; m_pStream->WriteReal(dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dH); m_pStream->WriteChar(' '); m_pStream->WriteReal(std::max(dWidth - dBorderSize * 2.0, 0.0)); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBaseLine); m_pStream->WriteStr(" re\012f\012"); } } } void CAnnotAppearanceObject::StartText(CFontDict* pFont, const double& dFontSize) { CWidgetAnnotation* pAnnot = dynamic_cast(m_pAnnot); if (!m_pStream || !pAnnot) return; m_dFontSize = std::min(1000.0, std::max(0.0, dFontSize)); m_pFont = pFont; m_bStart = true; m_pStream->WriteStr("BT\012"); if (pFont) m_pStream->WriteStr(pAnnot->GetDAforAP(pFont).c_str()); } void CAnnotAppearanceObject::DrawPictureInline(const double& dWidth, const double& dHeight, const char* sImageName, const double& dX, const double& dY, const double& dW, const double& dH, const bool& bRespectBorder) { CWidgetAnnotation* pAnnot = dynamic_cast(m_pAnnot); if (!m_pStream || !pAnnot || !sImageName) return; m_pStream->WriteStr("q\012"); if (bRespectBorder) { double dBorderSize = pAnnot->GetBorderWidth(); EBorderType nType = pAnnot->GetBorderType(); if (nType == EBorderType::Beveled || nType == EBorderType::Inset) dBorderSize *= 2; m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(fmax(dWidth - 4 * dBorderSize, 0.0)); m_pStream->WriteChar(' '); m_pStream->WriteReal(fmax(dHeight - 4 * dBorderSize, 0.0)); m_pStream->WriteStr(" re\012W\012n\012"); } m_pStream->WriteReal(dW); m_pStream->WriteStr(" 0 0 "); m_pStream->WriteReal(dH); m_pStream->WriteChar(' '); m_pStream->WriteReal(dX); m_pStream->WriteChar(' '); m_pStream->WriteReal(dY); m_pStream->WriteStr(" cm\012"); m_pStream->WriteEscapeName(sImageName); m_pStream->WriteStr(" Do\012"); m_pStream->WriteStr("Q\012"); } void CAnnotAppearanceObject::EndText() { m_pStream->WriteStr("ET\012"); } void CAnnotAppearanceObject::EndDraw() { m_pStream->WriteStr("Q\012"); } void CAnnotAppearanceObject::DrawBackground(const double& dWidth, const double& dHeight) { CWidgetAnnotation* pAnnot = dynamic_cast(m_pAnnot); if (!pAnnot || !pAnnot->HaveBG()) return; m_pStream->WriteStr("q\012"); m_pStream->WriteStr(pAnnot->GetBGforAP().c_str()); m_pStream->WriteStr("\012"); m_pStream->WriteStr("1 0 0 1 0 0 cm\012"); m_pStream->WriteStr("0 0 "); m_pStream->WriteReal(fmax(dWidth, 0.0)); m_pStream->WriteChar(' '); m_pStream->WriteReal(fmax(dHeight, 0.0)); m_pStream->WriteStr(" re\012f\012"); m_pStream->WriteStr("Q\012"); } void CAnnotAppearanceObject::DrawBorder(const double& dWidth, const double& dHeight) { CWidgetAnnotation* pAnnot = dynamic_cast(m_pAnnot); if (!pAnnot || !pAnnot->HaveBorder()) return; m_pStream->WriteStr("q\012"); double dBorderSize = pAnnot->GetBorderWidth(); EBorderType nType = pAnnot->GetBorderType(); switch (nType) { case EBorderType::Beveled: case EBorderType::Inset: { m_pStream->WriteStr(nType == EBorderType::Beveled ? "1 g\012" : "0.501953 g\012"); m_pStream->WriteReal(dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" m\012"); m_pStream->WriteReal(dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dHeight - dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(dWidth - dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dHeight - dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(dWidth - 2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dHeight - 2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dHeight - 2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteStr("f\012"); if (nType == EBorderType::Beveled && pAnnot->HaveBG()) { m_pStream->WriteStr(pAnnot->GetBGforAP(-0.25).c_str()); m_pStream->WriteStr("\012"); } else m_pStream->WriteStr("0.75293 g\012"); m_pStream->WriteReal(dWidth - dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dHeight - dBorderSize); m_pStream->WriteStr(" m\012"); m_pStream->WriteReal(dWidth - dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(dWidth - 2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteReal(dWidth - 2 * dBorderSize); m_pStream->WriteChar(' '); m_pStream->WriteReal(dHeight - 2 * dBorderSize); m_pStream->WriteStr(" l\012"); m_pStream->WriteStr("f\012"); break; } case EBorderType::Dashed: { m_pStream->WriteStr(pAnnot->GetBorderDash().c_str()); break; } default: break; } m_pStream->WriteStr(pAnnot->GetBCforAP().c_str()); m_pStream->WriteStr("\012"); m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" w\0120 j\0120 J\012"); if (nType == EBorderType::Underline) { m_pStream->WriteInt(0); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize / 2); m_pStream->WriteStr(" m\012"); m_pStream->WriteReal(dWidth); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize / 2); m_pStream->WriteStr(" l\012S\012"); } else { m_pStream->WriteReal(dBorderSize / 2); m_pStream->WriteChar(' '); m_pStream->WriteReal(dBorderSize / 2); m_pStream->WriteChar(' '); m_pStream->WriteReal(std::max(dWidth - dBorderSize, 0.0)); m_pStream->WriteChar(' '); m_pStream->WriteReal(std::max(dHeight - dBorderSize, 0.0)); m_pStream->WriteStr(" re\012S\012"); } m_pStream->WriteStr("Q\012"); } void CAnnotAppearanceObject::DrawTextLine(const double& dX, const double& dY, const unsigned short* pCodes, const unsigned int& unCount, CFontCidTrueType** ppFonts, const double* pShifts) { CResourcesDict* pResources = dynamic_cast(Get("Resources")); if (!pResources) return; if (pCodes && pShifts) { double _dX = dX + pShifts[0], _dY = dY; if (!m_bStart) { _dX -= m_dCurX; _dY -= m_dCurY; m_dCurX += _dX; m_dCurY += _dY; } else { m_dCurX = _dX; m_dCurY = _dY; } m_pStream->WriteReal(_dX); m_pStream->WriteChar(' '); m_pStream->WriteReal(_dY); m_pStream->WriteStr(" Td\012"); for (unsigned int unIndex = 0; unIndex < unCount; ++unIndex) { if (ppFonts) { CFontDict* pFont = (CFontDict*)(ppFonts[unIndex]); if (m_pFont != pFont) { m_pStream->WriteEscapeName(pResources->GetFontName((CFontDict*)(ppFonts[unIndex]))); m_pStream->WriteChar(' '); m_pStream->WriteReal(m_dFontSize); m_pStream->WriteStr(" Tf\012"); m_pFont = pFont; } } unsigned char unByte[2] = {static_cast((pCodes[unIndex] >> 8) & 0xFF), static_cast(pCodes[unIndex] & 0xFF)}; m_pStream->WriteChar('['); m_pStream->WriteChar('<'); m_pStream->WriteBinary(unByte, 2, NULL); m_pStream->WriteChar('>'); m_pStream->WriteStr("]TJ\012"); if (unIndex != unCount - 1) { m_pStream->WriteReal(pShifts[unIndex + 1]); m_pStream->WriteChar(' '); m_pStream->WriteReal(0.0); m_pStream->WriteStr(" Td\012"); } } } else { double _dX = dX, _dY = dY; if (!m_bStart) { _dX -= m_dCurX; _dY -= m_dCurY; m_dCurX += _dX; m_dCurY += _dY; } else { m_dCurX = _dX; m_dCurY = _dY; } m_pStream->WriteReal(_dX); m_pStream->WriteChar(' '); m_pStream->WriteReal(_dY); m_pStream->WriteStr(" Td\012"); for (unsigned int unIndex = 0; unIndex < unCount; ++unIndex) { if (ppFonts) { CFontDict* pFont = (CFontDict*)(ppFonts[unIndex]); if (m_pFont != pFont) { m_pStream->WriteEscapeName(pResources->GetFontName((CFontDict*)(ppFonts[unIndex]))); m_pStream->WriteChar(' '); m_pStream->WriteReal(m_dFontSize); m_pStream->WriteStr(" Tf\012"); m_pFont = pFont; } } unsigned char unByte[2] = {static_cast((pCodes[unIndex] >> 8) & 0xFF), static_cast(pCodes[unIndex] & 0xFF)}; m_pStream->WriteChar('<'); m_pStream->WriteBinary(unByte, 2, NULL); m_pStream->WriteChar('>'); m_pStream->WriteStr(" Tj\012"); } } m_bStart = false; } void CAnnotAppearanceObject::DrawTextLine(const double &dX, const double &dY, const std::wstring& wsText) { m_pStream->WriteReal(dX); m_pStream->WriteChar(' '); m_pStream->WriteReal(dY); m_pStream->WriteStr(" Td\012"); std::string sText = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(wsText); m_pStream->WriteEscapeText((BYTE*)(sText.c_str()), sText.length()); m_pStream->WriteStr(" Tj\012"); } void CAnnotAppearanceObject::EndDrawText() { m_pStream->WriteStr("ET\012"); m_pStream->WriteStr("Q\012EMC\012"); } void CAnnotAppearanceObject::AddBBox(double dX, double dY, double dW, double dH) { CArrayObject* pArray = new CArrayObject(); Add("BBox", pArray); pArray->Add(dX); pArray->Add(dY); pArray->Add(dW); pArray->Add(dH); } void CAnnotAppearanceObject::AddMatrix(double sx, double shy, double shx, double sy, double tx, double ty) { CArrayObject* pArray = new CArrayObject(); Add("Matrix", pArray); pArray->Add(sx); pArray->Add(shy); pArray->Add(shx); pArray->Add(sy); pArray->Add(tx); pArray->Add(ty); } void CAnnotAppearanceObject::DrawTextCommentN(const std::string& sColor) { CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); if (sExtGrStateName) { m_pStream->WriteEscapeName(sExtGrStateName); m_pStream->WriteStr(" gs "); } m_pStream->WriteStr("1 0 0 1 9 5.0908 cm 7.74 12.616 m -7.74 12.616 l -8.274 12.616 -8.707 12.184 -8.707 11.649 c -8.707 -3.831 l -8.707 -4.365 -8.274 -4.798 -7.74 -4.798 c "); m_pStream->WriteStr("7.74 -4.798 l 8.274 -4.798 8.707 -4.365 8.707 -3.831 c 8.707 11.649 l 8.707 12.184 8.274 12.616 7.74 12.616 c h f Q 0 G "); m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 i 0.60 w 4 M 1 j 0 J [0 100] 1 d 1 0 0 1 9 5.0908 cm 1 0 m -2.325 -2.81 l -2.325 0 l -5.72 0 l -5.72 8.94 l 5.51 8.94 l 5.51 0 l 1 0 l -3.50 5.01 m "); m_pStream->WriteStr("-3.50 5.59 l 3.29 5.59 l 3.29 5.01 l -3.50 5.01 l -3.50 3.34 m -3.50 3.92 l 2.27 3.92 l 2.27 3.34 l -3.50 3.34 l 7.74 12.616 m -7.74 12.616 l "); m_pStream->WriteStr("-8.274 12.616 -8.707 12.184 -8.707 11.649 c -8.707 -3.831 l -8.707 -4.365 -8.274 -4.798 -7.74 -4.798 c 7.74 -4.798 l "); m_pStream->WriteStr("8.274 -4.798 8.707 -4.365 8.707 -3.831 c 8.707 11.649 l 8.707 12.184 8.274 12.616 7.74 12.616 c b"); } void CAnnotAppearanceObject::DrawTextCommentR(const std::string& sColor) { m_pStream->WriteStr("0 G "); m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 i 0.60 w 4 M 1 j 0 J [0 100] 1 d 1 0 0 1 9 5.0908 cm 4.1 1.71 m -0.54 -2.29 l -0.54 1.71 l -5.5 1.71 l -5.5 14.42 l 10.5 14.42 l 10.5 1.71 l 4.1 1.71 l "); m_pStream->WriteStr("-2.33 9.66 m 7.34 9.66 l 7.34 8.83 l -2.33 8.83 l -2.33 9.66 l -2.33 7.28 m 5.88 7.28 l 5.88 6.46 l -2.33 6.46 l -2.33 7.28 l 14.9 23.1235 m -14.9 23.1235 l "); m_pStream->WriteStr("-14.9 -20.345 l 14.9 -20.345 l 14.9 23.1235 l b"); } void CAnnotAppearanceObject::DrawTextCheck(const std::string& sColor) { m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 7.1836 1.2061 cm 0 0 m 6.691 11.152 11.31 14.196 v 10.773 15.201 9.626 16.892 8.155 17.587 c "); m_pStream->WriteStr("2.293 10.706 -0.255 4.205 y -4.525 9.177 l -6.883 5.608 l h b"); } void CAnnotAppearanceObject::DrawTextCheckmark() { m_pStream->WriteStr("q 0.396 0.396 0.396 rg 1 0 0 1 13.5151 16.5 cm 0 0 m -6.7 -10.23 l -8.81 -7 l -13.22 -7 l -6.29 -15 l 4.19 0 l h f Q"); } void CAnnotAppearanceObject::DrawTextCircle(const std::string& sColor) { CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); if (sExtGrStateName) { m_pStream->WriteEscapeName(sExtGrStateName); m_pStream->WriteStr(" gs "); } m_pStream->WriteStr("1 0 0 1 9.999 3.6387 cm 0 0 m -3.513 0 -6.36 2.85 -6.36 6.363 c -6.36 9.875 -3.513 12.724 0 12.724 c 3.514 12.724 6.363 9.875 6.363 6.363 c "); m_pStream->WriteStr("6.363 2.85 3.514 0 0 0 c h f Q "); m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 9.999 3.6387 cm 0 0 m -3.513 0 -6.36 2.85 -6.36 6.363 c -6.36 9.875 -3.513 12.724 0 12.724 c "); m_pStream->WriteStr("3.514 12.724 6.363 9.875 6.363 6.363 c 6.363 2.85 3.514 0 0 0 c 0 16.119 m -5.388 16.119 -9.756 11.751 -9.756 6.363 c -9.756 0.973 -5.388 -3.395 0 -3.395 c "); m_pStream->WriteStr("5.391 -3.395 9.757 0.973 9.757 6.363 c 9.757 11.751 5.391 16.119 0 16.119 c b"); } void CAnnotAppearanceObject::DrawTextCross(const std::string& sColor) { m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 18.6924 3.1357 cm 0 0 m -6.363 6.364 l 0 12.728 l -2.828 15.556 l -9.192 9.192 l -15.556 15.556 l "); m_pStream->WriteStr("-18.384 12.728 l -12.02 6.364 l -18.384 0 l -15.556 -2.828 l -9.192 3.535 l -2.828 -2.828 l h b"); } void CAnnotAppearanceObject::DrawTextCrossHairs(const std::string& sColor) { CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); if (sExtGrStateName) { m_pStream->WriteEscapeName(sExtGrStateName); m_pStream->WriteStr(" gs "); } m_pStream->WriteStr("1 0 0 1 9.9771 1.9443 cm 0 0 m -4.448 0 -8.053 3.604 -8.053 8.053 c -8.053 12.5 -4.448 16.106 0 16.106 c 4.447 16.106 8.054 12.5 8.054 8.053 c "); m_pStream->WriteStr("8.054 3.604 4.447 0 0 0 c h f Q "); m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.61 w 4 M 0 j 0 J [] 0 d q 1 0 0 1 9.9771 1.9443 cm 0 0 m -4.448 0 -8.053 3.604 -8.053 8.053 c -8.053 12.5 -4.448 16.106 0 16.106 c "); m_pStream->WriteStr("4.447 16.106 8.054 12.5 8.054 8.053 c 8.054 3.604 4.447 0 0 0 c 0 17.716 m -5.336 17.716 -9.663 13.39 -9.663 8.053 c -9.663 2.716 -5.336 -1.61 0 -1.61 c "); m_pStream->WriteStr("5.337 -1.61 9.664 2.716 9.664 8.053 c 9.664 13.39 5.337 17.716 0 17.716 c b Q q 1 0 0 1 10.7861 14.8325 cm 0 0 m -1.611 0 l -1.611 -4.027 l -5.638 -4.027 l "); m_pStream->WriteStr("-5.638 -5.638 l -1.611 -5.638 l -1.611 -9.665 l 0 -9.665 l 0 -5.638 l 4.026 -5.638 l 4.026 -4.027 l 0 -4.027 l h b Q"); } void CAnnotAppearanceObject::DrawTextHelp(const std::string& sColor) { CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); if (sExtGrStateName) { m_pStream->WriteEscapeName(sExtGrStateName); m_pStream->WriteStr(" gs "); } m_pStream->WriteStr("1 0 0 1 12.1465 10.5137 cm -2.146 9.403 m -7.589 9.403 -12.001 4.99 -12.001 -0.453 c -12.001 -5.895 -7.589 -10.309 -2.146 -10.309 c "); m_pStream->WriteStr("3.296 -10.309 7.709 -5.895 7.709 -0.453 c 7.709 4.99 3.296 9.403 -2.146 9.403 c h f Q "); m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 12.1465 10.5137 cm 0 0 m -0.682 -0.756 -0.958 -1.472 -0.938 -2.302 c -0.938 -2.632 l -3.385 -2.632 l "); m_pStream->WriteStr("-3.403 -2.154 l -3.459 -1.216 -3.147 -0.259 -2.316 0.716 c -1.729 1.433 -1.251 2.022 -1.251 2.647 c -1.251 3.291 -1.674 3.715 -2.594 3.751 c "); m_pStream->WriteStr("-3.202 3.751 -3.937 3.531 -4.417 3.2 c -5.041 5.205 l -4.361 5.591 -3.274 5.959 -1.968 5.959 c 0.46 5.959 1.563 4.616 1.563 3.089 c "); m_pStream->WriteStr("1.563 1.691 0.699 0.771 0 0 c -2.227 -6.863 m -2.245 -6.863 l -3.202 -6.863 -3.864 -6.146 -3.864 -5.189 c -3.864 -4.196 -3.182 -3.516 -2.227 -3.516 c "); m_pStream->WriteStr("-1.233 -3.516 -0.589 -4.196 -0.57 -5.189 c -0.57 -6.146 -1.233 -6.863 -2.227 -6.863 c -2.146 9.403 m -7.589 9.403 -12.001 4.99 -12.001 -0.453 c "); m_pStream->WriteStr("-12.001 -5.895 -7.589 -10.309 -2.146 -10.309 c 3.296 -10.309 7.709 -5.895 7.709 -0.453 c 7.709 4.99 3.296 9.403 -2.146 9.403 c b"); } void CAnnotAppearanceObject::DrawTextInsert(const std::string& sColor) { m_pStream->WriteStr("0 G "); m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 i 0.59 w 4 M 0 j 0 J [] 0 d 1 0 0 1 8.5386 19.8545 cm 0 0 m -8.39 -19.719 l 8.388 -19.719 l h B"); } void CAnnotAppearanceObject::DrawTextKey(const std::string& sColor) { CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); if (sExtGrStateName) { m_pStream->WriteEscapeName(sExtGrStateName); m_pStream->WriteStr(" gs "); } m_pStream->WriteStr("1 0 0 1 6.5 12.6729 cm 0.001 5.138 m -2.543 5.138 -4.604 3.077 -4.604 0.534 c -4.604 -1.368 -3.449 -3.001 -1.802 -3.702 c "); m_pStream->WriteStr("-1.802 -4.712 l -0.795 -5.719 l -1.896 -6.82 l -0.677 -8.039 l -1.595 -8.958 l -0.602 -9.949 l -1.479 -10.829 l -0.085 -12.483 l 1.728 -10.931 l "); m_pStream->WriteStr("1.728 -3.732 l 1.737 -3.728 1.75 -3.724 1.76 -3.721 c 3.429 -3.03 4.604 -1.385 4.604 0.534 c 4.604 3.077 2.542 5.138 0.001 5.138 c f Q "); m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 6.5 12.6729 cm 0 0 m -1.076 0 -1.95 0.874 -1.95 1.95 c -1.95 3.028 -1.076 3.306 0 3.306 c "); m_pStream->WriteStr("1.077 3.306 1.95 3.028 1.95 1.95 c 1.95 0.874 1.077 0 0 0 c 0.001 5.138 m -2.543 5.138 -4.604 3.077 -4.604 0.534 c -4.604 -1.368 -3.449 -3.001 -1.802 -3.702 c "); m_pStream->WriteStr("-1.802 -4.712 l -0.795 -5.719 l -1.896 -6.82 l -0.677 -8.039 l -1.595 -8.958 l -0.602 -9.949 l -1.479 -10.829 l -0.085 -12.483 l 1.728 -10.931 l 1.728 -3.732 l "); m_pStream->WriteStr("1.737 -3.728 1.75 -3.724 1.76 -3.721 c 3.429 -3.03 4.604 -1.385 4.604 0.534 c 4.604 3.077 2.542 5.138 0.001 5.138 c b"); } void CAnnotAppearanceObject::DrawTextNewParagraph(const std::string& sColor) { m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d q 1 0 0 1 6.4995 20 cm 0 0 m -6.205 -12.713 l 6.205 -12.713 l h b Q q 1 0 0 1 1.1909 6.2949 cm 0 0 m 1.278 0 l "); m_pStream->WriteStr("1.353 0 1.362 -0.02 1.391 -0.066 c 2.128 -1.363 3.78 -4.275 3.966 -4.713 c 3.985 -4.713 l 3.976 -4.453 3.957 -3.91 3.957 -3.137 c 3.957 -0.076 l "); m_pStream->WriteStr("3.957 -0.02 3.976 0 4.041 0 c 4.956 0 l 5.021 0 5.04 -0.029 5.04 -0.084 c 5.04 -6.049 l 5.04 -6.113 5.021 -6.133 4.947 -6.133 c 3.695 -6.133 l "); m_pStream->WriteStr("3.621 -6.133 3.611 -6.113 3.574 -6.066 c 3.052 -4.955 1.353 -2.063 0.971 -1.186 c 0.961 -1.186 l 0.999 -1.68 0.999 -2.146 1.008 -3.025 c 1.008 -6.049 l "); m_pStream->WriteStr("1.008 -6.104 0.989 -6.133 0.933 -6.133 c 0.009 -6.133 l -0.046 -6.133 -0.075 -6.123 -0.075 -6.049 c -0.075 -0.066 l -0.075 -0.02 -0.056 0 0 0 c f Q q "); m_pStream->WriteStr("1 0 0 1 9.1367 3.0273 cm 0 0 m 0.075 0 0.215 -0.008 0.645 -0.008 c 1.4 -0.008 2.119 0.281 2.119 1.213 c 2.119 1.969 1.633 2.381 0.737 2.381 c "); m_pStream->WriteStr("0.354 2.381 0.075 2.371 0 2.361 c h -1.146 3.201 m -1.146 3.238 -1.129 3.268 -1.082 3.268 c -0.709 3.275 0.02 3.285 0.729 3.285 c "); m_pStream->WriteStr("2.613 3.285 3.248 2.314 3.258 1.232 c 3.258 -0.27 2.007 -0.914 0.607 -0.914 c 0.327 -0.914 0.057 -0.914 0 -0.904 c 0 -2.789 l "); m_pStream->WriteStr("0 -2.836 -0.019 -2.865 -0.074 -2.865 c -1.082 -2.865 l -1.119 -2.865 -1.146 -2.846 -1.146 -2.799 c h f Q"); } void CAnnotAppearanceObject::DrawTextNote(const std::string& sColor) { m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.61 w 4 M 0 j 0 J [] 0 d q 1 0 0 1 16.959 1.3672 cm 0 0 m 0 -0.434 -0.352 -0.785 -0.784 -0.785 c -14.911 -0.785 l "); m_pStream->WriteStr("-15.345 -0.785 -15.696 -0.434 -15.696 0 c -15.696 17.266 l -15.696 17.699 -15.345 18.051 -14.911 18.051 c -0.784 18.051 l -0.352 18.051 0 17.699 0 17.266 c "); m_pStream->WriteStr("h b Q q 1 0 0 1 4.4023 13.9243 cm 0 0 m 9.418 0 l S Q q 1 0 0 1 4.4019 11.2207 cm 0 0 m 9.418 0 l S Q q 1 0 0 1 4.4023 8.5176 cm 0 0 m 9.418 0 l S Q q "); m_pStream->WriteStr("1 0 0 1 4.4023 5.8135 cm 0 0 m 9.418 0 l S Q"); } void CAnnotAppearanceObject::DrawTextParagraph(const std::string& sColor) { CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); if (sExtGrStateName) { m_pStream->WriteEscapeName(sExtGrStateName); m_pStream->WriteStr(" gs "); } m_pStream->WriteStr("1 0 0 1 19.6973 10.0005 cm 0 0 m 0 -5.336 -4.326 -9.662 -9.663 -9.662 c -14.998 -9.662 -19.324 -5.336 -19.324 0 c -19.324 5.335 -14.998 9.662 -9.663 9.662 c "); m_pStream->WriteStr("-4.326 9.662 0 5.335 0 0 c h f Q "); m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d q 1 0 0 1 19.6973 10.0005 cm 0 0 m 0 -5.336 -4.326 -9.662 -9.663 -9.662 c -14.998 -9.662 -19.324 -5.336 -19.324 0 c "); m_pStream->WriteStr("-19.324 5.335 -14.998 9.662 -9.663 9.662 c -4.326 9.662 0 5.335 0 0 c h S Q q 1 0 0 1 11.6787 2.6582 cm 0 0 m -1.141 0 l -1.227 0 -1.244 0.052 -1.227 0.139 c "); m_pStream->WriteStr("-0.656 1.157 -0.52 2.505 -0.52 3.317 c -0.52 3.594 l -2.833 3.783 -5.441 4.838 -5.441 8.309 c -5.441 10.778 -3.714 12.626 -0.57 13.024 c "); m_pStream->WriteStr("-0.535 13.508 -0.381 14.129 -0.242 14.389 c -0.207 14.44 -0.174 14.475 -0.104 14.475 c 1.088 14.475 l 1.156 14.475 1.191 14.458 1.175 14.372 c "); m_pStream->WriteStr("1.105 14.095 0.881 13.127 0.881 12.402 c 0.881 9.431 0.932 7.324 0.95 4.06 c 0.95 2.298 0.708 0.813 0.189 0.07 c 0.155 0.034 0.103 0 0 0 c b Q"); } void CAnnotAppearanceObject::DrawTextRightArrow(const std::string& sColor) { CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(0.6, 0.6); const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); m_pStream->WriteStr("q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J [] 0 d "); if (sExtGrStateName) { m_pStream->WriteEscapeName(sExtGrStateName); m_pStream->WriteStr(" gs "); } m_pStream->WriteStr("1 0 0 1 3.7856 11.1963 cm 6.214 -10.655 m 11.438 -10.655 15.673 -6.42 15.673 -1.196 c 15.673 4.027 11.438 8.262 6.214 8.262 c "); m_pStream->WriteStr("0.991 8.262 -3.244 4.027 -3.244 -1.196 c -3.244 -6.42 0.991 -10.655 6.214 -10.655 c h f Q "); m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 0 j 0 J [] 0 d 1 0 0 1 3.7856 11.1963 cm 0 0 m 8.554 0 l 6.045 2.51 l 7.236 3.702 l 12.135 -1.197 l 7.236 -6.096 l 6.088 -4.949 l "); m_pStream->WriteStr("8.644 -2.394 l 0 -2.394 l h 6.214 -10.655 m 11.438 -10.655 15.673 -6.42 15.673 -1.196 c 15.673 4.027 11.438 8.262 6.214 8.262 c "); m_pStream->WriteStr("0.991 8.262 -3.244 4.027 -3.244 -1.196 c -3.244 -6.42 0.991 -10.655 6.214 -10.655 c b"); } void CAnnotAppearanceObject::DrawTextRightPointer(const std::string& sColor) { m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0.59 w 4 M 0 j 0 J [] 0 d 1 0 0 1 1.1871 17.0000 cm 0 0 m 4.703 -8.703 l 0 -17 l 18.813 -8.703 l b"); } void CAnnotAppearanceObject::DrawTextStar(const std::string& sColor) { m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 9.999 18.8838 cm 0 0 m 3.051 -6.178 l 9.867 -7.168 l 4.934 -11.978 l 6.099 -18.768 l 0 -15.562 l -6.097 -18.768 l "); m_pStream->WriteStr("-4.933 -11.978 l -9.866 -7.168 l -3.048 -6.178 l b"); } void CAnnotAppearanceObject::DrawTextUpArrow(const std::string& sColor) { m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 1.1007 6.7185 cm 0 0 m 4.009 0 l 4.009 -6.719 l 11.086 -6.719 l 11.086 0 l 14.963 0 l 7.499 13.081 l b"); } void CAnnotAppearanceObject::DrawTextUpLeftArrow(const std::string& sColor) { m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 2.8335 1.7627 cm 0 0 m -2.74 15.16 l 12.345 12.389 l 9.458 9.493 l 14.027 4.91 l 7.532 -1.607 l 2.964 2.975 l b"); } void CAnnotAppearanceObject::DrawLine() { AddBBox(m_pAnnot->GetRect().fLeft, m_pAnnot->GetRect().fBottom, m_pAnnot->GetRect().fRight, m_pAnnot->GetRect().fTop); AddMatrix(1, 0, 0, 1, -m_pAnnot->GetRect().fLeft, -m_pAnnot->GetRect().fBottom); if (m_pAnnot->GetBorderType() == EBorderType::Dashed) m_pStream->WriteStr(m_pAnnot->GetBorderDash().c_str()); double dBorderSize = m_pAnnot->GetBorderWidth(); m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" w\012"); m_pStream->WriteStr(m_pAnnot->GetColorName("IC", false).c_str()); m_pStream->WriteStr(m_pAnnot->GetColorName("C", true).c_str()); CObjectBase* pObj = m_pAnnot->Get("CA"); if (pObj && pObj->GetType() == object_type_REAL) { float dAlpha = ((CRealObject*)pObj)->Get(); if (dAlpha != 1) { CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(dAlpha, dAlpha); const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); if (sExtGrStateName) { m_pStream->WriteEscapeName(sExtGrStateName); m_pStream->WriteStr(" gs\012"); } } } double dLL = 0, dLLE = 0, dLLO = 0; pObj = m_pAnnot->Get("LL"); if (pObj && pObj->GetType() == object_type_REAL) dLL = ((CRealObject*)pObj)->Get(); pObj = m_pAnnot->Get("LLE"); if (pObj && pObj->GetType() == object_type_REAL) dLLE = ((CRealObject*)pObj)->Get(); pObj = m_pAnnot->Get("LLO"); if (pObj && pObj->GetType() == object_type_REAL) dLLO = ((CRealObject*)pObj)->Get(); CLineAnnotation* pAnnot = (CLineAnnotation*)m_pAnnot; DrawLineArrow(m_pStream, dBorderSize, pAnnot->dL[0], pAnnot->dL[1], pAnnot->dL[2], pAnnot->dL[3], pAnnot->m_nLE1, pAnnot->m_nLE2, dLL, dLLE, dLLO); } void CAnnotAppearanceObject::DrawCheckBoxCircle(int nRotate, bool bSet, bool bN) { CCheckBoxWidget* pAnnot = dynamic_cast(m_pAnnot); if (!pAnnot) return; double dBorder = 1; EBorderType nBorderType = EBorderType::Inset; if (m_pAnnot->HaveBorder()) { dBorder = m_pAnnot->GetBorderWidth(); nBorderType = m_pAnnot->GetBorderType(); } double dW = m_pAnnot->GetRect().fRight - m_pAnnot->GetRect().fLeft; double dH = std::abs(m_pAnnot->GetRect().fBottom - m_pAnnot->GetRect().fTop); if (nRotate == 90 || nRotate == 270) std::swap(dW, dH); double dCX = dW / 2.0, dCY = dH / 2.0; double dR = std::min(dW, dH) / 2.0; // Задний фон std::string sBG; if (!bN && nBorderType != EBorderType::Beveled) { sBG = pAnnot->GetBGforAP(); if (sBG == "1 g") sBG = "0.749023 -0.250977 -0.250977 rg"; else if (sBG.empty()) sBG = "0.749023 g"; else sBG = pAnnot->GetBGforAP(-0.250977); } else sBG = pAnnot->GetBGforAP(); if (!sBG.empty()) { m_pStream->WriteStr(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"); StreamWriteCircle(m_pStream, 0, 0, dR); m_pStream->WriteStr("f\012Q\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("\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"); 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"); } // Установлен if (!bSet) return; double dShift = dBorder / 2.0; if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset) dShift *= 2.0; 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"); } void CAnnotAppearanceObject::DrawCheckBoxSquare(int nRotate, bool bSet, bool bN) { CCheckBoxWidget* pAnnot = dynamic_cast(m_pAnnot); if (!pAnnot) return; double dBorder = 1; EBorderType nBorderType = EBorderType::Inset; if (m_pAnnot->HaveBorder()) { dBorder = m_pAnnot->GetBorderWidth(); nBorderType = m_pAnnot->GetBorderType(); } double dW = m_pAnnot->GetRect().fRight - m_pAnnot->GetRect().fLeft; double dH = std::abs(m_pAnnot->GetRect().fBottom - m_pAnnot->GetRect().fTop); if (nRotate == 90 || nRotate == 270) std::swap(dW, dH); // Задний фон m_pStream->WriteStr("q\012"); std::string sBG; if (!bN && nBorderType != EBorderType::Beveled) { sBG = pAnnot->GetBGforAP(-0.250977); if (sBG.empty()) sBG = "0.749023 g"; } else sBG = pAnnot->GetBGforAP(); if (!sBG.empty()) { m_pStream->WriteStr(sBG.c_str()); m_pStream->WriteStr("\012"); StreamWriteRect(m_pStream, 0, 0, dW, dH); m_pStream->WriteStr("f\012"); } // Граница if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset) { 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()); 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; double dDiff = std::abs(dW - dH) / 2.0; double dShift = dBorder; if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset) dShift *= 2; bool bW = dW > dH; double dCX = dW / 2.0, dCY = dH / 2.0; double dC = std::min(dW, dH) / 2.0; ECheckBoxStyle nStyle = pAnnot->GetStyle(); switch (nStyle) { case ECheckBoxStyle::Check: { 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); StreamWriteXYLine(m_pStream, 4 * dScale, 8.2 * dScale); StreamWriteXYLine(m_pStream, 7.71429 * dScale, 4 * dScale); StreamWriteXYCurve(m_pStream, 12.0476 * dScale, 10.6 * dScale, 13.2857 * dScale, 11.8 * dScale, 17 * dScale, 16 * dScale); StreamWriteXYCurve(m_pStream, 14.5238 * dScale, 16 * dScale, 9.77778 * dScale, 11.2 * dScale, 7.71429 * dScale, 8.2 * dScale); StreamWriteXYLine(m_pStream, 5.2381 * dScale, 11.2 * dScale); m_pStream->WriteStr("f\012Q\012"); break; } case ECheckBoxStyle::Cross: { double dCross = dBorder; if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset) dCross *= 2; m_pStream->WriteStr("q\012"); StreamWriteRect(m_pStream, dCross, dCross, dW - dCross, dH - dCross); 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); double x2 = dW - dShift - 1 - (bW ? dDiff : 0); double y2 = dH - dShift - 1 - (bW ? 0 : dDiff); StreamWriteXYMove(m_pStream, x1, y2); StreamWriteXYLine(m_pStream, x2, y1); StreamWriteXYMove(m_pStream, x2, y2); StreamWriteXYLine(m_pStream, x1, y1); m_pStream->WriteStr("s\012Q\012"); break; } case ECheckBoxStyle::Diamond: { double dSq = dC - dShift * 2.0 - 1; 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); StreamWriteXYLine(m_pStream, 0, -dSq); m_pStream->WriteStr("f\012Q\012"); break; } case ECheckBoxStyle::Circle: { double dR = dC - dShift * 2.0 - 1; 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; } case ECheckBoxStyle::Star: { double dROuter = dC - dShift * 2.0 - 1; double dRInner = dROuter / 2.5; int nPoints = 5; 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; double dAngle = M_PI / nPoints * i; double dX = dCX - dR * std::sin(dAngle); double dY = dCY + dR * std::cos(dAngle); if (i == 0) StreamWriteXYMove(m_pStream, dX, dY); else StreamWriteXYLine(m_pStream, dX, dY); } m_pStream->WriteStr("f\012Q\012"); break; } case ECheckBoxStyle::Square: { double dSq = std::min(dW, dH) * 2.0 / 3.0 - dShift * 2.0 - 1; 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; } } } }