FreeType 1.31.1
This commit is contained in:
304
contrib/ttf2pk/parse.c
Normal file
304
contrib/ttf2pk/parse.c
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* parse.c
|
||||
*
|
||||
* This file is part of the ttf2pk package.
|
||||
*
|
||||
* Copyright 1997-1999 by
|
||||
* Frederic Loyer <loyer@ensta.fr>
|
||||
* Werner Lemberg <wl@gnu.org>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h> /* for size_t */
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ttf2tfm.h"
|
||||
#include "errormsg.h"
|
||||
#include "newobj.h"
|
||||
#include "ligkern.h"
|
||||
#include "texenc.h"
|
||||
#include "parse.h"
|
||||
#include "filesrch.h"
|
||||
|
||||
|
||||
/*
|
||||
* Here we get a token from the encoding file. We parse just as much
|
||||
* PostScript as we expect to find in an encoding file. We allow
|
||||
* commented lines and names like 0, .notdef, _foo_. We do not allow
|
||||
* //abc.
|
||||
*
|
||||
* `bufferp' is a pointer to the current line; the offset of the beginning
|
||||
* of the token to be parsed relative to `bufferp' will be returned in
|
||||
* `offsetp'. On the first call of gettoken() `init' must be set to 1 and
|
||||
* to 0 on the following calls.
|
||||
*
|
||||
* If `ignoreligkern' is `True', no LIGKERN data will be extracted from the
|
||||
* encoding file.
|
||||
*
|
||||
* Don't modify `bufferp'!
|
||||
*
|
||||
* The memory management of `bufferp' will be done by gettoken() itself;
|
||||
* nevertheless, it returns a pointer to the current token which should be
|
||||
* freed after it has been used.
|
||||
*/
|
||||
|
||||
static char *
|
||||
gettoken(char **bufferp, size_t *offsetp, FILE *f, Font *fnt,
|
||||
Boolean ignoreligkern, Boolean init)
|
||||
{
|
||||
char *p, *q;
|
||||
char tempchar;
|
||||
static char *curp;
|
||||
|
||||
|
||||
if (init)
|
||||
curp = NULL;
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (curp == NULL || *curp == '\0')
|
||||
{
|
||||
if (*bufferp)
|
||||
free(*bufferp);
|
||||
|
||||
if (getline(bufferp, f) == False)
|
||||
oops("Premature end in encoding file.");
|
||||
|
||||
curp = *bufferp;
|
||||
|
||||
for (p = *bufferp; *p; p++)
|
||||
if (*p == '%')
|
||||
{
|
||||
if (ignoreligkern == False)
|
||||
checkligkern(p, fnt);
|
||||
*p = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (isspace(*curp))
|
||||
curp++;
|
||||
|
||||
*offsetp = curp - *bufferp;
|
||||
|
||||
if (*curp)
|
||||
{
|
||||
if (*curp == '[' || *curp == ']' ||
|
||||
*curp == '{' || *curp == '}')
|
||||
q = curp++;
|
||||
else if (*curp == '/' ||
|
||||
*curp == '-' || *curp == '_' || *curp == '.' ||
|
||||
('0' <= *curp && *curp <= '9') ||
|
||||
('a' <= *curp && *curp <= 'z') ||
|
||||
('A' <= *curp && *curp <= 'Z'))
|
||||
{
|
||||
q = curp++;
|
||||
while (*curp == '-' || *curp == '_' || *curp == '.' ||
|
||||
('0' <= *curp && *curp <= '9') ||
|
||||
('a' <= *curp && *curp <= 'z') ||
|
||||
('A' <= *curp && *curp <= 'Z'))
|
||||
curp++;
|
||||
}
|
||||
else
|
||||
q = curp;
|
||||
|
||||
tempchar = *curp;
|
||||
*curp = '\0';
|
||||
p = newstring(q);
|
||||
*curp = tempchar;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This routine reads in an encoding file, given the name. It returns
|
||||
* the final total structure. It performs a number of consistency checks.
|
||||
*/
|
||||
|
||||
encoding *
|
||||
readencoding(char **enc, Font *fnt, Boolean ignoreligkern)
|
||||
{
|
||||
char *real_encname;
|
||||
FILE *enc_file;
|
||||
char *p, *q, c;
|
||||
char *buffer;
|
||||
char numbuf[9];
|
||||
size_t offset;
|
||||
int i;
|
||||
long l;
|
||||
encoding *e = (encoding *)mymalloc(sizeof (encoding));
|
||||
|
||||
|
||||
if (enc && *enc)
|
||||
{
|
||||
real_encname = TeX_search_encoding_file(enc);
|
||||
if (!real_encname)
|
||||
oops("Cannot find encoding file `%s'.", *enc);
|
||||
|
||||
enc_file = fopen(real_encname, "rt");
|
||||
if (enc_file == NULL)
|
||||
oops("Cannot open encoding file `%s'.", real_encname);
|
||||
|
||||
buffer = NULL;
|
||||
p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, True);
|
||||
if (*p != '/' || p[1] == '\0')
|
||||
boops(buffer, offset,
|
||||
"First token in encoding must be literal encoding name.");
|
||||
e->name = newstring(p + 1);
|
||||
free(p);
|
||||
|
||||
p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, False);
|
||||
if (strcmp(p, "["))
|
||||
boops(buffer, offset,
|
||||
"Second token in encoding must be mark ([) token.");
|
||||
free(p);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, False);
|
||||
if (*p != '/' || p[1] == 0)
|
||||
boops(buffer, offset,
|
||||
"Tokens 3 to 257 in encoding must be literal names.");
|
||||
|
||||
/* now we test for a generic code point resp. glyph index value */
|
||||
|
||||
c = p[2];
|
||||
if (p[1] == '.' && (c == 'c' || c == 'g') && '0' <= p[3] && p[3] <= '9')
|
||||
{
|
||||
l = strtol(p + 3, &q, 0);
|
||||
if (*q != '\0' || l < 0 || l > 0xFFFF)
|
||||
boops(buffer, offset, "Invalid encoding token.");
|
||||
sprintf(numbuf, ".%c0x%x", c, (unsigned int)l);
|
||||
e->vec[i] = newstring(numbuf);
|
||||
}
|
||||
else
|
||||
e->vec[i] = newstring(p + 1);
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, False);
|
||||
if (strcmp(p, "]"))
|
||||
boops(buffer, offset,
|
||||
"Token 258 in encoding must be make-array (]).");
|
||||
free(p);
|
||||
|
||||
while (getline(&buffer, enc_file))
|
||||
{
|
||||
for (p = buffer; *p; p++)
|
||||
if (*p == '%')
|
||||
{
|
||||
if (ignoreligkern == False)
|
||||
checkligkern(p, fnt);
|
||||
*p = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(enc_file);
|
||||
|
||||
if (ignoreligkern == False && fnt->sawligkern == False)
|
||||
getligkerndefaults(fnt);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ignoreligkern == False)
|
||||
{
|
||||
e = &staticencoding;
|
||||
getligkerndefaults(fnt);
|
||||
}
|
||||
else
|
||||
e = NULL;
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We scan a glyph replacement file.
|
||||
* `%' is the comment character.
|
||||
*/
|
||||
|
||||
void
|
||||
get_replacements(Font *fnt)
|
||||
{
|
||||
char *real_replacement_name;
|
||||
FILE *replacement_file;
|
||||
char *buffer = NULL, *oldbuffer = NULL;
|
||||
char *p;
|
||||
char *old_name, *new_name;
|
||||
stringlist *sl;
|
||||
|
||||
|
||||
if (!fnt->replacementname)
|
||||
return;
|
||||
|
||||
real_replacement_name = TeX_search_replacement_file(&fnt->replacementname);
|
||||
if (!real_replacement_name)
|
||||
oops("Cannot find replacement file `%s'.", fnt->replacementname);
|
||||
|
||||
replacement_file = fopen(real_replacement_name, "rt");
|
||||
if (replacement_file == NULL)
|
||||
oops("Cannot open replacement file `%s'.", real_replacement_name);
|
||||
|
||||
while (getline(&buffer, replacement_file))
|
||||
{
|
||||
for (p = buffer; *p; p++)
|
||||
if (*p == '%')
|
||||
{
|
||||
*p = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
if (oldbuffer)
|
||||
free(oldbuffer);
|
||||
oldbuffer = newstring(buffer);
|
||||
|
||||
p = buffer;
|
||||
|
||||
while (isspace(*p))
|
||||
p++;
|
||||
if (!*p)
|
||||
continue;
|
||||
|
||||
old_name = p;
|
||||
|
||||
while (*p && !isspace(*p))
|
||||
p++;
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
|
||||
while (*p && isspace(*p))
|
||||
p++;
|
||||
if (!*p)
|
||||
boops(oldbuffer, old_name - oldbuffer, "Replacement glyph missing.");
|
||||
|
||||
new_name = p;
|
||||
|
||||
while (*p && !isspace(*p))
|
||||
p++;
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
|
||||
while (*p && isspace(*p))
|
||||
p++;
|
||||
if (*p)
|
||||
boops(oldbuffer, p - oldbuffer, "Invalid replacement syntax.");
|
||||
|
||||
sl = newstringlist();
|
||||
sl->new_name = newstring(new_name);
|
||||
sl->old_name = newstring(old_name);
|
||||
sl->next = fnt->replacements;
|
||||
fnt->replacements = sl;
|
||||
}
|
||||
|
||||
fclose(replacement_file);
|
||||
}
|
||||
|
||||
|
||||
/* end */
|
||||
Reference in New Issue
Block a user