Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_tlsv12/sys/src/cmd/gs/src/zcid.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 2000 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: zcid.c,v 1.9 2004/08/04 19:36:13 stefan Exp $ */
18
/* CMap and CID-keyed font services */
19
#include "ghost.h"
20
#include "ierrors.h"
21
#include "gxcid.h"
22
#include "icid.h"		/* for checking prototype */
23
#include "idict.h"
24
#include "idparam.h"
25
#include "store.h"
26
#include "oper.h"
27
 
28
/* Get the information from a CIDSystemInfo dictionary. */
29
int
30
cid_system_info_param(gs_cid_system_info_t *pcidsi, const ref *prcidsi)
31
{
32
    ref *pregistry;
33
    ref *pordering;
34
    int code;
35
 
36
    if (!r_has_type(prcidsi, t_dictionary))
37
	return_error(e_typecheck);
38
    if (dict_find_string(prcidsi, "Registry", &pregistry) <= 0 ||
39
	dict_find_string(prcidsi, "Ordering", &pordering) <= 0
40
	)
41
	return_error(e_rangecheck);
42
    check_read_type_only(*pregistry, t_string);
43
    check_read_type_only(*pordering, t_string);
44
    pcidsi->Registry.data = pregistry->value.const_bytes;
45
    pcidsi->Registry.size = r_size(pregistry);
46
    pcidsi->Ordering.data = pordering->value.const_bytes;
47
    pcidsi->Ordering.size = r_size(pordering);
48
    code = dict_int_param(prcidsi, "Supplement", 0, max_int, -1,
49
			  &pcidsi->Supplement);
50
    return (code < 0 ? code : 0);
51
}
52
 
53
/* Convert a CID into TT char code or to TT glyph index. */
54
private bool 
55
TT_char_code_from_CID_no_subst(const gs_memory_t *mem, 
56
			       const ref *Decoding, const ref *TT_cmap, uint nCID, uint *c)
57
{   ref *DecodingArray, char_code, ih, glyph_index;
58
 
59
    make_int(&ih, nCID / 256);
60
    if (dict_find(Decoding, &ih, &DecodingArray) <= 0 || 
61
	    !r_has_type(DecodingArray, t_array) ||
62
	    array_get(mem, DecodingArray, nCID % 256, &char_code) < 0 || 
63
	    !r_has_type(&char_code, t_integer)) {
64
	/* fixme : Generally, a single char_code can be insufficient. 
65
	   It could be an array. Fix lib/gs_ciddc.ps as well.  */
66
        return false;
67
    } 
68
    if (TT_cmap == NULL) {
69
	*c = char_code.value.intval;
70
	return true;
71
    }
72
    if (array_get(mem, TT_cmap, char_code.value.intval, &glyph_index) < 0 ||
73
	    !r_has_type(&glyph_index, t_integer))
74
	return false;
75
    *c = glyph_index.value.intval;
76
    return true;
77
}
78
 
79
/* Convert a CID into a TT char code or into a TT glyph index, using SubstNWP. */
80
/* Returns 1 if a glyph presents, 0 if not, <0 if error. */
81
int
82
cid_to_TT_charcode(const gs_memory_t *mem, 
83
		   const ref *Decoding, const ref *TT_cmap, const ref *SubstNWP, 
84
                   uint nCID, uint *c, ref *src_type, ref *dst_type)
85
{
86
    int SubstNWP_length = r_size(SubstNWP), i, code;
87
 
88
    if (TT_char_code_from_CID_no_subst(mem, Decoding, TT_cmap, nCID, c)) {
89
	make_null(src_type);
90
	/* Leaving dst_type uninitialized. */
91
	return 1;
92
    }
93
    for (i = 0; i < SubstNWP_length; i += 5) {
94
        ref rb, re, rs;
95
        int nb, ne, ns;
96
 
97
	if ((code = array_get(mem, SubstNWP, i + 1, &rb)) < 0)
98
	    return code;
99
        if ((code = array_get(mem, SubstNWP, i + 2, &re)) < 0)
100
	    return code;
101
        if ((code = array_get(mem, SubstNWP, i + 3, &rs)) < 0)
102
	    return code;
103
        nb = rb.value.intval;
104
        ne = re.value.intval;
105
        ns = rs.value.intval;
106
        if (nCID >= nb && nCID <= ne)
107
            if (TT_char_code_from_CID_no_subst(mem, Decoding, TT_cmap, ns + (nCID - nb), c)) {
108
		if ((code = array_get(mem, SubstNWP, i + 0, src_type)) < 0)
109
		    return code;
110
		if ((code = array_get(mem, SubstNWP, i + 4, dst_type)) < 0)
111
		    return code;
112
                return 1;
113
	    }
114
        if (nCID >= ns && nCID <= ns + (ne - nb))
115
            if (TT_char_code_from_CID_no_subst(mem, Decoding, TT_cmap, nb + (nCID - ns), c)) {
116
		if ((code = array_get(mem, SubstNWP, i + 0, dst_type)) < 0)
117
		    return code;
118
		if ((code = array_get(mem, SubstNWP, i + 4, src_type)) < 0)
119
		    return code;
120
                return 1;
121
	    }
122
    }
123
    *c = 0;
124
    return 0;
125
}
126
 
127
/* Set a CIDMap element. */
128
private int 
129
set_CIDMap_element(const gs_memory_t *mem, ref *CIDMap, uint cid, uint glyph_index)
130
{   /* Assuming the CIDMap is already type-checked. */
131
    /* Assuming GDBytes == 2. */
132
    int offset = cid * 2;
133
    int count = r_size(CIDMap), size, i;
134
    ref s;
135
    uchar *c;
136
 
137
    if (glyph_index >= 65536)
138
	return_error(e_rangecheck); /* Can't store with GDBytes == 2. */
139
    for (i = 0; i < count; i++) {
140
	array_get(mem, CIDMap, i, &s);
141
	size = r_size(&s) & ~1;
142
	if (offset < size) {
143
	    c = s.value.bytes + offset;
144
	    c[0] = (uchar)(glyph_index >> 8);
145
	    c[1] = (uchar)(glyph_index & 255);
146
	    break;
147
	}
148
	offset -= size;
149
    }
150
    /* We ignore the substitution if it goes out the CIDMap range.
151
       It must not happen, except for empty Decoding elements */
152
    return 0;
153
}
154
 
155
/* Create a CIDMap from a True Type cmap array, Decoding and SubstNWP. */
156
int
157
cid_fill_CIDMap(const gs_memory_t *mem, 
158
		const ref *Decoding, const ref *TT_cmap, const ref *SubstNWP, int GDBytes, 
159
                ref *CIDMap)
160
{   int dict_enum;
161
    ref el[2];
162
    int count, i;
163
 
164
    if (GDBytes != 2)
165
	return_error(e_unregistered); /* Unimplemented. */
166
    if (r_type(CIDMap) != t_array)
167
	return_error(e_unregistered); /* Unimplemented. It could be a single string. */
168
    count = r_size(CIDMap);
169
    /* Checking the CIDMap structure correctness : */
170
    for (i = 0; i < count; i++) {
171
	ref s;
172
	int code = array_get(mem, CIDMap, i, &s);
173
 
174
	if (code < 0)
175
	    return code;
176
	check_type(s, t_string); /* fixme : optimize with moving to TT_char_code_from_CID. */
177
    }
178
    /* Compute the CIDMap : */
179
    dict_enum = dict_first(Decoding);
180
    for (;;) {
181
        int index, count, i;
182
 
183
	if ((dict_enum = dict_next(Decoding, dict_enum, el)) == -1)
184
	    break;
185
	if (!r_has_type(&el[0], t_integer))
186
	    continue;
187
	if (!r_has_type(&el[1], t_array))
188
	    return_error(e_typecheck);
189
	index = el[0].value.intval;
190
	count = r_size(&el[1]);
191
	for (i = 0; i < count; i++) {
192
	    uint cid = index * 256 + i, glyph_index;
193
	    ref src_type, dst_type;
194
	    int code = cid_to_TT_charcode(mem, Decoding, TT_cmap, SubstNWP, 
195
                                cid, &glyph_index, &src_type, &dst_type);
196
 
197
	    if (code < 0)
198
		return code;
199
	    if (code > 0) {
200
	        code = set_CIDMap_element(mem, CIDMap, cid, glyph_index);
201
		if (code < 0)
202
		    return code;
203
	    }
204
	}
205
    }
206
    return 0;
207
}