Skip to content

Commit

Permalink
Fix imposition/layout issues (Issue #279)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelrsweet committed Sep 25, 2023
1 parent 9acefdb commit dd7eacc
Showing 1 changed file with 85 additions and 64 deletions.
149 changes: 85 additions & 64 deletions tools/ipptransform.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ extern void CGContextSetCTM(CGContextRef c, CGAffineTransform m);


// Constants...
#define XFORM_MAX_LAYOUT 16
#define XFORM_MAX_LAYOUT 16
#define XFORM_MAX_PAGES 10000
#define XFORM_MAX_RASTER 16777216

Expand Down Expand Up @@ -165,7 +165,7 @@ static void pdfio_end_page(xform_prepare_t *p, pdfio_stream_t *st);
static bool pdfio_error_cb(pdfio_file_t *pdf, const char *message, void *cb_data);
static const char *pdfio_password_cb(void *cb_data, const char *filename);
static pdfio_stream_t *pdfio_start_page(xform_prepare_t *p, pdfio_dict_t *dict);
static bool prepare_documents(size_t num_documents, xform_document_t *documents, ipp_options_t *options, const char *sheet_back, char *outfile, size_t outsize, unsigned *outpages);
static bool prepare_documents(size_t num_documents, xform_document_t *documents, ipp_options_t *options, const char *sheet_back, char *outfile, size_t outsize, const char *outformat, unsigned *outpages, bool generate_copies);
static void prepare_log(xform_prepare_t *p, bool error, const char *message, ...);
static void prepare_number_up(xform_prepare_t *p);
static void prepare_pages(xform_prepare_t *p, size_t num_documents, xform_document_t *documents);
Expand Down Expand Up @@ -444,7 +444,7 @@ main(int argc, // I - Number of command-line args
// Prepare a PDF file for printing...
ipp_options = ippOptionsNew(num_options, options);

if (!prepare_documents(num_files, files, ipp_options, sheet_back, pdf_file, sizeof(pdf_file), &pdf_pages))
if (!prepare_documents(num_files, files, ipp_options, sheet_back, pdf_file, sizeof(pdf_file), output_type, &pdf_pages, !strcmp(output_type, "application/pdf")))
{
// Unable to prepare documents, exit...
ippOptionsDelete(ipp_options);
Expand Down Expand Up @@ -1277,6 +1277,8 @@ copy_page(xform_prepare_t *p, // I - Preparation data
rotate = false;
}

fprintf(stderr, "DEBUG: iwidth=%g, iheight=%g, cwidth=%g, cheight=%g, rotate=%s\n", iwidth, iheight, cwidth, cheight, rotate ? "true" : "false");

scaling = cwidth / iwidth;
if (p->options->print_scaling == IPPOPT_SCALING_FILL)
{
Expand All @@ -1297,17 +1299,17 @@ copy_page(xform_prepare_t *p, // I - Preparation data
cm[0][1] = -scaling;
cm[1][0] = scaling;
cm[1][1] = 0.0;
cm[2][0] = cell->x1;
cm[2][1] = cell->y2;
cm[2][0] = cell->x1 + 0.5 * (cwidth - iwidth * scaling);
cm[2][1] = cell->y2 + 0.5 * (cheight - iheight * scaling);
}
else
{
cm[0][0] = scaling;
cm[0][1] = 0.0;
cm[1][0] = 0.0;
cm[1][1] = scaling;
cm[2][0] = cell->x1;
cm[2][1] = cell->y1;
cm[2][0] = cell->x1 + 0.5 * (cwidth - iwidth * scaling);
cm[2][1] = cell->y1 + 0.5 * (cheight - iheight * scaling);
}

if (Verbosity)
Expand Down Expand Up @@ -1508,6 +1510,7 @@ copy_page(xform_prepare_t *p, // I - Preparation data
}

// Restore state...
pdfioStreamPuts(outpage->output, "\n");
pdfioContentRestore(outpage->output);
}

Expand Down Expand Up @@ -2472,9 +2475,12 @@ prepare_documents(
const char *sheet_back, // I - Back side transform
char *outfile, // I - Output filename buffer
size_t outsize, // I - Output filename buffer size
unsigned *outpages) // O - Number of pages
const char *outformat, // I - Output format
unsigned *outpages, // O - Number of pages
bool generate_copies) // I - Generate copies in output PDF?
{
bool ret = false; // Return value
int copies; // Number of copies
size_t i; // Looping var
xform_prepare_t p; // Preparation data
xform_document_t *d; // Current document
Expand Down Expand Up @@ -2627,74 +2633,89 @@ prepare_documents(
generate_job_sheets(&p);

// Copy pages to the output file...
reverse_order = !strcmp(options->output_bin, "face-up");
if (options->page_delivery >= IPPOPT_DELIVERY_REVERSE_ORDER_FACE_DOWN)
reverse_order = !reverse_order;

if (reverse_order)
{
outpage = p.outpages + p.num_outpages - 1;
outdir = -1;
}
else
for (copies = generate_copies ? options->copies : 1; copies > 0; copies --)
{
outpage = p.outpages;
outdir = 1;
}

if (p.num_layout == 1)
{
// Simple path - no layout of pages so we can just copy the pages quickly.
if (Verbosity)
fputs("DEBUG: Doing fast copy of pages.\n", stderr);
reverse_order = !strcmp(options->output_bin, "face-up");
if (options->page_delivery >= IPPOPT_DELIVERY_REVERSE_ORDER_FACE_DOWN)
reverse_order = !reverse_order;

for (i = p.num_outpages; i > 0; i --, outpage += outdir)
if (reverse_order)
{
if (outpage->input[0])
pdfioPageCopy(p.pdf, outpage->input[0]);
outpage = p.outpages + p.num_outpages - 1;
outdir = -1;
}
else
{
outpage = p.outpages;
outdir = 1;
}
}
else
{
// Layout path - merge page resources and do mapping of resources as needed
if (Verbosity)
fprintf(stderr, "DEBUG: Doing full layout of %u pages.\n", (unsigned)p.num_outpages);

for (i = p.num_outpages; i > 0; i --, outpage += outdir)
if (p.num_layout == 1 && options->print_scaling == IPPOPT_SCALING_NONE && strcmp(outformat, "image/pwg-raster") && strcmp(outformat, "image/urf"))
{
// Create a page dictionary that merges the resources from each of the
// input pages...
// Simple path - no layout/scaling/rotation of pages so we can just copy the pages quickly.
if (Verbosity)
fprintf(stderr, "DEBUG: Laying out page %u/%u.\n", (unsigned)(outpage - p.outpages + 1), (unsigned)p.num_outpages);
fputs("DEBUG: Doing fast copy of pages.\n", stderr);

outpage->pagedict = pdfioDictCreate(p.pdf);
outpage->resdict = pdfioDictCreate(p.pdf);

pdfioDictSetRect(outpage->pagedict, "CropBox", &p.media);
pdfioDictSetRect(outpage->pagedict, "MediaBox", &p.media);
pdfioDictSetDict(outpage->pagedict, "Resources", outpage->resdict);
pdfioDictSetName(outpage->pagedict, "Type", "Page");
for (i = p.num_outpages; i > 0; i --, outpage += outdir)
{
if (outpage->input[0])
pdfioPageCopy(p.pdf, outpage->input[0]);
}
}
else
{
// Layout path - merge page resources and do mapping of resources as needed
if (Verbosity)
fprintf(stderr, "DEBUG: Doing full layout of %u pages.\n", (unsigned)p.num_outpages);

for (layout = 0; layout < p.num_layout; layout ++)
for (i = p.num_outpages; i > 0; i --, outpage += outdir)
{
if (!outpage->input[layout])
continue;
// Create a page dictionary that merges the resources from each of the
// input pages...
if (Verbosity)
fprintf(stderr, "DEBUG: Laying out page %u/%u.\n", (unsigned)(outpage - p.outpages + 1), (unsigned)p.num_outpages);

outpage->layout = layout;
outpage->restype = NULL;
pdfioDictIterateKeys(pdfioDictGetDict(pdfioObjGetDict(outpage->input[layout]), "Resources"), (pdfio_dict_cb_t)page_dict_cb, outpage);
// TODO: Handle inherited resources from parent page objects...
}
outpage->pagedict = pdfioDictCreate(p.pdf);
outpage->resdict = pdfioDictCreate(p.pdf);

pdfioDictSetRect(outpage->pagedict, "CropBox", &p.media);
pdfioDictSetRect(outpage->pagedict, "MediaBox", &p.media);
pdfioDictSetDict(outpage->pagedict, "Resources", outpage->resdict);
pdfioDictSetName(outpage->pagedict, "Type", "Page");

// Now copy the content streams to build the composite page, using the
// resource map for any named resources...
outpage->output = pdfio_start_page(&p, outpage->pagedict);
for (layout = 0; layout < p.num_layout; layout ++)
{
pdfio_dict_t *pagedict, // Page dictionary
*resdict; // Resources dictionary
pdfio_obj_t *resobj; // Resources object

for (layout = 0; layout < p.num_layout; layout ++)
copy_page(&p, outpage, layout);
if (!outpage->input[layout])
continue;

pdfio_end_page(&p, outpage->output);
outpage->output = NULL;
outpage->layout = layout;
outpage->restype = NULL;

pagedict = pdfioObjGetDict(outpage->input[layout]);
if ((resdict = pdfioDictGetDict(pagedict, "Resources")) != NULL)
pdfioDictIterateKeys(resdict, (pdfio_dict_cb_t)page_dict_cb, outpage);
else if ((resobj = pdfioDictGetObj(pagedict, "Resources")) != NULL)
pdfioDictIterateKeys(pdfioObjGetDict(resobj), (pdfio_dict_cb_t)page_dict_cb, outpage);
else if (Verbosity)
fprintf(stderr, "DEBUG: No Resources for cell %u.\n", (unsigned)layout);

// TODO: Handle inherited resources from parent page objects...
}

// Now copy the content streams to build the composite page, using the
// resource map for any named resources...
outpage->output = pdfio_start_page(&p, outpage->pagedict);

for (layout = 0; layout < p.num_layout; layout ++)
copy_page(&p, outpage, layout);

pdfio_end_page(&p, outpage->output);
outpage->output = NULL;
}
}
}

Expand Down Expand Up @@ -3528,7 +3549,7 @@ xform_document(
unsigned char *lineptr; // Pointer to line

pdf_page = CGPDFDocumentGetPage(document, page);
transform = CGPDFPageGetDrawingTransform(pdf_page, kCGPDFCropBox,dest, 0, true);
transform = CGPDFPageGetDrawingTransform(pdf_page, kCGPDFCropBox, dest, 0, true);

if (Verbosity > 1)
fprintf(stderr, "DEBUG: Printing copy %d/%d, page %d/%d, transform=[%g %g %g %g %g %g]\n", copy + 1, options->copies, page, pages, transform.a, transform.b, transform.c, transform.d, transform.tx, transform.ty);
Expand Down Expand Up @@ -3645,7 +3666,7 @@ xform_document(
}


#else
#else // pdftoppm
//
// 'xform_document()' - Transform a file for printing.
//
Expand Down

0 comments on commit dd7eacc

Please sign in to comment.