void pcl_set_cap_x(pcl_state_t * pcs, coord x, bool relative, bool use_margins) { coord old_x = pcs->cap.x; if (relative) x += pcs->cap.x; /* the horizontal text margins are only interesting in transition */ if (use_margins) { coord min_x = pcs->margins.left; coord max_x = pcs->margins.right; if ((old_x >= min_x) && (x < min_x)) x = min_x; else if ((old_x <= max_x) && (x > max_x)) x = max_x; } /* the logical page bounds always apply */ x = (x > pcs->xfm_state.pd_size.x ? pcs->xfm_state.pd_size.x : (x < 0L ? 0L : x)); /* leftward motion "breaks" an underline */ if (x < old_x) { pcl_break_underline(pcs); pcs->cap.x = x; pcl_continue_underline(pcs); } else pcs->cap.x = x; }
/* * Control character action implementation. * * These routines perform just the individual actions. The control character * routines may invoke several of these, based on the selected line termination * setting. * * do_CR and do_LF are exported for use by the text manipulation routines and * the display functions. * * Note: CR always "breaks" an underline, even if it is a movement to the right. */ void pcl_do_CR(pcl_state_t * pcs) { pcl_break_underline(pcs); pcl_set_cap_x(pcs, pcs->margins.left, false, false); pcl_continue_underline(pcs); pcs->cursor_moved = true; }
/* * ESC * l <rop> O * * Set logical operation. */ static int pcl_logical_operation(pcl_args_t * pargs, pcl_state_t * pcs) { uint rop = uint_arg(pargs); if (pcs->raster_state.graphics_mode) return 0; if (rop > 255) return e_Range; pcl_break_underline(pcs); /* use the 5c convention; in 5e, the * underline is not broken by a change in * the logical operation */ pcs->logical_op = rop; return 0; }
/* * ESC & a <angle> P */ static int set_print_direction(pcl_args_t * pargs, pcl_state_t * pcs) { uint i = uint_arg(pargs); if ((i <= 270) && (i % 90 == 0)) { i /= 90; if (i != pcs->xfm_state.print_dir) { pcl_break_underline(pcs); pcs->xfm_state.print_dir = i; update_xfm_state(pcs, 0); pcl_continue_underline(pcs); } else { pcs->xfm_state.print_dir = i; update_xfm_state(pcs, 0); } } return 0; }
/* * ESC * p # R * * Set pattern reference point. * */ static int set_pat_ref_pt( pcl_args_t * pargs, pcl_state_t * pcs ) { uint rotate = uint_arg(pargs); if (rotate <= 1) { pcl_break_underline(pcs); gs_point_transform( (floatp)pcs->cap.x, (floatp)pcs->cap.y, &(pcs->xfm_state.pd2lp_mtx), &(pcs->pcl_pat_ref_pt) ); pcs->rotate_patterns = (rotate == 0); } return 0; }
/* * End a page, either unconditionally or only if there are marks on it. * Return 1 if the page was actually printed and erased. */ int pcl_end_page( pcl_state_t * pcs, pcl_print_condition_t condition ) { int code = 0; pcl_break_underline(pcs); /* (could mark page) */ /* If we are conditionally printing (normal case) check if the page is marked */ if (condition != pcl_print_always) { if ( !pcl_page_marked(pcs) ) return 0; } /* If there's an overlay macro, execute it now. */ if (pcs->overlay_enabled) { void * value; if ( pl_dict_find( &pcs->macros, id_key(pcs->overlay_macro_id), 2, &value ) ) { pcs->overlay_enabled = false; /**** IN reset_overlay ****/ code = pcl_execute_macro( (const pcl_macro_t *)value, pcs, pcl_copy_before_overlay, pcl_reset_overlay, pcl_copy_after_overlay ); pcs->overlay_enabled = true; /**** IN copy_after ****/ } } /* output the page */ code = (*pcs->end_page)(pcs, pcs->num_copies, true); if ( code < 0 ) return code; /* allow the logical orientation command to be used again */ pcs->orientation_set = false; if ( pcs->end_page == pcl_end_page_top ) code = gs_erasepage(pcs->pgs); pcs->page_marked = false; /* force new logical page, allows external resolution changes. * see -dFirstPage -dLastPage * NB would be faster if we didn't do this every page. * * NB setting a new logical page defaults settings * that should carry over from the previous page * this error occurs only on documents that don't do any initilizations per page * hence only the viewer applications will see the speedup and the error */ if (!pjl_proc_compare(pcs->pjls, pjl_proc_get_envvar(pcs->pjls, "viewer"), "on")) { new_logical_page(pcs, pcs->xfm_state.lp_orient, pcs->xfm_state.paper_size, false, false); } /* * Advance of a page may move from a page front to a page back. This may * change the applicable transformations. */ update_xfm_state(pcs, 0); pcl_continue_underline(pcs); return (code < 0 ? code : 1); }
/* * End a page, either unconditionally or only if there are marks on it. * Return 1 if the page was actually printed and erased. */ int pcl_end_page(pcl_state_t * pcs, pcl_print_condition_t condition) { int code = 0; pcl_break_underline(pcs); /* (could mark page) */ /* If we are conditionally printing (normal case) check if the page is marked */ if (condition != pcl_print_always) { if (!pcl_page_marked(pcs)) return 0; } /* finish up graphics mode in case we finished the page in the middle of a raster stream */ if (pcs->raster_state.graphics_mode) pcl_end_graphics_mode(pcs); /* If there's an overlay macro, execute it now. */ if (pcs->overlay_enabled) { void *value; if (pl_dict_find(&pcs->macros, id_key(pcs->overlay_macro_id), 2, &value)) { pcs->overlay_enabled = false; /**** IN reset_overlay ****/ code = pcl_execute_macro((const pcl_macro_t *)value, pcs, pcl_copy_before_overlay, pcl_reset_overlay, pcl_copy_after_overlay); if (code < 0) return code; pcs->overlay_enabled = true; /**** IN copy_after ****/ } } /* output the page */ code = (*pcs->end_page) (pcs, pcs->num_copies, true); if (code < 0) return code; if (pcs->end_page == pcl_end_page_top) code = gs_erasepage(pcs->pgs); pcs->page_marked = false; /* * Advance of a page may move from a page front to a page back. This may * change the applicable transformations. */ /* * Keep track of the side you are on */ if (pcs->duplex) { pcs->back_side = ! pcs->back_side; } else { pcs->back_side = false; } put_param1_bool(pcs,"FirstSide", !pcs->back_side); update_xfm_state(pcs, 0); pcl_continue_underline(pcs); return (code < 0 ? code : 1); }
int pcl_set_cap_y(pcl_state_t * pcs, coord y, bool relative, bool use_margins, bool by_row, bool by_row_command) { coord lim_y = pcs->xfm_state.pd_size.y; coord max_y = pcs->margins.top + pcs->margins.length; bool page_eject = by_row && relative; /* this corresponds to rule 'k' above. */ if (relative && by_row_command) { /* calculate the advance to the next logical page bound. Note margins are false if by_row_command is true. */ coord advance_max = 2 * lim_y - pcs->cap.y; /* clamp */ y = (y < advance_max ? y : advance_max + HOME_Y(pcs)); } /* adjust the vertical position provided */ if (relative) y += pcs->cap.y; else y += (by_row ? HOME_Y(pcs) : pcs->margins.top); /* vertical moves always "break" underlines */ pcl_break_underline(pcs); max_y = (use_margins ? max_y : lim_y); if (y < 0L) pcs->cap.y = 0L; else if (y <= max_y) pcs->cap.y = y; else if (!page_eject) pcs->cap.y = (y <= lim_y ? y : lim_y); else { coord vmi_cp = pcs->vmi_cp; coord y0 = pcs->cap.y; while (y > max_y) { int code = pcl_end_page_always(pcs); if (code < 0) return code; y -= (y0 <= max_y ? max_y : y0); y0 = (use_margins ? HOME_Y(pcs) : DEFAULT_Y_START(pcs)); /* if one VMI distance or less remains, always exit */ if ((vmi_cp == 0) || (y <= vmi_cp)) { y = y0; break; } /* otherwise, round to a multiple of VMI distance */ y += y0 - 1 - ((y - 1) % vmi_cp); } pcs->cap.y = y; } pcl_continue_underline(pcs); return 0; }