2 Copyright 2012 Marten Richter
\r
4 This file is part of VOMP.
\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
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
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
21 #include "osdvector.h"
\r
22 #include "surfacevector.h"
\r
24 OsdVector::OsdVector()
\r
26 setlocale(LC_CTYPE,"C.UTF-8");
\r
29 OsdVector::~OsdVector()
\r
35 int OsdVector::getFD()
\r
40 void OsdVector::screenShot(const char* fileName)
\r
45 Surface * OsdVector::createNewSurface()
\r
47 return new SurfaceVector(this);
\r
50 void OsdVector::BeginPainting()
\r
52 surfaces_mutex.Lock();
\r
54 void OsdVector::EndPainting()
\r
56 surfaces_mutex.Unlock();
\r
59 void OsdVector::Blank()
\r
61 // do nothing? remove this one?
\r
64 int OsdVector::restore()
\r
66 // First clear the contents of all registered surfaces
\r
67 surfaces_mutex.Lock();
\r
69 //Now go through all surfaces and draw them
\r
70 list<SurfaceCommands>::iterator curdraw=scommands.begin();
\r
71 while (curdraw!=scommands.end()) {
\r
72 (*curdraw).commands.clear();
\r
75 //also clear all handles, they are now invalid, no need to release them
\r
76 images_ref.clear();;
\r
77 monobitmaps.clear();
\r
82 surfaces_mutex.Unlock();
\r
86 void OsdVector::drawSurfaces()
\r
88 surfaces_mutex.Lock();
\r
89 list<SurfaceCommands*> todraw; //First figure out if a surfaces is below another surface
\r
90 list<SurfaceCommands>::iterator itty1=scommands.begin();
\r
91 while (itty1!=scommands.end()) {
\r
92 list<SurfaceCommands>::iterator itty2=itty1;
\r
95 while (itty2!=scommands.end()) {
\r
96 SurfaceCommands & ref1=*itty1;
\r
97 SurfaceCommands & ref2=*itty2;
\r
98 if (ref1.x>=ref2.x && ref1.y>=ref2.y
\r
99 && (ref1.x+ref1.w) <= (ref2.x+ref2.w)
\r
100 && (ref1.y+ref1.h) <= (ref2.y+ref2.h) ) {
\r
106 if (!hidden) { // we are not hidden, perfect
\r
107 todraw.push_back(&(*itty1));
\r
111 //Now go through all surfaces and draw them
\r
112 list<SurfaceCommands*>::iterator curdraw=todraw.begin();
\r
113 while (curdraw!=todraw.end()) {
\r
114 drawSetTrans(*(*curdraw));
\r
115 list<SVGCommand>::iterator commands=(*(*curdraw)).commands.begin();
\r
116 list<SVGCommand>::iterator end=(*(*curdraw)).commands.end();
\r
117 while (commands!=end) {
\r
118 executeDrawCommand(*commands);
\r
124 surfaces_mutex.Unlock();
\r
128 void OsdVector::updateOrAddSurface(const SurfaceVector *surf,float x,float y,float height,float width,
\r
129 list<SVGCommand>& commands)
\r
131 surfaces_mutex.Lock();
\r
132 //First determine it is already in our system
\r
133 list<SurfaceCommands>::iterator itty=scommands.begin();
\r
134 while (itty!=scommands.end()) {
\r
135 if ((*itty).surf==surf) {
\r
136 //decrease the references
\r
137 dereferenceSVGCommand((*itty).commands);
\r
142 // if not insert it
\r
143 if (itty==scommands.end()) {
\r
144 SurfaceCommands new_sc;
\r
150 itty=scommands.insert(itty,new_sc);
\r
152 // then clear and copy
\r
153 (*itty).commands.clear();
\r
154 (*itty).commands=commands;
\r
155 //increase the references
\r
156 list<SVGCommand>::iterator sitty=(*itty).commands.begin();
\r
157 while (sitty!=(*itty).commands.end())
\r
159 incStyleRef((*sitty).getRef());
\r
160 ImageIndex ii=(*sitty).getImageIndex();
\r
161 if (ii) incImageRef(ii);
\r
164 cleanupOrphanedRefs();
\r
166 surfaces_mutex.Unlock();
\r
169 void OsdVector::removeSurface(const SurfaceVector *surf)
\r
171 surfaces_mutex.Lock();
\r
172 //First determine it is already in our system
\r
173 list<SurfaceCommands>::iterator itty=scommands.begin();
\r
174 while (itty!=scommands.end()) {
\r
175 if ((*itty).surf==surf) {
\r
176 dereferenceSVGCommand((*itty).commands);
\r
177 (*itty).commands.clear();
\r
178 scommands.erase(itty);
\r
183 surfaces_mutex.Unlock();
\r
187 void OsdVector::dereferenceSVGCommand(list<SVGCommand>& commands )
\r
190 list<SVGCommand>::iterator sitty = commands.begin();
\r
191 while (sitty != commands.end()) {
\r
192 removeStyleRef((*sitty).getRef());
\r
193 ImageIndex ii = (*sitty).getImageIndex();
\r
194 if (ii) removeImageRef(ii);
\r
199 void OsdVector::referenceSVGCommand(list<SVGCommand>& commands )
\r
201 list<SVGCommand>::iterator sitty=commands.begin();
\r
202 while (sitty!=commands.end())
\r
204 incStyleRef((*sitty).getRef());
\r
205 ImageIndex ii=(*sitty).getImageIndex();
\r
206 if (ii) incImageRef(ii);
\r
211 void OsdVector::incImageRef(ImageIndex index)
\r
213 if (images_ref.find(index)==images_ref.end()) {
\r
214 images_ref[index]=1;
\r
216 images_ref[index]++;
\r
220 void OsdVector::removeImageRef(const ImageIndex ref)
\r
225 void OsdVector::cleanupOrphanedRefs()
\r
226 { // Do some garbage collection
\r
227 map<ImageIndex,unsigned int>::iterator iitty=images_ref.begin();
\r
228 while (iitty!=images_ref.end()) {
\r
229 int count=(*iitty).second;
\r
231 ImageIndex ref=(*iitty).first;
\r
232 images_ref.erase(iitty++);
\r
233 destroyImageRef(ref);
\r
236 map<unsigned int,unsigned int>::iterator sitty=styles_ref.begin();
\r
237 while (sitty!=styles_ref.end()) {
\r
238 int count=(*sitty).second;
\r
240 unsigned int ref=(*sitty).first;
\r
241 styles_ref.erase(sitty++);
\r
242 destroyStyleRef(ref);
\r
249 unsigned int OsdVector::getImageRef(ImageIndex index)
\r
251 if (images_ref.find(index)==images_ref.end()) {
\r
254 return images_ref[index];
\r
258 void OsdVector::incStyleRef(unsigned int index)
\r
260 if (styles_ref.find(index)==styles_ref.end()) {
\r
261 styles_ref[index]=1;
\r
263 styles_ref[index]++;
\r
267 void OsdVector::removeStyleRef(unsigned int index)
\r
269 styles_ref[index]--;
\r
272 unsigned int OsdVector::getStyleRef(const DrawStyle &c)
\r
274 unsigned int style_handle=0;
\r
275 if (styles.find(pair<Colour*,unsigned int>((Colour*)&c,c.rgba()))==styles.end())
\r
277 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createStyleRef(c);
\r
279 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())];
\r
280 //Now check if the handle is valid
\r
281 if (styles_ref.find(style_handle)==styles_ref.end()) {
\r
282 //invalid handle recreate
\r
283 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createStyleRef(c);
\r
286 incStyleRef(style_handle);
\r
287 return style_handle;
\r
290 unsigned int OsdVector::getColorRef(const Colour &c)
\r
292 unsigned int style_handle=0;
\r
293 if (styles.find(pair<Colour*,unsigned int>((Colour*)&c,c.rgba()))==styles.end())
\r
295 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createColorRef(c);
\r
297 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())];
\r
298 if (styles_ref.find(style_handle)==styles_ref.end()) {
\r
299 //invalid handle recreate
\r
300 style_handle=styles[pair<Colour*,unsigned int>((Colour*)&c,c.rgba())]=createColorRef(c);
\r
303 incStyleRef(style_handle);
\r
304 return style_handle;
\r
307 unsigned int OsdVector::getStyleRef(unsigned int index)
\r
309 if (styles_ref.find(index)==styles_ref.end()) {
\r
312 return styles_ref[index];
\r
316 ImageIndex OsdVector::getJpegRef(const char* fileName, int *width,int *height)
\r
318 ImageIndex image_handle=0;
\r
319 if (jpegs.find(fileName)==jpegs.end())
\r
321 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
\r
323 image_handle=jpegs[fileName];
\r
326 if (images_ref.find(image_handle)==images_ref.end()) {
\r
327 //invalid handle recreate
\r
328 image_handle=jpegs[fileName]=createJpeg(fileName,width,height);
\r
331 incImageRef(image_handle);
\r
332 return image_handle;
\r
335 ImageIndex OsdVector::getMonoBitmapRef(void *base,int width,int height)
\r
337 ImageIndex image_handle;
\r
338 if (monobitmaps.find(base)==monobitmaps.end())
\r
340 image_handle=monobitmaps[base]=createMonoBitmap(base,width,height);
\r
342 image_handle=monobitmaps[base];
\r
343 if (images_ref.find(image_handle)==images_ref.end()) {
\r
344 //invalid handle recreate
\r
345 image_handle=monobitmaps[base]=createMonoBitmap(base,width,height);
\r
348 incImageRef(image_handle);
\r
349 return image_handle;
\r
352 ImageIndex OsdVector::getImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)
\r
354 ImageIndex image_handle;
\r
355 image_handle=createImagePalette(width,height,image_data,palette_data);
\r
356 incImageRef(image_handle);
\r
357 return image_handle;
\r