Subversion Repositories Kolibri OS

Rev

Rev 8402 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8402 maxcodehac 1
#include "fitz.h"
2
#include "mupdf.h"
3
 
4
#include 
5
#include FT_FREETYPE_H
6
#include FT_XFREE86_H
7
 
8
static fz_error pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_xref *xref, fz_obj *dict, char *collection, char *basefont);
9
 
10
static char *base_font_names[14][7] =
11
{
12
	{ "Courier", "CourierNew", "CourierNewPSMT", NULL },
13
	{ "Courier-Bold", "CourierNew,Bold", "Courier,Bold",
14
		"CourierNewPS-BoldMT", "CourierNew-Bold", NULL },
15
	{ "Courier-Oblique", "CourierNew,Italic", "Courier,Italic",
16
		"CourierNewPS-ItalicMT", "CourierNew-Italic", NULL },
17
	{ "Courier-BoldOblique", "CourierNew,BoldItalic", "Courier,BoldItalic",
18
		"CourierNewPS-BoldItalicMT", "CourierNew-BoldItalic", NULL },
19
	{ "Helvetica", "ArialMT", "Arial", NULL },
20
	{ "Helvetica-Bold", "Arial-BoldMT", "Arial,Bold", "Arial-Bold",
21
		"Helvetica,Bold", NULL },
22
	{ "Helvetica-Oblique", "Arial-ItalicMT", "Arial,Italic", "Arial-Italic",
23
		"Helvetica,Italic", "Helvetica-Italic", NULL },
24
	{ "Helvetica-BoldOblique", "Arial-BoldItalicMT",
25
		"Arial,BoldItalic", "Arial-BoldItalic",
26
		"Helvetica,BoldItalic", "Helvetica-BoldItalic", NULL },
27
	{ "Times-Roman", "TimesNewRomanPSMT", "TimesNewRoman",
28
		"TimesNewRomanPS", NULL },
29
	{ "Times-Bold", "TimesNewRomanPS-BoldMT", "TimesNewRoman,Bold",
30
		"TimesNewRomanPS-Bold", "TimesNewRoman-Bold", NULL },
31
	{ "Times-Italic", "TimesNewRomanPS-ItalicMT", "TimesNewRoman,Italic",
32
		"TimesNewRomanPS-Italic", "TimesNewRoman-Italic", NULL },
33
	{ "Times-BoldItalic", "TimesNewRomanPS-BoldItalicMT",
34
		"TimesNewRoman,BoldItalic", "TimesNewRomanPS-BoldItalic",
35
		"TimesNewRoman-BoldItalic", NULL },
36
	{ "Symbol", NULL },
37
	{ "ZapfDingbats", NULL }
38
};
39
 
40
static int is_dynalab(char *name)
41
{
42
	if (strstr(name, "HuaTian"))
43
		return 1;
44
	if (strstr(name, "MingLi"))
45
		return 1;
46
	if ((strstr(name, "DF") == name) || strstr(name, "+DF"))
47
		return 1;
48
	if ((strstr(name, "DLC") == name) || strstr(name, "+DLC"))
49
		return 1;
50
	return 0;
51
}
52
 
53
static int strcmp_ignore_space(char *a, char *b)
54
{
55
	while (1)
56
	{
57
		while (*a == ' ')
58
			a++;
59
		while (*b == ' ')
60
			b++;
61
		if (*a != *b)
62
			return 1;
63
		if (*a == 0)
64
			return *a != *b;
65
		if (*b == 0)
66
			return *a != *b;
67
		a++;
68
		b++;
69
	}
70
}
71
 
72
static char *clean_font_name(char *fontname)
73
{
74
	int i, k;
75
	for (i = 0; i < 14; i++)
76
		for (k = 0; base_font_names[i][k]; k++)
77
			if (!strcmp_ignore_space(base_font_names[i][k], fontname))
78
				return base_font_names[i][0];
79
	return fontname;
80
}
81
 
82
/*
83
 * FreeType and Rendering glue
84
 */
85
 
86
enum { UNKNOWN, TYPE1, TRUETYPE };
87
 
88
static int ft_kind(FT_Face face)
89
{
8411 maxcodehac 90
	/// STUB ///
8402 maxcodehac 91
	//const char *kind = FT_Get_X11_Font_Format(face);
92
	const char *kind = "TrueType";
93
 
94
	if (!strcmp(kind, "TrueType"))
95
		return TRUETYPE;
96
	if (!strcmp(kind, "Type 1"))
97
		return TYPE1;
98
	if (!strcmp(kind, "CFF"))
99
		return TYPE1;
100
	if (!strcmp(kind, "CID Type 1"))
101
		return TYPE1;
102
	return UNKNOWN;
103
}
104
 
105
static int ft_is_bold(FT_Face face)
106
{
107
	return face->style_flags & FT_STYLE_FLAG_BOLD;
108
}
109
 
110
static int ft_is_italic(FT_Face face)
111
{
112
	return face->style_flags & FT_STYLE_FLAG_ITALIC;
113
}
114
 
115
static int ft_char_index(FT_Face face, int cid)
116
{
117
	int gid = FT_Get_Char_Index(face, cid);
118
	if (gid == 0)
119
		gid = FT_Get_Char_Index(face, 0xf000 + cid);
120
 
121
	/* some chinese fonts only ship the similarly looking 0x2026 */
122
	if (gid == 0 && cid == 0x22ef)
123
		gid = FT_Get_Char_Index(face, 0x2026);
124
 
125
	return gid;
126
}
127
 
128
static int ft_cid_to_gid(pdf_font_desc *fontdesc, int cid)
129
{
130
	if (fontdesc->to_ttf_cmap)
131
	{
132
		cid = pdf_lookup_cmap(fontdesc->to_ttf_cmap, cid);
133
		return ft_char_index(fontdesc->font->ft_face, cid);
134
	}
135
 
136
	if (fontdesc->cid_to_gid)
137
		return fontdesc->cid_to_gid[cid];
138
 
139
	return cid;
140
}
141
 
142
int
143
pdf_font_cid_to_gid(pdf_font_desc *fontdesc, int cid)
144
{
145
	if (fontdesc->font->ft_face)
146
		return ft_cid_to_gid(fontdesc, cid);
147
	return cid;
148
}
149
 
150
static int ft_width(pdf_font_desc *fontdesc, int cid)
151
{
152
	int gid = ft_cid_to_gid(fontdesc, cid);
153
	int fterr = FT_Load_Glyph(fontdesc->font->ft_face, gid,
154
			FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
155
	if (fterr)
156
	{
157
		fz_warn("freetype load glyph (gid %d): %s", gid, ft_error_string(fterr));
158
		return 0;
159
	}
160
	return ((FT_Face)fontdesc->font->ft_face)->glyph->advance.x;
161
}
162
 
163
static int lookup_mre_code(char *name)
164
{
165
	int i;
166
	for (i = 0; i < 256; i++)
167
		if (pdf_mac_roman[i] && !strcmp(name, pdf_mac_roman[i]))
168
			return i;
169
	return -1;
170
}
171
 
172
/*
173
 * Load font files.
174
 */
175
 
176
static fz_error
177
pdf_load_builtin_font(pdf_font_desc *fontdesc, char *fontname)
178
{
179
	fz_error error;
180
	unsigned char *data;
181
	unsigned int len;
182
 
183
	data = pdf_find_builtin_font(fontname, &len);
184
	if (!data)
185
		return fz_throw("cannot find builtin font: '%s'", fontname);
186
 
187
	error = fz_new_font_from_memory(&fontdesc->font, data, len, 0);
188
	if (error)
189
		return fz_rethrow(error, "cannot load freetype font from memory");
190
 
191
	if (!strcmp(fontname, "Symbol") || !strcmp(fontname, "ZapfDingbats"))
192
		fontdesc->flags |= PDF_FD_SYMBOLIC;
193
 
194
	return fz_okay;
195
}
196
 
197
static fz_error
198
pdf_load_substitute_font(pdf_font_desc *fontdesc, int mono, int serif, int bold, int italic)
199
{
200
	fz_error error;
201
	unsigned char *data;
202
	unsigned int len;
203
 
204
	data = pdf_find_substitute_font(mono, serif, bold, italic, &len);
205
	if (!data)
206
		return fz_throw("cannot find substitute font");
207
 
208
	error = fz_new_font_from_memory(&fontdesc->font, data, len, 0);
209
	if (error)
210
		return fz_rethrow(error, "cannot load freetype font from memory");
211
 
212
	fontdesc->font->ft_substitute = 1;
213
	fontdesc->font->ft_bold = bold && !ft_is_bold(fontdesc->font->ft_face);
214
	fontdesc->font->ft_italic = italic && !ft_is_italic(fontdesc->font->ft_face);
215
	return fz_okay;
216
}
217
 
218
static fz_error
219
pdf_load_substitute_cjk_font(pdf_font_desc *fontdesc, int ros, int serif)
220
{
221
	fz_error error;
222
	unsigned char *data;
223
	unsigned int len;
224
 
225
	data = pdf_find_substitute_cjk_font(ros, serif, &len);
226
	if (!data)
227
		return fz_throw("cannot find builtin CJK font");
228
 
229
	error = fz_new_font_from_memory(&fontdesc->font, data, len, 0);
230
	if (error)
231
		return fz_rethrow(error, "cannot load builtin CJK font");
232
 
233
	fontdesc->font->ft_substitute = 1;
234
	return fz_okay;
235
}
236
 
237
static fz_error
238
pdf_load_system_font(pdf_font_desc *fontdesc, char *fontname, char *collection)
239
{
240
	fz_error error;
241
	int bold = 0;
242
	int italic = 0;
243
	int serif = 0;
244
	int mono = 0;
245
 
246
	if (strstr(fontname, "Bold"))
247
		bold = 1;
248
	if (strstr(fontname, "Italic"))
249
		italic = 1;
250
	if (strstr(fontname, "Oblique"))
251
		italic = 1;
252
 
253
	if (fontdesc->flags & PDF_FD_FIXED_PITCH)
254
		mono = 1;
255
	if (fontdesc->flags & PDF_FD_SERIF)
256
		serif = 1;
257
	if (fontdesc->flags & PDF_FD_ITALIC)
258
		italic = 1;
259
	if (fontdesc->flags & PDF_FD_FORCE_BOLD)
260
		bold = 1;
261
 
262
	if (collection)
263
	{
264
		if (!strcmp(collection, "Adobe-CNS1"))
265
			return pdf_load_substitute_cjk_font(fontdesc, PDF_ROS_CNS, serif);
266
		else if (!strcmp(collection, "Adobe-GB1"))
267
			return pdf_load_substitute_cjk_font(fontdesc, PDF_ROS_GB, serif);
268
		else if (!strcmp(collection, "Adobe-Japan1"))
269
			return pdf_load_substitute_cjk_font(fontdesc, PDF_ROS_JAPAN, serif);
270
		else if (!strcmp(collection, "Adobe-Korea1"))
271
			return pdf_load_substitute_cjk_font(fontdesc, PDF_ROS_KOREA, serif);
272
		return fz_throw("unknown cid collection: %s", collection);
273
	}
274
 
275
	error = pdf_load_substitute_font(fontdesc, mono, serif, bold, italic);
276
	if (error)
277
		return fz_rethrow(error, "cannot load substitute font");
278
 
279
	return fz_okay;
280
}
281
 
282
static fz_error
283
pdf_load_embedded_font(pdf_font_desc *fontdesc, pdf_xref *xref, fz_obj *stmref)
284
{
285
	fz_error error;
286
	fz_buffer *buf;
287
 
288
	error = pdf_load_stream(&buf, xref, fz_to_num(stmref), fz_to_gen(stmref));
289
	if (error)
290
		return fz_rethrow(error, "cannot load font stream (%d %d R)", fz_to_num(stmref), fz_to_gen(stmref));
291
 
292
	error = fz_new_font_from_memory(&fontdesc->font, buf->data, buf->len, 0);
293
	if (error)
294
	{
295
		fz_drop_buffer(buf);
296
		return fz_rethrow(error, "cannot load embedded font (%d %d R)", fz_to_num(stmref), fz_to_gen(stmref));
297
	}
298
 
299
	/* save the buffer so we can free it later */
300
	fontdesc->font->ft_data = buf->data;
301
	fontdesc->font->ft_size = buf->len;
302
	fz_free(buf); /* only free the fz_buffer struct, not the contained data */
303
 
304
	fontdesc->is_embedded = 1;
305
 
306
	return fz_okay;
307
}
308
 
309
/*
310
 * Create and destroy
311
 */
312
 
313
pdf_font_desc *
314
pdf_keep_font(pdf_font_desc *fontdesc)
315
{
316
	fontdesc->refs ++;
317
	return fontdesc;
318
}
319
 
320
void
321
pdf_drop_font(pdf_font_desc *fontdesc)
322
{
323
	if (fontdesc && --fontdesc->refs == 0)
324
	{
325
		if (fontdesc->font)
326
			fz_drop_font(fontdesc->font);
327
		if (fontdesc->encoding)
328
			pdf_drop_cmap(fontdesc->encoding);
329
		if (fontdesc->to_ttf_cmap)
330
			pdf_drop_cmap(fontdesc->to_ttf_cmap);
331
		if (fontdesc->to_unicode)
332
			pdf_drop_cmap(fontdesc->to_unicode);
333
		fz_free(fontdesc->cid_to_gid);
334
		fz_free(fontdesc->cid_to_ucs);
335
		fz_free(fontdesc->hmtx);
336
		fz_free(fontdesc->vmtx);
337
		fz_free(fontdesc);
338
	}
339
}
340
 
341
pdf_font_desc *
342
pdf_new_font_desc(void)
343
{
344
	pdf_font_desc *fontdesc;
345
 
346
	fontdesc = fz_malloc(sizeof(pdf_font_desc));
347
	fontdesc->refs = 1;
348
 
349
	fontdesc->font = NULL;
350
 
351
	fontdesc->flags = 0;
352
	fontdesc->italic_angle = 0;
353
	fontdesc->ascent = 0;
354
	fontdesc->descent = 0;
355
	fontdesc->cap_height = 0;
356
	fontdesc->x_height = 0;
357
	fontdesc->missing_width = 0;
358
 
359
	fontdesc->encoding = NULL;
360
	fontdesc->to_ttf_cmap = NULL;
361
	fontdesc->cid_to_gid_len = 0;
362
	fontdesc->cid_to_gid = NULL;
363
 
364
	fontdesc->to_unicode = NULL;
365
	fontdesc->cid_to_ucs_len = 0;
366
	fontdesc->cid_to_ucs = NULL;
367
 
368
	fontdesc->wmode = 0;
369
 
370
	fontdesc->hmtx_cap = 0;
371
	fontdesc->vmtx_cap = 0;
372
	fontdesc->hmtx_len = 0;
373
	fontdesc->vmtx_len = 0;
374
	fontdesc->hmtx = NULL;
375
	fontdesc->vmtx = NULL;
376
 
377
	fontdesc->dhmtx.lo = 0x0000;
378
	fontdesc->dhmtx.hi = 0xFFFF;
379
	fontdesc->dhmtx.w = 1000;
380
 
381
	fontdesc->dvmtx.lo = 0x0000;
382
	fontdesc->dvmtx.hi = 0xFFFF;
383
	fontdesc->dvmtx.x = 0;
384
	fontdesc->dvmtx.y = 880;
385
	fontdesc->dvmtx.w = -1000;
386
 
387
	fontdesc->is_embedded = 0;
388
 
389
	return fontdesc;
390
}
391
 
392
/*
393
 * Simple fonts (Type1 and TrueType)
394
 */
395
 
396
static fz_error
397
pdf_load_simple_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *dict)
398
{
399
	fz_error error;
400
	fz_obj *descriptor;
401
	fz_obj *encoding;
402
	fz_obj *widths;
403
	unsigned short *etable = NULL;
404
	pdf_font_desc *fontdesc;
405
	FT_Face face;
406
	FT_CharMap cmap;
407
	int symbolic;
408
	int kind;
409
 
410
	char *basefont;
411
	char *fontname;
412
	char *estrings[256];
413
	char ebuffer[256][32];
414
	int i, k, n;
415
	int fterr;
416
 
417
	basefont = fz_to_name(fz_dict_gets(dict, "BaseFont"));
418
	fontname = clean_font_name(basefont);
419
 
420
	/* Load font file */
421
 
422
	fontdesc = pdf_new_font_desc();
423
 
424
	descriptor = fz_dict_gets(dict, "FontDescriptor");
425
	if (descriptor)
426
		error = pdf_load_font_descriptor(fontdesc, xref, descriptor, NULL, basefont);
427
	else
428
		error = pdf_load_builtin_font(fontdesc, fontname);
429
	if (error)
430
		goto cleanup;
431
 
432
	/* Some chinese documents mistakenly consider WinAnsiEncoding to be codepage 936 */
433
	if (!*fontdesc->font->name &&
434
		!fz_dict_gets(dict, "ToUnicode") &&
435
		!strcmp(fz_to_name(fz_dict_gets(dict, "Encoding")), "WinAnsiEncoding") &&
436
		fz_to_int(fz_dict_gets(descriptor, "Flags")) == 4)
437
	{
438
		/* note: without the comma, pdf_load_font_descriptor would prefer /FontName over /BaseFont */
439
		char *cp936fonts[] = {
440
			"\xCB\xCE\xCC\xE5", "SimSun,Regular",
441
			"\xBA\xDA\xCC\xE5", "SimHei,Regular",
442
			"\xBF\xAC\xCC\xE5_GB2312", "SimKai,Regular",
443
			"\xB7\xC2\xCB\xCE_GB2312", "SimFang,Regular",
444
			"\xC1\xA5\xCA\xE9", "SimLi,Regular",
445
			NULL
446
		};
447
		for (i = 0; cp936fonts[i]; i += 2)
448
			if (!strcmp(basefont, cp936fonts[i]))
449
				break;
450
		if (cp936fonts[i])
451
		{
452
			fz_warn("workaround for S22PDF lying about chinese font encodings");
453
			pdf_drop_font(fontdesc);
454
			fontdesc = pdf_new_font_desc();
455
			error = pdf_load_font_descriptor(fontdesc, xref, descriptor, "Adobe-GB1", cp936fonts[i+1]);
456
			error |= pdf_load_system_cmap(&fontdesc->encoding, "GBK-EUC-H");
457
			error |= pdf_load_system_cmap(&fontdesc->to_unicode, "Adobe-GB1-UCS2");
458
			error |= pdf_load_system_cmap(&fontdesc->to_ttf_cmap, "Adobe-GB1-UCS2");
459
			if (error)
460
				return fz_rethrow(error, "cannot load font");
461
 
462
			face = fontdesc->font->ft_face;
463
			kind = ft_kind(face);
464
			goto skip_encoding;
465
		}
466
	}
467
 
468
	face = fontdesc->font->ft_face;
469
	kind = ft_kind(face);
470
 
471
	/* Encoding */
472
 
473
	symbolic = fontdesc->flags & 4;
474
 
475
	if (face->num_charmaps > 0)
476
		cmap = face->charmaps[0];
477
	else
478
		cmap = NULL;
479
 
480
	for (i = 0; i < face->num_charmaps; i++)
481
	{
482
		FT_CharMap test = face->charmaps[i];
483
 
484
		if (kind == TYPE1)
485
		{
486
			if (test->platform_id == 7)
487
				cmap = test;
488
		}
489
 
490
		if (kind == TRUETYPE)
491
		{
492
			if (test->platform_id == 1 && test->encoding_id == 0)
493
				cmap = test;
494
			if (test->platform_id == 3 && test->encoding_id == 1)
495
				cmap = test;
496
		}
497
	}
498
 
499
	if (cmap)
500
	{
501
		fterr = FT_Set_Charmap(face, cmap);
502
		if (fterr)
503
			fz_warn("freetype could not set cmap: %s", ft_error_string(fterr));
504
	}
505
	else
506
		fz_warn("freetype could not find any cmaps");
507
 
508
	etable = fz_calloc(256, sizeof(unsigned short));
509
	for (i = 0; i < 256; i++)
510
	{
511
		estrings[i] = NULL;
512
		etable[i] = 0;
513
	}
514
 
515
	encoding = fz_dict_gets(dict, "Encoding");
516
	if (encoding)
517
	{
518
		if (fz_is_name(encoding))
519
			pdf_load_encoding(estrings, fz_to_name(encoding));
520
 
521
		if (fz_is_dict(encoding))
522
		{
523
			fz_obj *base, *diff, *item;
524
 
525
			base = fz_dict_gets(encoding, "BaseEncoding");
526
			if (fz_is_name(base))
527
				pdf_load_encoding(estrings, fz_to_name(base));
528
			else if (!fontdesc->is_embedded && !symbolic)
529
				pdf_load_encoding(estrings, "StandardEncoding");
530
 
531
			diff = fz_dict_gets(encoding, "Differences");
532
			if (fz_is_array(diff))
533
			{
534
				n = fz_array_len(diff);
535
				k = 0;
536
				for (i = 0; i < n; i++)
537
				{
538
					item = fz_array_get(diff, i);
539
					if (fz_is_int(item))
540
						k = fz_to_int(item);
541
					if (fz_is_name(item))
542
						estrings[k++] = fz_to_name(item);
543
					if (k < 0) k = 0;
544
					if (k > 255) k = 255;
545
				}
546
			}
547
		}
548
	}
549
 
550
	/* start with the builtin encoding */
551
	for (i = 0; i < 256; i++)
552
		etable[i] = ft_char_index(face, i);
553
 
554
	/* encode by glyph name where we can */
555
	if (kind == TYPE1)
556
	{
557
		for (i = 0; i < 256; i++)
558
		{
559
			if (estrings[i])
560
			{
561
				etable[i] = FT_Get_Name_Index(face, estrings[i]);
562
				if (etable[i] == 0)
563
				{
564
					int aglcode = pdf_lookup_agl(estrings[i]);
565
					const char **dupnames = pdf_lookup_agl_duplicates(aglcode);
566
					while (*dupnames)
567
					{
568
						etable[i] = FT_Get_Name_Index(face, (char*)*dupnames);
569
						if (etable[i])
570
							break;
571
						dupnames++;
572
					}
573
				}
574
			}
575
		}
576
	}
577
 
578
	/* encode by glyph name where we can */
579
	if (kind == TRUETYPE)
580
	{
581
		/* Unicode cmap */
582
		if (!symbolic && face->charmap && face->charmap->platform_id == 3)
583
		{
584
			for (i = 0; i < 256; i++)
585
			{
586
				if (estrings[i])
587
				{
588
					int aglcode = pdf_lookup_agl(estrings[i]);
589
					if (!aglcode)
590
						etable[i] = FT_Get_Name_Index(face, estrings[i]);
591
					else
592
						etable[i] = ft_char_index(face, aglcode);
593
				}
594
			}
595
		}
596
 
597
		/* MacRoman cmap */
598
		else if (!symbolic && face->charmap && face->charmap->platform_id == 1)
599
		{
600
			for (i = 0; i < 256; i++)
601
			{
602
				if (estrings[i])
603
				{
604
					k = lookup_mre_code(estrings[i]);
605
					if (k <= 0)
606
						etable[i] = FT_Get_Name_Index(face, estrings[i]);
607
					else
608
						etable[i] = ft_char_index(face, k);
609
				}
610
			}
611
		}
612
 
613
		/* Symbolic cmap */
614
		else
615
		{
616
			for (i = 0; i < 256; i++)
617
			{
618
				if (estrings[i])
619
				{
620
					etable[i] = FT_Get_Name_Index(face, estrings[i]);
621
					if (etable[i] == 0)
622
						etable[i] = ft_char_index(face, i);
623
				}
624
			}
625
		}
626
	}
627
 
628
	/* try to reverse the glyph names from the builtin encoding */
629
	for (i = 0; i < 256; i++)
630
	{
631
		if (etable[i] && !estrings[i])
632
		{
633
			if (FT_HAS_GLYPH_NAMES(face))
634
			{
635
				fterr = FT_Get_Glyph_Name(face, etable[i], ebuffer[i], 32);
636
				if (fterr)
637
					fz_warn("freetype get glyph name (gid %d): %s", etable[i], ft_error_string(fterr));
638
				if (ebuffer[i][0])
639
					estrings[i] = ebuffer[i];
640
			}
641
			else
642
			{
643
				estrings[i] = (char*) pdf_win_ansi[i]; /* discard const */
644
			}
645
		}
646
	}
647
 
648
	fontdesc->encoding = pdf_new_identity_cmap(0, 1);
649
	fontdesc->cid_to_gid_len = 256;
650
	fontdesc->cid_to_gid = etable;
651
 
652
	error = pdf_load_to_unicode(fontdesc, xref, estrings, NULL, fz_dict_gets(dict, "ToUnicode"));
653
	if (error)
654
		fz_catch(error, "cannot load to_unicode");
655
 
656
skip_encoding:
657
 
658
	/* Widths */
659
 
660
	pdf_set_default_hmtx(fontdesc, fontdesc->missing_width);
661
 
662
	widths = fz_dict_gets(dict, "Widths");
663
	if (widths)
664
	{
665
		int first, last;
666
 
667
		first = fz_to_int(fz_dict_gets(dict, "FirstChar"));
668
		last = fz_to_int(fz_dict_gets(dict, "LastChar"));
669
 
670
		if (first < 0 || last > 255 || first > last)
671
			first = last = 0;
672
 
673
		for (i = 0; i < last - first + 1; i++)
674
		{
675
			int wid = fz_to_int(fz_array_get(widths, i));
676
			pdf_add_hmtx(fontdesc, i + first, i + first, wid);
677
		}
678
	}
679
	else
680
	{
681
		fterr = FT_Set_Char_Size(face, 1000, 1000, 72, 72);
682
		if (fterr)
683
			fz_warn("freetype set character size: %s", ft_error_string(fterr));
684
		for (i = 0; i < 256; i++)
685
		{
686
			pdf_add_hmtx(fontdesc, i, i, ft_width(fontdesc, i));
687
		}
688
	}
689
 
690
	pdf_end_hmtx(fontdesc);
691
 
692
	*fontdescp = fontdesc;
693
	return fz_okay;
694
 
695
cleanup:
696
	if (etable != fontdesc->cid_to_gid)
697
		fz_free(etable);
698
	pdf_drop_font(fontdesc);
699
	return fz_rethrow(error, "cannot load simple font (%d %d R)", fz_to_num(dict), fz_to_gen(dict));
700
}
701
 
702
/*
703
 * CID Fonts
704
 */
705
 
706
static fz_error
707
load_cid_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *dict, fz_obj *encoding, fz_obj *to_unicode)
708
{
709
	fz_error error;
710
	fz_obj *widths;
711
	fz_obj *descriptor;
712
	pdf_font_desc *fontdesc;
713
	FT_Face face;
714
	int kind;
715
	char collection[256];
716
	char *basefont;
717
	int i, k, fterr;
718
	fz_obj *obj;
719
	int dw;
720
 
721
	/* Get font name and CID collection */
722
 
723
	basefont = fz_to_name(fz_dict_gets(dict, "BaseFont"));
724
 
725
	{
726
		fz_obj *cidinfo;
727
		char tmpstr[64];
728
		int tmplen;
729
 
730
		cidinfo = fz_dict_gets(dict, "CIDSystemInfo");
731
		if (!cidinfo)
732
			return fz_throw("cid font is missing info");
733
 
734
		obj = fz_dict_gets(cidinfo, "Registry");
735
		tmplen = MIN(sizeof tmpstr - 1, fz_to_str_len(obj));
736
		memcpy(tmpstr, fz_to_str_buf(obj), tmplen);
737
		tmpstr[tmplen] = '\0';
738
		fz_strlcpy(collection, tmpstr, sizeof collection);
739
 
740
		fz_strlcat(collection, "-", sizeof collection);
741
 
742
		obj = fz_dict_gets(cidinfo, "Ordering");
743
		tmplen = MIN(sizeof tmpstr - 1, fz_to_str_len(obj));
744
		memcpy(tmpstr, fz_to_str_buf(obj), tmplen);
745
		tmpstr[tmplen] = '\0';
746
		fz_strlcat(collection, tmpstr, sizeof collection);
747
	}
748
 
749
	/* Load font file */
750
 
751
	fontdesc = pdf_new_font_desc();
752
 
753
	descriptor = fz_dict_gets(dict, "FontDescriptor");
754
	if (descriptor)
755
		error = pdf_load_font_descriptor(fontdesc, xref, descriptor, collection, basefont);
756
	else
757
		error = fz_throw("syntaxerror: missing font descriptor");
758
	if (error)
759
		goto cleanup;
760
 
761
	face = fontdesc->font->ft_face;
762
	kind = ft_kind(face);
763
 
764
	/* Encoding */
765
 
766
	error = fz_okay;
767
	if (fz_is_name(encoding))
768
	{
769
		if (!strcmp(fz_to_name(encoding), "Identity-H"))
770
			fontdesc->encoding = pdf_new_identity_cmap(0, 2);
771
		else if (!strcmp(fz_to_name(encoding), "Identity-V"))
772
			fontdesc->encoding = pdf_new_identity_cmap(1, 2);
773
		else
774
			error = pdf_load_system_cmap(&fontdesc->encoding, fz_to_name(encoding));
775
	}
776
	else if (fz_is_indirect(encoding))
777
	{
778
		error = pdf_load_embedded_cmap(&fontdesc->encoding, xref, encoding);
779
	}
780
	else
781
	{
782
		error = fz_throw("syntaxerror: font missing encoding");
783
	}
784
	if (error)
785
		goto cleanup;
786
 
787
	pdf_set_font_wmode(fontdesc, pdf_get_wmode(fontdesc->encoding));
788
 
789
	if (kind == TRUETYPE)
790
	{
791
		fz_obj *cidtogidmap;
792
 
793
		cidtogidmap = fz_dict_gets(dict, "CIDToGIDMap");
794
		if (fz_is_indirect(cidtogidmap))
795
		{
796
			fz_buffer *buf;
797
 
798
			error = pdf_load_stream(&buf, xref, fz_to_num(cidtogidmap), fz_to_gen(cidtogidmap));
799
			if (error)
800
				goto cleanup;
801
 
802
			fontdesc->cid_to_gid_len = (buf->len) / 2;
803
			fontdesc->cid_to_gid = fz_calloc(fontdesc->cid_to_gid_len, sizeof(unsigned short));
804
			for (i = 0; i < fontdesc->cid_to_gid_len; i++)
805
				fontdesc->cid_to_gid[i] = (buf->data[i * 2] << 8) + buf->data[i * 2 + 1];
806
 
807
			fz_drop_buffer(buf);
808
		}
809
 
810
		/* if truetype font is external, cidtogidmap should not be identity */
811
		/* so we map from cid to unicode and then map that through the (3 1) */
812
		/* unicode cmap to get a glyph id */
813
		else if (fontdesc->font->ft_substitute)
814
		{
815
			fterr = FT_Select_Charmap(face, ft_encoding_unicode);
816
			if (fterr)
817
			{
818
				error = fz_throw("fonterror: no unicode cmap when emulating CID font: %s", ft_error_string(fterr));
819
				goto cleanup;
820
			}
821
 
822
			if (!strcmp(collection, "Adobe-CNS1"))
823
				error = pdf_load_system_cmap(&fontdesc->to_ttf_cmap, "Adobe-CNS1-UCS2");
824
			else if (!strcmp(collection, "Adobe-GB1"))
825
				error = pdf_load_system_cmap(&fontdesc->to_ttf_cmap, "Adobe-GB1-UCS2");
826
			else if (!strcmp(collection, "Adobe-Japan1"))
827
				error = pdf_load_system_cmap(&fontdesc->to_ttf_cmap, "Adobe-Japan1-UCS2");
828
			else if (!strcmp(collection, "Adobe-Japan2"))
829
				error = pdf_load_system_cmap(&fontdesc->to_ttf_cmap, "Adobe-Japan2-UCS2");
830
			else if (!strcmp(collection, "Adobe-Korea1"))
831
				error = pdf_load_system_cmap(&fontdesc->to_ttf_cmap, "Adobe-Korea1-UCS2");
832
			else
833
				error = fz_okay;
834
 
835
			if (error)
836
			{
837
				error = fz_rethrow(error, "cannot load system cmap %s", collection);
838
				goto cleanup;
839
			}
840
		}
841
	}
842
 
843
	error = pdf_load_to_unicode(fontdesc, xref, NULL, collection, to_unicode);
844
	if (error)
845
		fz_catch(error, "cannot load to_unicode");
846
 
847
	/* Horizontal */
848
 
849
	dw = 1000;
850
	obj = fz_dict_gets(dict, "DW");
851
	if (obj)
852
		dw = fz_to_int(obj);
853
	pdf_set_default_hmtx(fontdesc, dw);
854
 
855
	widths = fz_dict_gets(dict, "W");
856
	if (widths)
857
	{
858
		int c0, c1, w;
859
 
860
		for (i = 0; i < fz_array_len(widths); )
861
		{
862
			c0 = fz_to_int(fz_array_get(widths, i));
863
			obj = fz_array_get(widths, i + 1);
864
			if (fz_is_array(obj))
865
			{
866
				for (k = 0; k < fz_array_len(obj); k++)
867
				{
868
					w = fz_to_int(fz_array_get(obj, k));
869
					pdf_add_hmtx(fontdesc, c0 + k, c0 + k, w);
870
				}
871
				i += 2;
872
			}
873
			else
874
			{
875
				c1 = fz_to_int(obj);
876
				w = fz_to_int(fz_array_get(widths, i + 2));
877
				pdf_add_hmtx(fontdesc, c0, c1, w);
878
				i += 3;
879
			}
880
		}
881
	}
882
 
883
	pdf_end_hmtx(fontdesc);
884
 
885
	/* Vertical */
886
 
887
	if (pdf_get_wmode(fontdesc->encoding) == 1)
888
	{
889
		int dw2y = 880;
890
		int dw2w = -1000;
891
 
892
		obj = fz_dict_gets(dict, "DW2");
893
		if (obj)
894
		{
895
			dw2y = fz_to_int(fz_array_get(obj, 0));
896
			dw2w = fz_to_int(fz_array_get(obj, 1));
897
		}
898
 
899
		pdf_set_default_vmtx(fontdesc, dw2y, dw2w);
900
 
901
		widths = fz_dict_gets(dict, "W2");
902
		if (widths)
903
		{
904
			int c0, c1, w, x, y;
905
 
906
			for (i = 0; i < fz_array_len(widths); )
907
			{
908
				c0 = fz_to_int(fz_array_get(widths, i));
909
				obj = fz_array_get(widths, i + 1);
910
				if (fz_is_array(obj))
911
				{
912
					for (k = 0; k * 3 < fz_array_len(obj); k ++)
913
					{
914
						w = fz_to_int(fz_array_get(obj, k * 3 + 0));
915
						x = fz_to_int(fz_array_get(obj, k * 3 + 1));
916
						y = fz_to_int(fz_array_get(obj, k * 3 + 2));
917
						pdf_add_vmtx(fontdesc, c0 + k, c0 + k, x, y, w);
918
					}
919
					i += 2;
920
				}
921
				else
922
				{
923
					c1 = fz_to_int(obj);
924
					w = fz_to_int(fz_array_get(widths, i + 2));
925
					x = fz_to_int(fz_array_get(widths, i + 3));
926
					y = fz_to_int(fz_array_get(widths, i + 4));
927
					pdf_add_vmtx(fontdesc, c0, c1, x, y, w);
928
					i += 5;
929
				}
930
			}
931
		}
932
 
933
		pdf_end_vmtx(fontdesc);
934
	}
935
 
936
	*fontdescp = fontdesc;
937
	return fz_okay;
938
 
939
cleanup:
940
	pdf_drop_font(fontdesc);
941
	return fz_rethrow(error, "cannot load cid font (%d %d R)", fz_to_num(dict), fz_to_gen(dict));
942
}
943
 
944
static fz_error
945
pdf_load_type0_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *dict)
946
{
947
	fz_error error;
948
	fz_obj *dfonts;
949
	fz_obj *dfont;
950
	fz_obj *subtype;
951
	fz_obj *encoding;
952
	fz_obj *to_unicode;
953
 
954
	dfonts = fz_dict_gets(dict, "DescendantFonts");
955
	if (!dfonts)
956
		return fz_throw("cid font is missing descendant fonts");
957
 
958
	dfont = fz_array_get(dfonts, 0);
959
 
960
	subtype = fz_dict_gets(dfont, "Subtype");
961
	encoding = fz_dict_gets(dict, "Encoding");
962
	to_unicode = fz_dict_gets(dict, "ToUnicode");
963
 
964
	if (fz_is_name(subtype) && !strcmp(fz_to_name(subtype), "CIDFontType0"))
965
		error = load_cid_font(fontdescp, xref, dfont, encoding, to_unicode);
966
	else if (fz_is_name(subtype) && !strcmp(fz_to_name(subtype), "CIDFontType2"))
967
		error = load_cid_font(fontdescp, xref, dfont, encoding, to_unicode);
968
	else
969
		error = fz_throw("syntaxerror: unknown cid font type");
970
	if (error)
971
		return fz_rethrow(error, "cannot load descendant font (%d %d R)", fz_to_num(dfont), fz_to_gen(dfont));
972
 
973
	return fz_okay;
974
}
975
 
976
/*
977
 * FontDescriptor
978
 */
979
 
980
static fz_error
981
pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_xref *xref, fz_obj *dict, char *collection, char *basefont)
982
{
983
	fz_error error;
984
	fz_obj *obj1, *obj2, *obj3, *obj;
985
	char *fontname;
986
	char *origname;
987
	FT_Face face;
988
 
989
	if (!strchr(basefont, ',') || strchr(basefont, '+'))
990
		origname = fz_to_name(fz_dict_gets(dict, "FontName"));
991
	else
992
		origname = basefont;
993
	fontname = clean_font_name(origname);
994
 
995
	fontdesc->flags = fz_to_int(fz_dict_gets(dict, "Flags"));
996
	fontdesc->italic_angle = fz_to_real(fz_dict_gets(dict, "ItalicAngle"));
997
	fontdesc->ascent = fz_to_real(fz_dict_gets(dict, "Ascent"));
998
	fontdesc->descent = fz_to_real(fz_dict_gets(dict, "Descent"));
999
	fontdesc->cap_height = fz_to_real(fz_dict_gets(dict, "CapHeight"));
1000
	fontdesc->x_height = fz_to_real(fz_dict_gets(dict, "XHeight"));
1001
	fontdesc->missing_width = fz_to_real(fz_dict_gets(dict, "MissingWidth"));
1002
 
1003
	obj1 = fz_dict_gets(dict, "FontFile");
1004
	obj2 = fz_dict_gets(dict, "FontFile2");
1005
	obj3 = fz_dict_gets(dict, "FontFile3");
1006
	obj = obj1 ? obj1 : obj2 ? obj2 : obj3;
1007
 
1008
	if (fz_is_indirect(obj))
1009
	{
1010
		error = pdf_load_embedded_font(fontdesc, xref, obj);
1011
		if (error)
1012
		{
1013
			fz_catch(error, "ignored error when loading embedded font, attempting to load system font");
1014
			if (origname != fontname)
1015
				error = pdf_load_builtin_font(fontdesc, fontname);
1016
			else
1017
				error = pdf_load_system_font(fontdesc, fontname, collection);
1018
			if (error)
1019
				return fz_rethrow(error, "cannot load font descriptor (%d %d R)", fz_to_num(dict), fz_to_gen(dict));
1020
		}
1021
	}
1022
	else
1023
	{
1024
		if (origname != fontname)
1025
			error = pdf_load_builtin_font(fontdesc, fontname);
1026
		else
1027
			error = pdf_load_system_font(fontdesc, fontname, collection);
1028
		if (error)
1029
			return fz_rethrow(error, "cannot load font descriptor (%d %d R)", fz_to_num(dict), fz_to_gen(dict));
1030
	}
1031
 
1032
	fz_strlcpy(fontdesc->font->name, fontname, sizeof fontdesc->font->name);
1033
 
1034
	/* Check for DynaLab fonts that must use hinting */
1035
	face = fontdesc->font->ft_face;
1036
	if (ft_kind(face) == TRUETYPE)
1037
	{
1038
		if (FT_IS_TRICKY(face) || is_dynalab(fontdesc->font->name))
1039
			fontdesc->font->ft_hint = 1;
1040
	}
1041
 
1042
	return fz_okay;
1043
 
1044
}
1045
 
1046
static void
1047
pdf_make_width_table(pdf_font_desc *fontdesc)
1048
{
1049
	fz_font *font = fontdesc->font;
1050
	int i, k, cid, gid;
1051
 
1052
	font->width_count = 0;
1053
	for (i = 0; i < fontdesc->hmtx_len; i++)
1054
	{
1055
		for (k = fontdesc->hmtx[i].lo; k <= fontdesc->hmtx[i].hi; k++)
1056
		{
1057
			cid = pdf_lookup_cmap(fontdesc->encoding, k);
1058
			gid = pdf_font_cid_to_gid(fontdesc, cid);
1059
			if (gid > font->width_count)
1060
				font->width_count = gid;
1061
		}
1062
	}
1063
	font->width_count ++;
1064
 
1065
	font->width_table = fz_calloc(font->width_count, sizeof(int));
1066
	memset(font->width_table, 0, sizeof(int) * font->width_count);
1067
 
1068
	for (i = 0; i < fontdesc->hmtx_len; i++)
1069
	{
1070
		for (k = fontdesc->hmtx[i].lo; k <= fontdesc->hmtx[i].hi; k++)
1071
		{
1072
			cid = pdf_lookup_cmap(fontdesc->encoding, k);
1073
			gid = pdf_font_cid_to_gid(fontdesc, cid);
1074
			if (gid >= 0 && gid < font->width_count)
1075
				font->width_table[gid] = fontdesc->hmtx[i].w;
1076
		}
1077
	}
1078
}
1079
 
1080
fz_error
1081
pdf_load_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict)
1082
{
1083
	fz_error error;
1084
	char *subtype;
1085
	fz_obj *dfonts;
1086
	fz_obj *charprocs;
1087
 
1088
	if ((*fontdescp = pdf_find_item(xref->store, pdf_drop_font, dict)))
1089
	{
1090
		pdf_keep_font(*fontdescp);
1091
		return fz_okay;
1092
	}
1093
 
1094
	subtype = fz_to_name(fz_dict_gets(dict, "Subtype"));
1095
	dfonts = fz_dict_gets(dict, "DescendantFonts");
1096
	charprocs = fz_dict_gets(dict, "CharProcs");
1097
 
1098
	if (subtype && !strcmp(subtype, "Type0"))
1099
		error = pdf_load_type0_font(fontdescp, xref, dict);
1100
	else if (subtype && !strcmp(subtype, "Type1"))
1101
		error = pdf_load_simple_font(fontdescp, xref, dict);
1102
	else if (subtype && !strcmp(subtype, "MMType1"))
1103
		error = pdf_load_simple_font(fontdescp, xref, dict);
1104
	else if (subtype && !strcmp(subtype, "TrueType"))
1105
		error = pdf_load_simple_font(fontdescp, xref, dict);
1106
	else if (subtype && !strcmp(subtype, "Type3"))
1107
		error = pdf_load_type3_font(fontdescp, xref, rdb, dict);
1108
	else if (charprocs)
1109
	{
1110
		fz_warn("unknown font format, guessing type3.");
1111
		error = pdf_load_type3_font(fontdescp, xref, rdb, dict);
1112
	}
1113
	else if (dfonts)
1114
	{
1115
		fz_warn("unknown font format, guessing type0.");
1116
		error = pdf_load_type0_font(fontdescp, xref, dict);
1117
	}
1118
	else
1119
	{
1120
		fz_warn("unknown font format, guessing type1 or truetype.");
1121
		error = pdf_load_simple_font(fontdescp, xref, dict);
1122
	}
1123
	if (error)
1124
		return fz_rethrow(error, "cannot load font (%d %d R)", fz_to_num(dict), fz_to_gen(dict));
1125
 
1126
	/* Save the widths to stretch non-CJK substitute fonts */
1127
	if ((*fontdescp)->font->ft_substitute && !(*fontdescp)->to_ttf_cmap)
1128
		pdf_make_width_table(*fontdescp);
1129
 
1130
	pdf_store_item(xref->store, pdf_keep_font, pdf_drop_font, dict, *fontdescp);
1131
 
1132
	return fz_okay;
1133
}
1134
 
1135
void
1136
pdf_debug_font(pdf_font_desc *fontdesc)
1137
{
1138
	int i;
1139
 
1140
	printf("fontdesc {\n");
1141
 
1142
	if (fontdesc->font->ft_face)
1143
		printf("\tfreetype font\n");
1144
	if (fontdesc->font->t3procs)
1145
		printf("\ttype3 font\n");
1146
 
1147
	printf("\twmode %d\n", fontdesc->wmode);
1148
	printf("\tDW %d\n", fontdesc->dhmtx.w);
1149
 
1150
	printf("\tW {\n");
1151
	for (i = 0; i < fontdesc->hmtx_len; i++)
1152
		printf("\t\t<%04x> <%04x> %d\n",
1153
			fontdesc->hmtx[i].lo, fontdesc->hmtx[i].hi, fontdesc->hmtx[i].w);
1154
	printf("\t}\n");
1155
 
1156
	if (fontdesc->wmode)
1157
	{
1158
		printf("\tDW2 [%d %d]\n", fontdesc->dvmtx.y, fontdesc->dvmtx.w);
1159
		printf("\tW2 {\n");
1160
		for (i = 0; i < fontdesc->vmtx_len; i++)
1161
			printf("\t\t<%04x> <%04x> %d %d %d\n", fontdesc->vmtx[i].lo, fontdesc->vmtx[i].hi,
1162
				fontdesc->vmtx[i].x, fontdesc->vmtx[i].y, fontdesc->vmtx[i].w);
1163
		printf("\t}\n");
1164
	}
1165
}