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/gsfcid2.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) 2002 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: gsfcid2.c,v 1.6 2004/08/04 19:36:12 stefan Exp $ */
18
/* Create a CIDFontType 2 font from a Type 42 font. */
19
#include "memory_.h"
20
#include "gx.h"
21
#include "gserrors.h"
22
#include "gsstruct.h"
23
#include "gsutil.h"
24
#include "gxfont.h"
25
#include "gxfcid.h"
26
#include "gxfcmap.h"
27
#include "gxfont0c.h"
28
 
29
/*
30
 * Create a Type 2 CIDFont from a Type 42 font.
31
 */
32
private int
33
identity_CIDMap_proc(gs_font_cid2 *pfont, gs_glyph glyph)
34
{
35
    ulong cid = glyph - gs_min_cid_glyph;
36
 
37
    if (cid >= pfont->cidata.common.CIDCount)
38
	return_error(gs_error_rangecheck);
39
    return (int)cid;
40
}
41
int
42
gs_font_cid2_from_type42(gs_font_cid2 **ppfcid, gs_font_type42 *pfont42,
43
			 int wmode, gs_memory_t *mem)
44
{
45
    gs_font_cid2 *pfcid =
46
	gs_alloc_struct(mem, gs_font_cid2, &st_gs_font_cid2,
47
			"gs_font_cid2_from_type42");
48
 
49
    if (pfcid == 0)
50
	return_error(gs_error_VMerror);
51
 
52
    /* CIDFontType 2 is a subclass (extension) of FontType 42. */
53
    memcpy(pfcid, pfont42, sizeof(*pfont42));
54
    pfcid->memory = mem;
55
    pfcid->next = pfcid->prev = 0; /* probably not necessary */
56
    pfcid->is_resource = 0;
57
    gs_font_notify_init((gs_font *)pfcid);
58
    pfcid->id = gs_next_ids(mem, 1);
59
    pfcid->base = (gs_font *)pfcid;
60
    pfcid->FontType = ft_CID_TrueType;
61
    /* Fill in the rest of the CIDFont data. */
62
    cid_system_info_set_null(&pfcid->cidata.common.CIDSystemInfo);
63
    pfcid->cidata.common.CIDCount = pfont42->data.numGlyphs;
64
    pfcid->cidata.common.GDBytes = 2; /* not used */
65
    pfcid->cidata.MetricsCount = 0;
66
    pfcid->cidata.CIDMap_proc = identity_CIDMap_proc;
67
    /* Since MetricsCount == 0, don't need orig_procs. */
68
 
69
    *ppfcid = pfcid;
70
    return 0;
71
}
72
 
73
/* Set up a pointer to a substring of the font data. */
74
#define ACCESS(base, length, vptr)\
75
  BEGIN\
76
    code = pfont->data.string_proc(pfont, (ulong)(base), length, &vptr);\
77
    if ( code < 0 ) return code;\
78
  END
79
#define U16(p) (((uint)((p)[0]) << 8) + (p)[1])
80
#define U32(p) get_u32_msb(p)
81
#define PUT16(p, v)\
82
  BEGIN (p)[0] = (byte)((v) >> 8); (p)[1] = (byte)(v); END
83
 
84
/*
85
 * Define a subclass of gs_cmap_t that accesses the most common type of
86
 * TrueType cmap (Platform 3, Encoding 1, Format 4) directly.
87
 */
88
typedef struct gs_cmap_tt_16bit_format4_s {
89
    GS_CMAP_COMMON;
90
    gs_font_type42 *font;
91
    uint segCount2;
92
    ulong endCount, startCount, idDelta, idRangeOffset, glyphIdArray;
93
} gs_cmap_tt_16bit_format4_t;
94
gs_private_st_suffix_add1(st_cmap_tt_16bit_format4, gs_cmap_tt_16bit_format4_t,
95
  "gs_cmap_tt_16bit_format4_t",
96
  cmap_tt_16bit_format4_enum_ptrs, cmap_tt_16bit_format4_reloc_ptrs,
97
  st_cmap, font);
98
 
99
private int
100
tt_16bit_format4_decode_next(const gs_cmap_t * pcmap_in,
101
		       const gs_const_string * pstr,
102
		       uint * pindex, uint * pfidx,
103
		       gs_char * pchr, gs_glyph * pglyph)
104
{
105
    const gs_cmap_tt_16bit_format4_t *pcmap =
106
	(const gs_cmap_tt_16bit_format4_t *)pcmap_in;
107
    gs_font_type42 *pfont = pcmap->font;
108
    const byte *ttdata;
109
    int code;
110
    uint chr, value = 0;
111
    uint segment2;
112
 
113
    if (pstr->size < *pindex + 2) {
114
	*pglyph = gs_no_glyph;
115
	return (*pindex == pstr->size ? 2 : -1);
116
    }
117
    chr = U16(pstr->data + *pindex);
118
    /* The table is sorted, but we use linear search for simplicity. */
119
    for (segment2 = 0; segment2 < pcmap->segCount2; segment2 += 2) {
120
	uint start, delta, roff;
121
 
122
	ACCESS(pcmap->endCount + segment2, 2, ttdata);
123
	if (chr > U16(ttdata))
124
	    continue;
125
	ACCESS(pcmap->startCount + segment2, 2, ttdata);
126
	start = U16(ttdata);
127
	if (chr < start)
128
	    continue;
129
	ACCESS(pcmap->idDelta + segment2, 2, ttdata);
130
	delta = U16(ttdata);
131
	ACCESS(pcmap->idRangeOffset + segment2, 2, ttdata);
132
	roff = U16(ttdata);
133
	if (roff) {
134
	    ulong gidoff = pcmap->idRangeOffset + segment2 + roff +
135
		(chr - start) * 2;
136
 
137
	    ACCESS(gidoff, 2, ttdata);
138
	    value = U16(ttdata);
139
	    if (value != 0)
140
		value += delta;
141
	} else
142
	    value = chr + delta;
143
	break;
144
    }
145
    *pglyph = gs_min_cid_glyph + (value & 0xffff);
146
    *pchr = chr;
147
    *pindex += 2;
148
    *pfidx = 0;
149
    return 0;
150
}
151
private int
152
tt_16bit_format4_next_range(gs_cmap_ranges_enum_t *penum)
153
{
154
    /* There is just a single 2-byte range. */
155
    if (penum->index == 0) {
156
	penum->range.first[0] = penum->range.first[1] = 0;
157
	penum->range.last[0] = penum->range.last[1] = 0xff;
158
	penum->range.size = 2;
159
	penum->index = 1;
160
	return 0;
161
    }
162
    return 1;
163
}
164
private const gs_cmap_ranges_enum_procs_t tt_16bit_format4_range_procs = {
165
    tt_16bit_format4_next_range
166
};
167
private void
168
tt_16bit_format4_enum_ranges(const gs_cmap_t *pcmap,
169
			     gs_cmap_ranges_enum_t *pre)
170
{
171
    gs_cmap_ranges_enum_setup(pre, pcmap, &tt_16bit_format4_range_procs);
172
}
173
private int
174
tt_16bit_format4_next_lookup(gs_cmap_lookups_enum_t *penum)
175
{
176
    if (penum->index[0] == 0) {
177
	penum->entry.key_size = 2;
178
	penum->entry.key_is_range = true;
179
	penum->entry.value_type = CODE_VALUE_CID;
180
	penum->entry.value.size = 2;
181
	penum->entry.font_index = 0;
182
	penum->index[0] = 1;
183
	return 0;
184
    }
185
    return 1;
186
}
187
private int
188
tt_16bit_format4_next_entry(gs_cmap_lookups_enum_t *penum)
189
{
190
    /* index[1] is segment # << 17 + first code. */
191
    uint segment2 = penum->index[1] >> 16;
192
    uint next = penum->index[1] & 0xffff;
193
    const gs_cmap_tt_16bit_format4_t *pcmap =
194
	(const gs_cmap_tt_16bit_format4_t *)penum->cmap;
195
    gs_font_type42 *pfont = pcmap->font;
196
    const byte *ttdata;
197
    int code;
198
    uint start, end, delta, roff;
199
    uint value;
200
 
201
 top:
202
    if (segment2 >= pcmap->segCount2)
203
	return 1;
204
    ACCESS(pcmap->endCount + segment2, 2, ttdata);
205
    end = U16(ttdata);
206
    if (next > end) {
207
	segment2 += 2;
208
	goto top;
209
    }
210
    ACCESS(pcmap->startCount + segment2, 2, ttdata);
211
    start = U16(ttdata);
212
    if (next < start)
213
	next = start;
214
    PUT16(penum->entry.key[0], next);
215
    ACCESS(pcmap->idDelta + segment2, 2, ttdata);
216
    delta = U16(ttdata);
217
    ACCESS(pcmap->idRangeOffset + segment2, 2, ttdata);
218
    roff = U16(ttdata);
219
    if (roff) {
220
	/* Non-zero offset, table lookup. */
221
	ulong gidoff = pcmap->idRangeOffset + segment2 + roff;
222
 
223
	ACCESS(gidoff, 2, ttdata);
224
	value = U16(ttdata);
225
	if (value != 0)
226
	    value += delta;
227
	++next;
228
    } else {
229
	/* Zero offset, account for high-order byte changes. */
230
	value = next + delta;
231
	next = min(end, (next | 0xff)) + 1;
232
    }
233
    PUT16(penum->entry.key[1], next - 1);
234
    PUT16(penum->temp_value, value);
235
    penum->entry.value.data = penum->temp_value;
236
    penum->entry.value.size = 2;
237
    penum->index[1] = (segment2 << 16) + next;
238
    return 0;
239
}
240
private const gs_cmap_lookups_enum_procs_t tt_16bit_format4_lookup_procs = {
241
    tt_16bit_format4_next_lookup, tt_16bit_format4_next_entry
242
};
243
private void
244
tt_16bit_format4_enum_lookups(const gs_cmap_t *pcmap, int which,
245
			gs_cmap_lookups_enum_t *pre)
246
{
247
    gs_cmap_lookups_enum_setup(pre, pcmap,
248
			       (which ? &gs_cmap_no_lookups_procs :
249
				&tt_16bit_format4_lookup_procs));
250
}
251
 
252
private const gs_cmap_procs_t tt_16bit_format4_procs = {
253
    tt_16bit_format4_decode_next,
254
    tt_16bit_format4_enum_ranges,
255
    tt_16bit_format4_enum_lookups,
256
    gs_cmap_compute_identity
257
};
258
 
259
/*
260
 * Create a CMap from a TrueType Platform 3, Encoding 1, Format 4 cmap.
261
 */
262
int
263
gs_cmap_from_type42_cmap(gs_cmap_t **ppcmap, gs_font_type42 *pfont,
264
			 int wmode, gs_memory_t *mem)
265
{
266
    ulong origin = pfont->data.cmap;
267
    gs_cmap_tt_16bit_format4_t *pcmap;
268
    int code;
269
    const byte *ttdata;
270
    ulong offset = origin;
271
    uint segCount2;
272
 
273
    if (origin == 0)
274
	return_error(gs_error_invalidfont);
275
 
276
    /*
277
     * Find the desired cmap sub-table, if any.
278
     */
279
    {
280
	uint cmap_count;
281
	uint i;
282
 
283
	ACCESS(origin + 2, 2, ttdata);
284
	cmap_count = U16(ttdata);
285
	for (i = 0; i < cmap_count; ++i) {
286
	    ACCESS(origin + 4 + i * 8, 8, ttdata);
287
	    if (U16(ttdata) != 3 || /* platform ID */
288
		U16(ttdata + 2) != 1 /* encoding ID */
289
		)
290
		continue;
291
	    offset = origin + U32(ttdata + 4);
292
	    ACCESS(offset, 2, ttdata);
293
	    if (U16(ttdata) != 4 /* format */)
294
		continue;
295
	    break;
296
	}
297
	if (i >= cmap_count)	/* not found */
298
	    return_error(gs_error_invalidfont);
299
	ACCESS(offset + 6, 2, ttdata);
300
	segCount2 = U16(ttdata);
301
    }
302
 
303
    /* Allocate the CMap. */
304
    {
305
	static const gs_cid_system_info_t null_cidsi = {
306
	    { (const byte*) "none", 4 },
307
	    { (const byte*) "none", 4 },
308
 
309
	};
310
	code = gs_cmap_alloc(ppcmap, &st_cmap_tt_16bit_format4, wmode,
311
			     (const byte *)"none", 4, &null_cidsi, 1,
312
			     &tt_16bit_format4_procs, mem);
313
	if (code < 0)
314
	    return code;
315
    }
316
    pcmap = (gs_cmap_tt_16bit_format4_t *)*ppcmap;
317
    pcmap->from_Unicode = true;
318
    pcmap->font = pfont;
319
    pcmap->segCount2 = segCount2;
320
    pcmap->endCount = offset + 14;
321
    pcmap->startCount = pcmap->endCount + segCount2 + 2;
322
    pcmap->idDelta = pcmap->startCount + segCount2;
323
    pcmap->idRangeOffset = pcmap->idDelta + segCount2;
324
    pcmap->glyphIdArray = pcmap->idRangeOffset + segCount2;
325
    return 0;
326
}