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, see <https://www.gnu.org/licenses/>.
24 #include "staticartwork.h"
25 #include "surfacevector.h"
27 SurfaceVector::SurfaceVector(OsdVector* vosd)
31 commands.reserve(2048);
34 SurfaceVector::~SurfaceVector()
36 osd->removeSurface(this);
37 std::vector<SVGCommand>::iterator itty=commands.begin();
38 while (itty!=commands.end())
40 osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
41 ImageIndex ii=(*itty).getImageIndex();
43 osd->removeImageRef(ii);
45 LoadIndex li=(*itty).getLoadIndex();
46 if (li) osd->removeLoadIndexRef(li);
52 int SurfaceVector::getFontHeight()
54 return (int)osd->getFontHeight();
57 float SurfaceVector::getCharWidth(wchar_t c)
59 return osd->getCharWidth(c);
63 int SurfaceVector::drawText(const char* text, int x, int y, const DrawStyle& c){
64 return drawText(text, x, y, 0, c);
67 int SurfaceVector::drawText(const char* text, int x, int y, int width, const DrawStyle& c)
71 size_t length=strlen(text);
76 VectorHandle ref=osd->getStyleRef(c);
77 float *charwidtharray=osd->getCharWidthArray();
78 int commands_size=commands.size();
80 commands.resize(commands_size+strlen(text));
85 memset((void*)&state,0,sizeof(state));
86 num_bytes=mbrtowc(&tempo, run, length, &state);
88 while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)
90 SVGCommand::PaintGlyph(commands[commands_size+chars],x+shift,y,tempo,ref);
93 float cur_shift=charwidtharray[tempo & 0xFF];
94 if (tempo && 0xFFFFFF00) cur_shift=osd->getCharWidth(tempo);
98 if (shift>width && width >0) {
99 command_mutex.unlock();
102 num_bytes=mbrtowc(&tempo, run, length, &state);
106 wchar_t* temptext = new wchar_t[length + 1];
107 int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1,
108 temptext, length + 1)-1;
109 for (int i = 0; i < real_length; i++) {
110 SVGCommand::PaintGlyph(commands[commands_size + chars], x + shift, y, temptext[i], ref);
113 float cur_shift = charwidtharray[temptext[i] & 0xFF];
114 if (temptext[i] && 0xFFFFFF00) cur_shift = osd->getCharWidth(temptext[i]);
120 commands.resize(commands_size+chars);
121 command_mutex.unlock();
125 int SurfaceVector::drawTextRJ(const char* text, int x, int y, const DrawStyle& c)
128 const char *run=text;
129 size_t length=strlen(text);
134 size_t num_bytes = 1;
135 memset((void*)&state,0,sizeof(state));
136 num_bytes=mbrtowc(tempo, run, length, &state);
137 while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)
139 shift+=osd->getCharWidth(*tempo);
142 num_bytes=mbrtowc(tempo, run, length, &state);
145 wchar_t* temptext=new wchar_t[length+1];
146 int real_length=MultiByteToWideChar(CP_UTF8, 0, text, -1,
147 temptext, length+ 1)-1;
148 for (int i = 0; i < real_length; i++) {
149 shift += osd->getCharWidth(temptext[i]);
153 return drawText(text, (int)(x-shift), y, c);
156 int SurfaceVector::drawTextCentre(const char* text, int x, int y, const DrawStyle& c)
159 const char *run=text;
160 size_t length=strlen(text);
165 size_t num_bytes = 1;
166 memset((void*)&state,0,sizeof(state));
167 num_bytes=mbrtowc(tempo, run, length, &state);
168 while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)
170 shift+=osd->getCharWidth(*tempo);
173 num_bytes=mbrtowc(tempo, run, length, &state);
176 wchar_t* temptext = new wchar_t[length + 1];
177 int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1,
178 temptext, length + 1)-1;
179 for (int i = 0; i < real_length; i++) {
180 shift += osd->getCharWidth(temptext[i]);
185 return drawText(text, (int)(x-shift/2.), y, c);
188 void SurfaceVector::drawJpeg(const char *fileName,int x, int y,int *width, int *height)
190 StaticArtwork index=sa_MAX; // This is for compatibility only
191 if (strcmp(fileName,"/vdr.jpg")==0) {
193 *height=100; // this is faked so that the system does use the old coordinate system
194 *width=(int)ceil(190.f*osd->getPixelAspect());
195 } else if (strcmp(fileName,"/wallpaperPAL.jpg")==0) {
197 *width=720; // this is faked so that the system does use the old coordinate system
202 info.setStaticArtwork(index);
203 drawTVMedia(info,x,y,*width,*height,TopLeft);
208 void SurfaceVector::drawJpeg(const char *fileName,int x, int y,int *width, int *height)
210 command_mutex.lock();
211 ImageIndex image=osd->getJpegRef(fileName,width,height);
212 commands.push_back(SVGCommand::PaintImage(x,y,*width,*height,image,0));
213 command_mutex.unlock();
217 void SurfaceVector::drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float width, float height, Corner corner)
219 command_mutex.lock();
221 LoadIndex load_index=osd->getTVMediaRef(tvmedia,image);
222 if (width!=0 && height!=0) {
223 removeCommands(x,y,width,height);
226 //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image %d %d", load_index,image);
227 commands.push_back(SVGCommand::PaintImage(x,y,width,height,image,0,corner));
230 commands.push_back(SVGCommand::PaintImageLoading(load_index,x,y,width,height,0,corner));
231 //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image loading %d %d", load_index,image);
233 command_mutex.unlock();
236 void SurfaceVector::drawClippingRectangle(float x, float y, float w, float h)
238 command_mutex.lock();
239 commands.push_back(SVGCommand::PaintClipping((float)x,(float)y,(float)w,(float)h));
240 command_mutex.unlock();
243 int SurfaceVector::create(UINT width, UINT height)
249 void SurfaceVector::display()
251 //nothing this is really mvp specific
254 int SurfaceVector::fillblt(int x, int y, int width, int height, const DrawStyle& c)
256 command_mutex.lock();
257 removeCommands(x,y,width,height); // remove commands below the box
258 VectorHandle ref=osd->getStyleRef(c);
259 commands.push_back(SVGCommand::PaintPath(x,y,width,height,PIRectangle,ref));
260 command_mutex.unlock();
264 void SurfaceVector::drawHorzLine(int x1, int x2, int y, const DrawStyle& c)
266 command_mutex.lock();
267 VectorHandle ref = osd->getStyleRef(c);
268 commands.push_back(SVGCommand::PaintPath(x1,y,x2-x1,1,PIHorzLine,ref));
269 command_mutex.unlock();
272 void SurfaceVector::drawVertLine(int x, int y1, int y2, const DrawStyle& c){
273 command_mutex.lock();
274 VectorHandle ref = osd->getStyleRef(c);
275 commands.push_back(SVGCommand::PaintPath(x,y1,1,y2-y1,PIVertLine,ref));
276 command_mutex.unlock();
279 void SurfaceVector::drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegion & region)
281 //this is complicated
282 command_mutex.lock();
284 unsigned int * data=(unsigned int*)malloc(sizeof(unsigned int)*bm.getWidth()*bm.getHeight());
285 for (UINT j = 0; j < bm.getHeight(); ++j){
286 for (UINT i = 0; i < bm.getWidth(); ++i)
288 data[i+j*bm.getHeight()]=bm.getColour(i,j);
291 ImageIndex image=osd->getImagePalette(bm.getWidth(),bm.getHeight(),&(bm.rawData()[0]),
292 (const unsigned int*)&bm.palette.getColourVector()[0]); // data is freed by the OSD
294 float tx=x+region.windowx;
295 float ty=y+region.windowy;
296 float th=bm.getHeight();
297 float tw=bm.getWidth();
299 float scalex=720.f/((float) (region.framewidth+1));
300 float scaley=576.f/((float) (region.frameheight+1));
305 SVGCommand temp=SVGCommand::PaintImage(tx,ty,tw,th,image,0);
306 removeCommands(tx,ty,tw,th);
307 commands.push_back(temp);
308 command_mutex.unlock();
311 void SurfaceVector::drawPoint(int x, int y, DrawStyle& c, bool fastdraw){
312 if (!fastdraw) command_mutex.lock();
313 VectorHandle ref = osd->getStyleRef(c);
314 commands.push_back(SVGCommand::PaintPath(x,y,1,1,PIPoint,ref));
315 if (!fastdraw) command_mutex.unlock();
317 void SurfaceVector::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height,unsigned int width, DrawStyle& nextColour)
319 command_mutex.lock();
320 ImageIndex image=osd->getMonoBitmapRef(base,width,height);
321 VectorHandle ref = osd->getStyleRef(nextColour);
322 removeCommands(dx,dy,width,height);
323 commands.push_back(SVGCommand::PaintImage(dx,dy,height,width,image,ref));
324 command_mutex.unlock();
328 int SurfaceVector::removeCommands(float x,float y,float width,float height)
330 // we iterate through all old commands in order to remove commands hidden by this rectangle
331 std::vector<SVGCommand>::iterator itty=commands.begin();
332 std::vector<SVGCommand>::iterator remstart;
334 float cx, cy, cw, ch;
338 bool clipping_erases = false;
339 while (itty!=commands.end())
341 if ((clipping_erases // test if clipping helps
342 || (*itty).Test(x,y,width,height) )
343 && (*itty).instr != DrawClipping) {
344 //Log::getInstance()->log("OSD", Log::DEBUG, "Remove command %d %g %g %g %g %d %d",(*itty).instr,
345 //(*itty).x,(*itty).y,(*itty).w,(*itty).h,(*itty).reference,(*itty).target.image);
346 osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
347 ImageIndex ii=(*itty).getImageIndex();
348 if (ii) osd->removeImageRef(ii);
349 LoadIndex li=(*itty).getLoadIndex();
350 if (li) osd->removeLoadIndexRef(li);
356 if ((*itty).instr == DrawClipping) {
357 if ((*itty).w == 0.f && (*itty).h == 0.f) {
368 clipping_erases = (cx >= x) && (cy >= y) && ((cx + cw) <= (x + width)) && ((cy + ch) <= (y + height));
371 itty=commands.erase(remstart,itty);
378 itty=commands.erase(remstart,itty);
384 int SurfaceVector::updateToScreen(int sx, int sy, int w, int h, int dx, int dy)
386 // ok this method really works in a pixel oriented way
387 command_mutex.lock();
388 osd->updateOrAddSurface(this,dx-sx,dy-sy,swidth,sheight,commands);
389 command_mutex.unlock();
394 /* This is for systems which need a locking of the drawing surface to speed up drawing */
395 void SurfaceVector::startFastDraw() {
396 command_mutex.lock();
398 void SurfaceVector::endFastDraw() {
399 command_mutex.unlock();
403 void SurfaceVector::drawTTChar(int ox, int oy,int x, int y, cTeletextChar c)
405 command_mutex.lock();
406 std::vector<SVGCommand>::iterator itty=commands.begin();
407 while (itty!=commands.end())
409 if ((*itty).TTTest(ox,oy,x,y) ) {
410 itty=commands.erase(itty);
416 commands.push_back(SVGCommand::PaintTTchar(ox,oy,x,y,c.getInternal()));
417 command_mutex.unlock();