From 7c69f13ba9811d147e20717053c13eb79029c810 Mon Sep 17 00:00:00 2001
From: Michael R Sweet Content in a page stream can be tagged to help a PDF reader application know the kind and organization of that content. Content inserted using the PDFio Page Stream Functions can be tagged by surrounding it with the The To mark the same paragraph with a content identifier you would first create a dictionary containing the "MCID" key/value pair and then mark the paragraph with that dictionary: PDFio includes several example programs that are typically installed to the Finally, we render each row in the table: The formatted content in arrays of
+pdfioContentTextShowJustified draws an array of literal strings with offsets between themTagged and Marked PDF Content
+pdfioContentBeginMarked and pdfioContentEndMarked functions.pdfioContentBeginMarked function accepts a named tag and optional dictionary of attributes such as the marked content identifier ("MCID"). For example, the following code tags a paragraph of text:
+pdfio_file_t *pdf; // PDF file
+pdfio_stream_t *st; // Page stream
+
+pdfioContentBeginMarked(st, "P", /*dict*/NULL);
+
+pdfioContentTextShow(st, /*unicode*/false, "Mary had a little lamb\n");
+pdfioContentTextShow(st, /*unicode*/false, "whose fleece was white as snow.\n");
+pdfioContentTextShow(st, /*unicode*/false, "And everywhere that Mary went\n");
+pdfioContentTextShow(st, /*unicode*/false, "the lamb was sure to go,\n");
+
+pdfioContentEndMarked(st);
+pdfio_file_t *pdf; // PDF file
+pdfio_stream_t *st; // Page stream
+pdfio_dict_t *dict; // Content dictionary
+
+dict = pdfioDictCreate(pdf);
+pdfioDictSetNumber(dict, "MCID", 42);
+
+pdfioContentBeginMarked(st, "P", dict);
+
+pdfioContentTextShow(st, /*unicode*/false, "Mary had a little lamb\n");
+pdfioContentTextShow(st, /*unicode*/false, "whose fleece was white as snow.\n");
+pdfioContentTextShow(st, /*unicode*/false, "And everywhere that Mary went\n");
+pdfioContentTextShow(st, /*unicode*/false, "the lamb was sure to go,\n");
+
+pdfioContentEndMarked(st);
+Examples
/usr/share/doc/pdfio/examples or /usr/local/share/doc/pdfio/examples directories. A makefile is included to build them.Read PDF Metadata
@@ -1753,6 +1788,9 @@ pdfioStreamClose(page_st);
// State for the current page
pdfio_stream_t *st; // Current page stream
double y; // Current position on page
+ const char *tag; // Current block tag
+ bool in_table, // Are we in a table?
+ in_row; // Are we in a table row?
docfont_t font; // Current font
double fsize; // Current font size
doccolor_t color; // Current color
@@ -2130,6 +2168,9 @@ pdfioContentPathRect(dd->st, left - CODE_PADDING, dd->y + SIZE_CODEBLOCK,
pdfioContentFillAndStroke(dd->st, false);
// Start a code text block...
+dd->tag = "P";
+pdfioContentBeginMarked(dd->st, dd->tag, /*dict*/NULL);
+
set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK);
pdfioContentTextBegin(dd->st);
pdfioContentTextMoveTo(dd->st, left, dd->y);
@@ -2166,6 +2207,9 @@ pdfioContentTextMoveTo(dd->st, left, dd->y);
pdfioContentTextEnd(dd->st);
dd->y += lineheight;
+pdfioContentEndMarked(dd->st);
+dd->tag = NULL;
+
// Draw the bottom padding...
set_color(dd, DOCCOLOR_LTGRAY);
pdfioContentPathRect(dd->st, left - CODE_PADDING,
@@ -2276,8 +2320,17 @@ pdfioContentFillAndStroke(dd->st, false);
// Render each table row...
+dd->in_table = true;
+
+if (dd->st)
+ pdfioContentBeginMarked(dd->st, "Table", /*dict*/NULL);
+
for (row = 0, rowptr = rows; row < num_rows; row ++, rowptr ++)
render_row(dd, num_cols, cols, rowptr);
+
+pdfioContentEndMarked(dd->st);
+
+dd->in_table = false;
Rendering the Markdown Document
linefrag_t and tablerow_t structures are passed to the render_line and render_row functions respectively to produce content in the PDF document.
true on success, false otherwise
Start marked content with an optional dictionary.
++bool pdfioContentBeginMarked(pdfio_stream_t *st, const char *tag, pdfio_dict_t *dict);
+| st | +Stream |
|---|---|
| tag | +Tag name of marked content |
| dict | +Dictionary of parameters or NULL if none |
true on success, false on failure
This function starts an area of marked content with an optional dictionary.
+It must be paired with a call to the pdfioContentEndMarked function.
+
+The "tag" argument specifies the tag name string for the content such as "P"
+for a paragraph, "H1" for a top-level heading, and so forth. The "dict"
+argument specifies an optional dictionary of properties for the content such
+as the marked content identifier ("MCID") number.
+
+Calling this function sets the "Marked" key in the "MarkInfo" dictionary of
+the document catalog. The caller is responsible for setting the
+"StructTreeRoot" dictionary when creating marked content.
+
+
Clip output to the current path.
@@ -2804,6 +2886,22 @@ size_t pdfioArrayGetSize(pdfio_array_t *a);
The object name must be part of the page dictionary resources, typically
using the pdfioPageDictAddImage function.
End marked content.
++bool pdfioContentEndMarked(pdfio_stream_t *st);
+| st | +Stream |
|---|
true on success, false on failure
This function ends an area of marked content that was started using the
+pdfioContentBeginMarked function.
+
+
Fill the current path.
diff --git a/doc/pdfio.md b/doc/pdfio.md
index 8709d33..eac3c67 100644
--- a/doc/pdfio.md
+++ b/doc/pdfio.md
@@ -868,6 +868,55 @@ escaping, as needed:
offsets between them
+Tagged and Marked PDF Content
+-----------------------------
+
+Content in a page stream can be tagged to help a PDF reader application know the
+kind and organization of that content. Content inserted using the PDFio
+[Page Stream Functions](@) can be tagged by surrounding it with the
+[`pdfioContentBeginMarked`](@@) and [`pdfioContentEndMarked`](@@) functions.
+
+The `pdfioContentBeginMarked` function accepts a named tag and optional
+dictionary of attributes such as the marked content identifier ("MCID"). For
+example, the following code tags a paragraph of text:
+
+```c
+pdfio_file_t *pdf; // PDF file
+pdfio_stream_t *st; // Page stream
+
+pdfioContentBeginMarked(st, "P", /*dict*/NULL);
+
+pdfioContentTextShow(st, /*unicode*/false, "Mary had a little lamb\n");
+pdfioContentTextShow(st, /*unicode*/false, "whose fleece was white as snow.\n");
+pdfioContentTextShow(st, /*unicode*/false, "And everywhere that Mary went\n");
+pdfioContentTextShow(st, /*unicode*/false, "the lamb was sure to go,\n");
+
+pdfioContentEndMarked(st);
+```
+
+To mark the same paragraph with a content identifier you would first create a
+dictionary containing the "MCID" key/value pair and then mark the paragraph with
+that dictionary:
+
+```c
+pdfio_file_t *pdf; // PDF file
+pdfio_stream_t *st; // Page stream
+pdfio_dict_t *dict; // Content dictionary
+
+dict = pdfioDictCreate(pdf);
+pdfioDictSetNumber(dict, "MCID", 42);
+
+pdfioContentBeginMarked(st, "P", dict);
+
+pdfioContentTextShow(st, /*unicode*/false, "Mary had a little lamb\n");
+pdfioContentTextShow(st, /*unicode*/false, "whose fleece was white as snow.\n");
+pdfioContentTextShow(st, /*unicode*/false, "And everywhere that Mary went\n");
+pdfioContentTextShow(st, /*unicode*/false, "the lamb was sure to go,\n");
+
+pdfioContentEndMarked(st);
+```
+
+
Examples
========
@@ -1597,6 +1646,9 @@ typedef struct docdata_s // Document formatting data
// State for the current page
pdfio_stream_t *st; // Current page stream
double y; // Current position on page
+ const char *tag; // Current block tag
+ bool in_table, // Are we in a table?
+ in_row; // Are we in a table row?
docfont_t font; // Current font
double fsize; // Current font size
doccolor_t color; // Current color
@@ -2100,6 +2152,9 @@ pdfioContentPathRect(dd->st, left - CODE_PADDING, dd->y + SIZE_CODEBLOCK,
pdfioContentFillAndStroke(dd->st, false);
// Start a code text block...
+dd->tag = "P";
+pdfioContentBeginMarked(dd->st, dd->tag, /*dict*/NULL);
+
set_font(dd, DOCFONT_MONOSPACE, SIZE_CODEBLOCK);
pdfioContentTextBegin(dd->st);
pdfioContentTextMoveTo(dd->st, left, dd->y);
@@ -2136,6 +2191,9 @@ for (code = mmdGetFirstChild(block); code; code = mmdGetNextSibling(code))
pdfioContentTextEnd(dd->st);
dd->y += lineheight;
+pdfioContentEndMarked(dd->st);
+dd->tag = NULL;
+
// Draw the bottom padding...
set_color(dd, DOCCOLOR_LTGRAY);
pdfioContentPathRect(dd->st, left - CODE_PADDING,
@@ -2276,8 +2334,17 @@ Finally, we render each row in the table:
```c
// Render each table row...
+dd->in_table = true;
+
+if (dd->st)
+ pdfioContentBeginMarked(dd->st, "Table", /*dict*/NULL);
+
for (row = 0, rowptr = rows; row < num_rows; row ++, rowptr ++)
render_row(dd, num_cols, cols, rowptr);
+
+pdfioContentEndMarked(dd->st);
+
+dd->in_table = false;
```
diff --git a/pdfio-content.c b/pdfio-content.c
index 81e1134..78f0ad5 100644
--- a/pdfio-content.c
+++ b/pdfio-content.c
@@ -467,13 +467,22 @@ pdfioArrayCreateColorFromStandard(
// This function starts an area of marked content with an optional dictionary.
// It must be paired with a call to the @link pdfioContentEndMarked@ function.
//
+// The "tag" argument specifies the tag name string for the content such as "P"
+// for a paragraph, "H1" for a top-level heading, and so forth. The "dict"
+// argument specifies an optional dictionary of properties for the content such
+// as the marked content identifier ("MCID") number.
+//
+// Calling this function sets the "Marked" key in the "MarkInfo" dictionary of
+// the document catalog. The caller is responsible for setting the
+// "StructTreeRoot" dictionary when creating marked content.
+//
// @since PDFio 1.6@
//
bool // O - `true` on success, `false` on failure
pdfioContentBeginMarked(
pdfio_stream_t *st, // I - Stream
- const char *name, // I - Name of marked content
+ const char *tag, // I - Tag name of marked content
pdfio_dict_t *dict) // I - Dictionary of parameters or `NULL` if none
{
if (!st || !name)
diff --git a/pdfio-content.h b/pdfio-content.h
index 0c325c5..6ee4d24 100644
--- a/pdfio-content.h
+++ b/pdfio-content.h
@@ -69,7 +69,7 @@ extern pdfio_array_t *pdfioArrayCreateColorFromPrimaries(pdfio_file_t *pdf, size
extern pdfio_array_t *pdfioArrayCreateColorFromStandard(pdfio_file_t *pdf, size_t num_colors, pdfio_cs_t cs);
// PDF content drawing functions...
-extern bool pdfioContentBeginMarked(pdfio_stream_t *st, const char *name, pdfio_dict_t *dict) _PDFIO_PUBLIC;
+extern bool pdfioContentBeginMarked(pdfio_stream_t *st, const char *tag, pdfio_dict_t *dict) _PDFIO_PUBLIC;
extern bool pdfioContentClip(pdfio_stream_t *st, bool even_odd) _PDFIO_PUBLIC;
extern bool pdfioContentDrawImage(pdfio_stream_t *st, const char *name, double x, double y, double w, double h) _PDFIO_PUBLIC;
extern bool pdfioContentEndMarked(pdfio_stream_t *st) _PDFIO_PUBLIC;
From 203a974682bd1091833bafe98e797e2c0aa12722 Mon Sep 17 00:00:00 2001
From: Michael R Sweet