summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdfm/mpost.c
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-10-11 00:32:13 +0000
committerKarl Berry <karl@freefriends.org>2009-10-11 00:32:13 +0000
commit455471f21689b8342041bf228ec1c4da29d67e20 (patch)
treeb7ca3d33e9b39e135ff47e174d5d09d66392323d /Build/source/texk/dvipdfm/mpost.c
parent5742b8f40f9f495df32d4fd4f3c72767273c6ad2 (diff)
dvipdfmx man pages have been written, so remove dvipdfm source tree now
git-svn-id: svn://tug.org/texlive/trunk@15756 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/dvipdfm/mpost.c')
-rw-r--r--Build/source/texk/dvipdfm/mpost.c1369
1 files changed, 0 insertions, 1369 deletions
diff --git a/Build/source/texk/dvipdfm/mpost.c b/Build/source/texk/dvipdfm/mpost.c
deleted file mode 100644
index 9f8803e0272..00000000000
--- a/Build/source/texk/dvipdfm/mpost.c
+++ /dev/null
@@ -1,1369 +0,0 @@
-/* $Header: SCCS/s.mpost.c 1.1 00/08/05 01:52:14-00:00 mwicks@gaspra $
-
- This is dvipdfm, a DVI to PDF translator.
- Copyright (C) 1998, 1999 by Mark A. Wicks
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- The author may be contacted via the e-mail address
-
- mwicks@kettering.edu
-*/
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <math.h>
-#include <string.h>
-#include "system.h"
-#include "mem.h"
-#include "error.h"
-#include "mfileio.h"
-#include "dvi.h"
-#include "pdfobj.h"
-#include "pdfspecial.h"
-#include "pdfparse.h"
-#include "mpost.h"
-#include "pdfparse.h"
-#include "pdflimits.h"
-#include "pdfdev.h"
-#include "pdfdoc.h"
-
-int check_for_mp (FILE *image_file)
-{
- int i;
- int n = 0;
- rewind (image_file);
- /* For now, this is an exact test that must be passed, character for
- character */
- mfgets (work_buffer, WORK_BUFFER_SIZE, image_file);
- if (strncmp (work_buffer, "%!PS", 4))
- return 0;
- for(i=0; i < 10; i++) {
- mfgets (work_buffer, WORK_BUFFER_SIZE, image_file);
- if(strncmp(work_buffer, "%%Creator: MetaPost", strlen("%%Creator: MetaPost"))
- == 0)
- n++;
- }
- if(n == 0)
- return 0;
- return 1;
-}
-
-static struct mp_fonts
-{
- char *tex_name;
- int font_id;
- double pt_size;
-} *mp_fonts = NULL;
-
-int n_mp_fonts = 0, max_mp_fonts = 0;
-
-static void need_more_mp_fonts (unsigned n)
-{
- if (n_mp_fonts + n > max_mp_fonts) {
- max_mp_fonts += MAX_FONTS;
- mp_fonts = RENEW (mp_fonts, max_mp_fonts, struct mp_fonts);
- }
-}
-
-
-
-int mp_locate_font (char *tex_name, double pt_size)
-{
- int result=-1, i;
- for (i=0; i<n_mp_fonts; i++) {
- if (!strcmp (tex_name, mp_fonts[i].tex_name) &&
- mp_fonts[i].pt_size == pt_size)
- break;
- }
- need_more_mp_fonts (1);
- if (i == n_mp_fonts) {
- n_mp_fonts += 1;
- mp_fonts[i].tex_name = NEW (strlen(tex_name)+1, char);
- strcpy (mp_fonts[i].tex_name, tex_name);
- mp_fonts[i].pt_size = pt_size;
- /* The following line is a bit of a kludge. MetaPost inclusion
- was an afterthought */
- mp_fonts[i].font_id = dev_locate_font (tex_name,
- pt_size/dvi_unit_size());
- result = mp_fonts[i].font_id;
- } else
- result = -1;
- return result;
-}
-
-static void release_fonts (void)
-{
- int i;
- for (i=0; i<n_mp_fonts; i++) {
- RELEASE (mp_fonts[i].tex_name);
- }
- if (mp_fonts) {
- RELEASE (mp_fonts);
- mp_fonts = NULL;
- }
- n_mp_fonts = 0;
- max_mp_fonts = 0;
-}
-
-int mp_is_font_name (char *tex_name)
-{
- int i;
- for (i=0; i<n_mp_fonts; i++) {
- if (!strcmp (tex_name, mp_fonts[i].tex_name))
- break;
- }
- if (i < n_mp_fonts)
- return 1;
- else
- return 0;
-}
-
-int mp_fontid (char *tex_name, double pt_size)
-{
- int i;
- for (i=0; i<n_mp_fonts; i++) {
- if (!strcmp (tex_name, mp_fonts[i].tex_name) &&
- (mp_fonts[i].pt_size == pt_size))
- break;
- }
- if (i < n_mp_fonts) {
- return i;
- }
- else {
- return -1;
- }
-}
-
-static int mp_parse_headers (FILE *image_file, struct xform_info *p)
-{
- int error = 0;
- char *start, *end, *token, *name;
- char *llx = NULL, *lly = NULL, *urx = NULL, *ury = NULL;
- unsigned long save_position;
-#ifdef MEM_DEBUG
- MEM_START
-#endif
- /* Scan for bounding box record */
- for (;;) {
- mfgets (work_buffer, WORK_BUFFER_SIZE, image_file);
- if (work_buffer[0] != '%' ||
- !strncmp (work_buffer, "%%BoundingBox:",
- strlen("%%BoundingBox")))
- break;
- }
- if (work_buffer[0] == '%') { /* Found %%BoundingBox */
- start = work_buffer + strlen("%%BoundingBox:");
- end = start+strlen(start);
- skip_white (&start, end);
- /* Expect 4 numbers or fail */
- if ((llx = parse_number (&start, end)) &&
- (lly = parse_number (&start, end)) &&
- (urx = parse_number (&start, end)) &&
- (ury = parse_number (&start, end))) {
- /* Set the crop box to the true bounding box specified in the
- file */
- p->c_llx = atof (llx);
- p->c_lly = atof (lly);
- p->c_urx = atof (urx);
- p->c_ury = atof (ury);
- } else{
- fprintf (stderr, "\nMissing expected number in bounding box specification:\n");
- dump (start, end);
- error = 1;
- }
- } else { /* Didn't find Bounding box */
- fprintf (stderr, "\nFailed to find an expected BoundingBox record.\n");
- error = 1;
- }
- if (llx) RELEASE(llx);
- if (lly) RELEASE(lly);
- if (urx) RELEASE(urx);
- if (ury) RELEASE(ury);
- /* Got four numbers */
- /* Read all headers--act on *Font records */
- save_position = tell_position(image_file);
- while (!error && !feof(image_file) && mfgets (work_buffer, WORK_BUFFER_SIZE,
- image_file)) {
- if (*work_buffer != '%') {
- seek_absolute (image_file, save_position);
- break;
- }
- save_position = tell_position (image_file);
- if (*(work_buffer+1) == '*' &&
- !strncmp (work_buffer+2, "Font:", strlen("Font:"))) {
- double ps_ptsize;
- start = work_buffer+strlen("%*Font:");
- end = start+strlen(start);
- skip_white (&start, end);
- if ((name = parse_ident (&start, end))) {
- skip_white (&start, end);
- } else {
- fprintf (stderr, "\nMissing expected font name:\n");
- dump (start, end);
- error = 1;
- break;
- }
- if ((token = parse_number (&start, end))) {
- ps_ptsize = atof (token);
- RELEASE (token);
- } else {
- fprintf (stderr, "\nMissing expected font point size specification:\n");
- dump (start, end);
- error = 1;
- break;
- }
- mp_locate_font (name, ps_ptsize);
- RELEASE (name);
- }
- }
-#ifdef MEM_DEBUG
- MEM_END
-#endif
- return !error;
-}
-
-struct point {
- double x, y;
-};
-
-struct curve {
- double x[3], y[3];
-};
-
-static struct path_element
-{
- char type;
- void *element;
-} *path = NULL;
-static int n_path_pts = 0, max_path_pts = 0;
-static int path_clip = 0, path_close = 0;
-
-#define MORE_PATH_POINTS 64
-
-static void need_points (int n)
-{
- if (n_path_pts+n > max_path_pts) {
- max_path_pts += MORE_PATH_POINTS;
- path = RENEW (path, max_path_pts, struct path_element);
- }
- return;
-}
-
-static void clip_path (void)
-{
- path_clip = 1;
-}
-
-static void close_path (void)
-{
- path_close = 1;
-}
-
-static void add_point_to_path (double x, double y, char type)
-{
- struct point *p;
- need_points (1);
- path[n_path_pts].type = type;
- p = NEW (1, struct point);
- p->x = x; p->y = y;
- path[n_path_pts].element = p;
- n_path_pts += 1;
- return;
-}
-
-static void add_curve_to_path (double x0, double y0,
- double x1, double y1,
- double x2, double y2)
-{
- struct curve *c;
- need_points (1);
- c = NEW (1, struct curve);
- path[n_path_pts].type = 'c';
- (c->x)[0] = x0; (c->y)[0] = y0;
- (c->x)[1] = x1; (c->y)[1] = y1;
- (c->x)[2] = x2; (c->y)[2] = y2;
- path[n_path_pts].element = c;
- n_path_pts += 1;
- return;
-}
-
-static void void_path (void)
-{
- int i;
- for (i=0; i<n_path_pts; i++) {
- RELEASE (path[i].element);
- }
- path_clip = 0;
- path_close = 0;
- n_path_pts = 0;
-}
-
-static void flush_path (void)
-{
- int i, len;
- for (i=0; i<n_path_pts; i++) {
- switch (path[i].type) {
- case 'm': /* moveto */
- /* Moveto must start a new path */
- /* void_path (); */
- case 'l': /* lineto */
- {
- struct point *p;
- p = path[i].element;
- sprintf (work_buffer, "\n%g %g %c",
- ROUND(p->x, 0.001), ROUND(p->y, 0.001),
- path[i].type);
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- RELEASE (p);
- }
- break;
- case 'c': /* curveto */
- {
- struct curve *p;
- p = path[i].element;
- sprintf (work_buffer, "\n%g %g %g %g %g %g c",
- ROUND((p->x)[0], 0.001), ROUND((p->y)[0], 0.001),
- ROUND((p->x)[1], 0.001), ROUND((p->y)[1], 0.001),
- ROUND((p->x)[2], 0.001), ROUND((p->y)[2], 0.001));
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- RELEASE (p);
- }
- break;
- default: /* This shouldn't happen! */
- ERROR ("Internal error in mpost.c, flush_path ()");
- }
- }
- n_path_pts = 0;
- if (path_close) {
- pdf_doc_add_to_page (" h", 2);
- path_close = 0;
- }
- if (path_clip) {
- pdf_doc_add_to_page (" W", 2);
- path_clip = 0;
- }
- return;
-}
-
-static void transform_path (double a, double b, double c, double d,
- double e, double f)
-{
- double an, bn, cn, dn, en, fn, delta, xn, yn;
- unsigned i;
- delta = a*d-b*c;
- if (delta == 0.0) {
- ERROR ("Determinant exactly zero in transform_path()");
- }
- an=d/delta; bn=-b/delta; cn=-c/delta; dn=a/delta;
- en=(c*f-e*d)/delta, fn=(b*e-a*f)/delta;
- for (i=0; i<n_path_pts; i++) {
- switch (path[i].type) {
- case 'l':
- case 'm':
- {
- struct point *p;
- p = path[i].element;
- xn = an*(p->x)+cn*(p->y)+en;
- yn = bn*(p->x)+dn*(p->y)+fn;
- p->x = xn;
- p->y = yn;
- }
- break;
- case 'c':
- {
- int j;
- struct curve *c;
- c = path[i].element;
- for (j=0; j<3; j++) {
- xn = an*(c->x)[j]+cn*(c->y)[j]+en;
- yn = bn*(c->x)[j]+dn*(c->y)[j]+fn;
- (c->x)[j] = xn; (c->y)[j] = yn;
- }
- }
- }
- }
-}
-static void dump_path (void)
-{
- unsigned i;
- for (i=0; i<n_path_pts; i++) {
- switch (path[i].type) {
- case 'l':
- case 'm':
- {
- struct point *p;
- p = path[i].element;
- fprintf (stderr, "\t%g %g %c\n", p->x, p->y, path[i].type);
- }
- break;
- case 'c':
- {
- struct curve *c;
- int j;
- c = path[i].element;
- for (j=0; j<3; j++) {
- fprintf (stderr, "\t%g %g\n", (c->x)[j], (c->y)[j]);
- }
- fprintf (stderr, "\t\t\tcurveto\n");
- break;
- }
- }
- }
-}
-
-#define PS_STACK_SIZE 1024
-static pdf_obj *stack[PS_STACK_SIZE];
-static unsigned top_stack;
-
-double x_state, y_state;
-static int state = 0;
-static int num_saves = 0;
-
-#define PUSH(o) { \
- if (top_stack<PS_STACK_SIZE) { \
- stack[top_stack++] = o; \
- } else { \
- fprintf (stderr, "PS stack overflow including MetaPost file or inline PS code"); \
- error=1; \
- break; \
- } \
- }
-
-#define POP_STACK() (top_stack>0?stack[--top_stack]:NULL)
-
-void dump_stack()
-{
- int i;
- fprintf (stderr, "\ndump_stack\n");
- for (i=0; i<top_stack; i++) {
- pdf_write_obj (stderr, stack[i]);
- fprintf (stderr, "\n");
- }
-}
-#define ADD 1
-#define CLIP 2
-#define CLOSEPATH 3
-#define CONCAT 4
-#define CURVETO 5
-#define DIV 6
-#define DTRANSFORM 7
-#define EXCH 8
-#define FILL 9
-#define FSHOW 10
-#define GSAVE 11
-#define GRESTORE 12
-#define IDTRANSFORM 13
-#define LINETO 14
-#define MOVETO 15
-#define MUL 16
-#define NEWPATH 17
-#define POP 18
-#define RLINETO 19
-#define SCALE 20
-#define SETCMYKCOLOR 21
-#define SETDASH 22
-#define SETGRAY 23
-#define SETLINECAP 24
-#define SETLINEJOIN 25
-#define SETLINEWIDTH 26
-#define SETMITERLIMIT 27
-#define SETRGBCOLOR 28
-#define SHOW 29
-#define SHOWPAGE 30
-#define STROKE 31
-#define SUB 32
-#define TRANSLATE 33
-#define TRUNCATE 34
-#define CURRENTPOINT 35
-#define NEG 36
-#define ROTATE 37
-#define TEXFIG 38
-#define ETEXFIG 39
-#define FONTNAME 99
-
-struct operators
-{
- char *t;
- int v;
-} operators[] = {
- {"add", ADD},
- {"clip", CLIP},
- {"closepath", CLOSEPATH},
- {"concat", CONCAT},
- {"curveto", CURVETO},
- {"currentpoint", CURRENTPOINT}, /* This is here for rotate
- support in graphics package-not MP support */
- {"div", DIV},
- {"dtransform", DTRANSFORM},
- {"exch", EXCH},
- {"fill", FILL},
- {"fshow", FSHOW},
- {"gsave", GSAVE},
- {"grestore", GRESTORE},
- {"idtransform", IDTRANSFORM},
- {"lineto", LINETO},
- {"moveto", MOVETO},
- {"mul", MUL},
- {"neg", NEG},
- {"newpath", NEWPATH},
- {"pop", POP},
- {"rlineto", RLINETO},
- {"rotate", ROTATE},
- {"scale", SCALE},
- {"setcmykcolor", SETCMYKCOLOR},
- {"setdash", SETDASH},
- {"setgray", SETGRAY},
- {"setlinecap", SETLINECAP},
- {"setlinejoin", SETLINEJOIN},
- {"setlinewidth", SETLINEWIDTH},
- {"setmiterlimit", SETMITERLIMIT},
- {"setrgbcolor", SETRGBCOLOR},
- {"show", SHOW},
- {"showpage", SHOWPAGE},
- {"startTexFig", TEXFIG},
- {"endTexFig", ETEXFIG},
- {"stroke", STROKE},
- {"sub", SUB},
- {"translate", TRANSLATE},
- {"truncate", TRUNCATE}
-};
-
-static int lookup_operator(char *token)
-{
- int i, operator;
- operator = -1;
- for (i=0; i<sizeof(operators)/sizeof(operators[0]); i++) {
- if (!strcmp (token, operators[i].t)) {
- operator = operators[i].v;
- break;
- }
- }
- if (i == sizeof(operators)/sizeof(operators[0]) &&
- mp_is_font_name (token)) {
- operator = FONTNAME;
- }
- return operator;
-}
-
-
-/* Following needed to save texfig state */
-
-static long next_fig = 1;
-static pdf_obj *fig_xobj = NULL;
-struct xform_info *fig_p;
-static char fig_res_name[16];
-
-static int do_operator(char *token,
- double x_user, double y_user)
- /* Again, the only piece that needs x_user and y_user is
- that piece dealing with texfig */
-{
- int operator, error = 0;
- pdf_obj *tmp1=NULL, *tmp2=NULL, *tmp3=NULL, *tmp4 = NULL;
- pdf_obj *tmp5=NULL, *tmp6=NULL;
- int len;
- /* PS to PDF conversion is not so simple. We maintain
- state so we can change "gsave fill grestore stroke" to "B".
- We need to keep track of what we have seen. This code is not
- too smart and could be easily fooled by real postscript.
- It makes some assumptions since it is only looking at MetaPost
-
- States are as follows:
- 0: Nothing special
- 1: Started a path
- 2: Saw gsave in path
- 3: Saw a painting operator in state 2(fill, stroke, or newpath)
- 4: Saw a grestore in state 3
- */
- operator = lookup_operator (token);
- switch (operator) {
- case ADD:
- tmp1 = POP_STACK();
- tmp2 = POP_STACK();
- if (tmp1 && tmp2)
- pdf_set_number (tmp1,
- pdf_number_value(tmp1)+pdf_number_value(tmp2));
- if (tmp2)
- pdf_release_obj (tmp2);
- if (tmp1)
- PUSH(tmp1);
- break;
- case CLIP:
- clip_path();
- break;
- case CLOSEPATH:
- close_path();
- break;
- case CONCAT:
- tmp1 = POP_STACK();
- if (tmp1 && tmp1 -> type == PDF_ARRAY) {
- int i, len = 0;
- for (i=0; i<6; i++) {
- if (!(tmp2 = pdf_get_array(tmp1, i)))
- break;
- if (i == 0) {
- sprintf (work_buffer+len, "\n");
- len += strlen (work_buffer+len);
- } else {
- sprintf (work_buffer+len, " ");
- len += strlen (work_buffer+len);
- }
- sprintf (work_buffer+len, "%g",
- ROUND(pdf_number_value(tmp2),0.0001));
- len += strlen (work_buffer+len);
- }
- sprintf (work_buffer+len, " cm");
- len += strlen (work_buffer+len);
- pdf_doc_add_to_page (work_buffer, len);
- /* Transform pending path, if any */
- transform_path (pdf_number_value(pdf_get_array(tmp1, 0)),
- pdf_number_value(pdf_get_array(tmp1, 1)),
- pdf_number_value(pdf_get_array(tmp1, 2)),
- pdf_number_value(pdf_get_array(tmp1, 3)),
- pdf_number_value(pdf_get_array(tmp1, 4)),
- pdf_number_value(pdf_get_array(tmp1, 5)));
- } else {
- fprintf (stderr, "\nMissing array before \"concat\"\n");
- }
- if (tmp1)
- pdf_release_obj (tmp1);
- break;
- case CURRENTPOINT:
- state = 0;
- PUSH (pdf_new_number (x_user)); /* Remember that x_user and y_user */
- PUSH (pdf_new_number (y_user)); /* are off by 0.02 % */
- break;
- case CURVETO:
- if (state <= 1) /* In path now */
- state = 1;
- else {
- fprintf (stderr, "\nUnexpected path segment\n");
- }
- if ((tmp6 = POP_STACK()) && tmp6->type == PDF_NUMBER &&
- (tmp5 = POP_STACK()) && tmp5->type == PDF_NUMBER &&
- (tmp4 = POP_STACK()) && tmp4->type == PDF_NUMBER &&
- (tmp3 = POP_STACK()) && tmp3->type == PDF_NUMBER &&
- (tmp2 = POP_STACK()) && tmp2->type == PDF_NUMBER &&
- (tmp1 = POP_STACK()) && tmp1->type == PDF_NUMBER) {
- add_curve_to_path (pdf_number_value(tmp1),
- pdf_number_value(tmp2),
- pdf_number_value(tmp3),
- pdf_number_value(tmp4),
- pdf_number_value(tmp5),
- pdf_number_value(tmp6));
- x_state = pdf_number_value (tmp5);
- y_state = pdf_number_value (tmp6);
- } else {
- fprintf (stderr, "\nMissing number(s) before \"curveto\"\n");
- }
- if (tmp1) pdf_release_obj (tmp1);
- if (tmp2) pdf_release_obj (tmp2);
- if (tmp3) pdf_release_obj (tmp3);
- if (tmp4) pdf_release_obj (tmp4);
- if (tmp5) pdf_release_obj (tmp5);
- if (tmp6) pdf_release_obj (tmp6);
- break;
- case DIV:
- tmp2 = POP_STACK();
- tmp1 = POP_STACK();
- if (tmp1 && tmp2)
- pdf_set_number (tmp1,
- pdf_number_value(tmp1)/pdf_number_value(tmp2));
- if (tmp1)
- PUSH(tmp1);
- if (tmp2)
- pdf_release_obj (tmp2);
- break;
- case DTRANSFORM:
- if ((tmp2 = POP_STACK()) && tmp2 -> type == PDF_NUMBER &&
- (tmp1 = POP_STACK()) && tmp1 -> type == PDF_NUMBER) {
- pdf_set_number (tmp1, pdf_number_value(tmp1)*100.0);
- pdf_set_number (tmp2, pdf_number_value(tmp2)*100.0);
- PUSH(tmp1);
- PUSH(tmp2);
- } else {
- if (tmp1)
- pdf_release_obj (tmp1);
- if (tmp2)
- pdf_release_obj (tmp2);
- fprintf (stderr, "\nExpecting two numbers before \"dtransform\"");
- }
- break;
- case EXCH:
- if ((tmp1 = POP_STACK()) &&
- (tmp2 = POP_STACK())) {
- PUSH (tmp1);
- PUSH (tmp2);
- } else {
- if (tmp1)
- pdf_release_obj (tmp1);
- }
- break;
- case FILL:
- switch (state) {
- case 0:
- state = 0;
- break;
- case 1:
- flush_path ();
- pdf_doc_add_to_page (" f", 2);
- state = 0;
- break;
- case 2:
- state = 3;
- break;
- case 3:
- fprintf (stderr, "\nUnexpected fill\n");
- break;
- case 4:
- flush_path ();
- pdf_doc_add_to_page (" B", 2);
- state = 0;
- break;
- }
- break;
- case FSHOW:
- {
- int fontid;
- if ((tmp3 = POP_STACK()) && (tmp3->type == PDF_NUMBER) &&
- (tmp2 = POP_STACK()) && (tmp2->type == PDF_STRING) &&
- (tmp1 = POP_STACK()) && (tmp1->type == PDF_STRING)) {
- if ((fontid = mp_fontid (pdf_string_value(tmp2),
- pdf_number_value(tmp3))) < 0) {
- fprintf (stderr, "\n\"fshow\": Missing font in MetaPost file? %s@%g\n",
- (char *) pdf_string_value(tmp2), pdf_number_value(tmp3));
- }
- dev_set_string (x_state/dvi_unit_size(), y_state/dvi_unit_size(),
- pdf_string_value(tmp1),
- pdf_string_length(tmp1), 0, mp_fonts[fontid].font_id);
- graphics_mode();
- }
- /* Treat fshow as a path terminator of sorts */
- state = 0;
-
- if (tmp1)
- pdf_release_obj (tmp1);
- if (tmp2)
- pdf_release_obj (tmp2);
- if (tmp3)
- pdf_release_obj (tmp3);
- }
- break;
- case GSAVE:
- switch (state) {
- case 0:
- pdf_doc_add_to_page ("\nq", 2);
- num_saves += 1;
- break;
- case 1:
- state = 2;
- break;
- case 4:
- state = 2;
- break;
- default:
- fprintf (stderr, "\nUnexpected gsave\n");
- break;
- }
- break;
- case GRESTORE:
- switch (state) {
- case 0:
- if (num_saves > 0) {
- num_saves -= 1;
- pdf_doc_add_to_page ("\nQ", 2);
- /* Unfortunately, the following two lines are necessary in case of a font or color
- change inside of the save/restore pair. Anything that was done
- there must be redone, so in effect, we make no assumptions about
- what fonts are active. We act like we are starting a new page */
- dev_reselect_font();
- /* The following line was causing trouble - 1/30/01 */
- /* dev_do_color(); */
- }
- else {
- fprintf (stderr, "PS special: \"grestore\" ignored. More restores than saves on a page.\n");
- }
- break;
- case 2:
- state = 1;
- break;
- case 3:
- state = 4;
- break;
- default:
- fprintf (stderr, "\nUnexpected grestore\n");
- break;
- }
- break;
- case IDTRANSFORM:
- if ((tmp2 = POP_STACK()) && tmp2 -> type == PDF_NUMBER &&
- (tmp1 = POP_STACK()) && tmp1 -> type == PDF_NUMBER) {
- pdf_set_number (tmp1, pdf_number_value(tmp1)/100.0);
- pdf_set_number (tmp2, pdf_number_value(tmp2)/100.0);
- PUSH(tmp1);
- PUSH(tmp2);
- } else {
- if (tmp1)
- pdf_release_obj (tmp1);
- if (tmp2)
- pdf_release_obj (tmp2);
- fprintf (stderr, "\nExpecting two numbers before \"idtransform\"");
- }
- break;
- case LINETO:
- {
- if (state <= 1) /* In path now */
- state = 1;
- else {
- fprintf (stderr, "\nUnexpected path segment\n");
- }
- if ((tmp2 = POP_STACK()) && tmp2-> type == PDF_NUMBER &&
- (tmp1 = POP_STACK()) && tmp1-> type == PDF_NUMBER) {
- x_state = pdf_number_value (tmp1);
- y_state = pdf_number_value (tmp2);
- add_point_to_path (x_state, y_state, 'l');
- }
- if (tmp1)
- pdf_release_obj (tmp1);
- if (tmp2)
- pdf_release_obj (tmp2);
- }
- break;
- case MOVETO:
- if (state <= 1) /* In path now */
- state = 1;
- else {
- fprintf (stderr, "\nUnexpected path segment\n");
- }
- if ((tmp2 = POP_STACK()) && tmp2-> type == PDF_NUMBER &&
- (tmp1 = POP_STACK()) && tmp1-> type == PDF_NUMBER) {
- /* MetaPost likes to ship out a moveto before displayed text.
- Save the results so we know where to place the text. Save
- the move but don't actually do it unless the next operator is
- a graphics operator */
- x_state = pdf_number_value (tmp1);
- y_state = pdf_number_value (tmp2);
- add_point_to_path (x_state, y_state, 'm');
- }
- if (tmp1)
- pdf_release_obj (tmp1);
- if (tmp2)
- pdf_release_obj (tmp2);
- break;
- case MUL:
- tmp2 = POP_STACK();
- tmp1 = POP_STACK();
- if (tmp1 && tmp2)
- pdf_set_number (tmp1,
- pdf_number_value(tmp1)*pdf_number_value(tmp2));
- if (tmp1)
- PUSH(tmp1);
- if (tmp2)
- pdf_release_obj (tmp2);
- break;
- case NEG:
- tmp1 = POP_STACK();
- if (tmp1 && tmp1 -> type == PDF_NUMBER) {
- pdf_set_number (tmp1, -pdf_number_value(tmp1));
- PUSH (tmp1);
- }
- break;
- case NEWPATH:
- flush_path ();
- pdf_doc_add_to_page ("\nn", 2);
- break;
- case POP:
- tmp1 = POP_STACK();
- if (tmp1)
- pdf_release_obj (tmp1);
- break;
- case RLINETO:
- if (state <= 1) /* In path now */
- state = 1;
- else {
- fprintf (stderr, "\nUnexpected path segment\n");
- }
- if ((tmp2 = POP_STACK()) && tmp2->type == PDF_NUMBER &&
- (tmp1 = POP_STACK()) && tmp1->type == PDF_NUMBER) {
- x_state += pdf_number_value (tmp1);
- y_state += pdf_number_value (tmp2);
- add_point_to_path (x_state, y_state, 'l');
- }
- if (tmp1)
- pdf_release_obj (tmp1);
- if (tmp2)
- pdf_release_obj (tmp2);
- break;
- case SCALE:
- if ((tmp2 = POP_STACK()) && tmp2->type == PDF_NUMBER &&
- (tmp1 = POP_STACK()) && tmp1->type == PDF_NUMBER) {
- sprintf (work_buffer, "\n%g 0 0 %g 0 0 cm",
- ROUND(pdf_number_value (tmp1),0.01),
- ROUND(pdf_number_value (tmp2),0.01));
- len = strlen (work_buffer);
- transform_path (pdf_number_value(tmp1), 0.0,
- 0.0, pdf_number_value(tmp2), 0.0, 0.0);
- pdf_doc_add_to_page (work_buffer, len);
- }
- if (tmp1)
- pdf_release_obj (tmp1);
- if (tmp2)
- pdf_release_obj (tmp2);
- break;
- case SETCMYKCOLOR:
- if ((tmp4 = POP_STACK()) && tmp4->type == PDF_NUMBER &&
- (tmp3 = POP_STACK()) && tmp3->type == PDF_NUMBER &&
- (tmp2 = POP_STACK()) && tmp2->type == PDF_NUMBER &&
- (tmp1 = POP_STACK()) && tmp1->type == PDF_NUMBER) {
- sprintf (work_buffer, "\n%g %g %g %g k",
- ROUND(pdf_number_value (tmp1),0.001),
- ROUND(pdf_number_value (tmp2),0.001),
- ROUND(pdf_number_value (tmp3),0.001),
- ROUND(pdf_number_value (tmp4),0.001));
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- sprintf (work_buffer, "\n%g %g %g %g K",
- ROUND(pdf_number_value (tmp1),0.001),
- ROUND(pdf_number_value (tmp2),0.001),
- ROUND(pdf_number_value (tmp3),0.001),
- ROUND(pdf_number_value (tmp4),0.001));
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- } else {
- fprintf (stderr, "\nExpecting four numbers before \"setcmykcolor\"\n");
- }
- if (tmp1)
- pdf_release_obj (tmp1);
- if (tmp2)
- pdf_release_obj (tmp2);
- if (tmp3)
- pdf_release_obj (tmp3);
- if (tmp4)
- pdf_release_obj (tmp4);
- break;
- case SETDASH:
- if ((tmp2 = POP_STACK()) && tmp2->type == PDF_NUMBER &&
- (tmp1 = POP_STACK()) && tmp1->type == PDF_ARRAY) {
- int i;
- pdf_doc_add_to_page ("\n[", 2);
- for (i=0;; i++) {
- if ((tmp3 = pdf_get_array (tmp1, i)) &&
- tmp3 -> type == PDF_NUMBER) {
- sprintf (work_buffer, " %g", ROUND(pdf_number_value(tmp3),0.01));
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- } else
- break;
- }
- pdf_doc_add_to_page (" ]", 2);
- if (tmp2 -> type == PDF_NUMBER) {
- sprintf (work_buffer, " %g d", ROUND(pdf_number_value(tmp2),0.01));
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- }
- } else {
- fprintf (stderr, "\nExpecting array and number before \"setdash\"");
- }
- if (tmp1)
- pdf_release_obj (tmp1);
- if (tmp2)
- pdf_release_obj (tmp2);
- break;
- case SETGRAY:
- if ((tmp1 = POP_STACK()) && tmp1->type == PDF_NUMBER) {
- sprintf (work_buffer, "\n%g g",
- ROUND(pdf_number_value (tmp1),0.001));
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- sprintf (work_buffer, " %g G",
- ROUND(pdf_number_value (tmp1),0.001));
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- } else {
- fprintf (stderr, "\nExpecting a number before \"setgray\"\n");
- }
- if (tmp1)
- pdf_release_obj (tmp1);
- break;
- case SETLINECAP:
- if ((tmp1 = POP_STACK()) && tmp1->type == PDF_NUMBER) {
- sprintf (work_buffer, "\n%g J", pdf_number_value (tmp1));
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- } else {
- fprintf (stderr, "\nExpecting a number before \"setlinecap\"\n");
- }
- if (tmp1)
- pdf_release_obj (tmp1);
- break;
- case SETLINEJOIN:
- if ((tmp1 = POP_STACK()) && tmp1->type == PDF_NUMBER) {
- sprintf (work_buffer, "\n%g j", pdf_number_value (tmp1));
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- } else {
- fprintf (stderr, "\nExpecting a number before \"setlinejoin\"\n");
- }
- if (tmp1)
- pdf_release_obj (tmp1);
- break;
- case SETLINEWIDTH:
- if ((tmp1 = POP_STACK()) && tmp1->type == PDF_NUMBER) {
- sprintf (work_buffer, "\n%g w", ROUND(pdf_number_value (tmp1),0.01));
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- } else {
- fprintf (stderr, "\nExpecting a number before \"setlinewidth\"\n");
- }
- if (tmp1)
- pdf_release_obj (tmp1);
- break;
- case SETMITERLIMIT:
- if ((tmp1 = POP_STACK()) && tmp1->type == PDF_NUMBER) {
- sprintf (work_buffer, "\n%g M", ROUND(pdf_number_value
- (tmp1),0.01));
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- } else {
- fprintf (stderr, "\nExpecting a number before \"setmiterlimit\"\n");
- }
- if (tmp1)
- pdf_release_obj (tmp1);
- break;
- case SETRGBCOLOR:
- if ((tmp3 = POP_STACK()) && tmp3->type == PDF_NUMBER &&
- (tmp2 = POP_STACK()) && tmp2->type == PDF_NUMBER &&
- (tmp1 = POP_STACK()) && tmp1->type == PDF_NUMBER) {
- sprintf (work_buffer, "\n%g %g %g rg",
- ROUND(pdf_number_value (tmp1),0.001),
- ROUND(pdf_number_value (tmp2),0.001),
- ROUND(pdf_number_value (tmp3),0.001));
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- sprintf (work_buffer, "\n%g %g %g RG",
- ROUND(pdf_number_value (tmp1),0.001),
- ROUND(pdf_number_value (tmp2),0.001),
- ROUND(pdf_number_value (tmp3),0.001));
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- } else {
- fprintf (stderr, "\nExpecting three numbers before \"setrgbcolor\"\n");
- }
- if (tmp1)
- pdf_release_obj (tmp1);
- if (tmp2)
- pdf_release_obj (tmp2);
- if (tmp3)
- pdf_release_obj (tmp3);
- break;
- case SHOWPAGE:
- /* Let's ignore this for now */
- void_path ();
- break;
- case STROKE:
- switch (state) {
- case 0:
- state = 0;
- break;
- case 1:
- flush_path ();
- pdf_doc_add_to_page (" S", 2);
- state = 0;
- break;
- case 2:
- state = 3;
- break;
- case 3:
- fprintf (stderr, "\nUnexpected fill\n");
- break;
- case 4:
- flush_path ();
- pdf_doc_add_to_page (" B", 2);
- state = 0;
- break;
- }
- break;
- case SUB:
- tmp2 = POP_STACK();
- tmp1 = POP_STACK();
- if (tmp1 && tmp2)
- pdf_set_number (tmp1,
- pdf_number_value(tmp1)-pdf_number_value(tmp2));
- if (tmp1)
- PUSH(tmp1);
- if (tmp2)
- pdf_release_obj (tmp2);
- break;
- case ROTATE:
- if ((tmp1 = POP_STACK()) && (tmp1 -> type == PDF_NUMBER)) {
- double theta = pdf_number_value(tmp1)*M_PI/180.0;
- sprintf (work_buffer, "\n%.4f %.4f %.4f %.4f 0 0 cm",
- cos(theta), -sin(theta),
- sin(theta), cos(theta));
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- }
- if (tmp1)
- pdf_release_obj (tmp1);
- break;
- case TEXFIG:
- if ((tmp6 = POP_STACK()) && (tmp6 -> type == PDF_NUMBER) &&
- (tmp5 = POP_STACK()) && (tmp5 -> type == PDF_NUMBER) &&
- (tmp4 = POP_STACK()) && (tmp4 -> type == PDF_NUMBER) &&
- (tmp3 = POP_STACK()) && (tmp3 -> type == PDF_NUMBER) &&
- (tmp2 = POP_STACK()) && (tmp2 -> type == PDF_NUMBER) &&
- (tmp1 = POP_STACK()) && (tmp1 -> type == PDF_NUMBER)) {
- double dvi2pts = dvi_unit_size();
- fig_p = new_xform_info ();
- fig_p -> width = pdf_number_value(tmp1)*dvi2pts;
- fig_p -> height = pdf_number_value(tmp2)*dvi2pts;
- fig_p -> c_llx = pdf_number_value(tmp3)*dvi2pts;
- fig_p -> c_lly = pdf_number_value(tmp4)*dvi2pts;
- fig_p -> c_urx = pdf_number_value(tmp5)*dvi2pts;
- fig_p -> c_ury = pdf_number_value(tmp6)*dvi2pts;
- pdf_scale_image (fig_p);
- sprintf (fig_res_name, "Tf%ld", next_fig);
- fig_xobj = begin_form_xobj (fig_p->c_llx, -fig_p->c_ury, fig_p->c_llx, -fig_p->c_lly,
- fig_p->c_urx, -fig_p->c_ury, fig_res_name);
- }
- if (tmp1) pdf_release_obj(tmp1);
- if (tmp2) pdf_release_obj(tmp2);
- if (tmp3) pdf_release_obj(tmp3);
- if (tmp4) pdf_release_obj(tmp4);
- if (tmp5) pdf_release_obj(tmp5);
- if (tmp6) pdf_release_obj(tmp6);
- break;
- case ETEXFIG:
- if (fig_xobj) {
- next_fig += 1;
- end_form_xobj ();
- pdf_doc_add_to_page_xobjects (fig_res_name, pdf_ref_obj(fig_xobj));
- pdf_release_obj (fig_xobj);
- fig_xobj = NULL;
- pdf_doc_add_to_page ("\nq", 2);
- add_xform_matrix (x_user, y_user, fig_p->xscale, -fig_p->yscale, fig_p->rotate);
- if (fig_p->depth != 0.0)
- add_xform_matrix (0.0, -fig_p->depth, 1.0, -1.0, 0.0);
- release_xform_info (fig_p);
- sprintf (work_buffer, " /%s Do Q", fig_res_name);
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- } else {
- fprintf (stderr, "\nendTexFig without valid startTexFig ignored\n");
- }
- break;
- case TRANSLATE:
- if ((tmp2 = POP_STACK()) && tmp2->type == PDF_NUMBER &&
- (tmp1 = POP_STACK()) && tmp1->type == PDF_NUMBER) {
- sprintf (work_buffer, "\n1 0 0 1 %g %g cm",
- ROUND(pdf_number_value (tmp1),0.01),
- ROUND(pdf_number_value (tmp2),0.01));
- len = strlen (work_buffer);
- pdf_doc_add_to_page (work_buffer, len);
- transform_path (1.0, 0.0, 0.0, 1.0,
- pdf_number_value (tmp1),
- pdf_number_value (tmp2));
- }
- if (tmp1)
- pdf_release_obj (tmp1);
- if (tmp2)
- pdf_release_obj (tmp2);
- break;
- case TRUNCATE:
- if ((tmp1 = POP_STACK()) && tmp1->type == PDF_NUMBER) {
- double val=pdf_number_value(tmp1);
- pdf_set_number (tmp1, val>0? floor(val): ceil(val));
- PUSH (tmp1);
- } else if (tmp1)
- pdf_release_obj (tmp1);
- break;
- case FONTNAME:
- PUSH (pdf_new_string (token, strlen(token)));
- break;
- default:
- fprintf (stderr,
- "\nIgnoring remaining special text following unknown PS operator: \"%s\"\n", token);
- error = 1;
- break;
- }
- return !error;
-}
-
-static int do_one_ps_line (char **start, char *end,
- double x_user, double y_user)
- /* the only sections that need to know x_user and y _user are those
- dealing with texfig */
-{
- char *token, *save = NULL;
- pdf_obj *obj;
- int error = 0;
- skip_white (start, end);
- while (*start < end && !error) {
- save = *start;
- if (isdigit (**start) || **start == '-' || **start == '.' ) {
- token = parse_number (start, end);
- PUSH (pdf_new_number(atof(token)));
- RELEASE (token);
- } else if (**start == '[' && /* This code assumes that arrays are contained on one line */
- (obj = parse_pdf_array (start, end))) {
- PUSH (obj);
- } else if (**start == '(' &&
- (obj = parse_pdf_string (start, end))) {
- PUSH (obj);
- } else if (**start == '/') {
- fprintf (stderr, "\nUnable to handle names in raw PS code.");
- dump (*start, end);
- error = 1;
- } else {
- token = parse_ident (start, end);
- if (!token || !do_operator (token, x_user, y_user)) {
- error = 1;
- }
- if (token)
- RELEASE (token);
- }
- skip_white (start, end);
- }
- if (*start < end) {
- fprintf (stderr, "\nRemainder of line unparsed.");
- dump (*start, end);
- }
- return !error;
-}
-
-static char line_buffer[1024];
-int parse_contents (FILE *image_file)
-{
- int error = 0;
- top_stack = 0;
- x_state = 0.0;
- y_state = 0.0;
- state = 0;
- while (!feof(image_file) && mfgets (line_buffer, sizeof(line_buffer),
- image_file)) {
- char *start, *end;
- start = line_buffer;
- end = start+strlen(line_buffer);
- if (!do_one_ps_line (&start, end, 0.0, 0.0)) {
- error = 1;
- break;
- }
- }
- return !error;
-}
-
-int do_raw_ps_special (char **start, char* end, int cleanup,
- double x_user, double y_user)
-{
- int error = 0;
- state = 0;
- do_one_ps_line (start, end, x_user, y_user);
- if (cleanup)
- mp_cleanup(1);
- return !error;
-}
-
-void mp_cleanup (int sloppy_ok)
-{
- release_fonts();
- if (state != 0) {
- if (!sloppy_ok)
- fprintf (stderr, "mp_cleanup(): State not zero\n");
- state = 0;
- }
- if (top_stack != 0) {
- if (!sloppy_ok)
- fprintf (stderr, "\nPS/MetaPost: PS stack not empty at end of figure!\n");
- }
- /* Cleanup paths */
- while (top_stack > 0) {
- pdf_obj *p;
- if ((p=POP_STACK()))
- pdf_release_obj (p);
- }
- if (n_path_pts > 0) {
- if (!sloppy_ok) {
- fprintf (stderr, "\nPS/MetaPost: Pending path at end of figure!\n");
- dump_path ();
- }
- void_path ();
- }
- if (max_path_pts > 0) {
- RELEASE (path);
- path = NULL;
- max_path_pts = 0;
- }
-}
-
-void mp_eop_cleanup(void)
-{
- mp_cleanup(1);
- num_saves = 0;
-}
-
-
-/* mp inclusion is a bit of a hack. The routine
- * starts a form at the lower left corner of
- * the page and then calls begin_form_xobj telling
- * it to record the image drawn there and bundle it
- * up in an xojbect. This allows us to use the coordinates
- * in the MP file directly. This appears to be the
- * easiest way to be able to use the dev_set_string()
- * command (with its scaled and extended fonts) without
- * getting all confused about the coordinate system.
- * After the xobject is created, the whole thing can
- * be scaled any way the user wants */
-
-pdf_obj *mp_include (FILE *image_file, struct xform_info *p,
- char *res_name, double x_user, double y_user)
-{
- pdf_obj *xobj = NULL;
- rewind (image_file);
- if (mp_parse_headers (image_file, p)) {
- /* Looks like an MP file. Setup xobj "capture" */
- pdf_scale_image (p);
- xobj = begin_form_xobj (p->u_llx,p->u_lly, p->c_llx, p->c_lly,
- p->c_urx, p->c_ury, res_name);
- if (!xobj)
- return NULL;
- /* Flesh out the contents */
- if (!parse_contents (image_file)) {
- fprintf (stderr, "Errors occured while interpreting MetaPost file.\n\n");
- }
- /* Finish off the form */
- end_form_xobj();
- } else {
- fprintf (stderr, "\nErrors occured while scanning MetaPost file headers.\n");
- }
- mp_cleanup(0);
- return xobj;
-}
-
-/* struct xform_info *texfig_info (void)
-{
- struct xform_info *p;
- p = new_xform_info ();
- p -> user_bbox = 1;
- p -> width = fig_width;
- p -> height = fig_height;
- p -> u_llx = fig_llx;
- p -> u_lly = fig_lly;
- p -> u_urx = fig_urx;
- p -> u_ury = fig_ury;
- return p;
-} */