1 /* Copyright (C) 2001-2006 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied, modified
8    or distributed except as expressly authorized under the terms of that
9    license.  Refer to licensing information at http://www.artifex.com/
10    or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11    San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12 */
13 
14 /* $Id: zfontenum.c 9043 2008-08-28 22:48:19Z giles $ */
15 
16 /* this is the ps interpreter interface to the native font
17    enumeration code. it calls the platform-specific routines
18    to obtain an additional set of entries that can be added
19    to the Fontmap to reference fonts stored on the system.
20  */
21 
22 #include "memory_.h"
23 #include "string_.h"
24 #include <stdlib.h>
25 #include "ghost.h"
26 #include "oper.h"
27 #include "gsstruct.h"
28 #include "gsmalloc.h"
29 #include "ialloc.h"
30 #include "iname.h"
31 #include "iutil.h"
32 #include "store.h"
33 #include "gp.h"
34 
35 
36 typedef struct fontenum_s {
37 	char *fontname, *path;
38 	struct fontenum_s *next;
39 } fontenum_t;
40 
41 /* .getnativefonts [ [<name> <path>] ... ] */
42 static int
z_fontenum(i_ctx_t * i_ctx_p)43 z_fontenum(i_ctx_t *i_ctx_p)
44 {
45     os_ptr op = osp;
46     void *enum_state;
47     int code = 0;
48     int e,elements;
49     char *fontname, *path;
50     fontenum_t *r, *results;
51     ref array;
52     uint length;
53     byte *string;
54 
55     enum_state = gp_enumerate_fonts_init(imemory);
56     if (enum_state == NULL) {
57       /* put false on the stack and return */
58       push(1);
59       make_bool(op, false);
60       return code;
61     }
62 
63     r = results = gs_malloc(imemory->non_gc_memory, 1, sizeof(fontenum_t), "fontenum list");
64     elements = 0;
65     while((code = gp_enumerate_fonts_next(enum_state, &fontname, &path )) > 0) {
66 	if (fontname == NULL || path == NULL) {
67 	    gp_enumerate_fonts_free(enum_state);
68 	    return_error(e_ioerror);
69 	}
70 
71 	length = strlen(fontname) + 1;
72 	r->fontname = gs_malloc(imemory->non_gc_memory, length, 1, "native font name");
73 	memcpy(r->fontname, fontname, length);
74 
75 	length = strlen(path) + 1;
76 	    r->path = gs_malloc(imemory->non_gc_memory, length, 1, "native font path");
77 	    memcpy(r->path, path, length);
78 
79 	    r->next = gs_malloc(imemory->non_gc_memory, 1, sizeof(fontenum_t), "fontenum list");
80 	    r = r->next;
81 	    elements += 1;
82 	}
83 
84 	gp_enumerate_fonts_free(enum_state);
85 
86 	code = ialloc_ref_array(&array, a_all | icurrent_space, elements, "native fontmap");
87 
88 	r = results;
89 	for (e = 0; e < elements; e++) {
90 	    ref mapping;
91 
92 	    code = ialloc_ref_array(&mapping, a_all | icurrent_space, 2, "native font mapping");
93 
94 	    length = strlen(r->fontname);
95 	    string = ialloc_string(length, "native font name");
96 	    if (string == NULL)
97 		return_error(e_VMerror);
98 	    memcpy(string, r->fontname, length);
99 	    make_string(&(mapping.value.refs[0]), a_all | icurrent_space, length, string);
100 
101 	    length = strlen(r->path);
102 	    string = ialloc_string(length, "native font path");
103 	    if (string == NULL)
104 		return_error(e_VMerror);
105 	    memcpy(string, r->path, length);
106 	    make_string(&(mapping.value.refs[1]), a_all | icurrent_space, length, string);
107 
108 	    ref_assign(&(array.value.refs[e]), &mapping);
109 	    results = r;
110 	    r = r->next;
111 
112 	    gs_free(imemory->non_gc_memory,
113 		    results->fontname, strlen(results->fontname) + 1, 1, "native font name");
114 	    gs_free(imemory->non_gc_memory,
115 		    results->path, strlen(results->path) + 1, 1, "native font path");
116 	    gs_free(imemory->non_gc_memory,
117 		    results, 1, sizeof(fontenum_t), "fontenum list");
118 	}
119 
120     push(2);
121     ref_assign(op-1, &array);
122     make_bool(op, true);
123 
124     return code;
125 }
126 
127 
128 /* Match the above routines to their postscript filter names.
129    This is how our static routines get called externally. */
130 const op_def zfontenum_op_defs[] = {
131     {"0.getnativefonts", z_fontenum},
132     op_def_end(0)
133 };
134