1 /* Copyright (C) 1992, 2000 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: zcharx.c,v 1.7 2004/08/04 19:36:13 stefan Exp $ */
18 /* Level 2 character operators */
19 #include "ghost.h"
20 #include "oper.h"
21 #include "gsmatrix.h" /* for gxfont.h */
22 #include "gstext.h"
23 #include "gxfixed.h" /* for gxfont.h */
24 #include "gxfont.h"
25 #include "ialloc.h"
26 #include "ichar.h"
27 #include "igstate.h"
28 #include "iname.h"
29 #include "ibnum.h"
30
31 /* Common setup for glyphshow and .glyphwidth. */
32 private int
glyph_show_setup(i_ctx_t * i_ctx_p,gs_glyph * pglyph)33 glyph_show_setup(i_ctx_t *i_ctx_p, gs_glyph *pglyph)
34 {
35 os_ptr op = osp;
36
37 switch (gs_currentfont(igs)->FontType) {
38 case ft_CID_encrypted:
39 case ft_CID_user_defined:
40 case ft_CID_TrueType:
41 case ft_CID_bitmap:
42 check_int_leu(*op, gs_max_glyph - gs_min_cid_glyph);
43 *pglyph = (gs_glyph) op->value.intval + gs_min_cid_glyph;
44 break;
45 default:
46 check_type(*op, t_name);
47 *pglyph = name_index(imemory, op);
48 }
49 return op_show_enum_setup(i_ctx_p);
50 }
51
52 /* <charname> glyphshow - */
53 private int
zglyphshow(i_ctx_t * i_ctx_p)54 zglyphshow(i_ctx_t *i_ctx_p)
55 {
56 gs_glyph glyph;
57 gs_text_enum_t *penum;
58 int code;
59
60 if ((code = glyph_show_setup(i_ctx_p, &glyph)) != 0 ||
61 (code = gs_glyphshow_begin(igs, glyph, imemory, &penum)) < 0)
62 return code;
63 if ((code = op_show_finish_setup(i_ctx_p, penum, 1, NULL)) < 0) {
64 ifree_object(penum, "zglyphshow");
65 return code;
66 }
67 return op_show_continue_pop(i_ctx_p, 1);
68 }
69
70 /* <charname> .glyphwidth <wx> <wy> */
71 private int
zglyphwidth(i_ctx_t * i_ctx_p)72 zglyphwidth(i_ctx_t *i_ctx_p)
73 {
74 gs_glyph glyph;
75 gs_text_enum_t *penum;
76 int code;
77
78 if ((code = glyph_show_setup(i_ctx_p, &glyph)) != 0 ||
79 (code = gs_glyphwidth_begin(igs, glyph, imemory, &penum)) < 0)
80 return code;
81 if ((code = op_show_finish_setup(i_ctx_p, penum, 1, finish_stringwidth)) < 0) {
82 ifree_object(penum, "zglyphwidth");
83 return code;
84 }
85 return op_show_continue_pop(i_ctx_p, 1);
86 }
87
88 /* <string> <numarray|numstring> xshow - */
89 /* <string> <numarray|numstring> yshow - */
90 /* <string> <numarray|numstring> xyshow - */
91 private int
moveshow(i_ctx_t * i_ctx_p,bool have_x,bool have_y)92 moveshow(i_ctx_t *i_ctx_p, bool have_x, bool have_y)
93 {
94 os_ptr op = osp;
95 gs_text_enum_t *penum;
96 int code = op_show_setup(i_ctx_p, op - 1);
97 int format;
98 uint i, size;
99 float *values;
100
101 if (code != 0)
102 return code;
103 format = num_array_format(op);
104 if (format < 0)
105 return format;
106 size = num_array_size(op, format);
107 values = (float *)ialloc_byte_array(size, sizeof(float), "moveshow");
108 if (values == 0)
109 return_error(e_VMerror);
110 for (i = 0; i < size; ++i) {
111 ref value;
112
113 switch (code = num_array_get(imemory, op, format, i, &value)) {
114 case t_integer:
115 values[i] = (float)value.value.intval; break;
116 case t_real:
117 values[i] = value.value.realval; break;
118 case t_null:
119 code = gs_note_error(e_rangecheck);
120 /* falls through */
121 default:
122 ifree_object(values, "moveshow");
123 return code;
124 }
125 }
126 if ((code = gs_xyshow_begin(igs, op[-1].value.bytes, r_size(op - 1),
127 (have_x ? values : (float *)0),
128 (have_y ? values : (float *)0),
129 size, imemory, &penum)) < 0 ||
130 (code = op_show_finish_setup(i_ctx_p, penum, 2, NULL)) < 0) {
131 ifree_object(values, "moveshow");
132 return code;
133 }
134 pop(2);
135 return op_show_continue(i_ctx_p);
136 }
137 private int
zxshow(i_ctx_t * i_ctx_p)138 zxshow(i_ctx_t *i_ctx_p)
139 {
140 return moveshow(i_ctx_p, true, false);
141 }
142 private int
zyshow(i_ctx_t * i_ctx_p)143 zyshow(i_ctx_t *i_ctx_p)
144 {
145 return moveshow(i_ctx_p, false, true);
146 }
147 private int
zxyshow(i_ctx_t * i_ctx_p)148 zxyshow(i_ctx_t *i_ctx_p)
149 {
150 return moveshow(i_ctx_p, true, true);
151 }
152
153 /* ------ Initialization procedure ------ */
154
155 const op_def zcharx_op_defs[] =
156 {
157 op_def_begin_level2(),
158 {"1glyphshow", zglyphshow},
159 {"1.glyphwidth", zglyphwidth},
160 {"2xshow", zxshow},
161 {"2xyshow", zxyshow},
162 {"2yshow", zyshow},
163 op_def_end(0)
164 };
165