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

Oskar Liljeblad oskar at osk.mine.nu
Sat Dec 21 17:50:41 CET 2002


Hi!

This patch adds support for vertical subtitle alignment
control. Possible values are top, center, and bottom,
with bottom being the default. Alignment is relevant when
it comes to positioning subtitles with one line (or fewer
lines) of text relative to multi-line subtitles.

 Example:

  top alignment:
    2 lines:     1 line:
     -----        -----
     -----

  bottom alignment:
    2 lines:     1 line:
     -----
     -----        -----

  center alignment
    2 lines:     1 line:
     -----        _____
     -----

The subtitles you see on TV and DVDs are usually bottom
aligned.

It is implemented as a new command (sub_alignment) that
without an argument cycles the alignment (between top,
center, and bottom), or with an argument sets the
alignment (0 for top, 1 for center, 2 for bottom).
The key 'i' is bound to this command.

Note that you won't see any effect of the alignment until
you move sub_pos to something a little less than 100.

I can only speak for myself when I say that this is
extremely useful when watching movies with subtitles
with three or more lines of text. This is because I have
to set sub_pos to something like 80 (widescreen TV with
zoomed in 16:9 mode discards top and bottom areas of
screen). To see all lines of 3-line subs, you'd have to
set sub_pos so something like 70. But this would mean
that 1-line subs would appear almost in the middle of the
screen! With bottom alignment this is no longer a problem -
the 1-line sub would be displayed in the very bottom while
the 3-line sub would be displayed as before.

If you don't understand a word of what I mean, do this:
Apply the patch, play a movie with some one-line
and some two-line subs. Use R to set sub_pos to something like
50. Press Y to "fast forward" to the next subtitle. Then
press I to toggle subtitle alignment.

Please let me know what happens with this patch!

Thanks,

Oskar Liljeblad (oskar at osk.mine.nu)
-------------- next part --------------
diff -u -p input/input.c.v0 input/input.c
--- input/input.c.v0	2002-12-19 11:09:42.000000000 +0100
+++ input/input.c	2002-12-21 16:56:43.000000000 +0100
@@ -66,6 +66,7 @@ static mp_cmd_t mp_cmds[] = {
   { MP_CMD_SATURATION, "saturation",1,  { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} }  },
   { MP_CMD_FRAMEDROPPING, "frame_drop",0, { { MP_CMD_ARG_INT,{-1} }, {-1,{0}} } },
   { MP_CMD_SUB_POS, "sub_pos", 1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
+  { MP_CMD_SUB_ALIGNMENT, "sub_alignment",0, { {MP_CMD_ARG_INT,{-1}}, {-1,{0}} } },
   { MP_CMD_SUB_VISIBILITY, "sub_visibility", 0, { {-1,{0}} } },
   { MP_CMD_VOBSUB_LANG, "vobsub_lang", 0, { {-1,{0}} } },
   { MP_CMD_GET_PERCENT_POS, "get_percent_pos", 0, { {-1,{0}} } },
@@ -244,6 +245,7 @@ static mp_cmd_bind_t def_cmd_binds[] = {
   { { 'd', 0 }, "frame_drop" },
   { { 'r', 0 }, "sub_pos -1" },
   { { 't', 0 }, "sub_pos +1" },
+  { { 'i', 0 }, "sub_alignment" },
   { { 'v', 0 }, "sub_visibility" },
   { { 'j', 0 }, "vobsub_lang" },
 #ifdef USE_TV
diff -u input/input.h.v0 input/input.h
--- input/input.h.v0	2002-12-19 11:09:42.000000000 +0100
+++ input/input.h	2002-12-21 16:56:43.000000000 +0100
@@ -37,6 +37,7 @@
 #define MP_CMD_GET_TIME_LENGTH 34
 #define MP_CMD_GET_PERCENT_POS 35
 #define MP_CMD_SUB_STEP 36
+#define MP_CMD_SUB_ALIGNMENT 37
 
 #define MP_CMD_GUI_EVENTS       5000
 #define MP_CMD_GUI_LOADFILE     5001
diff -u -p libvo/sub.c.v0 libvo/sub.c
--- libvo/sub.c.v0	2002-12-14 18:56:14.000000000 +0100
+++ libvo/sub.c	2002-12-21 16:56:43.000000000 +0100
@@ -37,6 +37,7 @@ unsigned char* vo_osd_text=NULL;
 int sub_unicode=0;
 int sub_utf8=0;
 int sub_pos=100;
+int sub_alignment=2; /* 0=top, 1=center, 2=bottom */
 int sub_visibility=1;
 
 // return the real height of a char:
@@ -418,12 +419,22 @@ inline static void vo_update_text_sub(mp
        *sfalco*
      */
     if(suboverlap_enabled) obj->y -= vo_font->pic_a[vo_font->font[40]]->h - vo_font->height;
-    if (obj->y >= (dys * sub_pos / 100)){
-	int old=obj->y;
-	obj->y = dys * sub_pos /100;
-	obj->bbox.y2-=old-obj->y;
-    }
-    
+
+    h = dys - obj->y;
+    if (sub_alignment == 2)
+        obj->y = dys * sub_pos / 100 - h;
+    else if (sub_alignment == 1)
+        obj->y = dys * sub_pos / 100 - h / 2;
+    else
+        obj->y = dys * sub_pos / 100;
+
+    if (obj->y < 0)
+        obj->y = 0;
+    if (obj->y > dys - h)
+        obj->y = dys - h;
+
+    obj->bbox.y2 = obj->y + h;
+
     // calculate bbox:
     obj->bbox.x1=xmin;
     obj->bbox.x2=xmax;
diff -u libvo/sub.h.v0 libvo/sub.h
--- libvo/sub.h.v0	2002-12-05 01:03:35.000000000 +0100
+++ libvo/sub.h	2002-12-21 16:56:43.000000000 +0100
@@ -97,6 +97,7 @@
 extern char *sub_cp;
 #endif
 extern int sub_pos;
+extern int sub_alignment;
 extern int sub_visibility;
 extern int suboverlap_enabled;
 
diff -u -p mplayer.c.v0 mplayer.c
--- mplayer.c.v0	2002-12-19 11:09:27.000000000 +0100
+++ mplayer.c	2002-12-21 16:56:43.000000000 +0100
@@ -561,6 +561,7 @@ int osd_show_av_delay = 0;
 int osd_show_sub_delay = 0;
 int osd_show_sub_pos = 0;
 int osd_show_sub_visibility = 0;
+int osd_show_sub_alignment = 0;
 int osd_show_vobsub_changed = 0;
 
 int rtc_fd=-1;
@@ -2341,6 +2342,16 @@ if (stream->type==STREAMTYPE_DVDNAV && d
 	vo_osd_changed(OSDTYPE_SUBTITLE);
         osd_show_sub_pos = 9;
     }	break;
+    case MP_CMD_SUB_ALIGNMENT:
+    {
+    	if (cmd->nargs >= 1)
+    	    sub_alignment = cmd->args[0].v.i;
+    	else
+            sub_alignment = (sub_alignment+1) % 3;
+	osd_show_sub_alignment = 9;
+	vo_osd_changed(OSDTYPE_SUBTITLE);
+	break;
+    }
     case MP_CMD_SUB_VISIBILITY:
     {
 	sub_visibility=1-sub_visibility;
@@ -2754,6 +2765,12 @@ if(rel_seek_secs || abs_seek_pos){
          sprintf(osd_text_tmp, "Sub position: %d/100", sub_pos);
          osd_show_sub_pos--;
       } else
+      if (osd_show_sub_alignment) {
+         sprintf(osd_text_tmp, "Sub alignment: %s",
+	    (sub_alignment == 2 ? "bottom" :
+	    (sub_alignment == 1 ? "center" : "top")));
+         osd_show_sub_alignment--;
+      } else
       if (osd_show_av_delay) {
 	  sprintf(osd_text_tmp, "A-V delay: %d ms",(int)(audio_delay*1000));
 	  osd_show_av_delay--;


More information about the MPlayer-dev-eng mailing list