1 /* Copyright (C) 1998, 1999 artofcode LLC. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify it
4 under the terms of the GNU General Public License as published by the
5 Free Software Foundation; either version 2 of the License, or (at your
6 option) any later version.
7
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along
14 with this program; if not, write to the Free Software Foundation, Inc.,
15 59 Temple Place, Suite 330, Boston, MA, 02111-1307.
16
17 */
18
19 /*$Id: zcfont.c,v 1.2.6.2.2.1 2003/01/17 00:49:05 giles Exp $ */
20 /* Composite font-related character operators */
21 #include "ghost.h"
22 #include "oper.h"
23 #include "gsmatrix.h" /* for gxfont.h */
24 #include "gxfixed.h" /* for gxfont.h */
25 #include "gxfont.h"
26 #include "gxtext.h"
27 #include "estack.h"
28 #include "ichar.h"
29 #include "ifont.h"
30 #include "igstate.h"
31 #include "store.h"
32
33 /* Forward references */
34 private int cshow_continue(P1(i_ctx_t *));
35 private int cshow_restore_font(P1(i_ctx_t *));
36
37 /* <proc> <string> cshow - */
38 private int
zcshow(i_ctx_t * i_ctx_p)39 zcshow(i_ctx_t *i_ctx_p)
40 {
41 os_ptr op = osp;
42 os_ptr proc_op = op - 1;
43 os_ptr str_op = op;
44 gs_text_enum_t *penum;
45 int code;
46
47 /*
48 * Even though this is not documented anywhere by Adobe,
49 * some Adobe interpreters apparently allow the string and
50 * the procedure to be provided in either order!
51 */
52 if (r_is_proc(proc_op))
53 ;
54 else if (r_is_proc(op)) { /* operands reversed */
55 proc_op = op;
56 str_op = op - 1;
57 } else {
58 check_op(2);
59 return_error(e_typecheck);
60 }
61 if ((code = op_show_setup(i_ctx_p, str_op)) != 0 ||
62 (code = gs_cshow_begin(igs, str_op->value.bytes, r_size(str_op),
63 imemory, &penum)) < 0)
64 return code;
65 if ((code = op_show_finish_setup(i_ctx_p, penum, 2, NULL)) < 0) {
66 ifree_object(penum, "op_show_enum_setup");
67 return code;
68 }
69 sslot = *proc_op; /* save kerning proc */
70 pop(2);
71 return cshow_continue(i_ctx_p);
72 }
73 private int
cshow_continue(i_ctx_t * i_ctx_p)74 cshow_continue(i_ctx_t *i_ctx_p)
75 {
76 os_ptr op = osp;
77 gs_text_enum_t *penum = senum;
78 int code;
79
80 check_estack(4); /* in case we call the procedure */
81 code = gs_text_process(penum);
82 if (code != TEXT_PROCESS_INTERVENE) {
83 code = op_show_continue_dispatch(i_ctx_p, 0, code);
84 if (code == o_push_estack) /* must be TEXT_PROCESS_RENDER */
85 make_op_estack(esp - 1, cshow_continue);
86 return code;
87 }
88 /* Push the character code and width, and call the procedure. */
89 {
90 ref *pslot = &sslot;
91 gs_point wpt;
92 gs_font *font = gs_text_current_font(penum);
93 gs_font *root_font = gs_rootfont(igs);
94 gs_font *scaled_font;
95 uint font_space = r_space(pfont_dict(font));
96 uint root_font_space = r_space(pfont_dict(root_font));
97 int fdepth = penum->fstack.depth;
98
99 gs_text_current_width(penum, &wpt);
100 if (font == root_font)
101 scaled_font = font;
102 else if (fdepth > 0) {
103 /* Construct a scaled version of the leaf font.
104 If font stack is deep enough, get the matrix for scaling
105 from the immediate parent of current font.
106 (The font matrix of root font is not good for the purpose
107 in some case.)
108 assert (penum->fstack.items[fdepth].font == font
109 && penum->fstack.items[0].font == root_font); */
110 uint save_space = idmemory->current_space;
111 gs_font * immediate_parent = penum->fstack.items[fdepth - 1].font;
112
113 ialloc_set_space(idmemory, font_space);
114 code = gs_makefont(font->dir, font,
115 &immediate_parent->FontMatrix,
116 &scaled_font);
117 ialloc_set_space(idmemory, save_space);
118 if (code < 0)
119 return code;
120 }
121 else {
122 /* Construct a scaled version of the leaf font. */
123 uint save_space = idmemory->current_space;
124
125 ialloc_set_space(idmemory, font_space);
126 code = gs_makefont(font->dir, font, &root_font->FontMatrix,
127 &scaled_font);
128 ialloc_set_space(idmemory, save_space);
129 if (code < 0)
130 return code;
131 }
132 push(3);
133 make_int(op - 2, gs_text_current_char(penum) & 0xff);
134 make_real(op - 1, wpt.x);
135 make_real(op, wpt.y);
136 make_struct(&ssfont, font_space, font);
137 make_struct(&srfont, root_font_space, root_font);
138 push_op_estack(cshow_restore_font);
139 /* cshow does not change rootfont for user procedure */
140 gs_set_currentfont(igs, scaled_font);
141 *++esp = *pslot; /* user procedure */
142 }
143 return o_push_estack;
144 }
145 private int
cshow_restore_font(i_ctx_t * i_ctx_p)146 cshow_restore_font(i_ctx_t *i_ctx_p)
147 {
148 /* We must restore both the root font and the current font. */
149 gs_setfont(igs, r_ptr(&srfont, gs_font));
150 gs_set_currentfont(igs, r_ptr(&ssfont, gs_font));
151 return cshow_continue(i_ctx_p);
152 }
153
154 /* - rootfont <font> */
155 private int
zrootfont(i_ctx_t * i_ctx_p)156 zrootfont(i_ctx_t *i_ctx_p)
157 {
158 os_ptr op = osp;
159
160 push(1);
161 *op = *pfont_dict(gs_rootfont(igs));
162 return 0;
163 }
164
165 /* ------ Initialization procedure ------ */
166
167 const op_def zcfont_op_defs[] =
168 {
169 {"2cshow", zcshow},
170 {"0rootfont", zrootfont},
171 /* Internal operators */
172 {"0%cshow_continue", cshow_continue},
173 {"0%cshow_restore_font", cshow_restore_font},
174 op_def_end(0)
175 };
176