1 // Copyright 2024 The PDFium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #ifndef CORE_FPDFAPI_EDIT_CPDF_NPAGETOONEEXPORTER_H_ 8 #define CORE_FPDFAPI_EDIT_CPDF_NPAGETOONEEXPORTER_H_ 9 10 #include <stddef.h> 11 #include <stdint.h> 12 13 #include <map> 14 #include <memory> 15 16 #include "core/fpdfapi/edit/cpdf_pageorganizer.h" 17 #include "core/fpdfapi/parser/cpdf_stream.h" 18 #include "core/fxcrt/bytestring.h" 19 #include "core/fxcrt/fx_coordinates.h" 20 #include "core/fxcrt/retain_ptr.h" 21 #include "core/fxcrt/span.h" 22 #include "core/fxcrt/unowned_ptr.h" 23 24 class CPDF_Document; 25 class CPDF_Page; 26 27 struct XObjectContext { 28 XObjectContext(); 29 ~XObjectContext(); 30 31 UnownedPtr<CPDF_Document> dest_doc; 32 RetainPtr<CPDF_Stream> xobject; 33 }; 34 35 // Copies pages from a source document into a destination document. Creates 1 36 // page in the destination document for every N source pages. This class is 37 // intended to be used once via ExportNPagesToOne() and then destroyed. 38 class CPDF_NPageToOneExporter final : public CPDF_PageOrganizer { 39 public: 40 // Struct that stores sub page origin and scale information. When importing 41 // more than one pages onto the same page, most likely the pages will need to 42 // be scaled down, and scale is in range of (0, 1) exclusive. 43 struct NupPageSettings { 44 CFX_PointF sub_page_start_point; 45 float scale = 0.0f; 46 }; 47 48 CPDF_NPageToOneExporter(CPDF_Document* dest_doc, CPDF_Document* src_doc); 49 ~CPDF_NPageToOneExporter(); 50 51 // For the pages from the source document with `page_indices` as their page 52 // indices, insert them into the destination document, starting at page index 53 // 0. 54 // `page_indices` is 0-based. 55 // `dest_page_size` is the destination document page dimensions, measured in 56 // PDF "user space" units. 57 // `pages_on_x_axis` and `nPagesOnXAxis` together defines how many source 58 // pages fit on one destination page. 59 bool ExportNPagesToOne(pdfium::span<const uint32_t> page_indices, 60 const CFX_SizeF& dest_page_size, 61 size_t pages_on_x_axis, 62 size_t pages_on_y_axis); 63 64 std::unique_ptr<XObjectContext> CreateXObjectContextFromPage( 65 int src_page_index); 66 67 // Helper that generates the content stream for a sub-page. Exposed for 68 // testing. 69 static ByteString GenerateSubPageContentStreamForTesting( 70 const ByteString& xobject_name, 71 const NupPageSettings& settings); 72 73 private: 74 // Map page object number to XObject object name. 75 using PageXObjectMap = std::map<uint32_t, ByteString>; 76 77 // Creates an XObject from `src_page`, or find an existing XObject that 78 // represents `src_page`. The transformation matrix is specified in 79 // `settings`. 80 // Returns the XObject reference surrounded by the transformation matrix. 81 ByteString AddSubPage(const RetainPtr<CPDF_Page>& src_page, 82 const NupPageSettings& settings); 83 84 // Creates an XObject from `src_page`. Updates mapping as needed. 85 // Returns the name of the newly created XObject. 86 ByteString MakeXObjectFromPage(RetainPtr<CPDF_Page> src_page); 87 RetainPtr<CPDF_Stream> MakeXObjectFromPageRaw(RetainPtr<CPDF_Page> src_page); 88 89 // Adds `content` as the Contents key in `dest_page_dict`. 90 // Adds the objects in `xobject_name_to_number_map_` to the XObject 91 // dictionary in `dest_page_dict`'s Resources dictionary. 92 void FinishPage(RetainPtr<CPDF_Dictionary> dest_page_dict, 93 const ByteString& content); 94 95 // Counter for giving new XObjects unique names. 96 uint32_t object_number_ = 0; 97 98 // Keeps track of created XObjects in the current page. 99 // Map XObject's object name to it's object number. 100 std::map<ByteString, uint32_t> xobject_name_to_number_map_; 101 102 // Mapping of source page object number and XObject name of the entire doc. 103 // If there are multiple source pages that reference the same object number, 104 // they can also share the same created XObject. 105 PageXObjectMap src_page_xobject_map_; 106 }; 107 108 #endif // CORE_FPDFAPI_EDIT_CPDF_NPAGETOONEEXPORTER_H_ 109