1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef MEDIAPROVIDER_PDF_JNI_PDFCLIENT_FORM_FILLER_H_ 18 #define MEDIAPROVIDER_PDF_JNI_PDFCLIENT_FORM_FILLER_H_ 19 20 #include <span> 21 #include <string> 22 #include <unordered_set> 23 #include <vector> 24 25 #include "cpp/fpdf_scopers.h" 26 #include "form_widget_info.h" 27 #include "fpdf_formfill.h" 28 #include "fpdfview.h" 29 #include "rect.h" 30 31 namespace pdfClient { 32 33 class Document; 34 35 // Handles all interactions with form filling elements including rendering and 36 // editing. 37 class FormFiller : public FPDF_FORMFILLINFO { 38 public: 39 explicit FormFiller(Document* document, FPDF_DOCUMENT fpdf_document); 40 41 ~FormFiller(); 42 43 // Must be called before this FormFiller is used to complete any form filling 44 // actions on the |page|. 45 void NotifyAfterPageLoad(FPDF_PAGE page); 46 47 // Must be called before releasing |page| to release resources when no 48 // further form filling actions will be executed on the |page|. 49 void NotifyBeforePageClose(FPDF_PAGE page); 50 51 // Renders form widget content. 52 bool RenderTile(FPDF_PAGE page, FPDF_BITMAP bitmap, FS_MATRIX transform, FS_RECTF clip, 53 int render_mode) const; 54 55 // Obtain information about the form widget at |point| on the page, if any. 56 // |point| is in page coordinates. 57 FormWidgetInfo GetFormWidgetInfo(FPDF_PAGE page, const Point_d point); 58 59 // Obtain information about the form widget with index |annotation_index| on 60 // the page, if any. 61 FormWidgetInfo GetFormWidgetInfo(FPDF_PAGE page, const int annotation_index); 62 63 // Obtain form widget information for |annotation|, if any. 64 FormWidgetInfo GetFormWidgetInfo(FPDF_PAGE page, FPDF_ANNOTATION annotation); 65 66 // Obtain form widget information for all form field annotations on |page|, 67 // optionally restricting by |type_ids| and store in |widget_infos|. See 68 // fpdf_formfill.h for type constants. If |type_ids| is empty all form 69 // widgets on |page| will be added to |widget_infos|, if any. 70 void GetFormWidgetInfos(FPDF_PAGE page, const std::unordered_set<int>& type_ids, 71 std::vector<FormWidgetInfo>* widget_infos); 72 73 // Perform a click at |point| on the page. Any focus in the document 74 // resulting from this operation will be killed before returning (i.e. there 75 // will be no "currently selected widget" resulting from the click). No-op if 76 // no widget present at |point| or widget cannot be edited. Returns true if 77 // click was performed. |point| is in page coordinates. 78 bool ClickOnPoint(FPDF_PAGE page, const Point_d point); 79 80 // Set the value text of the widget at |annotation_index| on |page|. No-op if 81 // no widget present or widget cannot be edited. Returns true if text was 82 // set, false otherwise. 83 bool SetText(FPDF_PAGE page, const int annotation_index, const std::string_view text); 84 85 // Set the |selected_indices| for the choice widget at |annotation_index| as 86 // selected and deselect all other indices. No-op if no widget present or 87 // widget cannot be edited. Returns true if indices were set, false otherwise. 88 bool SetChoiceSelection(FPDF_PAGE page, const int annotation_index, 89 std::span<const int> selected_indices); 90 91 private: 92 // Returns true if the |annotation| is a widget. 93 bool IsWidget(FPDF_ANNOTATION annotation); 94 // Returns the form annotation at |point|, if present. Else nullptr. 95 ScopedFPDFAnnotation GetFormAnnotation(FPDF_PAGE page, Point_d point); 96 // Returns the form annotation at |index|, if present. Else nullptr. 97 ScopedFPDFAnnotation GetFormAnnotation(FPDF_PAGE page, int index); 98 99 // Return the type of widget at |point|, if present. Else -1. 100 int GetFormFieldType(FPDF_PAGE page, Point_d point); 101 // Return the type of widget the |annotation| is. -1 if not a widget. 102 int GetFormFieldType(FPDF_PAGE page, FPDF_ANNOTATION annotation); 103 104 // Get the coordinate rectangle that the |annotation| occupies on the page. 105 // Result is in Page Coordinates. 106 Rectangle_i GetAnnotationRect(FPDF_ANNOTATION annotation); 107 108 // Return the index of the |annotation| on the |page| or -1 if not found. 109 int GetAnnotationIndex(FPDF_PAGE page, FPDF_ANNOTATION annotation); 110 111 // Returns the number of options the choice |annotation| contains. Returns -1 112 // if annotation is not a choice type. 113 int GetOptionCount(FPDF_ANNOTATION annotation); 114 115 // Get Options for the choice |annotation|. Returns empty list if the 116 // annotation is not a choice type or does not have options. 117 std::vector<Option> GetOptions(FPDF_PAGE page, FPDF_ANNOTATION annotation); 118 119 // Get the "MaxLen" value for the annotation. Returns -1 if the MaxLen value 120 // is not present in the annotation dictionary. 121 int GetMaxLen(FPDF_ANNOTATION annotation); 122 123 // Get the text font size of a widget containing text. Returns 0 if the font 124 // size was not found which indicates that widget text is autosized. 125 float GetFontSize(FPDF_ANNOTATION annotation); 126 127 // Gets the TU value for the form widget, if any. If TU is not provided will 128 // return the T value, if any. If not provided returns empty string. 129 std::string GetAccessibilityLabel(FPDF_ANNOTATION annotation); 130 131 // Gets the text value for a read only form widget (i.e. widget for which 132 // pdfium form filling operations are not permitted). Determines the checked 133 // state and returns "true" or "false" for checkboxes and radio buttons. 134 // Obtains the annotation dictionary "V" entry for all other types. 135 std::string GetReadOnlyTextValue(int type, FPDF_ANNOTATION annotation); 136 137 // Perform a click action on the document in Pdfium. 138 void PerformClick(FPDF_PAGE page, const Point_d point); 139 // Set the text of the field that is currently focused (in Pdfium) to |text|. 140 void SetFieldText(FPDF_PAGE page, std::string_view text); 141 // Set all the text of the field that is currently focused (in Pdfium) as 142 // selected. 143 void SelectAllFieldText(FPDF_PAGE page); 144 // Replace the text that is currently selected in the focused field (in 145 // Pdfium) with |replacement_text|. 146 void ReplaceSelectedText(FPDF_PAGE page, std::string_view replacement_text); 147 148 // Set Pdfium's focus to the widget at |point|, if any. 149 bool SetFormFocus(FPDF_PAGE page, const Point_d point); 150 // Set Pdfium's focus to the |annotation|. 151 bool SetFormFocus(FPDF_PAGE page, FPDF_ANNOTATION annotation); 152 // Kill all focus held in Pdfium, if any. 153 bool KillFormFocus(); 154 155 // Implementation of method from FPDF_FORMFILLINFO. Pdfium will use this 156 // method to inform FormFiller when a rectangle of |page|'s bitmap has been 157 // invalidated. This occurs following form filling actions. 158 static void Invalidate(FPDF_FORMFILLINFO* pThis, FPDF_PAGE page, double left, double top, 159 double right, double bottom); 160 161 Document* document_; // Not owned. 162 ScopedFPDFFormHandle form_handle_; 163 }; 164 165 } // namespace pdfClient 166 167 #endif // MEDIAPROVIDER_PDF_JNI_PDFCLIENT_FORM_FILLER_H_