/* RO; */ int hpgl_RO(hpgl_args_t *pargs, hpgl_state_t *pgls) { int angle=0; gs_point point, dev_pt; /* this business is used by both SC and RO -- perhaps it needs a new home */ hpgl_call(hpgl_set_ctm(pgls)); hpgl_call(hpgl_get_current_position(pgls, &point)); hpgl_call(gs_transform(pgls->pgs, point.x, point.y, &dev_pt)); if ( hpgl_arg_c_int(pgls->memory, pargs, &angle) ) switch ( angle ) { case 0: case 90: case 180: case 270: break; default: return e_Range; } if ( angle != pgls->g.rotation ) { hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); pgls->g.rotation = angle; hpgl_call(hpgl_set_ctm(pgls)); hpgl_call(gs_itransform(pgls->pgs, dev_pt.x, dev_pt.y, &point)); hpgl_call(hpgl_set_current_position(pgls, &point)); hpgl_call(hpgl_update_carriage_return_pos(pgls)); } return 0; }
/* * the following is not consistant with the general model as we * usually depend upon calling the commands directly to update * appropriate qtate variables, unfortunately we must guarantee a * reasonable picture frame, anchor point, and plot size for the rest * of the hpgl/2 code to function properly, and they must be provided * all at once. For example documented side effects of changing the * vertical picture frame height are IP;IW;PM;PM2, but these commands * do not make sense if the horizontal picture frame has never been * set. */ static void hpgl_default_coordinate_system(hpgl_state_t * pcs) { pcs->g.plot_width = pcs->g.picture_frame_width = pcs->xfm_state.lp_size.x; pcs->g.plot_height = pcs->g.picture_frame_height = pcs->xfm_state.lp_size.y; if (pcs->personality == rtl) { pcs->g.picture_frame.anchor_point.x = 0; pcs->g.picture_frame.anchor_point.y = 0; } else { pcs->g.picture_frame.anchor_point.x = pcs->margins.left; pcs->g.picture_frame.anchor_point.y = pcs->margins.top; { /* the previous setup subtracted 1" from the plot and picture frame height below, presumably derived from subtracting 1/2" for top and bottom margin. A better result is to use 2 * top margin. But this needs more testing against the HP printer, the new correction does work properly when the default top margin changes (ie. pclxl snippet mode). */ coord margins_extent = (2 * pcs->margins.top); pcs->g.plot_height -= margins_extent; pcs->g.picture_frame_height -= margins_extent; } } pcs->g.plot_size_vertical_specified = false; pcs->g.plot_size_horizontal_specified = false; /* The default coordinate system is absolute with the origin at 0,0 */ pcs->g.move_or_draw = hpgl_plot_move; pcs->g.relative_coords = hpgl_plot_absolute; { gs_point pos; pos.x = 0.0; pos.y = 0.0; (void)hpgl_set_current_position(pcs, &pos); } pcs->g.scaling_type = hpgl_scaling_none; pcs->g.soft_clip_window.rect.p.x = pcs->g.soft_clip_window.rect.p.y = 0; pcs->g.soft_clip_window.rect.q.x = pcs->g.soft_clip_window.rect.q.y = 0; return; }
/* SC; */ int hpgl_SC(hpgl_args_t *pargs, hpgl_state_t *pgls) { hpgl_real_t xy[4]; int i; int type; hpgl_scaling_params_t scale_params; gs_point point, dev_pt, dev_anchor; scale_params = pgls->g.scaling_params; hpgl_call(hpgl_get_current_position(pgls, &point)); hpgl_call(gs_transform(pgls->pgs, point.x, point.y, &dev_pt)); hpgl_call(gs_transform(pgls->pgs, pgls->g.anchor_corner.x, pgls->g.anchor_corner.y, &dev_anchor)); for ( i = 0; i < 4 && hpgl_arg_real(pgls->memory, pargs, &xy[i]); ++i ) ; switch ( i ) { case 0: /* set defaults */ { /* a naked SC implies the soft clip window is bound to plotter units. */ gs_matrix umat; type = hpgl_scaling_none; hpgl_compute_user_units_to_plu_ctm(pgls, &umat); /* in-place */ hpgl_call(gs_bbox_transform(&pgls->g.soft_clip_window.rect, &umat, &pgls->g.soft_clip_window.rect)); pgls->g.soft_clip_window.isbound = true; break; } default: return e_Range; case 4: type = hpgl_scaling_anisotropic; hpgl_arg_c_int(pgls->memory, pargs, &type); switch ( type ) { case hpgl_scaling_anisotropic: /* 0 */ if ( xy[0] == xy[1] || xy[2] == xy[3] ) return e_Range; pxy: scale_params.pmin.x = xy[0]; scale_params.pmax.x = xy[1]; scale_params.pmin.y = xy[2]; scale_params.pmax.y = xy[3]; break; case hpgl_scaling_isotropic: /* 1 */ if ( xy[0] == xy[1] || xy[2] == xy[3] ) return e_Range; { hpgl_real_t left = 50, bottom = 50; if ( (hpgl_arg_c_real(pgls->memory, pargs, &left) && (left < 0 || left > 100 || !hpgl_arg_c_real(pgls->memory, pargs, &bottom) || bottom < 0 || bottom > 100)) ) return e_Range; scale_params.left = left; scale_params.bottom = bottom; } goto pxy; case hpgl_scaling_point_factor: /* 2 */ if ( xy[1] == 0 || xy[3] == 0 ) return e_Range; scale_params.pmin.x = xy[0]; scale_params.factor.x = xy[1]; scale_params.pmin.y = xy[2]; scale_params.factor.y = xy[3]; break; default: return e_Range; } } hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); pgls->g.scaling_params = scale_params; pgls->g.scaling_type = type; hpgl_call(hpgl_set_ctm(pgls)); hpgl_call(gs_itransform(pgls->pgs, dev_pt.x, dev_pt.y, &point)); hpgl_call(hpgl_set_current_position(pgls, &point)); hpgl_call(gs_itransform(pgls->pgs, dev_anchor.x, dev_anchor.y, &pgls->g.anchor_corner)); /* PCLTRM 23-7 (commands the update cr position) does not list SC but PCL updates the position */ hpgl_call(hpgl_update_carriage_return_pos(pgls)); return 0; }
/* The part of the DF command applicable for overlay macros */ int hpgl_reset_overlay(hpgl_state_t *pgls) { hpgl_args_t args; hpgl_args_setup(&args); hpgl_AC(&args, pgls); hpgl_args_setup(&args); pgls->g.font_selected = 0; hpgl_AD(&args, pgls); hpgl_args_setup(&args); hpgl_SD(&args, pgls); hpgl_args_setup(&args); hpgl_CF(&args, pgls); hpgl_args_setup(&args); hpgl_args_add_int(&args, 1); hpgl_args_add_int(&args, 0); hpgl_DI(&args, pgls); /* HAS -- Figure out some way to do this so that it is consistant */ pgls->g.label.terminator = 3; pgls->g.label.print_terminator = false; hpgl_args_setup(&args); hpgl_DV(&args, pgls); hpgl_args_setup(&args); hpgl_ES(&args, pgls); pgls->g.label.write_vertical = false; pgls->g.label.double_byte = false; hpgl_args_setup(&args); hpgl_LM(&args, pgls); hpgl_args_set_int(&args, 1); hpgl_LO(&args, pgls); /* we do this instead of calling SC directly */ if ( pgls->g.scaling_type != hpgl_scaling_none ) { gs_point dpt, pt; /* device point and user point */ hpgl_call(hpgl_get_current_position(pgls, &pt)); hpgl_call(gs_transform(pgls->pgs, pt.x, pt.y, &dpt)); pgls->g.scaling_type = hpgl_scaling_none; hpgl_call(hpgl_set_ctm(pgls)); hpgl_call(gs_itransform(pgls->pgs, dpt.x, dpt.y, &pt)); hpgl_call(hpgl_set_current_position(pgls, &pt)); } pgls->g.fill_type = hpgl_even_odd_rule; hpgl_args_set_int(&args,0); hpgl_PM(&args, pgls); hpgl_args_set_int(&args,2); hpgl_PM(&args, pgls); pgls->g.bitmap_fonts_allowed = 0; hpgl_args_setup(&args); hpgl_SI(&args, pgls); hpgl_args_setup(&args); hpgl_SL(&args, pgls); /* We initialize symbol mode directly because hpgl_SM parses its argument differently than most other commands */ pgls->g.symbol_mode = 0; hpgl_args_setup(&args); hpgl_SS(&args, pgls); hpgl_args_set_int(&args,1); hpgl_TR(&args, pgls); hpgl_args_setup(&args); hpgl_TD(&args, pgls); hpgl_args_setup(&args); hpgl_MC(&args, pgls); #ifdef LJ6_COMPAT /* LJ6 seems to reset PP with an IN command the Color Laserjet does not. NB this needs to be handled with dynamic configuration */ hpgl_args_setup(&args); hpgl_PP(&args, pgls); #endif return 0; }