123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654 |
- #include "video.h"
- #include <multimon.h>
- #include "subtitles.h"
- #define INIT_DIRECTDRAW_STRUCT(x) (ZeroMemory(&x, sizeof(x)), x.dwSize=sizeof(x))
- #define OV_COL_R 16
- #define OV_COL_G 0
- #define OV_COL_B 16
- OverlayVideoOutput::OverlayVideoOutput() {
- lpDD=NULL;
- lpddsOverlay=NULL;
- lpddsPrimary=NULL;
- is_fullscreen=0;
- yuy2_output=uyvy_output=0;
- m_parent=NULL;
- initing=false;
- needchange=0;
- memset(&m_oldrd,0,sizeof(m_oldrd));
- memset(&winRect,0,sizeof(winRect));
- subFont=NULL;
- m_fontsize=0;
- resetSubtitle();
- }
- OverlayVideoOutput::~OverlayVideoOutput() {
- if(is_fullscreen) removeFullScreen();
- LPDIRECTDRAWSURFACE o=lpddsOverlay;
- lpddsOverlay=NULL;
- if(o) o->Release();
- if(lpddsPrimary) lpddsPrimary->Release();
- if (lpDD) lpDD->Release(); // BU added NULL check in response to talkback
- if(subFont) DeleteObject(subFont);
- }
- static DWORD DD_ColorMatch(LPDIRECTDRAWSURFACE pdds, COLORREF rgb)
- {
- COLORREF rgbT;
- HDC hdc;
- DWORD dw = CLR_INVALID;
- DDSURFACEDESC ddsd;
- HRESULT hres;
-
- //
- // use GDI SetPixel to color match for us
- //
- if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
- {
- rgbT = GetPixel(hdc, 0, 0); // save current pixel value
- SetPixel(hdc, 0, 0, rgb); // set our value
- pdds->ReleaseDC(hdc);
- }
-
- //
- // now lock the surface so we can read back the converted color
- //
- ddsd.dwSize = sizeof(ddsd);
- while ((hres = pdds->Lock(NULL, &ddsd, 0, NULL)) ==
- DDERR_WASSTILLDRAWING)
- ;
-
- if (hres == DD_OK)
- {
- dw = *(DWORD *)ddsd.lpSurface; // get DWORD
- if(ddsd.ddpfPixelFormat.dwRGBBitCount<32)
- dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount) - 1; // mask it to bpp
- pdds->Unlock(NULL);
- }
-
- //
- // now put the color that was there back.
- //
- if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
- {
- SetPixel(hdc, 0, 0, rgbT);
- pdds->ReleaseDC(hdc);
- }
-
- return dw;
- }
- int OverlayVideoOutput::create(VideoOutput *parent, int w, int h, unsigned int ptype, int flipit, double aspectratio) {
- type=ptype;
- width=w;
- height=h;
- flip=flipit;
- m_parent=parent;
- initing=true;
- HWND hwnd=parent->getHwnd();
- if (lpDD) lpDD->Release();
- lpDD=NULL;
- update_monitor_coords(parent);
- if(!m_found_devguid) DirectDrawCreate(NULL,&lpDD,NULL);
- else DirectDrawCreate(&m_devguid,&lpDD,NULL);
- if(!lpDD) {
- initing=false;
- return 0;
- }
- lpDD->SetCooperativeLevel(hwnd,DDSCL_NOWINDOWCHANGES|DDSCL_NORMAL);
- DDSURFACEDESC ddsd;
- INIT_DIRECTDRAW_STRUCT(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
- HRESULT ddrval = lpDD->CreateSurface(&ddsd, &lpddsPrimary, NULL );
- // init overlay
- DDSURFACEDESC ddsdOverlay;
- INIT_DIRECTDRAW_STRUCT(ddsdOverlay);
- ddsdOverlay.ddsCaps.dwCaps=DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
- ddsdOverlay.dwFlags= DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH;
- ddsdOverlay.dwWidth=w;
- ddsdOverlay.dwHeight=h;
- ddsdOverlay.lPitch=w*4;
- ddsdOverlay.dwBackBufferCount=0;
- DDPIXELFORMAT pf[]=
- {
- {sizeof(DDPIXELFORMAT),DDPF_FOURCC,MAKEFOURCC('Y','U','Y','2'),0,0,0,0,0},
- {sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('U','Y','V','Y'),0,0,0,0,0}, // UYVY
- {sizeof(DDPIXELFORMAT),DDPF_FOURCC,MAKEFOURCC('Y','V','1','2'),0,0,0,0,0},
- };
- int tab[5];
- if(type==NSV_MAKETYPE('Y','U','Y','2')) {
- tab[0]=0; // default is YUY2
- tab[1]=1;
- tab[2]=-1;
- } else if(type==NSV_MAKETYPE('U','Y','V','Y')) {
- tab[0]=1; // make UYVY default
- tab[1]=0;
- tab[2]=-1;
- } else if(type==NSV_MAKETYPE('Y','V','1','2')) {
- /*tab[0]=2;
- tab[1]=0;
- tab[2]=1;
- tab[3]=-1;*/
- //CT> Make YUY2 default too, cause YV12 is borked on some ATI cards/drivers :(
- tab[0]=0;
- tab[1]=1;
- tab[2]=-1;
- } else {
- tab[0]=-1; // default is RGB
- }
- int x=4096;
- HRESULT v=-1;
- for (x = 0; x < sizeof(tab)/sizeof(tab[0]) && tab[x]>=0; x ++) {
- ddsdOverlay.ddpfPixelFormat=pf[tab[x]];
- v=lpDD->CreateSurface(&ddsdOverlay, &lpddsOverlay, NULL);
- if (!FAILED(v)) break;
- }
- if(FAILED(v)||x>=sizeof(tab)/sizeof(tab[0])||tab[x]<0) {
- initing=false;
- return 0;
- }
- yuy2_output = (tab[x] == 0);
- uyvy_output = (tab[x] == 1);
- INIT_DIRECTDRAW_STRUCT(capsDrv);
- ddrval = lpDD->GetCaps(&capsDrv, NULL);
- uDestSizeAlign = capsDrv.dwAlignSizeDest;
- uSrcSizeAlign = capsDrv.dwAlignSizeSrc;
- dwUpdateFlags = DDOVER_SHOW | DDOVER_KEYDESTOVERRIDE;
- DEVMODE d;
- d.dmSize=sizeof(d);
- d.dmDriverExtra=0;
- EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &d);
- int rv=OV_COL_R, gv=OV_COL_G, bv=OV_COL_B;
- INIT_DIRECTDRAW_STRUCT(ovfx);
- ovfx.dwDDFX=0;
- switch(d.dmBitsPerPel) {
- case 16:
- ovfx.dckDestColorkey.dwColorSpaceLowValue=((rv>>3) << 11) | ((gv>>2) << 5) | (bv>>3);
- break;
- case 15:
- ovfx.dckDestColorkey.dwColorSpaceLowValue=((rv>>3) << 10) | ((gv>>3) << 5) | (bv>>3);
- break;
- case 24: case 32:
- ovfx.dckDestColorkey.dwColorSpaceLowValue=(rv << 16) | (gv << 8) | bv;
- break;
- }
- //try to get the correct bit depth thru directdraw (for fucked up 16 bits displays for ie.)
- {
- DDSURFACEDESC DDsd={sizeof(DDsd),};
- lpddsPrimary->GetSurfaceDesc(&ddsd);
- DDsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT; //create the surface at screen depth
- DDsd.dwWidth=8;
- DDsd.dwHeight=8;
- DDsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
- LPDIRECTDRAWSURFACE tempsurf;
- if(lpDD->CreateSurface(&DDsd, &tempsurf, NULL)==DD_OK)
- {
- int res=DD_ColorMatch(tempsurf, RGB(rv,gv,bv));
- if(res!=CLR_INVALID) ovfx.dckDestColorkey.dwColorSpaceLowValue=res;
- tempsurf->Release();
- }
- }
- ovfx.dckDestColorkey.dwColorSpaceHighValue=ovfx.dckDestColorkey.dwColorSpaceLowValue;
- getRects(&rs,&rd);
- if(FAILED(lpddsOverlay->UpdateOverlay(&rs, lpddsPrimary, &rd, dwUpdateFlags, &ovfx))) {
- initing=false;
- return 0;
- }
- initing=false;
- DDSURFACEDESC dd={sizeof(dd),};
- if (lpddsOverlay->Lock(NULL,&dd,DDLOCK_WAIT,NULL) != DD_OK) return 0;
- unsigned char *o=(unsigned char*)dd.lpSurface;
- if (uyvy_output||yuy2_output)
- {
- int x=dd.lPitch*height/2;
- while (x--)
- {
- if (uyvy_output)
- {
- *o++=128;
- *o++=0;
- }
- else
- {
- *o++=0;
- *o++=-128;
- }
- }
- }
- else
- {
- memset(o,0,dd.lPitch*height); o+=dd.lPitch*height;
- memset(o,128,dd.lPitch*height/2);
- }
- lpddsOverlay->Unlock(&dd);
- InvalidateRect(hwnd,NULL,TRUE);
- return 1;
- }
- void OverlayVideoOutput::getRects(RECT *drs, RECT *drd) {
- HWND hwnd=m_parent->getHwnd();
- if(GetParent(hwnd)) hwnd=GetParent(hwnd);
- RECT rd,rs;
- GetClientRect(hwnd,&rd);
- ClientToScreen(hwnd,(LPPOINT)&rd);
- ClientToScreen(hwnd,((LPPOINT)&rd) + 1);
- m_parent->adjustAspect(rd);
- rd.left-=m_mon_x;
- rd.right-=m_mon_x;
- rd.top-=m_mon_y;
- rd.bottom-=m_mon_y;
- memset(&rs,0,sizeof(rs));
- rs.right=width;
- rs.bottom=height;
- //resize overlay for off-screen
- RECT rfull;
- //m_parent->getViewport(&rfull,NULL,1); //FUCKO: assume monitor 0
- m_parent->getViewport(&rfull,hwnd,1); //FUCKO: okay to use this hwnd? (fixes multimon! -RG)
- if(rd.right>rfull.right) {
- int diff=rd.right-rfull.right;
- float sc=(float)(width)/(float)(rd.right-rd.left);
- rd.right=rfull.right;
- rs.right=width-(int)(diff*sc);
- }
- if(rd.left<rfull.left) {
- int diff=rfull.left-rd.left;
- float sc=(float)(width)/(float)(rd.right-rd.left);
- rd.left=rfull.left;
- rs.left=(int)(diff*sc);
- }
- if(rd.bottom>rfull.bottom) {
- int diff=rd.bottom-rfull.bottom;
- float sc=(float)(height)/(float)(rd.bottom-rd.top);
- rd.bottom=rfull.bottom;
- rs.bottom=height-(int)(diff*sc);
- }
- if(rd.top<rfull.top) {
- int diff=rfull.top-rd.top;
- float sc=(float)(height)/(float)(rd.bottom-rd.top);
- rd.top=rfull.top;
- rs.top=(int)(diff*sc);
- }
- if (capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC && uDestSizeAlign) {
- rs.left = (int)((rs.left+uDestSizeAlign-1)/uDestSizeAlign)*uDestSizeAlign;
- rs.right = (int)((rs.right+uDestSizeAlign-1)/uDestSizeAlign)*uDestSizeAlign;
- }
- if (capsDrv.dwCaps & DDCAPS_ALIGNSIZEDEST && uDestSizeAlign) {
- rd.left = (int)((rd.left+uDestSizeAlign-1)/uDestSizeAlign)*uDestSizeAlign;
- rd.right = (int)((rd.right+uDestSizeAlign-1)/uDestSizeAlign)*uDestSizeAlign;
- }
- *drd=rd;
- *drs=rs;
- }
- void OverlayVideoOutput::timerCallback() {
- if(!m_parent) return;
- RECT rd,rs;
- getRects(&rs,&rd);
- if(memcmp(&m_oldrd,&rd,sizeof(RECT))) {
- m_oldrd=rd;
- if(!initing && lpddsOverlay)
- if(FAILED(lpddsOverlay->UpdateOverlay(&rs, lpddsPrimary, &rd, dwUpdateFlags, &ovfx))) {
- needchange=1;
- }
- }
- }
- int OverlayVideoOutput::onPaint(HWND hwnd, HDC hdc) {
- if(!m_parent) return 0;
- PAINTSTRUCT p;
- BeginPaint(hwnd,&p);
- RECT r;
- GetClientRect(hwnd,&r);
- LOGBRUSH lb={BS_SOLID,RGB(OV_COL_R,OV_COL_G,OV_COL_B),};
- HBRUSH br=CreateBrushIndirect(&lb);
- FillRect(p.hdc,&r,br);
- DeleteObject(br);
- if (curSubtitle)
- {
- int m_lastsubxp=curSubtitle->xPos;
- int m_lastsubyp=curSubtitle->yPos;
- HDC out=p.hdc;
-
- HGDIOBJ oldobj=SelectObject(out,subFont);
-
- SetBkMode(out,TRANSPARENT);
- int centerflags=0;
- if (m_lastsubxp < 127) centerflags |= DT_LEFT;
- else if (m_lastsubxp > 127) centerflags |= DT_RIGHT;
- else centerflags |= DT_CENTER;
- if (m_lastsubyp < 127) centerflags |= DT_TOP;
- else if (m_lastsubyp > 127) centerflags |= DT_BOTTOM;
-
- // draw outline
- SetTextColor(out,RGB(0,0,0));
- for (int y = -1; y < 2; y++)
- for (int x = -1; x < 2; x++)
- {
- if(!y && !x) continue;
- RECT r2={subRect.left+x,subRect.top+y,subRect.right+x,subRect.bottom+y};
- DrawText(out,curSubtitle->text,-1,&r2,centerflags|DT_NOCLIP|DT_NOPREFIX);
- }
- // draw text
- SetTextColor(out,RGB(curSubtitle->colorRed,curSubtitle->colorGreen,curSubtitle->colorBlue));
- DrawText(out,curSubtitle->text,-1,&subRect,centerflags|DT_NOCLIP|DT_NOPREFIX);
- SelectObject(out,oldobj);
- }
- EndPaint(hwnd,&p);
- return 1;
- }
- void OverlayVideoOutput::displayFrame(const char *buf, int size, int time) {
- if(!m_parent) return;
-
- DDSURFACEDESC dd={sizeof(dd),};
- if (m_parent->vid_vsync) lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,0);
- HRESULT result;
- if ((result=lpddsOverlay->Lock(NULL,&dd,DDLOCK_WAIT,NULL)) != DD_OK) {
- //CT>FUCKO:reenable me (ctrl+alt+del on win2k)
- //if(result==DDERR_SURFACELOST) width=-1; //will try to recreate the surface in the next processData() call
- return;
- }
- if(type==NSV_MAKETYPE('Y','V','1','2')) {
- const YV12_PLANES *planes=(YV12_PLANES *)buf;
- if (uyvy_output||yuy2_output) { // YV12planar->UYVY or YUY2
- unsigned char *o=(unsigned char*)dd.lpSurface;
- const unsigned char *yi=planes->y.baseAddr;
- const unsigned char *ui=planes->u.baseAddr;
- const unsigned char *vi=planes->v.baseAddr;
- int y=height;
- if (flip) o+=dd.lPitch*(height-1);
- while (y>0) {
- int x=width;
- unsigned char *oo=o;
-
- if (uyvy_output) while (x>0) {
- o[0]=*ui++; o[1]=*yi++; o[2]=*vi++; o[3]=*yi++;
- o+=4; x-=2;
- }
- else while (x>0) {
- o[0]=*yi++; o[1]=*ui++; o[2]=*yi++; o[3]=*vi++;
- o+=4; x-=2;
- }
- ui-=width/2;
- vi-=width/2;
- yi+=planes->y.rowBytes-width;
- x=width;
- if (flip) o=oo-dd.lPitch;
- else o+=dd.lPitch-width*2;
- oo=o;
- if (uyvy_output) while (x>0) {
- o[0]=*ui++; o[1]=*yi++; o[2]=*vi++; o[3]=*yi++;
- o+=4; x-=2;
- } else while (x>0) {
- o[0]=*yi++; o[1]=*ui++; o[2]=*yi++; o[3]=*vi++;
- o+=4; x-=2;
- }
- if (flip) o=oo-dd.lPitch;
- else o+=dd.lPitch-width*2;
- ui+=planes->u.rowBytes-(width/2);
- vi+=planes->v.rowBytes-(width/2);
- yi+=planes->y.rowBytes-width;
- y-=2;
- }
- } else { // woo native YV12 copy
- int f=!!flip;
- char *o=(char*)dd.lpSurface+(f*height*dd.lPitch);
- const char *i=(const char*)planes->y.baseAddr;
- int d_o=dd.lPitch;
- if (f) d_o=-d_o;
- else o-=d_o;
-
- int h2=height;
- while (h2--) {
- o+=d_o; memcpy(o,i,width); i+=planes->y.rowBytes;
- }
- d_o/=2;
- int w2=width/2;
- h2=height/2;
- i=(const char*)planes->v.baseAddr;
- o=(char*)dd.lpSurface+(height*dd.lPitch*(f+4))/4;
- if (!f) o-=d_o;
- while (h2--) {
- o+=d_o; memcpy(o,i,w2); i+=planes->v.rowBytes;
- }
- o=(char*)dd.lpSurface+(height*dd.lPitch*(f+5))/4;
- i=(const char*)planes->u.baseAddr;
- h2=height/2;
- if (!f) o-=d_o;
- while (h2--) {
- o+=d_o; memcpy(o,i,w2);i+=planes->u.rowBytes;
- }
- }
- } else if(type==NSV_MAKETYPE('Y','U','Y','2') || type==NSV_MAKETYPE('U','Y','V','Y')) {
- const char *a=buf;
- char *b=(char *)dd.lpSurface;
- int l=width*2,l2=dd.lPitch;
- if(flip) {
- b+=(height-1)*l2;
- l2=-l2;
- }
- int is_uyvy=type==NSV_MAKETYPE('U','Y','V','Y');
- if (uyvy_output && !is_uyvy || (yuy2_output && is_uyvy)) // convert to uyvy
- {
- for(int i=0;i<height;i++) {
- int x=width/2;
- while (x-->0) {
- b[0]=a[1];
- b[1]=a[0];
- b[2]=a[3];
- b[3]=a[2];
- a+=4;
- b+=4;
- }
- memcpy(b,a,l);
- b+=l2;
- a+=l;
- }
- } else {
- //wee straight YUY2 copy
- for(int i=0;i<height;i++) {
- memcpy(b,a,l);
- b+=l2;
- a+=l;
- }
- }
- }
- lpddsOverlay->Unlock(&dd);
- if (m_parent->osdShowing())
- {
- RECT rs, rd;
- getRects(&rs,&rd);
- HDC hdc;
- #if 1 // set both these 1s to 0s to put it back on ryan's mode
- HWND h=m_parent->getHwnd();
- hdc=GetDC(h);
- #else
- if (lpddsPrimary->GetDC(&hdc)==DD_OK)
- {
- #endif
- m_parent->drawOSD(hdc, &rd);
- #if 1
- ReleaseDC(h,hdc);
- #else
- lpddsPrimary->ReleaseDC(hdc);
- }
- #endif
- }
- }
- void OverlayVideoOutput::goFullScreen() {
- /* fullscreen_controls = new GuiObjectWnd;
- fullscreen_controls->setContent("video.fullscreen_controls");
- fullscreen_controls->init(m_parent);
- RECT r;
- Std::getViewport(&r,m_parent->gethWnd(),1);
- RECT nr = r;
- nr.top = (int)(r.bottom - (r.bottom - r.top) * 0.15);
- nr.bottom = (int)(r.bottom - (r.bottom - r.top) * 0.05);
- fullscreen_controls->resizeToRect(&nr);
- */
- is_fullscreen=1;
- }
- void OverlayVideoOutput::removeFullScreen() {
- /* delete fullscreen_controls;
- fullscreen_controls = NULL;*/
- is_fullscreen=0;
- }
- int OverlayVideoOutput::showOSD() {
- // if (fullscreen_controls != NULL) fullscreen_controls->setVisible(TRUE);
- // enabling the following code will cause the top & bottom OSD bars
- // to squish the image (instead of crop it):
- /*if(lpddsOverlay) {
- RECT rd,rs;
- getRects(&rs,&rd);
-
- HWND hwnd=m_parent->getHwnd();
- if(GetParent(hwnd)) hwnd=GetParent(hwnd);
-
- RECT temp;
- GetClientRect(hwnd,&temp);
- int bottom_margin = ((temp.bottom-temp.top) - (rd.bottom-rd.top)) / 2;
- int pixels_to_clip = max(0, m_parent->getOSDbarHeight() - bottom_margin);
- rd.bottom -= pixels_to_clip;
- lpddsOverlay->UpdateOverlay(&rs, lpddsPrimary, &rd, dwUpdateFlags, &ovfx);
- }*/
- return 1;
- }
- void OverlayVideoOutput::hideOSD() {
- //if (fullscreen_controls != NULL) fullscreen_controls->setVisible(FALSE);
- // 1) repaint the OSD area with the overlay color here
- HWND hwnd = m_parent->getHwnd();
- if(GetParent(hwnd)) hwnd=GetParent(hwnd);
- HDC hdc = GetDC(hwnd);
- if (hdc) {
- RECT r;
- GetClientRect(hwnd,&r);
- LOGBRUSH lb={BS_SOLID,RGB(OV_COL_R,OV_COL_G,OV_COL_B),};
- HBRUSH br=CreateBrushIndirect(&lb);
- FillRect(hdc,&r,br);
- DeleteObject(br);
- ReleaseDC(hwnd, hdc);
- }
- // 2) readjust the overlay destination rectangle
- /*if(lpddsOverlay) {
- RECT rd,rs;
- getRects(&rs,&rd);
- lpddsOverlay->UpdateOverlay(&rs, lpddsPrimary, &rd, dwUpdateFlags, &ovfx);
- }*/
- }
- void OverlayVideoOutput::drawSubtitle(SubsItem *item) {
- curSubtitle=item;
- HWND hwnd=m_parent->getHwnd();
- RECT oldrect=subRect;
- GetClientRect(hwnd,&subRect);
-
- if(item) {
- RECT oldwinRect=winRect;
- GetClientRect(hwnd,&winRect);
- if(!subFont || ((winRect.bottom-winRect.top)!=(oldwinRect.bottom-oldwinRect.top)) || m_fontsize!=item->fontSize) {
- if(subFont) DeleteObject(subFont);
- m_fontsize=item->fontSize;
- subFont=CreateFont(14+item->fontSize+18*(winRect.bottom-winRect.top)/768,0,0,0,FW_SEMIBOLD,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_OUTLINE_PRECIS,CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"Arial");
- }
- HDC out=GetDC(hwnd);
- SelectObject(out,subFont);
- SIZE s;
- GetTextExtentPoint32(out,item->text,strlen(item->text),&s);
- {
- // calcul for multiline text
- const char *p=item->text;
- int n=0;
- while(*p!=0) if(*p++=='\n') n++;
- if(n) s.cy*=(n+1);
- }
- if (item->xPos > 127) // towards the right
- {
- subRect.right -= ((subRect.right-subRect.left) * (255-item->xPos)) / 256;
- }
- else if (item->xPos < 127)
- {
- subRect.left += ((subRect.right-subRect.left) * item->xPos) / 256;
- }
- subRect.top += ((subRect.bottom-s.cy-subRect.top) * item->yPos)/255;
- subRect.bottom=subRect.top + s.cy;
- ReleaseDC(hwnd,out);
- }
- //just redraw the correct portion
- InvalidateRect(hwnd,&oldrect,TRUE);
- InvalidateRect(hwnd,&subRect,TRUE);
- }
- void OverlayVideoOutput::resetSubtitle()
- {
- curSubtitle=NULL;
- subRect.top=65536;
- }
|