diff libvo/sub.c @ 1501:d40f2b686846

changes according to -utf8 option, draw_osd() function added
author atlka
date Mon, 13 Aug 2001 11:08:18 +0000
parents a013b2124f05
children ccb1f3ddb29a
line wrap: on
line diff
--- a/libvo/sub.c	Mon Aug 13 10:38:01 2001 +0000
+++ b/libvo/sub.c	Mon Aug 13 11:08:18 2001 +0000
@@ -6,17 +6,19 @@
 
 unsigned char* vo_osd_text="00:00:00";
 int sub_unicode=0;
+int sub_utf8=0;
 
-static void vo_draw_text_osd(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){
-        int len=strlen(vo_osd_text);
-        int j;
+inline static void vo_draw_text_osd(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){
+	unsigned char *cp=vo_osd_text;
+	int c;
+   	int font;
         int y=10;
         int x=20;
 
-        for(j=0;j<len;j++){
-          int c=vo_osd_text[j];
-          int font=vo_font->font[c];
-          if(font>=0)
+        while (*cp){
+          c=*cp;
+	  cp++;
+          if ((font=vo_font->font[c])>=0)
             draw_alpha(x,y,
               vo_font->width[c],
               vo_font->pic_a[font]->h,
@@ -31,9 +33,9 @@
 int vo_osd_progbar_type=-1;
 int vo_osd_progbar_value=100;   // 0..255
 
-static void vo_draw_text_progbar(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){
+inline static void vo_draw_text_progbar(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){
         int i;
-        int y=dys/2;
+        int y=(dys-vo_font->height)/2;
         int x;
         int c,font;
         int width=(dxs*2/3-vo_font->width[0x10]-vo_font->width[0x12]);
@@ -42,8 +44,8 @@
         x=(dxs-width)/2;
 //        printf("osd.progbar  width=%d  xpos=%d\n",width,x);
 
-        c=vo_osd_progbar_type;font=vo_font->font[c];
-        if(vo_osd_progbar_type>0 && font>=0)
+        c=vo_osd_progbar_type;
+        if(vo_osd_progbar_type>0 && (font=vo_font->font[c])>=0)
             draw_alpha(x-vo_font->width[c]-vo_font->spacewidth,y,
               vo_font->width[c],
               vo_font->pic_a[font]->h,
@@ -51,8 +53,8 @@
               vo_font->pic_a[font]->bmp+vo_font->start[c],
               vo_font->pic_a[font]->w);
 
-        c=OSD_PB_START;font=vo_font->font[c];
-        if(font>=0)
+        c=OSD_PB_START;
+        if ((font=vo_font->font[c])>=0)
             draw_alpha(x,y,
               vo_font->width[c],
               vo_font->pic_a[font]->h,
@@ -61,20 +63,32 @@
               vo_font->pic_a[font]->w);
         x+=vo_font->width[c];
 
-        for(i=0;i<elems;i++){
-          c=(i<mark)?OSD_PB_0:OSD_PB_1;font=vo_font->font[c];
-          if(font>=0)
-            draw_alpha(x,y,
-              vo_font->width[c],
-              vo_font->pic_a[font]->h,
-              vo_font->pic_b[font]->bmp+vo_font->start[c],
-              vo_font->pic_a[font]->bmp+vo_font->start[c],
-              vo_font->pic_a[font]->w);
-          x+=vo_font->width[c];
-        }
+   	c=OSD_PB_0;
+   	if ((font=vo_font->font[c])>=0)
+     	   for (i=mark;i--;){
+	       draw_alpha(x,y,
+			  vo_font->width[c],
+			  vo_font->pic_a[font]->h,
+			  vo_font->pic_b[font]->bmp+vo_font->start[c],
+			  vo_font->pic_a[font]->bmp+vo_font->start[c],
+			  vo_font->pic_a[font]->w);
+	       x+=vo_font->width[c];
+	   }
 
-        c=OSD_PB_END;font=vo_font->font[c];
-        if(font>=0)
+   	c=OSD_PB_1;
+	if ((font=vo_font->font[c])>=0)
+     	   for (i=elems-mark;i--;){
+	       draw_alpha(x,y,
+			  vo_font->width[c],
+			  vo_font->pic_a[font]->h,
+			  vo_font->pic_b[font]->bmp+vo_font->start[c],
+			  vo_font->pic_a[font]->bmp+vo_font->start[c],
+			  vo_font->pic_a[font]->w);
+	       x+=vo_font->width[c];
+	   }
+
+        c=OSD_PB_END;
+        if ((font=vo_font->font[c])>=0)
             draw_alpha(x,y,
               vo_font->width[c],
               vo_font->pic_a[font]->h,
@@ -90,64 +104,88 @@
 
 subtitle* vo_sub=NULL;
 
-static void vo_draw_text_sub(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){
-    int i;
-    int y;
-    y=dys-(1+vo_sub->lines-1)*vo_font->height-10;
+#define MAX_UCS 1600
+#define MAX_UCSLINES 16
 
-    // too long lines divide into smaller ones
-    for(i=0;i<vo_sub->lines;i++){
-        unsigned char* text=vo_sub->text[i];
-        int len=strlen(text);
-	int j;
-        int xsize=-vo_font->charspace;
-	int lastStripPosition=-1;
-	int previousStrip=0;
-	int lastxsize=0;
+inline static void vo_draw_text_sub(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){
+   static int utbl[MAX_UCS+1];
+   static int xtbl[MAX_UCSLINES];
+   static int lines;
+   static subtitle *memsub=NULL;
+   static int memy;
+   static int memdxs;
+   static int memdys;
+   unsigned char *t;
+   int i;
+   int j;
+   int k;
+   int l;
+   int x;
+   int y;
 
-	for(j=0;j<len;j++){
-          int c=text[j];
-          int w;
-          if (sub_unicode && (c>=0x80)) c=(c<<8)+text[++j];
-          w = vo_font->width[c];
-	  if (text[j]==' ' && dxs>xsize)
-	  {
-	    lastStripPosition=j;
-	    lastxsize=xsize;
-	  }
-          xsize+=w+vo_font->charspace;
-	  if (dxs<xsize && lastStripPosition>0)
-	  {
-	    xsize=lastxsize;
-	    j=lastStripPosition;
-            y-=vo_font->height;
-	    previousStrip=lastStripPosition;
-            xsize=-vo_font->charspace;
-	  }
-        }
-    }
+   int c;
+   int len;
+   int line;
+   int font;
+   int lastStripPosition;
+   int xsize;
+   int lastxsize;
+   int lastk;
+   
+   if ((memsub!=vo_sub)||(memdxs!=dxs)||(memdys!=dys)){
+      memsub=vo_sub;
+      memdxs=dxs;
+      memdys=dys;
+      
+      memy=dys-vo_font->height/4;
+      
+      // too long lines divide into smaller ones
+      i=k=lines=0; l=vo_sub->lines;
+      while (l--){
+	  t=vo_sub->text[i++];	  
+	  len=strlen(t)-1;
+	  xsize=lastxsize=-vo_font->charspace;
+	  lastStripPosition=-1;
 
-
-    for(i=0;i<vo_sub->lines;i++){
-        unsigned char* text=vo_sub->text[i];//  "Hello World! HÛDEJÓ!";
-        int len=strlen(text);
-        int j,k;
-        int xsize=-vo_font->charspace;
-        int x=0;
-
-	int lastStripPosition=-1;
-	int previousStrip=0;
-	int lastxsize=xsize;
-
-	for(j=0;j<len;j++){
-          int c=text[j];
-          int w;
-          if (sub_unicode && (c>=0x80)) c=(c<<8)+text[++j];
-          w = vo_font->width[c];
-          if (c==' ' && dxs>xsize)
-	  {
-	    lastStripPosition=j;
-	    lastxsize=xsize;
+	  for (j=0;j<=len;j++){
+	      if ((c=t[j])>=0x80){
+		 if (sub_unicode) 
+		    c = (c<<8) + t[++j]; 
+		 else
+		    if (sub_utf8){
+		       if ((c & 0xe0) == 0xc0)    /* 2 bytes U+00080..U+0007FF*/
+			  c = (c & 0x1f)<<6 | (t[++j] & 0x3f);
+		       else if((c & 0xf0) == 0xe0)/* 3 bytes U+00800..U+00FFFF*/
+			  c = ((c & 0x0f)<<6 |
+			       (t[++j] & 0x3f))<<6 | (t[++j] & 0x3f);
+		    }
+	      }
+	      if (k==MAX_UCS){
+		 utbl[k]=l=0;
+		 break;
+	      } else
+	         utbl[k++]=c;
+	      if (c==' '){
+		 lastk=k;
+		 lastStripPosition=j;
+		 lastxsize=xsize;
+	      }
+	      xsize+=vo_font->width[c]+vo_font->charspace;
+	      if (dxs<xsize && lastStripPosition>0){
+		 j=lastStripPosition;
+		 k=lastk;
+	      } else if (j==len){
+		 lastxsize=xsize;
+	      } else
+	         continue;	       	       	       
+	      utbl[k++]=0;
+	      xtbl[lines++]=(dxs-lastxsize)/2;
+	      if (lines==MAX_UCSLINES||k>MAX_UCS){
+		 l=0;
+		 break;
+	      }
+	      memy-=vo_font->height;
+	      xsize=lastxsize=-vo_font->charspace;
 	  }
           xsize+=w+vo_font->charspace;
 	  if ((dxs<xsize && lastStripPosition>0) || j==len-1)
@@ -179,8 +217,28 @@
             xsize=lastxsize=-vo_font->charspace;
 	  }
         }
-    }
+   }
+   
+   y = memy;
 
+   k=i=0; l=lines;
+   while (l--){
+       x = xtbl[i++];
+       while (utbl[k]){
+	     c=utbl[k]; 
+	     k++;
+	     if (x>=0 && x+vo_font->width[c]<=dxs)
+		if ((font=vo_font->font[c])>=0)
+	           draw_alpha(x,y,
+			      vo_font->width[c],
+			      vo_font->pic_a[font]->h,
+			      vo_font->pic_b[font]->bmp+vo_font->start[c],
+			      vo_font->pic_a[font]->bmp+vo_font->start[c],
+			      vo_font->pic_a[font]->w);
+	  x+=vo_font->width[c]+vo_font->charspace;
+       }
+       y+=vo_font->height;
+   }
 }
 
 static int draw_alpha_init_flag=0;