Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1996, 1997, 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: zchar42.c,v 1.15 2004/02/08 17:35:20 igor Exp $ */
18
/* Type 42 character display operator */
19
#include "ghost.h"
20
#include "oper.h"
21
#include "gsmatrix.h"
22
#include "gspaint.h"		/* for gs_fill, gs_stroke */
23
#include "gspath.h"
24
#include "gxfixed.h"
25
#include "gxfont.h"
26
#include "gxfont42.h"
27
#include "gxistate.h"
28
#include "gxpath.h"
29
#include "gxtext.h"
30
#include "gzstate.h"		/* only for ->path */
31
#include "dstack.h"		/* only for systemdict */
32
#include "estack.h"
33
#include "ichar.h"
34
#include "icharout.h"
35
#include "ifont.h"		/* for font_param */
36
#include "igstate.h"
37
#include "store.h"
38
#include "zchar42.h"
39
 
40
/* Get a Type 42 character metrics and set the cache device. */
41
int
42
zchar42_set_cache(i_ctx_t *i_ctx_p, gs_font_base *pbfont, ref *cnref, 
43
	    uint glyph_index, op_proc_t cont, op_proc_t *exec_cont, bool put_lsb)
44
{   double sbw[4];
45
    double w[2];
46
    int present;
47
    int code = zchar_get_metrics(pbfont, cnref, sbw);
48
 
49
    if (code < 0)
50
	return code;
51
    present = code;
52
    if (present == metricsNone) {
53
	float sbw42[4];
54
	int i;
55
 
56
	code = gs_type42_wmode_metrics((gs_font_type42 *)pbfont,
57
				       glyph_index, false, sbw42);
58
	if (code < 0)
59
	    return code;
60
	present = metricsSideBearingAndWidth;
61
	for (i = 0; i < 4; ++i)
62
	    sbw[i] = sbw42[i];
63
	w[0] = sbw[2];
64
	w[1] = sbw[3];
65
	if (gs_rootfont(igs)->WMode) { /* for vertically-oriented metrics */
66
	    code = gs_type42_wmode_metrics((gs_font_type42 *)pbfont,
67
					   glyph_index,
68
					   true, sbw42);
69
	    if (code < 0) { /* no vertical metrics */
70
		if (pbfont->FontType == ft_CID_TrueType) {
71
		    sbw[0] = sbw[2] / 2;
72
		    sbw[1] = pbfont->FontBBox.q.y;
73
		    sbw[2] = 0;
74
		    sbw[3] = pbfont->FontBBox.p.y - pbfont->FontBBox.q.y;
75
		}
76
	    } else {
77
		sbw[0] = sbw[2] / 2;
78
		sbw[1] = (pbfont->FontBBox.q.y + pbfont->FontBBox.p.y - sbw42[3]) / 2;
79
		sbw[2] = sbw42[2];
80
		sbw[3] = sbw42[3];
81
	    }
82
	}
83
    } else {
84
        w[0] = sbw[2];
85
        w[1] = sbw[3];
86
    }
87
    return zchar_set_cache(i_ctx_p, pbfont, cnref,
88
			   (put_lsb && present == metricsSideBearingAndWidth ?
89
			    sbw : NULL),
90
			   w, &pbfont->FontBBox,
91
			   cont, exec_cont,
92
			   gs_rootfont(igs)->WMode ? sbw : NULL);
93
}
94
 
95
/* <font> <code|name> <name> <glyph_index> .type42execchar - */
96
private int type42_fill(i_ctx_t *);
97
private int type42_stroke(i_ctx_t *);
98
private int
99
ztype42execchar(i_ctx_t *i_ctx_p)
100
{
101
    os_ptr op = osp;
102
    gs_font *pfont;
103
    int code = font_param(op - 3, &pfont);
104
    gs_font_base *const pbfont = (gs_font_base *) pfont;
105
    gs_text_enum_t *penum = op_show_find(i_ctx_p);
106
    op_proc_t cont = (pbfont->PaintType == 0 ? type42_fill : type42_stroke), exec_cont = 0;
107
    ref *cnref;
108
    uint glyph_index;
109
 
110
    if (code < 0)
111
	return code;
112
    if (penum == 0 ||
113
	(pfont->FontType != ft_TrueType &&
114
	 pfont->FontType != ft_CID_TrueType)
115
	)
116
	return_error(e_undefined);
117
    /*
118
     * Any reasonable implementation would execute something like
119
     *  1 setmiterlimit 0 setlinejoin 0 setlinecap
120
     * here, but apparently the Adobe implementations aren't reasonable.
121
     *
122
     * If this is a stroked font, set the stroke width.
123
     */
124
    if (pfont->PaintType)
125
	gs_setlinewidth(igs, pfont->StrokeWidth);
126
    check_estack(3);		/* for continuations */
127
    /*
128
     * Execute the definition of the character.
129
     */
130
    if (r_is_proc(op))
131
	return zchar_exec_char_proc(i_ctx_p);
132
    /*
133
     * The definition must be a Type 42 glyph index.
134
     * Note that we do not require read access: this is deliberate.
135
     */
136
    check_type(*op, t_integer);
137
    check_ostack(3);		/* for lsb values */
138
    /* Establish a current point. */
139
    code = gs_moveto(igs, 0.0, 0.0);
140
    if (code < 0)
141
	return code;
142
    cnref = op - 1;
143
    glyph_index = (uint)op->value.intval;
144
    code = zchar42_set_cache(i_ctx_p, pbfont, cnref, glyph_index, cont, &exec_cont, true);
145
    if (code >= 0 && exec_cont != 0)
146
	code = (*exec_cont)(i_ctx_p);
147
    return code;
148
}
149
 
150
/* Continue after a CDevProc callout. */
151
private int type42_finish(i_ctx_t *i_ctx_p,
152
			  int (*cont)(gs_state *));
153
private int
154
type42_fill(i_ctx_t *i_ctx_p)
155
{
156
    int code;
157
    gs_fixed_point fa = i_ctx_p->pgs->fill_adjust;
158
 
159
    i_ctx_p->pgs->fill_adjust.x = i_ctx_p->pgs->fill_adjust.y = -1;
160
    code = type42_finish(i_ctx_p, gs_fill);
161
    i_ctx_p->pgs->fill_adjust = fa; /* Not sure whether we need to restore it,
162
                                       but this isn't harmful. */
163
    return code;
164
}
165
private int
166
type42_stroke(i_ctx_t *i_ctx_p)
167
{
168
    return type42_finish(i_ctx_p, gs_stroke);
169
}
170
/* <font> <code|name> <name> <glyph_index> <sbx> <sby> %type42_{fill|stroke} - */
171
/* <font> <code|name> <name> <glyph_index> %type42_{fill|stroke} - */
172
private int
173
type42_finish(i_ctx_t *i_ctx_p, int (*cont) (gs_state *))
174
{
175
    os_ptr op = osp;
176
    gs_font *pfont;
177
    int code;
178
    gs_text_enum_t *penum = op_show_find(i_ctx_p);
179
    double sbxy[2];
180
    gs_point sbpt;
181
    gs_point *psbpt = 0;
182
    os_ptr opc = op;
183
 
184
    if (!r_has_type(op - 3, t_dictionary)) {
185
	check_op(6);
186
	code = num_params(op, 2, sbxy);
187
	if (code < 0)
188
	    return code;
189
	sbpt.x = sbxy[0];
190
	sbpt.y = sbxy[1];
191
	psbpt = &sbpt;
192
	opc -= 2;
193
    }
194
    check_type(*opc, t_integer);
195
    code = font_param(opc - 3, &pfont);
196
    if (code < 0)
197
	return code;
198
    if (penum == 0 || (pfont->FontType != ft_TrueType &&
199
		       pfont->FontType != ft_CID_TrueType)
200
	)
201
	return_error(e_undefined);
202
    /*
203
     * We have to disregard penum->pis and penum->path, and render to
204
     * the current gstate and path.  This is a design bug that we will
205
     * have to address someday!
206
     */
207
    code = gs_type42_append((uint)opc->value.intval, (gs_imager_state *)igs,
208
			    igs->path, &penum->log2_scale,
209
			    (penum->text.operation & TEXT_DO_ANY_CHARPATH) != 0,
210
			    pfont->PaintType, penum->pair);
211
    if (code < 0)
212
	return code;
213
    pop((psbpt == 0 ? 4 : 6));
214
    return (*cont)(igs);
215
}
216
 
217
/* ------ Initialization procedure ------ */
218
 
219
const op_def zchar42_op_defs[] =
220
{
221
    {"4.type42execchar", ztype42execchar},
222
    op_def_end(0)
223
};