Coverage Report

Created: 2026-04-01 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/pcl/pxl/pxffont.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
/* pxffont.c */
18
/* PCL XL font-finding procedures */
19
20
#include "string_.h"
21
#include "gx.h"
22
#include "gschar.h"
23
#include "gsmatrix.h"           /* for gsfont.h */
24
#include "gxfont.h"
25
#include "gxfont42.h"
26
#include "pxoper.h"
27
#include "pxstate.h"
28
#include "pxfont.h"
29
#include "pjtop.h"
30
31
/* ---------------- Operator utilities ---------------- */
32
33
#if ARCH_IS_BIG_ENDIAN
34
#  define pxd_native_byte_order pxd_big_endian
35
#else
36
2.39k
#  define pxd_native_byte_order 0
37
#endif
38
39
/* Widen and/or byte-swap a font name to Unicode if needed. */
40
/* The argument is a ubyte or uint16 array; the result is a uint16 array */
41
/* with the elements in native byte order. */
42
/* We don't deal with mappings: we just widen 8-bit to 16-bit characters */
43
/* and hope for the best.... */
44
static int
45
px_widen_font_name(px_value_t * pfnv, px_state_t * pxs)
46
1.19k
{
47
1.19k
    uint type = pfnv->type;
48
49
1.19k
    if ((type & (pxd_uint16 | pxd_big_endian)) ==
50
1.19k
        (pxd_uint16 | pxd_native_byte_order)
51
1.19k
        )
52
0
        return 0;               /* already in correct format */
53
1.19k
    {
54
1.19k
        byte *old_data = (byte *) pfnv->value.array.data;       /* break const */
55
1.19k
        uint size = pfnv->value.array.size;
56
1.19k
        char16 *new_data;
57
1.19k
        uint i;
58
59
1.19k
        if (type & pxd_on_heap)
60
27
            old_data = (byte *)
61
27
                (new_data =
62
27
                 (char16 *) gs_resize_object(pxs->memory, old_data,
63
27
                                             size * 2, "px_widen_font_name"));
64
1.17k
        else
65
1.17k
            new_data =
66
1.17k
                (char16 *) gs_alloc_byte_array(pxs->memory, size,
67
1.19k
                                               sizeof(char16),
68
1.19k
                                               "px_widen_font_name");
69
1.19k
        if (new_data == 0)
70
0
            return_error(errorInsufficientMemory);
71
28.5k
        for (i = size; i;) {
72
27.3k
            --i;
73
27.3k
            new_data[i] =
74
27.3k
                (type & pxd_ubyte ? old_data[i] :
75
27.3k
                 uint16at(old_data + i * 2, type & pxd_big_endian));
76
27.3k
        }
77
1.19k
        pfnv->value.array.data = (byte *) new_data;
78
1.19k
    }
79
0
    pfnv->type = (type & ~(pxd_ubyte | pxd_big_endian)) |
80
1.19k
        (pxd_uint16 | pxd_native_byte_order | pxd_on_heap);
81
1.19k
    return 0;
82
1.19k
}
83
84
/* ---------------- Operator implementations ---------------- */
85
86
/* Look up a font name and return an existing font. */
87
/* This procedure may widen and/or byte-swap the font name. */
88
/* If this font is supposed to be built in but no .TTF file is available, */
89
/* or if loading the font fails, return >= 0 and store 0 in *ppxfont. */
90
int
91
px_find_existing_font(px_value_t * pfnv, px_font_t ** ppxfont,
92
                      px_state_t * pxs)
93
1.19k
{
94
1.19k
    int code;
95
1.19k
    void *pxfont;
96
97
1.19k
    *ppxfont = NULL;
98
99
    /* Normalize the font name to Unicode. */
100
1.19k
    code = px_widen_font_name(pfnv, pxs);
101
1.19k
    if (code < 0)
102
0
        return code;
103
104
1.19k
    if (px_dict_find(&pxs->font_dict, pfnv, &pxfont)) {
105
        /* Make sure this isn't a partially defined font */
106
260
        if (((px_font_t *) pxfont)->pfont)
107
260
            *ppxfont = pxfont;
108
0
        else {
109
            /* in the process of being downloaded. */
110
0
            dmprintf(pxs->memory, "font is being downloaded???\n");
111
0
            return -1;
112
0
        }
113
937
    } else if (px_dict_find(&pxs->builtin_font_dict, pfnv, &pxfont))
114
601
        if (((px_font_t *) pxfont)->pfont)
115
601
            *ppxfont = pxfont;
116
0
        else {
117
0
            dmprintf(pxs->memory, "corrupt pxl builtin font\n");
118
0
            return -1;
119
0
    } else
120
336
        return -1;              /* font not found  or corrupt builtin font */
121
122
861
    return 0;
123
1.19k
}
124
125
/* Look up a font name and return a font, possibly with substitution. */
126
/* This procedure implements most of the SetFont operator. */
127
/* This procedure may widen and/or byte-swap the font name. */
128
int
129
px_find_font(px_value_t * pfnv, uint symbol_set, px_font_t ** ppxfont,
130
             px_state_t * pxs)
131
639
{
132
133
639
    int code;
134
135
    /* Check if we know the font already. */
136
    /* Note that px_find_existing_font normalizes the font name. */
137
639
    code = px_find_existing_font(pfnv, ppxfont, pxs);
138
139
    /* substitute for missing builtin font */
140
639
    if (code < 0) {
141
26
        px_value_t default_font_value;
142
143
        /* the documentation states the default font chosen here
144
           is device dependent */
145
26
        const char *default_font = "Courier         ";
146
26
        char message[px_max_error_line + 1];
147
148
26
        default_font_value.type = pxd_ubyte | pxd_array;
149
26
        default_font_value.value.array.data = (const byte *)default_font;
150
26
        default_font_value.value.array.size = strlen(default_font);
151
26
        code = px_find_existing_font(&default_font_value, ppxfont, pxs);
152
        /* shouldn't fail */
153
26
        if (code < 0)
154
0
            return code;
155
26
        message[0] = (char)0;
156
26
        px_concat_font_name(message, px_max_error_line, &default_font_value);
157
26
        strcat(message, "substituted for ");
158
26
        px_concat_font_name(message, px_max_error_line, pfnv);
159
26
        code = px_record_warning(message, false, pxs);
160
26
    }
161
639
    if (code >= 0)
162
639
        return pl_load_resident_font_data_from_file(pxs->memory, *ppxfont);
163
0
    else
164
0
        return code;
165
639
}