2021-04-10 14:00:52 +02:00
|
|
|
|
//
|
2021-05-30 13:10:44 +02:00
|
|
|
|
// Test program for PDFio.
|
2021-04-10 14:00:52 +02:00
|
|
|
|
//
|
|
|
|
|
// Copyright © 2021 by Michael R Sweet.
|
|
|
|
|
//
|
|
|
|
|
// Licensed under Apache License v2.0. See the file "LICENSE" for more
|
|
|
|
|
// information.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Include necessary headers...
|
|
|
|
|
//
|
|
|
|
|
|
2021-05-05 03:31:58 +02:00
|
|
|
|
#include "pdfio-private.h"
|
2021-05-28 16:41:21 +02:00
|
|
|
|
#include "pdfio-content.h"
|
2021-05-31 15:31:00 +02:00
|
|
|
|
#include <math.h>
|
2021-04-10 14:00:52 +02:00
|
|
|
|
|
|
|
|
|
|
2021-05-10 14:00:27 +02:00
|
|
|
|
//
|
|
|
|
|
// Local functions...
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
static int do_test_file(const char *filename);
|
|
|
|
|
static int do_unit_tests(void);
|
2021-05-10 14:40:52 +02:00
|
|
|
|
static bool error_cb(pdfio_file_t *pdf, const char *message, bool *error);
|
2021-05-10 14:00:27 +02:00
|
|
|
|
static ssize_t token_consume_cb(const char **s, size_t bytes);
|
|
|
|
|
static ssize_t token_peek_cb(const char **s, char *buffer, size_t bytes);
|
2021-05-31 15:31:00 +02:00
|
|
|
|
static int write_color_patch(pdfio_stream_t *st, bool device);
|
|
|
|
|
static int write_color_test(pdfio_file_t *pdf, int number);
|
2021-05-28 16:41:21 +02:00
|
|
|
|
static int write_page(pdfio_file_t *pdf, int number, pdfio_obj_t *image);
|
2021-05-10 14:00:27 +02:00
|
|
|
|
|
|
|
|
|
|
2021-04-10 14:00:52 +02:00
|
|
|
|
//
|
|
|
|
|
// 'main()' - Main entry for test program.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
int // O - Exit status
|
|
|
|
|
main(int argc, // I - Number of command-line arguments
|
|
|
|
|
char *argv[]) // I - Command-line arguments
|
|
|
|
|
{
|
2021-05-01 17:50:17 +02:00
|
|
|
|
if (argc > 1)
|
|
|
|
|
{
|
2021-05-10 14:00:27 +02:00
|
|
|
|
int i; // Looping var
|
2021-05-01 17:50:17 +02:00
|
|
|
|
|
|
|
|
|
for (i = 1; i < argc; i ++)
|
|
|
|
|
{
|
2021-05-10 14:40:52 +02:00
|
|
|
|
if (do_test_file(argv[i]))
|
2021-05-10 14:00:27 +02:00
|
|
|
|
return (1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
do_unit_tests();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'do_test_file()' - Try loading a PDF file and listing pages and objects.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
static int // O - Exit status
|
|
|
|
|
do_test_file(const char *filename) // I - PDF filename
|
|
|
|
|
{
|
2021-05-10 14:40:52 +02:00
|
|
|
|
bool error = false; // Have we shown an error yet?
|
2021-05-10 14:00:27 +02:00
|
|
|
|
pdfio_file_t *pdf; // PDF file
|
|
|
|
|
size_t n, // Object/page index
|
|
|
|
|
num_objs, // Number of objects
|
|
|
|
|
num_pages; // Number of pages
|
|
|
|
|
pdfio_obj_t *obj; // Object
|
|
|
|
|
pdfio_dict_t *dict; // Object dictionary
|
|
|
|
|
const char *type; // Object type
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Try opening the file...
|
2021-05-10 14:40:52 +02:00
|
|
|
|
printf("pdfioFileOpen(\"%s\", ...): ", filename);
|
|
|
|
|
if ((pdf = pdfioFileOpen(filename, (pdfio_error_cb_t)error_cb, &error)) != NULL)
|
2021-05-10 14:00:27 +02:00
|
|
|
|
{
|
2021-05-10 14:40:52 +02:00
|
|
|
|
puts("PASS");
|
|
|
|
|
|
2021-05-10 14:00:27 +02:00
|
|
|
|
// Show basic stats...
|
|
|
|
|
num_objs = pdfioFileGetNumObjects(pdf);
|
|
|
|
|
num_pages = pdfioFileGetNumPages(pdf);
|
|
|
|
|
|
2021-05-10 14:40:52 +02:00
|
|
|
|
printf(" PDF %s, %d pages, %d objects.\n", pdfioFileGetVersion(pdf), (int)num_pages, (int)num_objs);
|
2021-05-10 14:00:27 +02:00
|
|
|
|
|
|
|
|
|
// Show a summary of each page...
|
|
|
|
|
for (n = 0; n < num_pages; n ++)
|
|
|
|
|
{
|
|
|
|
|
if ((obj = pdfioFileGetPage(pdf, n)) == NULL)
|
|
|
|
|
{
|
|
|
|
|
printf("%s: Unable to get page #%d.\n", filename, (int)n + 1);
|
|
|
|
|
}
|
|
|
|
|
else
|
2021-05-01 17:50:17 +02:00
|
|
|
|
{
|
2021-05-10 14:00:27 +02:00
|
|
|
|
pdfio_rect_t media_box; // MediaBox value
|
|
|
|
|
|
|
|
|
|
memset(&media_box, 0, sizeof(media_box));
|
|
|
|
|
dict = pdfioObjGetDict(obj);
|
|
|
|
|
|
|
|
|
|
if (!pdfioDictGetRect(dict, "MediaBox", &media_box))
|
|
|
|
|
{
|
|
|
|
|
if ((obj = pdfioDictGetObject(dict, "Parent")) != NULL)
|
|
|
|
|
{
|
|
|
|
|
dict = pdfioObjGetDict(obj);
|
|
|
|
|
pdfioDictGetRect(dict, "MediaBox", &media_box);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-10 14:40:52 +02:00
|
|
|
|
printf(" Page #%d is %gx%g.\n", (int)n + 1, media_box.x2, media_box.y2);
|
2021-05-01 17:50:17 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-05-10 14:00:27 +02:00
|
|
|
|
|
|
|
|
|
// Show the associated value with each object...
|
|
|
|
|
for (n = 0; n < num_objs; n ++)
|
|
|
|
|
{
|
|
|
|
|
if ((obj = pdfioFileGetObject(pdf, n)) == NULL)
|
|
|
|
|
{
|
2021-05-10 14:40:52 +02:00
|
|
|
|
printf(" Unable to get object #%d.\n", (int)n);
|
2021-05-10 14:00:27 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dict = pdfioObjGetDict(obj);
|
|
|
|
|
|
2021-05-10 14:40:52 +02:00
|
|
|
|
printf(" %u %u obj dict=%p(%lu pairs)\n", (unsigned)pdfioObjGetNumber(obj), (unsigned)pdfioObjGetGeneration(obj), dict, dict ? (unsigned long)dict->num_pairs : 0UL);
|
|
|
|
|
fputs(" ", stdout);
|
|
|
|
|
_pdfioValueDebug(&obj->value, stdout);
|
|
|
|
|
putchar('\n');
|
2021-05-10 14:00:27 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Close the file and return success...
|
|
|
|
|
pdfioFileClose(pdf);
|
|
|
|
|
return (0);
|
2021-05-01 17:50:17 +02:00
|
|
|
|
}
|
2021-05-10 14:00:27 +02:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Error message will already be displayed so just indicate failure...
|
|
|
|
|
return (1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'do_unit_tests()' - Do unit tests.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
static int // O - Exit status
|
|
|
|
|
do_unit_tests(void)
|
|
|
|
|
{
|
2021-05-16 18:36:44 +02:00
|
|
|
|
int i; // Looping var
|
|
|
|
|
char filename[256]; // PDF filename
|
2021-05-30 02:00:48 +02:00
|
|
|
|
pdfio_file_t *pdf, // Test PDF file
|
|
|
|
|
*outpdf; // Output PDF file
|
2021-05-10 14:00:27 +02:00
|
|
|
|
bool error = false; // Error callback data
|
|
|
|
|
_pdfio_token_t tb; // Token buffer
|
|
|
|
|
const char *s; // String buffer
|
|
|
|
|
_pdfio_value_t value; // Value
|
2021-05-28 16:41:21 +02:00
|
|
|
|
pdfio_obj_t *color_jpg, // color.jpg image
|
2021-05-30 02:00:48 +02:00
|
|
|
|
*gray_jpg, // gray.jpg image
|
|
|
|
|
*page; // Page from test PDF file
|
2021-05-10 14:00:27 +02:00
|
|
|
|
static const char *complex_dict = // Complex dictionary value
|
|
|
|
|
"<</Annots 5457 0 R/Contents 5469 0 R/CropBox[0 0 595.4 842]/Group 725 0 R"
|
|
|
|
|
"/MediaBox[0 0 595.4 842]/Parent 23513 0 R/Resources<</ColorSpace<<"
|
|
|
|
|
"/CS0 21381 0 R/CS1 21393 0 R>>/ExtGState<</GS0 21420 0 R>>/Font<<"
|
|
|
|
|
"/TT0 21384 0 R/TT1 21390 0 R/TT2 21423 0 R/TT3 21403 0 R/TT4 21397 0 R>>"
|
|
|
|
|
"/ProcSet[/PDF/Text/ImageC]/Properties<</MC0 5472 0 R/MC1 5473 0 R>>"
|
|
|
|
|
"/XObject<</E3Dp0QGN3h9EZL2X 23690 0 R/E6DU0TGl3s9NZT2C 23691 0 R"
|
|
|
|
|
"/ENDB06GH3u9tZT2N 21391 0 R/ENDD0NGM339cZe2F 23692 0 R"
|
|
|
|
|
"/ENDK00GK3c9DZN2n 23693 0 R/EPDB0NGN3Q9GZP2t 23695 0 R"
|
|
|
|
|
"/EpDA0kG03o9rZX21 23696 0 R/Im0 5475 0 R>>>>/Rotate 0/StructParents 2105"
|
|
|
|
|
"/Tabs/S/Type/Page>>";
|
|
|
|
|
|
|
|
|
|
|
2021-05-28 16:41:21 +02:00
|
|
|
|
setbuf(stdout, NULL);
|
|
|
|
|
|
2021-05-10 14:00:27 +02:00
|
|
|
|
// First open the test PDF file...
|
2021-05-28 15:31:42 +02:00
|
|
|
|
fputs("pdfioFileOpen(\"testfiles/testpdfio.pdf\"): ", stdout);
|
|
|
|
|
if ((pdf = pdfioFileOpen("testfiles/testpdfio.pdf", (pdfio_error_cb_t)error_cb, &error)) != NULL)
|
2021-05-10 14:00:27 +02:00
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
// TODO: Test for known values in this test file.
|
|
|
|
|
|
|
|
|
|
// Test the value parsers for edge cases...
|
|
|
|
|
fputs("_pdfioValueRead(complex_dict): ", stdout);
|
|
|
|
|
s = complex_dict;
|
|
|
|
|
_pdfioTokenInit(&tb, pdf, (_pdfio_tconsume_cb_t)token_consume_cb, (_pdfio_tpeek_cb_t)token_peek_cb, &s);
|
|
|
|
|
if (_pdfioValueRead(pdf, &tb, &value))
|
|
|
|
|
{
|
|
|
|
|
// TODO: Check value...
|
|
|
|
|
puts("PASS");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
2021-05-16 18:36:44 +02:00
|
|
|
|
// Create a new PDF file...
|
2021-05-28 16:41:21 +02:00
|
|
|
|
fputs("pdfioFileCreate(\"testpdfio-out.pdf\", ...): ", stdout);
|
2021-05-30 02:00:48 +02:00
|
|
|
|
if ((outpdf = pdfioFileCreate("testpdfio-out.pdf", NULL, NULL, NULL, (pdfio_error_cb_t)error_cb, &error)) != NULL)
|
2021-05-28 16:41:21 +02:00
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
// Create some image objects...
|
|
|
|
|
fputs("pdfioFileCreateImageObject(\"testfiles/color.jpg\"): ", stdout);
|
2021-05-30 02:00:48 +02:00
|
|
|
|
if ((color_jpg = pdfioFileCreateImageObject(outpdf, "testfiles/color.jpg", true)) != NULL)
|
2021-05-28 16:41:21 +02:00
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioFileCreateImageObject(\"testfiles/gray.jpg\"): ", stdout);
|
2021-05-30 02:00:48 +02:00
|
|
|
|
if ((gray_jpg = pdfioFileCreateImageObject(outpdf, "testfiles/gray.jpg", true)) != NULL)
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
// Copy the first page from the test PDF file...
|
|
|
|
|
fputs("pdfioFileGetPage(0): ", stdout);
|
|
|
|
|
if ((page = pdfioFileGetPage(pdf, 0)) != NULL)
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioPageCopy(first page): ", stdout);
|
|
|
|
|
if (pdfioPageCopy(outpdf, page))
|
2021-05-16 18:36:44 +02:00
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
2021-05-31 15:31:00 +02:00
|
|
|
|
// Write a page with a color image...
|
|
|
|
|
if (write_page(outpdf, 2, color_jpg))
|
|
|
|
|
return (1);
|
2021-05-16 18:36:44 +02:00
|
|
|
|
|
2021-05-30 02:00:48 +02:00
|
|
|
|
// Copy the third page from the test PDF file...
|
|
|
|
|
fputs("pdfioFileGetPage(2): ", stdout);
|
|
|
|
|
if ((page = pdfioFileGetPage(pdf, 2)) != NULL)
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioPageCopy(third page): ", stdout);
|
|
|
|
|
if (pdfioPageCopy(outpdf, page))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
2021-05-31 15:31:00 +02:00
|
|
|
|
// Write a page with a grayscale image...
|
|
|
|
|
if (write_page(outpdf, 4, gray_jpg))
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
// Write a page that tests multiple color spaces...
|
|
|
|
|
if (write_color_test(outpdf, 5))
|
|
|
|
|
return (1);
|
|
|
|
|
|
2021-05-30 02:00:48 +02:00
|
|
|
|
// Close the test PDF file...
|
|
|
|
|
fputs("pdfioFileClose(\"testfiles/testpdfio.pdf\": ", stdout);
|
2021-05-16 18:36:44 +02:00
|
|
|
|
if (pdfioFileClose(pdf))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
2021-05-30 02:00:48 +02:00
|
|
|
|
// Close the new PDF file...
|
|
|
|
|
fputs("pdfioFileClose(\"testpdfio-out.pdf\": ", stdout);
|
|
|
|
|
if (pdfioFileClose(outpdf))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
2021-04-10 14:00:52 +02:00
|
|
|
|
return (0);
|
|
|
|
|
}
|
2021-05-10 14:00:27 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'error_cb()' - Display an error message during a unit test.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
static bool // O - `true` to stop, `false` to continue
|
2021-05-10 14:40:52 +02:00
|
|
|
|
error_cb(pdfio_file_t *pdf, // I - PDF file
|
|
|
|
|
const char *message, // I - Error message
|
|
|
|
|
bool *error) // IO - Have we displayed an error?
|
2021-05-10 14:00:27 +02:00
|
|
|
|
{
|
2021-05-10 14:40:52 +02:00
|
|
|
|
(void)pdf;
|
|
|
|
|
|
2021-05-10 14:00:27 +02:00
|
|
|
|
if (!*error)
|
|
|
|
|
{
|
|
|
|
|
// First error, so show a "FAIL" indicator
|
|
|
|
|
*error = true;
|
|
|
|
|
|
2021-05-10 14:40:52 +02:00
|
|
|
|
puts("FAIL");
|
2021-05-10 14:00:27 +02:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-10 14:40:52 +02:00
|
|
|
|
// Indent error messages...
|
|
|
|
|
printf(" %s\n", message);
|
|
|
|
|
|
2021-05-10 14:00:27 +02:00
|
|
|
|
// Continue to catch more errors...
|
|
|
|
|
return (false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'token_consume_cb()' - Consume bytes from a test string.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
static ssize_t // O - Number of bytes consumed
|
|
|
|
|
token_consume_cb(const char **s, // IO - Test string
|
|
|
|
|
size_t bytes) // I - Bytes to consume
|
|
|
|
|
{
|
|
|
|
|
size_t len = strlen(*s); // Number of bytes remaining
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// "Consume" bytes by incrementing the string pointer, limiting to the
|
|
|
|
|
// remaining length...
|
|
|
|
|
if (bytes > len)
|
|
|
|
|
bytes = len;
|
|
|
|
|
|
|
|
|
|
*s += bytes;
|
|
|
|
|
|
|
|
|
|
return ((ssize_t)bytes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'token_peek_cb()' - Peek bytes from a test string.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
static ssize_t // O - Number of bytes peeked
|
|
|
|
|
token_peek_cb(const char **s, // IO - Test string
|
|
|
|
|
char *buffer, // I - Buffer
|
|
|
|
|
size_t bytes) // I - Bytes to peek
|
|
|
|
|
{
|
|
|
|
|
size_t len = strlen(*s); // Number of bytes remaining
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Copy bytes from the test string as possible...
|
|
|
|
|
if (bytes > len)
|
|
|
|
|
bytes = len;
|
|
|
|
|
|
|
|
|
|
if (bytes > 0)
|
|
|
|
|
memcpy(buffer, *s, bytes);
|
|
|
|
|
|
|
|
|
|
return ((ssize_t)bytes);
|
|
|
|
|
}
|
2021-05-16 18:36:44 +02:00
|
|
|
|
|
|
|
|
|
|
2021-05-31 15:31:00 +02:00
|
|
|
|
//
|
|
|
|
|
// 'write_color_patch()' - Write a color patch...
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
static int // O - 1 on failure, 0 on success
|
|
|
|
|
write_color_patch(pdfio_stream_t *st, // I - Content stream
|
|
|
|
|
bool device)// I - Use device color?
|
|
|
|
|
{
|
|
|
|
|
int col, // Current column
|
|
|
|
|
row; // Current row
|
|
|
|
|
double x, y, // Relative position
|
|
|
|
|
r, // Radius
|
|
|
|
|
hue, // Hue angle
|
|
|
|
|
sat, // Saturation
|
|
|
|
|
cc, // Computed color
|
|
|
|
|
red, // Red value
|
|
|
|
|
green, // Green value
|
|
|
|
|
blue; // Blue value
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Draw an 11x11 patch...
|
|
|
|
|
for (col = 0; col < 21; col ++)
|
|
|
|
|
{
|
|
|
|
|
for (row = 0; row < 21; row ++)
|
|
|
|
|
{
|
|
|
|
|
// Compute color in patch...
|
|
|
|
|
x = 0.1 * (col - 10);
|
|
|
|
|
y = 0.1 * (row - 10);
|
|
|
|
|
r = sqrt(x * x + y * y);
|
|
|
|
|
|
|
|
|
|
if (r == 0.0)
|
|
|
|
|
{
|
|
|
|
|
red = green = blue = 1.0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ((sat = fabs(x)) < fabs(y))
|
|
|
|
|
sat = fabs(y);
|
|
|
|
|
sat = pow(sat, 1.5);
|
|
|
|
|
|
|
|
|
|
x /= r;
|
|
|
|
|
y /= r;
|
|
|
|
|
hue = 3.0 * atan2(y, x) / M_PI;
|
|
|
|
|
if (hue < 0.0)
|
|
|
|
|
hue += 6.0;
|
|
|
|
|
|
|
|
|
|
cc = sat * (1.0 - fabs(fmod(hue, 2.0) - 1.0)) + 1.0 - sat;
|
|
|
|
|
|
|
|
|
|
if (hue < 1.0)
|
|
|
|
|
{
|
|
|
|
|
red = 1.0;
|
|
|
|
|
green = cc;
|
|
|
|
|
blue = 1.0 - sat;
|
|
|
|
|
}
|
|
|
|
|
else if (hue < 2.0)
|
|
|
|
|
{
|
|
|
|
|
red = cc;
|
|
|
|
|
green = 1.0;
|
|
|
|
|
blue = 1.0 - sat;
|
|
|
|
|
}
|
|
|
|
|
else if (hue < 3.0)
|
|
|
|
|
{
|
|
|
|
|
red = 1.0 - sat;
|
|
|
|
|
green = 1.0;
|
|
|
|
|
blue = cc;
|
|
|
|
|
}
|
|
|
|
|
else if (hue < 4.0)
|
|
|
|
|
{
|
|
|
|
|
red = 1.0 - sat;
|
|
|
|
|
green = cc;
|
|
|
|
|
blue = 1.0;
|
|
|
|
|
}
|
|
|
|
|
else if (hue < 5.0)
|
|
|
|
|
{
|
|
|
|
|
red = cc;
|
|
|
|
|
green = 1.0 - sat;
|
|
|
|
|
blue = 1.0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
red = 1.0;
|
|
|
|
|
green = 1.0 - sat;
|
|
|
|
|
blue = cc;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Draw it...
|
|
|
|
|
if (device)
|
|
|
|
|
{
|
|
|
|
|
// Use device CMYK color instead of a calibrated RGB space...
|
|
|
|
|
double cyan = 1.0 - red; // Cyan color
|
|
|
|
|
double magenta = 1.0 - green; // Magenta color
|
|
|
|
|
double yellow = 1.0 - blue; // Yellow color
|
|
|
|
|
double black = cyan; // Black color
|
|
|
|
|
|
|
|
|
|
if (black > magenta)
|
|
|
|
|
black = magenta;
|
|
|
|
|
if (black > yellow)
|
|
|
|
|
black = yellow;
|
|
|
|
|
|
|
|
|
|
cyan -= black;
|
|
|
|
|
magenta -= black;
|
|
|
|
|
yellow -= black;
|
|
|
|
|
|
|
|
|
|
printf("pdfioContentSetFillColorDeviceCMYK(c=%g, m=%g, y=%g, k=%g): ", cyan, magenta, yellow, black);
|
|
|
|
|
if (pdfioContentSetFillColorDeviceCMYK(st, cyan, magenta, yellow, black))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Use calibrate RGB space...
|
|
|
|
|
printf("pdfioContentSetFillColorRGB(r=%g, g=%g, b=%g): ", red, green, blue);
|
|
|
|
|
if (pdfioContentSetFillColorRGB(st, red, green, blue))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("pdfioContentPathRect(x=%g, y=%g, w=%g, h=%g): ", col * 9.0, row * 9.0, 9.0, 9.0);
|
|
|
|
|
if (pdfioContentPathRect(st, col * 9.0, row * 9.0, 9.0, 9.0))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentFill(even_odd=false): ", stdout);
|
|
|
|
|
if (pdfioContentFill(st, false))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// 'write_color_test()' - Write a color test page...
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
static int // O - 1 on failure, 0 on success
|
|
|
|
|
write_color_test(pdfio_file_t *pdf, // I - PDF file
|
|
|
|
|
int number) // I - Page number
|
|
|
|
|
{
|
|
|
|
|
pdfio_dict_t *dict; // Page dictionary
|
|
|
|
|
pdfio_stream_t *st; // Page contents stream
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fputs("pdfioDictCreate: ", stdout);
|
|
|
|
|
if ((dict = pdfioDictCreate(pdf)) != NULL)
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioPageDictAddCalibratedColorSpace(AdobeRGB): ", stdout);
|
|
|
|
|
if (pdfioPageDictAddCalibratedColorSpace(dict, "AdobeRGB", 3, pdfioAdobeRGBGamma, pdfioAdobeRGBMatrix, pdfioAdobeRGBWhitePoint))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioPageDictAddCalibratedColorSpace(DisplayP3): ", stdout);
|
|
|
|
|
if (pdfioPageDictAddCalibratedColorSpace(dict, "DisplayP3", 3, pdfioDisplayP3Gamma, pdfioDisplayP3Matrix, pdfioDisplayP3WhitePoint))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioPageDictAddCalibratedColorSpace(sRGB): ", stdout);
|
|
|
|
|
if (pdfioPageDictAddCalibratedColorSpace(dict, "sRGB", 3, pdfioSRGBGamma, pdfioSRGBMatrix, pdfioSRGBWhitePoint))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
printf("pdfioFileCreatePage(%d): ", number);
|
|
|
|
|
|
|
|
|
|
if ((st = pdfioFileCreatePage(pdf, dict)) != NULL)
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentSave(): ", stdout);
|
|
|
|
|
if (pdfioContentSave(st))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentSetFillColorSpace(AdobeRGB): ", stdout);
|
|
|
|
|
if (pdfioContentSetFillColorSpace(st, "AdobeRGB"))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentMatrixTranslate(82, 180): ", stdout);
|
|
|
|
|
if (pdfioContentMatrixTranslate(st, 82, 180))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
if (write_color_patch(st, false))
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentRestore(): ", stdout);
|
|
|
|
|
if (pdfioContentRestore(st))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentSave(): ", stdout);
|
|
|
|
|
if (pdfioContentSave(st))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentSetFillColorSpace(DisplayP3): ", stdout);
|
|
|
|
|
if (pdfioContentSetFillColorSpace(st, "DisplayP3"))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentMatrixTranslate(316, 180): ", stdout);
|
|
|
|
|
if (pdfioContentMatrixTranslate(st, 316, 180))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
if (write_color_patch(st, false))
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentRestore(): ", stdout);
|
|
|
|
|
if (pdfioContentRestore(st))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentSave(): ", stdout);
|
|
|
|
|
if (pdfioContentSave(st))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentSetFillColorSpace(sRGB): ", stdout);
|
|
|
|
|
if (pdfioContentSetFillColorSpace(st, "sRGB"))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentMatrixTranslate(82, 414): ", stdout);
|
|
|
|
|
if (pdfioContentMatrixTranslate(st, 82, 414))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
if (write_color_patch(st, false))
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentRestore(): ", stdout);
|
|
|
|
|
if (pdfioContentRestore(st))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentSave(): ", stdout);
|
|
|
|
|
if (pdfioContentSave(st))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentMatrixTranslate(316, 414): ", stdout);
|
|
|
|
|
if (pdfioContentMatrixTranslate(st, 316, 414))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
if (write_color_patch(st, true))
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentRestore(): ", stdout);
|
|
|
|
|
if (pdfioContentRestore(st))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioStreamClose: ", stdout);
|
|
|
|
|
if (pdfioStreamClose(st))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-05-16 18:36:44 +02:00
|
|
|
|
//
|
|
|
|
|
// 'write_page()' - Write a page to a PDF file.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
static int // O - 1 on failure, 0 on success
|
|
|
|
|
write_page(pdfio_file_t *pdf, // I - PDF file
|
2021-05-28 16:41:21 +02:00
|
|
|
|
int number, // I - Page number
|
|
|
|
|
pdfio_obj_t *image) // I - Image to draw
|
2021-05-16 18:36:44 +02:00
|
|
|
|
{
|
|
|
|
|
// TODO: Add font object support...
|
2021-05-28 16:41:21 +02:00
|
|
|
|
pdfio_dict_t *dict; // Page dictionary
|
2021-05-16 18:36:44 +02:00
|
|
|
|
pdfio_stream_t *st; // Page contents stream
|
2021-05-30 03:16:21 +02:00
|
|
|
|
double width, // Width of image
|
2021-05-29 04:05:44 +02:00
|
|
|
|
height; // Height of image
|
2021-05-30 03:16:21 +02:00
|
|
|
|
double swidth, // Scaled width
|
2021-05-29 04:05:44 +02:00
|
|
|
|
sheight, // Scaled height
|
|
|
|
|
tx, // X offset
|
|
|
|
|
ty; // Y offset
|
2021-05-16 18:36:44 +02:00
|
|
|
|
|
|
|
|
|
|
2021-05-28 16:41:21 +02:00
|
|
|
|
fputs("pdfioDictCreate: ", stdout);
|
|
|
|
|
if ((dict = pdfioDictCreate(pdf)) != NULL)
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioPageDictAddImage: ", stdout);
|
|
|
|
|
if (pdfioPageDictAddImage(dict, "IM1", image))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
2021-05-16 18:36:44 +02:00
|
|
|
|
printf("pdfioFileCreatePage(%d): ", number);
|
|
|
|
|
|
2021-05-28 16:41:21 +02:00
|
|
|
|
if ((st = pdfioFileCreatePage(pdf, dict)) != NULL)
|
2021-05-16 18:36:44 +02:00
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioStreamPuts(...): ", stdout);
|
|
|
|
|
if (pdfioStreamPuts(st,
|
2021-05-17 00:31:45 +02:00
|
|
|
|
"1 0 0 RG 0 g 5 w\n"
|
|
|
|
|
"18 18 559 760 re 72 72 451 648 re B*\n"))
|
2021-05-16 18:36:44 +02:00
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
2021-05-28 16:41:21 +02:00
|
|
|
|
fputs("pdfioContentSave(): ", stdout);
|
|
|
|
|
if (pdfioContentSave(st))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
2021-05-29 04:05:44 +02:00
|
|
|
|
fputs("pdfioImageGetWidth(): ", stdout);
|
2021-05-30 03:16:21 +02:00
|
|
|
|
if ((width = pdfioImageGetWidth(image)) > 0.0)
|
2021-05-28 16:41:21 +02:00
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
2021-05-29 04:05:44 +02:00
|
|
|
|
fputs("pdfioImageGetHeight(): ", stdout);
|
2021-05-30 03:16:21 +02:00
|
|
|
|
if ((height = pdfioImageGetHeight(image)) > 0.0)
|
2021-05-29 04:05:44 +02:00
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
2021-05-30 03:16:21 +02:00
|
|
|
|
swidth = 400.0;
|
2021-05-29 04:05:44 +02:00
|
|
|
|
sheight = swidth * height / width;
|
2021-05-30 03:16:21 +02:00
|
|
|
|
if (sheight > 600.0)
|
2021-05-29 04:05:44 +02:00
|
|
|
|
{
|
2021-05-30 03:16:21 +02:00
|
|
|
|
sheight = 600.0;
|
2021-05-29 04:05:44 +02:00
|
|
|
|
swidth = sheight * width / height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tx = 0.5 * (595.28 - swidth);
|
|
|
|
|
ty = 0.5 * (792 - sheight);
|
2021-05-28 16:41:21 +02:00
|
|
|
|
|
2021-05-29 04:05:44 +02:00
|
|
|
|
printf("pdfioContentDrawImage(\"IM1\", x=%g, y=%g, w=%g, h=%g): ", tx, ty, swidth, sheight);
|
|
|
|
|
if (pdfioContentDrawImage(st, "IM1", tx, ty, swidth, sheight))
|
2021-05-28 16:41:21 +02:00
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
fputs("pdfioContentRestore(): ", stdout);
|
|
|
|
|
if (pdfioContentRestore(st))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
2021-05-16 18:36:44 +02:00
|
|
|
|
fputs("pdfioStreamClose: ", stdout);
|
|
|
|
|
if (pdfioStreamClose(st))
|
|
|
|
|
puts("PASS");
|
|
|
|
|
else
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
|
}
|