Coverage Report

Created: 2026-07-24 07:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
};