diff --git a/ChangeLog b/ChangeLog index c13f4ecb..16cfd204 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2021-12-16 Jay Berkenbilt + + * Add several functions to the C API for working with pages. C + wrappers around sevearl of the "Legacy" page operations from + QPDFObjectHandle.hh have been added. See "PAGE FUNCTIONS" in + qpdf-c.h for details. Fixes #594. + 2021-12-12 Jay Berkenbilt * Convert documentation from docbook to reStructuredText/Sphinx. diff --git a/include/qpdf/qpdf-c.h b/include/qpdf/qpdf-c.h index 9d121060..4a6eb3a5 100644 --- a/include/qpdf/qpdf-c.h +++ b/include/qpdf/qpdf-c.h @@ -788,6 +788,67 @@ extern "C" { char const* qpdf_oh_unparse_resolved(qpdf_data qpdf, qpdf_oh oh); QPDF_DLL char const* qpdf_oh_unparse_binary(qpdf_data qpdf, qpdf_oh oh); + + /* PAGE FUNCTIONS */ + + /* The first time a page function is called, qpdf will traverse + * the /Pages tree. Subsequent calls to retrieve the number of + * pages or a specific page run in constant time as they are + * accessing the pages cache. If you manipulate the page tree + * outside of these functions, you should call + * qpdf_update_all_pages_cache. See comments for getAllPages() and + * updateAllPagesCache() in QPDF.hh. + */ + + /* For each function, the corresponding method in QPDF.hh is + * referenced. Please see comments in QPDF.hh for details. + */ + + /* calls getAllPages(). On error, returns -1 and sets error for + * qpdf_get_error. */ + QPDF_DLL + int qpdf_get_num_pages(qpdf_data qpdf); + /* returns uninitialized object if out of range */ + QPDF_DLL + qpdf_oh qpdf_get_page_n(qpdf_data qpdf, size_t zero_based_index); + + /* updateAllPagesCache() */ + QPDF_DLL + QPDF_ERROR_CODE qpdf_update_all_pages_cache(qpdf_data qpdf); + + /* findPage() -- return zero-based index. If page is not found, + * return -1 and save the error to be retrieved with + * qpdf_get_error. + */ + QPDF_DLL + int qpdf_find_page_by_id(qpdf_data qpdf, int objid, int generation); + QPDF_DLL + int qpdf_find_page_by_oh(qpdf_data qpdf, qpdf_oh oh); + + /* pushInheritedAttributesToPage() */ + QPDF_DLL + QPDF_ERROR_CODE qpdf_push_inherited_attributes_to_page(qpdf_data qpdf); + + /* Functions that add pages may add pages from other files. If + * adding a page from the same file, newpage_qpdf and qpdf are the + * same. + /*/ + + /* addPage() */ + QPDF_DLL + QPDF_ERROR_CODE qpdf_add_page( + qpdf_data qpdf, + qpdf_data newpage_qpdf, qpdf_oh newpage, + QPDF_BOOL first); + /* addPageAt() */ + QPDF_DLL + QPDF_ERROR_CODE qpdf_add_page_at( + qpdf_data qpdf, + qpdf_data newpage_qpdf, qpdf_oh newpage, + QPDF_BOOL before, qpdf_oh refpage); + /* removePage() */ + QPDF_DLL + QPDF_ERROR_CODE qpdf_remove_page(qpdf_data qpdf, qpdf_oh page); #ifdef __cplusplus } #endif diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc index c4428d10..0ce9c39e 100644 --- a/libqpdf/qpdf-c.cc +++ b/libqpdf/qpdf-c.cc @@ -1579,3 +1579,102 @@ char const* qpdf_oh_unparse_binary(qpdf_data qpdf, qpdf_oh oh) return qpdf->tmp_string.c_str(); }); } + +int qpdf_get_num_pages(qpdf_data qpdf) +{ + QTC::TC("qpdf", "qpdf-c called qpdf_num_pages"); + int n = -1; + QPDF_ERROR_CODE code = trap_errors(qpdf, [&n](qpdf_data q) { + n = QIntC::to_int(q->qpdf->getAllPages().size()); + }); + if (code & QPDF_ERRORS) + { + return -1; + } + return n; +} + +qpdf_oh qpdf_get_page_n(qpdf_data qpdf, size_t i) +{ + QTC::TC("qpdf", "qpdf-c called qpdf_get_page_n"); + qpdf_oh result = 0; + QPDF_ERROR_CODE code = trap_errors(qpdf, [&result, i](qpdf_data q) { + result = new_object(q, q->qpdf->getAllPages().at(i)); + }); + if ((code & QPDF_ERRORS) || (result == 0)) + { + return qpdf_oh_new_uninitialized(qpdf); + } + return result; +} + +QPDF_ERROR_CODE qpdf_update_all_pages_cache(qpdf_data qpdf) +{ + QTC::TC("qpdf", "qpdf-c called qpdf_update_all_pages_cache"); + return trap_errors(qpdf, [](qpdf_data q) { + q->qpdf->updateAllPagesCache(); + }); +} + +int qpdf_find_page_by_id(qpdf_data qpdf, int objid, int generation) +{ + QTC::TC("qpdf", "qpdf-c called qpdf_find_page_by_id"); + int n = -1; + QPDFObjGen og(objid, generation); + QPDF_ERROR_CODE code = trap_errors(qpdf, [&n, &og](qpdf_data q) { + n = QIntC::to_int(q->qpdf->findPage(og)); + }); + if (code & QPDF_ERRORS) + { + return -1; + } + return n; +} + +int qpdf_find_page_by_oh(qpdf_data qpdf, qpdf_oh oh) +{ + QTC::TC("qpdf", "qpdf-c called qpdf_find_page_by_oh"); + return do_with_oh( + qpdf, oh, return_T(-1), [qpdf](QPDFObjectHandle& o) { + return qpdf->qpdf->findPage(o); + }); +} + +QPDF_ERROR_CODE qpdf_push_inherited_attributes_to_page(qpdf_data qpdf) +{ + QTC::TC("qpdf", "qpdf-c called qpdf_push_inherited_attributes_to_page"); + return trap_errors(qpdf, [](qpdf_data q) { + q->qpdf->pushInheritedAttributesToPage(); + }); +} + +QPDF_ERROR_CODE qpdf_add_page( + qpdf_data qpdf, qpdf_data newpage_qpdf, qpdf_oh newpage, QPDF_BOOL first) +{ + QTC::TC("qpdf", "qpdf-c called qpdf_add_page"); + auto page = qpdf_oh_item_internal(newpage_qpdf, newpage); + return trap_errors(qpdf, [&page, first](qpdf_data q) { + q->qpdf->addPage(page, first); + }); +} + +QPDF_ERROR_CODE qpdf_add_page_at( + qpdf_data qpdf, qpdf_data newpage_qpdf, qpdf_oh newpage, + QPDF_BOOL before, qpdf_oh refpage) +{ + QTC::TC("qpdf", "qpdf-c called qpdf_add_page_at"); + auto page = qpdf_oh_item_internal(newpage_qpdf, newpage); + auto ref = qpdf_oh_item_internal(qpdf, refpage); + return trap_errors(qpdf, [&page, before, &ref](qpdf_data q) { + q->qpdf->addPageAt(page, before, ref); + }); +} + +QPDF_ERROR_CODE qpdf_remove_page(qpdf_data qpdf, qpdf_oh page) +{ + QTC::TC("qpdf", "qpdf-c called qpdf_remove_page"); + auto p = qpdf_oh_item_internal(qpdf, page); + return trap_errors(qpdf, [&p](qpdf_data q) { + q->qpdf->removePage(p); + }); +} diff --git a/manual/index.rst b/manual/index.rst index 8fcb18f9..155d64b0 100644 --- a/manual/index.rst +++ b/manual/index.rst @@ -3626,7 +3626,9 @@ For a detailed list of changes, please see the file more detail what the behavior is. See :ref:`ref.object-accessors` for a more in-depth discussion. - - Overhaul error handling for the object handle functions in the + - C API Enhancements + + - Overhaul error handling for the object handle functions C API. See comments in the "Object handling" section of :file:`include/qpdf/qpdf-c.h` for details. In particular, exceptions thrown by the underlying C++ code @@ -3650,6 +3652,9 @@ For a detailed list of changes, please see the file and ``qpdf_replace_object``, exposing the corresponding methods in ``QPDF`` and ``QPDFObjectHandle``. + - Add several functions for working with pages. See ``PAGE + FUNCTIONS`` in ``include/qpdf/qpdf-c.h`` for details. + - Documentation change - The documentation sources have been switched from docbook to diff --git a/qpdf/qpdf-ctest.c b/qpdf/qpdf-ctest.c index 307b57c7..a0819599 100644 --- a/qpdf/qpdf-ctest.c +++ b/qpdf/qpdf-ctest.c @@ -931,6 +931,138 @@ static void test33(char const* infile, report_errors(); } +static void test34(char const* infile, + char const* password, + char const* outfile, + char const* xarg) +{ + /* This test expects 11-pages.pdf as file1 and minimal.pdf as xarg. */ + + /* Non-error cases for page API */ + + qpdf_data qpdf2 = qpdf_init(); + assert(qpdf_read(qpdf, infile, password) == 0); + assert(qpdf_read(qpdf2, xarg, "") == 0); + assert(qpdf_get_num_pages(qpdf) == 11); + assert(qpdf_get_num_pages(qpdf2) == 1); + + /* At this time, there is no C API for accessing stream data, so + * we hard-code object IDs from a known input file. + */ + assert(qpdf_oh_get_object_id(qpdf, qpdf_get_page_n(qpdf, 0)) == 4); + assert(qpdf_oh_get_object_id(qpdf, qpdf_get_page_n(qpdf, 10)) == 14); + qpdf_oh page3 = qpdf_get_page_n(qpdf, 3); + assert(qpdf_find_page_by_oh(qpdf, page3) == 3); + assert(qpdf_find_page_by_id( + qpdf, qpdf_oh_get_object_id(qpdf, page3), 0) == 3); + + /* Add other page to the end */ + qpdf_oh opage0 = qpdf_get_page_n(qpdf2, 0); + assert(qpdf_add_page(qpdf, qpdf2, opage0, QPDF_FALSE) == 0); + /* Add other page before page 3 */ + assert(qpdf_add_page_at(qpdf, qpdf2, opage0, QPDF_TRUE, page3) == 0); + /* Remove page 3 */ + assert(qpdf_remove_page(qpdf, page3) == 0); + /* At page 3 back at the beginning */ + assert(qpdf_add_page(qpdf, qpdf, page3, QPDF_TRUE) == 0); + + qpdf_init_write(qpdf, outfile); + qpdf_set_static_ID(qpdf, QPDF_TRUE); + qpdf_set_qdf_mode(qpdf, QPDF_TRUE); + qpdf_set_suppress_original_object_IDs(qpdf, QPDF_TRUE); + qpdf_write(qpdf); + report_errors(); + qpdf_cleanup(&qpdf2); +} + +static void test35(char const* infile, + char const* password, + char const* outfile, + char const* xarg) +{ + /* This test uses 11-pages.pdf */ + + assert(qpdf_get_num_pages(qpdf) == -1); + assert(qpdf_has_error(qpdf)); + qpdf_error e = qpdf_get_error(qpdf); + assert(qpdf_get_error_code(qpdf, e) != QPDF_SUCCESS); + assert(! qpdf_has_error(qpdf)); + + assert(qpdf_read(qpdf, infile, password) == 0); + + qpdf_oh range = qpdf_get_page_n(qpdf, 11); + assert(! qpdf_oh_is_initialized(qpdf, range)); + assert(qpdf_has_error(qpdf)); + e = qpdf_get_error(qpdf); + assert(qpdf_get_error_code(qpdf, e) != QPDF_SUCCESS); + assert(! qpdf_has_error(qpdf)); + + assert(qpdf_find_page_by_id(qpdf, 100, 0) == -1); + assert(qpdf_has_error(qpdf)); + e = qpdf_get_error(qpdf); + assert(qpdf_get_error_code(qpdf, e) != QPDF_SUCCESS); + assert(! qpdf_has_error(qpdf)); + + assert(qpdf_find_page_by_oh(qpdf, qpdf_get_root(qpdf)) == -1); + assert(qpdf_more_warnings(qpdf)); + e = qpdf_next_warning(qpdf); + assert(qpdf_get_error_code(qpdf, e) != QPDF_SUCCESS); + assert(! qpdf_has_error(qpdf)); + + assert(qpdf_find_page_by_id(qpdf, 100, 0) == -1); + assert(qpdf_has_error(qpdf)); + e = qpdf_get_error(qpdf); + assert(qpdf_get_error_code(qpdf, e) != QPDF_SUCCESS); + assert(! qpdf_has_error(qpdf)); + + assert(qpdf_add_page(qpdf, qpdf, 1000, QPDF_FALSE) != 0); + + report_errors(); +} + +static void test36(char const* infile, + char const* password, + char const* outfile, + char const* xarg) +{ + /* This test uses inherited-rotate.pdf */ + + assert(qpdf_read(qpdf, infile, password) == 0); + + /* Non-trivially push inherited attributes */ + qpdf_oh page0 = qpdf_get_object_by_id(qpdf, 3, 0); + assert(qpdf_oh_is_dictionary(qpdf, page0)); + qpdf_oh r = qpdf_oh_get_key(qpdf, page0, "/Rotate"); + assert(qpdf_oh_get_int_value(qpdf, r) == 90); + qpdf_oh_remove_key(qpdf, page0, "/Rotate"); + assert(! qpdf_oh_has_key(qpdf, page0, "/Rotate")); + + assert(qpdf_push_inherited_attributes_to_page(qpdf) == 0); + r = qpdf_oh_get_key(qpdf, page0, "/Rotate"); + assert(qpdf_oh_get_int_value(qpdf, r) == 270); + + assert(qpdf_add_page(qpdf, qpdf, page0, QPDF_TRUE) == 0); +} + +static void test37(char const* infile, + char const* password, + char const* outfile, + char const* xarg) +{ + /* This test uses 11-pages.pdf */ + + /* Manually manipulate pages tree */ + assert(qpdf_read(qpdf, infile, password) == 0); + assert(qpdf_get_num_pages(qpdf) == 11); + qpdf_oh pages = qpdf_get_object_by_id(qpdf, 3, 0); + qpdf_oh kids = qpdf_oh_get_key(qpdf, pages, "/Kids"); + assert(qpdf_oh_get_array_n_items(qpdf, kids) == 11); + qpdf_oh_erase_item(qpdf, kids, 0); + assert(qpdf_get_num_pages(qpdf) == 11); + assert(qpdf_update_all_pages_cache(qpdf) == 0); + assert(qpdf_get_num_pages(qpdf) == 10); +} + int main(int argc, char* argv[]) { char* p = 0; @@ -1004,6 +1136,10 @@ int main(int argc, char* argv[]) (n == 31) ? test31 : (n == 32) ? test32 : (n == 33) ? test33 : + (n == 34) ? test34 : + (n == 35) ? test35 : + (n == 36) ? test36 : + (n == 37) ? test37 : 0); if (fn == 0) diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov index 9b4e3cea..315c1200 100644 --- a/qpdf/qpdf.testcov +++ b/qpdf/qpdf.testcov @@ -608,3 +608,12 @@ qpdf-c registered oh error handler 0 qpdf-c cleanup warned about unhandled error 0 qpdf-c called qpdf_get_object_by_id 0 qpdf-c called qpdf_replace_object 0 +qpdf-c called qpdf_num_pages 0 +qpdf-c called qpdf_get_page_n 0 +qpdf-c called qpdf_update_all_pages_cache 0 +qpdf-c called qpdf_find_page_by_id 0 +qpdf-c called qpdf_find_page_by_oh 0 +qpdf-c called qpdf_push_inherited_attributes_to_page 0 +qpdf-c called qpdf_add_page 0 +qpdf-c called qpdf_add_page_at 0 +qpdf-c called qpdf_remove_page 0 diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index d4b3f2a5..c975f2c1 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -4868,6 +4868,36 @@ $td->runtest("C get object by ID", {$td->STRING => "", $td->EXIT_STATUS => 0}, $td->NORMALIZE_NEWLINES); +show_ntests(); +# ---------- +$td->notify("--- C API Page Functions ---"); +$n_tests += 5; + +$td->runtest("C page normal", + {$td->COMMAND => + "qpdf-ctest 34 11-pages.pdf '' a.pdf minimal.pdf"}, + {$td->STRING => "", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); +$td->runtest("check output", + {$td->FILE => 'a.pdf'}, + {$td->FILE => 'c-pages.pdf'}); + +$td->runtest("C page errors", + {$td->COMMAND => + "qpdf-ctest 35 11-pages.pdf '' ''"}, + {$td->FILE => "c-page-errors.out", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); +$td->runtest("C inherited page resources", + {$td->COMMAND => + "qpdf-ctest 36 inherited-rotate.pdf '' ''"}, + {$td->STRING => "", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); +$td->runtest("C pages cache", + {$td->COMMAND => + "qpdf-ctest 37 11-pages.pdf '' ''"}, + {$td->STRING => "", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); + show_ntests(); # ---------- $td->notify("--- Content Preservation Tests ---"); diff --git a/qpdf/qtest/qpdf/c-page-errors.out b/qpdf/qtest/qpdf/c-page-errors.out new file mode 100644 index 00000000..36afa406 --- /dev/null +++ b/qpdf/qtest/qpdf/c-page-errors.out @@ -0,0 +1,8 @@ +11-pages.pdf (page object: object 1 0): page object not referenced in /Pages tree +11-pages.pdf (C API object handle 1000): attempted access to unknown object handle +WARNING: object 27 0: operation for dictionary attempted on object of type null: ignoring key replacement request +warning: object 27 0: operation for dictionary attempted on object of type null: ignoring key replacement request + code: 7 + file: + pos : 0 + text: operation for dictionary attempted on object of type null: ignoring key replacement request diff --git a/qpdf/qtest/qpdf/c-pages.pdf b/qpdf/qtest/qpdf/c-pages.pdf new file mode 100644 index 00000000..40f9bc56 --- /dev/null +++ b/qpdf/qtest/qpdf/c-pages.pdf @@ -0,0 +1,599 @@ +%PDF-1.4 +%¿÷¢þ +%QDF-1.0 + +1 0 obj +<< + /Pages 3 0 R + /Type /Catalog +>> +endobj + +2 0 obj +<< + /CreationDate (D:20120721200217) + /Producer (Apex PDFWriter) +>> +endobj + +3 0 obj +<< + /Count 13 + /Kids [ + 4 0 R + 5 0 R + 6 0 R + 7 0 R + 8 0 R + 9 0 R + 10 0 R + 11 0 R + 12 0 R + 13 0 R + 14 0 R + 15 0 R + 16 0 R + ] + /Type /Pages +>> +endobj + +%% Page 1 +4 0 obj +<< + /Contents 17 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 19 0 R + >> + /ProcSet [ + /PDF + /Text + ] + >> + /Type /Page +>> +endobj + +%% Page 2 +5 0 obj +<< + /Contents 20 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 19 0 R + >> + /ProcSet [ + /PDF + /Text + ] + >> + /Type /Page +>> +endobj + +%% Page 3 +6 0 obj +<< + /Contents 22 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 19 0 R + >> + /ProcSet [ + /PDF + /Text + ] + >> + /Type /Page +>> +endobj + +%% Page 4 +7 0 obj +<< + /Contents 24 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 19 0 R + >> + /ProcSet [ + /PDF + /Text + ] + >> + /Type /Page +>> +endobj + +%% Page 5 +8 0 obj +<< + /Contents 26 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 28 0 R + >> + /ProcSet 29 0 R + >> + /Type /Page +>> +endobj + +%% Page 6 +9 0 obj +<< + /Contents 30 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 19 0 R + >> + /ProcSet [ + /PDF + /Text + ] + >> + /Type /Page +>> +endobj + +%% Page 7 +10 0 obj +<< + /Contents 32 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 19 0 R + >> + /ProcSet [ + /PDF + /Text + ] + >> + /Type /Page +>> +endobj + +%% Page 8 +11 0 obj +<< + /Contents 34 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 19 0 R + >> + /ProcSet [ + /PDF + /Text + ] + >> + /Type /Page +>> +endobj + +%% Page 9 +12 0 obj +<< + /Contents 36 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 19 0 R + >> + /ProcSet [ + /PDF + /Text + ] + >> + /Type /Page +>> +endobj + +%% Page 10 +13 0 obj +<< + /Contents 38 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 19 0 R + >> + /ProcSet [ + /PDF + /Text + ] + >> + /Type /Page +>> +endobj + +%% Page 11 +14 0 obj +<< + /Contents 40 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 19 0 R + >> + /ProcSet [ + /PDF + /Text + ] + >> + /Type /Page +>> +endobj + +%% Page 12 +15 0 obj +<< + /Contents 42 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 19 0 R + >> + /ProcSet [ + /PDF + /Text + ] + >> + /Type /Page +>> +endobj + +%% Page 13 +16 0 obj +<< + /Contents 26 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 3 0 R + /Resources << + /Font << + /F1 28 0 R + >> + /ProcSet 29 0 R + >> + /Type /Page +>> +endobj + +%% Contents for page 1 +17 0 obj +<< + /Length 18 0 R +>> +stream +BT /F1 15 Tf 72 720 Td (Original page 4) Tj ET +endstream +endobj + +18 0 obj +47 +endobj + +19 0 obj +<< + /BaseFont /Times-Roman + /Encoding /WinAnsiEncoding + /Subtype /Type1 + /Type /Font +>> +endobj + +%% Contents for page 2 +20 0 obj +<< + /Length 21 0 R +>> +stream +BT /F1 15 Tf 72 720 Td (Original page 1) Tj ET +endstream +endobj + +21 0 obj +47 +endobj + +%% Contents for page 3 +22 0 obj +<< + /Length 23 0 R +>> +stream +BT /F1 15 Tf 72 720 Td (Original page 2) Tj ET +endstream +endobj + +23 0 obj +47 +endobj + +%% Contents for page 4 +24 0 obj +<< + /Length 25 0 R +>> +stream +BT /F1 15 Tf 72 720 Td (Original page 3) Tj ET +endstream +endobj + +25 0 obj +47 +endobj + +%% Contents for page 13 +26 0 obj +<< + /Length 27 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Potato) Tj +ET +endstream +endobj + +27 0 obj +44 +endobj + +28 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +29 0 obj +[ + /PDF + /Text +] +endobj + +%% Contents for page 6 +30 0 obj +<< + /Length 31 0 R +>> +stream +BT /F1 15 Tf 72 720 Td (Original page 5) Tj ET +endstream +endobj + +31 0 obj +47 +endobj + +%% Contents for page 7 +32 0 obj +<< + /Length 33 0 R +>> +stream +BT /F1 15 Tf 72 720 Td (Original page 6) Tj ET +endstream +endobj + +33 0 obj +47 +endobj + +%% Contents for page 8 +34 0 obj +<< + /Length 35 0 R +>> +stream +BT /F1 15 Tf 72 720 Td (Original page 7) Tj ET +endstream +endobj + +35 0 obj +47 +endobj + +%% Contents for page 9 +36 0 obj +<< + /Length 37 0 R +>> +stream +BT /F1 15 Tf 72 720 Td (Original page 8) Tj ET +endstream +endobj + +37 0 obj +47 +endobj + +%% Contents for page 10 +38 0 obj +<< + /Length 39 0 R +>> +stream +BT /F1 15 Tf 72 720 Td (Original page 9) Tj ET +endstream +endobj + +39 0 obj +47 +endobj + +%% Contents for page 11 +40 0 obj +<< + /Length 41 0 R +>> +stream +BT /F1 15 Tf 72 720 Td (Original page 10) Tj ET +endstream +endobj + +41 0 obj +48 +endobj + +%% Contents for page 12 +42 0 obj +<< + /Length 43 0 R +>> +stream +BT /F1 15 Tf 72 720 Td (Original page 11) Tj ET +endstream +endobj + +43 0 obj +48 +endobj + +xref +0 44 +0000000000 65535 f +0000000025 00000 n +0000000079 00000 n +0000000165 00000 n +0000000375 00000 n +0000000604 00000 n +0000000833 00000 n +0000001062 00000 n +0000001291 00000 n +0000001496 00000 n +0000001725 00000 n +0000001955 00000 n +0000002185 00000 n +0000002416 00000 n +0000002647 00000 n +0000002878 00000 n +0000003109 00000 n +0000003328 00000 n +0000003432 00000 n +0000003452 00000 n +0000003584 00000 n +0000003688 00000 n +0000003731 00000 n +0000003835 00000 n +0000003878 00000 n +0000003982 00000 n +0000004026 00000 n +0000004127 00000 n +0000004147 00000 n +0000004266 00000 n +0000004325 00000 n +0000004429 00000 n +0000004472 00000 n +0000004576 00000 n +0000004619 00000 n +0000004723 00000 n +0000004766 00000 n +0000004870 00000 n +0000004914 00000 n +0000005018 00000 n +0000005062 00000 n +0000005167 00000 n +0000005211 00000 n +0000005316 00000 n +trailer << + /Info 2 0 R + /Root 1 0 R + /Size 44 + /ID [<31415926535897932384626433832795>] +>> +startxref +5336 +%%EOF