summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipsk/bitmapenc.c
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2020-01-29 18:51:54 +0000
committerKarl Berry <karl@freefriends.org>2020-01-29 18:51:54 +0000
commit940c24434690083c532105022ff57bdf662ca2f7 (patch)
tree889c2272a8074f142adae891a329151b55d98436 /Build/source/texk/dvipsk/bitmapenc.c
parentf3f1ff5d1b26a0f0f973c4a6b81fa6d49105faf2 (diff)
bitmapfontencoding updates for option/config name, strictness
git-svn-id: svn://tug.org/texlive/trunk@53589 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/dvipsk/bitmapenc.c')
-rw-r--r--Build/source/texk/dvipsk/bitmapenc.c161
1 files changed, 147 insertions, 14 deletions
diff --git a/Build/source/texk/dvipsk/bitmapenc.c b/Build/source/texk/dvipsk/bitmapenc.c
index c8ee318416d..717d51c2abe 100644
--- a/Build/source/texk/dvipsk/bitmapenc.c
+++ b/Build/source/texk/dvipsk/bitmapenc.c
@@ -72,6 +72,7 @@ struct bmenc {
const char **enc ; // the encoding itself
int downloaded_seq ; // -1: not downloaded; else, sequence number
struct bmenc *next ; // next encoding in linear linked list
+ unsigned char existsbm[32] ; // a bitmap of characters with names
} ;
static struct bmenc *bmlist ;
/*
@@ -172,7 +173,7 @@ static void add_encline(const char *encline) {
* for later lookup, and always return 0. Otherwise we just expect a
* single encoding and we store that away.
*/
-static const char **parseencoding(FILE *f, int use_all) {
+static const char **parseencodingfile(FILE *f, int use_all) {
char encbuf[MAX_LINE_LENGTH+1] ;
size_t i ;
for (i=0; i<sizeof(encbuf); i++)
@@ -259,6 +260,116 @@ static int eqencoding(const char **a, const char **b) {
return 1 ;
}
/*
+ * Try to parse an encoding to identify which names exist and which don't.
+ * If we can't trivially parse it we just mark all names as existing.
+ * We properly parse the following types of tokens:
+ * [ (at start) ] (at end) : ignored
+ * /name
+ * digits { /.notdef } repeat
+ *
+ * In all cases the spaces and linebreaks are arbitrary.
+ *
+ * The state machine works as follows:
+ *
+ * 'B': begin; expect [
+ * 'N': between entries; expect name or digits or ]
+ * 'E': finished (saw ]); expect nothing more
+ * '#': just saw digits; expect only {
+ * '{': just saw {; expect only name and should be /.notdef
+ * 'L': just saw a name inside {}; expect only }
+ * '}': just saw }; expect only repeat
+ */
+static int trytoparseenc(struct bmenc *bme) {
+ int i ;
+ const char **enc = bme->enc ;
+ const char *p ;
+ int seenchars = 0 ;
+ int num = 0 ;
+ char state = 'B' ;
+ for (i=0; i<32; i++)
+ bme->existsbm[i] = 255 ;
+ while (*enc != 0) {
+ p = *enc ;
+ enc++ ;
+ while (*p && *p <= ' ')
+ p++ ;
+ while (*p != 0) {
+ switch (state) {
+case 'B': if (*p != '[') return 0 ;
+ p++ ;
+ state = 'N' ;
+ break ;
+case 'N': if (*p == ']') {
+ p++ ;
+ state = 'E' ;
+ } else if (*p == '/') {
+ if (seenchars >= 256)
+ return 0 ;
+ if (strncmp(p, "/.notdef", 8) == 0 &&
+ (p[8] <= ' ' || index("{}[]<>()%/", p[8]) == 0)) {
+ bme->existsbm[seenchars>>3] &= ~(1<<(seenchars & 7)) ;
+ }
+ // see PostScript language reference manual syntax for this
+ p++ ;
+ while (*p > ' ' && index("{}[]<>()%/", *p) == 0)
+ p++ ;
+ seenchars++ ;
+ } else if ('0' <= *p && *p <= '9') {
+ num = 0 ;
+ while (num < 256 && '0' <= *p && *p <= '9')
+ num = 10 * num + *p++ - '0' ;
+ state = '#' ;
+ } else
+ return 0 ;
+ break ;
+case '#': if (*p != '{') return 0 ;
+ p++ ;
+ state = '{' ;
+ break ;
+case '{': if (strncmp(p, "/.notdef", 8) != 0)
+ return 0 ;
+ p += 8 ;
+ if (*p > ' ' && index("{}[]<>()%/", *p) == 0)
+ return 0 ;
+ while (num > 0) {
+ if (seenchars >= 256)
+ return 0 ;
+ bme->existsbm[seenchars>>3] &= ~(1<<(seenchars & 7)) ;
+ seenchars++ ;
+ num-- ;
+ }
+ state = 'L' ;
+ break ;
+case 'L': if (*p != '}')
+ return 0 ;
+ p++ ;
+ state = '}' ;
+ break ;
+case '}': if (strncmp(p, "repeat", 6) != 0)
+ return 0 ;
+ p += 6 ;
+ state = 'N' ;
+ break ;
+default:
+ error("! internal error in encoding vector parse") ;
+ }
+ while (*p && *p <= ' ')
+ p++ ;
+ }
+ }
+ if (seenchars != 256)
+ return 0 ;
+ return 1 ;
+}
+static void parseenc(struct bmenc *bme) {
+ int i ;
+ if (trytoparseenc(bme) == 0) {
+ printf("Failed to parse it.\n") ;
+ for (i=0; i<32; i++)
+ bme->existsbm[i] = 255 ;
+ }
+}
+/*
* Add an encoding to our list of deduplicated encodings.
*/
struct bmenc *addbmenc(const char **enc) {
@@ -266,6 +377,7 @@ struct bmenc *addbmenc(const char **enc) {
r->downloaded_seq = -1 ;
r->enc = enc ;
r->next = bmlist ;
+ parseenc(r) ;
bmlist = r ;
return r ;
}
@@ -289,7 +401,7 @@ static struct bmenc *deduplicateencoding(const char **enc) {
static const char **bitmap_enc_load(const char *fontname, int use_all) {
FILE *f = bitmap_enc_search(use_all ? "all" : fontname) ;
if (f != 0) {
- const char **r = parseencoding(f, use_all) ;
+ const char **r = parseencodingfile(f, use_all) ;
fclose(f) ;
return r ;
}
@@ -361,13 +473,32 @@ static void downloadenc(struct bmenc *enc) {
* used to do instead (don't give it an encoding or resize or
* rescale).
*/
-static int getencoding_seq(const char *fontname) ;
-int downloadbmencoding(const char *name, double scale,
- int llx, int lly, int urx, int ury) {
+static struct bmenc *getencoding_seq(const char *fontname) ;
+int downloadbmencoding(const char *name, double scale, fontdesctype *curfnt) {
int slop;
- int seq = getencoding_seq(name) ;
- if (seq < 0)
+ int i ;
+ int seq ;
+ int llx = curfnt->llx ;
+ int lly = curfnt->lly ;
+ int urx = curfnt->urx ;
+ int ury = curfnt->ury ;
+ struct bmenc *bme = getencoding_seq(name) ;
+ if (bme == 0)
return -1 ;
+ seq = bme->downloaded_seq ;
+/*
+ * Check that every character defined in the font has a name in the
+ * PostScript vector, and complain if this is not the case.
+ */
+ for (i=0; i<256 && i<curfnt->maxchars; i++) {
+ if ((curfnt->chardesc[i].flags2 & EXISTS) &&
+ !(bme->existsbm[i>>3] & (1 << (i & 7)))) {
+ fprintf(stderr,
+"Can't use PostScript encoding vector for font %s; character %d has no name.\n",
+ name, i) ;
+ return -1 ;
+ }
+ }
cmdout("IEn") ;
cmdout("S") ;
psnameout("/IEn") ;
@@ -443,14 +574,14 @@ static void bmenc_warn(const char *fontname, const char *msg) {
* -1; this font may not work as well for copy/paste and text search.
*/
static int tried_all = 0 ; // have we tried to load dvips-all.enc
-static int getencoding_seq(const char *fontname) {
+static struct bmenc *getencoding_seq(const char *fontname) {
struct bmenc *enc = 0 ;
struct bmfontenc *p = bmfontenclist ;
for (; p!=0; p=p->next)
if (strcmp(fontname, p->fontname) == 0) {
enc = p->enc ;
if (enc == 0) // remember failures
- return -1 ;
+ return 0 ;
break ;
}
// not in list; try to load it from a file
@@ -473,6 +604,7 @@ static int getencoding_seq(const char *fontname) {
p->fontname = strdup(fontname) ;
p->enc = enc ;
p->next = bmfontenclist ;
+// parseenc(enc) ;
bmfontenclist = p ;
}
if (enc == 0) {
@@ -480,10 +612,10 @@ static int getencoding_seq(const char *fontname) {
bmenc_warn(fontname, "no encoding found") ;
warned_about_missing_encoding = 2 ;
}
- return -1 ; // don't download an encoding
+ return 0 ; // don't download an encoding
}
downloadenc(enc) ;
- return enc->downloaded_seq ;
+ return enc ;
}
#ifdef STANDALONE
/*
@@ -505,7 +637,7 @@ void newline() {
idok = 1 ;
pos = 0 ;
}
-void doubleout(float f) {
+void doubleout(double f) {
printf("%g", f) ;
pos += 8 ;
}
@@ -549,9 +681,10 @@ void specialout(char c) {
int main(int argc, char *argv[]) {
bmenc_startsection() ;
for (int i=1; i<argc; i++) {
- int r = getencoding_seq(argv[i]) ;
+ struct bmenc *r = getencoding_seq(argv[i]) ;
+ int seq = r ? r->downloaded_seq : -1 ;
printf("\n") ;
- printf("Result for %s is %d\n", argv[i], r) ;
+ printf("Result for %s is %d\n", argv[i], seq) ;
}
}
#endif