static void xps_debug_item_imp(xps_item_t *item, int level, int loop) { int i; while (item) { indent(level); if (strlen(item->name) == 0) dlprintf1("%s\n", item->atts[1]); else { dlprintf1("<%s", item->name); for (i = 0; item->atts[i]; i += 2) dlprintf2(" %s=\"%s\"", item->atts[i], item->atts[i+1]); if (item->down) { dlprintf(">\n"); xps_debug_item_imp(item->down, level + 1, 1); indent(level); dlprintf1("</%s>\n", item->name); } else dlprintf(" />\n"); } item = item->next; if (!loop) return; } }
/* get the cache directory's path */ static char *gp_cache_prefix(void) { char *prefix = NULL; int plen = 0; /* get the cache directory path */ if (gp_getenv("GS_CACHE_DIR", (char *)NULL, &plen) < 0) { prefix = malloc(plen); gp_getenv("GS_CACHE_DIR", prefix, &plen); plen--; } else { #ifdef GS_CACHE_DIR prefix = strdup(GS_CACHE_DIR); #else prefix = strdup(".cache"); #endif plen = strlen(prefix); } /* substitute $HOME for '~' */ if (plen >= 1 && prefix[0] == '~') { char *home, *path; int hlen = 0; unsigned int pathlen = 0; gp_file_name_combine_result result; if (gp_getenv("HOME", (char *)NULL, &hlen) < 0) { home = malloc(hlen); if (home == NULL) return prefix; gp_getenv("HOME", home, &hlen); hlen--; if (plen == 1) { /* only "~" */ free(prefix); return home; } /* substitue for the initial '~' */ pathlen = hlen + plen + 1; path = malloc(pathlen); if (path == NULL) { free(home); return prefix; } result = gp_file_name_combine(home, hlen, prefix+2, plen-2, false, path, &pathlen); if (result == gp_combine_success) { free(prefix); prefix = path; } else { dlprintf1("file_name_combine failed with code %d\n", result); } free(home); } } #ifdef DEBUG_CACHE dlprintf1("cache dir read as '%s'\n", prefix); #endif return prefix; }
/* compute the cache index file's path */ static char * gp_cache_indexfilename(const char *prefix) { const char *fn = "gs_cache"; char *path; unsigned int len; gp_file_name_combine_result result; len = strlen(prefix) + strlen(fn) + 2; path = malloc(len); result = gp_file_name_combine(prefix, strlen(prefix), fn, strlen(fn), true, path, &len); if (result == gp_combine_small_buffer) { /* handle the case when the combination requires more than one extra character */ free(path); path = malloc(++len); result = gp_file_name_combine(prefix, strlen(prefix), fn, strlen(fn), true, path, &len); } if (result != gp_combine_success) { dlprintf1("pcache: file_name_combine for indexfilename failed with code %d\n", result); free(path); return NULL; } return path; }
/* * Install a DeviceRGB color space. */ static bool client_install_DeviceRGB(client_custom_color_params_t * pparams, gs_color_space * pcs, gs_state * pgs) { /* Nothing to do in our demo */ dlprintf1("client_install_DeviceRGB ri = %d\n", pgs->renderingintent); return true; }
int gs_rotate(gs_state * pgs, floatp ang) { int code = gs_matrix_rotate(&ctm_only(pgs), ang, &ctm_only_writable(pgs)); pgs->ctm_inverse_valid = false, pgs->char_tm_valid = false; #ifdef DEBUG if (gs_debug_c('x')) dlprintf1("[x]rotate: %f\n", ang), trace_ctm(pgs); #endif return code; }
/* Unmarking routine for ref objects. */ static void refs_clear_marks(const gs_memory_t *cmem, void /*obj_header_t */ *vptr, uint size, const gs_memory_struct_type_t * pstype) { ref_packed *rp = (ref_packed *) vptr; ref_packed *end = (ref_packed *) ((byte *) vptr + size); /* Since the last ref is full-size, we only need to check for */ /* the end of the block when we see one of those. */ for (;;) { if (r_is_packed(rp)) { #ifdef DEBUG if (gs_debug_c('8')) { dlprintf1(" [8]unmark packed 0x%lx ", (ulong) rp); debug_print_ref(cmem, (const ref *)rp); dputs("\n"); } #endif r_clear_pmark(rp); rp++; } else { /* full-size ref */ ref *const pref = (ref *)rp; #ifdef DEBUG if (gs_debug_c('8')) { dlprintf1(" [8]unmark ref 0x%lx ", (ulong) rp); debug_print_ref(cmem, pref); dputs("\n"); } #endif r_clear_attrs(pref, l_mark); rp += packed_per_ref; if (rp >= (ref_packed *) end) break; } } }
/* generate an access path for a cache item */ static char *gp_cache_itempath(const char *prefix, gp_cache_entry *item) { const char *fn = item->filename; gp_file_name_combine_result result; char *path; unsigned int len; len = strlen(prefix) + strlen(fn) + 2; path = malloc(len); result = gp_file_name_combine(prefix, strlen(prefix), fn, strlen(fn), false, path, &len); if (result != gp_combine_success) { dlprintf1("pcache: file_name_combine failed on cache item filename with code %d\n", result); } return path; }
int gs_setblendmode(gs_state *pgs, gs_blend_mode_t mode) { #ifdef DEBUG if (gs_debug_c('v')) { static const char *const bm_names[] = { GS_BLEND_MODE_NAMES }; dlprintf1("[v](0x%lx)blend_mode = ", (ulong)pgs); if (mode >= 0 && mode < countof(bm_names)) dprintf1("%s\n", bm_names[mode]); else dprintf1("%d??\n", (int)mode); } #endif if (mode < 0 || mode > MAX_BLEND_MODE) return_error(gs_error_rangecheck); pgs->blend_mode = mode; return 0; }
int gs_setblendmode(gs_state *pgs, gs_blend_mode_t mode) { #ifdef DEBUG if (gs_debug_c('v')) { static const char *const bm_names[] = { GS_BLEND_MODE_NAMES }; dlprintf1("[v](0x%lx)blend_mode = ", (ulong)pgs); if (mode >= 0 && mode < countof(bm_names)) dprintf1("%s\n", bm_names[mode]); else dprintf1("%d??\n", (int)mode); } #endif /* Map Compatible to Normal so other code treats Compatible as Normal */ /* Often BLEND_MODE_Normal is checked for optimized handling, and */ /* Compatible is now specified to be the same. */ if (mode == BLEND_MODE_Compatible) mode = BLEND_MODE_Normal; if (mode < 0 || mode > MAX_BLEND_MODE) return_error(gs_error_rangecheck); pgs->blend_mode = mode; return 0; }
int gp_cache_query(int type, byte* key, int keylen, void **buffer, gp_cache_alloc alloc, void *userdata) { char *prefix, *path; char *infn,*outfn; FILE *file, *in, *out; gp_cache_entry item, item2; int code, hit = 0; /* FIXME: not re-entrant! */ prefix = gp_cache_prefix(); infn = gp_cache_indexfilename(prefix); { int len = strlen(infn) + 2; outfn = malloc(len); memcpy(outfn, infn, len - 2); outfn[len-2] = '+'; outfn[len-1] = '\0'; } in = fopen(infn, "r"); if (in == NULL) { dlprintf1("pcache: unable to open '%s'\n", infn); free(prefix); free(infn); free(outfn); return -1; } out = fopen(outfn, "w"); if (out == NULL) { dlprintf1("pcache: unable to open '%s'\n", outfn); fclose(in); free(prefix); free(infn); free(outfn); return -1; } fprintf(out, "# Ghostscript persistent cache index table\n"); /* construct our query */ gp_cache_clear_entry(&item); item.type = type; item.key = key; item.keylen = keylen; item.last_used = time(NULL); gp_cache_hash(&item); gp_cache_filename(prefix, &item); /* look for it on the disk */ path = gp_cache_itempath(prefix, &item); file = fopen(path, "rb"); if (file != NULL) { hit = gp_cache_loaditem(file, &item, alloc, userdata); fclose(file); } else { hit = -1; } gp_cache_clear_entry(&item2); while ((code = gp_cache_read_entry(in, &item2)) >= 0) { if (code == 1) continue; if (!hit && !memcmp(item.hash, item2.hash, 16)) { /* replace the matching line */ gp_cache_write_entry(out, &item); item.dirty = 0; } else { /* copy out the previous line */ gp_cache_write_entry(out, &item2); } } if (item.dirty) { /* there was no matching line -- shouldn't happen */ gp_cache_write_entry(out, &item); } free(item.filename); fclose(out); fclose(in); /* replace the cache index with our new version */ unlink(infn); rename(outfn,infn); free(prefix); free(infn); free(outfn); if (!hit) { *buffer = item.buffer; return item.len; } else { *buffer = NULL; return -1; } }
/* insert a buffer under a (type, key) pair */ int gp_cache_insert(int type, byte *key, int keylen, void *buffer, int buflen) { char *prefix, *path; char *infn,*outfn; FILE *file, *in, *out; gp_cache_entry item, item2; int code, hit = 0; /* FIXME: not re-entrant! */ prefix = gp_cache_prefix(); infn = gp_cache_indexfilename(prefix); { int len = strlen(infn) + 2; outfn = malloc(len); memcpy(outfn, infn, len - 2); outfn[len-2] = '+'; outfn[len-1] = '\0'; } in = fopen(infn, "r"); if (in == NULL) { dlprintf1("pcache: unable to open '%s'\n", infn); free(prefix); free(infn); free(outfn); return -1; } out = fopen(outfn, "w"); if (out == NULL) { dlprintf1("pcache: unable to open '%s'\n", outfn); fclose(in); free(prefix); free(infn); free(outfn); return -1; } fprintf(out, "# Ghostscript persistent cache index table\n"); /* construct our cache item */ gp_cache_clear_entry(&item); item.type = type; item.key = key; item.keylen = keylen; item.buffer = buffer; item.len = buflen; item.dirty = 1; item.last_used = time(NULL); gp_cache_hash(&item); gp_cache_filename(prefix, &item); /* save it to disk */ path = gp_cache_itempath(prefix, &item); file = fopen(path, "wb"); if (file != NULL) { gp_cache_saveitem(file, &item); fclose(file); } /* now loop through the index to update or insert the entry */ gp_cache_clear_entry(&item2); while ((code = gp_cache_read_entry(in, &item2)) >= 0) { if (code == 1) continue; if (!memcmp(item.hash, item2.hash, 16)) { /* replace the matching line */ gp_cache_write_entry(out, &item); hit = 1; } else { /* copy out the previous line */ gp_cache_write_entry(out, &item2); } } if (!hit) { /* there was no matching line */ gp_cache_write_entry(out, &item); } free(item.filename); fclose(out); fclose(in); /* replace the cache index with our new version */ unlink(infn); rename(outfn,infn); free(prefix); free(infn); free(outfn); return 0; }
int gp_enumerate_fonts_next(void *enum_state, char **fontname, char **path) { #ifdef HAVE_FONTCONFIG unix_fontenum_t* state = (unix_fontenum_t *)enum_state; FcChar8 *file_fc = NULL; FcChar8 *family_fc = NULL; int outline_fc, slant_fc, weight_fc; FcPattern *font; FcResult result; if (state == NULL) { return 0; /* gp_enumerate_fonts_init failed for some reason */ } if (state->index == state->font_list->nfont) { return 0; /* we've run out of fonts */ } /* Bits of the following were borrowed from Red Hat's * fontconfig patch for Ghostscript 7 */ font = state->font_list->fonts[state->index]; result = FcPatternGetString (font, FC_FAMILY, 0, &family_fc); if (result != FcResultMatch || family_fc == NULL) { dlprintf ("DEBUG: FC_FAMILY mismatch\n"); return 0; } result = FcPatternGetString (font, FC_FILE, 0, &file_fc); if (result != FcResultMatch || file_fc == NULL) { dlprintf ("DEBUG: FC_FILE mismatch\n"); return 0; } result = FcPatternGetBool (font, FC_OUTLINE, 0, &outline_fc); if (result != FcResultMatch) { dlprintf1 ("DEBUG: FC_OUTLINE failed to match on %s\n", (char*)family_fc); return 0; } result = FcPatternGetInteger (font, FC_SLANT, 0, &slant_fc); if (result != FcResultMatch) { dlprintf ("DEBUG: FC_SLANT didn't match\n"); return 0; } result = FcPatternGetInteger (font, FC_WEIGHT, 0, &weight_fc); if (result != FcResultMatch) { dlprintf ("DEBUG: FC_WEIGHT didn't match\n"); return 0; } /* Gross hack to work around Fontconfig's inability to tell * us the font's PostScript name - generate it ourselves. * We must free the memory allocated here next time around. */ makePSFontName((char *)family_fc, weight_fc, slant_fc, (char *)&state->name, sizeof(state->name)); *fontname = (char *)&state->name; /* return the font path straight out of fontconfig */ *path = (char*)file_fc; state->index ++; return 1; #else return 0; #endif }