Mercurial > mplayer.hg
comparison libass/ass_render.c @ 23021:a81c390d4a22
Move outline glyph generation to a separate function, using outline glyph
cache.
author | eugeni |
---|---|
date | Fri, 20 Apr 2007 23:09:48 +0000 |
parents | f3b04984b0da |
children | 199a3c6f54e8 |
comparison
equal
deleted
inserted
replaced
23020:1cce8d37847e | 23021:a81c390d4a22 |
---|---|
251 priv->ftlibrary = ft; | 251 priv->ftlibrary = ft; |
252 // images_root and related stuff is zero-filled in calloc | 252 // images_root and related stuff is zero-filled in calloc |
253 | 253 |
254 ass_font_cache_init(); | 254 ass_font_cache_init(); |
255 ass_bitmap_cache_init(); | 255 ass_bitmap_cache_init(); |
256 ass_glyph_cache_init(); | |
256 | 257 |
257 text_info.glyphs = calloc(MAX_GLYPHS, sizeof(glyph_info_t)); | 258 text_info.glyphs = calloc(MAX_GLYPHS, sizeof(glyph_info_t)); |
258 | 259 |
259 ass_init_exit: | 260 ass_init_exit: |
260 if (priv) mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_Init); | 261 if (priv) mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_Init); |
265 | 266 |
266 void ass_renderer_done(ass_renderer_t* priv) | 267 void ass_renderer_done(ass_renderer_t* priv) |
267 { | 268 { |
268 ass_font_cache_done(); | 269 ass_font_cache_done(); |
269 ass_bitmap_cache_done(); | 270 ass_bitmap_cache_done(); |
271 ass_glyph_cache_done(); | |
270 if (render_context.stroker) { | 272 if (render_context.stroker) { |
271 FT_Stroker_Done(render_context.stroker); | 273 FT_Stroker_Done(render_context.stroker); |
272 render_context.stroker = 0; | 274 render_context.stroker = 0; |
273 } | 275 } |
274 if (priv && priv->ftlibrary) FT_Done_FreeType(priv->ftlibrary); | 276 if (priv && priv->ftlibrary) FT_Done_FreeType(priv->ftlibrary); |
1220 | 1222 |
1221 static void free_render_context(void) | 1223 static void free_render_context(void) |
1222 { | 1224 { |
1223 } | 1225 } |
1224 | 1226 |
1227 static int get_outline_glyph(int symbol, glyph_info_t* info, FT_Vector* advance) | |
1228 { | |
1229 int error; | |
1230 glyph_hash_val_t* val; | |
1231 glyph_hash_key_t key; | |
1232 key.font = render_context.font; | |
1233 key.size = render_context.font_size; | |
1234 key.ch = symbol; | |
1235 key.scale_x = (render_context.scale_x * 0xFFFF); | |
1236 key.scale_y = (render_context.scale_y * 0xFFFF); | |
1237 key.advance = *advance; | |
1238 key.bold = render_context.bold; | |
1239 key.italic = render_context.italic; | |
1240 | |
1241 info->glyph = info->outline_glyph = 0; | |
1242 | |
1243 val = cache_find_glyph(&key); | |
1244 if (val) { | |
1245 FT_Glyph_Copy(val->glyph, &info->glyph); | |
1246 info->bbox = val->bbox_scaled; | |
1247 info->advance.x = val->advance.x; | |
1248 info->advance.y = val->advance.y; | |
1249 } else { | |
1250 glyph_hash_val_t v; | |
1251 info->glyph = ass_font_get_glyph(frame_context.ass_priv->fontconfig_priv, render_context.font, symbol); | |
1252 if (!info->glyph) | |
1253 return 0; | |
1254 info->advance.x = d16_to_d6(info->glyph->advance.x); | |
1255 info->advance.y = d16_to_d6(info->glyph->advance.y); | |
1256 FT_Glyph_Get_CBox( info->glyph, FT_GLYPH_BBOX_PIXELS, &info->bbox); | |
1257 | |
1258 FT_Glyph_Copy(info->glyph, &v.glyph); | |
1259 v.advance = info->advance; | |
1260 v.bbox_scaled = info->bbox; | |
1261 cache_add_glyph(&key, &v); | |
1262 } | |
1263 | |
1264 if (render_context.stroker) { | |
1265 info->outline_glyph = info->glyph; | |
1266 error = FT_Glyph_StrokeBorder( &(info->outline_glyph), render_context.stroker, 0 , 0 ); // don't destroy original | |
1267 if (error) { | |
1268 mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FT_Glyph_Stroke_Error, error); | |
1269 } | |
1270 } | |
1271 return 0; | |
1272 } | |
1273 | |
1225 /** | 1274 /** |
1226 * \brief Get normal and outline glyphs from cache (if possible) or font face | 1275 * \brief Get normal and outline glyphs from cache (if possible) or font face |
1227 * \param index face glyph index | 1276 * \param index face glyph index |
1228 * \param symbol ucs4 char | 1277 * \param symbol ucs4 char |
1229 * \param info out: struct filled with extracted data | 1278 * \param info out: struct filled with extracted data |
1230 * \param advance advance vector of the extracted glyph | 1279 * \param advance advance vector of the extracted glyph |
1231 * \return 0 on success | 1280 * \return 0 on success |
1232 */ | 1281 */ |
1233 static void get_glyph(int symbol, glyph_info_t* info, FT_Vector* advance) | 1282 static int get_bitmap_glyph(int symbol, glyph_info_t* info, FT_Vector* advance) |
1234 { | 1283 { |
1235 int error; | 1284 int error; |
1236 bitmap_hash_val_t* val; | 1285 bitmap_hash_val_t* val; |
1237 bitmap_hash_key_t* key = &(info->hash_key); | 1286 bitmap_hash_key_t* key = &(info->hash_key); |
1238 | 1287 |
1252 | 1301 |
1253 val = cache_find_bitmap(key); | 1302 val = cache_find_bitmap(key); |
1254 /* val = 0; */ | 1303 /* val = 0; */ |
1255 | 1304 |
1256 if (val) { | 1305 if (val) { |
1257 info->glyph = info->outline_glyph = 0; | |
1258 info->bm = val->bm; | 1306 info->bm = val->bm; |
1259 info->bm_o = val->bm_o; | 1307 info->bm_o = val->bm_o; |
1260 info->bm_s = val->bm_s; | 1308 info->bm_s = val->bm_s; |
1261 info->bbox = val->bbox_scaled; | 1309 info->bbox = val->bbox_scaled; |
1262 info->advance.x = val->advance.x; | 1310 info->advance.x = val->advance.x; |
1263 info->advance.y = val->advance.y; | 1311 info->advance.y = val->advance.y; |
1264 | 1312 } else |
1265 return; | 1313 info->bm = info->bm_o = info->bm_s = 0; |
1266 } | 1314 |
1267 | 1315 return 0; |
1268 // not found, get a new outline glyph from face | |
1269 // mp_msg(MSGT_ASS, MSGL_INFO, "miss, index = %d, symbol = %c, adv = (%d, %d)\n", index, symbol, advance->x, advance->y); | |
1270 | |
1271 info->outline_glyph = 0; | |
1272 info->bm = info->bm_o = info->bm_s = 0; | |
1273 info->bbox.xMin = info->bbox.xMax = info->bbox.yMin = info->bbox.yMax = 0; | |
1274 info->advance.x = info->advance.y = 0; | |
1275 | |
1276 info->glyph = ass_font_get_glyph(frame_context.ass_priv->fontconfig_priv, render_context.font, symbol); | |
1277 if (!info->glyph) | |
1278 return; | |
1279 | |
1280 info->advance.x = d16_to_d6(info->glyph->advance.x); | |
1281 info->advance.y = d16_to_d6(info->glyph->advance.y); | |
1282 | |
1283 if (render_context.stroker) { | |
1284 info->outline_glyph = info->glyph; | |
1285 error = FT_Glyph_StrokeBorder( &(info->outline_glyph), render_context.stroker, 0 , 0 ); // don't destroy original | |
1286 if (error) { | |
1287 mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FT_Glyph_Stroke_Error, error); | |
1288 } | |
1289 } | |
1290 } | 1316 } |
1291 | 1317 |
1292 /** | 1318 /** |
1293 * This function goes through text_info and calculates text parameters. | 1319 * This function goes through text_info and calculates text parameters. |
1294 * The following text_info fields are filled: | 1320 * The following text_info fields are filled: |
1738 matrix.yx = (FT_Fixed)( 0 * 0x10000L ); | 1764 matrix.yx = (FT_Fixed)( 0 * 0x10000L ); |
1739 matrix.yy = (FT_Fixed)( render_context.scale_y * 0x10000L ); | 1765 matrix.yy = (FT_Fixed)( render_context.scale_y * 0x10000L ); |
1740 | 1766 |
1741 ass_font_set_transform(render_context.font, &matrix, &shift ); | 1767 ass_font_set_transform(render_context.font, &matrix, &shift ); |
1742 } | 1768 } |
1743 | 1769 |
1744 get_glyph(code, text_info.glyphs + text_info.length, &shift); | 1770 error = get_outline_glyph(code, text_info.glyphs + text_info.length, &shift); |
1771 error |= get_bitmap_glyph(code, text_info.glyphs + text_info.length, &shift); | |
1772 | |
1773 if (error) { | |
1774 continue; | |
1775 } | |
1745 | 1776 |
1746 text_info.glyphs[text_info.length].pos.x = pen.x >> 6; | 1777 text_info.glyphs[text_info.length].pos.x = pen.x >> 6; |
1747 text_info.glyphs[text_info.length].pos.y = pen.y >> 6; | 1778 text_info.glyphs[text_info.length].pos.y = pen.y >> 6; |
1748 | 1779 |
1749 pen.x += text_info.glyphs[text_info.length].advance.x; | 1780 pen.x += text_info.glyphs[text_info.length].advance.x; |
1750 pen.x += double_to_d6(render_context.hspacing); | 1781 pen.x += double_to_d6(render_context.hspacing); |
1751 pen.y += text_info.glyphs[text_info.length].advance.y; | 1782 pen.y += text_info.glyphs[text_info.length].advance.y; |
1752 | 1783 |
1753 // if it's an outline glyph, we still need to fill the bbox | |
1754 if (text_info.glyphs[text_info.length].glyph) { | |
1755 FT_Glyph_Get_CBox( text_info.glyphs[text_info.length].glyph, FT_GLYPH_BBOX_PIXELS, &(text_info.glyphs[text_info.length].bbox) ); | |
1756 } | |
1757 | |
1758 previous = code; | 1784 previous = code; |
1759 | 1785 |
1760 text_info.glyphs[text_info.length].symbol = code; | 1786 text_info.glyphs[text_info.length].symbol = code; |
1761 text_info.glyphs[text_info.length].linebreak = 0; | 1787 text_info.glyphs[text_info.length].linebreak = 0; |
1762 for (i = 0; i < 4; ++i) { | 1788 for (i = 0; i < 4; ++i) { |