]> git.vomp.tv Git - vompclient-marten.git/blob - osdvector.cc
Fix bug in demuxer widescreen signaling
[vompclient-marten.git] / osdvector.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, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #include "osdvector.h"
22 #include "surfacevector.h"
23
24 OsdVector::OsdVector()
25 {
26         setlocale(LC_CTYPE,"C.UTF-8");
27 }
28
29 OsdVector::~OsdVector()
30 {
31
32 }
33
34
35 int OsdVector::getFD()
36 {
37         return 0;
38 }
39
40 void OsdVector::screenShot(const char* fileName)
41 {
42         //Do nothing,
43 }
44
45 Surface * OsdVector::createNewSurface()
46 {
47         return new SurfaceVector(this);
48 }
49
50 void OsdVector::BeginPainting()
51 {
52         surfaces_mutex.Lock();
53 }
54 void OsdVector::EndPainting()
55 {
56         surfaces_mutex.Unlock();
57 }
58
59 void OsdVector::Blank()
60 {
61         // do nothing? remove this one?
62 }
63
64 int OsdVector::restore()
65 {
66         // First clear the contents of all registered surfaces
67         surfaces_mutex.Lock();
68
69         //Now go through all surfaces and draw them
70         list<SurfaceCommands>::iterator curdraw=scommands.begin();
71         while (curdraw!=scommands.end()) {
72                 (*curdraw).commands.clear();
73                 curdraw++;
74         }
75         //also clear all handles, they are now invalid, no need to release them
76         images_ref.clear();
77         monobitmaps.clear();
78         jpegs.clear();
79         styles.clear();
80         styles_ref.clear();
81
82         surfaces_mutex.Unlock();
83         return 1;
84 }
85
86 void OsdVector::drawSurfaces()
87 {
88         surfaces_mutex.Lock();
89         list<SurfaceCommands*> todraw; //First figure out if a surfaces is below another surface
90         list<SurfaceCommands>::iterator itty1=scommands.begin();
91         while (itty1!=scommands.end()) {
92                 list<SurfaceCommands>::iterator itty2=itty1;
93                 itty2++;
94                 bool hidden=false;
95                 while (itty2!=scommands.end()) {
96                         SurfaceCommands & ref1=*itty1;
97                         SurfaceCommands & ref2=*itty2;
98                         if (ref1.x>=ref2.x && ref1.y>=ref2.y
99                                         && (ref1.x+ref1.w) <= (ref2.x+ref2.w)
100                                         && (ref1.y+ref1.h) <= (ref2.y+ref2.h) ) {
101                                 hidden=true;
102                                 break;
103                         }
104                         itty2++;
105                 }
106                 if (!hidden) { // we are not hidden, perfect
107                         todraw.push_back(&(*itty1));
108                 }
109                 itty1++;
110         }
111         //Now go through all surfaces and draw them
112         list<SurfaceCommands*>::iterator curdraw=todraw.begin();
113         while (curdraw!=todraw.end()) {
114                 drawSetTrans(*(*curdraw));
115                 list<SVGCommand>::iterator commands=(*(*curdraw)).commands.begin();
116                 list<SVGCommand>::iterator end=(*(*curdraw)).commands.end();
117                 while (commands!=end) {
118                         executeDrawCommand(*commands);
119                         commands++;
120                 }
121                 curdraw++;
122         }
123
124         surfaces_mutex.Unlock();
125 }
126
127
128 void OsdVector::updateOrAddSurface(const SurfaceVector *surf,float x,float y,float height,float width,
129                         list<SVGCommand>& commands)
130 {
131         surfaces_mutex.Lock();
132         //First determine it is already in our system
133         list<SurfaceCommands>::iterator itty=scommands.begin();
134         while (itty!=scommands.end()) {
135                 if ((*itty).surf==surf) {
136                         //decrease the references
137                         dereferenceSVGCommand((*itty).commands);
138                         break;
139                 }
140                 itty++;
141         }
142         // if not insert it
143         if (itty==scommands.end()) {
144                 SurfaceCommands new_sc;
145                 new_sc.surf=surf;
146                 new_sc.x=x;
147                 new_sc.y=y;
148                 new_sc.w=width;
149                 new_sc.h=height;
150                 itty=scommands.insert(itty,new_sc);
151         }
152         // then clear and copy
153         (*itty).commands.clear();
154         (*itty).commands=commands;
155         //increase the references
156         list<SVGCommand>::iterator sitty=(*itty).commands.begin();
157         while (sitty!=(*itty).commands.end())
158         {
159                 incStyleRef((*sitty).getRef());
160                 ImageIndex ii=(*sitty).getImageIndex();
161                 if (ii) incImageRef(ii);
162                 sitty++;
163         }
164         cleanupOrphanedRefs();
165
166         surfaces_mutex.Unlock();
167 }
168
169 void OsdVector::removeSurface(const SurfaceVector *surf)
170 {
171         surfaces_mutex.Lock();
172         //First determine it is already in our system
173         list<SurfaceCommands>::iterator itty=scommands.begin();
174         while (itty!=scommands.end()) {
175                 if ((*itty).surf==surf) {
176                         dereferenceSVGCommand((*itty).commands);
177                         (*itty).commands.clear();
178                         scommands.erase(itty);
179                         break;
180                 }
181                 itty++;
182         }
183         surfaces_mutex.Unlock();
184
185 }
186
187 void OsdVector::dereferenceSVGCommand(list<SVGCommand>& commands )
188 {
189
190         list<SVGCommand>::iterator sitty = commands.begin();
191         while (sitty != commands.end()) {
192                 removeStyleRef((*sitty).getRef());
193                 ImageIndex ii = (*sitty).getImageIndex();
194                 if (ii) removeImageRef(ii);
195                 sitty++;
196         }
197 }
198
199 void OsdVector::referenceSVGCommand(list<SVGCommand>& commands )
200 {
201         list<SVGCommand>::iterator sitty=commands.begin();
202         while (sitty!=commands.end())
203         {
204                 incStyleRef((*sitty).getRef());
205                 ImageIndex ii=(*sitty).getImageIndex();
206                 if (ii) incImageRef(ii);
207                 sitty++;
208         }
209 }
210
211 void OsdVector::incImageRef(ImageIndex index)
212 {
213         if (images_ref.find(index)==images_ref.end()) {
214                 images_ref[index]=1;
215         } else {
216                 images_ref[index]++;
217         }
218 }
219
220 void OsdVector::removeImageRef(const ImageIndex ref)
221 {
222         images_ref[ref]--;
223 }
224
225 void OsdVector::cleanupOrphanedRefs()
226 { // Do some garbage collection
227
228         map<void *,ImageIndex>::iterator mitty=monobitmaps.begin();
229         while (mitty!=monobitmaps.end()) {
230                 map<ImageIndex,unsigned int>::iterator curitty=images_ref.find((*mitty).second);
231                 int count=(*curitty).second;
232                 if (count==0) {
233                         ImageIndex ref=(*curitty).first;
234                         monobitmaps.erase(mitty++);
235                         images_ref.erase(curitty++);
236                         destroyImageRef(ref);
237                 } else ++mitty;
238         }
239
240         map<string,ImageIndex>::iterator jitty=jpegs.begin();
241         while (jitty!=jpegs.end()) {
242                 map<ImageIndex,unsigned int>::iterator curitty=images_ref.find((*jitty).second);
243                 int count=(*curitty).second;
244                 if (count==0) {
245                         ImageIndex ref=(*curitty).first;
246                         jpegs.erase(jitty++);
247                         images_ref.erase(curitty++);
248                         destroyImageRef(ref);
249                 } else ++jitty;
250         }
251
252
253         map<pair<Colour*,unsigned int>,unsigned int>::iterator sitty=styles.begin();
254         while (sitty!=styles.end()) {
255                 map<unsigned int,unsigned int>::iterator curitty=styles_ref.find((*sitty).second);
256                 int count=(*curitty).second;
257                 if (count==0) {
258                         unsigned int ref=(*curitty).first;
259                         styles.erase(sitty++);
260                         styles_ref.erase(curitty++);
261                         destroyStyleRef(ref);
262
263                 } else ++sitty;
264
265         }
266 }
267
268
269 unsigned int OsdVector::getImageRef(ImageIndex index)
270 {
271         if (images_ref.find(index)==images_ref.end()) {
272                 return -1;
273         } else {
274                 return images_ref[index];
275         }
276 }
277
278 void OsdVector::incStyleRef(unsigned int index)
279 {
280         if (styles_ref.find(index)==styles_ref.end()) {
281                 styles_ref[index]=1;
282         } else {
283                 styles_ref[index]++;
284         }
285 }
286
287 void OsdVector::removeStyleRef(unsigned int index)
288 {
289         styles_ref[index]--;
290 }
291
292 unsigned int OsdVector::getStyleRef(const DrawStyle &c)
293 {
294         unsigned int style_handle=0;
295         if (styles.find(pair<Colour*,unsigned int>((Colour*)&c,c.rgba()))==styles.end())
296         {
297                 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createStyleRef(c);
298         } else {
299                 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())];
300                 //Now check if the handle is valid
301                 if (styles_ref.find(style_handle)==styles_ref.end()) {
302                         //invalid handle recreate
303                         style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createStyleRef(c);
304                 }
305         }
306         incStyleRef(style_handle);
307         return style_handle;
308 }
309
310 unsigned int OsdVector::getColorRef(const Colour &c)
311 {
312         unsigned int style_handle=0;
313         if (styles.find(pair<Colour*,unsigned int>((Colour*)&c,c.rgba()))==styles.end())
314         {
315                 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createColorRef(c);
316         } else {
317                 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())];
318                 if (styles_ref.find(style_handle)==styles_ref.end()) {
319                         //invalid handle recreate
320                         style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createColorRef(c);
321                 }
322         }
323         incStyleRef(style_handle);
324         return style_handle;
325 }
326
327 unsigned int OsdVector::getStyleRef(unsigned int index)
328 {
329         if (styles_ref.find(index)==styles_ref.end()) {
330                 return -1;
331         } else {
332                 return styles_ref[index];
333         }
334 }
335
336 ImageIndex OsdVector::getJpegRef(const char* fileName, int *width,int *height)
337 {
338         ImageIndex image_handle=0;
339         if (jpegs.find(fileName)==jpegs.end())
340         {
341                 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
342         } else {
343                 image_handle=jpegs[fileName];
344                 *width=0;
345                 *height=0;
346                 if (images_ref.find(image_handle)==images_ref.end()) {
347                         //invalid handle recreate
348                         image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
349                 }
350         }
351         incImageRef(image_handle);
352         return image_handle;
353 }
354
355 ImageIndex OsdVector::getMonoBitmapRef(void *base,int width,int height)
356 {
357         ImageIndex image_handle;
358         if (monobitmaps.find(base)==monobitmaps.end())
359         {
360                 image_handle=monobitmaps[base]=createMonoBitmap(base,width,height);
361         } else {
362                 image_handle=monobitmaps[base];
363                 if (images_ref.find(image_handle)==images_ref.end()) {
364                         //invalid handle recreate
365                         image_handle=monobitmaps[base]=createMonoBitmap(base,width,height);
366                 }
367         }
368         incImageRef(image_handle);
369         return image_handle;
370 }
371
372 ImageIndex  OsdVector::getImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)
373 {
374         ImageIndex image_handle;
375         image_handle=createImagePalette(width,height,image_data,palette_data);
376         incImageRef(image_handle);
377         return image_handle;
378 }