7#include "fpdfsdk/cpdfsdk_appstream.h"
17#include "constants/appearance.h"
18#include "constants/form_flags.h"
19#include "core/fpdfapi/edit/cpdf_contentstream_write_utils.h"
20#include "core/fpdfapi/font/cpdf_font.h"
21#include "core/fpdfapi/parser/cpdf_dictionary.h"
22#include "core/fpdfapi/parser/cpdf_document.h"
23#include "core/fpdfapi/parser/cpdf_name.h"
24#include "core/fpdfapi/parser/cpdf_number.h"
25#include "core/fpdfapi/parser/cpdf_reference.h"
26#include "core/fpdfapi/parser/cpdf_stream.h"
27#include "core/fpdfapi/parser/cpdf_string.h"
28#include "core/fpdfapi/parser/fpdf_parser_decode.h"
29#include "core/fpdfapi/parser/fpdf_parser_utility.h"
30#include "core/fpdfdoc/cpdf_bafontmap.h"
31#include "core/fpdfdoc/cpdf_formcontrol.h"
32#include "core/fpdfdoc/cpdf_icon.h"
33#include "core/fpdfdoc/cpvt_word.h"
34#include "core/fxcrt/fx_string_wrappers.h"
35#include "core/fxcrt/numerics/safe_conversions.h"
36#include "core/fxcrt/span.h"
37#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
38#include "fpdfsdk/cpdfsdk_interactiveform.h"
39#include "fpdfsdk/cpdfsdk_pageview.h"
40#include "fpdfsdk/cpdfsdk_widget.h"
41#include "fpdfsdk/pwl/cpwl_edit.h"
42#include "fpdfsdk/pwl/cpwl_edit_impl.h"
43#include "fpdfsdk/pwl/cpwl_wnd.h"
48enum class CheckStyle { kCheck = 0, kCircle, kCross, kDiamond, kSquare, kStar };
51enum class ButtonStyle {
61const char kAppendRectOperator[] =
"re";
62const char kConcatMatrixOperator[] =
"cm";
63const char kCurveToOperator[] =
"c";
64const char kEndPathNoFillOrStrokeOperator[] =
"n";
65const char kFillOperator[] =
"f";
66const char kFillEvenOddOperator[] =
"f*";
67const char kInvokeNamedXObjectOperator[] =
"Do";
68const char kLineToOperator[] =
"l";
69const char kMarkedSequenceBeginOperator[] =
"BMC";
70const char kMarkedSequenceEndOperator[] =
"EMC";
71const char kMoveTextPositionOperator[] =
"Td";
72const char kMoveToOperator[] =
"m";
73const char kSetCMYKOperator[] =
"k";
74const char kSetCMKYStrokedOperator[] =
"K";
75const char kSetDashOperator[] =
"d";
76const char kSetGrayOperator[] =
"g";
77const char kSetGrayStrokedOperator[] =
"G";
78const char kSetLineCapStyleOperator[] =
"J";
79const char kSetLineJoinStyleOperator[] =
"j";
80const char kSetLineWidthOperator[] =
"w";
81const char kSetNonZeroWindingClipOperator[] =
"W";
82const char kSetRGBOperator[] =
"rg";
83const char kSetRGBStrokedOperator[] =
"RG";
84const char kSetTextFontAndSizeOperator[] =
"Tf";
85const char kShowTextOperator[] =
"Tj";
86const char kStateRestoreOperator[] =
"Q";
87const char kStateSaveOperator[] =
"q";
88const char kStrokeOperator[] =
"S";
89const char kTextBeginOperator[] =
"BT";
90const char kTextEndOperator[] =
"ET";
92class AutoClosedCommand {
94 AutoClosedCommand(fxcrt::ostringstream* stream,
97 : stream_(stream), close_(close) {
98 *stream_ << open <<
"\n";
101 virtual ~AutoClosedCommand() { *stream_ << close_ <<
"\n"; }
104 UnownedPtr<fxcrt::ostringstream>
const stream_;
108class AutoClosedQCommand
final :
public AutoClosedCommand {
110 explicit AutoClosedQCommand(fxcrt::ostringstream* stream)
111 : AutoClosedCommand(stream, kStateSaveOperator, kStateRestoreOperator) {}
112 ~AutoClosedQCommand()
override =
default;
115void WriteMove(fxcrt::ostringstream& stream,
const CFX_PointF& point) {
116 WritePoint(stream, point) <<
" " << kMoveToOperator <<
"\n";
119void WriteLine(fxcrt::ostringstream& stream,
const CFX_PointF& point) {
120 WritePoint(stream, point) <<
" " << kLineToOperator <<
"\n";
123void WriteClosedLoop(fxcrt::ostringstream& stream,
124 pdfium::span<
const CFX_PointF> points) {
125 WriteMove(stream, points[0]);
126 for (
const auto& point : points.subspan(1))
127 WriteLine(stream, point);
128 WriteLine(stream, points[0]);
131void WriteBezierCurve(fxcrt::ostringstream& stream,
135 WritePoint(stream, point1) <<
" ";
136 WritePoint(stream, point2) <<
" ";
137 WritePoint(stream, point3) <<
" " << kCurveToOperator <<
"\n";
140void WriteAppendRect(fxcrt::ostringstream& stream,
const CFX_FloatRect& rect) {
141 WriteRect(stream, rect) <<
" " << kAppendRectOperator <<
"\n";
145 fxcrt::ostringstream sColorStream;
150 sColorStream << color
.fColor1 <<
" " << kSetGrayStrokedOperator <<
"\n";
154 << color
.fColor3 <<
" " << kSetRGBStrokedOperator <<
"\n";
159 << kSetCMKYStrokedOperator <<
"\n";
166 fxcrt::ostringstream sColorStream;
171 sColorStream << color
.fColor1 <<
" " << kSetGrayOperator <<
"\n";
175 << color
.fColor3 <<
" " << kSetRGBOperator <<
"\n";
180 << kSetCMYKOperator <<
"\n";
187 const float fWidth = crBBox
.Width();
191 std::array<PointRow, 8> point_table = {{
192 {{CFX_PointF(0.28f, 0.52f), CFX_PointF(0.27f, 0.48f),
193 CFX_PointF(0.29f, 0.40f)}},
194 {{CFX_PointF(0.30f, 0.33f), CFX_PointF(0.31f, 0.29f),
195 CFX_PointF(0.31f, 0.28f)}},
196 {{CFX_PointF(0.39f, 0.28f), CFX_PointF(0.49f, 0.29f),
197 CFX_PointF(0.77f, 0.67f)}},
198 {{CFX_PointF(0.76f, 0.68f), CFX_PointF(0.78f, 0.69f),
199 CFX_PointF(0.76f, 0.75f)}},
200 {{CFX_PointF(0.76f, 0.75f), CFX_PointF(0.73f, 0.80f),
201 CFX_PointF(0.68f, 0.75f)}},
202 {{CFX_PointF(0.68f, 0.74f), CFX_PointF(0.68f, 0.74f),
203 CFX_PointF(0.44f, 0.47f)}},
204 {{CFX_PointF(0.43f, 0.47f), CFX_PointF(0.40f, 0.47f),
205 CFX_PointF(0.41f, 0.58f)}},
206 {{CFX_PointF(0.40f, 0.60f), CFX_PointF(0.28f, 0.66f),
207 CFX_PointF(0.30f, 0.56f)}},
210 for (PointRow& row : point_table) {
211 for (CFX_PointF& point : row) {
212 point.x = point.x * fWidth + crBBox.left;
213 point.y = point.y * fHeight + crBBox.bottom;
217 fxcrt::ostringstream csAP;
218 WriteMove(csAP, point_table[0][0]);
220 for (size_t i = 0; i < point_table.size(); ++i) {
221 size_t nNext = i < point_table.size() - 1 ? i + 1 : 0;
222 const CFX_PointF& pt_next = point_table[nNext][0];
223 float px1 = point_table[i][1].x - point_table[i][0].x;
224 float py1 = point_table[i][1].y - point_table[i][0].y;
225 float px2 = point_table[i][2].x - pt_next.x;
226 float py2 = point_table[i][2].y - pt_next.y;
238 fxcrt::ostringstream csAP;
243 CFX_PointF pt1(crBBox.left, crBBox.bottom + fHeight / 2);
244 CFX_PointF pt2(crBBox.left + fWidth / 2, crBBox.top);
245 CFX_PointF pt3(crBBox.right, crBBox.bottom + fHeight / 2);
246 CFX_PointF pt4(crBBox.left + fWidth / 2, crBBox.bottom);
248 WriteMove(csAP, pt1);
250 float px = pt2.x - pt1.x;
251 float py = pt2.y - pt1.y;
253 WriteBezierCurve(csAP, {pt1.x, pt1.y + py *
FXSYS_BEZIER},
259 WriteBezierCurve(csAP, {pt2.x + px *
FXSYS_BEZIER, pt2.y},
265 WriteBezierCurve(csAP, {pt3.x, pt3.y - py *
FXSYS_BEZIER},
271 WriteBezierCurve(csAP, {pt4.x - px *
FXSYS_BEZIER, pt4.y},
278 fxcrt::ostringstream csAP;
280 WriteMove(csAP, {crBBox
.left, crBBox
.top});
289 fxcrt::ostringstream csAP;
294 const CFX_PointF points[] = {{crBBox.left, crBBox.bottom + fHeight / 2},
295 {crBBox.left + fWidth / 2, crBBox.top},
296 {crBBox.right, crBBox.bottom + fHeight / 2},
297 {crBBox.left + fWidth / 2, crBBox.bottom}};
298 WriteClosedLoop(csAP, points);
304 fxcrt::ostringstream csAP;
306 const CFX_PointF points[] = {{crBBox.left, crBBox.top},
307 {crBBox.right, crBBox.top},
308 {crBBox.right, crBBox.bottom},
309 {crBBox.left, crBBox.bottom}};
310 WriteClosedLoop(csAP, points);
316 fxcrt::ostringstream csAP;
319 CFX_PointF ptCenter = CFX_PointF((crBBox.left + crBBox.right) / 2.0f,
320 (crBBox.top + crBBox.bottom) / 2.0f);
324 for (
auto& point : points) {
326 ptCenter + CFX_PointF(fRadius * cosf(fAngle), fRadius * sinf(fAngle));
330 WriteMove(csAP, points[0]);
331 WriteLine(csAP, points[2]);
332 WriteLine(csAP, points[4]);
333 WriteLine(csAP, points[1]);
334 WriteLine(csAP, points[3]);
335 WriteLine(csAP, points[0]);
341 fxcrt::ostringstream csAP;
350 CFX_Matrix rotate_matrix
(cos(fRotate)
, sin(fRotate)
, -sin(fRotate)
,
351 cos(fRotate)
, crBBox
.left + fWidth / 2
,
353 WriteMatrix(csAP, rotate_matrix) <<
" " << kConcatMatrixOperator <<
"\n";
355 WriteMove(csAP, pt1);
357 float px = pt2.x - pt1.x;
358 float py = pt2.y - pt1.y;
360 WriteBezierCurve(csAP, {pt1.x, pt1.y + py *
FXSYS_BEZIER},
366 WriteBezierCurve(csAP, {pt2.x + px *
FXSYS_BEZIER, pt2.y},
374 fxcrt::ostringstream sAP;
376 AutoClosedQCommand q(&sAP);
377 sAP << GetFillColorAppStream(crText) << GetAP_Check(rcBBox) << kFillOperator
385 fxcrt::ostringstream sAP;
387 AutoClosedQCommand q(&sAP);
388 sAP << GetFillColorAppStream(crText) << GetAP_Circle(rcBBox)
389 << kFillOperator <<
"\n";
396 fxcrt::ostringstream sAP;
398 AutoClosedQCommand q(&sAP);
399 sAP << GetStrokeColorAppStream(crText) << GetAP_Cross(rcBBox)
400 << kStrokeOperator <<
"\n";
407 fxcrt::ostringstream sAP;
409 AutoClosedQCommand q(&sAP);
410 sAP <<
"1 " << kSetLineWidthOperator <<
"\n"
411 << GetFillColorAppStream(crText) << GetAP_Diamond(rcBBox)
412 << kFillOperator <<
"\n";
419 fxcrt::ostringstream sAP;
421 AutoClosedQCommand q(&sAP);
422 sAP << GetFillColorAppStream(crText) << GetAP_Square(rcBBox)
423 << kFillOperator <<
"\n";
430 fxcrt::ostringstream sAP;
432 AutoClosedQCommand q(&sAP);
433 sAP << GetFillColorAppStream(crText) << GetAP_Star(rcBBox) << kFillOperator
441 fxcrt::ostringstream sAppStream;
442 ByteString sColor = GetFillColorAppStream(color);
443 if (sColor.GetLength() > 0) {
444 AutoClosedQCommand q(&sAppStream);
445 sAppStream << sColor << GetAP_Circle(rect) << kFillOperator <<
"\n";
457 fxcrt::ostringstream sAppStream;
461 AutoClosedQCommand q(&sAppStream);
463 float fHalfWidth = fWidth / 2.0f;
466 float div = fHalfWidth * 0.75f;
471 sColor
= GetStrokeColorAppStream(color);
472 if (sColor.GetLength() > 0) {
473 AutoClosedQCommand q2(&sAppStream);
474 sAppStream << fWidth <<
" " << kSetLineWidthOperator <<
"\n"
475 << sColor << GetAP_Circle(rect_by_2) <<
" "
476 << kStrokeOperator <<
"\n";
480 sColor
= GetStrokeColorAppStream(color);
481 if (sColor.GetLength() > 0) {
482 AutoClosedQCommand q2(&sAppStream);
483 sAppStream << fWidth <<
" " << kSetLineWidthOperator <<
"\n"
485 << dash
.nPhase <<
" " << kSetDashOperator <<
"\n"
486 << sColor << GetAP_Circle(rect_by_2) <<
" "
487 << kStrokeOperator <<
"\n";
491 sColor
= GetStrokeColorAppStream(color);
492 if (sColor.GetLength() > 0) {
493 AutoClosedQCommand q2(&sAppStream);
494 sAppStream << fHalfWidth <<
" " << kSetLineWidthOperator <<
"\n"
495 << sColor << GetAP_Circle(rect) <<
" " << kStrokeOperator
498 sColor
= GetStrokeColorAppStream(crLeftTop);
499 if (sColor.GetLength() > 0) {
500 AutoClosedQCommand q2(&sAppStream);
501 sAppStream << fHalfWidth <<
" " << kSetLineWidthOperator <<
"\n"
502 << sColor << GetAP_HalfCircle(rect_by_75,
FXSYS_PI / 4.0f)
503 <<
" " << kStrokeOperator <<
"\n";
505 sColor
= GetStrokeColorAppStream(crRightBottom);
506 if (sColor.GetLength() > 0) {
507 AutoClosedQCommand q2(&sAppStream);
508 sAppStream << fHalfWidth <<
" " << kSetLineWidthOperator <<
"\n"
510 << GetAP_HalfCircle(rect_by_75,
FXSYS_PI * 5 / 4.0f) <<
" "
511 << kStrokeOperator <<
"\n";
515 sColor
= GetStrokeColorAppStream(color);
516 if (sColor.GetLength() > 0) {
517 AutoClosedQCommand q2(&sAppStream);
518 sAppStream << fHalfWidth <<
" " << kSetLineWidthOperator <<
"\n"
519 << sColor << GetAP_Circle(rect) <<
" " << kStrokeOperator
522 sColor
= GetStrokeColorAppStream(crLeftTop);
523 if (sColor.GetLength() > 0) {
524 AutoClosedQCommand q2(&sAppStream);
525 sAppStream << fHalfWidth <<
" " << kSetLineWidthOperator <<
"\n"
526 << sColor << GetAP_HalfCircle(rect_by_75,
FXSYS_PI / 4.0f)
527 <<
" " << kStrokeOperator <<
"\n";
529 sColor
= GetStrokeColorAppStream(crRightBottom);
530 if (sColor.GetLength() > 0) {
531 AutoClosedQCommand q2(&sAppStream);
532 sAppStream << fHalfWidth <<
" " << kSetLineWidthOperator <<
"\n"
534 << GetAP_HalfCircle(rect_by_75,
FXSYS_PI * 5 / 4.0f) <<
" "
535 << kStrokeOperator <<
"\n";
548 case CheckStyle::kCheck:
549 return GetAppStream_Check(rcCenter, crText);
550 case CheckStyle::kCircle:
552 return GetAppStream_Circle(rcCenter, crText);
553 case CheckStyle::kCross:
554 return GetAppStream_Cross(rcCenter, crText);
555 case CheckStyle::kDiamond:
557 return GetAppStream_Diamond(rcCenter, crText);
558 case CheckStyle::kSquare:
560 return GetAppStream_Square(rcCenter, crText);
561 case CheckStyle::kStar:
563 return GetAppStream_Star(rcCenter, crText);
572 case CheckStyle::kCheck:
573 return GetAppStream_Check(rcCenter, crText);
574 case CheckStyle::kCircle:
576 return GetAppStream_Circle(rcCenter, crText);
577 case CheckStyle::kCross:
578 return GetAppStream_Cross(rcCenter, crText);
579 case CheckStyle::kDiamond:
581 return GetAppStream_Diamond(rcCenter, crText);
582 case CheckStyle::kSquare:
584 return GetAppStream_Square(rcCenter, crText);
585 case CheckStyle::kStar:
587 return GetAppStream_Star(rcCenter, crText);
598 if (sFontAlias.GetLength() <= 0 || fFontSize <= 0)
601 fxcrt::ostringstream sRet;
602 sRet <<
"/" << sFontAlias <<
" " << fFontSize <<
" "
603 << kSetTextFontAndSizeOperator <<
"\n";
608 if (strWords.IsEmpty())
610 return PDF_EncodeString(strWords) +
" " + kShowTextOperator +
"\n";
620 fxcrt::ostringstream sEditStream;
621 int32_t nCurFontIndex = -1;
631 if (!sWords.IsEmpty()) {
632 sEditStream << GetWordRenderString(sWords.AsStringView());
638 ptNew =
CFX_PointF(word.ptWord.x + ptOffset.x,
639 word.ptWord.y + ptOffset.y);
643 ptNew =
CFX_PointF(line.ptLine.x + ptOffset.x,
644 line.ptLine.y + ptOffset.y);
647 if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
648 WritePoint(sEditStream, {ptNew.x - ptOld.x, ptNew.y - ptOld.y})
649 <<
" " << kMoveTextPositionOperator <<
"\n";
658 if (!sWords.IsEmpty()) {
659 sEditStream << GetWordRenderString(sWords.AsStringView());
674 CFX_PointF(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);
676 if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
677 WritePoint(sEditStream, {ptNew.x - ptOld.x, ptNew.y - ptOld.y})
678 <<
" " << kMoveTextPositionOperator <<
"\n";
686 sEditStream << GetWordRenderString(
693 if (!sWords.IsEmpty())
694 sEditStream << GetWordRenderString(sWords.AsStringView());
696 fxcrt::ostringstream sAppStream;
697 if (sEditStream.tellp() > 0) {
698 sAppStream << sEditStream.str();
711 auto pWnd =
std::make_unique<
CPWL_Wnd>(cp,
nullptr);
713 if (!pWnd->Move(rcIcon,
false,
false))
716 auto pPDFIcon =
std::make_unique<CPDF_Icon>(
std::move(pIconStream));
717 ByteString sAlias = pPDFIcon->GetImageAlias();
718 if (sAlias.GetLength() <= 0)
722 const CFX_SizeF image_size = pPDFIcon->GetImageSize();
723 const CFX_Matrix mt = pPDFIcon->GetImageMatrix().GetInverse();
724 const CFX_VectorF scale = fit.GetScale(image_size, rcPlate);
725 const CFX_VectorF offset = fit.GetImageOffset(image_size, scale, rcPlate);
727 fxcrt::ostringstream str;
729 AutoClosedQCommand q(&str);
730 WriteAppendRect(str, rcPlate);
731 str << kSetNonZeroWindingClipOperator <<
" "
732 << kEndPathNoFillOrStrokeOperator <<
"\n";
734 CFX_Matrix scale_matrix(scale.x, 0, 0, scale.y, rcPlate
.left + offset.x,
736 WriteMatrix(str, scale_matrix) <<
" " << kConcatMatrixOperator <<
"\n";
737 WriteMatrix(str, mt) <<
" " << kConcatMatrixOperator <<
"\n";
739 str <<
"0 " << kSetGrayOperator <<
" 0 " << kSetGrayStrokedOperator <<
" 1 "
740 << kSetLineWidthOperator <<
" /" << sAlias <<
" "
741 << kInvokeNamedXObjectOperator <<
"\n";
754 ButtonStyle nLayOut) {
755 const float fAutoFontScale = 1.0f / 3.0f;
758 pEdit->SetFontMap(pFontMap);
759 pEdit->SetAlignmentH(1);
760 pEdit->SetAlignmentV(1);
761 pEdit->SetMultiLine(
false);
762 pEdit->SetAutoReturn(
false);
764 pEdit->SetAutoFontSize(
true);
766 pEdit->SetFontSize(fFontSize);
769 pEdit->SetText(sLabel);
776 float fHeight = 0.0f;
779 case ButtonStyle::kLabel:
782 case ButtonStyle::kIcon:
785 case ButtonStyle::kIconTopLabelBottom:
790 rcBBox
.bottom + fHeight * fAutoFontScale
);
809 case ButtonStyle::kIconBottomLabelTop:
834 case ButtonStyle::kIconLeftLabelRight:
838 if (rcLabelContent
.Width() < fWidth * fAutoFontScale) {
844 if (rcLabelContent
.Width() < fWidth) {
868 case ButtonStyle::kIconRightLabelLeft:
872 if (rcLabelContent
.Width() < fWidth * fAutoFontScale) {
874 rcBBox
.left + fWidth * fAutoFontScale
,
879 if (rcLabelContent
.Width() < fWidth) {
904 case ButtonStyle::kLabelOverIcon:
910 fxcrt::ostringstream sTemp;
911 sTemp << GenerateIconAppStream(IconFit,
std::move(pIconStream), rcIcon);
914 pEdit->SetPlateRect(rcLabel);
917 GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, 0.0f),
true, 0);
918 if (sEdit.GetLength() > 0) {
919 AutoClosedCommand bt(&sTemp, kTextBeginOperator, kTextEndOperator);
920 sTemp << GetFillColorAppStream(crText) << sEdit;
924 if (sTemp.tellp() <= 0)
927 fxcrt::ostringstream sAppStream;
929 AutoClosedQCommand q(&sAppStream);
930 WriteAppendRect(sAppStream, rcBBox);
931 sAppStream << kSetNonZeroWindingClipOperator <<
" "
932 << kEndPathNoFillOrStrokeOperator <<
"\n";
933 sAppStream << sTemp.str().c_str();
945 fxcrt::ostringstream sAppStream;
948 float fLeft = rect
.left;
949 float fRight = rect
.right;
950 float fTop = rect
.top;
954 float fHalfWidth = fWidth / 2.0f;
955 AutoClosedQCommand q(&sAppStream);
959 sColor
= GetFillColorAppStream(color);
960 if (sColor.GetLength() > 0) {
961 sAppStream << sColor;
962 WriteAppendRect(sAppStream, {fLeft, fBottom, fRight, fTop});
963 WriteAppendRect(sAppStream, {fLeft + fWidth, fBottom + fWidth,
964 fRight - fWidth, fTop - fWidth});
965 sAppStream << kFillEvenOddOperator <<
"\n";
969 sColor
= GetStrokeColorAppStream(color);
970 if (sColor.GetLength() > 0) {
971 sAppStream << sColor;
972 sAppStream << fWidth <<
" " << kSetLineWidthOperator <<
" ["
974 <<
" " << kSetDashOperator <<
"\n";
976 {fLeft + fWidth / 2, fBottom + fWidth / 2},
977 {fLeft + fWidth / 2, fTop - fWidth / 2},
978 {fRight - fWidth / 2, fTop - fWidth / 2},
979 {fRight - fWidth / 2, fBottom + fWidth / 2}};
980 WriteClosedLoop(sAppStream, points);
981 sAppStream << kStrokeOperator <<
"\n";
986 sColor
= GetFillColorAppStream(crLeftTop);
987 if (sColor.GetLength() > 0) {
988 sAppStream << sColor;
989 WriteMove(sAppStream, {fLeft + fHalfWidth, fBottom + fHalfWidth});
990 WriteLine(sAppStream, {fLeft + fHalfWidth, fTop - fHalfWidth});
991 WriteLine(sAppStream, {fRight - fHalfWidth, fTop - fHalfWidth});
992 WriteLine(sAppStream,
993 {fRight - fHalfWidth * 2, fTop - fHalfWidth * 2});
994 WriteLine(sAppStream,
995 {fLeft + fHalfWidth * 2, fTop - fHalfWidth * 2});
996 WriteLine(sAppStream,
997 {fLeft + fHalfWidth * 2, fBottom + fHalfWidth * 2});
998 sAppStream << kFillOperator <<
"\n";
1000 sColor
= GetFillColorAppStream(crRightBottom);
1001 if (sColor.GetLength() > 0) {
1002 sAppStream << sColor;
1003 WriteMove(sAppStream, {fRight - fHalfWidth, fTop - fHalfWidth});
1004 WriteLine(sAppStream, {fRight - fHalfWidth, fBottom + fHalfWidth});
1005 WriteLine(sAppStream, {fLeft + fHalfWidth, fBottom + fHalfWidth});
1006 WriteLine(sAppStream,
1007 {fLeft + fHalfWidth * 2, fBottom + fHalfWidth * 2});
1008 WriteLine(sAppStream,
1009 {fRight - fHalfWidth * 2, fBottom + fHalfWidth * 2});
1010 WriteLine(sAppStream,
1011 {fRight - fHalfWidth * 2, fTop - fHalfWidth * 2});
1012 sAppStream << kFillOperator <<
"\n";
1014 sColor
= GetFillColorAppStream(color);
1015 if (sColor.GetLength() > 0) {
1016 sAppStream << sColor;
1017 WriteAppendRect(sAppStream, {fLeft, fBottom, fRight, fTop});
1018 WriteAppendRect(sAppStream, {fLeft + fHalfWidth, fBottom + fHalfWidth,
1019 fRight - fHalfWidth, fTop - fHalfWidth});
1020 sAppStream << kFillEvenOddOperator <<
"\n";
1024 sColor
= GetStrokeColorAppStream(color);
1025 if (sColor.GetLength() > 0) {
1026 sAppStream << sColor;
1027 sAppStream << fWidth <<
" " << kSetLineWidthOperator <<
"\n";
1028 WriteMove(sAppStream, {fLeft, fBottom + fWidth / 2});
1029 WriteLine(sAppStream, {fRight, fBottom + fWidth / 2});
1030 sAppStream << kStrokeOperator <<
"\n";
1042 fxcrt::ostringstream sAppStream;
1044 AutoClosedQCommand q(&sAppStream);
1045 sAppStream << GetFillColorAppStream(
1048 WriteAppendRect(sAppStream, rcBBox);
1049 sAppStream << kFillOperator <<
"\n";
1053 AutoClosedQCommand q(&sAppStream);
1054 sAppStream << GetBorderAppStreamInternal(
1061 CFX_PointF ptCenter = CFX_PointF((rcBBox.left + rcBBox.right) / 2,
1062 (rcBBox.top + rcBBox.bottom) / 2);
1065 AutoClosedQCommand q(&sAppStream);
1066 const CFX_PointF points[] = {{ptCenter.x - 3, ptCenter.y + 1.5f},
1067 {ptCenter.x + 3, ptCenter.y + 1.5f},
1068 {ptCenter.x, ptCenter.y - 1.5f}};
1069 sAppStream <<
" 0 " << kSetGrayOperator <<
"\n";
1070 WriteClosedLoop(sAppStream, points);
1071 sAppStream << kFillOperator <<
"\n";
1079 fxcrt::ostringstream sAppStream;
1080 ByteString sColor = GetFillColorAppStream(color);
1081 if (sColor.GetLength() > 0) {
1082 AutoClosedQCommand q(&sAppStream);
1083 sAppStream << sColor;
1084 WriteAppendRect(sAppStream, rect);
1085 sAppStream << kFillOperator <<
"\n";
1091void SetDefaultIconName(CPDF_Stream* pIcon,
const char* name) {
1096 if (pImageDict->KeyExist(
"Name"))
1099 pImageDict->SetNewFor<CPDF_String>(
"Name", name);
1102std::optional<CheckStyle> CheckStyleFromCaption(
const WideString& caption) {
1103 if (caption.IsEmpty())
1104 return std::nullopt;
1107 switch (caption[0]) {
1109 return CheckStyle::kCheck;
1111 return CheckStyle::kCross;
1113 return CheckStyle::kStar;
1115 return CheckStyle::kCircle;
1117 return CheckStyle::kSquare;
1119 return CheckStyle::kDiamond;
1121 return std::nullopt;
1136 ButtonStyle nLayout = ButtonStyle::kLabel;
1139 nLayout = ButtonStyle::kIcon;
1142 nLayout = ButtonStyle::kIconTopLabelBottom;
1145 nLayout = ButtonStyle::kIconBottomLabelTop;
1148 nLayout = ButtonStyle::kIconLeftLabelRight;
1151 nLayout = ButtonStyle::kIconRightLabelLeft;
1154 nLayout = ButtonStyle::kLabelOverIcon;
1157 nLayout = ButtonStyle::kLabel;
1164 float fBorderWidth =
static_cast<
float>(widget_->GetBorderWidth());
1169 BorderStyle nBorderStyle = widget_->GetBorderStyle();
1170 switch (nBorderStyle) {
1177 crRightBottom
= crBackground
/ 2.0f;
1196 if (font.has_value())
1197 csNameTag = font.value();
1218 pNormalIcon = pControl->GetNormalIcon();
1221 pRolloverIcon = pControl->GetRolloverIcon();
1224 pDownIcon = pControl->GetDownIcon();
1226 SetDefaultIconName(pNormalIcon.Get(),
"ImgA");
1227 SetDefaultIconName(pRolloverIcon.Get(),
"ImgB");
1228 SetDefaultIconName(pDownIcon.Get(),
"ImgC");
1232 CPDF_BAFontMap font_map(widget_->GetPDFPage()->GetDocument(),
1233 widget_->GetPDFAnnot()->GetMutableAnnotDict(),
"N");
1235 GetRectFillAppStream(rcWindow, crBackground)
+
1236 GetBorderAppStreamInternal(rcWindow, fBorderWidth, crBorder, crLeftTop,
1237 crRightBottom, nBorderStyle, dsBorder) +
1239 &font_map, pNormalIcon, iconFit, csNormalCaption,
1240 crText, fFontSize, nLayout);
1244 AddImage(
"N", pNormalIcon.Get());
1253 if (csRolloverCaption.IsEmpty() && !pRolloverIcon) {
1254 csRolloverCaption
= csNormalCaption;
1255 pRolloverIcon = pNormalIcon;
1259 CPDF_BAFontMap font_map(widget_->GetPDFPage()->GetDocument(),
1260 widget_->GetPDFAnnot()->GetMutableAnnotDict(),
"R");
1262 GetRectFillAppStream(rcWindow, crBackground)
+
1263 GetBorderAppStreamInternal(rcWindow, fBorderWidth, crBorder, crLeftTop,
1264 crRightBottom, nBorderStyle, dsBorder) +
1266 &font_map, pRolloverIcon, iconFit,
1267 csRolloverCaption, crText, fFontSize, nLayout);
1271 AddImage(
"R", pRolloverIcon.Get());
1273 if (csDownCaption.IsEmpty() && !pDownIcon) {
1274 csDownCaption
= csNormalCaption;
1275 pDownIcon = pNormalIcon;
1278 switch (nBorderStyle) {
1281 crLeftTop
= crRightBottom;
1282 crRightBottom
= crTemp;
1295 CPDF_BAFontMap font_map(widget_->GetPDFPage()->GetDocument(),
1296 widget_->GetPDFAnnot()->GetMutableAnnotDict(),
"D");
1298 GetRectFillAppStream(rcWindow, crBackground
- 0.25f)
+
1299 GetBorderAppStreamInternal(rcWindow, fBorderWidth, crBorder, crLeftTop,
1300 crRightBottom, nBorderStyle, dsBorder) +
1302 &font_map, pDownIcon, iconFit, csDownCaption,
1303 crText, fFontSize, nLayout);
1307 AddImage(
"D", pDownIcon.Get());
1315 float fBorderWidth =
static_cast<
float>(widget_->GetBorderWidth());
1320 BorderStyle nBorderStyle = widget_->GetBorderStyle();
1321 switch (nBorderStyle) {
1328 crRightBottom
= crBackground
/ 2.0f;
1341 std::optional<
CFX_Color> color = pControl->GetDefaultAppearance().GetColor();
1344 CheckStyle nStyle = CheckStyleFromCaption(pControl->GetNormalCaption())
1345 .value_or(CheckStyle::kCheck);
1347 GetRectFillAppStream(rcWindow, crBackground)
+
1348 GetBorderAppStreamInternal(rcWindow, fBorderWidth, crBorder, crLeftTop,
1349 crRightBottom, nBorderStyle, dsBorder);
1353 switch (nBorderStyle) {
1356 crLeftTop
= crRightBottom;
1357 crRightBottom
= crTemp;
1370 GetRectFillAppStream(rcWindow, crBackground
- 0.25f)
+
1371 GetBorderAppStreamInternal(rcWindow, fBorderWidth, crBorder, crLeftTop,
1372 crRightBottom, nBorderStyle, dsBorder);
1376 csAP_N_ON
+= GetCheckBoxAppStream(rcClient, nStyle, crText);
1377 csAP_D_ON
+= GetCheckBoxAppStream(rcClient, nStyle, crText);
1380 Write(
"N", csAP_N_OFF,
"Off");
1383 Write(
"D", csAP_D_OFF,
"Off");
1387 widget_->SetAppStateOff();
1394 float fBorderWidth =
static_cast<
float>(widget_->GetBorderWidth());
1399 BorderStyle nBorderStyle = widget_->GetBorderStyle();
1400 switch (nBorderStyle) {
1407 crRightBottom
= crBackground
/ 2.0f;
1420 std::optional<
CFX_Color> color = pControl->GetDefaultAppearance().GetColor();
1422 CheckStyle nStyle = CheckStyleFromCaption(pControl->GetNormalCaption())
1423 .value_or(CheckStyle::kCircle);
1427 if (nStyle == CheckStyle::kCircle) {
1430 crRightBottom
= crBackground
- 0.25f;
1437 GetCircleFillAppStream(rcCenter, crBackground)
+
1438 GetCircleBorderAppStream(rcCenter, fBorderWidth, crBorder, crLeftTop,
1439 crRightBottom, nBorderStyle, dsBorder);
1442 GetRectFillAppStream(rcWindow, crBackground)
+
1443 GetBorderAppStreamInternal(rcWindow, fBorderWidth, crBorder, crLeftTop,
1444 crRightBottom, nBorderStyle, dsBorder);
1449 switch (nBorderStyle) {
1452 crLeftTop
= crRightBottom;
1453 crRightBottom
= crTemp;
1467 if (nStyle == CheckStyle::kCircle) {
1470 crLeftTop
= crBackground
- 0.25f;
1472 crBK
= crBackground;
1479 GetCircleFillAppStream(rcCenter, crBK)
+
1480 GetCircleBorderAppStream(rcCenter, fBorderWidth, crBorder, crLeftTop,
1481 crRightBottom, nBorderStyle, dsBorder);
1484 GetRectFillAppStream(rcWindow, crBackground
- 0.25f)
+
1485 GetBorderAppStreamInternal(rcWindow, fBorderWidth, crBorder, crLeftTop,
1486 crRightBottom, nBorderStyle, dsBorder);
1491 ByteString app_stream = GetRadioButtonAppStream(rcClient, nStyle, crText);
1492 csAP_N_ON
+= app_stream;
1493 csAP_D_ON
+= app_stream;
1496 Write(
"N", csAP_N_OFF,
"Off");
1499 Write(
"D", csAP_D_OFF,
"Off");
1503 widget_->SetAppStateOff();
1509 fxcrt::ostringstream sBody;
1517 CPDF_BAFontMap font_map(widget_->GetPDFPage()->GetDocument(),
1518 widget_->GetPDFAnnot()->GetMutableAnnotDict(),
"N");
1521 pEdit->EnableRefresh(
false);
1522 pEdit->SetFontMap(&font_map);
1528 pEdit->SetPlateRect(rcEdit);
1529 pEdit->SetAlignmentV(1);
1531 float fFontSize = widget_->GetFontSize();
1533 pEdit->SetAutoFontSize(
true);
1535 pEdit->SetFontSize(fFontSize);
1537 pEdit->Initialize();
1538 if (sValue.has_value()) {
1539 pEdit->SetText(sValue.value());
1551 ByteString sEdit = GetEditAppStream(pEdit.get(), CFX_PointF(),
true, 0);
1552 if (sEdit.GetLength() > 0) {
1554 AutoClosedCommand bmc(&sBody, kMarkedSequenceBeginOperator,
1555 kMarkedSequenceEndOperator);
1556 AutoClosedQCommand q(&sBody);
1560 WriteAppendRect(sBody, rcEdit);
1561 sBody << kSetNonZeroWindingClipOperator <<
"\n"
1562 << kEndPathNoFillOrStrokeOperator <<
"\n";
1565 CFX_Color crText = widget_->GetTextPWLColor();
1566 AutoClosedCommand bt(&sBody, kTextBeginOperator, kTextEndOperator);
1567 sBody << GetFillColorAppStream(crText) << sEdit;
1570 sBody << GetDropButtonAppStream(rcButton);
1572 GetBackgroundAppStream()
+ GetBorderAppStream()
+ ByteString(sBody),
1580 fxcrt::ostringstream sBody;
1583 CPDF_BAFontMap font_map(widget_->GetPDFPage()->GetDocument(),
1584 widget_->GetPDFAnnot()->GetMutableAnnotDict(),
"N");
1587 pEdit->EnableRefresh(
false);
1588 pEdit->SetFontMap(&font_map);
1591 float fFontSize = widget_->GetFontSize();
1593 pEdit->Initialize();
1595 fxcrt::ostringstream sList;
1596 float fy = rcClient
.top;
1602 for (int32_t i = nTop; i < nCount; ++i) {
1603 bool bSelected =
false;
1604 for (int32_t j = 0; j < nSelCount; ++j) {
1621 AutoClosedQCommand q(&sList);
1624 WriteAppendRect(sList, rcItem);
1625 sList << kFillOperator <<
"\n";
1628 AutoClosedCommand bt(&sList, kTextBeginOperator, kTextEndOperator);
1630 << GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy),
true, 0);
1632 CFX_Color crText = widget_->GetTextPWLColor();
1634 AutoClosedCommand bt(&sList, kTextBeginOperator, kTextEndOperator);
1635 sList << GetFillColorAppStream(crText)
1636 << GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy),
true, 0);
1642 if (sList.tellp() > 0) {
1644 AutoClosedCommand bmc(&sBody, kMarkedSequenceBeginOperator,
1645 kMarkedSequenceEndOperator);
1646 AutoClosedQCommand q(&sBody);
1648 WriteAppendRect(sBody, rcClient);
1649 sBody << kSetNonZeroWindingClipOperator <<
"\n"
1650 << kEndPathNoFillOrStrokeOperator <<
"\n"
1654 GetBackgroundAppStream()
+ GetBorderAppStream()
+ ByteString(sBody),
1661 fxcrt::ostringstream sBody;
1662 fxcrt::ostringstream sLines;
1665 CPDF_BAFontMap font_map(widget_->GetPDFPage()->GetDocument(),
1666 widget_->GetPDFAnnot()->GetMutableAnnotDict(),
"N");
1669 pEdit->EnableRefresh(
false);
1670 pEdit->SetFontMap(&font_map);
1673 pEdit->SetPlateRect(rcClient);
1679 pEdit->SetMultiLine(
true);
1680 pEdit->SetAutoReturn(
true);
1682 pEdit->SetAlignmentV(1);
1685 uint16_t subWord = 0;
1688 pEdit->SetPasswordChar(subWord);
1693 float fFontSize = widget_->GetFontSize();
1695#ifdef PDF_ENABLE_XFA
1696 if (!sValue.has_value() && widget_->GetMixXFAWidget())
1697 sValue = widget_->GetValue();
1702 pEdit->SetCharArray(nMaxLen);
1708 if (sValue.has_value())
1709 nMaxLen =
pdfium::checked_cast<
int>(sValue.value().GetLength());
1710 pEdit->SetLimitChar(nMaxLen);
1715 pEdit->SetAutoFontSize(
true);
1717 pEdit->SetFontSize(fFontSize);
1719 pEdit->Initialize();
1725 GetEditAppStream(pEdit.get(), CFX_PointF(), !bCharArray, subWord);
1727 if (sEdit.GetLength() > 0) {
1729 AutoClosedCommand bmc(&sBody, kMarkedSequenceBeginOperator,
1730 kMarkedSequenceEndOperator);
1731 AutoClosedQCommand q(&sBody);
1735 WriteAppendRect(sBody, rcClient);
1736 sBody << kSetNonZeroWindingClipOperator <<
"\n"
1737 << kEndPathNoFillOrStrokeOperator <<
"\n";
1739 CFX_Color crText = widget_->GetTextPWLColor();
1741 AutoClosedCommand bt(&sBody, kTextBeginOperator, kTextEndOperator);
1742 sBody << GetFillColorAppStream(crText) << sEdit;
1746 switch (widget_->GetBorderStyle()) {
1747 case BorderStyle::kSolid: {
1749 GetStrokeColorAppStream(widget_->GetBorderPWLColor());
1750 if (sColor.GetLength() > 0) {
1751 AutoClosedQCommand q(&sLines);
1752 sLines << widget_->GetBorderWidth() <<
" " << kSetLineWidthOperator
1754 << GetStrokeColorAppStream(widget_->GetBorderPWLColor())
1755 <<
" 2 " << kSetLineCapStyleOperator <<
" 0 "
1756 << kSetLineJoinStyleOperator <<
"\n";
1758 const float width = rcClient
.right - rcClient
.left;
1759 for (int32_t i = 1; i < nMaxLen; ++i) {
1760 const float left = rcClient
.left + (width / nMaxLen) * i;
1761 WriteMove(sLines, {left, rcClient
.bottom});
1762 WriteLine(sLines, {left, rcClient
.top});
1763 sLines << kStrokeOperator <<
"\n";
1768 case BorderStyle::kDash: {
1770 GetStrokeColorAppStream(widget_->GetBorderPWLColor());
1771 if (sColor.GetLength() > 0) {
1773 AutoClosedQCommand q(&sLines);
1774 sLines << widget_->GetBorderWidth() <<
" " << kSetLineWidthOperator
1776 << GetStrokeColorAppStream(widget_->GetBorderPWLColor()) <<
"["
1777 << dsBorder.nDash <<
" " << dsBorder.nGap <<
"] "
1778 << dsBorder.nPhase <<
" " << kSetDashOperator <<
"\n";
1780 const float width = rcClient
.right - rcClient
.left;
1781 for (int32_t i = 1; i < nMaxLen; ++i) {
1782 const float left = rcClient
.left + (width / nMaxLen) * i;
1783 WriteMove(sLines, {left, rcClient
.bottom});
1784 WriteLine(sLines, {left, rcClient
.top});
1785 sLines << kStrokeOperator <<
"\n";
1796 GetBackgroundAppStream()
+ GetBorderAppStream()
+ ByteString(sLines)
+
1802 const CPDF_Stream* pImage) {
1803 RetainPtr<CPDF_Stream> pStream = dict_->GetMutableStreamFor(sAPType);
1809 pStreamDict->GetOrCreateDictFor(
"Resources");
1810 auto pXObject = pStreamResList->SetNewFor<
CPDF_Dictionary>(
"XObject");
1811 pXObject->SetNewFor<CPDF_Reference>(sImageAlias,
1812 widget_->GetPageView()->GetPDFDocument(),
1813 pImage->GetObjNum());
1821 if (sAPState.IsEmpty()) {
1822 parent_dict = dict_;
1825 parent_dict = dict_->GetOrCreateDictFor(sAPType);
1831 RetainPtr<CPDF_Stream> stream = parent_dict->GetMutableStreamFor(key);
1832 CPDF_Document* doc = widget_->GetPageView()->GetPDFDocument();
1835 new_stream_dict->SetNewFor<CPDF_Name>(
"Type",
"XObject");
1836 new_stream_dict->SetNewFor<CPDF_Name>(
"Subtype",
"Form");
1837 new_stream_dict->SetNewFor<CPDF_Number>(
"FormType", 1);
1841 if (original_stream_dict) {
1843 original_stream_dict->GetDictFor(
"Resources");
1844 if (resources_dict) {
1845 new_stream_dict->SetFor(
"Resources", resources_dict->Clone());
1850 parent_dict->SetNewFor<CPDF_Reference>(key, doc, stream->GetObjNum());
1854 stream_dict->SetMatrixFor(
"Matrix", widget_->GetMatrix());
1855 stream_dict->SetRectFor(
"BBox", widget_->GetRotatedRect());
1856 stream->SetDataAndRemoveFilter(sContents.unsigned_span());
1860 dict_->RemoveFor(sAPType);
1864 CFX_Color crBackground = widget_->GetFillPWLColor();
1865 if (crBackground.nColorType != CFX_Color::Type::kTransparent)
1866 return GetRectFillAppStream(widget_->GetRotatedRect(), crBackground);
1873 CFX_Color crBorder = widget_->GetBorderPWLColor();
1874 CFX_Color crBackground = widget_->GetFillPWLColor();
1878 float fBorderWidth =
static_cast<
float>(widget_->GetBorderWidth());
1881 BorderStyle nBorderStyle = widget_->GetBorderStyle();
1882 switch (nBorderStyle) {
1889 crRightBottom
= crBackground
/ 2.0f;
1900 return GetBorderAppStreamInternal(rcWindow, fBorderWidth, crBorder, crLeftTop,
1901 crRightBottom, nBorderStyle, dsBorder);
fxcrt::ByteString ByteString
CFX_FloatRect GetCenterSquare() const
constexpr CFX_FloatRect(float l, float b, float r, float t)
void ScaleFromCenterPoint(float fScale)
CFX_FloatRect & operator=(const CFX_FloatRect &that)=default
CFX_FloatRect GetDeflated(float x, float y) const
constexpr CFX_Matrix(float a1, float b1, float c1, float d1, float e1, float f1)
void SetAsComboBox(std::optional< WideString > sValue)
void SetAsTextField(std::optional< WideString > sValue)
CPDFSDK_AppStream(CPDFSDK_Widget *widget, CPDF_Dictionary *dict)
RetainPtr< CPDF_Font > GetPDFFont(int32_t nFontIndex) override
std::map< ByteString, RetainPtr< CPDF_Object >, std::less<> > DictMap
bool IsModifiedAPStream(const CPDF_Stream *stream) const
RetainPtr< CPDF_Stream > CreateModifiedAPStream(RetainPtr< CPDF_Dictionary > dict)
bool GetFittingBounds() const
RetainPtr< const CPDF_Dictionary > GetDict() const
void SetAt(int32_t nWordIndex)
bool GetWord(CPVT_Word &word) const
bool GetLine(CPVT_Line &line) const
const CPVT_WordPlace & GetAt() const
ByteString GetPDFWordString(int32_t nFontIndex, uint16_t Word, uint16_t SubWord)
IPVT_FontMap * GetFontMap()
static float GetCharArrayAutoFontSize(const CPDF_Font *pFont, const CFX_FloatRect &rcPlate, int32_t nCharArray)
CreateParams(CFX_Timer::HandlerIface *timer_handler, IPWL_FillerNotify *filler_notify, ProviderIface *provider)
virtual ByteString GetPDFFontAlias(int32_t nFontIndex)=0
ByteString & operator+=(const ByteString &str)
ByteString & operator=(const ByteString &that)
ByteString & operator=(ByteString &&that) noexcept
WideString & operator=(WideString &&that) noexcept
WideString & operator=(const WideString &that)
CFX_VTemplate< float > CFX_VectorF
CFX_PTemplate< float > CFX_PointF
CFX_STemplate< float > CFX_SizeF
#define FXSYS_IsFloatBigger(fa, fb)
#define FXSYS_IsFloatZero(f)
ByteString operator+(const ByteString &str1, const ByteString &str2)
fxcrt::ByteStringView ByteStringView
CFX_Color operator/(float fColorDivide) const
CFX_Color operator-(float fColorSub) const
CFX_Color & operator=(const CFX_Color &that)=default
constexpr CFX_Color(Type type=CFX_Color::Type::kTransparent, float color1=0.0f, float color2=0.0f, float color3=0.0f, float color4=0.0f)
int32_t LineCmp(const CPVT_WordPlace &wp) const
CPWL_Dash(int32_t dash, int32_t gap, int32_t phase)
fxcrt::WideString WideString