]> git.vomp.tv Git - vompclient.git/blob - surfacevector.cc
Remove some dead code, rename some things
[vompclient.git] / surfacevector.cc
1 /*
2     Copyright 2012 Marten Richter
3
4     This file is part of VOMP.
5
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.
10
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.
15
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/>.
18 */
19
20 #include <wchar.h>
21 #include <stdlib.h>
22 #include <math.h>
23 #include "bitmap.h"
24 #include "staticartwork.h"
25 #include "surfacevector.h"
26
27 SurfaceVector::SurfaceVector(OsdVector* vosd)
28 {
29
30   osd = vosd;
31   commands.reserve(2048);
32 }
33
34 SurfaceVector::~SurfaceVector()
35 {
36   osd->removeSurface(this);
37   std::vector<SVGCommand>::iterator itty = commands.begin();
38
39   while (itty != commands.end())
40   {
41     osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
42     ImageIndex ii = (*itty).getImageIndex();
43
44     if (ii)
45     {
46       osd->removeImageRef(ii);
47     }
48
49     LoadIndex li = (*itty).getLoadIndex();
50
51     if (li) osd->removeLoadIndexRef(li);
52
53     itty++;
54   }
55 }
56
57
58 int SurfaceVector::getFontHeight()
59 {
60   return (int)osd->getFontHeight();
61 }
62
63 float SurfaceVector::getCharWidth(wchar_t c)
64 {
65   return osd->getCharWidth(c);
66 }
67
68
69 int SurfaceVector::drawText(const char* text, int x, int y, const DrawStyle& c)
70 {
71   return drawText(text, x, y, 0, c);
72 }
73
74 int SurfaceVector::drawText(const char* text, int x, int y, int width, const DrawStyle& c)
75 {
76   float shift = 0.;
77   const char* run = text;
78   size_t length = strlen(text);
79
80
81   command_mutex.lock();
82
83   VectorHandle ref = osd->getStyleRef(c);
84   float* charwidtharray = osd->getCharWidthArray();
85   int commands_size = commands.size();
86   int chars = 0;
87   commands.resize(commands_size + strlen(text));
88 #ifndef WIN32
89   mbstate_t state;
90   wchar_t tempo;
91   size_t num_bytes = 1;
92   memset((void*)&state, 0, sizeof(state));
93   num_bytes = mbrtowc(&tempo, run, length, &state);
94
95   while (num_bytes != ((size_t) -1) && num_bytes != ((size_t) -2) && length > 0)
96   {
97     SVGCommand::PaintGlyph(commands[commands_size + chars], x + shift, y, tempo, ref);
98     chars++;
99
100     float cur_shift = charwidtharray[tempo & 0xFF];
101
102     if (tempo && 0xFFFFFF00) cur_shift = osd->getCharWidth(tempo);
103
104     shift += cur_shift;
105     length -= num_bytes;
106     run += num_bytes;
107
108     if (shift > width && width > 0)
109     {
110       command_mutex.unlock();
111       return 1;
112     }
113
114     num_bytes = mbrtowc(&tempo, run, length, &state);
115   }
116
117 #else
118   wchar_t* temptext = new wchar_t[length + 1];
119   int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1,
120                                         temptext, length + 1) - 1;
121
122   for (int i = 0; i < real_length; i++)
123   {
124     SVGCommand::PaintGlyph(commands[commands_size + chars], x + shift, y, temptext[i], ref);
125     chars++;
126
127     float cur_shift = charwidtharray[temptext[i] & 0xFF];
128
129     if (temptext[i] && 0xFFFFFF00) cur_shift = osd->getCharWidth(temptext[i]);
130
131     shift += cur_shift;
132   }
133
134   delete[] temptext;
135 #endif
136
137   commands.resize(commands_size + chars);
138   command_mutex.unlock();
139   return 1;
140
141 }
142 int SurfaceVector::drawTextRJ(const char* text, int x, int y, const DrawStyle& c)
143 {
144   float shift = 0.;
145   const char* run = text;
146   size_t length = strlen(text);
147
148 #ifndef WIN32
149   mbstate_t state;
150   wchar_t tempo[1];
151   size_t num_bytes = 1;
152   memset((void*)&state, 0, sizeof(state));
153   num_bytes = mbrtowc(tempo, run, length, &state);
154
155   while (num_bytes != ((size_t) -1) && num_bytes != ((size_t) -2) && length > 0)
156   {
157     shift += osd->getCharWidth(*tempo);
158     length -= num_bytes;
159     run += num_bytes;
160     num_bytes = mbrtowc(tempo, run, length, &state);
161   }
162
163 #else
164   wchar_t* temptext = new wchar_t[length + 1];
165   int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1,
166                                         temptext, length + 1) - 1;
167
168   for (int i = 0; i < real_length; i++)
169   {
170     shift += osd->getCharWidth(temptext[i]);
171   }
172
173   delete[] temptext;
174 #endif
175   return drawText(text, (int)(x - shift), y, c);
176 }
177
178 int SurfaceVector::drawTextCentre(const char* text, int x, int y, const DrawStyle& c)
179 {
180   float shift = 0;
181   const char* run = text;
182   size_t length = strlen(text);
183
184 #ifndef WIN32
185   mbstate_t state;
186   wchar_t tempo[1];
187   size_t num_bytes = 1;
188   memset((void*)&state, 0, sizeof(state));
189   num_bytes = mbrtowc(tempo, run, length, &state);
190
191   while (num_bytes != ((size_t) -1) && num_bytes != ((size_t) -2) && length > 0)
192   {
193     shift += osd->getCharWidth(*tempo);
194     length -= num_bytes;
195     run += num_bytes;
196     num_bytes = mbrtowc(tempo, run, length, &state);
197   }
198
199 #else
200   wchar_t* temptext = new wchar_t[length + 1];
201   int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1,
202                                         temptext, length + 1) - 1;
203
204   for (int i = 0; i < real_length; i++)
205   {
206     shift += osd->getCharWidth(temptext[i]);
207   }
208
209   delete[] temptext;
210 #endif
211
212   return drawText(text, (int)(x - shift / 2.),  y, c);
213 }
214
215 void SurfaceVector::drawJpeg(const char* fileName, int x, int y, int* width, int* height)
216 {
217   StaticArtwork index = sa_MAX; // This is for compatibility only
218
219   if (strcmp(fileName, "/vdr.jpg") == 0)
220   {
221     index = sa_vdrlogo;
222     *height = 100; // this is faked so that the system does use the old coordinate system
223     *width = (int)ceil(190.f * osd->getPixelAspect());
224   }
225   else if (strcmp(fileName, "/wallpaperPAL.jpg") == 0)
226   {
227     index = sa_wallpaper;
228     *width = 720; // this is faked so that the system does use the old coordinate system
229     *height = 576;
230   }
231
232   if (index != sa_MAX)
233   {
234     TVMediaInfo info;
235     info.setStaticArtwork(index);
236     drawTVMedia(info, x, y, *width, *height, TopLeft);
237   }
238 }
239
240 /*
241 void SurfaceVector::drawJpeg(const char *fileName,int x, int y,int *width, int *height)
242 {
243         command_mutex.lock();
244         ImageIndex image=osd->getJpegRef(fileName,width,height);
245         commands.push_back(SVGCommand::PaintImage(x,y,*width,*height,image,0));
246         command_mutex.unlock();
247 }
248 */
249
250 void SurfaceVector::drawTVMedia(TVMediaInfo& tvmedia, float x, float y, float  width, float height, Corner corner)
251 {
252   command_mutex.lock();
253   ImageIndex image = 0;
254   LoadIndex load_index = osd->getTVMediaRef(tvmedia, image);
255
256   if (width != 0 && height != 0)
257   {
258     removeCommands(x, y, width, height);
259   }
260
261   if (image)
262   {
263     //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image %d %d", load_index,image);
264     commands.push_back(SVGCommand::PaintImage(x, y, width, height, image, 0, corner));
265   }
266   else
267   {
268
269     commands.push_back(SVGCommand::PaintImageLoading(load_index, x, y, width, height, 0, corner));
270     //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image loading %d %d", load_index,image);
271   }
272
273   command_mutex.unlock();
274 }
275
276 void SurfaceVector::drawClippingRectangle(float x, float y, float w, float h)
277 {
278   command_mutex.lock();
279   commands.push_back(SVGCommand::PaintClipping((float)x, (float)y, (float)w, (float)h));
280   command_mutex.unlock();
281 }
282
283 int SurfaceVector::create(UINT width, UINT height)
284 {
285   sheight = height;
286   swidth = width;
287   return 1;
288 }
289 void SurfaceVector::display()
290 {
291   //nothing this is really mvp specific
292 }
293
294 int SurfaceVector::fillblt(int x, int y, int width, int height, const DrawStyle& c)
295 {
296   command_mutex.lock();
297   removeCommands(x, y, width, height); // remove commands below the box
298   VectorHandle ref = osd->getStyleRef(c);
299   commands.push_back(SVGCommand::PaintPath(x, y, width, height, PIRectangle, ref));
300   command_mutex.unlock();
301   return 1;
302
303 }
304 void SurfaceVector::drawHorzLine(int x1, int x2, int y, const DrawStyle& c)
305 {
306   command_mutex.lock();
307   VectorHandle ref = osd->getStyleRef(c);
308   commands.push_back(SVGCommand::PaintPath(x1, y, x2 - x1, 1, PIHorzLine, ref));
309   command_mutex.unlock();
310 }
311
312 void SurfaceVector::drawVertLine(int x, int y1, int y2, const DrawStyle& c)
313 {
314   command_mutex.lock();
315   VectorHandle ref = osd->getStyleRef(c);
316   commands.push_back(SVGCommand::PaintPath(x, y1, 1, y2 - y1, PIVertLine, ref));
317   command_mutex.unlock();
318 }
319
320 void SurfaceVector::drawBitmap(int x, int y, const Bitmap& bm, const DisplayRegion& region)
321 {
322   //this is complicated
323   command_mutex.lock();
324   /*
325         unsigned int * data=(unsigned int*)malloc(sizeof(unsigned int)*bm.getWidth()*bm.getHeight());
326         for (UINT j = 0; j < bm.getHeight(); ++j){
327            for (UINT i = 0; i < bm.getWidth(); ++i)
328            {
329                    data[i+j*bm.getHeight()]=bm.getColour(i,j);
330            }
331       }*/
332   ImageIndex image = osd->getImagePalette(bm.getWidth(), bm.getHeight(), &(bm.rawData()[0]),
333                                           (const unsigned int*)&bm.palette.getColourVector()[0]); // data is freed by the OSD
334   //free(data);
335   float tx = x + region.windowx;
336   float ty = y + region.windowy;
337   float th = bm.getHeight();
338   float tw = bm.getWidth();
339
340   float scalex = 720.f / ((float) (region.framewidth + 1));
341   float scaley = 576.f / ((float) (region.frameheight + 1));
342   tx *= scalex;
343   ty *= scaley;
344   tw *= scalex;
345   th *= scaley;
346   SVGCommand temp = SVGCommand::PaintImage(tx, ty, tw, th, image, 0);
347   removeCommands(tx, ty, tw, th);
348   commands.push_back(temp);
349   command_mutex.unlock();
350 }
351
352 void SurfaceVector::drawPoint(int x, int y, DrawStyle& c, bool fastdraw)
353 {
354   if (!fastdraw) command_mutex.lock();
355
356   VectorHandle ref = osd->getStyleRef(c);
357   commands.push_back(SVGCommand::PaintPath(x, y, 1, 1, PIPoint, ref));
358
359   if (!fastdraw)  command_mutex.unlock();
360 }
361 void SurfaceVector::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height, unsigned int width, DrawStyle& nextColour)
362 {
363   command_mutex.lock();
364   ImageIndex image = osd->getMonoBitmapRef(base, width, height);
365   VectorHandle ref = osd->getStyleRef(nextColour);
366   removeCommands(dx, dy, width, height);
367   commands.push_back(SVGCommand::PaintImage(dx, dy, height, width, image, ref));
368   command_mutex.unlock();
369 }
370
371
372 int SurfaceVector::removeCommands(float x, float y, float width, float height)
373 {
374   // we iterate through all old commands in order to remove commands hidden by this rectangle
375   std::vector<SVGCommand>::iterator itty = commands.begin();
376   std::vector<SVGCommand>::iterator remstart;
377   bool remove = false;
378   float cx, cy, cw, ch;
379   cx = cy = 0.f;
380   cw = swidth;
381   ch = sheight;
382   bool clipping_erases = false;
383
384   while (itty != commands.end())
385   {
386     if ((clipping_erases // test if clipping helps
387          || (*itty).Test(x, y, width, height)  )
388         && (*itty).instr != DrawClipping)
389     {
390       //Log::getInstance()->log("OSD", Log::DEBUG, "Remove command %d %g %g %g %g %d %d",(*itty).instr,
391       //(*itty).x,(*itty).y,(*itty).w,(*itty).h,(*itty).reference,(*itty).target.image);
392       osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
393       ImageIndex ii = (*itty).getImageIndex();
394
395       if (ii) osd->removeImageRef(ii);
396
397       LoadIndex li = (*itty).getLoadIndex();
398
399       if (li) osd->removeLoadIndexRef(li);
400
401       if (!remove)
402       {
403         remstart = itty;
404         remove = true;
405       }
406     }
407     else
408     {
409       if ((*itty).instr == DrawClipping)
410       {
411         if ((*itty).w == 0.f && (*itty).h == 0.f)
412         {
413           cx = cy = 0.f;
414           cw = swidth;
415           ch = sheight;
416
417         }
418         else
419         {
420           cx = (*itty).x;
421           cy = (*itty).y;
422           cw = (*itty).w;
423           ch = (*itty).h;
424         }
425
426         clipping_erases = (cx >= x) && (cy >= y) && ((cx + cw) <= (x + width)) && ((cy + ch) <= (y + height));
427       }
428
429       if (remove)
430       {
431         itty = commands.erase(remstart, itty);
432         remove = false;
433       }
434     }
435
436     itty++;
437   }
438
439   if (remove)
440   {
441     itty = commands.erase(remstart, itty);
442   }
443
444   return 1;
445
446 }
447
448 int SurfaceVector::updateToScreen(int sx, int sy, int w, int h, int dx, int dy)
449 {
450   // ok this method really works in a pixel oriented way
451   command_mutex.lock();
452   osd->updateOrAddSurface(this, dx - sx, dy - sy, swidth, sheight, commands);
453   command_mutex.unlock();
454   return 1;
455 }
456
457
458 /* This is for systems which need a locking of the drawing surface to speed up drawing */
459 void SurfaceVector::startFastDraw()
460 {
461   command_mutex.lock();
462 }
463 void SurfaceVector::endFastDraw()
464 {
465   command_mutex.unlock();
466 }
467
468
469 void SurfaceVector::drawTTChar(int ox, int oy, int x, int y, cTeletextChar c)
470 {
471   command_mutex.lock();
472   std::vector<SVGCommand>::iterator itty = commands.begin();
473
474   while (itty != commands.end())
475   {
476     if ((*itty).TTTest(ox, oy, x, y) )
477     {
478       itty = commands.erase(itty);
479       break;
480     }
481     else
482     {
483       itty++;
484     }
485   }
486
487   commands.push_back(SVGCommand::PaintTTchar(ox, oy, x, y, c.getInternal()));
488   command_mutex.unlock();
489 }