Write PushButton

This commit is contained in:
Svetlana Kulikova
2024-01-18 18:37:54 +03:00
parent a160bc7ad1
commit 0803b33067
4 changed files with 327 additions and 54 deletions

View File

@ -3556,7 +3556,12 @@ void CPdfWriter::DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWrit
wsValue = pButtonWidget->GetAC();
if (!pButtonWidget->HaveBorder())
pButtonWidget->SetEmptyBorder();
{
if (pButtonWidget->HaveBC())
pButtonWidget->SetBorder(0, 1, {});
else
pButtonWidget->SetEmptyBorder();
}
if (!wsValue.empty() && nTP != 1)
{
@ -3576,7 +3581,8 @@ void CPdfWriter::DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWrit
dShiftBorder *= 2;
if (dShiftBorder == 0)
dShiftBorder = 1;
if (!pButtonWidget->GetRespectBorder())
bool bRespectBorder = pButtonWidget->GetRespectBorder();
if (!bRespectBorder)
dShiftBorder = 0;
bool bFont = GetFontData(pAppFonts, wsValue, pFont, isBold, isItalic, pUnicodes, unLen, pCodes, ppFonts);
@ -3598,34 +3604,32 @@ void CPdfWriter::DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWrit
if (pFontTT)
{
double dKoef = dFontSize / pFontTT->m_dUnitsPerEm;
dLineH = pFontTT->m_dHeight * dKoef;
// TODO что-то между m_dMaxY-m_dMinY и m_dHeight, но не просто среднее
dLineH = (pFontTT->m_dMaxY + std::abs(pFontTT->m_dMinY) + pFontTT->m_dHeight) / 2.0 * dKoef;
// dLineH = (pFontTT->m_dMaxY + std::abs(pFontTT->m_dMinY)) * dKoef;
// dLineH = pFontTT->m_dHeight * dKoef;
// double dLineHeight = pFontTT->m_dHeight * dKoef;
// double dDescent = std::abs(pFontTT->m_dDescent * dKoef);
// double dAscent1 = pFontTT->m_dAscent * dKoef;
// double dAscent = dLineHeight - dDescent;
// double dMidPoint = dAscent - pFontTT->m_dMinY * dKoef + dAscent - pFontTT->m_dMaxY * dKoef;
// double dDiff = dLineHeight - dMidPoint;
if (nTP == 0 || nTP == 2 || nTP == 3 || nTP == 6)
dShiftX = (dWidth - dLineW) / 2;
else if (nTP == 4)
dShiftX = dWidth - dLineW - dShiftBorder * 2;
dShiftX = dWidth - dLineW - dShiftBorder * 1.5;
else if (nTP == 5)
dShiftX = dShiftBorder * 2;
dShiftX = dShiftBorder * 2.5;
if (nTP == 0 || nTP == 4 || nTP == 5 || nTP == 6)
dShiftY = (dHeight - dLineH) / 2.0 + std::abs(pFontTT->m_dDescent * dKoef);
if (nTP == 0 || nTP == 6)
dShiftY = (dHeight - dLineH) / 2 + std::abs(pFontTT->m_dMinY * dKoef);
else if (nTP == 3)
dShiftY = dHeight - dShiftBorder * 2 - dLineH + std::abs(pFontTT->m_dDescent * dKoef);
dShiftY = dHeight - dShiftBorder * 2.5 - dLineH + std::abs(pFontTT->m_dMinY * dKoef);
else if (nTP == 2)
{
// double dLineHeight = pFontTT->m_dHeight * dKoef;
// double dDescent = std::abs(pFontTT->m_dDescent * dKoef);
// double dAscent1 = pFontTT->m_dAscent * dKoef;
// double dAscent = dLineHeight - dDescent;
// double dMin = pFontTT->m_dMinY * dKoef;
// double dMax = pFontTT->m_dMaxY * dKoef;
// double dMidPoint = dAscent - pFontTT->m_dMinY * dKoef + dAscent - pFontTT->m_dMaxY * dKoef;
// double dDiff = dLineHeight - dMidPoint;
// dShiftY = dLineHeight / 2.0;
// dShiftY = dShiftY + dDescent;
// Find! PERFECT!!!
dShiftY = dShiftBorder * 2 + std::abs(pFontTT->m_dMinY * dKoef);
}
else if (nTP == 4 || nTP == 5)
dShiftY = (dHeight - dLineH) / 2 + std::abs(pFontTT->m_dMinY * dKoef);
}
}

View File

@ -221,7 +221,6 @@ namespace PdfWriter
}
void CAnnotation::SetEmptyBorder()
{
m_oBorder.bHave = true;
m_oBorder.nType = 0;
m_oBorder.dWidth = 1;
}
@ -1251,14 +1250,15 @@ namespace PdfWriter
return;
Add("AP", m_pAppearance);
double dHeight = fabs(m_oRect.fTop - m_oRect.fBottom);
double dWidth = fabs(m_oRect.fRight - m_oRect.fLeft);
pAppearance->StartDraw(dWidth, dHeight);
if (pForm)
{
double dH = fabs(m_oRect.fTop - m_oRect.fBottom);
double dW = fabs(m_oRect.fRight - m_oRect.fLeft);
if (m_nTP == 2 || m_nTP == 3)
dH -= dLineH;
if (m_nTP == 4 || m_nTP == 5)
dW -= dLineW;
double dH = dHeight;
double dW = dWidth;
double dOriginW = pForm->GetWidth();
double dOriginH = pForm->GetHeight();
@ -1267,20 +1267,32 @@ namespace PdfWriter
|| (2 == m_nScaleType && (dOriginH > dH || dOriginW > dW))
|| (3 == m_nScaleType && dOriginH < dH && dOriginW < dW));
double dBorderSize = m_oBorder.dWidth;
if (m_oBorder.nType == 1 || m_oBorder.nType == 3)
dBorderSize *= 2;
double dDstW = dOriginW;
double dDstH = dOriginH;
double dDstX = 0;
double dDstY = 0;
if (m_nTP == 2 || m_nTP == 3)
dDstY += dLineH;
if (m_nTP == 4 || m_nTP == 5)
dDstX += dLineW;
if (m_bRespectBorders && m_oBorder.bHave)
if (m_nTP == 2)
{
dH -= (dLineH + dBorderSize);
dDstY += (dLineH + dBorderSize);
}
if (m_nTP == 3)
dH -= (dLineH + dBorderSize);
if (m_nTP == 4)
dW -= (dLineW + dBorderSize);
if (m_nTP == 5)
{
dW -= (dLineW + dBorderSize);
dDstX += (dLineW + dBorderSize);
}
if (m_bRespectBorders)
{
double dBorderSize = m_oBorder.dWidth;
if (m_oBorder.nType == 1 || m_oBorder.nType == 3)
dBorderSize *= 2;
dDstX += 2 * dBorderSize;
dDstY += 2 * dBorderSize;
dH -= 4 * dBorderSize;
@ -1305,29 +1317,21 @@ namespace PdfWriter
dDstX += (dW - dDstW) * m_dShiftX;
dDstY += (dH - dDstH) * m_dShiftY;
pAppearance->DrawPicture(pForm->GetName().c_str(), dDstX, dDstY, dDstW / dOriginW, dDstH / dOriginH, m_bRespectBorders);
}
else
pAppearance->StartDrawText(m_pFont, m_dFontSize, 0, 0, 0, NULL, fabs(m_oRect.fRight - m_oRect.fLeft), fabs(m_oRect.fBottom - m_oRect.fTop));
pAppearance->DrawPictureInline(pForm->GetName().c_str(), dDstX, dDstY, dDstW / dOriginW, dDstH / dOriginH, m_bRespectBorders);
if (pCodes)
{
CStream* pStream = pAppearance->GetStream();
if (pForm)
pStream->WriteStr("\012q\012BT\012");
pAppearance->DrawTextLine(dX, dY, pCodes, unCount, ppFonts, NULL);
if (pForm)
pStream->WriteStr("ET\012Q\012");
else
pAppearance->EndDrawText();
}
if (pForm)
{
CheckMK();
std::string sAP = nAP == 0 ? "I" : (nAP == 1 ? "RI" : "IX");
m_pMK->Add(sAP, pForm);
}
if (pCodes)
{
pAppearance->StartText(m_pFont, m_dFontSize);
pAppearance->DrawTextLine(dX, dY, pCodes, unCount, ppFonts, NULL);
pAppearance->EndText();
}
pAppearance->EndDraw();
}
//----------------------------------------------------------------------------------------
// CCheckBoxWidget

View File

@ -2170,6 +2170,262 @@ namespace PdfWriter
m_bStart = true;
m_pFont = pFont;
}
void CAnnotAppearanceObject::StartDraw(const double& dWidth, const double& dHeight)
{
CWidgetAnnotation* pAnnot = dynamic_cast<CWidgetAnnotation*>(m_pAnnot);
if (!m_pStream || !pAnnot)
return;
DrawBackground(dWidth, dHeight);
DrawBorder(dWidth, dHeight);
m_pStream->WriteStr("q\012");
double dBorderSize = pAnnot->GetBorderWidth();
BYTE nType = pAnnot->GetBorderType();
if (nType == 1 || nType == 3)
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<CChoiceWidget*>(m_pAnnot);
double dBaseLine = pAnnot->GetListBoxHeight();
std::vector<int> 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<CWidgetAnnotation*>(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");
m_pStream->WriteStr(pAnnot->GetDAforAP(pFont).c_str());
}
void CAnnotAppearanceObject::DrawPictureInline(const char* sImageName, const double& dX, const double& dY, const double& dW, const double& dH, const bool& bRespectBorder)
{
CWidgetAnnotation* pAnnot = dynamic_cast<CWidgetAnnotation*>(m_pAnnot);
if (!m_pStream || !pAnnot || !sImageName)
return;
m_pStream->WriteStr("q\012");
if (bRespectBorder)
{
TRect oRect = pAnnot->GetRect();
double dWidth = fabs(oRect.fRight - oRect.fLeft);
double dHeight = fabs(oRect.fBottom - oRect.fTop);
double dBorderSize = pAnnot->GetBorderWidth();
BYTE nType = pAnnot->GetBorderType();
if (nType == 1 || nType == 3)
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<CWidgetAnnotation*>(m_pAnnot);
if (!pAnnot || !pAnnot->HaveBG())
return;
m_pStream->WriteStr("q\012");
m_pStream->WriteStr(pAnnot->GetBGforAP().c_str());
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<CWidgetAnnotation*>(m_pAnnot);
if (!pAnnot || !pAnnot->HaveBorder())
return;
m_pStream->WriteStr("q\012");
double dBorderSize = pAnnot->GetBorderWidth();
BYTE nType = 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(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());
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;
}
m_pStream->WriteStr(pAnnot->GetBCforAP().c_str());
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");
}
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<CResourcesDict*>(Get("Resources"));

View File

@ -390,6 +390,12 @@ namespace PdfWriter
void DrawTextLine(const double &dX, const double &dY, const std::wstring& wsText);
void EndDrawText();
void StartDraw(const double& dWidth, const double& dHeight);
void StartText(CFontDict* pFont, const double& dFontSize);
void DrawPictureInline(const char* sImageName, const double& dX, const double& dY, const double& dW, const double& dH, const bool& bRespectBorder);
void EndText();
void EndDraw();
void DrawTextComment();
CStream* GetStream() { return m_pStream; }
@ -398,6 +404,9 @@ namespace PdfWriter
private:
void Init(CXref* pXref, CResourcesDict* pResources, TRect* pRect);
void DrawBackground(const double& dWidth, const double& dHeight);
void DrawBorder(const double& dWidth, const double& dHeight);
CXref* m_pXref;
CStream* m_pStream;
CFieldBase* m_pField;