1 #include "mupdf/fitz.h"
2 #include "mupdf/ucdn.h"
3 
4 #include "draw-imp.h"
5 #include "color-imp.h"
6 #include "glyph-imp.h"
7 #include "pixmap-imp.h"
8 
9 #include <ft2build.h>
10 #include "hb.h"
11 #include "hb-ft.h"
12 
13 #include <assert.h>
14 
15 #include FT_FREETYPE_H
16 #include FT_ADVANCES_H
17 #include FT_MODULE_H
18 #include FT_STROKER_H
19 #include FT_SYSTEM_H
20 #include FT_TRUETYPE_TABLES_H
21 #include FT_TRUETYPE_TAGS_H
22 
23 #define MAX_BBOX_TABLE_SIZE 4096
24 #define MAX_ADVANCE_CACHE 4096
25 
26 #ifndef FT_SFNT_OS2
27 #define FT_SFNT_OS2 ft_sfnt_os2
28 #endif
29 
30 /* 20 degrees */
31 #define SHEAR 0.36397f
32 
ft_char_index(void * face,int cid)33 int ft_char_index(void *face, int cid)
34 {
35 	int gid = FT_Get_Char_Index(face, cid);
36 	if (gid == 0)
37 		gid = FT_Get_Char_Index(face, 0xf000 + cid);
38 
39 	/* some chinese fonts only ship the similarly looking 0x2026 */
40 	if (gid == 0 && cid == 0x22ef)
41 		gid = FT_Get_Char_Index(face, 0x2026);
42 
43 	return gid;
44 }
45 
ft_name_index(void * face,const char * name)46 int ft_name_index(void *face, const char *name)
47 {
48 	int code = FT_Get_Name_Index(face, (char*)name);
49 	if (code == 0)
50 	{
51 		int unicode = fz_unicode_from_glyph_name(name);
52 		if (unicode)
53 		{
54 			const char **dupnames = fz_duplicate_glyph_names_from_unicode(unicode);
55 			while (*dupnames)
56 			{
57 				code = FT_Get_Name_Index(face, (char*)*dupnames);
58 				if (code)
59 					break;
60 				dupnames++;
61 			}
62 			if (code == 0)
63 			{
64 				char buf[10];
65 				sprintf(buf, "uni%04X", unicode);
66 				code = FT_Get_Name_Index(face, buf);
67 			}
68 		}
69 	}
70 	return code;
71 }
72 
73 static void fz_drop_freetype(fz_context *ctx);
74 
75 static fz_font *
fz_new_font(fz_context * ctx,const char * name,int use_glyph_bbox,int glyph_count)76 fz_new_font(fz_context *ctx, const char *name, int use_glyph_bbox, int glyph_count)
77 {
78 	fz_font *font;
79 	int i;
80 
81 	font = fz_malloc_struct(ctx, fz_font);
82 	font->refs = 1;
83 
84 	if (name)
85 		fz_strlcpy(font->name, name, sizeof font->name);
86 	else
87 		fz_strlcpy(font->name, "(null)", sizeof font->name);
88 
89 	font->ft_face = NULL;
90 	font->flags.ft_substitute = 0;
91 	font->flags.fake_bold = 0;
92 	font->flags.fake_italic = 0;
93 	font->flags.has_opentype = 0;
94 
95 	font->t3matrix = fz_identity;
96 	font->t3resources = NULL;
97 	font->t3procs = NULL;
98 	font->t3lists = NULL;
99 	font->t3widths = NULL;
100 	font->t3flags = NULL;
101 	font->t3doc = NULL;
102 	font->t3run = NULL;
103 
104 	font->bbox.x0 = 0;
105 	font->bbox.y0 = 0;
106 	font->bbox.x1 = 1;
107 	font->bbox.y1 = 1;
108 
109 	font->glyph_count = glyph_count;
110 
111 	if (use_glyph_bbox && glyph_count <= MAX_BBOX_TABLE_SIZE)
112 	{
113 		fz_try(ctx)
114 			font->bbox_table = Memento_label(fz_malloc_array(ctx, glyph_count, fz_rect), "font_bbox_table");
115 		fz_catch(ctx)
116 		{
117 			fz_free(ctx, font);
118 			fz_rethrow(ctx);
119 		}
120 		for (i = 0; i < glyph_count; i++)
121 			font->bbox_table[i] = fz_infinite_rect;
122 	}
123 	else
124 	{
125 		font->bbox_table = NULL;
126 	}
127 
128 	font->width_count = 0;
129 	font->width_table = NULL;
130 
131 	return font;
132 }
133 
134 fz_font *
fz_keep_font(fz_context * ctx,fz_font * font)135 fz_keep_font(fz_context *ctx, fz_font *font)
136 {
137 	return fz_keep_imp(ctx, font, &font->refs);
138 }
139 
140 static void
free_resources(fz_context * ctx,fz_font * font)141 free_resources(fz_context *ctx, fz_font *font)
142 {
143 	int i;
144 
145 	if (font->t3resources)
146 	{
147 		font->t3freeres(ctx, font->t3doc, font->t3resources);
148 		font->t3resources = NULL;
149 	}
150 
151 	if (font->t3procs)
152 	{
153 		for (i = 0; i < 256; i++)
154 			fz_drop_buffer(ctx, font->t3procs[i]);
155 	}
156 	fz_free(ctx, font->t3procs);
157 	font->t3procs = NULL;
158 }
159 
160 /*
161 	Internal function to remove the
162 	references to a document held by a Type3 font. This is
163 	called during document destruction to ensure that Type3
164 	fonts clean up properly.
165 
166 	Without this call being made, Type3 fonts can be left
167 	holding pdf_obj references for the sake of interpretation
168 	operations that will never come. These references
169 	cannot be freed after the document, hence this function
170 	forces them to be freed earlier in the process.
171 
172 	font: The font to decouple.
173 
174 	t3doc: The document to which the font may refer.
175 */
fz_decouple_type3_font(fz_context * ctx,fz_font * font,void * t3doc)176 void fz_decouple_type3_font(fz_context *ctx, fz_font *font, void *t3doc)
177 {
178 	if (!font || !t3doc || font->t3doc == NULL)
179 		return;
180 
181 	if (font->t3doc != t3doc)
182 		fz_throw(ctx, FZ_ERROR_GENERIC, "can't decouple type3 font from a different doc");
183 
184 	font->t3doc = NULL;
185 	free_resources(ctx, font);
186 }
187 
188 void
fz_drop_font(fz_context * ctx,fz_font * font)189 fz_drop_font(fz_context *ctx, fz_font *font)
190 {
191 	int fterr;
192 	int i;
193 
194 	if (!fz_drop_imp(ctx, font, &font->refs))
195 		return;
196 
197 	free_resources(ctx, font);
198 	if (font->t3lists)
199 		for (i = 0; i < 256; i++)
200 			fz_drop_display_list(ctx, font->t3lists[i]);
201 	fz_free(ctx, font->t3procs);
202 	fz_free(ctx, font->t3lists);
203 	fz_free(ctx, font->t3widths);
204 	fz_free(ctx, font->t3flags);
205 
206 	if (font->ft_face)
207 	{
208 		fz_lock(ctx, FZ_LOCK_FREETYPE);
209 		fterr = FT_Done_Face((FT_Face)font->ft_face);
210 		fz_unlock(ctx, FZ_LOCK_FREETYPE);
211 		if (fterr)
212 			fz_warn(ctx, "FT_Done_Face(%s): %s", font->name, ft_error_string(fterr));
213 		fz_drop_freetype(ctx);
214 	}
215 
216 	for (i = 0; i < 256; ++i)
217 		fz_free(ctx, font->encoding_cache[i]);
218 
219 	fz_drop_buffer(ctx, font->buffer);
220 	fz_free(ctx, font->bbox_table);
221 	fz_free(ctx, font->width_table);
222 	fz_free(ctx, font->advance_cache);
223 	if (font->shaper_data.destroy && font->shaper_data.shaper_handle)
224 	{
225 		font->shaper_data.destroy(ctx, font->shaper_data.shaper_handle);
226 	}
227 	fz_free(ctx, font);
228 }
229 
230 void
fz_set_font_bbox(fz_context * ctx,fz_font * font,float xmin,float ymin,float xmax,float ymax)231 fz_set_font_bbox(fz_context *ctx, fz_font *font, float xmin, float ymin, float xmax, float ymax)
232 {
233 	if (xmin >= xmax || ymin >= ymax)
234 	{
235 		/* Invalid bbox supplied. */
236 		if (font->t3procs)
237 		{
238 			/* For type3 fonts we use the union of all the glyphs' bboxes. */
239 			font->bbox = fz_empty_rect;
240 		}
241 		else
242 		{
243 			/* For other fonts it would be prohibitively slow to measure the true one, so make one up. */
244 			font->bbox = fz_unit_rect;
245 		}
246 		font->flags.invalid_bbox = 1;
247 	}
248 	else
249 	{
250 		font->bbox.x0 = xmin;
251 		font->bbox.y0 = ymin;
252 		font->bbox.x1 = xmax;
253 		font->bbox.y1 = ymax;
254 	}
255 }
256 
fz_font_ascender(fz_context * ctx,fz_font * font)257 float fz_font_ascender(fz_context *ctx, fz_font *font)
258 {
259 	if (font->t3procs)
260 		return font->bbox.y1;
261 	else
262 	{
263 		FT_Face face = font->ft_face;
264 		if (face->ascender == 0)
265 			return 0.8f;
266 		return (float)face->ascender / face->units_per_EM;
267 	}
268 }
269 
fz_font_descender(fz_context * ctx,fz_font * font)270 float fz_font_descender(fz_context *ctx, fz_font *font)
271 {
272 	if (font->t3procs)
273 		return font->bbox.y0;
274 	else
275 	{
276 		FT_Face face = font->ft_face;
277 		if (face->descender == 0)
278 			return -0.2f;
279 		return (float)face->descender / face->units_per_EM;
280 	}
281 }
282 
283 /*
284  * Freetype hooks
285  */
286 
287 struct fz_font_context
288 {
289 	int ctx_refs;
290 	FT_Library ftlib;
291 	struct FT_MemoryRec_ ftmemory;
292 	int ftlib_refs;
293 	fz_load_system_font_fn *load_font;
294 	fz_load_system_cjk_font_fn *load_cjk_font;
295 	fz_load_system_fallback_font_fn *load_fallback_font;
296 
297 	/* Cached fallback fonts */
298 	fz_font *base14[14];
299 	fz_font *cjk[4];
300 	struct { fz_font *serif, *sans; } fallback[256];
301 	fz_font *symbol1, *symbol2, *math, *music;
302 	fz_font *emoji;
303 };
304 
305 #undef __FTERRORS_H__
306 #define FT_ERRORDEF(e, v, s) { (e), (s) },
307 #define FT_ERROR_START_LIST
308 #define FT_ERROR_END_LIST { 0, NULL }
309 
310 struct ft_error
311 {
312 	int err;
313 	char *str;
314 };
315 
ft_alloc(FT_Memory memory,long size)316 static void *ft_alloc(FT_Memory memory, long size)
317 {
318 	fz_context *ctx = (fz_context *) memory->user;
319 	return Memento_label(fz_malloc_no_throw(ctx, size), "ft_alloc");
320 }
321 
ft_free(FT_Memory memory,void * block)322 static void ft_free(FT_Memory memory, void *block)
323 {
324 	fz_context *ctx = (fz_context *) memory->user;
325 	fz_free(ctx, block);
326 }
327 
ft_realloc(FT_Memory memory,long cur_size,long new_size,void * block)328 static void *ft_realloc(FT_Memory memory, long cur_size, long new_size, void *block)
329 {
330 	fz_context *ctx = (fz_context *) memory->user;
331 	void *newblock = NULL;
332 	if (new_size == 0)
333 	{
334 		fz_free(ctx, block);
335 		return newblock;
336 	}
337 	if (block == NULL)
338 		return ft_alloc(memory, new_size);
339 	return fz_realloc_no_throw(ctx, block, new_size);
340 }
341 
fz_new_font_context(fz_context * ctx)342 void fz_new_font_context(fz_context *ctx)
343 {
344 	ctx->font = fz_malloc_struct(ctx, fz_font_context);
345 	ctx->font->ctx_refs = 1;
346 	ctx->font->ftlib = NULL;
347 	ctx->font->ftlib_refs = 0;
348 	ctx->font->load_font = NULL;
349 	ctx->font->ftmemory.user = ctx;
350 	ctx->font->ftmemory.alloc = ft_alloc;
351 	ctx->font->ftmemory.free = ft_free;
352 	ctx->font->ftmemory.realloc = ft_realloc;
353 }
354 
355 fz_font_context *
fz_keep_font_context(fz_context * ctx)356 fz_keep_font_context(fz_context *ctx)
357 {
358 	if (!ctx)
359 		return NULL;
360 	return fz_keep_imp(ctx, ctx->font, &ctx->font->ctx_refs);
361 }
362 
fz_drop_font_context(fz_context * ctx)363 void fz_drop_font_context(fz_context *ctx)
364 {
365 	if (!ctx)
366 		return;
367 
368 	if (fz_drop_imp(ctx, ctx->font, &ctx->font->ctx_refs))
369 	{
370 		int i;
371 
372 		for (i = 0; i < (int)nelem(ctx->font->base14); ++i)
373 			fz_drop_font(ctx, ctx->font->base14[i]);
374 		for (i = 0; i < (int)nelem(ctx->font->cjk); ++i)
375 			fz_drop_font(ctx, ctx->font->cjk[i]);
376 		for (i = 0; i < (int)nelem(ctx->font->fallback); ++i)
377 		{
378 			fz_drop_font(ctx, ctx->font->fallback[i].serif);
379 			fz_drop_font(ctx, ctx->font->fallback[i].sans);
380 		}
381 		fz_drop_font(ctx, ctx->font->symbol1);
382 		fz_drop_font(ctx, ctx->font->symbol2);
383 		fz_drop_font(ctx, ctx->font->math);
384 		fz_drop_font(ctx, ctx->font->music);
385 		fz_drop_font(ctx, ctx->font->emoji);
386 		fz_free(ctx, ctx->font);
387 		ctx->font = NULL;
388 	}
389 }
390 
fz_install_load_system_font_funcs(fz_context * ctx,fz_load_system_font_fn * f,fz_load_system_cjk_font_fn * f_cjk,fz_load_system_fallback_font_fn * f_back)391 void fz_install_load_system_font_funcs(fz_context *ctx,
392 		fz_load_system_font_fn *f,
393 		fz_load_system_cjk_font_fn *f_cjk,
394 		fz_load_system_fallback_font_fn *f_back)
395 {
396 	ctx->font->load_font = f;
397 	ctx->font->load_cjk_font = f_cjk;
398 	ctx->font->load_fallback_font = f_back;
399 }
400 
401 /* fz_load_*_font returns NULL if no font could be loaded (also on error) */
fz_load_system_font(fz_context * ctx,const char * name,int bold,int italic,int needs_exact_metrics)402 fz_font *fz_load_system_font(fz_context *ctx, const char *name, int bold, int italic, int needs_exact_metrics)
403 {
404 	fz_font *font = NULL;
405 
406 	if (ctx->font->load_font)
407 	{
408 		fz_try(ctx)
409 			font = ctx->font->load_font(ctx, name, bold, italic, needs_exact_metrics);
410 		fz_catch(ctx)
411 			font = NULL;
412 	}
413 
414 	return font;
415 }
416 
fz_load_system_cjk_font(fz_context * ctx,const char * name,int ros,int serif)417 fz_font *fz_load_system_cjk_font(fz_context *ctx, const char *name, int ros, int serif)
418 {
419 	fz_font *font = NULL;
420 
421 	if (ctx->font->load_cjk_font)
422 	{
423 		fz_try(ctx)
424 			font = ctx->font->load_cjk_font(ctx, name, ros, serif);
425 		fz_catch(ctx)
426 			font = NULL;
427 	}
428 
429 	return font;
430 }
431 
fz_load_system_fallback_font(fz_context * ctx,int script,int language,int serif,int bold,int italic)432 fz_font *fz_load_system_fallback_font(fz_context *ctx, int script, int language, int serif, int bold, int italic)
433 {
434 	fz_font *font = NULL;
435 
436 	if (ctx->font->load_fallback_font)
437 	{
438 		fz_try(ctx)
439 			font = ctx->font->load_fallback_font(ctx, script, language, serif, bold, italic);
440 		fz_catch(ctx)
441 			font = NULL;
442 	}
443 
444 	return font;
445 }
446 
fz_load_fallback_font(fz_context * ctx,int script,int language,int serif,int bold,int italic)447 fz_font *fz_load_fallback_font(fz_context *ctx, int script, int language, int serif, int bold, int italic)
448 {
449 	fz_font **fontp;
450 	const unsigned char *data;
451 	int index;
452 	int subfont;
453 	int size;
454 
455 	if (script < 0 || script >= (int)nelem(ctx->font->fallback))
456 		return NULL;
457 
458 	/* TODO: bold and italic */
459 
460 	index = script;
461 	if (script == UCDN_SCRIPT_HAN)
462 	{
463 		switch (language)
464 		{
465 		case FZ_LANG_ja: index = UCDN_LAST_SCRIPT + 1; break;
466 		case FZ_LANG_ko: index = UCDN_LAST_SCRIPT + 2; break;
467 		case FZ_LANG_zh_Hans: index = UCDN_LAST_SCRIPT + 3; break;
468 		case FZ_LANG_zh_Hant: index = UCDN_LAST_SCRIPT + 4; break;
469 		}
470 	}
471 	if (script == UCDN_SCRIPT_ARABIC)
472 	{
473 		if (language == FZ_LANG_ur || language == FZ_LANG_urd)
474 			index = UCDN_LAST_SCRIPT + 5;
475 	}
476 
477 	if (serif)
478 		fontp = &ctx->font->fallback[index].serif;
479 	else
480 		fontp = &ctx->font->fallback[index].sans;
481 
482 	if (!*fontp)
483 	{
484 		*fontp = fz_load_system_fallback_font(ctx, script, language, serif, bold, italic);
485 		if (!*fontp)
486 		{
487 			data = fz_lookup_noto_font(ctx, script, language, &size, &subfont);
488 			if (data)
489 				*fontp = fz_new_font_from_memory(ctx, NULL, data, size, subfont, 0);
490 		}
491 	}
492 
493 	return *fontp;
494 }
495 
fz_load_fallback_math_font(fz_context * ctx)496 static fz_font *fz_load_fallback_math_font(fz_context *ctx)
497 {
498 	const unsigned char *data;
499 	int size;
500 	if (!ctx->font->math)
501 	{
502 		data = fz_lookup_noto_math_font(ctx, &size);
503 		if (data)
504 			ctx->font->math = fz_new_font_from_memory(ctx, NULL, data, size, 0, 0);
505 	}
506 	return ctx->font->math;
507 }
508 
fz_load_fallback_music_font(fz_context * ctx)509 static fz_font *fz_load_fallback_music_font(fz_context *ctx)
510 {
511 	const unsigned char *data;
512 	int size;
513 	if (!ctx->font->music)
514 	{
515 		data = fz_lookup_noto_music_font(ctx, &size);
516 		if (data)
517 			ctx->font->music = fz_new_font_from_memory(ctx, NULL, data, size, 0, 0);
518 	}
519 	return ctx->font->music;
520 }
521 
fz_load_fallback_symbol1_font(fz_context * ctx)522 static fz_font *fz_load_fallback_symbol1_font(fz_context *ctx)
523 {
524 	const unsigned char *data;
525 	int size;
526 	if (!ctx->font->symbol1)
527 	{
528 		data = fz_lookup_noto_symbol1_font(ctx, &size);
529 		if (data)
530 			ctx->font->symbol1 = fz_new_font_from_memory(ctx, NULL, data, size, 0, 0);
531 	}
532 	return ctx->font->symbol1;
533 }
534 
fz_load_fallback_symbol2_font(fz_context * ctx)535 static fz_font *fz_load_fallback_symbol2_font(fz_context *ctx)
536 {
537 	const unsigned char *data;
538 	int size;
539 	if (!ctx->font->symbol2)
540 	{
541 		data = fz_lookup_noto_symbol2_font(ctx, &size);
542 		if (data)
543 			ctx->font->symbol2 = fz_new_font_from_memory(ctx, NULL, data, size, 0, 0);
544 	}
545 	return ctx->font->symbol2;
546 }
547 
fz_load_fallback_emoji_font(fz_context * ctx)548 static fz_font *fz_load_fallback_emoji_font(fz_context *ctx)
549 {
550 	const unsigned char *data;
551 	int size;
552 	if (!ctx->font->emoji)
553 	{
554 		data = fz_lookup_noto_emoji_font(ctx, &size);
555 		if (data)
556 			ctx->font->emoji = fz_new_font_from_memory(ctx, NULL, data, size, 0, 0);
557 	}
558 	return ctx->font->emoji;
559 }
560 
561 static const struct ft_error ft_errors[] =
562 {
563 #include FT_ERRORS_H
564 };
565 
ft_error_string(int err)566 const char *ft_error_string(int err)
567 {
568 	const struct ft_error *e;
569 
570 	for (e = ft_errors; e->str; e++)
571 		if (e->err == err)
572 			return e->str;
573 
574 	return "Unknown error";
575 }
576 
577 static void
fz_keep_freetype(fz_context * ctx)578 fz_keep_freetype(fz_context *ctx)
579 {
580 	int fterr;
581 	int maj, min, pat;
582 	fz_font_context *fct = ctx->font;
583 
584 	fz_lock(ctx, FZ_LOCK_FREETYPE);
585 	if (fct->ftlib)
586 	{
587 		fct->ftlib_refs++;
588 		fz_unlock(ctx, FZ_LOCK_FREETYPE);
589 		return;
590 	}
591 
592 	fterr = FT_New_Library(&fct->ftmemory, &fct->ftlib);
593 	if (fterr)
594 	{
595 		const char *mess = ft_error_string(fterr);
596 		fz_unlock(ctx, FZ_LOCK_FREETYPE);
597 		fz_throw(ctx, FZ_ERROR_GENERIC, "cannot init freetype: %s", mess);
598 	}
599 
600 	FT_Add_Default_Modules(fct->ftlib);
601 
602 	FT_Library_Version(fct->ftlib, &maj, &min, &pat);
603 	if (maj == 2 && min == 1 && pat < 7)
604 	{
605 		fterr = FT_Done_Library(fct->ftlib);
606 		if (fterr)
607 			fz_warn(ctx, "FT_Done_Library(): %s", ft_error_string(fterr));
608 		fz_unlock(ctx, FZ_LOCK_FREETYPE);
609 		fz_throw(ctx, FZ_ERROR_GENERIC, "freetype version too old: %d.%d.%d", maj, min, pat);
610 	}
611 
612 	fct->ftlib_refs++;
613 	fz_unlock(ctx, FZ_LOCK_FREETYPE);
614 }
615 
616 static void
fz_drop_freetype(fz_context * ctx)617 fz_drop_freetype(fz_context *ctx)
618 {
619 	int fterr;
620 	fz_font_context *fct = ctx->font;
621 
622 	fz_lock(ctx, FZ_LOCK_FREETYPE);
623 	if (--fct->ftlib_refs == 0)
624 	{
625 		fterr = FT_Done_Library(fct->ftlib);
626 		if (fterr)
627 			fz_warn(ctx, "FT_Done_Library(): %s", ft_error_string(fterr));
628 		fct->ftlib = NULL;
629 	}
630 	fz_unlock(ctx, FZ_LOCK_FREETYPE);
631 }
632 
633 fz_font *
fz_new_font_from_buffer(fz_context * ctx,const char * name,fz_buffer * buffer,int index,int use_glyph_bbox)634 fz_new_font_from_buffer(fz_context *ctx, const char *name, fz_buffer *buffer, int index, int use_glyph_bbox)
635 {
636 	FT_Face face;
637 	TT_OS2 *os2;
638 	fz_font *font;
639 	int fterr;
640 	FT_ULong tag, size, i, n;
641 	char namebuf[sizeof(font->name)];
642 
643 	fz_keep_freetype(ctx);
644 
645 	fz_lock(ctx, FZ_LOCK_FREETYPE);
646 	fterr = FT_New_Memory_Face(ctx->font->ftlib, buffer->data, (FT_Long)buffer->len, index, &face);
647 	fz_unlock(ctx, FZ_LOCK_FREETYPE);
648 	if (fterr)
649 	{
650 		fz_drop_freetype(ctx);
651 		fz_throw(ctx, FZ_ERROR_GENERIC, "FT_New_Memory_Face(%s): %s", name, ft_error_string(fterr));
652 	}
653 
654 	if (!name)
655 	{
656 		if (!face->family_name)
657 		{
658 			name = face->style_name;
659 		}
660 		else if (!face->style_name)
661 		{
662 			name = face->family_name;
663 		}
664 		else if (strstr(face->style_name, face->family_name) == face->style_name)
665 		{
666 			name = face->style_name;
667 		}
668 		else
669 		{
670 			fz_strlcpy(namebuf, face->family_name, sizeof(namebuf));
671 			fz_strlcat(namebuf, " ", sizeof(namebuf));
672 			fz_strlcat(namebuf, face->style_name, sizeof(namebuf));
673 			name = namebuf;
674 		}
675 	}
676 
677 	fz_try(ctx)
678 		font = fz_new_font(ctx, name, use_glyph_bbox, face->num_glyphs);
679 	fz_catch(ctx)
680 	{
681 		fz_lock(ctx, FZ_LOCK_FREETYPE);
682 		fterr = FT_Done_Face(face);
683 		fz_unlock(ctx, FZ_LOCK_FREETYPE);
684 		if (fterr)
685 			fz_warn(ctx, "FT_Done_Face(%s): %s", name, ft_error_string(fterr));
686 		fz_drop_freetype(ctx);
687 		fz_rethrow(ctx);
688 	}
689 
690 	font->ft_face = face;
691 	fz_set_font_bbox(ctx, font,
692 		(float) face->bbox.xMin / face->units_per_EM,
693 		(float) face->bbox.yMin / face->units_per_EM,
694 		(float) face->bbox.xMax / face->units_per_EM,
695 		(float) face->bbox.yMax / face->units_per_EM);
696 
697 	font->flags.is_mono = !!(face->face_flags & FT_FACE_FLAG_FIXED_WIDTH);
698 	font->flags.is_serif = 1;
699 	font->flags.is_bold = !!(face->style_flags & FT_STYLE_FLAG_BOLD);
700 	font->flags.is_italic = !!(face->style_flags & FT_STYLE_FLAG_ITALIC);
701 
702 	if (FT_IS_SFNT(face))
703 	{
704 		os2 = FT_Get_Sfnt_Table(face, FT_SFNT_OS2);
705 		if (os2)
706 			font->flags.is_serif = !(os2->sFamilyClass & 2048); /* Class 8 is sans-serif */
707 
708 		FT_Sfnt_Table_Info(face, 0, NULL, &n);
709 		for (i = 0; i < n; ++i)
710 		{
711 			FT_Sfnt_Table_Info(face, i, &tag, &size);
712 			if (tag == TTAG_GDEF || tag == TTAG_GPOS || tag == TTAG_GSUB)
713 				font->flags.has_opentype = 1;
714 		}
715 	}
716 
717 	if (name)
718 	{
719 		if (!font->flags.is_bold)
720 		{
721 			if (strstr(name, "Semibold")) font->flags.is_bold = 1;
722 			if (strstr(name, "Bold")) font->flags.is_bold = 1;
723 		}
724 		if (!font->flags.is_italic)
725 		{
726 			if (strstr(name, "Italic")) font->flags.is_italic = 1;
727 			if (strstr(name, "Oblique")) font->flags.is_italic = 1;
728 		}
729 	}
730 
731 	font->buffer = fz_keep_buffer(ctx, buffer);
732 
733 	return font;
734 }
735 
736 fz_font *
fz_new_font_from_memory(fz_context * ctx,const char * name,const unsigned char * data,int len,int index,int use_glyph_bbox)737 fz_new_font_from_memory(fz_context *ctx, const char *name, const unsigned char *data, int len, int index, int use_glyph_bbox)
738 {
739 	fz_buffer *buffer = fz_new_buffer_from_shared_data(ctx, data, len);
740 	fz_font *font = NULL;
741 	fz_try(ctx)
742 		font = fz_new_font_from_buffer(ctx, name, buffer, index, use_glyph_bbox);
743 	fz_always(ctx)
744 		fz_drop_buffer(ctx, buffer);
745 	fz_catch(ctx)
746 		fz_rethrow(ctx);
747 	return font;
748 }
749 
750 fz_font *
fz_new_font_from_file(fz_context * ctx,const char * name,const char * path,int index,int use_glyph_bbox)751 fz_new_font_from_file(fz_context *ctx, const char *name, const char *path, int index, int use_glyph_bbox)
752 {
753 	fz_buffer *buffer = fz_read_file(ctx, path);
754 	fz_font *font = NULL;
755 	fz_try(ctx)
756 		font = fz_new_font_from_buffer(ctx, name, buffer, index, use_glyph_bbox);
757 	fz_always(ctx)
758 		fz_drop_buffer(ctx, buffer);
759 	fz_catch(ctx)
760 		fz_rethrow(ctx);
761 	return font;
762 }
763 
764 static int
find_base14_index(const char * name)765 find_base14_index(const char *name)
766 {
767 	if (!strcmp(name, "Courier")) return 0;
768 	if (!strcmp(name, "Courier-Oblique")) return 1;
769 	if (!strcmp(name, "Courier-Bold")) return 2;
770 	if (!strcmp(name, "Courier-BoldOblique")) return 3;
771 	if (!strcmp(name, "Helvetica")) return 4;
772 	if (!strcmp(name, "Helvetica-Oblique")) return 5;
773 	if (!strcmp(name, "Helvetica-Bold")) return 6;
774 	if (!strcmp(name, "Helvetica-BoldOblique")) return 7;
775 	if (!strcmp(name, "Times-Roman")) return 8;
776 	if (!strcmp(name, "Times-Italic")) return 9;
777 	if (!strcmp(name, "Times-Bold")) return 10;
778 	if (!strcmp(name, "Times-BoldItalic")) return 11;
779 	if (!strcmp(name, "Symbol")) return 12;
780 	if (!strcmp(name, "ZapfDingbats")) return 13;
781 	return -1;
782 }
783 
784 fz_font *
fz_new_base14_font(fz_context * ctx,const char * name)785 fz_new_base14_font(fz_context *ctx, const char *name)
786 {
787 	const unsigned char *data;
788 	int size;
789 	int x = find_base14_index(name);
790 	if (x >= 0)
791 	{
792 		if (ctx->font->base14[x])
793 			return fz_keep_font(ctx, ctx->font->base14[x]);
794 		data = fz_lookup_base14_font(ctx, name, &size);
795 		if (data)
796 		{
797 			ctx->font->base14[x] = fz_new_font_from_memory(ctx, name, data, size, 0, 1);
798 			ctx->font->base14[x]->flags.is_serif = (name[0] == 'T'); /* Times-Roman */
799 			return fz_keep_font(ctx, ctx->font->base14[x]);
800 		}
801 	}
802 	fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find builtin font with name '%s'", name);
803 }
804 
805 fz_font *
fz_new_cjk_font(fz_context * ctx,int ordering)806 fz_new_cjk_font(fz_context *ctx, int ordering)
807 {
808 	const unsigned char *data;
809 	int size, index;
810 	if (ordering >= 0 && ordering < (int)nelem(ctx->font->cjk))
811 	{
812 		if (ctx->font->cjk[ordering])
813 			return fz_keep_font(ctx, ctx->font->cjk[ordering]);
814 		data = fz_lookup_cjk_font(ctx, ordering, &size, &index);
815 		if (data)
816 		{
817 			ctx->font->cjk[ordering] = fz_new_font_from_memory(ctx, NULL, data, size, index, 0);
818 			return fz_keep_font(ctx, ctx->font->cjk[ordering]);
819 		}
820 	}
821 	fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find builtin CJK font");
822 }
823 
824 fz_font *
fz_new_builtin_font(fz_context * ctx,const char * name,int is_bold,int is_italic)825 fz_new_builtin_font(fz_context *ctx, const char *name, int is_bold, int is_italic)
826 {
827 	const unsigned char *data;
828 	int size;
829 	data = fz_lookup_builtin_font(ctx, name, is_bold, is_italic, &size);
830 	if (!data)
831 		fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find builtin font with name '%s'", name);
832 	return fz_new_font_from_memory(ctx, NULL, data, size, 0, 0);
833 }
834 
835 static fz_matrix *
fz_adjust_ft_glyph_width(fz_context * ctx,fz_font * font,int gid,fz_matrix * trm)836 fz_adjust_ft_glyph_width(fz_context *ctx, fz_font *font, int gid, fz_matrix *trm)
837 {
838 	/* Fudge the font matrix to stretch the glyph if we've substituted the font. */
839 	if (font->flags.ft_stretch && font->width_table /* && font->wmode == 0 */)
840 	{
841 		FT_Error fterr;
842 		FT_Fixed adv = 0;
843 		float subw;
844 		float realw;
845 
846 		fz_lock(ctx, FZ_LOCK_FREETYPE);
847 		fterr = FT_Get_Advance(font->ft_face, gid, FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING | FT_LOAD_IGNORE_TRANSFORM, &adv);
848 		fz_unlock(ctx, FZ_LOCK_FREETYPE);
849 		if (fterr && fterr != FT_Err_Invalid_Argument)
850 			fz_warn(ctx, "FT_Get_Advance(%s,%d): %s", font->name, gid, ft_error_string(fterr));
851 
852 		realw = adv * 1000.0f / ((FT_Face)font->ft_face)->units_per_EM;
853 		if (gid < font->width_count)
854 			subw = font->width_table[gid];
855 		else
856 			subw = font->width_default;
857 
858 		/* Sanity check scaling in case of broken metrics. */
859 		if (realw > 0 && subw > 0)
860 			*trm = fz_pre_scale(*trm, subw / realw, 1);
861 	}
862 
863 	return trm;
864 }
865 
866 static fz_glyph *
glyph_from_ft_bitmap(fz_context * ctx,int left,int top,FT_Bitmap * bitmap)867 glyph_from_ft_bitmap(fz_context *ctx, int left, int top, FT_Bitmap *bitmap)
868 {
869 	(void)Memento_label(bitmap->buffer, "ft_bitmap");
870 	if (bitmap->pixel_mode == FT_PIXEL_MODE_MONO)
871 		return fz_new_glyph_from_1bpp_data(ctx, left, top - bitmap->rows, bitmap->width, bitmap->rows, bitmap->buffer + (bitmap->rows-1)*bitmap->pitch, -bitmap->pitch);
872 	else
873 		return fz_new_glyph_from_8bpp_data(ctx, left, top - bitmap->rows, bitmap->width, bitmap->rows, bitmap->buffer + (bitmap->rows-1)*bitmap->pitch, -bitmap->pitch);
874 }
875 
876 static fz_pixmap *
pixmap_from_ft_bitmap(fz_context * ctx,int left,int top,FT_Bitmap * bitmap)877 pixmap_from_ft_bitmap(fz_context *ctx, int left, int top, FT_Bitmap *bitmap)
878 {
879 	(void)Memento_label(bitmap->buffer, "ft_bitmap");
880 	if (bitmap->pixel_mode == FT_PIXEL_MODE_MONO)
881 		return fz_new_pixmap_from_1bpp_data(ctx, left, top - bitmap->rows, bitmap->width, bitmap->rows, bitmap->buffer + (bitmap->rows-1)*bitmap->pitch, -bitmap->pitch);
882 	else
883 		return fz_new_pixmap_from_8bpp_data(ctx, left, top - bitmap->rows, bitmap->width, bitmap->rows, bitmap->buffer + (bitmap->rows-1)*bitmap->pitch, -bitmap->pitch);
884 }
885 
886 /* Takes the freetype lock, and returns with it held */
887 static FT_GlyphSlot
do_ft_render_glyph(fz_context * ctx,fz_font * font,int gid,fz_matrix trm,int aa)888 do_ft_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, int aa)
889 {
890 	FT_Face face = font->ft_face;
891 	FT_Matrix m;
892 	FT_Vector v;
893 	FT_Error fterr;
894 
895 	float strength = fz_matrix_expansion(trm) * 0.02f;
896 
897 	fz_adjust_ft_glyph_width(ctx, font, gid, &trm);
898 
899 	if (font->flags.fake_italic)
900 		trm = fz_pre_shear(trm, SHEAR, 0);
901 
902 	fz_lock(ctx, FZ_LOCK_FREETYPE);
903 
904 	if (aa == 0)
905 	{
906 		/* enable grid fitting for non-antialiased rendering */
907 		float scale = fz_matrix_expansion(trm);
908 		m.xx = trm.a * 65536 / scale;
909 		m.yx = trm.b * 65536 / scale;
910 		m.xy = trm.c * 65536 / scale;
911 		m.yy = trm.d * 65536 / scale;
912 		v.x = 0;
913 		v.y = 0;
914 
915 		fterr = FT_Set_Char_Size(face, 64 * scale, 64 * scale, 72, 72);
916 		if (fterr)
917 			fz_warn(ctx, "FT_Set_Char_Size(%s,%d,72): %s", font->name, (int)(64*scale), ft_error_string(fterr));
918 		FT_Set_Transform(face, &m, &v);
919 		fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_TARGET_MONO);
920 		if (fterr)
921 		{
922 			fz_warn(ctx, "FT_Load_Glyph(%s,%d,FT_LOAD_TARGET_MONO): %s", font->name, gid, ft_error_string(fterr));
923 			goto retry_unhinted;
924 		}
925 	}
926 	else
927 	{
928 retry_unhinted:
929 		/*
930 		 * Freetype mutilates complex glyphs if they are loaded with
931 		 * FT_Set_Char_Size 1.0. It rounds the coordinates before applying
932 		 * transformation. To get more precision in freetype, we shift part of
933 		 * the scale in the matrix into FT_Set_Char_Size instead.
934 		 */
935 
936 		/* Check for overflow; FreeType matrices use 16.16 fixed-point numbers */
937 		if (trm.a < -512 || trm.a > 512) return NULL;
938 		if (trm.b < -512 || trm.b > 512) return NULL;
939 		if (trm.c < -512 || trm.c > 512) return NULL;
940 		if (trm.d < -512 || trm.d > 512) return NULL;
941 
942 		m.xx = trm.a * 64; /* should be 65536 */
943 		m.yx = trm.b * 64;
944 		m.xy = trm.c * 64;
945 		m.yy = trm.d * 64;
946 		v.x = trm.e * 64;
947 		v.y = trm.f * 64;
948 
949 		fterr = FT_Set_Char_Size(face, 65536, 65536, 72, 72); /* should be 64, 64 */
950 		if (fterr)
951 			fz_warn(ctx, "FT_Set_Char_Size(%s,65536,72): %s", font->name, ft_error_string(fterr));
952 		FT_Set_Transform(face, &m, &v);
953 		fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING);
954 		if (fterr)
955 		{
956 			fz_warn(ctx, "FT_Load_Glyph(%s,%d,FT_LOAD_NO_HINTING): %s", font->name, gid, ft_error_string(fterr));
957 			return NULL;
958 		}
959 	}
960 
961 	if (font->flags.fake_bold)
962 	{
963 		FT_Outline_Embolden(&face->glyph->outline, strength * 64);
964 		FT_Outline_Translate(&face->glyph->outline, -strength * 32, -strength * 32);
965 	}
966 
967 	fterr = FT_Render_Glyph(face->glyph, aa > 0 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
968 	if (fterr)
969 	{
970 		if (aa > 0)
971 			fz_warn(ctx, "FT_Render_Glyph(%s,%d,FT_RENDER_MODE_NORMAL): %s", font->name, gid, ft_error_string(fterr));
972 		else
973 			fz_warn(ctx, "FT_Render_Glyph(%s,%d,FT_RENDER_MODE_MONO): %s", font->name, gid, ft_error_string(fterr));
974 		return NULL;
975 	}
976 	return face->glyph;
977 }
978 
979 fz_pixmap *
fz_render_ft_glyph_pixmap(fz_context * ctx,fz_font * font,int gid,fz_matrix trm,int aa)980 fz_render_ft_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, int aa)
981 {
982 	FT_GlyphSlot slot = do_ft_render_glyph(ctx, font, gid, trm, aa);
983 	fz_pixmap *pixmap = NULL;
984 
985 	if (slot == NULL)
986 	{
987 		fz_unlock(ctx, FZ_LOCK_FREETYPE);
988 		return NULL;
989 	}
990 
991 	fz_try(ctx)
992 	{
993 		pixmap = pixmap_from_ft_bitmap(ctx, slot->bitmap_left, slot->bitmap_top, &slot->bitmap);
994 	}
995 	fz_always(ctx)
996 	{
997 		fz_unlock(ctx, FZ_LOCK_FREETYPE);
998 	}
999 	fz_catch(ctx)
1000 	{
1001 		fz_rethrow(ctx);
1002 	}
1003 
1004 	return pixmap;
1005 }
1006 
1007 /* The glyph cache lock is always taken when this is called. */
1008 fz_glyph *
fz_render_ft_glyph(fz_context * ctx,fz_font * font,int gid,fz_matrix trm,int aa)1009 fz_render_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, int aa)
1010 {
1011 	FT_GlyphSlot slot = do_ft_render_glyph(ctx, font, gid, trm, aa);
1012 	fz_glyph *glyph = NULL;
1013 
1014 	if (slot == NULL)
1015 	{
1016 		fz_unlock(ctx, FZ_LOCK_FREETYPE);
1017 		return NULL;
1018 	}
1019 
1020 	fz_try(ctx)
1021 	{
1022 		glyph = glyph_from_ft_bitmap(ctx, slot->bitmap_left, slot->bitmap_top, &slot->bitmap);
1023 	}
1024 	fz_always(ctx)
1025 	{
1026 		fz_unlock(ctx, FZ_LOCK_FREETYPE);
1027 	}
1028 	fz_catch(ctx)
1029 	{
1030 		fz_rethrow(ctx);
1031 	}
1032 
1033 	return glyph;
1034 }
1035 
1036 /* Takes the freetype lock, and returns with it held */
1037 static FT_Glyph
do_render_ft_stroked_glyph(fz_context * ctx,fz_font * font,int gid,fz_matrix trm,fz_matrix ctm,const fz_stroke_state * state,int aa)1038 do_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, const fz_stroke_state *state, int aa)
1039 {
1040 	FT_Face face = font->ft_face;
1041 	float expansion = fz_matrix_expansion(ctm);
1042 	int linewidth = state->linewidth * expansion * 64 / 2;
1043 	FT_Matrix m;
1044 	FT_Vector v;
1045 	FT_Error fterr;
1046 	FT_Stroker stroker;
1047 	FT_Glyph glyph;
1048 	FT_Stroker_LineJoin line_join;
1049 	FT_Stroker_LineCap line_cap;
1050 
1051 	fz_adjust_ft_glyph_width(ctx, font, gid, &trm);
1052 
1053 	if (font->flags.fake_italic)
1054 		trm = fz_pre_shear(trm, SHEAR, 0);
1055 
1056 	m.xx = trm.a * 64; /* should be 65536 */
1057 	m.yx = trm.b * 64;
1058 	m.xy = trm.c * 64;
1059 	m.yy = trm.d * 64;
1060 	v.x = trm.e * 64;
1061 	v.y = trm.f * 64;
1062 
1063 	fz_lock(ctx, FZ_LOCK_FREETYPE);
1064 	fterr = FT_Set_Char_Size(face, 65536, 65536, 72, 72); /* should be 64, 64 */
1065 	if (fterr)
1066 	{
1067 		fz_warn(ctx, "FT_Set_Char_Size(%s,65536,72): %s", font->name, ft_error_string(fterr));
1068 		return NULL;
1069 	}
1070 
1071 	FT_Set_Transform(face, &m, &v);
1072 
1073 	fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING);
1074 	if (fterr)
1075 	{
1076 		fz_warn(ctx, "FT_Load_Glyph(%s,%d,FT_LOAD_NO_HINTING): %s", font->name, gid, ft_error_string(fterr));
1077 		return NULL;
1078 	}
1079 
1080 	fterr = FT_Stroker_New(ctx->font->ftlib, &stroker);
1081 	if (fterr)
1082 	{
1083 		fz_warn(ctx, "FT_Stroker_New(): %s", ft_error_string(fterr));
1084 		return NULL;
1085 	}
1086 
1087 	line_join =
1088 		state->linejoin == FZ_LINEJOIN_MITER ? FT_STROKER_LINEJOIN_MITER_FIXED :
1089 		state->linejoin == FZ_LINEJOIN_ROUND ? FT_STROKER_LINEJOIN_ROUND :
1090 		state->linejoin == FZ_LINEJOIN_BEVEL ? FT_STROKER_LINEJOIN_BEVEL :
1091 		FT_STROKER_LINEJOIN_MITER_VARIABLE;
1092 	line_cap =
1093 		state->start_cap == FZ_LINECAP_BUTT ? FT_STROKER_LINECAP_BUTT :
1094 		state->start_cap == FZ_LINECAP_ROUND ? FT_STROKER_LINECAP_ROUND :
1095 		state->start_cap == FZ_LINECAP_SQUARE ? FT_STROKER_LINECAP_SQUARE :
1096 		state->start_cap == FZ_LINECAP_TRIANGLE ? FT_STROKER_LINECAP_BUTT :
1097 		FT_STROKER_LINECAP_BUTT;
1098 
1099 	FT_Stroker_Set(stroker, linewidth, line_cap, line_join, state->miterlimit * 65536);
1100 
1101 	fterr = FT_Get_Glyph(face->glyph, &glyph);
1102 	if (fterr)
1103 	{
1104 		fz_warn(ctx, "FT_Get_Glyph(): %s", ft_error_string(fterr));
1105 		FT_Stroker_Done(stroker);
1106 		return NULL;
1107 	}
1108 
1109 	fterr = FT_Glyph_Stroke(&glyph, stroker, 1);
1110 	if (fterr)
1111 	{
1112 		fz_warn(ctx, "FT_Glyph_Stroke(): %s", ft_error_string(fterr));
1113 		FT_Done_Glyph(glyph);
1114 		FT_Stroker_Done(stroker);
1115 		return NULL;
1116 	}
1117 
1118 	FT_Stroker_Done(stroker);
1119 
1120 	fterr = FT_Glyph_To_Bitmap(&glyph, aa > 0 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, 0, 1);
1121 	if (fterr)
1122 	{
1123 		fz_warn(ctx, "FT_Glyph_To_Bitmap(): %s", ft_error_string(fterr));
1124 		FT_Done_Glyph(glyph);
1125 		return NULL;
1126 	}
1127 	return glyph;
1128 }
1129 
1130 fz_glyph *
fz_render_ft_stroked_glyph(fz_context * ctx,fz_font * font,int gid,fz_matrix trm,fz_matrix ctm,const fz_stroke_state * state,int aa)1131 fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, const fz_stroke_state *state, int aa)
1132 {
1133 	FT_Glyph glyph = do_render_ft_stroked_glyph(ctx, font, gid, trm, ctm, state, aa);
1134 	FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
1135 	fz_glyph *result = NULL;
1136 
1137 	if (bitmap == NULL)
1138 	{
1139 		fz_unlock(ctx, FZ_LOCK_FREETYPE);
1140 		return NULL;
1141 	}
1142 
1143 	fz_try(ctx)
1144 	{
1145 		result = glyph_from_ft_bitmap(ctx, bitmap->left, bitmap->top, &bitmap->bitmap);
1146 	}
1147 	fz_always(ctx)
1148 	{
1149 		FT_Done_Glyph(glyph);
1150 		fz_unlock(ctx, FZ_LOCK_FREETYPE);
1151 	}
1152 	fz_catch(ctx)
1153 	{
1154 		fz_rethrow(ctx);
1155 	}
1156 
1157 	return result;
1158 }
1159 
1160 static fz_rect *
fz_bound_ft_glyph(fz_context * ctx,fz_font * font,int gid)1161 fz_bound_ft_glyph(fz_context *ctx, fz_font *font, int gid)
1162 {
1163 	FT_Face face = font->ft_face;
1164 	FT_Error fterr;
1165 	FT_BBox cbox;
1166 	FT_Matrix m;
1167 	FT_Vector v;
1168 	fz_rect *bounds = &font->bbox_table[gid];
1169 
1170 	// TODO: refactor loading into fz_load_ft_glyph
1171 	// TODO: cache results
1172 
1173 	const int scale = face->units_per_EM;
1174 	const float recip = 1.0f / scale;
1175 	const float strength = 0.02f;
1176 	fz_matrix trm = fz_identity;
1177 
1178 	fz_adjust_ft_glyph_width(ctx, font, gid, &trm);
1179 
1180 	if (font->flags.fake_italic)
1181 		trm = fz_pre_shear(trm, SHEAR, 0);
1182 
1183 	m.xx = trm.a * 65536;
1184 	m.yx = trm.b * 65536;
1185 	m.xy = trm.c * 65536;
1186 	m.yy = trm.d * 65536;
1187 	v.x = trm.e * 65536;
1188 	v.y = trm.f * 65536;
1189 
1190 	fz_lock(ctx, FZ_LOCK_FREETYPE);
1191 	/* Set the char size to scale=face->units_per_EM to effectively give
1192 	 * us unscaled results. This avoids quantisation. We then apply the
1193 	 * scale ourselves below. */
1194 	fterr = FT_Set_Char_Size(face, scale, scale, 72, 72);
1195 	if (fterr)
1196 		fz_warn(ctx, "FT_Set_Char_Size(%s,%d,72): %s", font->name, scale, ft_error_string(fterr));
1197 	FT_Set_Transform(face, &m, &v);
1198 
1199 	fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING);
1200 	if (fterr)
1201 	{
1202 		fz_warn(ctx, "FT_Load_Glyph(%s,%d,FT_LOAD_NO_HINTING): %s", font->name, gid, ft_error_string(fterr));
1203 		fz_unlock(ctx, FZ_LOCK_FREETYPE);
1204 		bounds->x0 = bounds->x1 = trm.e;
1205 		bounds->y0 = bounds->y1 = trm.f;
1206 		return bounds;
1207 	}
1208 
1209 	if (font->flags.fake_bold)
1210 	{
1211 		FT_Outline_Embolden(&face->glyph->outline, strength * scale);
1212 		FT_Outline_Translate(&face->glyph->outline, -strength * 0.5f * scale, -strength * 0.5f * scale);
1213 	}
1214 
1215 	FT_Outline_Get_CBox(&face->glyph->outline, &cbox);
1216 	fz_unlock(ctx, FZ_LOCK_FREETYPE);
1217 	bounds->x0 = cbox.xMin * recip;
1218 	bounds->y0 = cbox.yMin * recip;
1219 	bounds->x1 = cbox.xMax * recip;
1220 	bounds->y1 = cbox.yMax * recip;
1221 
1222 	if (fz_is_empty_rect(*bounds))
1223 	{
1224 		bounds->x0 = bounds->x1 = trm.e;
1225 		bounds->y0 = bounds->y1 = trm.f;
1226 	}
1227 
1228 	return bounds;
1229 }
1230 
1231 /* Turn FT_Outline into a fz_path */
1232 
1233 struct closure {
1234 	fz_context *ctx;
1235 	fz_path *path;
1236 	fz_matrix trm;
1237 };
1238 
move_to(const FT_Vector * p,void * cc_)1239 static int move_to(const FT_Vector *p, void *cc_)
1240 {
1241 	struct closure *cc = (struct closure *)cc_;
1242 	fz_context *ctx = cc->ctx;
1243 	fz_path *path = cc->path;
1244 	fz_point pt;
1245 
1246 	pt = fz_transform_point_xy(p->x, p->y, cc->trm);
1247 	fz_moveto(ctx, path, pt.x, pt.y);
1248 	return 0;
1249 }
1250 
line_to(const FT_Vector * p,void * cc_)1251 static int line_to(const FT_Vector *p, void *cc_)
1252 {
1253 	struct closure *cc = (struct closure *)cc_;
1254 	fz_context *ctx = cc->ctx;
1255 	fz_path *path = cc->path;
1256 	fz_point pt;
1257 
1258 	pt = fz_transform_point_xy(p->x, p->y, cc->trm);
1259 	fz_lineto(ctx, path, pt.x, pt.y);
1260 	return 0;
1261 }
1262 
conic_to(const FT_Vector * c,const FT_Vector * p,void * cc_)1263 static int conic_to(const FT_Vector *c, const FT_Vector *p, void *cc_)
1264 {
1265 	struct closure *cc = (struct closure *)cc_;
1266 	fz_context *ctx = cc->ctx;
1267 	fz_path *path = cc->path;
1268 	fz_point ct, pt;
1269 
1270 	ct = fz_transform_point_xy(c->x, c->y, cc->trm);
1271 	pt = fz_transform_point_xy(p->x, p->y, cc->trm);
1272 
1273 	fz_quadto(ctx, path, ct.x, ct.y, pt.x, pt.y);
1274 	return 0;
1275 }
1276 
cubic_to(const FT_Vector * c1,const FT_Vector * c2,const FT_Vector * p,void * cc_)1277 static int cubic_to(const FT_Vector *c1, const FT_Vector *c2, const FT_Vector *p, void *cc_)
1278 {
1279 	struct closure *cc = (struct closure *)cc_;
1280 	fz_context *ctx = cc->ctx;
1281 	fz_path *path = cc->path;
1282 	fz_point c1t, c2t, pt;
1283 
1284 	c1t = fz_transform_point_xy(c1->x, c1->y, cc->trm);
1285 	c2t = fz_transform_point_xy(c2->x, c2->y, cc->trm);
1286 	pt = fz_transform_point_xy(p->x, p->y, cc->trm);
1287 
1288 	fz_curveto(ctx, path, c1t.x, c1t.y, c2t.x, c2t.y, pt.x, pt.y);
1289 	return 0;
1290 }
1291 
1292 static const FT_Outline_Funcs outline_funcs = {
1293 	move_to, line_to, conic_to, cubic_to, 0, 0
1294 };
1295 
1296 fz_path *
fz_outline_ft_glyph(fz_context * ctx,fz_font * font,int gid,fz_matrix trm)1297 fz_outline_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm)
1298 {
1299 	struct closure cc;
1300 	FT_Face face = font->ft_face;
1301 	int fterr;
1302 
1303 	const int scale = face->units_per_EM;
1304 	const float recip = 1.0f / scale;
1305 	const float strength = 0.02f;
1306 
1307 	fz_adjust_ft_glyph_width(ctx, font, gid, &trm);
1308 
1309 	if (font->flags.fake_italic)
1310 		trm = fz_pre_shear(trm, SHEAR, 0);
1311 
1312 	fz_lock(ctx, FZ_LOCK_FREETYPE);
1313 
1314 	fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM);
1315 	if (fterr)
1316 	{
1317 		fz_warn(ctx, "FT_Load_Glyph(%s,%d,FT_LOAD_NO_SCALE|FT_LOAD_IGNORE_TRANSFORM): %s", font->name, gid, ft_error_string(fterr));
1318 		fz_unlock(ctx, FZ_LOCK_FREETYPE);
1319 		return NULL;
1320 	}
1321 
1322 	if (font->flags.fake_bold)
1323 	{
1324 		FT_Outline_Embolden(&face->glyph->outline, strength * scale);
1325 		FT_Outline_Translate(&face->glyph->outline, -strength * 0.5f * scale, -strength * 0.5f * scale);
1326 	}
1327 
1328 	cc.path = NULL;
1329 	fz_try(ctx)
1330 	{
1331 		cc.ctx = ctx;
1332 		cc.path = fz_new_path(ctx);
1333 		cc.trm = fz_concat(fz_scale(recip, recip), trm);
1334 		fz_moveto(ctx, cc.path, cc.trm.e, cc.trm.f);
1335 		FT_Outline_Decompose(&face->glyph->outline, &outline_funcs, &cc);
1336 		fz_closepath(ctx, cc.path);
1337 	}
1338 	fz_always(ctx)
1339 	{
1340 		fz_unlock(ctx, FZ_LOCK_FREETYPE);
1341 	}
1342 	fz_catch(ctx)
1343 	{
1344 		fz_warn(ctx, "freetype cannot decompose outline");
1345 		fz_drop_path(ctx, cc.path);
1346 		return NULL;
1347 	}
1348 
1349 	return cc.path;
1350 }
1351 
1352 /*
1353 	Type 3 fonts...
1354  */
1355 
1356 fz_font *
fz_new_type3_font(fz_context * ctx,const char * name,fz_matrix matrix)1357 fz_new_type3_font(fz_context *ctx, const char *name, fz_matrix matrix)
1358 {
1359 	fz_font *font;
1360 
1361 	font = fz_new_font(ctx, name, 1, 256);
1362 	fz_try(ctx)
1363 	{
1364 		font->t3procs = fz_calloc(ctx, 256, sizeof(fz_buffer*));
1365 		font->t3lists = fz_calloc(ctx, 256, sizeof(fz_display_list*));
1366 		font->t3widths = fz_calloc(ctx, 256, sizeof(float));
1367 		font->t3flags = fz_calloc(ctx, 256, sizeof(unsigned short));
1368 	}
1369 	fz_catch(ctx)
1370 	{
1371 		fz_drop_font(ctx, font);
1372 		fz_rethrow(ctx);
1373 	}
1374 
1375 	font->t3matrix = matrix;
1376 
1377 	return font;
1378 }
1379 
1380 static void
fz_bound_t3_glyph(fz_context * ctx,fz_font * font,int gid)1381 fz_bound_t3_glyph(fz_context *ctx, fz_font *font, int gid)
1382 {
1383 	fz_display_list *list;
1384 	fz_device *dev;
1385 
1386 	list = font->t3lists[gid];
1387 	if (!list)
1388 	{
1389 		font->bbox_table[gid] = fz_empty_rect;
1390 		return;
1391 	}
1392 
1393 	dev = fz_new_bbox_device(ctx, &font->bbox_table[gid]);
1394 	fz_try(ctx)
1395 	{
1396 		fz_run_display_list(ctx, list, dev, font->t3matrix, fz_infinite_rect, NULL);
1397 		fz_close_device(ctx, dev);
1398 	}
1399 	fz_always(ctx)
1400 	{
1401 		fz_drop_device(ctx, dev);
1402 	}
1403 	fz_catch(ctx)
1404 	{
1405 		fz_rethrow(ctx);
1406 	}
1407 
1408 	/* Update font bbox with glyph's computed bbox if the font bbox is invalid */
1409 	if (font->flags.invalid_bbox)
1410 		font->bbox = fz_union_rect(font->bbox, font->bbox_table[gid]);
1411 }
1412 
1413 void
fz_prepare_t3_glyph(fz_context * ctx,fz_font * font,int gid)1414 fz_prepare_t3_glyph(fz_context *ctx, fz_font *font, int gid)
1415 {
1416 	fz_buffer *contents;
1417 	fz_device *dev;
1418 	fz_rect d1_rect;
1419 
1420 	contents = font->t3procs[gid];
1421 	if (!contents)
1422 		return;
1423 
1424 	/* We've not already loaded this one! */
1425 	assert(font->t3lists[gid] == NULL);
1426 
1427 	font->t3lists[gid] = fz_new_display_list(ctx, font->bbox);
1428 
1429 	dev = fz_new_list_device(ctx, font->t3lists[gid]);
1430 	dev->flags = FZ_DEVFLAG_FILLCOLOR_UNDEFINED |
1431 			FZ_DEVFLAG_STROKECOLOR_UNDEFINED |
1432 			FZ_DEVFLAG_STARTCAP_UNDEFINED |
1433 			FZ_DEVFLAG_DASHCAP_UNDEFINED |
1434 			FZ_DEVFLAG_ENDCAP_UNDEFINED |
1435 			FZ_DEVFLAG_LINEJOIN_UNDEFINED |
1436 			FZ_DEVFLAG_MITERLIMIT_UNDEFINED |
1437 			FZ_DEVFLAG_LINEWIDTH_UNDEFINED;
1438 
1439 	/* Avoid cycles in glyph content streams referring to the glyph itself.
1440 	 * Remember to restore the content stream below, regardless of exceptions
1441 	 * or a successful run of the glyph. */
1442 	font->t3procs[gid] = NULL;
1443 
1444 	fz_try(ctx)
1445 	{
1446 		font->t3run(ctx, font->t3doc, font->t3resources, contents, dev, fz_identity, NULL, NULL);
1447 		fz_close_device(ctx, dev);
1448 		font->t3flags[gid] = dev->flags;
1449 		d1_rect = dev->d1_rect;
1450 	}
1451 	fz_always(ctx)
1452 	{
1453 		fz_drop_device(ctx, dev);
1454 		font->t3procs[gid] = contents;
1455 	}
1456 	fz_catch(ctx)
1457 		fz_rethrow(ctx);
1458 	if (fz_display_list_is_empty(ctx, font->t3lists[gid]))
1459 	{
1460 		/* If empty, no need for a huge bbox, especially as the logic
1461 		 * in the 'else if' can make it huge. */
1462 		font->bbox_table[gid].x0 = font->bbox.x0;
1463 		font->bbox_table[gid].y0 = font->bbox.y0;
1464 		font->bbox_table[gid].x1 = font->bbox.x0 + .00001f;
1465 		font->bbox_table[gid].y1 = font->bbox.y0 + .00001f;
1466 	}
1467 	else if (font->t3flags[gid] & FZ_DEVFLAG_BBOX_DEFINED)
1468 	{
1469 		assert(font->bbox_table != NULL);
1470 		assert(font->glyph_count > gid);
1471 		font->bbox_table[gid] = fz_transform_rect(d1_rect, font->t3matrix);
1472 
1473 		if (font->flags.invalid_bbox || !fz_contains_rect(font->bbox, d1_rect))
1474 		{
1475 			/* Either the font bbox is invalid, or the d1_rect returned is
1476 			 * incompatible with it. Either way, don't trust the d1 rect
1477 			 * and calculate it from the contents. */
1478 			fz_bound_t3_glyph(ctx, font, gid);
1479 		}
1480 	}
1481 	else
1482 	{
1483 		/* No bbox has been defined for this glyph, so compute it. */
1484 		fz_bound_t3_glyph(ctx, font, gid);
1485 	}
1486 }
1487 
1488 void
fz_run_t3_glyph(fz_context * ctx,fz_font * font,int gid,fz_matrix trm,fz_device * dev)1489 fz_run_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_device *dev)
1490 {
1491 	fz_display_list *list;
1492 	fz_matrix ctm;
1493 
1494 	list = font->t3lists[gid];
1495 	if (!list)
1496 		return;
1497 
1498 	ctm = fz_concat(font->t3matrix, trm);
1499 	fz_run_display_list(ctx, list, dev, ctm, fz_infinite_rect, NULL);
1500 }
1501 
1502 fz_pixmap *
fz_render_t3_glyph_pixmap(fz_context * ctx,fz_font * font,int gid,fz_matrix trm,fz_colorspace * model,const fz_irect * scissor,int aa)1503 fz_render_t3_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_colorspace *model, const fz_irect *scissor, int aa)
1504 {
1505 	fz_display_list *list;
1506 	fz_rect bounds;
1507 	fz_irect bbox;
1508 	fz_device *dev = NULL;
1509 	fz_pixmap *glyph;
1510 	fz_pixmap *result = NULL;
1511 
1512 	if (gid < 0 || gid > 255)
1513 		return NULL;
1514 
1515 	list = font->t3lists[gid];
1516 	if (!list)
1517 		return NULL;
1518 
1519 	if (font->t3flags[gid] & FZ_DEVFLAG_MASK)
1520 	{
1521 		if (font->t3flags[gid] & FZ_DEVFLAG_COLOR)
1522 			fz_warn(ctx, "type3 glyph claims to be both masked and colored");
1523 		model = NULL;
1524 	}
1525 	else if (font->t3flags[gid] & FZ_DEVFLAG_COLOR)
1526 	{
1527 		if (!model)
1528 			fz_warn(ctx, "colored type3 glyph wanted in masked context");
1529 	}
1530 	else
1531 	{
1532 		fz_warn(ctx, "type3 glyph doesn't specify masked or colored");
1533 		model = NULL; /* Treat as masked */
1534 	}
1535 
1536 	bounds = fz_expand_rect(fz_bound_glyph(ctx, font, gid, trm), 1);
1537 	bbox = fz_irect_from_rect(bounds);
1538 	bbox = fz_intersect_irect(bbox, *scissor);
1539 
1540 	/* Glyphs must always have alpha */
1541 	glyph = fz_new_pixmap_with_bbox(ctx, model, bbox, NULL/* FIXME */, 1);
1542 
1543 	fz_var(dev);
1544 	fz_try(ctx)
1545 	{
1546 		fz_clear_pixmap(ctx, glyph);
1547 		dev = fz_new_draw_device_type3(ctx, fz_identity, glyph);
1548 		fz_run_t3_glyph(ctx, font, gid, trm, dev);
1549 		fz_close_device(ctx, dev);
1550 	}
1551 	fz_always(ctx)
1552 	{
1553 		fz_drop_device(ctx, dev);
1554 	}
1555 	fz_catch(ctx)
1556 	{
1557 		fz_drop_pixmap(ctx, glyph);
1558 		fz_rethrow(ctx);
1559 	}
1560 
1561 	if (!model)
1562 	{
1563 		fz_try(ctx)
1564 		{
1565 			result = fz_alpha_from_gray(ctx, glyph);
1566 		}
1567 		fz_always(ctx)
1568 		{
1569 			fz_drop_pixmap(ctx, glyph);
1570 		}
1571 		fz_catch(ctx)
1572 		{
1573 			fz_rethrow(ctx);
1574 		}
1575 	}
1576 	else
1577 		result = glyph;
1578 
1579 	return result;
1580 }
1581 
1582 fz_glyph *
fz_render_t3_glyph(fz_context * ctx,fz_font * font,int gid,fz_matrix trm,fz_colorspace * model,const fz_irect * scissor,int aa)1583 fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_colorspace *model, const fz_irect *scissor, int aa)
1584 {
1585 	fz_pixmap *pixmap = fz_render_t3_glyph_pixmap(ctx, font, gid, trm, model, scissor, aa);
1586 	return fz_new_glyph_from_pixmap(ctx, pixmap);
1587 }
1588 
1589 void
fz_render_t3_glyph_direct(fz_context * ctx,fz_device * dev,fz_font * font,int gid,fz_matrix trm,void * gstate,fz_default_colorspaces * def_cs)1590 fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, fz_matrix trm, void *gstate, fz_default_colorspaces *def_cs)
1591 {
1592 	fz_matrix ctm;
1593 	void *contents;
1594 
1595 	if (gid < 0 || gid > 255)
1596 		return;
1597 
1598 	contents = font->t3procs[gid];
1599 	if (!contents)
1600 		return;
1601 
1602 	if (font->t3flags[gid] & FZ_DEVFLAG_MASK)
1603 	{
1604 		if (font->t3flags[gid] & FZ_DEVFLAG_COLOR)
1605 			fz_warn(ctx, "type3 glyph claims to be both masked and colored");
1606 	}
1607 	else if (!(font->t3flags[gid] & FZ_DEVFLAG_COLOR))
1608 	{
1609 		fz_warn(ctx, "type3 glyph doesn't specify masked or colored");
1610 	}
1611 
1612 	/* Avoid cycles in glyph content streams referring to the glyph itself.
1613 	 * Remember to restore the content stream below, regardless of exceptions
1614 	 * or a successful run of the glyph. */
1615 	font->t3procs[gid] = NULL;
1616 
1617 	fz_try(ctx)
1618 	{
1619 		ctm = fz_concat(font->t3matrix, trm);
1620 		font->t3run(ctx, font->t3doc, font->t3resources, contents, dev, ctm, gstate, def_cs);
1621 	}
1622 	fz_always(ctx)
1623 		font->t3procs[gid] = contents;
1624 	fz_catch(ctx)
1625 		fz_rethrow(ctx);
1626 }
1627 
1628 fz_rect
fz_bound_glyph(fz_context * ctx,fz_font * font,int gid,fz_matrix trm)1629 fz_bound_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm)
1630 {
1631 	fz_rect rect;
1632 	if (font->bbox_table && gid < font->glyph_count)
1633 	{
1634 		/* If the bbox is infinite or empty, distrust it */
1635 		if (fz_is_infinite_rect(font->bbox_table[gid]) || fz_is_empty_rect(font->bbox_table[gid]))
1636 		{
1637 			/* Get the real size from the glyph */
1638 			if (font->ft_face)
1639 				fz_bound_ft_glyph(ctx, font, gid);
1640 			else if (font->t3lists)
1641 				fz_bound_t3_glyph(ctx, font, gid);
1642 			else
1643 				/* If we can't get a real size, fall back to the font
1644 				 * bbox. */
1645 				font->bbox_table[gid] = font->bbox;
1646 			/* If the real size came back as empty, then store it as
1647 			 * a very small rectangle to avoid us calling this same
1648 			 * check every time. */
1649 			if (fz_is_empty_rect(font->bbox_table[gid]))
1650 			{
1651 				font->bbox_table[gid].x0 = 0;
1652 				font->bbox_table[gid].y0 = 0;
1653 				font->bbox_table[gid].x1 = 0.0000001f;
1654 				font->bbox_table[gid].y1 = 0.0000001f;
1655 			}
1656 		}
1657 		rect = font->bbox_table[gid];
1658 	}
1659 	else
1660 	{
1661 		/* fall back to font bbox */
1662 		rect = font->bbox;
1663 	}
1664 	return fz_transform_rect(rect, trm);
1665 }
1666 
1667 fz_path *
fz_outline_glyph(fz_context * ctx,fz_font * font,int gid,fz_matrix ctm)1668 fz_outline_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm)
1669 {
1670 	if (!font->ft_face)
1671 		return NULL;
1672 	return fz_outline_ft_glyph(ctx, font, gid, ctm);
1673 }
1674 
fz_glyph_cacheable(fz_context * ctx,fz_font * font,int gid)1675 int fz_glyph_cacheable(fz_context *ctx, fz_font *font, int gid)
1676 {
1677 	if (!font->t3procs || !font->t3flags || gid < 0 || gid >= font->glyph_count)
1678 		return 1;
1679 	return (font->t3flags[gid] & FZ_DEVFLAG_UNCACHEABLE) == 0;
1680 }
1681 
1682 static float
fz_advance_ft_glyph(fz_context * ctx,fz_font * font,int gid,int wmode)1683 fz_advance_ft_glyph(fz_context *ctx, fz_font *font, int gid, int wmode)
1684 {
1685 	FT_Error fterr;
1686 	FT_Fixed adv = 0;
1687 	int mask;
1688 
1689 	/* PDF and substitute font widths. */
1690 	if (font->flags.ft_stretch)
1691 	{
1692 		if (font->width_table)
1693 		{
1694 			if (gid < font->width_count)
1695 				return font->width_table[gid] / 1000.0f;
1696 			return font->width_default / 1000.0f;
1697 		}
1698 	}
1699 
1700 	mask = FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING | FT_LOAD_IGNORE_TRANSFORM;
1701 	if (wmode)
1702 		mask |= FT_LOAD_VERTICAL_LAYOUT;
1703 	fz_lock(ctx, FZ_LOCK_FREETYPE);
1704 	fterr = FT_Get_Advance(font->ft_face, gid, mask, &adv);
1705 	fz_unlock(ctx, FZ_LOCK_FREETYPE);
1706 	if (fterr && fterr != FT_Err_Invalid_Argument)
1707 	{
1708 		fz_warn(ctx, "FT_Get_Advance(%s,%d): %s", font->name, gid, ft_error_string(fterr));
1709 		if (font->width_table)
1710 		{
1711 			if (gid < font->width_count)
1712 				return font->width_table[gid] / 1000.0f;
1713 			return font->width_default / 1000.0f;
1714 		}
1715 	}
1716 	return (float) adv / ((FT_Face)font->ft_face)->units_per_EM;
1717 }
1718 
1719 static float
fz_advance_t3_glyph(fz_context * ctx,fz_font * font,int gid)1720 fz_advance_t3_glyph(fz_context *ctx, fz_font *font, int gid)
1721 {
1722 	if (gid < 0 || gid > 255)
1723 		return 0;
1724 	return font->t3widths[gid];
1725 }
1726 
1727 void
fz_get_glyph_name(fz_context * ctx,fz_font * font,int glyph,char * buf,int size)1728 fz_get_glyph_name(fz_context *ctx, fz_font *font, int glyph, char *buf, int size)
1729 {
1730 	FT_Face face = font->ft_face;
1731 	if (face)
1732 	{
1733 		if (FT_HAS_GLYPH_NAMES(face))
1734 		{
1735 			int fterr = FT_Get_Glyph_Name(face, glyph, buf, size);
1736 			if (fterr)
1737 				fz_warn(ctx, "FT_Get_Glyph_Name(%s,%d): %s", font->name, glyph, ft_error_string(fterr));
1738 		}
1739 		else
1740 			fz_snprintf(buf, size, "%d", glyph);
1741 	}
1742 	else
1743 	{
1744 		fz_snprintf(buf, size, "%d", glyph);
1745 	}
1746 }
1747 
1748 float
fz_advance_glyph(fz_context * ctx,fz_font * font,int gid,int wmode)1749 fz_advance_glyph(fz_context *ctx, fz_font *font, int gid, int wmode)
1750 {
1751 	if (font->ft_face)
1752 	{
1753 		if (wmode)
1754 			return fz_advance_ft_glyph(ctx, font, gid, 1);
1755 		if (gid >= 0 && gid < font->glyph_count && gid < MAX_ADVANCE_CACHE)
1756 		{
1757 			if (!font->advance_cache)
1758 			{
1759 				int i;
1760 				font->advance_cache = Memento_label(fz_malloc_array(ctx, font->glyph_count, float), "font_advance_cache");
1761 				for (i = 0; i < font->glyph_count; ++i)
1762 					font->advance_cache[i] = fz_advance_ft_glyph(ctx, font, i, 0);
1763 			}
1764 			return font->advance_cache[gid];
1765 		}
1766 
1767 		return fz_advance_ft_glyph(ctx, font, gid, 0);
1768 	}
1769 	if (font->t3procs)
1770 		return fz_advance_t3_glyph(ctx, font, gid);
1771 	return 0;
1772 }
1773 
1774 int
fz_encode_character(fz_context * ctx,fz_font * font,int ucs)1775 fz_encode_character(fz_context *ctx, fz_font *font, int ucs)
1776 {
1777 	if (font->ft_face)
1778 	{
1779 		if (ucs >= 0 && ucs < 0x10000)
1780 		{
1781 			int pg = ucs >> 8;
1782 			int ix = ucs & 0xFF;
1783 			if (!font->encoding_cache[pg])
1784 			{
1785 				int i;
1786 				font->encoding_cache[pg] = fz_malloc_array(ctx, 256, uint16_t);
1787 				for (i = 0; i < 256; ++i)
1788 					font->encoding_cache[pg][i] = FT_Get_Char_Index(font->ft_face, (pg << 8) + i);
1789 			}
1790 			return font->encoding_cache[pg][ix];
1791 		}
1792 		return FT_Get_Char_Index(font->ft_face, ucs);
1793 	}
1794 	return ucs;
1795 }
1796 
1797 int
fz_encode_character_sc(fz_context * ctx,fz_font * font,int unicode)1798 fz_encode_character_sc(fz_context *ctx, fz_font *font, int unicode)
1799 {
1800 	if (font->ft_face)
1801 	{
1802 		int cat = ucdn_get_general_category(unicode);
1803 		if (cat == UCDN_GENERAL_CATEGORY_LL || cat == UCDN_GENERAL_CATEGORY_LT)
1804 		{
1805 			int glyph;
1806 			const char *name;
1807 			char buf[20];
1808 
1809 			name = fz_glyph_name_from_unicode_sc(unicode);
1810 			if (name)
1811 			{
1812 				glyph = FT_Get_Name_Index(font->ft_face, (char*)name);
1813 				if (glyph > 0)
1814 					return glyph;
1815 			}
1816 
1817 			sprintf(buf, "uni%04X.sc", unicode);
1818 			glyph = FT_Get_Name_Index(font->ft_face, buf);
1819 			if (glyph > 0)
1820 				return glyph;
1821 		}
1822 	}
1823 	return fz_encode_character(ctx, font, unicode);
1824 }
1825 
1826 int
fz_encode_character_by_glyph_name(fz_context * ctx,fz_font * font,const char * glyphname)1827 fz_encode_character_by_glyph_name(fz_context *ctx, fz_font *font, const char *glyphname)
1828 {
1829 	int glyph = 0;
1830 	if (font->ft_face)
1831 	{
1832 		glyph = ft_name_index(font->ft_face, glyphname);
1833 		if (glyph == 0)
1834 			glyph = ft_char_index(font->ft_face, fz_unicode_from_glyph_name(glyphname));
1835 	}
1836 	// TODO: type3 fonts (not needed for now)
1837 	return glyph;
1838 }
1839 
1840 /* FIXME: This should take language too eventually, to allow for fonts where we can select different
1841  * languages using opentype features. */
1842 int
fz_encode_character_with_fallback(fz_context * ctx,fz_font * user_font,int unicode,int script,int language,fz_font ** out_font)1843 fz_encode_character_with_fallback(fz_context *ctx, fz_font *user_font, int unicode, int script, int language, fz_font **out_font)
1844 {
1845 	fz_font *font;
1846 	int gid;
1847 
1848 	gid = fz_encode_character(ctx, user_font, unicode);
1849 	if (gid > 0)
1850 		return *out_font = user_font, gid;
1851 
1852 	if (script == 0)
1853 		script = ucdn_get_script(unicode);
1854 
1855 	/* Fix for ideographic/halfwidth/fullwidth punctuation forms. */
1856 	if ((unicode >= 0x3000 && unicode <= 0x303F) || (unicode >= 0xFF00 && unicode <= 0xFFEF))
1857 	{
1858 		if (script != UCDN_SCRIPT_HANGUL &&
1859 				script != UCDN_SCRIPT_HIRAGANA &&
1860 				script != UCDN_SCRIPT_KATAKANA &&
1861 				script != UCDN_SCRIPT_BOPOMOFO)
1862 			script = UCDN_SCRIPT_HAN;
1863 	}
1864 
1865 	font = fz_load_fallback_font(ctx, script, language, user_font->flags.is_serif, user_font->flags.is_bold, user_font->flags.is_italic);
1866 	if (font)
1867 	{
1868 		gid = fz_encode_character(ctx, font, unicode);
1869 		if (gid > 0)
1870 			return *out_font = font, gid;
1871 	}
1872 
1873 #ifndef TOFU_CJK_LANG
1874 	if (script == UCDN_SCRIPT_HAN)
1875 	{
1876 		font = fz_load_fallback_font(ctx, script, FZ_LANG_zh_Hant, user_font->flags.is_serif, user_font->flags.is_bold, user_font->flags.is_italic);
1877 		if (font)
1878 		{
1879 			gid = fz_encode_character(ctx, font, unicode);
1880 			if (gid > 0)
1881 				return *out_font = font, gid;
1882 		}
1883 		font = fz_load_fallback_font(ctx, script, FZ_LANG_ja, user_font->flags.is_serif, user_font->flags.is_bold, user_font->flags.is_italic);
1884 		if (font)
1885 		{
1886 			gid = fz_encode_character(ctx, font, unicode);
1887 			if (gid > 0)
1888 				return *out_font = font, gid;
1889 		}
1890 		font = fz_load_fallback_font(ctx, script, FZ_LANG_ko, user_font->flags.is_serif, user_font->flags.is_bold, user_font->flags.is_italic);
1891 		if (font)
1892 		{
1893 			gid = fz_encode_character(ctx, font, unicode);
1894 			if (gid > 0)
1895 				return *out_font = font, gid;
1896 		}
1897 		font = fz_load_fallback_font(ctx, script, FZ_LANG_zh_Hans, user_font->flags.is_serif, user_font->flags.is_bold, user_font->flags.is_italic);
1898 		if (font)
1899 		{
1900 			gid = fz_encode_character(ctx, font, unicode);
1901 			if (gid > 0)
1902 				return *out_font = font, gid;
1903 		}
1904 	}
1905 #endif
1906 
1907 	font = fz_load_fallback_math_font(ctx);
1908 	if (font)
1909 	{
1910 		gid = fz_encode_character(ctx, font, unicode);
1911 		if (gid > 0)
1912 			return *out_font = font, gid;
1913 	}
1914 
1915 	font = fz_load_fallback_music_font(ctx);
1916 	if (font)
1917 	{
1918 		gid = fz_encode_character(ctx, font, unicode);
1919 		if (gid > 0)
1920 			return *out_font = font, gid;
1921 	}
1922 
1923 	font = fz_load_fallback_symbol1_font(ctx);
1924 	if (font)
1925 	{
1926 		gid = fz_encode_character(ctx, font, unicode);
1927 		if (gid > 0)
1928 			return *out_font = font, gid;
1929 	}
1930 
1931 	font = fz_load_fallback_symbol2_font(ctx);
1932 	if (font)
1933 	{
1934 		gid = fz_encode_character(ctx, font, unicode);
1935 		if (gid > 0)
1936 			return *out_font = font, gid;
1937 	}
1938 
1939 	font = fz_load_fallback_emoji_font(ctx);
1940 	if (font)
1941 	{
1942 		gid = fz_encode_character(ctx, font, unicode);
1943 		if (gid > 0)
1944 			return *out_font = font, gid;
1945 	}
1946 
1947 	font = fz_new_base14_font(ctx, "Symbol");
1948 	if (font)
1949 	{
1950 		fz_drop_font(ctx, font); /* it's cached in the font context, return a borrowed pointer */
1951 		gid = fz_encode_character(ctx, font, unicode);
1952 		if (gid > 0)
1953 			return *out_font = font, gid;
1954 	}
1955 
1956 	return *out_font = user_font, 0;
1957 }
1958 
fz_font_is_bold(fz_context * ctx,fz_font * font)1959 int fz_font_is_bold(fz_context *ctx, fz_font *font)
1960 {
1961 	return font ? font->flags.is_bold : 0;
1962 }
1963 
fz_font_is_italic(fz_context * ctx,fz_font * font)1964 int fz_font_is_italic(fz_context *ctx, fz_font *font)
1965 {
1966 	return font ? font->flags.is_italic : 0;
1967 }
1968 
fz_font_is_serif(fz_context * ctx,fz_font * font)1969 int fz_font_is_serif(fz_context *ctx, fz_font *font)
1970 {
1971 	return font ? font->flags.is_serif : 0;
1972 }
1973 
fz_font_is_monospaced(fz_context * ctx,fz_font * font)1974 int fz_font_is_monospaced(fz_context *ctx, fz_font *font)
1975 {
1976 	return font ? font->flags.is_mono : 0;
1977 }
1978 
fz_font_name(fz_context * ctx,fz_font * font)1979 const char *fz_font_name(fz_context *ctx, fz_font *font)
1980 {
1981 	return font ? font->name : "";
1982 }
1983 
fz_font_t3_procs(fz_context * ctx,fz_font * font)1984 fz_buffer **fz_font_t3_procs(fz_context *ctx, fz_font *font)
1985 {
1986 	return font ? font->t3procs : NULL;
1987 }
1988 
fz_font_bbox(fz_context * ctx,fz_font * font)1989 fz_rect fz_font_bbox(fz_context *ctx, fz_font *font)
1990 {
1991 	return font->bbox;
1992 }
1993 
fz_font_ft_face(fz_context * ctx,fz_font * font)1994 void *fz_font_ft_face(fz_context *ctx, fz_font *font)
1995 {
1996 	return font ? font->ft_face : NULL;
1997 }
1998 
fz_font_flags(fz_font * font)1999 fz_font_flags_t *fz_font_flags(fz_font *font)
2000 {
2001 	return font ? &font->flags : NULL;
2002 }
2003 
fz_font_shaper_data(fz_context * ctx,fz_font * font)2004 fz_shaper_data_t *fz_font_shaper_data(fz_context *ctx, fz_font *font)
2005 {
2006 	return font ? &font->shaper_data : NULL;
2007 }
2008 
fz_font_digest(fz_context * ctx,fz_font * font,unsigned char digest[16])2009 void fz_font_digest(fz_context *ctx, fz_font *font, unsigned char digest[16])
2010 {
2011 	if (!font->buffer)
2012 		fz_throw(ctx, FZ_ERROR_GENERIC, "no font file for digest");
2013 	if (!font->has_digest)
2014 	{
2015 		fz_md5_buffer(ctx, font->buffer, font->digest);
2016 		font->has_digest = 1;
2017 	}
2018 	memcpy(digest, font->digest, 16);
2019 }
2020