/src/ghostpdl/psi/zchar32.c
Line | Count | Source (jump to first uncovered line) |
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 | | /* Type 32 font glyph operators */ |
18 | | #include "ghost.h" |
19 | | #include "oper.h" |
20 | | #include "gsccode.h" /* for gxfont.h */ |
21 | | #include "gsmatrix.h" |
22 | | #include "gsutil.h" |
23 | | #include "gxfixed.h" |
24 | | #include "gxfont.h" |
25 | | #include "gxfcache.h" |
26 | | #include "ifont.h" |
27 | | #include "igstate.h" |
28 | | #include "store.h" |
29 | | |
30 | | /* ([wx wy llx lly urx ury] | [w0x w0y llx lly urx ury w1x w1y vx vy]) */ |
31 | | /* <bitmap> <cid> <type32font> <str22> .makeglyph32 <<same with substr>> */ |
32 | | static int |
33 | | zmakeglyph32(i_ctx_t *i_ctx_p) |
34 | 0 | { |
35 | 0 | os_ptr op = osp; |
36 | 0 | bool long_form; |
37 | 0 | uint msize; |
38 | 0 | double metrics[10]; |
39 | 0 | int wx, llx, lly, urx, ury; |
40 | 0 | int width, height, raster; |
41 | 0 | gs_font *pfont; |
42 | 0 | int code; |
43 | 0 | byte *str; |
44 | |
|
45 | 0 | check_array(op[-4]); |
46 | 0 | msize = r_size(op - 4); |
47 | 0 | switch (msize) { |
48 | 0 | case 10: |
49 | 0 | long_form = true; |
50 | 0 | break; |
51 | 0 | case 6: |
52 | 0 | long_form = false; |
53 | 0 | break; |
54 | 0 | default: |
55 | 0 | return_error(gs_error_rangecheck); |
56 | 0 | } |
57 | 0 | code = num_params(op[-4].value.refs + msize - 1, msize, metrics); |
58 | 0 | if (code < 0) |
59 | 0 | return code; |
60 | 0 | if (~code & 0x3c) /* check llx .. ury for integers */ |
61 | 0 | return_error(gs_error_typecheck); |
62 | 0 | check_read_type(op[-3], t_string); |
63 | 0 | llx = (int)metrics[2]; |
64 | 0 | lly = (int)metrics[3]; |
65 | 0 | urx = (int)metrics[4]; |
66 | 0 | ury = (int)metrics[5]; |
67 | 0 | width = urx - llx; |
68 | 0 | height = ury - lly; |
69 | 0 | raster = (width + 7) >> 3; |
70 | 0 | if (width < 0 || height < 0 || r_size(op - 3) != raster * height) |
71 | 0 | return_error(gs_error_rangecheck); |
72 | 0 | check_int_leu(op[-2], 65535); |
73 | 0 | code = font_param(op - 1, &pfont); |
74 | 0 | if (code < 0) |
75 | 0 | return code; |
76 | 0 | if (pfont->FontType != ft_CID_bitmap) |
77 | 0 | return_error(gs_error_invalidfont); |
78 | 0 | check_write_type(*op, t_string); |
79 | 0 | if (r_size(op) < 22) |
80 | 0 | return_error(gs_error_rangecheck); |
81 | 0 | str = op->value.bytes; |
82 | 0 | if (long_form || metrics[0] != (wx = (int)metrics[0]) || |
83 | 0 | metrics[1] != 0 || height == 0 || |
84 | 0 | ((wx | width | height | (llx + 128) | (lly + 128)) & ~255) != 0 |
85 | 0 | ) { |
86 | | /* Use the long form. */ |
87 | 0 | int i, n = (long_form ? 10 : 6); |
88 | |
|
89 | 0 | str[0] = 0; |
90 | 0 | str[1] = long_form; |
91 | 0 | for (i = 0; i < n; ++i) { |
92 | 0 | int v = (int)metrics[i]; /* no floating point widths yet */ |
93 | |
|
94 | 0 | str[2 + 2 * i] = (byte)(v >> 8); |
95 | 0 | str[2 + 2 * i + 1] = (byte)v; |
96 | 0 | } |
97 | 0 | r_set_size(op, 2 + n * 2); |
98 | 0 | } else { |
99 | | /* Use the short form. */ |
100 | 0 | str[0] = (byte)width; |
101 | 0 | str[1] = (byte)height; |
102 | 0 | str[2] = (byte)wx; |
103 | 0 | str[3] = (byte)(llx + 128); |
104 | 0 | str[4] = (byte)(lly + 128); |
105 | 0 | r_set_size(op, 5); |
106 | 0 | } |
107 | 0 | return code; |
108 | 0 | } |
109 | | |
110 | | /* <cid_min> <cid_max> <type32font> .removeglyphs - */ |
111 | | typedef struct { |
112 | | gs_glyph cid_min, cid_max; |
113 | | gs_font *font; |
114 | | } font_cid_range_t; |
115 | | static bool |
116 | | select_cid_range(const gs_memory_t *mem, cached_char * cc, void *range_ptr) |
117 | 0 | { |
118 | 0 | const font_cid_range_t *range = range_ptr; |
119 | |
|
120 | 0 | return (cc->code >= range->cid_min && |
121 | 0 | cc->code <= range->cid_max && |
122 | 0 | cc->pair->font == range->font); |
123 | 0 | } |
124 | | static int |
125 | | zremoveglyphs(i_ctx_t *i_ctx_p) |
126 | 0 | { |
127 | 0 | os_ptr op = osp; |
128 | 0 | int code; |
129 | 0 | font_cid_range_t range; |
130 | |
|
131 | 0 | check_int_leu(op[-2], 65535); |
132 | 0 | check_int_leu(op[-1], 65535); |
133 | 0 | code = font_param(op, &range.font); |
134 | 0 | if (code < 0) |
135 | 0 | return code; |
136 | 0 | if (range.font->FontType != ft_CID_bitmap) |
137 | 0 | return_error(gs_error_invalidfont); |
138 | 0 | range.cid_min = GS_MIN_CID_GLYPH + op[-2].value.intval; |
139 | 0 | range.cid_max = GS_MIN_CID_GLYPH + op[-1].value.intval; |
140 | 0 | gx_purge_selected_cached_chars(range.font->dir, select_cid_range, |
141 | 0 | &range); |
142 | 0 | pop(3); |
143 | 0 | return 0; |
144 | 0 | } |
145 | | |
146 | | /* <str5/14/22> .getmetrics32 <width> <height> <wx> ... <ury> 5/14 */ |
147 | | /* <str5/14/22> .getmetrics32 <width> <height> <w0x> ... <vy> 22 */ |
148 | | static int |
149 | | zgetmetrics32(i_ctx_t *i_ctx_p) |
150 | 0 | { |
151 | 0 | os_ptr op = osp; |
152 | 0 | const byte *data; |
153 | 0 | uint size; |
154 | 0 | int i, n = 6; |
155 | 0 | os_ptr wop; |
156 | |
|
157 | 0 | check_read_type(*op, t_string); |
158 | 0 | data = op->value.const_bytes; |
159 | 0 | size = r_size(op); |
160 | 0 | if (size < 5) |
161 | 0 | return_error(gs_error_rangecheck); |
162 | 0 | if (data[0]) { |
163 | | /* Short form. */ |
164 | 0 | int llx = (int)data[3] - 128, lly = (int)data[4] - 128; |
165 | |
|
166 | 0 | n = 6; |
167 | 0 | size = 5; |
168 | 0 | push(8); |
169 | 0 | make_int(op - 6, data[2]); /* wx */ |
170 | 0 | make_int(op - 5, 0); /* wy */ |
171 | 0 | make_int(op - 4, llx); |
172 | 0 | make_int(op - 3, lly); |
173 | 0 | make_int(op - 2, llx + data[0]); /* urx */ |
174 | 0 | make_int(op - 1, lly + data[1]); /* ury */ |
175 | 0 | } else { |
176 | 0 | if (data[1]) { |
177 | | /* Long form, both WModes. */ |
178 | 0 | if (size < 22) |
179 | 0 | return_error(gs_error_rangecheck); |
180 | 0 | n = 10; |
181 | 0 | size = 22; |
182 | 0 | } else { |
183 | | /* Long form, WMode = 0 only. */ |
184 | 0 | if (size < 14) |
185 | 0 | return_error(gs_error_rangecheck); |
186 | 0 | n = 6; |
187 | 0 | size = 14; |
188 | 0 | } |
189 | 0 | push(2 + n); |
190 | 0 | for (i = 0; i < n; ++i) |
191 | 0 | make_int(op - n + i, |
192 | 0 | ((int)((data[2 * i + 2] << 8) + data[2 * i + 3]) ^ 0x8000) |
193 | 0 | - 0x8000); |
194 | 0 | } |
195 | 0 | wop = op - n; |
196 | 0 | make_int(wop - 2, wop[4].value.intval - wop[2].value.intval); |
197 | 0 | make_int(wop - 1, wop[5].value.intval - wop[3].value.intval); |
198 | 0 | make_int(op, size); |
199 | 0 | return 0; |
200 | 0 | } |
201 | | |
202 | | /* ------ Initialization procedure ------ */ |
203 | | |
204 | | const op_def zchar32_op_defs[] = |
205 | | { |
206 | | {"1.getmetrics32", zgetmetrics32}, |
207 | | {"4.makeglyph32", zmakeglyph32}, |
208 | | {"3.removeglyphs", zremoveglyphs}, |
209 | | op_def_end(0) |
210 | | }; |