/************************************************* * The PMW Music Typesetter - 3rd incarnation * *************************************************/ /* Copyright (c) Philip Hazel, 1991 - 2008 */ /* Written by Philip Hazel, starting November 1991 */ /* This file last modified: September 2008 */ /* This file contains some functions for controlling printable output. */ #include "pmwhdr.h" #include "outhdr.h" /************************************************* * Initialize page list data * *************************************************/ /* This function is called at the start of the output phase. Its job is to set up the number of the first page to be printed, in print_curnumber, and to set print_curlist to point the first page selection item. Argument: TRUE if printing is to be in reverse order Returns: nothing */ void print_setup_pagelist(BOOL reverse) { print_curlist = output_pagelist; if (reverse) { if (print_curlist == NULL) print_curnumber = print_lastpage + 1; else { while (print_curlist->next != NULL) print_curlist = print_curlist->next; print_curnumber = print_curlist->last + 1; } } else { if (print_curlist == NULL) print_curnumber = main_firstpage - 1; else print_curnumber = print_curlist->first - 1; } } /************************************************* * Get next page(s) to print * *************************************************/ /* Called from the PostScript output routines. First we have a local function to get the next specified page, skipping any that do not exist. We have to handle both backwards and forward movement. Argument: nothing Returns: pointer to a pagestr, or NULL if no more. */ static pagestr * nextpage(void) { for (;;) { pagestr *yield = main_pageanchor; /* Find next page in reverse order */ if (print_reverse) { print_curnumber--; if (print_curlist == NULL) { if (print_curnumber < main_firstpage) return NULL; } else if (print_curnumber < print_curlist->first) { stave_list * p= output_pagelist; if (print_curlist == p) return NULL; while (p->next != print_curlist) p = p->next; print_curlist = p; print_curnumber = print_curlist->last; } } /* Find next page number in given order. */ else { print_curnumber++; if (print_curlist == NULL) { if (print_curnumber > print_lastpage) return NULL; } else if (print_curnumber > print_curlist->last) { if (print_curlist->next == NULL) return NULL; print_curlist = print_curlist->next; print_curnumber = print_curlist->first; } } /* If page exists, return it; otherwise loop. However, if we are in pamphlet mode with no explicit page list and the page number is past halfway and the mate exists, don't return the page. */ while (yield != NULL) { if (yield->number == print_curnumber) { if (print_pamphlet && print_curlist == NULL && print_curnumber > print_lastpage/2) { pagestr *p = main_pageanchor; int mate = print_lastpage - print_curnumber + 1; while (p != NULL) { if (p->number == mate) goto LOOP; p = p->next; } } return yield; } yield = yield->next; } LOOP:; } } /* The external function. It returns page structures for one or two pages, depending on the imposition. The yield is FALSE if there are no more pages. Arguments: p1 where to put a pointer to the first page p2 where to put a pointer to the second page Returns: FALSE if there are no more pages */ BOOL print_nextpage(pagestr **p1, pagestr **p2) { int n; BOOL swap = FALSE; *p2 = NULL; /* Loop for skipping unwanted pages (side selection). For pamphlet printing, side 1 contains odd-numbered pages less than half the total, and even-numbered pages greater than half. We may get either kind of page given. */ for (;;) { if ((*p1 = nextpage()) == NULL) return FALSE; n = (*p1)->number; if (!print_pamphlet || n <= print_lastpage/2) { if ((print_side1 && (n & 1) != 0) || (print_side2 && (n & 1) == 0)) break; } else if ((print_side1 && (n & 1) == 0) || (print_side2 && (n & 1) != 0)) break; } /* Handle 1-up printing: nothing more to do */ if (print_imposition != pc_a5ona4 && print_imposition != pc_a4ona3) return TRUE; /* Handle 2-up printing. For non-pamphlet ordering, just get the next page and set the order swap flag if required. */ if (!print_pamphlet) { if ((*p2 = nextpage()) == NULL) print_curnumber--; /* To get correct display */ swap = print_reverse; } /* For pamphlet printing, find the mate of the first page, and set the swap flag if necessary, to ensure the odd-numbered page is on the right. */ else { n = print_lastpage - n + 1; swap = (n & 1) == 0; *p2 = main_pageanchor; while (*p2 != NULL) { if ((*p2)->number == n) break; *p2 = (*p2)->next; } } /* Swap page order if necessary */ if (swap) { pagestr *temp = *p1; *p1 = *p2; *p2 = temp; } return TRUE; } /* End of print.c */