summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Sinclair <dsinclair@chromium.org>2017-07-19 15:24:49 -0400
committerChromium commit bot <commit-bot@chromium.org>2017-07-19 19:56:19 +0000
commitcb2ea42cc56eb6aaab3e498abf13e63742e64181 (patch)
treeb6e576eb901382cd302109e831d693f81913644a
parent67ccef73bf664b7cdb4c6eed7acbaa4163c22a80 (diff)
downloadpdfium-cb2ea42cc56eb6aaab3e498abf13e63742e64181.tar.xz
Create CPWL_AppStream.
This CL creates a CPWL_AppStream and consolidates app stream generation code from CPDFSDK_Widget, CPDFSDK_BAAnnot and CPWL_Utils. The remaining app stream code from CPWL_Utils will be cleaned up in a future CL. Change-Id: I20cfdec09a351bd509241d2c667a182fba84b0c1 Reviewed-on: https://pdfium-review.googlesource.com/8310 Commit-Queue: dsinclair <dsinclair@chromium.org> Reviewed-by: Tom Sepez <tsepez@chromium.org> Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
-rw-r--r--BUILD.gn2
-rw-r--r--fpdfsdk/cpdfsdk_baannot.cpp51
-rw-r--r--fpdfsdk/cpdfsdk_baannot.h8
-rw-r--r--fpdfsdk/cpdfsdk_widget.cpp858
-rw-r--r--fpdfsdk/cpdfsdk_widget.h18
-rw-r--r--fpdfsdk/pdfwindow/cpwl_appstream.cpp1558
-rw-r--r--fpdfsdk/pdfwindow/cpwl_appstream.h43
-rw-r--r--fpdfsdk/pdfwindow/cpwl_utils.cpp656
-rw-r--r--fpdfsdk/pdfwindow/cpwl_utils.h47
9 files changed, 1623 insertions, 1618 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 6bf3947867..4bf04fc40e 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1094,6 +1094,8 @@ static_library("fxedit") {
static_library("pdfwindow") {
sources = [
+ "fpdfsdk/pdfwindow/cpwl_appstream.cpp",
+ "fpdfsdk/pdfwindow/cpwl_appstream.h",
"fpdfsdk/pdfwindow/cpwl_button.cpp",
"fpdfsdk/pdfwindow/cpwl_button.h",
"fpdfsdk/pdfwindow/cpwl_caret.cpp",
diff --git a/fpdfsdk/cpdfsdk_baannot.cpp b/fpdfsdk/cpdfsdk_baannot.cpp
index 1f4f279b5e..a426749fff 100644
--- a/fpdfsdk/cpdfsdk_baannot.cpp
+++ b/fpdfsdk/cpdfsdk_baannot.cpp
@@ -38,6 +38,13 @@ CPDF_Dictionary* CPDFSDK_BAAnnot::GetAnnotDict() const {
return m_pAnnot->GetAnnotDict();
}
+CPDF_Dictionary* CPDFSDK_BAAnnot::GetAPDict() const {
+ CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP");
+ if (!pAPDict)
+ pAPDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("AP");
+ return pAPDict;
+}
+
void CPDFSDK_BAAnnot::SetRect(const CFX_FloatRect& rect) {
ASSERT(rect.right - rect.left >= GetMinWidth());
ASSERT(rect.top - rect.bottom >= GetMinHeight());
@@ -293,50 +300,6 @@ bool CPDFSDK_BAAnnot::GetColor(FX_COLORREF& color) const {
return false;
}
-void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType,
- const CFX_FloatRect& rcBBox,
- const CFX_Matrix& matrix,
- const CFX_ByteString& sContents,
- const CFX_ByteString& sAPState) {
- CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP");
- if (!pAPDict)
- pAPDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("AP");
-
- CPDF_Stream* pStream = nullptr;
- CPDF_Dictionary* pParentDict = nullptr;
- if (sAPState.IsEmpty()) {
- pParentDict = pAPDict;
- pStream = pAPDict->GetStreamFor(sAPType);
- } else {
- CPDF_Dictionary* pAPTypeDict = pAPDict->GetDictFor(sAPType);
- if (!pAPTypeDict)
- pAPTypeDict = pAPDict->SetNewFor<CPDF_Dictionary>(sAPType);
-
- pParentDict = pAPTypeDict;
- pStream = pAPTypeDict->GetStreamFor(sAPState);
- }
-
- if (!pStream) {
- CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
- pStream = pDoc->NewIndirect<CPDF_Stream>();
- pParentDict->SetNewFor<CPDF_Reference>(sAPType, pDoc, pStream->GetObjNum());
- }
-
- CPDF_Dictionary* pStreamDict = pStream->GetDict();
- if (!pStreamDict) {
- auto pNewDict = pdfium::MakeUnique<CPDF_Dictionary>(
- m_pAnnot->GetDocument()->GetByteStringPool());
- pStreamDict = pNewDict.get();
- pStreamDict->SetNewFor<CPDF_Name>("Type", "XObject");
- pStreamDict->SetNewFor<CPDF_Name>("Subtype", "Form");
- pStreamDict->SetNewFor<CPDF_Number>("FormType", 1);
- pStream->InitStream(nullptr, 0, std::move(pNewDict));
- }
- pStreamDict->SetMatrixFor("Matrix", matrix);
- pStreamDict->SetRectFor("BBox", rcBBox);
- pStream->SetData((uint8_t*)sContents.c_str(), sContents.GetLength());
-}
-
bool CPDFSDK_BAAnnot::IsVisible() const {
uint32_t nFlags = GetFlags();
return !((nFlags & ANNOTFLAG_INVISIBLE) || (nFlags & ANNOTFLAG_HIDDEN) ||
diff --git a/fpdfsdk/cpdfsdk_baannot.h b/fpdfsdk/cpdfsdk_baannot.h
index 6c9ae06ed4..18d25a1e02 100644
--- a/fpdfsdk/cpdfsdk_baannot.h
+++ b/fpdfsdk/cpdfsdk_baannot.h
@@ -36,6 +36,8 @@ class CPDFSDK_BAAnnot : public CPDFSDK_Annot {
CPDF_Dictionary* GetAnnotDict() const;
CPDF_Annot* GetPDFPopupAnnot() const;
+ CPDF_Dictionary* GetAPDict() const;
+
void SetContents(const CFX_WideString& sContents);
CFX_WideString GetContents() const;
@@ -88,12 +90,6 @@ class CPDFSDK_BAAnnot : public CPDFSDK_Annot {
void ClearCachedAP();
- void WriteAppearance(const CFX_ByteString& sAPType,
- const CFX_FloatRect& rcBBox,
- const CFX_Matrix& matrix,
- const CFX_ByteString& sContents,
- const CFX_ByteString& sAPState = "");
-
void SetOpenState(bool bState);
protected:
diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp
index 80e7c8adb1..fed6b953da 100644
--- a/fpdfsdk/cpdfsdk_widget.cpp
+++ b/fpdfsdk/cpdfsdk_widget.cpp
@@ -30,6 +30,7 @@
#include "fpdfsdk/fsdk_actionhandler.h"
#include "fpdfsdk/fsdk_define.h"
#include "fpdfsdk/fxedit/fxet_edit.h"
+#include "fpdfsdk/pdfwindow/cpwl_appstream.h"
#include "fpdfsdk/pdfwindow/cpwl_edit.h"
#include "fpdfsdk/pdfwindow/cpwl_utils.h"
@@ -764,26 +765,25 @@ void CPDFSDK_Widget::ResetAppearance(const CFX_WideString* sValue,
if (bValueChanged)
m_nValueAge++;
- int nFieldType = GetFieldType();
-
- switch (nFieldType) {
+ CPWL_AppStream appStream(this, GetAPDict());
+ switch (GetFieldType()) {
case FIELDTYPE_PUSHBUTTON:
- ResetAppearance_PushButton();
+ appStream.SetAsPushButton();
break;
case FIELDTYPE_CHECKBOX:
- ResetAppearance_CheckBox();
+ appStream.SetAsCheckBox();
break;
case FIELDTYPE_RADIOBUTTON:
- ResetAppearance_RadioButton();
+ appStream.SetAsRadioButton();
break;
case FIELDTYPE_COMBOBOX:
- ResetAppearance_ComboBox(sValue);
+ appStream.SetAsComboBox(sValue);
break;
case FIELDTYPE_LISTBOX:
- ResetAppearance_ListBox();
+ appStream.SetAsListBox();
break;
case FIELDTYPE_TEXTFIELD:
- ResetAppearance_TextField(sValue);
+ appStream.SetAsTextField(sValue);
break;
}
@@ -861,777 +861,6 @@ void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice,
m_pInterForm->GetHighlightColor(nFieldType)));
}
-void CPDFSDK_Widget::ResetAppearance_PushButton() {
- CPDF_FormControl* pControl = GetFormControl();
- CFX_FloatRect rcWindow = GetRotatedRect();
- int32_t nLayout = 0;
- switch (pControl->GetTextPosition()) {
- case TEXTPOS_ICON:
- nLayout = PPBL_ICON;
- break;
- case TEXTPOS_BELOW:
- nLayout = PPBL_ICONTOPLABELBOTTOM;
- break;
- case TEXTPOS_ABOVE:
- nLayout = PPBL_LABELTOPICONBOTTOM;
- break;
- case TEXTPOS_RIGHT:
- nLayout = PPBL_ICONLEFTLABELRIGHT;
- break;
- case TEXTPOS_LEFT:
- nLayout = PPBL_LABELLEFTICONRIGHT;
- break;
- case TEXTPOS_OVERLAID:
- nLayout = PPBL_LABELOVERICON;
- break;
- default:
- nLayout = PPBL_LABEL;
- break;
- }
-
- CFX_Color crBackground;
- CFX_Color crBorder;
- int iColorType;
- float fc[4];
- pControl->GetOriginalBackgroundColor(iColorType, fc);
- if (iColorType > 0)
- crBackground = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
- pControl->GetOriginalBorderColor(iColorType, fc);
- if (iColorType > 0)
- crBorder = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
- float fBorderWidth = (float)GetBorderWidth();
- CPWL_Dash dsBorder(3, 0, 0);
- CFX_Color crLeftTop;
- CFX_Color crRightBottom;
-
- BorderStyle nBorderStyle = GetBorderStyle();
- switch (nBorderStyle) {
- case BorderStyle::DASH:
- dsBorder = CPWL_Dash(3, 3, 0);
- break;
- case BorderStyle::BEVELED:
- fBorderWidth *= 2;
- crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
- crRightBottom = crBackground / 2.0f;
- break;
- case BorderStyle::INSET:
- fBorderWidth *= 2;
- crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
- crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
- break;
- default:
- break;
- }
-
- CFX_FloatRect rcClient = rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
- CFX_Color crText(COLORTYPE_GRAY, 0);
-
- CFX_ByteString csNameTag;
- CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
- if (da.HasColor()) {
- da.GetColor(iColorType, fc);
- crText = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
- }
- float fFontSize = 12.0f;
- if (da.HasFont())
- csNameTag = da.GetFont(&fFontSize);
-
- CFX_WideString csWCaption;
- CFX_WideString csNormalCaption;
- CFX_WideString csRolloverCaption;
- CFX_WideString csDownCaption;
- if (pControl->HasMKEntry("CA"))
- csNormalCaption = pControl->GetNormalCaption();
-
- if (pControl->HasMKEntry("RC"))
- csRolloverCaption = pControl->GetRolloverCaption();
-
- if (pControl->HasMKEntry("AC"))
- csDownCaption = pControl->GetDownCaption();
-
- CPDF_Stream* pNormalIcon = nullptr;
- CPDF_Stream* pRolloverIcon = nullptr;
- CPDF_Stream* pDownIcon = nullptr;
- if (pControl->HasMKEntry("I"))
- pNormalIcon = pControl->GetNormalIcon();
-
- if (pControl->HasMKEntry("RI"))
- pRolloverIcon = pControl->GetRolloverIcon();
-
- if (pControl->HasMKEntry("IX"))
- pDownIcon = pControl->GetDownIcon();
-
- if (pNormalIcon) {
- if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) {
- if (pImageDict->GetStringFor("Name").IsEmpty())
- pImageDict->SetNewFor<CPDF_String>("Name", "ImgA", false);
- }
- }
-
- if (pRolloverIcon) {
- if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) {
- if (pImageDict->GetStringFor("Name").IsEmpty())
- pImageDict->SetNewFor<CPDF_String>("Name", "ImgB", false);
- }
- }
-
- if (pDownIcon) {
- if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict()) {
- if (pImageDict->GetStringFor("Name").IsEmpty())
- pImageDict->SetNewFor<CPDF_String>("Name", "ImgC", false);
- }
- }
-
- CPDF_IconFit iconFit = pControl->GetIconFit();
-
- CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
- font_map.SetAPType("N");
-
- CFX_ByteString csAP =
- CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
- CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
- crLeftTop, crRightBottom, nBorderStyle,
- dsBorder) +
- CPWL_Utils::GetPushButtonAppStream(
- iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
- pNormalIcon, iconFit, csNormalCaption, crText, fFontSize, nLayout);
-
- WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP);
- if (pNormalIcon)
- AddImageToAppearance("N", pNormalIcon);
-
- CPDF_FormControl::HighlightingMode eHLM = pControl->GetHighlightingMode();
- if (eHLM == CPDF_FormControl::Push || eHLM == CPDF_FormControl::Toggle) {
- if (csRolloverCaption.IsEmpty() && !pRolloverIcon) {
- csRolloverCaption = csNormalCaption;
- pRolloverIcon = pNormalIcon;
- }
-
- font_map.SetAPType("R");
-
- csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
- CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
- crLeftTop, crRightBottom,
- nBorderStyle, dsBorder) +
- CPWL_Utils::GetPushButtonAppStream(
- iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
- pRolloverIcon, iconFit, csRolloverCaption, crText, fFontSize,
- nLayout);
-
- WriteAppearance("R", GetRotatedRect(), GetMatrix(), csAP);
- if (pRolloverIcon)
- AddImageToAppearance("R", pRolloverIcon);
-
- if (csDownCaption.IsEmpty() && !pDownIcon) {
- csDownCaption = csNormalCaption;
- pDownIcon = pNormalIcon;
- }
-
- switch (nBorderStyle) {
- case BorderStyle::BEVELED: {
- CFX_Color crTemp = crLeftTop;
- crLeftTop = crRightBottom;
- crRightBottom = crTemp;
- break;
- }
- case BorderStyle::INSET: {
- crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
- crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
- break;
- }
- default:
- break;
- }
-
- font_map.SetAPType("D");
-
- csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) +
- CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
- crLeftTop, crRightBottom,
- nBorderStyle, dsBorder) +
- CPWL_Utils::GetPushButtonAppStream(
- iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
- pDownIcon, iconFit, csDownCaption, crText, fFontSize, nLayout);
-
- WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP);
- if (pDownIcon)
- AddImageToAppearance("D", pDownIcon);
- } else {
- RemoveAppearance("D");
- RemoveAppearance("R");
- }
-}
-
-void CPDFSDK_Widget::ResetAppearance_CheckBox() {
- CPDF_FormControl* pControl = GetFormControl();
- CFX_Color crBackground, crBorder, crText;
- int iColorType;
- float fc[4];
-
- pControl->GetOriginalBackgroundColor(iColorType, fc);
- if (iColorType > 0)
- crBackground = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
- pControl->GetOriginalBorderColor(iColorType, fc);
- if (iColorType > 0)
- crBorder = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
- float fBorderWidth = (float)GetBorderWidth();
- CPWL_Dash dsBorder(3, 0, 0);
- CFX_Color crLeftTop, crRightBottom;
-
- BorderStyle nBorderStyle = GetBorderStyle();
- switch (nBorderStyle) {
- case BorderStyle::DASH:
- dsBorder = CPWL_Dash(3, 3, 0);
- break;
- case BorderStyle::BEVELED:
- fBorderWidth *= 2;
- crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
- crRightBottom = crBackground / 2.0f;
- break;
- case BorderStyle::INSET:
- fBorderWidth *= 2;
- crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
- crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
- break;
- default:
- break;
- }
-
- CFX_FloatRect rcWindow = GetRotatedRect();
- CFX_FloatRect rcClient = rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
- CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
- if (da.HasColor()) {
- da.GetColor(iColorType, fc);
- crText = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
- }
-
- int32_t nStyle = 0;
- CFX_WideString csWCaption = pControl->GetNormalCaption();
- if (csWCaption.GetLength() > 0) {
- switch (csWCaption[0]) {
- case L'l':
- nStyle = PCS_CIRCLE;
- break;
- case L'8':
- nStyle = PCS_CROSS;
- break;
- case L'u':
- nStyle = PCS_DIAMOND;
- break;
- case L'n':
- nStyle = PCS_SQUARE;
- break;
- case L'H':
- nStyle = PCS_STAR;
- break;
- default: // L'4'
- nStyle = PCS_CHECK;
- break;
- }
- } else {
- nStyle = PCS_CHECK;
- }
-
- CFX_ByteString csAP_N_ON =
- CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
- CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
- crLeftTop, crRightBottom, nBorderStyle,
- dsBorder);
-
- CFX_ByteString csAP_N_OFF = csAP_N_ON;
-
- switch (nBorderStyle) {
- case BorderStyle::BEVELED: {
- CFX_Color crTemp = crLeftTop;
- crLeftTop = crRightBottom;
- crRightBottom = crTemp;
- break;
- }
- case BorderStyle::INSET: {
- crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
- crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
- break;
- }
- default:
- break;
- }
-
- CFX_ByteString csAP_D_ON =
- CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) +
- CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
- crLeftTop, crRightBottom, nBorderStyle,
- dsBorder);
-
- CFX_ByteString csAP_D_OFF = csAP_D_ON;
-
- csAP_N_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
- csAP_D_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
-
- WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
- pControl->GetCheckedAPState());
- WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
-
- WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
- pControl->GetCheckedAPState());
- WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
-
- CFX_ByteString csAS = GetAppState();
- if (csAS.IsEmpty())
- SetAppState("Off");
-}
-
-void CPDFSDK_Widget::ResetAppearance_RadioButton() {
- CPDF_FormControl* pControl = GetFormControl();
- CFX_Color crBackground, crBorder, crText;
- int iColorType;
- float fc[4];
-
- pControl->GetOriginalBackgroundColor(iColorType, fc);
- if (iColorType > 0)
- crBackground = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
- pControl->GetOriginalBorderColor(iColorType, fc);
- if (iColorType > 0)
- crBorder = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
- float fBorderWidth = (float)GetBorderWidth();
- CPWL_Dash dsBorder(3, 0, 0);
- CFX_Color crLeftTop;
- CFX_Color crRightBottom;
- BorderStyle nBorderStyle = GetBorderStyle();
- switch (nBorderStyle) {
- case BorderStyle::DASH:
- dsBorder = CPWL_Dash(3, 3, 0);
- break;
- case BorderStyle::BEVELED:
- fBorderWidth *= 2;
- crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
- crRightBottom = crBackground / 2.0f;
- break;
- case BorderStyle::INSET:
- fBorderWidth *= 2;
- crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
- crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
- break;
- default:
- break;
- }
-
- CFX_FloatRect rcWindow = GetRotatedRect();
- CFX_FloatRect rcClient = rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
- CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
- if (da.HasColor()) {
- da.GetColor(iColorType, fc);
- crText = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
- }
-
- int32_t nStyle = 0;
- CFX_WideString csWCaption = pControl->GetNormalCaption();
- if (csWCaption.GetLength() > 0) {
- switch (csWCaption[0]) {
- default: // L'l':
- nStyle = PCS_CIRCLE;
- break;
- case L'8':
- nStyle = PCS_CROSS;
- break;
- case L'u':
- nStyle = PCS_DIAMOND;
- break;
- case L'n':
- nStyle = PCS_SQUARE;
- break;
- case L'H':
- nStyle = PCS_STAR;
- break;
- case L'4':
- nStyle = PCS_CHECK;
- break;
- }
- } else {
- nStyle = PCS_CIRCLE;
- }
-
- CFX_ByteString csAP_N_ON;
- CFX_FloatRect rcCenter = rcWindow.GetCenterSquare().GetDeflated(1.0f, 1.0f);
- if (nStyle == PCS_CIRCLE) {
- if (nBorderStyle == BorderStyle::BEVELED) {
- crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
- crRightBottom = crBackground - 0.25f;
- } else if (nBorderStyle == BorderStyle::INSET) {
- crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5f);
- crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75f);
- }
-
- csAP_N_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBackground) +
- CPWL_Utils::GetCircleBorderAppStream(
- rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
- nBorderStyle, dsBorder);
- } else {
- csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
- CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
- crLeftTop, crRightBottom,
- nBorderStyle, dsBorder);
- }
-
- CFX_ByteString csAP_N_OFF = csAP_N_ON;
-
- switch (nBorderStyle) {
- case BorderStyle::BEVELED: {
- CFX_Color crTemp = crLeftTop;
- crLeftTop = crRightBottom;
- crRightBottom = crTemp;
- break;
- }
- case BorderStyle::INSET: {
- crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
- crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
- break;
- }
- default:
- break;
- }
-
- CFX_ByteString csAP_D_ON;
-
- if (nStyle == PCS_CIRCLE) {
- CFX_Color crBK = crBackground - 0.25f;
- if (nBorderStyle == BorderStyle::BEVELED) {
- crLeftTop = crBackground - 0.25f;
- crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
- crBK = crBackground;
- } else if (nBorderStyle == BorderStyle::INSET) {
- crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
- crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
- }
-
- csAP_D_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBK) +
- CPWL_Utils::GetCircleBorderAppStream(
- rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
- nBorderStyle, dsBorder);
- } else {
- csAP_D_ON =
- CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) +
- CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
- crLeftTop, crRightBottom, nBorderStyle,
- dsBorder);
- }
-
- CFX_ByteString csAP_D_OFF = csAP_D_ON;
-
- csAP_N_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
- csAP_D_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
-
- WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
- pControl->GetCheckedAPState());
- WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
-
- WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
- pControl->GetCheckedAPState());
- WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
-
- CFX_ByteString csAS = GetAppState();
- if (csAS.IsEmpty())
- SetAppState("Off");
-}
-
-void CPDFSDK_Widget::ResetAppearance_ComboBox(const CFX_WideString* sValue) {
- CPDF_FormControl* pControl = GetFormControl();
- CPDF_FormField* pField = pControl->GetField();
- std::ostringstream sBody;
-
- CFX_FloatRect rcClient = GetClientRect();
- CFX_FloatRect rcButton = rcClient;
- rcButton.left = rcButton.right - 13;
- rcButton.Normalize();
-
- auto pEdit = pdfium::MakeUnique<CFX_Edit>();
- pEdit->EnableRefresh(false);
-
- CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
- pEdit->SetFontMap(&font_map);
-
- CFX_FloatRect rcEdit = rcClient;
- rcEdit.right = rcButton.left;
- rcEdit.Normalize();
-
- pEdit->SetPlateRect(rcEdit);
- pEdit->SetAlignmentV(1, true);
-
- float fFontSize = GetFontSize();
- if (IsFloatZero(fFontSize))
- pEdit->SetAutoFontSize(true, true);
- else
- pEdit->SetFontSize(fFontSize);
-
- pEdit->Initialize();
-
- if (sValue) {
- pEdit->SetText(*sValue);
- } else {
- int32_t nCurSel = pField->GetSelectedIndex(0);
- if (nCurSel < 0)
- pEdit->SetText(pField->GetValue());
- else
- pEdit->SetText(pField->GetOptionLabel(nCurSel));
- }
-
- CFX_FloatRect rcContent = pEdit->GetContentRect();
-
- CFX_ByteString sEdit =
- CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF());
- if (sEdit.GetLength() > 0) {
- sBody << "/Tx BMC\n"
- << "q\n";
- if (rcContent.Width() > rcEdit.Width() ||
- rcContent.Height() > rcEdit.Height()) {
- sBody << rcEdit.left << " " << rcEdit.bottom << " " << rcEdit.Width()
- << " " << rcEdit.Height() << " re\nW\nn\n";
- }
-
- CFX_Color crText = GetTextPWLColor();
- sBody << "BT\n"
- << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"
- << "Q\nEMC\n";
- }
-
- sBody << CPWL_Utils::GetDropButtonAppStream(rcButton);
-
- CFX_ByteString sAP =
- GetBackgroundAppStream() + GetBorderAppStream() + CFX_ByteString(sBody);
-
- WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
-}
-
-void CPDFSDK_Widget::ResetAppearance_ListBox() {
- CPDF_FormControl* pControl = GetFormControl();
- CPDF_FormField* pField = pControl->GetField();
- CFX_FloatRect rcClient = GetClientRect();
- std::ostringstream sBody;
-
- auto pEdit = pdfium::MakeUnique<CFX_Edit>();
- pEdit->EnableRefresh(false);
-
- CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
- pEdit->SetFontMap(&font_map);
-
- pEdit->SetPlateRect(CFX_FloatRect(rcClient.left, 0.0f, rcClient.right, 0.0f));
-
- float fFontSize = GetFontSize();
-
- pEdit->SetFontSize(IsFloatZero(fFontSize) ? 12.0f : fFontSize);
-
- pEdit->Initialize();
-
- std::ostringstream sList;
- float fy = rcClient.top;
-
- int32_t nTop = pField->GetTopVisibleIndex();
- int32_t nCount = pField->CountOptions();
- int32_t nSelCount = pField->CountSelectedItems();
-
- for (int32_t i = nTop; i < nCount; ++i) {
- bool bSelected = false;
- for (int32_t j = 0; j < nSelCount; ++j) {
- if (pField->GetSelectedIndex(j) == i) {
- bSelected = true;
- break;
- }
- }
-
- pEdit->SetText(pField->GetOptionLabel(i));
-
- CFX_FloatRect rcContent = pEdit->GetContentRect();
- float fItemHeight = rcContent.Height();
-
- if (bSelected) {
- CFX_FloatRect rcItem =
- CFX_FloatRect(rcClient.left, fy - fItemHeight, rcClient.right, fy);
- sList << "q\n"
- << CPWL_Utils::GetColorAppStream(
- CFX_Color(COLORTYPE_RGB, 0, 51.0f / 255.0f, 113.0f / 255.0f),
- true)
- << rcItem.left << " " << rcItem.bottom << " " << rcItem.Width()
- << " " << rcItem.Height() << " re f\n"
- << "Q\n";
-
- sList << "BT\n"
- << CPWL_Utils::GetColorAppStream(CFX_Color(COLORTYPE_GRAY, 1), true)
- << CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy))
- << "ET\n";
- } else {
- CFX_Color crText = GetTextPWLColor();
- sList << "BT\n"
- << CPWL_Utils::GetColorAppStream(crText, true)
- << CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy))
- << "ET\n";
- }
-
- fy -= fItemHeight;
- }
-
- if (sList.tellp() > 0) {
- sBody << "/Tx BMC\n"
- << "q\n"
- << rcClient.left << " " << rcClient.bottom << " " << rcClient.Width()
- << " " << rcClient.Height() << " re\nW\nn\n";
- sBody << sList.str() << "Q\nEMC\n";
- }
-
- CFX_ByteString sAP =
- GetBackgroundAppStream() + GetBorderAppStream() + CFX_ByteString(sBody);
-
- WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
-}
-
-void CPDFSDK_Widget::ResetAppearance_TextField(const CFX_WideString* sValue) {
- CPDF_FormControl* pControl = GetFormControl();
- CPDF_FormField* pField = pControl->GetField();
- std::ostringstream sBody;
- std::ostringstream sLines;
-
- auto pEdit = pdfium::MakeUnique<CFX_Edit>();
- pEdit->EnableRefresh(false);
-
- CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
- pEdit->SetFontMap(&font_map);
-
- CFX_FloatRect rcClient = GetClientRect();
- pEdit->SetPlateRect(rcClient);
- pEdit->SetAlignmentH(pControl->GetControlAlignment(), true);
-
- uint32_t dwFieldFlags = pField->GetFieldFlags();
- bool bMultiLine = (dwFieldFlags >> 12) & 1;
-
- if (bMultiLine) {
- pEdit->SetMultiLine(true, true);
- pEdit->SetAutoReturn(true, true);
- } else {
- pEdit->SetAlignmentV(1, true);
- }
-
- uint16_t subWord = 0;
- if ((dwFieldFlags >> 13) & 1) {
- subWord = '*';
- pEdit->SetPasswordChar(subWord, true);
- }
-
- int nMaxLen = pField->GetMaxLen();
- bool bCharArray = (dwFieldFlags >> 24) & 1;
- float fFontSize = GetFontSize();
-
-#ifdef PDF_ENABLE_XFA
- CFX_WideString sValueTmp;
- if (!sValue && GetMixXFAWidget()) {
- sValueTmp = GetValue(true);
- sValue = &sValueTmp;
- }
-#endif // PDF_ENABLE_XFA
-
- if (nMaxLen > 0) {
- if (bCharArray) {
- pEdit->SetCharArray(nMaxLen);
-
- if (IsFloatZero(fFontSize)) {
- fFontSize = CPWL_Edit::GetCharArrayAutoFontSize(font_map.GetPDFFont(0),
- rcClient, nMaxLen);
- }
- } else {
- if (sValue)
- nMaxLen = sValue->GetLength();
- pEdit->SetLimitChar(nMaxLen);
- }
- }
-
- if (IsFloatZero(fFontSize))
- pEdit->SetAutoFontSize(true, true);
- else
- pEdit->SetFontSize(fFontSize);
-
- pEdit->Initialize();
- pEdit->SetText(sValue ? *sValue : pField->GetValue());
-
- CFX_FloatRect rcContent = pEdit->GetContentRect();
- CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(
- pEdit.get(), CFX_PointF(), nullptr, !bCharArray, subWord);
-
- if (sEdit.GetLength() > 0) {
- sBody << "/Tx BMC\n"
- << "q\n";
- if (rcContent.Width() > rcClient.Width() ||
- rcContent.Height() > rcClient.Height()) {
- sBody << rcClient.left << " " << rcClient.bottom << " "
- << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
- }
- CFX_Color crText = GetTextPWLColor();
- sBody << "BT\n"
- << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"
- << "Q\nEMC\n";
- }
-
- if (bCharArray) {
- switch (GetBorderStyle()) {
- case BorderStyle::SOLID: {
- CFX_ByteString sColor =
- CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false);
- if (sColor.GetLength() > 0) {
- sLines << "q\n"
- << GetBorderWidth() << " w\n"
- << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false)
- << " 2 J 0 j\n";
-
- for (int32_t i = 1; i < nMaxLen; ++i) {
- sLines << rcClient.left +
- ((rcClient.right - rcClient.left) / nMaxLen) * i
- << " " << rcClient.bottom << " m\n"
- << rcClient.left +
- ((rcClient.right - rcClient.left) / nMaxLen) * i
- << " " << rcClient.top << " l S\n";
- }
-
- sLines << "Q\n";
- }
- break;
- }
- case BorderStyle::DASH: {
- CFX_ByteString sColor =
- CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false);
- if (sColor.GetLength() > 0) {
- CPWL_Dash dsBorder = CPWL_Dash(3, 3, 0);
-
- sLines << "q\n"
- << GetBorderWidth() << " w\n"
- << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false)
- << "[" << dsBorder.nDash << " " << dsBorder.nGap << "] "
- << dsBorder.nPhase << " d\n";
-
- for (int32_t i = 1; i < nMaxLen; ++i) {
- sLines << rcClient.left +
- ((rcClient.right - rcClient.left) / nMaxLen) * i
- << " " << rcClient.bottom << " m\n"
- << rcClient.left +
- ((rcClient.right - rcClient.left) / nMaxLen) * i
- << " " << rcClient.top << " l S\n";
- }
-
- sLines << "Q\n";
- }
- break;
- }
- default:
- break;
- }
- }
-
- CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
- CFX_ByteString(sLines) + CFX_ByteString(sBody);
- WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
-}
-
CFX_FloatRect CPDFSDK_Widget::GetClientRect() const {
CFX_FloatRect rcWindow = GetRotatedRect();
float fBorderWidth = (float)GetBorderWidth();
@@ -1668,47 +897,6 @@ CFX_FloatRect CPDFSDK_Widget::GetRotatedRect() const {
return rcPDFWindow;
}
-CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const {
- CFX_Color crBackground = GetFillPWLColor();
- if (crBackground.nColorType != COLORTYPE_TRANSPARENT)
- return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground);
-
- return "";
-}
-
-CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const {
- CFX_FloatRect rcWindow = GetRotatedRect();
- CFX_Color crBorder = GetBorderPWLColor();
- CFX_Color crBackground = GetFillPWLColor();
- CFX_Color crLeftTop, crRightBottom;
-
- float fBorderWidth = (float)GetBorderWidth();
- CPWL_Dash dsBorder(3, 0, 0);
-
- BorderStyle nBorderStyle = GetBorderStyle();
- switch (nBorderStyle) {
- case BorderStyle::DASH:
- dsBorder = CPWL_Dash(3, 3, 0);
- break;
- case BorderStyle::BEVELED:
- fBorderWidth *= 2;
- crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
- crRightBottom = crBackground / 2.0f;
- break;
- case BorderStyle::INSET:
- fBorderWidth *= 2;
- crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
- crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
- break;
- default:
- break;
- }
-
- return CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
- crLeftTop, crRightBottom, nBorderStyle,
- dsBorder);
-}
-
CFX_Matrix CPDFSDK_Widget::GetMatrix() const {
CFX_Matrix mt;
CPDF_FormControl* pControl = GetFormControl();
@@ -1775,34 +963,6 @@ CFX_Color CPDFSDK_Widget::GetFillPWLColor() const {
return crFill;
}
-void CPDFSDK_Widget::AddImageToAppearance(const CFX_ByteString& sAPType,
- CPDF_Stream* pImage) {
- CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP");
- CPDF_Stream* pStream = pAPDict->GetStreamFor(sAPType);
- CPDF_Dictionary* pStreamDict = pStream->GetDict();
- CFX_ByteString sImageAlias = "IMG";
-
- if (CPDF_Dictionary* pImageDict = pImage->GetDict()) {
- sImageAlias = pImageDict->GetStringFor("Name");
- if (sImageAlias.IsEmpty())
- sImageAlias = "IMG";
- }
-
- CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
- CPDF_Dictionary* pStreamResList = pStreamDict->GetDictFor("Resources");
- if (!pStreamResList)
- pStreamResList = pStreamDict->SetNewFor<CPDF_Dictionary>("Resources");
-
- CPDF_Dictionary* pXObject =
- pStreamResList->SetNewFor<CPDF_Dictionary>("XObject");
- pXObject->SetNewFor<CPDF_Reference>(sImageAlias, pDoc, pImage->GetObjNum());
-}
-
-void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType) {
- if (CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP"))
- pAPDict->RemoveFor(sAPType);
-}
-
bool CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type,
PDFSDK_FieldAction& data,
CPDFSDK_PageView* pPageView) {
diff --git a/fpdfsdk/cpdfsdk_widget.h b/fpdfsdk/cpdfsdk_widget.h
index 8f031cf45f..954369da1d 100644
--- a/fpdfsdk/cpdfsdk_widget.h
+++ b/fpdfsdk/cpdfsdk_widget.h
@@ -139,28 +139,14 @@ class CPDFSDK_Widget : public CPDFSDK_BAAnnot {
CPDF_Annot::AppearanceMode mode,
const CPDF_RenderOptions* pOptions) override;
- private:
- void ResetAppearance_PushButton();
- void ResetAppearance_CheckBox();
- void ResetAppearance_RadioButton();
- void ResetAppearance_ComboBox(const CFX_WideString* sValue);
- void ResetAppearance_ListBox();
- void ResetAppearance_TextField(const CFX_WideString* sValue);
-
+ CFX_Matrix GetMatrix() const;
CFX_FloatRect GetClientRect() const;
CFX_FloatRect GetRotatedRect() const;
-
- CFX_ByteString GetBackgroundAppStream() const;
- CFX_ByteString GetBorderAppStream() const;
- CFX_Matrix GetMatrix() const;
-
CFX_Color GetTextPWLColor() const;
CFX_Color GetBorderPWLColor() const;
CFX_Color GetFillPWLColor() const;
- void AddImageToAppearance(const CFX_ByteString& sAPType, CPDF_Stream* pImage);
- void RemoveAppearance(const CFX_ByteString& sAPType);
-
+ private:
CFX_UnownedPtr<CPDFSDK_InterForm> const m_pInterForm;
bool m_bAppModified;
int32_t m_nAppAge;
diff --git a/fpdfsdk/pdfwindow/cpwl_appstream.cpp b/fpdfsdk/pdfwindow/cpwl_appstream.cpp
new file mode 100644
index 0000000000..2b158cdfd0
--- /dev/null
+++ b/fpdfsdk/pdfwindow/cpwl_appstream.cpp
@@ -0,0 +1,1558 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/pdfwindow/cpwl_appstream.h"
+
+#include <utility>
+
+#include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/formfiller/cba_fontmap.h"
+#include "fpdfsdk/fxedit/fxet_edit.h"
+#include "fpdfsdk/pdfwindow/cpwl_edit.h"
+#include "fpdfsdk/pdfwindow/cpwl_icon.h"
+#include "fpdfsdk/pdfwindow/cpwl_utils.h"
+#include "fpdfsdk/pdfwindow/cpwl_wnd.h"
+
+namespace {
+
+CFX_ByteString GetAP_Check(const CFX_FloatRect& crBBox) {
+ const float fWidth = crBBox.right - crBBox.left;
+ const float fHeight = crBBox.top - crBBox.bottom;
+
+ CFX_PointF pts[8][3] = {{CFX_PointF(0.28f, 0.52f), CFX_PointF(0.27f, 0.48f),
+ CFX_PointF(0.29f, 0.40f)},
+ {CFX_PointF(0.30f, 0.33f), CFX_PointF(0.31f, 0.29f),
+ CFX_PointF(0.31f, 0.28f)},
+ {CFX_PointF(0.39f, 0.28f), CFX_PointF(0.49f, 0.29f),
+ CFX_PointF(0.77f, 0.67f)},
+ {CFX_PointF(0.76f, 0.68f), CFX_PointF(0.78f, 0.69f),
+ CFX_PointF(0.76f, 0.75f)},
+ {CFX_PointF(0.76f, 0.75f), CFX_PointF(0.73f, 0.80f),
+ CFX_PointF(0.68f, 0.75f)},
+ {CFX_PointF(0.68f, 0.74f), CFX_PointF(0.68f, 0.74f),
+ CFX_PointF(0.44f, 0.47f)},
+ {CFX_PointF(0.43f, 0.47f), CFX_PointF(0.40f, 0.47f),
+ CFX_PointF(0.41f, 0.58f)},
+ {CFX_PointF(0.40f, 0.60f), CFX_PointF(0.28f, 0.66f),
+ CFX_PointF(0.30f, 0.56f)}};
+
+ for (size_t i = 0; i < FX_ArraySize(pts); ++i) {
+ for (size_t j = 0; j < FX_ArraySize(pts[0]); ++j) {
+ pts[i][j].x = pts[i][j].x * fWidth + crBBox.left;
+ pts[i][j].y *= pts[i][j].y * fHeight + crBBox.bottom;
+ }
+ }
+
+ std::ostringstream csAP;
+ csAP << pts[0][0].x << " " << pts[0][0].y << " m\n";
+
+ for (size_t i = 0; i < FX_ArraySize(pts); ++i) {
+ size_t nNext = i < FX_ArraySize(pts) - 1 ? i + 1 : 0;
+
+ float px1 = pts[i][1].x - pts[i][0].x;
+ float py1 = pts[i][1].y - pts[i][0].y;
+ float px2 = pts[i][2].x - pts[nNext][0].x;
+ float py2 = pts[i][2].y - pts[nNext][0].y;
+
+ csAP << pts[i][0].x + px1 * FX_BEZIER << " "
+ << pts[i][0].y + py1 * FX_BEZIER << " "
+ << pts[nNext][0].x + px2 * FX_BEZIER << " "
+ << pts[nNext][0].y + py2 * FX_BEZIER << " " << pts[nNext][0].x << " "
+ << pts[nNext][0].y << " c\n";
+ }
+
+ return CFX_ByteString(csAP);
+}
+
+CFX_ByteString GetAP_Circle(const CFX_FloatRect& crBBox) {
+ std::ostringstream csAP;
+
+ float fWidth = crBBox.right - crBBox.left;
+ float fHeight = crBBox.top - crBBox.bottom;
+
+ CFX_PointF pt1(crBBox.left, crBBox.bottom + fHeight / 2);
+ CFX_PointF pt2(crBBox.left + fWidth / 2, crBBox.top);
+ CFX_PointF pt3(crBBox.right, crBBox.bottom + fHeight / 2);
+ CFX_PointF pt4(crBBox.left + fWidth / 2, crBBox.bottom);
+
+ csAP << pt1.x << " " << pt1.y << " m\n";
+
+ float px = pt2.x - pt1.x;
+ float py = pt2.y - pt1.y;
+
+ csAP << pt1.x << " " << pt1.y + py * FX_BEZIER << " "
+ << pt2.x - px * FX_BEZIER << " " << pt2.y << " " << pt2.x << " " << pt2.y
+ << " c\n";
+
+ px = pt3.x - pt2.x;
+ py = pt2.y - pt3.y;
+
+ csAP << pt2.x + px * FX_BEZIER << " " << pt2.y << " " << pt3.x << " "
+ << pt3.y + py * FX_BEZIER << " " << pt3.x << " " << pt3.y << " c\n";
+
+ px = pt3.x - pt4.x;
+ py = pt3.y - pt4.y;
+
+ csAP << pt3.x << " " << pt3.y - py * FX_BEZIER << " "
+ << pt4.x + px * FX_BEZIER << " " << pt4.y << " " << pt4.x << " " << pt4.y
+ << " c\n";
+
+ px = pt4.x - pt1.x;
+ py = pt1.y - pt4.y;
+
+ csAP << pt4.x - px * FX_BEZIER << " " << pt4.y << " " << pt1.x << " "
+ << pt1.y - py * FX_BEZIER << " " << pt1.x << " " << pt1.y << " c\n";
+
+ return CFX_ByteString(csAP);
+}
+
+CFX_ByteString GetAP_Cross(const CFX_FloatRect& crBBox) {
+ std::ostringstream csAP;
+
+ csAP << crBBox.left << " " << crBBox.top << " m\n";
+ csAP << crBBox.right << " " << crBBox.bottom << " l\n";
+ csAP << crBBox.left << " " << crBBox.bottom << " m\n";
+ csAP << crBBox.right << " " << crBBox.top << " l\n";
+
+ return CFX_ByteString(csAP);
+}
+
+CFX_ByteString GetAP_Diamond(const CFX_FloatRect& crBBox) {
+ std::ostringstream csAP;
+
+ float fWidth = crBBox.right - crBBox.left;
+ float fHeight = crBBox.top - crBBox.bottom;
+
+ CFX_PointF pt1(crBBox.left, crBBox.bottom + fHeight / 2);
+ CFX_PointF pt2(crBBox.left + fWidth / 2, crBBox.top);
+ CFX_PointF pt3(crBBox.right, crBBox.bottom + fHeight / 2);
+ CFX_PointF pt4(crBBox.left + fWidth / 2, crBBox.bottom);
+
+ csAP << pt1.x << " " << pt1.y << " m\n";
+ csAP << pt2.x << " " << pt2.y << " l\n";
+ csAP << pt3.x << " " << pt3.y << " l\n";
+ csAP << pt4.x << " " << pt4.y << " l\n";
+ csAP << pt1.x << " " << pt1.y << " l\n";
+
+ return CFX_ByteString(csAP);
+}
+
+CFX_ByteString GetAP_Square(const CFX_FloatRect& crBBox) {
+ std::ostringstream csAP;
+
+ csAP << crBBox.left << " " << crBBox.top << " m\n";
+ csAP << crBBox.right << " " << crBBox.top << " l\n";
+ csAP << crBBox.right << " " << crBBox.bottom << " l\n";
+ csAP << crBBox.left << " " << crBBox.bottom << " l\n";
+ csAP << crBBox.left << " " << crBBox.top << " l\n";
+
+ return CFX_ByteString(csAP);
+}
+
+CFX_ByteString GetAP_Star(const CFX_FloatRect& crBBox) {
+ std::ostringstream csAP;
+
+ float fRadius = (crBBox.top - crBBox.bottom) / (1 + (float)cos(FX_PI / 5.0f));
+ CFX_PointF ptCenter = CFX_PointF((crBBox.left + crBBox.right) / 2.0f,
+ (crBBox.top + crBBox.bottom) / 2.0f);
+
+ float px[5];
+ float py[5];
+ float fAngel = FX_PI / 10.0f;
+ for (int32_t i = 0; i < 5; i++) {
+ px[i] = ptCenter.x + fRadius * (float)cos(fAngel);
+ py[i] = ptCenter.y + fRadius * (float)sin(fAngel);
+ fAngel += FX_PI * 2 / 5.0f;
+ }
+
+ csAP << px[0] << " " << py[0] << " m\n";
+
+ int32_t nNext = 0;
+ for (int32_t j = 0; j < 5; j++) {
+ nNext += 2;
+ if (nNext >= 5)
+ nNext -= 5;
+ csAP << px[nNext] << " " << py[nNext] << " l\n";
+ }
+
+ return CFX_ByteString(csAP);
+}
+
+CFX_ByteString GetAP_HalfCircle(const CFX_FloatRect& crBBox, float fRotate) {
+ std::ostringstream csAP;
+
+ float fWidth = crBBox.right - crBBox.left;
+ float fHeight = crBBox.top - crBBox.bottom;
+
+ CFX_PointF pt1(-fWidth / 2, 0);
+ CFX_PointF pt2(0, fHeight / 2);
+ CFX_PointF pt3(fWidth / 2, 0);
+
+ float px;
+ float py;
+
+ csAP << cos(fRotate) << " " << sin(fRotate) << " " << -sin(fRotate) << " "
+ << cos(fRotate) << " " << crBBox.left + fWidth / 2 << " "
+ << crBBox.bottom + fHeight / 2 << " cm\n";
+
+ csAP << pt1.x << " " << pt1.y << " m\n";
+
+ px = pt2.x - pt1.x;
+ py = pt2.y - pt1.y;
+
+ csAP << pt1.x << " " << pt1.y + py * FX_BEZIER << " "
+ << pt2.x - px * FX_BEZIER << " " << pt2.y << " " << pt2.x << " " << pt2.y
+ << " c\n";
+
+ px = pt3.x - pt2.x;
+ py = pt2.y - pt3.y;
+
+ csAP << pt2.x + px * FX_BEZIER << " " << pt2.y << " " << pt3.x << " "
+ << pt3.y + py * FX_BEZIER << " " << pt3.x << " " << pt3.y << " c\n";
+
+ return CFX_ByteString(csAP);
+}
+
+CFX_ByteString GetAppStream_Check(const CFX_FloatRect& rcBBox,
+ const CFX_Color& crText) {
+ std::ostringstream sAP;
+ sAP << "q\n"
+ << CPWL_Utils::GetColorAppStream(crText, true) << GetAP_Check(rcBBox)
+ << "f\nQ\n";
+ return CFX_ByteString(sAP);
+}
+
+CFX_ByteString GetAppStream_Circle(const CFX_FloatRect& rcBBox,
+ const CFX_Color& crText) {
+ std::ostringstream sAP;
+ sAP << "q\n"
+ << CPWL_Utils::GetColorAppStream(crText, true) << GetAP_Circle(rcBBox)
+ << "f\nQ\n";
+ return CFX_ByteString(sAP);
+}
+
+CFX_ByteString GetAppStream_Cross(const CFX_FloatRect& rcBBox,
+ const CFX_Color& crText) {
+ std::ostringstream sAP;
+ sAP << "q\n"
+ << CPWL_Utils::GetColorAppStream(crText, false) << GetAP_Cross(rcBBox)
+ << "S\nQ\n";
+ return CFX_ByteString(sAP);
+}
+
+CFX_ByteString GetAppStream_Diamond(const CFX_FloatRect& rcBBox,
+ const CFX_Color& crText) {
+ std::ostringstream sAP;
+ sAP << "q\n1 w\n"
+ << CPWL_Utils::GetColorAppStream(crText, true) << GetAP_Diamond(rcBBox)
+ << "f\nQ\n";
+ return CFX_ByteString(sAP);
+}
+
+CFX_ByteString GetAppStream_Square(const CFX_FloatRect& rcBBox,
+ const CFX_Color& crText) {
+ std::ostringstream sAP;
+ sAP << "q\n"
+ << CPWL_Utils::GetColorAppStream(crText, true) << GetAP_Square(rcBBox)
+ << "f\nQ\n";
+ return CFX_ByteString(sAP);
+}
+
+CFX_ByteString GetAppStream_Star(const CFX_FloatRect& rcBBox,
+ const CFX_Color& crText) {
+ std::ostringstream sAP;
+ sAP << "q\n"
+ << CPWL_Utils::GetColorAppStream(crText, true) << GetAP_Star(rcBBox)
+ << "f\nQ\n";
+ return CFX_ByteString(sAP);
+}
+
+CFX_ByteString GetCircleFillAppStream(const CFX_FloatRect& rect,
+ const CFX_Color& color) {
+ std::ostringstream sAppStream;
+ CFX_ByteString sColor = CPWL_Utils::GetColorAppStream(color, true);
+ if (sColor.GetLength() > 0)
+ sAppStream << "q\n" << sColor << GetAP_Circle(rect) << "f\nQ\n";
+ return CFX_ByteString(sAppStream);
+}
+
+CFX_ByteString GetCircleBorderAppStream(const CFX_FloatRect& rect,
+ float fWidth,
+ const CFX_Color& color,
+ const CFX_Color& crLeftTop,
+ const CFX_Color& crRightBottom,
+ BorderStyle nStyle,
+ const CPWL_Dash& dash) {
+ std::ostringstream sAppStream;
+ CFX_ByteString sColor;
+
+ if (fWidth > 0.0f) {
+ sAppStream << "q\n";
+
+ float fHalfWidth = fWidth / 2.0f;
+ CFX_FloatRect rect_by_2 = rect.GetDeflated(fHalfWidth, fHalfWidth);
+
+ float div = fHalfWidth * 0.75f;
+ CFX_FloatRect rect_by_75 = rect.GetDeflated(div, div);
+ switch (nStyle) {
+ default:
+ case BorderStyle::SOLID:
+ case BorderStyle::UNDERLINE: {
+ sColor = CPWL_Utils::GetColorAppStream(color, false);
+ if (sColor.GetLength() > 0) {
+ sAppStream << "q\n"
+ << fWidth << " w\n"
+ << sColor << GetAP_Circle(rect_by_2) << " S\nQ\n";
+ }
+ } break;
+ case BorderStyle::DASH: {
+ sColor = CPWL_Utils::GetColorAppStream(color, false);
+ if (sColor.GetLength() > 0) {
+ sAppStream << "q\n"
+ << fWidth << " w\n"
+ << "[" << dash.nDash << " " << dash.nGap << "] "
+ << dash.nPhase << " d\n"
+ << sColor << GetAP_Circle(rect_by_2) << " S\nQ\n";
+ }
+ } break;
+ case BorderStyle::BEVELED: {
+ sColor = CPWL_Utils::GetColorAppStream(color, false);
+ if (sColor.GetLength() > 0) {
+ sAppStream << "q\n"
+ << fHalfWidth << " w\n"
+ << sColor << GetAP_Circle(rect) << " S\nQ\n";
+ }
+
+ sColor = CPWL_Utils::GetColorAppStream(crLeftTop, false);
+ if (sColor.GetLength() > 0) {
+ sAppStream << "q\n"
+ << fHalfWidth << " w\n"
+ << sColor << GetAP_HalfCircle(rect_by_75, FX_PI / 4.0f)
+ << " S\nQ\n";
+ }
+
+ sColor = CPWL_Utils::GetColorAppStream(crRightBottom, false);
+ if (sColor.GetLength() > 0) {
+ sAppStream << "q\n"
+ << fHalfWidth << " w\n"
+ << sColor << GetAP_HalfCircle(rect_by_75, FX_PI * 5 / 4.0f)
+ << " S\nQ\n";
+ }
+ } break;
+ case BorderStyle::INSET: {
+ sColor = CPWL_Utils::GetColorAppStream(color, false);
+ if (sColor.GetLength() > 0) {
+ sAppStream << "q\n"
+ << fHalfWidth << " w\n"
+ << sColor << GetAP_Circle(rect) << " S\nQ\n";
+ }
+
+ sColor = CPWL_Utils::GetColorAppStream(crLeftTop, false);
+ if (sColor.GetLength() > 0) {
+ sAppStream << "q\n"
+ << fHalfWidth << " w\n"
+ << sColor << GetAP_HalfCircle(rect_by_75, FX_PI / 4.0f)
+ << " S\nQ\n";
+ }
+
+ sColor = CPWL_Utils::GetColorAppStream(crRightBottom, false);
+ if (sColor.GetLength() > 0) {
+ sAppStream << "q\n"
+ << fHalfWidth << " w\n"
+ << sColor << GetAP_HalfCircle(rect_by_75, FX_PI * 5 / 4.0f)
+ << " S\nQ\n";
+ }
+ } break;
+ }
+
+ sAppStream << "Q\n";
+ }
+ return CFX_ByteString(sAppStream);
+}
+
+CFX_ByteString GetCheckBoxAppStream(const CFX_FloatRect& rcBBox,
+ int32_t nStyle,
+ const CFX_Color& crText) {
+ CFX_FloatRect rcCenter = rcBBox.GetCenterSquare();
+ switch (nStyle) {
+ default:
+ case PCS_CHECK:
+ return GetAppStream_Check(rcCenter, crText);
+ case PCS_CIRCLE:
+ rcCenter.Scale(2.0f / 3.0f);
+ return GetAppStream_Circle(rcCenter, crText);
+ case PCS_CROSS:
+ return GetAppStream_Cross(rcCenter, crText);
+ case PCS_DIAMOND:
+ rcCenter.Scale(2.0f / 3.0f);
+ return GetAppStream_Diamond(rcCenter, crText);
+ case PCS_SQUARE:
+ rcCenter.Scale(2.0f / 3.0f);
+ return GetAppStream_Square(rcCenter, crText);
+ case PCS_STAR:
+ rcCenter.Scale(2.0f / 3.0f);
+ return GetAppStream_Star(rcCenter, crText);
+ }
+}
+
+CFX_ByteString GetRadioButtonAppStream(const CFX_FloatRect& rcBBox,
+ int32_t nStyle,
+ const CFX_Color& crText) {
+ CFX_FloatRect rcCenter = rcBBox.GetCenterSquare();
+ switch (nStyle) {
+ default:
+ case PCS_CHECK:
+ return GetAppStream_Check(rcCenter, crText);
+ case PCS_CIRCLE:
+ rcCenter.Scale(1.0f / 2.0f);
+ return GetAppStream_Circle(rcCenter, crText);
+ case PCS_CROSS:
+ return GetAppStream_Cross(rcCenter, crText);
+ case PCS_DIAMOND:
+ rcCenter.Scale(2.0f / 3.0f);
+ return GetAppStream_Diamond(rcCenter, crText);
+ case PCS_SQUARE:
+ rcCenter.Scale(2.0f / 3.0f);
+ return GetAppStream_Square(rcCenter, crText);
+ case PCS_STAR:
+ rcCenter.Scale(2.0f / 3.0f);
+ return GetAppStream_Star(rcCenter, crText);
+ }
+}
+
+CFX_ByteString GetPushButtonAppStream(const CFX_FloatRect& rcBBox,
+ IPVT_FontMap* pFontMap,
+ CPDF_Stream* pIconStream,
+ CPDF_IconFit& IconFit,
+ const CFX_WideString& sLabel,
+ const CFX_Color& crText,
+ float fFontSize,
+ int32_t nLayOut) {
+ const float fAutoFontScale = 1.0f / 3.0f;
+
+ auto pEdit = pdfium::MakeUnique<CFX_Edit>();
+ pEdit->SetFontMap(pFontMap);
+ pEdit->SetAlignmentH(1, true);
+ pEdit->SetAlignmentV(1, true);
+ pEdit->SetMultiLine(false, true);
+ pEdit->SetAutoReturn(false, true);
+ if (IsFloatZero(fFontSize))
+ pEdit->SetAutoFontSize(true, true);
+ else
+ pEdit->SetFontSize(fFontSize);
+
+ pEdit->Initialize();
+ pEdit->SetText(sLabel);
+
+ CFX_FloatRect rcLabelContent = pEdit->GetContentRect();
+ CPWL_Icon Icon;
+ PWL_CREATEPARAM cp;
+ cp.dwFlags = PWS_VISIBLE;
+ Icon.Create(cp);
+ Icon.SetIconFit(&IconFit);
+ Icon.SetPDFStream(pIconStream);
+
+ CFX_FloatRect rcLabel;
+ CFX_FloatRect rcIcon;
+ float fWidth = 0.0f;
+ float fHeight = 0.0f;
+
+ switch (nLayOut) {
+ case PPBL_LABEL:
+ rcLabel = rcBBox;
+ break;
+ case PPBL_ICON:
+ rcIcon = rcBBox;
+ break;
+ case PPBL_ICONTOPLABELBOTTOM:
+ if (pIconStream) {
+ if (IsFloatZero(fFontSize)) {
+ fHeight = rcBBox.top - rcBBox.bottom;
+ rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
+ rcBBox.bottom + fHeight * fAutoFontScale);
+ rcIcon =
+ CFX_FloatRect(rcBBox.left, rcLabel.top, rcBBox.right, rcBBox.top);
+ } else {
+ fHeight = rcLabelContent.Height();
+
+ if (rcBBox.bottom + fHeight > rcBBox.top) {
+ rcLabel = rcBBox;
+ } else {
+ rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
+ rcBBox.bottom + fHeight);
+ rcIcon = CFX_FloatRect(rcBBox.left, rcLabel.top, rcBBox.right,
+ rcBBox.top);
+ }
+ }
+ } else {
+ rcLabel = rcBBox;
+ }
+ break;
+ case PPBL_LABELTOPICONBOTTOM:
+ if (pIconStream) {
+ if (IsFloatZero(fFontSize)) {
+ fHeight = rcBBox.top - rcBBox.bottom;
+ rcLabel =
+ CFX_FloatRect(rcBBox.left, rcBBox.top - fHeight * fAutoFontScale,
+ rcBBox.right, rcBBox.top);
+ rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
+ rcLabel.bottom);
+ } else {
+ fHeight = rcLabelContent.Height();
+
+ if (rcBBox.bottom + fHeight > rcBBox.top) {
+ rcLabel = rcBBox;
+ } else {
+ rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.top - fHeight,
+ rcBBox.right, rcBBox.top);
+ rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
+ rcLabel.bottom);
+ }
+ }
+ } else {
+ rcLabel = rcBBox;
+ }
+ break;
+ case PPBL_ICONLEFTLABELRIGHT:
+ if (pIconStream) {
+ if (IsFloatZero(fFontSize)) {
+ fWidth = rcBBox.right - rcBBox.left;
+ if (rcLabelContent.Width() < fWidth * fAutoFontScale) {
+ rcLabel = CFX_FloatRect(rcBBox.right - fWidth * fAutoFontScale,
+ rcBBox.bottom, rcBBox.right, rcBBox.top);
+ rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcLabel.left,
+ rcBBox.top);
+ } else {
+ if (rcLabelContent.Width() < fWidth) {
+ rcLabel = CFX_FloatRect(rcBBox.right - rcLabelContent.Width(),
+ rcBBox.bottom, rcBBox.right, rcBBox.top);
+ rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcLabel.left,
+ rcBBox.top);
+ } else {
+ rcLabel = rcBBox;
+ }
+ }
+ } else {
+ fWidth = rcLabelContent.Width();
+ if (rcBBox.left + fWidth > rcBBox.right) {
+ rcLabel = rcBBox;
+ } else {
+ rcLabel = CFX_FloatRect(rcBBox.right - fWidth, rcBBox.bottom,
+ rcBBox.right, rcBBox.top);
+ rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcLabel.left,
+ rcBBox.top);
+ }
+ }
+ } else {
+ rcLabel = rcBBox;
+ }
+ break;
+ case PPBL_LABELLEFTICONRIGHT:
+ if (pIconStream) {
+ if (IsFloatZero(fFontSize)) {
+ fWidth = rcBBox.right - rcBBox.left;
+ if (rcLabelContent.Width() < fWidth * fAutoFontScale) {
+ rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom,
+ rcBBox.left + fWidth * fAutoFontScale,
+ rcBBox.top);
+ rcIcon = CFX_FloatRect(rcLabel.right, rcBBox.bottom, rcBBox.right,
+ rcBBox.top);
+ } else {
+ if (rcLabelContent.Width() < fWidth) {
+ rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom,
+ rcBBox.left + rcLabelContent.Width(),
+ rcBBox.top);
+ rcIcon = CFX_FloatRect(rcLabel.right, rcBBox.bottom, rcBBox.right,
+ rcBBox.top);
+ } else {
+ rcLabel = rcBBox;
+ }
+ }
+ } else {
+ fWidth = rcLabelContent.Width();
+ if (rcBBox.left + fWidth > rcBBox.right) {
+ rcLabel = rcBBox;
+ } else {
+ rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom,
+ rcBBox.left + fWidth, rcBBox.top);
+ rcIcon = CFX_FloatRect(rcLabel.right, rcBBox.bottom, rcBBox.right,
+ rcBBox.top);
+ }
+ }
+ } else {
+ rcLabel = rcBBox;
+ }
+ break;
+ case PPBL_LABELOVERICON:
+ rcLabel = rcBBox;
+ rcIcon = rcBBox;
+ break;
+ }
+
+ std::ostringstream sTemp;
+
+ if (!rcIcon.IsEmpty()) {
+ Icon.Move(rcIcon, false, false);
+ sTemp << Icon.GetImageAppStream();
+ }
+
+ Icon.Destroy();
+
+ if (!rcLabel.IsEmpty()) {
+ pEdit->SetPlateRect(rcLabel);
+ CFX_ByteString sEdit =
+ CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, 0.0f));
+ if (sEdit.GetLength() > 0) {
+ sTemp << "BT\n"
+ << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n";
+ }
+ }
+
+ if (sTemp.tellp() <= 0)
+ return CFX_ByteString();
+
+ std::ostringstream sAppStream;
+ sAppStream << "q\n"
+ << rcBBox.left << " " << rcBBox.bottom << " "
+ << rcBBox.right - rcBBox.left << " " << rcBBox.top - rcBBox.bottom
+ << " re W n\n";
+ sAppStream << sTemp.str().c_str() << "Q\n";
+ return CFX_ByteString(sAppStream);
+}
+
+CFX_ByteString GetDropButtonAppStream(const CFX_FloatRect& rcBBox) {
+ if (rcBBox.IsEmpty())
+ return CFX_ByteString();
+
+ std::ostringstream sAppStream;
+ sAppStream << "q\n"
+ << CPWL_Utils::GetColorAppStream(
+ CFX_Color(COLORTYPE_RGB, 220.0f / 255.0f, 220.0f / 255.0f,
+ 220.0f / 255.0f),
+ true)
+ << rcBBox.left << " " << rcBBox.bottom << " "
+ << rcBBox.right - rcBBox.left << " " << rcBBox.top - rcBBox.bottom
+ << " re f\n"
+ << "Q\n";
+
+ sAppStream << "q\n"
+ << CPWL_Utils::GetBorderAppStream(
+ rcBBox, 2, CFX_Color(COLORTYPE_GRAY, 0),
+ CFX_Color(COLORTYPE_GRAY, 1),
+ CFX_Color(COLORTYPE_GRAY, 0.5), BorderStyle::BEVELED,
+ CPWL_Dash(3, 0, 0))
+ << "Q\n";
+
+ CFX_PointF ptCenter = CFX_PointF((rcBBox.left + rcBBox.right) / 2,
+ (rcBBox.top + rcBBox.bottom) / 2);
+ if (IsFloatBigger(rcBBox.right - rcBBox.left, 6) &&
+ IsFloatBigger(rcBBox.top - rcBBox.bottom, 6)) {
+ sAppStream << "q\n"
+ << " 0 g\n"
+ << ptCenter.x - 3 << " " << ptCenter.y + 1.5f << " m\n"
+ << ptCenter.x + 3 << " " << ptCenter.y + 1.5f << " l\n"
+ << ptCenter.x << " " << ptCenter.y - 1.5f << " l\n"
+ << ptCenter.x - 3 << " " << ptCenter.y + 1.5f << " l f\n"
+ << "Q\n";
+ }
+
+ return CFX_ByteString(sAppStream);
+}
+
+} // namespace
+
+CPWL_AppStream::CPWL_AppStream(CPDFSDK_Widget* widget, CPDF_Dictionary* dict)
+ : widget_(widget), dict_(dict) {}
+
+CPWL_AppStream::~CPWL_AppStream() {}
+
+void CPWL_AppStream::SetAsPushButton() {
+ CPDF_FormControl* pControl = widget_->GetFormControl();
+ CFX_FloatRect rcWindow = widget_->GetRotatedRect();
+ int32_t nLayout = 0;
+ switch (pControl->GetTextPosition()) {
+ case TEXTPOS_ICON:
+ nLayout = PPBL_ICON;
+ break;
+ case TEXTPOS_BELOW:
+ nLayout = PPBL_ICONTOPLABELBOTTOM;
+ break;
+ case TEXTPOS_ABOVE:
+ nLayout = PPBL_LABELTOPICONBOTTOM;
+ break;
+ case TEXTPOS_RIGHT:
+ nLayout = PPBL_ICONLEFTLABELRIGHT;
+ break;
+ case TEXTPOS_LEFT:
+ nLayout = PPBL_LABELLEFTICONRIGHT;
+ break;
+ case TEXTPOS_OVERLAID:
+ nLayout = PPBL_LABELOVERICON;
+ break;
+ default:
+ nLayout = PPBL_LABEL;
+ break;
+ }
+
+ CFX_Color crBackground;
+ CFX_Color crBorder;
+ int iColorType;
+ float fc[4];
+ pControl->GetOriginalBackgroundColor(iColorType, fc);
+ if (iColorType > 0)
+ crBackground = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+ pControl->GetOriginalBorderColor(iColorType, fc);
+ if (iColorType > 0)
+ crBorder = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+ float fBorderWidth = static_cast<float>(widget_->GetBorderWidth());
+ CPWL_Dash dsBorder(3, 0, 0);
+ CFX_Color crLeftTop;
+ CFX_Color crRightBottom;
+
+ BorderStyle nBorderStyle = widget_->GetBorderStyle();
+ switch (nBorderStyle) {
+ case BorderStyle::DASH:
+ dsBorder = CPWL_Dash(3, 3, 0);
+ break;
+ case BorderStyle::BEVELED:
+ fBorderWidth *= 2;
+ crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
+ crRightBottom = crBackground / 2.0f;
+ break;
+ case BorderStyle::INSET:
+ fBorderWidth *= 2;
+ crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
+ crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
+ break;
+ default:
+ break;
+ }
+
+ CFX_FloatRect rcClient = rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
+ CFX_Color crText(COLORTYPE_GRAY, 0);
+ CFX_ByteString csNameTag;
+ CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
+ if (da.HasColor()) {
+ da.GetColor(iColorType, fc);
+ crText = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+ }
+ float fFontSize = 12.0f;
+ if (da.HasFont())
+ csNameTag = da.GetFont(&fFontSize);
+
+ CFX_WideString csWCaption;
+ CFX_WideString csNormalCaption;
+ CFX_WideString csRolloverCaption;
+ CFX_WideString csDownCaption;
+ if (pControl->HasMKEntry("CA"))
+ csNormalCaption = pControl->GetNormalCaption();
+
+ if (pControl->HasMKEntry("RC"))
+ csRolloverCaption = pControl->GetRolloverCaption();
+
+ if (pControl->HasMKEntry("AC"))
+ csDownCaption = pControl->GetDownCaption();
+
+ CPDF_Stream* pNormalIcon = nullptr;
+ CPDF_Stream* pRolloverIcon = nullptr;
+ CPDF_Stream* pDownIcon = nullptr;
+ if (pControl->HasMKEntry("I"))
+ pNormalIcon = pControl->GetNormalIcon();
+
+ if (pControl->HasMKEntry("RI"))
+ pRolloverIcon = pControl->GetRolloverIcon();
+
+ if (pControl->HasMKEntry("IX"))
+ pDownIcon = pControl->GetDownIcon();
+
+ if (pNormalIcon) {
+ if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) {
+ if (pImageDict->GetStringFor("Name").IsEmpty())
+ pImageDict->SetNewFor<CPDF_String>("Name", "ImgA", false);
+ }
+ }
+
+ if (pRolloverIcon) {
+ if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) {
+ if (pImageDict->GetStringFor("Name").IsEmpty())
+ pImageDict->SetNewFor<CPDF_String>("Name", "ImgB", false);
+ }
+ }
+
+ if (pDownIcon) {
+ if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict()) {
+ if (pImageDict->GetStringFor("Name").IsEmpty())
+ pImageDict->SetNewFor<CPDF_String>("Name", "ImgC", false);
+ }
+ }
+
+ CPDF_IconFit iconFit = pControl->GetIconFit();
+
+ CBA_FontMap font_map(
+ widget_.Get(),
+ widget_->GetInterForm()->GetFormFillEnv()->GetSysHandler());
+ font_map.SetAPType("N");
+
+ CFX_ByteString csAP =
+ CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
+ CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+ crLeftTop, crRightBottom, nBorderStyle,
+ dsBorder) +
+ GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient,
+ &font_map, pNormalIcon, iconFit, csNormalCaption,
+ crText, fFontSize, nLayout);
+
+ Write("N", csAP, "");
+ if (pNormalIcon)
+ AddImage("N", pNormalIcon);
+
+ CPDF_FormControl::HighlightingMode eHLM = pControl->GetHighlightingMode();
+ if (eHLM == CPDF_FormControl::Push || eHLM == CPDF_FormControl::Toggle) {
+ if (csRolloverCaption.IsEmpty() && !pRolloverIcon) {
+ csRolloverCaption = csNormalCaption;
+ pRolloverIcon = pNormalIcon;
+ }
+
+ font_map.SetAPType("R");
+
+ csAP =
+ CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
+ CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+ crLeftTop, crRightBottom, nBorderStyle,
+ dsBorder) +
+ GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient,
+ &font_map, pRolloverIcon, iconFit,
+ csRolloverCaption, crText, fFontSize, nLayout);
+
+ Write("R", csAP, "");
+ if (pRolloverIcon)
+ AddImage("R", pRolloverIcon);
+
+ if (csDownCaption.IsEmpty() && !pDownIcon) {
+ csDownCaption = csNormalCaption;
+ pDownIcon = pNormalIcon;
+ }
+
+ switch (nBorderStyle) {
+ case BorderStyle::BEVELED: {
+ CFX_Color crTemp = crLeftTop;
+ crLeftTop = crRightBottom;
+ crRightBottom = crTemp;
+ break;
+ }
+ case BorderStyle::INSET: {
+ crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
+ crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
+ break;
+ }
+ default:
+ break;
+ }
+
+ font_map.SetAPType("D");
+
+ csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) +
+ CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+ crLeftTop, crRightBottom,
+ nBorderStyle, dsBorder) +
+ GetPushButtonAppStream(
+ iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
+ pDownIcon, iconFit, csDownCaption, crText, fFontSize, nLayout);
+
+ Write("D", csAP, "");
+ if (pDownIcon)
+ AddImage("D", pDownIcon);
+ } else {
+ Remove("D");
+ Remove("R");
+ }
+}
+
+void CPWL_AppStream::SetAsCheckBox() {
+ CPDF_FormControl* pControl = widget_->GetFormControl();
+ CFX_Color crBackground, crBorder, crText;
+ int iColorType;
+ float fc[4];
+
+ pControl->GetOriginalBackgroundColor(iColorType, fc);
+ if (iColorType > 0)
+ crBackground = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+ pControl->GetOriginalBorderColor(iColorType, fc);
+ if (iColorType > 0)
+ crBorder = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+ float fBorderWidth = static_cast<float>(widget_->GetBorderWidth());
+ CPWL_Dash dsBorder(3, 0, 0);
+ CFX_Color crLeftTop, crRightBottom;
+
+ BorderStyle nBorderStyle = widget_->GetBorderStyle();
+ switch (nBorderStyle) {
+ case BorderStyle::DASH:
+ dsBorder = CPWL_Dash(3, 3, 0);
+ break;
+ case BorderStyle::BEVELED:
+ fBorderWidth *= 2;
+ crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
+ crRightBottom = crBackground / 2.0f;
+ break;
+ case BorderStyle::INSET:
+ fBorderWidth *= 2;
+ crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
+ crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
+ break;
+ default:
+ break;
+ }
+
+ CFX_FloatRect rcWindow = widget_->GetRotatedRect();
+ CFX_FloatRect rcClient = rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
+ CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
+ if (da.HasColor()) {
+ da.GetColor(iColorType, fc);
+ crText = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+ }
+
+ int32_t nStyle = 0;
+ CFX_WideString csWCaption = pControl->GetNormalCaption();
+ if (csWCaption.GetLength() > 0) {
+ switch (csWCaption[0]) {
+ case L'l':
+ nStyle = PCS_CIRCLE;
+ break;
+ case L'8':
+ nStyle = PCS_CROSS;
+ break;
+ case L'u':
+ nStyle = PCS_DIAMOND;
+ break;
+ case L'n':
+ nStyle = PCS_SQUARE;
+ break;
+ case L'H':
+ nStyle = PCS_STAR;
+ break;
+ default: // L'4'
+ nStyle = PCS_CHECK;
+ break;
+ }
+ } else {
+ nStyle = PCS_CHECK;
+ }
+
+ CFX_ByteString csAP_N_ON =
+ CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
+ CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+ crLeftTop, crRightBottom, nBorderStyle,
+ dsBorder);
+
+ CFX_ByteString csAP_N_OFF = csAP_N_ON;
+
+ switch (nBorderStyle) {
+ case BorderStyle::BEVELED: {
+ CFX_Color crTemp = crLeftTop;
+ crLeftTop = crRightBottom;
+ crRightBottom = crTemp;
+ break;
+ }
+ case BorderStyle::INSET: {
+ crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
+ crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
+ break;
+ }
+ default:
+ break;
+ }
+
+ CFX_ByteString csAP_D_ON =
+ CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) +
+ CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+ crLeftTop, crRightBottom, nBorderStyle,
+ dsBorder);
+
+ CFX_ByteString csAP_D_OFF = csAP_D_ON;
+
+ csAP_N_ON += GetCheckBoxAppStream(rcClient, nStyle, crText);
+ csAP_D_ON += GetCheckBoxAppStream(rcClient, nStyle, crText);
+
+ Write("N", csAP_N_ON, pControl->GetCheckedAPState());
+ Write("N", csAP_N_OFF, "Off");
+
+ Write("D", csAP_D_ON, pControl->GetCheckedAPState());
+ Write("D", csAP_D_OFF, "Off");
+
+ CFX_ByteString csAS = widget_->GetAppState();
+ if (csAS.IsEmpty())
+ widget_->SetAppState("Off");
+}
+
+void CPWL_AppStream::SetAsRadioButton() {
+ CPDF_FormControl* pControl = widget_->GetFormControl();
+ CFX_Color crBackground;
+ CFX_Color crBorder;
+ CFX_Color crText;
+ int iColorType;
+ float fc[4];
+
+ pControl->GetOriginalBackgroundColor(iColorType, fc);
+ if (iColorType > 0)
+ crBackground = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+ pControl->GetOriginalBorderColor(iColorType, fc);
+ if (iColorType > 0)
+ crBorder = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+ float fBorderWidth = static_cast<float>(widget_->GetBorderWidth());
+ CPWL_Dash dsBorder(3, 0, 0);
+ CFX_Color crLeftTop;
+ CFX_Color crRightBottom;
+ BorderStyle nBorderStyle = widget_->GetBorderStyle();
+ switch (nBorderStyle) {
+ case BorderStyle::DASH:
+ dsBorder = CPWL_Dash(3, 3, 0);
+ break;
+ case BorderStyle::BEVELED:
+ fBorderWidth *= 2;
+ crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
+ crRightBottom = crBackground / 2.0f;
+ break;
+ case BorderStyle::INSET:
+ fBorderWidth *= 2;
+ crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
+ crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
+ break;
+ default:
+ break;
+ }
+
+ CFX_FloatRect rcWindow = widget_->GetRotatedRect();
+ CFX_FloatRect rcClient = rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
+ CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
+ if (da.HasColor()) {
+ da.GetColor(iColorType, fc);
+ crText = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+ }
+
+ int32_t nStyle = 0;
+ CFX_WideString csWCaption = pControl->GetNormalCaption();
+ if (csWCaption.GetLength() > 0) {
+ switch (csWCaption[0]) {
+ default: // L'l':
+ nStyle = PCS_CIRCLE;
+ break;
+ case L'8':
+ nStyle = PCS_CROSS;
+ break;
+ case L'u':
+ nStyle = PCS_DIAMOND;
+ break;
+ case L'n':
+ nStyle = PCS_SQUARE;
+ break;
+ case L'H':
+ nStyle = PCS_STAR;
+ break;
+ case L'4':
+ nStyle = PCS_CHECK;
+ break;
+ }
+ } else {
+ nStyle = PCS_CIRCLE;
+ }
+
+ CFX_ByteString csAP_N_ON;
+ CFX_FloatRect rcCenter = rcWindow.GetCenterSquare().GetDeflated(1.0f, 1.0f);
+ if (nStyle == PCS_CIRCLE) {
+ if (nBorderStyle == BorderStyle::BEVELED) {
+ crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
+ crRightBottom = crBackground - 0.25f;
+ } else if (nBorderStyle == BorderStyle::INSET) {
+ crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5f);
+ crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75f);
+ }
+
+ csAP_N_ON =
+ GetCircleFillAppStream(rcCenter, crBackground) +
+ GetCircleBorderAppStream(rcCenter, fBorderWidth, crBorder, crLeftTop,
+ crRightBottom, nBorderStyle, dsBorder);
+ } else {
+ csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
+ CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+ crLeftTop, crRightBottom,
+ nBorderStyle, dsBorder);
+ }
+
+ CFX_ByteString csAP_N_OFF = csAP_N_ON;
+
+ switch (nBorderStyle) {
+ case BorderStyle::BEVELED: {
+ CFX_Color crTemp = crLeftTop;
+ crLeftTop = crRightBottom;
+ crRightBottom = crTemp;
+ break;
+ }
+ case BorderStyle::INSET: {
+ crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
+ crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
+ break;
+ }
+ default:
+ break;
+ }
+
+ CFX_ByteString csAP_D_ON;
+
+ if (nStyle == PCS_CIRCLE) {
+ CFX_Color crBK = crBackground - 0.25f;
+ if (nBorderStyle == BorderStyle::BEVELED) {
+ crLeftTop = crBackground - 0.25f;
+ crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
+ crBK = crBackground;
+ } else if (nBorderStyle == BorderStyle::INSET) {
+ crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
+ crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
+ }
+
+ csAP_D_ON =
+ GetCircleFillAppStream(rcCenter, crBK) +
+ GetCircleBorderAppStream(rcCenter, fBorderWidth, crBorder, crLeftTop,
+ crRightBottom, nBorderStyle, dsBorder);
+ } else {
+ csAP_D_ON =
+ CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) +
+ CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+ crLeftTop, crRightBottom, nBorderStyle,
+ dsBorder);
+ }
+
+ CFX_ByteString csAP_D_OFF = csAP_D_ON;
+
+ csAP_N_ON += GetRadioButtonAppStream(rcClient, nStyle, crText);
+ csAP_D_ON += GetRadioButtonAppStream(rcClient, nStyle, crText);
+
+ Write("N", csAP_N_ON, pControl->GetCheckedAPState());
+ Write("N", csAP_N_OFF, "Off");
+
+ Write("D", csAP_D_ON, pControl->GetCheckedAPState());
+ Write("D", csAP_D_OFF, "Off");
+
+ CFX_ByteString csAS = widget_->GetAppState();
+ if (csAS.IsEmpty())
+ widget_->SetAppState("Off");
+}
+
+void CPWL_AppStream::SetAsComboBox(const CFX_WideString* sValue) {
+ CPDF_FormControl* pControl = widget_->GetFormControl();
+ CPDF_FormField* pField = pControl->GetField();
+ std::ostringstream sBody;
+
+ CFX_FloatRect rcClient = widget_->GetClientRect();
+ CFX_FloatRect rcButton = rcClient;
+ rcButton.left = rcButton.right - 13;
+ rcButton.Normalize();
+
+ auto pEdit = pdfium::MakeUnique<CFX_Edit>();
+ pEdit->EnableRefresh(false);
+
+ CBA_FontMap font_map(
+ widget_.Get(),
+ widget_->GetInterForm()->GetFormFillEnv()->GetSysHandler());
+ pEdit->SetFontMap(&font_map);
+
+ CFX_FloatRect rcEdit = rcClient;
+ rcEdit.right = rcButton.left;
+ rcEdit.Normalize();
+
+ pEdit->SetPlateRect(rcEdit);
+ pEdit->SetAlignmentV(1, true);
+
+ float fFontSize = widget_->GetFontSize();
+ if (IsFloatZero(fFontSize))
+ pEdit->SetAutoFontSize(true, true);
+ else
+ pEdit->SetFontSize(fFontSize);
+
+ pEdit->Initialize();
+
+ if (sValue) {
+ pEdit->SetText(*sValue);
+ } else {
+ int32_t nCurSel = pField->GetSelectedIndex(0);
+ if (nCurSel < 0)
+ pEdit->SetText(pField->GetValue());
+ else
+ pEdit->SetText(pField->GetOptionLabel(nCurSel));
+ }
+
+ CFX_FloatRect rcContent = pEdit->GetContentRect();
+ CFX_ByteString sEdit =
+ CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF());
+ if (sEdit.GetLength() > 0) {
+ sBody << "/Tx BMC\n"
+ << "q\n";
+ if (rcContent.Width() > rcEdit.Width() ||
+ rcContent.Height() > rcEdit.Height()) {
+ sBody << rcEdit.left << " " << rcEdit.bottom << " " << rcEdit.Width()
+ << " " << rcEdit.Height() << " re\nW\nn\n";
+ }
+
+ CFX_Color crText = widget_->GetTextPWLColor();
+ sBody << "BT\n"
+ << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"
+ << "Q\nEMC\n";
+ }
+
+ sBody << GetDropButtonAppStream(rcButton);
+ Write("N",
+ GetBackgroundAppStream() + GetBorderAppStream() + CFX_ByteString(sBody),
+ "");
+}
+
+void CPWL_AppStream::SetAsListBox() {
+ CPDF_FormControl* pControl = widget_->GetFormControl();
+ CPDF_FormField* pField = pControl->GetField();
+ CFX_FloatRect rcClient = widget_->GetClientRect();
+ std::ostringstream sBody;
+
+ auto pEdit = pdfium::MakeUnique<CFX_Edit>();
+ pEdit->EnableRefresh(false);
+
+ CBA_FontMap font_map(
+ widget_.Get(),
+ widget_->GetInterForm()->GetFormFillEnv()->GetSysHandler());
+ pEdit->SetFontMap(&font_map);
+ pEdit->SetPlateRect(CFX_FloatRect(rcClient.left, 0.0f, rcClient.right, 0.0f));
+
+ float fFontSize = widget_->GetFontSize();
+ pEdit->SetFontSize(IsFloatZero(fFontSize) ? 12.0f : fFontSize);
+ pEdit->Initialize();
+
+ std::ostringstream sList;
+ float fy = rcClient.top;
+
+ int32_t nTop = pField->GetTopVisibleIndex();
+ int32_t nCount = pField->CountOptions();
+ int32_t nSelCount = pField->CountSelectedItems();
+
+ for (int32_t i = nTop; i < nCount; ++i) {
+ bool bSelected = false;
+ for (int32_t j = 0; j < nSelCount; ++j) {
+ if (pField->GetSelectedIndex(j) == i) {
+ bSelected = true;
+ break;
+ }
+ }
+
+ pEdit->SetText(pField->GetOptionLabel(i));
+
+ CFX_FloatRect rcContent = pEdit->GetContentRect();
+ float fItemHeight = rcContent.Height();
+
+ if (bSelected) {
+ CFX_FloatRect rcItem =
+ CFX_FloatRect(rcClient.left, fy - fItemHeight, rcClient.right, fy);
+ sList << "q\n"
+ << CPWL_Utils::GetColorAppStream(
+ CFX_Color(COLORTYPE_RGB, 0, 51.0f / 255.0f, 113.0f / 255.0f),
+ true)
+ << rcItem.left << " " << rcItem.bottom << " " << rcItem.Width()
+ << " " << rcItem.Height() << " re f\n"
+ << "Q\n";
+
+ sList << "BT\n"
+ << CPWL_Utils::GetColorAppStream(CFX_Color(COLORTYPE_GRAY, 1), true)
+ << CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy))
+ << "ET\n";
+ } else {
+ CFX_Color crText = widget_->GetTextPWLColor();
+ sList << "BT\n"
+ << CPWL_Utils::GetColorAppStream(crText, true)
+ << CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy))
+ << "ET\n";
+ }
+
+ fy -= fItemHeight;
+ }
+
+ if (sList.tellp() > 0) {
+ sBody << "/Tx BMC\n"
+ << "q\n"
+ << rcClient.left << " " << rcClient.bottom << " " << rcClient.Width()
+ << " " << rcClient.Height() << " re\nW\nn\n";
+ sBody << sList.str() << "Q\nEMC\n";
+ }
+ Write("N",
+ GetBackgroundAppStream() + GetBorderAppStream() + CFX_ByteString(sBody),
+ "");
+}
+
+void CPWL_AppStream::SetAsTextField(const CFX_WideString* sValue) {
+ CPDF_FormControl* pControl = widget_->GetFormControl();
+ CPDF_FormField* pField = pControl->GetField();
+ std::ostringstream sBody;
+ std::ostringstream sLines;
+
+ auto pEdit = pdfium::MakeUnique<CFX_Edit>();
+ pEdit->EnableRefresh(false);
+
+ CBA_FontMap font_map(
+ widget_.Get(),
+ widget_->GetInterForm()->GetFormFillEnv()->GetSysHandler());
+ pEdit->SetFontMap(&font_map);
+
+ CFX_FloatRect rcClient = widget_->GetClientRect();
+ pEdit->SetPlateRect(rcClient);
+ pEdit->SetAlignmentH(pControl->GetControlAlignment(), true);
+
+ uint32_t dwFieldFlags = pField->GetFieldFlags();
+ bool bMultiLine = (dwFieldFlags >> 12) & 1;
+ if (bMultiLine) {
+ pEdit->SetMultiLine(true, true);
+ pEdit->SetAutoReturn(true, true);
+ } else {
+ pEdit->SetAlignmentV(1, true);
+ }
+
+ uint16_t subWord = 0;
+ if ((dwFieldFlags >> 13) & 1) {
+ subWord = '*';
+ pEdit->SetPasswordChar(subWord, true);
+ }
+
+ int nMaxLen = pField->GetMaxLen();
+ bool bCharArray = (dwFieldFlags >> 24) & 1;
+ float fFontSize = widget_->GetFontSize();
+
+#ifdef PDF_ENABLE_XFA
+ CFX_WideString sValueTmp;
+ if (!sValue && widget_->GetMixXFAWidget()) {
+ sValueTmp = widget_->GetValue(true);
+ sValue = &sValueTmp;
+ }
+#endif // PDF_ENABLE_XFA
+
+ if (nMaxLen > 0) {
+ if (bCharArray) {
+ pEdit->SetCharArray(nMaxLen);
+
+ if (IsFloatZero(fFontSize)) {
+ fFontSize = CPWL_Edit::GetCharArrayAutoFontSize(font_map.GetPDFFont(0),
+ rcClient, nMaxLen);
+ }
+ } else {
+ if (sValue)
+ nMaxLen = sValue->GetLength();
+ pEdit->SetLimitChar(nMaxLen);
+ }
+ }
+
+ if (IsFloatZero(fFontSize))
+ pEdit->SetAutoFontSize(true, true);
+ else
+ pEdit->SetFontSize(fFontSize);
+
+ pEdit->Initialize();
+ pEdit->SetText(sValue ? *sValue : pField->GetValue());
+
+ CFX_FloatRect rcContent = pEdit->GetContentRect();
+ CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(
+ pEdit.get(), CFX_PointF(), nullptr, !bCharArray, subWord);
+
+ if (sEdit.GetLength() > 0) {
+ sBody << "/Tx BMC\n"
+ << "q\n";
+ if (rcContent.Width() > rcClient.Width() ||
+ rcContent.Height() > rcClient.Height()) {
+ sBody << rcClient.left << " " << rcClient.bottom << " "
+ << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
+ }
+ CFX_Color crText = widget_->GetTextPWLColor();
+ sBody << "BT\n"
+ << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"
+ << "Q\nEMC\n";
+ }
+
+ if (bCharArray) {
+ switch (widget_->GetBorderStyle()) {
+ case BorderStyle::SOLID: {
+ CFX_ByteString sColor =
+ CPWL_Utils::GetColorAppStream(widget_->GetBorderPWLColor(), false);
+ if (sColor.GetLength() > 0) {
+ sLines << "q\n"
+ << widget_->GetBorderWidth() << " w\n"
+ << CPWL_Utils::GetColorAppStream(widget_->GetBorderPWLColor(),
+ false)
+ << " 2 J 0 j\n";
+
+ for (int32_t i = 1; i < nMaxLen; ++i) {
+ sLines << rcClient.left +
+ ((rcClient.right - rcClient.left) / nMaxLen) * i
+ << " " << rcClient.bottom << " m\n"
+ << rcClient.left +
+ ((rcClient.right - rcClient.left) / nMaxLen) * i
+ << " " << rcClient.top << " l S\n";
+ }
+
+ sLines << "Q\n";
+ }
+ break;
+ }
+ case BorderStyle::DASH: {
+ CFX_ByteString sColor =
+ CPWL_Utils::GetColorAppStream(widget_->GetBorderPWLColor(), false);
+ if (sColor.GetLength() > 0) {
+ CPWL_Dash dsBorder = CPWL_Dash(3, 3, 0);
+
+ sLines << "q\n"
+ << widget_->GetBorderWidth() << " w\n"
+ << CPWL_Utils::GetColorAppStream(widget_->GetBorderPWLColor(),
+ false)
+ << "[" << dsBorder.nDash << " " << dsBorder.nGap << "] "
+ << dsBorder.nPhase << " d\n";
+
+ for (int32_t i = 1; i < nMaxLen; ++i) {
+ sLines << rcClient.left +
+ ((rcClient.right - rcClient.left) / nMaxLen) * i
+ << " " << rcClient.bottom << " m\n"
+ << rcClient.left +
+ ((rcClient.right - rcClient.left) / nMaxLen) * i
+ << " " << rcClient.top << " l S\n";
+ }
+
+ sLines << "Q\n";
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ Write("N",
+ GetBackgroundAppStream() + GetBorderAppStream() +
+ CFX_ByteString(sLines) + CFX_ByteString(sBody),
+ "");
+}
+
+void CPWL_AppStream::AddImage(const CFX_ByteString& sAPType,
+ CPDF_Stream* pImage) {
+ CPDF_Stream* pStream = dict_->GetStreamFor(sAPType);
+ CPDF_Dictionary* pStreamDict = pStream->GetDict();
+ CFX_ByteString sImageAlias = "IMG";
+
+ if (CPDF_Dictionary* pImageDict = pImage->GetDict()) {
+ sImageAlias = pImageDict->GetStringFor("Name");
+ if (sImageAlias.IsEmpty())
+ sImageAlias = "IMG";
+ }
+
+ CPDF_Dictionary* pStreamResList = pStreamDict->GetDictFor("Resources");
+ if (!pStreamResList)
+ pStreamResList = pStreamDict->SetNewFor<CPDF_Dictionary>("Resources");
+
+ CPDF_Dictionary* pXObject =
+ pStreamResList->SetNewFor<CPDF_Dictionary>("XObject");
+ pXObject->SetNewFor<CPDF_Reference>(sImageAlias,
+ widget_->GetPageView()->GetPDFDocument(),
+ pImage->GetObjNum());
+}
+
+void CPWL_AppStream::Write(const CFX_ByteString& sAPType,
+ const CFX_ByteString& sContents,
+ const CFX_ByteString& sAPState) {
+ CPDF_Stream* pStream = nullptr;
+ CPDF_Dictionary* pParentDict = nullptr;
+ if (sAPState.IsEmpty()) {
+ pParentDict = dict_.Get();
+ pStream = dict_->GetStreamFor(sAPType);
+ } else {
+ CPDF_Dictionary* pAPTypeDict = dict_->GetDictFor(sAPType);
+ if (!pAPTypeDict)
+ pAPTypeDict = dict_->SetNewFor<CPDF_Dictionary>(sAPType);
+
+ pParentDict = pAPTypeDict;
+ pStream = pAPTypeDict->GetStreamFor(sAPState);
+ }
+
+ if (!pStream) {
+ CPDF_Document* doc = widget_->GetPageView()->GetPDFDocument();
+ pStream = doc->NewIndirect<CPDF_Stream>();
+ pParentDict->SetNewFor<CPDF_Reference>(sAPType, doc, pStream->GetObjNum());
+ }
+
+ CPDF_Dictionary* pStreamDict = pStream->GetDict();
+ if (!pStreamDict) {
+ auto pNewDict = pdfium::MakeUnique<CPDF_Dictionary>(
+ widget_->GetPDFAnnot()->GetDocument()->GetByteStringPool());
+ pStreamDict = pNewDict.get();
+ pStreamDict->SetNewFor<CPDF_Name>("Type", "XObject");
+ pStreamDict->SetNewFor<CPDF_Name>("Subtype", "Form");
+ pStreamDict->SetNewFor<CPDF_Number>("FormType", 1);
+ pStream->InitStream(nullptr, 0, std::move(pNewDict));
+ }
+ pStreamDict->SetMatrixFor("Matrix", widget_->GetMatrix());
+ pStreamDict->SetRectFor("BBox", widget_->GetRotatedRect());
+ pStream->SetData((uint8_t*)(sContents.c_str()), sContents.GetLength());
+}
+
+void CPWL_AppStream::Remove(const CFX_ByteString& sAPType) {
+ dict_->RemoveFor(sAPType);
+}
+
+CFX_ByteString CPWL_AppStream::GetBackgroundAppStream() const {
+ CFX_Color crBackground = widget_->GetFillPWLColor();
+ if (crBackground.nColorType != COLORTYPE_TRANSPARENT)
+ return CPWL_Utils::GetRectFillAppStream(widget_->GetRotatedRect(),
+ crBackground);
+
+ return CFX_ByteString();
+}
+
+CFX_ByteString CPWL_AppStream::GetBorderAppStream() const {
+ CFX_FloatRect rcWindow = widget_->GetRotatedRect();
+ CFX_Color crBorder = widget_->GetBorderPWLColor();
+ CFX_Color crBackground = widget_->GetFillPWLColor();
+ CFX_Color crLeftTop;
+ CFX_Color crRightBottom;
+
+ float fBorderWidth = static_cast<float>(widget_->GetBorderWidth());
+ CPWL_Dash dsBorder(3, 0, 0);
+
+ BorderStyle nBorderStyle = widget_->GetBorderStyle();
+ switch (nBorderStyle) {
+ case BorderStyle::DASH:
+ dsBorder = CPWL_Dash(3, 3, 0);
+ break;
+ case BorderStyle::BEVELED:
+ fBorderWidth *= 2;
+ crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
+ crRightBottom = crBackground / 2.0f;
+ break;
+ case BorderStyle::INSET:
+ fBorderWidth *= 2;
+ crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
+ crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
+ break;
+ default:
+ break;
+ }
+
+ return CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+ crLeftTop, crRightBottom, nBorderStyle,
+ dsBorder);
+}
diff --git a/fpdfsdk/pdfwindow/cpwl_appstream.h b/fpdfsdk/pdfwindow/cpwl_appstream.h
new file mode 100644
index 0000000000..56137864ec
--- /dev/null
+++ b/fpdfsdk/pdfwindow/cpwl_appstream.h
@@ -0,0 +1,43 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_PDFWINDOW_CPWL_APPSTREAM_H_
+#define FPDFSDK_PDFWINDOW_CPWL_APPSTREAM_H_
+
+#include "core/fxcrt/cfx_unowned_ptr.h"
+#include "core/fxcrt/fx_string.h"
+
+class CPDFSDK_Widget;
+class CPDF_Dictionary;
+class CPDF_Stream;
+
+class CPWL_AppStream {
+ public:
+ CPWL_AppStream(CPDFSDK_Widget* widget, CPDF_Dictionary* dict);
+ ~CPWL_AppStream();
+
+ void SetAsPushButton();
+ void SetAsCheckBox();
+ void SetAsRadioButton();
+ void SetAsComboBox(const CFX_WideString* sValue);
+ void SetAsListBox();
+ void SetAsTextField(const CFX_WideString* sValue);
+
+ private:
+ void AddImage(const CFX_ByteString& sAPType, CPDF_Stream* pImage);
+ void Write(const CFX_ByteString& sAPType,
+ const CFX_ByteString& sContents,
+ const CFX_ByteString& sAPState);
+ void Remove(const CFX_ByteString& sAPType);
+
+ CFX_ByteString GetBackgroundAppStream() const;
+ CFX_ByteString GetBorderAppStream() const;
+
+ CFX_UnownedPtr<CPDFSDK_Widget> widget_;
+ CFX_UnownedPtr<CPDF_Dictionary> dict_;
+};
+
+#endif // FPDFSDK_PDFWINDOW_CPWL_APPSTREAM_H_
diff --git a/fpdfsdk/pdfwindow/cpwl_utils.cpp b/fpdfsdk/pdfwindow/cpwl_utils.cpp
index b21047b623..b628b292c9 100644
--- a/fpdfsdk/pdfwindow/cpwl_utils.cpp
+++ b/fpdfsdk/pdfwindow/cpwl_utils.cpp
@@ -14,206 +14,6 @@
#include "fpdfsdk/fxedit/fxet_edit.h"
#include "fpdfsdk/pdfwindow/cpwl_icon.h"
-CFX_ByteString CPWL_Utils::GetAP_Check(const CFX_FloatRect& crBBox) {
- const float fWidth = crBBox.right - crBBox.left;
- const float fHeight = crBBox.top - crBBox.bottom;
-
- CFX_PointF pts[8][3] = {{CFX_PointF(0.28f, 0.52f), CFX_PointF(0.27f, 0.48f),
- CFX_PointF(0.29f, 0.40f)},
- {CFX_PointF(0.30f, 0.33f), CFX_PointF(0.31f, 0.29f),
- CFX_PointF(0.31f, 0.28f)},
- {CFX_PointF(0.39f, 0.28f), CFX_PointF(0.49f, 0.29f),
- CFX_PointF(0.77f, 0.67f)},
- {CFX_PointF(0.76f, 0.68f), CFX_PointF(0.78f, 0.69f),
- CFX_PointF(0.76f, 0.75f)},
- {CFX_PointF(0.76f, 0.75f), CFX_PointF(0.73f, 0.80f),
- CFX_PointF(0.68f, 0.75f)},
- {CFX_PointF(0.68f, 0.74f), CFX_PointF(0.68f, 0.74f),
- CFX_PointF(0.44f, 0.47f)},
- {CFX_PointF(0.43f, 0.47f), CFX_PointF(0.40f, 0.47f),
- CFX_PointF(0.41f, 0.58f)},
- {CFX_PointF(0.40f, 0.60f), CFX_PointF(0.28f, 0.66f),
- CFX_PointF(0.30f, 0.56f)}};
-
- for (size_t i = 0; i < FX_ArraySize(pts); ++i) {
- for (size_t j = 0; j < FX_ArraySize(pts[0]); ++j) {
- pts[i][j].x = pts[i][j].x * fWidth + crBBox.left;
- pts[i][j].y *= pts[i][j].y * fHeight + crBBox.bottom;
- }
- }
-
- std::ostringstream csAP;
- csAP << pts[0][0].x << " " << pts[0][0].y << " m\n";
-
- for (size_t i = 0; i < FX_ArraySize(pts); ++i) {
- size_t nNext = i < FX_ArraySize(pts) - 1 ? i + 1 : 0;
-
- float px1 = pts[i][1].x - pts[i][0].x;
- float py1 = pts[i][1].y - pts[i][0].y;
- float px2 = pts[i][2].x - pts[nNext][0].x;
- float py2 = pts[i][2].y - pts[nNext][0].y;
-
- csAP << pts[i][0].x + px1 * FX_BEZIER << " "
- << pts[i][0].y + py1 * FX_BEZIER << " "
- << pts[nNext][0].x + px2 * FX_BEZIER << " "
- << pts[nNext][0].y + py2 * FX_BEZIER << " " << pts[nNext][0].x << " "
- << pts[nNext][0].y << " c\n";
- }
-
- return CFX_ByteString(csAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAP_Circle(const CFX_FloatRect& crBBox) {
- std::ostringstream csAP;
-
- float fWidth = crBBox.right - crBBox.left;
- float fHeight = crBBox.top - crBBox.bottom;
-
- CFX_PointF pt1(crBBox.left, crBBox.bottom + fHeight / 2);
- CFX_PointF pt2(crBBox.left + fWidth / 2, crBBox.top);
- CFX_PointF pt3(crBBox.right, crBBox.bottom + fHeight / 2);
- CFX_PointF pt4(crBBox.left + fWidth / 2, crBBox.bottom);
-
- csAP << pt1.x << " " << pt1.y << " m\n";
-
- float px = pt2.x - pt1.x;
- float py = pt2.y - pt1.y;
-
- csAP << pt1.x << " " << pt1.y + py * FX_BEZIER << " "
- << pt2.x - px * FX_BEZIER << " " << pt2.y << " " << pt2.x << " " << pt2.y
- << " c\n";
-
- px = pt3.x - pt2.x;
- py = pt2.y - pt3.y;
-
- csAP << pt2.x + px * FX_BEZIER << " " << pt2.y << " " << pt3.x << " "
- << pt3.y + py * FX_BEZIER << " " << pt3.x << " " << pt3.y << " c\n";
-
- px = pt3.x - pt4.x;
- py = pt3.y - pt4.y;
-
- csAP << pt3.x << " " << pt3.y - py * FX_BEZIER << " "
- << pt4.x + px * FX_BEZIER << " " << pt4.y << " " << pt4.x << " " << pt4.y
- << " c\n";
-
- px = pt4.x - pt1.x;
- py = pt1.y - pt4.y;
-
- csAP << pt4.x - px * FX_BEZIER << " " << pt4.y << " " << pt1.x << " "
- << pt1.y - py * FX_BEZIER << " " << pt1.x << " " << pt1.y << " c\n";
-
- return CFX_ByteString(csAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAP_Cross(const CFX_FloatRect& crBBox) {
- std::ostringstream csAP;
-
- csAP << crBBox.left << " " << crBBox.top << " m\n";
- csAP << crBBox.right << " " << crBBox.bottom << " l\n";
- csAP << crBBox.left << " " << crBBox.bottom << " m\n";
- csAP << crBBox.right << " " << crBBox.top << " l\n";
-
- return CFX_ByteString(csAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAP_Diamond(const CFX_FloatRect& crBBox) {
- std::ostringstream csAP;
-
- float fWidth = crBBox.right - crBBox.left;
- float fHeight = crBBox.top - crBBox.bottom;
-
- CFX_PointF pt1(crBBox.left, crBBox.bottom + fHeight / 2);
- CFX_PointF pt2(crBBox.left + fWidth / 2, crBBox.top);
- CFX_PointF pt3(crBBox.right, crBBox.bottom + fHeight / 2);
- CFX_PointF pt4(crBBox.left + fWidth / 2, crBBox.bottom);
-
- csAP << pt1.x << " " << pt1.y << " m\n";
- csAP << pt2.x << " " << pt2.y << " l\n";
- csAP << pt3.x << " " << pt3.y << " l\n";
- csAP << pt4.x << " " << pt4.y << " l\n";
- csAP << pt1.x << " " << pt1.y << " l\n";
-
- return CFX_ByteString(csAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAP_Square(const CFX_FloatRect& crBBox) {
- std::ostringstream csAP;
-
- csAP << crBBox.left << " " << crBBox.top << " m\n";
- csAP << crBBox.right << " " << crBBox.top << " l\n";
- csAP << crBBox.right << " " << crBBox.bottom << " l\n";
- csAP << crBBox.left << " " << crBBox.bottom << " l\n";
- csAP << crBBox.left << " " << crBBox.top << " l\n";
-
- return CFX_ByteString(csAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAP_Star(const CFX_FloatRect& crBBox) {
- std::ostringstream csAP;
-
- float fRadius = (crBBox.top - crBBox.bottom) / (1 + (float)cos(FX_PI / 5.0f));
- CFX_PointF ptCenter = CFX_PointF((crBBox.left + crBBox.right) / 2.0f,
- (crBBox.top + crBBox.bottom) / 2.0f);
-
- float px[5], py[5];
-
- float fAngel = FX_PI / 10.0f;
-
- for (int32_t i = 0; i < 5; i++) {
- px[i] = ptCenter.x + fRadius * (float)cos(fAngel);
- py[i] = ptCenter.y + fRadius * (float)sin(fAngel);
-
- fAngel += FX_PI * 2 / 5.0f;
- }
-
- csAP << px[0] << " " << py[0] << " m\n";
-
- int32_t nNext = 0;
- for (int32_t j = 0; j < 5; j++) {
- nNext += 2;
- if (nNext >= 5)
- nNext -= 5;
- csAP << px[nNext] << " " << py[nNext] << " l\n";
- }
-
- return CFX_ByteString(csAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAP_HalfCircle(const CFX_FloatRect& crBBox,
- float fRotate) {
- std::ostringstream csAP;
-
- float fWidth = crBBox.right - crBBox.left;
- float fHeight = crBBox.top - crBBox.bottom;
-
- CFX_PointF pt1(-fWidth / 2, 0);
- CFX_PointF pt2(0, fHeight / 2);
- CFX_PointF pt3(fWidth / 2, 0);
-
- float px, py;
-
- csAP << cos(fRotate) << " " << sin(fRotate) << " " << -sin(fRotate) << " "
- << cos(fRotate) << " " << crBBox.left + fWidth / 2 << " "
- << crBBox.bottom + fHeight / 2 << " cm\n";
-
- csAP << pt1.x << " " << pt1.y << " m\n";
-
- px = pt2.x - pt1.x;
- py = pt2.y - pt1.y;
-
- csAP << pt1.x << " " << pt1.y + py * FX_BEZIER << " "
- << pt2.x - px * FX_BEZIER << " " << pt2.y << " " << pt2.x << " " << pt2.y
- << " c\n";
-
- px = pt3.x - pt2.x;
- py = pt2.y - pt3.y;
-
- csAP << pt2.x + px * FX_BEZIER << " " << pt2.y << " " << pt3.x << " "
- << pt3.y + py * FX_BEZIER << " " << pt3.x << " " << pt3.y << " c\n";
-
- return CFX_ByteString(csAP);
-}
-
CFX_ByteString CPWL_Utils::GetRectFillAppStream(const CFX_FloatRect& rect,
const CFX_Color& color) {
std::ostringstream sAppStream;
@@ -228,15 +28,6 @@ CFX_ByteString CPWL_Utils::GetRectFillAppStream(const CFX_FloatRect& rect,
return CFX_ByteString(sAppStream);
}
-CFX_ByteString CPWL_Utils::GetCircleFillAppStream(const CFX_FloatRect& rect,
- const CFX_Color& color) {
- std::ostringstream sAppStream;
- CFX_ByteString sColor = GetColorAppStream(color, true);
- if (sColor.GetLength() > 0)
- sAppStream << "q\n" << sColor << CPWL_Utils::GetAP_Circle(rect) << "f\nQ\n";
- return CFX_ByteString(sAppStream);
-}
-
CFX_ByteString CPWL_Utils::GetEditAppStream(CFX_Edit* pEdit,
const CFX_PointF& ptOffset,
const CPVT_WordRange* pRange,
@@ -252,206 +43,6 @@ CFX_ByteString CPWL_Utils::GetEditSelAppStream(CFX_Edit* pEdit,
return CFX_Edit::GetSelectAppearanceStream(pEdit, ptOffset, pRange);
}
-CFX_ByteString CPWL_Utils::GetPushButtonAppStream(const CFX_FloatRect& rcBBox,
- IPVT_FontMap* pFontMap,
- CPDF_Stream* pIconStream,
- CPDF_IconFit& IconFit,
- const CFX_WideString& sLabel,
- const CFX_Color& crText,
- float fFontSize,
- int32_t nLayOut) {
- const float fAutoFontScale = 1.0f / 3.0f;
-
- auto pEdit = pdfium::MakeUnique<CFX_Edit>();
- pEdit->SetFontMap(pFontMap);
- pEdit->SetAlignmentH(1, true);
- pEdit->SetAlignmentV(1, true);
- pEdit->SetMultiLine(false, true);
- pEdit->SetAutoReturn(false, true);
- if (IsFloatZero(fFontSize))
- pEdit->SetAutoFontSize(true, true);
- else
- pEdit->SetFontSize(fFontSize);
-
- pEdit->Initialize();
- pEdit->SetText(sLabel);
-
- CFX_FloatRect rcLabelContent = pEdit->GetContentRect();
- CPWL_Icon Icon;
- PWL_CREATEPARAM cp;
- cp.dwFlags = PWS_VISIBLE;
- Icon.Create(cp);
- Icon.SetIconFit(&IconFit);
- Icon.SetPDFStream(pIconStream);
-
- CFX_FloatRect rcLabel;
- CFX_FloatRect rcIcon;
- float fWidth = 0.0f;
- float fHeight = 0.0f;
-
- switch (nLayOut) {
- case PPBL_LABEL:
- rcLabel = rcBBox;
- break;
- case PPBL_ICON:
- rcIcon = rcBBox;
- break;
- case PPBL_ICONTOPLABELBOTTOM:
- if (pIconStream) {
- if (IsFloatZero(fFontSize)) {
- fHeight = rcBBox.top - rcBBox.bottom;
- rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
- rcBBox.bottom + fHeight * fAutoFontScale);
- rcIcon =
- CFX_FloatRect(rcBBox.left, rcLabel.top, rcBBox.right, rcBBox.top);
- } else {
- fHeight = rcLabelContent.Height();
-
- if (rcBBox.bottom + fHeight > rcBBox.top) {
- rcLabel = rcBBox;
- } else {
- rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
- rcBBox.bottom + fHeight);
- rcIcon = CFX_FloatRect(rcBBox.left, rcLabel.top, rcBBox.right,
- rcBBox.top);
- }
- }
- } else {
- rcLabel = rcBBox;
- }
- break;
- case PPBL_LABELTOPICONBOTTOM:
- if (pIconStream) {
- if (IsFloatZero(fFontSize)) {
- fHeight = rcBBox.top - rcBBox.bottom;
- rcLabel =
- CFX_FloatRect(rcBBox.left, rcBBox.top - fHeight * fAutoFontScale,
- rcBBox.right, rcBBox.top);
- rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
- rcLabel.bottom);
- } else {
- fHeight = rcLabelContent.Height();
-
- if (rcBBox.bottom + fHeight > rcBBox.top) {
- rcLabel = rcBBox;
- } else {
- rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.top - fHeight,
- rcBBox.right, rcBBox.top);
- rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
- rcLabel.bottom);
- }
- }
- } else {
- rcLabel = rcBBox;
- }
- break;
- case PPBL_ICONLEFTLABELRIGHT:
- if (pIconStream) {
- if (IsFloatZero(fFontSize)) {
- fWidth = rcBBox.right - rcBBox.left;
- if (rcLabelContent.Width() < fWidth * fAutoFontScale) {
- rcLabel = CFX_FloatRect(rcBBox.right - fWidth * fAutoFontScale,
- rcBBox.bottom, rcBBox.right, rcBBox.top);
- rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcLabel.left,
- rcBBox.top);
- } else {
- if (rcLabelContent.Width() < fWidth) {
- rcLabel = CFX_FloatRect(rcBBox.right - rcLabelContent.Width(),
- rcBBox.bottom, rcBBox.right, rcBBox.top);
- rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcLabel.left,
- rcBBox.top);
- } else {
- rcLabel = rcBBox;
- }
- }
- } else {
- fWidth = rcLabelContent.Width();
- if (rcBBox.left + fWidth > rcBBox.right) {
- rcLabel = rcBBox;
- } else {
- rcLabel = CFX_FloatRect(rcBBox.right - fWidth, rcBBox.bottom,
- rcBBox.right, rcBBox.top);
- rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcLabel.left,
- rcBBox.top);
- }
- }
- } else {
- rcLabel = rcBBox;
- }
- break;
- case PPBL_LABELLEFTICONRIGHT:
- if (pIconStream) {
- if (IsFloatZero(fFontSize)) {
- fWidth = rcBBox.right - rcBBox.left;
- if (rcLabelContent.Width() < fWidth * fAutoFontScale) {
- rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom,
- rcBBox.left + fWidth * fAutoFontScale,
- rcBBox.top);
- rcIcon = CFX_FloatRect(rcLabel.right, rcBBox.bottom, rcBBox.right,
- rcBBox.top);
- } else {
- if (rcLabelContent.Width() < fWidth) {
- rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom,
- rcBBox.left + rcLabelContent.Width(),
- rcBBox.top);
- rcIcon = CFX_FloatRect(rcLabel.right, rcBBox.bottom, rcBBox.right,
- rcBBox.top);
- } else {
- rcLabel = rcBBox;
- }
- }
- } else {
- fWidth = rcLabelContent.Width();
- if (rcBBox.left + fWidth > rcBBox.right) {
- rcLabel = rcBBox;
- } else {
- rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom,
- rcBBox.left + fWidth, rcBBox.top);
- rcIcon = CFX_FloatRect(rcLabel.right, rcBBox.bottom, rcBBox.right,
- rcBBox.top);
- }
- }
- } else {
- rcLabel = rcBBox;
- }
- break;
- case PPBL_LABELOVERICON:
- rcLabel = rcBBox;
- rcIcon = rcBBox;
- break;
- }
-
- std::ostringstream sTemp;
-
- if (!rcIcon.IsEmpty()) {
- Icon.Move(rcIcon, false, false);
- sTemp << Icon.GetImageAppStream();
- }
-
- Icon.Destroy();
-
- if (!rcLabel.IsEmpty()) {
- pEdit->SetPlateRect(rcLabel);
- CFX_ByteString sEdit =
- CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, 0.0f));
- if (sEdit.GetLength() > 0) {
- sTemp << "BT\n"
- << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n";
- }
- }
-
- if (sTemp.tellp() <= 0)
- return CFX_ByteString();
-
- std::ostringstream sAppStream;
- sAppStream << "q\n"
- << rcBBox.left << " " << rcBBox.bottom << " "
- << rcBBox.right - rcBBox.left << " " << rcBBox.top - rcBBox.bottom
- << " re W n\n";
- sAppStream << sTemp.str().c_str() << "Q\n";
- return CFX_ByteString(sAppStream);
-}
-
CFX_ByteString CPWL_Utils::GetColorAppStream(const CFX_Color& color,
const bool& bFillOrStroke) {
std::ostringstream sColorStream;
@@ -591,250 +182,3 @@ CFX_ByteString CPWL_Utils::GetBorderAppStream(const CFX_FloatRect& rect,
return CFX_ByteString(sAppStream);
}
-
-CFX_ByteString CPWL_Utils::GetCircleBorderAppStream(
- const CFX_FloatRect& rect,
- float fWidth,
- const CFX_Color& color,
- const CFX_Color& crLeftTop,
- const CFX_Color& crRightBottom,
- BorderStyle nStyle,
- const CPWL_Dash& dash) {
- std::ostringstream sAppStream;
- CFX_ByteString sColor;
-
- if (fWidth > 0.0f) {
- sAppStream << "q\n";
-
- float fHalfWidth = fWidth / 2.0f;
- CFX_FloatRect rect_by_2 = rect.GetDeflated(fHalfWidth, fHalfWidth);
-
- float div = fHalfWidth * 0.75f;
- CFX_FloatRect rect_by_75 = rect.GetDeflated(div, div);
- switch (nStyle) {
- default:
- case BorderStyle::SOLID:
- case BorderStyle::UNDERLINE: {
- sColor = CPWL_Utils::GetColorAppStream(color, false);
- if (sColor.GetLength() > 0) {
- sAppStream << "q\n"
- << fWidth << " w\n"
- << sColor << CPWL_Utils::GetAP_Circle(rect_by_2)
- << " S\nQ\n";
- }
- } break;
- case BorderStyle::DASH: {
- sColor = CPWL_Utils::GetColorAppStream(color, false);
- if (sColor.GetLength() > 0) {
- sAppStream << "q\n"
- << fWidth << " w\n"
- << "[" << dash.nDash << " " << dash.nGap << "] "
- << dash.nPhase << " d\n"
- << sColor << CPWL_Utils::GetAP_Circle(rect_by_2)
- << " S\nQ\n";
- }
- } break;
- case BorderStyle::BEVELED: {
- sColor = CPWL_Utils::GetColorAppStream(color, false);
- if (sColor.GetLength() > 0) {
- sAppStream << "q\n"
- << fHalfWidth << " w\n"
- << sColor << CPWL_Utils::GetAP_Circle(rect) << " S\nQ\n";
- }
-
- sColor = CPWL_Utils::GetColorAppStream(crLeftTop, false);
- if (sColor.GetLength() > 0) {
- sAppStream << "q\n"
- << fHalfWidth << " w\n"
- << sColor
- << CPWL_Utils::GetAP_HalfCircle(rect_by_75, FX_PI / 4.0f)
- << " S\nQ\n";
- }
-
- sColor = CPWL_Utils::GetColorAppStream(crRightBottom, false);
- if (sColor.GetLength() > 0) {
- sAppStream << "q\n"
- << fHalfWidth << " w\n"
- << sColor
- << CPWL_Utils::GetAP_HalfCircle(rect_by_75,
- FX_PI * 5 / 4.0f)
- << " S\nQ\n";
- }
- } break;
- case BorderStyle::INSET: {
- sColor = CPWL_Utils::GetColorAppStream(color, false);
- if (sColor.GetLength() > 0) {
- sAppStream << "q\n"
- << fHalfWidth << " w\n"
- << sColor << CPWL_Utils::GetAP_Circle(rect) << " S\nQ\n";
- }
-
- sColor = CPWL_Utils::GetColorAppStream(crLeftTop, false);
- if (sColor.GetLength() > 0) {
- sAppStream << "q\n"
- << fHalfWidth << " w\n"
- << sColor
- << CPWL_Utils::GetAP_HalfCircle(rect_by_75, FX_PI / 4.0f)
- << " S\nQ\n";
- }
-
- sColor = CPWL_Utils::GetColorAppStream(crRightBottom, false);
- if (sColor.GetLength() > 0) {
- sAppStream << "q\n"
- << fHalfWidth << " w\n"
- << sColor
- << CPWL_Utils::GetAP_HalfCircle(rect_by_75,
- FX_PI * 5 / 4.0f)
- << " S\nQ\n";
- }
- } break;
- }
-
- sAppStream << "Q\n";
- }
-
- return CFX_ByteString(sAppStream);
-}
-
-CFX_ByteString CPWL_Utils::GetAppStream_Check(const CFX_FloatRect& rcBBox,
- const CFX_Color& crText) {
- std::ostringstream sAP;
- sAP << "q\n"
- << CPWL_Utils::GetColorAppStream(crText, true)
- << CPWL_Utils::GetAP_Check(rcBBox) << "f\nQ\n";
- return CFX_ByteString(sAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAppStream_Circle(const CFX_FloatRect& rcBBox,
- const CFX_Color& crText) {
- std::ostringstream sAP;
- sAP << "q\n"
- << CPWL_Utils::GetColorAppStream(crText, true)
- << CPWL_Utils::GetAP_Circle(rcBBox) << "f\nQ\n";
- return CFX_ByteString(sAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAppStream_Cross(const CFX_FloatRect& rcBBox,
- const CFX_Color& crText) {
- std::ostringstream sAP;
- sAP << "q\n"
- << CPWL_Utils::GetColorAppStream(crText, false)
- << CPWL_Utils::GetAP_Cross(rcBBox) << "S\nQ\n";
- return CFX_ByteString(sAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAppStream_Diamond(const CFX_FloatRect& rcBBox,
- const CFX_Color& crText) {
- std::ostringstream sAP;
- sAP << "q\n1 w\n"
- << CPWL_Utils::GetColorAppStream(crText, true)
- << CPWL_Utils::GetAP_Diamond(rcBBox) << "f\nQ\n";
- return CFX_ByteString(sAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAppStream_Square(const CFX_FloatRect& rcBBox,
- const CFX_Color& crText) {
- std::ostringstream sAP;
- sAP << "q\n"
- << CPWL_Utils::GetColorAppStream(crText, true)
- << CPWL_Utils::GetAP_Square(rcBBox) << "f\nQ\n";
- return CFX_ByteString(sAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAppStream_Star(const CFX_FloatRect& rcBBox,
- const CFX_Color& crText) {
- std::ostringstream sAP;
- sAP << "q\n"
- << CPWL_Utils::GetColorAppStream(crText, true)
- << CPWL_Utils::GetAP_Star(rcBBox) << "f\nQ\n";
- return CFX_ByteString(sAP);
-}
-
-CFX_ByteString CPWL_Utils::GetCheckBoxAppStream(const CFX_FloatRect& rcBBox,
- int32_t nStyle,
- const CFX_Color& crText) {
- CFX_FloatRect rcCenter = rcBBox.GetCenterSquare();
- switch (nStyle) {
- default:
- case PCS_CHECK:
- return GetAppStream_Check(rcCenter, crText);
- case PCS_CIRCLE:
- rcCenter.Scale(2.0f / 3.0f);
- return GetAppStream_Circle(rcCenter, crText);
- case PCS_CROSS:
- return GetAppStream_Cross(rcCenter, crText);
- case PCS_DIAMOND:
- rcCenter.Scale(2.0f / 3.0f);
- return GetAppStream_Diamond(rcCenter, crText);
- case PCS_SQUARE:
- rcCenter.Scale(2.0f / 3.0f);
- return GetAppStream_Square(rcCenter, crText);
- case PCS_STAR:
- rcCenter.Scale(2.0f / 3.0f);
- return GetAppStream_Star(rcCenter, crText);
- }
-}
-
-CFX_ByteString CPWL_Utils::GetRadioButtonAppStream(const CFX_FloatRect& rcBBox,
- int32_t nStyle,
- const CFX_Color& crText) {
- CFX_FloatRect rcCenter = rcBBox.GetCenterSquare();
- switch (nStyle) {
- default:
- case PCS_CHECK:
- return GetAppStream_Check(rcCenter, crText);
- case PCS_CIRCLE:
- rcCenter.Scale(1.0f / 2.0f);
- return GetAppStream_Circle(rcCenter, crText);
- case PCS_CROSS:
- return GetAppStream_Cross(rcCenter, crText);
- case PCS_DIAMOND:
- rcCenter.Scale(2.0f / 3.0f);
- return GetAppStream_Diamond(rcCenter, crText);
- case PCS_SQUARE:
- rcCenter.Scale(2.0f / 3.0f);
- return GetAppStream_Square(rcCenter, crText);
- case PCS_STAR:
- rcCenter.Scale(2.0f / 3.0f);
- return GetAppStream_Star(rcCenter, crText);
- }
-}
-
-CFX_ByteString CPWL_Utils::GetDropButtonAppStream(const CFX_FloatRect& rcBBox) {
- if (rcBBox.IsEmpty())
- return CFX_ByteString();
-
- std::ostringstream sAppStream;
- sAppStream << "q\n"
- << CPWL_Utils::GetColorAppStream(
- CFX_Color(COLORTYPE_RGB, 220.0f / 255.0f, 220.0f / 255.0f,
- 220.0f / 255.0f),
- true)
- << rcBBox.left << " " << rcBBox.bottom << " "
- << rcBBox.right - rcBBox.left << " " << rcBBox.top - rcBBox.bottom
- << " re f\n"
- << "Q\n";
-
- sAppStream << "q\n"
- << CPWL_Utils::GetBorderAppStream(
- rcBBox, 2, CFX_Color(COLORTYPE_GRAY, 0),
- CFX_Color(COLORTYPE_GRAY, 1),
- CFX_Color(COLORTYPE_GRAY, 0.5), BorderStyle::BEVELED,
- CPWL_Dash(3, 0, 0))
- << "Q\n";
-
- CFX_PointF ptCenter = CFX_PointF((rcBBox.left + rcBBox.right) / 2,
- (rcBBox.top + rcBBox.bottom) / 2);
- if (IsFloatBigger(rcBBox.right - rcBBox.left, 6) &&
- IsFloatBigger(rcBBox.top - rcBBox.bottom, 6)) {
- sAppStream << "q\n"
- << " 0 g\n"
- << ptCenter.x - 3 << " " << ptCenter.y + 1.5f << " m\n"
- << ptCenter.x + 3 << " " << ptCenter.y + 1.5f << " l\n"
- << ptCenter.x << " " << ptCenter.y - 1.5f << " l\n"
- << ptCenter.x - 3 << " " << ptCenter.y + 1.5f << " l f\n"
- << "Q\n";
- }
-
- return CFX_ByteString(sAppStream);
-}
diff --git a/fpdfsdk/pdfwindow/cpwl_utils.h b/fpdfsdk/pdfwindow/cpwl_utils.h
index 67876edbc3..9445de3277 100644
--- a/fpdfsdk/pdfwindow/cpwl_utils.h
+++ b/fpdfsdk/pdfwindow/cpwl_utils.h
@@ -41,31 +41,8 @@ class CPWL_Utils {
const CFX_Color& crRightBottom,
BorderStyle nStyle,
const CPWL_Dash& dash);
- static CFX_ByteString GetCircleBorderAppStream(const CFX_FloatRect& rect,
- float fWidth,
- const CFX_Color& color,
- const CFX_Color& crLeftTop,
- const CFX_Color& crRightBottom,
- BorderStyle nStyle,
- const CPWL_Dash& dash);
static CFX_ByteString GetRectFillAppStream(const CFX_FloatRect& rect,
const CFX_Color& color);
- static CFX_ByteString GetCircleFillAppStream(const CFX_FloatRect& rect,
- const CFX_Color& color);
- static CFX_ByteString GetPushButtonAppStream(const CFX_FloatRect& rcBBox,
- IPVT_FontMap* pFontMap,
- CPDF_Stream* pIconStream,
- CPDF_IconFit& IconFit,
- const CFX_WideString& sLabel,
- const CFX_Color& crText,
- float fFontSize,
- int32_t nLayOut);
- static CFX_ByteString GetCheckBoxAppStream(const CFX_FloatRect& rcBBox,
- int32_t nStyle,
- const CFX_Color& crText);
- static CFX_ByteString GetRadioButtonAppStream(const CFX_FloatRect& rcBBox,
- int32_t nStyle,
- const CFX_Color& crText);
static CFX_ByteString GetEditAppStream(CFX_Edit* pEdit,
const CFX_PointF& ptOffset,
const CPVT_WordRange* pRange = nullptr,
@@ -75,30 +52,6 @@ class CPWL_Utils {
CFX_Edit* pEdit,
const CFX_PointF& ptOffset,
const CPVT_WordRange* pRange = nullptr);
- static CFX_ByteString GetDropButtonAppStream(const CFX_FloatRect& rcBBox);
-
- private:
- static CFX_ByteString GetAppStream_Check(const CFX_FloatRect& rcBBox,
- const CFX_Color& crText);
- static CFX_ByteString GetAppStream_Circle(const CFX_FloatRect& rcBBox,
- const CFX_Color& crText);
- static CFX_ByteString GetAppStream_Cross(const CFX_FloatRect& rcBBox,
- const CFX_Color& crText);
- static CFX_ByteString GetAppStream_Diamond(const CFX_FloatRect& rcBBox,
- const CFX_Color& crText);
- static CFX_ByteString GetAppStream_Square(const CFX_FloatRect& rcBBox,
- const CFX_Color& crText);
- static CFX_ByteString GetAppStream_Star(const CFX_FloatRect& rcBBox,
- const CFX_Color& crText);
-
- static CFX_ByteString GetAP_Check(const CFX_FloatRect& crBBox);
- static CFX_ByteString GetAP_Circle(const CFX_FloatRect& crBBox);
- static CFX_ByteString GetAP_Cross(const CFX_FloatRect& crBBox);
- static CFX_ByteString GetAP_Diamond(const CFX_FloatRect& crBBox);
- static CFX_ByteString GetAP_Square(const CFX_FloatRect& crBBox);
- static CFX_ByteString GetAP_Star(const CFX_FloatRect& crBBox);
- static CFX_ByteString GetAP_HalfCircle(const CFX_FloatRect& crBBox,
- float fRotate);
};
#endif // FPDFSDK_PDFWINDOW_CPWL_UTILS_H_