mirror of
https://github.com/michaelrsweet/pdfio.git
synced 2024-12-27 05:48:20 +01:00
Compare commits
4 Commits
d4e3bbcf16
...
53967552df
Author | SHA1 | Date | |
---|---|---|---|
|
53967552df | ||
|
f8639fbd64 | ||
|
9020e92928 | ||
|
48e6597337 |
175
doc/pdfio.md
175
doc/pdfio.md
@ -33,7 +33,7 @@ PDFio requires the following to build the software:
|
|||||||
IDE files for Xcode (macOS/iOS) and Visual Studio (Windows) are also provided.
|
IDE files for Xcode (macOS/iOS) and Visual Studio (Windows) are also provided.
|
||||||
|
|
||||||
|
|
||||||
Installing pdfio
|
Installing PDFio
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
PDFio comes with a configure script that creates a portable makefile that will
|
PDFio comes with a configure script that creates a portable makefile that will
|
||||||
@ -315,7 +315,8 @@ Reading PDF Files
|
|||||||
You open an existing PDF file using the [`pdfioFileOpen`](@@) function:
|
You open an existing PDF file using the [`pdfioFileOpen`](@@) function:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
pdfio_file_t *pdf = pdfioFileOpen("myinputfile.pdf", password_cb, password_data,
|
pdfio_file_t *pdf =
|
||||||
|
pdfioFileOpen("myinputfile.pdf", password_cb, password_data,
|
||||||
error_cb, error_data);
|
error_cb, error_data);
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -763,6 +764,9 @@ pdfio_obj_t *img =
|
|||||||
/*interpolate*/true);
|
/*interpolate*/true);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note: Currently `pdfioFileCreateImageObjFromFile` does not support 12 bit JPEG
|
||||||
|
> files or PNG files with an alpha channel.
|
||||||
|
|
||||||
|
|
||||||
### Page Dictionary Functions
|
### Page Dictionary Functions
|
||||||
|
|
||||||
@ -862,6 +866,7 @@ escaping, as needed:
|
|||||||
Examples
|
Examples
|
||||||
========
|
========
|
||||||
|
|
||||||
|
|
||||||
Read PDF Metadata
|
Read PDF Metadata
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
@ -992,3 +997,169 @@ create_pdf_image_file(const char *pdfname, const char *imagename,
|
|||||||
pdfioFileClose(pdf);
|
pdfioFileClose(pdf);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Generate a Code 128 Barcode
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
One-dimensional barcodes are often rendered using special fonts that map ASCII
|
||||||
|
characters to sequences of bars that can be read. The "examples" directory
|
||||||
|
contains such a font to create "Code 128" barcodes, with an accompanying bit of
|
||||||
|
example code.
|
||||||
|
|
||||||
|
The first thing you need to do is prepare the barcode string to use with the
|
||||||
|
font. Each barcode begins with a start pattern followed by the characters or
|
||||||
|
digits you want to encode, a weighted sum digit, and a stop pattern. The
|
||||||
|
`make_code128` function creates this string:
|
||||||
|
|
||||||
|
```c
|
||||||
|
static char * // O - Output string
|
||||||
|
make_code128(char *dst, // I - Destination buffer
|
||||||
|
const char *src, // I - Source string
|
||||||
|
size_t dstsize) // I - Size of destination buffer
|
||||||
|
{
|
||||||
|
char *dstptr, // Pointer into destination buffer
|
||||||
|
*dstend; // End of destination buffer
|
||||||
|
int sum; // Weighted sum
|
||||||
|
static const char *code128_chars = // Code 128 characters
|
||||||
|
" !\"#$%&'()*+,-./0123456789:;<=>?"
|
||||||
|
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
|
||||||
|
"`abcdefghijklmnopqrstuvwxyz{|}~\303"
|
||||||
|
"\304\305\306\307\310\311\312";
|
||||||
|
static const char code128_start_code_b = '\314';
|
||||||
|
// Start code B
|
||||||
|
static const char code128_stop = '\316';
|
||||||
|
// Stop pattern
|
||||||
|
|
||||||
|
|
||||||
|
// Start a Code B barcode...
|
||||||
|
dstptr = dst;
|
||||||
|
dstend = dst + dstsize - 3;
|
||||||
|
|
||||||
|
*dstptr++ = code128_start_code_b;
|
||||||
|
sum = code128_start_code_b - 100;
|
||||||
|
|
||||||
|
while (*src && dstptr < dstend)
|
||||||
|
{
|
||||||
|
if (*src >= ' ' && *src < 0x7f)
|
||||||
|
{
|
||||||
|
sum += (dstptr - dst) * (*src - ' ');
|
||||||
|
*dstptr++ = *src;
|
||||||
|
}
|
||||||
|
|
||||||
|
src ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the weighted sum modulo 103
|
||||||
|
*dstptr++ = code128_chars[sum % 103];
|
||||||
|
|
||||||
|
// Add the stop pattern and return...
|
||||||
|
*dstptr++ = code128_stop;
|
||||||
|
*dstptr = '\0';
|
||||||
|
|
||||||
|
return (dst);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `main` function does the rest of the work. The barcode font is imported
|
||||||
|
using the [`pdfioFileCreateFontObjFromFile`](@@) function. We pass `false`
|
||||||
|
for the "unicode" argument since we just want the (default) ASCII encoding:
|
||||||
|
|
||||||
|
```c
|
||||||
|
barcode_font = pdfioFileCreateFontObjFromFile(pdf, "code128.ttf",
|
||||||
|
/*unicode*/false);
|
||||||
|
```
|
||||||
|
|
||||||
|
Since barcodes usually have the number or text represented by the barcode
|
||||||
|
printed underneath it, we also need a regular text font, for which we can choose
|
||||||
|
one of the standard 14 PostScript base fonts using the
|
||||||
|
[`pdfioFIleCreateFontObjFromBase`](@@) function:
|
||||||
|
|
||||||
|
```c
|
||||||
|
text_font = pdfioFileCreateFontObjFromBase(pdf, "Helvetica");
|
||||||
|
```
|
||||||
|
|
||||||
|
Once we have these fonts we can measure the barcode and regular text labels
|
||||||
|
using the [`pdfioContentTextMeasure`](@@) function to determine how large the
|
||||||
|
PDF page needs to be to hold the barcode and text:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// Compute sizes of the text...
|
||||||
|
const char *barcode = argv[1];
|
||||||
|
char barcode_temp[256];
|
||||||
|
|
||||||
|
if (!(barcode[0] & 0x80))
|
||||||
|
barcode = make_code128(barcode_temp, barcode, sizeof(barcode_temp));
|
||||||
|
|
||||||
|
double barcode_height = 36.0;
|
||||||
|
double barcode_width =
|
||||||
|
pdfioContentTextMeasure(barcode_font, barcode, barcode_height);
|
||||||
|
|
||||||
|
const char *text = argv[2];
|
||||||
|
double text_height = 0.0;
|
||||||
|
double text_width = 0.0;
|
||||||
|
|
||||||
|
if (text && text_font)
|
||||||
|
{
|
||||||
|
text_height = 9.0;
|
||||||
|
text_width = pdfioContentTextMeasure(text_font, text,
|
||||||
|
text_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the size of the PDF page...
|
||||||
|
pdfio_rect_t media_box;
|
||||||
|
|
||||||
|
media_box.x1 = 0.0;
|
||||||
|
media_box.y1 = 0.0;
|
||||||
|
media_box.x2 = (barcode_width > text_width ?
|
||||||
|
barcode_width : text_width) + 18.0;
|
||||||
|
media_box.y2 = barcode_height + text_height + 18.0;
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, we just need to create a page of the specified size that references the
|
||||||
|
two fonts:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// Start a page for the barcode...
|
||||||
|
page_dict = pdfioDictCreate(pdf);
|
||||||
|
|
||||||
|
pdfioDictSetRect(page_dict, "MediaBox", &media_box);
|
||||||
|
pdfioDictSetRect(page_dict, "CropBox", &media_box);
|
||||||
|
|
||||||
|
pdfioPageDictAddFont(page_dict, "B128", barcode_font);
|
||||||
|
if (text_font)
|
||||||
|
pdfioPageDictAddFont(page_dict, "TEXT", text_font);
|
||||||
|
|
||||||
|
page_st = pdfioFileCreatePage(pdf, page_dict);
|
||||||
|
```
|
||||||
|
|
||||||
|
With the barcode font called "B128" and the text font called "TEXT", we can
|
||||||
|
use them to draw two strings:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// Draw the page...
|
||||||
|
pdfioContentSetFillColorGray(page_st, 0.0);
|
||||||
|
|
||||||
|
pdfioContentSetTextFont(page_st, "B128", barcode_height);
|
||||||
|
pdfioContentTextBegin(page_st);
|
||||||
|
pdfioContentTextMoveTo(page_st, 0.5 * (media_box.x2 - barcode_width),
|
||||||
|
9.0 + text_height);
|
||||||
|
pdfioContentTextShow(page_st, /*unicode*/false, barcode);
|
||||||
|
pdfioContentTextEnd(page_st);
|
||||||
|
|
||||||
|
if (text && text_font)
|
||||||
|
{
|
||||||
|
pdfioContentSetTextFont(page_st, "TEXT", text_height);
|
||||||
|
pdfioContentTextBegin(page_st);
|
||||||
|
pdfioContentTextMoveTo(page_st, 0.5 * (media_box.x2 - text_width), 9.0);
|
||||||
|
pdfioContentTextShow(page_st, /*unicode*/false, text);
|
||||||
|
pdfioContentTextEnd(page_st);
|
||||||
|
}
|
||||||
|
|
||||||
|
pdfioStreamClose(page_st);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Convert Markdown to PDF
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
// extended characters are ignored in the source string.
|
// extended characters are ignored in the source string.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
static char * // O - Output string
|
static char * // O - Output string
|
||||||
make_code128(char *dst, // I - Destination buffer
|
make_code128(char *dst, // I - Destination buffer
|
||||||
const char *src, // I - Source string
|
const char *src, // I - Source string
|
||||||
@ -54,9 +53,9 @@ make_code128(char *dst, // I - Destination buffer
|
|||||||
static const char code128_start_code_a = '\313';
|
static const char code128_start_code_a = '\313';
|
||||||
// Start code A
|
// Start code A
|
||||||
static const char code128_start_code_b = '\314';
|
static const char code128_start_code_b = '\314';
|
||||||
// Start code A
|
// Start code B
|
||||||
static const char code128_start_code_c = '\315';
|
static const char code128_start_code_c = '\315';
|
||||||
// Start code A
|
// Start code C
|
||||||
static const char code128_stop = '\316';
|
static const char code128_stop = '\316';
|
||||||
// Stop pattern
|
// Stop pattern
|
||||||
|
|
||||||
@ -149,7 +148,7 @@ main(int argc, // I - Number of command-line arguments
|
|||||||
// Load fonts...
|
// Load fonts...
|
||||||
barcode_font = pdfioFileCreateFontObjFromFile(pdf, "code128.ttf", /*unicode*/false);
|
barcode_font = pdfioFileCreateFontObjFromFile(pdf, "code128.ttf", /*unicode*/false);
|
||||||
if (text)
|
if (text)
|
||||||
text_font = pdfioFileCreateFontObjFromFile(pdf, "../testfiles/OpenSans-Regular.ttf", /*unicode*/true);
|
text_font = pdfioFileCreateFontObjFromBase(pdf, "Helvetica");
|
||||||
|
|
||||||
// Generate Code128 characters for the desired barcode...
|
// Generate Code128 characters for the desired barcode...
|
||||||
if (!(barcode[0] & 0x80))
|
if (!(barcode[0] & 0x80))
|
||||||
@ -182,7 +181,7 @@ main(int argc, // I - Number of command-line arguments
|
|||||||
page_st = pdfioFileCreatePage(pdf, page_dict);
|
page_st = pdfioFileCreatePage(pdf, page_dict);
|
||||||
|
|
||||||
// Draw the page...
|
// Draw the page...
|
||||||
pdfioContentSetStrokeColorGray(page_st, 0.0);
|
pdfioContentSetFillColorGray(page_st, 0.0);
|
||||||
|
|
||||||
pdfioContentSetTextFont(page_st, "B128", barcode_height);
|
pdfioContentSetTextFont(page_st, "B128", barcode_height);
|
||||||
pdfioContentTextBegin(page_st);
|
pdfioContentTextBegin(page_st);
|
||||||
@ -195,7 +194,7 @@ main(int argc, // I - Number of command-line arguments
|
|||||||
pdfioContentSetTextFont(page_st, "TEXT", text_height);
|
pdfioContentSetTextFont(page_st, "TEXT", text_height);
|
||||||
pdfioContentTextBegin(page_st);
|
pdfioContentTextBegin(page_st);
|
||||||
pdfioContentTextMoveTo(page_st, 0.5 * (media_box.x2 - text_width), 9.0);
|
pdfioContentTextMoveTo(page_st, 0.5 * (media_box.x2 - text_width), 9.0);
|
||||||
pdfioContentTextShow(page_st, /*unicode*/true, text);
|
pdfioContentTextShow(page_st, /*unicode*/false, text);
|
||||||
pdfioContentTextEnd(page_st);
|
pdfioContentTextEnd(page_st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
//
|
//
|
||||||
|
// ./md2pdf FILENAME.md FILENAME.pdf
|
||||||
// ./md2pdf FILENAME.md >FILENAME.pdf
|
// ./md2pdf FILENAME.md >FILENAME.pdf
|
||||||
//
|
//
|
||||||
// The generated PDF file is formatted for a "universal" paper size (8.27x11",
|
// The generated PDF file is formatted for a "universal" paper size (8.27x11",
|
||||||
@ -40,7 +41,7 @@ typedef enum doccolor_e // Document color enumeration
|
|||||||
{
|
{
|
||||||
DOCCOLOR_BLACK, // #000
|
DOCCOLOR_BLACK, // #000
|
||||||
DOCCOLOR_RED, // #900
|
DOCCOLOR_RED, // #900
|
||||||
DOCCOLOR_GREEN, // #090
|
DOCCOLOR_ORANGE, // #CC0
|
||||||
DOCCOLOR_BLUE, // #00C
|
DOCCOLOR_BLUE, // #00C
|
||||||
DOCCOLOR_LTGRAY, // #EEE
|
DOCCOLOR_LTGRAY, // #EEE
|
||||||
DOCCOLOR_GRAY // #555
|
DOCCOLOR_GRAY // #555
|
||||||
@ -238,7 +239,7 @@ static double measure_cell(docdata_t *dd, mmd_t *cell, tablecol_t *col);
|
|||||||
static mmd_t *mmd_walk_next(mmd_t *top, mmd_t *node);
|
static mmd_t *mmd_walk_next(mmd_t *top, mmd_t *node);
|
||||||
static void new_page(docdata_t *dd);
|
static void new_page(docdata_t *dd);
|
||||||
static ssize_t output_cb(void *output_cbdata, const void *buffer, size_t bytes);
|
static ssize_t output_cb(void *output_cbdata, const void *buffer, size_t bytes);
|
||||||
static void render_line(docdata_t *dd, double margin_left, double margin_top, double lineheight, size_t num_frags, linefrag_t *frags);
|
static void render_line(docdata_t *dd, double margin_left, double margin_top, double need_bottom, double lineheight, size_t num_frags, linefrag_t *frags);
|
||||||
static void render_row(docdata_t *dd, size_t num_cols, tablecol_t *cols, tablerow_t *row);
|
static void render_row(docdata_t *dd, size_t num_cols, tablecol_t *cols, tablerow_t *row);
|
||||||
static void set_color(docdata_t *dd, doccolor_t color);
|
static void set_color(docdata_t *dd, doccolor_t color);
|
||||||
static void set_font(docdata_t *dd, docfont_t font, double fsize);
|
static void set_font(docdata_t *dd, docfont_t font, double fsize);
|
||||||
@ -262,9 +263,10 @@ main(int argc, // I - Number of command-line arguments
|
|||||||
setbuf(stderr, NULL);
|
setbuf(stderr, NULL);
|
||||||
|
|
||||||
// Get the markdown file from the command-line...
|
// Get the markdown file from the command-line...
|
||||||
if (argc != 2)
|
if (argc < 2 || argc > 3)
|
||||||
{
|
{
|
||||||
fputs("Usage: md2pdf FILENANE.md >FILENAME.pdf\n", stderr);
|
fputs("Usage: md2pdf FILENANE.md [FILENAME.pdf]\n", stderr);
|
||||||
|
fputs(" md2pdf FILENANE.md >FILENAME.pdf\n", stderr);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,6 +291,8 @@ main(int argc, // I - Number of command-line arguments
|
|||||||
|
|
||||||
dd.title = mmdGetMetadata(doc, "title");
|
dd.title = mmdGetMetadata(doc, "title");
|
||||||
|
|
||||||
|
if (argc == 2)
|
||||||
|
{
|
||||||
// Output a PDF file to the standard output...
|
// Output a PDF file to the standard output...
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
setmode(1, O_BINARY); // Force binary output on Windows
|
setmode(1, O_BINARY); // Force binary output on Windows
|
||||||
@ -296,6 +300,11 @@ main(int argc, // I - Number of command-line arguments
|
|||||||
|
|
||||||
if ((dd.pdf = pdfioFileCreateOutput(output_cb, /*output_cbdata*/NULL, /*version*/NULL, /*media_box*/NULL, /*crop_box*/NULL, /*error_cb*/NULL, /*error_data*/NULL)) == NULL)
|
if ((dd.pdf = pdfioFileCreateOutput(output_cb, /*output_cbdata*/NULL, /*version*/NULL, /*media_box*/NULL, /*crop_box*/NULL, /*error_cb*/NULL, /*error_data*/NULL)) == NULL)
|
||||||
return (1);
|
return (1);
|
||||||
|
}
|
||||||
|
else if ((dd.pdf = pdfioFileCreate(argv[2], /*version*/NULL, /*media_box*/NULL, /*crop_box*/NULL, /*error_cb*/NULL, /*error_data*/NULL)) == NULL)
|
||||||
|
{
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
if ((value = mmdGetMetadata(doc, "author")) != NULL)
|
if ((value = mmdGetMetadata(doc, "author")) != NULL)
|
||||||
pdfioFileSetAuthor(dd.pdf, value);
|
pdfioFileSetAuthor(dd.pdf, value);
|
||||||
@ -540,6 +549,7 @@ format_block(docdata_t *dd, // I - Document data
|
|||||||
wswidth, // Width of whitespace
|
wswidth, // Width of whitespace
|
||||||
margin_left, // Left margin
|
margin_left, // Left margin
|
||||||
margin_top, // Top margin
|
margin_top, // Top margin
|
||||||
|
need_bottom, // Space needed after this block
|
||||||
height, // Height of current fragment
|
height, // Height of current fragment
|
||||||
lineheight; // Height of current line
|
lineheight; // Height of current line
|
||||||
|
|
||||||
@ -551,6 +561,11 @@ format_block(docdata_t *dd, // I - Document data
|
|||||||
else
|
else
|
||||||
margin_top = fsize * LINE_HEIGHT;
|
margin_top = fsize * LINE_HEIGHT;
|
||||||
|
|
||||||
|
if (mmdGetNextSibling(block))
|
||||||
|
need_bottom = 3.0 * SIZE_BODY * LINE_HEIGHT;
|
||||||
|
else
|
||||||
|
need_bottom = 0.0;
|
||||||
|
|
||||||
if (leader)
|
if (leader)
|
||||||
{
|
{
|
||||||
// Add leader text on first line...
|
// Add leader text on first line...
|
||||||
@ -620,15 +635,18 @@ format_block(docdata_t *dd, // I - Document data
|
|||||||
else
|
else
|
||||||
margin_left = 0.0;
|
margin_left = 0.0;
|
||||||
|
|
||||||
render_line(dd, margin_left, margin_top, lineheight, num_frags, frags);
|
render_line(dd, margin_left, margin_top, need_bottom, lineheight, num_frags, frags);
|
||||||
|
|
||||||
if (deffont == DOCFONT_ITALIC)
|
if (deffont == DOCFONT_ITALIC)
|
||||||
{
|
{
|
||||||
// Add a gray bar to the left of block quotes...
|
// Add an orange bar to the left of block quotes...
|
||||||
set_color(dd, DOCCOLOR_GREEN);
|
set_color(dd, DOCCOLOR_ORANGE);
|
||||||
|
pdfioContentSave(dd->st);
|
||||||
|
pdfioContentSetLineWidth(dd->st, 3.0);
|
||||||
pdfioContentPathMoveTo(dd->st, left - 6.0, dd->y - (LINE_HEIGHT - 1.0) * fsize);
|
pdfioContentPathMoveTo(dd->st, left - 6.0, dd->y - (LINE_HEIGHT - 1.0) * fsize);
|
||||||
pdfioContentPathLineTo(dd->st, left - 6.0, dd->y + fsize);
|
pdfioContentPathLineTo(dd->st, left - 6.0, dd->y + fsize);
|
||||||
pdfioContentStroke(dd->st);
|
pdfioContentStroke(dd->st);
|
||||||
|
pdfioContentRestore(dd->st);
|
||||||
}
|
}
|
||||||
|
|
||||||
num_frags = 0;
|
num_frags = 0;
|
||||||
@ -636,6 +654,7 @@ format_block(docdata_t *dd, // I - Document data
|
|||||||
x = left;
|
x = left;
|
||||||
lineheight = 0.0;
|
lineheight = 0.0;
|
||||||
margin_top = 0.0;
|
margin_top = 0.0;
|
||||||
|
need_bottom = 0.0;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -685,15 +704,18 @@ format_block(docdata_t *dd, // I - Document data
|
|||||||
else
|
else
|
||||||
margin_left = 0.0;
|
margin_left = 0.0;
|
||||||
|
|
||||||
render_line(dd, margin_left, margin_top, lineheight, num_frags, frags);
|
render_line(dd, margin_left, margin_top, need_bottom, lineheight, num_frags, frags);
|
||||||
|
|
||||||
if (deffont == DOCFONT_ITALIC)
|
if (deffont == DOCFONT_ITALIC)
|
||||||
{
|
{
|
||||||
// Add a gray bar to the left of block quotes...
|
// Add an orange bar to the left of block quotes...
|
||||||
set_color(dd, DOCCOLOR_GREEN);
|
set_color(dd, DOCCOLOR_ORANGE);
|
||||||
|
pdfioContentSave(dd->st);
|
||||||
|
pdfioContentSetLineWidth(dd->st, 3.0);
|
||||||
pdfioContentPathMoveTo(dd->st, left - 6.0, dd->y - (LINE_HEIGHT - 1.0) * fsize);
|
pdfioContentPathMoveTo(dd->st, left - 6.0, dd->y - (LINE_HEIGHT - 1.0) * fsize);
|
||||||
pdfioContentPathLineTo(dd->st, left - 6.0, dd->y + fsize);
|
pdfioContentPathLineTo(dd->st, left - 6.0, dd->y + fsize);
|
||||||
pdfioContentStroke(dd->st);
|
pdfioContentStroke(dd->st);
|
||||||
|
pdfioContentRestore(dd->st);
|
||||||
}
|
}
|
||||||
|
|
||||||
num_frags = 0;
|
num_frags = 0;
|
||||||
@ -701,6 +723,7 @@ format_block(docdata_t *dd, // I - Document data
|
|||||||
x = left;
|
x = left;
|
||||||
lineheight = 0.0;
|
lineheight = 0.0;
|
||||||
margin_top = 0.0;
|
margin_top = 0.0;
|
||||||
|
need_bottom = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the current node to the fragment list
|
// Add the current node to the fragment list
|
||||||
@ -737,15 +760,18 @@ format_block(docdata_t *dd, // I - Document data
|
|||||||
else
|
else
|
||||||
margin_left = 0.0;
|
margin_left = 0.0;
|
||||||
|
|
||||||
render_line(dd, margin_left, margin_top, lineheight, num_frags, frags);
|
render_line(dd, margin_left, margin_top, need_bottom, lineheight, num_frags, frags);
|
||||||
|
|
||||||
if (deffont == DOCFONT_ITALIC)
|
if (deffont == DOCFONT_ITALIC)
|
||||||
{
|
{
|
||||||
// Add a gray bar to the left of block quotes...
|
// Add an orange bar to the left of block quotes...
|
||||||
set_color(dd, DOCCOLOR_GREEN);
|
set_color(dd, DOCCOLOR_ORANGE);
|
||||||
|
pdfioContentSave(dd->st);
|
||||||
|
pdfioContentSetLineWidth(dd->st, 3.0);
|
||||||
pdfioContentPathMoveTo(dd->st, left - 6.0, dd->y - (LINE_HEIGHT - 1.0) * fsize);
|
pdfioContentPathMoveTo(dd->st, left - 6.0, dd->y - (LINE_HEIGHT - 1.0) * fsize);
|
||||||
pdfioContentPathLineTo(dd->st, left - 6.0, dd->y + fsize);
|
pdfioContentPathLineTo(dd->st, left - 6.0, dd->y + fsize);
|
||||||
pdfioContentStroke(dd->st);
|
pdfioContentStroke(dd->st);
|
||||||
|
pdfioContentRestore(dd->st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -771,7 +797,7 @@ format_code(docdata_t *dd, // I - Document data
|
|||||||
|
|
||||||
lineheight = SIZE_CODEBLOCK * LINE_HEIGHT;
|
lineheight = SIZE_CODEBLOCK * LINE_HEIGHT;
|
||||||
dd->y -= 2.0 * lineheight;
|
dd->y -= 2.0 * lineheight;
|
||||||
if (dd->y < dd->art_box.y1)
|
if ((dd->y - lineheight) < dd->art_box.y1)
|
||||||
{
|
{
|
||||||
new_page(dd);
|
new_page(dd);
|
||||||
|
|
||||||
@ -811,6 +837,7 @@ format_code(docdata_t *dd, // I - Document data
|
|||||||
|
|
||||||
// End the current text block...
|
// End the current text block...
|
||||||
pdfioContentTextEnd(dd->st);
|
pdfioContentTextEnd(dd->st);
|
||||||
|
dd->y += lineheight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -850,6 +877,11 @@ format_doc(docdata_t *dd, // I - Document data
|
|||||||
default :
|
default :
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MMD_TYPE_THEMATIC_BREAK :
|
||||||
|
// Force a page break
|
||||||
|
dd->y = dd->art_box.y1;
|
||||||
|
break;
|
||||||
|
|
||||||
case MMD_TYPE_BLOCK_QUOTE :
|
case MMD_TYPE_BLOCK_QUOTE :
|
||||||
format_doc(dd, current, DOCFONT_ITALIC, left + 36.0, right - 36.0);
|
format_doc(dd, current, DOCFONT_ITALIC, left + 36.0, right - 36.0);
|
||||||
break;
|
break;
|
||||||
@ -1372,6 +1404,7 @@ static void
|
|||||||
render_line(docdata_t *dd, // I - Document data
|
render_line(docdata_t *dd, // I - Document data
|
||||||
double margin_left, // I - Left margin
|
double margin_left, // I - Left margin
|
||||||
double margin_top, // I - Top margin
|
double margin_top, // I - Top margin
|
||||||
|
double need_bottom, // I - How much space is needed after
|
||||||
double lineheight, // I - Height of line
|
double lineheight, // I - Height of line
|
||||||
size_t num_frags, // I - Number of line fragments
|
size_t num_frags, // I - Number of line fragments
|
||||||
linefrag_t *frags) // I - Line fragments
|
linefrag_t *frags) // I - Line fragments
|
||||||
@ -1388,7 +1421,7 @@ render_line(docdata_t *dd, // I - Document data
|
|||||||
}
|
}
|
||||||
|
|
||||||
dd->y -= margin_top + lineheight;
|
dd->y -= margin_top + lineheight;
|
||||||
if (dd->y < dd->art_box.y1)
|
if ((dd->y - need_bottom) < dd->art_box.y1)
|
||||||
{
|
{
|
||||||
new_page(dd);
|
new_page(dd);
|
||||||
|
|
||||||
@ -1573,9 +1606,9 @@ set_color(docdata_t *dd, // I - Document data
|
|||||||
pdfioContentSetFillColorDeviceRGB(dd->st, 0.6, 0.0, 0.0);
|
pdfioContentSetFillColorDeviceRGB(dd->st, 0.6, 0.0, 0.0);
|
||||||
pdfioContentSetStrokeColorDeviceRGB(dd->st, 0.6, 0.0, 0.0);
|
pdfioContentSetStrokeColorDeviceRGB(dd->st, 0.6, 0.0, 0.0);
|
||||||
break;
|
break;
|
||||||
case DOCCOLOR_GREEN :
|
case DOCCOLOR_ORANGE :
|
||||||
pdfioContentSetFillColorDeviceRGB(dd->st, 0.0, 0.6, 0.0);
|
pdfioContentSetFillColorDeviceRGB(dd->st, 1.0, 0.5, 0.0);
|
||||||
pdfioContentSetStrokeColorDeviceRGB(dd->st, 0.0, 0.6, 0.0);
|
pdfioContentSetStrokeColorDeviceRGB(dd->st, 1.0, 0.5, 0.0);
|
||||||
break;
|
break;
|
||||||
case DOCCOLOR_BLUE :
|
case DOCCOLOR_BLUE :
|
||||||
pdfioContentSetFillColorDeviceRGB(dd->st, 0.0, 0.0, 0.8);
|
pdfioContentSetFillColorDeviceRGB(dd->st, 0.0, 0.0, 0.8);
|
||||||
|
Loading…
Reference in New Issue
Block a user