From 0f6aea154580c2f220be98d12108dd7d316c21f6 Mon Sep 17 00:00:00 2001 From: marha Date: Tue, 10 May 2011 13:17:13 +0000 Subject: libfontenc pixman mesa git update 10 May 2011 --- libfontenc/src/encparse.c | 1895 +++++++++++++-------------- mesalib/src/glsl/glcpp/glcpp-parse.y | 4 + mesalib/src/glsl/glsl_parser_extras.cpp | 8 + mesalib/src/glsl/glsl_parser_extras.h | 2 + mesalib/src/mesa/main/extensions.c | 2 +- mesalib/src/mesa/main/mtypes.h | 1 + mesalib/src/mesa/program/ir_to_mesa.cpp | 13 +- mesalib/src/mesa/program/prog_instruction.h | 28 +- pixman/configure.ac | 5 + pixman/test/utils.c | 2 +- 10 files changed, 994 insertions(+), 966 deletions(-) diff --git a/libfontenc/src/encparse.c b/libfontenc/src/encparse.c index 675fc740b..3fe94e8c0 100644 --- a/libfontenc/src/encparse.c +++ b/libfontenc/src/encparse.c @@ -1,948 +1,947 @@ -/* -Copyright (c) 1998-2001 by Juliusz Chroboczek - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -/* Parser for encoding files */ - -/* This code assumes that we are using ASCII. We don't use the ctype - functions, as they depend on the current locale. On the other - hand, we do use strcasecmp, but only on strings that we've checked - to be pure ASCII. Bloody ``Code Set Independence''. */ - -#include -#include - -#if defined(__SCO__) || defined(__UNIXWARE__) -#include -#endif - -#include - -#include "zlib.h" -typedef gzFile FontFilePtr; -#define FontFileGetc(f) gzgetc(f) -#define FontFileOpen(filename) gzopen(filename, "rb") -#define FontFileClose(f) gzclose(f) - -#define MAXFONTFILENAMELEN 1024 -#define MAXFONTNAMELEN 1024 - -#include -#include "fontencI.h" - -#define MAXALIASES 20 - -#define EOF_TOKEN -1 -#define ERROR_TOKEN -2 -#define EOL_TOKEN 0 -#define NUMBER_TOKEN 1 -#define KEYWORD_TOKEN 2 - -#define EOF_LINE -1 -#define ERROR_LINE -2 -#define STARTENCODING_LINE 1 -#define STARTMAPPING_LINE 2 -#define ENDMAPPING_LINE 3 -#define CODE_LINE 4 -#define CODE_RANGE_LINE 5 -#define CODE_UNDEFINE_LINE 6 -#define NAME_LINE 7 -#define SIZE_LINE 8 -#define ALIAS_LINE 9 -#define FIRSTINDEX_LINE 10 - -/* Return from lexer */ -#define MAXKEYWORDLEN 100 - -static long number_value; -static char keyword_value[MAXKEYWORDLEN+1]; - -static long value1, value2, value3; - -/* Lexer code */ - -/* Skip to the beginning of new line */ -static void -skipEndOfLine(FontFilePtr f, int c) -{ - if(c == 0) - c = FontFileGetc(f); - - for(;;) - if(c <= 0 || c == '\n') - return; - else - c = FontFileGetc(f); -} - -/* Get a number; we're at the first digit. */ -static unsigned -getnum(FontFilePtr f, int c, int *cp) -{ - unsigned n = 0; - int base = 10; - - /* look for `0' or `0x' prefix */ - if(c == '0') { - c = FontFileGetc(f); - base = 8; - if(c == 'x' || c == 'X') { - base = 16; - c = FontFileGetc(f); - } - } - - /* accumulate digits */ - for(;;) { - if ('0' <= c && c <= '9') { - n *= base; n += c - '0'; - } else if('a' <= c && c <= 'f') { - n *= base; n += c - 'a' + 10; - } else if('A' <=c && c <= 'F') { - n *= base; n += c - 'A' + 10; - } else - break; - c = FontFileGetc(f); - } - - *cp = c; return n; -} - -/* Skip to beginning of new line; return 1 if only whitespace was found. */ -static int -endOfLine(FontFilePtr f, int c) -{ - if(c == 0) - c = FontFileGetc(f); - - for(;;) { - if(c <= 0 || c == '\n') - return 1; - else if(c == '#') { - skipEndOfLine(f,c); - return 1; - } - else if(c == ' ' || c == '\t') { - skipEndOfLine(f,c); - return 0; - } - c = FontFileGetc(f); - } -} - -/* Get a token; we're at first char */ -static int -gettoken(FontFilePtr f, int c, int *cp) -{ - char *p; - - if(c <= 0) - c = FontFileGetc(f); - - if(c <= 0) { - return EOF_TOKEN; - } - - while(c == ' ' || c == '\t') - c = FontFileGetc(f); - - if(c=='\n') { - return EOL_TOKEN; - } else if(c == '#') { - skipEndOfLine(f,c); - return EOL_TOKEN; - } else if(c >= '0' && c <= '9') { - number_value = getnum(f,c,cp); - return NUMBER_TOKEN; - } else if((c >= 'A' && c <= 'Z') || - (c >= 'a' && c <= 'z') || - c == '/' || c == '_' || c == '-' || c == '.') { - p = keyword_value; - *p++ = c; - while(p-keyword_value < MAXKEYWORDLEN) { - c = FontFileGetc(f); - if(c <= ' ' || c > '~' || c == '#') - break; - *p++ = c; - } - *cp = c; - *p = '\0'; - return KEYWORD_TOKEN; - } else { - *cp = c; - return ERROR_TOKEN; - } -} - -/* Parse a line. - * Always skips to the beginning of a new line, even if an error occurs */ -static int -getnextline(FontFilePtr f) -{ - int c, token; - c = FontFileGetc(f); - if(c <= 0) - return EOF_LINE; - - again: - token=gettoken(f,c,&c); - - switch(token) { - case EOF_TOKEN: - return EOF_LINE; - case EOL_TOKEN: - /* empty line */ - c = FontFileGetc(f); - goto again; - case NUMBER_TOKEN: - value1 = number_value; - token = gettoken(f,c,&c); - switch(token) { - case NUMBER_TOKEN: - value2 = number_value; - token = gettoken(f,c,&c); - switch(token) { - case NUMBER_TOKEN: - value3 = number_value; - return CODE_RANGE_LINE; - case EOL_TOKEN: - return CODE_LINE; - default: - skipEndOfLine(f,c); - return ERROR_LINE; - } - case KEYWORD_TOKEN: - if(!endOfLine(f,c)) - return ERROR_LINE; - else - return NAME_LINE; - default: - skipEndOfLine(f,c); - return ERROR_LINE; - } - case KEYWORD_TOKEN: - if(!strcasecmp(keyword_value, "STARTENCODING")) { - token = gettoken(f,c,&c); - if(token == KEYWORD_TOKEN) { - if(endOfLine(f,c)) - return STARTENCODING_LINE; - else - return ERROR_LINE; - } else { - skipEndOfLine(f,c); - return ERROR_LINE; - } - } else if(!strcasecmp(keyword_value, "ALIAS")) { - token = gettoken(f,c,&c); - if(token == KEYWORD_TOKEN) { - if(endOfLine(f,c)) - return ALIAS_LINE; - else - return ERROR_LINE; - } else { - skipEndOfLine(f,c); - return ERROR_LINE; - } - } else if(!strcasecmp(keyword_value, "SIZE")) { - token = gettoken(f,c,&c); - if(token == NUMBER_TOKEN) { - value1 = number_value; - token = gettoken(f,c,&c); - switch(token) { - case NUMBER_TOKEN: - value2 = number_value; - return SIZE_LINE; - case EOL_TOKEN: - value2=0; - return SIZE_LINE; - default: - skipEndOfLine(f,c); - return ERROR_LINE; - } - } else { - skipEndOfLine(f,c); - return ERROR_LINE; - } - } else if(!strcasecmp(keyword_value, "FIRSTINDEX")) { - token = gettoken(f,c,&c); - if(token == NUMBER_TOKEN) { - value1 = number_value; - token = gettoken(f,c,&c); - switch(token) { - case NUMBER_TOKEN: - value2 = number_value; - return FIRSTINDEX_LINE; - case EOL_TOKEN: - value2 = 0; - return FIRSTINDEX_LINE; - default: - skipEndOfLine(f,c); - return ERROR_LINE; - } - } else { - skipEndOfLine(f,c); - return ERROR_LINE; - } - } else if(!strcasecmp(keyword_value, "STARTMAPPING")) { - keyword_value[0] = 0; - value1 = 0; value1 = 0; - /* first a keyword */ - token = gettoken(f,c,&c); - if(token != KEYWORD_TOKEN) { - skipEndOfLine(f, c); - return ERROR_LINE; - } - - /* optional first integer */ - token = gettoken(f,c,&c); - if(token == NUMBER_TOKEN) { - value1 = number_value; - } else if(token == EOL_TOKEN) { - return STARTMAPPING_LINE; - } else { - skipEndOfLine(f, c); - return ERROR_LINE; - } - - /* optional second integer */ - token = gettoken(f,c,&c); - if(token == NUMBER_TOKEN) { - value2 = number_value; - } else if(token == EOL_TOKEN) { - return STARTMAPPING_LINE; - } else { - skipEndOfLine(f, c); - return ERROR_LINE; - } - - if(!endOfLine(f,c)) - return ERROR_LINE; - else { - return STARTMAPPING_LINE; - } - } else if(!strcasecmp(keyword_value, "UNDEFINE")) { - /* first integer */ - token = gettoken(f,c,&c); - if(token != NUMBER_TOKEN) { - skipEndOfLine(f,c); - return ERROR_LINE; - } - value1 = number_value; - /* optional second integer */ - token = gettoken(f,c,&c); - if(token == EOL_TOKEN) { - value2 = value1; - return CODE_UNDEFINE_LINE; - } else if(token == NUMBER_TOKEN) { - value2 = number_value; - if(endOfLine(f,c)) { - return CODE_UNDEFINE_LINE; - } else - return ERROR_LINE; - } else { - skipEndOfLine(f,c); - return ERROR_LINE; - } - } else if(!strcasecmp(keyword_value, "ENDENCODING")) { - if(endOfLine(f,c)) - return EOF_LINE; - else - return ERROR_LINE; - } else if(!strcasecmp(keyword_value, "ENDMAPPING")) { - if(endOfLine(f,c)) - return ENDMAPPING_LINE; - else - return ERROR_LINE; - } else { - skipEndOfLine(f,c); - return ERROR_LINE; - } - default: - return ERROR_LINE; - } -} - -static void -install_mapping(FontEncPtr encoding, FontMapPtr mapping) -{ - FontMapPtr m; - - if(encoding->mappings == NULL) - encoding->mappings = mapping; - else { - m = encoding->mappings; - while(m->next != NULL) - m = m->next; - m->next = mapping; - } - mapping->next = NULL; - mapping->encoding = encoding; -} - -static int -setCode(unsigned from, unsigned to, unsigned row_size, - unsigned *first, unsigned *last, - unsigned *encsize, unsigned short **enc) -{ - unsigned index, i; - unsigned short *newenc; - - if(from>0xFFFF) - return 0; /* success */ - - if(row_size==0) - index=from; - else { - if((value1 & 0xFF) >= row_size) - return 0; /* ignore out of range mappings */ - index = (from>>8) * row_size + (from&0xFF); - } - - /* Optimize away useless identity mappings. This is only expected - to be useful with linear encodings. */ - if(index == to && (index < *first || index > *last)) - return 0; - if(*encsize == 0) { - *encsize = (index < 256) ? 256 : 0x10000; - *enc = malloc((*encsize) * sizeof(unsigned short)); - if(*enc == NULL) { - *encsize = 0; - return 1; - } - } else if(*encsize <= index) { - *encsize = 0x10000; - if((newenc = realloc(enc, *encsize))==NULL) - return 1; - *enc = newenc; - } - if(*first > *last) { - *first = *last = index; - } - if(index < *first) { - for(i = index; i < *first; i++) - (*enc)[i] = i; - *first = index; - } - if(index > *last) { - for(i = *last + 1; i <= index; i++) - (*enc)[i] = i; - *last = index; - } - (*enc)[index] = to; - return 0; -} - -/* Parser. If headerOnly is true, we're only interested in the - data contained in the encoding file's header. */ - -/* As font encodings are currently never freed, the allocations done - by this function are mostly its private business. Note, however, - that FontEncIdentify needs to free the header fields -- so if you - change this function, you may need to change FontEncIdentify. */ - -/* I want a garbage collector. */ - -static FontEncPtr -parseEncodingFile(FontFilePtr f, int headerOnly) -{ - int line; - - unsigned short *enc=NULL; - char **nam = NULL, **newnam; - unsigned i, first = 0xFFFF, last=0, encsize=0, namsize=0; - FontEncPtr encoding = NULL; - FontMapPtr mapping = NULL; - FontEncSimpleMapPtr sm; - FontEncSimpleNamePtr sn; - char *aliases[MAXALIASES]; - int numaliases=0; - -#if 0 - /* GCC complains about unused labels. Please fix GCC rather than - obfuscating my code. */ - no_encoding: -#endif - line = getnextline(f); - switch(line) { - case EOF_LINE: - goto error; - case STARTENCODING_LINE: - encoding = malloc(sizeof(FontEncRec)); - if(encoding == NULL) - goto error; - encoding->name = strdup(keyword_value); - if(encoding->name == NULL) - goto error; - encoding->size = 256; - encoding->row_size = 0; - encoding->mappings = NULL; - encoding->next = NULL; - encoding->first = encoding->first_col=0; - goto no_mapping; - default: - goto error; - } - - no_mapping: - line = getnextline(f); - switch(line) { - case EOF_LINE: goto done; - case ALIAS_LINE: - if(numaliases < MAXALIASES) { - aliases[numaliases] = strdup(keyword_value); - if(aliases[numaliases] == NULL) - goto error; - numaliases++; - } - goto no_mapping; - case SIZE_LINE: - encoding->size = value1; - encoding->row_size = value2; - goto no_mapping; - case FIRSTINDEX_LINE: - encoding->first = value1; - encoding->first_col = value2; - goto no_mapping; - case STARTMAPPING_LINE: - if(headerOnly) - goto done; - if(!strcasecmp(keyword_value, "unicode")) { - mapping = malloc(sizeof(FontMapRec)); - if(mapping == NULL) - goto error; - mapping->type = FONT_ENCODING_UNICODE; - mapping->pid = 0; - mapping->eid = 0; - mapping->recode = NULL; - mapping->name = NULL; - mapping->client_data = NULL; - mapping->next = NULL; - goto mapping; - } else if(!strcasecmp(keyword_value, "cmap")) { - mapping = malloc(sizeof(FontMapRec)); - if(mapping == NULL) - goto error; - mapping->type = FONT_ENCODING_TRUETYPE; - mapping->pid = value1; - mapping->eid = value2; - mapping->recode = NULL; - mapping->name = NULL; - mapping->client_data = NULL; - mapping->next = NULL; - goto mapping; - } else if(!strcasecmp(keyword_value, "postscript")) { - mapping = malloc(sizeof(FontMapRec)); - if(mapping == NULL) - goto error; - mapping->type = FONT_ENCODING_POSTSCRIPT; - mapping->pid = 0; - mapping->eid = 0; - mapping->recode = NULL; - mapping->name = NULL; - mapping->client_data = NULL; - mapping->next = NULL; - goto string_mapping; - } else { /* unknown mapping type -- ignore */ - goto skipmapping; - } - /* NOTREACHED */ - goto error; - default: goto no_mapping; /* ignore unknown lines */ - } - - skipmapping: - line = getnextline(f); - switch(line) { - case ENDMAPPING_LINE: - goto no_mapping; - case EOF_LINE: - goto error; - default: - goto skipmapping; - } - - mapping: - line = getnextline(f); - switch(line) { - case EOF_LINE: goto error; - case ENDMAPPING_LINE: - mapping->recode = FontEncSimpleRecode; - mapping->name = FontEncUndefinedName; - mapping->client_data = sm = malloc(sizeof(FontEncSimpleMapRec)); - if(sm == NULL) - goto error; - sm->row_size = encoding->row_size; - if(first <= last) { - unsigned short *newmap; - - sm->first = first; - sm->len=last-first+1; - newmap = malloc(sm->len * sizeof(unsigned short)); - if(newmap == NULL) { - free(sm); - mapping->client_data = sm = NULL; - goto error; - } - for(i=0; i < sm->len; i++) - newmap[i] = enc[first+i]; - sm->map = newmap; - } else { - sm->first = 0; - sm->len = 0; - sm->map = NULL; - } - install_mapping(encoding, mapping); - mapping = NULL; - first = 0xFFFF; last=0; - goto no_mapping; - - case CODE_LINE: - if(setCode(value1, value2, encoding->row_size, - &first, &last, &encsize, &enc)) - goto error; - goto mapping; - - case CODE_RANGE_LINE: - if(value1 > 0x10000) - value1 = 0x10000; - if(value2 > 0x10000) - value2 = 0x10000; - if(value2 < value1) - goto mapping; - /* Do the last value first to avoid having to realloc() */ - if(setCode(value2, value3+(value2-value1), encoding->row_size, - &first, &last, &encsize, &enc)) - goto error; - for(i=value1; irow_size, - &first, &last, &encsize, &enc)) - goto error; - } - goto mapping; - - case CODE_UNDEFINE_LINE: - if(value1 > 0x10000) - value1 = 0x10000; - if(value2 > 0x10000) - value2 = 0x10000; - if(value2 < value1) - goto mapping; - /* Do the last value first to avoid having to realloc() */ - if(setCode(value2, 0, encoding->row_size, - &first, &last, &encsize, &enc)) - goto error; - for(i = value1; i < value2; i++) { - if(setCode(i, 0, encoding->row_size, - &first, &last, &encsize, &enc)) - goto error; - } - goto mapping; - - default: goto mapping; /* ignore unknown lines */ - } - - string_mapping: - line = getnextline(f); - switch(line) { - case EOF_LINE: goto error; - case ENDMAPPING_LINE: - mapping->recode = FontEncUndefinedRecode; - mapping->name = FontEncSimpleName; - mapping->client_data = sn = malloc(sizeof(FontEncSimpleNameRec)); - if(sn == NULL) - goto error; - if(first > last) { - free(sn); - mapping->client_data = sn = NULL; - goto error; - } - sn->first = first; - sn->len = last - first + 1; - sn->map = malloc(sn->len*sizeof(char*)); - if(sn->map == NULL) { - free(sn); - mapping->client_data = sn = NULL; - goto error; - } - for(i = 0; i < sn->len; i++) - sn->map[i] = nam[first+i]; - install_mapping(encoding,mapping); - mapping = NULL; - first = 0xFFFF; last=0; - goto no_mapping; - case NAME_LINE: - if(value1 >= 0x10000) goto string_mapping; - if(namsize == 0) { - namsize = (value1) < 256 ? 256 : 0x10000; - nam = malloc(namsize * sizeof(char*)); - if(nam == NULL) { - namsize=0; - goto error; - } - } else if(namsize <= value1) { - namsize = 0x10000; - if((newnam = (char**)realloc(nam, namsize)) == NULL) - goto error; - nam = newnam; - } - if(first > last) { - first = last = value1; - } - if(value1 < first) { - for(i = value1; i < first; i++) - nam[i] = NULL; - first = value1; - } - if(value1 > last) { - for(i=last+1; i <= value1; i++) - nam[i]=NULL; - last = value1; - } - nam[value1] = strdup(keyword_value); - if(nam[value1] == NULL) { - goto error; - } - goto string_mapping; - - default: goto string_mapping; /* ignore unknown lines */ - } - - done: - if(encsize) free(enc); encsize=0; enc = NULL; - if(namsize) free(nam); namsize=0; nam = NULL; /* don't free entries! */ - - encoding->aliases=NULL; - if(numaliases) { - encoding->aliases = malloc((numaliases+1)*sizeof(char*)); - if(encoding->aliases == NULL) - goto error; - for(i=0; ialiases[i] = aliases[i]; - encoding->aliases[numaliases]=NULL; - } - - return encoding; - -error: - if(encsize) free(enc); encsize=0; - if(namsize) { - for(i = first; i <= last; i++) - free(nam[i]); - free(nam); - namsize = 0; - } - if(mapping) { - free(mapping->client_data); - free(mapping); - } - if(encoding) { - FontMapPtr nextmap; - free(encoding->name); - for (mapping = encoding->mappings; mapping; mapping = nextmap) { - free(mapping->client_data); - nextmap = mapping->next; - free(mapping); - } - free(encoding); - } - for(i = 0; i < numaliases; i++) - free(aliases[i]); - /* We don't need to free sn and sm as they handled locally in the body.*/ - return NULL; -} - -char* -FontEncDirectory(void) -{ - static char* dir = NULL; - - if(dir == NULL) { - char *c = getenv("FONT_ENCODINGS_DIRECTORY"); - if(c) { - dir = strdup(c); - if(!dir) - return NULL; - } else { - dir = FONT_ENCODINGS_DIRECTORY; - } - } - return dir; -} - -static void -parseFontFileName(const char *fontFileName, char *buf, char *dir) -{ - const char *p; - char *q, *lastslash; - - for(p = fontFileName, q = dir, lastslash = NULL; *p; p++, q++) { - *q = *p; - if(*p == '/') - lastslash = q+1; - } - - if(!lastslash) - lastslash = dir; - - *lastslash = '\0'; - - if(buf && strlen(dir) + 14 < MAXFONTFILENAMELEN) { - strcpy(buf, dir); - strcat(buf, "encodings.dir"); - } -} - -static FontEncPtr -FontEncReallyReallyLoad(const char *charset, - const char *dirname, const char *dir) -{ - FontFilePtr f; - FILE *file; - FontEncPtr encoding; - char file_name[MAXFONTFILENAMELEN], encoding_name[MAXFONTNAMELEN], - buf[MAXFONTFILENAMELEN]; - int count, n; - static char format[24] = ""; - - /* As we don't really expect to open encodings that often, we don't - take the trouble of caching encodings directories. */ - - if((file = fopen(dirname, "r")) == NULL) { - return NULL; - } - - count = fscanf(file, "%d\n", &n); - if(count == EOF || count != 1) { - fclose(file); - return NULL; - } - - encoding = NULL; - if (!format[0]) { - sprintf(format, "%%%ds %%%d[^\n]\n", (int)sizeof(encoding_name) - 1, - (int)sizeof(file_name) - 1); - } - for(;;) { - count = fscanf(file, format, encoding_name, file_name); - if(count == EOF) - break; - if(count != 2) - break; - - if(!strcasecmp(encoding_name, charset)) { - /* Found it */ - if(file_name[0] != '/') { - if(strlen(dir) + strlen(file_name) >= MAXFONTFILENAMELEN) { - fclose(file); - return NULL; - } - strcpy(buf, dir); - strcat(buf, file_name); - } else { - strcpy(buf , file_name); - } - - f = FontFileOpen(buf); - if(f == NULL) { - fclose(file); - return NULL; - } - encoding = parseEncodingFile(f, 0); - FontFileClose(f); - break; - } - } - - fclose(file); - - return encoding; -} - -/* Parser ntrypoint -- used by FontEncLoad */ -FontEncPtr -FontEncReallyLoad(const char *charset, const char *fontFileName) -{ - FontEncPtr encoding; - char dir[MAXFONTFILENAMELEN], dirname[MAXFONTFILENAMELEN]; - char *d; - - if(fontFileName) { - parseFontFileName(fontFileName, dirname, dir); - encoding = FontEncReallyReallyLoad(charset, dirname, dir); - if(encoding) - return(encoding); - } - - d = FontEncDirectory(); - if(d) { - parseFontFileName(d, NULL, dir); - encoding = FontEncReallyReallyLoad(charset, d, dir); - return encoding; - } - - return NULL; -} - -/* Return a NULL-terminated array of encoding names. Note that this - * function has incestuous knowledge of the allocations done by - * parseEncodingFile. */ - -char ** -FontEncIdentify(const char *fileName) -{ - FontFilePtr f; - FontEncPtr encoding; - char **names, **name, **alias; - int numaliases; - - if((f = FontFileOpen(fileName))==NULL) { - return NULL; - } - encoding = parseEncodingFile(f, 1); - FontFileClose(f); - - if(!encoding) - return NULL; - - numaliases = 0; - if(encoding->aliases) - for(alias = encoding->aliases; *alias; alias++) - numaliases++; - - names = malloc((numaliases+2)*sizeof(char*)); - if(names == NULL) { - free(encoding->aliases); - free(encoding); - return NULL; - } - - name = names; - *(name++) = encoding->name; - if(numaliases > 0) - for(alias = encoding->aliases; *alias; alias++, name++) - *name = *alias; - - *name = NULL; - free(encoding->aliases); - free(encoding); - - return names; -} +/* +Copyright (c) 1998-2001 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +/* Parser for encoding files */ + +/* This code assumes that we are using ASCII. We don't use the ctype + functions, as they depend on the current locale. On the other + hand, we do use strcasecmp, but only on strings that we've checked + to be pure ASCII. Bloody ``Code Set Independence''. */ + +#include +#include + +#if defined(__SCO__) || defined(__UNIXWARE__) +#include +#endif + +#include + +#include "zlib.h" +typedef gzFile FontFilePtr; +#define FontFileGetc(f) gzgetc(f) +#define FontFileOpen(filename) gzopen(filename, "rb") +#define FontFileClose(f) gzclose(f) + +#define MAXFONTFILENAMELEN 1024 +#define MAXFONTNAMELEN 1024 + +#include +#include "fontencI.h" + +#define MAXALIASES 20 + +#define EOF_TOKEN -1 +#define ERROR_TOKEN -2 +#define EOL_TOKEN 0 +#define NUMBER_TOKEN 1 +#define KEYWORD_TOKEN 2 + +#define EOF_LINE -1 +#define ERROR_LINE -2 +#define STARTENCODING_LINE 1 +#define STARTMAPPING_LINE 2 +#define ENDMAPPING_LINE 3 +#define CODE_LINE 4 +#define CODE_RANGE_LINE 5 +#define CODE_UNDEFINE_LINE 6 +#define NAME_LINE 7 +#define SIZE_LINE 8 +#define ALIAS_LINE 9 +#define FIRSTINDEX_LINE 10 + +/* Return from lexer */ +#define MAXKEYWORDLEN 100 + +static long number_value; +static char keyword_value[MAXKEYWORDLEN+1]; + +static long value1, value2, value3; + +/* Lexer code */ + +/* Skip to the beginning of new line */ +static void +skipEndOfLine(FontFilePtr f, int c) +{ + if(c == 0) + c = FontFileGetc(f); + + for(;;) + if(c <= 0 || c == '\n') + return; + else + c = FontFileGetc(f); +} + +/* Get a number; we're at the first digit. */ +static unsigned +getnum(FontFilePtr f, int c, int *cp) +{ + unsigned n = 0; + int base = 10; + + /* look for `0' or `0x' prefix */ + if(c == '0') { + c = FontFileGetc(f); + base = 8; + if(c == 'x' || c == 'X') { + base = 16; + c = FontFileGetc(f); + } + } + + /* accumulate digits */ + for(;;) { + if ('0' <= c && c <= '9') { + n *= base; n += c - '0'; + } else if('a' <= c && c <= 'f') { + n *= base; n += c - 'a' + 10; + } else if('A' <=c && c <= 'F') { + n *= base; n += c - 'A' + 10; + } else + break; + c = FontFileGetc(f); + } + + *cp = c; return n; +} + +/* Skip to beginning of new line; return 1 if only whitespace was found. */ +static int +endOfLine(FontFilePtr f, int c) +{ + if(c == 0) + c = FontFileGetc(f); + + for(;;) { + if(c <= 0 || c == '\n') + return 1; + else if(c == '#') { + skipEndOfLine(f,c); + return 1; + } + else if(c == ' ' || c == '\t') { + skipEndOfLine(f,c); + return 0; + } + c = FontFileGetc(f); + } +} + +/* Get a token; we're at first char */ +static int +gettoken(FontFilePtr f, int c, int *cp) +{ + char *p; + + if(c <= 0) + c = FontFileGetc(f); + + if(c <= 0) { + return EOF_TOKEN; + } + + while(c == ' ' || c == '\t') + c = FontFileGetc(f); + + if(c=='\n') { + return EOL_TOKEN; + } else if(c == '#') { + skipEndOfLine(f,c); + return EOL_TOKEN; + } else if(c >= '0' && c <= '9') { + number_value = getnum(f,c,cp); + return NUMBER_TOKEN; + } else if((c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + c == '/' || c == '_' || c == '-' || c == '.') { + p = keyword_value; + *p++ = c; + while(p-keyword_value < MAXKEYWORDLEN) { + c = FontFileGetc(f); + if(c <= ' ' || c > '~' || c == '#') + break; + *p++ = c; + } + *cp = c; + *p = '\0'; + return KEYWORD_TOKEN; + } else { + *cp = c; + return ERROR_TOKEN; + } +} + +/* Parse a line. + * Always skips to the beginning of a new line, even if an error occurs */ +static int +getnextline(FontFilePtr f) +{ + int c, token; + c = FontFileGetc(f); + if(c <= 0) + return EOF_LINE; + + again: + token=gettoken(f,c,&c); + + switch(token) { + case EOF_TOKEN: + return EOF_LINE; + case EOL_TOKEN: + /* empty line */ + c = FontFileGetc(f); + goto again; + case NUMBER_TOKEN: + value1 = number_value; + token = gettoken(f,c,&c); + switch(token) { + case NUMBER_TOKEN: + value2 = number_value; + token = gettoken(f,c,&c); + switch(token) { + case NUMBER_TOKEN: + value3 = number_value; + return CODE_RANGE_LINE; + case EOL_TOKEN: + return CODE_LINE; + default: + skipEndOfLine(f,c); + return ERROR_LINE; + } + case KEYWORD_TOKEN: + if(!endOfLine(f,c)) + return ERROR_LINE; + else + return NAME_LINE; + default: + skipEndOfLine(f,c); + return ERROR_LINE; + } + case KEYWORD_TOKEN: + if(!strcasecmp(keyword_value, "STARTENCODING")) { + token = gettoken(f,c,&c); + if(token == KEYWORD_TOKEN) { + if(endOfLine(f,c)) + return STARTENCODING_LINE; + else + return ERROR_LINE; + } else { + skipEndOfLine(f,c); + return ERROR_LINE; + } + } else if(!strcasecmp(keyword_value, "ALIAS")) { + token = gettoken(f,c,&c); + if(token == KEYWORD_TOKEN) { + if(endOfLine(f,c)) + return ALIAS_LINE; + else + return ERROR_LINE; + } else { + skipEndOfLine(f,c); + return ERROR_LINE; + } + } else if(!strcasecmp(keyword_value, "SIZE")) { + token = gettoken(f,c,&c); + if(token == NUMBER_TOKEN) { + value1 = number_value; + token = gettoken(f,c,&c); + switch(token) { + case NUMBER_TOKEN: + value2 = number_value; + return SIZE_LINE; + case EOL_TOKEN: + value2=0; + return SIZE_LINE; + default: + skipEndOfLine(f,c); + return ERROR_LINE; + } + } else { + skipEndOfLine(f,c); + return ERROR_LINE; + } + } else if(!strcasecmp(keyword_value, "FIRSTINDEX")) { + token = gettoken(f,c,&c); + if(token == NUMBER_TOKEN) { + value1 = number_value; + token = gettoken(f,c,&c); + switch(token) { + case NUMBER_TOKEN: + value2 = number_value; + return FIRSTINDEX_LINE; + case EOL_TOKEN: + value2 = 0; + return FIRSTINDEX_LINE; + default: + skipEndOfLine(f,c); + return ERROR_LINE; + } + } else { + skipEndOfLine(f,c); + return ERROR_LINE; + } + } else if(!strcasecmp(keyword_value, "STARTMAPPING")) { + keyword_value[0] = 0; + value1 = 0; value1 = 0; + /* first a keyword */ + token = gettoken(f,c,&c); + if(token != KEYWORD_TOKEN) { + skipEndOfLine(f, c); + return ERROR_LINE; + } + + /* optional first integer */ + token = gettoken(f,c,&c); + if(token == NUMBER_TOKEN) { + value1 = number_value; + } else if(token == EOL_TOKEN) { + return STARTMAPPING_LINE; + } else { + skipEndOfLine(f, c); + return ERROR_LINE; + } + + /* optional second integer */ + token = gettoken(f,c,&c); + if(token == NUMBER_TOKEN) { + value2 = number_value; + } else if(token == EOL_TOKEN) { + return STARTMAPPING_LINE; + } else { + skipEndOfLine(f, c); + return ERROR_LINE; + } + + if(!endOfLine(f,c)) + return ERROR_LINE; + else { + return STARTMAPPING_LINE; + } + } else if(!strcasecmp(keyword_value, "UNDEFINE")) { + /* first integer */ + token = gettoken(f,c,&c); + if(token != NUMBER_TOKEN) { + skipEndOfLine(f,c); + return ERROR_LINE; + } + value1 = number_value; + /* optional second integer */ + token = gettoken(f,c,&c); + if(token == EOL_TOKEN) { + value2 = value1; + return CODE_UNDEFINE_LINE; + } else if(token == NUMBER_TOKEN) { + value2 = number_value; + if(endOfLine(f,c)) { + return CODE_UNDEFINE_LINE; + } else + return ERROR_LINE; + } else { + skipEndOfLine(f,c); + return ERROR_LINE; + } + } else if(!strcasecmp(keyword_value, "ENDENCODING")) { + if(endOfLine(f,c)) + return EOF_LINE; + else + return ERROR_LINE; + } else if(!strcasecmp(keyword_value, "ENDMAPPING")) { + if(endOfLine(f,c)) + return ENDMAPPING_LINE; + else + return ERROR_LINE; + } else { + skipEndOfLine(f,c); + return ERROR_LINE; + } + default: + return ERROR_LINE; + } +} + +static void +install_mapping(FontEncPtr encoding, FontMapPtr mapping) +{ + FontMapPtr m; + + if(encoding->mappings == NULL) + encoding->mappings = mapping; + else { + m = encoding->mappings; + while(m->next != NULL) + m = m->next; + m->next = mapping; + } + mapping->next = NULL; + mapping->encoding = encoding; +} + +static int +setCode(unsigned from, unsigned to, unsigned row_size, + unsigned *first, unsigned *last, + unsigned *encsize, unsigned short **enc) +{ + unsigned index, i; + unsigned short *newenc; + + if(from>0xFFFF) + return 0; /* success */ + + if(row_size==0) + index=from; + else { + if((value1 & 0xFF) >= row_size) + return 0; /* ignore out of range mappings */ + index = (from>>8) * row_size + (from&0xFF); + } + + /* Optimize away useless identity mappings. This is only expected + to be useful with linear encodings. */ + if(index == to && (index < *first || index > *last)) + return 0; + if(*encsize == 0) { + *encsize = (index < 256) ? 256 : 0x10000; + *enc = malloc((*encsize) * sizeof(unsigned short)); + if(*enc == NULL) { + *encsize = 0; + return 1; + } + } else if(*encsize <= index) { + *encsize = 0x10000; + if((newenc = realloc(enc, *encsize))==NULL) + return 1; + *enc = newenc; + } + if(*first > *last) { + *first = *last = index; + } + if(index < *first) { + for(i = index; i < *first; i++) + (*enc)[i] = i; + *first = index; + } + if(index > *last) { + for(i = *last + 1; i <= index; i++) + (*enc)[i] = i; + *last = index; + } + (*enc)[index] = to; + return 0; +} + +/* Parser. If headerOnly is true, we're only interested in the + data contained in the encoding file's header. */ + +/* As font encodings are currently never freed, the allocations done + by this function are mostly its private business. Note, however, + that FontEncIdentify needs to free the header fields -- so if you + change this function, you may need to change FontEncIdentify. */ + +/* I want a garbage collector. */ + +static FontEncPtr +parseEncodingFile(FontFilePtr f, int headerOnly) +{ + int line; + + unsigned short *enc=NULL; + char **nam = NULL, **newnam; + unsigned i, first = 0xFFFF, last=0, encsize=0, namsize=0; + FontEncPtr encoding = NULL; + FontMapPtr mapping = NULL; + FontEncSimpleMapPtr sm; + FontEncSimpleNamePtr sn; + char *aliases[MAXALIASES]; + int numaliases=0; + +#if 0 + /* GCC complains about unused labels. Please fix GCC rather than + obfuscating my code. */ + no_encoding: +#endif + line = getnextline(f); + switch(line) { + case EOF_LINE: + goto error; + case STARTENCODING_LINE: + encoding = malloc(sizeof(FontEncRec)); + if(encoding == NULL) + goto error; + encoding->name = strdup(keyword_value); + if(encoding->name == NULL) + goto error; + encoding->size = 256; + encoding->row_size = 0; + encoding->mappings = NULL; + encoding->next = NULL; + encoding->first = encoding->first_col=0; + goto no_mapping; + default: + goto error; + } + + no_mapping: + line = getnextline(f); + switch(line) { + case EOF_LINE: goto done; + case ALIAS_LINE: + if(numaliases < MAXALIASES) { + aliases[numaliases] = strdup(keyword_value); + if(aliases[numaliases] == NULL) + goto error; + numaliases++; + } + goto no_mapping; + case SIZE_LINE: + encoding->size = value1; + encoding->row_size = value2; + goto no_mapping; + case FIRSTINDEX_LINE: + encoding->first = value1; + encoding->first_col = value2; + goto no_mapping; + case STARTMAPPING_LINE: + if(headerOnly) + goto done; + if(!strcasecmp(keyword_value, "unicode")) { + mapping = malloc(sizeof(FontMapRec)); + if(mapping == NULL) + goto error; + mapping->type = FONT_ENCODING_UNICODE; + mapping->pid = 0; + mapping->eid = 0; + mapping->recode = NULL; + mapping->name = NULL; + mapping->client_data = NULL; + mapping->next = NULL; + goto mapping; + } else if(!strcasecmp(keyword_value, "cmap")) { + mapping = malloc(sizeof(FontMapRec)); + if(mapping == NULL) + goto error; + mapping->type = FONT_ENCODING_TRUETYPE; + mapping->pid = value1; + mapping->eid = value2; + mapping->recode = NULL; + mapping->name = NULL; + mapping->client_data = NULL; + mapping->next = NULL; + goto mapping; + } else if(!strcasecmp(keyword_value, "postscript")) { + mapping = malloc(sizeof(FontMapRec)); + if(mapping == NULL) + goto error; + mapping->type = FONT_ENCODING_POSTSCRIPT; + mapping->pid = 0; + mapping->eid = 0; + mapping->recode = NULL; + mapping->name = NULL; + mapping->client_data = NULL; + mapping->next = NULL; + goto string_mapping; + } else { /* unknown mapping type -- ignore */ + goto skipmapping; + } + /* NOTREACHED */ + goto error; + default: goto no_mapping; /* ignore unknown lines */ + } + + skipmapping: + line = getnextline(f); + switch(line) { + case ENDMAPPING_LINE: + goto no_mapping; + case EOF_LINE: + goto error; + default: + goto skipmapping; + } + + mapping: + line = getnextline(f); + switch(line) { + case EOF_LINE: goto error; + case ENDMAPPING_LINE: + mapping->recode = FontEncSimpleRecode; + mapping->name = FontEncUndefinedName; + mapping->client_data = sm = malloc(sizeof(FontEncSimpleMapRec)); + if(sm == NULL) + goto error; + sm->row_size = encoding->row_size; + if(first <= last) { + unsigned short *newmap; + + sm->first = first; + sm->len=last-first+1; + newmap = malloc(sm->len * sizeof(unsigned short)); + if(newmap == NULL) { + free(sm); + mapping->client_data = sm = NULL; + goto error; + } + for(i=0; i < sm->len; i++) + newmap[i] = enc[first+i]; + sm->map = newmap; + } else { + sm->first = 0; + sm->len = 0; + sm->map = NULL; + } + install_mapping(encoding, mapping); + mapping = NULL; + first = 0xFFFF; last=0; + goto no_mapping; + + case CODE_LINE: + if(setCode(value1, value2, encoding->row_size, + &first, &last, &encsize, &enc)) + goto error; + goto mapping; + + case CODE_RANGE_LINE: + if(value1 > 0x10000) + value1 = 0x10000; + if(value2 > 0x10000) + value2 = 0x10000; + if(value2 < value1) + goto mapping; + /* Do the last value first to avoid having to realloc() */ + if(setCode(value2, value3+(value2-value1), encoding->row_size, + &first, &last, &encsize, &enc)) + goto error; + for(i=value1; irow_size, + &first, &last, &encsize, &enc)) + goto error; + } + goto mapping; + + case CODE_UNDEFINE_LINE: + if(value1 > 0x10000) + value1 = 0x10000; + if(value2 > 0x10000) + value2 = 0x10000; + if(value2 < value1) + goto mapping; + /* Do the last value first to avoid having to realloc() */ + if(setCode(value2, 0, encoding->row_size, + &first, &last, &encsize, &enc)) + goto error; + for(i = value1; i < value2; i++) { + if(setCode(i, 0, encoding->row_size, + &first, &last, &encsize, &enc)) + goto error; + } + goto mapping; + + default: goto mapping; /* ignore unknown lines */ + } + + string_mapping: + line = getnextline(f); + switch(line) { + case EOF_LINE: goto error; + case ENDMAPPING_LINE: + mapping->recode = FontEncUndefinedRecode; + mapping->name = FontEncSimpleName; + mapping->client_data = sn = malloc(sizeof(FontEncSimpleNameRec)); + if(sn == NULL) + goto error; + if(first > last) { + free(sn); + mapping->client_data = sn = NULL; + goto error; + } + sn->first = first; + sn->len = last - first + 1; + sn->map = malloc(sn->len*sizeof(char*)); + if(sn->map == NULL) { + free(sn); + mapping->client_data = sn = NULL; + goto error; + } + for(i = 0; i < sn->len; i++) + sn->map[i] = nam[first+i]; + install_mapping(encoding,mapping); + mapping = NULL; + first = 0xFFFF; last=0; + goto no_mapping; + case NAME_LINE: + if(value1 >= 0x10000) goto string_mapping; + if(namsize == 0) { + namsize = (value1) < 256 ? 256 : 0x10000; + nam = malloc(namsize * sizeof(char*)); + if(nam == NULL) { + namsize=0; + goto error; + } + } else if(namsize <= value1) { + namsize = 0x10000; + if((newnam = (char**)realloc(nam, namsize)) == NULL) + goto error; + nam = newnam; + } + if(first > last) { + first = last = value1; + } + if(value1 < first) { + for(i = value1; i < first; i++) + nam[i] = NULL; + first = value1; + } + if(value1 > last) { + for(i=last+1; i <= value1; i++) + nam[i]=NULL; + last = value1; + } + nam[value1] = strdup(keyword_value); + if(nam[value1] == NULL) { + goto error; + } + goto string_mapping; + + default: goto string_mapping; /* ignore unknown lines */ + } + + done: + if(encsize) free(enc); encsize=0; enc = NULL; + if(namsize) free(nam); namsize=0; nam = NULL; /* don't free entries! */ + + encoding->aliases=NULL; + if(numaliases) { + encoding->aliases = malloc((numaliases+1)*sizeof(char*)); + if(encoding->aliases == NULL) + goto error; + for(i=0; ialiases[i] = aliases[i]; + encoding->aliases[numaliases]=NULL; + } + + return encoding; + +error: + if(encsize) free(enc); encsize=0; + if(namsize) { + for(i = first; i <= last; i++) + free(nam[i]); + free(nam); + } + if(mapping) { + free(mapping->client_data); + free(mapping); + } + if(encoding) { + FontMapPtr nextmap; + free(encoding->name); + for (mapping = encoding->mappings; mapping; mapping = nextmap) { + free(mapping->client_data); + nextmap = mapping->next; + free(mapping); + } + free(encoding); + } + for(i = 0; i < numaliases; i++) + free(aliases[i]); + /* We don't need to free sn and sm as they handled locally in the body.*/ + return NULL; +} + +char* +FontEncDirectory(void) +{ + static char* dir = NULL; + + if(dir == NULL) { + char *c = getenv("FONT_ENCODINGS_DIRECTORY"); + if(c) { + dir = strdup(c); + if(!dir) + return NULL; + } else { + dir = FONT_ENCODINGS_DIRECTORY; + } + } + return dir; +} + +static void +parseFontFileName(const char *fontFileName, char *buf, char *dir) +{ + const char *p; + char *q, *lastslash; + + for(p = fontFileName, q = dir, lastslash = NULL; *p; p++, q++) { + *q = *p; + if(*p == '/') + lastslash = q+1; + } + + if(!lastslash) + lastslash = dir; + + *lastslash = '\0'; + + if(buf && strlen(dir) + 14 < MAXFONTFILENAMELEN) { + strcpy(buf, dir); + strcat(buf, "encodings.dir"); + } +} + +static FontEncPtr +FontEncReallyReallyLoad(const char *charset, + const char *dirname, const char *dir) +{ + FontFilePtr f; + FILE *file; + FontEncPtr encoding; + char file_name[MAXFONTFILENAMELEN], encoding_name[MAXFONTNAMELEN], + buf[MAXFONTFILENAMELEN]; + int count, n; + static char format[24] = ""; + + /* As we don't really expect to open encodings that often, we don't + take the trouble of caching encodings directories. */ + + if((file = fopen(dirname, "r")) == NULL) { + return NULL; + } + + count = fscanf(file, "%d\n", &n); + if(count == EOF || count != 1) { + fclose(file); + return NULL; + } + + encoding = NULL; + if (!format[0]) { + sprintf(format, "%%%ds %%%d[^\n]\n", (int)sizeof(encoding_name) - 1, + (int)sizeof(file_name) - 1); + } + for(;;) { + count = fscanf(file, format, encoding_name, file_name); + if(count == EOF) + break; + if(count != 2) + break; + + if(!strcasecmp(encoding_name, charset)) { + /* Found it */ + if(file_name[0] != '/') { + if(strlen(dir) + strlen(file_name) >= MAXFONTFILENAMELEN) { + fclose(file); + return NULL; + } + strcpy(buf, dir); + strcat(buf, file_name); + } else { + strcpy(buf , file_name); + } + + f = FontFileOpen(buf); + if(f == NULL) { + fclose(file); + return NULL; + } + encoding = parseEncodingFile(f, 0); + FontFileClose(f); + break; + } + } + + fclose(file); + + return encoding; +} + +/* Parser ntrypoint -- used by FontEncLoad */ +FontEncPtr +FontEncReallyLoad(const char *charset, const char *fontFileName) +{ + FontEncPtr encoding; + char dir[MAXFONTFILENAMELEN], dirname[MAXFONTFILENAMELEN]; + char *d; + + if(fontFileName) { + parseFontFileName(fontFileName, dirname, dir); + encoding = FontEncReallyReallyLoad(charset, dirname, dir); + if(encoding) + return(encoding); + } + + d = FontEncDirectory(); + if(d) { + parseFontFileName(d, NULL, dir); + encoding = FontEncReallyReallyLoad(charset, d, dir); + return encoding; + } + + return NULL; +} + +/* Return a NULL-terminated array of encoding names. Note that this + * function has incestuous knowledge of the allocations done by + * parseEncodingFile. */ + +char ** +FontEncIdentify(const char *fileName) +{ + FontFilePtr f; + FontEncPtr encoding; + char **names, **name, **alias; + int numaliases; + + if((f = FontFileOpen(fileName))==NULL) { + return NULL; + } + encoding = parseEncodingFile(f, 1); + FontFileClose(f); + + if(!encoding) + return NULL; + + numaliases = 0; + if(encoding->aliases) + for(alias = encoding->aliases; *alias; alias++) + numaliases++; + + names = malloc((numaliases+2)*sizeof(char*)); + if(names == NULL) { + free(encoding->aliases); + free(encoding); + return NULL; + } + + name = names; + *(name++) = encoding->name; + if(numaliases > 0) + for(alias = encoding->aliases; *alias; alias++, name++) + *name = *alias; + + *name = NULL; + free(encoding->aliases); + free(encoding); + + return names; +} diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y index 6f15e85a1..0a35e88ce 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.y +++ b/mesalib/src/glsl/glcpp/glcpp-parse.y @@ -1128,6 +1128,10 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api) if (extensions->ARB_explicit_attrib_location) add_builtin_define(parser, "GL_ARB_explicit_attrib_location", 1); + + if (extensions->ARB_shader_texture_lod) + add_builtin_define(parser, "GL_ARB_shader_texture_lod", 1); + if (extensions->AMD_conservative_depth) add_builtin_define(parser, "GL_AMD_conservative_depth", 1); } diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index 18bff88de..fce2faa75 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -240,6 +240,14 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, state->EXT_texture_array_warn = (ext_mode == extension_warn); unsupported = !state->extensions->EXT_texture_array; + } else if (strcmp(name, "GL_ARB_shader_texture_lod") == 0) { + /* Force ARB_texture_rectangle to be on so sampler2DRects are defined */ + state->ARB_texture_rectangle_enable = true; + + state->ARB_shader_texture_lod_enable = (ext_mode != extension_disable); + state->ARB_shader_texture_lod_warn = (ext_mode == extension_warn); + + unsupported = !state->extensions->ARB_shader_texture_lod; } else if (strcmp(name, "GL_ARB_shader_stencil_export") == 0) { state->ARB_shader_stencil_export_enable = (ext_mode != extension_disable); state->ARB_shader_stencil_export_warn = (ext_mode == extension_warn); diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index f9147653f..878d2ae3f 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -168,6 +168,8 @@ struct _mesa_glsl_parse_state { unsigned ARB_texture_rectangle_warn:1; unsigned EXT_texture_array_enable:1; unsigned EXT_texture_array_warn:1; + unsigned ARB_shader_texture_lod_enable:1; + unsigned ARB_shader_texture_lod_warn:1; unsigned ARB_shader_stencil_export_enable:1; unsigned ARB_shader_stencil_export_warn:1; unsigned AMD_conservative_depth_enable:1; diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index a9ef8fa4c..8672ac2a7 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -112,6 +112,7 @@ static const struct extension extension_table[] = { { "GL_ARB_seamless_cube_map", o(ARB_seamless_cube_map), GL, 2009 }, { "GL_ARB_shader_objects", o(ARB_shader_objects), GL, 2002 }, { "GL_ARB_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 }, + { "GL_ARB_shader_texture_lod", o(ARB_shader_texture_lod), GL, 2009 }, { "GL_ARB_shading_language_100", o(ARB_shading_language_100), GL, 2003 }, { "GL_ARB_shadow_ambient", o(ARB_shadow_ambient), GL, 2001 }, { "GL_ARB_shadow", o(ARB_shadow), GL, 2001 }, @@ -143,7 +144,6 @@ static const struct extension extension_table[] = { { "GL_ARB_vertex_shader", o(ARB_vertex_shader), GL, 2002 }, { "GL_ARB_vertex_type_2_10_10_10_rev", o(ARB_vertex_type_2_10_10_10_rev), GL, 2009 }, { "GL_ARB_window_pos", o(ARB_window_pos), GL, 2001 }, - /* EXT extensions */ { "GL_EXT_abgr", o(EXT_abgr), GL, 1995 }, { "GL_EXT_bgra", o(EXT_bgra), GL, 1995 }, diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 29c8cfd23..eb2efc89a 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -2793,6 +2793,7 @@ struct gl_extensions GLboolean ARB_seamless_cube_map; GLboolean ARB_shader_objects; GLboolean ARB_shader_stencil_export; + GLboolean ARB_shader_texture_lod; GLboolean ARB_shading_language_100; GLboolean ARB_shadow; GLboolean ARB_shadow_ambient; diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index bc10b455b..510aeab82 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -1966,7 +1966,7 @@ ir_to_mesa_visitor::visit(ir_call *ir) void ir_to_mesa_visitor::visit(ir_texture *ir) { - src_reg result_src, coord, lod_info, projector; + src_reg result_src, coord, lod_info, projector, dx, dy; dst_reg result_dst, coord_dst; ir_to_mesa_instruction *inst = NULL; prog_opcode opcode = OPCODE_NOP; @@ -2008,6 +2008,12 @@ ir_to_mesa_visitor::visit(ir_texture *ir) lod_info = this->result; break; case ir_txd: + opcode = OPCODE_TXD; + ir->lod_info.grad.dPdx->accept(this); + dx = this->result; + ir->lod_info.grad.dPdy->accept(this); + dy = this->result; + break; case ir_txf: assert(!"GLSL 1.30 features unsupported"); break; @@ -2080,7 +2086,10 @@ ir_to_mesa_visitor::visit(ir_texture *ir) coord_dst.writemask = WRITEMASK_XYZW; } - inst = emit(ir, opcode, result_dst, coord); + if (opcode == OPCODE_TXD) + inst = emit(ir, opcode, result_dst, coord, dx, dy); + else + inst = emit(ir, opcode, result_dst, coord); if (ir->shadow_comparitor) inst->tex_shadow = GL_TRUE; diff --git a/mesalib/src/mesa/program/prog_instruction.h b/mesalib/src/mesa/program/prog_instruction.h index 669d71029..db2b594e7 100644 --- a/mesalib/src/mesa/program/prog_instruction.h +++ b/mesalib/src/mesa/program/prog_instruction.h @@ -154,9 +154,9 @@ typedef enum prog_opcode { OPCODE_ARR, /* 2 */ OPCODE_BGNLOOP, /* opt */ OPCODE_BGNSUB, /* opt */ - OPCODE_BRA, /* 2 X */ + OPCODE_BRA, /* 2 */ OPCODE_BRK, /* 2 opt */ - OPCODE_CAL, /* 2 2 X */ + OPCODE_CAL, /* 2 2 opt */ OPCODE_CMP, /* X X */ OPCODE_CONT, /* opt */ OPCODE_COS, /* X 2 X X */ @@ -168,7 +168,7 @@ typedef enum prog_opcode { OPCODE_DP4, /* X X X X X */ OPCODE_DPH, /* X X 1.1 */ OPCODE_DST, /* X X X X */ - OPCODE_ELSE, /* X */ + OPCODE_ELSE, /* opt */ OPCODE_EMIT_VERTEX,/* X */ OPCODE_END, /* X X X X opt */ OPCODE_END_PRIMITIVE,/* X */ @@ -176,16 +176,16 @@ typedef enum prog_opcode { OPCODE_ENDLOOP, /* opt */ OPCODE_ENDSUB, /* opt */ OPCODE_EX2, /* X X 2 X X */ - OPCODE_EXP, /* X X X */ + OPCODE_EXP, /* X X */ OPCODE_FLR, /* X X 2 X X */ OPCODE_FRC, /* X X 2 X X */ OPCODE_IF, /* opt */ - OPCODE_KIL, /* X */ + OPCODE_KIL, /* X X */ OPCODE_KIL_NV, /* X X */ OPCODE_LG2, /* X X 2 X X */ OPCODE_LIT, /* X X X X */ - OPCODE_LOG, /* X X X */ - OPCODE_LRP, /* X X X */ + OPCODE_LOG, /* X X */ + OPCODE_LRP, /* X X */ OPCODE_MAD, /* X X X X X */ OPCODE_MAX, /* X X X X X */ OPCODE_MIN, /* X X X X X */ @@ -196,8 +196,8 @@ typedef enum prog_opcode { OPCODE_NOISE3, /* X */ OPCODE_NOISE4, /* X */ OPCODE_NOT, /* */ - OPCODE_NRM3, /* X */ - OPCODE_NRM4, /* X */ + OPCODE_NRM3, /* */ + OPCODE_NRM4, /* */ OPCODE_OR, /* */ OPCODE_PK2H, /* X */ OPCODE_PK2US, /* X */ @@ -209,10 +209,10 @@ typedef enum prog_opcode { OPCODE_PUSHA, /* 3 */ OPCODE_RCC, /* 1.1 */ OPCODE_RCP, /* X X X X X */ - OPCODE_RET, /* 2 2 X */ + OPCODE_RET, /* 2 2 opt */ OPCODE_RFL, /* X X */ OPCODE_RSQ, /* X X X X X */ - OPCODE_SCS, /* X */ + OPCODE_SCS, /* X X */ OPCODE_SEQ, /* 2 X X */ OPCODE_SFL, /* 2 X */ OPCODE_SGE, /* X X X X X */ @@ -221,10 +221,10 @@ typedef enum prog_opcode { OPCODE_SLE, /* 2 X X */ OPCODE_SLT, /* X X X X X */ OPCODE_SNE, /* 2 X X */ - OPCODE_SSG, /* 2 */ + OPCODE_SSG, /* 2 X */ OPCODE_STR, /* 2 X */ OPCODE_SUB, /* X X 1.1 X X */ - OPCODE_SWZ, /* X X */ + OPCODE_SWZ, /* X X X */ OPCODE_TEX, /* X 3 X X */ OPCODE_TXB, /* X 3 X */ OPCODE_TXD, /* X X */ @@ -238,7 +238,7 @@ typedef enum prog_opcode { OPCODE_UP4UB, /* X */ OPCODE_X2D, /* X */ OPCODE_XOR, /* */ - OPCODE_XPD, /* X X X */ + OPCODE_XPD, /* X X */ MAX_OPCODE } gl_inst_opcode; diff --git a/pixman/configure.ac b/pixman/configure.ac index 9a8ebe90a..2defbd4a2 100644 --- a/pixman/configure.ac +++ b/pixman/configure.ac @@ -650,6 +650,11 @@ fi AC_CHECK_HEADER([sys/mman.h], [AC_DEFINE(HAVE_SYS_MMAN_H, [1], [Define to 1 if we have ])]) +AC_CHECK_FUNC(mmap, have_mmap=yes, have_mmap=no) +if test x$have_mmap = xyes; then + AC_DEFINE(HAVE_MMAP, 1, [Whether we have mmap()]) +fi + AC_CHECK_FUNC(mprotect, have_mprotect=yes, have_mprotect=no) if test x$have_mprotect = xyes; then AC_DEFINE(HAVE_MPROTECT, 1, [Whether we have mprotect()]) diff --git a/pixman/test/utils.c b/pixman/test/utils.c index 56701c4bb..402560227 100644 --- a/pixman/test/utils.c +++ b/pixman/test/utils.c @@ -229,7 +229,7 @@ typedef struct int n_bytes; } info_t; -#if defined(HAVE_MPROTECT) && defined(HAVE_GETPAGESIZE) && defined(HAVE_SYS_MMAN_H) +#if defined(HAVE_MPROTECT) && defined(HAVE_GETPAGESIZE) && defined(HAVE_SYS_MMAN_H) && defined(HAVE_MMAP) /* This is apparently necessary on at least OS X */ #ifndef MAP_ANONYMOUS -- cgit v1.2.3