/* 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; }
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; } }
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); }
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; }
/* 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; }
/* 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; }