|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T z
Length: 9159 (0x23c7) Types: TextFile Names: »zchar.c«
└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89 └─⟦ff23ba0e6⟧ »./ghostscript-1.3.tar.Z« └─⟦a24a58cd3⟧ └─⟦this⟧ »zchar.c«
/* Copyright (C) 1989 Aladdin Enterprises. All rights reserved. Distributed by Free Software Foundation, Inc. This file is part of Ghostscript. Ghostscript is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone for the consequences of using it or for whether it serves any particular purpose or works at all, unless he says so in writing. Refer to the Ghostscript General Public License for full details. Everyone is granted permission to copy, modify and redistribute Ghostscript, but only under the conditions described in the Ghostscript General Public License. A copy of this license is supposed to have been given to you along with Ghostscript so you can know your rights and responsibilities. It should be in a file named COPYING. Among other things, the copyright notice and this notice must be preserved on all copies. */ /* zchar.c */ /* Character operators for GhostScript */ #include "ghost.h" #include "errors.h" #include "oper.h" #include "gsmatrix.h" /* for font.h */ #include "gschar.h" #include "gxdevice.h" /* for gxfont.h */ #include "gxfont.h" #include "alloc.h" #include "font.h" #include "estack.h" #include "state.h" #include "store.h" /* All the character rendering operators use the execution stack */ /* for loop control -- see estack.h for details. */ /* The information pushed by these operators is as follows: */ /* the enumerator (t_string, but points to a gs_show_enum); */ /* a slot for the procedure for kshow, unused otherwise; */ /* the procedure to be called at the end of the enumeration */ /* (t_operator, but called directly, not by the interpreter); */ /* the usual e-stack mark (t_null). */ #define snumpush 4 #define senum (gs_show_enum *)(esp->value.bytes) #define sslot esp[-1] #define seproc esp[-2] /* Forward references */ private int setup_show(P2(ref *, op_proc *)); private int show_continue(P1(ref *)); private int finish_show(P1(ref *)); private int finish_stringwidth(P1(ref *)); private gs_show_enum *find_show(); private void free_show(); /* show */ int zshow(register ref *op) { int code = setup_show(op, finish_show); if ( code < 0 ) return code; if ( (code = gs_show_n_init(senum, igs, op->value.bytes, op->size)) < 0 ) { free_show(); return code; } pop(1); op--; return show_continue(op); } /* ashow */ int zashow(register ref *op) { int code; float axy[2]; if ( (code = num_params(op - 1, 2, axy)) < 0 || (code = setup_show(op, finish_show)) < 0 ) return code; if ( (code = gs_ashow_n_init(senum, igs, axy[0], axy[1], op->value.bytes, op->size)) < 0 ) { free_show(); return code; } pop(3); op -= 3; return show_continue(op); } /* widthshow */ int zwidthshow(register ref *op) { int code; float cxy[2]; check_type(op[-1], t_integer); if ( (ulong)(op[-1].value.intval) > 255 ) return e_rangecheck; if ( (code = num_params(op - 2, 2, cxy)) < 0 || (code = setup_show(op, finish_show)) < 0 ) return code; if ( (code = gs_widthshow_n_init(senum, igs, cxy[0], cxy[1], (char)op[-1].value.intval, op->value.bytes, op->size)) < 0 ) { free_show(); return code; } pop(4); op -= 4; return show_continue(op); } /* awidthshow */ int zawidthshow(register ref *op) { int code; float cxy[2], axy[2]; check_type(op[-3], t_integer); if ( (ulong)(op[-3].value.intval) > 255 ) return e_rangecheck; if ( (code = num_params(op - 4, 2, cxy)) < 0 || (code = num_params(op - 1, 2, axy)) < 0 || (code = setup_show(op, finish_show)) < 0 ) return code; if ( (code = gs_awidthshow_n_init(senum, igs, cxy[0], cxy[1], (char)op[-3].value.intval, axy[0], axy[1], op->value.bytes, op->size)) < 0 ) { free_show(); return code; } pop(6); op -= 6; return show_continue(op); } /* kshow */ int zkshow(register ref *op) { int code; check_proc(op[-1]); if ( (code = setup_show(op, finish_show)) < 0 ) return code; if ( (code = gs_kshow_n_init(senum, igs, op->value.bytes, op->size)) < 0 ) { free_show(); return code; } sslot = op[-1]; /* save kerning proc */ pop(2); op -= 2; return show_continue(op); } /* Common finish procedure for all show operations. */ /* Doesn't have to do anything. */ private int finish_show(ref *op) { return 0; } /* stringwidth */ int zstringwidth(register ref *op) { int code = setup_show(op, finish_stringwidth); if ( code < 0 ) return code; if ( (code = gs_stringwidth_n_init(senum, igs, op->value.bytes, op->size)) < 0 ) { free_show(); return code; } pop(1); op--; return show_continue(op); } /* Finishing procedure for stringwidth. */ /* Pushes the accumulated width. */ private int finish_stringwidth(register ref *op) { gs_point width; gs_show_width(senum, &width); push(2); make_real(op - 1, width.x); make_real(op, width.y); return 0; } /* charpath */ int zcharpath(register ref *op) { int code; check_type(*op, t_boolean); code = setup_show(op - 1, finish_show); if ( code < 0 ) return code; if ( (code = gs_charpath_n_init(senum, igs, op[-1].value.bytes, op[-1].size, op->value.index)) < 0 ) { free_show(); return code; } pop(2); op -= 2; return show_continue(op); } /* setcachedevice */ int zsetcachedevice(register ref *op) { float wbox[6]; gs_show_enum *penum = find_show(); int code = num_params(op, 6, wbox); if ( penum == 0 ) return e_undefined; if ( code < 0 || (code = gs_setcachedevice(penum, wbox[0], wbox[1], wbox[2], wbox[3], wbox[4], wbox[5])) < 0 ) return code; pop(6); return 0; } /* setcharwidth */ int zsetcharwidth(register ref *op) { float width[2]; gs_show_enum *penum = find_show(); int code = num_params(op, 2, width); if ( penum == 0 ) return e_undefined; if ( code < 0 || (code = gs_setcharwidth(penum, width[0], width[1])) < 0 ) return code; pop(2); return 0; } /* addcharpath */ int zaddcharpath(register ref *op) { int code; check_type(op[-1], t_string); check_type(*op, t_integer); if ( op->value.intval != gs_addcharpath_FontType ) return e_invalidfont; code = gs_addcharpath(igs, op[-1].value.bytes, op[-1].size); if ( code >= 0 ) pop(2); return code; } /* imagecharpath */ int zimagecharpath(register ref *op) { uint len; int code; check_type(op[-3], t_string); check_type(op[-2], t_integer); check_type(op[-1], t_integer); check_type(*op, t_string); code = gs_imagecharpath(op[-3].value.bytes, (int)op[-2].value.intval, (int)op[-1].value.intval, op->value.bytes, op->size); if ( code < 0 ) return code; op[-3] = *op; op[-3].size = code; make_int(op - 2, gs_addcharpath_FontType); pop(2); return 0; } /* ------ Initialization procedure ------ */ void zchar_op_init() { static op_def my_defs[] = { {"2addcharpath", zaddcharpath}, {"3ashow", zashow}, {"6awidthshow", zawidthshow}, {"2charpath", zcharpath}, {"4imagecharpath", zimagecharpath}, {"2kshow", zkshow}, {"6setcachedevice", zsetcachedevice}, {"2setcharwidth", zsetcharwidth}, {"1show", zshow}, {"1stringwidth", zstringwidth}, {"4widthshow", zwidthshow}, op_def_end }; z_op_init(my_defs); } /* ------ Internal routines ------ */ /* Set up for a show operator. */ /* The top stack element must be the string to be scanned. */ /* The caller has already done all other argument checking. */ private int setup_show(ref *op, op_proc *endproc /* end procedure */) { int code; gs_show_enum *penum; check_type(*op, t_string); check_estack(snumpush + 2); if ( (penum = (gs_show_enum *)alloc(gs_show_enum_sizeof, "setup_show")) == 0 ) return e_VMerror; mark_estack(es_show); push_op_estack(endproc); ++esp; make_tv(esp, t_null, index, 0); /* reserve slot */ ++esp; make_tasv(esp, t_string, 0, gs_show_enum_sizeof, bytes, (byte *)penum); return o_check_estack; } /* Continuation operator for character rendering. */ private int show_continue(register ref *op) { gs_show_enum *penum = senum; int code = gs_show_next(penum); switch ( code ) { case 0: /* all done */ code = (*seproc.value.opproc)(op); free_show(); return (code >= 0 ? o_check_estack : code); case gs_show_kern: { ref *pslot = &sslot; push(2); make_int(op - 1, gs_kshow_previous_char(penum)); make_int(op, gs_kshow_next_char(penum)); push_op_estack(show_continue); /* continue after kerning */ *++esp = *pslot; /* kerning procedure */ } return o_check_estack; case gs_show_render: { font_data *pfont = (font_data *)gs_currentfont(igs)->client_data; push(2); op[-1] = pfont->dict; /* push the font */ make_int(op, gs_show_current_char(penum)); push_op_estack(show_continue); *++esp = pfont->BuildChar; } return o_check_estack; default: /* error */ free_show(); return code; } } /* Find the current show enumerator on the e-stack. */ private gs_show_enum * find_show() { ref *ep = esp; while ( !(r_type(ep) == t_null && ep->value.index == es_show) ) { if ( --ep < estack ) return 0; /* no mark */ } return (gs_show_enum *)ep[snumpush - 1].value.bytes; } /* Discard the show record (after an error, or at the end). */ private void free_show() { alloc_free((char *)senum, gs_show_enum_sizeof, "free_show"); esp -= snumpush; }