summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdfm/tpic.c
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-01-17 21:41:51 +0000
committerKarl Berry <karl@freefriends.org>2006-01-17 21:41:51 +0000
commit487ca4806cc046076293cf6cc5fbba0db282bac7 (patch)
tree847b412ab5158dd7bdd7ed7e5a4cc3fbca94be32 /Build/source/texk/dvipdfm/tpic.c
parenta3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (diff)
texk 1
git-svn-id: svn://tug.org/texlive/trunk@1485 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/dvipdfm/tpic.c')
-rw-r--r--Build/source/texk/dvipdfm/tpic.c498
1 files changed, 498 insertions, 0 deletions
diff --git a/Build/source/texk/dvipdfm/tpic.c b/Build/source/texk/dvipdfm/tpic.c
new file mode 100644
index 00000000000..639ba4af854
--- /dev/null
+++ b/Build/source/texk/dvipdfm/tpic.c
@@ -0,0 +1,498 @@
+/* $Header$
+
+ 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 <string.h>
+#include <stdlib.h>
+#include "system.h"
+#include "mem.h"
+#include "mfileio.h"
+#include "tpic.h"
+#include "pdfparse.h"
+#include "pdfdoc.h"
+#include "pdfdev.h"
+#include "dvi.h"
+
+/* Following "constant" converts milli-inches to
+ device (in this case PDF stream) coordinates */
+
+#define MI2DEV (0.072/pdf_dev_scale())
+
+double pen_size = 1.0;
+int fill_shape = 0;
+double fill_color = 0.0; double default_fill_color = 0.5;
+static struct path
+{
+ double x, y;
+} *path = NULL;
+unsigned long path_length = 0, max_path_length = 0;
+
+static void tpic_clear_state (void)
+{
+ if ((path))
+ RELEASE(path);
+ path = NULL;
+ path_length = 0;
+ max_path_length = 0;
+ fill_shape = 0;
+ fill_color = 0.0;
+ return;
+}
+
+static void set_pen_size (char **buffer, char *end)
+{
+ char *number;
+ skip_white (buffer, end);
+ if ((number = parse_number(buffer, end))) {
+ pen_size = atof (number) * MI2DEV;
+ RELEASE (number);
+ } else {
+ dump (*buffer, end);
+ fprintf (stderr, "tpic special: pn: Invalid pen size\n");
+ }
+}
+
+static void set_fill_color (char **buffer, char *end)
+{
+ char *number;
+MEM_START
+ fill_shape = 1;
+ fill_color = default_fill_color;
+ skip_white (buffer, end);
+ if ((number = parse_number(buffer, end))) {
+ fill_color = 1.0 - atof (number);
+ if (fill_color > 1.0)
+ fill_color = 1.0;
+ if (fill_color < 0.0)
+ fill_color = 0.0;
+ RELEASE (number);
+ }
+MEM_END
+}
+
+static void add_point (char **buffer, char *end)
+{
+ char *x= NULL, *y= NULL;
+MEM_START
+ skip_white (buffer, end);
+ if (*buffer < end)
+ x = parse_number (buffer, end);
+ skip_white (buffer, end);
+ if (*buffer < end)
+ y = parse_number (buffer, end);
+ if ((x) && (y)) {
+ if (path_length >= max_path_length) {
+ max_path_length += 256;
+ path = RENEW (path, max_path_length, struct path);
+ }
+ path[path_length].x = atof(x)*MI2DEV;
+ path[path_length].y = atof(y)*MI2DEV;
+ path_length += 1;
+ } else {
+ dump (*buffer, end);
+ fprintf (stderr, "tpic special: pa: Missing coordinate\n");
+ }
+ if (x) RELEASE(x);
+ if (y) RELEASE(y);
+MEM_END
+ return;
+}
+
+static void show_path (int hidden)
+{
+ int len;
+ /* The semantics of a fill_color of 0.0 or 0.5 will be to use current
+ painting color known to dvipdfm */
+ if (fill_shape && fill_color != 0.0) {
+ sprintf (work_buffer, " %.2f g", fill_color);
+ len = strlen (work_buffer);
+ pdf_doc_add_to_page (work_buffer, len);
+ }
+ if (!hidden && fill_shape) {
+ pdf_doc_add_to_page (" b", 2);
+ }
+ if (hidden && fill_shape) {
+ pdf_doc_add_to_page (" f", 2);
+ }
+ if (!hidden && !fill_shape)
+ pdf_doc_add_to_page (" S", 2);
+ if (fill_shape)
+ fill_shape = 0;
+ fill_color = 0.0;
+ fill_shape = 0.0;
+}
+
+
+static void flush_path (double x_user, double y_user, int hidden,
+ double dash_dot)
+{
+ int len;
+MEM_START
+ /* Make pen_size == 0 equivalent to hidden */
+ if (pen_size == 0)
+ hidden = 1;
+ if (path_length > 1) {
+ int i;
+ sprintf (work_buffer, " q");
+ len = strlen (work_buffer);
+ pdf_doc_add_to_page (work_buffer, len);
+ if (pen_size != 0.0) {
+ sprintf (work_buffer, " %.2f w", pen_size);
+ len = strlen (work_buffer);
+ }
+ pdf_doc_add_to_page (work_buffer, len);
+ sprintf (work_buffer, " 1 J 1 j");
+ len = strlen (work_buffer);
+ pdf_doc_add_to_page (work_buffer, len);
+ if (dash_dot != 0.0) {
+ if (dash_dot > 0.0) {
+ sprintf (work_buffer, " [%.1f %.1f] 0 d",
+ dash_dot*72.0, dash_dot*36.0);
+ len = strlen (work_buffer);
+ } else {
+ sprintf (work_buffer, " [%.1f %.1f] 0 d", pen_size,
+ -dash_dot*72.0);
+ len = strlen (work_buffer);
+ }
+ pdf_doc_add_to_page (work_buffer, len);
+ }
+ sprintf (work_buffer, " %.2f %.2f m",
+ x_user+path[0].x, y_user-path[0].y);
+ len = strlen (work_buffer);
+ pdf_doc_add_to_page (work_buffer, len);
+ for (i=0; i<path_length; i++) {
+ sprintf (work_buffer, " %.2f %.2f l", x_user+path[i].x, y_user-path[i].y);
+ len = strlen (work_buffer);
+ pdf_doc_add_to_page (work_buffer, len);
+ }
+ show_path (hidden);
+ pdf_doc_add_to_page (" Q", 2);
+ } else {
+ fprintf (stderr, "tpic special: fp: Not enough points!\n");
+ }
+ tpic_clear_state();
+MEM_END
+ return;
+}
+static void spline_path (double x_user, double y_user, double dash_dot)
+{
+ int len;
+MEM_START
+ /* Spline is meaningless for path length of less than 3 */
+ if (path_length > 2) {
+ int i;
+ sprintf (work_buffer, " q 1.4 M %.2f w", pen_size);
+ len = strlen (work_buffer);
+ pdf_doc_add_to_page (work_buffer, len);
+ if (dash_dot != 0.0) {
+ if (dash_dot > 0.0) {
+ sprintf (work_buffer, " [%.1f %.1f] 0 d",
+ dash_dot*72.0, dash_dot*36.0);
+ len = strlen (work_buffer);
+ } else if (dash_dot < 0.0) {
+ sprintf (work_buffer, " [%.1f %.1f] 0 d 1 J", pen_size,
+ -dash_dot*72.0);
+ len = strlen (work_buffer);
+ }
+ pdf_doc_add_to_page (work_buffer, len);
+ }
+ sprintf (work_buffer, " %.2f %.2f m",
+ x_user+path[0].x, y_user-path[0].y);
+ len = strlen (work_buffer);
+ pdf_doc_add_to_page (work_buffer, len);
+ sprintf (work_buffer, " %.2f %.2f l",
+ x_user+0.5*(path[0].x+path[1].x),
+ y_user-0.5*(path[0].y+path[1].y));
+ len = strlen (work_buffer);
+ pdf_doc_add_to_page (work_buffer, len);
+ for (i=1; i<path_length-1; i++) {
+ sprintf (work_buffer, " %.2f %.2f %.2f %.2f y",
+ x_user+path[i].x, y_user-path[i].y,
+ x_user+0.5*(path[i].x+path[i+1].x),
+ y_user-0.5*(path[i].y+path[i+1].y));
+ len = strlen (work_buffer);
+ pdf_doc_add_to_page (work_buffer, len);
+ }
+ sprintf (work_buffer, " %.2f %.2f l",
+ x_user+path[path_length-1].x,
+ y_user-path[path_length-1].y);
+ len = strlen (work_buffer);
+ pdf_doc_add_to_page (work_buffer, len);
+ show_path (0);
+ pdf_doc_add_to_page (" Q", 2);
+ } else {
+ fprintf (stderr, "tpic special: sp: Not enough points!\n");
+ }
+ tpic_clear_state();
+MEM_END
+ return;
+}
+
+static void arc (char **buffer, char *end, double x_user, double
+ y_user, int hidden)
+{
+ char *xcs= NULL, *ycs= NULL,
+ *xrs=NULL, *yrs=NULL, *sas=NULL, *eas=NULL;
+ char *save;
+ double xc, yc, xr, yr, sa, ea;
+MEM_START
+ save = *buffer;
+/* pen_size == 0 is equivalent to hidden */
+ if (pen_size == 0)
+ hidden = 1;
+ if ((xcs=parse_number(buffer, end)) &&
+ (ycs=parse_number(buffer, end)) &&
+ (xrs=parse_number(buffer, end)) &&
+ (yrs=parse_number(buffer, end)) &&
+ (sas=parse_number(buffer, end)) &&
+ (eas=parse_number(buffer, end))) {
+ double c, s, cur_x, cur_y, inc_ang;
+ double cp1_x, cp1_y, cp2_x, cp2_y;
+ double new_x, new_y;
+ int len, i, nsteps;
+ xc=atof (xcs)*MI2DEV; yc=atof (ycs)*MI2DEV;
+ xr=atof (xrs)*MI2DEV; yr=atof (yrs)*MI2DEV;
+ sa=atof (sas); ea=atof (eas);
+#define ROTATE(x,y,c,s) {new_x=(c)*(x)-(s)*(y);new_y=(s)*(x)+(c)*(y);x=new_x,y=new_y;}
+ #define MAX_ANG_STEP 1.0
+ nsteps = (int) ((ea-sa)/MAX_ANG_STEP) + 1;
+ inc_ang = (ea-sa)/nsteps;
+ c = cos(inc_ang); s = sin(inc_ang);
+ cur_x=cos(sa); cur_y=sin(sa);
+ cp1_x = cur_x - inc_ang/3.0*cur_y;
+ cp1_y = cur_y + inc_ang/3.0*cur_x;
+ cp2_x = cur_x + inc_ang/3.0*cur_y;
+ cp2_y = cur_y - inc_ang/3.0*cur_x;
+ sprintf (work_buffer, " q");
+ len = strlen (work_buffer);
+ pdf_doc_add_to_page (work_buffer, len);
+ if (pen_size != 0.0) {
+ sprintf (work_buffer, " %.2f w", pen_size);
+ len = strlen (work_buffer);
+ }
+ pdf_doc_add_to_page (work_buffer, len);
+ sprintf (work_buffer, " 1 J");
+ len = strlen (work_buffer);
+ pdf_doc_add_to_page (work_buffer, len);
+ sprintf (work_buffer, " %.2f %.2f m", x_user+xr*cur_x+xc, y_user-yr*cur_y-yc);
+ len = strlen (work_buffer);
+ pdf_doc_add_to_page (work_buffer, len);
+ ROTATE (cp2_x, cp2_y, c, s);
+ ROTATE (cur_x, cur_y, c, s);
+ for (i=0; i<nsteps; i++) {
+ sprintf (work_buffer, " %.2f %.2f %.2f %.2f %.2f %.2f c",
+ x_user+xr*cp1_x+xc, y_user-yr*cp1_y-yc,
+ x_user+xr*cp2_x+xc, y_user-yr*cp2_y-yc,
+ x_user+xr*cur_x+xc, y_user-yr*cur_y-yc);
+ len = strlen (work_buffer);
+ pdf_doc_add_to_page (work_buffer, len);
+ ROTATE (cur_x, cur_y, c, s);
+ ROTATE (cp1_x, cp1_y, c, s);
+ ROTATE (cp2_x, cp2_y, c, s);
+ }
+ show_path (hidden);
+ pdf_doc_add_to_page (" Q", 2);
+ } else {
+ dump (save, end);
+ fprintf (stderr, "tpic special: ar/ir: Error in parameters\n");
+ }
+ if (xcs) RELEASE(xcs);
+ if (ycs) RELEASE(ycs);
+ if (xrs) RELEASE(xrs);
+ if (yrs) RELEASE(yrs);
+ if (sas) RELEASE(sas);
+ if (eas) RELEASE(eas);
+MEM_END
+ tpic_clear_state();
+ return;
+}
+
+#define TPIC_PN 1
+#define TPIC_PA 2
+#define TPIC_FP 3
+#define TPIC_IP 4
+#define TPIC_DA 5
+#define TPIC_DT 6
+#define TPIC_SP 7
+#define TPIC_AR 8
+#define TPIC_IA 9
+#define TPIC_SH 10
+#define TPIC_WH 11
+#define TPIC_BK 12
+#define TPIC_TX 13
+
+struct {
+ char *s;
+ int tpic_command;
+} tpic_specials[] = {
+ {"pn", TPIC_PN},
+ {"pa", TPIC_PA},
+ {"fp", TPIC_FP},
+ {"ip", TPIC_IP},
+ {"da", TPIC_DA},
+ {"dt", TPIC_DT},
+ {"sp", TPIC_SP},
+ {"ar", TPIC_AR},
+ {"ia", TPIC_IA},
+ {"sh", TPIC_SH},
+ {"wh", TPIC_WH},
+ {"bk", TPIC_BK},
+ {"tx", TPIC_TX}
+};
+
+int tpic_parse_special(char *buffer, UNSIGNED_QUAD size, double
+ x_user, double y_user)
+{
+ int i, tpic_command, result = 0;
+ char *end = buffer + size;
+ char *token;
+ skip_white (&buffer, end);
+ if ((token = parse_ident (&buffer, end))) {
+ for (i=0; i<(sizeof(tpic_specials)/sizeof(tpic_specials[0])); i++) {
+ if (!strcmp (tpic_specials[i].s, token))
+ break;
+ }
+ RELEASE (token);
+ } else
+ return 0;
+ if (i < sizeof(tpic_specials)/sizeof(tpic_specials[0])) {
+ tpic_command = tpic_specials[i].tpic_command;
+ skip_white (&buffer, end);
+ result = 1;
+ switch (tpic_command) {
+ case TPIC_PN:
+ set_pen_size (&buffer, end);
+ break;
+ case TPIC_PA:
+ add_point (&buffer, end);
+ break;
+ case TPIC_FP:
+ flush_path(x_user, y_user, 0, 0.0);
+ break;
+ case TPIC_IP:
+ flush_path(x_user, y_user, 1, 0.0);
+ break;
+ case TPIC_DA:
+ {
+ char *s;
+ if ((s=parse_number(&buffer, end))) {
+ flush_path(x_user, y_user, 0, atof (s));
+ RELEASE (s);
+ }
+ }
+ break;
+ case TPIC_DT:
+ {
+ char *s;
+ if ((s=parse_number(&buffer, end))) {
+ flush_path(x_user, y_user, 0, -atof (s));
+ RELEASE (s);
+ }
+ }
+ break;
+ case TPIC_SP:
+ {
+ char *s;
+ if ((s=parse_number(&buffer, end)))
+ spline_path (x_user, y_user, atof (s));
+ else
+ spline_path(x_user, y_user, 0.0);
+ break;
+ }
+ case TPIC_AR:
+ arc (&buffer, end, x_user, y_user, 0);
+ break;
+ case TPIC_IA:
+ arc (&buffer, end, x_user, y_user, 1);
+ break;
+ case TPIC_SH:
+ set_fill_color (&buffer, end);
+ break;
+ case TPIC_WH:
+ fill_shape = 1;
+ fill_color = 1.0;
+ break;
+ case TPIC_BK:
+ fill_shape = 1;
+ fill_color = 0.0;
+ break;
+ case TPIC_TX:
+ fill_shape = 1;
+ {
+ long num = 0, den = 0;
+ while (buffer++ < end) {
+ switch (*(buffer++)) {
+ case '0':
+ num += 0;
+ case '1':
+ case '2':
+ case '4':
+ case '8':
+ num += 1;
+ break;
+ case '3':
+ case '5':
+ case '6':
+ case '9':
+ case 'a':
+ case 'A':
+ case 'c':
+ case 'C':
+ num += 2;
+ break;
+ case '7':
+ case 'b':
+ case 'B':
+ case 'd':
+ case 'D':
+ num += 3;
+ break;
+ case 'f':
+ case 'F':
+ num += 4;
+ break;
+ default:
+ break;
+ }
+ den += 16;
+ }
+ if (den != 0) {
+ default_fill_color = 1.0 - (float) (num)/(den);
+ }
+ else {
+ default_fill_color = 0.5;
+ }
+ }
+ break;
+ default:
+ fprintf (stderr, "Fix me, I'm broke. This should never happen");
+ exit(1);
+ }
+ } else {
+ result = 0;
+ }
+ return result;
+}
+
+
+