/* Compute the stroked outline of the current path */ int gs_strokepath(gs_state * pgs) { gx_path spath; int code; gx_path_init_local(&spath, pgs->path->memory); code = gx_stroke_add(pgs->path, &spath, pgs); if (code < 0) { gx_path_free(&spath, "gs_strokepath"); return code; } pgs->device->sgr.stroke_stored = false; code = gx_path_assign_free(pgs->path, &spath); if (code < 0) return code; /* NB: needs testing with PCL */ if (CPSI_mode && gx_path_is_void(pgs->path)) pgs->current_point_valid = false; else gx_setcurrentpoint(pgs, fixed2float(spath.position.x), fixed2float(spath.position.y)); return 0; }
static int bbox_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath, const gx_fill_params * params, const gx_device_color * pdevc, const gx_clip_path * pcpath) { gx_device_bbox *const bdev = (gx_device_bbox *) dev; gx_device *tdev = bdev->target; dev_proc_fill_path((*fill_path)) = (tdev == 0 ? dev_proc(&gs_null_device, fill_path) : dev_proc(tdev, fill_path)); int code; if (ppath == NULL) { /* A special handling of shfill with no path. */ gs_fixed_rect ibox; gs_fixed_point adjust; if (pcpath == NULL) return 0; gx_cpath_inner_box(pcpath, &ibox); adjust = params->adjust; adjust_box(&ibox, adjust); BBOX_ADD_RECT(bdev, ibox.p.x, ibox.p.y, ibox.q.x, ibox.q.y); return 0; } else if (!GX_DC_IS_TRANSPARENT(pdevc, bdev) && !gx_path_is_void(ppath)) { gs_fixed_rect ibox; gs_fixed_point adjust; if (gx_path_bbox(ppath, &ibox) < 0) return 0; adjust = params->adjust; adjust_box(&ibox, adjust); /* * If the path lies within the already accumulated box, just draw * on the target. */ if (BBOX_IN_RECT(bdev, &ibox)) return fill_path(tdev, pis, ppath, params, pdevc, pcpath); /* * If the target uses the default algorithm, just draw on the * bbox device. */ if (tdev != 0 && fill_path == gx_default_fill_path) return fill_path(dev, pis, ppath, params, pdevc, pcpath); /* Draw on the target now. */ code = fill_path(tdev, pis, ppath, params, pdevc, pcpath); if (code < 0) return code; if (pcpath != NULL && !gx_cpath_includes_rectangle(pcpath, ibox.p.x, ibox.p.y, ibox.q.x, ibox.q.y) ) { /* * Let the target do the drawing, but break down the * fill path into pieces for computing the bounding box. */ gx_drawing_color devc; set_nonclient_dev_color(&devc, bdev->black); /* any non-white color will do */ bdev->target = NULL; code = gx_default_fill_path(dev, pis, ppath, params, &devc, pcpath); bdev->target = tdev; } else { /* Just use the path bounding box. */ BBOX_ADD_RECT(bdev, ibox.p.x, ibox.p.y, ibox.q.x, ibox.q.y); } return code; } else return fill_path(tdev, pis, ppath, params, pdevc, pcpath); }