Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1998, 1999 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: zcfont.c,v 1.6 2002/06/16 03:43:50 lpd Exp $ */
18
/* Composite font-related character operators */
19
#include "ghost.h"
20
#include "oper.h"
21
#include "gsmatrix.h"		/* for gxfont.h */
22
#include "gxfixed.h"		/* for gxfont.h */
23
#include "gxfont.h"
24
#include "gxtext.h"
25
#include "estack.h"
26
#include "ichar.h"
27
#include "ifont.h"
28
#include "igstate.h"
29
#include "store.h"
30
 
31
/* Forward references */
32
private int cshow_continue(i_ctx_t *);
33
private int cshow_restore_font(i_ctx_t *);
34
 
35
/* <proc> <string> cshow - */
36
private int
37
zcshow(i_ctx_t *i_ctx_p)
38
{
39
    os_ptr op = osp;
40
    os_ptr proc_op = op - 1;
41
    os_ptr str_op = op;
42
    gs_text_enum_t *penum;
43
    int code;
44
 
45
    /*
46
     * Even though this is not documented anywhere by Adobe,
47
     * some Adobe interpreters apparently allow the string and
48
     * the procedure to be provided in either order!
49
     */
50
    if (r_is_proc(proc_op))
51
	;
52
    else if (r_is_proc(op)) {	/* operands reversed */
53
	proc_op = op;
54
	str_op = op - 1;
55
    } else {
56
	check_op(2);
57
	return_error(e_typecheck);
58
    }
59
    if ((code = op_show_setup(i_ctx_p, str_op)) != 0 ||
60
	(code = gs_cshow_begin(igs, str_op->value.bytes, r_size(str_op),
61
			       imemory, &penum)) < 0)
62
	return code;
63
    if ((code = op_show_finish_setup(i_ctx_p, penum, 2, NULL)) < 0) {
64
	ifree_object(penum, "op_show_enum_setup");
65
	return code;
66
    }
67
    sslot = *proc_op;		/* save kerning proc */
68
    pop(2);
69
    return cshow_continue(i_ctx_p);
70
}
71
private int
72
cshow_continue(i_ctx_t *i_ctx_p)
73
{
74
    os_ptr op = osp;
75
    gs_text_enum_t *penum = senum;
76
    int code;
77
 
78
    check_estack(4);		/* in case we call the procedure */
79
    code = gs_text_process(penum);
80
    if (code != TEXT_PROCESS_INTERVENE) {
81
	code = op_show_continue_dispatch(i_ctx_p, 0, code);
82
	if (code == o_push_estack)	/* must be TEXT_PROCESS_RENDER */
83
	    make_op_estack(esp - 1, cshow_continue);
84
	return code;
85
    }
86
    /* Push the character code and width, and call the procedure. */
87
    {
88
	ref *pslot = &sslot;
89
	gs_point wpt;
90
	gs_font *font = gs_text_current_font(penum);
91
	gs_font *root_font = gs_rootfont(igs);
92
	gs_font *scaled_font;
93
	uint font_space = r_space(pfont_dict(font));
94
	uint root_font_space = r_space(pfont_dict(root_font));
95
	int fdepth = penum->fstack.depth;
96
 
97
	gs_text_current_width(penum, &wpt);
98
	if (font == root_font)
99
	    scaled_font = font;
100
	else if (fdepth > 0) {
101
	  /* Construct a scaled version of the leaf font. 
102
	     If font stack is deep enough, get the matrix for scaling
103
	     from the immediate parent of current font. 
104
	     (The font matrix of root font is not good for the purpose
105
	     in some case.) 
106
	     assert (penum->fstack.items[fdepth].font == font
107
	             && penum->fstack.items[0].font == root_font); */
108
	  uint save_space = idmemory->current_space;
109
	  gs_font * immediate_parent = penum->fstack.items[fdepth - 1].font;
110
 
111
	  ialloc_set_space(idmemory, font_space);
112
	  code = gs_makefont(font->dir, font, 
113
			     &immediate_parent->FontMatrix,
114
			     &scaled_font);
115
	  ialloc_set_space(idmemory, save_space);
116
	  if (code < 0)
117
	    return code;
118
	}
119
	else {
120
	    /* Construct a scaled version of the leaf font. */
121
	    uint save_space = idmemory->current_space;
122
 
123
	    ialloc_set_space(idmemory, font_space);
124
	    code = gs_makefont(font->dir, font, &root_font->FontMatrix,
125
			       &scaled_font);
126
	    ialloc_set_space(idmemory, save_space);
127
	    if (code < 0)
128
		return code;
129
	}
130
	push(3);
131
	make_int(op - 2, gs_text_current_char(penum) & 0xff);
132
	make_real(op - 1, wpt.x);
133
	make_real(op, wpt.y);
134
	make_struct(&ssfont, font_space, font);
135
	make_struct(&srfont, root_font_space, root_font);
136
	push_op_estack(cshow_restore_font);
137
	/* cshow does not change rootfont for user procedure */
138
	gs_set_currentfont(igs, scaled_font);
139
	*++esp = *pslot;	/* user procedure */
140
    }
141
    return o_push_estack;
142
}
143
private int
144
cshow_restore_font(i_ctx_t *i_ctx_p)
145
{
146
    /* We must restore both the root font and the current font. */
147
    gs_setfont(igs, r_ptr(&srfont, gs_font));
148
    gs_set_currentfont(igs, r_ptr(&ssfont, gs_font));
149
    return cshow_continue(i_ctx_p);
150
}
151
 
152
/* - rootfont <font> */
153
private int
154
zrootfont(i_ctx_t *i_ctx_p)
155
{
156
    os_ptr op = osp;
157
 
158
    push(1);
159
    *op = *pfont_dict(gs_rootfont(igs));
160
    return 0;
161
}
162
 
163
/* ------ Initialization procedure ------ */
164
 
165
const op_def zcfont_op_defs[] =
166
{
167
    {"2cshow", zcshow},
168
    {"0rootfont", zrootfont},
169
		/* Internal operators */
170
    {"0%cshow_continue", cshow_continue},
171
    {"0%cshow_restore_font", cshow_restore_font},
172
    op_def_end(0)
173
};