/src/ghostpdl/pcl/pcl/pcfontpg.c
Line | Count | Source |
1 | | /* Copyright (C) 2001-2023 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, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | |
17 | | /* pcfontpg - print pcl resident typefaces */ |
18 | | |
19 | | #include "std.h" |
20 | | #include "gstypes.h" |
21 | | #include "pldict.h" |
22 | | #include "pcfont.h" |
23 | | #include "pcstate.h" |
24 | | #include "pcursor.h" |
25 | | #include "pcommand.h" |
26 | | #include "pllfont.h" |
27 | | #include "plftable.h" |
28 | | |
29 | | /* utility procedure to print n blank lines */ |
30 | | static int |
31 | | print_blank_lines(pcl_state_t * pcs, int count) |
32 | 316k | { |
33 | 316k | int code = 0; |
34 | | |
35 | 949k | while (count--) { |
36 | 633k | code = pcl_do_CR(pcs); |
37 | 633k | if (code < 0) |
38 | 0 | return code; |
39 | 633k | code = pcl_do_LF(pcs); |
40 | 633k | if (code < 0) |
41 | 0 | return code; |
42 | 633k | } |
43 | | |
44 | 316k | return code; |
45 | 316k | } |
46 | | |
47 | | static int |
48 | | process_font(pcl_state_t * pcs, pl_font_t * fp) |
49 | 310k | { |
50 | 310k | pcl_font_selection_t *pfs = &pcs->font_selection[pcs->font_selected]; |
51 | | |
52 | 310k | int code; |
53 | | |
54 | 310k | if (!fp) |
55 | 0 | return gs_throw(-1, "font is null"); |
56 | 310k | pcl_decache_font(pcs, -1, true); |
57 | 310k | pfs->params = fp->params; |
58 | 310k | pl_fp_set_pitch_per_inch(&pfs->params, 10); |
59 | 310k | pfs->params.height_4ths = 12 * 4; |
60 | 310k | { |
61 | | /* TODO we should print out the font name here to be more like |
62 | | the HP font page */ |
63 | 310k | const char *alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
64 | | /* current parameters */ |
65 | 310k | pl_font_params_t *pfp = &pfs->params; |
66 | 310k | char buff[150]; |
67 | | |
68 | 310k | code = pcl_text((byte *) alphabet, strlen(alphabet), pcs, false); |
69 | 310k | if (code < 0) |
70 | 0 | return gs_rethrow(code, "failed to display font"); |
71 | | |
72 | | /* go to approx center of the page */ |
73 | 310k | code = pcl_set_cap_x(pcs, pcs->margins.right / 2, false, false); |
74 | 310k | if (code < 0) |
75 | 0 | return gs_rethrow(code, "failed to set cap x\n"); |
76 | | |
77 | 310k | pcl_decache_font(pcs, -1, true); |
78 | | |
79 | | /* reset to default font and print the select font string and pjl number */ |
80 | | /* create the string command for font selection */ |
81 | 310k | gs_snprintf(buff, sizeof(buff), "<esc>(%u<esc>(s%dp%uv%us%db%dT\n", |
82 | 310k | pfp->symbol_set, (pfp->proportional_spacing ? 1 : 0), |
83 | 310k | pfp->height_4ths / 10, pfp->style, pfp->stroke_weight, |
84 | 310k | pfp->typeface_family); |
85 | | |
86 | 310k | code = pcl_set_current_font_environment(pcs); |
87 | 310k | if (code < 0) |
88 | 0 | return gs_rethrow(code, "failed to set default font"); |
89 | | |
90 | 310k | code = pcl_text((byte *) buff, strlen(buff), pcs, false); |
91 | 310k | if (code < 0) |
92 | 0 | return gs_rethrow(code, "failed to display font"); |
93 | | |
94 | 310k | code = pcl_set_cap_x(pcs, (coord) (pcs->margins.right / (16.0 / 15.0)), |
95 | 310k | false, false); |
96 | 310k | if (code < 0) |
97 | 0 | return gs_rethrow(code, "failed to set cap x\n"); |
98 | 310k | gs_snprintf(buff, sizeof(buff), "%d", fp->params.pjl_font_number); |
99 | | |
100 | 310k | code = pcl_text((byte *) buff, strlen(buff), pcs, false); |
101 | 310k | if (code < 0) |
102 | 0 | return gs_rethrow(code, "failed to display font number"); |
103 | 310k | } |
104 | 310k | code = print_blank_lines(pcs, 2); |
105 | 310k | if (code < 0) |
106 | 0 | return gs_rethrow(code, "failed to print blank lines"); |
107 | 310k | return 0; |
108 | 310k | } |
109 | | |
110 | | /* print a pcl font page. We do a pcl printer reset before and after |
111 | | the font list is printed */ |
112 | | static int |
113 | | pcl_print_font_page(pcl_args_t * pargs, pcl_state_t * pcs) |
114 | 3.04k | { |
115 | 3.04k | pl_dict_enum_t font_enum; |
116 | 3.04k | gs_const_string key; |
117 | 3.04k | void *value; |
118 | 3.04k | int pjl_num; |
119 | 3.04k | int code; |
120 | | |
121 | | /* reset the printer for a clean page */ |
122 | 3.04k | code = pcl_do_printer_reset(pcs); |
123 | 3.04k | if (code < 0) |
124 | 0 | return gs_rethrow(code, "printer reset failed"); |
125 | | |
126 | | /* font page header */ |
127 | 3.04k | { |
128 | 3.04k | const char *header_str = "PCL Font List"; |
129 | 3.04k | const char *sample_str = "Sample"; |
130 | 3.04k | const char *select_str = "Font Selection Command"; |
131 | 3.04k | uint hlen = strlen(header_str); |
132 | | /* assume the pcl font list string is 1 inch 7200 units */ |
133 | 3.04k | uint pos = pcs->margins.right / 2 - 7200 / 2; |
134 | | |
135 | 3.04k | code = pcl_set_cap_x(pcs, pos, false, false); |
136 | 3.04k | if (code < 0) |
137 | 0 | return gs_rethrow(code, "failed to set cap x\n"); |
138 | 3.04k | code = pcl_text((byte *) header_str, hlen, pcs, false); |
139 | 3.04k | if (code < 0) |
140 | 0 | return gs_rethrow(code, "printing PCL Font List failed\n"); |
141 | 3.04k | code = print_blank_lines(pcs, 2); |
142 | 3.04k | if (code < 0) |
143 | 0 | return gs_rethrow(code, "failed to print blank lines"); |
144 | 3.04k | code = pcl_text((byte *) sample_str, strlen(sample_str), pcs, false); |
145 | 3.04k | if (code < 0) |
146 | 0 | return gs_rethrow(code, "printing Sample failed\n"); |
147 | 3.04k | code = pcl_set_cap_x(pcs, pcs->margins.right / 2, false, false); |
148 | 3.04k | if (code < 0) |
149 | 0 | return gs_rethrow(code, "failed to set cap x\n"); |
150 | 3.04k | code = pcl_text((byte *) select_str, strlen(select_str), pcs, false); |
151 | 3.04k | if (code < 0) |
152 | 0 | return gs_rethrow(code, "printing Font Selection Command failed\n"); |
153 | 3.04k | code = print_blank_lines(pcs, 2); |
154 | 3.04k | if (code < 0) |
155 | 0 | return gs_rethrow(code, "failed to print blank lines"); |
156 | 3.04k | } |
157 | | |
158 | | /* enumerate all non-resident fonts. */ |
159 | 3.04k | pl_dict_enum_begin(&pcs->soft_fonts, &font_enum); |
160 | 313k | while (pl_dict_enum_next(&font_enum, &key, &value)) { |
161 | 310k | pl_font_t *fp = value; |
162 | | |
163 | | /* skip internal fonts */ |
164 | 310k | if (fp->storage == pcds_internal) |
165 | 310k | continue; |
166 | 0 | code = process_font(pcs, fp); |
167 | 0 | if (code < 0) |
168 | 0 | return gs_rethrow(code, "printing downloaded font failed\n"); |
169 | 0 | } |
170 | | |
171 | | /* now print out the resident fonts in pjl font number order */ |
172 | 313k | for (pjl_num = 0; pjl_num < pl_built_in_resident_font_table_count; |
173 | 310k | pjl_num++) { |
174 | 310k | pl_font_t *fp = |
175 | 310k | pl_lookup_font_by_pjl_number(&pcs->built_in_fonts, pjl_num); |
176 | 310k | code = process_font(pcs, fp); |
177 | 310k | if (code < 0) |
178 | 0 | return gs_rethrow1(code, "printing font number %d failed\n", |
179 | 310k | pjl_num); |
180 | 310k | } |
181 | 3.04k | code = pcl_do_printer_reset(pcs); |
182 | 3.04k | if (code < 0) |
183 | 0 | return gs_rethrow(code, "printer reset failed"); |
184 | 3.04k | return 0; |
185 | 3.04k | } |
186 | | |
187 | | static int |
188 | | pcfontpg_do_registration(pcl_parser_state_t * pcl_parser_state, |
189 | | gs_memory_t * mem) |
190 | 16.1k | { |
191 | 16.1k | DEFINE_ESCAPE_ARGS('A', "Print Font Page", pcl_print_font_page, |
192 | 16.1k | pca_in_rtl); |
193 | 16.1k | return 0; |
194 | 16.1k | } |
195 | | |
196 | | const pcl_init_t fontpg_init = { |
197 | | pcfontpg_do_registration, 0, 0 |
198 | | }; |