+ *psz_text++ = *psz_subtitle;
+ }
+
+ psz_subtitle++;
+ }
+ *psz_text = '\0';
+ char *psz = realloc( psz_text_start, strlen( psz_text_start ) + 1 );
+ if( psz ) psz_text_start = psz;
+
+ return psz_text_start;
+}
+
+/* Try to respect any style tags present in the subtitle string. The main
+ * problem here is a lack of adequate specs for the subtitle formats.
+ * SSA/ASS and USF are both detail spec'ed -- but they are handled elsewhere.
+ * SAMI has a detailed spec, but extensive rework is needed in the demux
+ * code to prevent all this style information being excised, as it presently
+ * does.
+ * That leaves the others - none of which were (I guess) originally intended
+ * to be carrying style information. Over time people have used them that way.
+ * In the absence of specifications from which to work, the tags supported
+ * have been restricted to the simple set permitted by the USF DTD, ie. :
+ * Basic: <br>, <i>, <b>, <u>, <s>
+ * Extended: <font>
+ * Attributes: face
+ * family
+ * size
+ * color
+ * outline-color
+ * shadow-color
+ * outline-level
+ * shadow-level
+ * back-color
+ * alpha
+ * There is also the further restriction that the subtitle be well-formed
+ * as an XML entity, ie. the HTML sentence:
+ * <b><i>Bold and Italics</b></i>
+ * doesn't qualify because the tags aren't nested one inside the other.
+ * <text> tags are automatically added to the output to ensure
+ * well-formedness.
+ * If the text doesn't qualify for any reason, a NULL string is
+ * returned, and the rendering engine will fall back to the
+ * plain text version of the subtitle.
+ */
+static void HtmlNPut( char **ppsz_html, const char *psz_text, int i_max )
+{
+ const int i_len = strlen(psz_text);
+
+ strncpy( *ppsz_html, psz_text, i_max );
+ *ppsz_html += __MIN(i_max,i_len);
+}
+
+static void HtmlPut( char **ppsz_html, const char *psz_text )
+{
+ strcpy( *ppsz_html, psz_text );
+ *ppsz_html += strlen(psz_text);
+}
+static void HtmlCopy( char **ppsz_html, char **ppsz_subtitle, const char *psz_text )
+{
+ HtmlPut( ppsz_html, psz_text );
+ *ppsz_subtitle += strlen(psz_text);
+}
+
+static char *CreateHtmlSubtitle( int *pi_align, char *psz_subtitle )
+{
+ /* */
+ char *psz_tag = malloc( ( strlen( psz_subtitle ) / 3 ) + 1 );
+ if( !psz_tag )
+ return NULL;
+ psz_tag[ 0 ] = '\0';
+
+ /* */
+ //Oo + 100 ???
+ size_t i_buf_size = strlen( psz_subtitle ) + 100;
+ char *psz_html_start = malloc( i_buf_size );
+ char *psz_html = psz_html_start;
+ if( psz_html_start == NULL )
+ {
+ free( psz_tag );
+ return NULL;
+ }
+ psz_html[0] = '\0';
+
+ bool b_has_align = false;
+
+ HtmlPut( &psz_html, "<text>" );
+
+ /* */
+ while( *psz_subtitle )
+ {
+ if( *psz_subtitle == '\n' )
+ {
+ HtmlPut( &psz_html, "<br/>" );
+ psz_subtitle++;
+ }
+ else if( *psz_subtitle == '<' )
+ {
+ if( !strncasecmp( psz_subtitle, "<br/>", 5 ))
+ {
+ HtmlCopy( &psz_html, &psz_subtitle, "<br/>" );
+ }
+ else if( !strncasecmp( psz_subtitle, "<b>", 3 ) )
+ {
+ HtmlCopy( &psz_html, &psz_subtitle, "<b>" );
+ strcat( psz_tag, "b" );
+ }
+ else if( !strncasecmp( psz_subtitle, "<i>", 3 ) )
+ {
+ HtmlCopy( &psz_html, &psz_subtitle, "<i>" );
+ strcat( psz_tag, "i" );
+ }
+ else if( !strncasecmp( psz_subtitle, "<u>", 3 ) )
+ {
+ HtmlCopy( &psz_html, &psz_subtitle, "<u>" );
+ strcat( psz_tag, "u" );
+ }
+ else if( !strncasecmp( psz_subtitle, "<s>", 3 ) )
+ {
+ HtmlCopy( &psz_html, &psz_subtitle, "<s>" );
+ strcat( psz_tag, "s" );
+ }
+ else if( !strncasecmp( psz_subtitle, "<font ", 6 ))
+ {
+ const char *psz_attribs[] = { "face=", "family=", "size=",
+ "color=", "outline-color=", "shadow-color=",
+ "outline-level=", "shadow-level=", "back-color=",
+ "alpha=", NULL };
+
+ HtmlCopy( &psz_html, &psz_subtitle, "<font " );
+ strcat( psz_tag, "f" );
+
+ while( *psz_subtitle != '>' )
+ {
+ int k;
+
+ for( k=0; psz_attribs[ k ]; k++ )
+ {
+ int i_len = strlen( psz_attribs[ k ] );
+
+ if( !strncasecmp( psz_subtitle, psz_attribs[k], i_len ) )
+ {
+ /* */
+ HtmlPut( &psz_html, psz_attribs[k] );
+ psz_subtitle += i_len;
+
+ /* */
+ if( *psz_subtitle == '"' )
+ {
+ psz_subtitle++;
+ i_len = strcspn( psz_subtitle, "\"" );
+ }
+ else
+ {
+ i_len = strcspn( psz_subtitle, " \t>" );
+ }
+ HtmlPut( &psz_html, "\"" );
+ if( !strcmp( psz_attribs[ k ], "color=" ) && *psz_subtitle >= '0' && *psz_subtitle <= '9' )
+ HtmlPut( &psz_html, "#" );
+ HtmlNPut( &psz_html, psz_subtitle, i_len );
+ HtmlPut( &psz_html, "\"" );
+
+ psz_subtitle += i_len;
+ if( *psz_subtitle == '\"' )
+ psz_subtitle++;
+ break;
+ }
+ }
+ if( psz_attribs[ k ] == NULL )
+ {
+ /* Jump over unrecognised tag */
+ int i_len = strcspn( psz_subtitle, "\"" );
+ if( psz_subtitle[i_len] == '\"' )
+ {
+ i_len += 1 + strcspn( &psz_subtitle[i_len + 1], "\"" );
+ if( psz_subtitle[i_len] == '\"' )
+ i_len++;
+ }
+ psz_subtitle += i_len;
+ }
+ while (*psz_subtitle == ' ')
+ *psz_html++ = *psz_subtitle++;
+ }
+ *psz_html++ = *psz_subtitle++;
+ }
+ else if( !strncmp( psz_subtitle, "</", 2 ))