/src/ghostpdl/base/gschar.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 | | /* Character writing "operators" for Ghostscript library */ |
18 | | #include "gx.h" |
19 | | #include "gserrors.h" |
20 | | #include "gsstruct.h" |
21 | | #include "gsmatrix.h" /* for gscoord.h */ |
22 | | #include "gscoord.h" /* for gs_idtransform */ |
23 | | #include "gzstate.h" |
24 | | #include "gxdevice.h" |
25 | | #include "gxdevmem.h" |
26 | | #include "gxchar.h" |
27 | | #include "gxfont.h" |
28 | | |
29 | | /* Structure descriptors */ |
30 | | extern_st(st_gs_show_enum); |
31 | | |
32 | | /* ------ String writing operators ------ */ |
33 | | |
34 | | /* Free the contents of a show enumerator. */ |
35 | | void |
36 | | gs_show_enum_release(gs_show_enum * penum, gs_memory_t * emem) |
37 | 0 | { |
38 | 0 | if (penum->text.operation) /* otherwise, never initialized */ |
39 | 0 | penum->procs->release((gs_text_enum_t *)penum, "gs_show_enum_release"); |
40 | 0 | if (emem != 0) |
41 | 0 | gs_free_object(emem, penum, "gs_show_enum_release"); |
42 | 0 | } |
43 | | |
44 | | /* ------ Width/cache operators ------ */ |
45 | | |
46 | | /* setcachedevice */ |
47 | | /* The elements of pw are: wx, wy, llx, lly, urx, ury. */ |
48 | | /* Note that this returns 1 if we just set up the cache device. */ |
49 | | int |
50 | | gs_setcachedevice_double(gs_show_enum *penum, gs_gstate *pgs, const double *pw) |
51 | 0 | { |
52 | 0 | if (penum->pgs != pgs) |
53 | 0 | return_error(gs_error_rangecheck); |
54 | 0 | return gs_text_setcachedevice((gs_text_enum_t *)penum, pw); |
55 | 0 | } |
56 | | /* The _float procedure is strictly for backward compatibility. */ |
57 | | int |
58 | | gs_setcachedevice_float(gs_show_enum * penum, gs_gstate * pgs, const float *pw) |
59 | 0 | { |
60 | 0 | double w[6]; |
61 | 0 | int i; |
62 | |
|
63 | 0 | for (i = 0; i < 6; ++i) |
64 | 0 | w[i] = pw[i]; |
65 | 0 | return gs_setcachedevice_double(penum, pgs, w); |
66 | 0 | } |
67 | | |
68 | | /* setcachedevice2 */ |
69 | | /* The elements of pw2 are: w0x, w0y, llx, lly, urx, ury, w1x, w1y, vx, vy. */ |
70 | | /* Note that this returns 1 if we just set up the cache device. */ |
71 | | int |
72 | | gs_setcachedevice2_double(gs_show_enum * penum, gs_gstate * pgs, |
73 | | const double *pw2) |
74 | 13.8M | { |
75 | 13.8M | if (penum->pgs != pgs) |
76 | 0 | return_error(gs_error_rangecheck); |
77 | 13.8M | return gs_text_setcachedevice2((gs_text_enum_t *)penum, pw2); |
78 | 13.8M | } |
79 | | /* The _float procedure is strictly for backward compatibility. */ |
80 | | int |
81 | | gs_setcachedevice2_float(gs_show_enum * penum, gs_gstate * pgs, const float *pw2) |
82 | 13.8M | { |
83 | 13.8M | double w2[10]; |
84 | 13.8M | int i; |
85 | | |
86 | 152M | for (i = 0; i < 10; ++i) |
87 | 138M | w2[i] = pw2[i]; |
88 | 13.8M | return gs_setcachedevice2_double(penum, pgs, w2); |
89 | 13.8M | } |
90 | | |
91 | | /* setcharwidth */ |
92 | | /* Note that this returns 1 if the current show operation is */ |
93 | | /* non-displaying (stringwidth or cshow). */ |
94 | | int |
95 | | gs_setcharwidth(gs_show_enum * penum, gs_gstate * pgs, |
96 | | double wx, double wy) |
97 | 0 | { |
98 | 0 | double w[2]; |
99 | |
|
100 | 0 | if (penum->pgs != pgs) |
101 | 0 | return_error(gs_error_rangecheck); |
102 | 0 | w[0] = wx, w[1] = wy; |
103 | 0 | return gs_text_setcharwidth((gs_text_enum_t *)penum, w); |
104 | 0 | } |
105 | | |
106 | | /* ------ Enumerator ------ */ |
107 | | |
108 | | /* Do the next step of a show (or stringwidth) operation */ |
109 | | int |
110 | | gs_show_next(gs_show_enum * penum) |
111 | 0 | { |
112 | 0 | return gs_text_process((gs_text_enum_t *)penum); |
113 | 0 | } |
114 | | |
115 | | /* |
116 | | * Return true if we only need the width from the rasterizer |
117 | | * and can short-circuit the full rendering of the character, |
118 | | * false if we need the actual character bits. |
119 | | */ |
120 | | bool |
121 | | gs_show_width_only(const gs_show_enum * penum) |
122 | 0 | { |
123 | 0 | return gs_text_is_width_only((const gs_text_enum_t *)penum); |
124 | 0 | } |
125 | | |
126 | | /* ------ Accessors ------ */ |
127 | | |
128 | | /* Return the current character for rendering. */ |
129 | | gs_char |
130 | | gs_show_current_char(const gs_show_enum * penum) |
131 | 0 | { |
132 | 0 | return gs_text_current_char((const gs_text_enum_t *)penum); |
133 | 0 | } |
134 | | |
135 | | /* Return the current glyph for rendering. */ |
136 | | gs_glyph |
137 | | gs_show_current_glyph(const gs_show_enum * penum) |
138 | 0 | { |
139 | 0 | return gs_text_current_glyph((const gs_text_enum_t *)penum); |
140 | 0 | } |
141 | | |
142 | | /* Return the width of the just-enumerated character (for cshow). */ |
143 | | int |
144 | | gs_show_current_width(const gs_show_enum * penum, gs_point * ppt) |
145 | 0 | { |
146 | 0 | return gs_text_current_width((const gs_text_enum_t *)penum, ppt); |
147 | 0 | } |
148 | | |
149 | | /* Return the just-displayed character for kerning. */ |
150 | | gs_char |
151 | | gs_kshow_previous_char(const gs_show_enum * penum) |
152 | 0 | { |
153 | 0 | return gs_text_current_char((const gs_text_enum_t *)penum); |
154 | 0 | } |
155 | | |
156 | | /* Return the about-to-be-displayed character for kerning. */ |
157 | | gs_char |
158 | | gs_kshow_next_char(const gs_show_enum * penum) |
159 | 0 | { |
160 | 0 | return penum->text.data.bytes[penum->index]; |
161 | 0 | } |
162 | | |
163 | | /* Return the accumulated width for stringwidth. */ |
164 | | void |
165 | | gs_show_width(const gs_show_enum * penum, gs_point * ppt) |
166 | 0 | { |
167 | 0 | gs_text_total_width((const gs_text_enum_t *)penum, ppt); |
168 | 0 | } |
169 | | |
170 | | /* ------ Internal routines ------ */ |
171 | | |
172 | | #if 0 |
173 | | /* |
174 | | * Force the enumerator to be a gs_show_enum *, which the current |
175 | | * implementation code requires. |
176 | | */ |
177 | | static int |
178 | | show_n_begin(gs_show_enum *penum, gs_gstate *pgs, int code, gs_text_enum_t *pte) |
179 | | { |
180 | | if (code < 0) |
181 | | return code; |
182 | | if (gs_object_type(pgs->memory, pte) != &st_gs_show_enum) { |
183 | | /* Use the default implementation. */ |
184 | | gx_device *dev = pgs->device; |
185 | | gs_text_params_t text; |
186 | | gs_memory_t *mem = pte->memory; |
187 | | dev_proc_text_begin((*text_begin)) = dev_proc(dev, text_begin); |
188 | | |
189 | | text = pte->text; |
190 | | gs_text_release(NULL, pte, "show_n_begin"); |
191 | | /* Temporarily reset the text_begin procedure to the default. */ |
192 | | set_dev_proc(dev, text_begin, gx_default_text_begin); |
193 | | code = gs_text_begin(pgs, &text, mem, &pte); |
194 | | set_dev_proc(dev, text_begin, text_begin); |
195 | | if (code < 0) |
196 | | return code; |
197 | | } |
198 | | /* Now we know pte points to a gs_show_enum. */ |
199 | | *penum = *(gs_show_enum *)pte; |
200 | | gs_free_object(pgs->memory, pte, "show_n_begin"); |
201 | | return code; |
202 | | } |
203 | | #endif |