/* * End (raster) graphics mode. This may be called explicitly by either of the * end graphics mode commands (<esc>*rB or <esc>*rC), or implicitly by any * commmand which is neither legal nor ignored in graphics mode. */ int pcl_end_graphics_mode( pcl_state_t * pcs ) { gs_point cur_pt; gs_matrix dev2pd; /* close the raster; exit graphics mode */ pcl_complete_raster(pcs); pcs->raster_state.graphics_mode = false; /* get the new current point; then restore the graphic state */ gs_transform(pcs->pgs, 0.0, 0.0, &cur_pt); pcl_grestore(pcs); /* transform the new point back to "pseudo print direction" space */ pcl_invert_mtx(&(pcs->xfm_state.pd2dev_mtx), &dev2pd); gs_point_transform(cur_pt.x, cur_pt.y, &dev2pd, &cur_pt); pcl_set_cap_x(pcs, (coord)(cur_pt.x + 0.5) - adjust_pres_mode(pcs), false, false); return pcl_set_cap_y( pcs, (coord)(cur_pt.y + 0.5) - pcs->margins.top, false, false, false, false ); }
/* * ESC & f <pp_enum> S * * Contrary to what is indicated in the "PCL 5 Printer Language Technical * Reference Manual", October 1992 ed., p. 6-16, pushd cursors are stored * in logical page space, not device space. */ static int push_pop_cursor(pcl_args_t * pargs, pcl_state_t * pcs) { int type = uint_arg(pargs); if ((type == 0) && (pcs->cursor_stk_size < countof(pcs->cursor_stk))) { gs_point *ppt = &(pcs->cursor_stk[pcs->cursor_stk_size++]); ppt->x = (double)pcs->cap.x; ppt->y = (double)pcs->cap.y; gs_point_transform(ppt->x, ppt->y, &(pcs->xfm_state.pd2lp_mtx), ppt); } else if ((type == 1) && (pcs->cursor_stk_size > 0)) { gs_point *ppt = &(pcs->cursor_stk[--pcs->cursor_stk_size]); gs_matrix lp2pd; pcl_invert_mtx(&(pcs->xfm_state.pd2lp_mtx), &lp2pd); gs_point_transform(ppt->x, ppt->y, &lp2pd, ppt); pcl_set_cap_x(pcs, (coord) ppt->x, false, false); pcl_set_cap_y(pcs, (coord) ppt->y - pcs->margins.top, false, false, false, false); } return 0; }
/* * 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; }
/* * BS */ static int cmd_BS(pcl_args_t * pargs, /* ignored */ pcl_state_t * pcs) { pcl_set_cap_x(pcs, (coord) - pcs->last_width, true, true); pcs->last_was_BS = true; pcs->cursor_moved = true; return 0; }
static inline void do_horiz_motion(pcl_args_t * pargs, pcl_state_t * pcs, coord mul, bool truncate_arg) { pcl_set_cap_x(pcs, (coord) (motion_args(pargs, truncate_arg) * mul), arg_is_signed(pargs), false); pcs->cursor_moved = true; return; }
/* * ESC & a <col> M * * Set right margin. The right margin is set to the *right* edge of the * specified column, so we need to add 1 to the column number. */ static int set_right_margin(pcl_args_t * pargs, pcl_state_t * pcs) { coord rmarg = (uint_arg(pargs) + 1) * pcl_hmi(pcs); if (rmarg > pcs->xfm_state.pd_size.x) rmarg = pcs->xfm_state.pd_size.x; if (rmarg > pcs->margins.left) { pcs->margins.right = rmarg; if (pcs->cap.x > rmarg) pcl_set_cap_x(pcs, rmarg, false, false); } return 0; }
/* * ESC & a <col> L * * Set left margin. */ static int set_left_margin(pcl_args_t * pargs, pcl_state_t * pcs) { coord lmarg = uint_arg(pargs) * pcl_hmi(pcs); /* adjust underlining if the left margin passes to the right of the underline start position */ if ((pcs->underline_enabled) && (lmarg > pcs->underline_start.x)) pcs->underline_start.x = lmarg; if (lmarg < pcs->margins.right) { pcs->margins.left = lmarg; if (pcs->cap.x < lmarg) pcl_set_cap_x(pcs, lmarg, false, false); } return 0; }
/* * HT * * Tabs occur at ever 8 columns, measure from the left text margin. */ static int cmd_HT(pcl_args_t * pargs, /* ignored */ pcl_state_t * pcs) { coord x = pcs->cap.x - pcs->margins.left; coord tab; if (x < 0) x = -x; else if ((tab = 8 * pcl_hmi(pcs)) > 0) x = tab - (x % tab); else x = 0L; pcl_set_cap_x(pcs, x, true, true); pcs->cursor_moved = true; return 0; }
/* * Return the cursor to its "home" position */ void pcl_home_cursor(pcl_state_t * pcs) { pcl_set_cap_x(pcs, pcs->margins.left, false, false); pcl_set_cap_y(pcs, 0L, false, false, true, false); }