Example #1
0
/* Read the bounding box of a path. */
int
gx_path_bbox(gx_path *ppath, gs_fixed_rect *pbox)
{	if ( ppath->first_subpath == 0 )
	   {	/* The path is empty, use the current point if any. */
		gx_path_current_point(ppath, &pbox->p);
		return gx_path_current_point(ppath, &pbox->q);
	   }
	/* The stored bounding box may not be up to date. */
	/* Correct it now if necessary. */
	if ( ppath->box_last == ppath->current_subpath->last )
	   {	/* Box is up to date */
		*pbox = ppath->bbox;
	   }
	else
	   {	gs_fixed_rect box;
		register segment *pseg = ppath->box_last;
		if ( pseg == 0 )	/* box is uninitialized */
		   {	pseg = (segment *)ppath->first_subpath;
			box.p.x = box.q.x = pseg->pt.x;
			box.p.y = box.q.y = pseg->pt.y;
		   }
		else
		   {	box = ppath->bbox;
			pseg = pseg->next;
		   }
/* Macro for adjusting the bounding box when adding a point */
#define adjust_bbox(pt)\
  if ( (pt).x < box.p.x ) box.p.x = (pt).x;\
  else if ( (pt).x > box.q.x ) box.q.x = (pt).x;\
  if ( (pt).y < box.p.y ) box.p.y = (pt).y;\
  else if ( (pt).y > box.q.y ) box.q.y = (pt).y
		while ( pseg )
		   {	switch ( pseg->type )
			   {
			case s_curve:
#define pcurve ((curve_segment *)pseg)
				adjust_bbox(pcurve->p1);
				adjust_bbox(pcurve->p2);
#undef pcurve
				/* falls through */
			default:
				adjust_bbox(pseg->pt);
			   }
			pseg = pseg->next;
		   }
#undef adjust_bbox
		ppath->bbox = box;
		ppath->box_last = ppath->current_subpath->last;
		*pbox = box;
	   }
	return 0;
}
Example #2
0
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_box;
        gs_fixed_point pt;
        int code;

        code = gx_default_clip_box(pcs->pgs, &page_box);
        if (code < 0)
            /* shouldn't happen. */
            return;
        
        code = gx_path_current_point(gx_current_path(pcs->pgs), &pt);
        if (code < 0)
            /* shouldn't happen */
            return;
        

        /* half-open lower - not sure this is correct */
        if (pt.x >= page_box.p.x && pt.y >= page_box.p.y &&
            pt.x < page_box.q.x && pt.y < page_box.q.y)
            pcs->page_marked = true;
    }
}
Example #3
0
int
gs_currentpoint(gs_state *pgs, gs_point *ppt)
{   gs_fixed_point pt;
    int code = gx_path_current_point(pgs->path, &pt);
    if ( code < 0 ) return code;
    return gs_itransform(pgs, fixed2float(pt.x), fixed2float(pt.y), ppt);
}
Example #4
0
int
gs_rlineto(gs_state *pgs, floatp x, floatp y)
{   gs_fixed_point cpt, dpt;
    int code = gx_path_current_point(pgs->path, &cpt);
    if ( code < 0 ) return code;
    if ( (code = gs_distance_transform2fixed(&pgs->ctm, x, y, &dpt)) >= 0 )
        code = gx_path_add_line(pgs->path, cpt.x + dpt.x, cpt.y + dpt.y);
    return code;
}
Example #5
0
/* relatives. */
int
gx_path_add_char_path(gx_path * to_path, gx_path * from_path,
                      gs_char_path_mode mode)
{
    int code;
    gs_fixed_rect bbox;

    switch (mode) {
        default:		/* shouldn't happen! */
            gx_path_new(from_path);
            return 0;
        case cpm_charwidth: {
            gs_fixed_point cpt;

            code = gx_path_current_point(from_path, &cpt);
            if (code < 0)
                break;
            return gx_path_add_point(to_path, cpt.x, cpt.y);
        }
        case cpm_true_charpath:
        case cpm_false_charpath:
            return gx_path_add_path(to_path, from_path);
        case cpm_true_charboxpath:
            gx_path_bbox(from_path, &bbox);
            code = gx_path_add_rectangle(to_path, bbox.p.x, bbox.p.y,
                                         bbox.q.x, bbox.q.y);
            break;
        case cpm_false_charboxpath:
            gx_path_bbox(from_path, &bbox);
            code = gx_path_add_point(to_path, bbox.p.x, bbox.p.y);
            if (code >= 0)
                code = gx_path_add_line(to_path, bbox.q.x, bbox.q.y);
            break;
    }
    if (code < 0)
        return code;
    gx_path_new(from_path);
    return 0;
}
Example #6
0
/* unless this is the only element of the path. */
int
gx_path_bbox(gx_path * ppath, gs_fixed_rect * pbox)
{
    if (ppath->bbox_accurate) {
	/* The bounding box was set by setbbox. */
	*pbox = ppath->bbox;
	return 0;
    }
    if (ppath->first_subpath == 0) {
	/* The path is empty, use the current point if any. */
	int code = gx_path_current_point(ppath, &pbox->p);

	if (code < 0) {
	    /*
	     * Don't return garbage, in case the caller doesn't
	     * check the return code.
	     */
	    pbox->p.x = pbox->p.y = 0;
	}
	pbox->q = pbox->p;
	return code;
    }
    /* The stored bounding box may not be up to date. */
    /* Correct it now if necessary. */
    if (ppath->box_last == ppath->current_subpath->last) {
	/* Box is up to date */
	*pbox = ppath->bbox;
    } else {
	fixed px, py, qx, qy;
	const segment *pseg = ppath->box_last;

	if (pseg == 0) {	/* box is uninitialized */
	    pseg = (const segment *)ppath->first_subpath;
	    px = qx = pseg->pt.x;
	    py = qy = pseg->pt.y;
	} else {
	    px = ppath->bbox.p.x, py = ppath->bbox.p.y;
	    qx = ppath->bbox.q.x, qy = ppath->bbox.q.y;
	}

/* Macro for adjusting the bounding box when adding a point */
#define ADJUST_BBOX(pt)\
  if ((pt).x < px) px = (pt).x;\
  else if ((pt).x > qx) qx = (pt).x;\
  if ((pt).y < py) py = (pt).y;\
  else if ((pt).y > qy) qy = (pt).y

	while ((pseg = pseg->next) != 0) {
	    switch (pseg->type) {
		case s_curve:
		    ADJUST_BBOX(((const curve_segment *)pseg)->p1);
		    ADJUST_BBOX(((const curve_segment *)pseg)->p2);
		    /* falls through */
		default:
		    ADJUST_BBOX(pseg->pt);
	    }
	}
#undef ADJUST_BBOX

#define STORE_BBOX(b)\
  (b).p.x = px, (b).p.y = py, (b).q.x = qx, (b).q.y = qy;
	STORE_BBOX(*pbox);
	STORE_BBOX(ppath->bbox);
#undef STORE_BBOX

	ppath->box_last = ppath->current_subpath->last;
    }
    return 0;
}