+ uint8_t buf[30], *p = buf;
+
+ // 0x00, 0x00, 0x00, 0x00, // uint32_t displayFlags
+ // 0x01, // int8_t horizontal-justification
+ // 0xFF, // int8_t vertical-justification
+ // 0x00, 0x00, 0x00, 0x00, // uint8_t background-color-rgba[4]
+ // BoxRecord {
+ // 0x00, 0x00, // int16_t top
+ // 0x00, 0x00, // int16_t left
+ // 0x00, 0x00, // int16_t bottom
+ // 0x00, 0x00, // int16_t right
+ // };
+ // StyleRecord {
+ // 0x00, 0x00, // uint16_t startChar
+ // 0x00, 0x00, // uint16_t endChar
+ // 0x00, 0x01, // uint16_t font-ID
+ // 0x00, // uint8_t face-style-flags
+ // 0x12, // uint8_t font-size
+ // 0xFF, 0xFF, 0xFF, 0xFF, // uint8_t text-color-rgba[4]
+ // };
+ // FontTableBox {
+ // 0x00, 0x00, 0x00, 0x12, // uint32_t size
+ // 'f', 't', 'a', 'b', // uint8_t name[4]
+ // 0x00, 0x01, // uint16_t entry-count
+ // FontRecord {
+ // 0x00, 0x01, // uint16_t font-ID
+ // 0x05, // uint8_t font-name-length
+ // 'S', 'e', 'r', 'i', 'f',// uint8_t font[font-name-length]
+ // };
+ // };
+
+ // Populate sample description from ASS header
+ ass = (ASS*)s->ass_ctx;
+ // Compute font scaling factor based on (optionally) provided
+ // output video height and ASS script play_res_y
+ if (s->frame_height && ass->script_info.play_res_y)
+ s->font_scale_factor = (double)s->frame_height / ass->script_info.play_res_y;
+ else
+ s->font_scale_factor = 1;
+
+ style = ff_ass_style_get(s->ass_ctx, "Default");
+ if (!style && ass->styles_count) {
+ style = &ass->styles[0];
+ }
+ s->d.style_fontID = DEFAULT_STYLE_FONT_ID;
+ s->d.style_fontsize = DEFAULT_STYLE_FONTSIZE;
+ s->d.style_color = DEFAULT_STYLE_COLOR;
+ s->d.style_flag = DEFAULT_STYLE_FLAG;
+ if (style) {
+ s->d.style_fontsize = FONTSIZE_SCALE(s, style->font_size);
+ s->d.style_color = BGR_TO_RGB(style->primary_color & 0xffffff) << 8 |
+ 255 - ((uint32_t)style->primary_color >> 24);
+ s->d.style_flag = (!!style->bold * STYLE_FLAG_BOLD) |
+ (!!style->italic * STYLE_FLAG_ITALIC) |
+ (!!style->underline * STYLE_FLAG_UNDERLINE);
+ back_color = (BGR_TO_RGB(style->back_color & 0xffffff) << 8) |
+ (255 - ((uint32_t)style->back_color >> 24));
+ }
+
+ bytestream_put_be32(&p, 0); // displayFlags
+ bytestream_put_be16(&p, 0x01FF); // horizontal/vertical justification (2x int8_t)
+ bytestream_put_be32(&p, back_color);
+ bytestream_put_be64(&p, 0); // BoxRecord - 4xint16_t: top, left, bottom, right
+ // StyleRecord {
+ bytestream_put_be16(&p, s->d.style_start);
+ bytestream_put_be16(&p, s->d.style_end);
+ bytestream_put_be16(&p, s->d.style_fontID);
+ bytestream_put_byte(&p, s->d.style_flag);
+ bytestream_put_byte(&p, s->d.style_fontsize);
+ bytestream_put_be32(&p, s->d.style_color);
+ // };
+ av_bprint_append_any(&s->buffer, buf, 30);
+
+ // Build font table
+ // We can't build a complete font table since that would require
+ // scanning all dialogs first. But we can at least fill in what
+ // is avaiable in the ASS header
+ if (style && ass->styles_count) {
+ // Find unique font names
+ if (style->font_name) {
+ av_dynarray_add(&s->fonts, &s->font_count, style->font_name);
+ font_names_total_len += strlen(style->font_name);
+ }
+ for (i = 0; i < ass->styles_count; i++) {
+ int found = 0;
+ if (!ass->styles[i].font_name)
+ continue;
+ for (j = 0; j < s->font_count; j++) {
+ if (!strcmp(s->fonts[j], ass->styles[i].font_name)) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ av_dynarray_add(&s->fonts, &s->font_count,
+ ass->styles[i].font_name);
+ font_names_total_len += strlen(ass->styles[i].font_name);
+ }
+ }
+ } else
+ av_dynarray_add(&s->fonts, &s->font_count, (char*)"Serif");
+
+ // FontTableBox {
+ p = buf;
+ bytestream_put_be32(&p, SIZE_ADD + 3 * s->font_count + font_names_total_len); // Size
+ bytestream_put_be32(&p, MKBETAG('f','t','a','b'));
+ bytestream_put_be16(&p, s->font_count);
+
+ av_bprint_append_any(&s->buffer, buf, 10);
+ // FontRecord {
+ for (i = 0; i < s->font_count; i++) {
+ size_t len = strlen(s->fonts[i]);
+
+ p = buf;
+ bytestream_put_be16(&p, i + 1); //fontID
+ bytestream_put_byte(&p, len);
+
+ av_bprint_append_any(&s->buffer, buf, 3);
+ av_bprint_append_any(&s->buffer, s->fonts[i], len);
+ }
+ // };
+ // };
+
+ if (!av_bprint_is_complete(&s->buffer)) {
+ return AVERROR(ENOMEM);
+ }