コード例 #1
0
/* but no client currently relies on this. */
bool
gx_path_enum_backup(gs_path_enum * penum)
{
    const segment *pseg = penum->pseg;

    if (pseg != 0) {
	if ((pseg = pseg->prev) == 0)
	    return false;
	penum->pseg = pseg;
	return true;
    }
    /* We're at the end of the path.  Check to see whether */
    /* we need to back up over a trailing moveto. */
    {
	const gx_path *ppath = penum->path;

	if (path_last_is_moveto(ppath) && penum->moveto_done) {		/* Back up over the trailing moveto. */
	    penum->moveto_done = false;
	    return true;
	} {
	    const subpath *psub = ppath->current_subpath;

	    if (psub == 0)	/* empty path */
		return false;
	    /* Back up to the last segment of the last subpath. */
	    penum->pseg = psub->last;
	    return true;
	}
    }
}
コード例 #2
0
ファイル: gxpath.c プロジェクト: BorodaZizitopa/ghostscript
static int
gz_path_close_subpath_notes(gx_path * ppath, segment_notes notes)
{
    subpath *psub;
    line_close_segment *lp;
    int code;

    if (!path_subpath_open(ppath))
        return 0;
    if (path_last_is_moveto(ppath)) {
        /* The last operation was a moveto: create a subpath. */
        code = gx_path_new_subpath(ppath);
        if (code < 0)
            return code;
    }
    path_alloc_segment(lp, line_close_segment, &st_line_close,
                       s_line_close, notes, "gx_path_close_subpath");
    path_alloc_link(lp);
    path_set_point(lp, psub->pt.x, psub->pt.y);
    lp->sub = psub;
    psub->is_closed = 1;
    path_update_closepath(ppath);
    trace_segment("[P]", (segment *) lp);
    return 0;
}
コード例 #3
0
int
gs_upathbbox(gs_state * pgs, gs_rect * pbox, bool include_moveto)
{
    gs_fixed_rect fbox;		/* box in device coordinates */
    gs_rect dbox;
    int code = gx_path_bbox_set(pgs->path, &fbox);

    if (code < 0)
	return code;
    /* If the path ends with a moveto and include_moveto is true, */
    /* include the moveto in the bounding box. */
    if (path_last_is_moveto(pgs->path) && include_moveto) {
	gs_fixed_point pt;

	code = gx_path_current_point_inline(pgs->path, &pt);
        if (code < 0)
	    return code;
	if (pt.x < fbox.p.x)
	    fbox.p.x = pt.x;
	if (pt.y < fbox.p.y)
	    fbox.p.y = pt.y;
	if (pt.x > fbox.q.x)
	    fbox.q.x = pt.x;
	if (pt.y > fbox.q.y)
	    fbox.q.y = pt.y;
    }
    /* Transform the result back to user coordinates. */
    dbox.p.x = fixed2float(fbox.p.x);
    dbox.p.y = fixed2float(fbox.p.y);
    dbox.q.x = fixed2float(fbox.q.x);
    dbox.q.y = fixed2float(fbox.q.y);
    return gs_bbox_transform_inverse(&dbox, &ctm_only(pgs), pbox);
}
コード例 #4
0
/* otherwise, return the element type. */
int
gx_path_enum_next(gs_path_enum * penum, gs_fixed_point ppts[3])
{
    const segment *pseg = penum->pseg;

    if (pseg == 0) {		/* We've enumerated all the segments, but there might be */
	/* a trailing moveto. */
	const gx_path *ppath = penum->path;

	if (path_last_is_moveto(ppath) && !penum->moveto_done) {	/* Handle a trailing moveto */
	    penum->moveto_done = true;
	    penum->notes = sn_none;
	    ppts[0] = ppath->position;
	    return gs_pe_moveto;
	}
	return 0;
    }
    penum->pseg = pseg->next;
    penum->notes = pseg->notes;
    switch (pseg->type) {
	case s_start:
	    ppts[0] = pseg->pt;
	    return gs_pe_moveto;
	case s_line:
	    ppts[0] = pseg->pt;
	    return gs_pe_lineto;
	case s_line_close:
	    ppts[0] = pseg->pt;
	    return gs_pe_closepath;
	case s_curve:
#define pcseg ((const curve_segment *)pseg)
	    ppts[0] = pcseg->p1;
	    ppts[1] = pcseg->p2;
	    ppts[2] = pseg->pt;
	    return gs_pe_curveto;
#undef pcseg
	default:
	    lprintf1("bad type %x in gx_path_enum_next!\n", pseg->type);
	    return_error(gs_error_Fatal);
    }
}
コード例 #5
0
/*
 * Reverse a path.  We know ppath != ppath_old.
 * NOTE: in releases 5.01 and earlier, the implicit line added by closepath
 * became the first segment of the reversed path.  Starting in release
 * 5.02, the code follows the Adobe implementation (and LanguageLevel 3
 * specification), in which this line becomes the *last* segment of the
 * reversed path.  This can produce some quite unintuitive results.
 *
 * The order of the subpaths is unspecified in the PLRM, but the CPSI
 * reverses the subpaths, and the CET (11-05 p6, test 3) tests for it.
 */
int
gx_path_copy_reversed(const gx_path * ppath_old, gx_path * ppath)
{
    const subpath *psub = ppath_old->current_subpath;

#ifdef DEBUG
    if (gs_debug_c('P'))
	gx_dump_path(ppath_old, "before reversepath");
#endif
 nsp:
    if (psub) {
	const segment *prev = psub->last;
	const segment *pseg;
	segment_notes notes =
	    (prev == (const segment *)psub ? sn_none :
	     psub->next->notes);
	segment_notes prev_notes;
	int code;

	if (!psub->is_closed) {
	    code = gx_path_add_point(ppath, prev->pt.x, prev->pt.y);
	    if (code < 0)
		return code;
	}
	/*
	 * The do ... while structure of this loop is artificial,
	 * designed solely to keep compilers from complaining about
	 * 'statement not reached' or 'end-of-loop code not reached'.
	 * The normal exit from this loop is the goto statement in
	 * the s_start arm of the switch.
	 */
	do {
	    pseg = prev;
	    prev_notes = notes;
	    prev = pseg->prev;
	    notes = pseg->notes;
	    prev_notes = (prev_notes & sn_not_first) |
		(notes & ~sn_not_first);
	    switch (pseg->type) {
		case s_start:
		    /* Finished subpath */
		    if (psub->is_closed) {
			code =
			    gx_path_close_subpath_notes(ppath, prev_notes);
			if (code < 0)
			    return code;
		    }
		    do {
			psub = (const subpath *)psub->prev;
		    } while (psub && psub->type != s_start);
		    goto nsp;
		case s_curve:
		    {
			const curve_segment *pc =
			(const curve_segment *)pseg;

			code = gx_path_add_curve_notes(ppath,
						       pc->p2.x, pc->p2.y,
						       pc->p1.x, pc->p1.y,
					prev->pt.x, prev->pt.y, prev_notes);
			break;
		    }
		case s_line:
		    code = gx_path_add_line_notes(ppath,
					prev->pt.x, prev->pt.y, prev_notes);
		    break;
		case s_line_close:
		    /* Skip the closing line. */
		    code = gx_path_add_point(ppath, prev->pt.x,
					     prev->pt.y);
		    break;
		default:	/* not possible */
		    return_error(gs_error_Fatal);
	    }
	} while (code >= 0);
	return code;		/* only reached if code < 0 */
    }
#undef sn_not_end
    /*
     * In the Adobe implementations, reversepath discards a trailing
     * moveto unless the path consists only of a moveto.  We reproduce
     * this behavior here, even though we consider it a bug.
     */
    if (ppath_old->first_subpath == 0 &&
	path_last_is_moveto(ppath_old)
	) {
	int code = gx_path_add_point(ppath, ppath_old->position.x,
				     ppath_old->position.y);

	if (code < 0)
	    return code;
    }
#ifdef DEBUG
    if (gs_debug_c('P'))
	gx_dump_path(ppath, "after reversepath");
#endif
    return 0;
}