From f7db3109429373d649dc347e4c6d01345c01e5be Mon Sep 17 00:00:00 2001 From: vididvidid Date: Tue, 30 Sep 2025 04:38:35 +0000 Subject: [PATCH] added the enum for the conformance levels in the pdfio-private.h under _pdfio_file_s and updated the create_common() function which is used by pdfiofilecreate to recognize the new pdf/a-.. strings --- examples/create_tagged_pdf | Bin 0 -> 16992 bytes examples/create_tagged_pdf.c | 77 +++++++++++++++++++++++++++++++++++ examples/pdf2text.c | 2 +- examples/tagged_document.pdf | Bin 0 -> 10144 bytes pdfio-file.c | 58 +++++++++++++++++++++++--- pdfio-private.h | 15 +++++++ 6 files changed, 146 insertions(+), 6 deletions(-) create mode 100755 examples/create_tagged_pdf create mode 100644 examples/create_tagged_pdf.c create mode 100644 examples/tagged_document.pdf diff --git a/examples/create_tagged_pdf b/examples/create_tagged_pdf new file mode 100755 index 0000000000000000000000000000000000000000..9614c993e7f27d9b075550fdb0bf64694904eef9 GIT binary patch literal 16992 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 e` +#include +#include + +int main(void) +{ + // 1. Basic PDF setup + pdfio_file_t *pdf; + pdfio_rect_t media_box = {0.0, 0.0, 612.0, 792.0}; // US Letter size + + // Create the PDF file + if ((pdf = pdfioFileCreate("tagged_document.pdf", "2.0", &media_box, &media_box, NULL, NULL)) == NULL) + { + puts("Error: Could not create PDF file."); + return (1); + } + + // 2. Build the Structure Tree Root (StructTreeRoot) + // This is the master "table of contents" for all tags. + pdfio_dict_t *struct_tree_root_dict = pdfioDictCreate(pdf); + pdfioDictSetName(struct_tree_root_dict, "Type", "StructTreeRoot"); + + // Create the top-level document element tag: /Document + pdfio_dict_t *doc_elem_dict = pdfioDictCreate(pdf); + pdfioDictSetName(doc_elem_dict, "Type", "StructElem"); + pdfioDictSetName(doc_elem_dict, "S", "Document"); // 'S' is the structure type + + // Create the paragraph element tag: /P + pdfio_dict_t *p_elem_dict = pdfioDictCreate(pdf); + pdfioDictSetName(p_elem_dict, "Type", "StructElem"); + pdfioDictSetName(p_elem_dict, "S", "P"); // 'S' is the structure type (Paragraph) + pdfioDictSetNumber(p_elem_dict, "K", 0); // 'K' is the content, pointing to MCID 0 on the page + + // Link the paragraph as a child of the document element + pdfio_array_t *doc_kids = pdfioArrayCreate(pdf); + pdfioArrayAppendDict(doc_kids, p_elem_dict); + pdfioDictSetArray(doc_elem_dict, "K", doc_kids); + + // Link the document element as a child of the StructTreeRoot + pdfio_array_t *root_kids = pdfioArrayCreate(pdf); + pdfioArrayAppendDict(root_kids, doc_elem_dict); + pdfioDictSetArray(struct_tree_root_dict, "K", root_kids); + + // Create a PDF object for the StructTreeRoot and link it to the main catalog + pdfio_obj_t *struct_tree_root_obj = pdfioFileCreateObj(pdf, struct_tree_root_dict); + pdfioDictSetObj(pdfioFileGetCatalog(pdf), "StructTreeRoot", struct_tree_root_obj); + + // 3. Create a page and its content + pdfio_dict_t *page_dict = pdfioDictCreate(pdf); + pdfio_obj_t *helvetica = pdfioFileCreateFontObjFromBase(pdf, "Helvetica"); + pdfioPageDictAddFont(page_dict, "F1", helvetica); + + pdfio_stream_t *st = pdfioFileCreatePage(pdf, page_dict); + + // 4. Write the tagged content to the page stream + pdfioContentTextBegin(st); + pdfioContentSetTextFont(st, "F1", 24.0); + pdfioContentTextMoveTo(st, 72.0, 700.0); + + // Create a dictionary for the marked content, specifying the ID + pdfio_dict_t *p_mcid_dict = pdfioDictCreate(pdf); + pdfioDictSetNumber(p_mcid_dict, "MCID", 0); // This ID must match the 'K' value in the StructElem + + // Use the functions from pdfio-content.c to wrap the text + pdfioContentBeginMarked(st, "P", p_mcid_dict); // Start tag for Paragraph + pdfioContentTextShow(st, false, "This is a tagged paragraph."); + pdfioContentEndMarked(st); // End tag + + pdfioContentTextEnd(st); + + // 5. Finalize and close + pdfioStreamClose(st); + pdfioFileClose(pdf); + + puts("Successfully created tagged_document.pdf"); + return (0); +} diff --git a/examples/pdf2text.c b/examples/pdf2text.c index 151ca83..fe8be68 100644 --- a/examples/pdf2text.c +++ b/examples/pdf2text.c @@ -1417,4 +1417,4 @@ puts_utf16(const char *s) // I - Hex string put_utf8(ch); } -} \ No newline at end of file +} diff --git a/examples/tagged_document.pdf b/examples/tagged_document.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ca13b9f2e6e1c69920a64053aa9949680b1ac135 GIT binary patch literal 10144 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 G;Qk-yeoutput_cb = output_cb; pdf->output_ctx = output_cbdata; pdf->filename = strdup(filename); - pdf->version = strdup(!strncmp(version, "PCLm-", 5) ? "1.4" : version); + + if (!version) + { + version = "2.0"; + } + + if (!strncmp(version, "PDF/A-1", 7)) + { + actual_version = "1.4"; + if (version[7] == 'a') + pdf->pdfa = _PDFIO_PDFA_1A; + else + pdf->pdfa = _PDFIO_PDFA_1B; // Default to 'b' + } + else if (!strncmp(version, "PDF/A-2", 7)) + { + actual_version = "1.7"; + if (version[7] == 'a') + pdf->pdfa = _PDFIO_PDFA_2A; + else if (version[7] == 'u') + pdf->pdfa = _PDFIO_PDFA_2U; + else + pdf->pdfa = _PDFIO_PDFA_2B; // Default to 'b' + } + else if (!strncmp(version, "PDF/A-3", 7)) + { + actual_version = "1.7"; + if (version[7] == 'a') + pdf->pdfa = _PDFIO_PDFA_3A; + else if (version[7] == 'u') + pdf->pdfa = _PDFIO_PDFA_3U; + else + pdf->pdfa = _PDFIO_PDFA_3B; // Default to 'b' + } + else if (!strncmp(version, "PDF/A-4", 7)) + { + actual_version = "2.0"; + pdf->pdfa = _PDFIO_PDFA_4; + } + else + { + actual_version = version; + pdf->pdfa = _PDFIO_PDFA_NONe; + } + + pdf->version = strdup(actual_version); pdf->mode = _PDFIO_MODE_WRITE; pdf->error_cb = error_cb; pdf->error_data = error_cbdata; diff --git a/pdfio-private.h b/pdfio-private.h index 2531a1c..d8f1319 100644 --- a/pdfio-private.h +++ b/pdfio-private.h @@ -105,6 +105,20 @@ typedef enum _pdfio_mode_e // Read/write mode _PDFIO_MODE_WRITE // Write a PDF file } _pdfio_mode_t; +typedef enum _pdfio_pdfa_e +{ + _PDFIO_PDFA_NONE = 0, // Not a PDF/A file + _PDFIO_PDFA_1A, // PDF/A-1a:2005 + _PDFIO_PDFA_1B, // PDF/A-1b:2005 + _PDFIO_PDFA_2A, // PDF/A-2a:2011 + _PDFIO_PDFA_2B, // PDF/A-2b:20011 + _PDFIO_PDFA_2U, // PDF/A-2u:2011 + _PDFIO_PDFA_3A, // PDF/A-3a:2012 + _PDFIO_PDFA_3B, // PDF/A-3b:2012 + _PDFIO_PDFA_3U, // PDF/A-3u:2012 + _PDFIO_PDFA_4, // PDF/A-4:2020 +} _pdfio_pdfa_t; + typedef enum _pdfio_predictor_e // PNG predictor constants { _PDFIO_PREDICTOR_NONE = 1, // No predictor (default) @@ -239,6 +253,7 @@ struct _pdfio_file_s // PDF file structure unsigned char file_id[32]; // File identifier bytes struct lconv *loc; // Locale data char *version; // Version number + _pdfio_pdfa_t pdfa; // PDF/A conformance pdfio_rect_t media_box, // Default MediaBox value crop_box; // Default CropBox value _pdfio_mode_t mode; // Read/write mode