diff options
author | jstebbins <jstebbins.hb@gmail.com> | 2015-04-05 20:20:28 +0000 |
---|---|---|
committer | jstebbins <jstebbins.hb@gmail.com> | 2015-04-05 20:20:28 +0000 |
commit | 75e81dbbaafa76dfde25343f50563aed8c7776e7 (patch) | |
tree | 0a77a01ccc250a10518505ba6df0e122e59e3cee | |
parent | 52f3c7354980d3f0467c7d8db7361d6009ab7d06 (diff) |
deccc608sub: fix column alignment issues
Use a fixed width font, and insert hard spaces where necessary to allign
columns correctly in multi-line CCs.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@7061 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | libhb/common.c | 7 | ||||
-rw-r--r-- | libhb/common.h | 3 | ||||
-rw-r--r-- | libhb/deccc608sub.c | 108 | ||||
-rw-r--r-- | libhb/decsrtsub.c | 2 | ||||
-rw-r--r-- | libhb/dectx3gsub.c | 2 | ||||
-rw-r--r-- | libhb/decutf8sub.c | 2 | ||||
-rw-r--r-- | libhb/rendersub.c | 20 |
7 files changed, 92 insertions, 52 deletions
diff --git a/libhb/common.c b/libhb/common.c index 7d97a0da0..053a4c4c2 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -3764,7 +3764,8 @@ void hb_subtitle_close( hb_subtitle_t **sub ) ********************************************************************** * *********************************************************************/ -int hb_subtitle_add_ssa_header(hb_subtitle_t *subtitle, int w, int h) +int hb_subtitle_add_ssa_header(hb_subtitle_t *subtitle, const char *font, + int w, int h) { // Free any pre-existing extradata free(subtitle->extradata); @@ -3784,9 +3785,9 @@ int hb_subtitle_add_ssa_header(hb_subtitle_t *subtitle, int w, int h) "\r\n" "[V4+ Styles]\r\n" "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\r\n" - "Style: Default,Arial,%d,&H00FFFFFF,&H00FFFFFF,&H000F0F0F,&H000F0F0F,0,0,0,0,100,100,0,0.00,1,2,3,2,20,20,20,0\r\n"; + "Style: Default,%s,%d,&H00FFFFFF,&H00FFFFFF,&H000F0F0F,&H000F0F0F,0,0,0,0,100,100,0,0.00,1,2,3,2,20,20,20,0\r\n"; - subtitle->extradata = (uint8_t*)hb_strdup_printf(ssa_header, w, h, fs); + subtitle->extradata = (uint8_t*)hb_strdup_printf(ssa_header, w, h, font, fs); if (subtitle->extradata == NULL) { hb_error("hb_subtitle_add_ssa_header: malloc failed"); diff --git a/libhb/common.h b/libhb/common.h index 60ef9cc82..ac5692642 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -158,7 +158,8 @@ void hb_audio_config_init(hb_audio_config_t * audiocfg); int hb_audio_add(const hb_job_t * job, const hb_audio_config_t * audiocfg); hb_audio_config_t * hb_list_audio_config_item(hb_list_t * list, int i); -int hb_subtitle_add_ssa_header(hb_subtitle_t *subtitle, int width, int height); +int hb_subtitle_add_ssa_header(hb_subtitle_t *subtitle, const char *font, + int width, int height); hb_subtitle_t *hb_subtitle_copy(const hb_subtitle_t *src); hb_list_t *hb_subtitle_list_copy(const hb_list_t *src); void hb_subtitle_close( hb_subtitle_t **sub ); diff --git a/libhb/deccc608sub.c b/libhb/deccc608sub.c index f75a8fa90..0a63d1e9c 100644 --- a/libhb/deccc608sub.c +++ b/libhb/deccc608sub.c @@ -563,6 +563,17 @@ static unsigned encode_line(unsigned char *buffer, unsigned char *text) return bytes; } +static unsigned stuff_space(unsigned char *buffer, int space) +{ + int ii; + for (ii = 0; ii < space; ii++) + { + *buffer++ = '\\'; + *buffer++ = 'h'; + } + return space * 2; +} + static void find_limit_characters(unsigned char *line, int *first_non_blank, int *last_non_blank) { @@ -798,7 +809,6 @@ static int write_cc_buffer_as_ssa(struct eia608_screen *data, int i; int64_t ms_start = wb->data608->current_visible_start_ms; //int64_t ms_end = get_last_pts(wb) + subs_delay; - int row = -1, col = -1; ms_start += subs_delay; if (ms_start<0) // Drop screens that because of subs_delay start too early @@ -820,6 +830,8 @@ static int write_cc_buffer_as_ssa(struct eia608_screen *data, * and have a big bottom line (strip spaces from any joined lines). */ int rows = 0, columns = 0; + int min_row = 15, max_row = 0; + int min_col = 31, max_col = 0; for (i = 0; i < 15; i++) { if (data->row_used[i]) @@ -830,76 +842,86 @@ static int write_cc_buffer_as_ssa(struct eia608_screen *data, find_limit_characters(data->characters[i], &first, &last); if (last - first + 1 > columns) columns = last - first + 1; + if (min_col > first) + min_col = first; + if (min_row > i) + min_row = i; + if (max_col < last) + max_col = last; + if (max_row < i) + max_row = i; } } wb->prev_font_style = FONT_REGULAR; wb->prev_font_color = COL_WHITE; wb->enc_buffer_used = 0; + + int cropped_width, cropped_height, font_size, safe_zone; + int cell_width, cell_height; + + // CC grid is 16 rows by 32 colums + // Our SSA resolution is the title resolution + // Tranlate CC grid to SSA coordinates + // The numbers are tweaked to keep things off the very + // edges of the screen and in the "safe" zone + cropped_height = wb->height - wb->crop[0] - wb->crop[1]; + cropped_width = wb->width - wb->crop[2] - wb->crop[3]; + font_size = cropped_height * .066; + + safe_zone = cropped_height * 0.025; + cell_height = (wb->height - 2 * safe_zone) / 16; + cell_width = (wb->width - 2 * safe_zone) / 32; + + char *pos; + int y, x, top; + y = cell_height * (min_row + 1 + rows) + safe_zone - wb->crop[0]; + x = cell_width * min_col + safe_zone - wb->crop[2]; + top = y - rows * font_size; + + if (top < safe_zone) + y = (rows * font_size) + safe_zone; + if (y > cropped_height - safe_zone) + y = cropped_height - safe_zone; + if (x + columns * cell_width > cropped_width - safe_zone) + x = cropped_width - columns * cell_width - safe_zone; + if (x < safe_zone) + x = safe_zone; + pos = hb_strdup_printf("{\\a1\\pos(%d,%d)}", x, y); + int line = 1; for (i = 0; i < 15; i++) { if (data->row_used[i]) { + int first, last; // Get position for this CC - if (row == -1) - { - int last, x, y, top, safe_zone, cell_width, cell_height; - int cropped_width, cropped_height, font_size; - char *pos; - - row = i; - find_limit_characters(data->characters[i], &col, &last); - - // CC grid is 16 rows by 62 colums - // Our SSA resolution is the title resolution - // Tranlate CC grid to SSA coordinates - // The numbers are tweaked to keep things off the very - // edges of the screen and in the "safe" zone - cropped_height = wb->height - wb->crop[0] - wb->crop[1]; - cropped_width = wb->width - wb->crop[2] - wb->crop[3]; - font_size = cropped_height * .066; - - safe_zone = cropped_height * 0.025; - cell_height = (wb->height - 2 * safe_zone) / 16; - cell_width = (wb->width - 2 * safe_zone) / 32; - - // Calculate position assuming the position defines - // the baseline of the text which is lower left corner - // of bottom row of characters - y = cell_height * (row + 1 + rows) + safe_zone - wb->crop[0]; - top = y - rows * font_size; - x = cell_width * col + safe_zone - wb->crop[2]; - if (top < safe_zone) - y = (rows * font_size) + safe_zone; - if (y > cropped_height - safe_zone) - y = cropped_height - safe_zone; - if (x + columns * cell_width > cropped_width - safe_zone) - x = cropped_width - columns * cell_width - safe_zone; - if (x < safe_zone) - x = safe_zone; - pos = hb_strdup_printf("{\\a1\\pos(%d,%d)}", x, y); - wb->enc_buffer_used += encode_line( - wb->enc_buffer + wb->enc_buffer_used, (uint8_t*)pos); - free(pos); - } + find_limit_characters(data->characters[i], &first, &last); /* * The intention was to use a newline but QT doesn't like it, * old code still here just in case.. */ + int space = first - min_col; if (line == 1) { + wb->enc_buffer_used += encode_line( + wb->enc_buffer + wb->enc_buffer_used, (uint8_t*)pos); + wb->enc_buffer_used += stuff_space( + wb->enc_buffer + wb->enc_buffer_used, space); wb->enc_buffer_used += get_decoder_line_encoded(wb, wb->enc_buffer + wb->enc_buffer_used, i, data); line = 2; } else { wb->enc_buffer_used += encode_line( wb->enc_buffer + wb->enc_buffer_used, (uint8_t*)"\\N"); + wb->enc_buffer_used += stuff_space( + wb->enc_buffer + wb->enc_buffer_used, space); wb->enc_buffer_used += get_decoder_line_encoded(wb, wb->enc_buffer + wb->enc_buffer_used, i, data); } } } + free(pos); if (wb->enc_buffer_used && wb->enc_buffer[0] != 0 && data->dirty) { hb_buffer_t *buffer; @@ -1761,7 +1783,7 @@ static int decccInit( hb_work_object_t * w, hb_job_t * job ) // Generate generic SSA Script Info. int height = job->title->geometry.height - job->crop[0] - job->crop[1]; int width = job->title->geometry.width - job->crop[2] - job->crop[3]; - hb_subtitle_add_ssa_header(w->subtitle, width, height); + hb_subtitle_add_ssa_header(w->subtitle, "Courier New", width, height); } // When rendering subs, we need to push rollup subtitles out // asap (instead of waiting for a completed line) so that we diff --git a/libhb/decsrtsub.c b/libhb/decsrtsub.c index d3f44a5bc..88c6def92 100644 --- a/libhb/decsrtsub.c +++ b/libhb/decsrtsub.c @@ -699,7 +699,7 @@ static int decsrtInit( hb_work_object_t * w, hb_job_t * job ) // Generate generic SSA Script Info. int height = job->title->geometry.height - job->crop[0] - job->crop[1]; int width = job->title->geometry.width - job->crop[2] - job->crop[3]; - hb_subtitle_add_ssa_header(w->subtitle, width, height); + hb_subtitle_add_ssa_header(w->subtitle, "Arial", width, height); } return retval; } diff --git a/libhb/dectx3gsub.c b/libhb/dectx3gsub.c index 7207feef8..cd121ac70 100644 --- a/libhb/dectx3gsub.c +++ b/libhb/dectx3gsub.c @@ -250,7 +250,7 @@ static int dectx3gInit( hb_work_object_t * w, hb_job_t * job ) // For now we just create a generic SSA Script Info. int height = job->title->geometry.height - job->crop[0] - job->crop[1]; int width = job->title->geometry.width - job->crop[2] - job->crop[3]; - hb_subtitle_add_ssa_header(w->subtitle, width, height); + hb_subtitle_add_ssa_header(w->subtitle, "Arial", width, height); return 0; } diff --git a/libhb/decutf8sub.c b/libhb/decutf8sub.c index 27b14b640..29c90383d 100644 --- a/libhb/decutf8sub.c +++ b/libhb/decutf8sub.c @@ -37,7 +37,7 @@ static int decutf8Init(hb_work_object_t *w, hb_job_t *job) // Generate generic SSA Script Info. int height = job->title->geometry.height - job->crop[0] - job->crop[1]; int width = job->title->geometry.width - job->crop[2] - job->crop[3]; - hb_subtitle_add_ssa_header(w->subtitle, width, height); + hb_subtitle_add_ssa_header(w->subtitle, "Arial", width, height); return 0; } diff --git a/libhb/rendersub.c b/libhb/rendersub.c index 960609aef..006f4f156 100644 --- a/libhb/rendersub.c +++ b/libhb/rendersub.c @@ -53,6 +53,7 @@ static void ssa_close( hb_filter_object_t * filter ); // SRT static int textsub_post_init( hb_filter_object_t * filter, hb_job_t * job ); +static int cc608sub_post_init( hb_filter_object_t * filter, hb_job_t * job ); static int textsub_work( hb_filter_object_t * filter, hb_buffer_t ** buf_in, @@ -589,13 +590,24 @@ static int ssa_work( hb_filter_object_t * filter, return HB_FILTER_OK; } +static int cc608sub_post_init( hb_filter_object_t * filter, hb_job_t * job ) +{ + // Text subtitles for which we create a dummy ASS header need + // to have the header rewritten with the correct dimensions. + int height = job->title->geometry.height - job->crop[0] - job->crop[1]; + int width = job->title->geometry.width - job->crop[2] - job->crop[3]; + // Use fixed widht font for CC + hb_subtitle_add_ssa_header(filter->subtitle, "Courier New", width, height); + return ssa_post_init(filter, job); +} + static int textsub_post_init( hb_filter_object_t * filter, hb_job_t * job ) { // Text subtitles for which we create a dummy ASS header need // to have the header rewritten with the correct dimensions. int height = job->title->geometry.height - job->crop[0] - job->crop[1]; int width = job->title->geometry.width - job->crop[2] - job->crop[3]; - hb_subtitle_add_ssa_header(filter->subtitle, width, height); + hb_subtitle_add_ssa_header(filter->subtitle, "Arial", width, height); return ssa_post_init(filter, job); } @@ -872,13 +884,17 @@ static int hb_rendersub_post_init( hb_filter_object_t * filter, hb_job_t *job ) } break; case SRTSUB: - case CC608SUB: case UTF8SUB: case TX3GSUB: { return textsub_post_init( filter, job ); } break; + case CC608SUB: + { + return cc608sub_post_init( filter, job ); + } break; + case PGSSUB: { return pgssub_post_init( filter, job ); |