Further split CPDF_GenerateAP::GenerateFormAP()
- Move /MK dictionary parsing into its own function.
- Move bounding box / matrix calculation into its own function.
- Move /DA string retrieval into its own function.
Change-Id: I23ade161f2bd72af3237dbedaf9a2088b7c4be08
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/126592
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfdoc/cpdf_generateap.cpp b/core/fpdfdoc/cpdf_generateap.cpp
index b66a947..609185f 100644
--- a/core/fpdfdoc/cpdf_generateap.cpp
+++ b/core/fpdfdoc/cpdf_generateap.cpp
@@ -105,6 +105,8 @@
return ByteString(font_stream);
}
+// ISO 32000-1:2008 spec, table 166.
+// ISO 32000-2:2020 spec, table 168.
struct BorderStyleInfo {
float width = 1;
BorderStyle style = BorderStyle::kSolid;
@@ -155,6 +157,100 @@
return border_style_info;
}
+// ISO 32000-1:2008 spec, table 189.
+// ISO 32000-2:2020 spec, table 192.
+struct AppearanceCharacteristics {
+ int rotation = 0; // In degrees.
+ CFX_Color border_color;
+ CFX_Color background_color;
+};
+
+AppearanceCharacteristics GetAppearanceCharacteristics(
+ const CPDF_Dictionary* mk_dict) {
+ AppearanceCharacteristics appearance_characteristics;
+ if (!mk_dict) {
+ return appearance_characteristics;
+ }
+
+ appearance_characteristics.rotation =
+ mk_dict->GetIntegerFor(pdfium::appearance::kR);
+
+ RetainPtr<const CPDF_Array> border_color_array =
+ mk_dict->GetArrayFor(pdfium::appearance::kBC);
+ if (border_color_array) {
+ appearance_characteristics.border_color =
+ fpdfdoc::CFXColorFromArray(*border_color_array);
+ }
+ RetainPtr<const CPDF_Array> background_color_array =
+ mk_dict->GetArrayFor(pdfium::appearance::kBG);
+ if (background_color_array) {
+ appearance_characteristics.background_color =
+ fpdfdoc::CFXColorFromArray(*background_color_array);
+ }
+ return appearance_characteristics;
+}
+
+struct AnnotationDimensionsAndColor {
+ CFX_FloatRect bbox;
+ CFX_Matrix matrix;
+ CFX_Color border_color;
+ CFX_Color background_color;
+};
+
+AnnotationDimensionsAndColor GetAnnotationDimensionsAndColor(
+ const CPDF_Dictionary* annot_dict) {
+ const AppearanceCharacteristics appearance_characteristics =
+ GetAppearanceCharacteristics(annot_dict->GetDictFor("MK"));
+ const CFX_FloatRect annot_rect =
+ annot_dict->GetRectFor(pdfium::annotation::kRect);
+
+ CFX_FloatRect bbox_rect;
+ CFX_Matrix matrix;
+ switch (appearance_characteristics.rotation % 360) {
+ case 0:
+ bbox_rect = CFX_FloatRect(0, 0, annot_rect.right - annot_rect.left,
+ annot_rect.top - annot_rect.bottom);
+ break;
+ case 90:
+ matrix = CFX_Matrix(0, 1, -1, 0, annot_rect.right - annot_rect.left, 0);
+ bbox_rect = CFX_FloatRect(0, 0, annot_rect.top - annot_rect.bottom,
+ annot_rect.right - annot_rect.left);
+ break;
+ case 180:
+ matrix = CFX_Matrix(-1, 0, 0, -1, annot_rect.right - annot_rect.left,
+ annot_rect.top - annot_rect.bottom);
+ bbox_rect = CFX_FloatRect(0, 0, annot_rect.right - annot_rect.left,
+ annot_rect.top - annot_rect.bottom);
+ break;
+ case 270:
+ matrix = CFX_Matrix(0, -1, 1, 0, 0, annot_rect.top - annot_rect.bottom);
+ bbox_rect = CFX_FloatRect(0, 0, annot_rect.top - annot_rect.bottom,
+ annot_rect.right - annot_rect.left);
+ break;
+ }
+
+ return {
+ .bbox = bbox_rect,
+ .matrix = matrix,
+ .border_color = appearance_characteristics.border_color,
+ .background_color = appearance_characteristics.background_color,
+ };
+}
+
+ByteString GetDefaultAppearanceString(CPDF_Dictionary* annot_dict,
+ CPDF_Dictionary* form_dict) {
+ ByteString default_appearance_string;
+ RetainPtr<const CPDF_Object> default_appearance_object =
+ CPDF_FormField::GetFieldAttrForDict(annot_dict, "DA");
+ if (default_appearance_object) {
+ default_appearance_string = default_appearance_object->GetString();
+ }
+ if (default_appearance_string.IsEmpty()) {
+ default_appearance_string = form_dict->GetByteStringFor("DA");
+ }
+ return default_appearance_string;
+}
+
ByteString GenerateEditAP(IPVT_FontMap* font_map,
CPVT_VariableText::Iterator* vt_iterator,
const CFX_PointF& offset,
@@ -974,15 +1070,8 @@
return;
}
- ByteString default_appearance_string;
- RetainPtr<const CPDF_Object> default_appearance_object =
- CPDF_FormField::GetFieldAttrForDict(annot_dict, "DA");
- if (default_appearance_object) {
- default_appearance_string = default_appearance_object->GetString();
- }
- if (default_appearance_string.IsEmpty()) {
- default_appearance_string = form_dict->GetByteStringFor("DA");
- }
+ const ByteString default_appearance_string =
+ GetDefaultAppearanceString(annot_dict, form_dict);
if (default_appearance_string.IsEmpty()) {
return;
}
@@ -1020,66 +1109,26 @@
return;
}
- CFX_FloatRect annot_rect = annot_dict->GetRectFor(pdfium::annotation::kRect);
- RetainPtr<const CPDF_Dictionary> mk_dict = annot_dict->GetDictFor("MK");
- const int32_t rotate =
- mk_dict ? mk_dict->GetIntegerFor(pdfium::appearance::kR) : 0;
-
- CFX_FloatRect bbox_rect;
- CFX_Matrix matrix;
- switch (rotate % 360) {
- case 0:
- bbox_rect = CFX_FloatRect(0, 0, annot_rect.right - annot_rect.left,
- annot_rect.top - annot_rect.bottom);
- break;
- case 90:
- matrix = CFX_Matrix(0, 1, -1, 0, annot_rect.right - annot_rect.left, 0);
- bbox_rect = CFX_FloatRect(0, 0, annot_rect.top - annot_rect.bottom,
- annot_rect.right - annot_rect.left);
- break;
- case 180:
- matrix = CFX_Matrix(-1, 0, 0, -1, annot_rect.right - annot_rect.left,
- annot_rect.top - annot_rect.bottom);
- bbox_rect = CFX_FloatRect(0, 0, annot_rect.right - annot_rect.left,
- annot_rect.top - annot_rect.bottom);
- break;
- case 270:
- matrix = CFX_Matrix(0, -1, 1, 0, 0, annot_rect.top - annot_rect.bottom);
- bbox_rect = CFX_FloatRect(0, 0, annot_rect.top - annot_rect.bottom,
- annot_rect.right - annot_rect.left);
- break;
+ const AnnotationDimensionsAndColor annot_dimensions_and_color =
+ GetAnnotationDimensionsAndColor(annot_dict);
+ fxcrt::ostringstream app_stream;
+ const ByteString background = GenerateColorAP(
+ annot_dimensions_and_color.background_color, PaintOperation::kFill);
+ if (background.GetLength() > 0) {
+ app_stream << "q\n" << background;
+ WriteRect(app_stream, annot_dimensions_and_color.bbox) << " re f\nQ\n";
}
const BorderStyleInfo border_style_info =
GetBorderStyleInfo(annot_dict->GetDictFor("BS"));
- CFX_Color border_color;
- CFX_Color background_color;
- if (mk_dict) {
- RetainPtr<const CPDF_Array> border_color_array =
- mk_dict->GetArrayFor(pdfium::appearance::kBC);
- if (border_color_array) {
- border_color = fpdfdoc::CFXColorFromArray(*border_color_array);
- }
- RetainPtr<const CPDF_Array> background_color_array =
- mk_dict->GetArrayFor(pdfium::appearance::kBG);
- if (background_color_array) {
- background_color = fpdfdoc::CFXColorFromArray(*background_color_array);
- }
- }
- fxcrt::ostringstream app_stream;
- ByteString background =
- GenerateColorAP(background_color, PaintOperation::kFill);
- if (background.GetLength() > 0) {
- app_stream << "q\n" << background;
- WriteRect(app_stream, bbox_rect) << " re f\nQ\n";
- }
- ByteString border_stream =
- GenerateBorderAP(bbox_rect, border_style_info, border_color);
+ const ByteString border_stream =
+ GenerateBorderAP(annot_dimensions_and_color.bbox, border_style_info,
+ annot_dimensions_and_color.border_color);
if (border_stream.GetLength() > 0) {
app_stream << "q\n" << border_stream << "Q\n";
}
- CFX_FloatRect body_rect = bbox_rect;
+ CFX_FloatRect body_rect = annot_dimensions_and_color.bbox;
body_rect.Deflate(border_style_info.width, border_style_info.width);
RetainPtr<CPDF_Dictionary> ap_dict =
@@ -1107,8 +1156,8 @@
} else {
stream_dict->SetFor("Resources", form_dict->GetDictFor("DR")->Clone());
}
- stream_dict->SetMatrixFor("Matrix", matrix);
- stream_dict->SetRectFor("BBox", bbox_rect);
+ stream_dict->SetMatrixFor("Matrix", annot_dimensions_and_color.matrix);
+ stream_dict->SetRectFor("BBox", annot_dimensions_and_color.bbox);
} else {
normal_stream =
doc->NewIndirect<CPDF_Stream>(pdfium::MakeRetain<CPDF_Dictionary>());
@@ -1338,8 +1387,8 @@
normal_stream->SetDataFromStringstreamAndRemoveFilter(&app_stream);
stream_dict = normal_stream->GetMutableDict();
- stream_dict->SetMatrixFor("Matrix", matrix);
- stream_dict->SetRectFor("BBox", bbox_rect);
+ stream_dict->SetMatrixFor("Matrix", annot_dimensions_and_color.matrix);
+ stream_dict->SetRectFor("BBox", annot_dimensions_and_color.bbox);
RetainPtr<CPDF_Dictionary> resources_dict =
stream_dict->GetMutableDictFor("Resources");
if (!resources_dict) {