From a9b5b7164e4664104fbdd9f7344e88c8f044df57 Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Sat, 6 Oct 2012 19:02:04 +0200 Subject: [PATCH] Drawing routines for teletext for vector based osd --- osdopenvg.cc | 100 +++++++++++++++++++++++++++++++++++----- osdopenvg.h | 5 ++ osdvector.h | 4 ++ surface.h | 3 +- surfacevector.cc | 10 ++++ teletextdecodervbiebu.h | 3 ++ videoomx.cc | 2 +- 7 files changed, 114 insertions(+), 13 deletions(-) diff --git a/osdopenvg.cc b/osdopenvg.cc index 46bc4a1..955f78b 100644 --- a/osdopenvg.cc +++ b/osdopenvg.cc @@ -22,10 +22,12 @@ #include "osdopenvg.h" #include "mtd.h" #include "videoomx.h" +#include "surface.h" #include #include "message.h" #include "command.h" +#include "teletxt/txtfont.h" #include #include @@ -210,19 +212,15 @@ int OsdOpenVG::init(void* device) 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 (!loadFont()) { return 0; } + vgttfont=vgCreateFont(0); + vgttpaint=vgCreatePaint(); + vgSetParameteri( vgttpaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); + vgSetColor(vgttpaint,0xffffffff); eglSwapInterval(egl_display, 1 ); @@ -313,6 +311,8 @@ int OsdOpenVG::shutdown() FT_Done_Face(ft_face); vgDestroyFont(vgfont); + vgDestroyFont(vgttfont); + vgDestroyPaint(vgttpaint); destroyPaths(); vgClear(0,0,BACKBUFFER_WIDTH,BACKBUFFER_HEIGHT); eglSwapBuffers(egl_display, egl_surface); @@ -419,6 +419,42 @@ float OsdOpenVG::getCharWidth(wchar_t 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 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; + } + + 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, glyphOrigin, escapement); + vgDestroyImage(handle); + tt_font_chars[glyph_index]=1; + + return glyph_index; +} + int OsdOpenVG::loadFont() { int error=FT_Init_FreeType(&ft_library); @@ -646,9 +682,6 @@ void OsdOpenVG::executeDrawCommand(SVGCommand & command) vgSetPaint((VGPaint) command.reference,VG_FILL_PATH); vgSetPaint((VGPaint) command.reference,VG_STROKE_PATH); vgTranslate(command.x,command.y); - // vgLoadIdentity(); - // vgTranslate(500.,500.); - //vgScale(18.f,18.f); VGfloat gori[]={0.,0.}; vgSetfv(VG_GLYPH_ORIGIN,2,gori); @@ -661,6 +694,51 @@ void OsdOpenVG::executeDrawCommand(SVGCommand & command) 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.95f*1.4f,command.y+command.h*19.95f); + 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; } diff --git a/osdopenvg.h b/osdopenvg.h index 3d4e5f4..3769d73 100644 --- a/osdopenvg.h +++ b/osdopenvg.h @@ -118,9 +118,14 @@ protected: FT_Library ft_library; FT_Face ft_face; VGFont vgfont; + VGFont vgttfont; + VGPaint vgttpaint; int loadFont(); map font_exp_x; + unsigned int loadTTchar(cTeletextChar c); + map tt_font_chars; + void threadMethod(); diff --git a/osdvector.h b/osdvector.h index 13b49c4..963bbf2 100644 --- a/osdvector.h +++ b/osdvector.h @@ -92,6 +92,10 @@ public: { return (x>=tx) && (y>=ty) && ((x+w)<=(tx+tw)) && ((y+h)<=(ty+th)); } + bool TTTest(float tox,float toy,float tx, float ty) + { + return (x==tox) && (toy==y) && (w==tx) && (h==ty); + } unsigned int getRef(){return reference;}; ImageIndex getImageIndex() { if (instr!=DrawImage) return 0; diff --git a/surface.h b/surface.h index 5777d9c..d92994b 100644 --- a/surface.h +++ b/surface.h @@ -85,6 +85,7 @@ class Surface virtual void drawTTChar(int ox, int oy,int x, int y, cTeletextChar c); + static Colour enumTeletextColorToCoulour(enumTeletextColor ttcol); @@ -97,7 +98,7 @@ class Surface protected: static Surface* screen; static osd_font_t* font; - Colour enumTeletextColorToCoulour(enumTeletextColor ttcol); + virtual void drawPixel(int x, int y, unsigned int c, bool fastdraw=false)=0; // deprecated preparation for vector based drawing, only allowed to be called inside implementation virtual void drawPixel(int x, int y, Colour& c, bool fastdraw=false)=0; // deprecated preparation for vector based drawing, only allowed to be called inside implementation diff --git a/surfacevector.cc b/surfacevector.cc index 6637aa4..9bec0aa 100644 --- a/surfacevector.cc +++ b/surfacevector.cc @@ -273,6 +273,16 @@ void SurfaceVector::endFastDraw() { void SurfaceVector::drawTTChar(int ox, int oy,int x, int y, cTeletextChar c) { command_mutex.Lock(); + list::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(ox,oy,x,y,c.getInternal())); command_mutex.Unlock(); } diff --git a/teletextdecodervbiebu.h b/teletextdecodervbiebu.h index 124ba83..54a1d86 100644 --- a/teletextdecodervbiebu.h +++ b/teletextdecodervbiebu.h @@ -234,6 +234,9 @@ public: { c=(Blink)?(c|BLINK):(c&~BLINK); } inline cTeletextChar ToBlink(bool Blink) { return cTeletextChar((Blink)?(c|BLINK):(c&~BLINK)); } + inline unsigned int getGlyphIndex() { + return c & (CHAR | CHARSET | DBLHEIGHT | DBLWIDTH); + }; inline void setInternal(unsigned int cc) {c=cc;}; inline unsigned int getInternal() {return c;}; diff --git a/videoomx.cc b/videoomx.cc index 3a219e9..50da679 100644 --- a/videoomx.cc +++ b/videoomx.cc @@ -799,7 +799,7 @@ int VideoOMX::AllocateCodecsOMX() Log::getInstance()->log("Video", Log::NOTICE, "Allocate Codecs OMX"); //Clock, move later to audio including events - if (deinterlace!=0 && demux->getHorizontalSize()<=720) { //only deinterlace SD material + if (deinterlace!=0 && (demux->getHorizontalSize()<=720 /*|| demux->getHorizontalSize()==1920*/)) { //only deinterlace SD material dodeint=true; deint_first_frame=true; -- 2.39.2