{
vgmutex.lock();
taskmutex.lock();
- lastrendertime=getTimeMS();
- display_height=0;
- display_width=0;
- mode=0;
- aspect_correction=1.;
+ lastrendertime = getTimeMS();
+ display_height = 0;
+ display_width = 0;
+ mode = 0;
+ aspect_correction = 1.;
bcm_backres = 0;
- freetype_inited=false;
- wait_id=1;
- const char *fontname="Droid Sans:style=Regular";
- cur_fontname=(char*)malloc(strlen(fontname)+1);
- strcpy(cur_fontname,fontname);
+ freetype_inited = false;
+ wait_id = 1;
+ const char* fontname = "Droid Sans:style=Regular";
+ cur_fontname = (char*)malloc(strlen(fontname) + 1);
+ strcpy(cur_fontname, fontname);
#define EXTERNALPICTURE(name, fname, fileextension) static_artwork_begin[sa_ ## name]=name ## _data;
if (initted)
{
- shutdown();
+ shutdown();
}
if (cur_fontname) free(cur_fontname);
+
if (freetype_inited) FT_Done_Face(ft_face);
// I think the following is broken as it is, but also possibly it shouldn't be free()ing the memory
// pointed at anyway, so it's correctly not working?!
- if (!fontnames.size()) {
- std::vector<char*>::iterator itty=fontnames.begin();
- while (itty!=fontnames.end()) {
- free((void*)*itty);
+ if (!fontnames.size())
+ {
+ std::vector<char*>::iterator itty = fontnames.begin();
+
+ while (itty != fontnames.end())
+ {
+ free((void*)*itty);
- itty++;
- }
+ itty++;
+ }
}
// end
- if (fontnames_keys.size()) {
- std::vector<char*>::iterator itty=fontnames_keys.begin();
- while (itty!=fontnames_keys.end()) {
- free((void*)*itty);
- itty++;
- }
+ if (fontnames_keys.size())
+ {
+ std::vector<char*>::iterator itty = fontnames_keys.begin();
+
+ while (itty != fontnames_keys.end())
+ {
+ free((void*)*itty);
+ itty++;
}
+ }
vgmutex.unlock();
taskmutex.unlock();
int OsdOpenVG::init()
{
if (initted) return 0;
+
reader.init();
- //init broadcom chipset (Move to video?)
+ //init broadcom chipset (Move to video?)
- //First get connection to egl
- egl_display=eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ //First get connection to egl
+ egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+
+ if (egl_display == EGL_NO_DISPLAY)
+ {
+ Log::getInstance()->log("OSD", Log::WARN, "Could not get egl display! %x", eglGetError());
+ vgmutex.unlock();
+ return 0;
+ }
+
+
+
+ if (eglInitialize(egl_display, NULL, NULL) == EGL_FALSE)
+ {
+ Log::getInstance()->log("OSD", Log::WARN, "Initialising display failed! %x", eglGetError());
+ vgmutex.unlock();
+ return 0;
+ }
+
- if (egl_display==EGL_NO_DISPLAY) {
- Log::getInstance()->log("OSD", Log::WARN, "Could not get egl display! %x",eglGetError());
- vgmutex.unlock();
- return 0;
- }
+ const char* query_str = eglQueryString(egl_display, EGL_CLIENT_APIS);
+ if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
+ else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x", eglGetError());
+ query_str = eglQueryString(egl_display, EGL_EXTENSIONS);
- if (eglInitialize(egl_display, NULL, NULL)==EGL_FALSE) {
- Log::getInstance()->log("OSD", Log::WARN, "Initialising display failed! %x",eglGetError());
- vgmutex.unlock();
- return 0;
- }
+ if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
+ else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x", eglGetError());
+ if (eglBindAPI(EGL_OPENVG_API) == EGL_FALSE)
+ {
+ Log::getInstance()->log("OSD", Log::WARN, "Binding openvg api failed! %x", eglGetError());
+ vgmutex.unlock();
+ return 0;
+ }
- const char *query_str=eglQueryString(egl_display,EGL_CLIENT_APIS);
- if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
- else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",eglGetError());
- query_str=eglQueryString(egl_display,EGL_EXTENSIONS);
- if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
- else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",eglGetError());
+ const EGLint attributs[] =
+ {
+ EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8,
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
+ EGL_CONFORMANT, EGL_OPENVG_BIT,
+ EGL_NONE
+ }; // Here, we might have to select the resolution!
- if (eglBindAPI(EGL_OPENVG_API)==EGL_FALSE) {
- Log::getInstance()->log("OSD", Log::WARN, "Binding openvg api failed! %x",eglGetError());
- vgmutex.unlock();
- return 0;
- }
- const EGLint attributs[]={
- EGL_RED_SIZE,8,EGL_GREEN_SIZE, 8,EGL_BLUE_SIZE, 8,EGL_ALPHA_SIZE, 8,
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT,
- EGL_CONFORMANT, EGL_OPENVG_BIT,
- EGL_NONE
- }; // Here, we might have to select the resolution!
+ EGLint number;
+ if (eglChooseConfig(egl_display, attributs, &egl_ourconfig, 1, &number) == EGL_FALSE)
+ {
+ Log::getInstance()->log("OSD", Log::WARN, "Choosing egl config failed! %x", eglGetError());
+ vgmutex.unlock();
+ return 0;
+ }
- EGLint number;
- if (eglChooseConfig(egl_display, attributs, &egl_ourconfig, 1, &number)==EGL_FALSE) {
- Log::getInstance()->log("OSD", Log::WARN, "Choosing egl config failed! %x",eglGetError());
- vgmutex.unlock();
- return 0;
- }
+ egl_context = eglCreateContext(egl_display, egl_ourconfig, NULL, NULL);
+ if (egl_context == EGL_NO_CONTEXT)
+ {
+ Log::getInstance()->log("OSD", Log::WARN, "Creating egl context failed! %x", eglGetError());
+ vgmutex.unlock();
+ return 0;
+ }
- egl_context=eglCreateContext(egl_display,egl_ourconfig,NULL,NULL);
- if (egl_context==EGL_NO_CONTEXT) {
- Log::getInstance()->log("OSD", Log::WARN, "Creating egl context failed! %x",eglGetError());
- vgmutex.unlock();
- return 0;
- }
+ // warning broadcom specific, get display size!
+ display_width = display_height = 0;
- // warning broadcom specific, get display size!
- display_width=display_height=0;
- if (graphics_get_display_size(0, &display_width, &display_height)<0) {
- Log::getInstance()->log("OSD", Log::WARN, "Getting display size failed! (BCM API) ");
- vgmutex.unlock();
- return 0;
- }
- Log::getInstance()->log("OSD", Log::NOTICE, "Displaysize is %d x %d ",display_width, display_height);
- VC_RECT_T dst_rect = {0, 0, (int32_t)display_width, (int32_t)display_height};
- VC_RECT_T src_rect={0,0,BACKBUFFER_WIDTH <<16,BACKBUFFER_HEIGHT<<16};
- VC_RECT_T src_rect_bg={0,0,16<<16,16<<16};
-// VC_RECT_T src_rect_im={0,0,16,16};
+ if (graphics_get_display_size(0, &display_width, &display_height) < 0)
+ {
+ Log::getInstance()->log("OSD", Log::WARN, "Getting display size failed! (BCM API) ");
+ vgmutex.unlock();
+ return 0;
+ }
- uint32_t back_image_ptr;
- bcm_backres=vc_dispmanx_resource_create(VC_IMAGE_RGBX32,16,16,&back_image_ptr);
+ Log::getInstance()->log("OSD", Log::NOTICE, "Displaysize is %d x %d ", display_width, display_height);
+ VC_RECT_T dst_rect = {0, 0, (int32_t)display_width, (int32_t)display_height};
+ VC_RECT_T src_rect = {0, 0, BACKBUFFER_WIDTH << 16, BACKBUFFER_HEIGHT << 16};
+ VC_RECT_T src_rect_bg = {0, 0, 16 << 16, 16 << 16};
+ // VC_RECT_T src_rect_im={0,0,16,16};
+ uint32_t back_image_ptr;
+ bcm_backres = vc_dispmanx_resource_create(VC_IMAGE_RGBX32, 16, 16, &back_image_ptr);
- updateBackgroundColor(DrawStyle::WALLPAPER);
+ updateBackgroundColor(DrawStyle::WALLPAPER);
- DISPMANX_UPDATE_HANDLE_T bcm_update;
- bcm_display=vc_dispmanx_display_open(0);
- bcm_update=vc_dispmanx_update_start(0);
- bcm_element=vc_dispmanx_element_add(bcm_update,bcm_display,
- 2,&dst_rect, 0,
- &src_rect,DISPMANX_PROTECTION_NONE,0, 0, (DISPMANX_TRANSFORM_T) 0);
+ DISPMANX_UPDATE_HANDLE_T bcm_update;
+ bcm_display = vc_dispmanx_display_open(0);
+ bcm_update = vc_dispmanx_update_start(0);
+ bcm_element = vc_dispmanx_element_add(bcm_update, bcm_display,
+ 2, &dst_rect, 0,
+ &src_rect, DISPMANX_PROTECTION_NONE, 0, 0, (DISPMANX_TRANSFORM_T) 0);
- bcm_background=vc_dispmanx_element_add(bcm_update,bcm_display,
- 0,&dst_rect,bcm_backres ,
- &src_rect_bg,DISPMANX_PROTECTION_NONE,0, 0, (DISPMANX_TRANSFORM_T) 0);
- vc_dispmanx_update_submit_sync(bcm_update);
+ bcm_background = vc_dispmanx_element_add(bcm_update, bcm_display,
+ 0, &dst_rect, bcm_backres,
+ &src_rect_bg, DISPMANX_PROTECTION_NONE, 0, 0, (DISPMANX_TRANSFORM_T) 0);
+ vc_dispmanx_update_submit_sync(bcm_update);
- static EGL_DISPMANX_WINDOW_T nativewindow;
- nativewindow.element=bcm_element;
- nativewindow.height=BACKBUFFER_HEIGHT;
- nativewindow.width=BACKBUFFER_WIDTH;
- egl_surface = eglCreateWindowSurface(egl_display,egl_ourconfig, &nativewindow,NULL );
- if (egl_surface==EGL_NO_SURFACE) {
- Log::getInstance()->log("OSD", Log::WARN, "Creating egl window surface failed!");
- vgmutex.unlock();
- return 0;
- }
- Log::getInstance()->log("OSD", Log::DEBUG, "Making egl current in1%d",syscall(SYS_gettid));
- if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
- Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed");
- vgmutex.unlock();
- return 0;
- }
- // Test stuff
+ static EGL_DISPMANX_WINDOW_T nativewindow;
+ nativewindow.element = bcm_element;
+ nativewindow.height = BACKBUFFER_HEIGHT;
+ nativewindow.width = BACKBUFFER_WIDTH;
- query_str=(const char*)vgGetString(VG_VERSION) ;
- if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
- else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",vgGetError());
+ egl_surface = eglCreateWindowSurface(egl_display, egl_ourconfig, &nativewindow, NULL );
- query_str=(const char*)vgGetString(VG_VENDOR) ;
- if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
- else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",vgGetError());
+ if (egl_surface == EGL_NO_SURFACE)
+ {
+ Log::getInstance()->log("OSD", Log::WARN, "Creating egl window surface failed!");
+ vgmutex.unlock();
+ return 0;
+ }
- query_str=(const char*)vgGetString(VG_RENDERER) ;
- if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
- else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",vgGetError());
+ Log::getInstance()->log("OSD", Log::DEBUG, "Making egl current in1%d", syscall(SYS_gettid));
- query_str=(const char*)vgGetString(VG_EXTENSIONS) ;
- if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
- else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x",vgGetError());
+ if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) == EGL_FALSE)
+ {
+ Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed");
+ vgmutex.unlock();
+ return 0;
+ }
- aspect_correction= ((float)BACKBUFFER_HEIGHT)/576.f/(((float)BACKBUFFER_WIDTH)/720.f);
+ // Test stuff
+
+ query_str = (const char*)vgGetString(VG_VERSION) ;
+
+ if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
+ else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x", vgGetError());
+
+ query_str = (const char*)vgGetString(VG_VENDOR) ;
+
+ if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
+ else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x", vgGetError());
+
+ query_str = (const char*)vgGetString(VG_RENDERER) ;
+
+ if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
+ else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x", vgGetError());
+
+ query_str = (const char*)vgGetString(VG_EXTENSIONS) ;
+
+ if (query_str) Log::getInstance()->logLongString("OSD", Log::NOTICE, query_str);
+ else Log::getInstance()->log("OSD", Log::WARN, "Could not query display %x", vgGetError());
+
+ aspect_correction = ((float)BACKBUFFER_HEIGHT) / 576.f / (((float)BACKBUFFER_WIDTH) / 720.f);
initPaths();
- if (!fontnames.size()) {
- //inspired by and copied from vdr's code
- FcInit();
- FcObjectSet *objset= FcObjectSetBuild(FC_FAMILY, FC_STYLE, NULL);
- FcPattern * pattern=FcPatternCreate();
- FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
- FcFontSet* fonts = FcFontList(NULL, pattern, objset);
- for (int i=0; i<fonts->nfont;i++) {
- char *s = (char *)FcNameUnparse(fonts->fonts[i]);
-
- if (s) {
- char *c= strchr(s,':');
- if (c) {
- char *s2= strchr(c+1,',');
- if (s2) *s2=0;
- }
- char *p=strchr(s,',');
- if (p) {
- if (!c) *p=0;
- else memmove(p,c,strlen(c)+1);
- }
- char *key=(char*)malloc(strlen(s)+1);
- strcpy(key,s);
- fontnames_keys.push_back(key);
- char *s2=strstr(s,"style=");
- if (s2) {
- memmove(s2,s2+6,strlen(s2+6)+1);
- }
- fontnames.push_back(s);
- }
- }
- FcFontSetDestroy(fonts);
- FcPatternDestroy(pattern);
- FcObjectSetDestroy(objset);
+
+ if (!fontnames.size())
+ {
+ //inspired by and copied from vdr's code
+ FcInit();
+ FcObjectSet* objset = FcObjectSetBuild(FC_FAMILY, FC_STYLE, NULL);
+ FcPattern* pattern = FcPatternCreate();
+ FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
+ FcFontSet* fonts = FcFontList(NULL, pattern, objset);
+
+ for (int i = 0; i < fonts->nfont; i++)
+ {
+ char* s = (char*)FcNameUnparse(fonts->fonts[i]);
+
+ if (s)
+ {
+ char* c = strchr(s, ':');
+
+ if (c)
+ {
+ char* s2 = strchr(c + 1, ',');
+
+ if (s2) *s2 = 0;
+ }
+
+ char* p = strchr(s, ',');
+
+ if (p)
+ {
+ if (!c) *p = 0;
+ else memmove(p, c, strlen(c) + 1);
+ }
+
+ char* key = (char*)malloc(strlen(s) + 1);
+ strcpy(key, s);
+ fontnames_keys.push_back(key);
+ char* s2 = strstr(s, "style=");
+
+ if (s2)
+ {
+ memmove(s2, s2 + 6, strlen(s2 + 6) + 1);
+ }
+
+ fontnames.push_back(s);
+ }
+ }
+
+ FcFontSetDestroy(fonts);
+ FcPatternDestroy(pattern);
+ FcObjectSetDestroy(objset);
}
- if (!loadFont(false)) {
- return 0;
+ if (!loadFont(false))
+ {
+ return 0;
}
- vgttfont=vgCreateFont(0);
- vgttpaint=vgCreatePaint();
+
+ vgttfont = vgCreateFont(0);
+ vgttpaint = vgCreatePaint();
vgSetParameteri( vgttpaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
- vgSetColor(vgttpaint,0xffffffff);
+ vgSetColor(vgttpaint, 0xffffffff);
eglSwapInterval(egl_display, 1 );
- Log::getInstance()->log("OSD", Log::DEBUG, "Making egl current out 1%d",syscall(SYS_gettid));
+ Log::getInstance()->log("OSD", Log::DEBUG, "Making egl current out 1%d", syscall(SYS_gettid));
eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
//Now we will create the Screen
initted = true; // must set this here or create surface won't work
/*if (((VideoOMX*)Video::getInstance())->initUsingOSDObjects()!=1) { //call Video for init stuff
- return 0;
+ return 0;
}*/
vgmutex.unlock();
#ifdef PICTURE_DECODER_OMX
- imageomx=new ImageOMX(&reader);
- reader.addDecoder(imageomx);
+ imageomx = new ImageOMX(&reader);
+ reader.addDecoder(imageomx);
#endif
void OsdOpenVG::updateBackgroundColor(DrawStyle bg)
{
- unsigned int color[16*16];
- if (!bcm_backres) return;
- VC_RECT_T src_rect_im={0,0,16,16};
+ unsigned int color[16 * 16];
- if (bg.ft!=DrawStyle::GradientLinear) {
- bg.grad_col[0]=bg;
- }
- //memset(color,0xFF,sizeof(unsigned int)*4*8);
- for (int j=0;j<16;j++) {
- int helpr=(((15-j)*bg.red)+(j*bg.grad_col[0].red))/15;
- int helpb=(((15-j)*bg.blue)+(j*bg.grad_col[0].blue))/15;
- int helpg=(((15-j)*bg.green)+(j*bg.grad_col[0].green))/15;
- //unsigned int cur_col=help | (help<< 8) | (help<< 16) | (0xFF<< 24);
- unsigned int cur_col=helpr | (helpg<< (8)) | (helpb<< (16)) | (0xFF<< (24));
- for (int i=0;i<16;i++) {
- color[i+16*j]=cur_col;
- }
- }
- vc_dispmanx_resource_write_data(bcm_backres,VC_IMAGE_RGBX32,16*4,color,&src_rect_im);
+ if (!bcm_backres) return;
+
+ VC_RECT_T src_rect_im = {0, 0, 16, 16};
+
+ if (bg.ft != DrawStyle::GradientLinear)
+ {
+ bg.grad_col[0] = bg;
+ }
+
+ //memset(color,0xFF,sizeof(unsigned int)*4*8);
+ for (int j = 0; j < 16; j++)
+ {
+ int helpr = (((15 - j) * bg.red) + (j * bg.grad_col[0].red)) / 15;
+ int helpb = (((15 - j) * bg.blue) + (j * bg.grad_col[0].blue)) / 15;
+ int helpg = (((15 - j) * bg.green) + (j * bg.grad_col[0].green)) / 15;
+ //unsigned int cur_col=help | (help<< 8) | (help<< 16) | (0xFF<< 24);
+ unsigned int cur_col = helpr | (helpg << (8)) | (helpb << (16)) | (0xFF << (24));
+
+ for (int i = 0; i < 16; i++)
+ {
+ color[i + 16 * j] = cur_col;
+ }
+ }
+
+ vc_dispmanx_resource_write_data(bcm_backres, VC_IMAGE_RGBX32, 16 * 4, color, &src_rect_im);
}
-void OsdOpenVG::getScreenSize(int &width, int &height)
+void OsdOpenVG::getScreenSize(int& width, int& height)
{
- width=BACKBUFFER_WIDTH;
- height=BACKBUFFER_HEIGHT;
+ width = BACKBUFFER_WIDTH;
+ height = BACKBUFFER_HEIGHT;
}
-void OsdOpenVG::getRealScreenSize(int &width, int &height)
+void OsdOpenVG::getRealScreenSize(int& width, int& height)
{
- width=display_width;
- height=display_height;
+ width = display_width;
+ height = display_height;
}
-bool OsdOpenVG::screenShot(void *buffer, int width, int height, bool osd /*include osd*/)
+bool OsdOpenVG::screenShot(void* buffer, int width, int height, bool osd /*include osd*/)
{
- if (!initted) return false;
- if (!buffer) return false;
-
- DISPMANX_RESOURCE_HANDLE_T res;
- DISPMANX_DISPLAY_HANDLE_T display;
-
- uint32_t image_ptr;
- VC_RECT_T rect;
- res=vc_dispmanx_resource_create(VC_IMAGE_RGBA32,width,height,&image_ptr);
- display=vc_dispmanx_display_open(0);
- if (!osd) {
- vc_dispmanx_snapshot(display, res,
- (DISPMANX_TRANSFORM_T)(DISPMANX_SNAPSHOT_NO_RGB|DISPMANX_SNAPSHOT_FILL/*|DISPMANX_SNAPSHOT_PACK*/));
- }
- else
- {
- vc_dispmanx_snapshot(display, res,
- (DISPMANX_TRANSFORM_T)(DISPMANX_SNAPSHOT_FILL));
- }
- vc_dispmanx_rect_set(&rect,0,0,width,height);
- vc_dispmanx_resource_read_data(res, &rect, buffer, width*4);
- vc_dispmanx_resource_delete(res);
- vc_dispmanx_display_close(display);
- return true;
+ if (!initted) return false;
+
+ if (!buffer) return false;
+
+ DISPMANX_RESOURCE_HANDLE_T res;
+ DISPMANX_DISPLAY_HANDLE_T display;
+
+ uint32_t image_ptr;
+ VC_RECT_T rect;
+ res = vc_dispmanx_resource_create(VC_IMAGE_RGBA32, width, height, &image_ptr);
+ display = vc_dispmanx_display_open(0);
+
+ if (!osd)
+ {
+ vc_dispmanx_snapshot(display, res,
+ (DISPMANX_TRANSFORM_T)(DISPMANX_SNAPSHOT_NO_RGB | DISPMANX_SNAPSHOT_FILL/*|DISPMANX_SNAPSHOT_PACK*/));
+ }
+ else
+ {
+ vc_dispmanx_snapshot(display, res,
+ (DISPMANX_TRANSFORM_T)(DISPMANX_SNAPSHOT_FILL));
+ }
+
+ vc_dispmanx_rect_set(&rect, 0, 0, width, height);
+ vc_dispmanx_resource_read_data(res, &rect, buffer, width * 4);
+ vc_dispmanx_resource_delete(res);
+ vc_dispmanx_display_close(display);
+ return true;
}
{
- VGPath current;
- current=vgCreatePath(VG_PATH_FORMAT_STANDARD,
- VG_PATH_DATATYPE_F,1.f,0.f,
- 0,0,VG_PATH_CAPABILITY_ALL);
-
- vguLine(current,0.f,0.f,1.f,0.f);
- // HorzLine
- std_paths[PIHorzLine]=current;
-
- current=vgCreatePath(VG_PATH_FORMAT_STANDARD,
- VG_PATH_DATATYPE_F,1.f,0.f,
- 0,0,VG_PATH_CAPABILITY_ALL);
- vguLine(current,0.f,0.f,0.f,1.f);
- // VertLine
- std_paths[PIVertLine]=current;
-
- current=vgCreatePath(VG_PATH_FORMAT_STANDARD,
- VG_PATH_DATATYPE_F,1.f,0.f,
- 0,0,VG_PATH_CAPABILITY_ALL);
- //vguRect(current,0.f,0.f,1.f,1.f);
- vguRect(current,0.f,0.f,1.f,1.f);
- // Rectabgle
- std_paths[PIRectangle]=current;
-
- current=vgCreatePath(VG_PATH_FORMAT_STANDARD,
- VG_PATH_DATATYPE_F,1.f,0.f,
- 0,0,0);
- vguEllipse(current,0.f,0.f,1.f,1.f);
- // Point
- std_paths[PIPoint]=current;
+ VGPath current;
+ current = vgCreatePath(VG_PATH_FORMAT_STANDARD,
+ VG_PATH_DATATYPE_F, 1.f, 0.f,
+ 0, 0, VG_PATH_CAPABILITY_ALL);
+
+ vguLine(current, 0.f, 0.f, 1.f, 0.f);
+ // HorzLine
+ std_paths[PIHorzLine] = current;
+
+ current = vgCreatePath(VG_PATH_FORMAT_STANDARD,
+ VG_PATH_DATATYPE_F, 1.f, 0.f,
+ 0, 0, VG_PATH_CAPABILITY_ALL);
+ vguLine(current, 0.f, 0.f, 0.f, 1.f);
+ // VertLine
+ std_paths[PIVertLine] = current;
+
+ current = vgCreatePath(VG_PATH_FORMAT_STANDARD,
+ VG_PATH_DATATYPE_F, 1.f, 0.f,
+ 0, 0, VG_PATH_CAPABILITY_ALL);
+ //vguRect(current,0.f,0.f,1.f,1.f);
+ vguRect(current, 0.f, 0.f, 1.f, 1.f);
+ // Rectabgle
+ std_paths[PIRectangle] = current;
+
+ current = vgCreatePath(VG_PATH_FORMAT_STANDARD,
+ VG_PATH_DATATYPE_F, 1.f, 0.f,
+ 0, 0, 0);
+ vguEllipse(current, 0.f, 0.f, 1.f, 1.f);
+ // Point
+ std_paths[PIPoint] = current;
}
void OsdOpenVG::destroyPaths()
{
- vgDestroyPath(std_paths[PIHorzLine]);
- vgDestroyPath(std_paths[PIVertLine]);
- vgDestroyPath(std_paths[PIRectangle]);
- vgDestroyPath(std_paths[PIPoint]);
+ vgDestroyPath(std_paths[PIHorzLine]);
+ vgDestroyPath(std_paths[PIVertLine]);
+ vgDestroyPath(std_paths[PIRectangle]);
+ vgDestroyPath(std_paths[PIPoint]);
}
int OsdOpenVG::stopUpdate()
{
- threadStop();
- processTasks();
- return 1;
+ threadStop();
+ processTasks();
+ return 1;
}
/*
void OsdOpenVG::purgeAllReferences()
{
reader.shutdown();
#ifdef PICTURE_DECODER_OMX
- if (imageomx) reader.removeDecoder(imageomx);
- imageomx=NULL;
+
+ if (imageomx) reader.removeDecoder(imageomx);
+
+ imageomx = NULL;
#endif
if (!initted) return 0;
Log::getInstance()->log("OSD", Log::DEBUG, "shutdown mark1");
threadStop();
Log::getInstance()->log("OSD", Log::DEBUG, "shutdown mark1a");
+
//(((VideoOMX*)Video::getInstance())->shutdownUsingOSDObjects());
- if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
- Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed in shutdown %x",eglGetError());
+ if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) == EGL_FALSE)
+ {
+ Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed in shutdown %x", eglGetError());
}
- if (eglBindAPI(EGL_OPENVG_API)==EGL_FALSE) {
- Log::getInstance()->log("OSD", Log::WARN, "Binding openvg api thread failed! %x",eglGetError());
+
+ if (eglBindAPI(EGL_OPENVG_API) == EGL_FALSE)
+ {
+ Log::getInstance()->log("OSD", Log::WARN, "Binding openvg api thread failed! %x", eglGetError());
}
Log::getInstance()->log("OSD", Log::DEBUG, "shutdown mark2");
vgDestroyFont(vgttfont);
vgDestroyPaint(vgttpaint);
destroyPaths();
- float colclear[]={0.8f,0.8f,0.8f,1.f};
- vgSetfv(VG_CLEAR_COLOR,4,colclear);
- vgClear(0,0,BACKBUFFER_WIDTH,BACKBUFFER_HEIGHT);
+ float colclear[] = {0.8f, 0.8f, 0.8f, 1.f};
+ vgSetfv(VG_CLEAR_COLOR, 4, colclear);
+ vgClear(0, 0, BACKBUFFER_WIDTH, BACKBUFFER_HEIGHT);
eglSwapBuffers(egl_display, egl_surface);
Log::getInstance()->log("OSD", Log::DEBUG, "Making egl current out final");
eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
- if (eglDestroySurface(egl_display,egl_surface)==EGL_FALSE) {
- Log::getInstance()->log("OSD", Log::ERR, "eglDestroySurface failed %x",eglGetError());
+
+ if (eglDestroySurface(egl_display, egl_surface) == EGL_FALSE)
+ {
+ Log::getInstance()->log("OSD", Log::ERR, "eglDestroySurface failed %x", eglGetError());
}
- if (eglDestroyContext(egl_display,egl_context)==EGL_FALSE) {
- Log::getInstance()->log("OSD", Log::ERR, "eglDestroyContext failed %x",eglGetError());
+
+ if (eglDestroyContext(egl_display, egl_context) == EGL_FALSE)
+ {
+ Log::getInstance()->log("OSD", Log::ERR, "eglDestroyContext failed %x", eglGetError());
}
- if (eglTerminate(egl_display )==EGL_FALSE) {
- Log::getInstance()->log("OSD", Log::ERR, "eglTerminate failed %x",eglGetError());
+
+ if (eglTerminate(egl_display ) == EGL_FALSE)
+ {
+ Log::getInstance()->log("OSD", Log::ERR, "eglTerminate failed %x", eglGetError());
}
DISPMANX_UPDATE_HANDLE_T bcm_update;
- bcm_update=vc_dispmanx_update_start(0);
+ bcm_update = vc_dispmanx_update_start(0);
- vc_dispmanx_element_remove(bcm_update,bcm_element);
- vc_dispmanx_element_remove(bcm_update,bcm_background);
+ vc_dispmanx_element_remove(bcm_update, bcm_element);
+ vc_dispmanx_element_remove(bcm_update, bcm_background);
vc_dispmanx_update_submit_sync(bcm_update);
vc_dispmanx_resource_delete(bcm_backres);
bcm_backres = 0;
void OsdOpenVG::threadMethod()
{
- // We have to claim the egl context for this thread
- Log::getInstance()->log("OSD", Log::NOTICE, "Entering drawing thread");
- if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context)== EGL_FALSE) {
- Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed in thread %x",eglGetError());
- return;
- }
- if (eglBindAPI(EGL_OPENVG_API)==EGL_FALSE) {
- Log::getInstance()->log("OSD", Log::WARN, "Binding openvg api thread failed! %x",eglGetError());
- return;
- }
- int ts=0;
- while (true)
- {
- ts=1;
- //unsigned int waittime=1;
-
- if (initted) {
-
- long long time1 = getTimeMS();
- if ((time1 - lastrendertime) > 200) {//5 fps for OSD updates are enough, avoids tearing
- InternalRendering();
- lastrendertime = getTimeMS();
-
- ts = 10;
- }
- else {
- ts = time1 - lastrendertime;
-
- }
- if (processTasks()) ts=0;
- }
- if (!threadIsActive()) {
- if (eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT )== EGL_FALSE) {
- Log::getInstance()->log("OSD", Log::WARN, "Making egl Current out thread failed");
- }
- threadCheckExit();
- }
- if (ts!=0) {
- struct timespec target_time;
- clock_gettime(CLOCK_REALTIME,&target_time);
- target_time.tv_nsec+=1000000LL*ts;
- if (target_time.tv_nsec>999999999) {
- target_time.tv_nsec-=1000000000L;
- target_time.tv_sec+=1;
- }
- threadLock();
- threadWaitForSignalTimed(&target_time);
- threadUnlock();
- }
- //Sleep(1);
- }
- eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
+ // We have to claim the egl context for this thread
+ Log::getInstance()->log("OSD", Log::NOTICE, "Entering drawing thread");
+
+ if (eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context) == EGL_FALSE)
+ {
+ Log::getInstance()->log("OSD", Log::WARN, "Making egl Current failed in thread %x", eglGetError());
+ return;
+ }
+
+ if (eglBindAPI(EGL_OPENVG_API) == EGL_FALSE)
+ {
+ Log::getInstance()->log("OSD", Log::WARN, "Binding openvg api thread failed! %x", eglGetError());
+ return;
+ }
+
+ int ts = 0;
+
+ while (true)
+ {
+ ts = 1;
+ //unsigned int waittime=1;
+
+ if (initted)
+ {
+
+ long long time1 = getTimeMS();
+
+ if ((time1 - lastrendertime) > 200) //5 fps for OSD updates are enough, avoids tearing
+ {
+ InternalRendering();
+ lastrendertime = getTimeMS();
+
+ ts = 10;
+ }
+ else
+ {
+ ts = time1 - lastrendertime;
+
+ }
+
+ if (processTasks()) ts = 0;
+ }
+
+ if (!threadIsActive())
+ {
+ if (eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ) == EGL_FALSE)
+ {
+ Log::getInstance()->log("OSD", Log::WARN, "Making egl Current out thread failed");
+ }
+
+ threadCheckExit();
+ }
+
+ if (ts != 0)
+ {
+ struct timespec target_time;
+ clock_gettime(CLOCK_REALTIME, &target_time);
+ target_time.tv_nsec += 1000000LL * ts;
+
+ if (target_time.tv_nsec > 999999999)
+ {
+ target_time.tv_nsec -= 1000000000L;
+ target_time.tv_sec += 1;
+ }
+
+ threadLock();
+ threadWaitForSignalTimed(&target_time);
+ threadUnlock();
+ }
+
+ //Sleep(1);
+ }
+
+ eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
}
-void OsdOpenVG::InternalRendering(){
- vgmutex.lock();
- Colour bg=DrawStyle::WALLPAPER;
- float colclear[]={1.f,1.0f,1.f,1.f};
- if (bg.alpha==0) colclear[3]=0.f;
- vgSetfv(VG_CLEAR_COLOR,4,colclear);
- vgClear(0,0,BACKBUFFER_WIDTH,BACKBUFFER_HEIGHT);
- vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
+void OsdOpenVG::InternalRendering()
+{
+ vgmutex.lock();
+ Colour bg = DrawStyle::WALLPAPER;
+ float colclear[] = {1.f, 1.0f, 1.f, 1.f};
+
+ if (bg.alpha == 0) colclear[3] = 0.f;
+ vgSetfv(VG_CLEAR_COLOR, 4, colclear);
+ vgClear(0, 0, BACKBUFFER_WIDTH, BACKBUFFER_HEIGHT);
+ vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
- drawSurfaces(); //iterate through and draws all commands
- //Show it to the user!
- eglSwapBuffers(egl_display, egl_surface);
- vgmutex.unlock();
+ drawSurfaces(); //iterate through and draws all commands
+
+ //Show it to the user!
+ eglSwapBuffers(egl_display, egl_surface);
+ vgmutex.unlock();
}
float OsdOpenVG::getFontHeight()
{
- return font_height; //dummy
+ return font_height; //dummy
}
float OsdOpenVG::getCharWidth(wchar_t c)
{
- if (c<256) return byte_char_width[c];
- unsigned int glyph_index=FT_Get_Char_Index(ft_face,c);
- return font_exp_x[glyph_index];
+ if (c < 256) return byte_char_width[c];
+
+ unsigned int glyph_index = FT_Get_Char_Index(ft_face, c);
+ return font_exp_x[glyph_index];
}
unsigned int OsdOpenVG::loadTTchar(cTeletextChar c)
{
- unsigned int glyph_index=c.getGlyphIndex();
- if (tt_font_chars.find(glyph_index)!=tt_font_chars.end())
- {
- return glyph_index;
- }
+ unsigned int glyph_index = c.getGlyphIndex();
- unsigned int buffer[10];
- const VGfloat glyphOrigin[] = { 0.f, 0.f };
- const VGfloat escapement[] = { 12.f, 0.f };
- unsigned int * charmap = GetFontChar(c, buffer);
- if (!charmap) { //invalid char
- return 0;
- }
- for (int i=0;i<10;i++) {
- buffer[i]=charmap[i]>>4;
- }
+ if (tt_font_chars.find(glyph_index) != tt_font_chars.end())
+ {
+ return glyph_index;
+ }
+
+ unsigned int buffer[10];
+ const VGfloat glyphOrigin[] = { 0.f, 0.f };
+ const VGfloat escapement[] = { 12.f, 0.f };
+ unsigned int* charmap = GetFontChar(c, buffer);
- VGImage handle = vgCreateImage(
- VG_A_8,
- 12,
- 10,
- VG_IMAGE_QUALITY_NONANTIALIASED | VG_IMAGE_QUALITY_FASTER
- | VG_IMAGE_QUALITY_BETTER);
- vgImageSubData(handle, buffer, 4, VG_A_1, 0, 0, 12, 10);
- vgSetGlyphToImage(
- vgttfont,
- glyph_index,
- handle, (VGfloat*)glyphOrigin, (VGfloat*)escapement);
- vgDestroyImage(handle);
- tt_font_chars[glyph_index]=1;
-
- return glyph_index;
+ if (!charmap) //invalid char
+ {
+ return 0;
+ }
+
+ for (int i = 0; i < 10; i++)
+ {
+ buffer[i] = charmap[i] >> 4;
+ }
+
+ VGImage handle = vgCreateImage(
+ VG_A_8,
+ 12,
+ 10,
+ VG_IMAGE_QUALITY_NONANTIALIASED | VG_IMAGE_QUALITY_FASTER
+ | VG_IMAGE_QUALITY_BETTER);
+ vgImageSubData(handle, buffer, 4, VG_A_1, 0, 0, 12, 10);
+ vgSetGlyphToImage(
+ vgttfont,
+ glyph_index,
+ handle, (VGfloat*)glyphOrigin, (VGfloat*)escapement);
+ vgDestroyImage(handle);
+ tt_font_chars[glyph_index] = 1;
+
+ return glyph_index;
}
-int OsdOpenVG::getFontNames(const char *** names,const char *** names_keys)
+int OsdOpenVG::getFontNames(const char*** names, const char*** names_keys)
{
- *names=(const char**)&(fontnames[0]);
- *names_keys=(const char**)&(fontnames_keys[0]);
- return fontnames.size();
+ *names = (const char**) & (fontnames[0]);
+ *names_keys = (const char**) & (fontnames_keys[0]);
+ return fontnames.size();
}
-void OsdOpenVG::setFont(const char * fontname) {
+void OsdOpenVG::setFont(const char* fontname)
+{
+
+ if (strcmp(fontname, cur_fontname))
+ {
+ // new font!
+ if (cur_fontname) free(cur_fontname);
- if (strcmp(fontname,cur_fontname)) {
- // new font!
- if (cur_fontname) free(cur_fontname);
- cur_fontname = static_cast<char*>(malloc(strlen(fontname)+1));
- strcpy(cur_fontname,fontname);
+ cur_fontname = static_cast<char*>(malloc(strlen(fontname) + 1));
+ strcpy(cur_fontname, fontname);
- struct OpenVGCommand comm;
- comm.task=OVGreplacefont;
- putOpenVGCommand(comm,false);
+ struct OpenVGCommand comm;
+ comm.task = OVGreplacefont;
+ putOpenVGCommand(comm, false);
- }
+ }
}
int OsdOpenVG::loadFont(bool newfont)
{
- int error;
- float font_size=16.f;
- if (!freetype_inited) {
- error=FT_Init_FreeType(&ft_library);
- if (error)
- {
- Log::getInstance()->log("OSD", Log::WARN, "Could not load freetype %x",error);
- return 0;
- }
- }
+ int error;
+ float font_size = 16.f;
- if (!freetype_inited || newfont) {
- //first get the filename algorith extracted from vdr by Klaus Schmidinger
- FcInit();
- FcPattern *pattern=FcNameParse((FcChar8*)cur_fontname);
- FcPatternAddBool(pattern,FC_SCALABLE,FcTrue);
- FcConfigSubstitute(NULL,pattern,FcMatchPattern);
- FcDefaultSubstitute(pattern);
- FcResult fres;
- FcFontSet *fonts=FcFontSort(NULL,pattern,FcFalse,NULL,&fres);
- FcChar8 *filename=NULL;
- if (fonts) {
- for (int i=0;i<fonts->nfont;i++) {
- FcBool canscale;
- FcPatternGetBool(fonts->fonts[i],FC_SCALABLE,0,&canscale);
- if (canscale){
- FcPatternGetString(fonts->fonts[i],FC_FILE,0,&filename);
- break;
- }
- }
- FcFontSetDestroy(fonts);
- } else {
- Log::getInstance()->log("OSD", Log::CRIT, "Could not locate a font! Abort!");
- return 0;
- }
- FcPatternDestroy(pattern);
-
- Log::getInstance()->log("OSD", Log::NOTICE, "Load Font %s: %s", cur_fontname,filename);
- // second load the font
- FT_Face new_ft_face;
- error=FT_New_Face(ft_library,(const char*)filename,0,&new_ft_face );
- if (error) {
- Log::getInstance()->log("OSD", Log::WARN, "Could not load font face %x %s",error,filename);
- return 0;
- }
- error=FT_Set_Char_Size(new_ft_face,0,font_size*256,0,0 /*dpi*/);
- if (error) {
- FT_Done_Face(new_ft_face);
- Log::getInstance()->log("OSD", Log::WARN, "Could not set face size %x",error);
- return 0;
- }
- FT_Face old_ft_face=ft_face; // do it thread safe
- ft_face=new_ft_face;
- if (freetype_inited) FT_Done_Face(old_ft_face);//
- freetype_inited=true;
- }
- vgfont=vgCreateFont(0);
- FT_ULong cur_char;
- FT_UInt glyph;
- font_height=ft_face->size->metrics.height/256.f;
- cur_char = FT_Get_First_Char(ft_face,&glyph);
- std::vector<VGubyte> segments;
- std::vector<VGfloat> coord;
- segments.reserve(256);
- coord.reserve(1024);
- //Log::getInstance()->log("OSD", Log::DEBUG, "Create Glyph test %d %x %x %d",cur_char,font_data_end,font_data,glyph);
- while (glyph !=0)
- {
- error=FT_Load_Glyph(ft_face,glyph,FT_LOAD_DEFAULT);
- if (error){
- cur_char = FT_Get_Next_Char(ft_face,cur_char,&glyph);
- Log::getInstance()->log("OSD", Log::WARN, "Could not load glyph %x %c",error);
- continue;
- }
- VGPath path;
- FT_Outline ot=ft_face->glyph->outline;
- segments.clear();
- coord.clear();
-
- if (ot.n_contours ==0) {
- path=VG_INVALID_HANDLE;
- } else {
- path=vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
- 1.0f,0.f,0,0,VG_PATH_CAPABILITY_ALL);
-
- /* convert glyph */
- FT_Vector *pt=ot.points;
- const char *tags=ot.tags;
- const short* cont=ot.contours;
- short n_cont=ot.n_contours;
- //short n_point=ot.n_points;
- //short last_cont=0;
- for (short point=0;n_cont!=0;cont++,n_cont--) {
- short next_cont=*cont+1;
- bool first=true;
- char last_tag=0;
- short first_point=point;
- //Log::getInstance()->log("OSD", Log::DEBUG, "runs %d",*cont);
- for (;point<next_cont;point++) {
- char tag=tags[point];
- FT_Vector fpoint=pt[point];
- // Log::getInstance()->log("OSD", Log::DEBUG, "tag %d point %d %d: %d %d",tag,fpoint.x,fpoint.y,point,n_point);
- if (first) {
- segments.push_back(VG_MOVE_TO);
- first=false;
- } else if (tag &0x1) { //on curve
- if (last_tag &0x1) {
- segments.push_back(VG_LINE_TO);
- } else if (last_tag &0x2){
- segments.push_back(VG_CUBIC_TO);
- } else {
- segments.push_back(VG_QUAD_TO);
- }
-
- } else {
- if (!(tag &0x2)){
- if (!(last_tag &0x1)) {
- segments.push_back(VG_QUAD_TO);
- int coord_size=coord.size();
- VGfloat x=(coord[coord_size-2]+ ((float)fpoint.x)/256.f)*0.5f*aspect_correction;
- VGfloat y=(coord[coord_size-1]+(font_size- ((float)fpoint.y)/256.f))*0.5f;
- coord.push_back(x);
- coord.push_back(y);
- }
- }
-
-
- }
- last_tag=tag;
- coord.push_back(((float)fpoint.x)*aspect_correction/256.);
- coord.push_back(font_size-((float)fpoint.y)/256.);
- //Log::getInstance()->log("OSD", Log::DEBUG, "Create APD Glyph coord %d %d %g %g",fpoint.x,fpoint.y,coord[coord.size()-2],coord[coord.size()-1]);
- }
- if (!(last_tag &0x1)) {
- if (last_tag &0x2) {
- segments.push_back(VG_CUBIC_TO);
- } else {
- segments.push_back(VG_QUAD_TO);
- }
- coord.push_back(((float)pt[first_point].x)*aspect_correction/256.);
- coord.push_back(font_size-((float)pt[first_point].y)/256.);
- }
- //segments.push_back(VG_CLOSE_PATH);
-
-
- }
- vgAppendPathData(path,segments.size(),&segments[0],&coord[0]);
- /* for (int m=0;m<segments.size();m++) {
- int n=0;
- switch (segments[m])
- {
- case VG_MOVE_TO:
- Log::getInstance()->log("OSD", Log::DEBUG, "Move To %g %g",coord[n],coord[n+1]);n+=2; break;
- case VG_LINE_TO:
- Log::getInstance()->log("OSD", Log::DEBUG, "Line To %g %g",coord[n],coord[n+1]);n+=2; break;
- case VG_CUBIC_TO:
- Log::getInstance()->log("OSD", Log::DEBUG, "Cubic To %g %g %g %g %g %g",coord[n],coord[n+1],coord[n+2],coord[n+3],coord[n+4],coord[n+5]);n+=6; break;
- case VG_QUAD_TO:
- Log::getInstance()->log("OSD", Log::DEBUG, "Quad To %g %g %g %g",coord[n],coord[n+1],coord[n+2],coord[n+3]);n+=4; break;
- case VG_CLOSE_PATH:
- Log::getInstance()->log("OSD", Log::DEBUG, "Close Path"); break;
- }
-
- }*/
- //vguRect(path,0.f,0.f,1.f,1.f);
- //Log::getInstance()->log("OSD", Log::DEBUG, "Create APD Glyph %d %x",segments.size(),vgGetError());
- }
- VGfloat ori[]={0.f,0.f};
- VGfloat esp[]={ft_face->glyph->advance.x/256.f*aspect_correction,ft_face->glyph->advance.y/256.f};
- font_exp_x[glyph]=ft_face->glyph->advance.x/256.f*aspect_correction; //recalculate
-
- vgSetGlyphToPath(vgfont,glyph,path,VG_FALSE,ori,esp);
- //Log::getInstance()->log("OSD", Log::DEBUG, "Create Glyph %d %d %x",path,glyph,vgGetError());
- if (path!=VG_INVALID_HANDLE) {
- vgDestroyPath(path);
- }
- cur_char = FT_Get_Next_Char(ft_face,cur_char,&glyph);
- }
- for (int i=0;i<256;i++) {
- unsigned int glyph_index=FT_Get_Char_Index(ft_face,i);
- byte_char_width[i]=font_exp_x[glyph_index];
- }
- return 1;
+ if (!freetype_inited)
+ {
+ error = FT_Init_FreeType(&ft_library);
+
+ if (error)
+ {
+ Log::getInstance()->log("OSD", Log::WARN, "Could not load freetype %x", error);
+ return 0;
+ }
+ }
+
+ if (!freetype_inited || newfont)
+ {
+ //first get the filename algorith extracted from vdr by Klaus Schmidinger
+ FcInit();
+ FcPattern* pattern = FcNameParse((FcChar8*)cur_fontname);
+ FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
+ FcConfigSubstitute(NULL, pattern, FcMatchPattern);
+ FcDefaultSubstitute(pattern);
+ FcResult fres;
+ FcFontSet* fonts = FcFontSort(NULL, pattern, FcFalse, NULL, &fres);
+ FcChar8* filename = NULL;
+
+ if (fonts)
+ {
+ for (int i = 0; i < fonts->nfont; i++)
+ {
+ FcBool canscale;
+ FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &canscale);
+
+ if (canscale)
+ {
+ FcPatternGetString(fonts->fonts[i], FC_FILE, 0, &filename);
+ break;
+ }
+ }
+
+ FcFontSetDestroy(fonts);
+ }
+ else
+ {
+ Log::getInstance()->log("OSD", Log::CRIT, "Could not locate a font! Abort!");
+ return 0;
+ }
+
+ FcPatternDestroy(pattern);
+
+ Log::getInstance()->log("OSD", Log::NOTICE, "Load Font %s: %s", cur_fontname, filename);
+ // second load the font
+ FT_Face new_ft_face;
+ error = FT_New_Face(ft_library, (const char*)filename, 0, &new_ft_face );
+
+ if (error)
+ {
+ Log::getInstance()->log("OSD", Log::WARN, "Could not load font face %x %s", error, filename);
+ return 0;
+ }
+
+ error = FT_Set_Char_Size(new_ft_face, 0, font_size * 256, 0, 0 /*dpi*/);
+
+ if (error)
+ {
+ FT_Done_Face(new_ft_face);
+ Log::getInstance()->log("OSD", Log::WARN, "Could not set face size %x", error);
+ return 0;
+ }
+
+ FT_Face old_ft_face = ft_face; // do it thread safe
+ ft_face = new_ft_face;
+
+ if (freetype_inited) FT_Done_Face(old_ft_face);//
+
+ freetype_inited = true;
+ }
+
+ vgfont = vgCreateFont(0);
+ FT_ULong cur_char;
+ FT_UInt glyph;
+ font_height = ft_face->size->metrics.height / 256.f;
+ cur_char = FT_Get_First_Char(ft_face, &glyph);
+ std::vector<VGubyte> segments;
+ std::vector<VGfloat> coord;
+ segments.reserve(256);
+ coord.reserve(1024);
+
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Create Glyph test %d %x %x %d",cur_char,font_data_end,font_data,glyph);
+ while (glyph != 0)
+ {
+ error = FT_Load_Glyph(ft_face, glyph, FT_LOAD_DEFAULT);
+
+ if (error)
+ {
+ cur_char = FT_Get_Next_Char(ft_face, cur_char, &glyph);
+ Log::getInstance()->log("OSD", Log::WARN, "Could not load glyph %x %c", error);
+ continue;
+ }
+
+ VGPath path;
+ FT_Outline ot = ft_face->glyph->outline;
+ segments.clear();
+ coord.clear();
+
+ if (ot.n_contours == 0)
+ {
+ path = VG_INVALID_HANDLE;
+ }
+ else
+ {
+ path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
+ 1.0f, 0.f, 0, 0, VG_PATH_CAPABILITY_ALL);
+
+ /* convert glyph */
+ FT_Vector* pt = ot.points;
+ const char* tags = ot.tags;
+ const short* cont = ot.contours;
+ short n_cont = ot.n_contours;
+
+ //short n_point=ot.n_points;
+ //short last_cont=0;
+ for (short point = 0; n_cont != 0; cont++, n_cont--)
+ {
+ short next_cont = *cont + 1;
+ bool first = true;
+ char last_tag = 0;
+ short first_point = point;
+
+ //Log::getInstance()->log("OSD", Log::DEBUG, "runs %d",*cont);
+ for (; point < next_cont; point++)
+ {
+ char tag = tags[point];
+ FT_Vector fpoint = pt[point];
+
+ // Log::getInstance()->log("OSD", Log::DEBUG, "tag %d point %d %d: %d %d",tag,fpoint.x,fpoint.y,point,n_point);
+ if (first)
+ {
+ segments.push_back(VG_MOVE_TO);
+ first = false;
+ }
+ else if (tag & 0x1) //on curve
+ {
+ if (last_tag & 0x1)
+ {
+ segments.push_back(VG_LINE_TO);
+ }
+ else if (last_tag & 0x2)
+ {
+ segments.push_back(VG_CUBIC_TO);
+ }
+ else
+ {
+ segments.push_back(VG_QUAD_TO);
+ }
+
+ }
+ else
+ {
+ if (!(tag & 0x2))
+ {
+ if (!(last_tag & 0x1))
+ {
+ segments.push_back(VG_QUAD_TO);
+ int coord_size = coord.size();
+ VGfloat x = (coord[coord_size - 2] + ((float)fpoint.x) / 256.f) * 0.5f * aspect_correction;
+ VGfloat y = (coord[coord_size - 1] + (font_size - ((float)fpoint.y) / 256.f)) * 0.5f;
+ coord.push_back(x);
+ coord.push_back(y);
+ }
+ }
+
+
+ }
+
+ last_tag = tag;
+ coord.push_back(((float)fpoint.x)*aspect_correction / 256.);
+ coord.push_back(font_size - ((float)fpoint.y) / 256.);
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Create APD Glyph coord %d %d %g %g",fpoint.x,fpoint.y,coord[coord.size()-2],coord[coord.size()-1]);
+ }
+
+ if (!(last_tag & 0x1))
+ {
+ if (last_tag & 0x2)
+ {
+ segments.push_back(VG_CUBIC_TO);
+ }
+ else
+ {
+ segments.push_back(VG_QUAD_TO);
+ }
+
+ coord.push_back(((float)pt[first_point].x)*aspect_correction / 256.);
+ coord.push_back(font_size - ((float)pt[first_point].y) / 256.);
+ }
+
+ //segments.push_back(VG_CLOSE_PATH);
+
+
+ }
+
+ vgAppendPathData(path, segments.size(), &segments[0], &coord[0]);
+ /* for (int m=0;m<segments.size();m++) {
+ int n=0;
+ switch (segments[m])
+ {
+ case VG_MOVE_TO:
+ Log::getInstance()->log("OSD", Log::DEBUG, "Move To %g %g",coord[n],coord[n+1]);n+=2; break;
+ case VG_LINE_TO:
+ Log::getInstance()->log("OSD", Log::DEBUG, "Line To %g %g",coord[n],coord[n+1]);n+=2; break;
+ case VG_CUBIC_TO:
+ Log::getInstance()->log("OSD", Log::DEBUG, "Cubic To %g %g %g %g %g %g",coord[n],coord[n+1],coord[n+2],coord[n+3],coord[n+4],coord[n+5]);n+=6; break;
+ case VG_QUAD_TO:
+ Log::getInstance()->log("OSD", Log::DEBUG, "Quad To %g %g %g %g",coord[n],coord[n+1],coord[n+2],coord[n+3]);n+=4; break;
+ case VG_CLOSE_PATH:
+ Log::getInstance()->log("OSD", Log::DEBUG, "Close Path"); break;
+ }
+
+ }*/
+ //vguRect(path,0.f,0.f,1.f,1.f);
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Create APD Glyph %d %x",segments.size(),vgGetError());
+ }
+
+ VGfloat ori[] = {0.f, 0.f};
+ VGfloat esp[] = {ft_face->glyph->advance.x / 256.f * aspect_correction, ft_face->glyph->advance.y / 256.f};
+ font_exp_x[glyph] = ft_face->glyph->advance.x / 256.f * aspect_correction; //recalculate
+
+ vgSetGlyphToPath(vgfont, glyph, path, VG_FALSE, ori, esp);
+
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Create Glyph %d %d %x",path,glyph,vgGetError());
+ if (path != VG_INVALID_HANDLE)
+ {
+ vgDestroyPath(path);
+ }
+
+ cur_char = FT_Get_Next_Char(ft_face, cur_char, &glyph);
+ }
+
+ for (int i = 0; i < 256; i++)
+ {
+ unsigned int glyph_index = FT_Get_Char_Index(ft_face, i);
+ byte_char_width[i] = font_exp_x[glyph_index];
+ }
+
+ return 1;
}
-void OsdOpenVG::drawSetTrans(SurfaceCommands & sc)
+void OsdOpenVG::drawSetTrans(SurfaceCommands& sc)
{
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
- vgLoadIdentity();
- vgScale(((float)BACKBUFFER_WIDTH)/720.f, -((float)BACKBUFFER_HEIGHT)/576.f);
- vgTranslate(0.f+sc.x,-576.f+sc.y);
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadIdentity();
+ vgScale(((float)BACKBUFFER_WIDTH) / 720.f, -((float)BACKBUFFER_HEIGHT) / 576.f);
+ vgTranslate(0.f + sc.x, -576.f + sc.y);
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
- vgLoadIdentity();
- vgScale(((float)BACKBUFFER_WIDTH)/720.f, -((float)BACKBUFFER_HEIGHT)/576.f);
- vgTranslate(0.f+sc.x,-576.f+sc.y);
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
+ vgLoadIdentity();
+ vgScale(((float)BACKBUFFER_WIDTH) / 720.f, -((float)BACKBUFFER_HEIGHT) / 576.f);
+ vgTranslate(0.f + sc.x, -576.f + sc.y);
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
- vgLoadIdentity();
- vgScale(((float)BACKBUFFER_WIDTH)/720.f, -((float)BACKBUFFER_HEIGHT)/576.f);
- vgTranslate(0.f+sc.x,-576.f+sc.y);
- clip_shift_x=sc.x;
- clip_shift_y=sc.y;
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadIdentity();
+ vgScale(((float)BACKBUFFER_WIDTH) / 720.f, -((float)BACKBUFFER_HEIGHT) / 576.f);
+ vgTranslate(0.f + sc.x, -576.f + sc.y);
+ clip_shift_x = sc.x;
+ clip_shift_y = sc.y;
- //vgTranslate(0.f+sc.x,576.f-sc.y);
- //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Translate %g %g",sc.x,sc.y);
+ //vgTranslate(0.f+sc.x,576.f-sc.y);
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Translate %g %g",sc.x,sc.y);
}
-void OsdOpenVG::executeDrawCommand(SVGCommand & command)
+void OsdOpenVG::executeDrawCommand(SVGCommand& command)
{
- VGfloat save_matrix[9];
- VGfloat save_matrix2[9];
- switch (command.instr) {
- case DrawPath: {
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
- // VGuint rgba;
- // rgba = vgGetColor((VGPaint) command.reference);
- //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Path %d %x %g %g %g %g",command.reference,command.target.path_index,command.x,command.y,command.w,command.h);
- //vgSeti(VG_FILL_RULE,);
-
- vgGetMatrix(save_matrix);
- vgSetPaint((VGPaint) command.reference,VG_FILL_PATH);
- vgSetPaint((VGPaint) command.reference,VG_STROKE_PATH);
- vgTranslate(command.x,command.y);
- vgScale(command.w,command.h);
- vgDrawPath(std_paths[command.target.path_index],VG_FILL_PATH);
- vgLoadMatrix(save_matrix);
- } break;
- case DrawImage: {
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
- vgGetMatrix(save_matrix);
- VGfloat imagewidth=vgGetParameteri((VGImage) command.target.image, VG_IMAGE_WIDTH);
- VGfloat imageheight=vgGetParameteri((VGImage) command.target.image, VG_IMAGE_HEIGHT);
-
-
- //vgScale(command.w,command.h);
-
- if (command.reference) { //special behaviout for bw images they act as a mask on the current paint
- vgTranslate(command.x,command.y);
- vgSetPaint((VGPaint) command.reference,VG_FILL_PATH);
- vgSetPaint((VGPaint) command.reference,VG_STROKE_PATH);
- vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_STENCIL);
- vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
- vgScale(aspect_correction,1.f);
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
- vgGetMatrix(save_matrix2);
- vgScale(imagewidth,imageheight);
- } else {
-
- //vgScale(720.f/((float)BACKBUFFER_WIDTH), 576.f/((float)BACKBUFFER_HEIGHT));
- float scalex=command.w/imagewidth;
- float scaley=command.h/imageheight;
- float tx=command.x;
- float ty=command.y;
- if (command.corner == TopLeftLimited) {
- if (scalex !=0.f && scaley !=0.f) {
- float imageaspect=imagewidth/imageheight;
- float boxaspect=command.w/command.h/aspect_correction;
- if (imageaspect > boxaspect) {
- scaley=0.f;
- ty+=(command.h-imageheight * scalex/aspect_correction)*0.5f;
- } else {
- scalex=0.f;
- tx+=(command.w-imagewidth * scaley*aspect_correction)*0.5f;
- }
-
- }
-
- }
- if (scalex==0.f && scaley==0.f) {
- scalex=aspect_correction;
- scaley=1.f;
- } else if (scalex==0.f) {
- scalex=scaley*aspect_correction;
- } else if (scaley==0.f) {
- scaley=scalex/aspect_correction;
- }
-
-
- if (command.corner == BottomRight || command.corner == BottomLeft || command.corner == BottomMiddle)
- {
- ty-=imageheight * scaley;
- }
-
- if (command.corner == BottomRight || command.corner == TopRight)
- {
- tx-=imagewidth * scalex;
- }
-
- if (command.corner == BottomMiddle || command.corner == TopMiddle)
- {
- tx-=imagewidth * scalex *0.5f;
- }
-
- vgTranslate(tx,ty);
- //vgScale(command.w/imagewidth,command.h/imageheight);
- vgScale(scalex,scaley);
- vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
- vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_NORMAL);
- //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia Draw Image Scale %g %g %g %g %g %g",command.w,imagewidth,command.h,imageheight,scalex,scaley);
- }
-
-
- //vgLoadIdentity();
- //vgTranslate(200.f,500.f);
- //vgScale(100.f,100.f);
-
- vgDrawImage((VGImage) command.target.image);
- //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Image %d %x %g %g %g %g %x",command.reference,command.target.image,command.x,command.y,command.w,command.h,
- // vgGetError());
- if (command.reference) {
- vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_NORMAL);
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
- vgLoadMatrix(save_matrix2);
- }
- vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
-
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
- vgLoadMatrix(save_matrix);
- } break;
- case DrawGlyph: {
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
- vgGetMatrix(save_matrix);
- vgSetPaint((VGPaint) command.reference,VG_FILL_PATH);
- vgSetPaint((VGPaint) command.reference,VG_STROKE_PATH);
- vgTranslate(command.x,command.y);
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
- vgGetMatrix(save_matrix2);
- unsigned int glyph_index=FT_Get_Char_Index(ft_face,command.target.textchar);
- vgScale(font_exp_x[glyph_index],font_height);
-
-
- VGfloat gori[]={0.,0.};
- vgSetfv(VG_GLYPH_ORIGIN,2,gori);
-
-
- vgDrawGlyph(vgfont,glyph_index,VG_FILL_PATH,VG_FALSE);
- //vgDrawPath(std_paths[Rectangle],VG_FILL_PATH);
- /* Log::getInstance()->log("OSD", Log::DEBUG, "Draw Glyph %d %c %d %g %g %x",command.reference,command.target.textchar,glyph_index,command.x,command.y,
- vgGetError());*/
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
- vgLoadMatrix(save_matrix);
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
- vgLoadMatrix(save_matrix2);
-
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
- } break;
- case DrawTTchar:{
- cTeletextChar tchar;
- tchar.setInternal(command.target.ttchar);
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
- vgGetMatrix(save_matrix);
- enumTeletextColor ttforegcolour=tchar.GetFGColor();
- enumTeletextColor ttbackgcolour=tchar.GetBGColor();
- if (tchar.GetBoxedOut()) {
- ttforegcolour=ttcTransparent;
- ttbackgcolour=ttcTransparent;
- }
- vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_STENCIL);
- vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
-
-
- vgTranslate(command.x+command.w*11.85f*1.4f,command.y+command.h*19.75f);
- VGfloat gori[]={0.,0.};
- vgSetfv(VG_GLYPH_ORIGIN,2,gori);
-
- vgScale(-1.4f,2.f);
- unsigned int color=Surface::enumTeletextColorToCoulour(ttbackgcolour).rgba();
- color=color<<8 | (color &0xff000000)>>24;
- vgSetColor(vgttpaint,color);
- vgSetPaint((VGPaint) vgttpaint,VG_FILL_PATH);
- vgSetPaint((VGPaint) vgttpaint,VG_STROKE_PATH);
- cTeletextChar filled;
- filled.setInternal(0x187f);
- unsigned int glyph_index=loadTTchar(filled);
- vgDrawGlyph(vgttfont,glyph_index,VG_FILL_PATH,VG_FALSE);
-
- color=Surface::enumTeletextColorToCoulour(ttforegcolour).rgba();
- color=color<<8 | (color &0xff000000)>>24;
- vgSetColor(vgttpaint,color);
- vgSetPaint((VGPaint) vgttpaint,VG_FILL_PATH);
- vgSetPaint((VGPaint) vgttpaint,VG_STROKE_PATH);
- glyph_index=loadTTchar(tchar);
- vgDrawGlyph(vgttfont,glyph_index,VG_FILL_PATH,VG_FALSE);
-
- /* Log::getInstance()->log("OSD", Log::DEBUG, "Draw TTchar %x %x %x %x",glyph_index,ttforegcolour,Surface::enumTeletextColorToCoulour(ttforegcolour).rgba(),
- vgGetColor(vgttpaint));*/
-
-
- vgLoadMatrix(save_matrix);
- vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
- vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_NORMAL);
- vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
-
- }break;
- case DrawClipping: {
- VGint coords[4]={0,0,0,0};
- coords[0]= ((command.x+clip_shift_x)*((float)BACKBUFFER_WIDTH)/720.f);
- coords[1]= ((576.f-command.y-clip_shift_y-command.h)*((float)BACKBUFFER_HEIGHT)/576.f);
- coords[2]= ((command.w-1.f)*((float)BACKBUFFER_WIDTH)/720.f);
- coords[3]= ((command.h-1.f)*((float)BACKBUFFER_HEIGHT)/576.f);
- vgSetiv(VG_SCISSOR_RECTS, 4,coords);
- if (command.w==0.f && command.h==0.f)
- vgSeti(VG_SCISSORING,VG_FALSE);
- else vgSeti(VG_SCISSORING,VG_TRUE);
- } break;
-
- case DrawImageLoading:
- case DrawNoop:
- {}
- }
+ VGfloat save_matrix[9];
+ VGfloat save_matrix2[9];
+
+ switch (command.instr)
+ {
+ case DrawPath:
+ {
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ // VGuint rgba;
+ // rgba = vgGetColor((VGPaint) command.reference);
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Path %d %x %g %g %g %g",command.reference,command.target.path_index,command.x,command.y,command.w,command.h);
+ //vgSeti(VG_FILL_RULE,);
+
+ vgGetMatrix(save_matrix);
+ vgSetPaint((VGPaint) command.reference, VG_FILL_PATH);
+ vgSetPaint((VGPaint) command.reference, VG_STROKE_PATH);
+ vgTranslate(command.x, command.y);
+ vgScale(command.w, command.h);
+ vgDrawPath(std_paths[command.target.path_index], VG_FILL_PATH);
+ vgLoadMatrix(save_matrix);
+ } break;
+
+ case DrawImage:
+ {
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgGetMatrix(save_matrix);
+ VGfloat imagewidth = vgGetParameteri((VGImage) command.target.image, VG_IMAGE_WIDTH);
+ VGfloat imageheight = vgGetParameteri((VGImage) command.target.image, VG_IMAGE_HEIGHT);
+
+
+ //vgScale(command.w,command.h);
+
+ if (command.reference) //special behaviout for bw images they act as a mask on the current paint
+ {
+ vgTranslate(command.x, command.y);
+ vgSetPaint((VGPaint) command.reference, VG_FILL_PATH);
+ vgSetPaint((VGPaint) command.reference, VG_STROKE_PATH);
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_STENCIL);
+ vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
+ vgScale(aspect_correction, 1.f);
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
+ vgGetMatrix(save_matrix2);
+ vgScale(imagewidth, imageheight);
+ }
+ else
+ {
+
+ //vgScale(720.f/((float)BACKBUFFER_WIDTH), 576.f/((float)BACKBUFFER_HEIGHT));
+ float scalex = command.w / imagewidth;
+ float scaley = command.h / imageheight;
+ float tx = command.x;
+ float ty = command.y;
+
+ if (command.corner == TopLeftLimited)
+ {
+ if (scalex != 0.f && scaley != 0.f)
+ {
+ float imageaspect = imagewidth / imageheight;
+ float boxaspect = command.w / command.h / aspect_correction;
+
+ if (imageaspect > boxaspect)
+ {
+ scaley = 0.f;
+ ty += (command.h - imageheight * scalex / aspect_correction) * 0.5f;
+ }
+ else
+ {
+ scalex = 0.f;
+ tx += (command.w - imagewidth * scaley * aspect_correction) * 0.5f;
+ }
+
+ }
+
+ }
+
+ if (scalex == 0.f && scaley == 0.f)
+ {
+ scalex = aspect_correction;
+ scaley = 1.f;
+ }
+ else if (scalex == 0.f)
+ {
+ scalex = scaley * aspect_correction;
+ }
+ else if (scaley == 0.f)
+ {
+ scaley = scalex / aspect_correction;
+ }
+
+
+ if (command.corner == BottomRight || command.corner == BottomLeft || command.corner == BottomMiddle)
+ {
+ ty -= imageheight * scaley;
+ }
+
+ if (command.corner == BottomRight || command.corner == TopRight)
+ {
+ tx -= imagewidth * scalex;
+ }
+
+ if (command.corner == BottomMiddle || command.corner == TopMiddle)
+ {
+ tx -= imagewidth * scalex * 0.5f;
+ }
+
+ vgTranslate(tx, ty);
+ //vgScale(command.w/imagewidth,command.h/imageheight);
+ vgScale(scalex, scaley);
+ vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+ //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia Draw Image Scale %g %g %g %g %g %g",command.w,imagewidth,command.h,imageheight,scalex,scaley);
+ }
+
+
+ //vgLoadIdentity();
+ //vgTranslate(200.f,500.f);
+ //vgScale(100.f,100.f);
+
+ vgDrawImage((VGImage) command.target.image);
+
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Image %d %x %g %g %g %g %x",command.reference,command.target.image,command.x,command.y,command.w,command.h,
+ // vgGetError());
+ if (command.reference)
+ {
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
+ vgLoadMatrix(save_matrix2);
+ }
+
+ vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+ vgLoadMatrix(save_matrix);
+ } break;
+
+ case DrawGlyph:
+ {
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
+ vgGetMatrix(save_matrix);
+ vgSetPaint((VGPaint) command.reference, VG_FILL_PATH);
+ vgSetPaint((VGPaint) command.reference, VG_STROKE_PATH);
+ vgTranslate(command.x, command.y);
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
+ vgGetMatrix(save_matrix2);
+ unsigned int glyph_index = FT_Get_Char_Index(ft_face, command.target.textchar);
+ vgScale(font_exp_x[glyph_index], font_height);
+
+
+ VGfloat gori[] = {0., 0.};
+ vgSetfv(VG_GLYPH_ORIGIN, 2, gori);
+
+
+ vgDrawGlyph(vgfont, glyph_index, VG_FILL_PATH, VG_FALSE);
+ //vgDrawPath(std_paths[Rectangle],VG_FILL_PATH);
+ /* Log::getInstance()->log("OSD", Log::DEBUG, "Draw Glyph %d %c %d %g %g %x",command.reference,command.target.textchar,glyph_index,command.x,command.y,
+ vgGetError());*/
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
+ vgLoadMatrix(save_matrix);
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
+ vgLoadMatrix(save_matrix2);
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ } break;
+
+ case DrawTTchar:
+ {
+ cTeletextChar tchar;
+ tchar.setInternal(command.target.ttchar);
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
+ vgGetMatrix(save_matrix);
+ enumTeletextColor ttforegcolour = tchar.GetFGColor();
+ enumTeletextColor ttbackgcolour = tchar.GetBGColor();
+
+ if (tchar.GetBoxedOut())
+ {
+ ttforegcolour = ttcTransparent;
+ ttbackgcolour = ttcTransparent;
+ }
+
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_STENCIL);
+ vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
+
+
+ vgTranslate(command.x + command.w * 11.85f * 1.4f, command.y + command.h * 19.75f);
+ VGfloat gori[] = {0., 0.};
+ vgSetfv(VG_GLYPH_ORIGIN, 2, gori);
+
+ vgScale(-1.4f, 2.f);
+ unsigned int color = Surface::enumTeletextColorToCoulour(ttbackgcolour).rgba();
+ color = color << 8 | (color & 0xff000000) >> 24;
+ vgSetColor(vgttpaint, color);
+ vgSetPaint((VGPaint) vgttpaint, VG_FILL_PATH);
+ vgSetPaint((VGPaint) vgttpaint, VG_STROKE_PATH);
+ cTeletextChar filled;
+ filled.setInternal(0x187f);
+ unsigned int glyph_index = loadTTchar(filled);
+ vgDrawGlyph(vgttfont, glyph_index, VG_FILL_PATH, VG_FALSE);
+
+ color = Surface::enumTeletextColorToCoulour(ttforegcolour).rgba();
+ color = color << 8 | (color & 0xff000000) >> 24;
+ vgSetColor(vgttpaint, color);
+ vgSetPaint((VGPaint) vgttpaint, VG_FILL_PATH);
+ vgSetPaint((VGPaint) vgttpaint, VG_STROKE_PATH);
+ glyph_index = loadTTchar(tchar);
+ vgDrawGlyph(vgttfont, glyph_index, VG_FILL_PATH, VG_FALSE);
+
+ /* Log::getInstance()->log("OSD", Log::DEBUG, "Draw TTchar %x %x %x %x",glyph_index,ttforegcolour,Surface::enumTeletextColorToCoulour(ttforegcolour).rgba(),
+ vgGetColor(vgttpaint));*/
+
+
+ vgLoadMatrix(save_matrix);
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+ vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
+
+ } break;
+
+ case DrawClipping:
+ {
+ VGint coords[4] = {0, 0, 0, 0};
+ coords[0] = ((command.x + clip_shift_x) * ((float)BACKBUFFER_WIDTH) / 720.f);
+ coords[1] = ((576.f - command.y - clip_shift_y - command.h) * ((float)BACKBUFFER_HEIGHT) / 576.f);
+ coords[2] = ((command.w - 1.f) * ((float)BACKBUFFER_WIDTH) / 720.f);
+ coords[3] = ((command.h - 1.f) * ((float)BACKBUFFER_HEIGHT) / 576.f);
+ vgSetiv(VG_SCISSOR_RECTS, 4, coords);
+
+ if (command.w == 0.f && command.h == 0.f)
+ vgSeti(VG_SCISSORING, VG_FALSE);
+ else vgSeti(VG_SCISSORING, VG_TRUE);
+ } break;
+
+ case DrawImageLoading:
+ case DrawNoop:
+ {}
+ }
}
//int imcount=0;// this is debug code and should not go into release
unsigned int OsdOpenVG::handleTask(OpenVGCommand& command)
{
- switch (command.task){
- case OVGreplacefont: {
- vgDestroyFont(vgfont);
- loadFont(true);
- return 0;
- } break;
-
- case OVGdestroyImageRef: {//imcount--;
- //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia Draw Image Destroy %x %d",command.param1,imcount);
- vgDestroyImage((VGImage)command.param1);
- return 0;
- } break;
- case OVGdestroyPaint: {
- //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Paint Destroy %d ",command.param1);
- vgDestroyPaint((VGPaint)command.param1);
- return 0;
- } break;
- case OVGcreateImagePalette: {//imcount++;
- VGImage input=vgCreateImage(VG_A_8,command.param1, command.param2,
- VG_IMAGE_QUALITY_NONANTIALIASED|
- VG_IMAGE_QUALITY_FASTER|VG_IMAGE_QUALITY_BETTER);
- //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create palette %d %d %x %d",command.param1,command.param2,vgGetError(),input);
- vgImageSubData(input,command.data,command.param1,
- VG_A_8,0,0,command.param1, command.param2); // upload palettized image data
- VGImage handle=vgCreateImage(VG_sRGBA_8888,command.param1, command.param2,
- VG_IMAGE_QUALITY_NONANTIALIASED|
- VG_IMAGE_QUALITY_FASTER|VG_IMAGE_QUALITY_BETTER);
- VGuint *palette=(VGuint*)malloc(256*sizeof(VGuint));
- VGuint *in_palette=(VGuint*)command.data2;
- for (int i=0;i<256;i++) {
- VGuint color=in_palette[i];
- palette[i]=color<<8 | (color &0xff000000)>>24;
- }
-
- vgLookupSingle(handle,input,palette,VG_ALPHA,VG_FALSE,VG_FALSE);
- free(palette);
- vgDestroyImage(input);
-
- return handle;
- } break;
- case OVGcreateMonoBitmap: {//imcount++;
- VGImage handle=vgCreateImage(VG_A_1,command.param1, command.param2,
- VG_IMAGE_QUALITY_FASTER);
- //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create mono %d %d %x %d",command.param1,command.param2,vgGetError(),handle);
- unsigned int buffer_len=(command.param1*command.param2)>>3;
- unsigned char * buffer=(unsigned char*)malloc(buffer_len);
- unsigned char * r_buffer1=buffer;
- const unsigned char* r_buffer2= static_cast<const unsigned char *>(command.data);
- unsigned char *buffer_end=buffer+buffer_len;
- while (r_buffer1!=buffer_end) {
- unsigned char byte=*r_buffer2;
- *r_buffer1=((byte * 0x0802LU & 0x22110LU) | (byte * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
- r_buffer1++;r_buffer2++;
- }
-
-
- vgImageSubData(handle,buffer,command.param1>>3,
- VG_A_1,0,0,command.param1, command.param2);
- free(buffer);
- // Log::getInstance()->log("OSD", Log::DEBUG, "Draw create mono2 %d %d %x %d",command.param1,command.param2,vgGetError(),handle);
- return handle;
- } break;
- /*case OVGcreateImageFile: {
- VGImage handle;
- try{
- Image *imagefile=(Image*)command.data;
- Blob imageblob;
- imagefile->write(&imageblob,"RGBA");
-
-
- handle=vgCreateImage(VG_sXBGR_8888,imagefile->columns(),imagefile->rows(),
- VG_IMAGE_QUALITY_BETTER);
- //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details %d %d %x mark1",imagefile->columns(),imagefile->rows(),(unsigned int*)imageblob.data());
- vgImageSubData(handle,imageblob.data(),imagefile->columns()*4,
- VG_sXBGR_8888,0,0,imagefile->columns(),imagefile->rows());
- //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details %d %d %x mark2",imagefile->columns(),imagefile->rows(),(unsigned int*)imageblob.data());
- delete imagefile;
- }catch( Exception &error_ )
- {
- Log::getInstance()->log("OSD", Log::DEBUG, "Libmagick hT: %s",error_.what());
-
- return 0;
- }
-
- //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create file %d %d %x %d",command.param1,command.param2,vgGetError(),handle);
- return handle;
- } break;*/
- case OVGcreateImageMemory: {//imcount++;
- PictureInfo *info = (PictureInfo*) command.data;
- VGImage handle;
- //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateImageMemory %d",imcount);
- handle=vgCreateImage(VG_sABGR_8888,info->width,info->height,VG_IMAGE_QUALITY_BETTER);
- vgImageSubData(handle,info->image,info->width*4,
- VG_sABGR_8888,0,0,info->width,info->height);
- info->decoder->freeReference(info->reference);
-
- bool static_image=true;
- if (info->lindex & 0xffffffff) static_image=false;
-
- Message* m = new Message();
- // We have a pictures! send a message to ourself, to switch to gui thread
- m->from=this;
- m->p_to = Message::CONTROL;
- m->data = reinterpret_cast<void*>(handle);
- if (!static_image) {
- m->message=Message::NEW_PICTURE;
- m->tag = info->lindex;
- } else {
- m->message=Message::NEW_PICTURE_STATIC;
- m->tag = info->lindex>> 32LL;
- }
- MessageQueue::getInstance()->postMessage(m); // inform command about new picture
-
- delete info;
-
- } break;
- case OVGcreateEGLImage: {//imcount++;
- PictureInfo *info = (PictureInfo*) command.data;
- VGImage handle;
-
- handle=vgCreateImage(VG_sABGR_8888,info->width,info->height,VG_IMAGE_QUALITY_BETTER);
-// Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateEGLImage %d %d %x %d",info->width,info->height, handle,imcount);
-
- info->handle = handle;
- info->reference = eglCreateImageKHR(egl_display, egl_context, EGL_VG_PARENT_IMAGE_KHR, (EGLClientBuffer)handle, NULL);
- if (info->reference) return true;
- else {
- Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateEGLImage %d %d %x Fail!",info->width,info->height, handle);
- if (handle) vgDestroyImage(handle);
- return false;
- }
-
- } break;
-
- case OVGreadyEGLImage: {
- PictureInfo *info = (PictureInfo*) command.data;
- eglDestroyImageKHR(egl_display,info->reference);
- bool static_image=true;
- if (info->lindex & 0xffffffff) static_image=false;
- Message* m = new Message();
- m->from=this;
- m->p_to = Message::CONTROL;
- m->data = reinterpret_cast<void*>(info->handle);
- if (!static_image) {
- m->message=Message::NEW_PICTURE;
- m->tag = info->lindex;
- } else {
- m->message=Message::NEW_PICTURE_STATIC;
- m->tag = info->lindex>> 32LL;
- }
- MessageQueue::getInstance()->postMessage(m); // inform command about new picture
-
- delete info;
- } break;
-
-
-
- case OVGcreateColorRef :{
- VGPaint handle;
- handle=vgCreatePaint();
- DrawStyle *style=(DrawStyle*)command.data;
- switch (style->ft) {
- case DrawStyle::Color: {
- vgSetParameteri(handle, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
- vgSetColor(handle,command.param1);
- //VGuint rgba;
- //rgba = vgGetColor((VGPaint)handle);
- //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Paint %d %x %x",handle,command.param1,rgba);
- } break;
- case DrawStyle::GradientLinear: {
- vgSetParameteri(handle, VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT);
- VGfloat params[]={style->x1,style->y1,style->x2,style->y2,style->r};
- //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Gradient %d %g %g %g %g",handle,params[0],params[1],params[2],params[3]);
- vgSetParameterfv(handle,VG_PAINT_LINEAR_GRADIENT,4,params);
-
-
-
- } break;
- case DrawStyle::GradientRadial: {
- vgSetParameteri(handle, VG_PAINT_TYPE, VG_PAINT_TYPE_RADIAL_GRADIENT);
- VGfloat params[]={style->x1,style->y1,style->x2,style->y2,style->r};
- vgSetParameterfv(handle,VG_PAINT_RADIAL_GRADIENT,5,params);
-
-
-
- } break;
- };
- if (style->ft==DrawStyle::GradientLinear ||style->ft==DrawStyle::GradientRadial) {
- VGfloat colorramp[5*5];
- colorramp[0+0*5]=0.f;
- colorramp[1+0*5]=((float)style->red)/255.f;
- colorramp[2+0*5]=((float)style->green)/255.f;
- colorramp[3+0*5]=((float)style->blue)/255.f;
- colorramp[4+0*5]=((float)style->alpha)/255.f;
- for (int i=0;i<(style->num_colors-1);i++) {
- colorramp[0+(i+1)*5]=style->grad_pos[i];
- colorramp[1+(i+1)*5]=((float)style->grad_col[i].red)/255.f;
- colorramp[2+(i+1)*5]=((float)style->grad_col[i].green)/255.f;
- colorramp[3+(i+1)*5]=((float)style->grad_col[i].blue)/255.f;
- colorramp[4+(i+1)*5]=((float)style->grad_col[i].alpha)/255.f;
- }
- colorramp[0+(style->num_colors)*5]=1.f;
- colorramp[1+(style->num_colors)*5]=((float)style->grad_col[style->num_colors-1].red)/255.f;
- colorramp[2+(style->num_colors)*5]=((float)style->grad_col[style->num_colors-1].green)/255.f;
- colorramp[3+(style->num_colors)*5]=((float)style->grad_col[style->num_colors-1].blue)/255.f;
- colorramp[4+(style->num_colors)*5]=((float)style->grad_col[style->num_colors-1].alpha)/255.f;
- vgSetParameteri(handle, VG_PAINT_COLOR_RAMP_SPREAD_MODE,VG_COLOR_RAMP_SPREAD_REFLECT);
- vgSetParameteri(handle, VG_PAINT_COLOR_RAMP_PREMULTIPLIED,VG_FALSE);
- vgSetParameterfv(handle,VG_PAINT_COLOR_RAMP_STOPS,5+(style->num_colors)*5,colorramp);
- }
-
- return handle;
- } break;
-
-
- case OVGimageUploadLine:
- {}
+ switch (command.task)
+ {
+ case OVGreplacefont:
+ {
+ vgDestroyFont(vgfont);
+ loadFont(true);
+ return 0;
+ } break;
+
+ case OVGdestroyImageRef: //imcount--;
+ {
+ //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia Draw Image Destroy %x %d",command.param1,imcount);
+ vgDestroyImage((VGImage)command.param1);
+ return 0;
+ } break;
+
+ case OVGdestroyPaint:
+ {
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Paint Destroy %d ",command.param1);
+ vgDestroyPaint((VGPaint)command.param1);
+ return 0;
+ } break;
+
+ case OVGcreateImagePalette: //imcount++;
+ {
+ VGImage input = vgCreateImage(VG_A_8, command.param1, command.param2,
+ VG_IMAGE_QUALITY_NONANTIALIASED |
+ VG_IMAGE_QUALITY_FASTER | VG_IMAGE_QUALITY_BETTER);
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create palette %d %d %x %d",command.param1,command.param2,vgGetError(),input);
+ vgImageSubData(input, command.data, command.param1,
+ VG_A_8, 0, 0, command.param1, command.param2); // upload palettized image data
+ VGImage handle = vgCreateImage(VG_sRGBA_8888, command.param1, command.param2,
+ VG_IMAGE_QUALITY_NONANTIALIASED |
+ VG_IMAGE_QUALITY_FASTER | VG_IMAGE_QUALITY_BETTER);
+ VGuint* palette = (VGuint*)malloc(256 * sizeof(VGuint));
+ VGuint* in_palette = (VGuint*)command.data2;
+
+ for (int i = 0; i < 256; i++)
+ {
+ VGuint color = in_palette[i];
+ palette[i] = color << 8 | (color & 0xff000000) >> 24;
+ }
+
+ vgLookupSingle(handle, input, palette, VG_ALPHA, VG_FALSE, VG_FALSE);
+ free(palette);
+ vgDestroyImage(input);
+
+ return handle;
+ } break;
+
+ case OVGcreateMonoBitmap: //imcount++;
+ {
+ VGImage handle = vgCreateImage(VG_A_1, command.param1, command.param2,
+ VG_IMAGE_QUALITY_FASTER);
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create mono %d %d %x %d",command.param1,command.param2,vgGetError(),handle);
+ unsigned int buffer_len = (command.param1 * command.param2) >> 3;
+ unsigned char* buffer = (unsigned char*)malloc(buffer_len);
+ unsigned char* r_buffer1 = buffer;
+ const unsigned char* r_buffer2 = static_cast<const unsigned char*>(command.data);
+ unsigned char* buffer_end = buffer + buffer_len;
+
+ while (r_buffer1 != buffer_end)
+ {
+ unsigned char byte = *r_buffer2;
+ *r_buffer1 = ((byte * 0x0802LU & 0x22110LU) | (byte * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
+ r_buffer1++; r_buffer2++;
+ }
+
+
+ vgImageSubData(handle, buffer, command.param1 >> 3,
+ VG_A_1, 0, 0, command.param1, command.param2);
+ free(buffer);
+ // Log::getInstance()->log("OSD", Log::DEBUG, "Draw create mono2 %d %d %x %d",command.param1,command.param2,vgGetError(),handle);
+ return handle;
+ } break;
+
+ /*case OVGcreateImageFile: {
+ VGImage handle;
+ try{
+ Image *imagefile=(Image*)command.data;
+ Blob imageblob;
+ imagefile->write(&imageblob,"RGBA");
+
+
+ handle=vgCreateImage(VG_sXBGR_8888,imagefile->columns(),imagefile->rows(),
+ VG_IMAGE_QUALITY_BETTER);
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details %d %d %x mark1",imagefile->columns(),imagefile->rows(),(unsigned int*)imageblob.data());
+ vgImageSubData(handle,imageblob.data(),imagefile->columns()*4,
+ VG_sXBGR_8888,0,0,imagefile->columns(),imagefile->rows());
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details %d %d %x mark2",imagefile->columns(),imagefile->rows(),(unsigned int*)imageblob.data());
+ delete imagefile;
+ }catch( Exception &error_ )
+ {
+ Log::getInstance()->log("OSD", Log::DEBUG, "Libmagick hT: %s",error_.what());
+
+ return 0;
+ }
+
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create file %d %d %x %d",command.param1,command.param2,vgGetError(),handle);
+ return handle;
+ } break;*/
+ case OVGcreateImageMemory: //imcount++;
+ {
+ PictureInfo* info = (PictureInfo*) command.data;
+ VGImage handle;
+ //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateImageMemory %d",imcount);
+ handle = vgCreateImage(VG_sABGR_8888, info->width, info->height, VG_IMAGE_QUALITY_BETTER);
+ vgImageSubData(handle, info->image, info->width * 4,
+ VG_sABGR_8888, 0, 0, info->width, info->height);
+ info->decoder->freeReference(info->reference);
+
+ bool static_image = true;
+
+ if (info->lindex & 0xffffffff) static_image = false;
+
+ Message* m = new Message();
+ // We have a pictures! send a message to ourself, to switch to gui thread
+ m->from = this;
+ m->p_to = Message::CONTROL;
+ m->data = reinterpret_cast<void*>(handle);
+
+ if (!static_image)
+ {
+ m->message = Message::NEW_PICTURE;
+ m->tag = info->lindex;
+ }
+ else
+ {
+ m->message = Message::NEW_PICTURE_STATIC;
+ m->tag = info->lindex >> 32LL;
+ }
+
+ MessageQueue::getInstance()->postMessage(m); // inform command about new picture
+
+ delete info;
+
+ } break;
+
+ case OVGcreateEGLImage: //imcount++;
+ {
+ PictureInfo* info = (PictureInfo*) command.data;
+ VGImage handle;
+
+ handle = vgCreateImage(VG_sABGR_8888, info->width, info->height, VG_IMAGE_QUALITY_BETTER);
+ // Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateEGLImage %d %d %x %d",info->width,info->height, handle,imcount);
+
+ info->handle = handle;
+ info->reference = eglCreateImageKHR(egl_display, egl_context, EGL_VG_PARENT_IMAGE_KHR, (EGLClientBuffer)handle, NULL);
+
+ if (info->reference) return true;
+ else
+ {
+ Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateEGLImage %d %d %x Fail!", info->width, info->height, handle);
+
+ if (handle) vgDestroyImage(handle);
+
+ return false;
+ }
+
+ } break;
+
+ case OVGreadyEGLImage:
+ {
+ PictureInfo* info = (PictureInfo*) command.data;
+ eglDestroyImageKHR(egl_display, info->reference);
+ bool static_image = true;
+
+ if (info->lindex & 0xffffffff) static_image = false;
+
+ Message* m = new Message();
+ m->from = this;
+ m->p_to = Message::CONTROL;
+ m->data = reinterpret_cast<void*>(info->handle);
+
+ if (!static_image)
+ {
+ m->message = Message::NEW_PICTURE;
+ m->tag = info->lindex;
+ }
+ else
+ {
+ m->message = Message::NEW_PICTURE_STATIC;
+ m->tag = info->lindex >> 32LL;
+ }
+
+ MessageQueue::getInstance()->postMessage(m); // inform command about new picture
+
+ delete info;
+ } break;
+
+
+
+ case OVGcreateColorRef :
+ {
+ VGPaint handle;
+ handle = vgCreatePaint();
+ DrawStyle* style = (DrawStyle*)command.data;
+
+ switch (style->ft)
+ {
+ case DrawStyle::Color:
+ {
+ vgSetParameteri(handle, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+ vgSetColor(handle, command.param1);
+ //VGuint rgba;
+ //rgba = vgGetColor((VGPaint)handle);
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Paint %d %x %x",handle,command.param1,rgba);
+ } break;
+
+ case DrawStyle::GradientLinear:
+ {
+ vgSetParameteri(handle, VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT);
+ VGfloat params[] = {style->x1, style->y1, style->x2, style->y2, style->r};
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Gradient %d %g %g %g %g",handle,params[0],params[1],params[2],params[3]);
+ vgSetParameterfv(handle, VG_PAINT_LINEAR_GRADIENT, 4, params);
+
+
+
+ } break;
+
+ case DrawStyle::GradientRadial:
+ {
+ vgSetParameteri(handle, VG_PAINT_TYPE, VG_PAINT_TYPE_RADIAL_GRADIENT);
+ VGfloat params[] = {style->x1, style->y1, style->x2, style->y2, style->r};
+ vgSetParameterfv(handle, VG_PAINT_RADIAL_GRADIENT, 5, params);
- }
- return 0;
+
+ } break;
+ };
+
+ if (style->ft == DrawStyle::GradientLinear || style->ft == DrawStyle::GradientRadial)
+ {
+ VGfloat colorramp[5 * 5];
+ colorramp[0 + 0 * 5] = 0.f;
+ colorramp[1 + 0 * 5] = ((float)style->red) / 255.f;
+ colorramp[2 + 0 * 5] = ((float)style->green) / 255.f;
+ colorramp[3 + 0 * 5] = ((float)style->blue) / 255.f;
+ colorramp[4 + 0 * 5] = ((float)style->alpha) / 255.f;
+
+ for (int i = 0; i < (style->num_colors - 1); i++)
+ {
+ colorramp[0 + (i + 1) * 5] = style->grad_pos[i];
+ colorramp[1 + (i + 1) * 5] = ((float)style->grad_col[i].red) / 255.f;
+ colorramp[2 + (i + 1) * 5] = ((float)style->grad_col[i].green) / 255.f;
+ colorramp[3 + (i + 1) * 5] = ((float)style->grad_col[i].blue) / 255.f;
+ colorramp[4 + (i + 1) * 5] = ((float)style->grad_col[i].alpha) / 255.f;
+ }
+
+ colorramp[0 + (style->num_colors) * 5] = 1.f;
+ colorramp[1 + (style->num_colors) * 5] = ((float)style->grad_col[style->num_colors - 1].red) / 255.f;
+ colorramp[2 + (style->num_colors) * 5] = ((float)style->grad_col[style->num_colors - 1].green) / 255.f;
+ colorramp[3 + (style->num_colors) * 5] = ((float)style->grad_col[style->num_colors - 1].blue) / 255.f;
+ colorramp[4 + (style->num_colors) * 5] = ((float)style->grad_col[style->num_colors - 1].alpha) / 255.f;
+ vgSetParameteri(handle, VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_REFLECT);
+ vgSetParameteri(handle, VG_PAINT_COLOR_RAMP_PREMULTIPLIED, VG_FALSE);
+ vgSetParameterfv(handle, VG_PAINT_COLOR_RAMP_STOPS, 5 + (style->num_colors) * 5, colorramp);
+ }
+
+ return handle;
+ } break;
+
+
+ case OVGimageUploadLine:
+ {}
+
+ }
+
+ return 0;
}
bool OsdOpenVG::processTasks()
{
- bool worked=false;
- taskmutex.lock();
- vgmutex.lock();
- while (vgcommands.size()>0)
- {
- OpenVGCommand comm=vgcommands.front();
- vgcommands.pop_front();
- taskmutex.unlock();
-
- OpenVGResponse resp;
- resp.result=handleTask(comm);
- resp.id=comm.id;
- taskmutex.lock();
- if (comm.id) {
- vgresponses.push_back(resp);
- }
- taskmutex.unlock();
- vgmutex.unlock();
- //threadCheckExit();
-
- /* Getting rid of Signal class. As with VideoOMX, just replicate what Signal did here
- * and figure out if any of this can be simplified later. e.g. taskmutex sounds
- * like it should be the mutex being used. 3 mutexes here???
- */
-
- vgTaskSignalMutex.lock();
- vgTaskSignal.notify_one();
- vgTaskSignalMutex.unlock();
-
- taskmutex.lock();
- vgmutex.lock();
- worked=true;
- }
- taskmutex.unlock();
- vgmutex.unlock();
+ bool worked = false;
+ taskmutex.lock();
+ vgmutex.lock();
+
+ while (vgcommands.size() > 0)
+ {
+ OpenVGCommand comm = vgcommands.front();
+ vgcommands.pop_front();
+ taskmutex.unlock();
+
+ OpenVGResponse resp;
+ resp.result = handleTask(comm);
+ resp.id = comm.id;
+ taskmutex.lock();
+
+ if (comm.id)
+ {
+ vgresponses.push_back(resp);
+ }
+
+ taskmutex.unlock();
+ vgmutex.unlock();
+ //threadCheckExit();
+
+ /* Getting rid of Signal class. As with VideoOMX, just replicate what Signal did here
+ * and figure out if any of this can be simplified later. e.g. taskmutex sounds
+ * like it should be the mutex being used. 3 mutexes here???
+ */
+
+ vgTaskSignalMutex.lock();
+ vgTaskSignal.notify_one();
+ vgTaskSignalMutex.unlock();
- return worked;
+ taskmutex.lock();
+ vgmutex.lock();
+ worked = true;
+ }
+
+ taskmutex.unlock();
+ vgmutex.unlock();
+
+ return worked;
}
-bool OsdOpenVG::haveOpenVGResponse(unsigned int id,unsigned int * resp)
+bool OsdOpenVG::haveOpenVGResponse(unsigned int id, unsigned int* resp)
{
- taskmutex.lock();
- if (vgresponses.size()>0)
- {
- std::deque<OpenVGResponse>::iterator itty=vgresponses.begin();
- while (itty!=vgresponses.end())
- {
- if ((*itty).id==id) {
- *resp=(*itty).result;
- taskmutex.unlock();
- return true;
- }
- itty++;
- }
- }
- taskmutex.unlock();
- return false;
+ taskmutex.lock();
+
+ if (vgresponses.size() > 0)
+ {
+ std::deque<OpenVGResponse>::iterator itty = vgresponses.begin();
+
+ while (itty != vgresponses.end())
+ {
+ if ((*itty).id == id)
+ {
+ *resp = (*itty).result;
+ taskmutex.unlock();
+ return true;
+ }
+
+ itty++;
+ }
+ }
+
+ taskmutex.unlock();
+ return false;
}
-unsigned int OsdOpenVG::putOpenVGCommand(OpenVGCommand& comm,bool wait)
+unsigned int OsdOpenVG::putOpenVGCommand(OpenVGCommand& comm, bool wait)
{
- taskmutex.lock();
- if (wait){
- comm.id=wait_id;
- wait_id++;
- } else {
- comm.id=0; // we are not waiting
- }
- vgcommands.push_back(comm);
- taskmutex.unlock();
- threadSignal();
- while (wait) {
- unsigned int resp;
- if (!haveOpenVGResponse(comm.id,&resp)) {
-
-// Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "putOpenVGCommand wait_for");
- std::unique_lock<std::mutex> ul(vgTaskSignalMutex);
- /*auto a = */ vgTaskSignal.wait_for(ul, std::chrono::milliseconds(100));
- ul.unlock();
-/*
- if (a == std::cv_status::timeout)
- Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "putOpenVGCommand timeout");
- else
- Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "putOpenVGCommand no timeout");
-*/
- /*
- struct timespec target_time;
- clock_gettime(CLOCK_REALTIME,&target_time);
- target_time.tv_nsec+=1000000LL*100;
- if (target_time.tv_nsec>999999999) {
- target_time.tv_nsec-=1000000000L;
- target_time.tv_sec+=1;
- }
- vgtaskSignal.waitForSignalTimed(&target_time);
- */
-
-
- } else {
- return resp;
- }
- }
- return 0;
+ taskmutex.lock();
+
+ if (wait)
+ {
+ comm.id = wait_id;
+ wait_id++;
+ }
+ else
+ {
+ comm.id = 0; // we are not waiting
+ }
+
+ vgcommands.push_back(comm);
+ taskmutex.unlock();
+ threadSignal();
+
+ while (wait)
+ {
+ unsigned int resp;
+
+ if (!haveOpenVGResponse(comm.id, &resp))
+ {
+
+ // Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "putOpenVGCommand wait_for");
+ std::unique_lock<std::mutex> ul(vgTaskSignalMutex);
+ /*auto a = */ vgTaskSignal.wait_for(ul, std::chrono::milliseconds(100));
+ ul.unlock();
+ /*
+ if (a == std::cv_status::timeout)
+ Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "putOpenVGCommand timeout");
+ else
+ Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "putOpenVGCommand no timeout");
+ */
+ /*
+ struct timespec target_time;
+ clock_gettime(CLOCK_REALTIME,&target_time);
+ target_time.tv_nsec+=1000000LL*100;
+ if (target_time.tv_nsec>999999999) {
+ target_time.tv_nsec-=1000000000L;
+ target_time.tv_sec+=1;
+ }
+ vgtaskSignal.waitForSignalTimed(&target_time);
+ */
+
+
+ }
+ else
+ {
+ return resp;
+ }
+ }
+
+ return 0;
}
void OsdOpenVG::destroyImageRef(ImageIndex index)
{
- struct OpenVGCommand comm;
- comm.task=OVGdestroyImageRef;
- comm.param1=index;
- putOpenVGCommand(comm,false);
+ struct OpenVGCommand comm;
+ comm.task = OVGdestroyImageRef;
+ comm.param1 = index;
+ putOpenVGCommand(comm, false);
}
-bool OsdOpenVG::getStaticImageData(unsigned int static_id, UCHAR **userdata, ULONG *length)
+bool OsdOpenVG::getStaticImageData(unsigned int static_id, UCHAR** userdata, ULONG* length)
{
- if (sa_MAX>static_id) {
- *userdata = static_artwork_begin[static_id];
- *length = static_artwork_end[static_id] - static_artwork_begin[static_id];
- return true;
- }
+ if (sa_MAX > static_id)
+ {
+ *userdata = static_artwork_begin[static_id];
+ *length = static_artwork_end[static_id] - static_artwork_begin[static_id];
+ return true;
+ }
- *userdata = NULL;
- *length = 0;
- return false;
+ *userdata = NULL;
+ *length = 0;
+ return false;
}
void OsdOpenVG::createPicture(struct PictureInfo& pict_inf)
{
- struct OpenVGCommand comm;
- Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "TVMedia Create Picture %d",pict_inf.type);
- if (pict_inf.type == PictureInfo::RGBAMemBlock) {
- comm.task = OVGcreateImageMemory;
- comm.data = new PictureInfo(pict_inf);
- putOpenVGCommand(comm,false);
- } else if (pict_inf.type == PictureInfo::EGLImage) {
- comm.task = OVGreadyEGLImage;
- comm.data = new PictureInfo(pict_inf);
- putOpenVGCommand(comm,false);
- } else {
- // unsupported
- pict_inf.decoder->freeReference(pict_inf.reference);
+ struct OpenVGCommand comm;
+ Log::getInstance()->log("OsdOpenVG", Log::DEBUG, "TVMedia Create Picture %d", pict_inf.type);
+ if (pict_inf.type == PictureInfo::RGBAMemBlock)
+ {
+ comm.task = OVGcreateImageMemory;
+ comm.data = new PictureInfo(pict_inf);
+ putOpenVGCommand(comm, false);
+ }
+ else if (pict_inf.type == PictureInfo::EGLImage)
+ {
+ comm.task = OVGreadyEGLImage;
+ comm.data = new PictureInfo(pict_inf);
+ putOpenVGCommand(comm, false);
+ }
+ else
+ {
+ // unsupported
+ pict_inf.decoder->freeReference(pict_inf.reference);
- }
+
+ }
}
-bool OsdOpenVG::getEGLPicture(struct OsdVector::PictureInfo & info , EGLDisplay * display)
+bool OsdOpenVG::getEGLPicture(struct OsdVector::PictureInfo& info, EGLDisplay* display)
{
- struct OpenVGCommand comm;
- info.type = PictureInfo::EGLImage;
- comm.task = OVGcreateEGLImage;
- comm.data = &info;
- *display = egl_display;
- return putOpenVGCommand(comm,true);
+ struct OpenVGCommand comm;
+ info.type = PictureInfo::EGLImage;
+ comm.task = OVGcreateEGLImage;
+ comm.data = &info;
+ *display = egl_display;
+ return putOpenVGCommand(comm, true);
}
-ImageIndex OsdOpenVG::createMonoBitmap(void *base,int width,int height)
+ImageIndex OsdOpenVG::createMonoBitmap(void* base, int width, int height)
{
- struct OpenVGCommand comm;
- comm.task=OVGcreateMonoBitmap;
- comm.param1=width;
- comm.param2=height;
- comm.data=base;
- return putOpenVGCommand(comm,true);
+ struct OpenVGCommand comm;
+ comm.task = OVGcreateMonoBitmap;
+ comm.param1 = width;
+ comm.param2 = height;
+ comm.data = base;
+ return putOpenVGCommand(comm, true);
}
-ImageIndex OsdOpenVG::createImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)
+ImageIndex OsdOpenVG::createImagePalette(int width, int height, const unsigned char* image_data, const unsigned int* palette_data)
{
- struct OpenVGCommand comm;
- comm.task=OVGcreateImagePalette;
- comm.param1=width;
- comm.param2=height;
- comm.data=image_data;
- comm.data2=palette_data;
- return putOpenVGCommand(comm,true);
+ struct OpenVGCommand comm;
+ comm.task = OVGcreateImagePalette;
+ comm.param1 = width;
+ comm.param2 = height;
+ comm.data = image_data;
+ comm.data2 = palette_data;
+ return putOpenVGCommand(comm, true);
}
void OsdOpenVG::destroyStyleRef(VectorHandle index)
{
- struct OpenVGCommand comm;
- comm.task=OVGdestroyPaint;
- comm.param1=index;
- putOpenVGCommand(comm,false);
+ struct OpenVGCommand comm;
+ comm.task = OVGdestroyPaint;
+ comm.param1 = index;
+ putOpenVGCommand(comm, false);
}
-VectorHandle OsdOpenVG::createStyleRef(const DrawStyle &c)
+VectorHandle OsdOpenVG::createStyleRef(const DrawStyle& c)
{
- unsigned int col=c.rgba();
- struct OpenVGCommand comm;
- comm.task=OVGcreateColorRef;
- comm.param1=col<<8 | (col &0xff000000)>>24;
- comm.data=&c;
- return putOpenVGCommand(comm,true);
+ unsigned int col = c.rgba();
+ struct OpenVGCommand comm;
+ comm.task = OVGcreateColorRef;
+ comm.param1 = col << 8 | (col & 0xff000000) >> 24;
+ comm.data = &c;
+ return putOpenVGCommand(comm, true);
}
#define MAGICKCORE_HDRI_ENABLE 0
#include <Magick++.h>
-using namespace Magick;
+using namespace Magick;
-class MagickDecoder: public OsdVector::PictureDecoder {
-public:
- MagickDecoder(OsdVector::PictureReader* treader): OsdVector::PictureDecoder(treader) {pictInfValid=false;};
+class MagickDecoder: public OsdVector::PictureDecoder
+{
+ public:
+ MagickDecoder(OsdVector::PictureReader* treader): OsdVector::PictureDecoder(treader) {pictInfValid = false;};
- unsigned char *decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem);
+ unsigned char* decodePicture(LoadIndex index, unsigned char* buffer, unsigned int length, bool freemem);
bool getDecodedPicture( struct OsdVector::PictureInfo& pict_inf);
- void freeReference(void * ref);
+ void freeReference(void* ref);
-protected:
+ protected:
OsdVector::PictureInfo pictInf;
- bool pictInfValid;
+ bool pictInfValid;
};
-unsigned char * MagickDecoder::decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem)
+unsigned char* MagickDecoder::decodePicture(LoadIndex index, unsigned char* buffer, unsigned int length, bool freemem)
{
- if (pictInfValid) return buffer; // does support only one image at a Time;
- Image magicimage;
- Blob *imageblob = new Blob();
- Blob myblob;
- try{
- Log::getInstance()->log("MagickDecoder", Log::DEBUG, "decodePicture");
+ if (pictInfValid) return buffer; // does support only one image at a Time;
- if (freemem) myblob.updateNoCopy(buffer,length,Blob::MallocAllocator);
- else myblob.update(buffer,length);
- magicimage.read(myblob);
+ Image magicimage;
+ Blob* imageblob = new Blob();
+ Blob myblob;
- magicimage.write(imageblob,"RGBA");
+ try
+ {
+ Log::getInstance()->log("MagickDecoder", Log::DEBUG, "decodePicture");
- }catch( Exception &error_ )
- {
- Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: %s",error_.what());
- delete imageblob;
- Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: error mark2");
- unsigned char* newbuffer=(unsigned char*) malloc(length);
- memcpy(newbuffer,myblob.data(),length);
- return newbuffer;
- }
- pictInf.reference = (void*) imageblob;
- pictInf.width = magicimage.columns();
- pictInf.height = magicimage.rows();
- pictInf.image = imageblob->data();
- pictInf.decoder = this;
- pictInf.type = OsdVector::PictureInfo::RGBAMemBlock;
- pictInf.lindex = index;
- pictInfValid = true;
+ if (freemem) myblob.updateNoCopy(buffer, length, Blob::MallocAllocator);
+ else myblob.update(buffer, length);
+
+ magicimage.read(myblob);
+
+ magicimage.write(imageblob, "RGBA");
+ }
+ catch ( Exception& error_ )
+ {
+ Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: %s", error_.what());
+ delete imageblob;
+ Log::getInstance()->log("MagickDecoder", Log::DEBUG, "Libmagick: error mark2");
+ unsigned char* newbuffer = (unsigned char*) malloc(length);
+ memcpy(newbuffer, myblob.data(), length);
+ return newbuffer;
+ }
+ pictInf.reference = (void*) imageblob;
+ pictInf.width = magicimage.columns();
+ pictInf.height = magicimage.rows();
+ pictInf.image = imageblob->data();
+ pictInf.decoder = this;
+ pictInf.type = OsdVector::PictureInfo::RGBAMemBlock;
+ pictInf.lindex = index;
+ pictInfValid = true;
- // I can handle everything, so the return value is always true
- return NULL;
+
+
+ // I can handle everything, so the return value is always true
+ return NULL;
}
-void MagickDecoder::freeReference(void * ref)
+void MagickDecoder::freeReference(void* ref)
{
- Blob *todelete = (Blob*) ref;
- delete todelete;
+ Blob* todelete = (Blob*) ref;
+ delete todelete;
}
bool MagickDecoder::getDecodedPicture(struct OsdVector::PictureInfo& pict_inf)
{
- if (!pictInfValid) return false;
- pict_inf=pictInf;
- pictInfValid = false;
- return true;
+ if (!pictInfValid) return false;
+
+ pict_inf = pictInf;
+ pictInfValid = false;
+ return true;
}
OsdVector::OsdVector()
{
- setlocale(LC_CTYPE,"C.UTF-8");
+ setlocale(LC_CTYPE, "C.UTF-8");
#ifdef PICTURE_DECODER_MAGICK
- reader.addDecoder(new MagickDecoder(&reader));
+ reader.addDecoder(new MagickDecoder(&reader));
#endif
- for (int i=0;i<256;i++) {
- byte_char_width[i]=0.f;
- }
- styles_lastit_valid=styles_ref_lastit_valid=false;
+ for (int i = 0; i < 256; i++)
+ {
+ byte_char_width[i] = 0.f;
+ }
+
+ styles_lastit_valid = styles_ref_lastit_valid = false;
}
int OsdVector::getFD()
{
- return 0;
+ return 0;
}
void OsdVector::screenShot(const char* fileName)
{
- //Do nothing, if no libmagick is there
+ //Do nothing, if no libmagick is there
#ifdef PICTURE_DECODER_MAGICK
- int width,height;
- getRealScreenSize(width,height);
- size_t length=width*height*4;
- void *mem=malloc(length);
-
- try {
- Blob myblob;
- if (!screenShot(mem,width,height,true)) {
- Log::getInstance()->log("OsdVector", Log::DEBUG, "Screenshot failed!");
- free(mem);
- return;
- }
- myblob.updateNoCopy(mem,length,Blob::MallocAllocator);
- Image image(myblob,Geometry(width,height),8,"RGBA");
- image.write(fileName);
- }catch( Exception &error_ )
- {
- Log::getInstance()->log("MagickEncoder", Log::DEBUG, "Libmagick: %s",error_.what());
-
- }
+ int width, height;
+ getRealScreenSize(width, height);
+ size_t length = width * height * 4;
+ void* mem = malloc(length);
+
+ try
+ {
+ Blob myblob;
+
+ if (!screenShot(mem, width, height, true))
+ {
+ Log::getInstance()->log("OsdVector", Log::DEBUG, "Screenshot failed!");
+ free(mem);
+ return;
+ }
+
+ myblob.updateNoCopy(mem, length, Blob::MallocAllocator);
+ Image image(myblob, Geometry(width, height), 8, "RGBA");
+ image.write(fileName);
+ }
+ catch ( Exception& error_ )
+ {
+ Log::getInstance()->log("MagickEncoder", Log::DEBUG, "Libmagick: %s", error_.what());
+
+ }
#endif
}
-Surface * OsdVector::createNewSurface()
+Surface* OsdVector::createNewSurface()
{
- return new SurfaceVector(this);
+ return new SurfaceVector(this);
}
void OsdVector::Blank()
{
- // do nothing? remove this one?
+ // do nothing? remove this one?
}
int OsdVector::restore()
{
- // First clear the contents of all registered surfaces
- surfaces_mutex.lock();
-
- //Now go through all surfaces and draw them
- std::list<SurfaceCommands>::iterator curdraw=scommands.begin();
- while (curdraw!=scommands.end()) {
- (*curdraw).commands.clear();
- (*curdraw).commands.reserve(2048);
- curdraw++;
- }
- //also clear all handles, they are now invalid, no need to release them
- images_ref.clear();
- monobitmaps.clear();
- //jpegs.clear();
- styles.clear();
- styles_ref.clear();
- styles_lastit_valid=styles_ref_lastit_valid=false;
- palettepics.clear();
-
- tvmedias.clear();
- loadindex_ref.clear();
- tvmedias_load.clear();
- tvmedias_load_inv.clear();
- tvmedias_loaded.clear();
-
- surfaces_mutex.unlock();
- return 1;
+ // First clear the contents of all registered surfaces
+ surfaces_mutex.lock();
+
+ //Now go through all surfaces and draw them
+ std::list<SurfaceCommands>::iterator curdraw = scommands.begin();
+
+ while (curdraw != scommands.end())
+ {
+ (*curdraw).commands.clear();
+ (*curdraw).commands.reserve(2048);
+ curdraw++;
+ }
+
+ //also clear all handles, they are now invalid, no need to release them
+ images_ref.clear();
+ monobitmaps.clear();
+ //jpegs.clear();
+ styles.clear();
+ styles_ref.clear();
+ styles_lastit_valid = styles_ref_lastit_valid = false;
+ palettepics.clear();
+
+ tvmedias.clear();
+ loadindex_ref.clear();
+ tvmedias_load.clear();
+ tvmedias_load_inv.clear();
+ tvmedias_loaded.clear();
+
+ surfaces_mutex.unlock();
+ return 1;
}
void OsdVector::drawSurfaces()
{
- surfaces_mutex.lock();
- std::list<SurfaceCommands*> todraw; //First figure out if a surfaces is below another surface
- std::list<SurfaceCommands>::iterator itty1=scommands.begin();
- while (itty1!=scommands.end()) {
- std::list<SurfaceCommands>::iterator itty2=itty1;
- itty2++;
- bool hidden=false;
- while (itty2!=scommands.end()) {
- SurfaceCommands & ref1=*itty1;
- SurfaceCommands & ref2=*itty2;
- if (ref1.x>=ref2.x && ref1.y>=ref2.y
- && (ref1.x+ref1.w) <= (ref2.x+ref2.w)
- && (ref1.y+ref1.h) <= (ref2.y+ref2.h) ) {
- hidden=true;
- break;
- }
- itty2++;
- }
- if (!hidden) { // we are not hidden, perfect
- todraw.push_back(&(*itty1));
- }
- itty1++;
- }
- int swidth,sheight;
- getScreenSize(swidth,sheight);
- //Now go through all surfaces and draw them
- std::list<SurfaceCommands*>::iterator curdraw=todraw.begin();
- while (curdraw!=todraw.end()) {
- drawSetTrans(*(*curdraw));
- std::vector<SVGCommand>::iterator commands=(*(*curdraw)).commands.begin();
- std::vector<SVGCommand>::iterator end=(*(*curdraw)).commands.end();
- while (commands!=end) {
- // update any images loaded in the mean time
- if ((*commands).instr==DrawImageLoading) {
- LoadIndex loadindex=(*commands).target.loadindex;
- if (tvmedias_loaded.find(loadindex)!=tvmedias_loaded.end()) {
- (*commands).instr=DrawImage;
- (*commands).target.image=tvmedias_loaded[loadindex];;
- incImageRef((*commands).target.image);
- removeLoadIndexRef(loadindex);
- }
-
- }
- // Now check if the command is on screen!
- if (!(*commands).Outside(0,0,swidth,sheight)) {
- executeDrawCommand(*commands);
- }
- commands++;
- }
- curdraw++;
- }
+ surfaces_mutex.lock();
+ std::list<SurfaceCommands*> todraw; //First figure out if a surfaces is below another surface
+ std::list<SurfaceCommands>::iterator itty1 = scommands.begin();
+
+ while (itty1 != scommands.end())
+ {
+ std::list<SurfaceCommands>::iterator itty2 = itty1;
+ itty2++;
+ bool hidden = false;
+
+ while (itty2 != scommands.end())
+ {
+ SurfaceCommands& ref1 = *itty1;
+ SurfaceCommands& ref2 = *itty2;
+
+ if (ref1.x >= ref2.x && ref1.y >= ref2.y
+ && (ref1.x + ref1.w) <= (ref2.x + ref2.w)
+ && (ref1.y + ref1.h) <= (ref2.y + ref2.h) )
+ {
+ hidden = true;
+ break;
+ }
+
+ itty2++;
+ }
+
+ if (!hidden) // we are not hidden, perfect
+ {
+ todraw.push_back(&(*itty1));
+ }
+
+ itty1++;
+ }
+
+ int swidth, sheight;
+ getScreenSize(swidth, sheight);
+ //Now go through all surfaces and draw them
+ std::list<SurfaceCommands*>::iterator curdraw = todraw.begin();
+
+ while (curdraw != todraw.end())
+ {
+ drawSetTrans(*(*curdraw));
+ std::vector<SVGCommand>::iterator commands = (*(*curdraw)).commands.begin();
+ std::vector<SVGCommand>::iterator end = (*(*curdraw)).commands.end();
+
+ while (commands != end)
+ {
+ // update any images loaded in the mean time
+ if ((*commands).instr == DrawImageLoading)
+ {
+ LoadIndex loadindex = (*commands).target.loadindex;
+
+ if (tvmedias_loaded.find(loadindex) != tvmedias_loaded.end())
+ {
+ (*commands).instr = DrawImage;
+ (*commands).target.image = tvmedias_loaded[loadindex];;
+ incImageRef((*commands).target.image);
+ removeLoadIndexRef(loadindex);
+ }
+
+ }
+
+ // Now check if the command is on screen!
+ if (!(*commands).Outside(0, 0, swidth, sheight))
+ {
+ executeDrawCommand(*commands);
+ }
+
+ commands++;
+ }
+
+ curdraw++;
+ }
+
+ surfaces_mutex.unlock();
+}
- surfaces_mutex.unlock();
+void OsdVector::updateOrAddSurface(const SurfaceVector* surf, float x, float y, float height, float width,
+ std::vector<SVGCommand>& commands)
+{
+ surfaces_mutex.lock();
+ //First determine it is already in our system
+ std::list<SurfaceCommands>::iterator itty = scommands.begin();
+
+ while (itty != scommands.end())
+ {
+ if ((*itty).surf == surf)
+ {
+ //decrease the references
+ dereferenceSVGCommand((*itty).commands);
+ break;
+ }
+
+ itty++;
+ }
+
+ // if not insert it
+ if (itty == scommands.end())
+ {
+ SurfaceCommands new_sc;
+ new_sc.surf = surf;
+ new_sc.x = x;
+ new_sc.y = y;
+ new_sc.w = width;
+ new_sc.h = height;
+ itty = scommands.insert(itty, new_sc);
+ }
+
+ // update any images loaded in the mean time
+ std::vector<SVGCommand>::iterator ilitty = commands.begin();
+
+ while (ilitty != commands.end())
+ {
+ if ((*ilitty).instr == DrawImageLoading)
+ {
+ LoadIndex loadindex = (*ilitty).target.loadindex;
+
+ if (tvmedias_loaded.find(loadindex) != tvmedias_loaded.end())
+ {
+
+ (*ilitty).instr = DrawImage;
+ (*ilitty).target.image = tvmedias_loaded[loadindex];
+ incImageRef((*ilitty).target.image);
+ removeLoadIndexRef(loadindex);
+ }
+ }
+
+ ilitty++;
+ }
+
+
+ // then clear and copy
+ (*itty).commands.clear();
+ (*itty).commands = commands;
+ //increase the references
+ referenceSVGCommand((*itty).commands);
+ cleanupOrphanedRefs();
+
+ surfaces_mutex.unlock();
}
-void OsdVector::updateOrAddSurface(const SurfaceVector *surf,float x,float y,float height,float width,
- std::vector<SVGCommand>& commands)
+void OsdVector::removeSurface(const SurfaceVector* surf)
{
- surfaces_mutex.lock();
- //First determine it is already in our system
- std::list<SurfaceCommands>::iterator itty=scommands.begin();
- while (itty!=scommands.end()) {
- if ((*itty).surf==surf) {
- //decrease the references
- dereferenceSVGCommand((*itty).commands);
- break;
- }
- itty++;
- }
- // if not insert it
- if (itty==scommands.end()) {
- SurfaceCommands new_sc;
- new_sc.surf=surf;
- new_sc.x=x;
- new_sc.y=y;
- new_sc.w=width;
- new_sc.h=height;
- itty=scommands.insert(itty,new_sc);
- }
- // update any images loaded in the mean time
- std::vector<SVGCommand>::iterator ilitty=commands.begin();
+ surfaces_mutex.lock();
+ //First determine it is already in our system
+ std::list<SurfaceCommands>::iterator itty = scommands.begin();
- while (ilitty!=commands.end())
- {
- if ((*ilitty).instr==DrawImageLoading) {
- LoadIndex loadindex=(*ilitty).target.loadindex;
- if (tvmedias_loaded.find(loadindex)!=tvmedias_loaded.end()) {
-
- (*ilitty).instr=DrawImage;
- (*ilitty).target.image=tvmedias_loaded[loadindex];
- incImageRef((*ilitty).target.image);
- removeLoadIndexRef(loadindex);
- }
- }
- ilitty++;
- }
+ while (itty != scommands.end())
+ {
+ if ((*itty).surf == surf)
+ {
+ dereferenceSVGCommand((*itty).commands);
+ (*itty).commands.clear();
+ scommands.erase(itty);
+ break;
+ }
+ itty++;
+ }
- // then clear and copy
- (*itty).commands.clear();
- (*itty).commands=commands;
- //increase the references
- referenceSVGCommand((*itty).commands);
- cleanupOrphanedRefs();
+ surfaces_mutex.unlock();
- surfaces_mutex.unlock();
}
-void OsdVector::removeSurface(const SurfaceVector *surf)
+void OsdVector::dereferenceSVGCommand(std::vector<SVGCommand>& commands )
{
- surfaces_mutex.lock();
- //First determine it is already in our system
- std::list<SurfaceCommands>::iterator itty=scommands.begin();
- while (itty!=scommands.end()) {
- if ((*itty).surf==surf) {
- dereferenceSVGCommand((*itty).commands);
- (*itty).commands.clear();
- scommands.erase(itty);
- break;
- }
- itty++;
- }
- surfaces_mutex.unlock();
-}
+ std::vector<SVGCommand>::iterator sitty = commands.begin();
-void OsdVector::dereferenceSVGCommand(std::vector<SVGCommand>& commands )
-{
+ while (sitty != commands.end())
+ {
+ removeStyleRef((*sitty).getRef());
+ ImageIndex ii = (*sitty).getImageIndex();
- std::vector<SVGCommand>::iterator sitty = commands.begin();
- while (sitty != commands.end()) {
- removeStyleRef((*sitty).getRef());
- ImageIndex ii = (*sitty).getImageIndex();
- if (ii) removeImageRef(ii);
- LoadIndex li=(*sitty).getLoadIndex();
- if (li) removeLoadIndexRef(li);
- sitty++;
- }
+ if (ii) removeImageRef(ii);
+
+ LoadIndex li = (*sitty).getLoadIndex();
+
+ if (li) removeLoadIndexRef(li);
+
+ sitty++;
+ }
}
void OsdVector::referenceSVGCommand(std::vector<SVGCommand>& commands )
{
- std::vector<SVGCommand>::iterator sitty=commands.begin();
- while (sitty!=commands.end())
- {
- incStyleRef((*sitty).getRef());
- ImageIndex ii=(*sitty).getImageIndex();
- if (ii) incImageRef(ii);
- LoadIndex li=(*sitty).getLoadIndex();
- if (li) incLoadIndexRef(li);
- sitty++;
- }
+ std::vector<SVGCommand>::iterator sitty = commands.begin();
+
+ while (sitty != commands.end())
+ {
+ incStyleRef((*sitty).getRef());
+ ImageIndex ii = (*sitty).getImageIndex();
+
+ if (ii) incImageRef(ii);
+
+ LoadIndex li = (*sitty).getLoadIndex();
+
+ if (li) incLoadIndexRef(li);
+
+ sitty++;
+ }
}
void OsdVector::incImageRef(ImageIndex index)
{
- if (images_ref.find(index)==images_ref.end()) {
- images_ref[index]=1;
- } else {
- images_ref[index]++;
- }
+ if (images_ref.find(index) == images_ref.end())
+ {
+ images_ref[index] = 1;
+ }
+ else
+ {
+ images_ref[index]++;
+ }
}
void OsdVector::removeImageRef(const ImageIndex ref)
{
- images_ref[ref]--;
+ images_ref[ref]--;
}
int OsdVector::getLoadIndexRef(LoadIndex index)
{
- surfaces_mutex.lock();
- if (loadindex_ref.find(index)==loadindex_ref.end()) {
- return -1;
- } else {
- return loadindex_ref[index];
- }
- surfaces_mutex.unlock();
+ surfaces_mutex.lock();
+
+ if (loadindex_ref.find(index) == loadindex_ref.end())
+ {
+ return -1;
+ }
+ else
+ {
+ return loadindex_ref[index];
+ }
+
+ surfaces_mutex.unlock();
}
void OsdVector::incLoadIndexRef(LoadIndex index)
{
- if (loadindex_ref.find(index)==loadindex_ref.end()) {
- loadindex_ref[index]=1;
- } else {
- loadindex_ref[index]++;
- }
+ if (loadindex_ref.find(index) == loadindex_ref.end())
+ {
+ loadindex_ref[index] = 1;
+ }
+ else
+ {
+ loadindex_ref[index]++;
+ }
}
void OsdVector::removeLoadIndexRef(const LoadIndex ref)
{
- loadindex_ref[ref]--;
- if (loadindex_ref[ref]==0) {
- //now check, if it is already loaded
- std::map<LoadIndex,ImageIndex>::iterator itty=tvmedias_loaded.find(ref);
- if ( itty != tvmedias_loaded.end()) {
- removeImageRef((*itty).second); // remove lock
- }
- tvmedias_loaded.erase(ref);
-// Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia removeLoadIndexRef %d %llx",tvmedias_load.size(),ref);
- tvmedias_load.erase(tvmedias_load_inv[ref]);
- tvmedias_load_inv.erase(ref);
-
- reader.invalidateLoadIndex(ref);
-
-
- }
-}
-
-
-
-void OsdVector::cleanupOrphanedRefs()
-{ // Do some garbage collection
-
- std::map<void *,ImageIndex>::iterator mitty=monobitmaps.begin();
- while (mitty!=monobitmaps.end()) {
- std::map<ImageIndex,int>::iterator curitty=images_ref.find((*mitty).second);
- int count=(*curitty).second;
- if (count==0) {
- ImageIndex ref=(*curitty).first;
- monobitmaps.erase(mitty++);
- images_ref.erase(curitty++);
- destroyImageRef(ref);
- } else ++mitty;
- }
+ loadindex_ref[ref]--;
- /*map<string,ImageIndex>::iterator jitty=jpegs.begin();
- while (jitty!=jpegs.end()) {
- map<ImageIndex,int>::iterator curitty=images_ref.find((*jitty).second);
- int count=(*curitty).second;
- if (count==0) {
- ImageIndex ref=(*curitty).first;
- jpegs.erase(jitty++);
- images_ref.erase(curitty++);
- destroyImageRef(ref);
- } else ++jitty;
- }*/
-
- std::map<TVMediaInfo,ImageIndex>::iterator titty=tvmedias.begin();
- while (titty!=tvmedias.end()) {
- std::map<ImageIndex,int>::iterator curitty=images_ref.find((*titty).second);
- int count=(*curitty).second;
- if (count==0) {
- ImageIndex ref=(*curitty).first;
- tvmedias.erase(titty++);
- images_ref.erase(curitty);
- destroyImageRef(ref);
- } else ++titty;
- }
+ if (loadindex_ref[ref] == 0)
+ {
+ //now check, if it is already loaded
+ std::map<LoadIndex, ImageIndex>::iterator itty = tvmedias_loaded.find(ref);
+ if ( itty != tvmedias_loaded.end())
+ {
+ removeImageRef((*itty).second); // remove lock
+ }
- std::map<TVMediaInfo,LoadIndex>::iterator litty=tvmedias_load.begin();
- while (litty!=tvmedias_load.end()) {
- std::map<LoadIndex,int>::iterator curitty=loadindex_ref.find((*litty).second);
- int count=(*curitty).second;
- if (count==0) {
- tvmedias_load_inv.erase((*litty).second);
- tvmedias_loaded.erase((*litty).second);
- tvmedias_load.erase(litty++);
- } else ++litty;
- }
+ tvmedias_loaded.erase(ref);
+ // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia removeLoadIndexRef %d %llx",tvmedias_load.size(),ref);
+ tvmedias_load.erase(tvmedias_load_inv[ref]);
+ tvmedias_load_inv.erase(ref);
- std::list<ImageIndex>::iterator pitty=palettepics.begin();
- while (pitty!=palettepics.end()) {
- std::map<ImageIndex,int>::iterator curitty=images_ref.find((*pitty));
- int count=(*curitty).second;
- if (count==0) {
- ImageIndex ref=(*curitty).first;
- palettepics.erase(pitty++);
- images_ref.erase(curitty++);
- destroyImageRef(ref);
- } else ++pitty;
- }
+ reader.invalidateLoadIndex(ref);
- std::map<ImageIndex,int>::iterator citty=images_ref.begin();
- while (citty!=images_ref.end()) {
- int count=(*citty).second;
- if (count==0) {
- ImageIndex ref=(*citty).first;
- images_ref.erase(citty++);
- destroyImageRef(ref);
- } else ++citty;
- }
+ }
+}
- std::map<DrawStyle, VectorHandle>::iterator sitty = styles.begin();
- while (sitty!=styles.end()) {
- std::map<VectorHandle, int>::iterator curitty = styles_ref.find((*sitty).second);
- int count=(*curitty).second;
- if (count==0) {
- VectorHandle ref = (*curitty).first;
- styles.erase(sitty++);
- styles_ref.erase(curitty++);
- styles_lastit_valid=styles_ref_lastit_valid=false;
- destroyStyleRef(ref);
- } else ++sitty;
- }
+void OsdVector::cleanupOrphanedRefs()
+{
+ // Do some garbage collection
+
+ std::map<void*, ImageIndex>::iterator mitty = monobitmaps.begin();
+
+ while (mitty != monobitmaps.end())
+ {
+ std::map<ImageIndex, int>::iterator curitty = images_ref.find((*mitty).second);
+ int count = (*curitty).second;
+
+ if (count == 0)
+ {
+ ImageIndex ref = (*curitty).first;
+ monobitmaps.erase(mitty++);
+ images_ref.erase(curitty++);
+ destroyImageRef(ref);
+ }
+ else ++mitty;
+ }
+
+ /*map<string,ImageIndex>::iterator jitty=jpegs.begin();
+ while (jitty!=jpegs.end()) {
+ map<ImageIndex,int>::iterator curitty=images_ref.find((*jitty).second);
+ int count=(*curitty).second;
+ if (count==0) {
+ ImageIndex ref=(*curitty).first;
+ jpegs.erase(jitty++);
+ images_ref.erase(curitty++);
+ destroyImageRef(ref);
+ } else ++jitty;
+ }*/
+
+ std::map<TVMediaInfo, ImageIndex>::iterator titty = tvmedias.begin();
+
+ while (titty != tvmedias.end())
+ {
+ std::map<ImageIndex, int>::iterator curitty = images_ref.find((*titty).second);
+ int count = (*curitty).second;
+
+ if (count == 0)
+ {
+ ImageIndex ref = (*curitty).first;
+ tvmedias.erase(titty++);
+ images_ref.erase(curitty);
+ destroyImageRef(ref);
+ }
+ else ++titty;
+ }
+
+
+ std::map<TVMediaInfo, LoadIndex>::iterator litty = tvmedias_load.begin();
+
+ while (litty != tvmedias_load.end())
+ {
+ std::map<LoadIndex, int>::iterator curitty = loadindex_ref.find((*litty).second);
+ int count = (*curitty).second;
+
+ if (count == 0)
+ {
+ tvmedias_load_inv.erase((*litty).second);
+ tvmedias_loaded.erase((*litty).second);
+ tvmedias_load.erase(litty++);
+ }
+ else ++litty;
+ }
+
+ std::list<ImageIndex>::iterator pitty = palettepics.begin();
+
+ while (pitty != palettepics.end())
+ {
+ std::map<ImageIndex, int>::iterator curitty = images_ref.find((*pitty));
+ int count = (*curitty).second;
+
+ if (count == 0)
+ {
+ ImageIndex ref = (*curitty).first;
+ palettepics.erase(pitty++);
+ images_ref.erase(curitty++);
+ destroyImageRef(ref);
+ }
+ else ++pitty;
+ }
+
+ std::map<ImageIndex, int>::iterator citty = images_ref.begin();
+
+ while (citty != images_ref.end())
+ {
+ int count = (*citty).second;
+
+ if (count == 0)
+ {
+ ImageIndex ref = (*citty).first;
+ images_ref.erase(citty++);
+ destroyImageRef(ref);
+ }
+ else ++citty;
+ }
+
+
+ std::map<DrawStyle, VectorHandle>::iterator sitty = styles.begin();
+
+ while (sitty != styles.end())
+ {
+ std::map<VectorHandle, int>::iterator curitty = styles_ref.find((*sitty).second);
+ int count = (*curitty).second;
+
+ if (count == 0)
+ {
+ VectorHandle ref = (*curitty).first;
+ styles.erase(sitty++);
+ styles_ref.erase(curitty++);
+ styles_lastit_valid = styles_ref_lastit_valid = false;
+ destroyStyleRef(ref);
+
+ }
+ else ++sitty;
+
+ }
}
int OsdVector::getImageRef(ImageIndex index)
{
- surfaces_mutex.lock();
- if (images_ref.find(index)==images_ref.end()) {
- return -1;
- } else {
- return images_ref[index];
- }
- surfaces_mutex.unlock();
+ surfaces_mutex.lock();
+
+ if (images_ref.find(index) == images_ref.end())
+ {
+ return -1;
+ }
+ else
+ {
+ return images_ref[index];
+ }
+
+ surfaces_mutex.unlock();
}
void OsdVector::incStyleRef(VectorHandle index)
{
- if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=index) {
- styles_ref_lastit_valid=false;
- styles_ref_lastit=styles_ref.find(index);
- }
- if (styles_ref_lastit==styles_ref.end()) {
- styles_ref_lastit = styles_ref.insert(std::pair<VectorHandle, int>(index, 1)).first;
- } else {
- (*styles_ref_lastit).second++;
- }
- styles_ref_lastit_valid=true;
+ if (!styles_ref_lastit_valid || (*styles_ref_lastit).first != index)
+ {
+ styles_ref_lastit_valid = false;
+ styles_ref_lastit = styles_ref.find(index);
+ }
+
+ if (styles_ref_lastit == styles_ref.end())
+ {
+ styles_ref_lastit = styles_ref.insert(std::pair<VectorHandle, int>(index, 1)).first;
+ }
+ else
+ {
+ (*styles_ref_lastit).second++;
+ }
+
+ styles_ref_lastit_valid = true;
}
void OsdVector::removeStyleRef(VectorHandle index)
{
- if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=index) {
- styles_ref_lastit_valid=false;
- styles_ref_lastit=styles_ref.find(index);
- }
- if (styles_ref_lastit!=styles_ref.end()) {
- styles_ref_lastit_valid=true;
- (*styles_ref_lastit).second--;
- }
+ if (!styles_ref_lastit_valid || (*styles_ref_lastit).first != index)
+ {
+ styles_ref_lastit_valid = false;
+ styles_ref_lastit = styles_ref.find(index);
+ }
+
+ if (styles_ref_lastit != styles_ref.end())
+ {
+ styles_ref_lastit_valid = true;
+ (*styles_ref_lastit).second--;
+ }
}
-VectorHandle OsdVector::getStyleRef(const DrawStyle &c)
+VectorHandle OsdVector::getStyleRef(const DrawStyle& c)
{
- surfaces_mutex.lock();
- VectorHandle style_handle = 0;
- if (!styles_lastit_valid || (*styles_lastit).first!=c) {
- styles_lastit_valid=false;
- styles_lastit=styles.find(c);
- }
-
- if (styles_lastit==styles.end())
- {
- surfaces_mutex.unlock();
- style_handle=createStyleRef(c);
- surfaces_mutex.lock();
- styles_lastit = styles.insert(std::pair<DrawStyle, VectorHandle>(c, style_handle)).first;
- } else {
-
- style_handle=(*styles_lastit).second;
- //Now check if the handle is valid
- if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=style_handle) {
- styles_ref_lastit_valid=false;
- styles_ref_lastit=styles_ref.find(style_handle);
- }
-
- if (styles_ref_lastit==styles_ref.end()) {
- //invalid handle recreate
- surfaces_mutex.unlock();
- style_handle=createStyleRef(c);
- surfaces_mutex.lock();
- (*styles_lastit).second=style_handle;
- } else styles_ref_lastit_valid=true;
- }
- styles_lastit_valid=true;
- incStyleRef(style_handle);
- surfaces_mutex.unlock();
- return style_handle;
+ surfaces_mutex.lock();
+ VectorHandle style_handle = 0;
+
+ if (!styles_lastit_valid || (*styles_lastit).first != c)
+ {
+ styles_lastit_valid = false;
+ styles_lastit = styles.find(c);
+ }
+
+ if (styles_lastit == styles.end())
+ {
+ surfaces_mutex.unlock();
+ style_handle = createStyleRef(c);
+ surfaces_mutex.lock();
+ styles_lastit = styles.insert(std::pair<DrawStyle, VectorHandle>(c, style_handle)).first;
+ }
+ else
+ {
+
+ style_handle = (*styles_lastit).second;
+
+ //Now check if the handle is valid
+ if (!styles_ref_lastit_valid || (*styles_ref_lastit).first != style_handle)
+ {
+ styles_ref_lastit_valid = false;
+ styles_ref_lastit = styles_ref.find(style_handle);
+ }
+
+ if (styles_ref_lastit == styles_ref.end())
+ {
+ //invalid handle recreate
+ surfaces_mutex.unlock();
+ style_handle = createStyleRef(c);
+ surfaces_mutex.lock();
+ (*styles_lastit).second = style_handle;
+ }
+ else styles_ref_lastit_valid = true;
+ }
+
+ styles_lastit_valid = true;
+ incStyleRef(style_handle);
+ surfaces_mutex.unlock();
+ return style_handle;
}
int OsdVector::getStyleRef(VectorHandle index)
{
- if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=index) {
- styles_ref_lastit_valid=false;
- styles_ref_lastit=styles_ref.find(index);
- }
- if (styles_ref_lastit==styles_ref.end()) {
- return -1;
- } else {
- styles_ref_lastit_valid=true;
- return (*styles_ref_lastit).second;
- }
+ if (!styles_ref_lastit_valid || (*styles_ref_lastit).first != index)
+ {
+ styles_ref_lastit_valid = false;
+ styles_ref_lastit = styles_ref.find(index);
+ }
+
+ if (styles_ref_lastit == styles_ref.end())
+ {
+ return -1;
+ }
+ else
+ {
+ styles_ref_lastit_valid = true;
+ return (*styles_ref_lastit).second;
+ }
}
LoadIndex OsdVector::getTVMediaRef(TVMediaInfo& tvmedia, ImageIndex& image)
{
- ImageIndex image_handle=0;
- LoadIndex loadindex=0;
- surfaces_mutex.lock();
- if (tvmedias.find(tvmedia)==tvmedias.end())
- {
- loadindex=loadTVMedia(tvmedia);
- } else {
- image_handle=tvmedias[tvmedia];
- if (images_ref.find(image_handle)==images_ref.end()) {
- //invalid handle recreate
- loadindex=loadTVMedia(tvmedia);
- image_handle=0;
- } else {
- incImageRef(image_handle);
- }
- }
- /*tvmedias[tvmedia]=createTVMedia(tvmedia,width,height);
- incImageRef(image_handle);*/
- image=image_handle;
- surfaces_mutex.unlock();
- return loadindex;
+ ImageIndex image_handle = 0;
+ LoadIndex loadindex = 0;
+ surfaces_mutex.lock();
+
+ if (tvmedias.find(tvmedia) == tvmedias.end())
+ {
+ loadindex = loadTVMedia(tvmedia);
+ }
+ else
+ {
+ image_handle = tvmedias[tvmedia];
+
+ if (images_ref.find(image_handle) == images_ref.end())
+ {
+ //invalid handle recreate
+ loadindex = loadTVMedia(tvmedia);
+ image_handle = 0;
+ }
+ else
+ {
+ incImageRef(image_handle);
+ }
+ }
+
+ /*tvmedias[tvmedia]=createTVMedia(tvmedia,width,height);
+ incImageRef(image_handle);*/
+ image = image_handle;
+ surfaces_mutex.unlock();
+ return loadindex;
}
LoadIndex OsdVector::loadTVMedia(TVMediaInfo& tvmedia)
{
- LoadIndex index=0;
-
- if (tvmedias_load.find(tvmedia)==tvmedias_load.end())
- {
- switch (tvmedia.getType()) {
- case 3:
- index=VDR::getInstance()->loadTVMediaRecThumb(tvmedia);
- break;
- case 4: {
- index = ((long long) tvmedia.getPrimaryID()) << 32LL;
- reader.addStaticImage(tvmedia.getPrimaryID());
- } break;
- case 5:
- index=VDR::getInstance()->loadTVMediaEventThumb(tvmedia);
- break;
- case 6:
- index=VDR::getInstance()->loadChannelLogo(tvmedia);
- break;
- default:
- index=VDR::getInstance()->loadTVMedia(tvmedia);
- break;
- }
- if (tvmedia.getType()!=4 && tvmedia.getStaticFallback()>-1) {
- reader.informFallback(index,tvmedia.getStaticFallback());
- }
-
- tvmedias_load[tvmedia]=index;
- tvmedias_load_inv[index]=tvmedia;
- } else {
- index=tvmedias_load[tvmedia];
- }
-
- incLoadIndexRef(index);
-
- return index;
+ LoadIndex index = 0;
+
+ if (tvmedias_load.find(tvmedia) == tvmedias_load.end())
+ {
+ switch (tvmedia.getType())
+ {
+ case 3:
+ index = VDR::getInstance()->loadTVMediaRecThumb(tvmedia);
+ break;
+
+ case 4:
+ {
+ index = ((long long) tvmedia.getPrimaryID()) << 32LL;
+ reader.addStaticImage(tvmedia.getPrimaryID());
+ } break;
+
+ case 5:
+ index = VDR::getInstance()->loadTVMediaEventThumb(tvmedia);
+ break;
+
+ case 6:
+ index = VDR::getInstance()->loadChannelLogo(tvmedia);
+ break;
+
+ default:
+ index = VDR::getInstance()->loadTVMedia(tvmedia);
+ break;
+ }
+
+ if (tvmedia.getType() != 4 && tvmedia.getStaticFallback() > -1)
+ {
+ reader.informFallback(index, tvmedia.getStaticFallback());
+ }
+
+ tvmedias_load[tvmedia] = index;
+ tvmedias_load_inv[index] = tvmedia;
+ }
+ else
+ {
+ index = tvmedias_load[tvmedia];
+ }
+
+ incLoadIndexRef(index);
+
+ return index;
}
void OsdVector::informPicture(LoadIndex index, ImageIndex imageIndex)
{
- //Beware for thread safety
- ImageIndex image_index=0;
-
- Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Picture for request id %llx arrived %x",index, imageIndex);
- surfaces_mutex.lock();
- TVMediaInfo tvmedia=tvmedias_load_inv[index];
- if (imageIndex) {
- std::map<LoadIndex,int>::iterator itty=loadindex_ref.find(index);
- image_index=tvmedias[tvmedia]=imageIndex;
- tvmedias_loaded[index]=image_index;
-
- if (itty==loadindex_ref.end() || (*itty).second == 0) {
- // we do not want the picture anymore . Really...
- // fill images_ref in to not irritate the garbage collector
- if (images_ref.find(image_index)==images_ref.end()) {
- images_ref[image_index]=0;
- }
- } else {
- incImageRef(image_index); // hold one index until all loadings refs are gone;
- }
- }
- surfaces_mutex.unlock();
+ //Beware for thread safety
+ ImageIndex image_index = 0;
+
+ Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Picture for request id %llx arrived %x", index, imageIndex);
+ surfaces_mutex.lock();
+ TVMediaInfo tvmedia = tvmedias_load_inv[index];
+
+ if (imageIndex)
+ {
+ std::map<LoadIndex, int>::iterator itty = loadindex_ref.find(index);
+ image_index = tvmedias[tvmedia] = imageIndex;
+ tvmedias_loaded[index] = image_index;
+
+ if (itty == loadindex_ref.end() || (*itty).second == 0)
+ {
+ // we do not want the picture anymore . Really...
+ // fill images_ref in to not irritate the garbage collector
+ if (images_ref.find(image_index) == images_ref.end())
+ {
+ images_ref[image_index] = 0;
+ }
+ }
+ else
+ {
+ incImageRef(image_index); // hold one index until all loadings refs are gone;
+ }
+ }
+
+ surfaces_mutex.unlock();
}
}
*/
-ImageIndex OsdVector::getMonoBitmapRef(void *base,int width,int height)
+ImageIndex OsdVector::getMonoBitmapRef(void* base, int width, int height)
{
- ImageIndex image_handle;
- surfaces_mutex.lock();
- if (monobitmaps.find(base)==monobitmaps.end())
- {
- surfaces_mutex.unlock();
- image_handle=createMonoBitmap(base,width,height);
- surfaces_mutex.lock();
- monobitmaps[base]=image_handle;
- } else {
- image_handle=monobitmaps[base];
- if (images_ref.find(image_handle)==images_ref.end()) {
- //invalid handle recreate
- surfaces_mutex.unlock();
- image_handle=createMonoBitmap(base,width,height);
- surfaces_mutex.lock();
- monobitmaps[base]=image_handle;
- }
- }
- incImageRef(image_handle);
- surfaces_mutex.unlock();
- return image_handle;
+ ImageIndex image_handle;
+ surfaces_mutex.lock();
+
+ if (monobitmaps.find(base) == monobitmaps.end())
+ {
+ surfaces_mutex.unlock();
+ image_handle = createMonoBitmap(base, width, height);
+ surfaces_mutex.lock();
+ monobitmaps[base] = image_handle;
+ }
+ else
+ {
+ image_handle = monobitmaps[base];
+
+ if (images_ref.find(image_handle) == images_ref.end())
+ {
+ //invalid handle recreate
+ surfaces_mutex.unlock();
+ image_handle = createMonoBitmap(base, width, height);
+ surfaces_mutex.lock();
+ monobitmaps[base] = image_handle;
+ }
+ }
+
+ incImageRef(image_handle);
+ surfaces_mutex.unlock();
+ return image_handle;
}
-ImageIndex OsdVector::getImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)
+ImageIndex OsdVector::getImagePalette(int width, int height, const unsigned char* image_data, const unsigned int* palette_data)
{
- ImageIndex image_handle;
- image_handle=createImagePalette(width,height,image_data,palette_data);
- surfaces_mutex.lock();
- palettepics.push_back(image_handle);
- incImageRef(image_handle);
- surfaces_mutex.unlock();
- return image_handle;
+ ImageIndex image_handle;
+ image_handle = createImagePalette(width, height, image_data, palette_data);
+ surfaces_mutex.lock();
+ palettepics.push_back(image_handle);
+ incImageRef(image_handle);
+ surfaces_mutex.unlock();
+ return image_handle;
}
OsdVector::PictureReader::~PictureReader()
{
- decoders_lock.lock();
- while ( decoders.size()) {
- PictureDecoder* dec=decoders.front();
- decoders.pop_front();
- delete dec;
- }
+ decoders_lock.lock();
+
+ while ( decoders.size())
+ {
+ PictureDecoder* dec = decoders.front();
+ decoders.pop_front();
+ delete dec;
+ }
- decoders_lock.unlock();
+ decoders_lock.unlock();
}
void OsdVector::PictureReader::init()
{
- threadStart();
+ threadStart();
}
void OsdVector::PictureReader::shutdown()
{
- threadStop();
+ threadStop();
}
void OsdVector::PictureReader::addDecoder(PictureDecoder* decoder)
{
- decoders_lock.lock();
- decoder->init();
- decoders.push_front(decoder);
- decoders_lock.unlock();
+ decoders_lock.lock();
+ decoder->init();
+ decoders.push_front(decoder);
+ decoders_lock.unlock();
}
void OsdVector::PictureReader::removeDecoder(PictureDecoder* decoder)
{
- decoders_lock.lock();
- std::list<PictureDecoder*>::iterator itty=decoders.begin();
- while (itty!=decoders.end()) {
- if ((*itty) == decoder)
- {
- decoders.erase(itty);
- break;
- }
- itty++;
- }
- Log::getInstance()->log("OsdVector", Log::DEBUG, "removeDecoder");
- decoder->shutdown();
- delete decoder;
- decoders_lock.unlock();
+ decoders_lock.lock();
+ std::list<PictureDecoder*>::iterator itty = decoders.begin();
+
+ while (itty != decoders.end())
+ {
+ if ((*itty) == decoder)
+ {
+ decoders.erase(itty);
+ break;
+ }
+
+ itty++;
+ }
+
+ Log::getInstance()->log("OsdVector", Log::DEBUG, "removeDecoder");
+ decoder->shutdown();
+ delete decoder;
+ decoders_lock.unlock();
}
void OsdVector::PictureReader::threadMethod()
{
- OsdVector *osdvector = dynamic_cast<OsdVector*>(Osd::getInstance());
- Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Start Picture Reader");
- while (true) {
- if (!threadIsActive()) {
- Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia End Picture Reader");
- threadCheckExit();
- }
-
- bool todos=true;
- while (todos)
- {
- todos=false;
- PictureInfo pictinf;
- decoders_lock.lock();
- std::list<PictureDecoder*>::iterator itty=decoders.begin();
-
- while (itty!=decoders.end()) {
- if ((*itty)->getDecodedPicture(pictinf)) {
- todos = true;
- osdvector->createPicture(pictinf);
- }
-
- itty++;
- }
- if (processReceivedPictures())
- {
- todos = true;
- }
-
- decoders_lock.unlock();
- }
- //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep Picture Reader");
-
- struct timespec target_time;
- getClockRealTime(&target_time);
-
- target_time.tv_nsec+=1000000LL*10;
- if (target_time.tv_nsec>999999999) {
- target_time.tv_nsec-=1000000000L;
- target_time.tv_sec+=1;
- }
- threadLock();
- threadWaitForSignalTimed(&target_time);
- threadUnlock();
- //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep end Picture Reader");
- }
+ OsdVector* osdvector = dynamic_cast<OsdVector*>(Osd::getInstance());
+ Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Start Picture Reader");
+
+ while (true)
+ {
+ if (!threadIsActive())
+ {
+ Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia End Picture Reader");
+ threadCheckExit();
+ }
+
+ bool todos = true;
+
+ while (todos)
+ {
+ todos = false;
+ PictureInfo pictinf;
+ decoders_lock.lock();
+ std::list<PictureDecoder*>::iterator itty = decoders.begin();
+
+ while (itty != decoders.end())
+ {
+ if ((*itty)->getDecodedPicture(pictinf))
+ {
+ todos = true;
+ osdvector->createPicture(pictinf);
+ }
+
+ itty++;
+ }
+
+ if (processReceivedPictures())
+ {
+ todos = true;
+ }
+
+ decoders_lock.unlock();
+ }
+
+ //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep Picture Reader");
+
+ struct timespec target_time;
+ getClockRealTime(&target_time);
+
+ target_time.tv_nsec += 1000000LL * 10;
+
+ if (target_time.tv_nsec > 999999999)
+ {
+ target_time.tv_nsec -= 1000000000L;
+ target_time.tv_sec += 1;
+ }
+
+ threadLock();
+ threadWaitForSignalTimed(&target_time);
+ threadUnlock();
+ //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Sleep end Picture Reader");
+ }
}
void OsdVector::PictureReader::invalidateLoadIndex(LoadIndex index)
{
- pict_lock_incoming.lock();
- invalid_loadindex.insert(index);
- pict_lock_incoming.unlock();
+ pict_lock_incoming.lock();
+ invalid_loadindex.insert(index);
+ pict_lock_incoming.unlock();
}
void OsdVector::PictureReader::informFallback(LoadIndex index, int fallback)
{
- pict_lock_incoming.lock();
- inform_fallback[index]=fallback;
- pict_lock_incoming.unlock();
+ pict_lock_incoming.lock();
+ inform_fallback[index] = fallback;
+ pict_lock_incoming.unlock();
}
-void OsdVector::PictureReader::receivePicture(VDR_ResponsePacket *vresp)
+void OsdVector::PictureReader::receivePicture(VDR_ResponsePacket* vresp)
{
- pict_lock_incoming.lock();
- pict_incoming.push(vresp);
- pict_lock_incoming.unlock();
- threadSignal();
+ pict_lock_incoming.lock();
+ pict_incoming.push(vresp);
+ pict_lock_incoming.unlock();
+ threadSignal();
}
void OsdVector::PictureReader::addStaticImage(unsigned int id)
{
- pict_lock_incoming.lock();
- pict_incoming_static.push(id);
- invalid_loadindex.erase(((long long) id) << 32LL);
- pict_lock_incoming.unlock();
- threadSignal();
+ pict_lock_incoming.lock();
+ pict_incoming_static.push(id);
+ invalid_loadindex.erase(((long long) id) << 32LL);
+ pict_lock_incoming.unlock();
+ threadSignal();
}
#if WIN32
-// FIXME win pragma
-#pragma warning(disable : 4703)
+ // FIXME win pragma
+ #pragma warning(disable : 4703)
#endif
bool OsdVector::PictureReader::processReceivedPictures()
{
- bool decoded = false;
- bool valid = true;
- pict_lock_incoming.lock();
- if (pict_incoming.size()) {
- VDR_ResponsePacket *vresp=pict_incoming.front();
- pict_incoming.pop();
- std::set<LoadIndex>::iterator setpos = invalid_loadindex.find(vresp->getStreamID());
- if (setpos != invalid_loadindex.end()) {
- valid = false;
- invalid_loadindex.erase(setpos);
- }
- pict_lock_incoming.unlock();
- if (!valid) { // we do not want it anymore skip it;
- delete vresp;
- return true;
- }
-// Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Pictures arrived VDR %x %d %d",
-// vresp->getStreamID(),vresp->getUserDataLength(),vresp->getFlag());
- bool decode = false;
- bool freed = false;
- UCHAR *userdata;
- ULONG length;
-
- if (vresp->getFlag() != 2) {
- userdata=vresp->getUserData();
- length=vresp->getUserDataLength();
- decode = true;
- freed = true;
- } else {
- int fallback=-1;
- pict_lock_incoming.lock();
- if (inform_fallback.find(vresp->getStreamID())!=inform_fallback.end()) {
- fallback=inform_fallback[vresp->getStreamID()];
- }
- pict_lock_incoming.unlock();
- if (fallback >= 0 && ((OsdVector*)Osd::getInstance())->getStaticImageData(fallback, &userdata, &length))
- {
- decode = true;
- freed = false;
- }
-
- }
- if (decode) {
- std::list<PictureDecoder*>::iterator itty=decoders.begin();
- while (itty!=decoders.end()) {
- userdata=(*itty)->decodePicture(vresp->getStreamID(), userdata, length, freed);
- if (!userdata){
- decoded=true;
- break;
- }
- itty++;
- }
- if (!decoded && userdata && freed){
- free(userdata);
- }
- }
- pict_lock_incoming.lock();
- inform_fallback.erase(vresp->getStreamID());
- pict_lock_incoming.unlock();
- //else osd->informPicture(vresp->getStreamID(), 0);
- delete vresp;
- } else if (pict_incoming_static.size()){
- unsigned int static_id = pict_incoming_static.front();
- pict_incoming_static.pop();
- std::set<LoadIndex>::iterator setpos = invalid_loadindex.find(((long long) static_id) << 32LL);
- if (setpos != invalid_loadindex.end()) {
- valid = false;
- invalid_loadindex.erase(setpos);
- }
- pict_lock_incoming.unlock();
- if (!valid) { // we do not want it anymore skip it;
- return true;
- }
-
- UCHAR *userdata;
- ULONG length;
- if (((OsdVector*)Osd::getInstance())->getStaticImageData(static_id, &userdata, &length))
- {
- std::list<PictureDecoder*>::iterator itty=decoders.begin();
- while (itty!=decoders.end()) {
- if (!(*itty)->decodePicture(((long long) static_id) << 32LL,userdata, length, false)){
- decoded=true;
- break;
- }
- itty++;
- }
- }
- } else {
- pict_lock_incoming.unlock();
- }
-
-
- if (pict_incoming.size() || pict_incoming_static.size()) return true;
- return decoded;
+ bool decoded = false;
+ bool valid = true;
+ pict_lock_incoming.lock();
+
+ if (pict_incoming.size())
+ {
+ VDR_ResponsePacket* vresp = pict_incoming.front();
+ pict_incoming.pop();
+ std::set<LoadIndex>::iterator setpos = invalid_loadindex.find(vresp->getStreamID());
+
+ if (setpos != invalid_loadindex.end())
+ {
+ valid = false;
+ invalid_loadindex.erase(setpos);
+ }
+
+ pict_lock_incoming.unlock();
+
+ if (!valid) // we do not want it anymore skip it;
+ {
+ delete vresp;
+ return true;
+ }
+
+ // Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Pictures arrived VDR %x %d %d",
+ // vresp->getStreamID(),vresp->getUserDataLength(),vresp->getFlag());
+ bool decode = false;
+ bool freed = false;
+ UCHAR* userdata;
+ ULONG length;
+
+ if (vresp->getFlag() != 2)
+ {
+ userdata = vresp->getUserData();
+ length = vresp->getUserDataLength();
+ decode = true;
+ freed = true;
+ }
+ else
+ {
+ int fallback = -1;
+ pict_lock_incoming.lock();
+
+ if (inform_fallback.find(vresp->getStreamID()) != inform_fallback.end())
+ {
+ fallback = inform_fallback[vresp->getStreamID()];
+ }
+
+ pict_lock_incoming.unlock();
+
+ if (fallback >= 0 && ((OsdVector*)Osd::getInstance())->getStaticImageData(fallback, &userdata, &length))
+ {
+ decode = true;
+ freed = false;
+ }
+
+ }
+
+ if (decode)
+ {
+ std::list<PictureDecoder*>::iterator itty = decoders.begin();
+
+ while (itty != decoders.end())
+ {
+ userdata = (*itty)->decodePicture(vresp->getStreamID(), userdata, length, freed);
+
+ if (!userdata)
+ {
+ decoded = true;
+ break;
+ }
+
+ itty++;
+ }
+
+ if (!decoded && userdata && freed)
+ {
+ free(userdata);
+ }
+ }
+
+ pict_lock_incoming.lock();
+ inform_fallback.erase(vresp->getStreamID());
+ pict_lock_incoming.unlock();
+ //else osd->informPicture(vresp->getStreamID(), 0);
+ delete vresp;
+ }
+ else if (pict_incoming_static.size())
+ {
+ unsigned int static_id = pict_incoming_static.front();
+ pict_incoming_static.pop();
+ std::set<LoadIndex>::iterator setpos = invalid_loadindex.find(((long long) static_id) << 32LL);
+
+ if (setpos != invalid_loadindex.end())
+ {
+ valid = false;
+ invalid_loadindex.erase(setpos);
+ }
+
+ pict_lock_incoming.unlock();
+
+ if (!valid) // we do not want it anymore skip it;
+ {
+ return true;
+ }
+
+ UCHAR* userdata;
+ ULONG length;
+
+ if (((OsdVector*)Osd::getInstance())->getStaticImageData(static_id, &userdata, &length))
+ {
+ std::list<PictureDecoder*>::iterator itty = decoders.begin();
+
+ while (itty != decoders.end())
+ {
+ if (!(*itty)->decodePicture(((long long) static_id) << 32LL, userdata, length, false))
+ {
+ decoded = true;
+ break;
+ }
+
+ itty++;
+ }
+ }
+ }
+ else
+ {
+ pict_lock_incoming.unlock();
+ }
+
+
+ if (pict_incoming.size() || pict_incoming_static.size()) return true;
+
+ return decoded;
}
SurfaceVector::SurfaceVector(OsdVector* vosd)
{
- osd=vosd;
- commands.reserve(2048);
+ osd = vosd;
+ commands.reserve(2048);
}
SurfaceVector::~SurfaceVector()
{
- osd->removeSurface(this);
- std::vector<SVGCommand>::iterator itty=commands.begin();
- while (itty!=commands.end())
- {
- osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
- ImageIndex ii=(*itty).getImageIndex();
- if (ii) {
- osd->removeImageRef(ii);
- }
- LoadIndex li=(*itty).getLoadIndex();
- if (li) osd->removeLoadIndexRef(li);
- itty++;
- }
+ osd->removeSurface(this);
+ std::vector<SVGCommand>::iterator itty = commands.begin();
+
+ while (itty != commands.end())
+ {
+ osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
+ ImageIndex ii = (*itty).getImageIndex();
+
+ if (ii)
+ {
+ osd->removeImageRef(ii);
+ }
+
+ LoadIndex li = (*itty).getLoadIndex();
+
+ if (li) osd->removeLoadIndexRef(li);
+
+ itty++;
+ }
}
int SurfaceVector::getFontHeight()
{
- return (int)osd->getFontHeight();
+ return (int)osd->getFontHeight();
}
float SurfaceVector::getCharWidth(wchar_t c)
{
- return osd->getCharWidth(c);
+ return osd->getCharWidth(c);
}
-int SurfaceVector::drawText(const char* text, int x, int y, const DrawStyle& c){
- return drawText(text, x, y, 0, c);
+int SurfaceVector::drawText(const char* text, int x, int y, const DrawStyle& c)
+{
+ return drawText(text, x, y, 0, c);
}
int SurfaceVector::drawText(const char* text, int x, int y, int width, const DrawStyle& c)
{
- float shift=0.;
- const char *run=text;
- size_t length=strlen(text);
+ float shift = 0.;
+ const char* run = text;
+ size_t length = strlen(text);
-
- command_mutex.lock();
-
- VectorHandle ref=osd->getStyleRef(c);
- float *charwidtharray=osd->getCharWidthArray();
- int commands_size=commands.size();
- int chars=0;
- commands.resize(commands_size+strlen(text));
+
+ command_mutex.lock();
+
+ VectorHandle ref = osd->getStyleRef(c);
+ float* charwidtharray = osd->getCharWidthArray();
+ int commands_size = commands.size();
+ int chars = 0;
+ commands.resize(commands_size + strlen(text));
#ifndef WIN32
- mbstate_t state;
- wchar_t tempo;
- size_t num_bytes = 1;
- memset((void*)&state,0,sizeof(state));
- num_bytes=mbrtowc(&tempo, run, length, &state);
-
- while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)
- {
- SVGCommand::PaintGlyph(commands[commands_size+chars],x+shift,y,tempo,ref);
- chars++;
-
- float cur_shift=charwidtharray[tempo & 0xFF];
- if (tempo && 0xFFFFFF00) cur_shift=osd->getCharWidth(tempo);
- shift+=cur_shift;
- length -= num_bytes;
- run += num_bytes;
- if (shift>width && width >0) {
- command_mutex.unlock();
- return 1;
- }
- num_bytes=mbrtowc(&tempo, run, length, &state);
- }
+ mbstate_t state;
+ wchar_t tempo;
+ size_t num_bytes = 1;
+ memset((void*)&state, 0, sizeof(state));
+ num_bytes = mbrtowc(&tempo, run, length, &state);
+
+ while (num_bytes != ((size_t) -1) && num_bytes != ((size_t) -2) && length > 0)
+ {
+ SVGCommand::PaintGlyph(commands[commands_size + chars], x + shift, y, tempo, ref);
+ chars++;
+
+ float cur_shift = charwidtharray[tempo & 0xFF];
+
+ if (tempo && 0xFFFFFF00) cur_shift = osd->getCharWidth(tempo);
+
+ shift += cur_shift;
+ length -= num_bytes;
+ run += num_bytes;
+
+ if (shift > width && width > 0)
+ {
+ command_mutex.unlock();
+ return 1;
+ }
+
+ num_bytes = mbrtowc(&tempo, run, length, &state);
+ }
#else
- wchar_t* temptext = new wchar_t[length + 1];
- int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1,
- temptext, length + 1)-1;
- for (int i = 0; i < real_length; i++) {
- SVGCommand::PaintGlyph(commands[commands_size + chars], x + shift, y, temptext[i], ref);
- chars++;
-
- float cur_shift = charwidtharray[temptext[i] & 0xFF];
- if (temptext[i] && 0xFFFFFF00) cur_shift = osd->getCharWidth(temptext[i]);
- shift += cur_shift;
- }
- delete[] temptext;
+ wchar_t* temptext = new wchar_t[length + 1];
+ int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1,
+ temptext, length + 1) - 1;
+
+ for (int i = 0; i < real_length; i++)
+ {
+ SVGCommand::PaintGlyph(commands[commands_size + chars], x + shift, y, temptext[i], ref);
+ chars++;
+
+ float cur_shift = charwidtharray[temptext[i] & 0xFF];
+
+ if (temptext[i] && 0xFFFFFF00) cur_shift = osd->getCharWidth(temptext[i]);
+
+ shift += cur_shift;
+ }
+
+ delete[] temptext;
#endif
- commands.resize(commands_size+chars);
- command_mutex.unlock();
- return 1;
+ commands.resize(commands_size + chars);
+ command_mutex.unlock();
+ return 1;
}
int SurfaceVector::drawTextRJ(const char* text, int x, int y, const DrawStyle& c)
{
- float shift=0.;
- const char *run=text;
- size_t length=strlen(text);
+ float shift = 0.;
+ const char* run = text;
+ size_t length = strlen(text);
#ifndef WIN32
- mbstate_t state;
- wchar_t tempo[1];
- size_t num_bytes = 1;
- memset((void*)&state,0,sizeof(state));
- num_bytes=mbrtowc(tempo, run, length, &state);
- while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)
- {
- shift+=osd->getCharWidth(*tempo);
- length -= num_bytes;
- run += num_bytes;
- num_bytes=mbrtowc(tempo, run, length, &state);
- }
+ mbstate_t state;
+ wchar_t tempo[1];
+ size_t num_bytes = 1;
+ memset((void*)&state, 0, sizeof(state));
+ num_bytes = mbrtowc(tempo, run, length, &state);
+
+ while (num_bytes != ((size_t) -1) && num_bytes != ((size_t) -2) && length > 0)
+ {
+ shift += osd->getCharWidth(*tempo);
+ length -= num_bytes;
+ run += num_bytes;
+ num_bytes = mbrtowc(tempo, run, length, &state);
+ }
+
#else
- wchar_t* temptext=new wchar_t[length+1];
- int real_length=MultiByteToWideChar(CP_UTF8, 0, text, -1,
- temptext, length+ 1)-1;
- for (int i = 0; i < real_length; i++) {
- shift += osd->getCharWidth(temptext[i]);
- }
- delete[] temptext;
+ wchar_t* temptext = new wchar_t[length + 1];
+ int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1,
+ temptext, length + 1) - 1;
+
+ for (int i = 0; i < real_length; i++)
+ {
+ shift += osd->getCharWidth(temptext[i]);
+ }
+
+ delete[] temptext;
#endif
- return drawText(text, (int)(x-shift), y, c);
+ return drawText(text, (int)(x - shift), y, c);
}
int SurfaceVector::drawTextCentre(const char* text, int x, int y, const DrawStyle& c)
{
- float shift=0;
- const char *run=text;
- size_t length=strlen(text);
+ float shift = 0;
+ const char* run = text;
+ size_t length = strlen(text);
#ifndef WIN32
- mbstate_t state;
- wchar_t tempo[1];
- size_t num_bytes = 1;
- memset((void*)&state,0,sizeof(state));
- num_bytes=mbrtowc(tempo, run, length, &state);
- while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)
- {
- shift+=osd->getCharWidth(*tempo);
- length -= num_bytes;
- run += num_bytes;
- num_bytes=mbrtowc(tempo, run, length, &state);
- }
-#else
- wchar_t* temptext = new wchar_t[length + 1];
- int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1,
- temptext, length + 1)-1;
- for (int i = 0; i < real_length; i++) {
- shift += osd->getCharWidth(temptext[i]);
- }
- delete[] temptext;
+ mbstate_t state;
+ wchar_t tempo[1];
+ size_t num_bytes = 1;
+ memset((void*)&state, 0, sizeof(state));
+ num_bytes = mbrtowc(tempo, run, length, &state);
+
+ while (num_bytes != ((size_t) -1) && num_bytes != ((size_t) -2) && length > 0)
+ {
+ shift += osd->getCharWidth(*tempo);
+ length -= num_bytes;
+ run += num_bytes;
+ num_bytes = mbrtowc(tempo, run, length, &state);
+ }
+
+#else
+ wchar_t* temptext = new wchar_t[length + 1];
+ int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1,
+ temptext, length + 1) - 1;
+
+ for (int i = 0; i < real_length; i++)
+ {
+ shift += osd->getCharWidth(temptext[i]);
+ }
+
+ delete[] temptext;
#endif
- return drawText(text, (int)(x-shift/2.), y, c);
+ return drawText(text, (int)(x - shift / 2.), y, c);
}
-void SurfaceVector::drawJpeg(const char *fileName,int x, int y,int *width, int *height)
+void SurfaceVector::drawJpeg(const char* fileName, int x, int y, int* width, int* height)
{
- StaticArtwork index=sa_MAX; // This is for compatibility only
- if (strcmp(fileName,"/vdr.jpg")==0) {
- index=sa_vdrlogo;
- *height=100; // this is faked so that the system does use the old coordinate system
- *width=(int)ceil(190.f*osd->getPixelAspect());
- } else if (strcmp(fileName,"/wallpaperPAL.jpg")==0) {
- index=sa_wallpaper;
- *width=720; // this is faked so that the system does use the old coordinate system
- *height=576;
- }
- if (index!=sa_MAX) {
- TVMediaInfo info;
- info.setStaticArtwork(index);
- drawTVMedia(info,x,y,*width,*height,TopLeft);
- }
+ StaticArtwork index = sa_MAX; // This is for compatibility only
+
+ if (strcmp(fileName, "/vdr.jpg") == 0)
+ {
+ index = sa_vdrlogo;
+ *height = 100; // this is faked so that the system does use the old coordinate system
+ *width = (int)ceil(190.f * osd->getPixelAspect());
+ }
+ else if (strcmp(fileName, "/wallpaperPAL.jpg") == 0)
+ {
+ index = sa_wallpaper;
+ *width = 720; // this is faked so that the system does use the old coordinate system
+ *height = 576;
+ }
+
+ if (index != sa_MAX)
+ {
+ TVMediaInfo info;
+ info.setStaticArtwork(index);
+ drawTVMedia(info, x, y, *width, *height, TopLeft);
+ }
}
/*
}
*/
-void SurfaceVector::drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float width, float height, Corner corner)
+void SurfaceVector::drawTVMedia(TVMediaInfo& tvmedia, float x, float y, float width, float height, Corner corner)
{
- command_mutex.lock();
- ImageIndex image=0;
- LoadIndex load_index=osd->getTVMediaRef(tvmedia,image);
- if (width!=0 && height!=0) {
- removeCommands(x,y,width,height);
- }
- if (image) {
- //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image %d %d", load_index,image);
- commands.push_back(SVGCommand::PaintImage(x,y,width,height,image,0,corner));
- } else {
-
- commands.push_back(SVGCommand::PaintImageLoading(load_index,x,y,width,height,0,corner));
- //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image loading %d %d", load_index,image);
- }
- command_mutex.unlock();
+ command_mutex.lock();
+ ImageIndex image = 0;
+ LoadIndex load_index = osd->getTVMediaRef(tvmedia, image);
+
+ if (width != 0 && height != 0)
+ {
+ removeCommands(x, y, width, height);
+ }
+
+ if (image)
+ {
+ //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image %d %d", load_index,image);
+ commands.push_back(SVGCommand::PaintImage(x, y, width, height, image, 0, corner));
+ }
+ else
+ {
+
+ commands.push_back(SVGCommand::PaintImageLoading(load_index, x, y, width, height, 0, corner));
+ //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image loading %d %d", load_index,image);
+ }
+
+ command_mutex.unlock();
}
void SurfaceVector::drawClippingRectangle(float x, float y, float w, float h)
{
- command_mutex.lock();
- commands.push_back(SVGCommand::PaintClipping((float)x,(float)y,(float)w,(float)h));
- command_mutex.unlock();
+ command_mutex.lock();
+ commands.push_back(SVGCommand::PaintClipping((float)x, (float)y, (float)w, (float)h));
+ command_mutex.unlock();
}
int SurfaceVector::create(UINT width, UINT height)
{
- sheight=height;
- swidth=width;
- return 1;
+ sheight = height;
+ swidth = width;
+ return 1;
}
void SurfaceVector::display()
{
- //nothing this is really mvp specific
+ //nothing this is really mvp specific
}
int SurfaceVector::fillblt(int x, int y, int width, int height, const DrawStyle& c)
{
- command_mutex.lock();
- removeCommands(x,y,width,height); // remove commands below the box
- VectorHandle ref=osd->getStyleRef(c);
- commands.push_back(SVGCommand::PaintPath(x,y,width,height,PIRectangle,ref));
- command_mutex.unlock();
- return 1;
+ command_mutex.lock();
+ removeCommands(x, y, width, height); // remove commands below the box
+ VectorHandle ref = osd->getStyleRef(c);
+ commands.push_back(SVGCommand::PaintPath(x, y, width, height, PIRectangle, ref));
+ command_mutex.unlock();
+ return 1;
}
void SurfaceVector::drawHorzLine(int x1, int x2, int y, const DrawStyle& c)
{
- command_mutex.lock();
- VectorHandle ref = osd->getStyleRef(c);
- commands.push_back(SVGCommand::PaintPath(x1,y,x2-x1,1,PIHorzLine,ref));
- command_mutex.unlock();
+ command_mutex.lock();
+ VectorHandle ref = osd->getStyleRef(c);
+ commands.push_back(SVGCommand::PaintPath(x1, y, x2 - x1, 1, PIHorzLine, ref));
+ command_mutex.unlock();
}
-void SurfaceVector::drawVertLine(int x, int y1, int y2, const DrawStyle& c){
- command_mutex.lock();
- VectorHandle ref = osd->getStyleRef(c);
- commands.push_back(SVGCommand::PaintPath(x,y1,1,y2-y1,PIVertLine,ref));
- command_mutex.unlock();
+void SurfaceVector::drawVertLine(int x, int y1, int y2, const DrawStyle& c)
+{
+ command_mutex.lock();
+ VectorHandle ref = osd->getStyleRef(c);
+ commands.push_back(SVGCommand::PaintPath(x, y1, 1, y2 - y1, PIVertLine, ref));
+ command_mutex.unlock();
}
-void SurfaceVector::drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegion & region)
+void SurfaceVector::drawBitmap(int x, int y, const Bitmap& bm, const DisplayRegion& region)
{
- //this is complicated
- command_mutex.lock();
-/*
- unsigned int * data=(unsigned int*)malloc(sizeof(unsigned int)*bm.getWidth()*bm.getHeight());
- for (UINT j = 0; j < bm.getHeight(); ++j){
- for (UINT i = 0; i < bm.getWidth(); ++i)
- {
- data[i+j*bm.getHeight()]=bm.getColour(i,j);
- }
- }*/
- ImageIndex image=osd->getImagePalette(bm.getWidth(),bm.getHeight(),&(bm.rawData()[0]),
- (const unsigned int*)&bm.palette.getColourVector()[0]); // data is freed by the OSD
- //free(data);
- float tx=x+region.windowx;
- float ty=y+region.windowy;
- float th=bm.getHeight();
- float tw=bm.getWidth();
-
- float scalex=720.f/((float) (region.framewidth+1));
- float scaley=576.f/((float) (region.frameheight+1));
- tx*=scalex;
- ty*=scaley;
- tw*=scalex;
- th*=scaley;
- SVGCommand temp=SVGCommand::PaintImage(tx,ty,tw,th,image,0);
- removeCommands(tx,ty,tw,th);
- commands.push_back(temp);
- command_mutex.unlock();
+ //this is complicated
+ command_mutex.lock();
+ /*
+ unsigned int * data=(unsigned int*)malloc(sizeof(unsigned int)*bm.getWidth()*bm.getHeight());
+ for (UINT j = 0; j < bm.getHeight(); ++j){
+ for (UINT i = 0; i < bm.getWidth(); ++i)
+ {
+ data[i+j*bm.getHeight()]=bm.getColour(i,j);
+ }
+ }*/
+ ImageIndex image = osd->getImagePalette(bm.getWidth(), bm.getHeight(), &(bm.rawData()[0]),
+ (const unsigned int*)&bm.palette.getColourVector()[0]); // data is freed by the OSD
+ //free(data);
+ float tx = x + region.windowx;
+ float ty = y + region.windowy;
+ float th = bm.getHeight();
+ float tw = bm.getWidth();
+
+ float scalex = 720.f / ((float) (region.framewidth + 1));
+ float scaley = 576.f / ((float) (region.frameheight + 1));
+ tx *= scalex;
+ ty *= scaley;
+ tw *= scalex;
+ th *= scaley;
+ SVGCommand temp = SVGCommand::PaintImage(tx, ty, tw, th, image, 0);
+ removeCommands(tx, ty, tw, th);
+ commands.push_back(temp);
+ command_mutex.unlock();
}
-void SurfaceVector::drawPoint(int x, int y, DrawStyle& c, bool fastdraw){
- if (!fastdraw) command_mutex.lock();
- VectorHandle ref = osd->getStyleRef(c);
- commands.push_back(SVGCommand::PaintPath(x,y,1,1,PIPoint,ref));
- if (!fastdraw) command_mutex.unlock();
+void SurfaceVector::drawPoint(int x, int y, DrawStyle& c, bool fastdraw)
+{
+ if (!fastdraw) command_mutex.lock();
+
+ VectorHandle ref = osd->getStyleRef(c);
+ commands.push_back(SVGCommand::PaintPath(x, y, 1, 1, PIPoint, ref));
+
+ if (!fastdraw) command_mutex.unlock();
}
-void SurfaceVector::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height,unsigned int width, DrawStyle& nextColour)
+void SurfaceVector::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height, unsigned int width, DrawStyle& nextColour)
{
- command_mutex.lock();
- ImageIndex image=osd->getMonoBitmapRef(base,width,height);
- VectorHandle ref = osd->getStyleRef(nextColour);
- removeCommands(dx,dy,width,height);
- commands.push_back(SVGCommand::PaintImage(dx,dy,height,width,image,ref));
- command_mutex.unlock();
+ command_mutex.lock();
+ ImageIndex image = osd->getMonoBitmapRef(base, width, height);
+ VectorHandle ref = osd->getStyleRef(nextColour);
+ removeCommands(dx, dy, width, height);
+ commands.push_back(SVGCommand::PaintImage(dx, dy, height, width, image, ref));
+ command_mutex.unlock();
}
-int SurfaceVector::removeCommands(float x,float y,float width,float height)
+int SurfaceVector::removeCommands(float x, float y, float width, float height)
{
- // we iterate through all old commands in order to remove commands hidden by this rectangle
- std::vector<SVGCommand>::iterator itty=commands.begin();
- std::vector<SVGCommand>::iterator remstart;
- bool remove=false;
- float cx, cy, cw, ch;
- cx = cy = 0.f;
- cw = swidth;
- ch = sheight;
- bool clipping_erases = false;
- while (itty!=commands.end())
- {
- if ((clipping_erases // test if clipping helps
- || (*itty).Test(x,y,width,height) )
- && (*itty).instr != DrawClipping) {
- //Log::getInstance()->log("OSD", Log::DEBUG, "Remove command %d %g %g %g %g %d %d",(*itty).instr,
- //(*itty).x,(*itty).y,(*itty).w,(*itty).h,(*itty).reference,(*itty).target.image);
- osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
- ImageIndex ii=(*itty).getImageIndex();
- if (ii) osd->removeImageRef(ii);
- LoadIndex li=(*itty).getLoadIndex();
- if (li) osd->removeLoadIndexRef(li);
- if (!remove) {
- remstart=itty;
- remove=true;
- }
- } else {
- if ((*itty).instr == DrawClipping) {
- if ((*itty).w == 0.f && (*itty).h == 0.f) {
- cx = cy = 0.f;
- cw = swidth;
- ch = sheight;
-
- } else {
- cx = (*itty).x;
- cy = (*itty).y;
- cw = (*itty).w;
- ch = (*itty).h;
- }
- clipping_erases = (cx >= x) && (cy >= y) && ((cx + cw) <= (x + width)) && ((cy + ch) <= (y + height));
- }
- if (remove) {
- itty=commands.erase(remstart,itty);
- remove=false;
- }
- }
- itty++;
- }
- if (remove) {
- itty=commands.erase(remstart,itty);
- }
- return 1;
+ // we iterate through all old commands in order to remove commands hidden by this rectangle
+ std::vector<SVGCommand>::iterator itty = commands.begin();
+ std::vector<SVGCommand>::iterator remstart;
+ bool remove = false;
+ float cx, cy, cw, ch;
+ cx = cy = 0.f;
+ cw = swidth;
+ ch = sheight;
+ bool clipping_erases = false;
+
+ while (itty != commands.end())
+ {
+ if ((clipping_erases // test if clipping helps
+ || (*itty).Test(x, y, width, height) )
+ && (*itty).instr != DrawClipping)
+ {
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Remove command %d %g %g %g %g %d %d",(*itty).instr,
+ //(*itty).x,(*itty).y,(*itty).w,(*itty).h,(*itty).reference,(*itty).target.image);
+ osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
+ ImageIndex ii = (*itty).getImageIndex();
+
+ if (ii) osd->removeImageRef(ii);
+
+ LoadIndex li = (*itty).getLoadIndex();
+
+ if (li) osd->removeLoadIndexRef(li);
+
+ if (!remove)
+ {
+ remstart = itty;
+ remove = true;
+ }
+ }
+ else
+ {
+ if ((*itty).instr == DrawClipping)
+ {
+ if ((*itty).w == 0.f && (*itty).h == 0.f)
+ {
+ cx = cy = 0.f;
+ cw = swidth;
+ ch = sheight;
+
+ }
+ else
+ {
+ cx = (*itty).x;
+ cy = (*itty).y;
+ cw = (*itty).w;
+ ch = (*itty).h;
+ }
+
+ clipping_erases = (cx >= x) && (cy >= y) && ((cx + cw) <= (x + width)) && ((cy + ch) <= (y + height));
+ }
+
+ if (remove)
+ {
+ itty = commands.erase(remstart, itty);
+ remove = false;
+ }
+ }
+
+ itty++;
+ }
+
+ if (remove)
+ {
+ itty = commands.erase(remstart, itty);
+ }
+
+ return 1;
}
int SurfaceVector::updateToScreen(int sx, int sy, int w, int h, int dx, int dy)
{
- // ok this method really works in a pixel oriented way
- command_mutex.lock();
- osd->updateOrAddSurface(this,dx-sx,dy-sy,swidth,sheight,commands);
- command_mutex.unlock();
- return 1;
+ // ok this method really works in a pixel oriented way
+ command_mutex.lock();
+ osd->updateOrAddSurface(this, dx - sx, dy - sy, swidth, sheight, commands);
+ command_mutex.unlock();
+ return 1;
}
/* This is for systems which need a locking of the drawing surface to speed up drawing */
-void SurfaceVector::startFastDraw() {
- command_mutex.lock();
+void SurfaceVector::startFastDraw()
+{
+ command_mutex.lock();
}
-void SurfaceVector::endFastDraw() {
- command_mutex.unlock();
+void SurfaceVector::endFastDraw()
+{
+ command_mutex.unlock();
}
-void SurfaceVector::drawTTChar(int ox, int oy,int x, int y, cTeletextChar c)
+void SurfaceVector::drawTTChar(int ox, int oy, int x, int y, cTeletextChar c)
{
- command_mutex.lock();
- std::vector<SVGCommand>::iterator itty=commands.begin();
- while (itty!=commands.end())
- {
- if ((*itty).TTTest(ox,oy,x,y) ) {
- itty=commands.erase(itty);
- break;
- } else {
- itty++;
- }
- }
- commands.push_back(SVGCommand::PaintTTchar(ox,oy,x,y,c.getInternal()));
- command_mutex.unlock();
+ command_mutex.lock();
+ std::vector<SVGCommand>::iterator itty = commands.begin();
+
+ while (itty != commands.end())
+ {
+ if ((*itty).TTTest(ox, oy, x, y) )
+ {
+ itty = commands.erase(itty);
+ break;
+ }
+ else
+ {
+ itty++;
+ }
+ }
+
+ commands.push_back(SVGCommand::PaintTTchar(ox, oy, x, y, c.getInternal()));
+ command_mutex.unlock();
}