⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tfont.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
📖 第 1 页 / 共 3 页
字号:
					{
						unsigned int alpha = circle[circleSize*ry+rx];
						if (alpha)
						{
							unsigned int dstpos = _dx*(y+ry-shadowSize)+x+rx-shadowSize;
							unsigned int shadow = bmp[0][pos] * alpha >> 8;
							if (msk[0][dstpos]<shadow)
								msk[0][dstpos] = (unsigned char)shadow;
						}
					}
				}

			}
	   }
   }
   else if (shadowMode == 1) //Gradient classic shadow
   {
	   unsigned int shadowStep = shadowAlpha/shadowSize;
	   for (unsigned int y=0; y<_dy;y++)
	   {
		   for (unsigned int x=0; x<_dx;x++)
		   {
			   unsigned int pos = _dx*y+x;
			   if (bmp[0][pos] == 0) continue;
			   /*else
				bmp[0][pos] = 255;*/

			   unsigned int shadowAlphaGradient = shadowAlpha;
			   for (unsigned int xx=1; xx<=shadowSize; xx++)
			   {
					unsigned int shadow = bmp[0][pos]*shadowAlphaGradient>>8;
					if (x + xx < _dx)
					{
						if (y+xx < _dy && 
							msk[0][_dx*(y+xx)+x+xx] <shadow)
						{
							msk[0][_dx*(y+xx)+x+xx] = shadow;
						}
					}
				   shadowAlphaGradient -= shadowStep;
			   }
		   }
	   }
   }
   else if (shadowMode == 2) //Classic shadow
   {
		shadowAlpha*=0.53;
		unsigned int lookup085[256],lookupAlpha[256];
		for (int i=0;i<256;i++)
		{
			lookup085[i]=i*0.85;
			lookupAlpha[i]=i*shadowAlpha>>8;
		}
		for (unsigned int y=_dy-1; y>=shadowSize;y--)
		{
			for (unsigned int x=_dx-1; x>=shadowSize;x--)
			{
				unsigned int srcpos = _dx*(y-shadowSize)+x-shadowSize;
				unsigned int dstpos = _dx*y+x;
				unsigned char srcPixel = (unsigned char)std::max<unsigned int>(bmp[0][srcpos],lookup085[msk[0][srcpos]]); // lookup085[msk[0][srcpos]] = shadow of outline.
				if (srcPixel != 0)
					msk[0][dstpos] = (unsigned char)std::max<unsigned int>(msk[0][dstpos],lookupAlpha[srcPixel]);
			}
		}
   }
}

unsigned int TrenderedSubtitleWord::getShadowSize(const TrenderedSubtitleLines::TprintPrefs &prefs,LONG fontHeight)
{
 if (prefs.shadowSize==0)
  return 0;
 if (prefs.shadowSize < 0) // SSA/ASS/ASS2
 return -1 * prefs.shadowSize;
 unsigned int shadowSize = prefs.shadowSize*fontHeight/180.0+2.6;
 if (prefs.shadowMode==0)
  shadowSize*=0.6;
 else if (prefs.shadowMode==1)
  shadowSize/=1.4142;  // 1.4142 = sqrt(2.0)
 else if (prefs.shadowMode==2)
  shadowSize*=0.4;

 if (shadowSize==0)
  shadowSize = 1;
 if (shadowSize>16)
  shadowSize = 16;
 return shadowSize;
}

// fast rendering
template<class tchar> TrenderedSubtitleWord::TrenderedSubtitleWord(TcharsChache *charsChache,const tchar *s,size_t strlens,const TrenderedSubtitleLines::TprintPrefs &prefs):TrenderedSubtitleWordBase(true),shiftChroma(true)
{
 const TrenderedSubtitleWord **chars=(const TrenderedSubtitleWord**)_alloca(strlens*sizeof(TrenderedSubtitleLine*));
 for (int i=0;i<3;i++)
  dx[i]=dy[i]=0;
 for (size_t i=0;i<strlens;i++)
  {
   chars[i]=charsChache->getChar(&s[i],prefs);
   dx[0]+=chars[i]->dxCharY;
   if (s[i]=='\t')
    {
     int tabsize=prefs.tabsize*std::max(chars[0]->dyCharY,1U);
     dx[0]=(dx[0]/tabsize+1)*tabsize;
    }
   for (int p=0;p<3;p++)
    dy[p]=std::max(dy[p],chars[i]->dy[p]);
   if(sizeof(tchar)==sizeof(char))
    if(_mbclen((const unsigned char *)&s[i])==2)
     i++;
  }
 dx[0]=(dx[0]/8+2)*8;dx[1]=dx[2]=(dx[0]/16+1)*8;
 dxCharY=dx[0];
 dyCharY=chars[0]->dyCharY;
 for (int i=0;i<3;i++)
  {
   bmp[i]=(unsigned char*)aligned_calloc(dx[i],dy[i]);//bmp[1]=(unsigned char*)aligned_calloc(dxUV,dyUV);bmp[2]=(unsigned char*)aligned_calloc(dxUV,dyUV);
   msk[i]=(unsigned char*)aligned_calloc(dx[i],dy[i]);//msk[1]=(unsigned char*)aligned_calloc(dxUV,dyUV);msk[2]=(unsigned char*)aligned_calloc(dxUV,dyUV);
   bmpmskstride[i]=dx[i];
  }
 unsigned int x=0;
 for (size_t i=0;i<strlens;i++)
  {
   if (s[i]=='\t')
    {
     int tabsize=prefs.tabsize*std::max(chars[0]->dyCharY,1U);
     x=(x/tabsize+1)*tabsize;
    }
   for (unsigned int p=0;p<3;p++)
    {
     const unsigned char *charbmpptr=chars[i]->bmp[p],*charmskptr=chars[i]->msk[p];
     unsigned char *bmpptr=bmp[p]+roundRshift(x,prefs.shiftX[p]),*mskptr=msk[p]+roundRshift(x,prefs.shiftX[p]);
     for (unsigned int y=0;y<chars[i]->dy[p];y++,bmpptr+=bmpmskstride[p],mskptr+=bmpmskstride[p],charbmpptr+=chars[i]->bmpmskstride[p],charmskptr+=chars[i]->bmpmskstride[p])
      {
       memadd(bmpptr,charbmpptr,chars[i]->dx[p]);
       memadd(mskptr,charmskptr,chars[i]->dx[p]);
      }
    }
   x+=chars[i]->dxCharY;
   if(sizeof(tchar)==sizeof(char))
    if(_mbclen((const unsigned char *)&s[i])==2)
     i++;
  }
 _mm_empty();
}

void TrenderedSubtitleWord::print(unsigned int sdx[3],unsigned char *dstLn[3],const stride_t stride[3],const unsigned char *bmp[3],const unsigned char *msk[3]) const
{
 int sdx15=sdx[0]-15;
 for (unsigned int y=0;y<dy[0];y++,dstLn[0]+=stride[0],msk[0]+=bmpmskstride[0],bmp[0]+=bmpmskstride[0])
  {
   int x=0;
   for (;x<sdx15;x+=16)
    {
     __m64 mm0=*(__m64*)(dstLn[0]+x),mm1=*(__m64*)(dstLn[0]+x+8);
     mm0=_mm_subs_pu8(mm0,*(__m64*)(msk[0]+x));mm1=_mm_subs_pu8(mm1,*(__m64*)(msk[0]+x+8));
     mm0=_mm_adds_pu8(mm0,*(__m64*)(bmp[0]+x));mm1=_mm_adds_pu8(mm1,*(__m64*)(bmp[0]+x+8));
     *(__m64*)(dstLn[0]+x)=mm0;*(__m64*)(dstLn[0]+x+8)=mm1;
    }
   for (;x<int(sdx[0]);x++)
    {
     int c=dstLn[0][x];
     c-=msk[0][x];if (c<0) c=0;
     c+=bmp[0][x];if (c>255) c=255;
     dstLn[0][x]=(unsigned char)c;
    }
  }
 __m64 m128=_mm_set1_pi8((char)128),m0=_mm_setzero_si64(),mAdd=shiftChroma?m128:m0;
 int add=shiftChroma?128:0;
 int sdx7=sdx[1]-7;
 for (unsigned int y=0;y<dy[1];y++,dstLn[1]+=stride[1],dstLn[2]+=stride[2],msk[1]+=bmpmskstride[1],bmp[1]+=bmpmskstride[1],bmp[2]+=bmpmskstride[2])
  {
   int x=0;
   for (;x<sdx7;x+=8)
    {
     __m64 mm0=*(__m64*)(dstLn[1]+x);
     __m64 mm1=*(__m64*)(dstLn[2]+x);

     psubb(mm0,m128);
     psubb(mm1,m128);

     const __m64 msk8=*(const __m64*)(msk[1]+x);

     __m64 mskU=_mm_cmpgt_pi8(m0,mm0); //what to be negated
     mm0=_mm_or_si64(_mm_and_si64(mskU,_mm_adds_pu8(mm0,msk8)),_mm_andnot_si64(mskU,_mm_subs_pu8(mm0,msk8)));

     __m64 mskV=_mm_cmpgt_pi8(m0,mm1);
     mm1=_mm_or_si64(_mm_and_si64(mskV,_mm_adds_pu8(mm1,msk8)),_mm_andnot_si64(mskV,_mm_subs_pu8(mm1,msk8)));

     mm0=_mm_add_pi8(_mm_add_pi8(mm0,*(__m64*)(bmp[1]+x)),mAdd);
     mm1=_mm_add_pi8(_mm_add_pi8(mm1,*(__m64*)(bmp[2]+x)),mAdd);

     *(__m64*)(dstLn[1]+x)=mm0;
     *(__m64*)(dstLn[2]+x)=mm1;
    }
   for (;x<int(sdx[1]);x++)
    {
     int m=msk[1][x],c;
     c=dstLn[1][x];
     c-=128;
     if (c<0) {c+=m;if (c>0) c=0;}
     else     {c-=m;if (c<0) c=0;}
     c+=bmp[1][x];
     c+=add;
     dstLn[1][x]=c;//(unsigned char)limit(c,0,255);

     c=dstLn[2][x];
     c-=128;
     if (c<0) {c+=m;if (c>0) c=0;}
     else     {c-=m;if (c<0) c=0;};
     c+=bmp[2][x];
     c+=add;
     dstLn[2][x]=c;//(unsigned char)limit(c,0,255);
    }
  }

/* for (int x=0;x<dx[0];x++)
	 for (int y=0;y<dy[0];y++)
	 {
		 if (bmp[0][dy[0]*y+x] !=0)
		 {
			 dstLn[0][x]=c
		 }
	 }*/
 _mm_empty();
}

//============================== TrenderedSubtitleLine ===============================
unsigned int TrenderedSubtitleLine::width(void) const
{
 unsigned int dx=0;
 for (const_iterator w=begin();w!=end();w++)
  dx+=(*w)->dx[0];
 return dx;
}
unsigned int TrenderedSubtitleLine::height(void) const
{
 unsigned int dy=0;
 for (const_iterator w=begin();w!=end();w++)
  dy=std::max(dy,(*w)->dy[0]);
 return dy;
}
unsigned int TrenderedSubtitleLine::charHeight(void) const
{
 unsigned int dy=0;
 for (const_iterator w=begin();w!=end();w++)
  dy=std::max(dy,(*w)->dyCharY);
 return dy;
}
void TrenderedSubtitleLine::print(int startx,int starty,const TrenderedSubtitleLines::TprintPrefs &prefs,unsigned int prefsdx,unsigned int prefsdy) const
{
 for (const_iterator w=begin();w!=end() && startx<(int)prefsdx;startx+=(*w)->dxCharY,w++)
  {
   const unsigned char *msk[3],*bmp[3];
   unsigned char *dstLn[3];
   int x[3];
   unsigned int dx[3];
   for (int i=0;i<3;i++)
    {
     x[i]=startx>>prefs.shiftX[i];
     msk[i]=(*w)->msk[i];
     bmp[i]=(*w)->bmp[i];
     if (prefs.align!=ALIGN_FFDSHOW && x[i]<0)
      {
       msk[i]+=-x[i];
       bmp[i]+=-x[i];
      }
     dstLn[i]=prefs.dst[i]+prefs.stride[i]*(starty>>prefs.shiftY[i]);if (x[i]>0) dstLn[i]+=x[i];

     if (x[i]+(*w)->dx[i]>(prefsdx>>prefs.shiftX[i])) dx[i]=(prefsdx>>prefs.shiftX[i])-x[i];
     else if (x[i]<0) dx[i]=(*w)->dx[i]+x[i];
     else dx[i]=(*w)->dx[i];
     dx[i]=std::min(dx[i],prefsdx>>prefs.shiftX[i]);
    }
   (*w)->print(dx,dstLn,prefs.stride,bmp,msk);
  }
}
void TrenderedSubtitleLine::clear(void)
{
 for (iterator w=begin();w!=end();w++)
  delete *w;
 std::vector<value_type>::clear();
}

//============================== TrenderedSubtitleLines ==============================
void TrenderedSubtitleLines::print(const TprintPrefs &prefs)
{
 if (empty()) return;
 unsigned int prefsdx,prefsdy;
 if (prefs.sizeDx && prefs.sizeDy)
  {
   prefsdx=prefs.sizeDx;
   prefsdy=prefs.sizeDy;
  }
 else
  {
   prefsdx=prefs.dx;
   prefsdy=prefs.dy;
  }
 unsigned int h=0;
 for (const_iterator i=begin();i!=end();i++)
  h+=prefs.linespacing*(*i)->charHeight()/100;

 const_reverse_iterator ri=rbegin();
 unsigned int h1 = h - prefs.linespacing*(*ri)->charHeight()/100 + (*ri)->height();

 double y=(prefs.ypos<0) ? -(double)prefs.ypos : ((double)prefs.ypos*prefsdy)/100-h/2;
 if (y+h1 >= (double)prefsdy) y=(double)prefsdy-h1-1;
 if (y<0) y=0;

 int old_alignment=-1;
 int old_marginTop=-1,old_marginL=-1;

 for (const_iterator i=begin();i!=end();y+=(double)prefs.linespacing*(*i)->charHeight()/100,i++)
  {
   if (y<0) continue;

   unsigned int marginTop=(*i)->props.get_marginTop(prefsdy);
   unsigned int marginBottom=(*i)->props.get_marginBottom(prefsdy);

   // When the alignment or marginTop or marginL changes, it's a new paragraph.
   if ((*i)->props.alignment>0 && ((*i)->props.alignment!=old_alignment || old_marginTop!=(*i)->props.marginTop || old_marginL!=(*i)->props.marginL))
    {
     old_alignment=(*i)->props.alignment;
     old_marginTop=(*i)->props.marginTop;
     old_marginL=(*i)->props.marginL;
     // calculate the height of the paragraph
     double hParagraph=0;
     for (const_iterator pi=i;pi!=end();pi++)
      {
       if ((*pi)->props.alignment!=old_alignment || (*pi)->props.marginTop!=old_marginTop || (*pi)->props.marginL!=old_marginL)
        break;
       if (pi+1!=end() && (*(pi+1))->props.alignment==old_alignment && (*(pi+1))->props.marginTop==old_marginTop && (*(pi+1))->props.marginL==old_marginL)
        hParagraph+=(double)prefs.linespacing*(*pi)->charHeight()/100;
       else
        hParagraph+=(*pi)->height();
      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -