static int set_logical_page(pcl_args_t * pargs, pcl_state_t * pcs) { uint count = uint_arg(pargs); const pcl_logical_page_t *plogpage = (pcl_logical_page_t *) arg_data(pargs); pcl_paper_size_t *pcur_paper; #ifdef DEBUG if (gs_debug_c('i')) { pcl_debug_dump_data(pcs->memory, arg_data(pargs), uint_arg(pargs)); } #endif /* the currently selected paper size */ pcur_paper = (pcl_paper_size_t *) pcs->xfm_state.paper_size; /* the command can set width, height and offsets (10) or just offsets (4) */ if (count != 10 && count != 4) return e_Range; if (count == 10) { pcur_paper->width = pl_get_uint16(plogpage->Width) * 10; pcur_paper->height = pl_get_uint16(plogpage->Height) * 10; if (pcur_paper->width == 0 || pcur_paper->height == 0) return e_Range; } pcur_paper->offset_portrait = pl_get_int16(plogpage->LeftOffset) * 10; pcur_paper->offset_landscape = pl_get_int16(plogpage->TopOffset) * 10; new_page_size(pcs, pcur_paper, false, false); gs_erasepage(pcs->pgs); pcs->page_marked = false; return 0; }
/* Set a device into an interpreter instance */ static int /* ret 0 ok, else -ve error code */ ps_impl_set_device( pl_interp_instance_t *instance, /* interp instance to use */ gx_device *device /* device to set (open or closed) */ ) { int code = 0; int exit_code = 0; ps_interp_instance_t *psi = (ps_interp_instance_t *)instance; gs_state *pgs = psi->minst->i_ctx_p->pgs; /* Initialize device ICC profile */ code = gsicc_init_device_profile(pgs, device); if (code < 0) return code; /* Set the device into the gstate */ code = gs_setdevice_no_erase(pgs, device); if (code >= 0 ) code = gs_erasepage(pgs); if (code < 0) return code; /* install a screen appropriate for the device */ { const char *screen_str = ".setdefaultscreen\n"; code = gsapi_run_string_continue(psi->plmemory->gs_lib_ctx, screen_str, strlen(screen_str), 0, &exit_code); /* needs more input this is not an error */ if ( code == e_NeedInput ) code = 0; if (code < 0) return code; } return exit_code; }
/* * End a page, either unconditionally or only if there are marks on it. * Return 1 if the page was actually printed and erased. */ int pcl_end_page( pcl_state_t * pcs, pcl_print_condition_t condition ) { int code = 0; pcl_break_underline(pcs); /* (could mark page) */ /* If we are conditionally printing (normal case) check if the page is marked */ if (condition != pcl_print_always) { if ( !pcl_page_marked(pcs) ) return 0; } /* If there's an overlay macro, execute it now. */ if (pcs->overlay_enabled) { void * value; if ( pl_dict_find( &pcs->macros, id_key(pcs->overlay_macro_id), 2, &value ) ) { pcs->overlay_enabled = false; /**** IN reset_overlay ****/ code = pcl_execute_macro( (const pcl_macro_t *)value, pcs, pcl_copy_before_overlay, pcl_reset_overlay, pcl_copy_after_overlay ); pcs->overlay_enabled = true; /**** IN copy_after ****/ } } /* output the page */ code = (*pcs->end_page)(pcs, pcs->num_copies, true); if ( code < 0 ) return code; /* allow the logical orientation command to be used again */ pcs->orientation_set = false; if ( pcs->end_page == pcl_end_page_top ) code = gs_erasepage(pcs->pgs); pcs->page_marked = false; /* force new logical page, allows external resolution changes. * see -dFirstPage -dLastPage * NB would be faster if we didn't do this every page. * * NB setting a new logical page defaults settings * that should carry over from the previous page * this error occurs only on documents that don't do any initilizations per page * hence only the viewer applications will see the speedup and the error */ if (!pjl_proc_compare(pcs->pjls, pjl_proc_get_envvar(pcs->pjls, "viewer"), "on")) { new_logical_page(pcs, pcs->xfm_state.lp_orient, pcs->xfm_state.paper_size, false, false); } /* * Advance of a page may move from a page front to a page back. This may * change the applicable transformations. */ update_xfm_state(pcs, 0); pcl_continue_underline(pcs); return (code < 0 ? code : 1); }
/* * Reset all parameters which must be reset whenever the page size changes. * * The third operand indicates if this routine is being called as part of * an initial reset. In that case, done't call HPGL's reset - the reset * will do that later. */ static void new_page_size( pcl_state_t * pcs, const pcl_paper_size_t * psize, bool reset_initial, bool for_passthrough ) { floatp width_pts = psize->width * 0.01; floatp height_pts = psize->height * 0.01; float page_size[2]; static float old_page_size[2] = { 0, 0 }; gs_state * pgs = pcs->pgs; gs_matrix mat; bool changed_page_size; page_size[0] = width_pts; page_size[1] = height_pts; old_page_size[0] = pcs->xfm_state.paper_size ? pcs->xfm_state.paper_size->width : 0; old_page_size[1] = pcs->xfm_state.paper_size ? pcs->xfm_state.paper_size->height : 0; put_param1_float_array(pcs, "PageSize", page_size); /* * Reset the default transformation. * * The graphic library provides a coordinate system in points, with the * origin at the lower left corner of the page. The PCL code uses a * coordinate system in centi-points, with the origin at the upper left * corner of the page. */ gs_setdefaultmatrix(pgs, NULL); gs_initmatrix(pgs); gs_currentmatrix(pgs, &mat); gs_matrix_translate(&mat, 0.0, height_pts, &mat); gs_matrix_scale(&mat, 0.01, -0.01, &mat); gs_setdefaultmatrix(pgs, &mat); pcs->xfm_state.paper_size = psize; pcs->overlay_enabled = false; update_xfm_state(pcs, reset_initial); reset_margins(pcs, for_passthrough); /* check if update_xfm_state changed the page size */ changed_page_size = !(old_page_size[0] == pcs->xfm_state.paper_size->width && old_page_size[1] == pcs->xfm_state.paper_size->height); /* * make sure underlining is disabled (homing the cursor may cause * an underline to be put out. */ pcs->underline_enabled = false; pcl_home_cursor(pcs); pcl_xfm_reset_pcl_pat_ref_pt(pcs); if (!reset_initial) hpgl_do_reset(pcs, pcl_reset_page_params); if ( pcs->end_page == pcl_end_page_top ) { /* don't erase in snippet mode */ if (pcs->page_marked || changed_page_size) { gs_erasepage(pcs->pgs); pcs->page_marked = false; } } }
/* * End a page, either unconditionally or only if there are marks on it. * Return 1 if the page was actually printed and erased. */ int pcl_end_page(pcl_state_t * pcs, pcl_print_condition_t condition) { int code = 0; pcl_break_underline(pcs); /* (could mark page) */ /* If we are conditionally printing (normal case) check if the page is marked */ if (condition != pcl_print_always) { if (!pcl_page_marked(pcs)) return 0; } /* finish up graphics mode in case we finished the page in the middle of a raster stream */ if (pcs->raster_state.graphics_mode) pcl_end_graphics_mode(pcs); /* If there's an overlay macro, execute it now. */ if (pcs->overlay_enabled) { void *value; if (pl_dict_find(&pcs->macros, id_key(pcs->overlay_macro_id), 2, &value)) { pcs->overlay_enabled = false; /**** IN reset_overlay ****/ code = pcl_execute_macro((const pcl_macro_t *)value, pcs, pcl_copy_before_overlay, pcl_reset_overlay, pcl_copy_after_overlay); if (code < 0) return code; pcs->overlay_enabled = true; /**** IN copy_after ****/ } } /* output the page */ code = (*pcs->end_page) (pcs, pcs->num_copies, true); if (code < 0) return code; if (pcs->end_page == pcl_end_page_top) code = gs_erasepage(pcs->pgs); pcs->page_marked = false; /* * Advance of a page may move from a page front to a page back. This may * change the applicable transformations. */ /* * Keep track of the side you are on */ if (pcs->duplex) { pcs->back_side = ! pcs->back_side; } else { pcs->back_side = false; } put_param1_bool(pcs,"FirstSide", !pcs->back_side); update_xfm_state(pcs, 0); pcl_continue_underline(pcs); return (code < 0 ? code : 1); }
static int test10(gs_state * pgs, gs_memory_t * mem) { gs_c_param_list list; gs_param_string nstr, OFstr; gs_param_float_array PSa; gs_param_float_array HWRa; gs_param_int_array HWSa; int HWSize[2]; float HWResolution[2], PageSize[2]; long MaxBitmap; int code; gx_device *dev = gs_currentdevice(pgs); float xlate_x, xlate_y; gs_rect cliprect; gs_c_param_list_write(&list, mem); code = gs_getdeviceparams(dev, (gs_param_list *) & list); if (code < 0) { lprintf1("getdeviceparams failed! code = %d\n", code); gs_abort(mem); } gs_c_param_list_read(&list); code = param_read_string((gs_param_list *) & list, "Name", &nstr); if (code < 0) { lprintf1("reading Name failed! code = %d\n", code); gs_abort(mem); } code = param_read_int_array((gs_param_list *) & list, "HWSize", &HWSa); if (code < 0) { lprintf1("reading HWSize failed! code = %d\n", code); gs_abort(mem); } emprintf3(mem, "HWSize[%d] = [ %d, %d ]\n", HWSa.size, HWSa.data[0], HWSa.data[1]); code = param_read_float_array((gs_param_list *) & list, "HWResolution", &HWRa); if (code < 0) { lprintf1("reading Resolution failed! code = %d\n", code); gs_abort(mem); } emprintf3(mem, "HWResolution[%d] = [ %f, %f ]\n", HWRa.size, HWRa.data[0], HWRa.data[1]); code = param_read_float_array((gs_param_list *) & list, "PageSize", &PSa); if (code < 0) { lprintf1("reading PageSize failed! code = %d\n", code); gs_abort(mem); } emprintf3(mem, "PageSize[%d] = [ %f, %f ]\n", PSa.size, PSa.data[0], PSa.data[1]); code = param_read_long((gs_param_list *) & list, "MaxBitmap", &MaxBitmap); if (code < 0) { lprintf1("reading MaxBitmap failed! code = %d\n", code); gs_abort(mem); } emprintf1(mem, "MaxBitmap = %ld\n", MaxBitmap); /* Switch to param list functions to "write" */ gs_c_param_list_write(&list, mem); /* Always set the PageSize. */ PageSize[0] = 72.0 * ypage_wid; PageSize[1] = 72.0 * xpage_len; PSa.data = PageSize; code = param_write_float_array((gs_param_list *) & list, "PageSize", &PSa); if (nstr.data[0] != 'v') { /* Set the OutputFile string file name */ OFstr.persistent = false; OFstr.data = outfile; OFstr.size = strlen(outfile); code = param_write_string((gs_param_list *) & list, "OutputFile", &OFstr); if (code < 0) { lprintf1("setting OutputFile name failed, code=%d\n", code); gs_abort(mem); } if (nstr.data[0] == 'x') { HWResolution[0] = HWResolution[1] = 72.0; } else { HWResolution[0] = HWResolution[1] = 360.0; } HWRa.data = HWResolution; HWSize[0] = (int)(HWResolution[0] * ypage_wid); HWSize[1] = (int)(HWResolution[1] * xpage_len); emprintf3(mem, "\tHWSize = [%d,%d], HWResolution = %f dpi\n", HWSize[0], HWSize[1], HWResolution[0]); HWSa.data = HWSize; code = param_write_float_array((gs_param_list *) & list, "HWResolution", &HWRa); code = param_write_int_array((gs_param_list *) & list, "HWSize", &HWSa); MaxBitmap = 1000000L; code = param_write_long((gs_param_list *) & list, "MaxBitmap", &MaxBitmap); } gs_c_param_list_read(&list); code = gs_putdeviceparams(dev, (gs_param_list *) & list); emprintf1(mem, "putdeviceparams: code=%d\n", code); gs_c_param_list_release(&list); /* note: initgraphics no longer resets the color or color space */ gs_erasepage(pgs); gs_initgraphics(pgs); { gs_color_space *cs = gs_cspace_new_DeviceGray(mem); gs_setcolorspace(pgs, cs); gs_setcolorspace(pgs, cs); gs_decrement(cs, "test10 DeviceGray"); } gs_clippath(pgs); gs_pathbbox(pgs, &cliprect); emprintf4(mem, "\tcliprect = [[%g,%g],[%g,%g]]\n", cliprect.p.x, cliprect.p.y, cliprect.q.x, cliprect.q.y); gs_newpath(pgs); switch (((rotate_value + 270) / 90) & 3) { default: case 0: /* 0 = 360 degrees in PS == 90 degrees in printer */ xlate_x = cliprect.p.x; xlate_y = cliprect.p.y; break; case 1: /* 90 degrees in PS = 180 degrees printer */ xlate_x = cliprect.q.x; xlate_y = cliprect.p.y; break; case 2: /* 180 degrees in PS == 270 degrees in printer */ xlate_x = cliprect.q.x; xlate_y = cliprect.q.y; break; case 3: /* 270 degrees in PS == 0 degrees in printer */ xlate_x = cliprect.p.x; xlate_y = cliprect.q.y; break; } emprintf2(mem, "translate origin to [ %f, %f ]\n", xlate_x, xlate_y); gs_translate(pgs, xlate_x, xlate_y); /* further move (before rotate) by user requested amount */ gs_translate(pgs, 72.0 * (float)xmove_origin, 72.0 * (float)ymove_origin); gs_rotate(pgs, (float)rotate_value + 270.0); gs_scale(pgs, scale_x * 72.0 / 2032.0, scale_y * 72.0 / 2032.0); gs_setlinecap(pgs, gs_cap_butt); gs_setlinejoin(pgs, gs_join_bevel); gs_setfilladjust(pgs, 0.0, 0.0); capture_exec(pgs); return 0; }
int main(int argc, const char *argv[]) { char achar = '0'; gs_memory_t *mem; gs_state *pgs; const gx_device *const *list; gx_device *dev; gx_device_bbox *bbdev; int code; gp_init(); mem = gs_malloc_init(); gs_lib_init1(mem); if (argc < 2 || (achar = argv[1][0]) < '1' || achar > '0' + countof(tests) - 1 ) { lprintf1("Usage: gslib 1..%c\n", '0' + (char)countof(tests) - 1); gs_abort(mem); } gs_debug['@'] = 1; gs_debug['?'] = 1; /*gs_debug['B'] = 1; *//****** PATCH ******/ /*gs_debug['L'] = 1; *//****** PATCH ******/ /* * gs_iodev_init must be called after the rest of the inits, for * obscure reasons that really should be documented! */ gs_iodev_init(mem); /****** WRONG ******/ gs_lib_device_list(&list, NULL); gs_copydevice(&dev, list[0], mem); check_device_separable(dev); gx_device_fill_in_procs(dev); bbdev = gs_alloc_struct_immovable(mem, gx_device_bbox, &st_device_bbox, "bbox"); gx_device_bbox_init(bbdev, dev, mem); code = dev_proc(dev, get_profile)(dev, &bbdev->icc_struct); rc_increment(bbdev->icc_struct); /* Print out the device name just to test the gsparam.c API. */ { gs_c_param_list list; gs_param_string nstr; gs_c_param_list_write(&list, mem); code = gs_getdeviceparams(dev, (gs_param_list *) & list); if (code < 0) { lprintf1("getdeviceparams failed! code = %d\n", code); gs_abort(mem); } gs_c_param_list_read(&list); code = param_read_string((gs_param_list *) & list, "Name", &nstr); if (code < 0) { lprintf1("reading Name failed! code = %d\n", code); gs_abort(mem); } dputs("Device name = "); debug_print_string(nstr.data, nstr.size); dputs("\n"); gs_c_param_list_release(&list); } /* * If this is a device that takes an OutputFile, set the OutputFile * to "-" in the copy. */ { gs_c_param_list list; gs_param_string nstr; gs_c_param_list_write(&list, mem); param_string_from_string(nstr, "-"); code = param_write_string((gs_param_list *)&list, "OutputFile", &nstr); if (code < 0) { lprintf1("writing OutputFile failed! code = %d\n", code); gs_abort(mem); } gs_c_param_list_read(&list); code = gs_putdeviceparams(dev, (gs_param_list *)&list); gs_c_param_list_release(&list); if (code < 0 && code != gs_error_undefined) { lprintf1("putdeviceparams failed! code = %d\n", code); gs_abort(mem); } } dev = (gx_device *) bbdev; pgs = gs_state_alloc(mem); gs_setdevice_no_erase(pgs, dev); /* can't erase yet */ { gs_point dpi; gs_screen_halftone ht; gs_dtransform(pgs, 72.0, 72.0, &dpi); ht.frequency = min(fabs(dpi.x), fabs(dpi.y)) / 16.001; ht.angle = 0; ht.spot_function = odsf; gs_setscreen(pgs, &ht); } /* gsave and grestore (among other places) assume that */ /* there are at least 2 gstates on the graphics stack. */ /* Ensure that now. */ gs_gsave(pgs); gs_erasepage(pgs); code = (*tests[achar - '1']) (pgs, mem); gs_output_page(pgs, 1, 1); { gs_rect bbox; gx_device_bbox_bbox(bbdev, &bbox); dprintf4("Bounding box: [%g %g %g %g]\n", bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y); } if (code) dprintf1("**** Test returned code = %d.\n", code); dputs("Done. Press <enter> to exit."); fgetc(mem->gs_lib_ctx->fstdin); gs_lib_finit(0, 0, mem); return 0; #undef mem }
/* Set a device into an interperter instance */ static int /* ret 0 ok, else -ve error code */ pxl_impl_set_device( pl_interp_instance_t *instance, /* interp instance to use */ gx_device *device /* device to set (open or closed) */ ) { int code; pxl_interp_instance_t *pxli = (pxl_interp_instance_t *)instance; px_state_t *pxs = pxli->pxs; enum {Sbegin, Ssetdevice, Sinitg, Sgsave, Serase, Sdone} stage; stage = Sbegin; gs_opendevice(device); pxs->interpolate = pxl_get_interpolation(instance); /* Set the device into the gstate */ stage = Ssetdevice; if ((code = gs_setdevice_no_erase(pxli->pgs, device)) < 0) /* can't erase yet */ goto pisdEnd; /* Initialize device ICC profile */ code = gsicc_init_device_profile(pxli->pgs, device); if (code < 0) return code; /* Init XL graphics */ stage = Sinitg; if ((code = px_initgraphics(pxli->pxs)) < 0) goto pisdEnd; /* Do inits of gstate that may be reset by setdevice */ gs_setaccuratecurves(pxli->pgs, true); /* All H-P languages want accurate curves. */ /* disable hinting at high res */ if (gs_currentdevice(pxli->pgs)->HWResolution[0] >= 300) gs_setgridfittt(pxs->font_dir, 0); /* gsave and grestore (among other places) assume that */ /* there are at least 2 gstates on the graphics stack. */ /* Ensure that now. */ stage = Sgsave; if ( (code = gs_gsave(pxli->pgs)) < 0) goto pisdEnd; stage = Serase; if ( (code = gs_erasepage(pxli->pgs)) < 0 ) goto pisdEnd; stage = Sdone; /* success */ /* Unwind any errors */ pisdEnd: switch (stage) { case Sdone: /* don't undo success */ break; case Serase: /* gs_erasepage failed */ /* undo gsave */ gs_grestore_only(pxli->pgs); /* destroys gs_save stack */ /* fall thru to next */ case Sgsave: /* gsave failed */ case Sinitg: /* undo setdevice */ gs_nulldevice(pxli->pgs); /* fall thru to next */ case Ssetdevice: /* gs_setdevice failed */ case Sbegin: /* nothing left to undo */ break; } return code; }
int xps_parse_fixed_page(xps_context_t *ctx, xps_part_t *part) { xps_item_t *root, *node; xps_resource_t *dict; char *width_att; char *height_att; char base_uri[1024]; char *s; int code; if_debug1m('|', ctx->memory, "doc: parsing page %s\n", part->name); xps_strlcpy(base_uri, part->name, sizeof base_uri); s = strrchr(base_uri, '/'); if (s) s[1] = 0; root = xps_parse_xml(ctx, part->data, part->size); if (!root) return gs_rethrow(-1, "cannot parse xml"); if (strcmp(xps_tag(root), "FixedPage")) return gs_throw1(-1, "expected FixedPage element (found %s)", xps_tag(root)); width_att = xps_att(root, "Width"); height_att = xps_att(root, "Height"); if (!width_att) return gs_throw(-1, "FixedPage missing required attribute: Width"); if (!height_att) return gs_throw(-1, "FixedPage missing required attribute: Height"); dict = NULL; /* Setup new page */ { gs_memory_t *mem = ctx->memory; gs_state *pgs = ctx->pgs; gx_device *dev = gs_currentdevice(pgs); gs_param_float_array fa; float fv[2]; gs_c_param_list list; gs_c_param_list_write(&list, mem); fv[0] = atoi(width_att) / 96.0 * 72.0; fv[1] = atoi(height_att) / 96.0 * 72.0; fa.persistent = false; fa.data = fv; fa.size = 2; code = param_write_float_array((gs_param_list *)&list, ".MediaSize", &fa); if ( code >= 0 ) { gs_c_param_list_read(&list); code = gs_putdeviceparams(dev, (gs_param_list *)&list); } gs_c_param_list_release(&list); /* nb this is for the demo it is wrong and should be removed */ gs_initgraphics(pgs); /* 96 dpi default - and put the origin at the top of the page */ gs_initmatrix(pgs); code = gs_scale(pgs, 72.0/96.0, -72.0/96.0); if (code < 0) return gs_rethrow(code, "cannot set page transform"); code = gs_translate(pgs, 0.0, -atoi(height_att)); if (code < 0) return gs_rethrow(code, "cannot set page transform"); code = gs_erasepage(pgs); if (code < 0) return gs_rethrow(code, "cannot clear page"); } /* Pre-parse looking for transparency */ ctx->has_transparency = 0; for (node = xps_down(root); node; node = xps_next(node)) { if (!strcmp(xps_tag(node), "FixedPage.Resources") && xps_down(node)) if (xps_resource_dictionary_has_transparency(ctx, base_uri, xps_down(node))) ctx->has_transparency = 1; if (xps_element_has_transparency(ctx, base_uri, node)) ctx->has_transparency = 1; } /* save the state with the original device before we push */ gs_gsave(ctx->pgs); if (ctx->use_transparency && ctx->has_transparency) { code = gs_push_pdf14trans_device(ctx->pgs, false); if (code < 0) { gs_grestore(ctx->pgs); return gs_rethrow(code, "cannot install transparency device"); } } /* Draw contents */ for (node = xps_down(root); node; node = xps_next(node)) { if (!strcmp(xps_tag(node), "FixedPage.Resources") && xps_down(node)) { code = xps_parse_resource_dictionary(ctx, &dict, base_uri, xps_down(node)); if (code) { gs_pop_pdf14trans_device(ctx->pgs, false); gs_grestore(ctx->pgs); return gs_rethrow(code, "cannot load FixedPage.Resources"); } } code = xps_parse_element(ctx, base_uri, dict, node); if (code) { gs_pop_pdf14trans_device(ctx->pgs, false); gs_grestore(ctx->pgs); return gs_rethrow(code, "cannot parse child of FixedPage"); } } if (ctx->use_transparency && ctx->has_transparency) { code = gs_pop_pdf14trans_device(ctx->pgs, false); if (code < 0) { gs_grestore(ctx->pgs); return gs_rethrow(code, "cannot uninstall transparency device"); } } /* Flush page */ { code = xps_show_page(ctx, 1, true); /* copies, flush */ if (code < 0) { gs_grestore(ctx->pgs); return gs_rethrow(code, "cannot flush page"); } } /* restore the original device, discarding the pdf14 compositor */ gs_grestore(ctx->pgs); if (dict) { xps_free_resource_dictionary(ctx, dict); } xps_free_item(ctx, root); return 0; }