/* Copyright (C) 1992, 2000 artofcode LLC. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA, 02111-1307. */ /*$Id: zcharx.c,v 1.3.6.1.2.1 2003/01/17 00:49:05 giles Exp $ */ /* Level 2 character operators */ #include "ghost.h" #include "oper.h" #include "gsmatrix.h" /* for gxfont.h */ #include "gstext.h" #include "gxfixed.h" /* for gxfont.h */ #include "gxfont.h" #include "ialloc.h" #include "ichar.h" #include "igstate.h" #include "iname.h" #include "ibnum.h" /* Common setup for glyphshow and .glyphwidth. */ private int glyph_show_setup(i_ctx_t *i_ctx_p, gs_glyph *pglyph) { os_ptr op = osp; switch (gs_currentfont(igs)->FontType) { case ft_CID_encrypted: case ft_CID_user_defined: case ft_CID_TrueType: case ft_CID_bitmap: check_int_leu(*op, gs_max_glyph - gs_min_cid_glyph); *pglyph = (gs_glyph) op->value.intval + gs_min_cid_glyph; break; default: check_type(*op, t_name); *pglyph = name_index(op); } return op_show_enum_setup(i_ctx_p); } /* glyphshow - */ private int zglyphshow(i_ctx_t *i_ctx_p) { gs_glyph glyph; gs_text_enum_t *penum; int code; if ((code = glyph_show_setup(i_ctx_p, &glyph)) != 0 || (code = gs_glyphshow_begin(igs, glyph, imemory, &penum)) < 0) return code; if ((code = op_show_finish_setup(i_ctx_p, penum, 1, NULL)) < 0) { ifree_object(penum, "zglyphshow"); return code; } return op_show_continue_pop(i_ctx_p, 1); } /* .glyphwidth */ private int zglyphwidth(i_ctx_t *i_ctx_p) { gs_glyph glyph; gs_text_enum_t *penum; int code; if ((code = glyph_show_setup(i_ctx_p, &glyph)) != 0 || (code = gs_glyphwidth_begin(igs, glyph, imemory, &penum)) < 0) return code; if ((code = op_show_finish_setup(i_ctx_p, penum, 1, finish_stringwidth)) < 0) { ifree_object(penum, "zglyphwidth"); return code; } return op_show_continue_pop(i_ctx_p, 1); } /* xshow - */ /* yshow - */ /* xyshow - */ private int moveshow(i_ctx_t *i_ctx_p, bool have_x, bool have_y) { os_ptr op = osp; gs_text_enum_t *penum; int code = op_show_setup(i_ctx_p, op - 1); int format; uint i, size; float *values; if (code != 0) return code; format = num_array_format(op); if (format < 0) return format; size = num_array_size(op, format); values = (float *)ialloc_byte_array(size, sizeof(float), "moveshow"); if (values == 0) return_error(e_VMerror); for (i = 0; i < size; ++i) { ref value; switch (code = num_array_get(op, format, i, &value)) { case t_integer: values[i] = value.value.intval; break; case t_real: values[i] = value.value.realval; break; case t_null: code = gs_note_error(e_rangecheck); /* falls through */ default: ifree_object(values, "moveshow"); return code; } } if ((code = gs_xyshow_begin(igs, op[-1].value.bytes, r_size(op - 1), (have_x ? values : (float *)0), (have_y ? values : (float *)0), size, imemory, &penum)) < 0 || (code = op_show_finish_setup(i_ctx_p, penum, 2, NULL)) < 0) { ifree_object(values, "moveshow"); return code; } pop(2); return op_show_continue(i_ctx_p); } private int zxshow(i_ctx_t *i_ctx_p) { return moveshow(i_ctx_p, true, false); } private int zyshow(i_ctx_t *i_ctx_p) { return moveshow(i_ctx_p, false, true); } private int zxyshow(i_ctx_t *i_ctx_p) { return moveshow(i_ctx_p, true, true); } /* ------ Initialization procedure ------ */ const op_def zcharx_op_defs[] = { op_def_begin_level2(), {"1glyphshow", zglyphshow}, {"1.glyphwidth", zglyphwidth}, {"2xshow", zxshow}, {"2xyshow", zxyshow}, {"2yshow", zyshow}, op_def_end(0) };