[MPlayer-dev-eng] [PATCH] subtitles alignment
Salvatore Falco
sfalco at studenti.ing.uniroma1.it
Wed Feb 9 15:23:04 CET 2005
> This patch is the extension of the previous one, not yet applied.
Yeah, right, the patch...
-------------- next part --------------
diff -Nur MPlayer-20050209/AUTHORS MPlayer-20050209.patch/AUTHORS
--- MPlayer-20050209/AUTHORS 2005-02-05 15:00:47.000000000 +0100
+++ MPlayer-20050209.patch/AUTHORS 2005-02-09 14:10:02.929435344 +0100
@@ -217,6 +217,7 @@
* jacosub parsing & dump support
* overlapping subtitles & sub sorting support
* SAMI subtitles dump support
+ * subtitle alignment: handling code + SAMI & JACOsub
Feigl, Johannes (jaf) <johannes.feigl at aon.at>
* original German docs translation (outdated)
diff -Nur MPlayer-20050209/libvo/sub.c MPlayer-20050209.patch/libvo/sub.c
--- MPlayer-20050209/libvo/sub.c 2004-10-28 03:15:52.000000000 +0200
+++ MPlayer-20050209.patch/libvo/sub.c 2005-02-09 14:10:02.930435192 +0100
@@ -653,43 +653,62 @@
y = obj->y;
- obj->alignment = 0;
- switch(vo_sub->alignment) {
- case SUB_ALIGNMENT_BOTTOMLEFT:
- case SUB_ALIGNMENT_MIDDLELEFT:
- case SUB_ALIGNMENT_TOPLEFT:
- obj->alignment |= 0x1;
- break;
- case SUB_ALIGNMENT_BOTTOMRIGHT:
- case SUB_ALIGNMENT_MIDDLERIGHT:
- case SUB_ALIGNMENT_TOPRIGHT:
- obj->alignment |= 0x2;
- break;
- case SUB_ALIGNMENT_BOTTOMCENTER:
- case SUB_ALIGNMENT_MIDDLECENTER:
- case SUB_ALIGNMENT_TOPCENTER:
- default:
- obj->alignment |= 0x0;
+ obj->alignment = vo_sub->alignment;
+ for(counter = 0; counter < obj->params.subtitle.lines; ++counter) {
+ obj->params.subtitle.xtbl[counter] -= obj->bbox.x1;
+ }
+
+ switch (obj->alignment&SUB_ALIGNMENT_HORIZONTAL) {
+ case SUB_ALIGNMENT_PHLEFT:
+ obj->bbox.x2 -= obj->bbox.x1 - 1;
+ obj->bbox.x1 = 1;
+ break;
+ case SUB_ALIGNMENT_PHCENTER:
+ default:
+ break;
+ case SUB_ALIGNMENT_PHRIGHT:
+ obj->bbox.x1 += dxs - 1 - obj->bbox.x2;
+ obj->bbox.x2 = dxs - 1;
+ break;
+ }
+
+
+ switch (obj->alignment&SUB_ALIGNMENT_VERTICAL) {
+ case SUB_ALIGNMENT_PVTOP:
+ obj->bbox.y1 = 1;
+ break;
+ case SUB_ALIGNMENT_PVMIDDLE:
+ obj->bbox.y1 = (dys - h) / 2;
+ break;
+ case SUB_ALIGNMENT_PVBOTTOM:
+ default:
+ obj->bbox.y1 = dys - h - 1;
+ break;
}
+ y = obj->y = obj->bbox.y1;
+ obj->bbox.y2 = obj->bbox.y1 + h;
i=j=0;
if ((l = obj->params.subtitle.lines)) {
for(counter = dxs; i < l; ++i)
if (obj->params.subtitle.xtbl[i] < counter) counter = obj->params.subtitle.xtbl[i];
for (i = 0; i < l; ++i) {
- switch (obj->alignment&0x3) {
- case 1:
+ switch (obj->alignment&SUB_ALIGNMENT_BLOCK) {
+ case SUB_ALIGNMENT_BLEFT:
// left
x = counter;
break;
- case 2:
+ case SUB_ALIGNMENT_BRIGHT:
// right
x = 2 * obj->params.subtitle.xtbl[i] - counter - ((obj->params.subtitle.xtbl[i] == counter) ? 0 : 1);
break;
+ case SUB_ALIGNMENT_BCENTER:
+ case SUB_ALIGNMENT_BJUSTIFY:
default:
- //center
+ //center or justify
x = obj->params.subtitle.xtbl[i];
}
+ x += obj->bbox.x1;
prevc = -1;
while ((c=obj->params.subtitle.utbl[j++])){
x += kerning(vo_font,prevc,c);
diff -Nur MPlayer-20050209/subreader.c MPlayer-20050209.patch/subreader.c
--- MPlayer-20050209/subreader.c 2005-02-04 19:31:03.000000000 +0100
+++ MPlayer-20050209.patch/subreader.c 2005-02-09 14:20:10.999994568 +0100
@@ -101,7 +101,7 @@
int state;
current->lines = current->start = current->end = 0;
- current->alignment = SUB_ALIGNMENT_BOTTOMCENTER;
+ current->alignment = SUB_ALIGNMENT_PVBOTTOM|SUB_ALIGNMENT_PHCENTER|SUB_ALIGNMENT_BCENTER;
state = 0;
/* read the first line */
@@ -177,35 +177,51 @@
break;
case 5: /* get rid of {...} text, but read the alignment code */
if ((*s == '\\') && (*(s + 1) == 'a') && !sub_no_text_pp) {
- if (stristr(s, "\\a1") != NULL) {
- current->alignment = SUB_ALIGNMENT_BOTTOMLEFT;
- s = s + 3;
- }
- if (stristr(s, "\\a2") != NULL) {
- current->alignment = SUB_ALIGNMENT_BOTTOMCENTER;
- s = s + 3;
- } else if (stristr(s, "\\a3") != NULL) {
- current->alignment = SUB_ALIGNMENT_BOTTOMRIGHT;
- s = s + 3;
- } else if ((stristr(s, "\\a4") != NULL) || (stristr(s, "\\a5") != NULL) || (stristr(s, "\\a8") != NULL)) {
- current->alignment = SUB_ALIGNMENT_TOPLEFT;
- s = s + 3;
- } else if (stristr(s, "\\a6") != NULL) {
- current->alignment = SUB_ALIGNMENT_TOPCENTER;
- s = s + 3;
- } else if (stristr(s, "\\a7") != NULL) {
- current->alignment = SUB_ALIGNMENT_TOPRIGHT;
- s = s + 3;
- } else if (stristr(s, "\\a9") != NULL) {
- current->alignment = SUB_ALIGNMENT_MIDDLELEFT;
- s = s + 3;
- } else if (stristr(s, "\\a10") != NULL) {
- current->alignment = SUB_ALIGNMENT_MIDDLECENTER;
- s = s + 4;
- } else if (stristr(s, "\\a11") != NULL) {
- current->alignment = SUB_ALIGNMENT_MIDDLERIGHT;
- s = s + 4;
- }
+ switch(s[2]) {
+ case '1':
+ if (s[3]) {
+ switch (s[3]) {
+ case '0':
+ current->alignment = SUB_ALIGNMENT_PVMIDDLE|SUB_ALIGNMENT_PHCENTER|SUB_ALIGNMENT_BCENTER;
+ s = s + 4;
+ break;
+ case '1':
+ current->alignment = SUB_ALIGNMENT_PVMIDDLE|SUB_ALIGNMENT_PHRIGHT|SUB_ALIGNMENT_BRIGHT;
+ s = s + 4;
+ break;
+ default:
+ current->alignment = SUB_ALIGNMENT_PVBOTTOM|SUB_ALIGNMENT_PHLEFT|SUB_ALIGNMENT_BLEFT;
+ s = s + 3;
+ }
+ }
+ break;
+ case '2':
+ current->alignment = SUB_ALIGNMENT_PVBOTTOM|SUB_ALIGNMENT_PHCENTER|SUB_ALIGNMENT_BCENTER;
+ s = s + 3;
+ break;
+ case '3':
+ current->alignment = SUB_ALIGNMENT_PVBOTTOM|SUB_ALIGNMENT_PHRIGHT|SUB_ALIGNMENT_BRIGHT;
+ s = s + 3;
+ break;
+ case '4':
+ case '5':
+ case '8':
+ current->alignment = SUB_ALIGNMENT_PVTOP|SUB_ALIGNMENT_PHLEFT|SUB_ALIGNMENT_BLEFT;
+ s = s + 3;
+ break;
+ case '6':
+ current->alignment = SUB_ALIGNMENT_PVTOP|SUB_ALIGNMENT_PHCENTER|SUB_ALIGNMENT_BCENTER;
+ s = s + 3;
+ break;
+ case '7':
+ current->alignment = SUB_ALIGNMENT_PVTOP|SUB_ALIGNMENT_PHRIGHT|SUB_ALIGNMENT_BRIGHT;
+ s = s + 3;
+ break;
+ case '9':
+ current->alignment = SUB_ALIGNMENT_PVMIDDLE|SUB_ALIGNMENT_PHLEFT|SUB_ALIGNMENT_BLEFT;
+ s = s + 3;
+ break;
+ }
}
if (*s == '}') state = 3;
++s;
@@ -353,6 +369,7 @@
continue;
current->start = a1*360000+a2*6000+a3*100+a4/10;
current->end = b1*360000+b2*6000+b3*100+b4/10;
+ current->alignment = SUB_ALIGNMENT_PHCENTER|SUB_ALIGNMENT_PHCENTER|SUB_ALIGNMENT_BCENTER;
for (i=0; i<SUB_MAX_TEXT;) {
if (!fgets (line, LINE_LEN, fd)) break;
len=0;
@@ -519,6 +536,8 @@
return current;
}
+Substyles_struct *sub_styles = NULL;
+
subtitle *sub_read_line_ssa(FILE *fd,subtitle *current) {
/*
* Sub Station Alpha v4 (and v2?) scripts have 9 commas before subtitle
@@ -535,25 +554,71 @@
int hour1, min1, sec1, hunsec1,
hour2, min2, sec2, hunsec2, nothing;
- int num;
+ int num, style_alignment;
char line[LINE_LEN+1],
line3[LINE_LEN+1],
+ line4[LINE_LEN+1],
*line2;
char *tmp;
+ Substyles_struct *ss_tmp1, *ss_tmp2;
+
+ current->alignment = SUB_ALIGNMENT_PVBOTTOM|SUB_ALIGNMENT_PHCENTER|SUB_ALIGNMENT_BCENTER;
do {
if (!fgets (line, LINE_LEN, fd)) return NULL;
+ if (sscanf(line, "Style: %[^,],%*[^,],%*d,%*d,%*d,%*d,%*d,%*d,%*d,%*d,%*d,%*d,%d,%*d,%*d,%*d,%*d,%*d", line4, &style_alignment) == 2) {
+ ss_tmp1 = (struct sub_styles_t *) malloc(sizeof(struct sub_styles_t));
+ ss_tmp1->next = NULL;
+ switch(style_alignment) {
+ case 1:
+ ss_tmp1->alignment = SUB_ALIGNMENT_BCENTER|SUB_ALIGNMENT_PHLEFT|SUB_ALIGNMENT_PVBOTTOM;
+ break;
+ case 2:
+ ss_tmp1->alignment = SUB_ALIGNMENT_BCENTER|SUB_ALIGNMENT_PHCENTER|SUB_ALIGNMENT_PVBOTTOM;
+ break;
+ case 3:
+ ss_tmp1->alignment = SUB_ALIGNMENT_BCENTER|SUB_ALIGNMENT_PHRIGHT|SUB_ALIGNMENT_PVBOTTOM;
+ break;
+ case 5:
+ ss_tmp1->alignment = SUB_ALIGNMENT_BCENTER|SUB_ALIGNMENT_PHLEFT|SUB_ALIGNMENT_PVTOP;
+ break;
+ case 6:
+ ss_tmp1->alignment = SUB_ALIGNMENT_BCENTER|SUB_ALIGNMENT_PHCENTER|SUB_ALIGNMENT_PVTOP;
+ break;
+ case 7:
+ ss_tmp1->alignment = SUB_ALIGNMENT_BCENTER|SUB_ALIGNMENT_PHRIGHT|SUB_ALIGNMENT_PVTOP;
+ break;
+ case 9:
+ ss_tmp1->alignment = SUB_ALIGNMENT_BCENTER|SUB_ALIGNMENT_PHLEFT|SUB_ALIGNMENT_PVMIDDLE;
+ break;
+ case 10:
+ ss_tmp1->alignment = SUB_ALIGNMENT_BCENTER|SUB_ALIGNMENT_PHCENTER|SUB_ALIGNMENT_PVMIDDLE;
+ break;
+ case 11:
+ ss_tmp1->alignment = SUB_ALIGNMENT_BCENTER|SUB_ALIGNMENT_PHRIGHT|SUB_ALIGNMENT_PVMIDDLE;
+ break;
+ }
+ ss_tmp1->style_name = (char *)malloc(strlen(line4) + 1);
+ strcpy(ss_tmp1->style_name, line4);
+ if (sub_styles == NULL) {
+ sub_styles = ss_tmp1;
+ } else {
+ ss_tmp2 = sub_styles;
+ while (ss_tmp2->next != NULL) ss_tmp2 = ss_tmp2->next;
+ ss_tmp2->next = ss_tmp1;
+ }
+ }
} while (sscanf (line, "Dialogue: Marked=%d,%d:%d:%d.%d,%d:%d:%d.%d,"
- "%[^\n\r]", ¬hing,
+ "%[^,\n\r]%[^\n\r]", ¬hing,
&hour1, &min1, &sec1, &hunsec1,
- &hour2, &min2, &sec2, &hunsec2,
+ &hour2, &min2, &sec2, &hunsec2, line4,
line3) < 9
&&
sscanf (line, "Dialogue: %d,%d:%d:%d.%d,%d:%d:%d.%d,"
- "%[^\n\r]", ¬hing,
+ "%[^,\n\r]%[^\n\r]", ¬hing,
&hour1, &min1, &sec1, &hunsec1,
- &hour2, &min2, &sec2, &hunsec2,
+ &hour2, &min2, &sec2, &hunsec2, line4,
line3) < 9 );
line2=strchr(line3, ',');
@@ -573,7 +638,13 @@
current->lines=0;num=0;
current->start = 360000*hour1 + 6000*min1 + 100*sec1 + hunsec1;
- current->end = 360000*hour2 + 6000*min2 + 100*sec2 + hunsec2;
+ current->end = 360000*hour2 + 6000*min2 + 100*sec2 + hunsec2;
+ for (ss_tmp1 = sub_styles ; ss_tmp1 != NULL ; ss_tmp1 = ss_tmp1->next) {
+ if (strcmp(ss_tmp1->style_name, line4) == 0) {
+ current->alignment = ss_tmp1->alignment;
+ break;
+ }
+ }
while (((tmp=strstr(line2, "\\n")) != NULL) || ((tmp=strstr(line2, "\\N")) != NULL) ){
current->text[num]=(char *)malloc(tmp-line2+1);
@@ -823,6 +894,7 @@
memset(line1, 0, LINE_LEN);
memset(line2, 0, LINE_LEN);
memset(directive, 0, LINE_LEN);
+ current->alignment = SUB_ALIGNMENT_PVBOTTOM|SUB_ALIGNMENT_PHCENTER|SUB_ALIGNMENT_BCENTER;
while (!current->text[0]) {
if (!fgets(line1, LINE_LEN, fd)) {
return NULL;
@@ -922,11 +994,33 @@
continue;
}
if (strstr(directive, "JL") != NULL) {
- current->alignment = SUB_ALIGNMENT_BOTTOMLEFT;
- } else if (strstr(directive, "JR") != NULL) {
- current->alignment = SUB_ALIGNMENT_BOTTOMRIGHT;
+ current->alignment = SUB_ALIGNMENT_BLEFT;
+ if (strstr(directive, "JBC") != NULL)
+ current->alignment |= SUB_ALIGNMENT_PHCENTER;
+ else if (strstr(directive, "JBR") != NULL)
+ current->alignment |= SUB_ALIGNMENT_PHRIGHT;
+ else current->alignment |= SUB_ALIGNMENT_PHLEFT;
+ } else if (strstr(directive, "JR") != NULL) {
+ current->alignment = SUB_ALIGNMENT_BRIGHT;
+ if (strstr(directive, "JBC") != NULL)
+ current->alignment |= SUB_ALIGNMENT_PHCENTER;
+ else if (strstr(directive, "JBL") != NULL)
+ current->alignment |= SUB_ALIGNMENT_PHLEFT;
+ else current->alignment |= SUB_ALIGNMENT_PHRIGHT;
} else {
- current->alignment = SUB_ALIGNMENT_BOTTOMCENTER;
+ current->alignment = SUB_ALIGNMENT_BCENTER;
+ if (strstr(directive, "JBL") != NULL)
+ current->alignment |= SUB_ALIGNMENT_PHLEFT;
+ else if (strstr(directive, "JBR") != NULL)
+ current->alignment |= SUB_ALIGNMENT_PHRIGHT;
+ else current->alignment |= SUB_ALIGNMENT_PHCENTER;
+ }
+ if (strstr(directive, "VT") != NULL) {
+ current->alignment |= SUB_ALIGNMENT_PVTOP;
+ } else if (strstr(directive, "VM") != NULL) {
+ current->alignment |= SUB_ALIGNMENT_PVMIDDLE;
+ } else {
+ current->alignment |= SUB_ALIGNMENT_PVBOTTOM;
}
strcpy(line2, line1);
p = line2;
@@ -1715,6 +1809,18 @@
subt_data->sub_num = sub_num;
subt_data->sub_errs = sub_errs;
subt_data->subtitles = return_sub;
+
+ /* free memory allocated for sub styles */
+ if (sub_styles != NULL) {
+ Substyles_struct *ss_tmp;
+ do {
+ ss_tmp = sub_styles;
+ sub_styles = ss_tmp->next;
+ free(ss_tmp->style_name);
+ free(ss_tmp);
+ } while (sub_styles != NULL);
+ }
+
return subt_data;
}
diff -Nur MPlayer-20050209/subreader.h MPlayer-20050209.patch/subreader.h
--- MPlayer-20050209/subreader.h 2004-10-18 22:41:05.000000000 +0200
+++ MPlayer-20050209.patch/subreader.h 2005-02-09 14:10:02.933434736 +0100
@@ -30,15 +30,19 @@
#define MAX_SUBTITLE_FILES 128
#define SUB_MAX_TEXT 10
-#define SUB_ALIGNMENT_BOTTOMLEFT 1
-#define SUB_ALIGNMENT_BOTTOMCENTER 2
-#define SUB_ALIGNMENT_BOTTOMRIGHT 3
-#define SUB_ALIGNMENT_MIDDLELEFT 4
-#define SUB_ALIGNMENT_MIDDLECENTER 5
-#define SUB_ALIGNMENT_MIDDLERIGHT 6
-#define SUB_ALIGNMENT_TOPLEFT 7
-#define SUB_ALIGNMENT_TOPCENTER 8
-#define SUB_ALIGNMENT_TOPRIGHT 9
+#define SUB_ALIGNMENT_BLOCK 0x30 // block alignment mask
+#define SUB_ALIGNMENT_HORIZONTAL 0x03 // horizontal alignment mask
+#define SUB_ALIGNMENT_VERTICAL 0x0C // vertical alignment mask
+#define SUB_ALIGNMENT_PHLEFT 0x2
+#define SUB_ALIGNMENT_PHCENTER 0x3
+#define SUB_ALIGNMENT_PHRIGHT 0x1
+#define SUB_ALIGNMENT_PVTOP 0x8
+#define SUB_ALIGNMENT_PVMIDDLE 0xC
+#define SUB_ALIGNMENT_PVBOTTOM 0x4
+#define SUB_ALIGNMENT_BLEFT 0x20
+#define SUB_ALIGNMENT_BCENTER 0x30
+#define SUB_ALIGNMENT_BRIGHT 0x10
+#define SUB_ALIGNMENT_BJUSTIFY 0x00
typedef struct {
@@ -59,6 +63,13 @@
int sub_errs;
} sub_data;
+typedef struct sub_styles_t {
+ // this is used to store style informations in complex sub formats (ssa/ass, jacosub)
+ char *style_name;
+ unsigned char alignment;
+ struct sub_styles_t *next;
+} Substyles_struct;
+
#ifdef USE_FRIBIDI
extern char *fribidi_charset;
extern int flip_hebrew;
More information about the MPlayer-dev-eng
mailing list