xref: /plan9/sys/src/cmd/gs/src/zcharx.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
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