/* * Allocate a path on the heap, and initialize it. If shared is NULL, * allocate a segments object; if shared is an existing path, share its * segments. */ gx_path * gx_path_alloc_shared(const gx_path * shared, gs_memory_t * mem, client_name_t cname) { gx_path *ppath = gs_alloc_struct(mem, gx_path, &st_path, cname); if (ppath == 0) return 0; ppath->procs = &default_path_procs; if (shared) { if (shared->segments == &shared->local_segments) { lprintf1("Attempt to share (local) segments of path 0x%lx!\n", (ulong) shared); gs_free_object(mem, ppath, cname); return 0; } *ppath = *shared; rc_increment(ppath->segments); } else { int code = path_alloc_segments(&ppath->segments, mem, cname); if (code < 0) { gs_free_object(mem, ppath, cname); return 0; } gx_path_init_contents(ppath); } ppath->memory = mem; ppath->allocation = path_allocated_on_heap; return ppath; }
/* See gdevpdfx.h for why this is needed. */ const char * pprintg1(stream * s, const char *format, floatp v) { const char *fp = pprintf_scan(s, format); char dot, str[150]; #ifdef DEBUG if (*fp == 0 || fp[1] != 'g') /* shouldn't happen! */ lprintf1("Bad format in pprintg: %s\n", format); #endif sprintf(str, "%f", 1.5); dot = str[1]; /* locale-dependent */ sprintf(str, "%g", v); if (strchr(str, 'e')) { /* Bad news. Try again using f-format. */ sprintf(str, (fabs(v) > 1 ? "%1.1f" : "%1.8f"), v); } /* Juggling locales isn't thread-safe. Posix me harder. */ if (dot != '.') { char *pdot = strchr(str, dot); if (pdot) *pdot = '.'; } pputs_short(s, str); return pprintf_scan(s, fp + 2); }
static int test4(gs_state * pgs, gs_memory_t * mem) { gs_c_param_list list; float resv[2]; gs_param_float_array ares; int code; gx_device *dev = gs_currentdevice(pgs); gs_c_param_list_write(&list, mem); resv[0] = resv[1] = 100; ares.data = resv; ares.size = 2; ares.persistent = true; code = param_write_float_array((gs_param_list *) & list, "HWResolution", &ares); if (code < 0) { lprintf1("Writing HWResolution failed: %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) { lprintf1("Setting HWResolution failed: %d\n", code); gs_abort(mem); } gs_initmatrix(pgs); gs_initclip(pgs); if (code == 1) { code = (*dev_proc(dev, open_device)) (dev); if (code < 0) { lprintf1("Reopening device failed: %d\n", code); gs_abort(mem); } } gs_moveto(pgs, 0.0, 72.0); gs_rlineto(pgs, 72.0, 0.0); gs_rlineto(pgs, 0.0, 72.0); gs_closepath(pgs); gs_stroke(pgs); return 0; }
/* Print (a) string(s) using a format. */ const char * pprints1(stream * s, const char *format, const char *str) { const char *fp = pprintf_scan(s, format); #ifdef DEBUG if (*fp == 0 || fp[1] != 's') /* shouldn't happen! */ lprintf1("Bad format in pprints: %s\n", format); #endif pputs_short(s, str); return pprintf_scan(s, fp + 2); }
/* Print (an) int value(s) using a format. */ const char * pprintd1(stream * s, const char *format, int v) { const char *fp = pprintf_scan(s, format); char str[25]; #ifdef DEBUG if (*fp == 0 || fp[1] != 'd') /* shouldn't happen! */ lprintf1("Bad format in pprintd1: %s\n", format); #endif sprintf(str, "%d", v); pputs_short(s, str); return pprintf_scan(s, fp + 2); }
static void jpeg_free(j_common_ptr cinfo, void *data, const char *info) { jpeg_compress_data *jcd = cinfo2jcd(cinfo); gs_memory_t *mem = jcd->memory; jpeg_block_t *p = jcd->blocks; jpeg_block_t **pp = &jcd->blocks; gs_free_object(mem, data, info); while(p && p->data != data) { pp = &p->next; p = p->next; } if(p == 0) lprintf1("Freeing unrecorded JPEG data 0x%lx!\n", (ulong)data); else *pp = p->next; gs_free_object(mem, p, "jpeg_free(block)"); }
/* 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); } }
/* * Initialize a stack-allocated path. This doesn't allocate anything, * but may still share the segments. */ int gx_path_init_local_shared(gx_path * ppath, const gx_path * shared, gs_memory_t * mem) { if (shared) { if (shared->segments == &shared->local_segments) { lprintf1("Attempt to share (local) segments of path 0x%lx!\n", (ulong) shared); return_error(gs_error_Fatal); } *ppath = *shared; rc_increment(ppath->segments); } else { rc_init_free(&ppath->local_segments, mem, 1, rc_free_path_segments_local); ppath->segments = &ppath->local_segments; gx_path_init_contents(ppath); } ppath->memory = mem; ppath->allocation = path_allocated_on_stack; ppath->procs = &default_path_procs; return 0; }
int gx_path_init_contained_shared(gx_path * ppath, const gx_path * shared, gs_memory_t * mem, client_name_t cname) { if (shared) { if (shared->segments == &shared->local_segments) { lprintf1("Attempt to share (local) segments of path 0x%lx!\n", (ulong) shared); return_error(gs_error_Fatal); } *ppath = *shared; rc_increment(ppath->segments); } else { int code = path_alloc_segments(&ppath->segments, mem, cname); if (code < 0) return code; gx_path_init_contents(ppath); } ppath->memory = mem; ppath->allocation = path_allocated_contained; ppath->procs = &default_path_procs; return 0; }
void s_zlib_free(void *zmem, void *data) { zlib_dynamic_state_t *const zds = zmem; gs_memory_t *mem = zds->memory->stable_memory; zlib_block_t *block = zds->blocks; gs_free_object(mem, data, "s_zlib_free(data)"); for (; ; block = block->next) { if (block == 0) { lprintf1("Freeing unrecorded data 0x%lx!\n", (ulong)data); return; } if (block->data == data) break; } if (block->next) block->next->prev = block->prev; if (block->prev) block->prev->next = block->next; else zds->blocks = block->next; gs_free_object(mem, block, "s_zlib_free(block)"); }
/* Initialize the operator table. */ int op_init(i_ctx_t *i_ctx_p) { const op_def *const *tptr; int code; /* Enter each operator into the appropriate dictionary. */ for (tptr = op_defs_all; *tptr != 0; tptr++) { ref *pdict = systemdict; const op_def *def; const char *nstr; for (def = *tptr; (nstr = def->oname) != 0; def++) if (op_def_is_begin_dict(def)) { ref nref; code = name_ref(imemory, (const byte *)nstr, strlen(nstr), &nref, -1); if (code < 0) return code; if (!dict_find(systemdict, &nref, &pdict)) return_error(e_Fatal); if (!r_has_type(pdict, t_dictionary)) return_error(e_Fatal); } else { ref oper; uint index_in_table = def - *tptr; uint opidx = (tptr - op_defs_all) * OP_DEFS_MAX_SIZE + index_in_table; if (index_in_table >= OP_DEFS_MAX_SIZE) { lprintf1("opdef overrun! %s\n", def->oname); return_error(e_Fatal); } gs_interp_make_oper(&oper, def->proc, opidx); /* The first character of the name is a digit */ /* giving the minimum acceptable number of operands. */ /* Check to make sure it's within bounds. */ if (*nstr - '0' > gs_interp_max_op_num_args) return_error(e_Fatal); nstr++; /* * Skip internal operators, and the second occurrence of * operators with special indices. */ if (*nstr != '%' && r_size(&oper) == opidx) { code = i_initial_enter_name_in(i_ctx_p, pdict, nstr, &oper); if (code < 0) return code; } } } /* Allocate the tables for `operator' procedures. */ /* Make one of them local so we can have local operators. */ if ((code = alloc_op_array_table(i_ctx_p, OP_ARRAY_TABLE_GLOBAL_SIZE, avm_global, &op_array_table_global) < 0)) return code; op_array_table_global.base_index = op_def_count; if ((code = gs_register_ref_root(imemory, NULL, (void **)&op_array_table_global.root_p, "op_array_table(global)")) < 0 || (code = gs_register_struct_root(imemory, NULL, (void **)&op_array_table_global.nx_table, "op_array nx_table(global)")) < 0 || (code = alloc_op_array_table(i_ctx_p, OP_ARRAY_TABLE_LOCAL_SIZE, avm_local, &op_array_table_local) < 0) ) return code; op_array_table_local.base_index = op_array_table_global.base_index + r_size(&op_array_table_global.table); if ((code = gs_register_ref_root(imemory, NULL, (void **)&op_array_table_local.root_p, "op_array_table(local)")) < 0 || (code = gs_register_struct_root(imemory, NULL, (void **)&op_array_table_local.nx_table, "op_array nx_table(local)")) < 0 ) return code; return 0; }
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 }
/* Remove an element from a dictionary. */ int dict_undef(ref * pdref, const ref * pkey, dict_stack_t *pds) { gs_ref_memory_t *mem; ref *pvslot; dict *pdict; uint index; int code = dict_find(pdref, pkey, &pvslot); switch (code) { case 0: case gs_error_dictfull: return_error(gs_error_undefined); case 1: break; default: /* other error */ return code; } /* Remove the entry from the dictionary. */ pdict = pdref->value.pdict; index = pvslot - pdict->values.value.refs; mem = dict_memory(pdict); if (dict_is_packed(pdict)) { ref_packed *pkp = pdict->keys.value.writable_packed + index; bool must_save = ref_must_save_in(mem, &pdict->keys); if_debug3m('d', (const gs_memory_t *)mem, "[d]0x%lx: removing key at 0%lx: 0x%x\n", (ulong)pdict, (ulong)pkp, (uint)*pkp); /* See the initial comment for why it is safe not to save */ /* the change if the keys array itself is new. */ if (must_save) ref_do_save_in(mem, &pdict->keys, pkp, "dict_undef(key)"); /* * Accumulating deleted entries slows down lookup. * Detect the easy case where we can use an empty entry * rather than a deleted one, namely, when the next entry * in the probe order is empty. */ if (pkp[-1] == packed_key_empty) { /* * In this case we can replace any preceding deleted keys with * empty ones as well. */ uint end = nslots(pdict); *pkp = packed_key_empty; if (must_save) { while (++index < end && *++pkp == packed_key_deleted) { ref_do_save_in(mem, &pdict->keys, pkp, "dict_undef(key)"); *pkp = packed_key_empty; } } else { while (++index < end && *++pkp == packed_key_deleted) *pkp = packed_key_empty; } } else *pkp = packed_key_deleted; } else { /* not packed */ ref *kp = pdict->keys.value.refs + index; if_debug4m('d', (const gs_memory_t *)mem, "[d]0x%lx: removing key at 0%lx: 0x%lx 0x%lx\n", (ulong)pdict, (ulong)kp, ((ulong *)kp)[0], ((ulong *)kp)[1]); make_null_old_in(mem, &pdict->keys, kp, "dict_undef(key)"); /* * Accumulating deleted entries slows down lookup. * Detect the easy case where we can use an empty entry * rather than a deleted one, namely, when the next entry * in the probe order is empty. */ if (!r_has_type(kp - 1, t_null) || /* full entry */ r_has_attr(kp - 1, a_executable) /* deleted or wraparound */ ) r_set_attrs(kp, a_executable); /* mark as deleted */ } ref_save_in(mem, pdref, &pdict->count, "dict_undef(count)"); pdict->count.value.intval--; /* If the key is a name, update its 1-element cache. */ if (r_has_type(pkey, t_name)) { name *pname = pkey->value.pname; if (pv_valid(pname->pvalue)) { #ifdef DEBUG /* Check the the cache is correct. */ if (!(pds && dstack_dict_is_permanent(pds, pdref))) lprintf1("dict_undef: cached name value pointer 0x%lx is incorrect!\n", (ulong) pname->pvalue); #endif /* Clear the cache */ pname->pvalue = pv_no_defn; } } make_null_old_in(mem, &pdict->values, pvslot, "dict_undef(value)"); return 0; }