[MPlayer-dev-eng] [PATCH] subtitle alignment - again

Salvatore Falco sfalco at studenti.ing.uniroma1.it
Wed Jan 19 16:14:38 CET 2005


Hi all.

This is a patch to extend subtitles alignment capabilities of MPlayer.
The subtitles are now drawn inside a box; with this patch it is possible
to align the subtitles in three, independent ways:
 + horizontally (left, center, right)
 + vertically (top, middle, bottom)
 + inside the block (left, center, right, justified*)
   
Currently, SAMI and JACOsub formats are correctly supported.
   
*Note that the patch correctly handles the indication that the subs must be
block-justified, but that such subtitles are currently center-aligned: further
work is required to actually justify them (it is necessary to keep track of the
number of white spaces inside the subtitle text).
   

    Best regards,
	Salvatore Falco
-- 
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
-------------- next part --------------
diff -Nur MPlayer-20050110/libvo/sub.c MPlayer-20050110.patch/libvo/sub.c
--- MPlayer-20050110/libvo/sub.c	2004-10-28 03:15:52.000000000 +0200
+++ MPlayer-20050110.patch/libvo/sub.c	2005-01-16 17:49:47.979823800 +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:
+        obj->bbox.y1 = dys - h - 1;
+    default:
+        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-20050110/subreader.c MPlayer-20050110.patch/subreader.c
--- MPlayer-20050110/subreader.c	2004-10-18 22:56:11.000000000 +0200
+++ MPlayer-20050110.patch/subreader.c	2005-01-16 18:01:03.344152816 +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;
@@ -922,11 +939,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;
diff -Nur MPlayer-20050110/subreader.h MPlayer-20050110.patch/subreader.h
--- MPlayer-20050110/subreader.h	2004-10-18 22:41:05.000000000 +0200
+++ MPlayer-20050110.patch/subreader.h	2005-01-16 18:03:55.754942392 +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 {
 
diff -Nur MPlayer-20050110/AUTHORS MPlayer-20050110.patch/AUTHORS
--- MPlayer-20050110/AUTHORS	2005-01-02 21:28:27.000000000 +0100
+++ MPlayer-20050110.patch/AUTHORS	2005-01-16 18:23:50.049382040 +0100
@@ -216,6 +216,7 @@
     * jacosub parsing & dump support
     * overlapping subtitles & sub sorting support
     * SAMI subtitles dump support
+    * subtitle alignment, handling code + SAMI & JACOsub support
 
 Fargas, Marc (TeLeNiEkO) <telenieko at telenieko.com>
     * first Spanish documentation translation (outdated)


More information about the MPlayer-dev-eng mailing list