| | 1162 | static ft_style_t *CreateStyle( char *psz_fontname, int i_font_size, |
|---|
| | 1163 | int i_font_color, int i_font_alpha, vlc_bool_t b_bold, |
|---|
| | 1164 | vlc_bool_t b_italic, vlc_bool_t b_uline ) |
|---|
| | 1165 | { |
|---|
| | 1166 | ft_style_t *p_style = malloc( sizeof( ft_style_t )); |
|---|
| | 1167 | |
|---|
| | 1168 | if( p_style ) |
|---|
| | 1169 | { |
|---|
| | 1170 | p_style->i_font_size = i_font_size; |
|---|
| | 1171 | p_style->i_font_color = ( i_font_color & 0x00ffffff ) |
|---|
| | 1172 | | (( i_font_alpha & 0xff ) << 24 ); |
|---|
| | 1173 | p_style->b_italic = b_italic; |
|---|
| | 1174 | p_style->b_bold = b_bold; |
|---|
| | 1175 | p_style->b_underline = b_uline; |
|---|
| | 1176 | /* p_style has just been malloc'ed in this function - |
|---|
| | 1177 | * it CAN'T have a previous assignment, and hence we |
|---|
| | 1178 | * don't need to do a free() for any previous value - |
|---|
| | 1179 | * which will in fact be undefined. */ |
|---|
| | 1180 | p_style->psz_fontname = strdup( psz_fontname ); |
|---|
| | 1181 | } |
|---|
| | 1182 | return p_style; |
|---|
| | 1183 | } |
|---|
| | 1184 | |
|---|
| | 1185 | static void DeleteStyle( ft_style_t *p_style ) |
|---|
| | 1186 | { |
|---|
| | 1187 | if( p_style ) |
|---|
| | 1188 | { |
|---|
| | 1189 | if( p_style->psz_fontname ) |
|---|
| | 1190 | free( p_style->psz_fontname ); |
|---|
| | 1191 | free( p_style ); |
|---|
| | 1192 | } |
|---|
| | 1193 | } |
|---|
| | 1194 | |
|---|
| | 1195 | static vlc_bool_t StyleEquals( ft_style_t *s1, ft_style_t *s2 ) |
|---|
| | 1196 | { |
|---|
| | 1197 | if( !s1 || !s2 ) |
|---|
| | 1198 | return VLC_FALSE; |
|---|
| | 1199 | if( s1 == s2 ) |
|---|
| | 1200 | return VLC_TRUE; |
|---|
| | 1201 | |
|---|
| | 1202 | if(( s1->i_font_size == s2->i_font_size ) && |
|---|
| | 1203 | ( s1->i_font_color == s2->i_font_color ) && |
|---|
| | 1204 | ( s1->b_italic == s2->b_italic ) && |
|---|
| | 1205 | ( s1->b_bold == s2->b_bold ) && |
|---|
| | 1206 | ( s1->b_underline == s2->b_underline ) && |
|---|
| | 1207 | ( !strcmp( s1->psz_fontname, s2->psz_fontname ))) |
|---|
| | 1208 | { |
|---|
| | 1209 | return VLC_TRUE; |
|---|
| | 1210 | } |
|---|
| | 1211 | return VLC_FALSE; |
|---|
| | 1212 | } |
|---|
| | 1213 | |
|---|
| 1259 | | if( iconv_handle == (vlc_iconv_t)-1 ) |
|---|
| 1260 | | { |
|---|
| 1261 | | msg_Warn( p_filter, "unable to do conversion" ); |
|---|
| 1262 | | free( psz_unicode ); |
|---|
| 1263 | | return NULL;; |
|---|
| 1264 | | } |
|---|
| 1265 | | |
|---|
| 1266 | | { |
|---|
| 1267 | | char *p_in_buffer, *p_out_buffer; |
|---|
| 1268 | | size_t i_in_bytes, i_out_bytes, i_out_bytes_left, i_ret; |
|---|
| 1269 | | i_in_bytes = strlen( psz_string ); |
|---|
| 1270 | | i_out_bytes = i_in_bytes * sizeof( uint32_t ); |
|---|
| 1271 | | i_out_bytes_left = i_out_bytes; |
|---|
| 1272 | | p_in_buffer = psz_string; |
|---|
| 1273 | | p_out_buffer = (char *)psz_unicode; |
|---|
| 1274 | | i_ret = vlc_iconv( iconv_handle, (const char**)&p_in_buffer, &i_in_bytes, |
|---|
| 1275 | | &p_out_buffer, &i_out_bytes_left ); |
|---|
| 1276 | | |
|---|
| 1277 | | vlc_iconv_close( iconv_handle ); |
|---|
| 1278 | | |
|---|
| 1279 | | if( i_in_bytes ) |
|---|
| 1280 | | { |
|---|
| 1281 | | msg_Warn( p_filter, "failed to convert string to unicode (%s), " |
|---|
| 1282 | | "bytes left %d", strerror(errno), (int)i_in_bytes ); |
|---|
| 1283 | | free( psz_unicode ); |
|---|
| 1284 | | return NULL;; |
|---|
| 1285 | | } |
|---|
| 1286 | | *(uint32_t*)p_out_buffer = 0; |
|---|
| 1287 | | i_string_length = (i_out_bytes - i_out_bytes_left) / sizeof(uint32_t); |
|---|
| 1288 | | } |
|---|
| 1289 | | |
|---|
| 1290 | | #if defined(HAVE_FRIBIDI) |
|---|
| 1291 | | { |
|---|
| 1292 | | uint32_t *p_fribidi_string; |
|---|
| 1293 | | |
|---|
| 1294 | | p_fribidi_string = malloc( (i_string_length + 1) * sizeof(uint32_t) ); |
|---|
| 1295 | | if( !p_fribidi_string ) |
|---|
| 1296 | | { |
|---|
| 1297 | | msg_Err( p_filter, "out of memory" ); |
|---|
| 1298 | | free( psz_unicode ); |
|---|
| 1299 | | return NULL; |
|---|
| 1300 | | } |
|---|
| 1301 | | |
|---|
| 1302 | | /* Do bidi conversion line-by-line */ |
|---|
| 1303 | | FriBidiCharType base_dir = FRIBIDI_TYPE_LTR; |
|---|
| 1304 | | fribidi_log2vis((FriBidiChar*)psz_unicode, i_string_length, |
|---|
| 1305 | | &base_dir, (FriBidiChar*)p_fribidi_string, 0, 0, 0); |
|---|
| 1306 | | |
|---|
| 1307 | | free( psz_unicode ); |
|---|
| 1308 | | psz_unicode = p_fribidi_string; |
|---|
| 1309 | | p_fribidi_string[ i_string_length ] = 0; |
|---|
| 1310 | | } |
|---|
| 1311 | | #endif |
|---|
| 1312 | | return psz_unicode; |
|---|
| | 1324 | if( iconv_handle != (vlc_iconv_t)-1 ) |
|---|
| | 1325 | { |
|---|
| | 1326 | char *p_in_buffer, *p_out_buffer; |
|---|
| | 1327 | size_t i_in_bytes, i_out_bytes, i_out_bytes_left, i_ret; |
|---|
| | 1328 | i_in_bytes = strlen( psz_string ); |
|---|
| | 1329 | i_out_bytes = i_in_bytes * sizeof( uint32_t ); |
|---|
| | 1330 | i_out_bytes_left = i_out_bytes; |
|---|
| | 1331 | p_in_buffer = (char *) psz_string; |
|---|
| | 1332 | p_out_buffer = (char *) *ppsz_unicode; |
|---|
| | 1333 | i_ret = vlc_iconv( iconv_handle, (const char**)&p_in_buffer, |
|---|
| | 1334 | &i_in_bytes, &p_out_buffer, &i_out_bytes_left ); |
|---|
| | 1335 | |
|---|
| | 1336 | vlc_iconv_close( iconv_handle ); |
|---|
| | 1337 | |
|---|
| | 1338 | if( i_in_bytes ) |
|---|
| | 1339 | { |
|---|
| | 1340 | msg_Warn( p_filter, "failed to convert string to unicode (%s), " |
|---|
| | 1341 | "bytes left %d", strerror(errno), (int)i_in_bytes ); |
|---|
| | 1342 | } |
|---|
| | 1343 | else |
|---|
| | 1344 | { |
|---|
| | 1345 | *(uint32_t*)p_out_buffer = 0; |
|---|
| | 1346 | *i_string_length = |
|---|
| | 1347 | (i_out_bytes - i_out_bytes_left) / sizeof(uint32_t); |
|---|
| | 1348 | } |
|---|
| | 1349 | } |
|---|
| | 1350 | else |
|---|
| | 1351 | { |
|---|
| | 1352 | msg_Warn( p_filter, "unable to do conversion" ); |
|---|
| | 1353 | } |
|---|
| | 1354 | } |
|---|
| | 1355 | } |
|---|
| | 1356 | |
|---|
| | 1357 | static ft_style_t *GetStyleFromFontStack( filter_sys_t *p_sys, |
|---|
| | 1358 | font_stack_t **p_fonts, vlc_bool_t b_bold, vlc_bool_t b_italic, |
|---|
| | 1359 | vlc_bool_t b_uline ) |
|---|
| | 1360 | { |
|---|
| | 1361 | ft_style_t *p_style = NULL; |
|---|
| | 1362 | |
|---|
| | 1363 | char *psz_fontname = NULL; |
|---|
| | 1364 | int i_font_color = p_sys->i_font_color; |
|---|
| | 1365 | int i_font_alpha = 0; |
|---|
| | 1366 | int i_font_size = p_sys->i_font_size; |
|---|
| | 1367 | |
|---|
| | 1368 | if( VLC_SUCCESS == PeekFont( p_fonts, &psz_fontname, &i_font_size, |
|---|
| | 1369 | &i_font_color, &i_font_alpha ) ) |
|---|
| | 1370 | { |
|---|
| | 1371 | p_style = CreateStyle( psz_fontname, i_font_size, i_font_color, |
|---|
| | 1372 | i_font_alpha, b_bold, b_italic, b_uline ); |
|---|
| | 1373 | } |
|---|
| | 1374 | return p_style; |
|---|
| 1462 | | static int ProcessNodes( filter_t *p_filter, xml_reader_t *p_xml_reader, char *psz_html, text_style_t *p_font_style, line_desc_t **p_lines, FT_Vector *p_result ) |
|---|
| 1463 | | { |
|---|
| 1464 | | filter_sys_t *p_sys = p_filter->p_sys; |
|---|
| 1465 | | |
|---|
| 1466 | | FT_Vector tmp_result; |
|---|
| 1467 | | |
|---|
| 1468 | | font_stack_t *p_fonts = NULL; |
|---|
| | 1553 | static int HandleFontAttributes( xml_reader_t *p_xml_reader, |
|---|
| | 1554 | font_stack_t **p_fonts ) |
|---|
| | 1555 | { |
|---|
| | 1556 | int rv; |
|---|
| | 1557 | char *psz_fontname = NULL; |
|---|
| | 1558 | int i_font_color = 0xffffff; |
|---|
| | 1559 | int i_font_alpha = 0; |
|---|
| | 1560 | int i_font_size = 24; |
|---|
| | 1561 | |
|---|
| | 1562 | /* Default all attributes to the top font in the stack -- in case not |
|---|
| | 1563 | * all attributes are specified in the sub-font |
|---|
| | 1564 | */ |
|---|
| | 1565 | if( VLC_SUCCESS == PeekFont( p_fonts, |
|---|
| | 1566 | &psz_fontname, |
|---|
| | 1567 | &i_font_size, |
|---|
| | 1568 | &i_font_color, |
|---|
| | 1569 | &i_font_alpha )) |
|---|
| | 1570 | { |
|---|
| | 1571 | psz_fontname = strdup( psz_fontname ); |
|---|
| | 1572 | } |
|---|
| | 1573 | |
|---|
| | 1574 | while ( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) |
|---|
| | 1575 | { |
|---|
| | 1576 | char *psz_name = xml_ReaderName ( p_xml_reader ); |
|---|
| | 1577 | char *psz_value = xml_ReaderValue ( p_xml_reader ); |
|---|
| | 1578 | |
|---|
| | 1579 | if( psz_name && psz_value ) |
|---|
| | 1580 | { |
|---|
| | 1581 | if( !strcasecmp( "face", psz_name ) ) |
|---|
| | 1582 | { |
|---|
| | 1583 | if( psz_fontname ) free( psz_fontname ); |
|---|
| | 1584 | psz_fontname = strdup( psz_value ); |
|---|
| | 1585 | } |
|---|
| | 1586 | else if( !strcasecmp( "size", psz_name ) ) |
|---|
| | 1587 | { |
|---|
| | 1588 | if( ( *psz_value == '+' ) || ( *psz_value == '-' ) ) |
|---|
| | 1589 | { |
|---|
| | 1590 | int i_value = atoi( psz_value ); |
|---|
| | 1591 | |
|---|
| | 1592 | if( ( i_value >= -5 ) && ( i_value <= 5 ) ) |
|---|
| | 1593 | i_font_size += ( i_value * i_font_size ) / 10; |
|---|
| | 1594 | else if( i_value < -5 ) |
|---|
| | 1595 | i_font_size = - i_value; |
|---|
| | 1596 | else if( i_value > 5 ) |
|---|
| | 1597 | i_font_size = i_value; |
|---|
| | 1598 | } |
|---|
| | 1599 | else |
|---|
| | 1600 | i_font_size = atoi( psz_value ); |
|---|
| | 1601 | } |
|---|
| | 1602 | else if( !strcasecmp( "color", psz_name ) && |
|---|
| | 1603 | ( psz_value[0] == '#' ) ) |
|---|
| | 1604 | { |
|---|
| | 1605 | i_font_color = strtol( psz_value + 1, NULL, 16 ); |
|---|
| | 1606 | i_font_color &= 0x00ffffff; |
|---|
| | 1607 | } |
|---|
| | 1608 | else if( !strcasecmp( "alpha", psz_name ) && |
|---|
| | 1609 | ( psz_value[0] == '#' ) ) |
|---|
| | 1610 | { |
|---|
| | 1611 | i_font_alpha = strtol( psz_value + 1, NULL, 16 ); |
|---|
| | 1612 | i_font_alpha &= 0xff; |
|---|
| | 1613 | } |
|---|
| | 1614 | free( psz_name ); |
|---|
| | 1615 | free( psz_value ); |
|---|
| | 1616 | } |
|---|
| | 1617 | } |
|---|
| | 1618 | rv = PushFont( p_fonts, |
|---|
| | 1619 | psz_fontname, |
|---|
| | 1620 | i_font_size, |
|---|
| | 1621 | i_font_color, |
|---|
| | 1622 | i_font_alpha ); |
|---|
| | 1623 | |
|---|
| | 1624 | free( psz_fontname ); |
|---|
| | 1625 | |
|---|
| | 1626 | return rv; |
|---|
| | 1627 | } |
|---|
| | 1628 | |
|---|
| | 1629 | static void SetupLine( filter_t *p_filter, const char *psz_text_in, |
|---|
| | 1630 | uint32_t **psz_text_out, uint32_t *pi_runs, |
|---|
| | 1631 | uint32_t **ppi_run_lengths, ft_style_t ***ppp_styles, |
|---|
| | 1632 | ft_style_t *p_style ) |
|---|
| | 1633 | { |
|---|
| | 1634 | uint32_t i_string_length = 0; |
|---|
| | 1635 | |
|---|
| | 1636 | IconvText( p_filter, psz_text_in, &i_string_length, psz_text_out ); |
|---|
| | 1637 | *psz_text_out += i_string_length; |
|---|
| | 1638 | |
|---|
| | 1639 | if( ppp_styles && ppi_run_lengths ) |
|---|
| | 1640 | { |
|---|
| | 1641 | (*pi_runs)++; |
|---|
| | 1642 | |
|---|
| | 1643 | if( *ppp_styles ) |
|---|
| | 1644 | { |
|---|
| | 1645 | *ppp_styles = (ft_style_t **) |
|---|
| | 1646 | realloc( *ppp_styles, *pi_runs * sizeof( ft_style_t * ) ); |
|---|
| | 1647 | } |
|---|
| | 1648 | else if( *pi_runs == 1 ) |
|---|
| | 1649 | { |
|---|
| | 1650 | *ppp_styles = (ft_style_t **) |
|---|
| | 1651 | malloc( *pi_runs * sizeof( ft_style_t * ) ); |
|---|
| | 1652 | } |
|---|
| | 1653 | |
|---|
| | 1654 | /* We have just malloc'ed this memory successfully - |
|---|
| | 1655 | * *pi_runs HAS to be within the memory area of *ppp_styles */ |
|---|
| | 1656 | if( *ppp_styles ) |
|---|
| | 1657 | { |
|---|
| | 1658 | (*ppp_styles)[ *pi_runs - 1 ] = p_style; |
|---|
| | 1659 | p_style = NULL; |
|---|
| | 1660 | } |
|---|
| | 1661 | |
|---|
| | 1662 | if( *ppi_run_lengths ) |
|---|
| | 1663 | { |
|---|
| | 1664 | *ppi_run_lengths = (uint32_t *) |
|---|
| | 1665 | realloc( *ppi_run_lengths, *pi_runs * sizeof( uint32_t ) ); |
|---|
| | 1666 | } |
|---|
| | 1667 | else if( *pi_runs == 1 ) |
|---|
| | 1668 | { |
|---|
| | 1669 | *ppi_run_lengths = (uint32_t *) |
|---|
| | 1670 | malloc( *pi_runs * sizeof( uint32_t ) ); |
|---|
| | 1671 | } |
|---|
| | 1672 | |
|---|
| | 1673 | /* same remarks here */ |
|---|
| | 1674 | if( *ppi_run_lengths ) |
|---|
| | 1675 | { |
|---|
| | 1676 | (*ppi_run_lengths)[ *pi_runs - 1 ] = i_string_length; |
|---|
| | 1677 | } |
|---|
| | 1678 | } |
|---|
| | 1679 | /* If we couldn't use the p_style argument due to memory allocation |
|---|
| | 1680 | * problems above, release it here. |
|---|
| | 1681 | */ |
|---|
| | 1682 | if( p_style ) DeleteStyle( p_style ); |
|---|
| | 1683 | } |
|---|
| | 1684 | |
|---|
| | 1685 | static int ProcessNodes( filter_t *p_filter, xml_reader_t *p_xml_reader, |
|---|
| | 1686 | text_style_t *p_font_style, uint32_t *psz_text, |
|---|
| | 1687 | int *pi_len, uint32_t *pi_runs, |
|---|
| | 1688 | uint32_t **ppi_run_lengths, ft_style_t ***ppp_styles) |
|---|
| | 1689 | { |
|---|
| | 1690 | int rv = VLC_SUCCESS; |
|---|
| | 1691 | filter_sys_t *p_sys = p_filter->p_sys; |
|---|
| | 1692 | uint32_t *psz_text_orig = psz_text; |
|---|
| | 1693 | font_stack_t *p_fonts = NULL; |
|---|
| | 1694 | |
|---|
| | 1695 | char *psz_node = NULL; |
|---|
| | 1696 | |
|---|
| 1535 | | { |
|---|
| 1536 | | char *psz_fontname = NULL; |
|---|
| 1537 | | int i_font_color = 0xffffff; |
|---|
| 1538 | | int i_font_alpha = 0; |
|---|
| 1539 | | int i_font_size = 24; |
|---|
| 1540 | | |
|---|
| 1541 | | /* Default all attributes to the top font in the stack -- in case not |
|---|
| 1542 | | * all attributes are specified in the sub-font |
|---|
| 1543 | | */ |
|---|
| 1544 | | if( VLC_SUCCESS == PeekFont( &p_fonts, &psz_fontname, &i_font_size, &i_font_color, &i_font_alpha )) |
|---|
| 1545 | | { |
|---|
| 1546 | | psz_fontname = strdup( psz_fontname ); |
|---|
| 1547 | | } |
|---|
| 1548 | | |
|---|
| 1549 | | while ( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) |
|---|
| 1550 | | { |
|---|
| 1551 | | char *psz_name = xml_ReaderName ( p_xml_reader ); |
|---|
| 1552 | | char *psz_value = xml_ReaderValue ( p_xml_reader ); |
|---|
| 1553 | | |
|---|
| 1554 | | if( psz_name && psz_value ) |
|---|
| 1555 | | { |
|---|
| 1556 | | if( !strcasecmp( "face", psz_name ) ) |
|---|
| 1557 | | { |
|---|
| 1558 | | if( psz_fontname ) free( psz_fontname ); |
|---|
| 1559 | | psz_fontname = strdup( psz_value ); |
|---|
| 1560 | | } |
|---|
| 1561 | | else if( !strcasecmp( "size", psz_name ) ) |
|---|
| 1562 | | { |
|---|
| 1563 | | i_font_size = atoi( psz_value ); |
|---|
| 1564 | | } |
|---|
| 1565 | | else if( !strcasecmp( "color", psz_name ) && |
|---|
| 1566 | | ( psz_value[0] == '#' ) ) |
|---|
| 1567 | | { |
|---|
| 1568 | | i_font_color = strtol( psz_value+1, NULL, 16 ); |
|---|
| 1569 | | i_font_color &= 0x00ffffff; |
|---|
| 1570 | | } |
|---|
| 1571 | | else if( !strcasecmp( "alpha", psz_name ) && |
|---|
| 1572 | | ( psz_value[0] == '#' ) ) |
|---|
| 1573 | | { |
|---|
| 1574 | | i_font_alpha = strtol( psz_value+1, NULL, 16 ); |
|---|
| 1575 | | i_font_alpha &= 0xff; |
|---|
| 1576 | | } |
|---|
| 1577 | | free( psz_name ); |
|---|
| 1578 | | free( psz_value ); |
|---|
| 1579 | | } |
|---|
| 1580 | | } |
|---|
| 1581 | | PushFont( &p_fonts, psz_fontname, i_font_size, i_font_color, i_font_alpha ); |
|---|
| 1582 | | free( psz_fontname ); |
|---|
| 1583 | | } |
|---|
| | 1755 | rv = HandleFontAttributes( p_xml_reader, &p_fonts ); |
|---|
| 1652 | | |
|---|
| 1653 | | if( FT_Select_Charmap( p_face ? p_face : p_sys->p_face, ft_encoding_unicode ) || |
|---|
| 1654 | | FT_Set_Pixel_Sizes( p_face ? p_face : p_sys->p_face, 0, i_font_size ) ) |
|---|
| 1655 | | { |
|---|
| 1656 | | free( psz_node ); |
|---|
| 1657 | | rv = VLC_EGENERIC; |
|---|
| 1658 | | break; |
|---|
| 1659 | | } |
|---|
| 1660 | | p_sys->i_use_kerning = FT_HAS_KERNING( ( p_face ? p_face : p_sys->p_face ) ); |
|---|
| 1661 | | |
|---|
| 1662 | | uint32_t *psz_unicode = IconvText( p_filter, psz_node ); |
|---|
| 1663 | | |
|---|
| 1664 | | if( !psz_unicode ) |
|---|
| 1665 | | { |
|---|
| 1666 | | free( psz_node ); |
|---|
| 1667 | | if( p_face ) FT_Done_Face( p_face ); |
|---|
| 1668 | | rv = VLC_EGENERIC; |
|---|
| 1669 | | break; |
|---|
| 1670 | | } |
|---|
| 1671 | | |
|---|
| 1672 | | while( *psz_unicode ) |
|---|
| 1673 | | { |
|---|
| 1674 | | if( !p_line ) |
|---|
| 1675 | | { |
|---|
| 1676 | | if( !(p_line = NewLine( (byte_t *)psz_html )) ) |
|---|
| 1677 | | { |
|---|
| 1678 | | msg_Err( p_filter, "out of memory" ); |
|---|
| 1679 | | free( psz_node ); |
|---|
| 1680 | | if( p_face ) FT_Done_Face( p_face ); |
|---|
| 1681 | | rv = VLC_EGENERIC; |
|---|
| 1682 | | break; |
|---|
| 1683 | | } |
|---|
| 1684 | | /* New Color mode only works in YUVA rendering mode -- |
|---|
| 1685 | | * (RGB mode has palette constraints on it). We therefore |
|---|
| 1686 | | * need to populate the legacy colour fields also. |
|---|
| 1687 | | */ |
|---|
| 1688 | | p_line->b_new_color_mode = VLC_TRUE; |
|---|
| 1689 | | p_line->i_alpha = i_font_alpha; |
|---|
| 1690 | | p_line->i_red = ( i_font_color & 0xff0000 ) >> 16; |
|---|
| 1691 | | p_line->i_green = ( i_font_color & 0x00ff00 ) >> 8; |
|---|
| 1692 | | p_line->i_blue = ( i_font_color & 0x0000ff ); |
|---|
| 1693 | | p_line->p_next = NULL; |
|---|
| 1694 | | i_pen_x = 0; |
|---|
| 1695 | | i_pen_y += tmp_result.y; |
|---|
| 1696 | | tmp_result.x = 0; |
|---|
| 1697 | | tmp_result.y = 0; |
|---|
| 1698 | | i_posn = 0; |
|---|
| 1699 | | if( p_prev ) p_prev->p_next = p_line; |
|---|
| 1700 | | else *p_lines = p_line; |
|---|
| 1701 | | } |
|---|
| 1702 | | |
|---|
| 1703 | | if( RenderTag( p_filter, p_face, i_font_color, b_uline, p_line, psz_unicode, &i_pen_x, i_pen_y, &i_posn, &tmp_result ) != VLC_SUCCESS ) |
|---|
| 1704 | | { |
|---|
| 1705 | | free( psz_node ); |
|---|
| 1706 | | if( p_face ) FT_Done_Face( p_face ); |
|---|
| 1707 | | rv = VLC_EGENERIC; |
|---|
| 1708 | | break; |
|---|
| 1709 | | } |
|---|
| 1710 | | if( *psz_unicode ) |
|---|
| 1711 | | { |
|---|
| 1712 | | p_result->x = __MAX( p_result->x, tmp_result.x ); |
|---|
| 1713 | | p_result->y += tmp_result.y; |
|---|
| 1714 | | |
|---|
| 1715 | | p_prev = p_line; |
|---|
| 1716 | | p_line = NULL; |
|---|
| 1717 | | } |
|---|
| 1718 | | } |
|---|
| 1719 | | if( rv != VLC_SUCCESS ) break; |
|---|
| 1720 | | |
|---|
| 1721 | | if( p_face ) FT_Done_Face( p_face ); |
|---|
| 1722 | | free( psz_unicode ); |
|---|
| | 1794 | SetupLine( p_filter, psz_node, &psz_text, |
|---|
| | 1795 | pi_runs, ppi_run_lengths, ppp_styles, |
|---|
| | 1796 | GetStyleFromFontStack( p_sys, |
|---|
| | 1797 | &p_fonts, |
|---|
| | 1798 | b_bold, |
|---|
| | 1799 | b_italic, |
|---|
| | 1800 | b_uline ) ); |
|---|
| 1727 | | } |
|---|
| | 1805 | if( rv != VLC_SUCCESS ) |
|---|
| | 1806 | { |
|---|
| | 1807 | psz_text = psz_text_orig; |
|---|
| | 1808 | break; |
|---|
| | 1809 | } |
|---|
| | 1810 | } |
|---|
| | 1811 | |
|---|
| | 1812 | *pi_len = psz_text - psz_text_orig; |
|---|
| | 1813 | |
|---|
| | 1814 | while( VLC_SUCCESS == PopFont( &p_fonts ) ); |
|---|
| | 1815 | |
|---|
| | 1816 | return rv; |
|---|
| | 1817 | } |
|---|
| | 1818 | |
|---|
| | 1819 | static int ProcessLines( filter_t *p_filter, uint32_t *psz_text, |
|---|
| | 1820 | int i_len, uint32_t i_runs, |
|---|
| | 1821 | uint32_t *pi_run_lengths, ft_style_t **pp_styles, |
|---|
| | 1822 | line_desc_t **pp_lines, FT_Vector *p_result ) |
|---|
| | 1823 | { |
|---|
| | 1824 | filter_sys_t *p_sys = p_filter->p_sys; |
|---|
| | 1825 | ft_style_t **pp_char_styles; |
|---|
| | 1826 | uint32_t i, j, k; |
|---|
| | 1827 | int i_prev; |
|---|
| | 1828 | |
|---|
| | 1829 | /* Assign each character in the text string its style explicitly, so that |
|---|
| | 1830 | * after the characters have been shuffled around by Fribidi, we can re-apply |
|---|
| | 1831 | * the styles, and to simplify the calculation of runs within a line. |
|---|
| | 1832 | */ |
|---|
| | 1833 | pp_char_styles = (ft_style_t **) malloc( i_len * sizeof( ft_style_t * )); |
|---|
| | 1834 | if( !pp_char_styles ) |
|---|
| | 1835 | return VLC_ENOMEM; |
|---|
| | 1836 | |
|---|
| | 1837 | i = 0; |
|---|
| | 1838 | for( j = 0; j < i_runs; j++ ) |
|---|
| | 1839 | for( k = 0; k < pi_run_lengths[ j ]; k++ ) |
|---|
| | 1840 | pp_char_styles[ i++ ] = pp_styles[ j ]; |
|---|
| | 1841 | |
|---|
| | 1842 | #if defined(HAVE_FRIBIDI) |
|---|
| | 1843 | { |
|---|
| | 1844 | ft_style_t **pp_char_styles_new; |
|---|
| | 1845 | int *p_positions; |
|---|
| | 1846 | uint32_t *p_fribidi_string; |
|---|
| | 1847 | int start_pos, pos = 0; |
|---|
| | 1848 | |
|---|
| | 1849 | p_fribidi_string = malloc( (i_len + 1) * sizeof(uint32_t) ); |
|---|
| | 1850 | if(! p_fribidi_string ) |
|---|
| | 1851 | { |
|---|
| | 1852 | msg_Err( p_filter, "out of memory" ); |
|---|
| | 1853 | free( pp_char_styles ); |
|---|
| | 1854 | return VLC_ENOMEM; |
|---|
| | 1855 | } |
|---|
| | 1856 | pp_char_styles_new = (ft_style_t **) |
|---|
| | 1857 | malloc( i_len * sizeof( ft_style_t * )); |
|---|
| | 1858 | if(! pp_char_styles_new ) |
|---|
| | 1859 | { |
|---|
| | 1860 | msg_Err( p_filter, "out of memory" ); |
|---|
| | 1861 | free( p_fribidi_string ); |
|---|
| | 1862 | free( pp_char_styles ); |
|---|
| | 1863 | return VLC_ENOMEM; |
|---|
| | 1864 | } |
|---|
| | 1865 | p_positions = (int *) malloc( (i_len + 1) * sizeof( int ) ); |
|---|
| | 1866 | if(! p_positions ) |
|---|
| | 1867 | { |
|---|
| | 1868 | msg_Err( p_filter, "out of memory" ); |
|---|
| | 1869 | free( pp_char_styles_new ); |
|---|
| | 1870 | free( p_fribidi_string ); |
|---|
| | 1871 | free( pp_char_styles ); |
|---|
| | 1872 | return VLC_ENOMEM; |
|---|
| | 1873 |
|---|