1 // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
2 // vim:ts=8:sw=8:noet:ai:
4 Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include FT_FREETYPE_H
32 #include "ass_fontconfig.h"
34 #include "ass_bitmap.h"
35 #include "ass_cache.h"
37 #define MAX_FONT_CACHE_SIZE 100
39 static ass_font_t
** font_cache
;
40 static int font_cache_size
;
42 static int font_compare(ass_font_desc_t
* a
, ass_font_desc_t
* b
) {
43 if (strcmp(a
->family
, b
->family
) != 0)
45 if (a
->bold
!= b
->bold
)
47 if (a
->italic
!= b
->italic
)
53 * \brief Get a face struct from cache.
54 * \param desc required face description
57 ass_font_t
* ass_font_cache_find(ass_font_desc_t
* desc
)
61 for (i
=0; i
<font_cache_size
; ++i
)
62 if (font_compare(desc
, &(font_cache
[i
]->desc
)))
69 * \brief Add a face struct to cache.
70 * \param font font struct
72 void ass_font_cache_add(ass_font_t
* font
)
74 if (font_cache_size
== MAX_FONT_CACHE_SIZE
) {
75 mp_msg(MSGT_ASS
, MSGL_FATAL
, MSGTR_LIBASS_TooManyFonts
);
76 // FIXME: possible memory leak
80 font_cache
[font_cache_size
] = font
;
84 void ass_font_cache_init(void)
86 font_cache
= calloc(MAX_FONT_CACHE_SIZE
, sizeof(ass_font_t
*));
90 void ass_font_cache_done(void)
93 for (i
= 0; i
< font_cache_size
; ++i
) {
94 ass_font_t
* item
= font_cache
[i
];
101 //---------------------------------
104 #define GLYPH_HASH_SIZE (0xFFFF + 13)
106 typedef struct glyph_hash_item_s
{
107 glyph_hash_key_t key
;
108 glyph_hash_val_t val
;
109 struct glyph_hash_item_s
* next
;
112 typedef glyph_hash_item_t
* glyph_hash_item_p
;
114 static glyph_hash_item_p
* glyph_hash_root
;
115 static int glyph_hash_size
;
117 static int glyph_compare(glyph_hash_key_t
* a
, glyph_hash_key_t
* b
) {
118 if (memcmp(a
, b
, sizeof(glyph_hash_key_t
)) == 0)
124 static unsigned glyph_hash(glyph_hash_key_t
* key
) {
127 for (i
= 0; i
< sizeof(key
->font
); ++i
)
128 val
+= *(unsigned char *)(&(key
->font
) + i
);
131 if (key
->bitmap
) val
&= 0x80000000;
132 if (key
->be
) val
&= 0x40000000;
134 val
+= key
->size
<< 8;
135 val
+= key
->outline
<< 3;
136 val
+= key
->advance
.x
<< 10;
137 val
+= key
->advance
.y
<< 16;
138 val
+= key
->bold
<< 1;
139 val
+= key
->italic
<< 20;
141 val
+= key
->fry
<< 1;
142 val
+= key
->frz
<< 2;
147 * \brief Add a glyph to glyph cache.
148 * \param key hash key
149 * \param val hash val: 2 bitmap glyphs + some additional info
151 void cache_add_glyph(glyph_hash_key_t
* key
, glyph_hash_val_t
* val
)
153 unsigned hash
= glyph_hash(key
);
154 glyph_hash_item_t
** next
= glyph_hash_root
+ (hash
% GLYPH_HASH_SIZE
);
156 if (glyph_compare(key
, &((*next
)->key
)))
158 next
= &((*next
)->next
);
161 (*next
) = malloc(sizeof(glyph_hash_item_t
));
162 // (*next)->desc = glyph_key_copy(key, &((*next)->key));
163 memcpy(&((*next
)->key
), key
, sizeof(glyph_hash_key_t
));
164 memcpy(&((*next
)->val
), val
, sizeof(glyph_hash_val_t
));
168 /* if (glyph_hash_size && (glyph_hash_size % 25 == 0)) {
169 printf("\nGlyph cache: %d entries, %d bytes\n", glyph_hash_size, glyph_hash_size * sizeof(glyph_hash_item_t));
174 * \brief Get a glyph from glyph cache.
175 * \param key hash key
176 * \return requested hash val or 0 if not found
178 glyph_hash_val_t
* cache_find_glyph(glyph_hash_key_t
* key
)
180 unsigned hash
= glyph_hash(key
);
181 glyph_hash_item_t
* item
= glyph_hash_root
[hash
% GLYPH_HASH_SIZE
];
183 if (glyph_compare(key
, &(item
->key
))) {
191 void ass_glyph_cache_init(void)
193 glyph_hash_root
= calloc(GLYPH_HASH_SIZE
, sizeof(glyph_hash_item_p
));
197 void ass_glyph_cache_done(void)
200 for (i
= 0; i
< GLYPH_HASH_SIZE
; ++i
) {
201 glyph_hash_item_t
* item
= glyph_hash_root
[i
];
203 glyph_hash_item_t
* next
= item
->next
;
204 if (item
->val
.bm
) ass_free_bitmap(item
->val
.bm
);
205 if (item
->val
.bm_o
) ass_free_bitmap(item
->val
.bm_o
);
206 if (item
->val
.bm_s
) ass_free_bitmap(item
->val
.bm_s
);
211 free(glyph_hash_root
);
215 void ass_glyph_cache_reset(void)
217 ass_glyph_cache_done();
218 ass_glyph_cache_init();