Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4680 right-hear 1
#include "fitz.h"
2
 
3
#define MAX_FONT_SIZE 1000
4
#define MAX_GLYPH_SIZE 256
5
#define MAX_CACHE_SIZE (1024*1024)
6
 
7
typedef struct fz_glyph_key_s fz_glyph_key;
8
 
9
struct fz_glyph_cache_s
10
{
11
	fz_hash_table *hash;
12
	int total;
13
};
14
 
15
struct fz_glyph_key_s
16
{
17
	fz_font *font;
18
	int a, b;
19
	int c, d;
20
	unsigned short gid;
21
	unsigned char e, f;
22
};
23
 
24
fz_glyph_cache *
25
fz_new_glyph_cache(void)
26
{
27
	fz_glyph_cache *cache;
28
 
29
	cache = fz_malloc(sizeof(fz_glyph_cache));
30
	cache->hash = fz_new_hash_table(509, sizeof(fz_glyph_key));
31
	cache->total = 0;
32
 
33
	return cache;
34
}
35
 
36
static void
37
fz_evict_glyph_cache(fz_glyph_cache *cache)
38
{
39
	fz_glyph_key *key;
40
	fz_pixmap *pixmap;
41
	int i;
42
 
43
	for (i = 0; i < fz_hash_len(cache->hash); i++)
44
	{
45
		key = fz_hash_get_key(cache->hash, i);
46
		if (key->font)
47
			fz_drop_font(key->font);
48
		pixmap = fz_hash_get_val(cache->hash, i);
49
		if (pixmap)
50
			fz_drop_pixmap(pixmap);
51
	}
52
 
53
	cache->total = 0;
54
 
55
	fz_empty_hash(cache->hash);
56
}
57
 
58
void
59
fz_free_glyph_cache(fz_glyph_cache *cache)
60
{
61
	fz_evict_glyph_cache(cache);
62
	fz_free_hash(cache->hash);
63
	fz_free(cache);
64
}
65
 
66
fz_pixmap *
67
fz_render_stroked_glyph(fz_glyph_cache *cache, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *stroke)
68
{
69
	if (font->ft_face)
70
		return fz_render_ft_stroked_glyph(font, gid, trm, ctm, stroke);
71
	return fz_render_glyph(cache, font, gid, trm, NULL);
72
}
73
 
74
fz_pixmap *
75
fz_render_glyph(fz_glyph_cache *cache, fz_font *font, int gid, fz_matrix ctm, fz_colorspace *model)
76
{
77
	fz_glyph_key key;
78
	fz_pixmap *val;
79
	float size = fz_matrix_expansion(ctm);
80
 
81
	if (size > MAX_FONT_SIZE)
82
	{
83
		/* TODO: this case should be handled by rendering glyph as a path fill */
84
		fz_warn("font size too large (%g), not rendering glyph", size);
85
		return NULL;
86
	}
87
 
88
	memset(&key, 0, sizeof key);
89
	key.font = font;
90
	key.gid = gid;
91
	key.a = ctm.a * 65536;
92
	key.b = ctm.b * 65536;
93
	key.c = ctm.c * 65536;
94
	key.d = ctm.d * 65536;
95
	key.e = (ctm.e - floorf(ctm.e)) * 256;
96
	key.f = (ctm.f - floorf(ctm.f)) * 256;
97
 
98
	val = fz_hash_find(cache->hash, &key);
99
	if (val)
100
		return fz_keep_pixmap(val);
101
 
102
	ctm.e = floorf(ctm.e) + key.e / 256.0f;
103
	ctm.f = floorf(ctm.f) + key.f / 256.0f;
104
 
105
	if (font->ft_face)
106
	{
107
		val = fz_render_ft_glyph(font, gid, ctm);
108
	}
109
	else if (font->t3procs)
110
	{
111
		val = fz_render_t3_glyph(font, gid, ctm, model);
112
	}
113
	else
114
	{
115
		fz_warn("assert: uninitialized font structure");
116
		return NULL;
117
	}
118
 
119
	if (val)
120
	{
121
		if (val->w < MAX_GLYPH_SIZE && val->h < MAX_GLYPH_SIZE)
122
		{
123
			if (cache->total + val->w * val->h > MAX_CACHE_SIZE)
124
				fz_evict_glyph_cache(cache);
125
			fz_keep_font(key.font);
126
			fz_hash_insert(cache->hash, &key, val);
127
			cache->total += val->w * val->h;
128
			return fz_keep_pixmap(val);
129
		}
130
		return val;
131
	}
132
 
133
	return NULL;
134
}