diff options
author | Martin Schröder <martin@oneiros.de> | 2008-03-24 15:47:15 +0000 |
---|---|---|
committer | Martin Schröder <martin@oneiros.de> | 2008-03-24 15:47:15 +0000 |
commit | 0b5550c241229764120d133af80a0cbab5937ddd (patch) | |
tree | 81309c18d6f0deba7407813cf15b9add2db375d1 /Build/source/texk/web2c/luatexdir/font/subfont.c | |
parent | 51f55df6a36ce376952a1f2b30bdb4dd0e06548d (diff) |
First step of importing luatex (up to r1121)
git-svn-id: svn://tug.org/texlive/trunk@7124 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/font/subfont.c')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/subfont.c | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/font/subfont.c b/Build/source/texk/web2c/luatexdir/font/subfont.c new file mode 100644 index 00000000000..836985c10fd --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/font/subfont.c @@ -0,0 +1,264 @@ +/* +Copyright (c) 2005-2006 Han The Thanh, <thanh@pdftex.org> + +This file is part of pdfTeX. + +pdfTeX 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. + +pdfTeX 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 pdfTeX; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ptexlib.h" +#include <string.h> + +static struct avl_table *sfd_tree = NULL; + +static unsigned char *sfd_buffer = NULL; +static integer sfd_size = 0; +static integer sfd_curbyte = 0; + +#define SFD_BUF_SIZE SMALL_BUF_SIZE + +#define sfd_close() xfclose(sfd_file, cur_file_name) +#define sfd_open() open_input(&sfd_file, kpse_sfd_format, FOPEN_RBIN_MODE) + +#define sfd_read_file() readbinfile(sfd_file,&sfd_buffer,&sfd_size) +#define sfd_getchar() sfd_buffer[sfd_curbyte++] +#define sfd_eof() (sfd_curbyte>sfd_size) + + +static FILE *sfd_file; +static char sfd_line[SFD_BUF_SIZE]; + +static subfont_entry *new_subfont_entry (void) +{ + int i; + subfont_entry *subfont; + subfont = xtalloc (1, subfont_entry); + subfont->infix = NULL; + for (i = 0; i < 256; ++i) + subfont->charcodes[i] = -1; /* unassigned */ + subfont->next = NULL; + return subfont; +} + +static sfd_entry *new_sfd_entry (void) +{ + sfd_entry *sfd; + sfd = xtalloc (1, sfd_entry); + sfd->name = NULL; + sfd->subfont = NULL; + return sfd; +} + +static void destroy_sfd_entry (void *pa, void *pb) +{ + subfont_entry *p, *q; + sfd_entry *sfd; + sfd = (sfd_entry *) pa; + p = sfd->subfont; + while (p != NULL) { + q = p->next; + xfree (p->infix); + xfree (p); + p = q; + } + xfree (sfd->name); +} + +static int comp_sfd_entry (const void *pa, const void *pb, void *p) +{ + return strcmp (((const sfd_entry *) pa)->name, + ((const sfd_entry *) pb)->name); +} + +void sfd_free (void) +{ + if (sfd_tree != NULL) + avl_destroy (sfd_tree, destroy_sfd_entry); +} + +static void sfd_getline (boolean expect_eof) +{ + char *p; + int c; + restart: + if (sfd_eof ()) { + if (expect_eof) + return; + else + pdftex_fail ("unexpected end of file"); + } + p = sfd_line; + do { + c = sfd_getchar (); + append_char_to_buf (c, p, sfd_line, SFD_BUF_SIZE); + } while (c != 10 && !sfd_eof()); + append_eol (p, sfd_line, SFD_BUF_SIZE); + if (p - sfd_line < 2 || *sfd_line == '#') + goto restart; +} + +static sfd_entry *read_sfd (char *sfd_name) +{ + void **aa; + sfd_entry *sfd, tmp_sfd; + subfont_entry *sf; + char *ftemp = NULL; + char buf[SMALL_BUF_SIZE], *p; + long int i, j, k; + int n; + int callback_id=0; + int file_opened=0; + /* check whether this sfd has been read */ + tmp_sfd.name = sfd_name; + if (sfd_tree == NULL) { + sfd_tree = avl_create (comp_sfd_entry, NULL, &avl_xallocator); + assert (sfd_tree != NULL); + } + sfd = (sfd_entry *) avl_find (sfd_tree, &tmp_sfd); + if (sfd != NULL) + return sfd; + set_cur_file_name (sfd_name); + if (sfd_buffer!=NULL) { + xfree(sfd_buffer); + sfd_buffer=NULL; + } + sfd_curbyte=0; + sfd_size=0; + + callback_id=callback_defined(find_sfd_file_callback); + if (callback_id>0) { + if(run_callback(callback_id,"S->S",cur_file_name,&ftemp)) { + if(ftemp!=NULL&&strlen(ftemp)) { + if (cur_file_name) + free(cur_file_name); + cur_file_name = xstrdup(ftemp); + free(ftemp); + } + } + } + callback_id=callback_defined(read_sfd_file_callback); + if (callback_id>0) { + if(! (run_callback(callback_id,"S->bSd",cur_file_name, + &file_opened, &sfd_buffer,&sfd_size) && + file_opened && + sfd_size>0 ) ) { + pdftex_warn ("cannot open SFD file for reading"); + cur_file_name = NULL; + return NULL; + } + sfd_read_file(); + sfd_close(); + } + tex_printf ("{"); + tex_printf (cur_file_name); + sfd = new_sfd_entry (); + sfd->name = xstrdup (sfd_name); + while (!sfd_eof ()) { + sfd_getline (true); + if (*sfd_line == 10) /* empty line indicating eof */ + break; + sf = new_subfont_entry (); + sf->next = sfd->subfont; + sfd->subfont = sf; + sscanf (sfd_line, "%s %n", buf, &n); + sf->infix = xstrdup (buf); + p = sfd_line + n; /* skip to the next word */ + k = 0; + read_ranges: + for (;;) { + if (*p == '\\') { /* continue on next line */ + sfd_getline (false); + p = sfd_line; + goto read_ranges; + } else if (*p == 0) /* end of subfont */ + break; + if (sscanf (p, " %li %n", &i, &n) == 0) + pdftex_fail ("invalid token:\n%s", p); + p += n; + if (*p == ':') { /* offset */ + k = i; + p++; + } else if (*p == '_') { /* range */ + if (sscanf (p + 1, " %li %n", &j, &n) == 0) + pdftex_fail ("invalid token:\n%s", p); + if (i > j || k + (j - i) > 255) + pdftex_fail ("invalid range:\n%s", p); + while (i <= j) + sf->charcodes[k++] = i++; + p += n + 1; + } else /* codepoint */ + sf->charcodes[k++] = i; + } + } + tex_printf ("}"); + aa = avl_probe (sfd_tree, sfd); + assert (aa != NULL); + return sfd; +} + +boolean handle_subfont_fm (fm_entry * fm, int mode) +{ + size_t l; + char *p, *q, *r; + sfd_entry *sfd; + subfont_entry *sf; + fm_entry *fm2; + char buf[SMALL_BUF_SIZE]; + assert (fm->tfm_name != NULL); + p = fm->tfm_name; + q = strchr (p, '@'); /* search for the first '@' */ + if (q == NULL) + return false; + r = strchr (q + 1, '@'); /* search for the second '@' */ + if (r == NULL) + return false; + if (q <= p || r <= q + 1 /* prefix or sfd name is empty */ + || r - p != strlen (p) - 1) /* or the second '@' is not the last char yet */ + return false; + l = r - (q + 1); /* length of sfd name */ + strncpy (buf, q + 1, l); + buf[l] = 0; + check_buf(strlen(buf) + 4, SMALL_BUF_SIZE); + strcat (buf, ".sfd"); + sfd = read_sfd (buf); + if (sfd == NULL) + return false; + /* at this point we know fm is a subfont */ + set_subfont (fm); + xfree (fm->ps_name); + fm->ps_name = NULL; + /* set default values for PidEid */ + if (fm->pid == -1) { + fm->pid = 3; + fm->eid = 1; + } + l = q - p; /* length of base tfm name (prefix) */ + for (sf = sfd->subfont; sf != NULL; sf = sf->next) { + strncpy (buf, p, l); + buf[l] = 0; + strcat (buf, sf->infix); + fm2 = new_fm_entry (); + fm2->tfm_name = xstrdup (buf); + fm2->ff_name = xstrdup (fm->ff_name); + fm2->type = fm->type; + fm2->pid = fm->pid; + fm2->eid = fm->eid; + fm2->subfont = sf; + if (avl_do_entry (fm2, mode) != 0) /* try to insert the entry */ + delete_fm_entry (fm2); /* delete it if failed */ + } + delete_fm_entry (fm); + return true; +} |