void sp_layer(DviContext *dvi, const char *prefix, const char *arg) { if(STREQ("push", arg)) dvi->curr_layer++; else if(STREQ("pop", arg)) { if(dvi->curr_layer) dvi->curr_layer--; else mdvi_warning(_("%s: tried to pop top level layer\n"), dvi->filename); } else if(STREQ("reset", arg)) dvi->curr_layer = 0; DEBUG((DBG_SPECIAL, "Layer level: %d\n", dvi->curr_layer)); }
void font_finish_definitions(DviContext *dvi) { int count; DviFontRef **map, *ref; /* first get rid of unused fonts */ font_free_unused(&dvi->device); if(dvi->fonts == NULL) { mdvi_warning(_("%s: no fonts defined\n"), dvi->filename); return; } map = xnalloc(DviFontRef *, dvi->nfonts); for(count = 0, ref = dvi->fonts; ref; ref = ref->next) map[count++] = ref; /* sort the array by font id */ qsort(map, dvi->nfonts, sizeof(DviFontRef *), compare_refs); dvi->fontmap = map; }
/* Note: the given strings are modified in place */ static char *parse_epsf_special(EpsfBox *box, char **ret, char *prefix, char *arg) { static struct { char *name; int has_arg; char *value; } keys[] = { {"llx", 1, "0"}, {"lly", 1, "0"}, {"urx", 1, "0"}, {"ury", 1, "0"}, {"rwi", 1, "0"}, {"rhi", 1, "0"}, {"hoffset", 1, "0"}, {"voffset", 1, "0"}, {"hsize", 1, "612"}, {"vsize", 1, "792"}, {"hscale", 1, "100"}, {"vscale", 1, "100"}, {"angle", 1, "0"}, {"clip", 0, "0"} }; #define NKEYS (sizeof(keys) / sizeof(keys[0])) char *ptr; char *filename; double value[NKEYS]; Uchar present[NKEYS]; Buffer buffer; char *name; int i; double originx; double originy; double hsize; double vsize; double hscale; double vscale; /* this special has the form * ["]file.ps["] [key=valye]* */ /* scan the filename */ while(*arg == ' ' || *arg == '\t') arg++; /* make a copy of the string */ ptr = arg; if(*ptr == '"') for(name = ++ptr; *ptr && *ptr != '"'; ptr++); else for(name = ptr; *ptr && *ptr != ' ' && *ptr != '\t'; ptr++); if(ptr == name) return NULL; *ptr++ = 0; filename = name; /* reset values to defaults */ for(i = 0; i < NKEYS; i++) { value[i] = atof(keys[i].value); present[i] = 0; } buff_init(&buffer); buff_add(&buffer, "@beginspecial ", 0); while(*ptr) { const char *keyname; char *val; char *p; while(*ptr == ' ' || *ptr == '\t') ptr++; keyname = ptr; /* get the whole key=value pair */ for(; *ptr && *ptr != ' ' && *ptr != '\t'; ptr++); if(*ptr) *ptr++ = 0; /* now we shouldn't touch `ptr' anymore */ /* now work on this pair */ p = strchr(keyname, '='); if(p == NULL) val = NULL; else { *p++ = 0; if(*p == '"') { val = ++p; /* skip until closing quote */ while(*p && *p != '"') p++; if(*p != '"') mdvi_warning( _("%s: malformed value for key `%s'\n"), filename, keyname); } else val = p; } /* lookup the key */ for(i = 0; i < NKEYS; i++) if(STRCEQ(keys[i].name, keyname)) break; if(i == NKEYS) { mdvi_warning(_("%s: unknown key `%s' ignored\n"), filename, keyname); continue; } if(keys[i].has_arg && val == NULL) { mdvi_warning(_("%s: no argument for key `%s', using defaults\n"), filename, keyname); val = keys[i].value; } else if(!keys[i].has_arg && val) { mdvi_warning(_("%s: argument `%s' ignored for key `%s'\n"), filename, val, keyname); val = NULL; } if(val) value[i] = atof(val); /* put the argument */ buff_add(&buffer, val, 0); buff_add(&buffer, " @", 2); buff_add(&buffer, keyname, 0); buff_add(&buffer, " ", 1); /* remember that this option was given */ present[i] = 0xff; } buff_add(&buffer, " @setspecial", 0); /* now compute the bounding box (code comes from dvips) */ originx = 0; originy = 0; hscale = 1; vscale = 1; hsize = 0; vsize = 0; if(present[HSIZE]) hsize = value[HSIZE]; if(present[VSIZE]) vsize = value[VSIZE]; if(present[HOFF]) originx = value[HOFF]; if(present[VOFF]) originy = value[VOFF]; if(present[HSCALE]) hscale = value[HSCALE] / 100.0; if(present[VSCALE]) vscale = value[VSCALE] / 100.0; if(present[URX] && present[LLX]) hsize = value[URX] - value[LLX]; if(present[URY] && present[LLY]) vsize = value[URY] - value[LLY]; if(present[RWI] || present[RHI]) { if(present[RWI] && !present[RHI]) hscale = vscale = value[RWI] / (10.0 * hsize); else if(present[RHI] && !present[RWI]) hscale = vscale = value[RHI] / (10.0 * vsize); else { hscale = value[RWI] / (10.0 * hsize); vscale = value[RHI] / (10.0 * vsize); } } box->ox = originx; box->oy = originy; box->bw = hsize * hscale; box->bh = vsize * vscale; box->angle = value[ANGLE]; *ret = buffer.data; return filename; }
static int gf_load_font(DviParams *unused, DviFont *font) { int i; int n; int loc; int hic; FILE *p; Int32 word; int op; long alpha, beta, z; #ifndef NODEBUG char s[256]; #endif p = font->in; /* check preamble */ loc = fuget1(p); hic = fuget1(p); if(loc != GF_PRE || hic != GF_ID) goto badgf; loc = fuget1(p); #ifndef NODEBUG for(i = 0; i < loc; i++) s[i] = fuget1(p); s[i] = 0; DEBUG((DBG_FONTS, "(gf) %s: %s\n", font->fontname, s)); #else fseek(p, (long)loc, SEEK_CUR); #endif /* now read character locators in postamble */ if(fseek(p, (long)-1, SEEK_END) == -1) return -1; n = 0; while((op = fuget1(p)) == GF_TRAILER) { if(fseek(p, (long)-2, SEEK_CUR) < 0) break; n++; } if(op != GF_ID || n < 4) goto badgf; /* get the pointer to the postamble */ fseek(p, (long)-5, SEEK_CUR); op = fuget4(p); /* jump to it */ fseek(p, (long)op, SEEK_SET); if(fuget1(p) != GF_POST) goto badgf; /* skip pointer to last EOC */ fuget4(p); /* get the design size */ font->design = fuget4(p); /* the checksum */ word = fuget4(p); if(word && font->checksum && font->checksum != word) { mdvi_warning(_("%s: bad checksum (expected %u, found %u)\n"), font->fontname, font->checksum, word); } else if(!font->checksum) font->checksum = word; /* skip pixels per point ratio */ fuget4(p); fuget4(p); font->chars = xnalloc(DviFontChar, 256); for(loc = 0; loc < 256; loc++) font->chars[loc].offset = 0; /* skip glyph "bounding box" */ fseek(p, (long)16, SEEK_CUR); loc = 256; hic = -1; TFMPREPARE(font->scale, z, alpha, beta); while((op = fuget1(p)) != GF_POST_POST) { DviFontChar *ch; int cc; /* get the character code */ cc = fuget1(p); if(cc < loc) loc = cc; if(cc > hic) hic = cc; ch = &font->chars[cc]; switch(op) { case GF_LOC: fsget4(p); /* skip dx */ fsget4(p); /* skip dy */ break; case GF_LOC0: fuget1(p); /* skip dx */ /* dy assumed 0 */ break; default: mdvi_error(_("%s: junk in postamble\n"), font->fontname); goto error; } ch->code = cc; ch->tfmwidth = fuget4(p); ch->tfmwidth = TFMSCALE(ch->tfmwidth, z, alpha, beta); ch->offset = fuget4(p); if(ch->offset == -1) ch->offset = 0; /* initialize the rest of the glyph information */ ch->x = 0; ch->y = 0; ch->width = 0; ch->height = 0; ch->glyph.data = NULL; ch->shrunk.data = NULL; ch->grey.data = NULL; ch->flags = 0; ch->loaded = 0; } if(op != GF_POST_POST) goto badgf; if(loc > 0 || hic < 255) { /* shrink to optimal size */ memmove(font->chars, font->chars + loc, (hic - loc + 1) * sizeof(DviFontChar)); font->chars = xresize(font->chars, DviFontChar, hic - loc + 1); } font->loc = loc; font->hic = hic; return 0; badgf: mdvi_error(_("%s: File corrupted, or not a GF file\n"), font->fontname); error: if(font->chars) { mdvi_free(font->chars); font->chars = NULL; } font->loc = font->hic = 0; return -1; }