]> git.vomp.tv Git - vompclient.git/blob - osdvector.cc
Preparations for AC3 passthrough and parser for deinterlacing
[vompclient.git] / osdvector.cc
1 /*\r
2     Copyright 2012 Marten Richter\r
3 \r
4     This file is part of VOMP.\r
5 \r
6     VOMP is free software; you can redistribute it and/or modify\r
7     it under the terms of the GNU General Public License as published by\r
8     the Free Software Foundation; either version 2 of the License, or\r
9     (at your option) any later version.\r
10 \r
11     VOMP is distributed in the hope that it will be useful,\r
12     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14     GNU General Public License for more details.\r
15 \r
16     You should have received a copy of the GNU General Public License\r
17     along with VOMP; if not, write to the Free Software\r
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
19 */\r
20 \r
21 #include "osdvector.h"\r
22 #include "surfacevector.h"\r
23 \r
24 OsdVector::OsdVector()\r
25 {\r
26         setlocale(LC_CTYPE,"C.UTF-8");\r
27 }\r
28 \r
29 OsdVector::~OsdVector()\r
30 {\r
31 \r
32 }\r
33 \r
34 \r
35 int OsdVector::getFD()\r
36 {\r
37         return 0;\r
38 }\r
39 \r
40 void OsdVector::screenShot(const char* fileName)\r
41 {\r
42         //Do nothing,\r
43 }\r
44 \r
45 Surface * OsdVector::createNewSurface()\r
46 {\r
47         return new SurfaceVector(this);\r
48 }\r
49 \r
50 void OsdVector::BeginPainting()\r
51 {\r
52         surfaces_mutex.Lock();\r
53 }\r
54 void OsdVector::EndPainting()\r
55 {\r
56         surfaces_mutex.Unlock();\r
57 }\r
58 \r
59 void OsdVector::Blank()\r
60 {\r
61         // do nothing? remove this one?\r
62 }\r
63 \r
64 void OsdVector::drawSurfaces()\r
65 {\r
66         surfaces_mutex.Lock();\r
67         list<SurfaceCommands*> todraw; //First figure out if a surfaces is below another surface\r
68         list<SurfaceCommands>::iterator itty1=scommands.begin();\r
69         while (itty1!=scommands.end()) {\r
70                 list<SurfaceCommands>::iterator itty2=itty1;\r
71                 itty2++;\r
72                 bool hidden=false;\r
73                 while (itty2!=scommands.end()) {\r
74                         SurfaceCommands & ref1=*itty1;\r
75                         SurfaceCommands & ref2=*itty2;\r
76                         if (ref1.x>=ref2.x && ref1.y>=ref2.y\r
77                                         && (ref1.x+ref1.w) <= (ref2.x+ref2.w)\r
78                                         && (ref1.y+ref1.h) <= (ref2.y+ref2.h) ) {\r
79                                 hidden=true;\r
80                                 break;\r
81                         }\r
82                         itty2++;\r
83                 }\r
84                 if (!hidden) { // we are not hidden, perfect\r
85                         todraw.push_back(&(*itty1));\r
86                 }\r
87                 itty1++;\r
88         }\r
89         //Now go through all surfaces and draw them\r
90         list<SurfaceCommands*>::iterator curdraw=todraw.begin();\r
91         while (curdraw!=todraw.end()) {\r
92                 drawSetTrans(*(*curdraw));\r
93                 list<SVGCommand>::iterator commands=(*(*curdraw)).commands.begin();\r
94                 list<SVGCommand>::iterator end=(*(*curdraw)).commands.end();\r
95                 while (commands!=end) {\r
96                         executeDrawCommand(*commands);\r
97                         commands++;\r
98                 }\r
99                 curdraw++;\r
100         }\r
101 \r
102         surfaces_mutex.Unlock();\r
103 }\r
104 \r
105 \r
106 void OsdVector::updateOrAddSurface(const SurfaceVector *surf,float x,float y,float height,float width,\r
107                         list<SVGCommand>& commands)\r
108 {\r
109         surfaces_mutex.Lock();\r
110         //First determine it is already in our system\r
111         list<SurfaceCommands>::iterator itty=scommands.begin();\r
112         while (itty!=scommands.end()) {\r
113                 if ((*itty).surf==surf) {\r
114                         //decrease the references\r
115                         dereferenceSVGCommand((*itty).commands);\r
116                         break;\r
117                 }\r
118                 itty++;\r
119         }\r
120         // if not insert it\r
121         if (itty==scommands.end()) {\r
122                 SurfaceCommands new_sc;\r
123                 new_sc.surf=surf;\r
124                 new_sc.x=x;\r
125                 new_sc.y=y;\r
126                 new_sc.w=width;\r
127                 new_sc.h=height;\r
128                 itty=scommands.insert(itty,new_sc);\r
129         }\r
130         // then clear and copy\r
131         (*itty).commands.clear();\r
132         (*itty).commands=commands;\r
133         //increase the references\r
134         list<SVGCommand>::iterator sitty=(*itty).commands.begin();\r
135         while (sitty!=(*itty).commands.end())\r
136         {\r
137                 incStyleRef((*sitty).getRef());\r
138                 ImageIndex ii=(*sitty).getImageIndex();\r
139                 if (ii) incImageRef(ii);\r
140                 sitty++;\r
141         }\r
142         cleanupOrphanedRefs();\r
143 \r
144         surfaces_mutex.Unlock();\r
145 }\r
146 \r
147 void OsdVector::removeSurface(const SurfaceVector *surf)\r
148 {\r
149         surfaces_mutex.Lock();\r
150         //First determine it is already in our system\r
151         list<SurfaceCommands>::iterator itty=scommands.begin();\r
152         while (itty!=scommands.end()) {\r
153                 if ((*itty).surf==surf) {\r
154                         dereferenceSVGCommand((*itty).commands);\r
155                         (*itty).commands.clear();\r
156                         scommands.erase(itty);\r
157                         break;\r
158                 }\r
159                 itty++;\r
160         }\r
161         surfaces_mutex.Unlock();\r
162 \r
163 }\r
164 \r
165 void OsdVector::dereferenceSVGCommand(list<SVGCommand>& commands )\r
166 {\r
167 \r
168         list<SVGCommand>::iterator sitty = commands.begin();\r
169         while (sitty != commands.end()) {\r
170                 removeStyleRef((*sitty).getRef());\r
171                 ImageIndex ii = (*sitty).getImageIndex();\r
172                 if (ii) removeImageRef(ii);\r
173                 sitty++;\r
174         }\r
175 }\r
176 \r
177 void OsdVector::referenceSVGCommand(list<SVGCommand>& commands )\r
178 {\r
179         list<SVGCommand>::iterator sitty=commands.begin();\r
180         while (sitty!=commands.end())\r
181         {\r
182                 incStyleRef((*sitty).getRef());\r
183                 ImageIndex ii=(*sitty).getImageIndex();\r
184                 if (ii) incImageRef(ii);\r
185                 sitty++;\r
186         }\r
187 }\r
188 \r
189 void OsdVector::incImageRef(ImageIndex index)\r
190 {\r
191         if (images_ref.find(index)==images_ref.end()) {\r
192                 images_ref[index]=1;\r
193         } else {\r
194                 images_ref[index]++;\r
195         }\r
196 }\r
197 \r
198 void OsdVector::removeImageRef(const ImageIndex ref)\r
199 {\r
200         images_ref[ref]--;\r
201 }\r
202 \r
203 void OsdVector::cleanupOrphanedRefs()\r
204 { // Do some garbage collection\r
205         map<ImageIndex,unsigned int>::iterator iitty=images_ref.begin();\r
206         while (iitty!=images_ref.end()) {\r
207                 int count=(*iitty).second;\r
208                 if (count==0) {\r
209                         ImageIndex ref=(*iitty).first;\r
210                         images_ref.erase(iitty++);\r
211                         destroyImageRef(ref);\r
212                 } else ++iitty;\r
213         }\r
214         map<unsigned int,unsigned int>::iterator sitty=styles_ref.begin();\r
215         while (sitty!=styles_ref.end()) {\r
216                 int count=(*sitty).second;\r
217                 if (count==0) {\r
218                         unsigned int ref=(*sitty).first;\r
219                         styles_ref.erase(sitty++);\r
220                         destroyStyleRef(ref);\r
221                 } else ++sitty;\r
222 \r
223         }\r
224 }\r
225 \r
226 \r
227 unsigned int OsdVector::getImageRef(ImageIndex index)\r
228 {\r
229         if (images_ref.find(index)==images_ref.end()) {\r
230                 return -1;\r
231         } else {\r
232                 return images_ref[index];\r
233         }\r
234 }\r
235 \r
236 void OsdVector::incStyleRef(unsigned int index)\r
237 {\r
238         if (styles_ref.find(index)==styles_ref.end()) {\r
239                 styles_ref[index]=1;\r
240         } else {\r
241                 styles_ref[index]++;\r
242         }\r
243 }\r
244 \r
245 void OsdVector::removeStyleRef(unsigned int index)\r
246 {\r
247         styles_ref[index]--;\r
248 }\r
249 \r
250 unsigned int OsdVector::getStyleRef(const DrawStyle &c)\r
251 {\r
252         unsigned int style_handle=0;\r
253         if (styles.find(pair<Colour*,unsigned int>((Colour*)&c,c.rgba()))==styles.end())\r
254         {\r
255                 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createStyleRef(c);\r
256         } else {\r
257                 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())];\r
258                 //Now check if the handle is valid\r
259                 if (styles_ref.find(style_handle)==styles_ref.end()) {\r
260                         //invalid handle recreate\r
261                         style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createStyleRef(c);\r
262                 }\r
263         }\r
264         incStyleRef(style_handle);\r
265         return style_handle;\r
266 }\r
267 \r
268 unsigned int OsdVector::getColorRef(const Colour &c)\r
269 {\r
270         unsigned int style_handle=0;\r
271         if (styles.find(pair<Colour*,unsigned int>((Colour*)&c,c.rgba()))==styles.end())\r
272         {\r
273                 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createColorRef(c);\r
274         } else {\r
275                 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())];\r
276                 if (styles_ref.find(style_handle)==styles_ref.end()) {\r
277                         //invalid handle recreate\r
278                         style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createColorRef(c);\r
279                 }\r
280         }\r
281         incStyleRef(style_handle);\r
282         return style_handle;\r
283 }\r
284 \r
285 unsigned int OsdVector::getStyleRef(unsigned int index)\r
286 {\r
287         if (styles_ref.find(index)==styles_ref.end()) {\r
288                 return -1;\r
289         } else {\r
290                 return styles_ref[index];\r
291         }\r
292 }\r
293 \r
294 ImageIndex OsdVector::getJpegRef(const char* fileName, int *width,int *height)\r
295 {\r
296         ImageIndex image_handle=0;\r
297         if (jpegs.find(fileName)==jpegs.end())\r
298         {\r
299                 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);\r
300         } else {\r
301                 image_handle=jpegs[fileName];\r
302                 *width=0;\r
303                 *height=0;\r
304                 if (images_ref.find(image_handle)==images_ref.end()) {\r
305                         //invalid handle recreate\r
306                         image_handle=jpegs[fileName]=createJpeg(fileName,width,height);\r
307                 }\r
308         }\r
309         incImageRef(image_handle);\r
310         return image_handle;\r
311 }\r
312 \r
313 ImageIndex OsdVector::getMonoBitmapRef(void *base,int width,int height)\r
314 {\r
315         ImageIndex image_handle;\r
316         if (monobitmaps.find(base)==monobitmaps.end())\r
317         {\r
318                 image_handle=monobitmaps[base]=createMonoBitmap(base,width,height);\r
319         } else {\r
320                 image_handle=monobitmaps[base];\r
321                 if (images_ref.find(image_handle)==images_ref.end()) {\r
322                         //invalid handle recreate\r
323                         image_handle=monobitmaps[base]=createMonoBitmap(base,width,height);\r
324                 }\r
325         }\r
326         incImageRef(image_handle);\r
327         return image_handle;\r
328 }\r
329 \r
330 ImageIndex  OsdVector::getImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)\r
331 {\r
332         ImageIndex image_handle;\r
333         image_handle=createImagePalette(width,height,image_data,palette_data);\r
334         incImageRef(image_handle);\r
335         return image_handle;\r
336 }\r