[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