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

📄 tfont.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
📖 第 1 页 / 共 3 页
字号:

     switch ((*i)->props.alignment)
      {
       case 1: // SSA bottom
       case 2:
       case 3:
        y=prefsdy-hParagraph-marginBottom;
        break;
       case 9: // SSA mid
       case 10:
       case 11:
        y=(prefsdy-hParagraph)/2;
        break;
       case 5: // SSA top
       case 6:
       case 7:
        y=marginTop;
        break;
       default:
        break;
      }

     if (y+hParagraph>=(double)prefsdy)
      y=(double)prefsdy-hParagraph-1;
     if (y<0) y=0;
    }

   if (y+(*i)->height()>=(double)prefsdy) break;
   //TODO: cleanup
   int x;
   unsigned int cdx=(*i)->width();
   if (prefs.xpos<0) x=-prefs.xpos;
   else
    {
     switch ((*i)->props.alignment)
      {
       case 1: // left(SSA)
       case 5:
       case 9:
        x=(*i)->props.get_marginL(prefsdx);
        break;
       case 2: // center(SSA)
       case 6:
       case 10:
        x=(prefsdx-cdx)/2;
        if (x<0) x=0;
        if (x+cdx>=prefsdx) x=prefsdx-cdx;
        break;
       case 3: // right(SSA)
       case 7:
       case 11:
        x=prefsdx-cdx-(*i)->props.get_marginR(prefsdx);
        break;
       default: // -1 (non SSA)
        x=(prefs.xpos*prefsdx)/100+prefs.posXpix;
        switch (prefs.align)
         {
          case ALIGN_FFDSHOW:x=x-cdx/2;if (x<0) x=0;if (x+cdx>=prefsdx) x=prefsdx-cdx;break;
          case ALIGN_LEFT:break;
          case ALIGN_CENTER:x=x-cdx/2;break;
          case ALIGN_RIGHT:x=x-cdx;break;
         }
        break;
      }
    }
   // if (x+cdx>prefsdx) x=prefsdx-cdx-1;
   if (x<0) x=0;
   (*i)->print(x,y,prefs,prefsdx,prefsdy); // print a line (=print words).
  }
}
void TrenderedSubtitleLines::add(TrenderedSubtitleLine *ln,unsigned int *height)
{
 push_back(ln);
 if (height)
  *height+=ln->height();
}
void TrenderedSubtitleLines::clear(void)
{
 for (iterator l=begin();l!=end();l++)
  {
   (*l)->clear();
   delete *l;
  }
 std::vector<value_type>::clear();
}

//================================= TcharsChache =================================
TcharsChache::TcharsChache(HDC Ihdc,const short (*Imatrix)[5],const YUVcolor &Iyuv,int Ixscale,IffdshowBase *Ideci):hdc(Ihdc),matrix(Imatrix),yuv(Iyuv),xscale(Ixscale),deci(Ideci)
{
}
TcharsChache::~TcharsChache()
{
 for (Tchars::iterator c=chars.begin();c!=chars.end();c++)
  delete c->second;
}
template<> const TrenderedSubtitleWord* TcharsChache::getChar(const wchar_t *s,const TrenderedSubtitleLines::TprintPrefs &prefs)
{
 int key=(int)*s;
 Tchars::iterator l=chars.find(key);
 if (l!=chars.end()) return l->second;
 TrenderedSubtitleWord *ln=new TrenderedSubtitleWord(hdc,s,1,matrix,yuv,prefs,xscale);
 chars[key]=ln;
 return ln;
}

template<> const TrenderedSubtitleWord* TcharsChache::getChar(const char *s,const TrenderedSubtitleLines::TprintPrefs &prefs)
{
 if(_mbclen((unsigned char *)s)==1)
  {
   int key=(int)*s;
   Tchars::iterator l=chars.find(key);
   if (l!=chars.end()) return l->second;
   TrenderedSubtitleWord *ln=new TrenderedSubtitleWord(hdc,s,1,matrix,yuv,prefs,xscale);
   chars[key]=ln;
   return ln;
  }
 else
  {
   const wchar_t *mbcs=(wchar_t *)s; // ANSI-MBCS
   int key=(int)*mbcs;
   Tchars::iterator l=chars.find(key);
   if (l!=chars.end()) return l->second;
   TrenderedSubtitleWord *ln=new TrenderedSubtitleWord(hdc,s,2,matrix,yuv,prefs,xscale);
   chars[key]=ln;
   return ln;
  }
}

//==================================== Tfont ====================================
Tfont::Tfont(IffdshowBase *Ideci):
 fontManager(NULL),
 deci(Ideci),
 oldsub(NULL),
 hdc(NULL),oldFont(NULL),
 charsCache(NULL),
 height(0),
 fontSettings((TfontSettings*)malloc(sizeof(TfontSettings)))
{
}
Tfont::~Tfont()
{
 done();
 free(fontSettings);
}
void Tfont::init(const TfontSettings *IfontSettings)
{
 done();
 memcpy(fontSettings,IfontSettings,sizeof(TfontSettings));
 hdc=CreateCompatibleDC(NULL);
 if (!hdc) return;
 yuvcolor=YUVcolor(fontSettings->color);
 if (fontSettings->outlineStrength<100)
  for (int y=-2;y<=2;y++)
   for (int x=-2;x<=2;x++)
    {
     double d=8-(x*x+y*y);
     matrix[y+2][x+2]=short(3.57*fontSettings->outlineStrength*pow(d/8,2-fontSettings->outlineRadius/50.0)+0.5);
    }
 if (fontSettings->fast)
  charsCache=new TcharsChache(hdc,fontSettings->outlineStrength==100?NULL:matrix,yuvcolor,fontSettings->xscale,deci);
}
void Tfont::done(void)
{
 lines.clear();
 if (hdc)
  {
   if (oldFont) SelectObject(hdc,oldFont);oldFont=NULL;
   DeleteDC(hdc);hdc=NULL;
  }
 oldsub=NULL;
 if (charsCache) delete charsCache;charsCache=NULL;
}

template<class tchar> TrenderedSubtitleWord* Tfont::newWord(const tchar *s,size_t slen,TrenderedSubtitleLines::TprintPrefs prefs,const TsubtitleWord<tchar> *w,bool trimRightSpaces)
{
 OUTLINETEXTMETRIC otm;
 GetOutlineTextMetrics(hdc,sizeof(otm),&otm);

 ffstring s1(s);
 if (trimRightSpaces)
  {
   while (s1.size() && s1.at(s1.size()-1)==' ')
    s1.erase(s1.size()-1,1);
  }

 if (w->props.shadowDepth != -1) // SSA/ASS/ASS2
  {
   if (w->props.shadowDepth == 0)
    {
     prefs.shadowMode = 3;
     prefs.shadowSize = 0;
    }
   else
    {
     prefs.shadowMode = 2;
     prefs.shadowSize = -1 * w->props.shadowDepth;
    }
  }

 if (!w->props.isColor && fontSettings->fast && !otm.otmItalicAngle && !otm.otmTextMetrics.tmItalic && !(prefs.shadowSize!=0 && prefs.shadowMode!=3))
  return new TrenderedSubtitleWord(charsCache,s1.c_str(),slen,prefs); // fast rendering
 else
  return new TrenderedSubtitleWord(hdc,                      // full rendering
                                   s1.c_str(),
                                   slen,
                                   fontSettings->outlineStrength==100?NULL:matrix,w->props.isColor?w->props.color:yuvcolor,prefs,
                                   w->props.scaleX!=-1?w->props.scaleX:fontSettings->xscale,
                                   w->props.alignment);
}

template<class tchar> int Tfont::get_splitdx1(const TsubtitleWord<tchar> &w,int splitdx,int dx) const
{
 if (w.props.get_marginR(dx) || w.props.get_marginL(dx))
  return (dx- w.props.get_marginR(dx) - w.props.get_marginL(dx))*4;
 else
  return splitdx;
}

template<class tchar> void Tfont::prepareC(const TsubtitleTextBase<tchar> *sub,const TrenderedSubtitleLines::TprintPrefs &prefs,bool forceChange)
{
 if (oldsub!=sub || forceChange)
  {
   oldsub=sub;

   unsigned int dx,dy;
   if (prefs.sizeDx && prefs.sizeDy)
    {
     dx=prefs.sizeDx;
     dy=prefs.sizeDy;
    }
   else
    {
     dx=prefs.dx;
     dy=prefs.dy;
    }

   lines.clear();height=0;
   if (!sub) return;
   if (!fontManager)
    comptrQ<IffdshowDecVideo>(deci)->getFontManager(&fontManager);
   bool nosplit=!fontSettings->split && !(prefs.fontchangesplit && prefs.fontsplit);
   int splitdx0=nosplit?0:(prefs.textBorderLR-40>(int)dx?dx:dx-prefs.textBorderLR)*4;
   for (typename TsubtitleTextBase<tchar>::const_iterator l=sub->begin();l!=sub->end();l++)
    {
     TrenderedSubtitleLine *line=NULL;
     int splitdx=splitdx0;
     int splitdx1=-1;
     for (typename TsubtitleLine<tchar>::const_iterator w=l->begin();w!=l->end();w++)
      {
       if (splitdx1==-1)
        splitdx1=get_splitdx1(*w,splitdx,dx);
       LOGFONT lf;
       w->props.toLOGFONT(lf,*fontSettings,dx,dy);
       HFONT font=fontManager->getFont(lf);
       HGDIOBJ old=SelectObject(hdc,font);
       if (!oldFont) oldFont=old;
       SetTextCharacterExtra(hdc,w->props.spacing>=0?w->props.spacing:fontSettings->spacing);
       if (!line)
        {
         line=new TrenderedSubtitleLine(w->props);
         splitdx1=get_splitdx1(*w,splitdx,dx);
        }
       if (nosplit)
        line->push_back(newWord<tchar>(*w,strlen(*w),prefs,&*w));
       else
        {
         const tchar *p=*w;
         while (*p)
          {
           int nfit;
           SIZE sz;
           size_t strlenp=strlenp=strlen(p);
           int *pwidths=(int*)_alloca(sizeof(int)*(strlenp+1));
           if (!prefs.config->getGDI<tchar>().getTextExtentExPoint(hdc,p,(int)strlenp,splitdx1,&nfit,pwidths,&sz) || nfit>=(int)strlen(p))
            {
             TrenderedSubtitleWord *rw;
             if (w+1==l->end())
              rw=newWord(p,strlen(p),prefs,&*w,true); // trim right space
             else
              rw=newWord(p,strlen(p),prefs,&*w,false);
             line->push_back(rw);
             splitdx1-=rw->dxCharY*4;
             if (splitdx1<0) splitdx1=0;
             splitdx-=rw->dxCharY*4;
             if (splitdx<0) splitdx=0;
             break;
            }

           bool spaceOK=false;
           if (nfit==0) nfit=1;
           for (int j=nfit;j>0;j--)
            if (tchar_traits<tchar>::isspace((typename tchar_traits<tchar>::uchar_t)p[j]))
             {
              spaceOK=true;
              nfit=j;
              break;
             }

           if (spaceOK || /* to avoid infinity loop */ splitdx1==get_splitdx1(*w,splitdx,dx))
            {
             TrenderedSubtitleWord *rw=newWord(p,nfit,prefs,&*w,true);
             line->push_back(rw);
             p+=nfit;
            }
           lines.add(line,&height);
           line=new TrenderedSubtitleLine(w->props);
           splitdx1=get_splitdx1(*w,splitdx,dx);
           splitdx=splitdx0;
           while (*p && tchar_traits<tchar>::isspace((typename tchar_traits<tchar>::uchar_t)*p))
            p++;
          }
        }
      }

     if (line)
      if (!line->empty())
       lines.add(line,&height);
      else
       delete line;
    }
  }
}

template<class tchar> void Tfont::print(const TsubtitleTextBase<tchar> *sub,bool forceChange,const TrenderedSubtitleLines::TprintPrefs &prefs,unsigned int *y)
{
 if (!sub) return;
 prepareC(sub,prefs,forceChange);if (y) *y+=height;
 lines.print(prefs);
}

template void Tfont::print(const TsubtitleTextBase<char> *sub,bool forceChange,const TrenderedSubtitleLines::TprintPrefs &prefs,unsigned int *y);
template void Tfont::print(const TsubtitleTextBase<wchar_t> *sub,bool forceChange,const TrenderedSubtitleLines::TprintPrefs &prefs,unsigned int *y);

⌨️ 快捷键说明

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