2 Copyright 2012 Marten Richter
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "surfacevector.h"
23 #include "staticartwork.h"
28 SurfaceVector::SurfaceVector(OsdVector* vosd)
32 commands.reserve(2048);
35 SurfaceVector::~SurfaceVector()
37 osd->removeSurface(this);
38 vector<SVGCommand>::iterator itty=commands.begin();
39 while (itty!=commands.end())
41 osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
42 ImageIndex ii=(*itty).getImageIndex();
44 osd->removeImageRef(ii);
46 LoadIndex li=(*itty).getLoadIndex();
47 if (li) osd->removeLoadIndexRef(li);
53 int SurfaceVector::getFontHeight()
55 return osd->getFontHeight();
58 float SurfaceVector::getCharWidth(wchar_t c)
60 return osd->getCharWidth(c);
64 int SurfaceVector::drawText(const char* text, int x, int y, const DrawStyle& c){
65 return drawText(text, x, y, 0, c);
68 int SurfaceVector::drawText(const char* text, int x, int y, int width, const DrawStyle& c)
75 size_t length=strlen(text);
76 memset((void*)&state,0,sizeof(state));
79 num_bytes=mbrtowc(&tempo, run, length, &state);
80 unsigned int ref=osd->getStyleRef(c);
81 float *charwidtharray=osd->getCharWidthArray();
83 int commands_size=commands.size();
85 commands.resize(commands_size+strlen(text));
87 while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)
89 SVGCommand::PaintGlyph(commands[commands_size+chars],x+shift,y,tempo,ref);
92 float cur_shift=charwidtharray[tempo & 0xFF];
93 if (tempo && 0xFFFFFF00) cur_shift=osd->getCharWidth(tempo);
97 if (shift>width && width >0) {
98 command_mutex.Unlock();
101 num_bytes=mbrtowc(&tempo, run, length, &state);
103 commands.resize(commands_size+chars);
104 command_mutex.Unlock();
108 int SurfaceVector::drawTextRJ(const char* text, int x, int y, const DrawStyle& c)
111 const char *run=text;
115 size_t length=strlen(text);
116 memset((void*)&state,0,sizeof(state));
118 num_bytes=mbrtowc(tempo, run, length, &state);
119 while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)
121 shift+=osd->getCharWidth(*tempo);
124 num_bytes=mbrtowc(tempo, run, length, &state);
126 return drawText(text, x-shift, y, c);
129 int SurfaceVector::drawTextCentre(const char* text, int x, int y, const DrawStyle& c)
132 const char *run=text;
136 size_t length=strlen(text);
137 memset((void*)&state,0,sizeof(state));
139 num_bytes=mbrtowc(tempo, run, length, &state);
140 while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)
142 shift+=osd->getCharWidth(*tempo);
145 num_bytes=mbrtowc(tempo, run, length, &state);
147 return drawText(text, x-shift/2., y, c);
150 void SurfaceVector::drawJpeg(const char *fileName,int x, int y,int *width, int *height)
152 StaticArtwork index=sa_MAX; // This is for compatibility only
153 if (strcmp(fileName,"/vdr.jpg")==0) {
155 *height=100; // this is faked so that the system does use the old coordinate system
156 *width=ceil(190.f*osd->getPixelAspect());
157 } else if (strcmp(fileName,"/wallpaperPAL.jpg")==0) {
159 *width=720; // this is faked so that the system does use the old coordinate system
164 info.setStaticArtwork(index);
165 drawTVMedia(info,x,y,*width,*height,TopLeft);
170 void SurfaceVector::drawJpeg(const char *fileName,int x, int y,int *width, int *height)
172 command_mutex.Lock();
173 ImageIndex image=osd->getJpegRef(fileName,width,height);
174 commands.push_back(SVGCommand::PaintImage(x,y,*width,*height,image,0));
175 command_mutex.Unlock();
179 void SurfaceVector::drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float width, float height, Corner corner)
181 command_mutex.Lock();
183 LoadIndex load_index=osd->getTVMediaRef(tvmedia,image);
184 if (width!=0 && height!=0) {
185 removeCommands(x,y,width,height);
188 //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image %d %d", load_index,image);
189 commands.push_back(SVGCommand::PaintImage(x,y,width,height,image,0,corner));
192 commands.push_back(SVGCommand::PaintImageLoading(load_index,x,y,width,height,0,corner));
193 //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image loading %d %d", load_index,image);
195 command_mutex.Unlock();
198 void SurfaceVector::drawClippingRectangle(float x, float y, float w, float h)
200 command_mutex.Lock();
201 commands.push_back(SVGCommand::PaintClipping((float)x,(float)y,(float)w,(float)h));
202 command_mutex.Unlock();
205 int SurfaceVector::create(UINT width, UINT height)
211 void SurfaceVector::display()
213 //nothing this is really mvp specific
216 int SurfaceVector::fillblt(int x, int y, int width, int height, const DrawStyle& c)
218 command_mutex.Lock();
219 removeCommands(x,y,width,height); // remove commands below the box
220 unsigned int ref=osd->getStyleRef(c);
221 commands.push_back(SVGCommand::PaintPath(x,y,width,height,PIRectangle,ref));
222 command_mutex.Unlock();
226 void SurfaceVector::drawHorzLine(int x1, int x2, int y, const DrawStyle& c)
228 command_mutex.Lock();
229 unsigned int ref=osd->getStyleRef(c);
230 commands.push_back(SVGCommand::PaintPath(x1,y,x2-x1,1,PIHorzLine,ref));
231 command_mutex.Unlock();
234 void SurfaceVector::drawVertLine(int x, int y1, int y2, const DrawStyle& c){
235 command_mutex.Lock();
236 unsigned int ref=osd->getStyleRef(c);
237 commands.push_back(SVGCommand::PaintPath(x,y1,1,y2-y1,PIVertLine,ref));
238 command_mutex.Unlock();
241 void SurfaceVector::drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegion & region)
243 //this is complicated
244 command_mutex.Lock();
246 unsigned int * data=(unsigned int*)malloc(sizeof(unsigned int)*bm.getWidth()*bm.getHeight());
247 for (UINT j = 0; j < bm.getHeight(); ++j){
248 for (UINT i = 0; i < bm.getWidth(); ++i)
250 data[i+j*bm.getHeight()]=bm.getColour(i,j);
253 ImageIndex image=osd->getImagePalette(bm.getWidth(),bm.getHeight(),&(bm.rawData()[0]),
254 (const unsigned int*)&bm.palette.getColourVector()[0]); // data is freed by the OSD
256 float tx=x+region.windowx;
257 float ty=y+region.windowy;
258 float th=bm.getHeight();
259 float tw=bm.getWidth();
261 float scalex=720.f/((float) (region.framewidth+1));
262 float scaley=576.f/((float) (region.frameheight+1));
267 SVGCommand temp=SVGCommand::PaintImage(tx,ty,tw,th,image,0);
268 removeCommands(tx,ty,tw,th);
269 commands.push_back(temp);
270 command_mutex.Unlock();
273 void SurfaceVector::drawPoint(int x, int y, DrawStyle& c, bool fastdraw){
274 if (!fastdraw) command_mutex.Lock();
275 unsigned int ref=osd->getStyleRef(c);
276 commands.push_back(SVGCommand::PaintPath(x,y,1,1,PIPoint,ref));
277 if (!fastdraw) command_mutex.Unlock();
279 void SurfaceVector::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height,unsigned int width, DrawStyle& nextColour)
281 command_mutex.Lock();
282 ImageIndex image=osd->getMonoBitmapRef(base,width,height);
283 unsigned int ref=osd->getStyleRef(nextColour);
284 removeCommands(dx,dy,width,height);
285 commands.push_back(SVGCommand::PaintImage(dx,dy,height,width,image,ref));
286 command_mutex.Unlock();
290 int SurfaceVector::removeCommands(float x,float y,float width,float height)
292 // we iterate through all old commands in order to remove commands hidden by this rectangle
293 vector<SVGCommand>::iterator itty=commands.begin();
294 vector<SVGCommand>::iterator remstart;
296 while (itty!=commands.end())
298 if ((*itty).Test(x,y,width,height) && (*itty).instr != DrawClipping) {
299 //Log::getInstance()->log("OSD", Log::DEBUG, "Remove command %d %g %g %g %g %d %d",(*itty).instr,
300 //(*itty).x,(*itty).y,(*itty).w,(*itty).h,(*itty).reference,(*itty).target.image);
301 osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
302 ImageIndex ii=(*itty).getImageIndex();
303 if (ii) osd->removeImageRef(ii);
304 LoadIndex li=(*itty).getLoadIndex();
305 if (li) osd->removeLoadIndexRef(li);
312 itty=commands.erase(remstart,itty);
319 itty=commands.erase(remstart,itty);
325 int SurfaceVector::updateToScreen(int sx, int sy, int w, int h, int dx, int dy)
327 // ok this method really works in a pixel oriented way
328 command_mutex.Lock();
329 osd->updateOrAddSurface(this,dx-sx,dy-sy,swidth,sheight,commands);
330 command_mutex.Unlock();
335 /* This is for systems which need a locking of the drawing surface to speed up drawing */
336 void SurfaceVector::startFastDraw() {
337 command_mutex.Lock();
339 void SurfaceVector::endFastDraw() {
340 command_mutex.Unlock();
344 void SurfaceVector::drawTTChar(int ox, int oy,int x, int y, cTeletextChar c)
346 command_mutex.Lock();
347 vector<SVGCommand>::iterator itty=commands.begin();
348 while (itty!=commands.end())
350 if ((*itty).TTTest(ox,oy,x,y) ) {
351 itty=commands.erase(itty);
357 commands.push_back(SVGCommand::PaintTTchar(ox,oy,x,y,c.getInternal()));
358 command_mutex.Unlock();