summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2015-04-05 20:20:28 +0000
committerjstebbins <[email protected]>2015-04-05 20:20:28 +0000
commit75e81dbbaafa76dfde25343f50563aed8c7776e7 (patch)
tree0a77a01ccc250a10518505ba6df0e122e59e3cee
parent52f3c7354980d3f0467c7d8db7361d6009ab7d06 (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.c7
-rw-r--r--libhb/common.h3
-rw-r--r--libhb/deccc608sub.c108
-rw-r--r--libhb/decsrtsub.c2
-rw-r--r--libhb/dectx3gsub.c2
-rw-r--r--libhb/decutf8sub.c2
-rw-r--r--libhb/rendersub.c20
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 );