diff lib-src/mule/m2ps.c @ 70:131b0175ea99 r20-0b30

Import from CVS: tag r20-0b30
author cvs
date Mon, 13 Aug 2007 09:02:59 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib-src/mule/m2ps.c	Mon Aug 13 09:02:59 2007 +0200
@@ -0,0 +1,585 @@
+/* m2ps Ver.2.2 -- Convert multilingual text to PostScript
+   Copyright (C) 1992 Free Software Foundation, Inc. */
+
+/* This file is part of Mule (MULtilingual Enhancement of GNU Emacs).
+
+Mule is free software distributed in the form of patches to GNU Emacs.
+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 1, or (at your option)
+any later version.
+
+Mule 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 GNU Emacs; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* 92.10.8  written by K.Handa <handa@etl.go.jp> */
+/* 92.11.3  modified for Mule Ver.0.9.7
+                by T.Matsuzawa <mzw_t@hpujisa.yhp.co.jp>
+        Support NONSPACING characters and send smaller bitmap. */
+/* 92.11.6  modified for Mule Ver.0.9.7 by K.Shibata <shibata@sgi.co.jp>
+	Modified for ANSI-C. */
+/* 92.11.10 modified for Mule Ver.0.9.7
+		by K.Sakaeda <saka@tomorose.trad.pfu.fujitsu.co.jp>
+	Modified for SystemV. */
+/* 92.11.24 modified for Mule Ver.0.9.7 by K.Handa <handa@etl.go.jp>
+	Modified to reduce memory. */
+/* 92.12.14 modified for Mule Ver.0.9.7 by K.Handa <handa@etl.go.jp>
+	Support composite character. */
+/* 93.5.7   modified for Mule Ver.0.9.8 by K.Handa <handa@etl.go.jp>
+	Bug in handling missing font fixed.
+	Support Big5. */
+/* 93.5.29  modified for Mule Ver.0.9.8 by Y.Niibe <gniibe@mri.co.jp>
+	Include config.h in src directory */  
+/* 93.6.4   modified for Mule Ver.0.9.8 by K.Shibata <shibata@sgi.co.jp>
+	Modified for ANSI-C. */
+/* 93.12.25 modified for Mule Ver.1.0 by K.Handa <handa@etl.go.jp>
+	In textmode(), bug of right-to-left handling fixed  */
+/* 94.3.8   modified for Mule Ver.1.1 by K.Handa <handa@etl.go.jp>
+	Bug in find_encoding() fixed. */
+/* See `mule/ChangeLog.Mule' for the recent change log */
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include "mulelib.h"
+
+static char *m2ps_version = "2.2";
+
+#ifndef PSHeader
+#define PSHeader "m2ps.ps"
+#endif
+
+#ifndef DPI
+#define DPI 300
+#endif
+
+#ifndef FontScale
+#define FontScale 10
+#endif
+
+#ifndef LinePitch
+#define LinePitch 14
+#endif
+
+/* Parameters for A4 paper */
+#define A4_MaxLine 56
+#define A4_TopMargin 800
+
+/* Parameters for US-LETTER paper */
+#define US_MaxLine 50
+#define US_TopMargin 746
+
+#ifndef USLETTER
+
+#ifndef MaxLine
+#define MaxLine A4_MaxLine
+#endif
+
+#ifndef TopMargin
+#define TopMargin A4_TopMargin
+#endif
+
+#else  /* US-LETTER */
+
+#ifndef MaxLine
+#define MaxLine US_MaxLine
+#endif
+
+#ifndef TopMargin
+#define TopMargin US_TopMargin
+#endif
+
+#endif /* US-LETTER */
+
+#ifndef LeftMargin
+#define LeftMargin 30	/* To widen left margin, specify larger value. */
+#endif
+
+#ifndef ShortMemory
+#define ShortMemory 0
+#endif
+
+char *psheader = PSHeader;
+int dpi = DPI;
+int fontscale = FontScale;
+int linepitch = LinePitch;
+int maxline = MaxLine;
+int topmargin = TopMargin;
+int leftmargin = LeftMargin;
+int shortmemory = ShortMemory;
+
+/***************/
+/* Main staffs */
+/***************/
+
+/* GLOBAL VARIABLES */
+int clm, row, current_lc;
+
+set_font(lc)
+     int lc;
+{				/* 93.5.7, 94.11.29 by K.Handa -- Big change */
+  if (FONT_LOADED (lc) == 0) {
+    if (bdf_load_font(lc))
+      ps_newfont(lc);
+    else
+      lc = 0;
+  } else if (FONT_LOADED (lc) < 0)
+    lc = 0;
+  if (lc != current_lc) {
+    ps_setfont(lc);
+    current_lc = lc;
+  }
+}
+
+renew_font(lc)
+     int lc;
+{
+  bzero(((font_extra *)font[lc & 0x7F].extra)->new, 256 * (sizeof (char)));
+}
+
+/* Load specified glyph, then return the index to glyph.  Note the index
+   is within the range of [0,255].  Return -1 if error. */
+set_glyph1(lc, c)
+     int lc, c;
+{
+  if (!DEFINED1(lc, c)) {
+    if (bdf_load_glyph(lc, c, &glyph)) {
+      ps_newglyph(c, &glyph);
+      DEFINE1(lc, c);
+    } else
+      return -1;
+  }
+  return c;
+}
+
+find_encoding(fontp, lc, c)
+     font_struct *fontp;
+     int lc, c;
+{
+  font_extra *ext = (font_extra *)fontp->extra;
+  int i, min_count = ext->count[0], j = 0;
+
+  if (min_count > 0) {
+    min_count = 0x7FFF;		/* 94.3.8 by K.Handa */
+    for (i = 0; i < 256; i++) {
+      if (ext->count[i] <= min_count && !ext->new[i]) {
+	min_count = ext->count[i], j = i;
+	if (min_count == 0) break;
+      }
+    }
+  }
+  if (min_count > 0)
+    UNDEFINE2(lc, ext->code[j]);
+
+  ext->count[j] = ext->new[j] = 1;
+  ext->code[j] = c;
+  DEFINE2(lc, ext->code[j]);
+  return j;
+}
+
+/* Load specified glyph, replacing previously loaded glyph if necessary,
+   then return the index to glyph.  Note the index is within the range
+   of [0,255].  Return -1 if error. */
+set_glyph2(lc, c)
+     int lc, c;
+{
+  int code;
+  font_struct *fontp = &font[lc & 0x7F];
+  font_extra *ext = (font_extra *)fontp->extra;
+
+  if (!DEFINED2(lc, c)) {
+    if (bdf_load_glyph(lc, c, &glyph)) {
+      code = find_encoding(fontp, lc, c);
+      ps_newglyph(code, &glyph);
+    } else
+      return -1;
+  } else {
+    for (code = 0; code < 256; code++) {
+      if (ext->code[code] == c) break;
+    }
+    ext->new[code] = 1;
+    ext->count[code]++;
+  }
+  return code;
+}
+
+swap_buf(buf, from, to)
+     unsigned char *buf;
+     int from, to;
+{
+  int i, j;
+  unsigned char buf2[1024], *p = buf2;
+
+  i = j = to;
+  while (--i >= from) {
+    if (NONASCII_P(buf[i])) continue;
+    bcopy(buf + i, p, j - i);
+    p += j - i;
+    j = i;
+  }
+  bcopy(buf2, buf + from, to - from);
+}
+
+textmode()
+{
+  register int i, j, k, c, lc;
+  char buf[1024];		/* 92.11.6 by K.Shibata */
+  unsigned char line[1024], *p;
+  int cmp_flag = 0, len, r2l_chars;
+
+  ps_bot(); ps_bop();
+  clm = row = 0; current_lc = -1;
+  /* set_font(0); */
+  while ((len = get_line(line, 1024, stdin)) >= 0) { /* 93.6.4 by K.Shibata */
+    /* We should process line by line to handle r2l direction. */
+    j = 0; r2l_chars = 0;
+
+    /* At first, re-order characters of r2l direction. */
+    while (j < len) {
+      p = line + j;
+      if (*p <= 0x7F) {
+	lc = 0;
+	p++;
+      } else {
+	lc = *p++;
+	if (lc == LCCMP) lc = *p++ - 0x20;
+	if (lc >= LCPRV11) lc = *p++;
+      }
+      while (NONASCII_P(*p)) p++;
+      if (char_direction[lc]) {
+	if (!r2l_chars) k = j;
+	r2l_chars++;
+      } else {
+	if (r2l_chars > 1) 
+	  swap_buf(line, k, j);
+	r2l_chars = 0;
+      }
+      j = p - line;
+    }
+    if (r2l_chars > 1) swap_buf(line, k, j); /* 93.12.25 by K.Handa */
+
+    /* Then output characters. */
+    for (j = 0; j < len;) {
+      c = line[j];
+
+      if (c == LCCMP) {		/* start of composite characters */
+	cmp_flag = 1;
+	j++;
+	continue;
+      }
+      if (cmp_flag) {		/* composed characters have special encoding */
+	if (c == 0xA0) c = line[++j] & 0x7F;
+	else if (c > 0xA0) c -= 0x20;
+	else cmp_flag = 0;
+      }
+
+      if (c < 0x20 || c == 0x7F) { /* Control code */
+	switch (c) {
+	case '\t':
+	  i = 8 - (clm % 8);
+	  clm += i;
+	  set_font(0);
+	  if (set_glyph1(0, ' ') >= 0) {
+	    putchar('(');
+	    while (i--) putchar(' ');
+	    printf(") s ");
+	  }
+	  break;
+	case '\f': 
+	  ps_eop(), ps_bop();
+	  break;
+	default:
+	  if (c < ' ') control_char(c);
+	  else invalid_char(c);
+	}
+	j++;
+      } else if (c < 0x7F) {	/* ASCII */
+	set_font(0);
+	i = 0;
+	do {
+	  if ((c = set_glyph1(0, c)) >= 0) {
+	    if (c == '\\' || c == '(' || c == ')')
+	      buf[i++] = '\\', buf[i++] = c;
+	    else
+	      buf[i++] = c;
+	    clm++;
+	  }
+	  c = line[++j];
+	} while (!cmp_flag	/* process composite character one by one */
+		 && 0x20 <= c && c < 0x7F);
+	buf[i] = 0;
+	switch (cmp_flag) {
+	case 0:			/* not composite character */
+	  printf("(%s) s ", buf);
+	  break;
+	case 1:			/* first of composite character */
+	  printf("(%s) cs1 ", buf);
+	  cmp_flag = 2;
+	  break;
+	default:		/* case 2: rest of composite character*/
+	  if (font[0].relative_compose)
+	    printf("(%s) cs2 ", buf);
+	  else
+	    printf("(%s) cs3 ", buf);
+	}
+      } else if (c < LCINV) {	/* Multilingual character */
+	int cur_lc = c < LCPRV11 ? c : line[j + 1];
+	CCL_PROGRAM *ccl = x_ccl_programs[cur_lc & 0x7F];
+	unsigned char c1, c2;
+
+	set_font(cur_lc);
+	i = 0, lc = cur_lc;
+	while (1) {
+	  if (lc >= LCPRV11) lc = line[j + 1];
+	  if (lc != cur_lc)
+	    break;
+	  if (lc < LCJPOLD) c1 = 0, c2 = line[j + 1], j += 2;
+	  else if (lc < LCPRV11) c1 = line[j + 1], c2 = line[j + 2], j += 3;
+	  else if (lc < LCPRV21EXT) c1 = 0, c2 = line[j + 2], j += 3;
+	  else  c1 = line[j + 2], c2 = line[j + 3], j += 4;
+	  if (!ccl) {
+	    c = c1 * 256 + c2;
+	  } else {
+	    ccl->reg[0] = c1; ccl->reg[1] = c2;
+	    ccl_driver (ccl, NULL, NULL, 0, 0);
+	    c = ccl->reg[0] * 256 + ccl->reg[1];
+	  }
+	  if (current_lc != lc) {
+	    /* Font is not found.  Use ASCII to write the code. */
+	    c &= 0x7F;
+	    if (c >= ' ' && c <= 126)
+	      c = set_glyph1(0, c & 0x7F);
+	    else
+	      c = set_glyph1(0, ' ');
+	  } else if (char_type[lc] < TYPE94N)
+	    c = set_glyph1(lc, c);
+	  else
+	    c = set_glyph2(lc, c);
+	  if (c >= 0) {
+	    if (c == '\\' || c == '(' || c == ')')
+	      buf[i++] = '\\', buf[i++] = c;
+	    else if (c >= ' ' && c < 127)
+	      buf[i++] = c;
+	    else
+	      sprintf(buf + i, "\\%03o", c), i += 4;
+	    clm += lc < 0x90 || (lc >= LCPRV11EXT && lc < LCPRV21EXT) ? 1 : 2;
+	  }
+	  if (cmp_flag) break;
+	  lc = line[j];
+	}
+	buf[i] = 0;
+	switch (cmp_flag) {
+	case 0:
+	  printf("(%s) s ", buf);
+	  break;
+	case 1:
+	  printf("(%s) cs1 ", buf);
+	  cmp_flag = 2;
+	  break;
+	case 2:
+	default:
+	  if (font[lc & 0x7F].relative_compose)
+	    printf("(%s) cs2 ", buf);
+	  else
+	    printf("(%s) cs3 ", buf);
+	}
+	renew_font(cur_lc);
+      } else {
+	invalid_char(c);
+      }
+    }
+    printf("n\n");
+    row++, clm = 0;
+    if (row >= maxline) ps_eop(), ps_bop();
+  }
+
+  ps_eop();
+  ps_eot();
+}
+
+control_char(c)
+     int c;
+{
+  c += '@';
+  set_font(0);
+  if ((set_glyph1(0, '^') >= 0) && (set_glyph1(0, c) >= 0)) {
+    printf("(^%c) s ", c);
+    clm += 2;
+  }
+}    
+
+invalid_char(c)
+     int c;
+{
+  int i;
+
+  set_font(0);
+  if (set_glyph1(0, '\\') >= 0) {
+    for (i = '0'; i <= '9'; i++) {
+      if (set_glyph1(0, i) < 0) break;
+    }
+    if (i > '9') {
+      printf("(\\\\%03o) s ", c);
+      clm += 4;
+    }
+  }
+}
+
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+  register int i = 1;
+  char *bdf_path = NULL, *charsets = NULL;
+
+  while (i < argc) {
+    if (!strcmp(argv[i], "-ps") && (i + 1) < argc) {
+      psheader = argv[i + 1];
+      i += 2;
+    } else if (!strcmp(argv[i], "-fp") && (i + 1) < argc) {
+      bdf_path = argv[i + 1];
+      i += 2;
+    } else if (!strcmp(argv[i], "-cs") && (i + 1) < argc) {
+      charsets = argv[i + 1];
+      i += 2;
+    } else if (!strcmp(argv[i], "-dpi") && (i + 1) < argc) {
+      dpi = atoi(argv[i + 1]);
+      i += 2;
+    } else if (!strcmp(argv[i], "-fs") && (i + 1) < argc) {
+      fontscale = atoi(argv[i + 1]);
+      i += 2;
+    } else if (!strcmp(argv[i], "-lp") && (i + 1) < argc) {
+      linepitch = atoi(argv[i + 1]);
+      i += 2;
+    } else if (!strcmp(argv[i], "-ml") && (i + 1) < argc) {
+      maxline = atoi(argv[i + 1]);
+      i += 2;
+    } else if (!strcmp(argv[i], "-tm") && (i + 1) < argc) {
+      topmargin = atoi(argv[i + 1]);
+      i += 2;
+    } else if (!strcmp(argv[i], "-lm") && (i + 1) < argc) {
+      leftmargin = atoi(argv[i + 1]);
+      i += 2;
+    } else if (!strcmp(argv[i], "-sm")) {
+      shortmemory = 1;
+      i++;
+    } else if (!strcmp(argv[i], "-bm")) {
+      shortmemory = 0;
+      i++;
+    } else if (!strcmp(argv[i], "-a4") || !strcmp(argv[i], "-A4")) {
+      maxline = A4_MaxLine;
+      topmargin = A4_TopMargin;
+      i++;
+    } else if (!strcmp(argv[i], "-us") || !strcmp(argv[i], "-US")) {
+      maxline = US_MaxLine;
+      topmargin = US_TopMargin;
+      i++;
+    } else if (!strncmp(argv[i], "-ver", 4)) {
+      printf("m2ps Ver.%s\n", m2ps_version);
+      exit(0);
+    } else {
+      fprintf(stderr, "%s: Invalid argument: %s\n", argv[0], argv[i]);
+      exit(1);
+    }
+  }
+
+  mulelib_initialize(argc, argv, charsets, NULL);
+  bdf_initialize(bdf_path, 0);
+  textmode();
+  exit(0);
+}
+
+/*********************/
+/* PostScript staffs */
+/*********************/
+
+ps_bot()
+{
+  int c;
+  FILE *fp;
+
+  if ((fp = open_file(PATH_DATA, psheader)) == NULL)
+    fatal1("PostScript header file not found.");
+
+  while ((c = getc(fp)) != EOF) putchar(c);
+  fclose(fp);
+  printf("Mydict begin\n");
+  printf("/DPI %d def\n", dpi);
+  printf("/FontScale %d def\n", fontscale);
+  printf("/LinePitch %d def\n", linepitch);
+  printf("/TopMargin %d def\n", topmargin);
+  printf("/LeftMargin %d def\n", leftmargin);
+  printf("/ShortMemory %s def\n", (shortmemory ? "true" : "false"));
+}
+
+ps_eot()
+{
+  printf("end\n");
+}
+
+/* Define new PS font for a leading char LC.
+   No_cache flag is for the fonts be modified (replacing the glyphs, etc.)
+   at execution time. */
+ps_newfont(lc)
+     int lc;
+{
+  font_struct *fontp = &font[lc & 0x7F];
+
+  printf("/F%02x /FF%02x %d [%d %d %d %d] %d %s nf\n",
+	 lc, lc, ((font_extra *)fontp->extra)->fs,
+	 fontp->llx, fontp->lly - fontp->yoffset,
+	 fontp->urx, fontp->ury - fontp->yoffset,
+	 fontp->relative_compose,
+	 (fontp->bytes == 1 ? "true" : "false"));
+}
+
+ps_setfont(lc)
+     int lc;
+{
+  printf("F%02x f\n", lc);
+}
+
+ps_newglyph(encoding, glyph)
+     int encoding;
+     glyph_struct *glyph;
+{
+  char *bitmap = glyph->bitmap;
+
+  if (*bitmap == '\0')
+    bitmap = "00";
+
+  printf("/C%d%s[ %d %d %d %d %d %d %d %d %d <%s> ] g\n",
+	 encoding, (encoding < 10 ? "XX " : encoding < 100 ? "X " : " "),
+	 glyph->dwidth,
+	 glyph->bbox, glyph->bboy,
+	 glyph->bbw + glyph->bbox, glyph->bbh + glyph->bboy,
+	 glyph->bbw, glyph->bbh,
+	 glyph->bbox, glyph->bbh + glyph->bboy,
+	 bitmap);
+}
+
+ps_bop()
+{
+  int lc;
+
+  row = clm = 0;
+  printf("bp\n");
+  if (shortmemory) {
+    current_lc = -1;
+    for (lc = 0; lc < 256; lc++) { /* 93.5.7 by K.Handa */
+      if (FONT_LOADED (lc) == 1) FONT_LOADED (lc) = 0;
+    }
+  }
+}
+
+ps_eop()
+{
+  printf("ep\n");
+}