mirror of
https://github.com/michaelrsweet/pdfio.git
synced 2024-12-26 05:18:21 +01:00
Add text color and optimize text groups into whole blocks.
Add UNICODE_VALUE define to allow toggling between Unicode and ISO-8859-1 modes.
This commit is contained in:
parent
5a4afad566
commit
4b29c9a1c2
@ -29,6 +29,15 @@
|
|||||||
// Types...
|
// Types...
|
||||||
//
|
//
|
||||||
|
|
||||||
|
typedef enum doccolor_e // Document color enumeration
|
||||||
|
{
|
||||||
|
DOCCOLOR_BLACK, // #000
|
||||||
|
DOCCOLOR_RED, // #900
|
||||||
|
DOCCOLOR_GREEN, // #090
|
||||||
|
DOCCOLOR_BLUE, // #00C
|
||||||
|
DOCCOLOR_GRAY // #555
|
||||||
|
} doccolor_t;
|
||||||
|
|
||||||
typedef enum docfont_e // Document font enumeration
|
typedef enum docfont_e // Document font enumeration
|
||||||
{
|
{
|
||||||
DOCFONT_REGULAR, // Roboto-Regular
|
DOCFONT_REGULAR, // Roboto-Regular
|
||||||
@ -59,6 +68,7 @@ typedef struct docdata_s // Document formatting data
|
|||||||
char *heading; // Current document heading
|
char *heading; // Current document heading
|
||||||
pdfio_stream_t *st; // Current page stream
|
pdfio_stream_t *st; // Current page stream
|
||||||
double y; // Current position on page
|
double y; // Current position on page
|
||||||
|
doccolor_t color; // Current color
|
||||||
} docdata_t;
|
} docdata_t;
|
||||||
|
|
||||||
|
|
||||||
@ -90,17 +100,18 @@ static const char * const docfont_names[] =
|
|||||||
"FM"
|
"FM"
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LINE_HEIGHT 1.2 // Multiplier for line height
|
#define LINE_HEIGHT 1.4 // Multiplier for line height
|
||||||
|
|
||||||
#define SIZE_BODY 11.0 // Size of body text (points)
|
#define SIZE_BODY 11.0 // Size of body text (points)
|
||||||
#define SIZE_HEADFOOT 9.0 // Size of header/footer text
|
#define SIZE_CODEBLOCK 10.0 // Size of code block text (points)
|
||||||
#define SIZE_HEADING_1 18.0 // Size of first level heading
|
#define SIZE_HEADFOOT 9.0 // Size of header/footer text (points)
|
||||||
#define SIZE_HEADING_2 16.0 // Size of top level heading
|
#define SIZE_HEADING_1 18.0 // Size of first level heading (points)
|
||||||
#define SIZE_HEADING_3 15.0 // Size of top level heading
|
#define SIZE_HEADING_2 16.0 // Size of top level heading (points)
|
||||||
#define SIZE_HEADING_4 14.0 // Size of top level heading
|
#define SIZE_HEADING_3 15.0 // Size of top level heading (points)
|
||||||
#define SIZE_HEADING_5 13.0 // Size of top level heading
|
#define SIZE_HEADING_4 14.0 // Size of top level heading (points)
|
||||||
#define SIZE_HEADING_6 12.0 // Size of top level heading
|
#define SIZE_HEADING_5 13.0 // Size of top level heading (points)
|
||||||
#define SIZE_TABLE 10.0 // Size of table text
|
#define SIZE_HEADING_6 12.0 // Size of top level heading (points)
|
||||||
|
#define SIZE_TABLE 10.0 // Size of table text (points)
|
||||||
|
|
||||||
#define PAGE_WIDTH mm2pt(210) // Page width in points
|
#define PAGE_WIDTH mm2pt(210) // Page width in points
|
||||||
#define PAGE_LENGTH in2pt(11) // Page length in points
|
#define PAGE_LENGTH in2pt(11) // Page length in points
|
||||||
@ -114,6 +125,44 @@ static const char * const docfont_names[] =
|
|||||||
// Vertical position of header
|
// Vertical position of header
|
||||||
#define PAGE_FOOTER in2pt(0.5) // Vertical position of footer
|
#define PAGE_FOOTER in2pt(0.5) // Vertical position of footer
|
||||||
|
|
||||||
|
#define UNICODE_VALUE true // `true` for Unicode text, `false` for ISO-8859-1
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 'set_color()' - Set the stroke and fill color.
|
||||||
|
//
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_color(docdata_t *dd, // I - Document data
|
||||||
|
doccolor_t color) // I - Document color
|
||||||
|
{
|
||||||
|
switch (color)
|
||||||
|
{
|
||||||
|
case DOCCOLOR_BLACK :
|
||||||
|
pdfioContentSetFillColorDeviceGray(dd->st, 0.0);
|
||||||
|
pdfioContentSetStrokeColorDeviceGray(dd->st, 0.0);
|
||||||
|
break;
|
||||||
|
case DOCCOLOR_RED :
|
||||||
|
pdfioContentSetFillColorDeviceRGB(dd->st, 0.6, 0.0, 0.0);
|
||||||
|
pdfioContentSetStrokeColorDeviceRGB(dd->st, 0.6, 0.0, 0.0);
|
||||||
|
break;
|
||||||
|
case DOCCOLOR_GREEN :
|
||||||
|
pdfioContentSetFillColorDeviceRGB(dd->st, 0.0, 0.6, 0.0);
|
||||||
|
pdfioContentSetStrokeColorDeviceRGB(dd->st, 0.0, 0.6, 0.0);
|
||||||
|
break;
|
||||||
|
case DOCCOLOR_BLUE :
|
||||||
|
pdfioContentSetFillColorDeviceRGB(dd->st, 0.0, 0.0, 0.8);
|
||||||
|
pdfioContentSetStrokeColorDeviceRGB(dd->st, 0.0, 0.0, 0.8);
|
||||||
|
break;
|
||||||
|
case DOCCOLOR_GRAY :
|
||||||
|
pdfioContentSetFillColorDeviceGray(dd->st, 0.333);
|
||||||
|
pdfioContentSetStrokeColorDeviceGray(dd->st, 0.333);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd->color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// 'new_page()' - Start a new page.
|
// 'new_page()' - Start a new page.
|
||||||
@ -151,8 +200,7 @@ new_page(docdata_t *dd) // I - Document data
|
|||||||
dd->st = pdfioFileCreatePage(dd->pdf, page_dict);
|
dd->st = pdfioFileCreatePage(dd->pdf, page_dict);
|
||||||
|
|
||||||
// Add header/footer text
|
// Add header/footer text
|
||||||
pdfioContentSetFillColorGray(dd->st, 0.333);
|
set_color(dd, DOCCOLOR_GRAY);
|
||||||
pdfioContentSetStrokeColorGray(dd->st, 0.333);
|
|
||||||
pdfioContentSetTextFont(dd->st, docfont_names[DOCFONT_REGULAR], SIZE_HEADFOOT);
|
pdfioContentSetTextFont(dd->st, docfont_names[DOCFONT_REGULAR], SIZE_HEADFOOT);
|
||||||
|
|
||||||
if (pdfioFileGetNumPages(dd->pdf) > 1 && dd->title)
|
if (pdfioFileGetNumPages(dd->pdf) > 1 && dd->title)
|
||||||
@ -162,7 +210,7 @@ new_page(docdata_t *dd) // I - Document data
|
|||||||
|
|
||||||
pdfioContentTextBegin(dd->st);
|
pdfioContentTextBegin(dd->st);
|
||||||
pdfioContentTextMoveTo(dd->st, dd->crop_box.x1 + 0.5 * (dd->crop_box.x2 - dd->crop_box.x1 - width), dd->crop_box.y2 - SIZE_HEADFOOT);
|
pdfioContentTextMoveTo(dd->st, dd->crop_box.x1 + 0.5 * (dd->crop_box.x2 - dd->crop_box.x1 - width), dd->crop_box.y2 - SIZE_HEADFOOT);
|
||||||
pdfioContentTextShow(dd->st, /*unicode*/true, dd->title);
|
pdfioContentTextShow(dd->st, UNICODE_VALUE, dd->title);
|
||||||
pdfioContentTextEnd(dd->st);
|
pdfioContentTextEnd(dd->st);
|
||||||
|
|
||||||
pdfioContentPathMoveTo(dd->st, dd->crop_box.x1, dd->crop_box.y2 - 2 * SIZE_HEADFOOT * LINE_HEIGHT + SIZE_HEADFOOT);
|
pdfioContentPathMoveTo(dd->st, dd->crop_box.x1, dd->crop_box.y2 - 2 * SIZE_HEADFOOT * LINE_HEIGHT + SIZE_HEADFOOT);
|
||||||
@ -189,12 +237,13 @@ new_page(docdata_t *dd) // I - Document data
|
|||||||
pdfioContentTextMoveTo(dd->st, dd->crop_box.x1, dd->crop_box.y1);
|
pdfioContentTextMoveTo(dd->st, dd->crop_box.x1, dd->crop_box.y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pdfioContentTextShow(dd->st, /*unicode*/true, temp);
|
pdfioContentTextShow(dd->st, UNICODE_VALUE, temp);
|
||||||
pdfioContentTextEnd(dd->st);
|
pdfioContentTextEnd(dd->st);
|
||||||
|
|
||||||
if (dd->heading)
|
if (dd->heading)
|
||||||
{
|
{
|
||||||
pdfioContentTextBegin(dd->st);
|
pdfioContentTextBegin(dd->st);
|
||||||
|
|
||||||
if (pdfioFileGetNumPages(dd->pdf) & 1)
|
if (pdfioFileGetNumPages(dd->pdf) & 1)
|
||||||
{
|
{
|
||||||
// Current heading on left...
|
// Current heading on left...
|
||||||
@ -206,13 +255,12 @@ new_page(docdata_t *dd) // I - Document data
|
|||||||
pdfioContentTextMoveTo(dd->st, dd->crop_box.x2 - width, dd->crop_box.y1);
|
pdfioContentTextMoveTo(dd->st, dd->crop_box.x2 - width, dd->crop_box.y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pdfioContentTextShow(dd->st, /*unicode*/true, dd->heading);
|
pdfioContentTextShow(dd->st, UNICODE_VALUE, dd->heading);
|
||||||
pdfioContentTextEnd(dd->st);
|
pdfioContentTextEnd(dd->st);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The rest of the text will be full black...
|
// The rest of the text will be full black...
|
||||||
pdfioContentSetFillColorGray(dd->st, 0.0);
|
set_color(dd, DOCCOLOR_BLACK);
|
||||||
pdfioContentSetStrokeColorGray(dd->st, 0.0);
|
|
||||||
|
|
||||||
dd->y = dd->art_box.y2;
|
dd->y = dd->art_box.y2;
|
||||||
}
|
}
|
||||||
@ -242,7 +290,9 @@ format_block(docdata_t *dd, // I - Document data
|
|||||||
prevface; // Previous font face
|
prevface; // Previous font face
|
||||||
double x, y; // Current position
|
double x, y; // Current position
|
||||||
double width, // Width of current fragment
|
double width, // Width of current fragment
|
||||||
|
lwidth, // Leader width
|
||||||
wswidth; // Width of whitespace
|
wswidth; // Width of whitespace
|
||||||
|
doccolor_t color; // Color of text
|
||||||
|
|
||||||
|
|
||||||
blocktype = mmdGetType(block);
|
blocktype = mmdGetType(block);
|
||||||
@ -261,16 +311,17 @@ format_block(docdata_t *dd, // I - Document data
|
|||||||
// Add leader text on first line...
|
// Add leader text on first line...
|
||||||
pdfioContentSetTextFont(dd->st, docfont_names[prevface = fontface], fontsize);
|
pdfioContentSetTextFont(dd->st, docfont_names[prevface = fontface], fontsize);
|
||||||
|
|
||||||
width = pdfioContentTextMeasure(dd->fonts[fontface], leader, fontsize);
|
lwidth = pdfioContentTextMeasure(dd->fonts[fontface], leader, fontsize);
|
||||||
|
|
||||||
pdfioContentTextBegin(dd->st);
|
pdfioContentTextBegin(dd->st);
|
||||||
pdfioContentTextMoveTo(dd->st, left - width, y);
|
pdfioContentTextMoveTo(dd->st, left - lwidth, y);
|
||||||
pdfioContentTextShow(dd->st, /*unicode*/true, leader);
|
pdfioContentTextShow(dd->st, UNICODE_VALUE, leader);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// No leader text...
|
// No leader text...
|
||||||
prevface = DOCFONT_MAX;
|
prevface = DOCFONT_MAX;
|
||||||
|
lwidth = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (current = mmdGetFirstChild(block), x = left; current; current = next)
|
for (current = mmdGetFirstChild(block), x = left; current; current = next)
|
||||||
@ -314,6 +365,13 @@ format_block(docdata_t *dd, // I - Document data
|
|||||||
else
|
else
|
||||||
curface = fontface;
|
curface = fontface;
|
||||||
|
|
||||||
|
if (curtype == MMD_TYPE_CODE_TEXT)
|
||||||
|
color = DOCCOLOR_RED;
|
||||||
|
else if (curtype == MMD_TYPE_LINKED_TEXT)
|
||||||
|
color = DOCCOLOR_BLUE;
|
||||||
|
else
|
||||||
|
color = DOCCOLOR_BLACK;
|
||||||
|
|
||||||
width = pdfioContentTextMeasure(dd->fonts[curface], curtext, fontsize);
|
width = pdfioContentTextMeasure(dd->fonts[curface], curtext, fontsize);
|
||||||
if (curws)
|
if (curws)
|
||||||
wswidth = pdfioContentTextMeasure(dd->fonts[curface], " ", fontsize);
|
wswidth = pdfioContentTextMeasure(dd->fonts[curface], " ", fontsize);
|
||||||
@ -326,38 +384,48 @@ format_block(docdata_t *dd, // I - Document data
|
|||||||
x = left;
|
x = left;
|
||||||
y -= fontsize * LINE_HEIGHT;
|
y -= fontsize * LINE_HEIGHT;
|
||||||
|
|
||||||
if (prevface != DOCFONT_MAX)
|
|
||||||
pdfioContentTextEnd(dd->st);
|
|
||||||
|
|
||||||
prevface = DOCFONT_MAX;
|
|
||||||
|
|
||||||
if (y < dd->art_box.y1)
|
if (y < dd->art_box.y1)
|
||||||
{
|
{
|
||||||
// New page...
|
// New page...
|
||||||
|
if (prevface != DOCFONT_MAX)
|
||||||
|
{
|
||||||
|
pdfioContentTextEnd(dd->st);
|
||||||
|
prevface = DOCFONT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
new_page(dd);
|
new_page(dd);
|
||||||
|
|
||||||
y = dd->y - fontsize * LINE_HEIGHT;
|
y = dd->y - fontsize * LINE_HEIGHT;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pdfioContentTextMoveTo(dd->st, lwidth, -fontsize * LINE_HEIGHT);
|
||||||
|
lwidth = 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curface != prevface)
|
if (curface != prevface)
|
||||||
{
|
{
|
||||||
if (prevface != DOCFONT_MAX)
|
if (prevface == DOCFONT_MAX)
|
||||||
pdfioContentTextEnd(dd->st);
|
{
|
||||||
|
pdfioContentTextBegin(dd->st);
|
||||||
|
pdfioContentTextMoveTo(dd->st, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
pdfioContentSetTextFont(dd->st, docfont_names[prevface = curface], fontsize);
|
pdfioContentSetTextFont(dd->st, docfont_names[prevface = curface], fontsize);
|
||||||
pdfioContentTextBegin(dd->st);
|
|
||||||
pdfioContentTextMoveTo(dd->st, x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (color != dd->color)
|
||||||
|
set_color(dd, color);
|
||||||
|
|
||||||
if (x > left && curws)
|
if (x > left && curws)
|
||||||
{
|
{
|
||||||
pdfioContentTextShowf(dd->st, /*unicode*/true, " %s", curtext);
|
pdfioContentTextShowf(dd->st, UNICODE_VALUE, " %s", curtext);
|
||||||
x += width + wswidth;
|
x += width + wswidth;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pdfioContentTextShow(dd->st, /*unicode*/true, curtext);
|
pdfioContentTextShow(dd->st, UNICODE_VALUE, curtext);
|
||||||
x += width;
|
x += width;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,18 +435,24 @@ format_block(docdata_t *dd, // I - Document data
|
|||||||
x = left;
|
x = left;
|
||||||
y -= fontsize * LINE_HEIGHT;
|
y -= fontsize * LINE_HEIGHT;
|
||||||
|
|
||||||
if (prevface != DOCFONT_MAX)
|
|
||||||
pdfioContentTextEnd(dd->st);
|
|
||||||
|
|
||||||
prevface = DOCFONT_MAX;
|
|
||||||
|
|
||||||
if (y < dd->art_box.y1)
|
if (y < dd->art_box.y1)
|
||||||
{
|
{
|
||||||
// New page...
|
// New page...
|
||||||
|
if (prevface != DOCFONT_MAX)
|
||||||
|
{
|
||||||
|
pdfioContentTextEnd(dd->st);
|
||||||
|
prevface = DOCFONT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
new_page(dd);
|
new_page(dd);
|
||||||
|
|
||||||
y = dd->y - fontsize * LINE_HEIGHT;
|
y = dd->y - fontsize * LINE_HEIGHT;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pdfioContentTextMoveTo(dd->st, lwidth, -fontsize * LINE_HEIGHT);
|
||||||
|
lwidth = 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,7 +613,7 @@ main(int argc, // I - Number of command-line arguments
|
|||||||
// Add fonts...
|
// Add fonts...
|
||||||
for (fontface = DOCFONT_REGULAR; fontface < DOCFONT_MAX; fontface ++)
|
for (fontface = DOCFONT_REGULAR; fontface < DOCFONT_MAX; fontface ++)
|
||||||
{
|
{
|
||||||
if ((dd.fonts[fontface] = pdfioFileCreateFontObjFromFile(dd.pdf, docfont_filenames[fontface], /*unicode*/true)) == NULL)
|
if ((dd.fonts[fontface] = pdfioFileCreateFontObjFromFile(dd.pdf, docfont_filenames[fontface], UNICODE_VALUE)) == NULL)
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user