예제 #1
0
static int
hpgl_picture_frame_coords(hpgl_state_t *pgls, gs_int_rect *gl2_win)
{
	gs_rect dev_win; /* device window */
	hpgl_real_t x1 = pgls->g.picture_frame.anchor_point.x;
	hpgl_real_t y1 = pgls->g.picture_frame.anchor_point.y;
	hpgl_real_t x2 = x1 + pgls->g.picture_frame_width;
	hpgl_real_t y2 = y1 + pgls->g.picture_frame_height;

	pcl_set_ctm(pgls, false);
	hpgl_call(gs_transform(pgls->pgs, x1, y1, &dev_win.p));
	hpgl_call(gs_transform(pgls->pgs, x2, y2, &dev_win.q));
	hpgl_call(hpgl_set_plu_ctm(pgls));
	/*
	 * gs_bbox_transform_inverse puts the resulting points in the
	 * correct order, with p < q.
	 */
	{ gs_matrix mat;
	  gs_rect pcl_win; /* pcl window */

	  gs_currentmatrix(pgls->pgs, &mat);
	  hpgl_call(gs_bbox_transform_inverse(&dev_win, &mat, &pcl_win));
/* Round all coordinates to the nearest integer. */
#define set_round(e) gl2_win->e = (int)floor(pcl_win.e + 0.5)
	  set_round(p.x);
	  set_round(p.y);
	  set_round(q.x);
	  set_round(q.y);
#undef set_round
	}
	/* restore the ctm */
	hpgl_call(hpgl_set_ctm(pgls));
	return 0;
}
예제 #2
0
/* 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;
}
예제 #3
0
/*
 * 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
                          );
}
예제 #4
0
/* Set up a clipping path and device for insideness testing. */
static int
in_path(os_ptr oppath, i_ctx_t *i_ctx_p, gx_device * phdev)
{
    int code = gs_gsave(igs);
    int npop;
    double uxy[2];

    if (code < 0)
        return code;
    code = num_params(oppath, 2, uxy);
    if (code >= 0) {		/* Aperture is a single pixel. */
        gs_point dxy;
        gs_fixed_rect fr;

        gs_transform(igs, uxy[0], uxy[1], &dxy);
        fr.p.x = fixed_floor(float2fixed(dxy.x));
        fr.p.y = fixed_floor(float2fixed(dxy.y));
        fr.q.x = fr.p.x + fixed_1;
        fr.q.y = fr.p.y + fixed_1;
        code = gx_clip_to_rectangle(igs, &fr);
        npop = 2;
    } else if (code == e_stackunderflow) {
        /* If 0 elements, definitely a stackunderflow; otherwise, */
        /* only 1 number, also a stackunderflow. */
        npop = code;
    } else {			/* Aperture is a user path. */
        /* We have to set the clipping path without disturbing */
        /* the current path. */
        gx_path *ipath = igs->path;
        gx_path save;

        gx_path_init_local(&save, imemory);
        gx_path_assign_preserve(&save, ipath);
        gs_newpath(igs);
        code = upath_append(oppath, i_ctx_p, false);
        if (code >= 0)
            code = gx_clip_to_path(igs);
        gx_path_assign_free(igs->path, &save);
        npop = 1;
    }
    if (code < 0) {
        gs_grestore(igs);
        return code;
    }
    /* Install the hit detection device. */
    gx_set_device_color_1(igs);
    gx_device_init((gx_device *) phdev, (const gx_device *)&gs_hit_device,
                   NULL, true);
    phdev->width = phdev->height = max_int;
    gx_device_fill_in_procs(phdev);
    gx_set_device_only(igs, phdev);
    return npop;
}
예제 #5
0
/*
 * Set up the pattern orientatin and reference point for GL. The anchor point
 * is taken as being in the current GL space, and the current transform is
 * assumed properly set. The orientation is that of the logical page.
 */
  void
pcl_xfm_gl_set_pat_ref_pt(
    pcl_state_t *   pcs
)
{
    gs_transform( pcs->pgs,
                  pcs->g.anchor_corner.x,
                  pcs->g.anchor_corner.y,
                  &(pcs->pat_ref_pt)
                  );
    pcs->pat_ref_pt.x = floor(pcs->pat_ref_pt.x + 0.5);
    pcs->pat_ref_pt.y = floor(pcs->pat_ref_pt.y + 0.5);
    pcs->pat_orient = (pcs->xfm_state.lp_orient + (pcs->g.rotation / 90)) & 0x3;
}
예제 #6
0
/* set variables other than setting the page device that do not
   default to pcl reset values */
void
pxPassthrough_pcl_state_nonpage_exceptions(px_state_t * pxs)
{
    /* xl cursor -> pcl cursor position */
    gs_point xlcp, pclcp, dp;

    /* make the pcl ctm active, after resets the hpgl/2 ctm is
       active. */
    pcl_set_graphics_state(global_pcs);
    /* xl current point -> device point -> pcl current
       point.  If anything fails we assume the current
       point is not valid and use the cap from the pcl
       state initialization - pcl's origin */
    if (gs_currentpoint(pxs->pgs, &xlcp) ||
        gs_transform(pxs->pgs, xlcp.x, xlcp.y, &dp) ||
        gs_itransform(global_pcs->pgs, dp.x, dp.y, &pclcp)) {
        global_pcs->cap.x = 0;
        global_pcs->cap.y = inch2coord(2.0 / 6.0);      /* 1/6" off by 2x in resolution. */
        if (gs_debug_c('i'))
            dmprintf2(pxs->memory,
                      "passthrough: changing cap NO currentpoint (%d, %d) \n",
                      global_pcs->cap.x, global_pcs->cap.y);
    } else {
        if (gs_debug_c('i'))
            dmprintf8(pxs->memory,
                      "passthrough: changing cap from (%d,%d) (%d,%d) (%d, %d) (%d, %d) \n",
                      global_pcs->cap.x, global_pcs->cap.y, (coord) xlcp.x,
                      (coord) xlcp.y, (coord) dp.x, (coord) dp.y,
                      (coord) pclcp.x, (coord) pclcp.y);
        global_pcs->cap.x = (coord) pclcp.x;
        global_pcs->cap.y = (coord) pclcp.y;
    }
    if (global_pcs->underline_enabled)
        global_pcs->underline_start = global_pcs->cap;


    global_char_angle = pxs->pxgs->char_angle;
    global_char_shear.x = pxs->pxgs->char_shear.x;
    global_char_shear.y = pxs->pxgs->char_shear.y;
    global_char_scale.x = pxs->pxgs->char_scale.x;
    global_char_scale.y = pxs->pxgs->char_scale.y;
    global_char_bold_value = pxs->pxgs->char_bold_value;

}
예제 #7
0
파일: pcpage.c 프로젝트: ststeiger/ghostsvg
void
pcl_mark_page_for_current_pos(pcl_state_t *pcs)
{
    /* nothing to do */
    if ( pcs->page_marked )
        return;

    /* convert current point to device space and check if it is inside
       device rectangle for the page */
    {
        gs_fixed_rect page_bbox_fixed = pcs->xfm_state.dev_print_rect;
        gs_rect page_bbox_float;
        gs_point current_pt, dev_pt;

        page_bbox_float.p.x = fixed2float(page_bbox_fixed.p.x);
        page_bbox_float.p.y = fixed2float(page_bbox_fixed.p.y);
        page_bbox_float.q.x = fixed2float(page_bbox_fixed.q.x);
        page_bbox_float.q.y = fixed2float(page_bbox_fixed.q.y);

        if ( gs_currentpoint(pcs->pgs, &current_pt) < 0 ) {
             dprintf("Not expected to fail\n" );
             return;
        }

        if ( gs_transform(pcs->pgs, current_pt.x, current_pt.y, &dev_pt) ) {
             dprintf("Not expected to fail\n" );
             return;
        }

        /* half-open lower - not sure this is correct */
        if ( dev_pt.x >= page_bbox_float.p.x &&
             dev_pt.y >= page_bbox_float.p.y &&
             dev_pt.x < page_bbox_float.q.x &&
             dev_pt.y < page_bbox_float.q.y )
            pcs->page_marked = true;

    }
}
예제 #8
0
파일: rtmisc.c 프로젝트: ststeiger/ghostsvg
/*
 * We export this so we can call it from HP-GL/2 configurations.
 * Note that it returns 1 iff it changed the PCL CAP.
 *
 * ESC % <enum> A
 */ 
  int
rtl_enter_pcl_mode(
    pcl_args_t *    pargs,
    pcl_state_t *   pcs
)
{
    int             b = int_arg(pargs) & 1;

    if ( pcs->parse_other == 
	 (int(*)(void *, pcl_state_t *, stream_cursor_read *))hpgl_process ) {
        /* 
         * We were in HP-GL/2 mode.  Destroy the gl/2 polygon path
	 * and conditionally copy back the cursor position.
         */
	if (b != 0) {
            /* the usual user -> device -> user dance. */
	    gs_point    pt, dev_pt;

	    hpgl_call_mem(pcs->memory, hpgl_set_ctm(pcs));
	    hpgl_call_mem(pcs->memory, hpgl_get_current_position(pcs, &pt));
	    hpgl_call_mem(pcs->memory, gs_transform(pcs->pgs, pt.x, pt.y, &dev_pt));
	    hpgl_call_mem(pcs->memory, pcl_set_ctm(pcs, true));
	    hpgl_call_mem(pcs->memory, gs_itransform(pcs->pgs, dev_pt.x, dev_pt.y, &pt));

	    /* HPGL/2 uses floats for coordinates */
#define round(x)    (((x) < 0.0) ? (ceil ((x) - 0.5)) : (floor ((x) + 0.5)))
	    pcs->cap.x = round(pt.x);
	    pcs->cap.y = round(pt.y);
#undef round
	}
    } else
	  b = 0;

    pcs->parse_other = 0;
    return b;		/* not 0, see comment above */
}
예제 #9
0
파일: plfapi.c 프로젝트: hackqiang/gs
static int
pl_fapi_set_cache(gs_text_enum_t * penum, const gs_font_base * pbfont,
                  const gs_string * char_name, int cid,
                  const double pwidth[2], const gs_rect * pbbox,
                  const double Metrics2_sbw_default[4], bool * imagenow)
{
    gs_state *pgs = (gs_state *) penum->pis;
    float w2[6];
    int code = 0;
    gs_fapi_server *I = pbfont->FAPI;

    if ((penum->text.operation & TEXT_DO_DRAW) && (pbfont->WMode & 1)
        && pwidth[0] == 1.0) {
        gs_rect tmp_pbbox;
        gs_matrix save_ctm;
        const gs_matrix id_ctm = { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 };
        /* This is kind of messy, but the cache entry has already been calculated
           using the in-force matrix. The problem is that we have to call gs_setcachedevice
           with the in-force matrix, not the rotated one, so we have to recalculate the extents
           to be correct for the rotated glyph.
         */

        /* save the ctm */
        gs_currentmatrix(pgs, &save_ctm);
        gs_setmatrix(pgs, &id_ctm);

        /* magic numbers - we don't completelely understand
           the translation magic used by HP.  This provides a
           good approximation */
        gs_translate(pgs, 1.0 / 1.15, -(1.0 - 1.0 / 1.15));
        gs_rotate(pgs, 90);

        gs_transform(pgs, pbbox->p.x, pbbox->p.y, &tmp_pbbox.p);
        gs_transform(pgs, pbbox->q.x, pbbox->q.y, &tmp_pbbox.q);

        w2[0] = pwidth[0];
        w2[1] = pwidth[1];
        w2[2] = tmp_pbbox.p.x;
        w2[3] = tmp_pbbox.p.y;
        w2[4] = tmp_pbbox.q.x;
        w2[5] = tmp_pbbox.q.y;

        gs_setmatrix(pgs, &save_ctm);
    } else {
        w2[0] = pwidth[0];
        w2[1] = pwidth[1];
        w2[2] = pbbox->p.x;
        w2[3] = pbbox->p.y;
        w2[4] = pbbox->q.x;
        w2[5] = pbbox->q.y;
    }

    if (pbfont->PaintType) {
        double expand = max(1.415,
                            gs_currentmiterlimit(pgs)) *
            gs_currentlinewidth(pgs) / 2;

        w2[2] -= expand;
        w2[3] -= expand;
        w2[4] += expand;
        w2[5] += expand;
    }

    if (I->ff.embolden != 0) {
        code = gs_setcharwidth((gs_show_enum *) penum, pgs, w2[0], w2[1]);
    } else {
        if ((code = gs_setcachedevice((gs_show_enum *) penum, pgs, w2)) < 0) {
            return (code);
        }
    }

    if ((penum->text.operation & TEXT_DO_DRAW) && (pbfont->WMode & 1)
        && pwidth[0] == 1.0) {
        *imagenow = false;
        return (gs_error_unknownerror);
    }

    *imagenow = true;
    return (code);
}
예제 #10
0
/* 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;
}
예제 #11
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;
}