[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]", &nothing,
+			"%[^,\n\r]%[^\n\r]", &nothing,
 			&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]", &nothing,
+			 "%[^,\n\r]%[^\n\r]", &nothing,
 			 &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