summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdfm/pkfont.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvipdfm/pkfont.c')
-rw-r--r--Build/source/texk/dvipdfm/pkfont.c620
1 files changed, 0 insertions, 620 deletions
diff --git a/Build/source/texk/dvipdfm/pkfont.c b/Build/source/texk/dvipdfm/pkfont.c
deleted file mode 100644
index b0fd8b94583..00000000000
--- a/Build/source/texk/dvipdfm/pkfont.c
+++ /dev/null
@@ -1,620 +0,0 @@
-/* $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 <stdio.h>
-#include "system.h"
-#include "mem.h"
-#include "error.h"
-#include "mfileio.h"
-#include "numbers.h"
-#include "pkfont.h"
-#include "pdfobj.h"
-#include "pdflimits.h"
-#include "tfm.h"
-#include "ctype.h"
-
-pdf_obj *pk_encoding_ref = NULL;
-static unsigned char verbose = 0, debug = 0;
-static unsigned font_dpi = 600;
-
-void pk_set_verbose(void)
-{
- if (verbose < 255) {
- verbose += 1;
- }
-}
-
-void pk_set_dpi (int dpi)
-{
- font_dpi = dpi;
-}
-
-
-static void make_pk_encoding_ref (void)
-{
- static char first = 1;
- if (first) {
- int i;
- pdf_obj *encoding, *differences;
- encoding = pdf_new_dict();
- pdf_add_dict (encoding,
- pdf_new_name ("Type"),
- pdf_new_name ("Encoding"));
- differences = pdf_new_array();
- pdf_add_dict (encoding,
- pdf_new_name ("Differences"),
- differences);
- pdf_add_array (differences, pdf_new_number (0.0));
- for (i=0; i<256; i++) {
- sprintf (work_buffer, "x%x", i);
- pdf_add_array (differences, pdf_new_name(work_buffer));
- }
- pk_encoding_ref = pdf_ref_obj (encoding);
- pdf_release_obj (encoding);
- }
- first = 0;
- return;
-}
-
-static void release_pk_encoding_ref (void)
-{
- pdf_release_obj (pk_encoding_ref);
-}
-
-struct a_pk_font
-{
- pdf_obj *direct, *indirect;
- char *tex_name, *pk_file_name;
- double ptsize;
- char *used_chars;
-} *pk_fonts;
-
-void init_pk_record (struct a_pk_font *p)
-{
- int i;
- p->used_chars = NEW (256, char);
- for (i=0; i<256; i++) {
- (p->used_chars)[i] = 0;
- }
- p->tex_name = NULL;
- p->pk_file_name = NULL;
-}
-
-
-int num_pk_fonts = 0, max_pk_fonts = 0;
-
-int pk_font (const char *tex_name, double ptsize, int tfm_font_id, char
- *res_name)
-{
- int i, j;
- int firstchar, lastchar;
- pdf_obj *tmp1;
- for (i=0; i<num_pk_fonts; i++) {
- if (!strcmp (tex_name, pk_fonts[i].tex_name) &&
- (ptsize == pk_fonts[i].ptsize))
- break;
- }
- if (i == num_pk_fonts) {
- char *pk_file_name;
- kpse_glyph_file_type kpse_file_info;
- if ((pk_file_name = kpse_find_glyph(tex_name,
- font_dpi*ptsize/tfm_get_design_size(tfm_font_id)+0.5,
- kpse_pk_format,
- &kpse_file_info))) {
- /* Make sure there is enough room in pk_fonts for this entry */
- if (num_pk_fonts >= max_pk_fonts) {
- max_pk_fonts += MAX_FONTS;
- pk_fonts = RENEW (pk_fonts, max_pk_fonts, struct a_pk_font);
- }
- init_pk_record (pk_fonts+i);
- pk_fonts[i].pk_file_name = NEW (strlen(pk_file_name)+1, char);
- strcpy (pk_fonts[i].pk_file_name, pk_file_name);
- pk_fonts[i].tex_name = NEW (strlen (tex_name)+1, char);
- strcpy (pk_fonts[i].tex_name, tex_name);
- pk_fonts[i].ptsize = ptsize;
- pk_fonts[i].direct = pdf_new_dict ();
- pdf_add_dict (pk_fonts[i].direct,
- pdf_new_name ("Type"),
- pdf_new_name ("Font"));
- pdf_add_dict (pk_fonts[i].direct,
- pdf_new_name ("Name"),
- pdf_new_name (res_name));
- pdf_add_dict (pk_fonts[i].direct,
- pdf_new_name ("Subtype"),
- pdf_new_name ("Type3"));
- firstchar = tfm_get_firstchar(tfm_font_id);
- pdf_add_dict (pk_fonts[i].direct,
- pdf_new_name ("FirstChar"),
- pdf_new_number (firstchar));
- lastchar = tfm_get_lastchar(tfm_font_id);
- pdf_add_dict (pk_fonts[i].direct,
- pdf_new_name ("LastChar"),
- pdf_new_number (lastchar));
- tmp1 = pdf_new_array ();
- for (j=firstchar; j<=lastchar; j++) {
- pdf_add_array (tmp1,
- pdf_new_number(ROUND(tfm_get_width (tfm_font_id, j)*1000.0,0.01)));
- }
- pdf_add_dict (pk_fonts[i].direct,
- pdf_new_name ("Widths"),
- tmp1);
- {
- double max_height, max_depth, max_width;
- max_height = tfm_get_max_height (tfm_font_id)*1000.0;
- max_depth = tfm_get_max_depth (tfm_font_id)*1000.0;
- max_width = tfm_get_max_width (tfm_font_id)*1000.0;
- max_height = ROUND(max_height, 1.0);
- max_depth = ROUND(max_depth, 1.0);
- max_width = ROUND(max_width, 1.0);
- tmp1 = pdf_new_array();
- pdf_add_array (tmp1, pdf_new_number(-0.10*max_width));
- pdf_add_array (tmp1,
- pdf_new_number(-max_depth-0.20*(max_height+max_depth)));
- pdf_add_array (tmp1, pdf_new_number(1.10*max_width));
- pdf_add_array (tmp1, pdf_new_number(max_height+0.10*(max_height+max_depth)));
- pdf_add_dict (pk_fonts[i].direct,
- pdf_new_name ("FontBBox"), tmp1);
- }
- {
- tmp1 = pdf_new_array();
- pdf_add_array (tmp1, pdf_new_number (0.001));
- pdf_add_array (tmp1, pdf_new_number (0.0));
- pdf_add_array (tmp1, pdf_new_number (0.0));
- pdf_add_array (tmp1, pdf_new_number (0.001));
- pdf_add_array (tmp1, pdf_new_number (0.0));
- pdf_add_array (tmp1, pdf_new_number (0.0));
- pdf_add_dict (pk_fonts[i].direct, pdf_new_name ("FontMatrix"),
- tmp1);
- }
- if (pk_encoding_ref == NULL) {
- make_pk_encoding_ref();
- }
- pdf_add_dict (pk_fonts[i].direct,
- pdf_new_name ("Encoding"),
- pdf_link_obj (pk_encoding_ref));
- pk_fonts[i].indirect = pdf_ref_obj (pk_fonts[i].direct);
- num_pk_fonts += 1;
- } else { /* Found no glyph file */
- i = -1;
- }
- }
- return i;
-}
-
-pdf_obj *pk_font_resource (int pk_id)
-{
- if (pk_id <0 || pk_id >= num_pk_fonts) {
- fprintf (stderr, "pk_id = %d\n", pk_id);
- ERROR ("pk_font_resource: Invalid pk_id\n");
- }
- return pdf_link_obj (pk_fonts[pk_id].indirect);
-}
-
-char *pk_font_used (int pk_id)
-{
- if (pk_id < 0 || pk_id >= num_pk_fonts) {
- fprintf (stderr, "pk_id = %d\n", pk_id);
- ERROR ("pk_font_used: Invalid pk_id\n");
- }
- return pk_fonts[pk_id].used_chars;
-}
-
-
-static FILE *pk_file;
-
-static void do_skip(unsigned long length)
-{
- unsigned long i;
- for (i=0; i<length; i++)
- fgetc (pk_file);
- return;
-}
-
-static void add_raster_data (pdf_obj *glyph, long w, long h,
- int dyn_f, int run_color,
- unsigned char *pk_data,
- unsigned char *eod)
-
- /* First define some macros to be used as "in-line" functions */
-#define advance_nybble() \
-{ \
- if (partial_byte) { \
- partial_byte=0; \
- pk_data++; \
- } else \
- partial_byte=1; \
-}
-
-#define current_nybble() (partial_byte? (*pk_data%16): (*pk_data/16))
-#define set_bits(n) {\
- int i; \
- for (i=0; i<(n); i++) { \
- row[next_col] |= (128u>>next_bit++); \
- if (next_bit > 7) { \
- next_bit = 0; \
- next_col += 1; \
- } \
- } \
-}
-
-#define skip_bits(n) {\
- next_col += (n)/8; \
- next_bit += (n)%8; \
- if (next_bit > 7) { \
- next_bit -= 8; \
- next_col += 1; \
- } \
-}
-
-#define get_bit(p,n) (p[(n)/8] & (128u>>((n)%8)))
-
-{
- long i, w_bytes, repeat_count, run_count = 0;
- int partial_byte = 0;
- unsigned char *row;
- w_bytes = (w%8 == 0)? w/8: (w/8+1);
- row = NEW (w_bytes, unsigned char);
- /* Make sure we output "h" rows of data */
- if (dyn_f == 14) {
- for (i=0; i<h; i++) {
- int next_col = 0, next_bit = 0;
- int j;
- for (j=0; j<w_bytes; j++) row[j] = 0;
- for (j=0; j<w; j++) {
- if (get_bit(pk_data,i*w+j)) {
- skip_bits(1);
- }
- else {
- set_bits(1);
- }
- }
- pdf_add_stream (glyph, (char *) row, w_bytes);
- }
- } else
- for (i=0; i<h; i++) {
- int next_col = 0, next_bit = 0;
- int j, row_bits_left = w;
- /* Initialize row to all zeros */
- for (j=0; j<w_bytes; j++) row[j] = 0;
- repeat_count = 0;
- /* Fill any run left over from previous rows */
- if (run_count != 0) {
- int nbits;
- nbits = MIN (w, run_count);
- run_count -= nbits;
- switch (run_color) {
- case 1: /* This is actually white ! */
- set_bits(nbits);
- break;
- case 0:
- skip_bits(nbits);
- break;
- }
- row_bits_left -= nbits;
- }
- /* Read nybbles until we have a full row */
- while (pk_data < eod && row_bits_left>0) {
- int com_nyb;
- long packed = 0;
- com_nyb = current_nybble();
- if (com_nyb == 15) {
- repeat_count = 1;
- advance_nybble();
- continue;
- }
- if (com_nyb == 14) {
- advance_nybble();
- }
- /* Get a packed number */
- {
- int nyb;
- nyb = current_nybble();
- /* Test for single nybble case */
- if (nyb > 0 && nyb <= dyn_f) {
- packed = nyb;
- advance_nybble();
- }
- if (nyb > dyn_f) {
- advance_nybble();
- packed = (nyb-dyn_f-1)*16+current_nybble()+dyn_f+1;
- advance_nybble();
- }
- if (nyb == 0) {
- int nnybs = 1;
- while (current_nybble() == 0) {
- advance_nybble();
- nnybs += 1;
- }
- packed = 0;
- while (nnybs) {
- packed = packed*16 + current_nybble();
- advance_nybble();
- nnybs -= 1;
- }
- packed += (13-dyn_f)*16-15+dyn_f;
- }
- }
- if (com_nyb == 14) {
- repeat_count = packed;
- continue;
- }
- {
- int nbits;
- run_count = packed;
- run_color = !run_color;
- nbits = MIN (row_bits_left, run_count);
- run_count -= nbits;
- row_bits_left -= nbits;
- switch (run_color) {
- case 1:
- set_bits(nbits);
- break;
- case 0:
- skip_bits(nbits);
- break;
- }
- }
- continue;
- }
- pdf_add_stream (glyph, (char *) row, w_bytes);
- /* Duplicate the row "repeat_count" times */
- for (j=0; j<repeat_count; j++) {
- pdf_add_stream (glyph, (char *) row, w_bytes);
- }
- /* Skip repeat_count interations */
- i += repeat_count;
- }
- RELEASE (row);
-}
-
-static void do_preamble(void)
-{
- /* Check for id byte */
- if (fgetc (pk_file) == 89) {
- /* Skip comment */
- do_skip (get_unsigned_byte (pk_file));
- /* Skip other header info. It's normally used for verifying this
- is the file wethink it is */
- do_skip (16);
- } else {
- ERROR ("embed_pk_font: PK ID byte is incorrect. Are you sure this is a PK file?");
- }
- return;
-}
-
-#define SHORT_FORM 1
-#define MED_FORM 2
-#define LONG_FORM 3
-static void do_character (unsigned char flag, int pk_id, pdf_obj *char_procs)
-{
- int format;
- unsigned long packet_length = 0, code = 0;
- /* Last three bits of flag determine packet size in a complex way */
- if ((flag & 4) == 0) {
- format = SHORT_FORM;
- } else if ((flag & 7) == 7) {
- format = LONG_FORM;
- } else {
- format = MED_FORM;
- }
- if (debug) {
- fprintf (stderr, "packet format: %d\n", format);
- }
- switch (format) {
- case SHORT_FORM:
- packet_length = (flag & 3) * 256u + get_unsigned_byte (pk_file);
- code = get_unsigned_byte (pk_file);
- break;
- case MED_FORM:
- packet_length = (flag & 3) * 65536ul + get_unsigned_pair(pk_file);
- code = get_unsigned_byte (pk_file);
- break;
- case LONG_FORM:
- packet_length = get_unsigned_quad (pk_file);
- code = get_unsigned_quad (pk_file);
- if (code > 255)
- ERROR ("Unable to handle long characters in PK files");
- break;
- }
- if (debug) {
- fprintf (stderr, "\npk_do_character: code=%lu, packet_length=%lu\n",
- code, packet_length);
- }
- if ((pk_fonts[pk_id].used_chars)[code%256]) {
- int dyn_f;
- unsigned long tfm_width = 0;
- long dm=0, dx=0, dy=0, w=0, h=0;
- int hoff=0, voff=0;
- dyn_f = flag/16;
- switch (format) {
- case SHORT_FORM:
- tfm_width = get_unsigned_triple (pk_file);
- dm = get_unsigned_byte (pk_file);
- w = get_unsigned_byte (pk_file);
- h = get_unsigned_byte (pk_file);
- hoff = get_signed_byte (pk_file);
- voff = get_signed_byte (pk_file);
- packet_length -= 8;
- break;
- case MED_FORM:
- tfm_width = get_unsigned_triple (pk_file);
- dm = get_unsigned_pair (pk_file);
- w = get_unsigned_pair (pk_file);
- h = get_unsigned_pair (pk_file);
- hoff = get_signed_pair (pk_file);
- voff = get_signed_pair (pk_file);
- packet_length -= 13;
- break;
- case LONG_FORM:
- tfm_width = get_signed_quad (pk_file);
- dx = get_signed_quad (pk_file);
- dy = get_signed_quad (pk_file);
- w = get_signed_quad (pk_file);
- h = get_signed_quad (pk_file);
- hoff = get_signed_quad (pk_file);
- voff = get_signed_quad (pk_file);
- packet_length -= 28;
- break;
- }
- {
- pdf_obj *glyph;
- double char_width, llx, lly, urx, ury;
- double pix2charu;
- int len;
- pix2charu = 72000.0/((double) font_dpi)/pk_fonts[pk_id].ptsize;
- char_width = tfm_width / (double) (1<<20) * 1000.0;
- char_width = ROUND (char_width, 0.01);
- llx = -hoff*pix2charu;
- lly = (voff-h)*pix2charu;
- urx = (w-hoff)*pix2charu;
- ury = voff*pix2charu;
- glyph = pdf_new_stream(STREAM_COMPRESS);
- /* The following line is a "metric" for the PDF reader */
- sprintf (work_buffer, "%.2f %.2f %.2f %.2f %.2f %.2f d1",
- char_width, 0.0,
- llx, lly, urx, ury);
- len = strlen (work_buffer);
- pdf_add_stream (glyph, work_buffer, len);
- /* For now add an outline box for debugging purposes */
- /* len = sprintf (work_buffer, " %.2f %.2f m %.2f %.2f l %.2f %.2f l %.2f %.2f l s",
- llx, lly, urx, lly, urx, ury, llx, ury);
- pdf_add_stream (glyph, work_buffer, len); */
- /* Scale and translate origin to lower left corner for raster data */
- sprintf (work_buffer, " q %.2f 0 0 %.2f %.2f %.2f cm",
- w*pix2charu, h*pix2charu, llx, lly);
- len = strlen (work_buffer);
- pdf_add_stream (glyph, work_buffer, len);
- if (w != 0 && h != 0 && packet_length != 0) {
- unsigned char *pk_data;
- long read_len;
- sprintf (work_buffer, "\nBI\n/W %ld\n/H %ld\n/IM true\n/BPC 1\n/I true\n", w, h);
- len = strlen (work_buffer);
- pdf_add_stream (glyph, work_buffer, len);
- sprintf (work_buffer, "ID ");
- len = strlen (work_buffer);
- pdf_add_stream (glyph, work_buffer, len);
- pk_data = NEW (packet_length, unsigned char);
- if ((read_len=fread (pk_data, 1, packet_length, pk_file))!=
- packet_length) {
- fprintf (stderr, "packet length should be %ld, but only %ld bytes were read\n",
- packet_length, read_len);
- ERROR ("Error reading character packet from PK file\n");
- }
- add_raster_data (glyph, w, h, dyn_f, (flag&8)>>3, pk_data, pk_data+packet_length);
- RELEASE (pk_data);
- sprintf (work_buffer, "\nEI");
- len = strlen (work_buffer);
- pdf_add_stream (glyph, work_buffer, len);
- } /* Otherwise we embed an empty stream :-( */
- sprintf (work_buffer, "\nQ");
- len = strlen (work_buffer);
- pdf_add_stream (glyph, work_buffer, len);
- sprintf (work_buffer, "x%x", (int)code%256);
- pdf_add_dict (char_procs, pdf_new_name (work_buffer),
- pdf_ref_obj (glyph));
- pdf_release_obj (glyph);
- }
- } else {
- if (debug)
- fprintf (stderr, "\npk_do_character: Skipping code=%ld, length=%ld\n", code,
- packet_length);
- do_skip (packet_length);
- }
-}
-
-#define PK_XXX1 240
-#define PK_XXX2 241
-#define PK_XXX3 242
-#define PK_XXX4 243
-#define PK_YYY 244
-#define PK_POST 245
-#define PK_NO_OP 246
-#define PK_PRE 247
-
-static void embed_pk_font (int pk_id)
-{
- if (verbose)
- fprintf (stderr, "(%s", pk_fonts[pk_id].pk_file_name);
- if ((pk_file = MFOPEN (pk_fonts[pk_id].pk_file_name,
- FOPEN_RBIN_MODE))) {
- int pk_command_byte;
- pdf_obj *char_procs;
- char_procs = pdf_new_dict();
- while ((pk_command_byte = fgetc(pk_file)) >= 0 &&
- pk_command_byte != PK_POST) {
- if (pk_command_byte < 240) {
- do_character (pk_command_byte, pk_id, char_procs);
- } else /* A command byte */
- switch (pk_command_byte) {
- case PK_NO_OP:
- break;
- case PK_XXX1:
- do_skip(get_unsigned_byte(pk_file));
- break;
- case PK_XXX2:
- do_skip(get_unsigned_pair(pk_file));
- break;
- case PK_XXX3:
- do_skip(get_unsigned_triple(pk_file));
- break;
- case PK_XXX4:
- do_skip(get_unsigned_quad(pk_file));
- break;
- case PK_YYY:
- do_skip(4);
- break;
- case PK_PRE:
- do_preamble();
- break;
- }
- }
- MFCLOSE (pk_file);
- if (verbose)
- fprintf (stderr, ")\n");
- pdf_add_dict (pk_fonts[pk_id].direct,
- pdf_new_name ("CharProcs"),
- pdf_ref_obj(char_procs));
- pdf_release_obj (char_procs);
- } else {
- ERROR ("embed_pk_font: Failed to open PK file");
- }
-}
-
-void pk_close_all (void)
-{
- int i;
- if (pk_encoding_ref)
- pdf_release_obj (pk_encoding_ref);
- for (i=0; i<num_pk_fonts; i++) {
- embed_pk_font (i);
- pdf_release_obj (pk_fonts[i].direct);
- pdf_release_obj (pk_fonts[i].indirect);
- RELEASE (pk_fonts[i].tex_name);
- RELEASE (pk_fonts[i].pk_file_name);
- RELEASE (pk_fonts[i].used_chars);
- }
- if (pk_fonts)
- RELEASE (pk_fonts);
-}
-